diff --git a/examples/sphere-mollweide.js b/examples/sphere-mollweide.js index 232c75ae53..a3c1ad7c9f 100644 --- a/examples/sphere-mollweide.js +++ b/examples/sphere-mollweide.js @@ -16,7 +16,7 @@ var sphereMollweideProjection = new ol.proj.Projection({ code: 'ESRI:53009', extent: [-9009954.605703328, -9009954.605703328, 9009954.605703328, 9009954.605703328], - worldExtent: [-179, -90, 179, 90] + worldExtent: [-179, -89.99, 179, 89.99] }); var map = new ol.Map({ diff --git a/src/ol/graticule.js b/src/ol/graticule.js index 89adadad5e..a005774177 100644 --- a/src/ol/graticule.js +++ b/src/ol/graticule.js @@ -58,6 +58,30 @@ ol.Graticule = function(opt_options) { */ this.minLon_ = -Infinity; + /** + * @type {number} + * @private + */ + this.maxLatP_ = Infinity; + + /** + * @type {number} + * @private + */ + this.maxLonP_ = Infinity; + + /** + * @type {number} + * @private + */ + this.minLatP_ = -Infinity; + + /** + * @type {number} + * @private + */ + this.minLonP_ = -Infinity; + /** * @type {number} * @private @@ -135,6 +159,8 @@ ol.Graticule.intervals_ = [90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, /** * @param {number} lon Longitude. + * @param {number} minLat Minimal latitude. + * @param {number} maxLat Maximal latitude. * @param {number} squaredTolerance Squared tolerance. * @param {ol.Extent} extent Extent. * @param {number} index Index. @@ -142,8 +168,9 @@ ol.Graticule.intervals_ = [90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, * @private */ ol.Graticule.prototype.addMeridian_ = - function(lon, squaredTolerance, extent, index) { - var lineString = this.getMeridian_(lon, squaredTolerance, index); + function(lon, minLat, maxLat, squaredTolerance, extent, index) { + var lineString = this.getMeridian_(lon, minLat, maxLat, + squaredTolerance, index); if (ol.extent.intersects(lineString.getExtent(), extent)) { this.meridians_[index++] = lineString; } @@ -153,6 +180,8 @@ ol.Graticule.prototype.addMeridian_ = /** * @param {number} lat Latitude. + * @param {number} minLon Minimal longitude. + * @param {number} maxLon Maximal longitude. * @param {number} squaredTolerance Squared tolerance. * @param {ol.Extent} extent Extent. * @param {number} index Index. @@ -160,8 +189,9 @@ ol.Graticule.prototype.addMeridian_ = * @private */ ol.Graticule.prototype.addParallel_ = - function(lat, squaredTolerance, extent, index) { - var lineString = this.getParallel_(lat, squaredTolerance, index); + function(lat, minLon, maxLon, squaredTolerance, extent, index) { + var lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance, + index); if (ol.extent.intersects(lineString.getExtent(), extent)) { this.parallels_[index++] = lineString; } @@ -191,17 +221,31 @@ ol.Graticule.prototype.createGraticule_ = var maxLines = this.maxLines_; var cnt, idx, lat, lon; + var validExtent = [ + Math.max(extent[0], this.minLonP_), + Math.max(extent[1], this.minLatP_), + Math.min(extent[2], this.maxLonP_), + Math.min(extent[3], this.maxLatP_) + ]; + + validExtent = ol.proj.transformExtent(validExtent, this.projection_, + 'EPSG:4326'); + var maxLat = validExtent[3]; + var maxLon = validExtent[2]; + var minLat = validExtent[1]; + var minLon = validExtent[0]; + // Create meridians centerLon = Math.floor(centerLon / interval) * interval; lon = goog.math.clamp(centerLon, this.minLon_, this.maxLon_); - idx = this.addMeridian_(lon, squaredTolerance, extent, 0); + idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0); cnt = 0; while (lon != this.minLon_ && cnt++ < maxLines) { lon = Math.max(lon - interval, this.minLon_); - idx = this.addMeridian_(lon, squaredTolerance, extent, idx); + idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx); } lon = goog.math.clamp(centerLon, this.minLon_, this.maxLon_); @@ -209,7 +253,7 @@ ol.Graticule.prototype.createGraticule_ = cnt = 0; while (lon != this.maxLon_ && cnt++ < maxLines) { lon = Math.min(lon + interval, this.maxLon_); - idx = this.addMeridian_(lon, squaredTolerance, extent, idx); + idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx); } this.meridians_.length = idx; @@ -219,12 +263,12 @@ ol.Graticule.prototype.createGraticule_ = centerLat = Math.floor(centerLat / interval) * interval; lat = goog.math.clamp(centerLat, this.minLat_, this.maxLat_); - idx = this.addParallel_(lat, squaredTolerance, extent, 0); + idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, 0); cnt = 0; while (lat != this.minLat_ && cnt++ < maxLines) { lat = Math.max(lat - interval, this.minLat_); - idx = this.addParallel_(lat, squaredTolerance, extent, idx); + idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, idx); } lat = goog.math.clamp(centerLat, this.minLat_, this.maxLat_); @@ -232,7 +276,7 @@ ol.Graticule.prototype.createGraticule_ = cnt = 0; while (lat != this.maxLat_ && cnt++ < maxLines) { lat = Math.min(lat + interval, this.maxLat_); - idx = this.addParallel_(lat, squaredTolerance, extent, idx); + idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, idx); } this.parallels_.length = idx; @@ -285,18 +329,21 @@ ol.Graticule.prototype.getMap = function() { /** * @param {number} lon Longitude. + * @param {number} minLat Minimal latitude. + * @param {number} maxLat Maximal latitude. * @param {number} squaredTolerance Squared tolerance. * @return {ol.geom.LineString} The meridian line string. * @param {number} index Index. * @private */ -ol.Graticule.prototype.getMeridian_ = function(lon, squaredTolerance, index) { +ol.Graticule.prototype.getMeridian_ = function(lon, minLat, maxLat, + squaredTolerance, index) { goog.asserts.assert(lon >= this.minLon_, 'lon should be larger than or equal to this.minLon_'); goog.asserts.assert(lon <= this.maxLon_, 'lon should be smaller than or equal to this.maxLon_'); var flatCoordinates = ol.geom.flat.geodesic.meridian(lon, - this.minLat_, this.maxLat_, this.projection_, squaredTolerance); + minLat, maxLat, this.projection_, squaredTolerance); goog.asserts.assert(flatCoordinates.length > 0, 'flatCoordinates cannot be empty'); var lineString = goog.isDef(this.meridians_[index]) ? @@ -318,12 +365,15 @@ ol.Graticule.prototype.getMeridians = function() { /** * @param {number} lat Latitude. + * @param {number} minLon Minimal longitude. + * @param {number} maxLon Maximal longitude. * @param {number} squaredTolerance Squared tolerance. * @return {ol.geom.LineString} The parallel line string. * @param {number} index Index. * @private */ -ol.Graticule.prototype.getParallel_ = function(lat, squaredTolerance, index) { +ol.Graticule.prototype.getParallel_ = function(lat, minLon, maxLon, + squaredTolerance, index) { goog.asserts.assert(lat >= this.minLat_, 'lat should be larger than or equal to this.minLat_'); goog.asserts.assert(lat <= this.maxLat_, @@ -395,25 +445,48 @@ ol.Graticule.prototype.handlePostCompose_ = function(e) { ol.Graticule.prototype.updateProjectionInfo_ = function(projection) { goog.asserts.assert(!goog.isNull(projection), 'projection cannot be null'); + var epsg4326Projection = ol.proj.get('EPSG:4326'); + var extent = projection.getExtent(); var worldExtent = projection.getWorldExtent(); + var worldExtentP = ol.proj.transformExtent(worldExtent, + epsg4326Projection, projection); + var maxLat = worldExtent[3]; var maxLon = worldExtent[2]; var minLat = worldExtent[1]; var minLon = worldExtent[0]; + var maxLatP = worldExtentP[3]; + var maxLonP = worldExtentP[2]; + var minLatP = worldExtentP[1]; + var minLonP = worldExtentP[0]; + goog.asserts.assert(!goog.isNull(extent), 'extent cannot be null'); goog.asserts.assert(goog.isDef(maxLat), 'maxLat should be defined'); goog.asserts.assert(goog.isDef(maxLon), 'maxLon should be defined'); goog.asserts.assert(goog.isDef(minLat), 'minLat should be defined'); goog.asserts.assert(goog.isDef(minLon), 'minLon should be defined'); + goog.asserts.assert(goog.isDef(maxLatP), + 'projected maxLat should be defined'); + goog.asserts.assert(goog.isDef(maxLonP), + 'projected maxLon should be defined'); + goog.asserts.assert(goog.isDef(minLatP), + 'projected minLat should be defined'); + goog.asserts.assert(goog.isDef(minLonP), + 'projected minLon should be defined'); + this.maxLat_ = maxLat; this.maxLon_ = maxLon; this.minLat_ = minLat; this.minLon_ = minLon; - var epsg4326Projection = ol.proj.get('EPSG:4326'); + this.maxLatP_ = maxLatP; + this.maxLonP_ = maxLonP; + this.minLatP_ = minLatP; + this.minLonP_ = minLonP; + this.fromLonLatTransform_ = ol.proj.getTransform( epsg4326Projection, projection);