Ticket #1241: measure.patch
| File measure.patch, 15.8 kB (added by tschaub, 1 month ago) |
|---|
-
lib/OpenLayers/Control/Measure.js
old new 1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD 2 * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the 3 * full text of the license. */ 4 5 /** 6 * @requires OpenLayers/Control.js 7 * @requires OpenLayers/Feature/Vector.js 8 */ 9 10 /** 11 * Class: OpenLayers.Control.Measure 12 * Allows for drawing of features for measurements. 13 * 14 * Inherits from: 15 * - <OpenLayers.Control> 16 */ 17 OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, { 18 19 /** 20 * APIProperty: handlerOptions 21 * {Object} Used to set non-default properties on the control's handler 22 */ 23 handlerOptions: null, 24 25 /** 26 * APIProperty: onMeasure 27 * {Function} After a geometry is drawn, onMeasure is called with three 28 * arguments: the geometry, its length, and its area. 29 */ 30 onMeasure: function() {}, 31 32 /** 33 * Property: callbacks 34 * {Object} The functions that are sent to the handler for callback 35 */ 36 callbacks: null, 37 38 /** 39 * Property: displayUnits 40 * {String} Units for output. Must be one of 'in', 'ft', 'mi', 'm', 'km', 41 * or 'dd'. If null, displayUnits will be assumed to be the same as 42 * map units. 43 */ 44 displayUnits: null, 45 46 /** 47 * Constructor: OpenLayers.Control.Measure 48 * 49 * Parameters: 50 * handler - {<OpenLayers.Handler>} 51 * options - {Object} 52 */ 53 initialize: function(handler, options) { 54 OpenLayers.Control.prototype.initialize.apply(this, [options]); 55 this.callbacks = OpenLayers.Util.extend( 56 {done: this.measureGeometry, point: this.partialMeasure}, 57 this.callbacks 58 ); 59 this.handler = new handler(this, this.callbacks, this.handlerOptions); 60 }, 61 62 /** 63 * Method: measureGeometry 64 */ 65 measureGeometry: function(geometry) { 66 var area = this.getArea(geometry); 67 var length = this.getLength(geometry); 68 this.onMeasure(geometry, length, area, this.displayUnits); 69 }, 70 71 /** 72 * Method: getArea 73 */ 74 getArea: function(geometry) { 75 var area = geometry.getArea(); 76 var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[this.displayUnits]; 77 if(inPerDisplayUnit) { 78 var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.units]; 79 area *= Math.pow((inPerMapUnit / inPerDisplayUnit), 2); 80 } 81 return area; 82 }, 83 84 /** 85 * Method: getLength 86 */ 87 getLength: function(geometry) { 88 var length = geometry.getLength(); 89 var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[this.displayUnits]; 90 if(inPerDisplayUnit) { 91 var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.units]; 92 length *= (inPerMapUnit / inPerDisplayUnit); 93 } 94 return length; 95 }, 96 97 CLASS_NAME: "OpenLayers.Control.Measure" 98 }); -
lib/OpenLayers/Handler/Polygon.js
old new 59 59 this.polygon.geometry.addComponent(this.line.geometry); 60 60 this.point = new OpenLayers.Feature.Vector( 61 61 new OpenLayers.Geometry.Point()); 62 this.layer.addFeatures([this.polygon, this.point]); 62 63 }, 63 64 64 65 /** … … 67 68 */ 68 69 destroyFeature: function() { 69 70 OpenLayers.Handler.Path.prototype.destroyFeature.apply(this); 70 if(this.polygon) {71 this.polygon.destroy();72 }73 71 this.polygon = null; 74 72 }, 75 73 … … 102 100 * {<OpenLayers.Geometry.Polygon>} 103 101 */ 104 102 geometryClone: function() { 105 return this.polygon.geometry.clone(); 103 var geometry = this.polygon.geometry.clone(); 104 if(this.multi) { 105 geometry = new OpenLayers.Geometry.MultiPolygon([geometry]); 106 } 107 return geometry; 106 108 }, 107 109 108 110 /** … … 118 120 // remove the penultimate point 119 121 var index = this.line.geometry.components.length - 2; 120 122 this.line.geometry.removeComponent(this.line.geometry.components[index]); 123 if(this.persist) { 124 this.destroyPoint(); 125 } 121 126 this.finalize(); 122 127 } 123 128 return false; -
lib/OpenLayers/Handler/Point.js
old new 33 33 layer: null, 34 34 35 35 /** 36 * Property: multi 37 * {Boolean} Cast features to multi-part geometries before passing to the 38 * layer. Default is false. 39 */ 40 multi: false, 41 42 /** 36 43 * Property: drawing 37 44 * {Boolean} A point is being drawn 38 45 */ … … 57 64 lastUp: null, 58 65 59 66 /** 67 * APIProperty: persist 68 * {Boolean} Leave the feature rendered until destroyFeature is called. 69 * Default is false. If set to true, the feature remains rendered until 70 * destroyFeature is called, typically by deactivating the handler or 71 * starting another drawing. 72 */ 73 persist: false, 74 75 /** 60 76 * Constructor: OpenLayers.Handler.Point 61 77 * Create a new point handler. 62 78 * … … 108 124 */ 109 125 createFeature: function() { 110 126 this.point = new OpenLayers.Feature.Vector( 111 new OpenLayers.Geometry.Point()); 127 new OpenLayers.Geometry.Point() 128 ); 129 this.layer.addFeatures([this.point]); 112 130 }, 113 131 114 132 /** … … 123 141 if(this.drawing) { 124 142 this.cancel(); 125 143 } 144 this.destroyFeature(); 126 145 // If a layer's map property is set to null, it means that that layer 127 146 // isn't added to the map. Since we ourself added the layer to the map 128 147 // in activate(), we can assume that if this.layer.map is null it means … … 140 159 * Destroy the temporary geometries 141 160 */ 142 161 destroyFeature: function() { 143 if(this.point) { 144 this.point.destroy(); 145 } 162 this.layer.destroyFeatures(); 146 163 this.point = null; 147 164 }, 148 165 149 166 /** 150 167 * Method: finalize 151 168 * Finish the geometry and call the "done" callback. 169 * 170 * Parameters: 171 * cancel - {Boolean} Call cancel instead of done callback. Default is 172 * false. 152 173 */ 153 finalize: function( ) {154 this.layer.renderer.clear();174 finalize: function(cancel) { 175 var key = cancel ? "cancel" : "done"; 155 176 this.drawing = false; 156 177 this.mouseDown = false; 157 178 this.lastDown = null; 158 179 this.lastUp = null; 159 this.callback("done", [this.geometryClone()]); 160 this.destroyFeature(); 180 this.callback(key, [this.geometryClone()]); 181 if(cancel || !this.persist) { 182 this.destroyFeature(); 183 } 161 184 }, 162 185 163 186 /** … … 165 188 * Finish the geometry and call the "cancel" callback. 166 189 */ 167 190 cancel: function() { 168 this.layer.renderer.clear(); 169 this.drawing = false; 170 this.mouseDown = false; 171 this.lastDown = null; 172 this.lastUp = null; 173 this.callback("cancel", [this.geometryClone()]); 174 this.destroyFeature(); 191 this.finalize(true); 175 192 }, 176 193 177 194 /** … … 222 239 * {<OpenLayers.Geometry.Point>} 223 240 */ 224 241 geometryClone: function() { 225 return this.point.geometry.clone(); 242 var geometry = this.point.geometry.clone(); 243 if(this.multi) { 244 geometry = new OpenLayers.Geometry.MultiPoint([geometry]); 245 } 246 return geometry; 226 247 }, 227 248 228 249 /** 229 250 * Method: mousedown 230 251 * Handle mouse down. Adjust the geometry and redraw. … … 246 267 return true; 247 268 } 248 269 if(this.lastDown == null) { 270 if(this.persist) { 271 this.destroyFeature(); 272 } 249 273 this.createFeature(); 250 274 } 251 275 this.lastDown = evt.xy; -
lib/OpenLayers/Handler/Path.js
old new 73 73 new OpenLayers.Geometry.LineString()); 74 74 this.point = new OpenLayers.Feature.Vector( 75 75 new OpenLayers.Geometry.Point()); 76 this.layer.addFeatures([this.line, this.point]); 76 77 }, 77 78 78 79 /** … … 81 82 */ 82 83 destroyFeature: function() { 83 84 OpenLayers.Handler.Point.prototype.destroyFeature.apply(this); 84 if(this.line) {85 this.line.destroy();86 }87 85 this.line = null; 88 86 }, 87 88 /** 89 * Method: destroyPoint 90 * Destroy the temporary point. 91 */ 92 destroyPoint: function() { 93 if(this.point) { 94 this.layer.destroyFeatures([this.point]); 95 } 96 }, 89 97 90 98 /** 91 99 * Method: addPoint … … 138 146 * {<OpenLayers.Geometry.LineString>} 139 147 */ 140 148 geometryClone: function() { 141 return this.line.geometry.clone(); 149 var geometry = this.line.geometry.clone(); 150 if(this.multi) { 151 geometry = new OpenLayers.Geometry.MultiLineString([geometry]); 152 } 153 return geometry; 142 154 }, 143 155 144 156 /** … … 158 170 return false; 159 171 } 160 172 if(this.lastDown == null) { 173 if(this.persist) { 174 this.destroyFeature(); 175 } 161 176 this.createFeature(); 162 177 } 163 178 this.mouseDown = true; … … 214 229 this.mouseDown = false; 215 230 if(this.drawing) { 216 231 if(this.freehandMode(evt)) { 232 if(this.persist) { 233 this.destroyPoint(); 234 } 217 235 this.finalize(); 218 236 } else { 219 237 if(this.lastUp == null) { … … 241 259 if(!this.freehandMode(evt)) { 242 260 var index = this.line.geometry.components.length - 1; 243 261 this.line.geometry.removeComponent(this.line.geometry.components[index]); 262 if(this.persist) { 263 this.destroyPoint(); 264 } 244 265 this.finalize(); 245 266 } 246 267 return false; -
lib/OpenLayers.js
old new 147 147 "OpenLayers/Control/DragPan.js", 148 148 "OpenLayers/Control/Navigation.js", 149 149 "OpenLayers/Control/MouseDefaults.js", 150 "OpenLayers/Control/Measure.js", 150 151 "OpenLayers/Control/MousePosition.js", 151 152 "OpenLayers/Control/OverviewMap.js", 152 153 "OpenLayers/Control/KeyboardDefaults.js", -
examples/measure.html
old new 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <link rel="stylesheet" href="../theme/default/style.css" type="text/css" /> 4 <link rel="stylesheet" href="style.css" type="text/css" /> 5 <style type="text/css"> 6 #controlToggle li { 7 list-style: none; 8 } 9 p { 10 width: 512px; 11 } 12 #options { 13 position: relative; 14 width: 512px; 15 } 16 #output { 17 float: right; 18 } 19 </style> 20 <script src="../lib/OpenLayers.js"></script> 21 <script type="text/javascript"> 22 var map, measureControls; 23 OpenLayers.Util.onImageLoadErrorColor = "transparent"; 24 function init(){ 25 map = new OpenLayers.Map('map'); 26 27 var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 28 "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'}); 29 30 map.addLayers([wmsLayer]); 31 map.addControl(new OpenLayers.Control.LayerSwitcher()); 32 map.addControl(new OpenLayers.Control.MousePosition()); 33 34 var options = { 35 displayUnits: 'km', 36 handlerOptions: { 37 persist: true 38 } 39 }; 40 var circleOptions = { 41 displayUnits: 'km', 42 handlerOptions: { 43 sides: 35, 44 persist: true 45 } 46 }; 47 measureControls = { 48 line: new OpenLayers.Control.Measure( 49 OpenLayers.Handler.Path, options 50 ), 51 polygon: new OpenLayers.Control.Measure( 52 OpenLayers.Handler.Polygon, options 53 ), 54 circle: new OpenLayers.Control.Measure( 55 OpenLayers.Handler.RegularPolygon, circleOptions 56 ) 57 }; 58 59 var control; 60 for(var key in measureControls) { 61 control = measureControls[key]; 62 control.onMeasure = handleMeasurements; 63 map.addControl(control); 64 } 65 66 map.setCenter(new OpenLayers.LonLat(0, 0), 3); 67 68 document.getElementById('noneToggle').checked = true; 69 } 70 71 function handleMeasurements(geometry, length, area, units) { 72 var element = document.getElementById('output'); 73 var out = ""; 74 if(geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") { 75 out += "length: " + length.toFixed(3) + " " + units; 76 } else { 77 out += "perimeter: " + length.toFixed(3) + " " + units + "<br />"; 78 out += "area: " + area.toFixed(3) + " " + units + "<sup>2</" + "sup>"; 79 } 80 element.innerHTML = out; 81 } 82 83 function toggleControl(element) { 84 for(key in measureControls) { 85 var control = measureControls[key]; 86 if(element.value == key && element.checked) { 87 control.activate(); 88 } else { 89 control.deactivate(); 90 } 91 } 92 } 93 </script> 94 </head> 95 <body onload="init()"> 96 <h1 id="title">OpenLayers Measure Example</h1> 97 <p id="shortdesc"> 98 Demonstrates the measure control to measure distances and areas. 99 </p> 100 <div id="map" class="smallmap"></div> 101 <div id="options"> 102 <div id="output"> 103 </div> 104 <ul id="controlToggle"> 105 <li> 106 <input type="radio" name="type" value="none" id="noneToggle" 107 onclick="toggleControl(this);" checked="checked" /> 108 <label for="noneToggle">navigate</label> 109 </li> 110 <li> 111 <input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" /> 112 <label for="lineToggle">draw line</label> 113 </li> 114 <li> 115 <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" /> 116 <label for="polygonToggle">draw polygon</label> 117 </li> 118 <li> 119 <input type="radio" name="type" value="circle" id="circleToggle" onclick="toggleControl(this);" /> 120 <label for="circleToggle">draw circle</label> 121 </li> 122 </ul> 123 </div> 124 </body> 125 </html>
