客户端专题图
除了向服务器端发送请求制作专题图,在线地图尤其互联网地图更常用的方式是直接在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";
}
}
在线演示与源码编辑
您可以在线访问完整代码、体验演示效果,也可以直接在线编辑源码并实时查看效果。