示例

导入 shapefile

Neo4j-Spatial 包含一个用于导入 ESRI Shapefile 数据的实用程序。ShapefileImporter 将为每个导入的 Shapefile 创建一个新的图层,并将每个几何图形作为 WKB 存储在单个节点的单个属性中。要素的所有属性都将作为该节点的其他属性存储。有关如何实现此功能的更多信息,您可以参考类 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 数据集(包含具有多种不同几何图形类型的数据),然后通过使用 DynamicLayer 选择仅类型为“LineString”的几何图形,我们可以将所有 OSM 路线导出到 Shapefile。当您考虑到 ESRI Shapefile 格式不允许每个 shapefile 多于一种几何图形类型时,这一点尤其重要。

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。

更多示例