diff --git a/lib/OpenLayers/Control/EditingToolbar.js b/lib/OpenLayers/Control/EditingToolbar.js index b56188b36b..73aea416d9 100644 --- a/lib/OpenLayers/Control/EditingToolbar.js +++ b/lib/OpenLayers/Control/EditingToolbar.js @@ -24,6 +24,13 @@ OpenLayers.Control.EditingToolbar = OpenLayers.Class( OpenLayers.Control.Panel, { + /** + * APIProperty: citeCompliant + * {Boolean} If set to true, coordinates of features drawn in a map extent + * crossing the date line won't exceed the world bounds. Default is false. + */ + citeCompliant: false, + /** * Constructor: OpenLayers.Control.EditingToolbar * Create an editing toolbar for a given layer. @@ -39,9 +46,18 @@ OpenLayers.Control.EditingToolbar = OpenLayers.Class( [ new OpenLayers.Control.Navigation() ] ); var controls = [ - new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}), - new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}), - new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}) + new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, { + displayClass: 'olControlDrawFeaturePoint', + handlerOptions: {citeCompliant: this.citeCompliant} + }), + new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, { + displayClass: 'olControlDrawFeaturePath', + handlerOptions: {citeCompliant: this.citeCompliant} + }), + new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, { + displayClass: 'olControlDrawFeaturePolygon', + handlerOptions: {citeCompliant: this.citeCompliant} + }) ]; this.addControls(controls); }, diff --git a/lib/OpenLayers/Handler/Path.js b/lib/OpenLayers/Handler/Path.js index 83f634cf04..3849a1eaa0 100644 --- a/lib/OpenLayers/Handler/Path.js +++ b/lib/OpenLayers/Handler/Path.js @@ -108,7 +108,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { * feature. */ createFeature: function(pixel) { - var lonlat = this.map.getLonLatFromPixel(pixel); + var lonlat = this.layer.getLonLatFromViewPortPx(pixel); var geometry = new OpenLayers.Geometry.Point( lonlat.lon, lonlat.lat ); @@ -165,7 +165,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { */ addPoint: function(pixel) { this.layer.removeFeatures([this.point]); - var lonlat = this.control.map.getLonLatFromPixel(pixel); + var lonlat = this.layer.getLonLatFromViewPortPx(pixel); this.point = new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat) ); @@ -326,7 +326,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, { if(!this.line) { this.createFeature(pixel); } - var lonlat = this.control.map.getLonLatFromPixel(pixel); + var lonlat = this.layer.getLonLatFromViewPortPx(pixel); this.point.geometry.x = lonlat.lon; this.point.geometry.y = lonlat.lat; this.callback("modify", [this.point.geometry, this.getSketch(), drawing]); diff --git a/lib/OpenLayers/Handler/Point.js b/lib/OpenLayers/Handler/Point.js index da31296634..a4b4377ba3 100644 --- a/lib/OpenLayers/Handler/Point.js +++ b/lib/OpenLayers/Handler/Point.js @@ -42,6 +42,13 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { */ multi: false, + /** + * APIProperty: citeCompliant + * {Boolean} If set to true, coordinates of features drawn in a map extent + * crossing the date line won't exceed the world bounds. Default is false. + */ + citeCompliant: false, + /** * Property: mouseDown * {Boolean} The mouse is down @@ -164,7 +171,8 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { // without this, resolution properties must be specified at the // map-level for this temporary layer to init its resolutions // correctly - calculateInRange: OpenLayers.Function.True + calculateInRange: OpenLayers.Function.True, + wrapDateLine: this.citeCompliant }, this.layerOptions); this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options); this.map.addLayer(this.layer); @@ -179,7 +187,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { * pixel - {} A pixel location on the map. */ createFeature: function(pixel) { - var lonlat = this.map.getLonLatFromPixel(pixel); + var lonlat = this.layer.getLonLatFromViewPortPx(pixel); var geometry = new OpenLayers.Geometry.Point( lonlat.lon, lonlat.lat ); @@ -306,7 +314,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, { if(!this.point) { this.createFeature(pixel); } - var lonlat = this.map.getLonLatFromPixel(pixel); + var lonlat = this.layer.getLonLatFromViewPortPx(pixel); this.point.geometry.x = lonlat.lon; this.point.geometry.y = lonlat.lat; this.callback("modify", [this.point.geometry, this.point, false]); diff --git a/lib/OpenLayers/Handler/Polygon.js b/lib/OpenLayers/Handler/Polygon.js index 64e626e445..399f9afe62 100644 --- a/lib/OpenLayers/Handler/Polygon.js +++ b/lib/OpenLayers/Handler/Polygon.js @@ -75,7 +75,7 @@ OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, { * feature. */ createFeature: function(pixel) { - var lonlat = this.map.getLonLatFromPixel(pixel); + var lonlat = this.layer.getLonLatFromViewPortPx(pixel); var geometry = new OpenLayers.Geometry.Point( lonlat.lon, lonlat.lat ); diff --git a/lib/OpenLayers/Handler/RegularPolygon.js b/lib/OpenLayers/Handler/RegularPolygon.js index 3627497ccc..ee6b9fc4d1 100644 --- a/lib/OpenLayers/Handler/RegularPolygon.js +++ b/lib/OpenLayers/Handler/RegularPolygon.js @@ -83,6 +83,13 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { */ irregular: false, + /** + * APIProperty: citeCompliant + * {Boolean} If set to true, coordinates of features drawn in a map extent + * crossing the date line won't exceed the world bounds. Default is false. + */ + citeCompliant: false, + /** * Property: angle * {Float} The angle from the origin (mouse down) to the current mouse @@ -174,7 +181,8 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { // without this, resolution properties must be specified at the // map-level for this temporary layer to init its resolutions // correctly - calculateInRange: OpenLayers.Function.True + calculateInRange: OpenLayers.Function.True, + wrapDateLine: this.citeCompliant }, this.layerOptions); this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options); this.map.addLayer(this.layer); @@ -224,7 +232,7 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { */ down: function(evt) { this.fixedRadius = !!(this.radius); - var maploc = this.map.getLonLatFromPixel(evt.xy); + var maploc = this.layer.getLonLatFromViewPortPx(evt.xy); this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat); // create the new polygon if(!this.fixedRadius || this.irregular) { @@ -250,7 +258,7 @@ OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, { * evt - {Evt} The move event */ move: function(evt) { - var maploc = this.map.getLonLatFromPixel(evt.xy); + var maploc = this.layer.getLonLatFromViewPortPx(evt.xy); var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat); if(this.irregular) { var ry = Math.sqrt(2) * Math.abs(point.y - this.origin.y) / 2; diff --git a/tests/Control/EditingToolbar.html b/tests/Control/EditingToolbar.html index 031868d4a6..570986d580 100644 --- a/tests/Control/EditingToolbar.html +++ b/tests/Control/EditingToolbar.html @@ -3,12 +3,14 @@ diff --git a/tests/Handler/Polygon.html b/tests/Handler/Polygon.html index 94e8febc5c..8fad5dd977 100644 --- a/tests/Handler/Polygon.html +++ b/tests/Handler/Polygon.html @@ -1128,6 +1128,31 @@ map.destroy(); } + function test_citeComplaint(t) { + t.plan(2); + var map = new OpenLayers.Map('map'); + map.addLayer(new OpenLayers.Layer.OSM()); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + var control = new OpenLayers.Control({}); + var handler = new OpenLayers.Handler.Polygon(control, {}); + control.handler = handler; + map.addControl(control); + map.zoomToExtent(new OpenLayers.Bounds(-24225034.496992, -11368938.517442, -14206280.326992, -1350184.3474418)); + control.activate(); + handler.createFeature(new OpenLayers.Pixel(100, 50)); + t.ok(handler.point.geometry.x < 0, "Geometry started correctly when wrapping the dateline using citeCompliant false"); + control.deactivate(); + + var handler = new OpenLayers.Handler.Polygon(control, {}, {citeCompliant: true}); + control.handler = handler; + control.activate(); + handler.createFeature(new OpenLayers.Pixel(100, 50)); + t.ok(handler.point.geometry.x > 0, "Geometry started correctly when wrapping the dateline using citeCompliant true"); + + map.destroy(); + } + diff --git a/tests/Handler/RegularPolygon.html b/tests/Handler/RegularPolygon.html index 3ce9e78089..ee43dc77fa 100644 --- a/tests/Handler/RegularPolygon.html +++ b/tests/Handler/RegularPolygon.html @@ -149,9 +149,6 @@ function test_Handler_RegularPolygon_irregular(t) { t.plan(4); var map = { - getLonLatFromPixel: function(px) { - return {lon: px.x, lat: px.y}; - }, getResolution: function() { return 1; } @@ -164,6 +161,9 @@ t.eq(ring.components[0].y, 10, "correct bottom"); t.eq(ring.components[2].x, 10, "correct left"); t.eq(ring.components[2].y, 15, "correct top"); + }, + getLonLatFromViewPortPx: function(px) { + return {lon: px.x, lat: px.y}; } }; var control = {}; @@ -190,11 +190,7 @@ t.plan(1); // setup - var map = new OpenLayers.Map("map", { - getLonLatFromPixel: function(px) { - return {lon: px.x, lat: px.y}; - } - }); + var map = new OpenLayers.Map("map"); var control = {"map": map}; @@ -211,6 +207,17 @@ var isLeftClick = OpenLayers.Event.isLeftClick; OpenLayers.Event.isLeftClick = function() { return true; }; + handler.layer = { + renderer: { + clear: OpenLayers.Function.Void + }, + addFeatures: OpenLayers.Function.Void, + drawFeature: OpenLayers.Function.Void, + destroyFeatures: OpenLayers.Function.Void, + getLonLatFromViewPortPx: function() { + return xy; + } + }; // test map.events.triggerEvent("mousedown", {"xy": xy}); diff --git a/tests/manual/dateline-sketch.html b/tests/manual/dateline-sketch.html new file mode 100644 index 0000000000..62d4391324 --- /dev/null +++ b/tests/manual/dateline-sketch.html @@ -0,0 +1,59 @@ + + + + + + + OpenLayers: Sketch handlers crossing the dateline + + + + + + + + + + +

OpenLayers sketch handlers crossing the dateline example

+ +
+ international date line, dateline, sketch +
+

+ Start digitizing a polygon or line + on one side of the international dateline, and then cross the dateline + whilst digitizing. The feature should behave like digitizing on any + other location. +

+
+ +
+
+ +