From c7b8a5bce68dc8454a797001a4a2bd329511b329 Mon Sep 17 00:00:00 2001 From: euzuro Date: Fri, 5 Sep 2008 15:06:04 +0000 Subject: [PATCH] Sketch handler updates. Patch by tschaub, review elemoine (Closes #1698) git-svn-id: http://svn.openlayers.org/trunk/openlayers@7964 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Handler/Path.js | 39 ++++++++++++--- lib/OpenLayers/Handler/Point.js | 83 ++++++++++++++++++++++++------- lib/OpenLayers/Handler/Polygon.js | 22 +++++--- 3 files changed, 109 insertions(+), 35 deletions(-) diff --git a/lib/OpenLayers/Handler/Path.js b/lib/OpenLayers/Handler/Path.js index 54f27bbd4b..4ef5299f26 100644 --- a/lib/OpenLayers/Handler/Path.js +++ b/lib/OpenLayers/Handler/Path.js @@ -73,6 +73,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { new OpenLayers.Geometry.LineString()); this.point = new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point()); + this.layer.addFeatures([this.line, this.point], {silent: true}); }, /** @@ -81,11 +82,18 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { */ destroyFeature: function() { OpenLayers.Handler.Point.prototype.destroyFeature.apply(this); - if(this.line) { - this.line.destroy(); - } this.line = null; }, + + /** + * Method: destroyPoint + * Destroy the temporary point. + */ + destroyPoint: function() { + if(this.point) { + this.layer.destroyFeatures([this.point]); + } + }, /** * Method: addPoint @@ -95,7 +103,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { addPoint: function() { this.line.geometry.addComponent(this.point.geometry.clone(), this.line.geometry.components.length); - this.callback("point", [this.point.geometry]); + this.callback("point", [this.point.geometry, this.getGeometry()]); }, /** @@ -131,14 +139,19 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { }, /** - * Method: geometryClone - * Return a clone of the relevant geometry. + * Method: getGeometry + * Return the sketch geometry. If is true, this will return + * a multi-part geometry. * * Returns: * {} */ - geometryClone: function() { - return this.line.geometry.clone(); + getGeometry: function() { + var geometry = this.line.geometry; + if(this.multi) { + geometry = new OpenLayers.Geometry.MultiLineString([geometry]); + } + return geometry; }, /** @@ -158,6 +171,9 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { return false; } if(this.lastDown == null) { + if(this.persist) { + this.destroyFeature(); + } this.createFeature(); } this.mouseDown = true; @@ -165,6 +181,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { var lonlat = this.control.map.getLonLatFromPixel(evt.xy); this.point.geometry.x = lonlat.lon; this.point.geometry.y = lonlat.lat; + this.point.geometry.clearBounds(); if((this.lastUp == null) || !this.lastUp.equals(evt.xy)) { this.addPoint(); } @@ -215,6 +232,9 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { this.mouseDown = false; if(this.drawing) { if(this.freehandMode(evt)) { + if(this.persist) { + this.destroyPoint(); + } this.finalize(); } else { if(this.lastUp == null) { @@ -242,6 +262,9 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { if(!this.freehandMode(evt)) { var index = this.line.geometry.components.length - 1; this.line.geometry.removeComponent(this.line.geometry.components[index]); + if(this.persist) { + this.destroyPoint(); + } this.finalize(); } return false; diff --git a/lib/OpenLayers/Handler/Point.js b/lib/OpenLayers/Handler/Point.js index 79e67b28b8..995577a50a 100644 --- a/lib/OpenLayers/Handler/Point.js +++ b/lib/OpenLayers/Handler/Point.js @@ -32,6 +32,13 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { */ layer: null, + /** + * Property: multi + * {Boolean} Cast features to multi-part geometries before passing to the + * layer. Default is false. + */ + multi: false, + /** * Property: drawing * {Boolean} A point is being drawn @@ -56,6 +63,21 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { */ lastUp: null, + /** + * APIProperty: persist + * {Boolean} Leave the feature rendered until destroyFeature is called. + * Default is false. If set to true, the feature remains rendered until + * destroyFeature is called, typically by deactivating the handler or + * starting another drawing. + */ + persist: false, + + /** + * Property: layerOptions + * {Object} Any optional properties to be set on the sketch layer. + */ + layerOptions: null, + /** * Constructor: OpenLayers.Handler.Point * Create a new point handler. @@ -89,14 +111,14 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { } // create temporary vector layer for rendering geometry sketch // TBD: this could be moved to initialize/destroy - setting visibility here - var options = { + var options = OpenLayers.Util.extend({ displayInLayerSwitcher: false, // indicate that the temp vector layer will never be out of range // without this, resolution properties must be specified at the // map-level for this temporary layer to init its resolutions // correctly calculateInRange: function() { return true; } - }; + }, this.layerOptions); this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options); this.map.addLayer(this.layer); return true; @@ -108,7 +130,9 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { */ createFeature: function() { this.point = new OpenLayers.Feature.Vector( - new OpenLayers.Geometry.Point()); + new OpenLayers.Geometry.Point() + ); + this.layer.addFeatures([this.point], {silent: true}); }, /** @@ -123,6 +147,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { if(this.drawing) { this.cancel(); } + this.destroyFeature(); // If a layer's map property is set to null, it means that that layer // isn't added to the map. Since we ourself added the layer to the map // in activate(), we can assume that if this.layer.map is null it means @@ -140,8 +165,8 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { * Destroy the temporary geometries */ destroyFeature: function() { - if(this.point) { - this.point.destroy(); + if(this.layer) { + this.layer.destroyFeatures(); } this.point = null; }, @@ -149,15 +174,21 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { /** * Method: finalize * Finish the geometry and call the "done" callback. + * + * Parameters: + * cancel - {Boolean} Call cancel instead of done callback. Default is + * false. */ - finalize: function() { - this.layer.renderer.clear(); + finalize: function(cancel) { + var key = cancel ? "cancel" : "done"; this.drawing = false; this.mouseDown = false; this.lastDown = null; this.lastUp = null; - this.callback("done", [this.geometryClone()]); - this.destroyFeature(); + this.callback(key, [this.geometryClone()]); + if(cancel || !this.persist) { + this.destroyFeature(); + } }, /** @@ -165,13 +196,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { * Finish the geometry and call the "cancel" callback. */ cancel: function() { - this.layer.renderer.clear(); - this.drawing = false; - this.mouseDown = false; - this.lastDown = null; - this.lastUp = null; - this.callback("cancel", [this.geometryClone()]); - this.destroyFeature(); + this.finalize(true); }, /** @@ -215,14 +240,30 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { }, /** - * Method: geometryClone - * Return a clone of the relevant geometry. + * Method: getGeometry + * Return the sketch geometry. If is true, this will return + * a multi-part geometry. * * Returns: * {} */ + getGeometry: function() { + var geometry = this.point.geometry; + if(this.multi) { + geometry = new OpenLayers.Geometry.MultiPoint([geometry]); + } + return geometry; + }, + + /** + * Method: geometryClone + * Return a clone of the relevant geometry. + * + * Returns: + * {} + */ geometryClone: function() { - return this.point.geometry.clone(); + return this.getGeometry().clone(); }, /** @@ -246,6 +287,9 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { return true; } if(this.lastDown == null) { + if(this.persist) { + this.destroyFeature(); + } this.createFeature(); } this.lastDown = evt.xy; @@ -253,6 +297,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { var lonlat = this.map.getLonLatFromPixel(evt.xy); this.point.geometry.x = lonlat.lon; this.point.geometry.y = lonlat.lat; + this.point.geometry.clearBounds(); this.drawFeature(); return false; }, diff --git a/lib/OpenLayers/Handler/Polygon.js b/lib/OpenLayers/Handler/Polygon.js index 7f8c7862af..4691398896 100644 --- a/lib/OpenLayers/Handler/Polygon.js +++ b/lib/OpenLayers/Handler/Polygon.js @@ -59,6 +59,7 @@ OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, { this.polygon.geometry.addComponent(this.line.geometry); this.point = new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point()); + this.layer.addFeatures([this.polygon, this.point], {silent: true}); }, /** @@ -67,9 +68,6 @@ OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, { */ destroyFeature: function() { OpenLayers.Handler.Path.prototype.destroyFeature.apply(this); - if(this.polygon) { - this.polygon.destroy(); - } this.polygon = null; }, @@ -93,16 +91,21 @@ OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, { this.layer.drawFeature(this.polygon, this.style); this.layer.drawFeature(this.point, this.style); }, - + /** - * Method: geometryClone - * Return a clone of the relevant geometry. + * Method: getGeometry + * Return the sketch geometry. If is true, this will return + * a multi-part geometry. * * Returns: * {} */ - geometryClone: function() { - return this.polygon.geometry.clone(); + getGeometry: function() { + var geometry = this.polygon.geometry; + if(this.multi) { + geometry = new OpenLayers.Geometry.MultiPolygon([geometry]); + } + return geometry; }, /** @@ -118,6 +121,9 @@ OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, { // remove the penultimate point var index = this.line.geometry.components.length - 2; this.line.geometry.removeComponent(this.line.geometry.components[index]); + if(this.persist) { + this.destroyPoint(); + } this.finalize(); } return false;