栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Geotools操作总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Geotools操作总结

我家的那条河

前言

最近工作上需要用到geotools工具进行开发,发现资料真的少得可怜,可能很少人用吧。后来发现这个工具类对于简单的地理信息处理还是蛮厉害,高难度(缝隙检测、道路线压盖面之类,这些可以用arcpy或者ArcEngine)的就压根没有对应的api了。本着既然用过了就总结一下,万一以后遇到就直接可以用了呗。

正文 1、 从shp文件读取要素集

这里主要是针对shp文件,操作类似于Java连接数据库,比如mybatis的sqlSession

 
    private SimpleFeatureStore getSFeatureSource(String layerShpPath) {
 try {
     String path = layerShpPath + ".shp";
     File file = new File(path);
     if (file.exists()) {
  Map params = new HashMap();
  params.put("url", file.toURI().toURL());
  for (Iterator i = DataStoreFinder.getAvailableDataStores(); i.hasNext(); ) {
      DataStoreFactorySpi factory = (DataStoreFactorySpi) i.next();
      if (factory.canProcess(params)) {
   //获取到shp数据源
   DataStore dataStore = factory.createNewDataStore(params);
   // 设置编码后可以正确读取
   ((ShapefileDataStore) dataStore).setCharset(Charset.forName("GBK"));
   //根据图层名称来获取要素的source
   SimpleFeatureStore featureSource = (SimpleFeatureStore) dataStore.getFeatureSource(dataStore.getTypeNames()[0]);
   return featureSource;
      }
  }
     }
 } catch (Exception e) {
     e.printStackTrace();
 }
 return null;
    }
2、输出要素到shp文件

输出文件就相当于我们平时定义好自己的表结构,然后获取连接数据库的连接,将表数据插入到shp文件中。

    public static ShapefileDataStore getOutputDataStore(String targetFilePath, SimpleFeatureType sourceSchema) {
 try {
     File targetFile = new File(targetFilePath);
     if (!targetFile.exists()) {
  targetFile.createNewFile();
     }
     Map params1 = new HashMap();
     params1.put(ShapefileDataStoreFactory.URLP.key, targetFile.toURI().toURL());
     ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params1);
     // create new schema
     SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
     builder.setName(sourceSchema.getName());
     builder.setSuperType((SimpleFeatureType) sourceSchema.getSuper());
     //自定义字段名
     builder.add("rowId", Integer.class);
     builder.add("ruleId", Integer.class);
     builder.add("sId", String.class);
     builder.add("curFld", String.class);
     builder.add("curVal", String.class);
     builder.add("refLayCode", String.class);
     builder.add("refLayer", String.class);
     builder.add("errDesc", String.class);
     builder.add(sourceSchema.getDescriptor("the_geom"));
     SimpleFeatureType nSchema = builder.buildFeatureType();
     ds.createSchema(nSchema);//将图层表头设置给target shape
     ds.setCharset(Charset.forName("GBK"));
     return ds;
 } catch (IOException e) {
     e.printStackTrace();
 }
 return null;
    }
3、获取要素字段属性

获取shp文件的字段属性可以通过getSchema().getAttributeDescriptors()来完成。

List attrList = sourceFeatureStore.getSchema().getAttributeDescriptors();
for (AttributeDescriptor attr : attrList) {
      //字段名
      String fieldName =  attr.getLocalName();
      //字段类型
      String typeName = attr.getType().getBinding().getSimpleName();
      //字段限制
      String restr = attr.getType().getRestrictions().toString();
}

4、遍历要素集

这里的遍历是用迭代器来实现的,所以务必记得遍历完之后需要关闭数据连接,不然会报警告的。

SimpleFeatureCollection features = sourceFeatureStore.getFeatures();
 SimpleFeatureIterator iterator = features.features();
while (iterator .hasNext()) {
      SimpleFeature next = iterator.next();
      Object geom = next.getAttribute(geometryPropertyName);
}

iterator.close();
5、按条件查询要素集

这里类似于mybatis的查询数据库,这里可以实现空间检索,也就是说通过经纬度图形,可以找到与它有相交的周边的所有要素。

Object geom = feature.getAttribute(geometryPropertyName);
Geometry geometry = reader.read(geom.toString());
Geometry boundary = geometry.getBoundary();
Filter filter = ff.intersects(ff.property(geometryPropertyName), ff.literal(boundary));
SimpleFeatureCollection features = sourceFeatureStore.getFeatures();
 SimpleFeatureIterator iterator = features.features();
while (iterator.hasNext()) {
      SimpleFeature next = iterator.next();
      Object geom = next.getAttribute(geometryPropertyName);
}
6、构建或获取要素几何图形

