ArcGIS图例过滤功能

 

 

移动图例过滤功能 · Fellow Travellers
     
 

 

简介

图例过滤是对于多图例图层的一种查看方式,这种查看方式方便对特定类型的图块进行统一查看。


多图例图层一般为DynamicLayer与FeatureLayer,而且单个图例的图层与多个图例的图层,其渲染器也是不同的,单个图例的为SimpleRenderer,多个图例为UniqueValueRenderer。


在本文中,图例过滤主要为对图例进行特定过滤达到多图层互斥过滤的效果,另外对于在线图例过滤使用了Layer Definition进行图层Visible控制问题。

 

 

实现逻辑略析

  1. 可视化与相关功能操作监听的基本实现
  1. 加载功能基础的分析操作图层与其图例
  1. 单个图例的点击并获取其LabelName
  1. 在线将ArcGisDynamicServiceLayer通过ArcGisFeatureLayer加载,并获取其Renderer转为UniqueValueRenderer(离线获取FeatureLayer的Renderer) 并获取Render中的Feild1字段(配置的过滤字段)
  1. WhereClause语句的拼接(过滤字段与LabelName中的值拼接成Sql Where语句)
  1. 在线通过设置ArcGisDynamicServiceLayer的LayerDefinition(离线通过设置FeatureLayer的DefinitionExpression)进行过滤

  2. 对于在线DynamicLayer多图层控制显示问题,将Visible控制可视改为Layer Definition控制可视,只维护一套属性。

 


 

重要部分代码实现

1.LayerDefinition控制可视

/**

** 根据visibleIds 更新DynamicLayer 通过DynamicLayer的Definition进行控制显示

** Definition中 1-> “1=1” 表示图层 1 全部显示

**/
 

//要存储的LayerDefinitions
Map<String, Map<Integer, String>> dynamicLayerDefinitionMap = TotalApplication.getDynamicLayerDefinitionMap();
//要操作的LayerDefinitions
Map<Integer, String> layerDefinitions = dynamicLayer.getLayerDefinitions();
if (layerDefinitions==null) {
    layerDefinitions=new HashMap<>();
}
if (isOpenLayer) {
    //显示
    if (dynamicLayerDefinitionMap.containsKey(dynamicLayer.getUrl())) {
        //从存储语句中获取之前的过滤语句
        for (int visibleId : visibleIds) {

            Map<Integer, String> integerStringMap = dynamicLayerDefinitionMap.get(dynamicLayer.getUrl());
            if (integerStringMap.containsKey(visibleId)
                    &&integerStringMap.get(visibleId)!=null
                    &&!Constants.SQL_FALSE.equalsIgnoreCase(integerStringMap.get(visibleId))) {
                //已存该layer的id的Layer Definition Sql 语句
                layerDefinitions.put(visibleId,integerStringMap.get(visibleId));
            }else {
                //全部显示
                layerDefinitions.put(visibleId,Constants.SQL_TURE);
            }
        }
    }else {
        //全部显示
        for (int visibleId : visibleIds) {
            layerDefinitions.put(visibleId,Constants.SQL_TURE);
        }
    }
}else {
    //关闭
    if (!layerDefinitions.isEmpty()) {
        Map<Integer, String> integerStringMap;
        if (dynamicLayerDefinitionMap.containsKey(dynamicLayer.getUrl())) {
            //存储中有这个Layer的Definition
            integerStringMap = dynamicLayerDefinitionMap.get(dynamicLayer.getUrl());
        }else {
            //存储中没有这个layer的definition
            integerStringMap=new HashMap<>();
        }
        for (int visibleId : visibleIds) {
            if (layerDefinitions.containsKey(visibleId)
                    &&layerDefinitions.get(visibleId)!=null
                    &&!Constants.SQL_FALSE.equalsIgnoreCase(layerDefinitions.get(visibleId))) {
                //有可视语句,进行储存
                integerStringMap.put(visibleId,layerDefinitions.get(visibleId));
            }
            //取消可视
            layerDefinitions.put(visibleId,Constants.SQL_FALSE);
        }
        TotalApplication.getDynamicLayerDefinitionMap().put(dynamicLayer.getUrl(),integerStringMap);

    }else {
        //一般走不到这,避免花里胡哨的操作
        for (int visibleId : visibleIds) {
            //取消可视
            layerDefinitions.put(visibleId,Constants.SQL_FALSE);
        }
    }
}
dynamicLayer.setLayerDefinitions(layerDefinitions);
dynamicLayer.refresh();

 

2.Render获取与过滤字段获取

离线获取

离线用的FeatureLayer.getRenderer()
 

 FeatureLayer featureLayer= (FeatureLayer) layer;
//判断是否获取过,避免重复查询
if (TotalApplication.getInstanceFilterFieldMap().containsKey(layerName)) {
    filterField=TotalApplication.getInstanceFilterFieldMap().get(layerName);
}else{
    //记录已查询 以免无结果 重复查询
    TotalApplication.getInstanceFilterFieldMap().put(layerName,Constants.NO_FILTER_FIELD);
    filterField=Constants.NO_FILTER_FIELD;
    //获取过滤字段
    Renderer renderer = featureLayer.getRenderer();
    if (renderer instanceof UniqueValueRenderer) {
        UniqueValueRenderer uniqueValueRenderer= (UniqueValueRenderer) renderer;
        filterField = uniqueValueRenderer.getField1();
        TotalApplication.getInstanceFilterFieldMap().put(layerName,filterField);
    }
}

 

在线获取

在线通过加载ArcGisFeatureLayer获取Renderer中的过滤字段
 

