Geotools是Java语言编写的开源GIS工具包。该项目已有十多年历史,生命力旺盛,代码非常丰富,包含多个开源GIS项目,并且基于标准的GIS接口。Geotools主要提供各种GIS算法,各种数据格式的读写和显示。在显示方面要差一些,只是用Swing实现了地图的简单查看和操作。但是用户可以根据Geotools提供的算法自己实现地图的可视化。OpenJump和udig就是基于Geotools的。
Geotools用到的两个较重要的开源GIS工具包是JTS和GeoAPI。前者主要是实现各种GIS拓扑算法,也是基于GeoAPI的。但是由于两个工具包的GeoAPI分别采用不同的Java代码实现,所以在使用时需要相互转化。Geotools又根据两者定义了部分自己的GeoAPI,所以代码显得臃肿,有时容易混淆。由于GeoAPI进展缓慢,Geotools自己对其进行了扩充。另外,Geotools现在还只是基于2D图形的,缺乏对3D空间数据算法和显示的支持。
一、Geotools The Open Source Java GIS Toolkit
http://geotools.org/ Geotools官方网站
http://docs.geotools.org/latest/javadocs/ Geotools API在线文档
http://docs.codehaus.org/display/GEOTDOC/Home Geotools用户指南
http://repo.opengeo.org Geotools的maven仓库地址
http://download.osgeo.org/webdav/geotools/ maven仓库地址
POM.xml配置
<repositories> <repository> <id>osgeo</id> <name>Open Source Geospatial Foundation Repository</name> <url>http://download.osgeo.org/webdav/geotools/</url> </repository> <repository> <snapshots> <enabled>true</enabled> </snapshots> <id>opengeo</id> <name>OpenGeo Maven Repository</name> <url>http://repo.opengeo.org</url> </repository> </repositories>
eg:取到gt-main.jar的依赖关系
<dependency> <groupId>org.geotools</groupId> <artifactId>gt-main</artifactId> <version>8.4</version> </dependency>
二、OpenGIS 软件架构
org.geotools.data
包负责地理数据的读写(如:ShavefileReader用于读取shpfile数据),org.geotools.geometry
包负责提供对JTs的调用接口,以将地理数据封装成JTS中定义的几何对象(Geometry),
org.geotools.feature包负责封装空间几何要素对象(Feature),对应于地图中一个实体,
包含:空间数据(Geometry)、属性数据(Aitribute)、参考坐标系(Refereneedsystem)、
最小外包矩形(EnveloPe)等属性,是Gls操作的核心数据模型。
Geotools 读取shp 数据格式的例子:
/** * 读取shap格式的文件 * * @param path */ public void readSHP(String path) { ShapefileDataStore shpDataStore = null; try { shpDataStore = new ShapefileDataStore(new File(path).toURI() .toURL()); shpDataStore.setStringCharset(Charset.forName("GBK")); // 文件名称 String typeName = shpDataStore.getTypeNames()[0]; FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = null; featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) shpDataStore .getFeatureSource(typeName); FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource .getFeatures(); SimpleFeatureType schema = result.getSchema(); // schema List<AttributeDescriptor> columns = schema .getAttributeDescriptors(); FeatureIterator<SimpleFeature> itertor = result.features(); /* * 或者使用 FeatureReader FeatureReader reader = * DataUtilities.reader(result); while(reader.hasNext()){ * SimpleFeature feature = (SimpleFeature) reader.next(); } */ while (itertor.hasNext()) { SimpleFeature feature = itertor.next(); for (AttributeDescriptor attributeDes : columns) { String attributeName = attributeDes.getName().toString();// attribute if (attributeName.equals("the_geom")) continue; feature.getAttribute(attributeName); // attributeValue } Geometry g = (Geometry) feature.getDefaultGeometry();// Geometry } itertor.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
/** * 读取dbf格式的文件,只存储属性值,不存储空间值 * * @param path */ public void readDBF(String path) { DbaseFileReader reader = null; try { reader = new DbaseFileReader(new ShpFiles(path), false, Charset.forName("GBK")); DbaseFileHeader header = reader.getHeader(); int numFields = header.getNumFields(); for (int i = 0; i < numFields; i++) { header.getFieldName(i); header.getFieldType(i);// 'C','N' header.getFieldLength(i); } // 迭代读取记录 while (reader.hasNext()) { try { Object[] entry = reader.readEntry(); for (int i = 0; i < numFields; i++) { String title = header.getFieldName(i); Object value = entry[i]; String name = title.toString(); // column String info = value.toString(); // value } } catch (Exception e) { e.printStackTrace(); } } } catch (Exception ex) { ex.printStackTrace(); } finally { if (reader != null) { // 关闭 try { reader.close(); } catch (Exception e) { } } } }
输出一个shp文件
/** * 创建shp文件 * * @param outPath */ public void createShp(String outPath) { try { // 定义属性 final SimpleFeatureType TYPE = DataUtilities.createType("Location", "location:Point," + "NAME:String," + "INFO:String," + "OWNER:String"); FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection(); GeometryFactory geometryFactory = new GeometryFactory(); SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE); double latitude = Double.parseDouble("116.123456789"); double longitude = Double.parseDouble("39.120001"); String NAME = "运通110路"; String INFO = "白班车,学生票有效"; String OWNER = "001"; //创建坐标 Point point = geometryFactory.createPoint(new Coordinate(longitude,latitude)); //创建属性值 Object[] obj = {point, NAME, INFO, OWNER }; //构造一个Feature SimpleFeature feature = featureBuilder.buildFeature(null, obj); //添加到集合 collection.add(feature); // shap文件的输出路径 File newFile = new File(outPath); Map<String, Serializable> params = new HashMap<String, Serializable>(); params.put("url", (Serializable) newFile.toURI().toURL()); params.put("create spatial index", (Serializable) Boolean.TRUE); ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory(); ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory .createNewDataStore(params); newDataStore.createSchema(TYPE); newDataStore.setStringCharset(Charset.forName("GBK")); newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); String typeName = newDataStore.getTypeNames()[0]; ShapefileFeatureLocking featureSource = (ShapefileFeatureLocking) newDataStore .getFeatureSource(typeName); // 创建一个事务 Transaction transaction = new DefaultTransaction("create"); featureSource.setTransaction(transaction); try { featureSource.addFeatures(collection); // 提交事务 transaction.commit(); } catch (Exception problem) { problem.printStackTrace(); transaction.rollback(); } finally { transaction.close(); } } catch (Exception e) { e.printStackTrace(); } }