在实际应用中,根据业务需要往往需要对对象的可见性进行控制。在SuperMap GIS 8C SP1版本支持更加便捷、高效的对象可见性控制方式。下文将通过示例代码,详细介绍如何在二次开发中控制地图几何对象的可见性,示例代码基于SuperMap iObjects .NET组件。
SuperMap GIS 8C SP1版本本着提升软件灵活性、易用性以及地图显示效率的原则,应用户需求,支持依字段值控制对象可见性的功能。
有这样一个应用场景,在通讯行业,通讯管理系统与地理信息系统进行集成,对基站点数据以及每个基站信号覆盖情况进行可视化显示,现在需要在地图上根据指定的条件显示出不同信号(如:2G、3G、4G信号)覆盖情况的基站点与其信号覆盖。
如图 1所示,点表示基站(station点数据集)、扇面表示该基站信号覆盖(cover面数据集),两个数据集中都有一个cell字段,记录基站ID编号。此时,如果想查看3G信号基站及其覆盖,那么通讯管理系统可以查询给出3G信号基站的ID号,地图将根据给定的ID号,过滤显示需要的对象,查询结果如图 2所示,符合条件的基站ID号为:
1003,1005,1111,1408,1001,1104,1205,1010,1050,1485,1923,1087,1034,1790,1980,1721,1300,1000,1401。
图 1 某地区基站及信号覆盖分布图
图 2 显示符合条件的信号基站
SuperMap GIS 8C SP1版本针对这个应用需求可以有两种解决方案,下面一一为您说明。
使用Layer. DisplayFilter属性,通过指定一个SQL条件表达式来过滤显示图层中的符合要求的对象。由于通讯系统查询结果为一组基站ID号,所以我们需要使用“station.cellin (1003,1005)”表达式(其中“station.cell”为staion基站数据集中记录基站ID号的字段)。
假设上述符合要求的基站编号为:1003,1005,1010…….等几千几万个基站,并且编号没有规则,相对随意和离散,那么要过滤显示需要的数据,就需要构建如下代码:
(下面的代码就以图 2中符合条件的基站编号
[1003,1005,1111,1408,1001,1104,1205,1010,1050,1485,1923,1087,1034,1790,1980,1721,1300,1000,1401]为例)
"test.cell in (1003,1005,1111,1408,1001,1104,1205,1010,1050,1485,1923,1087,1034,1790,1980,1721,1300,1000,1401)" 为过滤显示条件,显然,当基站编号数量上千或者上万时时,这种写法很不方便,且性能不理想。
public void LayerFilterSet() { //设置查询条件 QueryParameter queryParameter = new QueryParameter(); queryParameter.CursorType =CursorType.Static; queryParameter.AttributeFilter ="test.cell in (1003,1005,1111,1408,1001,1104,1205,1010,1050,1485,1923,1087,1034,1790,1980,1721,1300,1000,1401)"; //指定基站点数据的过滤条件 stationLayer.DisplayFilter =queryParameter; //指定基站信号覆盖面数据的过滤条件 coverLayer.DisplayFilter =queryParameter; m_mapControl.Map.EnsureVisible(layer); m_mapControl.Map.Refresh(); }
|
前面的方法在海量数据情况下不仅在构建过滤条件时很麻烦,而且地图显示性能也受到影响,因此,SuperMap GIS 8C SP1版本提供了FieldValuesDisplayFilter类,很好地支持这种根据指定值过滤显示地图对象的应用场景。
Ø 通过FieldValuesDisplayFilter.FieldName 指定一个字段,过滤显示条件的指定值都将来源于这个字段。
Ø FieldValuesDisplayFilter.Values 为一个数组,过滤显示条件的指定值都使用这个数组存储,在图层显示时,与数组匹配的值才显示或者不显示。上述例子中,通讯管理系统返回的为基站编号的数组,刚好可以直接传递给这个属性作为过滤条件,相比通过方法一,在重新构建SQL查询表达式的方式要省时省力的多。
Ø FieldValuesDisplayFilter.DisplayMode,决定图层中与FieldValuesDisplayFilter.Values数组中值匹配的对象是否显示。该属性为FieldValuesDisplayMode枚举,当枚举值为Display表示显示;Disable值表示隐藏不显示。
那么上述的过滤显示,就需要构建如下代码:假设上述符合要求的基站编号为:1003,1005,1010…….(下面的代码就以
[1003,1005,1111,1408,1001,1104,1205,1010,1050,1485,1923,1087,1034,1790,1980,1721,1300,1000,1401]编号为例)
public voidLayerDisplayValues() { //从通讯管理系统传回的符合要求的基站ID数组 Int32[] ids = {1003,1005,1111,1408,1001,1104,1205,1010,1050,1485,1923,1087,1034,1790,1980,1721,1300,1000,1401}; //根据符合条件的基站编号过滤显示基站点数据 FieldValuesDisplayFilterstationFilter = stationLayer.FieldValuesDisplayFilter; filtervalue.SetDisableFieldName("cell"); filtervalue.DisplayMode =FieldValuesDisplayMode.Display; filtervalue.Values =ids; //根据符合条件的基站编号过滤显示信号符号扇面数据 FieldValuesDisplayFiltercoverFilter = coverLayer.FieldValuesDisplayFilter; filtervalue.SetDisableFieldName("cell"); filtervalue.DisplayMode =FieldValuesDisplayMode.Display; filtervalue.Values =ids; m_mapControl.Map.EnsureVisible(layer); m_mapControl.Map.Refresh(); }
|
在地图制图中可能会存在这样情况,某图层中的对象通过过滤条件隐藏了一部分对象,而这些对象对应的标签仍然显示。例如:有一幅关于某地区小区和物业管理中心分布的图(如图3),现在想查看“景泰物业管理处”所管辖的小区情况,如图 4所示,经过过滤显示后,符合条件小区面对象留下了,不符合添加的隐藏了,但是被过滤掉的面对象的标签仍旧显示,这显然是不合理的,合理的做法是对象隐藏了对应的标注也应该随之隐藏。
图 3 某小区分布图
图 4 过滤显示符合条件的小区后
SuperMap GIS 8C SP1版本提供了建立图层和标签专题图的可见性关联功能(Layer.SetDisplayControledLayer),可以实现对象隐藏对应的标签也隐藏的效果(同样的效果通过标签专题图设置相同的过滤表达式也能实现,有了该属性会更方便使用)。上面的数据,建立小区面图层和对应的标签专题图的关联关系后,再次过滤显示面对象,隐藏面对象的标签也隐藏了,如图 5所示。
public voidDisplayControledLayer () { Layer layer = null; Layer labellayer = null; //获取点对象图层 layer = m_mapControl.Map.Layers[2]; //获取与面对象图层关联的标签专题图层 labellayer=m_mapControl.Map.Layers[1]; //建立面对象图层与标签专题图层的关联关系 layer.SetDisplayControledLayer(labellayer); //设置面对象图层过滤显示条件,隐藏一部分对象 QueryParameter queryParameter = new QueryParameter(); queryParameter.CursorType =CursorType.Static; queryParameter.AttributeFilter =" buildarea.area in (1105)"; layer.DisplayFilter =queryParameter; m_mapControl.Map.EnsureVisible(layer); m_mapControl.Map.Refresh(); } |
图 5 建立面图层与标签专题图层关联后过滤显示效果
补充说明:不过Layer.SetDisplayControledLayer属性并不能作用于通过FieldValuesDisplayFilter属性控制的可见性上。