作者:非法小恋
老规矩,先上效果截图:(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中就能看到最终的量算结果了。下面我们将进行优化,让结果显示的更直观。
新建一个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);
}
}
当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);
}
这里也新建了一个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);
大家在绘制完成时,一般会在绘制结果旁增加一个关闭按钮,用于删除量算结果。
初始化时添加保存按钮的图层控件:
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();
}
还没完,现在量算结果只是单独的数字,不知道最终的数字代表什么,下来我们就来添加单位。
量算过程和结果中,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