From a5f9baa9a3aa9d2fe134d6cef3280f7836e9a3e9 Mon Sep 17 00:00:00 2001 From: Benjamin Gerber Date: Fri, 9 Feb 2024 13:43:15 +0100 Subject: [PATCH] Add getExtent utils and constants --- CHANGES.md | 1 + src/VectorEncoder.ts | 2 +- src/constants.ts | 13 +++++++++++++ src/utils.ts | 23 ++++++++++++++++++++--- test.js | 5 +++-- 5 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/constants.ts diff --git a/CHANGES.md b/CHANGES.md index b2e8cf2..e48cf66 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # @geoblocks/geoblocks changes ## 0.2.3 +- Add utility functions. - In `BaseCustomizer`, the printExtent can be now set and get/set are dedicated methods. - `pdfA` (allow transparency) is now a spec.map optional param. - spec.attributes are now partial and `datasources` attribute is removed. diff --git a/src/VectorEncoder.ts b/src/VectorEncoder.ts index 85d897c..7660ee9 100644 --- a/src/VectorEncoder.ts +++ b/src/VectorEncoder.ts @@ -81,7 +81,7 @@ export default class VectorEncoder { } console.assert(source instanceof VectorSource); - const features = source.getFeaturesInExtent(this.customizer_.printExtent); + const features = source.getFeaturesInExtent(this.customizer_.getPrintExtent()); const geojsonFeatures: GeoJSONFeature[] = []; const mapfishStyleObject: MFPVectorStyle = { diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..cc1ca20 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,13 @@ +export const Constants = { + /** "Standardized rendering pixel size" is defined as 0.28 mm, see http://www.opengeospatial.org/standards/wmts */ + WMTS_PIXEL_SIZE: 0.28e-3, + /** Standard PPI */ + POINTS_PER_INCH: 72, + /** According to the "international yard" definition 1 inch is defined as exactly 2.54 cm. */ + METERS_PER_INCH: 0.0254, +}; + +export const CalculatedConstants = { + /** Default to PPI / METERS per Inch */ + POINTS_PER_DISTANCE_UNIT: () => Constants.POINTS_PER_INCH / Constants.METERS_PER_INCH, +}; diff --git a/src/utils.ts b/src/utils.ts index 9d51631..e956dc5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,9 +2,26 @@ import WMTSTileGrid from 'ol/tilegrid/WMTS.js'; import {toSize} from 'ol/size.js'; import type {MFPReportResponse, MFPSpec, MFPStatusResponse, MFPWmtsMatrix} from './types'; import type {WMTS} from 'ol/source.js'; +import type {Extent} from 'ol/extent'; +import {Constants, CalculatedConstants} from './constants'; -// "Standardized rendering pixel size" is defined as 0.28 mm, see http://www.opengeospatial.org/standards/wmts -const WMTS_PIXEL_SIZE_ = 0.28e-3; +/** + * @param mapPageSize The page size (width, height) + * @param center The coordinate of the extent's center. + * @param scale The scale to calculate the extent width. + * @returns an extent that fit the page size. Calculated with POINTS_PER_DISTANCE_UNIT (by default using meters) + */ +export function getPrintExtent(mapPageSize: number[], center: number[], scale: number): Extent { + const [mapPageWidthMeters, mapPageHeightMeters] = mapPageSize.map( + (side) => ((side / CalculatedConstants.POINTS_PER_DISTANCE_UNIT()) * scale) / 2, + ); + return [ + center[0] - mapPageWidthMeters, + center[1] - mapPageHeightMeters, + center[0] + mapPageWidthMeters, + center[1] + mapPageHeightMeters, + ]; +} /** * Takes a hex value and prepends a zero if it's a single digit. @@ -51,7 +68,7 @@ export function getWmtsMatrices(source: WMTS): MFPWmtsMatrix[] { const resolutionMeters = tileGrid.getResolution(i) * metersPerUnit; wmtsMatrices.push({ identifier: matrixIds[i], - scaleDenominator: resolutionMeters / WMTS_PIXEL_SIZE_, + scaleDenominator: resolutionMeters / Constants.WMTS_PIXEL_SIZE, tileSize: toSize(tileGrid.getTileSize(i)), topLeftCorner: tileGrid.getOrigin(i), matrixSize: [tileRange.maxX - tileRange.minX, tileRange.maxY - tileRange.minY], diff --git a/test.js b/test.js index be340c0..8c5c755 100644 --- a/test.js +++ b/test.js @@ -25,7 +25,7 @@ test('Empty map', async (t) => { dpi: 300, layout: 'landscape_a4', format: 'pdf', - customAttributes: {}, + customAttributes: {title: 'My title'}, customizer: customizer, }); assert.deepEqual(result, { @@ -38,6 +38,7 @@ test('Empty map', async (t) => { rotation: 0, scale: 1, }, + title: 'My title', }, format: 'pdf', layout: 'landscape_a4', @@ -45,7 +46,7 @@ test('Empty map', async (t) => { }); test('OSM map', async (t) => { - const MFP_URL = 'https://geomapfish-demo-2-5.camptocamp.com/printproxy'; + const MFP_URL = 'https://geomapfish-demo-2-8.camptocamp.com/printproxy'; const layout = '1 A4 portrait'; // better take from MFP const map = new Map({ target: 'map',