仿百度地图,使用iClient for JavaScript实现客户端量算

作者:非法小恋

老规矩,先上效果截图:(CSDN上传图片限制2M以下,GIF高清上传不了,唉 压缩后的如下)

要实现上图效果,主要分以下几个思路来实现:
1. 实现量算功能。
2. 优化显示结果。

一、实现量算功能

新建一个SuperMap.Control.Measure量算类,而该量算类中包含activate激活方法和deactivate注销方法。
然后在监听量算类中的measure 和 measurepartial 两个事件,
measure是完成时事件
measurepartial 是绘制过程中事件

具体代码如下:

var map = new SuperMap.Map("map"); 
//实例化 measureControls 控件,用于测量距离和面积 
measureControls = { 
     //距离量算 
     line:new SuperMap.Control.Measure( 
         SuperMap.Handler.Path, {persist:true} 
     )
 }; 
var control; 
//监听 measure 和 measurepartial 两个事件,量算完成时触发时 
//量算完成时触发 measure 事件,当点被添加到量算过程中时触发 measurepartial 
for(var key in measureControls){ 
    control = measureControls[key]; 
    control.events.on({ 
        "measure": handleMeasure, 
        "measurepartial": handleMeasurements 
    }); 
//添加控件到 map 上 
map.addControl(control); 
} 
//激活控件 
control.activate(); 

