Merge pull request #11 from ahocevar/3526
Dateline handling improvements for vector layers. Thanks @tschaub for the great collaboration on this. r=tschaub (closes #3526)
This commit is contained in:
@@ -354,14 +354,37 @@ OpenLayers.Bounds = OpenLayers.Class({
|
||||
*
|
||||
* Parameters:
|
||||
* ll - {<OpenLayers.LonLat>}
|
||||
* options - {Object} Optional parameters
|
||||
*
|
||||
* Acceptable options:
|
||||
* inclusive - {Boolean} Whether or not to include the border.
|
||||
* Default is true.
|
||||
* worldBounds - {<OpenLayers.Bounds>} If a worldBounds is provided, the
|
||||
* ll will be considered as contained if it exceeds the world bounds,
|
||||
* but can be wrapped around the dateline so it is contained by this
|
||||
* bounds.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The passed-in lonlat is within this bounds.
|
||||
*/
|
||||
containsLonLat:function(ll, inclusive) {
|
||||
return this.contains(ll.lon, ll.lat, inclusive);
|
||||
containsLonLat: function(ll, options) {
|
||||
if (typeof options === "boolean") {
|
||||
options = {inclusive: options};
|
||||
}
|
||||
options = options || {};
|
||||
var contains = this.contains(ll.lon, ll.lat, options.inclusive),
|
||||
worldBounds = options.worldBounds;
|
||||
if (worldBounds && !contains) {
|
||||
var worldWidth = worldBounds.getWidth();
|
||||
ll = ll.clone();
|
||||
var worldCenterX = (worldBounds.left + worldBounds.right) / 2;
|
||||
var worldsAway = Math.round((ll.lon - worldCenterX) / worldWidth);
|
||||
ll.lon -= (worldsAway * worldWidth);
|
||||
contains = this.containsLonLat(
|
||||
ll, {inclusive: options.inclusive}
|
||||
);
|
||||
}
|
||||
return contains;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -424,48 +447,79 @@ OpenLayers.Bounds = OpenLayers.Class({
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.Bounds>} The target bounds.
|
||||
* options - {Object} Optional parameters.
|
||||
*
|
||||
* Acceptable options:
|
||||
* inclusive - {Boolean} Treat coincident borders as intersecting. Default
|
||||
* is true. If false, bounds that do not overlap but only touch at the
|
||||
* border will not be considered as intersecting.
|
||||
* worldBounds - {<OpenLayers.Bounds>} If a worldBounds is provided, two
|
||||
* bounds will be considered as intersecting if they intersect when
|
||||
* shifted to within the world bounds. This applies only to bounds that
|
||||
* cross or are completely outside the world bounds.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The passed-in bounds object intersects this bounds.
|
||||
*/
|
||||
intersectsBounds:function(bounds, inclusive) {
|
||||
if (inclusive == null) {
|
||||
inclusive = true;
|
||||
intersectsBounds:function(bounds, options) {
|
||||
if (typeof options === "boolean") {
|
||||
options = {inclusive: options};
|
||||
}
|
||||
options = options || {};
|
||||
if (options.worldBounds) {
|
||||
var self = this.wrapDateLine(options.worldBounds);
|
||||
bounds = bounds.wrapDateLine(options.worldBounds);
|
||||
} else {
|
||||
self = this;
|
||||
}
|
||||
if (options.inclusive == null) {
|
||||
options.inclusive = true;
|
||||
}
|
||||
var intersects = false;
|
||||
var mightTouch = (
|
||||
this.left == bounds.right ||
|
||||
this.right == bounds.left ||
|
||||
this.top == bounds.bottom ||
|
||||
this.bottom == bounds.top
|
||||
self.left == bounds.right ||
|
||||
self.right == bounds.left ||
|
||||
self.top == bounds.bottom ||
|
||||
self.bottom == bounds.top
|
||||
);
|
||||
|
||||
// if the two bounds only touch at an edge, and inclusive is false,
|
||||
// then the bounds don't *really* intersect.
|
||||
if (inclusive || !mightTouch) {
|
||||
if (options.inclusive || !mightTouch) {
|
||||
// otherwise, if one of the boundaries even partially contains another,
|
||||
// inclusive of the edges, then they do intersect.
|
||||
var inBottom = (
|
||||
((bounds.bottom >= this.bottom) && (bounds.bottom <= this.top)) ||
|
||||
((this.bottom >= bounds.bottom) && (this.bottom <= bounds.top))
|
||||
((bounds.bottom >= self.bottom) && (bounds.bottom <= self.top)) ||
|
||||
((self.bottom >= bounds.bottom) && (self.bottom <= bounds.top))
|
||||
);
|
||||
var inTop = (
|
||||
((bounds.top >= this.bottom) && (bounds.top <= this.top)) ||
|
||||
((this.top > bounds.bottom) && (this.top < bounds.top))
|
||||
((bounds.top >= self.bottom) && (bounds.top <= self.top)) ||
|
||||
((self.top > bounds.bottom) && (self.top < bounds.top))
|
||||
);
|
||||
var inLeft = (
|
||||
((bounds.left >= this.left) && (bounds.left <= this.right)) ||
|
||||
((this.left >= bounds.left) && (this.left <= bounds.right))
|
||||
((bounds.left >= self.left) && (bounds.left <= self.right)) ||
|
||||
((self.left >= bounds.left) && (self.left <= bounds.right))
|
||||
);
|
||||
var inRight = (
|
||||
((bounds.right >= this.left) && (bounds.right <= this.right)) ||
|
||||
((this.right >= bounds.left) && (this.right <= bounds.right))
|
||||
((bounds.right >= self.left) && (bounds.right <= self.right)) ||
|
||||
((self.right >= bounds.left) && (self.right <= bounds.right))
|
||||
);
|
||||
intersects = ((inBottom || inTop) && (inLeft || inRight));
|
||||
}
|
||||
// document me
|
||||
if (options.worldBounds && !intersects) {
|
||||
var world = options.worldBounds;
|
||||
var width = world.getWidth();
|
||||
var selfCrosses = !world.containsBounds(self);
|
||||
var boundsCrosses = !world.containsBounds(bounds);
|
||||
if (selfCrosses && !boundsCrosses) {
|
||||
bounds = bounds.add(-width, 0);
|
||||
intersects = self.intersectsBounds(bounds, {inclusive: options.inclusive});
|
||||
} else if (boundsCrosses && !selfCrosses) {
|
||||
self = self.add(-width, 0);
|
||||
intersects = bounds.intersectsBounds(self, {inclusive: options.inclusive});
|
||||
}
|
||||
}
|
||||
return intersects;
|
||||
},
|
||||
|
||||
@@ -573,8 +627,9 @@ OpenLayers.Bounds = OpenLayers.Class({
|
||||
* a different bounds value if this bounds is
|
||||
* *entirely* outside of the maxExtent. If this
|
||||
* bounds straddles the dateline (is part in/part
|
||||
* out of maxExtent), the returned bounds will be
|
||||
* merely a copy of this one.
|
||||
* out of maxExtent), the returned bounds will always
|
||||
* cross the left edge of the given maxExtent.
|
||||
*.
|
||||
*/
|
||||
wrapDateLine: function(maxExtent, options) {
|
||||
options = options || {};
|
||||
@@ -585,18 +640,26 @@ OpenLayers.Bounds = OpenLayers.Class({
|
||||
var newBounds = this.clone();
|
||||
|
||||
if (maxExtent) {
|
||||
var width = maxExtent.getWidth();
|
||||
|
||||
//shift right?
|
||||
while ( newBounds.left < maxExtent.left &&
|
||||
(newBounds.right - rightTolerance) <= maxExtent.left ) {
|
||||
newBounds = newBounds.add(maxExtent.getWidth(), 0);
|
||||
}
|
||||
//shift right?
|
||||
while (newBounds.left < maxExtent.left &&
|
||||
newBounds.right - rightTolerance <= maxExtent.left ) {
|
||||
newBounds = newBounds.add(width, 0);
|
||||
}
|
||||
|
||||
//shift left?
|
||||
while ( (newBounds.left + leftTolerance) >= maxExtent.right &&
|
||||
//shift left?
|
||||
while (newBounds.left + leftTolerance >= maxExtent.right &&
|
||||
newBounds.right > maxExtent.right ) {
|
||||
newBounds = newBounds.add(-maxExtent.getWidth(), 0);
|
||||
}
|
||||
newBounds = newBounds.add(-width, 0);
|
||||
}
|
||||
|
||||
// crosses right only? force left
|
||||
var newLeft = newBounds.left + leftTolerance;
|
||||
if (newLeft < maxExtent.right && newLeft > maxExtent.left &&
|
||||
newBounds.right - rightTolerance > maxExtent.right) {
|
||||
newBounds = newBounds.add(-width, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return newBounds;
|
||||
|
||||
@@ -517,15 +517,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
*/
|
||||
calculateGridLayout: function(bounds, origin, resolution) {
|
||||
bounds = bounds.clone();
|
||||
if (this.map.baseLayer.wrapDateLine) {
|
||||
var maxExtent = this.map.getMaxExtent(),
|
||||
width = maxExtent.getWidth();
|
||||
// move the bounds one world width to the right until the origin is
|
||||
// within the world extent
|
||||
while (bounds.left < maxExtent.left) {
|
||||
bounds.left += width;
|
||||
bounds.right += width;
|
||||
}
|
||||
var map = this.map;
|
||||
if (map.wrapDateLine) {
|
||||
bounds = bounds.wrapDateLine(map.getMaxExtent());
|
||||
}
|
||||
|
||||
var tilelon = resolution * this.tileSize.w;
|
||||
|
||||
@@ -1909,7 +1909,8 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
var valid = false;
|
||||
if (lonlat != null) {
|
||||
var maxExtent = this.getMaxExtent();
|
||||
valid = maxExtent.containsLonLat(lonlat);
|
||||
var worldBounds = this.baseLayer.wrapDateLine && maxExtent;
|
||||
valid = maxExtent.containsLonLat(lonlat, {worldBounds: worldBounds});
|
||||
}
|
||||
return valid;
|
||||
},
|
||||
@@ -2223,10 +2224,7 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
}
|
||||
//if the bounds was straddling (see above), then the center point
|
||||
// we got from it was wrong. So we take our new bounds and ask it
|
||||
// for the center. Because our new bounds is at least partially
|
||||
// outside the bounds of maxExtent, the new calculated center
|
||||
// might also be. We don't want to pass a bad center value to
|
||||
// setCenter, so we have it wrap itself across the date line.
|
||||
// for the center.
|
||||
//
|
||||
center = bounds.getCenterLonLat().wrapDateLine(maxExtent);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,14 @@ OpenLayers.Renderer = OpenLayers.Class({
|
||||
*/
|
||||
map: null,
|
||||
|
||||
/**
|
||||
* Property: featureDx
|
||||
* {Number} Feature offset in x direction. Will be calculated for and
|
||||
* applied to the current feature while rendering (see
|
||||
* <calculateFeatureDx>).
|
||||
*/
|
||||
featureDx: 0,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Renderer
|
||||
*
|
||||
@@ -122,12 +130,21 @@ OpenLayers.Renderer = OpenLayers.Class({
|
||||
* Parameters:
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
* resolutionChanged - {Boolean}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true to notify the layer that the new extent does not exceed
|
||||
* the coordinate range, and the features will not need to be redrawn.
|
||||
* False otherwise.
|
||||
*/
|
||||
setExtent: function(extent, resolutionChanged) {
|
||||
this.extent = extent.clone();
|
||||
if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
|
||||
this.extent = extent.wrapDateLine(this.map.getMaxExtent());
|
||||
}
|
||||
if (resolutionChanged) {
|
||||
this.resolution = null;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -179,11 +196,18 @@ OpenLayers.Renderer = OpenLayers.Class({
|
||||
if (feature.geometry) {
|
||||
var bounds = feature.geometry.getBounds();
|
||||
if(bounds) {
|
||||
if (!bounds.intersectsBounds(this.extent)) {
|
||||
var worldBounds;
|
||||
if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
|
||||
worldBounds = this.map.getMaxExtent();
|
||||
}
|
||||
if (!bounds.intersectsBounds(this.extent, {worldBounds: worldBounds})) {
|
||||
style = {display: "none"};
|
||||
} else {
|
||||
this.calculateFeatureDx(bounds, worldBounds);
|
||||
}
|
||||
var rendered = this.drawGeometry(feature.geometry, style, feature.id);
|
||||
if(style.display != "none" && style.label && rendered !== false) {
|
||||
|
||||
var location = feature.geometry.getCentroid();
|
||||
if(style.labelXOffset || style.labelYOffset) {
|
||||
var xOffset = isNaN(style.labelXOffset) ? 0 : style.labelXOffset;
|
||||
@@ -200,6 +224,29 @@ OpenLayers.Renderer = OpenLayers.Class({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: calculateFeatureDx
|
||||
* {Number} Calculates the feature offset in x direction. Looking at the
|
||||
* center of the feature bounds and the renderer extent, we calculate how
|
||||
* many world widths the two are away from each other. This distance is
|
||||
* used to shift the feature as close as possible to the center of the
|
||||
* current enderer extent, which ensures that the feature is visible in the
|
||||
* current viewport.
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.Bounds>} Bounds of the feature
|
||||
* worldBounds - {<OpenLayers.Bounds>} Bounds of the world
|
||||
*/
|
||||
calculateFeatureDx: function(bounds, worldBounds) {
|
||||
this.featureDx = 0;
|
||||
if (worldBounds) {
|
||||
var worldWidth = worldBounds.getWidth(),
|
||||
rendererCenterX = (this.extent.left + this.extent.right) / 2,
|
||||
featureCenterX = (bounds.left + bounds.right) / 2,
|
||||
worldsAway = Math.round((featureCenterX - rendererCenterX) / worldWidth);
|
||||
this.featureDx = worldsAway * worldWidth;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawGeometry
|
||||
|
||||
@@ -70,6 +70,25 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setExtent
|
||||
* Set the visible part of the layer.
|
||||
*
|
||||
* Parameters:
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
* resolutionChanged - {Boolean}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true to notify the layer that the new extent does not exceed
|
||||
* the coordinate range, and the features will not need to be redrawn.
|
||||
* False otherwise.
|
||||
*/
|
||||
setExtent: function() {
|
||||
OpenLayers.Renderer.prototype.setExtent.apply(this, arguments);
|
||||
// always redraw features
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: eraseGeometry
|
||||
* Erase a geometry from the renderer. Because the Canvas renderer has
|
||||
@@ -141,8 +160,15 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
style = this.applyDefaultSymbolizer(style || feature.style);
|
||||
// don't render if display none or feature outside extent
|
||||
var bounds = feature.geometry.getBounds();
|
||||
rendered = (style.display !== "none") && !!bounds &&
|
||||
bounds.intersectsBounds(this.extent);
|
||||
|
||||
var worldBounds;
|
||||
if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
|
||||
worldBounds = this.map.getMaxExtent();
|
||||
}
|
||||
|
||||
var intersects = bounds && bounds.intersectsBounds(this.extent, {worldBounds: worldBounds});
|
||||
|
||||
rendered = (style.display !== "none") && !!bounds && intersects;
|
||||
if (rendered) {
|
||||
// keep track of what we have rendered for redraw
|
||||
this.features[feature.id] = [feature, style];
|
||||
@@ -573,7 +599,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
getLocalXY: function(point) {
|
||||
var resolution = this.getResolution();
|
||||
var extent = this.extent;
|
||||
var x = (point.x / resolution + (-extent.left / resolution));
|
||||
var x = ((point.x - this.featureDx) / resolution + (-extent.left / resolution));
|
||||
var y = ((extent.top / resolution) - point.y / resolution);
|
||||
return [x, y];
|
||||
},
|
||||
@@ -659,12 +685,15 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
this.hitContext.clearRect(0, 0, width, height);
|
||||
}
|
||||
var labelMap = [];
|
||||
var feature, style;
|
||||
var feature, geometry, style;
|
||||
var worldBounds = (this.map.baseLayer && this.map.baseLayer.wrapDateLine) && this.map.getMaxExtent();
|
||||
for (var id in this.features) {
|
||||
if (!this.features.hasOwnProperty(id)) { continue; }
|
||||
feature = this.features[id][0];
|
||||
geometry = feature.geometry;
|
||||
this.calculateFeatureDx(geometry.getBounds(), worldBounds);
|
||||
style = this.features[id][1];
|
||||
this.drawGeometry(feature.geometry, style, feature.id);
|
||||
this.drawGeometry(geometry, style, feature.id);
|
||||
if(style.label) {
|
||||
labelMap.push([feature, style]);
|
||||
}
|
||||
|
||||
@@ -373,6 +373,28 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
*/
|
||||
xmlns: null,
|
||||
|
||||
/**
|
||||
* Property: xOffset
|
||||
* {Number} Offset to apply to the renderer viewport translation in x
|
||||
* direction. If the renderer extent's center is on the right of the
|
||||
* dateline (i.e. exceeds the world bounds), we shift the viewport to the
|
||||
* left by one world width. This avoids that features disappear from the
|
||||
* map viewport. Because our dateline handling logic in other places
|
||||
* ensures that extents crossing the dateline always have a center
|
||||
* exceeding the world bounds on the left, we need this offset to make sure
|
||||
* that the same is true for the renderer extent in pixel space as well.
|
||||
*/
|
||||
xOffset: 0,
|
||||
|
||||
/**
|
||||
* Property: rightOfDateLine
|
||||
* {Boolean} Keeps track of the location of the map extent relative to the
|
||||
* date line. The <setExtent> method compares this value (which is the one
|
||||
* from the previous <setExtent> call) with the current position of the map
|
||||
* extent relative to the date line and updates the xOffset when the extent
|
||||
* has moved from one side of the date line to the other.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Property: Indexer
|
||||
* {<OpenLayers.ElementIndexer>} An instance of OpenLayers.ElementsIndexer
|
||||
@@ -458,6 +480,41 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
this.indexer.clear();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setExtent
|
||||
* Set the visible part of the layer.
|
||||
*
|
||||
* Parameters:
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
* resolutionChanged - {Boolean}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} true to notify the layer that the new extent does not exceed
|
||||
* the coordinate range, and the features will not need to be redrawn.
|
||||
* False otherwise.
|
||||
*/
|
||||
setExtent: function(extent, resolutionChanged) {
|
||||
var coordSysUnchanged = OpenLayers.Renderer.prototype.setExtent.apply(this, arguments);
|
||||
var resolution = this.getResolution();
|
||||
if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
|
||||
coordSysUnchanged = this.featureDx === 0;
|
||||
var rightOfDateLine,
|
||||
world = this.map.getMaxExtent();
|
||||
if (world.right > extent.left && world.right < extent.right) {
|
||||
rightOfDateLine = true;
|
||||
} else if (world.left > extent.left && world.left < extent.right) {
|
||||
rightOfDateLine = false;
|
||||
}
|
||||
if (rightOfDateLine !== this.rightOfDateLine || resolutionChanged) {
|
||||
coordSysUnchanged = false;
|
||||
this.xOffset = rightOfDateLine === true ?
|
||||
world.getWidth() / resolution : 0;
|
||||
}
|
||||
this.rightOfDateLine = rightOfDateLine;
|
||||
}
|
||||
return coordSysUnchanged;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getNodeType
|
||||
|
||||
@@ -114,12 +114,11 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* False otherwise.
|
||||
*/
|
||||
setExtent: function(extent, resolutionChanged) {
|
||||
OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
|
||||
arguments);
|
||||
var coordSysUnchanged = OpenLayers.Renderer.Elements.prototype.setExtent.apply(this, arguments);
|
||||
|
||||
var resolution = this.getResolution();
|
||||
var left = -extent.left / resolution;
|
||||
var top = extent.top / resolution;
|
||||
var resolution = this.getResolution(),
|
||||
left = -extent.left / resolution,
|
||||
top = extent.top / resolution;
|
||||
|
||||
// If the resolution has changed, start over changing the corner, because
|
||||
// the features will redraw.
|
||||
@@ -130,15 +129,15 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var extentString = "0 0 " + this.size.w + " " + this.size.h;
|
||||
|
||||
this.rendererRoot.setAttributeNS(null, "viewBox", extentString);
|
||||
this.translate(0, 0);
|
||||
this.translate(this.xOffset, 0);
|
||||
return true;
|
||||
} else {
|
||||
var inRange = this.translate(left - this.left, top - this.top);
|
||||
inRange = this.translate(left - this.left + this.xOffset, top - this.top);
|
||||
if (!inRange) {
|
||||
// recenter the coordinate system
|
||||
this.setExtent(extent, true);
|
||||
}
|
||||
return inRange;
|
||||
return coordSysUnchanged && inRange;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -505,7 +504,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
*/
|
||||
drawCircle: function(node, geometry, radius) {
|
||||
var resolution = this.getResolution();
|
||||
var x = (geometry.x / resolution + this.left);
|
||||
var x = ((geometry.x - this.featureDx) / resolution + this.left);
|
||||
var y = (this.top - geometry.y / resolution);
|
||||
|
||||
if (this.inValidRange(x, y)) {
|
||||
@@ -615,7 +614,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
*/
|
||||
drawRectangle: function(node, geometry) {
|
||||
var resolution = this.getResolution();
|
||||
var x = (geometry.x / resolution + this.left);
|
||||
var x = ((geometry.x - this.featureDx) / resolution + this.left);
|
||||
var y = (this.top - geometry.y / resolution);
|
||||
|
||||
if (this.inValidRange(x, y)) {
|
||||
@@ -681,7 +680,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
drawText: function(featureId, style, location) {
|
||||
var resolution = this.getResolution();
|
||||
|
||||
var x = (location.x / resolution + this.left);
|
||||
var x = ((location.x - this.featureDx) / resolution + this.left);
|
||||
var y = (location.y / resolution - this.top);
|
||||
|
||||
var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, "text");
|
||||
@@ -833,9 +832,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var resolution = this.getResolution();
|
||||
var maxX = this.MAX_PIXEL - this.translationParameters.x;
|
||||
var maxY = this.MAX_PIXEL - this.translationParameters.y;
|
||||
var x1 = goodComponent.x / resolution + this.left;
|
||||
var x1 = (goodComponent.x - this.featureDx) / resolution + this.left;
|
||||
var y1 = this.top - goodComponent.y / resolution;
|
||||
var x2 = badComponent.x / resolution + this.left;
|
||||
var x2 = (badComponent.x - this.featureDx) / resolution + this.left;
|
||||
var y2 = this.top - badComponent.y / resolution;
|
||||
var k;
|
||||
if (x2 < -maxX || x2 > maxX) {
|
||||
@@ -862,7 +861,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
*/
|
||||
getShortString: function(point) {
|
||||
var resolution = this.getResolution();
|
||||
var x = (point.x / resolution + this.left);
|
||||
var x = ((point.x - this.featureDx) / resolution + this.left);
|
||||
var y = (this.top - point.y / resolution);
|
||||
|
||||
if (this.inValidRange(x, y)) {
|
||||
@@ -908,7 +907,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var id = this.container.id + "-" + graphicName;
|
||||
|
||||
// check if symbol already exists in the defs
|
||||
var existing = document.getElementById(id)
|
||||
var existing = document.getElementById(id);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
@@ -90,8 +90,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
* the coordinate range, and the features will not need to be redrawn.
|
||||
*/
|
||||
setExtent: function(extent, resolutionChanged) {
|
||||
OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
|
||||
arguments);
|
||||
var coordSysUnchanged = OpenLayers.Renderer.Elements.prototype.setExtent.apply(this, arguments);
|
||||
var resolution = this.getResolution();
|
||||
|
||||
var left = (extent.left/resolution) | 0;
|
||||
@@ -106,7 +105,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
}
|
||||
|
||||
|
||||
var org = left + " " + top;
|
||||
var org = (left - this.xOffset) + " " + top;
|
||||
this.root.coordorigin = org;
|
||||
var roots = [this.root, this.vectorRoot, this.textRoot];
|
||||
var root;
|
||||
@@ -121,7 +120,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
// matches the display Y axis of the map
|
||||
this.root.style.flip = "y";
|
||||
|
||||
return true;
|
||||
return coordSysUnchanged;
|
||||
},
|
||||
|
||||
|
||||
@@ -226,7 +225,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var yOffset = (style.graphicYOffset != undefined) ?
|
||||
style.graphicYOffset : -(0.5 * height);
|
||||
|
||||
node.style.left = (((geometry.x/resolution - this.offset.x)+xOffset) | 0) + "px";
|
||||
node.style.left = ((((geometry.x - this.featureDx)/resolution - this.offset.x)+xOffset) | 0) + "px";
|
||||
node.style.top = (((geometry.y/resolution - this.offset.y)-(yOffset+height)) | 0) + "px";
|
||||
node.style.width = width + "px";
|
||||
node.style.height = height + "px";
|
||||
@@ -483,9 +482,9 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var resolution = this.getResolution();
|
||||
|
||||
var scaledBox =
|
||||
new OpenLayers.Bounds((bbox.left/resolution - this.offset.x) | 0,
|
||||
new OpenLayers.Bounds(((bbox.left - this.featureDx)/resolution - this.offset.x) | 0,
|
||||
(bbox.bottom/resolution - this.offset.y) | 0,
|
||||
(bbox.right/resolution - this.offset.x) | 0,
|
||||
((bbox.right - this.featureDx)/resolution - this.offset.x) | 0,
|
||||
(bbox.top/resolution - this.offset.y) | 0);
|
||||
|
||||
// Set the internal coordinate system to draw the path
|
||||
@@ -652,7 +651,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
if(!isNaN(geometry.x)&& !isNaN(geometry.y)) {
|
||||
var resolution = this.getResolution();
|
||||
|
||||
node.style.left = (((geometry.x /resolution - this.offset.x) | 0) - radius) + "px";
|
||||
node.style.left = ((((geometry.x - this.featureDx) /resolution - this.offset.x) | 0) - radius) + "px";
|
||||
node.style.top = (((geometry.y /resolution - this.offset.y) | 0) - radius) + "px";
|
||||
|
||||
var diameter = radius * 2;
|
||||
@@ -718,7 +717,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var comp, x, y;
|
||||
for (var i = 0; i < numComponents; i++) {
|
||||
comp = geometry.components[i];
|
||||
x = (comp.x/resolution - this.offset.x) | 0;
|
||||
x = ((comp.x - this.featureDx)/resolution - this.offset.x) | 0;
|
||||
y = (comp.y/resolution - this.offset.y) | 0;
|
||||
parts[i] = " " + x + "," + y + " l ";
|
||||
}
|
||||
@@ -754,7 +753,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
second = null;
|
||||
for (i=0, ii=points.length; i<ii; i++) {
|
||||
comp = points[i];
|
||||
x = (comp.x / resolution - this.offset.x) | 0;
|
||||
x = ((comp.x - this.featureDx) / resolution - this.offset.x) | 0;
|
||||
y = (comp.y / resolution - this.offset.y) | 0;
|
||||
pathComp = " " + x + "," + y;
|
||||
path.push(pathComp);
|
||||
@@ -801,7 +800,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
drawRectangle: function(node, geometry) {
|
||||
var resolution = this.getResolution();
|
||||
|
||||
node.style.left = ((geometry.x/resolution - this.offset.x) | 0) + "px";
|
||||
node.style.left = (((geometry.x - this.featureDx)/resolution - this.offset.x) | 0) + "px";
|
||||
node.style.top = ((geometry.y/resolution - this.offset.y) | 0) + "px";
|
||||
node.style.width = ((geometry.width/resolution) | 0) + "px";
|
||||
node.style.height = ((geometry.height/resolution) | 0) + "px";
|
||||
@@ -823,7 +822,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var textbox = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_textbox", "olv:textbox");
|
||||
|
||||
var resolution = this.getResolution();
|
||||
label.style.left = ((location.x/resolution - this.offset.x) | 0) + "px";
|
||||
label.style.left = (((location.x - this.featureDx)/resolution - this.offset.x) | 0) + "px";
|
||||
label.style.top = ((location.y/resolution - this.offset.y) | 0) + "px";
|
||||
label.style.flip = "y";
|
||||
|
||||
@@ -900,7 +899,7 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {
|
||||
var comp, x, y;
|
||||
for (var i=0, len=geometry.components.length; i<len; i++) {
|
||||
comp = geometry.components[i];
|
||||
x = (comp.x / resolution - this.offset.x) | 0;
|
||||
x = ((comp.x - this.featureDx) / resolution - this.offset.x) | 0;
|
||||
y = (comp.y / resolution - this.offset.y) | 0;
|
||||
if ((i%3)==0 && (i/3)==0) {
|
||||
path.push("m");
|
||||
|
||||
@@ -175,29 +175,10 @@ OpenLayers.Tile = OpenLayers.Class({
|
||||
var withinMaxExtent = false,
|
||||
maxExtent = this.layer.maxExtent;
|
||||
if (maxExtent) {
|
||||
// prepare up to 3 versions of the layer's maxExtent, to make sure
|
||||
// that the intersectsBounds check below catches all cases of
|
||||
// extents that cross the dateline:
|
||||
// (1) left bound positive, right bound negative (wrapped)
|
||||
// (2) left bound positive, right bound positive (exceeding world)
|
||||
// (3) left bound negative (exceeding world), right bound positive
|
||||
var maxExtents = [maxExtent];
|
||||
if (this.layer.map.baseLayer.wrapDateLine) {
|
||||
if (maxExtent.left > maxExtent.right) {
|
||||
var worldWidth = this.layer.map.getMaxExtent().getWidth();
|
||||
maxExtent = this.layer.maxExtent.clone();
|
||||
maxExtent.left -= worldWidth;
|
||||
maxExtents.push(maxExtent);
|
||||
maxExtent = this.layer.maxExtent.clone();
|
||||
maxExtent.right += worldWidth;
|
||||
maxExtents.push(maxExtent);
|
||||
}
|
||||
}
|
||||
for (var i=maxExtents.length-1; i>=0; --i) {
|
||||
if (this.bounds.intersectsBounds(maxExtents[i], false)) {
|
||||
withinMaxExtent = true;
|
||||
break;
|
||||
}
|
||||
var map = this.layer.map;
|
||||
var worldBounds = map.baseLayer.wrapDateLine && map.getMaxExtent();
|
||||
if (this.bounds.intersectsBounds(maxExtent, {inclusive: false, worldBounds: worldBounds})) {
|
||||
withinMaxExtent = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,9 +194,13 @@ OpenLayers.Tile = OpenLayers.Class({
|
||||
*/
|
||||
setBounds: function(bounds) {
|
||||
bounds = bounds.clone();
|
||||
if (this.layer.map && this.layer.map.baseLayer.wrapDateLine) {
|
||||
var worldExtent = this.layer.map.getMaxExtent();
|
||||
bounds = bounds.wrapDateLine(worldExtent);
|
||||
if (this.layer.map.baseLayer.wrapDateLine) {
|
||||
var worldExtent = this.layer.map.getMaxExtent(),
|
||||
tolerance = this.layer.map.getResolution();
|
||||
bounds = bounds.wrapDateLine(worldExtent, {
|
||||
leftTolerance: tolerance,
|
||||
rightTolerance: tolerance
|
||||
});
|
||||
}
|
||||
this.bounds = bounds;
|
||||
},
|
||||
|
||||
@@ -124,6 +124,43 @@
|
||||
t.eq( bounds.containsLonLat(ll), bounds.contains(ll.lon, ll.lat), "containsLonLat works");
|
||||
|
||||
}
|
||||
|
||||
function test_containsLonLat_wraped(t) {
|
||||
|
||||
var worldBounds = new OpenLayers.Bounds(-180, -90, 180, 90);
|
||||
|
||||
var cases = [{
|
||||
ll: [0, 0], bbox: [-10, -10, 10, 10], contained: true
|
||||
}, {
|
||||
ll: [20, 0], bbox: [-10, -10, 10, 10], contained: false
|
||||
}, {
|
||||
ll: [360, 0], bbox: [-10, -10, 10, 10], contained: true
|
||||
}, {
|
||||
ll: [380, 0], bbox: [-10, -10, 10, 10], contained: false
|
||||
}, {
|
||||
ll: [725, 5], bbox: [-10, -10, 10, 10], contained: true
|
||||
}, {
|
||||
ll: [-355, -5], bbox: [-10, -10, 10, 10], contained: true
|
||||
}, {
|
||||
ll: [-715, 5], bbox: [-10, -10, 10, 10], contained: true
|
||||
}, {
|
||||
ll: [-735, 5], bbox: [-10, -10, 10, 10], contained: false
|
||||
}, {
|
||||
ll: [-180 * 50, 5], bbox: [-10, -10, 10, 10], contained: true
|
||||
}];
|
||||
|
||||
var len = cases.length;
|
||||
t.plan(len);
|
||||
|
||||
var c, bounds, loc;
|
||||
for (var i=0; i<len; ++i) {
|
||||
c = cases[i];
|
||||
loc = new OpenLayers.LonLat(c.ll[0], c.ll[1]);
|
||||
bounds = new OpenLayers.Bounds.fromArray(c.bbox);
|
||||
t.eq(bounds.containsLonLat(loc, {worldBounds: worldBounds}), c.contained, "case " + i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_Bounds_fromString(t) {
|
||||
t.plan( 12 );
|
||||
@@ -555,7 +592,8 @@
|
||||
//straddling right
|
||||
testBounds = simpleBounds.add(10,0);
|
||||
wrappedBounds = testBounds.wrapDateLine(maxExtent);
|
||||
t.ok(wrappedBounds.equals(testBounds), "wrapping a bounds that straddles the right of maxextent does nothing");
|
||||
desiredBounds = testBounds.add(-maxExtent.getWidth(), 0)
|
||||
t.ok(wrappedBounds.equals(desiredBounds), "wrapping a bounds that straddles the right of maxextent moves extent to left side of the world");
|
||||
|
||||
//right leftTolerance
|
||||
testBounds = simpleBounds.add(14,0);
|
||||
|
||||
120
tests/Map.html
120
tests/Map.html
@@ -1386,54 +1386,86 @@
|
||||
}
|
||||
|
||||
function test_Map_zoomToExtent(t) {
|
||||
t.plan(8);
|
||||
|
||||
t.plan(9);
|
||||
|
||||
var m = {
|
||||
'baseLayer': {
|
||||
'wrapDateLine': false
|
||||
},
|
||||
'setCenter': function(center, zoomLevel) {
|
||||
g_Center = center;
|
||||
g_ZoomLevel = zoomLevel;
|
||||
},
|
||||
'getZoomForExtent': function(bounds, closest) {
|
||||
t.ok(bounds.equals(g_ToCenterBounds), "bounds correctly passed into getZoomForExtent()");
|
||||
t.ok(closest == g_Closest, "closest correctly passed along to getZoomForExtent()");
|
||||
return g_ZoomLevelReturn;
|
||||
}
|
||||
};
|
||||
|
||||
//no wrapDateLine
|
||||
g_ZoomLevelReturn = {};
|
||||
g_Bounds = new OpenLayers.Bounds(-20,-15,0,5);
|
||||
g_ExpectedCenter = new OpenLayers.LonLat(-10,-5);
|
||||
g_Closest = {};
|
||||
g_ToCenterBounds = g_Bounds;
|
||||
var args = [g_Bounds, g_Closest];
|
||||
OpenLayers.Map.prototype.zoomToExtent.apply(m, args);
|
||||
var map = new OpenLayers.Map("map");
|
||||
var layer = new OpenLayers.Layer(null, {isBaseLayer: true});
|
||||
map.addLayer(layer);
|
||||
|
||||
t.ok(g_Center.equals(g_ExpectedCenter), "setCenter called on correct center");
|
||||
t.ok(g_ZoomLevel == g_ZoomLevelReturn, "correctly passes along zoom level as returned from getZoomForExtent()");
|
||||
|
||||
|
||||
//wrapDateLine
|
||||
m.baseLayer.wrapDateLine = true;
|
||||
m.getMaxExtent = function() { return new OpenLayers.Bounds(-200,-200,200,200); };
|
||||
|
||||
g_ZoomLevelReturn = {};
|
||||
g_BoundsCenter = {};
|
||||
g_Bounds = new OpenLayers.Bounds(160,-60,-60,60);
|
||||
g_ExpectedCenter = new OpenLayers.LonLat(-150,0);
|
||||
g_Closest = {};
|
||||
g_ToCenterBounds = new OpenLayers.Bounds(160,-60,340,60);
|
||||
var args = [g_Bounds, g_Closest];
|
||||
OpenLayers.Map.prototype.zoomToExtent.apply(m, args);
|
||||
t.ok(g_Center.equals(g_ExpectedCenter), "setCenter called on correct center");
|
||||
t.ok(g_ZoomLevel == g_ZoomLevelReturn, "correctly passes along zoom level as returned from getZoomForExtent()");
|
||||
|
||||
var bounds = new OpenLayers.Bounds(-160, 15, -50, 69);
|
||||
var center;
|
||||
|
||||
// default for closest
|
||||
map.zoomToExtent(bounds);
|
||||
center = map.getCenter();
|
||||
t.eq(center.lon, -105, "a) correct x");
|
||||
t.eq(center.lat, 42, "a) correct y");
|
||||
t.eq(map.getZoom(), 2, "a) correct zoom");
|
||||
|
||||
// false for closest
|
||||
map.zoomToExtent(bounds, false);
|
||||
center = map.getCenter();
|
||||
t.eq(center.lon, -105, "b) correct x");
|
||||
t.eq(center.lat, 42, "b) correct y");
|
||||
t.eq(map.getZoom(), 2, "b) correct zoom");
|
||||
|
||||
// true for closest
|
||||
map.zoomToExtent(bounds, true);
|
||||
center = map.getCenter();
|
||||
t.eq(center.lon, -105, "c) correct x");
|
||||
t.eq(center.lat, 42, "c) correct y");
|
||||
t.eq(map.getZoom(), 3, "c) correct zoom");
|
||||
|
||||
map.destroy();
|
||||
}
|
||||
|
||||
function test_Map_zoomToExtent_wrapped(t) {
|
||||
t.plan(9);
|
||||
|
||||
var map = new OpenLayers.Map("map");
|
||||
var layer = new OpenLayers.Layer(null, {isBaseLayer: true, wrapDateLine: true});
|
||||
map.addLayer(layer);
|
||||
|
||||
var bounds, center;
|
||||
|
||||
var cases = [{
|
||||
// real world
|
||||
bbox: [120, -20, 140, 0],
|
||||
center: [130, -10]
|
||||
}, {
|
||||
// one world to the right
|
||||
bbox: [220, -45, 240, 45],
|
||||
center: [-130, 0]
|
||||
}, {
|
||||
// two worlds to the right
|
||||
bbox: [550, -15, 560, 5],
|
||||
center: [-165, -5]
|
||||
}, {
|
||||
// one world to the left
|
||||
bbox: [-240, -15, -220, 5],
|
||||
center: [130, -5]
|
||||
}, {
|
||||
// two worlds to the left
|
||||
bbox: [-600, -15, -580, 5],
|
||||
center: [130, -5]
|
||||
}];
|
||||
|
||||
var num = cases.length;
|
||||
t.plan(num * 2);
|
||||
|
||||
var c, bounds, center;
|
||||
for (var i=0; i<num; ++i) {
|
||||
c = cases[i];
|
||||
bounds = OpenLayers.Bounds.fromArray(c.bbox);
|
||||
map.zoomToExtent(bounds);
|
||||
center = map.getCenter();
|
||||
t.eq(center.lon, c.center[0], "y: " + bounds);
|
||||
t.eq(center.lat, c.center[1], "x: " + bounds);
|
||||
}
|
||||
|
||||
map.destroy();
|
||||
}
|
||||
|
||||
|
||||
function test_allOverlays(t) {
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
t.plan(2);
|
||||
|
||||
var r = new OpenLayers.Renderer();
|
||||
r.map = {};
|
||||
var extent = new OpenLayers.Bounds(1,2,3,4);
|
||||
r.resolution = 1;
|
||||
r.setExtent(extent, true);
|
||||
@@ -52,6 +53,21 @@
|
||||
t.eq(resolution, map.getResolution(), "resolution matches the map resolution");
|
||||
t.eq(r.resolution, resolution, "resolution is correctly set");
|
||||
}
|
||||
|
||||
function test_calculateFeatureDx(t) {
|
||||
t.plan(4);
|
||||
var r = new OpenLayers.Renderer();
|
||||
r.extent = new OpenLayers.Bounds(177, -2, 183, 2);
|
||||
var worldBounds = new OpenLayers.Bounds(-180,-90,180,90);
|
||||
r.calculateFeatureDx(new OpenLayers.Bounds(179,-1,181,1), worldBounds);
|
||||
t.eq(r.featureDx, 0, "no offset for feature inside extent");
|
||||
r.calculateFeatureDx(new OpenLayers.Bounds(-181,-1,-179,1), worldBounds);
|
||||
t.eq(r.featureDx, -360, "negative offset for feature on other end of world");
|
||||
r.calculateFeatureDx(new OpenLayers.Bounds(359,-1,361,1), worldBounds);
|
||||
t.eq(r.featureDx, 360, "positive offset for feature that is one world away");
|
||||
r.calculateFeatureDx(new OpenLayers.Bounds(719,-1,721,1), worldBounds);
|
||||
t.eq(r.featureDx, 720, "correct offset for feature that is two worlds away");
|
||||
}
|
||||
|
||||
function test_Renderer_destroy(t) {
|
||||
t.plan(5);
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
<script src="../OLLoader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var supported = OpenLayers.Renderer.Canvas.prototype.supported();
|
||||
|
||||
var map, layer;
|
||||
function setUp() {
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer.Vector(null, {
|
||||
isBaseLayer: true,
|
||||
renderers: ["Canvas"]
|
||||
});
|
||||
map.addLayer(layer);
|
||||
map.setCenter(new OpenLayers.LonLat(0, 0));
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
map.destroy();
|
||||
map = null;
|
||||
layer = null;
|
||||
}
|
||||
|
||||
function test_Renderer_Canvas_constructor(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(2);
|
||||
@@ -18,16 +36,17 @@
|
||||
function test_Renderer_Canvas_setextent(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(2);
|
||||
var el = document.body;
|
||||
el.id = "foo";
|
||||
var r = new OpenLayers.Renderer.Canvas(el.id);
|
||||
|
||||
setUp();
|
||||
|
||||
var r = layer.renderer;
|
||||
var extent = new OpenLayers.Bounds(1,2,3,4);
|
||||
r.resolution = 1;
|
||||
r.setExtent(extent, true);
|
||||
t.ok(r.extent.equals(extent), "extent is correctly set");
|
||||
t.eq(r.resolution, null, "resolution nullified");
|
||||
r.destroy();
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_Renderer_Canvas_setsize(t) {
|
||||
@@ -124,18 +143,8 @@
|
||||
}
|
||||
|
||||
t.plan(10);
|
||||
var layer = new OpenLayers.Layer.Vector(null, {
|
||||
isBaseLayer: true,
|
||||
renderers: ["Canvas"]
|
||||
});
|
||||
|
||||
var map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
controls: [],
|
||||
layers: [layer],
|
||||
center: new OpenLayers.LonLat(0, 0),
|
||||
zoom: 0
|
||||
});
|
||||
setUp();
|
||||
|
||||
var renderer = layer.renderer;
|
||||
var count = 0;
|
||||
@@ -192,7 +201,7 @@
|
||||
t.eq(count, 1, "d) redraw is called when drawing a feature without bounds");
|
||||
renderer.clear();
|
||||
|
||||
map.destroy();
|
||||
tearDown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -616,7 +616,40 @@
|
||||
tearDown();
|
||||
}
|
||||
|
||||
|
||||
function test_setExtent(t) {
|
||||
t.plan(10);
|
||||
setUp();
|
||||
var resolution = 1;
|
||||
var r = create_renderer();
|
||||
r.map = {
|
||||
getMaxExtent: function() {
|
||||
return new OpenLayers.Bounds(-180,-90,180,90);
|
||||
},
|
||||
getResolution: function() {
|
||||
return resolution;
|
||||
},
|
||||
baseLayer: {wrapDateLine: true}
|
||||
}
|
||||
|
||||
r.setExtent(new OpenLayers.Bounds(179, -1, 182, 1), true);
|
||||
t.eq(r.rightOfDateLine, true, "on the right side of the dateline");
|
||||
t.eq(r.xOffset, r.map.getMaxExtent().getWidth(), "correct xOffset");
|
||||
r.setExtent(new OpenLayers.Bounds(179.5, -1, 182.5, 1), false);
|
||||
t.eq(r.rightOfDateLine, true, "still on the right side of the dateline");
|
||||
t.eq(r.xOffset, r.map.getMaxExtent().getWidth(), "still correct xOffset");
|
||||
resolution = 2;
|
||||
r.setExtent(new OpenLayers.Bounds(178, -2, 184, 2), true);
|
||||
t.eq(r.rightOfDateLine, true, "still on the right side of the dateline");
|
||||
t.eq(r.xOffset, r.map.getMaxExtent().getWidth() / resolution, "xOffset adjusted for new resolution");
|
||||
r.setExtent(new OpenLayers.Bounds(-184, -2, 178, 2), false);
|
||||
t.eq(r.rightOfDateLine, false, "on the left side of the dateline");
|
||||
t.eq(r.xOffset, 0, "no xOffset");
|
||||
r.setExtent(new OpenLayers.Bounds(178, -2, 184, 2), true);
|
||||
t.eq(r.rightOfDateLine, true, "back on the right side of the dateline");
|
||||
t.eq(r.xOffset, r.map.getMaxExtent().getWidth() / resolution, "correct xOffset");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -3,11 +3,31 @@
|
||||
<script src="OLLoader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var tile;
|
||||
|
||||
var map, layer;
|
||||
function setUp() {
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer(null, {
|
||||
isBaseLayer: true
|
||||
});
|
||||
map.addLayer(layer)
|
||||
map.setCenter(new OpenLayers.LonLat(0, 0));
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
map.destroy();
|
||||
map = null;
|
||||
layer = null;
|
||||
}
|
||||
|
||||
|
||||
function test_Tile_constructor (t) {
|
||||
t.plan( 12 );
|
||||
|
||||
var layer = {}; // bogus layer
|
||||
setUp();
|
||||
|
||||
var dummy = {};
|
||||
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
@@ -15,31 +35,30 @@
|
||||
|
||||
tile = new OpenLayers.Tile(layer, position, bounds, url, size);
|
||||
|
||||
t.ok( tile instanceof OpenLayers.Tile, "new OpenLayers.Tile returns Tile object" );
|
||||
t.eq( tile.layer, layer, "tile.layer set correctly");
|
||||
t.ok( tile.position.equals(position), "tile.position set correctly");
|
||||
t.ok( tile.position != position, "tile.position set not by reference");
|
||||
t.ok( tile.bounds.equals(bounds), "tile.bounds set correctly");
|
||||
t.ok( tile.bounds != bounds, "tile.bounds set not by reference");
|
||||
t.eq( tile.url, url, "tile.url set correctly");
|
||||
t.ok( tile.size.equals(size), "tile.size is set correctly" );
|
||||
t.ok( tile.size != size, "tile.size set not by reference");
|
||||
t.ok(tile instanceof OpenLayers.Tile, "new OpenLayers.Tile returns Tile object");
|
||||
t.ok(tile.layer === layer, "tile.layer set correctly");
|
||||
t.ok(tile.position.equals(position), "tile.position set correctly");
|
||||
t.ok(tile.position != position, "tile.position set not by reference");
|
||||
t.ok(tile.bounds.equals(bounds), "tile.bounds set correctly");
|
||||
t.ok(tile.bounds != bounds, "tile.bounds set not by reference");
|
||||
t.eq(tile.url, url, "tile.url set correctly");
|
||||
t.ok(tile.size.equals(size), "tile.size is set correctly");
|
||||
t.ok(tile.size != size, "tile.size set not by reference");
|
||||
|
||||
t.ok( tile.id != null, "tile is given an id");
|
||||
t.ok(tile.id != null, "tile is given an id");
|
||||
t.ok(OpenLayers.String.startsWith(tile.id, "Tile_"),
|
||||
"tile's id starts correctly");
|
||||
t.ok( tile.events != null, "tile's events intitialized");
|
||||
t.ok(tile.events != null, "tile's events intitialized");
|
||||
|
||||
tearDown();
|
||||
|
||||
}
|
||||
|
||||
function test_Tile_destroy(t) {
|
||||
t.plan( 6 );
|
||||
|
||||
setUp();
|
||||
|
||||
var layer = {
|
||||
SUPPORTED_TRANSITIONS: [],
|
||||
events: {
|
||||
unregister: function() {}
|
||||
}
|
||||
}; // bogus layer
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
@@ -59,6 +78,9 @@
|
||||
t.ok(tile.position == null, "tile.position set to null");
|
||||
|
||||
t.ok(tile.events == null, "tile.events set to null");
|
||||
|
||||
tearDown();
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -3,41 +3,67 @@
|
||||
<script src="../OLLoader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var tile;
|
||||
var layer = new OpenLayers.Layer.WMS(
|
||||
|
||||
var map, layer;
|
||||
function setUp() {
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer.WMS(
|
||||
"WMS",
|
||||
window.location.href + "#",
|
||||
null,
|
||||
{transitionEffect: "resize"});
|
||||
{transitionEffect: "resize"}
|
||||
);
|
||||
map.addLayer(layer)
|
||||
map.setCenter(new OpenLayers.LonLat(0, 0));
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
map.destroy();
|
||||
map = null;
|
||||
layer = null;
|
||||
}
|
||||
|
||||
|
||||
var position = new OpenLayers.Pixel(20,30);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
|
||||
|
||||
function test_initialize (t) {
|
||||
t.plan(2);
|
||||
|
||||
setUp();
|
||||
|
||||
tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
|
||||
t.eq(tile.backBufferData, {}, "back buffer data initialized");
|
||||
t.eq(tile.size.w, 256, "size object with default width created");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_backBufferMode(t) {
|
||||
t.plan(4);
|
||||
|
||||
var l;
|
||||
|
||||
|
||||
var map = new OpenLayers.Map("map");
|
||||
l = new OpenLayers.Layer.WMS('', window.location.href + '#');
|
||||
map.addLayer(l);
|
||||
map.zoomToMaxExtent();
|
||||
|
||||
tile = new OpenLayers.Tile.Image(l, position, bounds, null);
|
||||
t.eq(tile.backBufferMode, 0,
|
||||
'backBufferMode correctly set [tiled]');
|
||||
|
||||
l = new OpenLayers.Layer.WMS('', window.location.href + '#',
|
||||
null, {singleTile: true});
|
||||
map.addLayer(l);
|
||||
|
||||
|
||||
tile = new OpenLayers.Tile.Image(l, position, bounds, null);
|
||||
t.eq(tile.backBufferMode, 1,
|
||||
'backBufferMode correctly set [singleTile]');
|
||||
|
||||
l = new OpenLayers.Layer.WMS('', window.location.href + '#',
|
||||
null, {transitionEffect: 'resize'});
|
||||
map.addLayer(l);
|
||||
tile = new OpenLayers.Tile.Image(l, position, bounds, null);
|
||||
t.eq(tile.backBufferMode, 2,
|
||||
'backBufferMode correctly set [tiled, transition]');
|
||||
@@ -45,17 +71,18 @@
|
||||
l = new OpenLayers.Layer.WMS('', window.location.href + '#',
|
||||
null, {singleTile: true,
|
||||
transitionEffect: 'resize'});
|
||||
map.addLayer(l);
|
||||
tile = new OpenLayers.Tile.Image(l, position, bounds, null);
|
||||
t.eq(tile.backBufferMode, 3,
|
||||
'backBufferMode correctly set [singleTile, transition]');
|
||||
map.destroy();
|
||||
}
|
||||
|
||||
function test_setBackBufferData(t) {
|
||||
t.plan(2);
|
||||
|
||||
setUp();
|
||||
|
||||
var map = new OpenLayers.Map("map");
|
||||
map.addLayer(layer);
|
||||
map.zoomToMaxExtent();
|
||||
tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
|
||||
tile.draw();
|
||||
// moveTo calls setBackBufferData
|
||||
@@ -65,16 +92,15 @@
|
||||
"bounds stored correctly");
|
||||
t.eq(tile.backBufferData.resolution, map.getResolution(),
|
||||
"resolution stored correctly");
|
||||
map.removeLayer(layer);
|
||||
map.destroy();
|
||||
|
||||
tearDown();
|
||||
|
||||
}
|
||||
|
||||
function test_updateBackBuffer(t) {
|
||||
t.plan(1);
|
||||
|
||||
var map = new OpenLayers.Map("map");
|
||||
map.addLayer(layer);
|
||||
map.zoomToMaxExtent();
|
||||
setUp();
|
||||
|
||||
tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
|
||||
tile.draw();
|
||||
tile.isLoading = false;
|
||||
@@ -82,15 +108,14 @@
|
||||
tile.updateBackBuffer();
|
||||
t.eq(tile.backBufferData.tile.style.width, (layer.tileSize.w*2)+"%",
|
||||
"backBuffer frame correctly resized");
|
||||
map.removeLayer(layer);
|
||||
map.destroy();
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_removeBackBuffer(t) {
|
||||
t.plan(2);
|
||||
var map = new OpenLayers.Map("map");
|
||||
map.addLayer(layer);
|
||||
map.zoomToMaxExtent();
|
||||
setUp();
|
||||
|
||||
tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
|
||||
tile.draw();
|
||||
tile.isLoading = false;
|
||||
@@ -102,8 +127,8 @@
|
||||
"backBuffer reference removed");
|
||||
t.ok(backBuffer.parentNode !== layer.div,
|
||||
"backBuffer removed from layer");
|
||||
map.removeLayer(layer);
|
||||
map.destroy();
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_updateBackBuffer_scaled_layer(t) {
|
||||
@@ -118,6 +143,13 @@
|
||||
var map = new OpenLayers.Map('map', {
|
||||
resolutions: [32, 16, 8, 4, 2, 1]
|
||||
});
|
||||
var layer = new OpenLayers.Layer.WMS(
|
||||
"WMS",
|
||||
window.location.href + "#",
|
||||
null,
|
||||
{transitionEffect: "resize"}
|
||||
);
|
||||
|
||||
|
||||
var serverResolitions = layer.serverResolutions;
|
||||
layer.serverResolutions = [32, 16, 8];
|
||||
|
||||
@@ -5,12 +5,27 @@
|
||||
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
|
||||
var tile;
|
||||
|
||||
var map, layer;
|
||||
function setUp() {
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer(null, {
|
||||
isBaseLayer: true
|
||||
});
|
||||
map.addLayer(layer)
|
||||
map.setCenter(new OpenLayers.LonLat(0, 0));
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
map.destroy();
|
||||
map = null;
|
||||
layer = null;
|
||||
}
|
||||
|
||||
function test_Tile_Image_constructor (t) {
|
||||
t.plan( 6 );
|
||||
|
||||
var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
||||
"http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});
|
||||
|
||||
setUp();
|
||||
|
||||
var position = new OpenLayers.Pixel(20,30);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "http://www.openlayers.org/dev/tests/tileimage";
|
||||
@@ -23,6 +38,8 @@
|
||||
t.ok( tile.bounds.equals(bounds), "tile.bounds is set correctly");
|
||||
t.eq( tile.url, url, "tile.url is set correctly");
|
||||
t.ok( tile.size.equals(size), "tile.size is set correctly");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_destroy_observers(t) {
|
||||
|
||||
@@ -3,11 +3,27 @@
|
||||
<script src="../OLLoader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var tile;
|
||||
|
||||
var map, layer;
|
||||
function setUp() {
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer(null, {
|
||||
isBaseLayer: true
|
||||
});
|
||||
map.addLayer(layer)
|
||||
map.setCenter(new OpenLayers.LonLat(0, 0));
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
map.destroy();
|
||||
map = null;
|
||||
layer = null;
|
||||
}
|
||||
|
||||
function test_Tile_WFS_constructor (t) {
|
||||
t.plan( 8 );
|
||||
setUp();
|
||||
|
||||
var layer = {}; // bogus layer
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
@@ -16,7 +32,7 @@
|
||||
tile = new OpenLayers.Tile.WFS(layer, position, bounds, url, size);
|
||||
|
||||
t.ok( tile instanceof OpenLayers.Tile.WFS, "new OpenLayers.Tile.WFS returns Tile.WFS object" );
|
||||
t.eq( tile.layer, layer, "tile.layer set correctly");
|
||||
t.ok( tile.layer === layer, "tile.layer set correctly");
|
||||
t.ok( tile.position.equals(position), "tile.position set correctly");
|
||||
t.ok( tile.bounds.equals(bounds), "tile.bounds set correctly");
|
||||
t.eq( tile.url, url, "tile.url set correctly");
|
||||
@@ -24,10 +40,13 @@
|
||||
|
||||
t.ok( tile.id != null, "tile is given an id");
|
||||
t.ok( tile.events != null, "tile's events intitialized");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_Tile_WFS_requestSuccess(t) {
|
||||
t.plan(2);
|
||||
setUp();
|
||||
|
||||
var tile = {
|
||||
'request': {}
|
||||
@@ -37,12 +56,6 @@
|
||||
|
||||
t.ok(tile.request == null, "request property on tile set to null");
|
||||
|
||||
var layer = {
|
||||
SUPPORTED_TRANSITIONS: [],
|
||||
events: {
|
||||
unregister: function() {}
|
||||
}
|
||||
}; // bogus layer
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
@@ -53,6 +66,7 @@
|
||||
tile.requestSuccess({'requestText': '<xml><foo /></xml>'});
|
||||
t.ok(true, "Didn't fail after calling requestSuccess on destroyed tile.");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_Tile_WFS_loadFeaturesForRegion(t) {
|
||||
@@ -88,13 +102,8 @@
|
||||
|
||||
function test_Tile_WFS_destroy(t) {
|
||||
t.plan(9);
|
||||
setUp();
|
||||
|
||||
var layer = {
|
||||
SUPPORTED_TRANSITIONS: [],
|
||||
events: {
|
||||
unregister: function() {}
|
||||
}
|
||||
}; // bogus layer
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
@@ -127,43 +136,75 @@
|
||||
|
||||
tile.requestSuccess({'requestText': '<xml><foo /></xml>'});
|
||||
t.ok(true, "Didn't fail after calling requestSuccess on destroyed tile.");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
function test_nonxml_format(t) {
|
||||
t.plan(1);
|
||||
t.plan(2);
|
||||
|
||||
setUp();
|
||||
|
||||
var data = '{"type":"Feature", "id":"OpenLayers.Feature.Vector_135", "properties":{}, "geometry":{"type":"Point", "coordinates":[118.125, -18.6328125]}, "crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}'
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
var size = new OpenLayers.Size(5,6);
|
||||
|
||||
var tile = new OpenLayers.Tile.WFS({
|
||||
vectorMode: true,
|
||||
var log = [];
|
||||
|
||||
var l = new OpenLayers.Layer(null, {
|
||||
vectorMode: true,
|
||||
formatObject: new OpenLayers.Format.GeoJSON(),
|
||||
addFeatures: function(features) {
|
||||
t.eq(features.length, 1, "GeoJSON format returned a single feature which was added.")
|
||||
log.push(features);
|
||||
}
|
||||
}, position, bounds, url, size);
|
||||
})
|
||||
map.addLayer(l);
|
||||
|
||||
var tile = new OpenLayers.Tile.WFS(l, position, bounds, url, size);
|
||||
|
||||
tile.requestSuccess({responseText: data});
|
||||
|
||||
t.eq(log.length, 1, "one call logged")
|
||||
t.eq(log[0] && log[0].length, 1, "GeoJSON format returned a single feature which was added.");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
function test_xml_string_and_dom(t) {
|
||||
t.plan(2);
|
||||
t.plan(4);
|
||||
setUp();
|
||||
|
||||
var data = '<?xml version="1.0" encoding="ISO-8859-1" ?><wfs:FeatureCollection xmlns:bsc="http://www.bsc-eoc.org/bsc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd http://www.bsc-eoc.org/bsc http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=OWLS&OUTPUTFORMAT=XMLSCHEMA"> <gml:boundedBy> <gml:Box srsName="EPSG:4326"> <gml:coordinates>-94.989723,43.285833 -74.755001,51.709520</gml:coordinates> </gml:Box> </gml:boundedBy> <gml:featureMember> <bsc:OWLS> <gml:boundedBy> <gml:Box srsName="EPSG:4326"> <gml:coordinates>-94.142500,50.992777 -94.142500,50.992777</gml:coordinates> </gml:Box> </gml:boundedBy> <bsc:msGeometry> <gml:Point srsName="EPSG:4326"> <gml:coordinates>-94.142500,50.992777</gml:coordinates> </gml:Point> </bsc:msGeometry> <bsc:ROUTEID>ON_2</bsc:ROUTEID> <bsc:ROUTE_NAME>Suffel Road</bsc:ROUTE_NAME> <bsc:LATITUDE>50.9927770</bsc:LATITUDE> <bsc:LONGITUDE>-94.1425000</bsc:LONGITUDE> </bsc:OWLS> </gml:featureMember></wfs:FeatureCollection>';
|
||||
var position = new OpenLayers.Pixel(10,20);
|
||||
var bounds = new OpenLayers.Bounds(1,2,3,4);
|
||||
var url = "bobob";
|
||||
var size = new OpenLayers.Size(5,6);
|
||||
var tile = new OpenLayers.Tile.WFS({
|
||||
}, position, bounds, url, size);
|
||||
|
||||
var l = new OpenLayers.Layer();
|
||||
map.addLayer(l);
|
||||
|
||||
var tile = new OpenLayers.Tile.WFS(l, position, bounds, url, size);
|
||||
|
||||
var log = [];
|
||||
tile.addResults = function(results) {
|
||||
t.eq(results.length, 1, "results count is correct when passing in XML as a string into non-vectormode");
|
||||
log.push(results);
|
||||
}
|
||||
tile.requestSuccess({responseText: data});
|
||||
|
||||
t.eq(log.length, 1, "first call logged");
|
||||
t.eq(log[0] && log[0].length, 1, "results count is correct when passing in XML as a string into non-vectormode");
|
||||
|
||||
log.length = 0;
|
||||
tile.addResults = function(results) {
|
||||
t.eq(results.length, 1, "results count is correct when passing in XML as DOM into non-vectormode");
|
||||
log.push(results);
|
||||
}
|
||||
tile.requestSuccess({responseXML: OpenLayers.Format.XML.prototype.read(data)});
|
||||
|
||||
t.eq(log.length, 1, "second call logged");
|
||||
t.eq(log[0] && log[0].length, 1, "results count is correct when passing in XML as DOM into non-vectormode");
|
||||
|
||||
tearDown();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -14,35 +14,8 @@
|
||||
</style>
|
||||
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
// make map available for easy debugging
|
||||
var map;
|
||||
|
||||
function init(){
|
||||
var options = {
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
units: "m",
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)
|
||||
};
|
||||
map = new OpenLayers.Map('map', options);
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM(
|
||||
"OSM", null, {wrapDateLine: true}
|
||||
);
|
||||
var vector = new OpenLayers.Layer.Vector("Editable Vectors");
|
||||
|
||||
map.addLayers([osm, vector]);
|
||||
map.addControl(new OpenLayers.Control.EditingToolbar(vector));
|
||||
|
||||
var extent = new OpenLayers.Bounds(15849982.183008, -11368938.517442, -14206280.326992, -1350184.3474418);
|
||||
map.zoomToExtent(extent);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<body>
|
||||
<h1 id="title">OpenLayers sketch handlers crossing the dateline example</h1>
|
||||
|
||||
<div id="tags">
|
||||
@@ -58,5 +31,36 @@ function init(){
|
||||
|
||||
<div id="docs">
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new OpenLayers.Map('map');
|
||||
|
||||
var base = new OpenLayers.Layer.WMS("marble",
|
||||
"http://demo.opengeo.org/geoserver/wms",
|
||||
{layers: "topp:naturalearth"},
|
||||
{wrapDateLine: true}
|
||||
);
|
||||
|
||||
// allow testing of specific renderers via "?renderer=Canvas", etc
|
||||
var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
|
||||
renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;
|
||||
|
||||
var vector = new OpenLayers.Layer.Vector("Editable Vectors", {renderers: renderer});
|
||||
|
||||
map.addLayers([base, vector]);
|
||||
|
||||
var wkt = new OpenLayers.Format.WKT();
|
||||
var f = wkt.read("POLYGON((210.8828125 39.7265625,151.8203125 36.2109375,152.171875 -9.4921875,219.3203125 -10.546875,210.8828125 39.7265625))");
|
||||
|
||||
var f2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-190, 0));
|
||||
|
||||
vector.addFeatures([f, f2]);
|
||||
|
||||
map.addControl(new OpenLayers.Control.EditingToolbar(vector));
|
||||
|
||||
map.setCenter(new OpenLayers.LonLat(-179, 0), 2);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers: Sketch handlers crossing the dateline</title>
|
||||
<title>OpenLayers: Overlay layer extents crossing the dateline</title>
|
||||
<link rel="stylesheet" href="../../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../../examples/style.css" type="text/css">
|
||||
<style type="text/css">
|
||||
@@ -22,19 +22,26 @@ var map;
|
||||
function init(){
|
||||
map = new OpenLayers.Map('map');
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM(
|
||||
"OSM", null,
|
||||
var base = new OpenLayers.Layer.WMS("marble",
|
||||
"http://demo.opengeo.org/geoserver/wms",
|
||||
{layers: "topp:naturalearth"},
|
||||
{wrapDateLine: true}
|
||||
);
|
||||
var extent = new OpenLayers.Bounds(15849982.183008, -11368938.517442, -14206280.326992, -1350184.3474419);
|
||||
var extent = new OpenLayers.Bounds(142.3828125,-70.902270266175,233.6171875,-12.039326531729);
|
||||
var wms = new OpenLayers.Layer.WMS( "world",
|
||||
"http://demo.opengeo.org/geoserver/wms",
|
||||
{layers: 'world', transparent: true},
|
||||
{maxExtent: extent}
|
||||
);
|
||||
|
||||
var vector = new OpenLayers.Layer.Vector();
|
||||
vector.addFeatures([
|
||||
new OpenLayers.Feature.Vector(extent.toGeometry())
|
||||
]);
|
||||
|
||||
map.addLayers([osm, wms]);
|
||||
map.addLayers([base, wms, vector]);
|
||||
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.zoomToExtent(extent);
|
||||
}
|
||||
|
||||
@@ -44,9 +51,10 @@ function init(){
|
||||
<h1 id="title">OpenLayers overlays crossing the dateline test</h1>
|
||||
|
||||
<p id="shortdesc">
|
||||
The overlay has an extent smaller than the world extent. The base layer
|
||||
is configured with wrapDateLine set to true. New Zealand and a part of
|
||||
Australia should always be visible on the map.
|
||||
The overlay has an extent smaller than the world extent, but exceeds
|
||||
the world extent. The base layer is configured with wrapDateLine set to
|
||||
true. The area inside the orange rectangle should always contain tiles
|
||||
from the world layer, regardless of the zoom level.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user