[OpenLayers-Commits] r2308 - in sandbox/vector: lib/OpenLayers lib/OpenLayers/Control lib/OpenLayers/Layer lib/OpenLayers/Layer/WMS lib/OpenLayers/Tile tests theme/default
commits at openlayers.org
commits at openlayers.org
Mon Mar 5 10:43:53 EST 2007
Author: crschmidt
Date: 2007-03-05 10:43:38 -0500 (Mon, 05 Mar 2007)
New Revision: 2308
Added:
sandbox/vector/tests/atom-1.0.xml
sandbox/vector/tests/grid_inittiles.html
sandbox/vector/tests/test_Control_Scale.html
Modified:
sandbox/vector/lib/OpenLayers/Control/EditingAttributes.js
sandbox/vector/lib/OpenLayers/Control/OverviewMap.js
sandbox/vector/lib/OpenLayers/Control/PanZoom.js
sandbox/vector/lib/OpenLayers/Control/Scale.js
sandbox/vector/lib/OpenLayers/Events.js
sandbox/vector/lib/OpenLayers/Layer.js
sandbox/vector/lib/OpenLayers/Layer/Boxes.js
sandbox/vector/lib/OpenLayers/Layer/GeoRSS.js
sandbox/vector/lib/OpenLayers/Layer/Grid.js
sandbox/vector/lib/OpenLayers/Layer/KaMap.js
sandbox/vector/lib/OpenLayers/Layer/WMS.js
sandbox/vector/lib/OpenLayers/Layer/WMS/Untiled.js
sandbox/vector/lib/OpenLayers/Map.js
sandbox/vector/lib/OpenLayers/Tile/Image.js
sandbox/vector/lib/OpenLayers/Util.js
sandbox/vector/tests/list-tests.html
sandbox/vector/tests/test_Layer_GeoRSS.html
sandbox/vector/tests/test_Layer_KaMap.html
sandbox/vector/tests/test_Layer_WMS.html
sandbox/vector/tests/test_Util.html
sandbox/vector/theme/default/style.css
Log:
Bring vector branch up to trunk.
Modified: sandbox/vector/lib/OpenLayers/Control/EditingAttributes.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Control/EditingAttributes.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Control/EditingAttributes.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -176,7 +176,7 @@
// For the top layer, query the SVG/VML feature
if(this.map.layers.length>0){
- evt.targetGeometry = this.map.layers[this.map.layers.length-1].renderer.getGeometryFromEvent(evt);
+ evt.targetGeometry = this.map.layers[0].renderer.getGeometryFromEvent(evt);
}
// For remaining layers, query features based on feature bounds.
// Exit loop when a feature is found.
@@ -232,6 +232,16 @@
ignoreEvent: function(evt) {
OpenLayers.Event.stop(evt);
},
+
+ setLayer: function(layer){
+ if(layer)
+ this.layer = layer;
+ else
+ for(var i = 0; i < this.map.layers.length; i++) {
+ if(this.map.layers[i].CLASS_NAME == "OpenLayers.Layer.Vector")
+ this.layer = this.map.layers[i];
+ }
+ },
CLASS_NAME: "OpenLayers.Control.EditingAttributes"
Modified: sandbox/vector/lib/OpenLayers/Control/OverviewMap.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Control/OverviewMap.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Control/OverviewMap.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -6,11 +6,11 @@
* @author Tim Schaub
*/
-// @require: OpenLayers/Control.js
-
/**
-* @class
-*/
+ * @class
+ *
+ * @requires OpenLayers/Control.js
+ */
OpenLayers.Control.OverviewMap = OpenLayers.Class.create();
OpenLayers.Control.OverviewMap.prototype =
@@ -90,6 +90,7 @@
this.extentRectangle = document.createElement('div');
this.extentRectangle.style.position = 'absolute';
this.extentRectangle.style.zIndex = 1000; //HACK
+ this.extentRectangle.style.overflow = 'hidden';
this.extentRectangle.style.backgroundImage = 'url(' +
OpenLayers.Util.getImagesLocation() +
'/blank.png)';
@@ -118,7 +119,6 @@
OpenLayers.Event.stop(e);
});
this.rectEvents = new OpenLayers.Events(this, this.extentRectangle);
- this.rectEvents.register('mouseover', this, this.rectMouseOver);
this.rectEvents.register('mouseout', this, this.rectMouseOut);
this.rectEvents.register('mousedown', this, this.rectMouseDown);
this.rectEvents.register('mousemove', this, this.rectMouseMove);
@@ -130,24 +130,59 @@
this.mapDivEvents = new OpenLayers.Events(this, this.mapDiv);
this.mapDivEvents.register('click', this, this.mapDivClick);
- // There should be an option to place the control outside of the
- // map viewport. This would make these buttons optional.
- var imgLocation = OpenLayers.Util.getImagesLocation();
- // maximize button div
- var img = imgLocation + 'layer-switcher-maximize.png';
- this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
- 'olControlOverviewMapMaximizeButton',
- null,
- new OpenLayers.Size(18,18),
- img,
- 'absolute');
- this.maximizeDiv.style.display = 'none';
- this.maximizeDiv.className = 'olControlOverviewMapMaximizeButton';
- OpenLayers.Event.observe(this.maximizeDiv,
- 'click',
- this.maximizeControl.bindAsEventListener(this));
- this.div.appendChild(this.maximizeDiv);
-
+ // Optionally add min/max buttons if the control will go in the
+ // map viewport.
+ if(!this.outsideViewport) {
+ this.div.className = 'olControlOverviewMapContainer';
+ var imgLocation = OpenLayers.Util.getImagesLocation();
+ // maximize button div
+ var img = imgLocation + 'layer-switcher-maximize.png';
+ this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
+ 'olControlOverviewMapMaximizeButton',
+ null,
+ new OpenLayers.Size(18,18),
+ img,
+ 'absolute');
+ this.maximizeDiv.style.display = 'none';
+ this.maximizeDiv.className = 'olControlOverviewMapMaximizeButton';
+ OpenLayers.Event.observe(this.maximizeDiv,
+ 'click',
+ this.maximizeControl.bindAsEventListener(this));
+ OpenLayers.Event.observe(this.maximizeDiv,
+ 'dblclick',
+ function(e) {
+ OpenLayers.Event.stop(e);
+ });
+ this.div.appendChild(this.maximizeDiv);
+
+ // minimize button div
+ var img = imgLocation + 'layer-switcher-minimize.png';
+ this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(
+ 'OpenLayers_Control_minimizeDiv',
+ null,
+ new OpenLayers.Size(18,18),
+ img,
+ 'absolute');
+ this.minimizeDiv.style.display = 'none';
+ this.minimizeDiv.className = 'olControlOverviewMapMinimizeButton';
+ OpenLayers.Event.observe(this.minimizeDiv,
+ 'click',
+ this.minimizeControl.bindAsEventListener(this));
+ OpenLayers.Event.observe(this.minimizeDiv,
+ 'dblclick',
+ function(e) {
+ OpenLayers.Event.stop(e);
+ });
+ this.div.appendChild(this.minimizeDiv);
+
+ this.minimizeControl();
+ } else {
+ // show the overview map
+ this.element.style.display = '';
+ }
+ if(this.map.getExtent()) {
+ this.update();
+ }
// minimize button div
var img = imgLocation + 'layer-switcher-minimize.png';
this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(
@@ -177,19 +212,21 @@
/**
* @param {OpenLayers.Event} evt
*/
- rectMouseOver: function (evt) {
- this.extentRectangle.style.cursor = 'move';
- },
-
- /**
- * @param {OpenLayers.Event} evt
- */
rectMouseOut: function (evt) {
- this.extentRectangle.style.cursor = 'default';
if(this.rectDragStart != null) {
if(this.performedRectDrag) {
- this.updateMapToRect();
- }
+ this.rectMouseMove(evt);
+ var rectPxBounds = this.getRectPxBounds();
+ // if we're off of the overview map, update the main map
+ // otherwise, keep moving the rect
+ if((rectPxBounds.top <= 0) || (rectPxBounds.left <= 0) ||
+ (rectPxBounds.bottom >= this.size.h - this.hComp) ||
+ (rectPxBounds.right >= this.size.w - this.wComp)) {
+ this.updateMapToRect();
+ } else {
+ return;
+ }
+ }
document.onselectstart = null;
this.rectDragStart = null;
}
@@ -390,12 +427,14 @@
*/
updateRectToMap: function() {
if(this.map.units != 'degrees') {
- if(this.map.projection != this.ovmap.map.projection) {
+ if(this.ovmap.getProjection() && (this.map.getProjection() != this.ovmap.getProjection())) {
alert('The overview map only works when it is in the same projection as the main map');
}
}
var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent());
- this.setRectPxBounds(pxBounds);
+ if (pxBounds) {
+ this.setRectPxBounds(pxBounds);
+ }
},
/**
@@ -451,8 +490,12 @@
lonLatBounds.top);
var leftBottomPx = this.getOverviewPxFromLonLat(leftBottomLonLat);
var rightTopPx = this.getOverviewPxFromLonLat(rightTopLonLat);
- return new OpenLayers.Bounds(leftBottomPx.x, leftBottomPx.y,
- rightTopPx.x, rightTopPx.y);
+ var bounds = null;
+ if (leftBottomPx && rightTopPx) {
+ bounds = new OpenLayers.Bounds(leftBottomPx.x, leftBottomPx.y,
+ rightTopPx.x, rightTopPx.y);
+ }
+ return bounds;
},
/**
@@ -502,10 +545,13 @@
getOverviewPxFromLonLat: function(lonlat) {
var res = this.ovmap.getResolution();
var extent = this.ovmap.getExtent();
- return new OpenLayers.Pixel(
- Math.round(1/res * (lonlat.lon - extent.left)),
- Math.round(1/res * (extent.top - lonlat.lat))
- );
+ var px = null;
+ if (extent) {
+ px = new OpenLayers.Pixel(
+ Math.round(1/res * (lonlat.lon - extent.left)),
+ Math.round(1/res * (extent.top - lonlat.lat)));
+ }
+ return px;
},
/** @final @type String */
Modified: sandbox/vector/lib/OpenLayers/Control/PanZoom.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Control/PanZoom.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Control/PanZoom.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -85,8 +85,8 @@
this.div.appendChild(btn);
btn.onmousedown = this.buttonDown.bindAsEventListener(btn);
+ btn.onmouseup = this.doubleClick.bindAsEventListener(btn);
btn.ondblclick = this.doubleClick.bindAsEventListener(btn);
- btn.onclick = this.doubleClick.bindAsEventListener(btn);
btn.action = id;
btn.map = this.map;
btn.slideFactor = this.slideFactor;
Modified: sandbox/vector/lib/OpenLayers/Control/Scale.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Control/Scale.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Control/Scale.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -53,8 +53,9 @@
} else if (scale >= 950000) {
scale = Math.round(scale / 1000000) + "M";
} else {
- scale = Math.round(scale / 100) * 100;
- }
+ scale = Math.round(scale);
+ }
+
this.element.innerHTML = "Scale = 1 : " + scale;
},
Modified: sandbox/vector/lib/OpenLayers/Events.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Events.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Events.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -277,7 +277,10 @@
evt.element = this.element;
// execute all callbacks registered for specified type
- var listeners = this.listeners[type];
+ // get a clone of the listeners array to
+ // allow for splicing during callbacks
+ var listeners = (this.listeners[type]) ?
+ this.listeners[type].slice() : null;
if ((listeners != null) && (listeners.length > 0)) {
for (var i = 0; i < listeners.length; i++) {
var callback = listeners[i];
Modified: sandbox/vector/lib/OpenLayers/Layer/Boxes.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer/Boxes.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer/Boxes.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -44,6 +44,19 @@
}
},
+
+ /** OVERRIDDEN
+ *
+ * @param {OpenLayers.Marker} marker
+ */
+ removeMarker: function(marker) {
+ OpenLayers.Util.removeItem(this.markers, marker);
+ if ((marker.div != null) &&
+ (marker.div.parentNode == this.div) ) {
+ this.div.removeChild(marker.div);
+ }
+ },
+
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.Boxes"
});
Modified: sandbox/vector/lib/OpenLayers/Layer/GeoRSS.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer/GeoRSS.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer/GeoRSS.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -130,7 +130,18 @@
}
catch (e) { description="No description."; }
- try { var link = OpenLayers.Util.getNodes(itemlist[i], "link")[0].firstChild.nodeValue; } catch (e) { }
+ /* If no link URL is found in the first child node, try the
+ href attribute */
+ try {
+ var link = OpenLayers.Util.getNodes(itemlist[i], "link")[0].firstChild.nodeValue;
+ }
+ catch (e) {
+ try {
+ var link = OpenLayers.Util.getNodes(itemlist[i], "link")[0].getAttribute("href");
+ }
+ catch (e) {}
+ }
+
data.icon = OpenLayers.Marker.defaultIcon();
data.popupSize = new OpenLayers.Size(250, 120);
if ((title != null) && (description != null)) {
Modified: sandbox/vector/lib/OpenLayers/Layer/Grid.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer/Grid.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer/Grid.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -351,6 +351,20 @@
// Should be implemented by subclasses
},
+ /**
+ * Once params have been changed, we will need to re-init our tiles
+ *
+ * @param {Object} newParams Hashtable of new params to use
+ */
+ mergeNewParams:function(newArguments) {
+ OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this,
+ [newArguments]);
+
+ if (this.map != null) {
+ this._initTiles();
+ }
+ },
+
/** go through and remove all tiles from the grid, calling
* destroy() on each of them to kill circular references
Modified: sandbox/vector/lib/OpenLayers/Layer/KaMap.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer/KaMap.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer/KaMap.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -50,10 +50,9 @@
*/
getURL: function (bounds) {
var mapRes = this.map.getResolution();
- var scale = Math.round((this.map.getScale() * 10000)) / 10000;
- var cellSize = new OpenLayers.Size(mapRes*this.tileSize.w, mapRes*this.tileSize.h);
- var pX = Math.round(((bounds.left) / cellSize.w) * this.tileSize.w);
- var pY = -Math.round(((bounds.top) / cellSize.h) * this.tileSize.h);
+ var scale = Math.round((this.map.getScale() * 10000)) / 10000;
+ var pX = Math.round(bounds.left / mapRes);
+ var pY = -Math.round(bounds.top / mapRes);
return this.getFullRequestString(
{ t: pY,
l: pX,
Modified: sandbox/vector/lib/OpenLayers/Layer/WMS/Untiled.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer/WMS/Untiled.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer/WMS/Untiled.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -30,8 +30,11 @@
/** @type OpenLayers.Tile.Image */
tile: null,
-
+ /** did the image finish loading before a new draw was initiated?
+ * @type Boolean */
+ doneLoading: false,
+
/**
* @constructor
*
@@ -63,8 +66,10 @@
*
*/
destroy: function() {
- this.tile.destroy();
- this.tile = null;
+ if (this.tile) {
+ this.tile.destroy();
+ this.tile = null;
+ }
OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments);
},
@@ -108,6 +113,10 @@
* @param {Boolean} dragging
*/
moveTo:function(bounds, zoomChanged, dragging) {
+ if (!this.doneLoading) {
+ this.events.triggerEvent("loadcancel");
+ this.doneLoading = true;
+ }
OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this,arguments);
if (bounds == null) {
@@ -155,10 +164,18 @@
this.tile = null;
}
+ this.events.triggerEvent("loadstart");
+ this.doneLoading = false;
if (!this.tile) {
this.tile = new OpenLayers.Tile.Image(this, pos, tileBounds,
url, tileSize);
this.tile.draw();
+ var onload = function() {
+ this.doneLoading = true;
+ this.events.triggerEvent("loadend");
+ }
+ OpenLayers.Event.observe(this.tile.imgDiv, 'load',
+ onload.bindAsEventListener(this));
} else {
this.tile.moveTo(tileBounds, pos);
}
Modified: sandbox/vector/lib/OpenLayers/Layer/WMS.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer/WMS.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer/WMS.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -126,10 +126,6 @@
var newArguments = [upperParams];
OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,
newArguments);
-
- if (this.map != null) {
- this._initTiles();
- }
},
/** combine the layer's url with its params and these newParams.
Modified: sandbox/vector/lib/OpenLayers/Layer.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Layer.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Layer.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -18,7 +18,16 @@
/** @type DOMElement */
div: null,
- /** This variable is set when the layer is added to the map, via the
+ /** supported application event types
+ *
+ * @type Array */
+ EVENT_TYPES: [
+ "loadstart", "loadend", "loadcancel"],
+
+ /** @type OpenLayers.Events */
+ events: null,
+
+ /** This variable is set when the layer is added to the map, via the
* accessor function setMap()
*
* @type OpenLayers.Map */
@@ -121,20 +130,30 @@
this.div.style.height = "100%";
this.div.id = this.id;
}
+
+ this.events = new OpenLayers.Events(this, this.div, this.EVENT_TYPES);
},
/**
* Destroy is a destructor: this is to alleviate cyclic references which
* the Javascript garbage cleaner can not take care of on its own.
+ *
+ * @param {Boolean} setNewBaseLayer Should a new baselayer be selected when
+ * this has been removed?
+ * Default is true
*/
- destroy: function() {
+ destroy: function(setNewBaseLayer) {
+ if (setNewBaseLayer == null) {
+ setNewBaseLayer = true;
+ }
if (this.map != null) {
- this.map.removeLayer(this);
+ this.map.removeLayer(this, setNewBaseLayer);
}
this.map = null;
this.name = null;
this.div = null;
this.options = null;
+ this.events = null;
},
/**
@@ -509,8 +528,8 @@
var center = this.map.getCenter();
var res = this.map.getResolution();
- var delta_x = viewPortPx.x - Math.ceil(size.w / 2);
- var delta_y = viewPortPx.y - Math.ceil(size.h / 2);
+ var delta_x = viewPortPx.x - (size.w / 2);
+ var delta_y = viewPortPx.y - (size.h / 2);
lonlat = new OpenLayers.LonLat(center.lon + delta_x * res ,
center.lat - delta_y * res);
Modified: sandbox/vector/lib/OpenLayers/Map.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Map.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Map.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -86,6 +86,18 @@
/** @type int */
zoom: 0,
+ /** Used to store a unique identifier that changes when the map view
+ * changes. viewRequestID should be used when adding data asynchronously
+ * to the map: viewRequestID is incremented when you initiate your
+ * request (right now during changing of baselayers and changing of zooms).
+ * It is stored here in the map and also in the data that will be coming
+ * back asynchronously. Before displaying this data on request completion,
+ * we check that the viewRequestID of the data is still the same as that
+ * of the map. Fix for #480
+ *
+ * @type String */
+ viewRequestID: 0,
+
// Options
/** @type OpenLayers.Size */
@@ -244,7 +256,9 @@
destroy:function() {
if (this.layers != null) {
for (var i=0; i< this.layers.length; i++) {
- this.layers[i].destroy();
+ //pass 'false' to destroy so that map wont try to set a new
+ // baselayer after each baselayer is removed
+ this.layers[i].destroy(false);
}
this.layers = null;
}
@@ -395,8 +409,13 @@
* its own personal list of popups, removing them from the map.
*
* @param {OpenLayers.Layer} layer
+ * @param {Boolean} setNewBaseLayer Default is true
*/
- removeLayer: function(layer) {
+ removeLayer: function(layer, setNewBaseLayer) {
+ if (setNewBaseLayer == null) {
+ setNewBaseLayer = true;
+ }
+
if (layer.isFixed) {
this.viewPortDiv.removeChild(layer.div);
} else {
@@ -406,7 +425,7 @@
OpenLayers.Util.removeItem(this.layers, layer);
// if we removed the base layer, need to set a new one
- if (this.baseLayer == layer) {
+ if (setNewBaseLayer && (this.baseLayer == layer)) {
this.baseLayer = null;
for (i=0; i < this.layers.length; i++) {
var iLayer = this.layers[i];
@@ -482,29 +501,37 @@
* @param {Boolean} noEvent
*/
setBaseLayer: function(newBaseLayer, noEvent) {
- var oldBaseLayer = this.baseLayer;
+ var oldExtent = null;
+ if(this.baseLayer) {
+ oldExtent = this.baseLayer.getExtent();
+ }
- if (newBaseLayer != oldBaseLayer) {
+ if (newBaseLayer != this.baseLayer) {
// is newBaseLayer an already loaded layer?
if (OpenLayers.Util.indexOf(this.layers, newBaseLayer) != -1) {
// make the old base layer invisible
- if (oldBaseLayer != null) {
- oldBaseLayer.setVisibility(false, noEvent);
+ if (this.baseLayer != null) {
+ this.baseLayer.setVisibility(false, noEvent);
}
// set new baselayer and make it visible
this.baseLayer = newBaseLayer;
+
+ // Increment viewRequestID since the baseLayer is
+ // changing. This is used by tiles to check if they should
+ // draw themselves.
+ this.viewRequestID++;
this.baseLayer.setVisibility(true, noEvent);
//redraw all layers
var center = this.getCenter();
if (center != null) {
- if (oldBaseLayer == null) {
+ if (oldExtent == null) {
this.setCenter(center);
} else {
- this.zoomToExtent(oldBaseLayer.getExtent());
+ this.zoomToExtent(oldExtent);
}
}
@@ -762,12 +789,12 @@
this.div.clientHeight);
// Workaround for the fact that hidden elements return 0 for size.
- if (size.w == 0 && size.h == 0) {
+ if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {
var dim = OpenLayers.Element.getDimensions(this.div);
size.w = dim.width;
size.h = dim.height;
}
- if (size.w == 0 && size.h == 0) {
+ if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {
size.w = parseInt(this.div.style.width);
size.h = parseInt(this.div.style.height);
}
@@ -901,8 +928,11 @@
for (var i = 0; i < this.popups.length; i++) {
this.popups[i].updatePosition();
}
- }
+ // zoom level has changed, increment viewRequestID.
+ this.viewRequestID++;
+ }
+
var bounds = this.getExtent();
//send the move call to the baselayer and all the overlays
Modified: sandbox/vector/lib/OpenLayers/Tile/Image.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Tile/Image.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Tile/Image.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -34,6 +34,7 @@
destroy: function() {
if ((this.imgDiv != null) && (this.imgDiv.parentNode == this.layer.div)) {
this.layer.div.removeChild(this.imgDiv);
+ this.imgDiv.map = null;
}
this.imgDiv = null;
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
@@ -52,6 +53,8 @@
if (this.imgDiv == null) {
this.initImgDiv();
}
+
+ this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
this.url = this.layer.getURL(this.bounds);
@@ -117,12 +120,14 @@
this.imgDiv.className = 'olTileImage';
- /* checkImgURL *should* pretty predictably get called after the
- createImage / createAlphaImageDiv onLoad handler */
+ /* checkImgURL used to be used to called as a work around, but it
+ ended up hiding problems instead of solving them and broke things
+ like relative URLs. See discussion on the dev list:
+ http://openlayers.org/pipermail/dev/2007-January/000205.html
OpenLayers.Event.observe( this.imgDiv, "load",
this.checkImgURL.bindAsEventListener(this) );
-
+ */
this.layer.div.appendChild(this.imgDiv);
if (this.layer.opacity != null) {
@@ -130,6 +135,10 @@
null, null, null,
this.layer.opacity);
}
+
+ // we need this reference to check back the viewRequestID
+ this.imgDiv.map = this.layer.map;
+
},
/**
@@ -139,6 +148,14 @@
* the imgDiv display to 'none', as either (a) it will be reset to visible
* when the new URL loads in the image, or (b) we don't want to display
* this tile after all because its new bounds are outside our maxExtent.
+ *
+ * This function should no longer be neccesary with the improvements to
+ * Grid.js in OpenLayers 2.3. The lack of a good isEquivilantURL function
+ * caused problems in 2.2, but it's possible that with the improved
+ * isEquivilant URL function, this might be neccesary at some point.
+ *
+ * See discussion in the thread at
+ * http://openlayers.org/pipermail/dev/2007-January/000205.html
*
* @private
*/
Modified: sandbox/vector/lib/OpenLayers/Util.js
===================================================================
--- sandbox/vector/lib/OpenLayers/Util.js 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/lib/OpenLayers/Util.js 2007-03-05 15:43:38 UTC (rev 2308)
@@ -217,8 +217,25 @@
}
OpenLayers.Util.onImageLoad = function() {
- this.style.backgroundColor = null;
- this.style.display = "";
+ // The complex check here is to solve issues described in #480.
+ // Every time a map view changes, it increments the 'viewRequestID'
+ // property. As the requests for the images for the new map view are sent
+ // out, they are tagged with this unique viewRequestID.
+ //
+ // If an image has no viewRequestID property set, we display it regardless,
+ // but if it does have a viewRequestID property, we check that it matches
+ // the viewRequestID set on the map.
+ //
+ // If the viewRequestID on the map has changed, that means that the user
+ // has changed the map view since this specific request was sent out, and
+ // therefore this tile does not need to be displayed (so we do not execute
+ // this code that turns its display on).
+ //
+ if (!this.viewRequestID ||
+ (this.map && this.viewRequestID == this.map.viewRequestID)) {
+ this.style.backgroundColor = null;
+ this.style.display = "";
+ }
};
OpenLayers.Util.onImageLoadErrorColor = "pink";
@@ -321,7 +338,7 @@
var div = OpenLayers.Util.createDiv();
var img = OpenLayers.Util.createImage(null, null, null, null, null, null,
- false);
+ null, false);
div.appendChild(img);
if (delayDisplay) {
@@ -377,17 +394,32 @@
* @returns a concatenation of the properties of an object in
* http parameter notation.
* (ex. <i>"key1=value1&key2=value2&key3=value3"</i>)
+* If a parameter is actually a list, that parameter will then
+* be set to a comma-seperated list of values (foo,bar) instead
+* of being URL escaped (foo%3Abar).
* @type String
*/
OpenLayers.Util.getParameterString = function(params) {
paramsArray = new Array();
for (var key in params) {
- var value = params[key];
- if ((value != null) && (typeof value != 'function')) {
- paramsArray.push(encodeURIComponent(key) + "=" +
- encodeURIComponent(value));
+ var value = params[key];
+ if ((value != null) && (typeof value != 'function')) {
+ var encodedValue;
+ if (typeof value == 'object' && value.constructor == Array) {
+ /* value is an array; encode items and separate with "," */
+ var encodedItemArray = new Array();
+ for (var itemIndex=0; itemIndex<value.length; itemIndex++) {
+ encodedItemArray.push(encodeURIComponent(value[itemIndex]));
+ }
+ encodedValue = encodedItemArray.join(",");
}
+ else {
+ /* value is a string; simply encode */
+ encodedValue = encodeURIComponent(value);
+ }
+ paramsArray.push(encodeURIComponent(key) + "=" + encodedValue);
+ }
}
return paramsArray.join("&");
@@ -909,11 +941,36 @@
urlObj1 = OpenLayers.Util.createUrlObject(url1, options);
urlObj2 = OpenLayers.Util.createUrlObject(url2, options);
- //compare keys (host, port, etc)
+ //compare all keys (host, port, etc)
for(var key in urlObj1) {
- if ( (key != "args") && (urlObj1[key] != urlObj2[key]) ) {
- return false;
+ if (options.test) {
+ alert(key + "\n1:" + urlObj1[key] + "\n2:" + urlObj2[key]);
}
+ var val1 = urlObj1[key];
+ var val2 = urlObj2[key];
+
+ switch(key) {
+ case "args":
+ //do nothing, they'll be treated below
+ break;
+ case "host":
+ case "port":
+ case "protocol":
+ if ((val1 == "") || (val2 == "")) {
+ //these will be blank for relative urls, so no need to
+ // compare them here -- call break.
+ //
+ break;
+ }
+ // otherwise continue with default compare
+ //
+ default:
+ if ( (key != "args") && (urlObj1[key] != urlObj2[key]) ) {
+ return false;
+ }
+ break;
+ }
+
}
// compare search args - irrespective of order
@@ -951,25 +1008,8 @@
}
var a = document.createElement('a');
-
a.href = url;
- //protocol
- urlObject.protocol = a.protocol;
-
- //pathname (this part allows for relative <-> absolute comparison)
- urlObject.pathname = a.pathname;
-
- //Test to see if the pathname includes the arguments (this happens in Opera)
- var qIndex = urlObject.pathname.indexOf("?");
- if (qIndex != -1) {
- urlObject.pathname = urlObject.pathname.substring(0, qIndex);
- }
-
-
- //hash
- urlObject.hash = (options.ignoreHash) ? "" : a.hash;
-
//host (without port)
urlObject.host = a.host;
var port = a.port;
@@ -977,12 +1017,107 @@
var newHostLength = urlObject.host.length - (port.length);
urlObject.host = urlObject.host.substring(0, newHostLength);
}
-
+
+ //protocol
+ urlObject.protocol = a.protocol;
+
//port
urlObject.port = ((port == "80") && (options.ignorePort80)) ? "" : port;
+ //hash
+ urlObject.hash = (options.ignoreHash) ? "" : a.hash;
+
//args
- urlObject.args = OpenLayers.Util.getArgs(a.search);
+ var queryString = a.search;
+ if (!queryString) {
+ var qMark = url.indexOf("?");
+ queryString = (qMark != -1) ? url.substr(qMark) : "";
+ }
+ urlObject.args = OpenLayers.Util.getArgs(queryString);
+
+ //pathname (this part allows for relative <-> absolute comparison)
+ if ( ((urlObject.protocol == "file:") && (url.indexOf("file:") != -1)) ||
+ ((urlObject.protocol != "file:") && (urlObject.host != "")) ) {
+
+ urlObject.pathname = a.pathname;
+
+ //Test to see if the pathname includes the arguments (Opera)
+ var qIndex = urlObject.pathname.indexOf("?");
+ if (qIndex != -1) {
+ urlObject.pathname = urlObject.pathname.substring(0, qIndex);
+ }
+
+ } else {
+ var relStr = OpenLayers.Util.removeTail(url);
+
+ var backs = 0;
+ do {
+ var index = relStr.indexOf("../");
+
+ if (index == 0) {
+ backs++
+ relStr = relStr.substr(3);
+ } else if (index >= 0) {
+ var prevChunk = relStr.substr(0,index - 1);
+
+ var slash = prevChunk.indexOf("/");
+ prevChunk = (slash != -1) ? prevChunk.substr(0, slash +1)
+ : "";
+
+ var postChunk = relStr.substr(index + 3);
+ relStr = prevChunk + postChunk;
+ }
+ } while(index != -1)
+
+ var windowAnchor = document.createElement("a");
+ var windowUrl = window.location.href;
+ if (options.ignoreCase) {
+ windowUrl = windowUrl.toLowerCase();
+ }
+ windowAnchor.href = windowUrl;
+
+ //set protocol of window
+ urlObject.protocol = windowAnchor.protocol;
+
+ var splitter = (windowAnchor.pathname.indexOf("/") != -1) ? "/" : "\\";
+ var dirs = windowAnchor.pathname.split(splitter);
+ dirs.pop(); //remove filename
+ while ((backs > 0) && (dirs.length > 0)) {
+ dirs.pop();
+ backs--;
+ }
+ relStr = dirs.join("/") + "/"+ relStr;
+ urlObject.pathname = relStr;
+ }
+
+ if ((urlObject.protocol == "file:") || (urlObject.protocol == "")) {
+ urlObject.host = "localhost";
+ }
+
return urlObject;
};
+<<<<<<< .working
+=======
+
+/**
+ * @param {String} url
+ *
+ * @returns The string with all queryString and Hash removed
+ * @type String
+ */
+OpenLayers.Util.removeTail = function(url) {
+ var head = null;
+
+ var qMark = url.indexOf("?");
+ var hashMark = url.indexOf("#");
+
+ if (qMark == -1) {
+ head = (hashMark != -1) ? url.substr(0,hashMark) : url;
+ } else {
+ head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark))
+ : url.substr(0, qMark);
+ }
+ return head;
+};
+>>>>>>> .merge-right.r2307
Copied: sandbox/vector/tests/atom-1.0.xml (from rev 2307, trunk/openlayers/tests/atom-1.0.xml)
===================================================================
--- sandbox/vector/tests/atom-1.0.xml (rev 0)
+++ sandbox/vector/tests/atom-1.0.xml 2007-03-05 15:43:38 UTC (rev 2308)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:georss="http://www.georss.org/georss">
+
+ <title>tumulus</title>
+ <link rel="self"
+ href="http://pleiades.stoa.org/places/tumulus"/>
+ <updated/>
+ <author/>
+ <id>http://pleiades.stoa.org/places/tumulus</id>
+
+ <entry>
+ <title>Unnamed Tumulus</title>
+ <link rel="alternate"
+ href="http://pleiades.stoa.org/places/638896"
+ />
+ <id>http://pleiades.stoa.org/places/638896</id>
+ <updated/>
+ <summary>An ancient tumulus, attested during the Classical period (modern location: Karaburun). Its ancient name is not known.</summary>
+ <georss:point>36.7702 29.9805</georss:point>
+ </entry>
+ <entry>
+ <title>Unnamed Tumulus</title>
+ <link rel="alternate"
+ href="http://pleiades.stoa.org/places/638924"
+ />
+ <id>http://pleiades.stoa.org/places/638924</id>
+ <updated/>
+ <summary>An ancient tumulus, attested during the Classical period (modern location: Kızılbel). Its ancient name is not known.</summary>
+ <georss:point>36.7263 29.8619</georss:point>
+ </entry>
+
+</feed>
+
Copied: sandbox/vector/tests/grid_inittiles.html (from rev 2307, trunk/openlayers/tests/grid_inittiles.html)
===================================================================
--- sandbox/vector/tests/grid_inittiles.html (rev 0)
+++ sandbox/vector/tests/grid_inittiles.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -0,0 +1,32 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <style type="text/css">
+ #map {
+ width: 800px;
+ height: 475px;
+ border: 1px solid black;
+ }
+ </style>
+ <script src="../lib/OpenLayers.js"></script>
+ <script type="text/javascript">
+ <!--
+ function init(){
+ var map = new OpenLayers.Map('map', {'maxResolution': 1.40625/2, tileSize: new OpenLayers.Size(256,256)});
+ ww = new OpenLayers.Layer.WMS( "Basic",
+ "http://labs.metacarta.com/wms-c/Basic.py?",
+ {layers:"basic"});
+ map.addLayers([ww]);
+ map.zoomToMaxExtent();
+ map.zoomIn();
+ map.zoomOut();
+ map.zoomOut();
+ }
+ // -->
+ </script>
+ </head>
+ <body onload="init()">
+ <h1>Grid Test</h1>
+ <p>Map should display with two centered tiles. If there appear to be a combination of two zoom levels, then this test is failed, and something is broken in OpenLayers.</p>
+ <div id="map"></div>
+ </body>
+</html>
Modified: sandbox/vector/tests/list-tests.html
===================================================================
--- sandbox/vector/tests/list-tests.html 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/tests/list-tests.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -36,5 +36,6 @@
<li>test_Control_PanZoom.html</li>
<li>test_Control_PanZoomBar.html</li>
<li>test_Control_Permalink.html</li>
+ <li>test_Control_Scale.html</li>
<li>test_Map.html</li>
</ul>
Copied: sandbox/vector/tests/test_Control_Scale.html (from rev 2307, trunk/openlayers/tests/test_Control_Scale.html)
===================================================================
--- sandbox/vector/tests/test_Control_Scale.html (rev 0)
+++ sandbox/vector/tests/test_Control_Scale.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -0,0 +1,47 @@
+<html>
+<head>
+ <script src="../lib/OpenLayers.js"></script>
+ <script type="text/javascript"><!--
+ var map;
+ function test_01_Control_Scale_constructor (t) {
+ t.plan( 1 );
+
+ control = new OpenLayers.Control.Scale();
+ t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
+ }
+ function test_02_Control_Scale_updateScale (t) {
+ t.plan( 4 );
+
+ control = new OpenLayers.Control.Scale($('scale'));
+ t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map($('map'));
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq($('scale').innerHTML, "Scale = 1 : 443M", "Scale set by default." );
+ map.zoomIn();
+ t.eq($('scale').innerHTML, "Scale = 1 : 221M", "Zooming in changes scale" );
+ map.baseLayer.resolutions = [OpenLayers.Util.getResolutionFromScale(110)];
+ map.zoomTo(0);
+ t.eq($('scale').innerHTML, "Scale = 1 : 110", "Scale of 100 isn't rounded" );
+ }
+ function test_03_Control_Scale_internalScale (t) {
+ t.plan(2);
+ control = new OpenLayers.Control.Scale();
+ t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map($('map'));
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq(control.div.firstChild.innerHTML, "Scale = 1 : 443M", "Internal scale displayed properly.");
+ }
+ // -->
+ </script>
+</head>
+<body>
+ <a id="scale" href="">Scale</a> <br />
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
Modified: sandbox/vector/tests/test_Layer_GeoRSS.html
===================================================================
--- sandbox/vector/tests/test_Layer_GeoRSS.html 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/tests/test_Layer_GeoRSS.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -18,6 +18,22 @@
t.eq( layer.name, "Crschmidt's Places At Platial", "Layer name is correct." );
} );
}
+
+ function test_01_Layer_GeoRSS_AtomParsing (t) {
+ t.plan( 6 );
+ layer = new OpenLayers.Layer.GeoRSS('Test Layer', "./atom-1.0.xml" );
+ t.ok( layer instanceof OpenLayers.Layer.GeoRSS, "new OpenLayers.Layer.GeoRSS returns object" );
+ t.eq( layer.location, "./atom-1.0.xml", "layer.location is correct" );
+ var markers;
+ t.delay_call( 1, function() {
+ t.eq( layer.markers.length, 2, "marker length is correct" );
+ var ll = new OpenLayers.LonLat(29.9805, 36.7702);
+ t.ok( layer.markers[0].lonlat.equals(ll), "lonlat on first marker is correct" );
+ t.like( layer.features[0].data['popupContentHTML'], '<a class="link" href="http://pleiades.stoa.org/places/638896" target="_blank">Unnamed Tumulus</a>', "Link is correct.");
+ t.eq( layer.name, "tumulus", "Layer name is correct." );
+ } );
+ }
+
function test_02_Layer_GeoRSS_draw (t) {
// t.plan(5);
t.plan( 2 );
Modified: sandbox/vector/tests/test_Layer_KaMap.html
===================================================================
--- sandbox/vector/tests/test_Layer_KaMap.html 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/tests/test_Layer_KaMap.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -101,8 +101,33 @@
t.eq( zoom, 2, "getZoomForExtent() returns correct value");
}
+
+ function test_06_Layer_kaMap_mergeNewParams (t) {
+ t.plan( 5 );
+ var map = new OpenLayers.Map("map");
+ var url = "http://octo.metacarta.com/cgi-bin/mapserv";
+ layer = new OpenLayers.Layer.KaMap(name, url, params);
+
+ var newParams = { layers: 'sooper',
+ chickpeas: 'image/png'};
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ t.ok( !layer.grid[0][0].url.match("chickpeas"), "chickpeas is not in URL of first tile in grid" );
+
+ layer.mergeNewParams(newParams);
+
+ t.eq( layer.params.layers, "sooper", "mergeNewParams() overwrites well");
+ t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() adds well");
+ t.ok( layer.grid[0][0].url.match("chickpeas"), "CHICKPEAS is in URL of first tile in grid" );
+
+ newParams.chickpeas = 151;
+
+ t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() makes clean copy of hashtable");
+ }
+
+
/** THIS WOULD BE WHERE THE TESTS WOULD GO FOR
*
* -moveTo
Modified: sandbox/vector/tests/test_Layer_WMS.html
===================================================================
--- sandbox/vector/tests/test_Layer_WMS.html 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/tests/test_Layer_WMS.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -120,18 +120,24 @@
}
function test_06_Layer_WMS_mergeNewParams (t) {
- t.plan( 3 );
+ t.plan( 5 );
+ var map = new OpenLayers.Map("map");
var url = "http://octo.metacarta.com/cgi-bin/mapserv";
layer = new OpenLayers.Layer.WMS(name, url, params);
var newParams = { layers: 'sooper',
chickpeas: 'image/png'};
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ t.ok( !layer.grid[0][0].url.match("CHICKPEAS"), "CHICKPEAS is not in URL of first tile in grid" );
+
layer.mergeNewParams(newParams);
t.eq( layer.params.LAYERS, "sooper", "mergeNewParams() overwrites well");
t.eq( layer.params.CHICKPEAS, "image/png", "mergeNewParams() adds well");
+ t.ok( layer.grid[0][0].url.match("CHICKPEAS"), "CHICKPEAS is in URL of first tile in grid" );
newParams.CHICKPEAS = 151;
Modified: sandbox/vector/tests/test_Util.html
===================================================================
--- sandbox/vector/tests/test_Util.html 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/tests/test_Util.html 2007-03-05 15:43:38 UTC (rev 2308)
@@ -177,7 +177,7 @@
}
function test_07_Util_getParameterString(t) {
- t.plan( 2 );
+ t.plan( 4 );
var params = { foo: "bar",
chicken: 1.5
@@ -185,6 +185,15 @@
t.eq( OpenLayers.Util.getParameterString(params), "foo=bar&chicken=1.5", "getParameterString returns correctly");
t.eq( OpenLayers.Util.getParameterString({'a:':'b='}), "a%3A=b%3D", "getParameterString returns correctly with non-ascii keys/values");
+
+
+ // Parameters which are a list should end up being a comma-seperated
+ // list of the URL encoded strings
+ var params = { foo: ["bar,baz"] };
+ t.eq( OpenLayers.Util.getParameterString(params), "foo=bar%2Cbaz", "getParameterString encodes , correctly in arrays");
+
+ var params = { foo: ["bar","baz,"] };
+ t.eq( OpenLayers.Util.getParameterString(params), "foo=bar,baz%2C", "getParameterString returns with list of CSVs when given a list. ");
}
function test_08_Util_createAlphaImageDiv(t) {
@@ -547,8 +556,8 @@
//PATHNAME
- url1 = "foo.html";
- url2 = "../tests/foo.html";
+ url1 = "foo.html?bar=now#go";
+ url2 = "../tests/../tests/foo.html?bar=now#go";
t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), "relative vs. absolute paths works");
Modified: sandbox/vector/theme/default/style.css
===================================================================
--- sandbox/vector/theme/default/style.css 2007-03-05 15:14:27 UTC (rev 2307)
+++ sandbox/vector/theme/default/style.css 2007-03-05 15:43:38 UTC (rev 2308)
@@ -56,6 +56,7 @@
}
.olControlOverviewMapExtentRectangle {
+ cursor: move;
border: 2px dotted red;
}
.olLayerGeoRSSDescription {
More information about the Commits
mailing list