# gis-postgis-jts **Repository Path**: optcode/gis-postgis-jts ## Basic Information - **Project Name**: gis-postgis-jts - **Description**: PostGIS + Postgresql + JTS + GeoJSON +Jackson 序列化反序列化 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 10 - **Created**: 2023-05-27 - **Last Updated**: 2023-05-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gis-postgis-jts # GEOJSON官网:[GEOJSON](https://geojson.org/) #### 介绍 PostGIS + Postgresql + JTS + GeoJSON +Jackson 序列化反序列化 java中使用postgis操作地理位置数据简单说明了基本的postgis建模,还有其如何与java程序进行数据交互。 但postgis-jdbc中提供的java模型生态与通用行不好,在java生态中,还有一个专门进行几何运算的库[JTS](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Flocationtech%2Fjts)。 JTS Topology Suite([JTS](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Flocationtech%2Fjts))拓扑套件是开源Java软件库,它提供平面几何的对象模型以及一组基本几何功能。并且 [JTS](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Flocationtech%2Fjts)符合Open GIS联盟发布的SQL简单功能规范(Simple Features Specification for SQL)。所以[JTS](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Flocationtech%2Fjts) 不仅可以和postgis的数据进行交互,并且还可以在java层提供空间数据关系的运算。 下面会介绍下怎样在一个java项目中引入[JTS](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Flocationtech%2Fjts)并与postgis中的数据进行交互 引入[JTS](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Flocationtech%2Fjts) 使用maven,直接引入`jts-core`即可 > ``` > > org.locationtech.jts > jts-core > 1.18.2 > > ``` 其中核心是`org.locationtech.jts.geom.Geometry`类,可以看到其结构与postgis的数据类型是基本一致的 ![img](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/1/6/16f79b319d1393c4~tplv-t2oaga2asx-zoom-in-crop-mark:1304:0:0:0.awebp) # JTS与GeoJSON 格式序列化反序列化 引入maven jar ``` com.gis.postgis postgis-geojson-jts 1.0-SNAPSHOT ``` ```java package com.gis.postgis.jts; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.gis.postgis.geojson.collection.FeatureCollection; import com.gis.postgis.geojson.crs.Crs; import com.gis.postgis.geojson.crs.CrsType; import com.gis.postgis.jackson.JtsModule; import com.gis.postgis.jts.bean.Feature; import com.gis.postgis.jts.bean.Features; import com.gis.postgis.jts.bean.GeomCollection; import com.google.common.collect.Maps; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryCollection; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.PrecisionModel; import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; /** * 〈功能简述〉
* 〈〉 * * @author Mr.QL * @ClassName geojsonTest * @Date 2022-03-05 13:22 * @Version 1.0 */ public class geojsonTest { private static ObjectMapper objectMapper = new ObjectMapper(); private static GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); private static WKTReader wktReader = new WKTReader(geometryFactory); static { objectMapper.registerModule(jtsModule()); } public static JtsModule jtsModule() { return new JtsModule(geometryFactory()); } public static GeometryFactory geometryFactory() { return new GeometryFactory(precisionModel(), 4326); } public static PrecisionModel precisionModel() { return new PrecisionModel(); } public static void main(String[] args) throws IOException, ParseException { TestFeatureVO(); TestFeature(); TestFeatures(); TestGeomCollection(); } private static void TestFeatureVO() throws JsonProcessingException, ParseException { Geometry location = wktReader.read("POINT(2.2944313287734985 48.85826523681466)"); System.out.println("--------------泛型---------------------"); com.gis.postgis.geojson.collection.Feature geometryFeature = new com.gis.postgis.geojson.collection.Feature(location); String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(geometryFeature); System.out.println(json); com.gis.postgis.geojson.collection.Feature geometryFeature1 = objectMapper.readValue(json, new TypeReference>() { }); System.out.println(geometryFeature1.toString()); } public static void TestFeature() throws IOException, ParseException { Geometry location = wktReader.read("POINT(2.2944313287734985 48.85826523681466)"); Feature fe = new Feature(1L, "Eiffel Tower", "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France", location); String jsonx = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(fe); System.out.println(jsonx); Feature featurex = objectMapper.readValue(jsonx, Feature.class); System.out.println(featurex.toString()); String jsonxx = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featurex); System.out.println(jsonxx); Crs crs = new Crs(); crs.setType(CrsType.link); Map properties = Maps.newHashMap(); properties.put("href","http://example.com/crs/42"); properties.put("type", "proj4"); crs.setProperties(properties); fe.setCrs(crs); double[] bbox = new double[]{-180.0, -90.0, 180.0, 90.0}; fe.setBbox(bbox); String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(fe); System.out.println(json); Feature feature = objectMapper.readValue(json, Feature.class); System.out.println(feature.toString()); String jsonvo = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(feature); System.out.println(jsonvo); Feature fe2 = new Feature(2L, "CHONGQING Tower", "CHONGQING CHINA", location); Crs crs2 = new Crs(); Map properties2 = Maps.newHashMap(); properties2.put("name","urn:ogc:def:crs:OGC:1.3:CRS84"); crs2.setProperties(properties2); fe2.setCrs(crs2); fe2.setBbox(bbox); String json2 = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(fe2); System.out.println(json2); Feature feature2 = objectMapper.readValue(json2, Feature.class); System.out.println(feature2.toString()); String jsonvo2 = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(feature2); System.out.println(jsonvo2); } public static void TestFeatures() throws IOException, ParseException { Geometry location = wktReader.read("POINT(2.2944313287734985 48.85826523681466)"); Feature fe = new Feature(1L, "Eiffel Tower", "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France", location); Crs crs = new Crs(); crs.setType(CrsType.link); Map properties = Maps.newHashMap(); properties.put("href","http://example.com/crs/42"); properties.put("type", "proj4"); crs.setProperties(properties); fe.setCrs(crs); double[] bbox = new double[]{-180.0, -90.0, 180.0, 90.0}; fe.setBbox(bbox); Feature fe2 = new Feature(2L, "CHONGQING Tower", "CHONGQING CHINA", location); Crs crs2 = new Crs(); Map properties2 = Maps.newHashMap(); properties2.put("name","urn:ogc:def:crs:OGC:1.3:CRS84"); crs2.setProperties(properties2); fe2.setCrs(crs2); fe2.setBbox(bbox); ArrayList features = new ArrayList<>(); features.add(fe); features.add(fe2); System.out.println("-------------继承------------------"); FeatureCollection featureCollection = new Features().build(features); featureCollection.setBbox(bbox); String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCollection); System.out.println(json); FeatureCollection featureCol = objectMapper.readValue(json, Features.class); String s = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCol); System.out.println(s); System.out.println("-------------泛型------------------"); FeatureCollection featureCollection2 = new FeatureCollection().build(features); featureCollection2.setBbox(bbox); String jsons = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCollection2); System.out.println(jsons); FeatureCollection featureCol2 = objectMapper.readValue(jsons, new TypeReference>() { }); String jsonss = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCol2); System.out.println(jsonss); FeatureCollection featureCollection3 = new FeatureCollection(); String jsons3 = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCollection3); System.out.println(jsons3); FeatureCollection featureCol3 = objectMapper.readValue(jsons3, new TypeReference>() { }); String jsons3s = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCol3); System.out.println(jsons3s); } public static void TestGeomCollection() throws IOException, ParseException { Geometry location = wktReader.read("POINT(2.2944313287734985 48.85826523681466)"); Geometry Line = wktReader.read("LineString (0 0, 1 1, 2 2,3 3)"); org.locationtech.jts.geom.LinearRing lr = new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(0, 0), new Coordinate(0, 10), new Coordinate(10, 10), new Coordinate(10, 0), new Coordinate(0, 0)}); ArrayList geometries = new ArrayList<>(); geometries.add(location); geometries.add(Line); geometries.add(lr); System.out.println("----------------继承-------------------"); com.gis.postgis.geojson.collection.GeometryCollection featureCollection = new GeomCollection().build(geometries); String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCollection); System.out.println(json); GeomCollection featureCol = objectMapper.readValue(json, GeomCollection.class); String s = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(featureCol); System.out.println(s); System.out.println("-----------------集合------------------"); Geometry[] garray = new Geometry[]{location, Line}; GeometryCollection gc = geometryFactory.createGeometryCollection(garray); String jsongc = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(gc); System.out.println(jsongc); GeometryCollection geometryCollection = objectMapper.readValue(jsongc, GeometryCollection.class); String jsongcc = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(geometryCollection); System.out.println(jsongcc); System.out.println("----------------泛型-------------------"); com.gis.postgis.geojson.collection.GeometryCollection collection = new com.gis.postgis.geojson.collection.GeometryCollection().build(geometries); String jsons = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(collection); System.out.println(jsons); com.gis.postgis.geojson.collection.GeometryCollection geometryGeometryCollection = objectMapper.readValue(json, new TypeReference>() { }); String ss = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(geometryGeometryCollection); System.out.println(ss); } } 运行结果: --------------泛型--------------------- { "type" : "Feature", "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] } } Feature{geom=POINT (2.2944313287734985 48.85826523681466)} { "type" : "Feature", "id" : 1, "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" } } Feature{id=1, name='Eiffel Tower', description='Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France', location=POINT (2.2944313287734985 48.85826523681466)}GeoJsonObject{crs=null, bbox=null} { "type" : "Feature", "id" : 1, "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" } } { "type" : "Feature", "id" : 1, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" }, "crs" : { "type" : "link", "properties" : { "href" : "http://example.com/crs/42", "type" : "proj4" } } } Feature{id=1, name='Eiffel Tower', description='Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France', location=POINT (2.2944313287734985 48.85826523681466)}GeoJsonObject{crs=Crs{type='link', properties={href=http://example.com/crs/42, type=proj4}}, bbox=[-180.0, -90.0, 180.0, 90.0]} { "type" : "Feature", "id" : 1, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" }, "crs" : { "type" : "link", "properties" : { "href" : "http://example.com/crs/42", "type" : "proj4" } } } { "type" : "Feature", "id" : 2, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "CHONGQING Tower", "description" : "CHONGQING CHINA" }, "crs" : { "type" : "name", "properties" : { "name" : "urn:ogc:def:crs:OGC:1.3:CRS84" } } } Feature{id=2, name='CHONGQING Tower', description='CHONGQING CHINA', location=POINT (2.2944313287734985 48.85826523681466)}GeoJsonObject{crs=Crs{type='name', properties={name=urn:ogc:def:crs:OGC:1.3:CRS84}}, bbox=[-180.0, -90.0, 180.0, 90.0]} { "type" : "Feature", "id" : 2, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "CHONGQING Tower", "description" : "CHONGQING CHINA" }, "crs" : { "type" : "name", "properties" : { "name" : "urn:ogc:def:crs:OGC:1.3:CRS84" } } } -------------继承------------------ { "type" : "FeatureCollection", "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "features" : [ { "type" : "Feature", "id" : 1, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" }, "crs" : { "type" : "link", "properties" : { "href" : "http://example.com/crs/42", "type" : "proj4" } } }, { "type" : "Feature", "id" : 2, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "CHONGQING Tower", "description" : "CHONGQING CHINA" }, "crs" : { "type" : "name", "properties" : { "name" : "urn:ogc:def:crs:OGC:1.3:CRS84" } } } ] } { "type" : "FeatureCollection", "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "features" : [ { "type" : "Feature", "id" : 1, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" }, "crs" : { "type" : "link", "properties" : { "href" : "http://example.com/crs/42", "type" : "proj4" } } }, { "type" : "Feature", "id" : 2, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "CHONGQING Tower", "description" : "CHONGQING CHINA" }, "crs" : { "type" : "name", "properties" : { "name" : "urn:ogc:def:crs:OGC:1.3:CRS84" } } } ] } -------------泛型------------------ { "type" : "FeatureCollection", "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "features" : [ { "type" : "Feature", "id" : 1, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" }, "crs" : { "type" : "link", "properties" : { "href" : "http://example.com/crs/42", "type" : "proj4" } } }, { "type" : "Feature", "id" : 2, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "CHONGQING Tower", "description" : "CHONGQING CHINA" }, "crs" : { "type" : "name", "properties" : { "name" : "urn:ogc:def:crs:OGC:1.3:CRS84" } } } ] } { "type" : "FeatureCollection", "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "features" : [ { "type" : "Feature", "id" : 1, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "Eiffel Tower", "description" : "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France" }, "crs" : { "type" : "link", "properties" : { "href" : "http://example.com/crs/42", "type" : "proj4" } } }, { "type" : "Feature", "id" : 2, "bbox" : [ -180.0, -90.0, 180.0, 90.0 ], "geometry" : { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, "properties" : { "name" : "CHONGQING Tower", "description" : "CHONGQING CHINA" }, "crs" : { "type" : "name", "properties" : { "name" : "urn:ogc:def:crs:OGC:1.3:CRS84" } } } ] } { "type" : "FeatureCollection", "features" : [ ] } { "type" : "FeatureCollection", "features" : [ ] } ----------------继承------------------- { "type" : "GeometryCollection", "geometries" : [ { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, { "type" : "LineString", "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 1.0 ], [ 2.0, 2.0 ], [ 3.0, 3.0 ] ] }, { "type" : "LinearRing", "coordinates" : [ [ 0.0, 0.0 ], [ 0.0, 10.0 ], [ 10.0, 10.0 ], [ 10.0, 0.0 ], [ 0.0, 0.0 ] ] } ] } { "type" : "GeometryCollection", "geometries" : [ { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, { "type" : "LineString", "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 1.0 ], [ 2.0, 2.0 ], [ 3.0, 3.0 ] ] }, { "type" : "LinearRing", "coordinates" : [ [ 0.0, 0.0 ], [ 0.0, 10.0 ], [ 10.0, 10.0 ], [ 10.0, 0.0 ], [ 0.0, 0.0 ] ] } ] } -----------------集合------------------ { "type" : "GeometryCollection", "geometries" : [ { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, { "type" : "LineString", "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 1.0 ], [ 2.0, 2.0 ], [ 3.0, 3.0 ] ] } ] } { "type" : "GeometryCollection", "geometries" : [ { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, { "type" : "LineString", "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 1.0 ], [ 2.0, 2.0 ], [ 3.0, 3.0 ] ] } ] } ----------------泛型------------------- { "type" : "GeometryCollection", "geometries" : [ { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, { "type" : "LineString", "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 1.0 ], [ 2.0, 2.0 ], [ 3.0, 3.0 ] ] }, { "type" : "LinearRing", "coordinates" : [ [ 0.0, 0.0 ], [ 0.0, 10.0 ], [ 10.0, 10.0 ], [ 10.0, 0.0 ], [ 0.0, 0.0 ] ] } ] } { "type" : "GeometryCollection", "geometries" : [ { "type" : "Point", "coordinates" : [ 2.2944313287734985, 48.85826523681466 ] }, { "type" : "LineString", "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 1.0 ], [ 2.0, 2.0 ], [ 3.0, 3.0 ] ] }, { "type" : "LinearRing", "coordinates" : [ [ 0.0, 0.0 ], [ 0.0, 10.0 ], [ 10.0, 10.0 ], [ 10.0, 0.0 ], [ 0.0, 0.0 ] ] } ] } ``` ## 备注:GIS开发文档友情链接 [GIS麻辣香锅](https://gitee.com/good_money/gis-spicy-hot-pot) [Jackson-datatype-jts](https://github.com/bedatadriven/jackson-datatype-jts) [geojson-serializer](https://github.com/ancore/geojson-serializer)