工作之余记录,没有美化好: POM引入: <!-- for geotools begin --> <!--处理空间数据--> <!-- geotools主要依赖 --> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-metadata</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-referencing</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-epsg-wkt</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-shapefile</artifactId> <version>27.2</version> </dependency> <!--<dependency>--> <!--<groupId>org.geotools</groupId>--> <!--<artifactId>gt-data</artifactId>--> <!--<version>27.2</version>--> <!--</dependency>--> <!--<dependency>--> <!--<groupId>org.geotools</groupId>--> <!--<artifactId>gt-api</artifactId>--> <!--<version>27.2</version>--> <!--</dependency>--> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-main</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-swing</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-jdbc</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools.jdbc</groupId> <artifactId>gt-jdbc-postgis</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-opengis</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-epsg-hsql</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-geojson</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-process-feature</artifactId> <version>27.2</version> </dependency> <dependency> <groupId>org.locationtech.jts</groupId> <artifactId>jts-core</artifactId> <version>1.18.2</version> </dependency> <!--for geotools end--> <!--读取geojson文件--> <dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.wowtools</groupId> <artifactId>giscat-vector-pojo</artifactId> <version>1.1.1-STABLE</version> </dependency> <!--读取geojson文件end--> </dependencies> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> <!-- geotools的远程库 --> <repository> <id>osgeo</id> <name>OSGeo Release Repository</name> <url>https://repo.osgeo.org/repository/release/</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> <repository> <id>osgeo-snapshot</id> <name>OSGeo Snapshot Repository</name> <url>https://repo.osgeo.org/repository/snapshot/</url> <snapshots> <enabled>true</enabled> </snapshots> <releases> <enabled>false</enabled> </releases> </repository> <!-- geotools的远程库end -->
import org.geotools.data.DefaultTransaction; import org.geotools.data.FeatureSource; import org.geotools.data.Transaction; import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.shapefile.ShapefileDataStoreFactory; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.data.simple.SimpleFeatureSource; import org.geotools.data.simple.SimpleFeatureStore; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.filter.text.cql2.CQL; import org.geotools.geojson.GeoJSON; import org.geotools.geojson.feature.FeatureJSON; import org.geotools.geojson.geom.GeometryJSON; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.util.factory.GeoTools; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.MultiPolygon; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; import org.opengis.feature.Property; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory2; import org.springframework.stereotype.Component; import java.io.*; import java.net.MalformedURLException; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.*; @Component public class GeoToolsMethod { //使用openGIS FilterFactory2 private static org.opengis.filter.FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()); //读取shp public FeatureSource<SimpleFeatureType, SimpleFeature> ReadShpFile(String filePath) throws Exception{ File dir = new File(filePath); File[] subFiles = dir.listFiles(); if (null!=subFiles){ for (File subFile : subFiles) { if (subFile.getName().endsWith(".shp")) { filePath = subFile.getPath();break; } } } File shpFile = new File(filePath); //源shape文件 //ShapefileDataStore shpDataStore = (ShapefileDataStore) new ShapefileDataStoreFactory().createDataStore(subFile.toURI().toURL()); ShapefileDataStore shpDataStore = new ShapefileDataStore(shpFile.toURI().toURL()); shpDataStore.setCharset(Charset.forName("UTF-8")); FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = shpDataStore.getFeatureSource(); return featureSource; } //读取geojson public FeatureCollection ReadGeojsonFile(String pathfile) throws Exception{ FeatureCollection featureCollection = null; //创建一个JSONParser对象 JSONParser jsonParser = new JSONParser(); //解析JSON文件的内容 try { //String pathfile = getClass().getClassLoader().getResource("csdata").getPath()+"/csfeature.geojson"; //先用json.simple读取geojson文件 // org.json.simple.JSONObject obj = (org.json.simple.JSONObject) jsonParser.parse(new FileReader("D:/hjyTest/JAVA/demo_gdal2/target/classes/csdata/csfeature.geojson")); JSONObject obj = (JSONObject) jsonParser.parse(new FileReader(pathfile)); //JSONObject obj = (JSONObject) jsonParser.parse(new FileReader("E:\\河南省乡镇点\\FieldPolygon.geojson")); //删除除features以外其它对象,方便下面所需的geojson字符串 // obj.remove("type"); // obj.remove("name"); // obj.remove("crs"); //获取features对象json字符串 String strGeoJson =obj.toString(); System.out.println(strGeoJson); // 指定GeometryJSON构造器,15位小数 FeatureJSON fjson_15 = new FeatureJSON(new GeometryJSON(15)); // fjson_15已经保留15位 fjson_15.setEncodeFeatureCollectionCRS(true); fjson_15.setEncodeNullValues(true); featureCollection = fjson_15.readFeatureCollection(strGeoJson); fjson_15.writeFeatureCollection(featureCollection,System.out); // 控制台输出和原始geojson一致 // OutputStream ostream = new ByteArrayOutputStream(); // GeoJSON.write(featureCollection, ostream); // // 输出:{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[116.1983,39.7832],[116.0445,39.2323],[116.8959,39.3831],[116.8698,39.9182],[116.1983,39.7832]]]},"properties":{"area":3865207830},"id":"polygon.1"}]} // System.out.println(ostream); // //获取数据 // FeatureIterator<SimpleFeature> iterator = featureCollection.features(); // while(iterator.hasNext()) { // SimpleFeature feature = iterator.next(); // try{ // org.locationtech.jts.geom.Geometry geom1 = (org.locationtech.jts.geom.Geometry) feature.getDefaultGeometry(); // System.out.println(geom1.getCoordinate()); // }catch (Exception e){ // // } // // // feature.getName(); // Iterator<Property> it = feature.getProperties().iterator(); // LinkedHashMap<String, Object> data = new LinkedHashMap<>(); // String geometry = ""; // while (it.hasNext()) { // Property pro = it.next(); // if (pro.getValue() instanceof org.locationtech.jts.geom.Point) {//点 // geometry = "'" + ((org.locationtech.jts.geom.Point) pro.getValue()).toString() + "'"; // data.put("geom", geometry); // } else if (pro.getValue() instanceof org.locationtech.jts.geom.Polygon) {//面 // geometry = "'" + ((org.locationtech.jts.geom.Polygon) pro.getValue()).toString() + "'"; // data.put("geom", geometry); // } else if (pro.getValue() instanceof org.locationtech.jts.geom.MultiPolygon) {//多面 // geometry = "'" + ((org.locationtech.jts.geom.MultiPolygon) pro.getValue()).toString() + "'"; // data.put("geom", geometry); // } else if (pro.getValue() instanceof org.locationtech.jts.geom.LineString) {//线 // geometry = "'" + ((org.locationtech.jts.geom.LineString) pro.getValue()).toString() + "'"; // data.put("geom", geometry); // } else { // data.put(pro.getName().toString(), pro.getValue()); // } // } // System.out.println(data); // } } catch (IOException e) { e.printStackTrace(); } return featureCollection; } //方法一: //返回其属性值 public List<LinkedHashMap<String,Object>> getAttirbutes(String srs, FeatureCollection col){ //srs="EPSG:4326" List<LinkedHashMap<String,Object>> listMap = new ArrayList<>(); FeatureIterator<SimpleFeature> iterator = col.features(); while(iterator.hasNext()) { SimpleFeature feature = iterator.next(); //获取属性 Iterator<Property> it = feature.getProperties().iterator(); LinkedHashMap<String, Object> data = new LinkedHashMap<>(); String geometry = ""; while (it.hasNext()) { Property pro = it.next(); if (pro.getValue() instanceof Point) {//点 geometry = "'" +((Point) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else if (pro.getValue() instanceof Polygon) {//面 geometry = "'"+((Polygon) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else if (pro.getValue() instanceof MultiPolygon) {//多面 geometry = "'"+((MultiPolygon) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else if (pro.getValue() instanceof LineString) {//线 geometry = "'" +((LineString) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else { if(pro.getValue() instanceof Date){ Date myDate = (Date)pro.getValue(); SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String strDate3 = sdf3.format(myDate); data.put(pro.getName().toString(),strDate3); }else{ data.put(pro.getName().toString(),pro.getValue()); } } } //System.out.println(data); listMap.add(data); } return listMap; } //方法二: //返回属性值 public List<LinkedHashMap<String,Object>> getAttirbutes2(String srs, FeatureCollection col){ //srs="EPSG:4326" List<LinkedHashMap<String,Object>> listMap = new ArrayList<>(); //另外一种循环start SimpleFeatureCollection sfc = (SimpleFeatureCollection)col; // 获取当前矢量数据有哪些属性字段值 List<AttributeDescriptor> attributes = sfc.getSchema().getAttributeDescriptors(); // 拿到迭代器 SimpleFeatureIterator simpleFeatureIterator = sfc.features(); // 遍历每一个要素 while(simpleFeatureIterator.hasNext()) { SimpleFeature simpleFeature = simpleFeatureIterator.next(); LinkedHashMap<String, Object> data = new LinkedHashMap<>(); // java8新特性流api attributes.stream().forEach((a) -> { Object tempobj = simpleFeature.getAttribute(a.getLocalName()); // 依次读取这个shape中每一个属性值,当然这个属性值,可以处理其它业务 if(a.getLocalName().indexOf("geom")>=0){ String geometry = ""; if (tempobj instanceof Point) {//点 geometry = "'" +((Point) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else if (tempobj instanceof Polygon) {//面 geometry = "'"+((Polygon) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else if (tempobj instanceof MultiPolygon) {//多面 geometry = "'"+((MultiPolygon) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } else if (tempobj instanceof LineString) {//线 geometry = "'" +((LineString) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1); data.put("geom",geometry); } }else{ if(tempobj instanceof Date){ Date myDate = (Date)tempobj; SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String strDate3 = sdf3.format(myDate); data.put(a.getLocalName(),strDate3); }else{ data.put(a.getLocalName(),tempobj); } // System.out.println(a.getLocalName() + ":" + simpleFeature.getAttribute(a.getLocalName())); } }); listMap.add(data); } return listMap; } //查询 CQL public Filter ReturnFilter(String sql)throws Exception{ String wkt = "POLYGON ((113.17574362102584 23.135924459989738, 113.07445367113468 22.981863911800943, 113.3121749821035 22.932375044753726, 113.3907263718155 23.073180341529934, 113.17574362102584 23.135924459989738))"; Filter filter = null; // 相交 filter = CQL.toFilter( "OBJECTID = 5 or INTERSECTS(the_geom," + wkt + ")"); if(sql!=null || sql!=""){ filter = CQL.toFilter(sql); } // 在10公里以内 // Filter filter = CQL.toFilter( "DWITHIN(the_geom," + wkt + ", 10, kilometers)"); return filter; } //查询 使用openGIS FilterFactory2 public Filter ReturnFilter2(){ Filter filter = ff.greaterOrEqual(ff.property("OBJECTID"), ff.literal(5)); return filter; } public static SimpleFeatureType createType(Class<?> c, String layerName) { SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.setCRS(DefaultGeographicCRS.WGS84); builder.add("FID",String.class); builder.add("the_geom", c); // 设置了图层的名字 builder.setName(layerName); SimpleFeatureType simpleFeatureType = builder.buildFeatureType(); return simpleFeatureType; } //生成shp public static void createShp(String shpPath, SimpleFeatureCollection collection) throws IOException { File shpFile = new File(shpPath); ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory(); SimpleFeatureType simpleFeatureType = collection.getSchema(); // 创造shpstore需要的参数 Map<String, Serializable> params = new HashMap<>(); params.put("url", shpFile.toURI().toURL()); params.put("create spatial index", Boolean.TRUE); ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params); newDataStore.createSchema(simpleFeatureType); Transaction transaction = new DefaultTransaction("create"); String typeName = newDataStore.getTypeNames()[0]; SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName); SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource; featureStore.setTransaction(transaction); featureStore.addFeatures(collection); featureStore.setTransaction(transaction); transaction.commit(); transaction.close(); } / //这里也是读取shp public static SimpleFeatureCollection readFeatureCollection(String shpPath) { SimpleFeatureCollection featureCollection = null; File shpFile = new File(shpPath); try { ShapefileDataStore shapefileDataStore = new ShapefileDataStore(shpFile.toURI().toURL()); // 设置编码,防止属性的中文字符出现乱码 shapefileDataStore.setCharset(Charset.forName("UTF-8")); // 这个typeNamae不传递,默认是文件名称 FeatureSource featuresource = shapefileDataStore.getFeatureSource(shapefileDataStore.getTypeNames()[0]); featureCollection = (SimpleFeatureCollection) featuresource.getFeatures(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return featureCollection; } }
@Autowired
GeoToolsMethod geoToolsMethod;
//测试geoTools封装好的方法
@Test
public void Test_geoToolsMethod() throws Exception{
//测试读取shp
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource=geoToolsMethod.ReadShpFile("D:\\ceshi\\dwq0606");
String srs = CRS.lookupIdentifier(featureSource.getSchema().getCoordinateReferenceSystem(),true); // 获取EPSG
System.out.println(srs);
FeatureCollection collection = featureSource.getFeatures();
long startTime = System.currentTimeMillis();
//测试获取getAttributes
List<LinkedHashMap<String,Object>> listAttr = geoToolsMethod.getAttirbutes(srs,collection);
long endTime = System.currentTimeMillis();
System.out.println("运行时长:"+(endTime-startTime)+"ms"); //1128ms
startTime = System.currentTimeMillis();
//测试获取getAttributes2
List<LinkedHashMap<String,Object>> listAttr2 = geoToolsMethod.getAttirbutes2(srs,collection);
endTime = System.currentTimeMillis();
System.out.println("运行时长:"+(endTime-startTime)+"ms"); //980ms 1015
//System.out.println(listAttr);
}
//做geometry 的计算距离,取交集、合并几何、difference
@Test
public void GeometryOperate() throws Exception{
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
//创建一条线
List<Coordinate> points1 = new ArrayList<Coordinate>();
points1.add(new Coordinate(0,0));
points1.add(new Coordinate(1,3));
points1.add(new Coordinate(2,3));
Coordinate[] coords = (Coordinate[]) points1.toArray(new Coordinate[points1.size()]);
LineString line1 = geometryFactory.createLineString(coords);
//创建第二条线
List<Coordinate> points2 = new ArrayList<Coordinate>();
points2.add(new Coordinate(3,0));
points2.add(new Coordinate(3,3));
points2.add(new Coordinate(5,6));
Coordinate[] coords2 = (Coordinate[]) points2.toArray(new Coordinate[points2.size()]);
LineString line2 = geometryFactory.createLineString(coords2);
// 返回(A)与(B)中距离最近的两个点的距离
System.out.println(line1.distance(line2));//out 1.0
// 两个几何对象的交集
System.out.println(line1.intersection(line2));//out GEOMETRYCOLLECTION EMPTY
// 几何对象合并
Geometry lineunion = line1.union(line2);
System.out.println(lineunion); //out MULTILINESTRING ((0 0, 1 3, 2 3), (3 0, 3 3, 5 6))
//在A几何对象中有的,但是B几何对象中没有
System.out.println(line1.difference(line2));//out LINESTRING (0 0, 1 3, 2 3)
System.out.println(lineunion.difference(line2));//out LINESTRING (0 0, 1 3, 2 3)
//交集
System.out.println(lineunion.intersection(line2));//out MULTILINESTRING ((3 0, 3 3), (3 3, 5 6))
WKTReader reader = new WKTReader(geometryFactory);
Polygon geometry1 = (Polygon) reader.read("POLYGON((0 0, 2 0 ,2 2, 0 2,0 0))");
Polygon geometry2 = (Polygon) reader.read("POLYGON((0 0, 4 0 , 4 1, 0 1, 0 0))");
OverlayOp op = new OverlayOp(geometry1,geometry2);
Geometry g =op.getResultGeometry(OverlayOp.INTERSECTION);//POLYGON ((2 0, 0 0, 0 1, 2 1, 2 0))
//Geometry g2 = op.getResultGeometry(OverlayOp.UNION);
//Geometry g3 = op.getResultGeometry(OverlayOp.DIFFERENCE);
//Geometry g4 = op.getResultGeometry(OverlayOp.SYMDIFFERENCE);
//PlanarGraph p = op.getGraph(); //图<v,e
//LineMerger 线路合并,线路之间不能有交点,并且只在线路末尾有公共交点
// lineMerger 和union区别,union可以在两条相交的线中生成交点(noded)
WKTReader wktReader = new WKTReader();
LineMerger lineMerger = new LineMerger();
List<Geometry> list = new ArrayList<Geometry>();
list.add(wktReader.read("LINESTRING (3 3,2 2,0 0)"));
list.add(wktReader.read("LINESTRING (3 3,6 6,0 10)"));
list.add(wktReader.read("LINESTRING (0 10,3 1,10 1)"));
lineMerger.add(list);
Collection<Geometry> mergerLineStrings = lineMerger.getMergedLineStrings();
for (Geometry tempg : mergerLineStrings) {
System.out.println(tempg.toText()); //LINESTRING (0 0, 2 2, 3 3, 6 6, 0 10, 3 1, 10 1)
}
}