基于GeoTools实现建筑物高度的提取

  接上一篇文章:https://www.jianshu.com/p/d9150de6058b
  继续对建筑物数据进行高度的提取,其中分为底座、单层、柱顶和柱顶四类,为了在mapbox gl中加载3D建筑物,分别进行baseHeight和Height的提取。

    /**
     * 建筑物高度提取
     *
     * @param fileName
     */
    private void extractHeight(String fileName) throws SchemaException, 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 + "NewBuilding.shp";
        File newFile =new File(shpFileName);
        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
        tb.setCRS(DefaultGeographicCRS.WGS84);
        tb.setName("shapefile");
        tb.add("the_geom", com.vividsolutions.jts.geom.MultiPolygon.class);
        tb.add("BuildingID", Long.class);
        tb.add("BDName", String.class);
        tb.add("Height", Double.class);
        tb.add("BaseHeight", Double.class);
        tb.add("Type", Integer.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, "BuildingID","BDName","BDFaceType","FHeight","FNum","UpBDID","Height");
        try {
            mainController.setStatus("正在进行建筑物高度提取...");
            try {
                Map<Long, Build> singleMap = new HashMap<Long,Build>();
                Map<Long, Build> baseMap = new HashMap<Long,Build>();
                Map<Long, Build> mainMap = new HashMap<Long,Build>();
                Map<Long, Build> topMap = new HashMap<Long,Build>();
                Integer realHeight = null;
                //逐笔写入数据库
                try (SimpleFeatureIterator iterator = featureSource.getFeatures().features()) {
                    int index = 0;
                    SimpleFeature newFeature = null;
                    while (iterator.hasNext()) {
                        Build build = new Build();
                        SimpleFeature feature = iterator.next();
                        Object attribute = feature.getAttribute("BuildingID");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setBuildID(Long.valueOf(attribute.toString()));
                        attribute = feature.getAttribute("BDName");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setBDName(attribute.toString());
                        attribute = feature.getAttribute("BDFaceType");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setType(Integer.valueOf(attribute.toString()));
                        attribute = feature.getAttribute("FHeight");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setFHeight(Integer.valueOf(attribute.toString()));
                        attribute = feature.getAttribute("FNum");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setFNum(Integer.valueOf(attribute.toString()));
                        attribute = feature.getAttribute("UpBDID");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setUpBDID(Long.valueOf(attribute.toString()));
                        attribute = feature.getAttribute("Height");
                        if (attribute != null && !Strings.isNullOrEmpty(attribute.toString()))
                            build.setHeight(Integer.valueOf(attribute.toString()));
                        Geometry geometry = reLoadGeometry(feature);
                        if (geometry != null) {
                            geometry.setSRID(SRID);
                            build.setGeometry(geometry);
                        }
                        if (build.getType() == 1){
                            realHeight = build.getFHeight() * build.getFNum();
                            build.setTopHeight(realHeight);
                            singleMap.put(build.getBuildID(),build);
                            writeFeature(writer,newFeature,build);
                        }else if (build.getType() == 2){
                            build.setTopHeight(build.getHeight());
                            baseMap.put(build.getBuildID(),build);
                            writeFeature(writer,newFeature,build);
                        }else if(build.getType() == 3){
                            mainMap.put(build.getBuildID(),build);
                        }else if(build.getType() == 4){
                            topMap.put(build.getBuildID(),build);
                        }
                        index++;
                    }
                    Iterator mainBuild = mainMap.keySet().iterator();
                    while (mainBuild.hasNext()) {
                        Long mainID = (Long) mainBuild.next();
                        Long upID = mainMap.get(mainID).getUpBDID();
                        //去基础层中寻找ID与当前的upID相同的基础建筑
                        Iterator baseBuild = baseMap.keySet().iterator();
                        while(baseBuild.hasNext()){
                            Long baseID = (Long)baseBuild.next();
                            if(upID == baseID){
                                mainMap.get(mainID).setBaseHeight(baseMap.get(baseID).getTopHeight());
                                mainMap.get(mainID).setTopHeight(baseMap.get(baseID).getTopHeight() +
                                        mainMap.get(mainID).getFNum() * mainMap.get(mainID).getFHeight());
                            }
                        }
                        writeFeature(writer,newFeature,mainMap.get(mainID));
                    }

                    Iterator topBuild = topMap.keySet().iterator();
                    while (topBuild.hasNext()) {
                        Long topID = (Long) topBuild.next();
                        Long upID = topMap.get(topID).getUpBDID();
                        //去主体层中寻找ID与当前的upID相同的主体建筑
                        Iterator mainBuild1 = mainMap.keySet().iterator();
                        while(mainBuild1.hasNext()){
                            Long mainID = (Long)mainBuild1.next();
                            if(upID == mainID){
                                topMap.get(topID).setBaseHeight(mainMap.get(mainID).getTopHeight());
                                topMap.get(topID).setTopHeight(mainMap.get(mainID).getTopHeight() + topMap.get(topID).getHeight());
                            }
                        }
                        writeFeature(writer,newFeature,topMap.get(topID));
                    }

                    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();
        }
    }

加载建筑物数据,效果如下:


10338988-e8a93db14edd851d.png
结果图

大功告成!!!

猜你喜欢

转载自blog.csdn.net/weixin_34409741/article/details/86931538
今日推荐