客户端专题图


除了向服务器端发送请求制作专题图,在线地图尤其互联网地图更常用的方式是直接在GIS客户端制作专题图。借助前端技术的快速发展,客户端专题图相对具有更加美观的展示效果。不过,客户端的专题图基于Canvas实现,如果浏览器不支持Canvas,那就不能正常展示出来。

如果您需要使用您自己的数据制作客户端专题图,如果数据量较大,可以先把数据发布成SuperMap REST数据服务,然后通过本例的方式来制作专题图。如果数据量不大,则可以使用GeoJSON格式来存储数据,然后使用GeoJSON格式的数据来制作专题图。

Step1 初始化地图

本例将对Jingjin数据中的BaseMap_R数据集制作专题图,并不依赖地图服务,但是会以“京津地区地图”为底图叠加客户端专题图,因此需要使用地图和数据两个REST服务。

    var map, layer, themeLayer,
        url1 = "http://www.supermapol.com/iserver/services/map_City5/rest/maps/京津地区地图",
        url2 = "http://www.supermapol.com/iserver/services/data_City2/rest/data";
    var value="IbooSg6gIBmhIRaesVgjSED0",
        name = "ak";
    SuperMap.Credential.CREDENTIAL = new SuperMap.Credential(value, "ak");

    function init(){
        // 检测是否支持 Canvas
        if(!document.createElement('canvas').getContext){
            alert("您的浏览器不支持 Canvas,请升级!");
            return;
        }

        map = new SuperMap.Map("map",{controls: [
            new SuperMap.Control.LayerSwitcher(),
            new SuperMap.Control.ScaleLine(),
            new SuperMap.Control.Zoom(),
            new SuperMap.Control.Navigation({
                dragPanOptions: {
                    enableKinetic: true
                }
            })]
        });
        layer = new SuperMap.Layer.TiledDynamicRESTLayer("Jingjin", url1, {transparent: true, cacheEnabled: true}, {maxResolution:"auto"});
        layer.events.on({"layerInitialized":addLayer});

Step2 初始化分段专题图层

        // 定义 Range 分段专题图层
        themeLayer = new SuperMap.Layer.Range("ThemeLayer");
        themeLayer.setOpacity(0.8);

Step3 定义分段值和样式

除了定义颜色、阴影等基础样式外,客户端专题图还可以使用Canvas特效,如设置鼠标滑过的hover高亮效果、点击查询等。

        // 图层基础样式
        themeLayer.style = {
            shadowBlur: 16,
            shadowColor: "#000000",
            fillColor: "#FFFFFF"
        };

        // 开启 hover 高亮效果
        themeLayer.isHoverAble = true;
        // hover高亮样式
        themeLayer.highlightStyle = {
            stroke: true,
            strokeWidth: 4,
            strokeColor: 'blue',
            fillColor: "#00EEEE",
            //shadowBlur: 6,
            //shadowColor: "#000000",
            //shadowOffsetX: 6,
            //shadowOffsetY: 6,
            fillOpacity: 0.8
        };

        // 用于范围分段的属性字段名称
        themeLayer.themeField = "POP_DENSITY99";
        // 风格数组,设定分段范围对应的样式,分段范围不是直接对字段值分段,而是采用归一化处理,本例为0到0.2。
        themeLayer.styleGroups=[
            {
                start: 0,
                end: 0.02,
                style:{
                    color: '#FDE2CA'
                }
            },
            {
                start: 0.02,
                end: 0.04,
                style:{
                    color: '#FACE9C'
                }
            },
            {
                start: 0.04,
                end: 0.06,
                style:{
                    color: '#F09C42'
                }
            },
            {
                start: 0.06,
                end: 0.1,
                style:{
                    color: '#D0770B'
                }
            },
            {
                start: 0.1,
                end: 0.2,
                style:{
                    color: '#945305'
                }
            }
        ]

        // 注册 mousemove 事件
        themeLayer.on("mousemove", evn);
    }

Step4 制作客户端专题图

使用上一步定义的分段和样式,对Jingjin数据源中BaseMap_R数据集的POP_DENSITY99字段,制作分段专题图。客户端专题图的制作与服务器专题图不同,并不是对图层做专题图,而是通过数据查询(SQL)得到矢量要素数据(Feature),然后对要素按POP_DENSITY99字段分段,制作专题图themeLayer。

    //获取 feature 数据, 专题图的数据必须是 SuperMap.Feature.Vector
    function addThemeLayer() {
        clearLayer();
        var getFeatureParam, getFeatureBySQLService, getFeatureBySQLParams;
        getFeatureParam = new SuperMap.REST.FilterParameter({
            name: "Jingjin",
            attributeFilter: "SMID > -1"
        });
        getFeatureBySQLParams = new SuperMap.REST.GetFeaturesBySQLParameters({
            queryParameter: getFeatureParam,
            toIndex: 500,
            datasetNames:["Jingjin:BaseMap_R"]
        });
        getFeatureBySQLService = new SuperMap.REST.GetFeaturesBySQLService(url2, {
            eventListeners: {"processCompleted": processCompleted, "processFailed": processFailed}});

        getFeatureBySQLService.processAsync(getFeatureBySQLParams);
    }
    function processCompleted(getFeaturesEventArgs) {
        var result = getFeaturesEventArgs.result;
        if (result && result.features) {
            themeLayer.addFeatures(result.features);
        }

        //显示图例
        document.getElementById("mapLegend").style.display = "block";
    }

Step5 把专题图添加到地图上

通过addLayer(),把底图“京津地区地图”和专题图添加到地图容器。

    function addLayer() {
        map.addLayers([layer, themeLayer]);
        map.setCenter(new SuperMap.LonLat(117.2, 40.11), 0);
    }

Step6 添加鼠标交互时的信息框

除了hover交互效果,本例还支持鼠标点击时要素信息展示,通过evn即可实现。鼠标点击某个要素时,可获取到该要素的id:fid = e.target.refDataID,然后根据这个id(SMID)在themeLayer中查询该要素的信息(NAME、POP_DENSITY99)。

    //事件处理,控制信息框数据显示
    function evn(e){
        if(e.target && e.target.refDataID){
            document.getElementById("infoBox").style.display = "block";
            var fid = e.target.refDataID;
            var fea = themeLayer.getFeatureById(fid);
            if(fea){
                document.getElementById("infoContent").innerHTML = "";
                document.getElementById("infoContent").innerHTML += "ID: " + fea.attributes.SMID + "<br/>";
                document.getElementById("infoContent").innerHTML += "行政区名:" + fea.attributes.NAME + "<br/>";
                document.getElementById("infoContent").innerHTML += "人口密度:" + parseFloat(fea.attributes.POP_DENSITY99).toFixed(5) + "<br/>";
            }
        }
        else{
            document.getElementById("infoContent").innerHTML = "";
            document.getElementById("infoBox").style.display = "none";
        }
    }

在线演示与源码编辑

您可以在线访问完整代码、体验演示效果,也可以直接在线编辑源码并实时查看效果。