高亮地图点及属性信息展示优化方案


作者:小阳

###1、序言

本文主要是利用了UTFGrid图层快速交互获取地物信息的特点,以SuperMap iClient for JavaScript的开发作为示范。(注:要实现本文所讲述的功能,同时需要SuperMap iServer和SuperMap iClient for JavaScript 7C系列及以上的版本才支持)。

在此之前,我先简要的讲一下什么是UTFGrid:UTFGrid只包含地物的属性信息,可以根据地物的屏幕像素位置在客户端快速获地物的属性信息, 如:实现鼠标悬停或鼠标单击某一地物时,快速获取该地物某些属性信息。UTFGrid可由iServer动态生成,也可以将其预先切成瓦片。详细了解UTFGrid(请参见参见
###2、优化思路
####1.使用分布式切图切属性瓦片缓存
这里要着重说一下UTFGrid单元格网大小的设置,这个值决定了UTFGrid的效率和精准度,设置的值越小精度越高,但是单元格也会越多,在一定程度上也会影响性能,怎样设置这个参数取决于地物的像素尺寸。首先,这个参数能被瓦片的大小整除,比如UTFGrid的瓦片大小为256×256,那么这个值就应该要被256整除。其次,我们需要参考地物在最小比例尺下的像素尺寸来设置(UTFGrid隐藏的情况下除外),如:在地图的最小比例尺下点符号的像素尺寸大概为8×8的大小,这里可以设置pixcell的值为8×8,在精度允许的情况下,这种情况推荐设置为16×16,因为8×8的单元格比较小,在监听鼠标事件时不易成功。
这里写图片描述

####2.iServer启用属性瓦片缓存
默认发布的地图服务是没有启用 UTFGrid缓存的,需要进入到服务管理页面找到发布的地图服务,然后点击进入到缓存一栏勾选是否启用属性瓦片缓存
这里写图片描述

iServer默认将UTFGrid瓦片放置在\webapps\iserver\output\sqlite路径下。
这里写图片描述

如果不启用属性瓦片缓存可以使用UTFGrid吗?答案是肯定的,如果是在大数据量的前提下,建议将UTFGrid预先切成瓦片,下图是各种方式使用UTFGrid的性能对比。
这里写图片描述

####3.编程实现

初始化

var map,layer,vectorLayer,infowin,infowin1,highlightFea,popfeature,
                host = document.location.toString().match(/file:\/\//)?"http://localhost:8090":'http://' + document.location.host,
                url="http://support.supermap.com.cn:8090/iserver/services/map-changchun/rest/maps/长春市区图_Local";
        var controlmove,controlclick,utfgridPark,utfgridSchool;

        function init(){
            map = new SuperMap.Map("map", {controls: [
                new SuperMap.Control.ScaleLine(),
                new SuperMap.Control.Zoom(),
                new SuperMap.Control.LayerSwitcher(),
                new SuperMap.Control.Navigation({
                    dragPanOptions: {
                        enableKinetic: true
                    }
                })],
                projection: "EPSG:0",
                //设置地图的最大范围,这行代码相当重要
                maxExtent:new SuperMap.Bounds(48.4 , -7668.25,8958.85 , -55.58 )
            });
            layer = new SuperMap.Layer.TiledDynamicRESTLayer("China", url, {transparent: false}, {useCanvas: true, maxResolution: "auto",
                scales:[1/2000,1/4000,1/8000,1/16000,1/32000]
            });
            vectorLayer=new SuperMap.Layer.Vector("Vector Layer");
//注意:pixcell与utfgridResolution两个属性有对应关系,在使用的时候也要注意场景;
//1.其中pixcell为发送给服务端请求utfgrid瓦片的精度,数值越小,精度越高,相应的瓦片大小也就越大;
//2.utfgridResolution为客户端解析瓦片使用的精度,应该与pixcell的值相等,否则会产生位置与属性对应不上的问题;
//3.通常如果UTFGrid图层为面图层,对应的数据量会比较大,为了不影响页面的正常浏览,可以将这两个属性设的大一些;
//4.isUseCache设置是否使用缓存,使用缓存能够提高性能;

            utfgridSchool = new SuperMap.Layer.UTFGrid("UTFGridLayerSchool", url,
                    {
                        layerName: "School@Changchun",
                        utfTileSize: 256,
                        pixcell: 16,
                        isUseCache: true
                    },
                    {
                        utfgridResolution: 16
                    });
            utfgridSchool.maxExtent=layer.maxExtent;
            utfgridPark = new SuperMap.Layer.UTFGrid("UTFGridLayerPark", url,
                    {
                        layerName: "Park@Changchun",
                        utfTileSize: 256,
                        pixcell: 16,
                        isUseCache: true
                    },
                    {
                        utfgridResolution: 16
                    });
            utfgridPark.maxExtent=layer.maxExtent;

            //监听move事件控件
            controlmove = new SuperMap.Control.UTFGrid({
                layers: [utfgridPark,utfgridSchool],
                callback: callback,
                handlerMode: "move"
            });
            //监听click事件控件
            controlclick = new SuperMap.Control.UTFGrid({
                layers: [utfgridPark,utfgridSchool],
                callback: callback2,
            });

            layer.events.on({"layerInitialized": addLayer});
            map.addControl(controlmove);
            map.addControl(controlclick);
            map.events.on({"zoomend":reviewUTFgrid});
        }
     function addLayer() {
            var center = new SuperMap.LonLat(4539.98 , -3835.29);
            map.addLayers([layer,vectorLayer,utfgridSchool,utfgridPark,]);
            map.setCenter(center, 0);
            reviewUTFgrid();
        }

高亮点:在这里,我们利用了Control.UTFGrid监听move事件的方式,获取到点的坐标,然后绘制一个feature叠加到该点上实现高亮。如果想实现类似于百度地图每种类型的点都有不同的高亮图标方式,可以在feature的源数据属性表里面加字段来判断。实现效果如下:
这里写图片描述

        //move事件回调函数
        var callback = function (infoLookup) {
            if(infowin)
            map.removePopup(infowin);
            if(highlightFea)
            vectorLayer.removeFeatures(highlightFea);
            if (infoLookup) {
                var info;
                for (var idx in infoLookup) {
                    info = infoLookup[idx];
                    if (info && info.data) {
                        var dom = "<div style='padding: 5px;padding-left:5px;font-size:12px;font-family:Microsoft YaHei;line-height:8px;color: black;background:lightgoldenrodyellow'>" + info.data.name +"<br></br>"+"点击查看更多..."+ "</div>";
                         //设置x与y的像素偏移量,不影响地图浏览;
                        var xOff = (1 / map.getScale()) * 0.003;
                        var yOff = -(1 / map.getScale()) * 0.003;
                        var pos = new SuperMap.LonLat(new Number(info.data.X)+xOff,new Number(info.data.Y)+yOff);
                        infowin = new SuperMap.Popup("chicken",
                                pos,
                                new SuperMap.Size(0, 0),
                                dom,
                                false, null);
                        //根据弹窗内容自动调整弹窗大小
                        infowin.autoSize=true;
                        //设置默认样式不显示
                        infowin.setBackgroundColor("none");
                        map.addPopup(infowin);
                        highlightFea = new SuperMap.Feature.Vector(new SuperMap.Geometry.Point(info.data.X,info.data.Y),
                                null,
                                {

                                    //绘制矢量点方式
//                                    pointRadius:7,
//                                    fillColor:"#3399FF",
//                                    fillOpacity:0.5,
//                                    strokeColor:"#0033FF",
//                                    strokeWidth:3,
//                                    strokeOpacity:0.2
                                    //引用图片方式
                                    externalGraphic:"image/h12.png",
                                    graphicWidth:15,
                                    graphicHeight:15

                                }
                        );
                        vectorLayer.addFeatures([highlightFea]);
                    }
                }
            }
        };

弹窗展示:利用Control.UTFGrid监听click事件的方式,并结合Popup展示地物的信息,这里的Popup为自定义的CSS样式,因为Popup本身为div,可以任意设计CSS样式。实现效果如下:
这里写图片描述

 //点击弹窗回调函数
        var callback2=function(infoLookup1)
        {
            if(infowin1)
                map.removePopup(infowin1);
            if(popfeature)
                vectorLayer.removeFeatures(popfeature);
            if (infoLookup1) {
                if (infoLookup1) {
                    var info1;
                    for (var idx1 in infoLookup1) {
                        info1 = infoLookup1[idx1];
                        if (info1 && info1.data) {
                            var dom1 = "<div class='pop' >" +
                                    "<div class='pop_header'><div class='pop_close' 'closeInfoWin1()'></div></div>" +
                                    "<img src='image/park.png' style='height: auto;width: auto;max-width: 100%;opacity: 1'>" +
                                    "<div class='pop_content'><p><span>地点:</span><span>" + info1.data.name + "</span></p><p><span>坐标:</span><span>x:" + info1.data.X + "  y:" + info1.data.Y + "</span></p></div>" +
                                    "<div class='pop_arrow'></div>" +
                                    "</div>";
                            var xOff1 = -(1 / map.getScale()) * 0.018;
                            var yOff1 = (1 / map.getScale()) * 0.035;
                            var pos1 = new SuperMap.LonLat(new Number(info1.data.X) + xOff1, new Number(info1.data.Y) + yOff1);
                            infowin1 = new SuperMap.Popup("chicken",
                                    pos1,
                                    new SuperMap.Size(20, 20),
                                    dom1,
                                    false, null);
                            //根据弹窗内容自动调整弹窗大小
                            infowin1.autoSize = true;
                            //设置默认样式不显示
                            infowin1.backgroundColor = "none";
                            //移动地图以确保弹窗显示在窗口内
                            infowin1.panMapIfOutOfView=true;
                            map.addPopup(infowin1);
                            popfeature = new SuperMap.Feature.Vector(new SuperMap.Geometry.Point(info1.data.X, info1.data.Y),
                                    null,
                                    {
                                        externalGraphic: "image/radar.gif",
                                        graphicWidth: 64,
                                        graphicHeight: 64
                                    }
                            );
                            vectorLayer.addFeatures([popfeature]);
                        }
                    }
                }
            }
        };

源码地址http://download.csdn.net/detail/supermapsupport/9503675

转载自:https://blog.csdn.net/supermapsupport/article/details/51249866

You may also like...