ShapeFile数据到mongodb的导入

时间:2021-11-23 06:39:32

开发环境为:
系统环境 Linux 4.4.0-36-generic #55~14.04.1-Ubuntu x86_64 x86_64 x86_64 GNU/Linux
mongodb版本 当前最新版本3.2.9
但是下面的代码同样适用Windows环境!

具体mongodb的安装参照官方文档,强烈建议参照官方安装文档。网上博客这种资料良莠不齐,而且新版本可能和老板的安装略有区别,博客中的安装方法不一定适合你。所以,一句话,参照官方文档进行安装。

开发语言为Java,开发工具为GeoTools和mongodb的Java Driver。

具体实现思想是:首先使用GeoTools读取shapefile文件,然后遍历每个feature,将feature转为GeoJSON的字符串。每个GeoJSON的字符串作为mongodb的collection中的一个document。

使用Maven构建项目工程,核心pom文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>cn.tzy</groupId>
<artifactId>mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>mongodb</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<geotools.version>15.1</geotools.version>
</properties>

<repositories>
<repository>
<id>repo2.maven.org</id>
<name>maven2 repository</name>
<url>http://repo2.maven.org/maven2/</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>${geotools.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

具体代码如下(mongodb的API从3.x版本进行了比较大的变化,好些API标记为过时。下面代码是使用最新的API写的):

package cn.tzy.mongodb;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;

import org.bson.Document;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.feature.FeatureJSON;
import org.opengis.feature.simple.SimpleFeature;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class MongoEx {

public static void main(String[] args) throws IOException {

final String IP_ADDRESS = "127.0.0.1"; // 本机地址
final String DB_NAME = "world"; // 数据库名称
final String COLLECTION_NAME = "continents"; // Collection名称
final String SHAPE_FILE = "/home/zytan/data/continent.shp"; // ShapeFile全路径

// 初始化mongodb
MongoClient client = new MongoClient(IP_ADDRESS);
MongoDatabase db = client.getDatabase(DB_NAME);
db.createCollection(COLLECTION_NAME);
MongoCollection<Document> coll = db.getCollection(COLLECTION_NAME);

// 使用GeoTools读取ShapeFile文件
File shapeFile = new File(SHAPE_FILE);
ShapefileDataStore store = new ShapefileDataStore(shapeFile.toURI().toURL());
SimpleFeatureSource sfSource = store.getFeatureSource();
SimpleFeatureIterator sfIter = sfSource.getFeatures().features();
// 从ShapeFile文件中遍历每一个Feature,然后将Feature转为GeoJSON字符串,最后将字符串插入到mongodb的Collection中
while (sfIter.hasNext()) {
SimpleFeature feature = (SimpleFeature) sfIter.next();
// Feature转GeoJSON
FeatureJSON fjson = new FeatureJSON();
StringWriter writer = new StringWriter();
fjson.writeFeature(feature, writer);
String sjson = writer.toString();
System.out.println(sjson);
// 插入到Collection中
Document doc = Document.parse(sjson);
coll.insertOne(doc);
}

client.close(); // 关闭数据库连接
System.out.println("数据导入完毕!");

}
}

接下来,我们使用命令行进入mongodb建立索引:

db.countries.createIndex({"geometry":"2dsphere"})
因为我们的数据是WGS84地理坐标系,所以我们使用2dsphere索引在geometry字段上建立索引。

下面是一个地理查询的示例:
查询在给定点的最大距离约束下的地理实体

db.continents.find( { geometry :
{ $near :
{ $geometry :
{ type : "Point" ,
coordinates : [ 108 , 34 ] } ,
$maxDistance : 2000
} } } )