基于GeoTools的GeoJson导入到PostGis实战

          GeoJson是一种对各种地理数据结构进行编码的格式,基于json的地理空间信息数据交换格式。GeoJson对象可以用来表示几何,特征或者特征集合。支持地理点、线、面、多点、多线、多面及几何集合。GeoJson不是本文的重点,因此不再赘述。

         PostGIS是在对象关系型数据库PostgreSQL上增加了存储管理空间数据的能力的开源GIS数据库。本文的例子不能直接运行在PostgreSql的数据库上,需要装扩展依赖才行(具体可参考某度的详细教程)。

        本文将重点介绍如何基于GeoTools将GeoJson数据导入到PostGis中,并通过数据库客户端软件查询到导入结果。

        本实例运行环境:

1:win7+jdk8+GeoTools 24+POSTGIS: 3.1+PostgreSQL 9.6.14

       第一步:准备GeoTools依赖的包,详情见pom.xml

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-metadata</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <!--非必需,简化I/O操作-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.postgis</groupId>
            <artifactId>postgis-driver</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

         第二步:创建PostGis数据源操作对象,相当于JDBC 数据源

public class PostgisDataStore {
    private static Logger logger = Logger.getLogger(PostgisDataStore.class);
    private static DataStore postgisDataStore = null;
    private static String dbtype = null;
    private static String host = null;
    private static String port = null;
    private static String database = null;
    private static String schema = null;
    private static String username = null;
    private static String password = null;

    public PostgisDataStore() {
    }

    public static DataStore getInstance() {
        if (postgisDataStore == null) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put(PostgisNGDataStoreFactory.DBTYPE.key, dbtype);
            params.put(PostgisNGDataStoreFactory.HOST.key, host);
            params.put(PostgisNGDataStoreFactory.PORT.key, new Integer(port));
            params.put(PostgisNGDataStoreFactory.DATABASE.key, database);
            params.put(PostgisNGDataStoreFactory.SCHEMA.key, schema);
            params.put(PostgisNGDataStoreFactory.USER.key, username);
            params.put(PostgisNGDataStoreFactory.PASSWD.key, password);
            try {
                postgisDataStore = DataStoreFinder.getDataStore(params);
                logger.info("\nPostgisDataStore 初始化geotools中的 Datastore成功\n");
            } catch (IOException e) {
                logger.error("\nPostgisDataStore 初始化geotools中的 Datastore失败\n");
                logger.error(e.getMessage());
            }
        }
        return postgisDataStore;
    }
    
}

        以上代码仅供参考,如需在实战中使用,还是尽可能利用已有的连接池技术提高应用性能。

        第三步:准备待带入的GeoJson数据,以Line为例

{
	"type": "FeatureCollection",
	"features": [
		{
			"type": "Feature",
			"properties": {
				"name": "north",
				"linedesc": "A"
			},
			"geometry": {
				"type": "LineString",
				"coordinates": [
					[
						476.7884016036988,
						39.9663655061331
					],
					[
						476.7959976196289,
						39.96679309103126
					],
					[
						476.80423736572268,
						39.96613526700328
					]
				]
			}
		}
   ]
}

        第四步:将GeoJson数据写入到数据库中,关键代码如下:

/**
     * geojson 文件导入的Postgis数据库
     *
     * @param geojsonpath geojson文件存储路径,包括文件拓展名.json或者.geojson
     * @param tablename   自定义存储到postgis数据库存储的表的名称
     * @return 导入结果
     * @throws IOException
     */
    public static boolean importGeojson(String geojsonpath, String tablename) throws IOException {
        if (!validateGeojson(geojsonpath, true)) return false;
        DataStore pgDatastore = postgisDataStore.getInstance();
        FeatureJSON featureJSON = new FeatureJSON();
        FeatureCollection featureCollection = featureJSON.readFeatureCollection(new FileInputStream(geojsonpath));
        SimpleFeatureType geojsontype = (SimpleFeatureType) featureCollection.getSchema();

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.init(geojsontype);
        typeBuilder.setName(tablename);
        SimpleFeatureType newtype = typeBuilder.buildFeatureType();
        pgDatastore.createSchema(newtype);

        FeatureIterator iterator = featureCollection.features();
        FeatureWriter<SimpleFeatureType, SimpleFeature> featureWriter = pgDatastore.getFeatureWriterAppend(tablename, Transaction.AUTO_COMMIT);

        while (iterator.hasNext()) {
            Feature feature = iterator.next();
            SimpleFeature simpleFeature = featureWriter.next();
            Collection<Property> properties = feature.getProperties();
            Iterator<Property> propertyIterator = properties.iterator();
            while (propertyIterator.hasNext()) {
                Property property = propertyIterator.next();
                simpleFeature.setAttribute(property.getName().toString(), property.getValue());
            }
            featureWriter.write();
        }
        iterator.close();
        featureWriter.close();
        pgDatastore.dispose();
        return true;
    }

        第五步:测试调用

PostgisDataStore postgisDataStore = new PostgisDataStore();
PostgisDataStore.setHost("127.0.0.1");
PostgisDataStore.setPort("5432");
// 扩展数据库类型,读取postgis该参数类型设置为postgis
// 其余设置对应的数据库类型,要求jdbc支持并且引入相关库
PostgisDataStore.setDbtype("postgis");
PostgisDataStore.setDatabase("postgis_31_sample");
PostgisDataStore.setSchema("public");
PostgisDataStore.setUsername("asus");
PostgisDataStore.setPassword("postgres");

PostgisUtility.setPostgisDataStore(postgisDataStore);

boolean flag = PostgisUtility.importGeojson("D:\\wzh_workspace_20210320\\geotools4postgis\\src\\main\\java\\iwuang\\line.geojson", "wzh_line2");
System.out.println(flag);

        使用数据客户端软件打开后可以查询到导入的数据

图片

       总结,通过以上程序可以实现GeoJson数据的导入,如果遇到数据库连不上,请查找是不是数据连接信息没有正确配置,比如用户名密码等有没有正确输入。应用程序处理通用序列图如下:

图片

        本文代码参考至https://github.com/yieryi/geotools4postgis,有兴趣的各位可以到github上将代码下载下来进行调试。

Guess you like

Origin blog.csdn.net/yelangkingwuzuhu/article/details/120812987