最近公司的地图业务数据换了供应商,由于在进行路径规划的时候需 要使用到道路结点进行图的构建,因而需要根据道路图层提取出道路的节点。因为经常使用arcpy,所以先用python写了个版本,通常将数据放在地理数据库中会有更高的运行效率,这里是之前的代码,并未存到文件地理数据库中运行,代码如下:
import arcpy
import time,os
import math
print '程序开始: ' + str(time.ctime())
#设置工作环境 地理数据库
from arcpy import env
env.workspace = r'E:\data\import'
#新建要素输出路径 地理数据库
out_path = r'E:\data\import'
#输入要素 地理数据库中的文件
input_name = 'Road.shp'
start_name = 'Starts.shp'
end_name = 'Ends.shp'
node_name = 'Node.shp'
field_name = 'NodeID'
try:
arcpy.FeatureVerticesToPoints_management(input_name,start_name,"START")
print arcpy.GetMessages()
arcpy.AddField_management(start_name, field_name, "LONG", "", "")
print arcpy.GetMessages()
arcpy.CalculateField_management(start_name, field_name, "!SNodeID!","PYTHON_9.3")
print arcpy.GetMessages()
arcpy.FeatureVerticesToPoints_management(input_name,end_name,"END")
print arcpy.GetMessages()
arcpy.AddField_management(end_name, field_name, "LONG", "", "")
print arcpy.GetMessages()
arcpy.CalculateField_management(end_name, field_name, "!ENodeID!","PYTHON_9.3")
print arcpy.GetMessages()
arcpy.Merge_management([start_name, end_name], node_name)
print arcpy.GetMessages()
arcpy.DeleteIdentical_management(node_name, field_name)
print arcpy.GetMessages()
except Exception as e:
print(e)
finally:
print('Success!')
但是为了和公司保持统一,于是使用java基于geotools又实现了一遍,可视化界面的代码就不贴了,就放一些节点提取的代码,以作备份。
/**
* 道路结点提取
*
* @param fileName
*/
private void extractNode(String fileName) throws IOException {
if (Strings.isNullOrEmpty(fileName)) return;
String temp[] = fileName.split("\\\\");
String shpName = "";
if (temp.length > 1) {
for (int j = 0; j < temp.length - 1; j++) {
shpName = shpName + temp[j] + "\\";
}
}
String shpFileName = shpName + "Node.shp";
File newFile =new File(shpFileName);
//设置要生成的shp文件的属性
//下面是定义要素的字段(属性)
//第一个参数是要素类型,第二个参数是字段名
//下面对应SHP文件的dbf表中的Shape、name和number字段,FID字段默认生成
//其中srid=4326是定义地理坐标系WGS_84,与ESRI的WKID一样,因为都是OGC定义的
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setCRS(DefaultGeographicCRS.WGS84);
tb.setName("shapefile");
tb.add("the_geom", com.vividsolutions.jts.geom.Point.class);
tb.add("NODEID", Long.class);
//SHP数据存储工厂
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
//定义生成时的属性
Map params = new HashMap();
params.put("url", newFile.toURI().toURL());
params.put("create spatial index", Boolean.TRUE);
//生成SHP
ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
newDataStore.createSchema(tb.buildFeatureType());
newDataStore.setCharset(Charset.forName("GBK"));
//设置Writer
FeatureWriter writer = newDataStore.getFeatureWriter(newDataStore.getTypeNames()[0], Transaction.AUTO_COMMIT);
//加载shapefile
SimpleFeatureSource featureSource = loadShapeFile(fileName);
//检查shapefile字段信息
checkShapeFileSchema(featureSource.getSchema(), fileName, "SNodeID","ENodeID");
try {
mainController.setStatus("正在进行道路结点提取...");
String finalNodeID = null;
try {
//总笔数
int count = DataUtilities.count(featureSource.getFeatures());
Map map = new HashMap();
//逐笔写入数据库
try (SimpleFeatureIterator iterator = featureSource.getFeatures().features()) {
int index = 0;
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Object attribute = feature.getAttribute("SNodeID");
if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
finalNodeID = attribute.toString();
Geometry geometry = getNode(feature,"start");
if (geometry != null) {
geometry.setSRID(SRID);
map.put(finalNodeID,geometry);
}
attribute = feature.getAttribute("ENodeID");
if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
finalNodeID = attribute.toString();
geometry = getNode(feature,"end");
if (geometry != null) {
geometry.setSRID(SRID);
map.put(finalNodeID,geometry);
}
index++;
}
SimpleFeature newFeature = null;
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
newFeature = writer.next();
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
Geometry geom = (Geometry) entry.getValue();
newFeature.setAttribute("NODEID",key);
newFeature.setAttribute("the_geom",geom);
}
writer.write();
writer.close();
newDataStore.dispose();
}
} catch (Exception e) {
throw new IllegalStateException(String.format("shapefile 文件: %s 数据处理出错!\n错误信息: %s", fileName, e.getMessage()), e);
}
} finally {
mainController.setStatus(null);
mainController.setProgress(0);
featureSource.getDataStore().dispose();
}
}
/**
* 根据Feature要素获取geometry并重新设置geometry
*
*/
private Geometry getNode(SimpleFeature feature,String str){
Geometry geo = (Geometry) feature.getDefaultGeometry();
if(geo == null)
return null;
if (geo == null) return null;
if(geo.getGeometryType().equals("LineString")){
return geometryFactory.createLineString(formatSingleGeometryCorrdinate(geo));
}else if(geo.getGeometryType().equals("MultiLineString")){
return geometryFactory.createPoint(formatMultiLineStringCorrdinate(geo,str));
}else {
return geo;
}
}
最终完成道路结点的提取,随着需求越来越多,后期会逐步加深对geotools的研究。