移动用地分析功能 |
简介
用地分析是指在对地区各自然要素进行综合分析研究的基础上,按照城市规划和建设要求、用地整备工程技术的可能性和经济性,对城市规划用地进行适用性分析评定,以划出城市用地的不同等级。另外用于查清村和农、林、牧、渔场,居民点及其以外的独立工矿企事业单位土地权属界线和村以上各级行政界线,查清各类用地面积、分布和利用状况。
在本文中,用地分析主要实现为对所选中区域进行土地类别、面积和分布的识别与判断,计算其中各个层级占其父级的百分比以及面积情况。
实现逻辑略析
- 可视化与相关功能操作窗口的基本实现
- 加载功能基础的地图底图与分析操作图层
- 分析区域的选择并获取当前图形
- 离线调用FeatureQuery(在线调用QueryTask)进行要素查询与过滤
- 获得结果FeatureResult,从中获取Geometry(并非与绘制图形做过交叉处理的Geometry)与Attribute
- 图形切割与面积计算
- 通过GraphicLayer进行图形展示以及图形条组与相应控件Item绑定
重要部分代码实现
1.分析区域选择
//通过多点集合绘制几何图形
polygon.lineTo(currentPoint);
currentGraphic = new Graphic(polygon, symbol);
drawLayer.updateGraphic(currentGraphicIndex,currentGraphic);
pointGraphic=new Graphic(multiPoint,pointSymbol);
drawLayer.updateGraphic(pointGraphicIndex,pointGraphic);
multiPoint.add(currentPoint);
if(lastGraphicIndex!=-1){
drawLayer.removeGraphic(lastGraphicIndex);
}
lastGraphic=new Graphic(currentPoint,lastSymbol);
lastGraphicIndex=drawLayer.addGraphic(lastGraphic);
2.地图查询
离线查询
离线查询通过初始化一个QueryParameter并设置其参数,调用FeatureLayer对象的QueryFeature方法进行查询,拿到查询结果的Geometry与Attribute。
QueryParameters queryParams=new QueryParameters();
//设置区域
if (isALL) {
queryParams.setGeometry(mapView_main.getExtent());
}else {
Polygon queryPolygon=measureManager.getpolygon();
queryParams.setGeometry(queryPolygon);
}
//设置过滤字段
queryParams.setOutFields(new String[]{"*"});
landAnalysisResultInfos=new ArrayList<>();
List<LandAnalysisResultInfo> analysisResultInfos=new ArrayList<>();
Future<FeatureResult> resultFuture=null;
FeatureResult featureResult=null;
FeatureLayer featureLayer=(FeatureLayer)layer;
resultFuture=featureLayer.getFeatureTable().queryFeatures(queryParams,callbackListener);
try {
//获取结果
featureResult=resultFuture.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if (featureResult!=null&&featureResult.featureCount()>0) {
Iterator it = featureResult.iterator();
while (it.hasNext()){
GeodatabaseFeature geodatabaseFeature= (GeodatabaseFeature) it.next();
Geometry geometry=geodatabaseFeature.getGeometry();
<String, Object> featureMap=geodatabaseFeature.getAttributes();
if(geometry!=null){
//进行图形处理
}
if (featureMap!=null&&featureMap.size()>0) {
//进行内容详情提取处理
}
}
在线查询
在线查询通过初始化一个QueryParameter并设置其参数,然后通过在线图层的URL初始化一个QueryTask,通过其对象的execute方法拿到查询结果的Geometry与Attribute。
QueryParameters queryParams=new QueryParameters();
Polygon Querypolygon=measureManager.getpolygon();
queryParams.setGeometry(Querypolygon);
landAnalysisResultInfos=new ArrayList<>();
queryParams.setOutFields(new String[]{"*"});
List<LandAnalysisResultInfo> analysisResultInfos=new ArrayList<>();
Future<FeatureResult> resultFuture=null;
FeatureResult featureResult=null;
ArcGISDynamicMapServiceLayer featureLayer=(ArcGISDynamicMapServiceLayer)layer;
QueryTask queryTask=new QueryTask(featureLayer.getQueryUrl(0));
resultFuture=queryTask.execute(queryParams, callbackListener);
try {
featureResult=resultFuture.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if (featureResult!=null&&featureResult.featureCount()>0) {
for (Object element : featureResult) {
if (element instanceof Feature) {
Feature f = (Feature) element;
Geometry geometry=f.getGeometry();
Map<String, Object> featureMap=f.getAttributes();
if(geometry!=null){
//进行图形处理
}
if (featureMap!=null&&featureMap.size()>0) {
//进行内容详情提取处理
}
}
}
}
3.图形交叉处理
通过调用GeometeyEngine.intersect()方法获取。
Geometry geometry = GeometryEngine.intersect(geometry,measureManager.getpolygon(),mapView_main.getSpatialReference());
4.面积计算
由于获取的Geometry的面积与其父Geometry的面积均为调用Geometry对象的calculateArea2D()方法,并非实际面积。
所以我们需要通过Attribute获得的实际面积计算切割Geometry与其父Geometry的实际面积,并计算其百分比。
/**
*通过在地图上的Area大小计算百分比与实际面积
*
* @param landResourceInfos 分析结果的数组 成员: {@link LandAnalysisResultInfo}
* @return 一个结果的数组 变更了参数数组中成员的属性
*/
public static List<LandAnalysisResultInfo> getLandPercentValue(List<LandAnalysisResultInfo> landResourceInfos){
/*计算实际面积 */
double MUM=0;
for (LandAnalysisResultInfo landResourceInfo : landResourceInfos) {
if (landResourceInfo.getYDMJ()==null) {
landResourceInfos.remove(landResourceInfo);
continue;
}
Double visualArea=landResourceInfo.getGeometry().calculateArea2D();
Double visualParentArea=landResourceInfo.getParentGeometry().calculateArea2D();
Double realArea=landResourceInfo.getYDMJ()/visualParentArea*visualArea;
landResourceInfo.setYDMJ(realArea);
//累计求和
MUM=MUM+landResourceInfo.getYDMJ();
}
/*分别计算百分比*/
for (LandAnalysisResultInfo landResourceInfo : landResourceInfos) {
landResourceInfo.setPercentValue(String.valueOf(landResourceInfo.getYDMJ()/MUM*100));
}
return landResourceInfos;
}
5.图形展示
由于本次使用为列表显示,故图形展示在点击子Item的时候进行Geometry的绘制与添加。
/**
* 结果列表点击效果
*/
private AdapterView.OnItemClickListener resultListOnItemClickListener =new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
resultDrawerLayer.removeAll();
resultDrawerLayer.addGraphic(new Graphic(landAnalysisResultInfos.get(position).getGeometry(), MapViewTapTool.getLabelSymbol(MainMapActivity.this,Geometry.Type.POLYGON, Color.BLUE)));
resultDrawerLayer.addGraphic(new Graphic(landAnalysisResultInfos.get(position).getParentGeometry(),MapViewTapTool.getLabelSymbol(MainMapActivity.this,Geometry.Type.POLYLINE, Color.BLACK)));
Envelope tempEnvelope = new Envelope();
landAnalysisResultInfos.get(position).getParentGeometry().queryEnvelope(tempEnvelope);
Point tempPoint = tEnvelope.getCenter();
mapView_main.centerAt(tempPoint,true);
}
};
结语
用地分析功能的开发,既减少了用户查看地图计算面积的时间,提高了地图的可阅读性。让用户通过移动设备简单的操作即可获取选取区域中各类型的板块内容与面积,并通过绘制图层让用户在地图上更直观的看清板块对象。