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中,工廠類這么重要,那么怎么獲得合適的工廠類呢。根據就項目環境的不同,獲取的方式也多種多樣:
- 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" ) );