OL2中测量工具的扩展

概述:

本文共享一个扩展后的测量工具,实现绘制时测量结果的实时展示。


效果:

OL2中测量工具的扩展

测距

OL2中测量工具的扩展

测面

实现:

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%;
            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;
			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 >
	<div style="position: absolute;top: 10px;right: 10px;z-index: 999;">
        <button >距离</button>
        <button >面积</button>
    </div>
</div>
</body>
</html>

---------------------------------------------------------------------------------------------------------------

技术博客

http://blog.csdn.NET/gisshixisheng

在线教程

http://edu.csdn.Net/course/detail/799
Github

https://github.com/lzugis/

联系方式

q       q:1004740957

e-mail:niujp08@qq.com

公众号:lzugis15

Q Q 群:452117357(webgis)
             337469080(Android)

OL2中测量工具的扩展