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;
|
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
|
// Constrain the center to fit into the extent available to the graticule
|
||||||
|
|
||||||
const validCenterP = [
|
const validCenterP = [
|
||||||
@@ -740,44 +756,56 @@ class Graticule extends VectorLayer {
|
|||||||
|
|
||||||
// Limit the extent to fit into the extent available to the graticule
|
// 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[0], this.minX_, this.maxX_),
|
||||||
clamp(extent[1], this.minY_, this.maxY_),
|
clamp(extent[1], this.minY_, this.maxY_),
|
||||||
clamp(extent[2], this.minX_, this.maxX_),
|
clamp(extent[2], this.minX_, this.maxX_),
|
||||||
clamp(extent[3], this.minY_, this.maxY_)
|
clamp(extent[3], this.minY_, this.maxY_)
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// Transform the extent to get the lon lat ranges for the edges of the extent
|
// Transform the extent to get the lon lat ranges for the edges of the extent
|
||||||
|
|
||||||
const validExtent = applyTransform(validExtentP, this.toLonLatTransform_, undefined, 8);
|
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
|
// Check if extremities of the world extent lie inside the extent
|
||||||
// (for example the pole in a polar projection)
|
// (for example the pole in a polar projection)
|
||||||
// and extend the extent as appropriate
|
// and extend the extent as appropriate
|
||||||
|
|
||||||
if (containsCoordinate(validExtentP, this.bottomLeft_)) {
|
if (containsCoordinate(validExtentP, this.bottomLeft_)) {
|
||||||
validExtent[0] = this.minLon_;
|
minLon = this.minLon_;
|
||||||
validExtent[1] = this.minLat_;
|
minLat = this.minLat_;
|
||||||
}
|
}
|
||||||
if (containsCoordinate(validExtentP, this.bottomRight_)) {
|
if (containsCoordinate(validExtentP, this.bottomRight_)) {
|
||||||
validExtent[2] = this.maxLon_;
|
maxLon = this.maxLon_;
|
||||||
validExtent[1] = this.minLat_;
|
minLat = this.minLat_;
|
||||||
}
|
}
|
||||||
if (containsCoordinate(validExtentP, this.topLeft_)) {
|
if (containsCoordinate(validExtentP, this.topLeft_)) {
|
||||||
validExtent[0] = this.minLon_;
|
minLon = this.minLon_;
|
||||||
validExtent[3] = this.maxLat_;
|
maxLat = this.maxLat_;
|
||||||
}
|
}
|
||||||
if (containsCoordinate(validExtentP, this.topRight_)) {
|
if (containsCoordinate(validExtentP, this.topRight_)) {
|
||||||
validExtent[2] = this.maxLon_;
|
maxLon = this.maxLon_;
|
||||||
validExtent[3] = this.maxLat_;
|
maxLat = this.maxLat_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The transformed center may also extend the lon lat ranges used for rendering
|
// The transformed center may also extend the lon lat ranges used for rendering
|
||||||
|
|
||||||
const maxLat = clamp(validExtent[3], centerLat, this.maxLat_);
|
maxLat = clamp(maxLat, centerLat, this.maxLat_);
|
||||||
const maxLon = clamp(validExtent[2], centerLon, this.maxLon_);
|
maxLon = clamp(maxLon, centerLon, this.maxLon_);
|
||||||
const minLat = clamp(validExtent[1], this.minLat_, centerLat);
|
minLat = clamp(minLat, this.minLat_, centerLat);
|
||||||
const minLon = clamp(validExtent[0], this.minLon_, centerLon);
|
minLon = clamp(minLon, this.minLon_, centerLon);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Create meridians
|
// Create meridians
|
||||||
|
|
||||||
@@ -787,18 +815,30 @@ class Graticule extends VectorLayer {
|
|||||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0);
|
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0);
|
||||||
|
|
||||||
cnt = 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) {
|
while (lon != this.minLon_ && cnt++ < maxLines) {
|
||||||
lon = Math.max(lon - interval, this.minLon_);
|
lon = Math.max(lon - interval, this.minLon_);
|
||||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lon = clamp(centerLon, this.minLon_, this.maxLon_);
|
lon = clamp(centerLon, this.minLon_, this.maxLon_);
|
||||||
|
|
||||||
cnt = 0;
|
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) {
|
while (lon != this.maxLon_ && cnt++ < maxLines) {
|
||||||
lon = Math.min(lon + interval, this.maxLon_);
|
lon = Math.min(lon + interval, this.maxLon_);
|
||||||
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.meridians_.length = idx;
|
this.meridians_.length = idx;
|
||||||
if (this.meridiansLabels_) {
|
if (this.meridiansLabels_) {
|
||||||
|
|||||||
Reference in New Issue
Block a user