//Renderer中过滤字段的查询和保存,避免重复加载 例:RDDM
if (TotalApplication.getInstanceFilterFieldMap().keySet().contains(url+Constants.SPLIT_SYMBOL[4]+layerID)) {
    //通知过滤
}else{
    final ArcGISFeatureLayer arcGISFeatureLayer= new ArcGISFeatureLayer(url+Constants.SPLIT_SYMBOL[4]+layerID, ArcGISFeatureLayer.MODE.SELECTION);
    final String finalUrl = url;
    final String finalLayerID = layerID;
    arcGISFeatureLayer.setOnStatusChangedListener(new OnStatusChangedListener() {
        @Override
        public void onStatusChanged(Object o, STATUS status) {
            if (status== STATUS.INITIALIZED) {
                //记录已查询 以免无结果 重复查询
                TotalApplication.getInstanceFilterFieldMap().put(arcGISFeatureLayer.getUrl(),Constants.NO_FILTER_FIELD);
                Renderer renderer = arcGISFeatureLayer.getRenderer();
                if (renderer!=null) {

                    if (renderer instanceof UniqueValueRenderer) {
                        UniqueValueRenderer uniqueValueRenderer= (UniqueValueRenderer) renderer;
                        //获取过滤字段 RDDM
                        String filterField = uniqueValueRenderer.getField1();
                        if (filterField!=null&&!filterField.isEmpty()) {
                            TotalApplication.getInstanceFilterFieldMap().put(arcGISFeatureLayer.getUrl(),filterField);
                        }
                    }
                }
                //通知过滤
            }

        }
    });
}  

3.图例过滤

离线过滤

离线用的FeatureLayer过滤 FeatureLayer的LayerDefinition为 String (Sql Where Clause),


无需控制图层,且可以和Visible混合使用

//图例过滤 例:YDDM = 'mc'
featureLayer.setDefinitionExpression(filterField+Constants.WHERE_EQUAL+Constants.WHERE_QUOTATION_MARKS+finalLegendLabel+Constants.WHERE_QUOTATION_MARKS);

 

在线过滤

在线用的ArcGISDynamicMapServiceLayer过滤

ArcGISDynamicMapServiceLayer的LayerDefinition为Map< int(layerId) , String(Sql Where Clause) >,


得到所需数据进行过滤
 

//图例过滤
if (filterField!=null&&!Constants.NO_FILTER_FIELD.equalsIgnoreCase(filterField)&&!filterField.isEmpty()) {
    if (layer instanceof ArcGISDynamicMapServiceLayer) {
        //拼组Sql Where clause 并设置LayerDefinitions 进行过滤
        Map<Integer, String> layerDefinitions = ((ArcGISDynamicMapServiceLayer) layer).getLayerDefinitions();
        if (layerDefinitions==null) {
            layerDefinitions=new HashMap<Integer, String>();
        }
        //map中: layerId -> where clause   YDDM = 'G1'
        layerDefinitions.put(Integer.parseInt(layerId),filterField+Constants.WHERE_EQUAL+Constants.WHERE_QUOTATION_MARKS+legendName+Constants.WHERE_QUOTATION_MARKS);
        ((ArcGISDynamicMapServiceLayer) layer).setLayerDefinitions(layerDefinitions);
        ((ArcGISDynamicMapServiceLayer) layer).refresh();
    }
}

4.结束过滤(全部显示)

离线结束过滤

Map<String, Layer> layerMap = TotalApplication.getInstanceAllLayerMap();
if (layerMap.containsKey(name)) {
    Layer layer = layerMap.get(name);
    if (layer instanceof FeatureLayer) {
        //设置LayerDefinition
        ((FeatureLayer) layer).setDefinitionExpression(Constants.SQL_TURE);
        //数据改变
        legendAdapter.selectLabel= Constants.NO_SELECT;
        TotalApplication.getLayerSelectLabelMap().put(name,Constants.NO_SELECT);
        legendAdapter.notifyDataSetChanged();
    }
}

 

//获取当前layer对应的Service Layer 的URL与Id
List<ThemeInfo> theme = oneMapActivity.mDataSource.getTheme();
for (ThemeInfo themeInfo : theme) {
    if (name.equalsIgnoreCase(themeInfo.getName())) {
        serviceUID=themeInfo.getServiceUid();
        layerID=themeInfo.getLayerId();
    }
}
List<MapServicesInfo> mapServices = oneMapActivity.mDataSource.getMapServices();
for (MapServicesInfo mapService : mapServices) {
    if (serviceUID!=null&&serviceUID.equalsIgnoreCase(mapService.getName())) {
        url=mapService.getUrl();
    }
}
//数据改变
legendAdapter.selectLabel= Constants.NO_SELECT;
TotalApplication.getLayerSelectLabelMap().put(name,Constants.NO_SELECT);
legendAdapter.notifyDataSetChanged();
//TODO 通知图例过滤



全部显示

if (layer instanceof ArcGISDynamicMapServiceLayer) {
    Map<Integer, String> layerDefinitions = ((ArcGISDynamicMapServiceLayer) layer).getLayerDefinitions();
    if (layerDefinitions==null){
        layerDefinitions=new HashMap<Integer, String>();
    }
    layerDefinitions.put(Integer.parseInt(layerId),Constants.SQL_TURE);
    ((ArcGISDynamicMapServiceLayer) layer).setLayerDefinitions(layerDefinitions);
    ((ArcGISDynamicMapServiceLayer) layer).refresh();
}

 

 

结语

  图例过滤功能的开发,既减少了用户手动查找相应地块和汇总的时间,提高了地图的可阅读性。让用户通过移动设备简单的操作地图中同一类型的地块汇总,并通过绘制图层让用户在地图上更直观的看清板块对象。

 



 


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值