示例:火车动态监控模拟


Step1 准备数据和服务

本例中使用的数据和服务包括:

  • 底图:使用SuperMap Online发布的地图服务 map_China4003 中的矢量瓦片,便于定义颜色等风格
  • 用于绘制动态图层的点时空数据:SuperMap iServer示范服务中的 data-DynamicData中的Train@DynamicData点数据集,该点数据集中除了标识火车位置的坐标信息(空间)外,还包含时间等属性信息。

Step2 预定义矢量分块图的风格样式

为图层定义填充颜色等风格样式。

        /*此处定义不同的颜色变量,在后面可以重复用这些颜色值*/

        @waterColor:rgb(34,56,78);
        @roadColora:rgb(109,102,91);
        @roadColorb:rgb(109,102,91);
        @railwayColora:rgb(80,80,80);
        @railwayColorb:rgb(137,137,137);
        @vegetationColor:rgb(27,27,27);
        @continentColor:rgb(68,68,68);
        @provinceLineColor:rgb(180,0,0);


        #China_Railway_L___China400::a{

        /*每一段的长度为15px,间隔也是15px*/
        line-color:@railwayColora;
        line-width:2.5;
        }
        #China_Railway_L___China400::b{

        /*每一段的长度为15px,间隔也是15px*/
        line-dasharray:18,18;
        line-color:@railwayColorb;
        line-width:2;
        }
        /*底下的地图背景图层*/

        #World_Division___China400{
        polygon-fill:@waterColor;
        }

        /*中国除外的其他国家的图层*/

        #World_Continent___China400{
        polygon-fill:@continentColor;
        line-width:1;
        line-color:rgb(180,180,180);
        }

        #World_Division___China400{
        polygon-fill:@waterColor;
        }

Step3 初始化地图

初始化地图并添加基本控件,本例使用SuperMap Online发布的地图,并预定义深、浅两色样式风格用于渲染铁路。

    var map, layer, animatorVector, lineVector1, lineVector2, 
        url = "http://www.supermapol.com/iserver/services/map_China4003/rest/maps/China",
        url2 = "http://localhost:8090/iserver/services/data-DynamicData/rest/data";
    var value="IbooSg6gIBmhIRaesVgjSED0",
        name = "key";
    SuperMap.Credential.CREDENTIAL = new SuperMap.Credential(value, "key");

    var style1=
    {
        fillColor: "#ffff00",
        fillOpacity: 0.8,
        strokeOpacity: 0,
        pointRadius: 5
    };
    var style2=
    {
        fillColor: "#c165f6",
        fillOpacity: 1,
        strokeOpacity: 0,
        pointRadius: 5
    };
    function init() {
        if(!document.createElement('canvas').getContext) {
            alert('您的浏览器不支持 canvas,请升级');
            return;
        }
        //初始化地图
        map = new SuperMap.Map("map",{controls: [
            new SuperMap.Control.ScaleLine(),
            new SuperMap.Control.Zoom(),
            new SuperMap.Control.Navigation({
                dragPanOptions: {
                    enableKinetic: true
                }
            })],
            projection: "EPSG:3857"
        });


    }

Step4 初始化底图和动态图层

本例使用矢量分块图TiledVectorLayer来做底图,使用Step1中预定义的CartoCSS样式。

        //初始化图层
        var cartoCssStr=document.getElementById("cartocssStr");
        var cartoCss=cartoCssStr.text;
        var layerNames=["World_Division@China400","World_Continent@China400",
            "China_Province_R@China400","China_island_R@China400",
            "China_Provinces_L@China400","China_Capital_P@China400",
            "China_BeiJing@China400"].join(",");
        layerNames="["+layerNames+"]";
        layer = new SuperMap.Layer.TiledVectorLayer("China", url,{cacheEnabled:true,layerNames:layerNames},{useLocalStorage:true,cartoCss:cartoCss});
        layer.events.on({"layerInitialized": addLayer});

Step5 初始化火车线路、动态图层并添加到地图上

构建动态火车监控图层:

  • 初始化动画矢量图层Train,设置点的移动速度、起始、终止时间。
  • 初始化两个不同风格的矢量火车线路图层lineVector1、lineVector2,二者深浅色叠加可以获得常见的铁路样式。
  • 把上述图层添加到地图上。
    function addLayer() {
        //初始化动画矢量图层
        animatorVector = new SuperMap.Layer.AnimatorVector("Train", {rendererType:"TadpolePoint"},{
            //设置速度为每帧播放0.02小时的数据
            speed:0.02,
            //开始时间为0
            startTime:0,
            //结束时间设置为最后运行结束的火车结束时间
            endTime:39
        });
        lineVector1 = new SuperMap.Layer.Vector("Line1");
        lineVector2 = new SuperMap.Layer.Vector("Line2");
        map.addLayers([layer,lineVector1,lineVector2,animatorVector]);

        map.setCenter(new SuperMap.LonLat(12009634.286396, 4258716.5813769), 4);
        //增加数据
        addTrain();

    }

