使用SuperMap Online的实时AQI数据服务


SuperMap Online提供了在线的AQI(Air Quality Index)实时数据,该数据通过REST接口提供。您可以在SuperMap Online 数据栏目 查看并在线浏览数据。 数据包含全国主要城市AQI(Air Quality Index)实时数据,由世界空气质量指数队(http://aqicn.org )提供。AQI实时数据覆盖了来自70多个国家、600多个城市的9000多个站点。

该数据通过REST接口提供,请求方式如:

http://www.supermapol.com/iserver/services/aqi/restjsr/aqi/pm2_5.rjson?bounds=116.2705,39.8050,116.6089,40.0898

返回的单个站点的具体信息包括:

  {
    "aqi": 139,
    "area": null,
    "city": "北京昌平定陵",
    "lat": 40.292,
    "location": {
      "x": 1.44027730609418E12,
      "y": 5.9613540198970206E7
    },
    "lon": 116.22,
    "pol": "北京昌平定陵",
    "positionName": "北京昌平定陵",
    "primaryPollutant": "pm25",
    "quality": null,
    "stationCode": null,
    "time": 1484208000000
  }

本例将带您一起探索:如何使用上述实时AQI数据服务,在线开发Web应用。

Step1 初始化地图

本例将使用SuperMap Online发布的实时AQI数据服务:http://www.supermapol.com/iserver/services/aqi/restjsr/aqi/pm2_5.rjson

//初始化地图窗口,AQI服务地址
var mapDivId = "map", airQualityServiceUrl = "http://www.supermapol.com/iserver/services/aqi/restjsr/aqi/pm25.json",

    //根据空气质量指数,定义分段显示的样式
    aqiLabelStrategy = {
        //设置标签的样式
        style : {
            fontColor:"white",
            fontSize:"14px",
            fontWeight:"lighter",
            fill: true,
            fillColor: "#FFFFFF",
            fillOpacity: 0.8,
            stroke: false
        },
        //用于标签分组的属性字段名称
        groupField : "aqi",
        //标签分组数组,根据每个城市的空气指数来设置分段。
        styleGroups : [
            {
                start:0,
                end:51,
                style:{
                    fontColor:"white",
                    fontWeight:"lighter",
                    fillColor:"#009966",
                    fontSize:"20px"
                }
            }, {
                start:51,
                end:101,
                style:{
                    fontColor:"#000",
                    fontWeight:"lighter",
                    fillColor:"#ffde33",
                    fontSize:"21px"
                }
            }, {
                start:101,
                end:151,
                style:{
                    fontColor:"#000",
                    fontWeight:"lighter",
                    fillColor:"#ff9933",
                    fontSize:"22px"
                }
            }, {
                start:151,
                end:201,
                style:{
                    fontColor:"white",
                    fontWeight:"lighter",
                    fillColor:"#FF0000",
                    fontSize:"23px"
                }
            }, {
                start:201,
                end:301,
                style:{
                    fontColor:"white",
                    fontWeight:"lighter",
                    fillColor:"#CC0000",
                    fontSize:"24px"
                }
            }, {
                start:301,
                end:601,
                style:{
                    fontColor:"white",
                    fontWeight:"lighter",
                    fillColor:"#7e0023",
                    fontSize:"26px"
                }
            }
        ]
    };

//初始化地图  
var map, layer, vectorLayer, selectFeature, popup, strategy, $popupContent;
function init(mapDivId){
    map = new SuperMap.Map(mapDivId,{controls: [
        new SuperMap.Control.ScaleLine(),
        new SuperMap.Control.Zoom(),
        new SuperMap.Control.Navigation({
            dragPanOptions: {
                enableKinetic: true
            }
        })]
    });
    //新建一个超图云图层作为Demo的底图
    layer = new SuperMap.Layer.CloudLayer();
    //新建一个标签专题图层,定义策略,用于显示AQI数据
    strategy = new SuperMap.Strategy.GeoText();
    //关闭自动避让,让所有的标签都显示出来
    strategy.isOverLay=false;
    vectorLayer = new SuperMap.Layer.Vector("Label",{strategies: [strategy]});
    $.extend(strategy, aqiLabelStrategy);       
}

Step2 使用REST API调用SuperMap Online的AQI数据服务,根据地图范围获取具体的AQI数值,然后把该值写入标签专题图

//请求AQI数据
function queryAQIData(url, success) {
    $.ajax({
        url: url,
        type: "GET",
        dataType: "JSON",
        data: null,
        success: success
    });
}
// 根据地图范围查询pm2.5数据
function addAQIByExtent() {
    var url, point1,point2, mapExtent = map.getExtent();
    //把地图范围由3857坐标系转为4326下的经纬度并赋值给bounds
    point1 =new SuperMap.LonLat(mapExtent.left, mapExtent.bottom);
    point2 = new SuperMap.LonLat(mapExtent.right,mapExtent.top);
    var transpoint1=point1.transform("EPSG:3857", "EPSG:4326");
    var transpoint2=point2.transform("EPSG:3857", "EPSG:4326");                    
    var bounds = transpoint1.lon + "," + transpoint1.lat + "," + transpoint2.lon + "," + transpoint2.lat;
    //把响应结果中的位置坐标,由4326坐标系转换为910111(兼容底图中高德地图的WebMercator)
    url = airQualityServiceUrl + "?bounds=" + bounds + "&to=910111";
    queryAQIData(url, addLabel);
}

//添加AQI标签
function addLabel(airQualitySet) {
    clearLabels();
    var airQualityList = airQualitySet.airQualityList;            
    var labelFeas=[];
    for(var i = 0; i < airQualityList.length; i++){
        var location = airQualityList[i].location;
        var aqi = airQualityList[i].aqi;
        if(!location || aqi > 600 || aqi < 0) {
            continue;
        }
        var label = new SuperMap.Geometry.GeoText(parseFloat(location.x), parseFloat(location.y), aqi);
        labelFeas.push(new SuperMap.Feature.Vector(label, airQualityList[i]));
    }
    vectorLayer.addFeatures(labelFeas);
}
//清除标签专题图层
function clearLabels() {
    closeInfoWin();
    vectorLayer.removeAllFeatures();
}

Step3 添加鼠标交互弹窗,显示时间、监测站点等详细信息


//构建一个popup提示框modle
function getAqiModle(feature) {
    var formatDate = function(date) {
        var d = new Date(date),
            month = '' + (d.getMonth() + 1),
            day = '' + d.getDate(),
            year = d.getFullYear(),
            time = d.toLocaleTimeString();

        return [year, month, day].join('-') + " " + time;
    }
    return {
        aqi: feature.attributes.aqi,
        quality: feature.attributes.quality,
        time: formatDate(new Date(feature.attributes.time)),
        area: feature.attributes.positionName
    };
}
//打弹窗,显示具体信息
function openInfoWin(feature){
    closeInfoWin();
    var popupContent = new Vue({
      el: "#popupContent",
      data: getAqiModle(feature)
    });
    //新建一个弹窗并加入地图
    var location = feature.attributes.location;
    var xy = map.getPixelFromLonLat(new SuperMap.LonLat(parseFloat(location.x), parseFloat(location.y)));
    xy.x += 10;
    var postion = map.getLonLatFromPixel(new SuperMap.Pixel(xy.x, xy.y));
    //新建popup
    popup = new SuperMap.Popup("popwin", new SuperMap.LonLat(postion.lon, postion.lat), new SuperMap.Size(210,110),
            $("#popupContent").html(), null, true, function() {
        closeInfoWin();
    });
    map.addPopup(popup);
    //设置div的背景颜色
    var groups = strategy.styleGroups, 
        featureAqi = feature.attributes.aqi;
    for(var i = 0; i < groups.length; i++){
        if(featureAqi >= groups[i].start && featureAqi < groups[i].end){
            var clolor = groups[i].style.fillColor;
            popup.setBorder("3px solid" + clolor);
            $("#contentID").css("backgroundColor", clolor);
            $("#textID").css("color", clolor);
            break;
        }
    }
}
//关闭弹窗
function closeInfoWin() {
    if (popup) {
        try {
            map.removePopup(popup);
            $("#popupContent").html($popupContent.html());
        } catch (e) {}
    }
}

Step4 把底图与AQI图层添加到地图上

// 添加图层
function addLayer() {
    map.addLayers([layer, vectorLayer]);
    map.setCenter(new SuperMap.LonLat(1.158508989250445E7,4120324.384351004),4);

    //兼容PC与移动端
    var broz = SuperMap.Util.getBrowser();
    var callbacks={};
    if (broz.device === 'android'|| broz.device === 'apple' ) {
        callbacks = {
            click: openInfoWin,
            clickout:  closeInfoWin
        };
    } else {
        callbacks = {
            over: openInfoWin,
            out:  closeInfoWin
        };
    }
    //实例化 selectFeature 控件
    selectFeature = new SuperMap.Control.SelectFeature(vectorLayer,{callbacks:callbacks,hover:false});
    map.addControl(selectFeature);
    selectFeature.activate();
}
…
show();

Step5 在HTMl页面中,分别创建地图窗口和弹出框的窗口(默认关闭):

    <!--地图显示的div-->
    <div id="map" style="position: relative; width: 100%; height: 900px"></div>>
    <div id="popupContent" class="hide">
        <table style="margin-left: 5px;">
            <tbody>
                <tr>
                    <td>
                        <div id="contentID" class="content-aqi">AQI: {{ aqi }}</div> 
                    </td>                                
                </tr>
                <tr> 
                    <td>
                        <div class="content-time">时间:{{ time }}</div>
                    </td>
                </tr>
                <tr>    
                    <td>
                        <div class="content-area">监测点:{{ area }}</div>
                    </td>                                            
                </tr> 
            </tbody>
        </table>
    </div>

在线演示与源码编辑

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