diff --git a/examples/sphere-mollweide.js b/examples/sphere-mollweide.js index 7540cd095b..83fc6adcc4 100644 --- a/examples/sphere-mollweide.js +++ b/examples/sphere-mollweide.js @@ -17,8 +17,8 @@ register(proj4); // and a world extent. These are required for the Graticule. const sphereMollweideProjection = new Projection({ code: 'ESRI:53009', - extent: [-9009954.605703328, -9009954.605703328, - 9009954.605703328, 9009954.605703328], + extent: [-18019909.21177587, -9009954.605703328, + 18019909.21177587, 9009954.605703328], worldExtent: [-179, -89.99, 179, 89.99] }); @@ -37,6 +37,6 @@ const map = new Map({ view: new View({ center: [0, 0], projection: sphereMollweideProjection, - zoom: 0 + zoom: 1 }) }); diff --git a/src/ol/extent.js b/src/ol/extent.js index cc74b803fb..94eb9cb249 100644 --- a/src/ol/extent.js +++ b/src/ol/extent.js @@ -778,18 +778,38 @@ export function intersectsSegment(extent, start, end) { * @param {import("./proj.js").TransformFunction} transformFn Transform function. * Called with `[minX, minY, maxX, maxY]` extent coordinates. * @param {Extent=} opt_extent Destination extent. + * @param {number=} opt_stops Number of stops per side used for the transform. + * By default only the corners are used. * @return {Extent} Extent. * @api */ -export function applyTransform(extent, transformFn, opt_extent) { - const coordinates = [ - extent[0], extent[1], - extent[0], extent[3], - extent[2], extent[1], - extent[2], extent[3] - ]; +export function applyTransform(extent, transformFn, opt_extent, opt_stops) { + let coordinates = []; + if (opt_stops > 1) { + const width = extent[2] - extent[0]; + const height = extent[3] - extent[1]; + for (let i = 0; i < opt_stops; ++i) { + coordinates.push( + extent[0] + width * i / opt_stops, extent[1], + extent[2], extent[1] + height * i / opt_stops, + extent[2] - width * i / opt_stops, extent[3], + extent[0], extent[3] - height * i / opt_stops + ); + } + } else { + coordinates = [ + extent[0], extent[1], + extent[2], extent[1], + extent[2], extent[3], + extent[0], extent[3] + ]; + } transformFn(coordinates, coordinates, 2); - const xs = [coordinates[0], coordinates[2], coordinates[4], coordinates[6]]; - const ys = [coordinates[1], coordinates[3], coordinates[5], coordinates[7]]; + const xs = []; + const ys = []; + for (let i = 0, l = coordinates.length; i < l; i += 2) { + xs.push(coordinates[i]); + ys.push(coordinates[i + 1]); + } return _boundingExtentXYs(xs, ys, opt_extent); } diff --git a/src/ol/layer/Graticule.js b/src/ol/layer/Graticule.js index f1480dddc9..31e0f5aaee 100644 --- a/src/ol/layer/Graticule.js +++ b/src/ol/layer/Graticule.js @@ -144,7 +144,8 @@ const INTERVALS = [ /** * @classdesc - * Layer that renders a grid for a coordinate system. + * Layer that renders a grid for a coordinate system (currently only EPSG:4326 is supported). + * Note that the view projection must define both extent and worldExtent. * * @fires import("../render/Event.js").RenderEvent * @api @@ -677,7 +678,7 @@ class Graticule extends VectorLayer { Math.min(extent[3], this.maxLatP_) ]; - validExtent = transformExtent(validExtent, this.projection_, 'EPSG:4326'); + validExtent = transformExtent(validExtent, this.projection_, 'EPSG:4326', 8); const maxLat = validExtent[3]; const maxLon = validExtent[2]; const minLat = validExtent[1]; @@ -896,7 +897,7 @@ class Graticule extends VectorLayer { const epsg4326Projection = getProjection('EPSG:4326'); const worldExtent = projection.getWorldExtent(); - const worldExtentP = transformExtent(worldExtent, epsg4326Projection, projection); + const worldExtentP = transformExtent(worldExtent, epsg4326Projection, projection, 8); this.maxLat_ = worldExtent[3]; this.maxLon_ = worldExtent[2]; diff --git a/src/ol/proj.js b/src/ol/proj.js index f64cc05a85..d2be0feb3f 100644 --- a/src/ol/proj.js +++ b/src/ol/proj.js @@ -476,12 +476,14 @@ export function transform(coordinate, source, destination) { * @param {import("./extent.js").Extent} extent The extent to transform. * @param {ProjectionLike} source Source projection-like. * @param {ProjectionLike} destination Destination projection-like. + * @param {number=} opt_stops Number of stops per side used for the transform. + * By default only the corners are used. * @return {import("./extent.js").Extent} The transformed extent. * @api */ -export function transformExtent(extent, source, destination) { +export function transformExtent(extent, source, destination, opt_stops) { const transformFunc = getTransform(source, destination); - return applyTransform(extent, transformFunc); + return applyTransform(extent, transformFunc, undefined, opt_stops); }