//定义 handleMeasurements 函数,触发 measure 事件会调用此函数 
//事件参数 event 包含了测量要素 geometry 信息 
function handleMeasure(event) { 
    //获取传入参数 event 的 geometry 信息 
    var geometry = event.geometry; 
    //TODO 具体操作方法用户可根据需要自行定义 
} 
//定义 handleMeasurements 函数,触发 measurepartial 事件会调用此函数 
//事件参数 event 包含了测量要素 geometry 信息 
function handleMeasurements(event) { 
    //获取传入参数 event 的 geometry 信息 
    var geometry = event.geometry; 
    //获取传入参数 event 的 type 信息(click指示的是点击事件,move指示的是移动事件) 
    var type=event.type; 
    //TODO 具体操作方法用户可根据需要自行定义 

其实这时候如果断点调试的话,就可以在handleMeasure中就能看到最终的量算结果了。下面我们将进行优化,让结果显示的更直观。

二、优化显示结果

1.优化量算过程中鼠标单击点样式

新建一个Vector图层,用来承载单击节点时,点的样式以及文字显示。

   vectorLayer = new SuperMap.Layer.Vector("点和文字");

PS:记得在map中添加该vectorLayer图层。

在handleMeasurements方法中,
当var type=event.type 为 click时,即为鼠标点击操作,且event.geometry.components.length == 2时为首次点击起点。

if(type == 'click') {
     //当==2时为起点
     if(event.geometry.components.length == 2) {
         var pointStart = new SuperMap.Geometry.Point(event.geometry.components[(event.geometry.components.length-1)].x,event.geometry.components[0].y);
         var f = new SuperMap.Feature.Vector;
         f.geometry = pointStart;
         f.style= {
             label:'起点',
             fontColor:'red',
             strokeColor: "red",
             strokeOpacity: 1,
             fillColor: "#ffffff",
             labelXOffset:20,
             labelYOffset:20,
             pointRadius: 4};
         vectorLayer.addFeatures(f);
     }else {
         //单机节点
         var pointStart = new SuperMap.Geometry.Point(event.geometry.components[(event.geometry.components.length-1)].x,event.geometry.components[(event.geometry.components.length-1)].y);
         var f = new SuperMap.Feature.Vector;
         f.geometry = pointStart;
         f.style= {
             label: + event.measure.toFixed(1),
             fontColor:'red',
             strokeColor: "red",
             strokeOpacity: 1,
             fillColor: "#ffffff",
             labelXOffset:20,
             labelYOffset:20,
             pointRadius: 4};
         vectorLayer.addFeatures(f);
     }
 }

2.优化量算过程中移动显示样式

当var type=event.type 为 move时,即为鼠标移动操作

if(type == 'click') {
    .............
}else {
   //临时显示点信息
    vectorLayerTmp.removeAllFeatures();
    var pointStart = new SuperMap.Geometry.Point(event.geometry.components[(event.geometry.components.length-1)].x,event.geometry.components[(event.geometry.components.length-1)].y);
    var f = new SuperMap.Feature.Vector;
    f.geometry = pointStart;
    f.style= {
        label: + event.measure.toFixed(1),
        fontColor:'red',
        strokeColor: "red",
        strokeOpacity: 1,
        fillColor: "#ffffff",
        labelXOffset:20,
        labelYOffset:20,
        pointRadius: 4};
    vectorLayerTmp.addFeatures(f);
  }

3.优化量结果显示样式样式

这里也新建了一个vectorLayerLine,是为了让线条显示的更清楚,既绘制完成后显示深色。
初始化添加:

 vectorLayerLine = new SuperMap.Layer.Vector("线");

更换颜色和添加文字

//获取当前坐标点
var pointStart = new SuperMap.Geometry.Point(event.geometry.components[(event.geometry.components.length-1)].x,event.geometry.components[(event.geometry.components.length-1)].y);

var f = new SuperMap.Feature.Vector;
f.geometry = pointStart;
 f.style= {label:"总长:" + event.measure.toFixed(1),
     fontColor:'red',
     strokeColor: "red",
     strokeOpacity: 1,
     fillColor: "#ffffff",
     labelXOffset:20,
     labelYOffset:20,
     pointRadius: 4};
//保存之前绘制的节点用于显示其他样式
var points = [];
for(var i = 0;i < event.geometry.components.length; i++) {
    points.push(new SuperMap.Geometry.Point(event.geometry.components[i].x, event.geometry.components[i].y));
}
var qu = new SuperMap.Geometry.LineString(points);
//保留线样式
var ff = new SuperMap.Feature.Vector;
ff.geometry = qu;
ff.style = {
    strokeColor: "#FC854D",
    strokeWidth: 2.5,
    pointerEvents: "visiblePainted",
    fillColor: "#FC854D",
    fillOpacity: 1};
vectorLayerLine.addFeatures(ff);
vectorLayer.addFeatures(f);

4.在显示结果旁边增加一个关闭按钮并添加事件

大家在绘制完成时,一般会在绘制结果旁增加一个关闭按钮,用于删除量算结果。

初始化时添加保存按钮的图层控件:

 vectorLayerX = new SuperMap.Layer.Vector("删除");
 //添加删除事件
 select = new SuperMap.Control.SelectFeature(vectorLayerX, {onSelect: onFeatureSelect});
 //激活删除事件
 map.addControl(select);
 //点击删除量算按钮
 function onFeatureSelect(feature) {
     vectorLayer.removeAllFeatures();
     vectorLayerLine.removeAllFeatures();
     vectorLayerX.removeAllFeatures();
     select.deactivate();
 }

并在结束绘制事件handleMeasure中添加上该按钮

  //最终双击结束
 function handleMeasure(event) {
     control.deactivate();
     vectorLayerTmp.removeAllFeatures();
     //获取当前坐标点
     var pointStart = new SuperMap.Geometry.Point(event.geometry.components[(event.geometry.components.length-1)].x,event.geometry.components[(event.geometry.components.length-1)].y);
     //克隆坐标点 用于显示关闭按钮
     var pointCopy = pointStart.clone();
     //删除按钮
     var fc = new SuperMap.Feature.Vector;
     fc.geometry = pointCopy;
     fc.style= {
         externalGraphic: "./Error.png",
         strokeColor: "red",
         graphicWidth:16,
         graphicHeight:16,
         strokeOpacity: 1,
         fillColor: "#ffffff",
         graphicXOffset:10,
         pointRadius: 4};

     vectorLayerX.addFeatures(fc);

     //激活选择要素的控件
     select.activate();
 }

5.优化量算单位显示

还没完,现在量算结果只是单独的数字,不知道最终的数字代表什么,下来我们就来添加单位。

量算过程和结果中,event中的units就能获取到量算单位,我们在根据单位,可以转换为具体的中文。
可以在handleMeasure和handleMeasurements中添加以下内容

//单位转换
var unitString = "";
if(event.units == "m") {
    unitString = "米";
}else if(event.units == "km") {
    unitString = "公里";
}else{
    unitString = "";
}

并在节点style的label中添加上该字符串,例如:

label: event.measure.toFixed(1)+unitString

这样我们就实现最开始时的效果了。

全部代码如下:
http://download.csdn.net/download/supermapsupport/9434525

你可能感兴趣的:(百度地图,supermap,iClient)