如何使用GeoTools

GeoTools的API系统被其开发者精心的维护者,其保证在更新的过程中尽可能的不改动其API体系,以减少对使用者的影响。并且GeoTool的API在实现库的基础上,被清晰的划分为几组应用编程接口供调用。

 

一、公共API

 

作为一个开源库,您可以自由调用按时交付应用程序所需的任何 GeoTools 类。

然而,GeoTools 提供了一种干净的方法,随着 GeoTools 的成熟,它应该在库升级期间对您的代码造成最少的中断。

GeoTools 从库的内部实现中干净地分离出几组应用程序编程接口 (API)。

如果您针对这些接口编写代码,它们会在库升级时提供稳定的目标。如果这些接口发生变化(有时我们的标准会发生变化),这些接口将在单个发布周期内被弃用,让您有机会升级。

1.1通常接口来自于三个位置:

  • gt-opengis  依据ISO和OGC发布的接口
  • jts topology suit  Simple Features for SQL(SFSQL) OGC标准的地理实现库
  • gt-api  GeoTools提供的接口

我们还有一项停滞不前的工作正在进行中:

  • gt-opengis 有一组 ISO19107 几何接口(有人对曲线和 3D 感兴趣吗?)

这些接口代表应用程序中的空间概念和数据结构,适用于方法签名。

1.2工厂类:

GeoTools使用接口来表示数据类型,使用工厂类的create方法来创建数据对象(而不使用new。工厂类使你能够创建各种库需要的数据对象,例如:Features,Styles,Filters,CoordinateReferencingSystems,和DataStores等。另外还提供了一个FactoryFinder类帮助你寻找CLASSPATH上面所有的工厂类。借助于这样的设计,甚至可以仅通过接口就可以实现功能

 

二、对象的创建

2.1工厂类示例:

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" );
}

2.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

 

三、获取工厂类

既然在GeoTools中,工厂类这么重要,那么怎么获得合适的工厂类呢。根据就项目环境的不同,获取的方式也多种多样:

  1. GeoTools提供的FactoryFinder
  2. Spring上下文Bean
  3. JNDI
  4. 直接使用一个Factory
  5. 直接new对象
  6. 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" ) );

 

posted @ 2021-08-24 17:48  羊大葱  阅读(596)  评论(0编辑  收藏  举报