示例
导入 Shapefile
Neo4j-Spatial 包含一个用于导入 ESRI Shapefile 数据的工具。ShapefileImporter 将为导入的每个 Shapefile 创建一个新的 Layer,并将每个 Geometry 作为 WKB 存储在单个节点的单个属性中。Feature 的所有属性将作为该节点的附加属性存储。有关此实现方式的更多信息,请参阅 WKBGeometryEncoder 类。但是,您无需了解这些即可使用此功能。请看下面的简单代码。
ShapefileImporter importer = new ShapefileImporter(database);
importer.importFile("shp/highway.shp", "highway", StandardCharsets.UTF_8);
此代码将从源分发中包含的 'shp/highway.shp' 文件导入图层 'highway'。该图层将使用 RTree 进行索引,因此可以使用任何受支持的空间操作进行查询。请参阅下面的查询图层示例。
导入 Open Street Map 文件
这更复杂,因为当前的 OSMImporter 类分两个阶段运行,第一阶段需要在数据库上使用批量插入器。目前正在进行工作以实现在整个过程中使用非批量插入器,可能当您读到此处时,此功能已经可用。有关导入 OSM 数据的最新代码,请参阅 TestDynamicLayers 和 TestOSMImport 类中的单元测试。例如
OSMImporter importer = new OSMImporter("map.osm");
importer.setCharset(StandardCharsets.UTF_8);
importer.importFile(db, "map.osm");
importer.reIndex(db);
此代码将导入 map.osm Open Street Map 文件,用略多于 200 个几何图形填充数据库,包括街道、建筑物和兴趣点。
执行空间查询
假设您像前面的示例一样导入了 map.osm 文件,您现在可以对数据执行空间搜索。以下示例将在一个矩形内搜索它能找到的任何几何图形
SpatialDatabaseService spatial = new SpatialDatabaseService(
new IndexManager((GraphDatabaseAPI) graphDb, SecurityContext.AUTH_DISABLED));
try (Transaction tx = database.beginTx()) {
Layer layer = spatial.getLayer(tx, "map.osm");
LayerIndexReader spatialIndex = layer.getIndex();
System.out.println("Have " + spatialIndex.count(tx) + " geometries in " + spatialIndex.getBoundingBox(tx));
Envelope bbox = new Envelope(12.94, 12.96, 56.04, 56.06);
List<SpatialDatabaseRecord> results = GeoPipeline
.startIntersectWindowSearch(tx, layer, bbox)
.toSpatialDatabaseRecordList();
doGeometryTestsOnResults(bbox, results);
tx.commit();
}
有关查询代码的更多示例,请参阅 LayerTest 和 SpatialTest 类中的测试代码。另请查阅 org.neo4j.gis.spatial.query 包中的类,了解当前已实现的全部搜索查询范围。
导出 Shapefile
我们在第一个示例中导入的 ESRI Shapefile 实际上是由 Neo4j-Spatial 创建的。可以使用查询结果或 DynamicLayer,通过 ShapefileExporter 创建一个新的 Shapefile。如果我们导出从导入 Shapefile 创建的完整图层,效果不大,但我们可以利用此功能创建其他图层的子集,或从其他格式的数据创建 Shapefile。
SpatialDatabaseService spatial = new SpatialDatabaseService(
new IndexManager((GraphDatabaseAPI) graphDb, SecurityContext.AUTH_DISABLED));
String wayLayerName;
try (Transaction tx = database.beginTx()) {
OSMLayer layer = (OSMLayer) spatial.getLayer(tx, "map.osm");
DynamicLayerConfig wayLayer = layer.addSimpleDynamicLayer(tx, Constants.GTYPE_LINESTRING);
wayLayerName = wayLayer.getName();
tx.commit();
}
ShapefileExporter shpExporter = new ShapefileExporter(database);
shpExporter.exportLayer(wayLayerName);
此示例展示了如何导入一个 OSM 数据集(其中包含多种不同 Geometry 类型的数据),然后通过使用 DynamicLayer 仅选择类型为 'LineString' 的几何图形,我们可以将所有 OSM 路径导出到 Shapefile。考虑到 ESRI Shapefile 格式不允许每个 Shapefile 包含多种 Geometry 类型,这一点尤为重要。
SpatialDatabaseService spatial = new SpatialDatabaseService(
new IndexManager((GraphDatabaseAPI) graphDb, SecurityContext.AUTH_DISABLED));
Envelope bbox = new Envelope(12.94, 12.96, 56.04, 56.06);
List<SpatialDatabaseRecord> results;
try (Transaction tx = database.beginTx()) {
Layer layer = spatial.getLayer(tx, "map.osm");
LayerIndexReader spatialIndex = layer.getIndex();
System.out.println("Have " + spatialIndex.count(tx) + " geometries in " + spatialIndex.getBoundingBox(tx));
results = GeoPipeline
.startIntersectWindowSearch(tx, layer, bbox)
.toSpatialDatabaseRecordList();
spatial.createResultsLayer(tx, "results", results);
tx.commit();
}
ShapefileExporter shpExporter = new ShapefileExporter(database);
shpExporter.exportLayer("results");
这次我们导入相同的 OSM 模型,但查询信封内的所有几何图形,并将其导出到新的 Shapefile。