为GeoServer增加自定义空间数据(一)

这段时间由于一个项目,需要为GeoServer添加自定义的空间数据源,因此对GeoServer以及GeoTools作了点的学习。

 

由于GeoServer使用的是GeoTools体系。因此,增加自定义数据源本质上就是按照GeoTools的数据源plugin规范写一个plugin

 

I.   数据源的创建

空间数据源的创建采用了工厂方法,GeoTools的工厂类派生结构如下(下图中的类仅为将涉及到的部分):

 

 

因此,第一步工作就是要为数据源写一个工厂类,在这里我们需要决定应该从哪个类派生。由于我的数据源是以数据库为基础的空间数据,因此,这里选择从JDBCDataStoreFactory类派生。

并不是所有的空间数据库一定要从该类派生,比如PostgisDataStoreFactory就是从AbstractDataStoreFactory派生出来。

另外ShapefileDataStoreFactory则是从DataStoreFactorySpi派生出来。

在创建了自己的工厂类之后,GeoTools是如何找到该工厂的?GeoTools其实是通过org.geotools.data.DataStoreFactorySpi配置文件得到工厂信息。因此,需要为自己的工厂类建立该文件。该文件应存放在jar包的META-INF/services目录下,文件内容如下:

org.geotools.data.zengjie.SqlServerDataStoreFactory

(也就是工厂类的全名)

 

I.   实现数据源工厂类

接下来,我们就需要实现该类,该工厂类中几个必需要实现的方法如下:

l        createSQLDialect

l        getDatabaseID

l        getDriverClassName

l        getValidationQuery

l        getDescription

其中createSQLDialect方法是其中最重要的(并不意味着复杂)。该方法声明如下:

SQLDialect createSQLDialect(JDBCDataStore dataStore)

该方法使用JDBCDataStore创建一个SQLDialect对象。SQLDialect对象用于屏蔽各个数据库之间的差异,比如:decodeGeometryValue方法,该方法用于从二进制流中得到Geometry对象。

看到以上的方法,你也许会产生疑惑,对于一个已经创建好的数据源,GeoTools在初始化时是如何确定使用哪一个工厂?

GeoTools得到所有可用的Factory。然后调用每个FactorycanProcess,将params作为参数传到该方法中,由每个Factory来判断是否可以处理该params。如果可以处理就用该Factory创建DataStore。对于JDBC类的canProcess方法来说,

    public boolean canProcess(Map params) {

        if (!super.canProcess(params)) {

            return false; // was not in agreement with getParametersInfo

        }

 

        return checkDBType(params);

}

首先调用了基类(AbstractDataStoreFactory)的canProcess,在该方法中得到所有该数据源的参数(Param),然后循环判断每个参数是否在params中存在,如果不存在且该参数又是必需的则返回false

在执行完了基类的canProcess后,又调用了checkDBType(params)。因为作为JDBC类的数据源,参数大多一样,因此仅仅检查了参数并不能保证该数据源必定能被处理。这里JDBC的数据源工厂利用getDatabaseID方法返回的ID来进行判断。因此我们在实现getDatabaseID方法时一定要注意,返回的字符串不要太简单。

 

 

 

 

除了以上必须要实现的函数外,还可以根据需要重载基类的方法。我这里由于需要自己生成数据源的URL,因此还重载了

String getJDBCUrl(Map param)函数,如下:

    protected String getJDBCUrl(Map params) throws IOException {

        // jdbc url

        String host = (String) HOST.lookUp(params);

        Integer port = (Integer) PORT.lookUp(params);

        String db = (String) DATABASE.lookUp(params);

       

        String url = URL + host;

        if ( port != null ) {

            url += “:” + port;

        }

       

        url += “;DatabaseName=” + db;

 

        return url;

    }

 

 

转载自:https://blog.csdn.net/nc8000/article/details/5515659

You may also like...