From a6b1df3574bb8f5ea520200a942fbdd7d0caba50 Mon Sep 17 00:00:00 2001 From: philip Date: Sat, 28 Dec 2019 17:47:53 +0000 Subject: [PATCH] Fix missing corners of the world --- src/ol/reproj.js | 31 ++++++++++++++++++++++++++++++- src/ol/reproj/Tile.js | 9 ++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/ol/reproj.js b/src/ol/reproj.js index bb54d07f01..e669a4ec82 100644 --- a/src/ol/reproj.js +++ b/src/ol/reproj.js @@ -2,7 +2,7 @@ * @module ol/reproj */ import {createCanvasContext2D} from './dom.js'; -import {containsCoordinate, createEmpty, extend, getHeight, getTopLeft, getWidth} from './extent.js'; +import {containsCoordinate, createEmpty, extend, forEachCorner, getCenter, getHeight, getTopLeft, getWidth} from './extent.js'; import {solveLinearSystem} from './math.js'; import {getPointResolution, transform} from './proj.js'; @@ -53,6 +53,35 @@ export function calculateSourceResolution(sourceProj, targetProj, } +/** + * Calculates ideal resolution to use from the source in order to achieve + * pixel mapping as close as possible to 1:1 during reprojection. + * The resolution is calculated regardless of what resolutions + * are actually available in the dataset (TileGrid, Image, ...). + * + * @param {import("./proj/Projection.js").default} sourceProj Source projection. + * @param {import("./proj/Projection.js").default} targetProj Target projection. + * @param {import("./extent.js").Extent} targetExtent Target extent + * @param {number} targetResolution Target resolution. + * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0. + */ +export function calculateSourceExtentResolution(sourceProj, targetProj, + targetExtent, targetResolution) { + + const targetCenter = getCenter(targetExtent); + let sourceResolution = calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution); + + if (!isFinite(sourceResolution) || sourceResolution <= 0) { + forEachCorner(targetExtent, function(corner) { + sourceResolution = calculateSourceResolution(sourceProj, targetProj, corner, targetResolution); + return isFinite(sourceResolution) && sourceResolution > 0; + }); + } + + return sourceResolution; +} + + /** * Renders the source data into new canvas based on the triangulation. * diff --git a/src/ol/reproj/Tile.js b/src/ol/reproj/Tile.js index 909b125e7e..648431ac7f 100644 --- a/src/ol/reproj/Tile.js +++ b/src/ol/reproj/Tile.js @@ -7,9 +7,9 @@ import Tile from '../Tile.js'; import TileState from '../TileState.js'; import {listen, unlistenByKey} from '../events.js'; import EventType from '../events/EventType.js'; -import {getArea, getCenter, getIntersection} from '../extent.js'; +import {getArea, getIntersection} from '../extent.js'; import {clamp} from '../math.js'; -import {calculateSourceResolution, render as renderReprojected} from '../reproj.js'; +import {calculateSourceExtentResolution, render as renderReprojected} from '../reproj.js'; import Triangulation from './Triangulation.js'; @@ -140,9 +140,8 @@ class ReprojTile extends Tile { const targetResolution = targetTileGrid.getResolution( this.wrappedTileCoord_[0]); - const targetCenter = getCenter(limitedTargetExtent); - const sourceResolution = calculateSourceResolution( - sourceProj, targetProj, targetCenter, targetResolution); + const sourceResolution = calculateSourceExtentResolution( + sourceProj, targetProj, limitedTargetExtent, targetResolution); if (!isFinite(sourceResolution) || sourceResolution <= 0) { // invalid sourceResolution -> EMPTY