GeoTools从入门到使用
GeoTools是什么
Geotools是一个符合OGC标准(也称为OpenGIS标准)的Java类库,它提供了很多的标准类来处理空间数据。OpenGIS标准是一个空间数据处理的国际标准。目前的大部分基于Java的开源GIS软件,如udig,geoserver等,都是调用GeoTools库来进行空间数据的处理。 GeoTools是一个处理空间数据的工具包,其中包含构建一个完整的地理信息系统所需要的的全部工具类,常见的问题比如投影的转换、基准面的设定、空间数据对象的渲染和样式、各种数据源的支持、各种GIS文件格式支持、空间数据过滤与搜索等,都有对应的解决方案,这些解决方案被封装成一个一个的类,可供用户调用
GeoTools的组成
简单的说GeoTools由GeoAPI,JTS(Java Topology Suite),以及其自身实现GeoAPI接口的代码、支持的一些插件(如连接postgis的插件)
GeoAPI是根据OpenGIS规范而开发一组Java接口,这组接口代表了OpenGIS规范。GeoTools自身的代码实现了GeoAPI中的接口,从而也就是实现了OpenGIS标准。GeoAPI制定了地理信息系统中所有的数据类型应该是什么,投影转换的方式有哪几种诸如此类的规范,所以兼容GeoAPI接口的GeoTools是一个符合规范的地理信息系统工具包。
JTS是用来做空间图形的拓扑关系判断的一个Java类库。它在GeoTools出现之前就已经存在了,所以GeoTools项目在解决空间对象拓扑判定问题的时候,就没有自己重新开发,而是直接采用了JTS,将JTS作为自己的一部分,纳入自己的体系中了。JTS解决了对象与对象之间拓扑关系的判定和计算,所以,它提供了很多算法来解决对象之间包含关系、相交关系等的拓扑关系判定问题。
GeoTools实战
从postgis中加载图层数据到内存里,并建立四叉树索引
private static DataStore ConnPostGis(String host, int port,String dataBase,
String userName,String password,String schema) throws IOException {
Map<String, Object> params = new HashMap<>();
params.put("dbtype", "postgis");
params.put("host", host);
params.put("port", port);
params.put("schema", "public");
params.put("database", dataBase);
params.put("user", userName);
params.put("passwd", password);
params.put("Expose primary keys",true);
return DataStoreFinder.getDataStore(params);
。。。省略的代码,只写关键代码
pgDatastore = ConnPostGis(fenceDatabaseConfig.getHost(),fenceDatabaseConfig.getPort(),fenceDatabaseConfig.getDatabase(),fenceDatabaseConfig.getUsername(),fenceDatabaseConfig.getPasswd(),"");
fenceLayernames = Arrays.asList(fenceDatabaseConfig.getLoadlayernames().split(","));
for(String layerName : fenceLayernames) {
SimpleFeatureSource featureSource = pgDatastore.getFeatureSource(layerName);
//普通要素集转换成带索引的要素集
SpatialIndexFeatureCollection spatialIndexFeatureCollection = new SpatialIndexFeatureCollection(featureSource.getFeatures());
mapping.put(layerName,spatialIndexFeatureCollection);
}
点面相交查询(在建立好四叉树索引的面要素集合里面查出与给定点相交的面)
SpatialIndexFeatureCollection spatialIndexFeatureCollection = FeaturesHoldContainer.get(layerName);
Coordinate coordinate = new Coordinate();
coordinate.x = Double.parseDouble(geo.split(",")[0]);
coordinate.y = Double.parseDouble(geo.split(",")[1]);
//获取点的外接矩形
BBOX bbox = getBBOX(coordinate,spatialIndexFeatureCollection);
//到带索引的要素集合中查询所有与点的外接矩形相交的要素集
SimpleFeatureCollection subCollection = spatialIndexFeatureCollection.subCollection(bbox);
SimpleFeatureIterator indexFeatures = subCollection.features();
GeometryFactory geometryFactory = new GeometryFactory();
Point point = geometryFactory.createPoint(coordinate);//创建点
while(indexFeatures.hasNext()){
if(((MultiPolygon)indexFeatures.next().getDefaultGeometry()).intersects(point)){
SimpleFeature simpleFeature = subCollection.features().next();
List list = buildRlt(simpleFeature);
return list;
private BBOX getBBOX(Coordinate coordinate,SpatialIndexFeatureCollection spatialIndexFeatureCollection) {
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
ReferencedEnvelope search = new ReferencedEnvelope(new Envelope(coordinate),
spatialIndexFeatureCollection.getSchema().getCoordinateReferenceSystem());
search.expandBy(0.0001d);
BBOX bbox = ff.bbox(ff.property(spatialIndexFeatureCollection.getSchema().getGeometryDescriptor().getName()), search);
return bbox;
}
距离计算
private double getDistance(double lat1,double lon1,double lat2, double lon2){
// 84坐标系构造GeodeticCalculator
GeodeticCalculator geodeticCalculator = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
// 起点经纬度
geodeticCalculator.setStartingGeographicPoint(lon1,lat1);