基于GeoTools實現(xiàn)建筑物高度的提取

??接上一篇文章:http://www.itdecent.cn/p/d9150de6058b
??繼續(xù)對建筑物數(shù)據(jù)進行高度的提取,其中分為底座、單層、柱頂和柱頂四類,為了在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數(shù)據(jù)存儲工廠
        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"));
        //設(shè)置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;
                //逐筆寫入數(shù)據(jù)庫
                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();
                        //去基礎(chǔ)層中尋找ID與當前的upID相同的基礎(chǔ)建筑
                        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 數(shù)據(jù)處理出錯!\n錯誤信息: %s", fileName, e.getMessage()), e);
            }
        } finally {
            mainController.setStatus(null);
            mainController.setProgress(0);
            featureSource.getDataStore().dispose();
        }
    }

加載建筑物數(shù)據(jù),效果如下:


結(jié)果圖

大功告成!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容