一、SimpleFeatureBuilder方式创建

    	//创建GeometryFactory工厂
    	GeometryFactory geometryFactory = new GeometryFactory();
    	SimpleFeatureCollection collection =null;
    	//获取类型
    	SimpleFeatureType TYPE = featureSource.getSchema();
    	System.out.println(TYPE);
 //创建要素集合
 List features = new ArrayList<>();
 //创建要素模板
 SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
 //创建要素并添加道集合
 double latitude = Double.parseDouble("39.9");
 double longitude = Double.parseDouble("116.3");
 String name ="beijing";
 int number = Integer.parseInt("16");
 //创建一个点geometry
 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
 //添加的数据一定按照SimpleFeatureType给的字段顺序进行赋值
 //添加name属性
 featureBuilder.add(name);
 //添加number属性
 featureBuilder.add(number);
 //添加geometry属性
 featureBuilder.add(point);
 //构建要素
 SimpleFeature feature = featureBuilder.buildFeature(null);

Note:featureBuilder添加的数据一定按照SimpleFeatureType给的字段顺序进行赋值!!!!!!!!!!

二、getFeatureWriter方式创建

     SimpleFeatureSource featureSource = null;
     //根据图层名称来获取要素的source
     featureSource = shpDataStore.getFeatureSource (typeName);
	 //根据参数创建shape存储空间
	 ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
	 SimpleFeatureType sft = featureSource.getSchema();
	 //创建要素模板
     SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
     //设置坐标系
     tb.setCRS(DefaultGeographicCRS.WGS84);     
     tb.setName("shapefile");
   //创建
     ds.createSchema(tb.buildFeatureType());
     //设置编码
     ds.setCharset(charset);
      
     //设置Writer,并设置为自动提交
     FeatureWriter writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
      //循环写入要素
     while (itertor.hasNext())
     {
     	//获取要写入的要素
  SimpleFeature feature = itertor.next();
  //将要写入位置
  SimpleFeature featureBuf = writer.next();
  //设置写入要素所有属性
  featureBuf.setAttributes(feature.getAttributes());
  //获取the_geom属性的值
  Geometry geo =(Geometry) feature.getAttribute("the_geom");
  Geometry geoBuffer = geoR.calBuffer(geo, 0.1);
  System.out.println(geoBuffer);
  //重新覆盖the_geom属性的值,这里的geoBuffer必须为Geometry类型
  featureBuf.setAttribute("the_geom", geoBuffer);
     } 
     //将所有数据写入
     writer.write();
     //关闭写入流
     writer.close();
     itertor.close();
 }
 catch(Exception e){
     e.printStackTrace();
 }

总结:
两种都差不多,个人感觉第二种方式创建更为灵活一点,关于第一种必须保证写入字段的Value的顺序,第二种是采用Key,value方式更为保险安全,第一种可读性更为好点。

7、获取几何图形边界

没啥好讲的,就是为了直接掉API

Geometry geometry = reader.read("MULTIPOINT(109.013388 32.715519,119.32488 31.435678)");
Geometry boundary = geometry.getBoundary();
8、JWT几何关系

几何信息和拓扑关系是地理信息系统中描述地理要素的空间位置和空间关系的不可缺少的基本信息。其中几何信息主要涉及几何目标的坐标位置、方向、角度、距离和面积等信息,它通常用解析几何的方法来分析。而空间关系信息主要涉及几何关系的“相连”、“相邻”、“包含”等信息,它通常用拓扑关系或拓扑结构的方法来分析。拓扑关系是明确定的

几何关系 说明
相等(Equals): 几何形状拓扑上相等。
脱节(Disjoint): 几何形状没有共有的点。
相交(Intersects): 几何形状至少有一个共有点(区别于脱节)
接触(Touches): 几何形状有至少一个公共的边界点,但是没有内部点。
交叉(Crosses): 几何形状共享一些但不是所有的内部点。
内含(Within): 几何形状A的线都在几何形状B内部。
包含(Contains): 几何形状B的线都在几何形状A内部(区别于内含)
重叠(Overlaps): 几何形状共享一部分但不是所有的公共点,而且相交处有他们自己相同的区域。
package com.mapbar.geo.jts;
 
import org.geotools.geometry.jts.JTSFactoryFinder;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
 

public class GeometryRelated {
	
	private GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
	
