DistChen

shp 文件数据入库的几种解决思路

最近因为工作上的项目需求,研究了下如何将shp文件里面的空间数据入库。

oracle提供oracle.spatial.util.SampleShapefileToJGeomFeature

http://docs.oracle.com/cd/E11882_01/appdev.112/e11830/sdo_shapefile_converter.htm#SPATL1427

这是由oracle 提供的 shp 入库方法,入库后的空间数据类型是 SDO_GEOMETRY,而不是ST_GEOMETRY。该方法使用很简单,只需设定好对应的参数即可,可以直接通过命令行的形式使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Parameters
-h: Host machine with an existing Oracle database
-p: Port on the host machine (for example, 1521)
-s: SID (database name) on the host machine
-u: Database user
-d: Password for the database use
-t: Table name for the converted Shapefile
-f: File name of an input Shapefile (with or without extension)
-i: Column name for unique numeric ID, if required
-r: Valid Oracle SRID for coordinate system; use 0 if unknown
-g: Preferred SDO_GEOMETRY column name
-x: Bounds for the X dimension; use -180,180 if unknown
-y: Bounds for the Y dimension; use -90,90 if unknown
-o: Load tolerance fields (x and y) in metadata; if not specified, tolerance fields are 0.05
-a: Append Shapefile data to an existing table
-n: Start ID for column specified in -i parameter
-c: Commit interval; by default, commits occur every 1000 conversions and at the end
-v: Println interval; by default, a display every 10 conversions

oracle提供的用于操作 oracle spatial 的jar包位于 ORACLE_HOME/md/*,如下:
这里写图片描述

oracleplugin

http://docs.geotools.org/latest/userguide/library/jdbc/oracle.html

这是由geotools提供的专门连接并操作oracle 数据库的方法,使用该 Plugin可以很方便的基于oracle 创建图层、添加要素,但是遗憾的是,也是属于 oracle spatial,不过可以学习了解下,一个简单的连接数据库并基于一个shp图层创建一张空间表的示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void oracle115(){
Map params = new java.util.HashMap();
params.put( "dbtype", "oracle");
params.put( "host", "127.0.0.1");
params.put( "port", 1521);
params.put( "schema", "SCOTT");
params.put( "database", "ORCL");
params.put( "user", "scott");
params.put( "passwd", "orcl");
try {
OracleNGDataStoreFactory factory=new OracleNGDataStoreFactory();
DataStore dataStore = factory.createDataStore(params);
String typeName = "DEMO";//dataStore.getTypeNames()[0]; // 文件名称
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = null;
featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>)dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource.getFeatures();
SimpleFeatureType schema=result.getSchema();
List<AttributeDescriptor> columns=schema.getAttributeDescriptors();
FeatureIterator<SimpleFeature> itertor = result.features();
while(itertor.hasNext()){
SimpleFeature feature = itertor.next();
System.out.print(feature.getID()+" ");
for (AttributeDescriptor column : columns) {
String attribute = column.getName().toString();
System.out.print(attribute + ":" + feature.getAttribute(attribute) + " ");
}
}
itertor.close();
} catch (Exception e) {
e.printStackTrace();
}
}

基于已经连接的DataStore可以取得当前连接对象等,可以很方便的进行数据库操作,这个Plugin依赖如下的jar包:

1
2
3
4
5
<dependency>
<groupId>org.geotools.jdbc</groupId>
<artifactId>gt-jdbc-oracle</artifactId>
<version>11.5</version>
</dependency>

这里写图片描述

利用maven配置依赖时,需要指定私服地址,在中央仓库中并没有这些资源,私服地址如下:

1
2
3
4
5
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>

arcsdeplugin

http://docs.geotools.org/latest/userguide/library/data/arcsde.html

这是Geotools 针对 arcsde 的方法,使用该插件与oracle plugin 类似,生成的空间数据类型是st_geometry ,是符合要求的,感觉基本上就是调用的 arcsde jdk for java 提供的方法,所以还需要使用到 arcsde 的jdk。其连接到srcsde服务的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private static void arcsde(){
Map map = new HashMap();
map.put( "dbtype", "arcsde" );
map.put( "server", "localhost" );
map.put( "port", "5151" );
map.put( "instance", "sde" );
map.put( "user", "scott" );
map.put( "password", "orcl" );
try {
ArcSDEDataStore dataStore=(ArcSDEDataStore) DataStoreFinder.getDataStore(map);
File file = new File("C:\\Users\\chenyp\\Desktop\\tj\\data\\dk.shp");
ShapefileDataStore shpDataStore = new ShapefileDataStore(file.toURI().toURL());
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>)shpDataStore.getFeatureSource("DEMO");
FeatureCollection<SimpleFeatureType, SimpleFeature> results = featureSource.getFeatures();
dataStore.createSchema(shpDataStore.getSchema());
ArcSdeFeatureStore arcSdeFeatureStore=new ArcSdeFeatureStore(null,dataStore);
Transaction transaction=arcSdeFeatureStore.getTransaction();
arcSdeFeatureStore.addFeatures(results);
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
}
}

arcsde服务连接到数据库,并基于某个图层创建空间表。不过在这里直接把图层里的feature 插入到刚刚创建的图层时还有点问题。主要是彼此之间的关系还没弄清楚,很多类都是保护型的,没法实例化,需要转来转去的。需要用到的依赖如下:

1
2
3
4
5
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-arcsde</artifactId>
<version>11.5</version>
</dependency>

这里写图片描述

除此之外,还需要引入arcsde 的相关jar包。

Arcgis 工具 arcsde

调用arcsde提供的工具shp2sde(也是偶然想到既然有sdeservice 工具,会不会还有其它工具,一看果然还有好多有用的)。ArcSDE提供了很多工具,可以借助这些工具来完成相关的操作。在ArcCatalog 中带ui的功能,有一些通过命令行是可以完成的。shp2sde 就是用来完成shp入库的,而且效率很高。
这里写图片描述

关于shp2sde命令,参考如下:http://edndoc.esri.com/arcsde/9.0/admin_cmd_refs/shp2sde.htm,下面是一个示例:
这里写图片描述

ArcSDE还提供了很多其它类型的工具:
这里写图片描述

最终,依据可行性和效率的考量,我实现的将服务器中的shp入库效果如下:
这里写图片描述

还有一些其他的开源gis工具也可以实现shp入库,比如OGR 等。

坚持原创技术分享,您的支持将鼓励我继续创作!