GeoTools使用
1.API系统介绍
原则:
GeoTools的API系统被其开发者精心的维护者,其保证在更新的过程中尽可能的不改动其API体系,以减少对使用者的影响。
并且GeoTool的API在实现库的基础上,被清晰的划分为几组应用编程接口供调用。
分类:
通常接口来自于三个位置:
gt-opengis 依据ISO和OGC发布的接口
jts topology suit Simple Features for SQL(SFSQL) OGC标准的地理实现库
gt-api GeoTools提供的接口
公共实现类:
GeoTools使用接口来表示数据结构,也提供了一些实现类实现其他的功能,主要有以下三种:
工具类:例如CQL、DataUtilities 和JTS。
在运行时使用的辅助类:例如FactoryFinders让你能够寻找CLASSPATH上面可用的实现类。
与GeoTools扩展相关的类:例如ColorBrewer由gt-brewer提供,与扩展合作可以在库的上部提供额外的服务
工厂类:
GeoTools使用接口来表示数据类型,使用工厂类的create方法来创建数据对象(而不使用new。工厂类使你能够创建各种库需要的数据对象,例如:Features,Styles,Filters,CoordinateReferencingSystems,和DataStores等。另外还提供了一个FactoryFinder类帮助你寻找CLASSPATH上面所有的工厂类。借助于这样的设计,甚至可以仅通过接口就可以实现功能。
2.对象的创建
工厂类示例:
Scala允许将构造函数定义在接口中,但是java不能这样,因此为了创建实现(而不是具体的对象),GeoTools采用工厂类来创建实现。GeoTools创建对象的逻辑为:FactoryFinder找到合适的工厂类,使用工厂类创建对象。一个典型的工厂类创建实现的示例如下:
FilterFactory2 factory = CommonFactoryFinder.getFilterFactory2( null ); Filter filter = factory.less( factory.property( "size" ), factory.literal( 2 ) ); if( filter.evaulate( feature )){ System.out.println( feature.getId() + " had a size larger than 2" ); }
工厂类参考:
从上面的示例中,可以看到从工厂类和接口的名字之间有明显的规律:接口比工厂类少了FactoryFinder。
在实际应用中,可以将多个工厂类合并到一个类中来获取所需的工厂类:
CommonFactoryFinder:FilterFactory、StyleFactory、Function、FeatureLockFactory、FileDataStore(文件)、FeatureFactory、FeatureTypeFactory、FeatureCollections
访问feature(例如vector)内容:DataAccessFinder, DataStoreFinder,FileDataStoreFinder
访问coverage(例如raster)信息:GridFormatFinder,CoverageFactoryFinder
JTSFactoryFinder(用于创建JTS GeometryFactory和PercisionModel):GeometryFactory,PrecisionModel
ReferencingFactoryFinder(用于列出参考的工厂类):atumFactory ,CSFactory ,DatumAuthorityFactory ,CSAuthorityFactory , CRSAuthorityFactory ,MathTransformFactory , CoordinateOperationFactory ,CoordinateOperationAuthorityFactory
3.获取工厂类
既然在GeoTools中,工厂类这么重要,那么怎么获得合适的工厂类呢。根据就项目环境的不同,获取的方式也多种多样:
GeoTools提供的FactoryFinder
Spring上下文Bean
JNDI
直接使用一个Factory
直接new对象
FactoryFinder:
FactoryFinder是Spring框架下的项目最佳的选择,它是全局唯一的,可以查找可以使用的插件。非Spring项目也可以使用GeoTools提供的FactoryFinder。
FactoryFinder使用了java内置的插件系统,名为工厂服务提供接口(Factory Service Provide Interface)。这个技术允许一个jar指明它创建的哪些服务是可用的(这里是一个工厂接口的各种实现)。
为了便于使用,GeoTools提供了一系列的FactoryFinders。这些类像火柴制造者一样,在CLASSPATH中寻找可用的实现。例如:
FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory( null );
直接使用Factory
例如:
DataStoreFactorySpi factory = new ShapefileDataStoreFactory(); File file = new File("example.shp"); Map map = Collections.singletonMap( "url", file.toURL() ); DataStore dataStore = factory.createDataStore( map );
但是这样的话,你使用了一个具体的类,而不是依靠GeoTools的插件系统来为你寻找一个最佳的实现。
可以为FactoryFinder指定一个线索(Hint)来帮助寻找需要的Factory,例如:
Hints hints = new Hints( Hints.FILTER_FACTORY, "org.geotools.filter.StrictFactory" ); FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory( hints );
直接new对象:
File file = new File("example.shp"); URI namespace = new URI("refractions"); ShapefileDataStore shapefile = new ShapefileDataStore( example.toURL()); shapefile.setNamespace(namespace); shapefile.setMemoryMapped(true);
GeoTools不鼓励,甚至反对这么直接new对象,因为它提高了耦合度,并且不符合插入原则。但是GeoTools并没有把相应接口实现的构造函数生命为private来禁止你直接new对象。GeoTools为了支持这种快速使用的方法,使用了一些额外的方法来处理一些数据例如ShapefileDataStore中的:
shapefile.forceSchemaCRS( CRS.decode( "EPSG:4326" ) );