接上一篇文章: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();
}
}
加载建筑物数据,效果如下:
结果图
大功告成!!!