diff --git a/lib/OpenLayers/BaseTypes.js b/lib/OpenLayers/BaseTypes.js index 6602d76439..5220788901 100644 --- a/lib/OpenLayers/BaseTypes.js +++ b/lib/OpenLayers/BaseTypes.js @@ -424,6 +424,30 @@ OpenLayers.Bounds.prototype = { this.right + x, this.top + y); }, + /** + * @param {OpenLayers.LonLat} ll + * @param {Boolean} inclusive Whether or not to include the border. + * Default is true + * + * @return Whether or not the passed-in lonlat is within this bounds + * @type Boolean + */ + containsLonLat:function(ll, inclusive) { + return this.contains(ll.lon, ll.lat, inclusive); + }, + + /** + * @param {OpenLayers.Pixel} px + * @param {Boolean} inclusive Whether or not to include the border. + * Default is true + * + * @return Whether or not the passed-in pixel is within this bounds + * @type Boolean + */ + containsPixel:function(px, inclusive) { + return this.contains(px.x, px.y, inclusive); + }, + /** * @param {float} x * @param {float} y diff --git a/lib/OpenLayers/Feature.js b/lib/OpenLayers/Feature.js index d701664745..0f3cb5760b 100644 --- a/lib/OpenLayers/Feature.js +++ b/lib/OpenLayers/Feature.js @@ -67,16 +67,34 @@ OpenLayers.Feature.prototype= { this.marker = null; } if (this.popup != null) { - this.popup.destroy(); + this.destroyPopup(this.popup); this.popup = null; } }, + /** + * @returns Whether or not the feature is currently visible on screen + * (based on its 'lonlat' property) + * @type Boolean + */ + onScreen:function() { + + var onScreen = false; + if ((this.layer != null) && (this.layer.map != null)) { + var screenBounds = this.layer.map.getExtent(); + onScreen = screenBounds.containsLonLat(this.lonlat); + } + return onScreen; + }, + /** * @returns A Marker Object created from the 'lonlat' and 'icon' properties * set in this.data. If no 'lonlat' is set, returns null. If no - * 'icon' is set, OpenLayers.Marker() will load the default image + * 'icon' is set, OpenLayers.Marker() will load the default image. + * + * Note: this.marker is set to return value + * * @type OpenLayers.Marker */ createMarker: function() { @@ -89,12 +107,24 @@ OpenLayers.Feature.prototype= { return this.marker; }, + /** If user overrides the createMarker() function, s/he should be able + * to also specify an alternative function for destroying it + */ destroyMarker: function() { this.marker.destroy(); }, /** + * @returns A Popup Object created from the 'lonlat', 'popupSize', + * and 'popupContentHTML' properties set in this.data. It uses + * this.marker.icon as default anchor. + * + * If no 'lonlat' is set, returns null. + * If no this.marker has been created, no anchor is sent. * + * Note: this.popup is set to return value + * + * @type OpenLayers.Popup.AnchoredBubble */ createPopup: function() { @@ -112,5 +142,13 @@ OpenLayers.Feature.prototype= { return this.popup; }, + + /** As with the marker, if user overrides the createPopup() function, s/he + * should also be able to override the destruction + */ + destroyPopup: function() { + this.popup.destroy() + }, + CLASS_NAME: "OpenLayers.Feature" }; diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index ad79a36d57..4eed13d2d3 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -393,7 +393,7 @@ OpenLayers.Layer.prototype = { */ getZoomForResolution: function(resolution) { - for(var i=1; i <= this.resolutions.length; i++) { + for(var i=1; i < this.resolutions.length; i++) { if ( this.resolutions[i] < resolution) { break; } diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index 22ee39810f..861546730c 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -354,8 +354,7 @@ OpenLayers.Map.prototype = { if (newBaseLayer != this.baseLayer) { // is newBaseLayer an already loaded layer? - var foundLayer = (this.layers.indexOf(newBaseLayer) != -1); - if (foundLayer) { + if (this.layers.indexOf(newBaseLayer) != -1) { // make the old base layer invisible if (this.baseLayer != null) { @@ -455,10 +454,20 @@ OpenLayers.Map.prototype = { /********************************************************/ /** - * @returns {OpenLayers.Size} + * @returns An OpenLayers.Size object that represents the size, in pixels, + * of the div into which OpenLayers has been loaded. + * + * Note: A clone() of this locally cached variable is returned, so + * as not to allow users to modify it. + * + * @type OpenLayers.Size */ getSize: function () { - return this.size; + var size = null; + if (this.size != null) { + size = this.size.clone(); + } + return size; }, /** @@ -669,7 +678,7 @@ OpenLayers.Map.prototype = { var valid = false; if (lonlat != null) { var maxExtent = this.getMaxExtent(); - valid = maxExtent.contains(lonlat.lon, lonlat.lat); + valid = maxExtent.containsLonLat(lonlat); } return valid; }, diff --git a/lib/OpenLayers/Marker.js b/lib/OpenLayers/Marker.js index 7e672f2cd6..e36661e336 100644 --- a/lib/OpenLayers/Marker.js +++ b/lib/OpenLayers/Marker.js @@ -82,7 +82,7 @@ OpenLayers.Marker.prototype = { var onScreen = false; if (this.map) { var screenBounds = this.map.getExtent(); - onScreen = screenBounds.contains(this.lonlat.lon, this.lonlat.lat); + onScreen = screenBounds.containsLonLat(this.lonlat); } return onScreen; }, diff --git a/tests/test_Bounds.html b/tests/test_Bounds.html index 2a0561c9fe..2f9aaa6235 100644 --- a/tests/test_Bounds.html +++ b/tests/test_Bounds.html @@ -53,12 +53,19 @@ } function test_04_Bounds_contains(t) { - t.plan( 4 ); + t.plan( 6 ); bounds = new OpenLayers.Bounds(10,10,40,40); t.eq( bounds.contains(20,20), true, "bounds(10,10,40,40) correctly contains LonLat(20,20)" ); t.eq( bounds.contains(0,0), false, "bounds(10,10,40,40) correctly does not contain LonLat(0,0)" ); t.eq( bounds.contains(40,40), true, "bounds(10,10,40,40) correctly contains LonLat(40,40) with inclusive set to true" ); t.eq( bounds.contains(40,40, false), false, "bounds(10,10,40,40) correctly does not contain LonLat(40,40) with inclusive set to false" ); + + var px = new OpenLayers.Pixel(15,30); + t.eq( bounds.containsPixel(px), bounds.contains(px.x, px.y), "containsPixel works"); + + var ll = new OpenLayers.LonLat(15,30); + t.eq( bounds.containsLonLat(ll), bounds.contains(ll.lon, ll.lat), "containsLonLat works"); + } function test_05_Bounds_fromString(t) { diff --git a/tests/test_Feature.html b/tests/test_Feature.html index a700f3eb75..aaaae5bae4 100644 --- a/tests/test_Feature.html +++ b/tests/test_Feature.html @@ -76,6 +76,32 @@ "Layer div img contains correct url" ); */ } + + function test_03_Feature_onScreen(t) { + t.plan( 2 ); + + var map = new OpenLayers.Map("map"); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + var wms = new OpenLayers.Layer.WMS(name, url); + + map.addLayer(wms); + + var layer = new OpenLayers.Layer("foo"); + map.addLayer(layer); + + map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50)); + + //onscreen feature + var feature1 = new OpenLayers.Feature(layer, + new OpenLayers.LonLat(0,0)); + t.ok( feature1.onScreen(), "feature knows it's onscreen" ); + + //onscreen feature + var feature2 = new OpenLayers.Feature(layer, + new OpenLayers.LonLat(100,100)); + t.ok( !feature2.onScreen(), "feature knows it's offscreen" ); + } // --> diff --git a/tests/test_Layer.html b/tests/test_Layer.html index ba22a6a73f..41057d7470 100644 --- a/tests/test_Layer.html +++ b/tests/test_Layer.html @@ -126,6 +126,23 @@ } + function test_06_Layer_getZoomForResolution(t) { + + t.plan(4); + + var layer = new OpenLayers.Layer('Test Layer'); + + //make some dummy resolutions + layer.resolutions = [128, 64, 32, 16, 8, 4, 2]; + + t.eq(layer.getZoomForResolution(200), 0, "zoom all the way out"); + t.eq(layer.getZoomForResolution(25), 2, "zoom in middle"); + t.eq(layer.getZoomForResolution(3), 5, "zoom allmost all the way in"); + t.eq(layer.getZoomForResolution(1), 6, "zoom all the way in"); + + } + + /****** * * diff --git a/tests/test_Layer_WMS.html b/tests/test_Layer_WMS.html index cc133ea573..04de0b2057 100644 --- a/tests/test_Layer_WMS.html +++ b/tests/test_Layer_WMS.html @@ -14,8 +14,6 @@ function test_01_Layer_WMS_constructor (t) { t.plan( 4 ); - layer = new OpenLayers.Layer.WMS(); - var url = "http://octo.metacarta.com/cgi-bin/mapserv"; layer = new OpenLayers.Layer.WMS(name, url, params); t.ok( layer instanceof OpenLayers.Layer.WMS, "new OpenLayers.Layer.WMS returns object" ); diff --git a/tests/test_Marker.html b/tests/test_Marker.html index a66f311de8..64a671916e 100644 --- a/tests/test_Marker.html +++ b/tests/test_Marker.html @@ -14,10 +14,42 @@ t.ok( marker.lonlat.equals(ll), "marker.lonlat returns correct" ); } + function test_02_Marker_onScreen(t) { + t.plan( 2 ); + + var map = new OpenLayers.Map("map"); + + var url = "http://octo.metacarta.com/cgi-bin/mapserv"; + layer = new OpenLayers.Layer.WMS(name, url); + + map.addLayer(layer); + + mlayer = new OpenLayers.Layer.Markers('Test Layer'); + map.addLayer(mlayer); + + map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50)); + + //onscreen marker + var ll = new OpenLayers.LonLat(0,0); + var marker = new OpenLayers.Marker(ll); + mlayer.addMarker(marker); + + t.ok( marker.onScreen(), "marker knows it's onscreen" ); + + //offscreen marker + var ll = new OpenLayers.LonLat(100,100); + var marker2 = new OpenLayers.Marker(ll); + mlayer.addMarker(marker2); + + t.ok( !marker2.onScreen(), "marker knows it's offscreen" ); + + } + // -->
+