Step6 获取火车数据,构建火车线路并实现动态效果

首先,从数据服务data-DynamicData中的Train@DynamicData数据集中获取需要的几何要素点(火车位置)及其时间等属性信息。

    //添加火车数据,返回Train@DynamicData图层中的要素点(共2240个)
    function addTrain()
    {
        var getFeatureParam, getFeatureBySQLService, getFeatureBySQLParams;

        getFeatureParam = new SuperMap.REST.FilterParameter({
            name: "Train@DynamicData",
            attributeFilter: "SmID < 2240"
        });
        getFeatureBySQLParams = new SuperMap.REST.GetFeaturesBySQLParameters({
            queryParameter: getFeatureParam,
            datasetNames:["DynamicData:Train"]
        });
        //返回个数
        getFeatureBySQLParams.toIndex  = 2240;
        getFeatureBySQLService = new SuperMap.REST.GetFeaturesBySQLService(url2, {
            eventListeners: {"processCompleted": processCompleted, "processFailed": processFailed}});

        getFeatureBySQLService.processAsync(getFeatureBySQLParams);

    }

然后,根据返回的点要素:

  • 创建火车线路,并通过深、浅两种不同颜色样式的叠加,实现火车线路常见符号样式
  • 设置表示火车的点的样式, 火车显示使用两种点样式以区分短途车和长途车
    //根据返回的点要素,构建火车线路并设置样式,设置表示火车的点的样式
    function processCompleted(getFeaturesEventArgs){
        var features,result = getFeaturesEventArgs.result;
        if (result && result.features) {
            features = result.features;
        }
        console.log(features);

        //使用数据
        var pointFeatures = [];
        var lines1 = [];
        var lines2 = [];
        var points = [];
        var id = 0;
        for(var i = 0,len = features.length;i<len;i++)
        {
            var point = features[i].geometry;
            var po = features[i].geometry;
            //创建火车线路,并实现火车线路符号样式
            if(id == features[i].data.FEATUREID)
            {
                points.push(po);
            }
            else
            {
                id = features[i].data.FEATUREID;
                lines1.push(
                        new SuperMap.Feature.Vector(
                                new SuperMap.Geometry.LineString(points),
                                {},
                                {
                                    stroke:true,
                                    strokeColor:"#dddddd",
                                    strokeWidth:3,
                                    strokeDashstyle:"solid"

                                }
                        )
                );
                lines2.push(
                        new SuperMap.Feature.Vector(
                                new SuperMap.Geometry.LineString(points),
                                {},
                                {
                                    stroke:true,
                                    strokeColor:"#41403f",
                                    strokeWidth:2,
                                    strokeDashstyle:"dash"
                                }
                        )
                );

                points = [];
            }

                //火车显示使用两种点样式以区分短途车和长途车
                if(features[i].data.FEATUREID <151)
                {
                    var pointFeature = new SuperMap.Feature.Vector(point,{
                        FEATUREID:features[i].data.FEATUREID,
                        TIME:features[i].data.TIME
                    },style1);
                }
                else
                {
                    var pointFeature = new SuperMap.Feature.Vector(point,{
                        FEATUREID:features[i].data.FEATUREID,
                        TIME:features[i].data.TIME
                    },style2);
                }

                pointFeatures.push(pointFeature);
        }
        animatorVector.addFeatures(pointFeatures);
        lineVector1.addFeatures(lines1);
        lineVector2.addFeatures(lines2);

    }

Step7 实现启动、暂停等播放控制

animatorVector提供了一些列的播放控制方法,如开始、暂停、停止,以及正/反方向的切换、加速、开/关闪烁等。

    function processFailed(e){
        alert(e.error.errorMsg);
    }
    //开始播放动画
    function startAnimator(){
        animatorVector.animator.start();
    }
    //暂停播放动画
    function pauseAnimator(){
        animatorVector.animator.pause();
    }
    //停止播放动画
    function stopAnimator(){
        animatorVector.animator.stop();
    }
    //减速播放
    function decreaseSpeed(){
        animatorVector.animator.setSpeed(animatorVector.animator.getSpeed()*0.7);
    }

    //正反向播放切换
    function setReverseAnimator(){
        animatorVector.animator.setReverse(!animatorVector.animator.getReverse());
    }
    //加速播放
    function increaseSpeed(){
        animatorVector.animator.setSpeed(animatorVector.animator.getSpeed()*1.5);
    }
    //开关闪烁
    function setGlint(){
        animatorVector.renderer.glint = !animatorVector.renderer.glint;
    }
    //开关尾巴
    function setTailr(){
        animatorVector.renderer.tail = !animatorVector.renderer.tail;
    }
    function show(){
        lineVector1.setVisibility(!lineVector1.getVisibility());
        lineVector2.setVisibility(!lineVector2.getVisibility());
    }

在线演示与源码编辑

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