当前位置: 代码迷 >> GIS >> 解决有关GIS点选重叠点的有关问题
  详细解决方案

解决有关GIS点选重叠点的有关问题

热度:249   发布时间:2016-05-05 06:18:12.0
解决有关GIS点选重叠点的问题

        当GIS地图中出现点要素比较集中的情况时,进行点选如果不加以设置调整的话就会出现点选不上要素。目前有如下两种设置方式,都是对选中要素进行范围扩大,但是差别很大,现在以极端方式来验证这两种方式的效果。

        我们先来看一下将要操作的地图底图效果:

        这是一个管网图层+管网附属建筑物图层,在截图中不难看到很多附属建筑物都靠近在一起,而且图层信息比较复杂,若要实现点选,默认的点选方法如下:     

          IdentifyTask IdentifyTask = new IdentifyTask(Config.MapServiceAddr);  //实例化Task对象            IdentifyTask.ExecuteCompleted += new EventHandler<IdentifyEventArgs>(IdentifyTask_ExecuteCompleted);  //注册Task完成监听事件            ESRI.ArcGIS.Client.Tasks.IdentifyParameters identyfyParams = new IdentifyParameters();  //实例化Task参数对象            identyfyParams.Geometry = e.MapPoint;  //待识别的几何图形,常用的有点选,矩形选择,多边形选择等            identyfyParams.Height = (int)MyMap.ActualHeight;  //当前浏览器的地图高度            identyfyParams.Width = (int)MyMap.ActualWidth;   //当前浏览器的地图宽度            identyfyParams.MapExtent = MyMap.Extent;  //当前地图的范围            identyfyParams.SpatialReference = MyMap.SpatialReference;  //定义输入和输出几何图形,以及mapExtent的空间参考            identyfyParams.LayerOption = LayerOption.all;  //定义查询图层            /**             * 固定查询第一个图层,即高速公路,可以使用下拉框进行选择其它图层(需要遍历所有图层),查询多个图层             *      identifyParams.layerOption=IdentifyParameters.LAYER_OPTION_VISIBLE;  所有可见图层             *                                                    LAYER_OPTION_ALL;      所有图层             *                                                    LAYER_OPTION_TOP;      最上层             * */            foreach (int intIndex in lstLayerIndex)            {                identyfyParams.LayerIds.Add(intIndex);            }            IdentifyTask.ExecuteAsync(identyfyParams);  //为必要属性赋值,发送请求             IdentifyTask.Failed += new EventHandler<TaskFailedEventArgs>(IdentifyTask_Failed);


        说明:紫色部分看似是重复的对查询图层进行了定义,但当Arcgis10.1运行在Windows2012上的时候,单独使用LayerOptionidentyfyParams.LayerIds.Add都会有失效率,所以这里才把两种方式都添加进来(这只是我遇到的情况,不知道其他大侠是否也有类似的经历)

        这样的方式就很难命中选择的要素。于是我们想到的是扩大点的命中范围,来增强它的命中率。

        方式一:  获取选中点的四角坐标范围,然后将其进行一定程度的范围扩大,然后将Geometry指向扩大后的四角坐标范围。这里的范围值是对真实数据的地理坐标范围进行扩大或缩小。

          //获取点选的点对象            ESRI.ArcGIS.Client.Geometry.MapPoint clickPoint = e.MapPoint;          //为了让点选范围扩大,更容易点一些            ESRI.ArcGIS.Client.Geometry.Envelope test = clickPoint.Extent;           test.XMax += 50;           test.XMin -= 50;           test.YMax += 50;           test.YMin -= 50;           MousePoint = clickPoint;          IdentifyTask IdentifyTask = new IdentifyTask(Config.MapServiceAddr);  //实例化Task对象            IdentifyTask.ExecuteCompleted += new EventHandler<IdentifyEventArgs>(IdentifyTask_ExecuteCompleted);  //注册Task完成监听事件            ESRI.ArcGIS.Client.Tasks.IdentifyParameters identyfyParams = new IdentifyParameters();  //实例化Task参数对象            identyfyParams.Geometry = test;  //待识别的几何图形,常用的有点选,矩形选择,多边形选择等            identyfyParams.Height = (int)MyMap.ActualHeight;  //当前浏览器的地图高度            identyfyParams.Width = (int)MyMap.ActualWidth;   //当前浏览器的地图宽度            identyfyParams.MapExtent = MyMap.Extent;  //当前地图的范围            identyfyParams.SpatialReference = MyMap.SpatialReference;  //定义输入和输出几何图形,以及mapExtent的空间参考            identyfyParams.LayerOption = LayerOption.all;  //定义查询图层            /**             * 固定查询第一个图层,即高速公路,可以使用下拉框进行选择其它图层(需要遍历所有图层),查询多个图层             *      identifyParams.layerOption=IdentifyParameters.LAYER_OPTION_VISIBLE;  所有可见图层             *                                                    LAYER_OPTION_ALL;      所有图层             *                                                    LAYER_OPTION_TOP;      最上层             * */            foreach (int intIndex in lstLayerIndex)            {                identyfyParams.LayerIds.Add(intIndex);            }            IdentifyTask.ExecuteAsync(identyfyParams);  //为必要属性赋值,发送请求            IdentifyTask.Failed += new EventHandler<TaskFailedEventArgs>(IdentifyTask_Failed);

        通常而言,这种方式也没有什么不妥,但对于我么截图的图层进行点选就会出现问题。因为是对数据的真实坐标值进行范围的扩大或缩小,那么即使重合比较严重的两个点进行无限放大,该放大也只是比例尺无限放大,变化的是屏幕像素值而不是地理坐标值,这时对其中一个点进行点选,最后还是会将两个点的信息全部显示出来。如下左图:


        方式二:获取选中点,并且设置容差参数值(即以选中要素为中心,设置值为半径的屏幕像素范围内的要素将被视为一个要素,否则是两个要素)。

          IdentifyTask IdentifyTask = new IdentifyTask(Config.MapServiceAddr);  //实例化Task对象            IdentifyTask.ExecuteCompleted += new EventHandler<IdentifyEventArgs>(IdentifyTask_ExecuteCompleted);  //注册Task完成监听事件            ESRI.ArcGIS.Client.Tasks.IdentifyParameters identyfyParams = new IdentifyParameters();  //实例化Task参数对象            identyfyParams.Tolerance = 10;  //容差半径            identyfyParams.Geometry = e.MapPoint;  //待识别的几何图形,常用的有点选,矩形选择,多边形选择等            identyfyParams.Height = (int)MyMap.ActualHeight;  //当前浏览器的地图高度            identyfyParams.Width = (int)MyMap.ActualWidth;   //当前浏览器的地图宽度            identyfyParams.MapExtent = MyMap.Extent;  //当前地图的范围            identyfyParams.SpatialReference = MyMap.SpatialReference;  //定义输入和输出几何图形,以及mapExtent的空间参考            identyfyParams.LayerOption = LayerOption.all;  //定义查询图层            /**             * 固定查询第一个图层,即高速公路,可以使用下拉框进行选择其它图层(需要遍历所有图层),查询多个图层             *      identifyParams.layerOption=IdentifyParameters.LAYER_OPTION_VISIBLE;  所有可见图层             *                                                    LAYER_OPTION_ALL;      所有图层             *                                                    LAYER_OPTION_TOP;      最上层             * */            foreach (int intIndex in lstLayerIndex)            {                identyfyParams.LayerIds.Add(intIndex);            }            IdentifyTask.ExecuteAsync(identyfyParams);  //为必要属性赋值,发送请求            IdentifyTask.Failed += new EventHandler<TaskFailedEventArgs>(IdentifyTask_Failed);

        这种方式的效果就很明显了,选中的要素是同一个,不需要放大那么大的比例,就可以直接获取都想要的附属建筑物的要素信息了。如下左图:


        通过上述说明,两种方法的精准度一目了然,当然对于要素信息没有如此密集程度时,也可以采用第一种方式。

  相关解决方案