	public Point createPoint(String lon,String lat){
		Coordinate coord = new Coordinate(Double.parseDouble(lon), Double.parseDouble(lat));
		Point point = geometryFactory.createPoint( coord );
		return point;
	}
	
	
	public boolean equalsGeo() throws ParseException{
		WKTReader reader = new WKTReader( geometryFactory );
	    LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
	    LineString geometry2 = (LineString) reader.read("LINESTRING(5 0, 0 0)");
	    // return geometry1 ==geometry2;  false
	    //check if two geometries are exactly equal; right down to the coordinate level.
	    // return geometry1.equalsExact(geometry2);   false
	    return geometry1.equals(geometry2);//true
	}
	
	
	public boolean disjointGeo() throws ParseException{
		WKTReader reader = new WKTReader( geometryFactory );
	    LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
	    LineString geometry2 = (LineString) reader.read("LINESTRING(0 1, 0 2)");
	    return geometry1.disjoint(geometry2);
	}
	
	
	public boolean intersectsGeo() throws ParseException{
		WKTReader reader = new WKTReader( geometryFactory );
	    LineString geometry1 = (LineString) reader.read("LINESTRING(0 0, 2 0, 5 0)");
	    LineString geometry2 = (LineString) reader.read("LINESTRING(0 0, 0 2)");
	    Geometry interPoint = geometry1.intersection(geometry2);//相交点
	    System.out.println(interPoint.toText());//输出 POINT (0 0)
	    return geometry1.intersects(geometry2);
	}
	
	public static void main(String[] args) throws ParseException {
		GeometryRelated gr = new GeometryRelated();
		System.out.println(gr.equalsGeo());
		System.out.println(gr.disjointGeo());
		System.out.println(gr.intersectsGeo());
	}
 
}
9、Geotools创建Feature的两种方式

一、SimpleFeatureBuilder方式创建

    	//创建GeometryFactory工厂
    	GeometryFactory geometryFactory = new GeometryFactory();
    	SimpleFeatureCollection collection =null;
    	//获取类型
    	SimpleFeatureType TYPE = featureSource.getSchema();
    	System.out.println(TYPE);
 //创建要素集合
 List features = new ArrayList<>();
 //创建要素模板
 SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
 //创建要素并添加道集合
 double latitude = Double.parseDouble("39.9");
 double longitude = Double.parseDouble("116.3");
 String name ="beijing";
 int number = Integer.parseInt("16");
 //创建一个点geometry
 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
 //添加的数据一定按照SimpleFeatureType给的字段顺序进行赋值
 //添加name属性
 featureBuilder.add(name);
 //添加number属性
 featureBuilder.add(number);
 //添加geometry属性
 featureBuilder.add(point);
 //构建要素
 SimpleFeature feature = featureBuilder.buildFeature(null);

Note:featureBuilder添加的数据一定按照SimpleFeatureType给的字段顺序进行赋值!!!!!!!!!!
二、getFeatureWriter方式创建

     SimpleFeatureSource featureSource = null;
     //根据图层名称来获取要素的source
     featureSource = shpDataStore.getFeatureSource (typeName);
	 //根据参数创建shape存储空间
	 ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
	 SimpleFeatureType sft = featureSource.getSchema();
	 //创建要素模板
     SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
     //设置坐标系
     tb.setCRS(DefaultGeographicCRS.WGS84);     
     tb.setName("shapefile");
   //创建
     ds.createSchema(tb.buildFeatureType());
     //设置编码
     ds.setCharset(charset);
      
     //设置Writer,并设置为自动提交
     FeatureWriter writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
      //循环写入要素
     while (itertor.hasNext())
     {
     	//获取要写入的要素
  SimpleFeature feature = itertor.next();
  //将要写入位置
  SimpleFeature featureBuf = writer.next();
  //设置写入要素所有属性
  featureBuf.setAttributes(feature.getAttributes());
  //获取the_geom属性的值
  Geometry geo =(Geometry) feature.getAttribute("the_geom");
  Geometry geoBuffer = geoR.calBuffer(geo, 0.1);
  System.out.println(geoBuffer);
  //重新覆盖the_geom属性的值,这里的geoBuffer必须为Geometry类型
  featureBuf.setAttribute("the_geom", geoBuffer);
     } 
     //将所有数据写入
     writer.write();
     //关闭写入流
     writer.close();
     itertor.close();
 }
 catch(Exception e){
     e.printStackTrace();
 }

总结:
两种都差不多,个人感觉第二种方式创建更为灵活一点,关于第一种必须保证写入字段的Value的顺序,第二种是采用Key,value方式更为保险安全,第一种可读性更为好点。

参考文章

https://blog.csdn.net/weixin_40184249/article/details/84480652
http://www.aiuxian.com/article/p-455672.html

最后

如果对 Java、大数据感兴趣请长按二维码关注一波,我会努力带给你们价值。觉得对你哪怕有一丁点帮助的请帮忙点个赞或者转发哦。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/237924.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号