概述:
本文共享一个扩展后的测量工具,实现绘制时测量结果的实时展示。
效果:
测距
测面
实现:
1、扩展MeasureControl
/**
* Class: OpenLayers.Control.MeasureDistance
*
* 地图距离量算控件
*
*
* 继承自:
* - <OpenLayers.Control.Measure>
*/
/**
* @requires OpenLayers/Control/Measure.js
*/
OpenLayers.Control.MeasureDistance = OpenLayers.Class(OpenLayers.Control.Measure, {
/**
* Property: type
* {String} 工具类型
*/
type: OpenLayers.Control.TYPE_TOOL,
/**
* Property: outputDiv
* {String} 量算结果输出DIV
*/
outputDiv: null,
/**
* Property: correctParam
* 纠正系数
*/
correctParam: 1,
/**
* Property: clicks
* {Integer} 鼠标点击次数
*/
clicks: null,
/**
* Property: title
* {String} 工具按钮提示文字
*/
title: "距离量算",
/**
* Constructor: OpenLayers.Control.MeasureDistance
* 初始化函数
*
* Parameters:
* handler - {<OpenLayers.Handler>}
* options - {Object}
*/
initialize: function(options) {
OpenLayers.Util.extend(this, options);
var style = new OpenLayers.Style();
style.addRules([
new OpenLayers.Rule({symbolizer: measureSymbolizers})]);
var styleMap = new OpenLayers.StyleMap({"default": style});
test={layerOptions:{stypeMap:styleMap}};
newArguments = [OpenLayers.Handler.Path, {
persist: true,
handlerOptions: {
layerOptions: {styleMap: styleMap}
}
}];
OpenLayers.Control.Measure.prototype.initialize.apply(this,newArguments);
this.events.on({
measure: this.handleMeasurements,
measurepartial: this.handlePartialMeasurements
});
var modifyFeature = this.handler.modifyFeature;
var scope = this;
this.handler.modifyFeature = function(pixel, drawing){
modifyFeature.apply(scope.handler, arguments);
};
this.clicks = 0;
},
/**
* Method: activate
* 控件被触发时设置鼠标手势
*/
activate: function(){
if(this.map.labelLayer){
this.map.labelLayer.clear();
}
else{
this.map.labelLayer = new OpenLayers.Layer.Labels("mesurelabel", "mesurelabelLayer");
this.map.addLayer(this.map.labelLayer);
}
if(this.map.vectorLayer){
this.map.vectorLayer.removeAllFeatures();
}
else{
this.map.vectorLayer = new OpenLayers.Layer.Vector("Vector Layer");
this.map.addLayer(this.map.vectorLayer);
}
OpenLayers.Control.Measure.prototype.activate.apply(this, arguments);
},
/**
* Method: activate
* 控件被触发时设置鼠标手势
*/
deactivate: function(){
OpenLayers.Control.Measure.prototype.deactivate.apply(this, arguments);
if(this.map.labelLayer){
this.map.labelLayer.clear();
this.map.vectorLayer.removeAllFeatures();
}
},
/**
* Method: handleMeasurements
* 量算结束
*/
handleMeasurements:function(event) {
var geometry = event.geometry;
var units = event.units;
var order = event.order;
var measure = event.measure;
var out = "";
var point="";
this.handler.deactivate();
var features = [new OpenLayers.Feature.Vector(
geometry,{}
)];
this.map.vectorLayer.style = measureSymbolizers.Polygon;
this.map.vectorLayer.addFeatures(features);
if(order == 1) {
var length=geometry.components.length;
point =geometry.components[length-1];
}
else {
out += "" + measure.toFixed(3)*this.correctParam + " " + units + "<sup>2</" + "sup>";
var length=geometry.components[0].components.length;
point =geometry.components[0].components[length-2];
this.map.labelLayer.setZIndex(this.map.Z_INDEX_BASE["Control"]);
var labelDiv = new OpenLayers.Label(new OpenLayers.LonLat(point.x,point.y),out, "MeasureLable");
this.map.labelLayer.add(labelDiv);
}
$(this.map.labelLayer.div).css("z-index","999");
var closeDiv = new OpenLayers.Label(new OpenLayers.LonLat(point.x,point.y),"×", "MeasureClose");
this.map.labelLayer.add(closeDiv);
var scope = this;
$(closeDiv.labelDiv).attr("title","关闭");
$(closeDiv.labelDiv).on("click",function(e){
scope.deactivate();
});
},
/**
* Method: measurePartial
* Called each time a new point is added to the measurement sketch.
*
* Parameters:
* point - {<OpenLayers.Geometry.Point>} The last point added.
* geometry - {<OpenLayers.Geometry>} The sketch geometry.
*/
measurePartial: function(point, geometry) {
if (geometry.getLength() > 0) {
geometry = geometry.clone();
if(geometry.CLASS_NAME==="OpenLayers.Geometry.LineString"){
var length = geometry.getGeodesicLength(this.map.getProjectionObject());
var out = (length/1000).toFixed(3)*this.correctParam+"km";
var labelDiv = new OpenLayers.Label(new OpenLayers.LonLat(point.x,point.y),out, "MeasureLable");
this.map.labelLayer.add(labelDiv);
}
this.delayedTrigger = window.setTimeout(
OpenLayers.Function.bind(function() {
this.measure(geometry, "measurepartial");
}, this),
this.partialDelay
);
}
else{
this.map.labelLayer.clear();
this.map.vectorLayer.removeAllFeatures();
if(geometry.CLASS_NAME==="OpenLayers.Geometry.LineString"){
var out = "起点";
var labelDiv = new OpenLayers.Label(new OpenLayers.LonLat(point.x,point.y),out, "MeasureLable");
this.map.labelLayer.add(labelDiv);
}
}
},
CLASS_NAME: "OpenLayers.Control.MeasureDistance"
});
/**
* Class: OpenLayers.Control.MeasureArea
*
* 地图面积量算控件
*
*
* 继承自:
* - <OpenLayers.Control.MeasureDistance>
*/
OpenLayers.Control.MeasureArea = OpenLayers.Class(OpenLayers.Control.MeasureDistance, {
/**
* Property: title
* {String} 工具按钮提示文字
*/
title: "面积量算",
/**
* Constructor: OpenLayers.Control.MeasureDistance
*
* Parameters:
* handler - {<OpenLayers.Handler>}
* options - {Object}
*/
initialize: function(options) {
var style = new OpenLayers.Style();
style.addRules([
new OpenLayers.Rule({symbolizer: measureSymbolizers})]);
var styleMap = new OpenLayers.StyleMap({"default": style});
test={layerOptions:{stypeMap:styleMap}};
newArguments = [OpenLayers.Handler.Polygon, {
persist: true,
handlerOptions: {
layerOptions: {styleMap: styleMap}
}
}];
OpenLayers.Control.Measure.prototype.initialize.apply(this,newArguments);
this.events.on({
measure: this.handleMeasurements,
measurepartial: this.handlePartialMeasurements
});
var modifyFeature = this.handler.modifyFeature;
var scope = this;
this.handler.modifyFeature = function(pixel, drawing){
modifyFeature.apply(scope.handler, arguments);
}
this.clicks = 0;
},
/**
* Method: activate
* 控件被触发时设置鼠标手势
*/
activate: function(){
if(this.map.labelLayer){
this.map.labelLayer.clear();
}
else{
this.map.labelLayer = new OpenLayers.Layer.Labels("mesurelabel", "mesurelabelLayer");
this.map.addLayer(this.map.labelLayer);
}
if(this.map.vectorLayer){
this.map.vectorLayer.removeAllFeatures();
}
else{
this.map.vectorLayer = new OpenLayers.Layer.Vector("Vector Layer");
this.map.addLayer(this.map.vectorLayer);
}
OpenLayers.Control.Measure.prototype.activate.apply(this, arguments);
},
CLASS_NAME: "OpenLayers.Control.MeasureArea"
});
//style the sketch fancy
var measureSymbolizers = {
"Point": {
pointRadius: 3,
graphicName: "circle",
fillColor: "#8AC4F0",
fillOpacity: 1,
strokeWidth: 1,
strokeOpacity: 1,
strokeColor: "#FAD00B"
},
"Line": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#ee9900",
strokeDashstyle: "solid"
},
"Polygon": {
strokeWidth: 3,
strokeOpacity: 1,
strokeColor: "#ee9900",
fillColor: "#66cccc",
fillOpacity: 0.3
}
};
2、页面调用
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>openlayers map</title>
<link rel="stylesheet" href="../../../plugin/OpenLayers-2.13.1/theme/default/style.css" type="text/css">
<style>
html, body, #map{
padding:0;
margin:0;
height:100%;
width:100%;
overflow: hidden;
}
.MeasureLable{
background-color: #F8D699;
color:#000000;
border: solid 1px #1E90F5;
border-radius: 3px;
font-size: 12px;
padding: 2px 5px;
white-space:nowrap;
}
.MeasureClose{
margin-top:-18px;
cursor:pointer;
width:14px;
height:14px;
background:#ffffff;
border: solid 1px #1E90F5;
border-radius: 3px;
text-align: center;
line-height: 14px;
font-weight: bold;
padding-right: 1px;
}
</style>
<script src="../../../plugin/OpenLayers-2.13.1/OpenLayers.js"></script>
<script src="extend/MeasureControl.js"></script>
<script src="extend/LabelLayer.js"></script>
<script src="../../../plugin/jquery/jquery-1.8.3.js"></script>
<script>
var map;
var tiled;
$(window).load(function() {
var format = 'image/png';
var bounds = new OpenLayers.Bounds(
73.45100463562233, 18.16324718764174,
134.97679764650596, 53.531943152223576
);
var options = {
controls: [],
maxExtent: bounds,
maxResolution: 0.2403351289487642,
projection: "EPSG:4326",
units: 'degrees'
};
map = new OpenLayers.Map('map', options);
tiled = new OpenLayers.Layer.WMS(
"Geoserver layers - Tiled",
"http://localhost:8088/geoserver/lzugis/wms",
{
"LAYERS": 'province',
"STYLES": '',
format: format
},
{
buffer: 0,
displayOutsideMaxExtent: true,
isBaseLayer: true,
yx : {'EPSG:4326' : true}
}
);
map.addLayers([tiled]);
map.addControl(new OpenLayers.Control.Zoom());
map.addControl(new OpenLayers.Control.Navigation());
map.zoomToExtent(bounds);
var measuredist = new OpenLayers.Control.MeasureDistance();
var measurearea = new OpenLayers.Control.MeasureArea();
map.addControl(measuredist);
map.addControl(measurearea);
$("#measuredist").on("click",function(){
measurearea.deactivate();
measuredist.activate();
});
$("#measurearea").on("click",function(){
measuredist.deactivate();
measurearea.activate();
});
});
</script>
</head>
<body>
<div id="map">
<div style="position: absolute;top: 10px;right: 10px;z-index: 999;">
<button id="measuredist">距离</button>
<button id="measurearea">面积</button>
</div>
</div>
</body>
</html>