handle wrapX without calculating excess meridians
avoid calculating more meridians or longer parallels than necessary when viewport extent includes a wrapped world
This commit is contained in:
committed by
Andreas Hocevar
parent
772741cd0e
commit
bad0ff38ca
@@ -717,6 +717,22 @@ class Graticule extends VectorLayer {
|
||||
return;
|
||||
}
|
||||
|
||||
let wrapX = false;
|
||||
const projectionExtent = this.projection_.getExtent();
|
||||
const worldWidth = getWidth(projectionExtent);
|
||||
if (this.getSource().getWrapX() && this.projection_.canWrapX() && !containsExtent(projectionExtent, extent)) {
|
||||
if (getWidth(extent) >= worldWidth) {
|
||||
extent[0] = projectionExtent[0];
|
||||
extent[2] = projectionExtent[2];
|
||||
} else {
|
||||
const worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth);
|
||||
center[0] -= (worldsAway * worldWidth);
|
||||
extent[0] -= (worldsAway * worldWidth);
|
||||
extent[2] -= (worldsAway * worldWidth);
|
||||
wrapX = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Constrain the center to fit into the extent available to the graticule
|
||||
|
||||
const validCenterP = [
|
||||
@@ -740,44 +756,56 @@ class Graticule extends VectorLayer {
|
||||
|
||||
// Limit the extent to fit into the extent available to the graticule
|
||||
|
||||
const validExtentP = [
|
||||
let validExtentP = extent;
|
||||
if (!wrapX) {
|
||||
validExtentP = [
|
||||
clamp(extent[0], this.minX_, this.maxX_),
|
||||
clamp(extent[1], this.minY_, this.maxY_),
|
||||
clamp(extent[2], this.minX_, this.maxX_),
|
||||
clamp(extent[3], this.minY_, this.maxY_)
|
||||
];
|
||||
}
|
||||
|
||||
// Transform the extent to get the lon lat ranges for the edges of the extent
|
||||
|
||||
const validExtent = applyTransform(validExtentP, this.toLonLatTransform_, undefined, 8);
|
||||
|
||||
let maxLat = validExtent[3];
|
||||
let maxLon = validExtent[2];
|
||||
let minLat = validExtent[1];
|
||||
let minLon = validExtent[0];
|
||||
|
||||
if (!wrapX) {
|
||||
|
||||
// Check if extremities of the world extent lie inside the extent
|
||||
// (for example the pole in a polar projection)
|
||||
// and extend the extent as appropriate
|
||||
|
||||
if (containsCoordinate(validExtentP, this.bottomLeft_)) {
|
||||
validExtent[0] = this.minLon_;
|
||||
validExtent[1] = this.minLat_;
|
||||
minLon = this.minLon_;
|
||||
minLat = this.minLat_;
|
||||
}
|
||||
if (containsCoordinate(validExtentP, this.bottomRight_)) {
|
||||
validExtent[2] = this.maxLon_;
|
||||
validExtent[1] = this.minLat_;
|
||||
maxLon = this.maxLon_;
|
||||
minLat = this.minLat_;
|
||||
}
|
||||
if (containsCoordinate(validExtentP, this.topLeft_)) {
|
||||
validExtent[0] = this.minLon_;
|
||||
validExtent[3] = this.maxLat_;
|
||||
minLon = this.minLon_;
|
||||
maxLat = this.maxLat_;
|
||||
}
|
||||
if (containsCoordinate(validExtentP, this.topRight_)) {
|
||||
validExtent[2] = this.maxLon_;
|
||||
validExtent[3] = this.maxLat_;
|
||||
maxLon = this.maxLon_;
|
||||
maxLat = this.maxLat_;
|
||||
}
|
||||
|
||||
// The transformed center may also extend the lon lat ranges used for rendering
|
||||
|
||||
const maxLat = clamp(validExtent[3], centerLat, this.maxLat_);
|
||||
const maxLon = clamp(validExtent[2], centerLon, this.maxLon_);
|
||||
const minLat = clamp(validExtent[1], this.minLat_, centerLat);
|
||||
const minLon = clamp(validExtent[0], this.minLon_, centerLon);
|
||||
maxLat = clamp(maxLat, centerLat, this.maxLat_);
|
||||
maxLon = clamp(maxLon, centerLon, this.maxLon_);
|
||||
minLat = clamp(minLat, this.minLat_, centerLat);
|
||||
minLon = clamp(minLon, this.minLon_, centerLon);
|
||||
|
||||
}
|
||||
|
||||
// Create meridians
|
||||
|
||||
@@ -787,18 +815,30 @@ class Graticule extends VectorLayer {
|
||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0);
|
||||
|
||||
cnt = 0;
|
||||
if (wrapX) {
|
||||
while ((lon -= interval) >= minLon && cnt++ < maxLines) {
|
||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
||||
}
|
||||
} else {
|
||||
while (lon != this.minLon_ && cnt++ < maxLines) {
|
||||
lon = Math.max(lon - interval, this.minLon_);
|
||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
||||
}
|
||||
}
|
||||
|
||||
lon = clamp(centerLon, this.minLon_, this.maxLon_);
|
||||
|
||||
cnt = 0;
|
||||
if (wrapX) {
|
||||
while ((lon += interval) <= maxLon && cnt++ < maxLines) {
|
||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
||||
}
|
||||
} else {
|
||||
while (lon != this.maxLon_ && cnt++ < maxLines) {
|
||||
lon = Math.min(lon + interval, this.maxLon_);
|
||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
||||
}
|
||||
}
|
||||
|
||||
this.meridians_.length = idx;
|
||||
if (this.meridiansLabels_) {
|
||||
|
||||
Reference in New Issue
Block a user