Wechat: yu389741| Email: gisdqy@163.com

Shop:https://www.giserdqy.com/shop

基于GeoTools实现道路结点的提取


  最近公司的地图业务数据换了供应商,由于在进行路径规划的时候需 要使用到道路结点进行图的构建,因而需要根据道路图层提取出道路的节点。因为经常使用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<SimpleFeatureType, SimpleFeature> 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<String,Geometry> map = new HashMap<String,Geometry>();
                //逐笔写入数据库
                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的研究。

转载自:https://blog.csdn.net/weixin_33825683/article/details/86931541