@swissgeo/coordinates 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -4
- package/dist/{registerProj4-CwR_kPOz.js → index-C-LPtO1W.js} +2094 -2148
- package/dist/index-C-LPtO1W.js.map +1 -0
- package/dist/{registerProj4-BuUOcPpF.cjs → index-e9ERo8-f.cjs} +7 -6
- package/dist/index-e9ERo8-f.cjs.map +1 -0
- package/dist/index.cjs +6 -5
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +16 -14
- package/dist/index.js +606 -551
- package/dist/index.js.map +1 -0
- package/dist/ol.cjs +2 -1
- package/dist/ol.cjs.map +1 -0
- package/dist/ol.d.ts +10 -5
- package/dist/ol.js +582 -4080
- package/dist/ol.js.map +1 -0
- package/index.html +3 -0
- package/package.json +5 -3
- package/src/DevApp.vue +33 -32
- package/src/ol.ts +60 -53
- package/src/proj/CoordinateSystem.ts +6 -4
- package/src/proj/SwissCoordinateSystem.ts +7 -7
- package/src/proj/WGS84CoordinateSystem.ts +4 -4
- package/src/proj/WebMercatorCoordinateSystem.ts +2 -2
- package/src/proj/__test__/CoordinateSystem.spec.ts +2 -2
- package/src/proj/__test__/SwissCoordinateSystem.spec.ts +9 -9
- package/vite.config.ts +4 -0
package/dist/ol.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ol.js","sources":["../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/TileRange.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/array.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/asserts.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/extent/Relationship.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/extent.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/geom/flat/contains.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/geom/flat/segments.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/geom/flat/intersectsextent.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/math.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/size.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/tilecoord.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/tilegrid/common.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/tilegrid/TileGrid.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/proj/Units.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/proj/Projection.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/proj/epsg3857.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/proj/epsg4326.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/proj/transforms.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/proj.js","../../../node_modules/.pnpm/ol@10.7.0_patch_hash=c45d55_1a6317f7ab800544ddc8a1bed35f2540/node_modules/ol/tilegrid/WMTS.js","../src/ol.ts"],"sourcesContent":["/**\n * @module ol/TileRange\n */\n\n/**\n * A representation of a contiguous block of tiles. A tile range is specified\n * by its min/max tile coordinates and is inclusive of coordinates.\n */\nclass TileRange {\n /**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n */\n constructor(minX, maxX, minY, maxY) {\n /**\n * @type {number}\n */\n this.minX = minX;\n\n /**\n * @type {number}\n */\n this.maxX = maxX;\n\n /**\n * @type {number}\n */\n this.minY = minY;\n\n /**\n * @type {number}\n */\n this.maxY = maxY;\n }\n\n /**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @return {boolean} Contains tile coordinate.\n */\n contains(tileCoord) {\n return this.containsXY(tileCoord[1], tileCoord[2]);\n }\n\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Contains.\n */\n containsTileRange(tileRange) {\n return (\n this.minX <= tileRange.minX &&\n tileRange.maxX <= this.maxX &&\n this.minY <= tileRange.minY &&\n tileRange.maxY <= this.maxY\n );\n }\n\n /**\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @return {boolean} Contains coordinate.\n */\n containsXY(x, y) {\n return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;\n }\n\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Equals.\n */\n equals(tileRange) {\n return (\n this.minX == tileRange.minX &&\n this.minY == tileRange.minY &&\n this.maxX == tileRange.maxX &&\n this.maxY == tileRange.maxY\n );\n }\n\n /**\n * @param {TileRange} tileRange Tile range.\n */\n extend(tileRange) {\n if (tileRange.minX < this.minX) {\n this.minX = tileRange.minX;\n }\n if (tileRange.maxX > this.maxX) {\n this.maxX = tileRange.maxX;\n }\n if (tileRange.minY < this.minY) {\n this.minY = tileRange.minY;\n }\n if (tileRange.maxY > this.maxY) {\n this.maxY = tileRange.maxY;\n }\n }\n\n /**\n * @return {number} Height.\n */\n getHeight() {\n return this.maxY - this.minY + 1;\n }\n\n /**\n * @return {import(\"./size.js\").Size} Size.\n */\n getSize() {\n return [this.getWidth(), this.getHeight()];\n }\n\n /**\n * @return {number} Width.\n */\n getWidth() {\n return this.maxX - this.minX + 1;\n }\n\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Intersects.\n */\n intersects(tileRange) {\n return (\n this.minX <= tileRange.maxX &&\n this.maxX >= tileRange.minX &&\n this.minY <= tileRange.maxY &&\n this.maxY >= tileRange.minY\n );\n }\n}\n\n/**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n * @param {TileRange} [tileRange] TileRange.\n * @return {TileRange} Tile range.\n */\nexport function createOrUpdate(minX, maxX, minY, maxY, tileRange) {\n if (tileRange !== undefined) {\n tileRange.minX = minX;\n tileRange.maxX = maxX;\n tileRange.minY = minY;\n tileRange.maxY = maxY;\n return tileRange;\n }\n return new TileRange(minX, maxX, minY, maxY);\n}\n\nexport default TileRange;\n","/**\n * @module ol/array\n */\n\n/**\n * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1.\n * https://github.com/darkskyapp/binary-search\n *\n * @param {Array<*>} haystack Items to search through.\n * @param {*} needle The item to look for.\n * @param {Function} [comparator] Comparator function.\n * @return {number} The index of the item if found, -1 if not.\n */\nexport function binarySearch(haystack, needle, comparator) {\n let mid, cmp;\n comparator = comparator || ascending;\n let low = 0;\n let high = haystack.length;\n let found = false;\n\n while (low < high) {\n /* Note that \"(low + high) >>> 1\" may overflow, and results in a typecast\n * to double (which gives the wrong results). */\n mid = low + ((high - low) >> 1);\n cmp = +comparator(haystack[mid], needle);\n\n if (cmp < 0.0) {\n /* Too low. */\n low = mid + 1;\n } else {\n /* Key found or too high */\n high = mid;\n found = !cmp;\n }\n }\n\n /* Key not found. */\n return found ? low : ~low;\n}\n\n/**\n * Compare function sorting arrays in ascending order. Safe to use for numeric values.\n * @param {*} a The first object to be compared.\n * @param {*} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second.\n */\nexport function ascending(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\n\n/**\n * Compare function sorting arrays in descending order. Safe to use for numeric values.\n * @param {*} a The first object to be compared.\n * @param {*} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is greater than, equal to, or less than the second.\n */\nexport function descending(a, b) {\n return a < b ? 1 : a > b ? -1 : 0;\n}\n\n/**\n * {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution} can use a function\n * of this type to determine which nearest resolution to use.\n *\n * This function takes a `{number}` representing a value between two array entries,\n * a `{number}` representing the value of the nearest higher entry and\n * a `{number}` representing the value of the nearest lower entry\n * as arguments and returns a `{number}`. If a negative number or zero is returned\n * the lower value will be used, if a positive number is returned the higher value\n * will be used.\n * @typedef {function(number, number, number): number} NearestDirectionFunction\n * @api\n */\n\n/**\n * @param {Array<number>} arr Array in descending order.\n * @param {number} target Target.\n * @param {number|NearestDirectionFunction} direction\n * 0 means return the nearest,\n * > 0 means return the largest nearest,\n * < 0 means return the smallest nearest.\n * @return {number} Index.\n */\nexport function linearFindNearest(arr, target, direction) {\n if (arr[0] <= target) {\n return 0;\n }\n\n const n = arr.length;\n if (target <= arr[n - 1]) {\n return n - 1;\n }\n\n if (typeof direction === 'function') {\n for (let i = 1; i < n; ++i) {\n const candidate = arr[i];\n if (candidate === target) {\n return i;\n }\n if (candidate < target) {\n if (direction(target, arr[i - 1], candidate) > 0) {\n return i - 1;\n }\n return i;\n }\n }\n return n - 1;\n }\n\n if (direction > 0) {\n for (let i = 1; i < n; ++i) {\n if (arr[i] < target) {\n return i - 1;\n }\n }\n return n - 1;\n }\n\n if (direction < 0) {\n for (let i = 1; i < n; ++i) {\n if (arr[i] <= target) {\n return i;\n }\n }\n return n - 1;\n }\n\n for (let i = 1; i < n; ++i) {\n if (arr[i] == target) {\n return i;\n }\n if (arr[i] < target) {\n if (arr[i - 1] - target < target - arr[i]) {\n return i - 1;\n }\n return i;\n }\n }\n return n - 1;\n}\n\n/**\n * @param {Array<*>} arr Array.\n * @param {number} begin Begin index.\n * @param {number} end End index.\n */\nexport function reverseSubArray(arr, begin, end) {\n while (begin < end) {\n const tmp = arr[begin];\n arr[begin] = arr[end];\n arr[end] = tmp;\n ++begin;\n --end;\n }\n}\n\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {!Array<VALUE>|VALUE} data The elements or arrays of elements to add to arr.\n * @template VALUE\n */\nexport function extend(arr, data) {\n const extension = Array.isArray(data) ? data : [data];\n const length = extension.length;\n for (let i = 0; i < length; i++) {\n arr[arr.length] = extension[i];\n }\n}\n\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {VALUE} obj The element to remove.\n * @template VALUE\n * @return {boolean} If the element was removed.\n */\nexport function remove(arr, obj) {\n const i = arr.indexOf(obj);\n const found = i > -1;\n if (found) {\n arr.splice(i, 1);\n }\n return found;\n}\n\n/**\n * @param {Array<any>|Uint8ClampedArray} arr1 The first array to compare.\n * @param {Array<any>|Uint8ClampedArray} arr2 The second array to compare.\n * @return {boolean} Whether the two arrays are equal.\n */\nexport function equals(arr1, arr2) {\n const len1 = arr1.length;\n if (len1 !== arr2.length) {\n return false;\n }\n for (let i = 0; i < len1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Sort the passed array such that the relative order of equal elements is preserved.\n * See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.\n * @param {Array<*>} arr The array to sort (modifies original).\n * @param {!function(*, *): number} compareFnc Comparison function.\n * @api\n * @deprecated\n */\nexport function stableSort(arr, compareFnc) {\n const length = arr.length;\n const tmp = Array(arr.length);\n let i;\n for (i = 0; i < length; i++) {\n tmp[i] = {index: i, value: arr[i]};\n }\n tmp.sort(function (a, b) {\n return compareFnc(a.value, b.value) || a.index - b.index;\n });\n for (i = 0; i < arr.length; i++) {\n arr[i] = tmp[i].value;\n }\n}\n\n/**\n * @param {Array<*>} arr The array to test.\n * @param {Function} [func] Comparison function.\n * @param {boolean} [strict] Strictly sorted (default false).\n * @return {boolean} Return index.\n */\nexport function isSorted(arr, func, strict) {\n const compare = func || ascending;\n return arr.every(function (currentVal, index) {\n if (index === 0) {\n return true;\n }\n const res = compare(arr[index - 1], currentVal);\n return !(res > 0 || (strict && res === 0));\n });\n}\n","/**\n * @module ol/asserts\n */\n\n/**\n * @param {*} assertion Assertion we expected to be truthy.\n * @param {string} errorMessage Error message.\n */\nexport function assert(assertion, errorMessage) {\n if (!assertion) {\n throw new Error(errorMessage);\n }\n}\n","/**\n * @module ol/extent/Relationship\n */\n\n/**\n * Relationship to an extent.\n * @enum {number}\n */\nexport default {\n UNKNOWN: 0,\n INTERSECTING: 1,\n ABOVE: 2,\n RIGHT: 4,\n BELOW: 8,\n LEFT: 16,\n};\n","/**\n * @module ol/extent\n */\nimport Relationship from './extent/Relationship.js';\n\n/**\n * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.\n * @typedef {Array<number>} Extent\n * @api\n */\n\n/**\n * Extent corner.\n * @typedef {'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'} Corner\n */\n\n/**\n * Build an extent that includes all given coordinates.\n *\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates Coordinates.\n * @return {Extent} Bounding extent.\n * @api\n */\nexport function boundingExtent(coordinates) {\n const extent = createEmpty();\n for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n return extent;\n}\n\n/**\n * @param {Array<number>} xs Xs.\n * @param {Array<number>} ys Ys.\n * @param {Extent} [dest] Destination extent.\n * @private\n * @return {Extent} Extent.\n */\nfunction _boundingExtentXYs(xs, ys, dest) {\n const minX = Math.min.apply(null, xs);\n const minY = Math.min.apply(null, ys);\n const maxX = Math.max.apply(null, xs);\n const maxY = Math.max.apply(null, ys);\n return createOrUpdate(minX, minY, maxX, maxY, dest);\n}\n\n/**\n * Return extent increased by the provided value.\n * @param {Extent} extent Extent.\n * @param {number} value The amount by which the extent should be buffered.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n * @api\n */\nexport function buffer(extent, value, dest) {\n if (dest) {\n dest[0] = extent[0] - value;\n dest[1] = extent[1] - value;\n dest[2] = extent[2] + value;\n dest[3] = extent[3] + value;\n return dest;\n }\n return [\n extent[0] - value,\n extent[1] - value,\n extent[2] + value,\n extent[3] + value,\n ];\n}\n\n/**\n * Creates a clone of an extent.\n *\n * @param {Extent} extent Extent to clone.\n * @param {Extent} [dest] Extent.\n * @return {Extent} The clone.\n */\nexport function clone(extent, dest) {\n if (dest) {\n dest[0] = extent[0];\n dest[1] = extent[1];\n dest[2] = extent[2];\n dest[3] = extent[3];\n return dest;\n }\n return extent.slice();\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {number} Closest squared distance.\n */\nexport function closestSquaredDistanceXY(extent, x, y) {\n let dx, dy;\n if (x < extent[0]) {\n dx = extent[0] - x;\n } else if (extent[2] < x) {\n dx = x - extent[2];\n } else {\n dx = 0;\n }\n if (y < extent[1]) {\n dy = extent[1] - y;\n } else if (extent[3] < y) {\n dy = y - extent[3];\n } else {\n dy = 0;\n }\n return dx * dx + dy * dy;\n}\n\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @return {boolean} The coordinate is contained in the extent.\n * @api\n */\nexport function containsCoordinate(extent, coordinate) {\n return containsXY(extent, coordinate[0], coordinate[1]);\n}\n\n/**\n * Check if one extent contains another.\n *\n * An extent is deemed contained if it lies completely within the other extent,\n * including if they share one or more edges.\n *\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The second extent is contained by or on the edge of the\n * first.\n * @api\n */\nexport function containsExtent(extent1, extent2) {\n return (\n extent1[0] <= extent2[0] &&\n extent2[2] <= extent1[2] &&\n extent1[1] <= extent2[1] &&\n extent2[3] <= extent1[3]\n );\n}\n\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n * @return {boolean} The x, y values are contained in the extent.\n * @api\n */\nexport function containsXY(extent, x, y) {\n return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];\n}\n\n/**\n * Get the relationship between a coordinate and extent.\n * @param {Extent} extent The extent.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate The coordinate.\n * @return {import(\"./extent/Relationship.js\").default} The relationship (bitwise compare with\n * import(\"./extent/Relationship.js\").Relationship).\n */\nexport function coordinateRelationship(extent, coordinate) {\n const minX = extent[0];\n const minY = extent[1];\n const maxX = extent[2];\n const maxY = extent[3];\n const x = coordinate[0];\n const y = coordinate[1];\n let relationship = Relationship.UNKNOWN;\n if (x < minX) {\n relationship = relationship | Relationship.LEFT;\n } else if (x > maxX) {\n relationship = relationship | Relationship.RIGHT;\n }\n if (y < minY) {\n relationship = relationship | Relationship.BELOW;\n } else if (y > maxY) {\n relationship = relationship | Relationship.ABOVE;\n }\n if (relationship === Relationship.UNKNOWN) {\n relationship = Relationship.INTERSECTING;\n }\n return relationship;\n}\n\n/**\n * Create an empty extent.\n * @return {Extent} Empty extent.\n * @api\n */\nexport function createEmpty() {\n return [Infinity, Infinity, -Infinity, -Infinity];\n}\n\n/**\n * Create a new extent or update the provided extent.\n * @param {number} minX Minimum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxX Maximum X.\n * @param {number} maxY Maximum Y.\n * @param {Extent} [dest] Destination extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdate(minX, minY, maxX, maxY, dest) {\n if (dest) {\n dest[0] = minX;\n dest[1] = minY;\n dest[2] = maxX;\n dest[3] = maxY;\n return dest;\n }\n return [minX, minY, maxX, maxY];\n}\n\n/**\n * Create a new empty extent or make the provided one empty.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateEmpty(dest) {\n return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, dest);\n}\n\n/**\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromCoordinate(coordinate, dest) {\n const x = coordinate[0];\n const y = coordinate[1];\n return createOrUpdate(x, y, x, y, dest);\n}\n\n/**\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates Coordinates.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromCoordinates(coordinates, dest) {\n const extent = createOrUpdateEmpty(dest);\n return extendCoordinates(extent, coordinates);\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromFlatCoordinates(\n flatCoordinates,\n offset,\n end,\n stride,\n dest,\n) {\n const extent = createOrUpdateEmpty(dest);\n return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);\n}\n\n/**\n * @param {Array<Array<import(\"./coordinate.js\").Coordinate>>} rings Rings.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromRings(rings, dest) {\n const extent = createOrUpdateEmpty(dest);\n return extendRings(extent, rings);\n}\n\n/**\n * Determine if two extents are equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The two extents are equivalent.\n * @api\n */\nexport function equals(extent1, extent2) {\n return (\n extent1[0] == extent2[0] &&\n extent1[2] == extent2[2] &&\n extent1[1] == extent2[1] &&\n extent1[3] == extent2[3]\n );\n}\n\n/**\n * Determine if two extents are approximately equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {number} tolerance Tolerance in extent coordinate units.\n * @return {boolean} The two extents differ by less than the tolerance.\n */\nexport function approximatelyEquals(extent1, extent2, tolerance) {\n return (\n Math.abs(extent1[0] - extent2[0]) < tolerance &&\n Math.abs(extent1[2] - extent2[2]) < tolerance &&\n Math.abs(extent1[1] - extent2[1]) < tolerance &&\n Math.abs(extent1[3] - extent2[3]) < tolerance\n );\n}\n\n/**\n * Modify an extent to include another extent.\n * @param {Extent} extent1 The extent to be modified.\n * @param {Extent} extent2 The extent that will be included in the first.\n * @return {Extent} A reference to the first (extended) extent.\n * @api\n */\nexport function extend(extent1, extent2) {\n if (extent2[0] < extent1[0]) {\n extent1[0] = extent2[0];\n }\n if (extent2[2] > extent1[2]) {\n extent1[2] = extent2[2];\n }\n if (extent2[1] < extent1[1]) {\n extent1[1] = extent2[1];\n }\n if (extent2[3] > extent1[3]) {\n extent1[3] = extent2[3];\n }\n return extent1;\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n */\nexport function extendCoordinate(extent, coordinate) {\n if (coordinate[0] < extent[0]) {\n extent[0] = coordinate[0];\n }\n if (coordinate[0] > extent[2]) {\n extent[2] = coordinate[0];\n }\n if (coordinate[1] < extent[1]) {\n extent[1] = coordinate[1];\n }\n if (coordinate[1] > extent[3]) {\n extent[3] = coordinate[1];\n }\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates Coordinates.\n * @return {Extent} Extent.\n */\nexport function extendCoordinates(extent, coordinates) {\n for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n return extent;\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Extent} Extent.\n */\nexport function extendFlatCoordinates(\n extent,\n flatCoordinates,\n offset,\n end,\n stride,\n) {\n for (; offset < end; offset += stride) {\n extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);\n }\n return extent;\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {Array<Array<import(\"./coordinate.js\").Coordinate>>} rings Rings.\n * @return {Extent} Extent.\n */\nexport function extendRings(extent, rings) {\n for (let i = 0, ii = rings.length; i < ii; ++i) {\n extendCoordinates(extent, rings[i]);\n }\n return extent;\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n */\nexport function extendXY(extent, x, y) {\n extent[0] = Math.min(extent[0], x);\n extent[1] = Math.min(extent[1], y);\n extent[2] = Math.max(extent[2], x);\n extent[3] = Math.max(extent[3], y);\n}\n\n/**\n * This function calls `callback` for each corner of the extent. If the\n * callback returns a truthy value the function returns that value\n * immediately. Otherwise the function returns `false`.\n * @param {Extent} extent Extent.\n * @param {function(import(\"./coordinate.js\").Coordinate): S} callback Callback.\n * @return {S|boolean} Value.\n * @template S\n */\nexport function forEachCorner(extent, callback) {\n let val;\n val = callback(getBottomLeft(extent));\n if (val) {\n return val;\n }\n val = callback(getBottomRight(extent));\n if (val) {\n return val;\n }\n val = callback(getTopRight(extent));\n if (val) {\n return val;\n }\n val = callback(getTopLeft(extent));\n if (val) {\n return val;\n }\n return false;\n}\n\n/**\n * Get the size of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Area.\n * @api\n */\nexport function getArea(extent) {\n let area = 0;\n if (!isEmpty(extent)) {\n area = getWidth(extent) * getHeight(extent);\n }\n return area;\n}\n\n/**\n * Get the bottom left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Bottom left coordinate.\n * @api\n */\nexport function getBottomLeft(extent) {\n return [extent[0], extent[1]];\n}\n\n/**\n * Get the bottom right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Bottom right coordinate.\n * @api\n */\nexport function getBottomRight(extent) {\n return [extent[2], extent[1]];\n}\n\n/**\n * Get the center coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Center.\n * @api\n */\nexport function getCenter(extent) {\n return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];\n}\n\n/**\n * Get a corner coordinate of an extent.\n * @param {Extent} extent Extent.\n * @param {Corner} corner Corner.\n * @return {import(\"./coordinate.js\").Coordinate} Corner coordinate.\n */\nexport function getCorner(extent, corner) {\n let coordinate;\n if (corner === 'bottom-left') {\n coordinate = getBottomLeft(extent);\n } else if (corner === 'bottom-right') {\n coordinate = getBottomRight(extent);\n } else if (corner === 'top-left') {\n coordinate = getTopLeft(extent);\n } else if (corner === 'top-right') {\n coordinate = getTopRight(extent);\n } else {\n throw new Error('Invalid corner');\n }\n return coordinate;\n}\n\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Enlarged area.\n */\nexport function getEnlargedArea(extent1, extent2) {\n const minX = Math.min(extent1[0], extent2[0]);\n const minY = Math.min(extent1[1], extent2[1]);\n const maxX = Math.max(extent1[2], extent2[2]);\n const maxY = Math.max(extent1[3], extent2[3]);\n return (maxX - minX) * (maxY - minY);\n}\n\n/**\n * @param {import(\"./coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import(\"./size.js\").Size} size Size.\n * @param {Extent} [dest] Destination extent.\n * @return {Extent} Extent.\n */\nexport function getForViewAndSize(center, resolution, rotation, size, dest) {\n const [x0, y0, x1, y1, x2, y2, x3, y3] = getRotatedViewport(\n center,\n resolution,\n rotation,\n size,\n );\n return createOrUpdate(\n Math.min(x0, x1, x2, x3),\n Math.min(y0, y1, y2, y3),\n Math.max(x0, x1, x2, x3),\n Math.max(y0, y1, y2, y3),\n dest,\n );\n}\n\n/**\n * @param {import(\"./coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import(\"./size.js\").Size} size Size.\n * @return {Array<number>} Linear ring representing the viewport.\n */\nexport function getRotatedViewport(center, resolution, rotation, size) {\n const dx = (resolution * size[0]) / 2;\n const dy = (resolution * size[1]) / 2;\n const cosRotation = Math.cos(rotation);\n const sinRotation = Math.sin(rotation);\n const xCos = dx * cosRotation;\n const xSin = dx * sinRotation;\n const yCos = dy * cosRotation;\n const ySin = dy * sinRotation;\n const x = center[0];\n const y = center[1];\n return [\n x - xCos + ySin,\n y - xSin - yCos,\n x - xCos - ySin,\n y - xSin + yCos,\n x + xCos - ySin,\n y + xSin + yCos,\n x + xCos + ySin,\n y + xSin - yCos,\n x - xCos + ySin,\n y - xSin - yCos,\n ];\n}\n\n/**\n * Get the height of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Height.\n * @api\n */\nexport function getHeight(extent) {\n return extent[3] - extent[1];\n}\n\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Intersection area.\n */\nexport function getIntersectionArea(extent1, extent2) {\n const intersection = getIntersection(extent1, extent2);\n return getArea(intersection);\n}\n\n/**\n * Get the intersection of two extents.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {Extent} [dest] Optional extent to populate with intersection.\n * @return {Extent} Intersecting extent.\n * @api\n */\nexport function getIntersection(extent1, extent2, dest) {\n const intersection = dest ? dest : createEmpty();\n if (intersects(extent1, extent2)) {\n if (extent1[0] > extent2[0]) {\n intersection[0] = extent1[0];\n } else {\n intersection[0] = extent2[0];\n }\n if (extent1[1] > extent2[1]) {\n intersection[1] = extent1[1];\n } else {\n intersection[1] = extent2[1];\n }\n if (extent1[2] < extent2[2]) {\n intersection[2] = extent1[2];\n } else {\n intersection[2] = extent2[2];\n }\n if (extent1[3] < extent2[3]) {\n intersection[3] = extent1[3];\n } else {\n intersection[3] = extent2[3];\n }\n } else {\n createOrUpdateEmpty(intersection);\n }\n return intersection;\n}\n\n/**\n * @param {Extent} extent Extent.\n * @return {number} Margin.\n */\nexport function getMargin(extent) {\n return getWidth(extent) + getHeight(extent);\n}\n\n/**\n * Get the size (width, height) of an extent.\n * @param {Extent} extent The extent.\n * @return {import(\"./size.js\").Size} The extent size.\n * @api\n */\nexport function getSize(extent) {\n return [extent[2] - extent[0], extent[3] - extent[1]];\n}\n\n/**\n * Get the top left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Top left coordinate.\n * @api\n */\nexport function getTopLeft(extent) {\n return [extent[0], extent[3]];\n}\n\n/**\n * Get the top right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Top right coordinate.\n * @api\n */\nexport function getTopRight(extent) {\n return [extent[2], extent[3]];\n}\n\n/**\n * Get the width of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Width.\n * @api\n */\nexport function getWidth(extent) {\n return extent[2] - extent[0];\n}\n\n/**\n * Determine if one extent intersects another.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent.\n * @return {boolean} The two extents intersect.\n * @api\n */\nexport function intersects(extent1, extent2) {\n return (\n extent1[0] <= extent2[2] &&\n extent1[2] >= extent2[0] &&\n extent1[1] <= extent2[3] &&\n extent1[3] >= extent2[1]\n );\n}\n\n/**\n * Determine if an extent is empty.\n * @param {Extent} extent Extent.\n * @return {boolean} Is empty.\n * @api\n */\nexport function isEmpty(extent) {\n return extent[2] < extent[0] || extent[3] < extent[1];\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {Extent} [dest] Extent.\n * @return {Extent} Extent.\n */\nexport function returnOrUpdate(extent, dest) {\n if (dest) {\n dest[0] = extent[0];\n dest[1] = extent[1];\n dest[2] = extent[2];\n dest[3] = extent[3];\n return dest;\n }\n return extent;\n}\n\n/**\n * @param {Extent} extent Extent.\n * @param {number} value Value.\n */\nexport function scaleFromCenter(extent, value) {\n const deltaX = ((extent[2] - extent[0]) / 2) * (value - 1);\n const deltaY = ((extent[3] - extent[1]) / 2) * (value - 1);\n extent[0] -= deltaX;\n extent[2] += deltaX;\n extent[1] -= deltaY;\n extent[3] += deltaY;\n}\n\n/**\n * Determine if the segment between two coordinates intersects (crosses,\n * touches, or is contained by) the provided extent.\n * @param {Extent} extent The extent.\n * @param {import(\"./coordinate.js\").Coordinate} start Segment start coordinate.\n * @param {import(\"./coordinate.js\").Coordinate} end Segment end coordinate.\n * @return {boolean} The segment intersects the extent.\n */\nexport function intersectsSegment(extent, start, end) {\n let intersects = false;\n const startRel = coordinateRelationship(extent, start);\n const endRel = coordinateRelationship(extent, end);\n if (\n startRel === Relationship.INTERSECTING ||\n endRel === Relationship.INTERSECTING\n ) {\n intersects = true;\n } else {\n const minX = extent[0];\n const minY = extent[1];\n const maxX = extent[2];\n const maxY = extent[3];\n const startX = start[0];\n const startY = start[1];\n const endX = end[0];\n const endY = end[1];\n const slope = (endY - startY) / (endX - startX);\n let x, y;\n if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {\n // potentially intersects top\n x = endX - (endY - maxY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n if (\n !intersects &&\n !!(endRel & Relationship.RIGHT) &&\n !(startRel & Relationship.RIGHT)\n ) {\n // potentially intersects right\n y = endY - (endX - maxX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n if (\n !intersects &&\n !!(endRel & Relationship.BELOW) &&\n !(startRel & Relationship.BELOW)\n ) {\n // potentially intersects bottom\n x = endX - (endY - minY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n if (\n !intersects &&\n !!(endRel & Relationship.LEFT) &&\n !(startRel & Relationship.LEFT)\n ) {\n // potentially intersects left\n y = endY - (endX - minX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n }\n return intersects;\n}\n\n/**\n * Apply a transform function to the extent.\n * @param {Extent} extent Extent.\n * @param {import(\"./proj.js\").TransformFunction} transformFn Transform function.\n * Called with `[minX, minY, maxX, maxY]` extent coordinates.\n * @param {Extent} [dest] Destination extent.\n * @param {number} [stops] Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {Extent} Extent.\n * @api\n */\nexport function applyTransform(extent, transformFn, dest, stops) {\n if (isEmpty(extent)) {\n return createOrUpdateEmpty(dest);\n }\n let coordinates = [];\n if (stops > 1) {\n const width = extent[2] - extent[0];\n const height = extent[3] - extent[1];\n for (let i = 0; i < stops; ++i) {\n coordinates.push(\n extent[0] + (width * i) / stops,\n extent[1],\n extent[2],\n extent[1] + (height * i) / stops,\n extent[2] - (width * i) / stops,\n extent[3],\n extent[0],\n extent[3] - (height * i) / stops,\n );\n }\n } else {\n coordinates = [\n extent[0],\n extent[1],\n extent[2],\n extent[1],\n extent[2],\n extent[3],\n extent[0],\n extent[3],\n ];\n }\n transformFn(coordinates, coordinates, 2);\n const xs = [];\n const ys = [];\n for (let i = 0, l = coordinates.length; i < l; i += 2) {\n xs.push(coordinates[i]);\n ys.push(coordinates[i + 1]);\n }\n return _boundingExtentXYs(xs, ys, dest);\n}\n\n/**\n * Modifies the provided extent in-place to be within the real world\n * extent.\n *\n * @param {Extent} extent Extent.\n * @param {import(\"./proj/Projection.js\").default} projection Projection\n * @return {Extent} The extent within the real world extent.\n */\nexport function wrapX(extent, projection) {\n const projectionExtent = projection.getExtent();\n const center = getCenter(extent);\n if (\n projection.canWrapX() &&\n (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])\n ) {\n const worldWidth = getWidth(projectionExtent);\n const worldsAway = Math.floor(\n (center[0] - projectionExtent[0]) / worldWidth,\n );\n const offset = worldsAway * worldWidth;\n extent[0] -= offset;\n extent[2] -= offset;\n }\n return extent;\n}\n\n/**\n * Fits the extent to the real world\n *\n * If the extent does not cross the anti meridian, this will return the extent in an array\n * If the extent crosses the anti meridian, the extent will be sliced, so each part fits within the\n * real world\n *\n *\n * @param {Extent} extent Extent.\n * @param {import(\"./proj/Projection.js\").default} projection Projection\n * @param {boolean} [multiWorld] Return all worlds\n * @return {Array<Extent>} The extent within the real world extent.\n */\nexport function wrapAndSliceX(extent, projection, multiWorld) {\n if (projection.canWrapX()) {\n const projectionExtent = projection.getExtent();\n\n if (!isFinite(extent[0]) || !isFinite(extent[2])) {\n return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];\n }\n\n wrapX(extent, projection);\n const worldWidth = getWidth(projectionExtent);\n\n if (getWidth(extent) > worldWidth && !multiWorld) {\n // the extent wraps around on itself\n return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];\n }\n if (extent[0] < projectionExtent[0]) {\n // the extent crosses the anti meridian, so it needs to be sliced\n return [\n [extent[0] + worldWidth, extent[1], projectionExtent[2], extent[3]],\n [projectionExtent[0], extent[1], extent[2], extent[3]],\n ];\n }\n if (extent[2] > projectionExtent[2]) {\n // the extent crosses the anti meridian, so it needs to be sliced\n return [\n [extent[0], extent[1], projectionExtent[2], extent[3]],\n [projectionExtent[0], extent[1], extent[2] - worldWidth, extent[3]],\n ];\n }\n }\n\n return [extent];\n}\n","/**\n * @module ol/geom/flat/contains\n */\nimport {forEachCorner} from '../../extent.js';\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} Contains extent.\n */\nexport function linearRingContainsExtent(\n flatCoordinates,\n offset,\n end,\n stride,\n extent,\n) {\n const outside = forEachCorner(\n extent,\n /**\n * @param {import(\"../../coordinate.js\").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains (x, y).\n */\n function (coordinate) {\n return !linearRingContainsXY(\n flatCoordinates,\n offset,\n end,\n stride,\n coordinate[0],\n coordinate[1],\n );\n },\n );\n return !outside;\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingContainsXY(\n flatCoordinates,\n offset,\n end,\n stride,\n x,\n y,\n) {\n // https://web.archive.org/web/20210504233957/http://geomalgorithms.com/a03-_inclusion.html\n // Copyright 2000 softSurfer, 2012 Dan Sunday\n // This code may be freely used and modified for any purpose\n // providing that this copyright notice is included with it.\n // SoftSurfer makes no warranty for this code, and cannot be held\n // liable for any real or imagined damage resulting from its use.\n // Users of this code must verify correctness for their application.\n let wn = 0;\n let x1 = flatCoordinates[end - stride];\n let y1 = flatCoordinates[end - stride + 1];\n for (; offset < end; offset += stride) {\n const x2 = flatCoordinates[offset];\n const y2 = flatCoordinates[offset + 1];\n if (y1 <= y) {\n if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {\n wn++;\n }\n } else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {\n wn--;\n }\n x1 = x2;\n y1 = y2;\n }\n return wn !== 0;\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingsContainsXY(\n flatCoordinates,\n offset,\n ends,\n stride,\n x,\n y,\n) {\n if (ends.length === 0) {\n return false;\n }\n if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {\n return false;\n }\n for (let i = 1, ii = ends.length; i < ii; ++i) {\n if (\n linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)\n ) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingssContainsXY(\n flatCoordinates,\n offset,\n endss,\n stride,\n x,\n y,\n) {\n if (endss.length === 0) {\n return false;\n }\n for (let i = 0, ii = endss.length; i < ii; ++i) {\n const ends = endss[i];\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n return true;\n }\n offset = ends[ends.length - 1];\n }\n return false;\n}\n","/**\n * @module ol/geom/flat/segments\n */\n\n/**\n * This function calls `callback` for each segment of the flat coordinates\n * array. If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {function(import(\"../../coordinate.js\").Coordinate, import(\"../../coordinate.js\").Coordinate): T} callback Function\n * called for each segment.\n * @return {T|boolean} Value.\n * @template T\n */\nexport function forEach(flatCoordinates, offset, end, stride, callback) {\n let ret;\n offset += stride;\n for (; offset < end; offset += stride) {\n ret = callback(\n flatCoordinates.slice(offset - stride, offset),\n flatCoordinates.slice(offset, offset + stride),\n );\n if (ret) {\n return ret;\n }\n }\n return false;\n}\n\n/**\n * Calculate the intersection point of two line segments.\n * Reference: https://stackoverflow.com/a/72474223/2389327\n * @param {Array<import(\"../../coordinate.js\").Coordinate>} segment1 The first line segment as an array of two points.\n * @param {Array<import(\"../../coordinate.js\").Coordinate>} segment2 The second line segment as an array of two points.\n * @return {import(\"../../coordinate.js\").Coordinate|undefined} The intersection point or `undefined` if no intersection.\n */\nexport function getIntersectionPoint(segment1, segment2) {\n const [a, b] = segment1;\n const [c, d] = segment2;\n const t =\n ((a[0] - c[0]) * (c[1] - d[1]) - (a[1] - c[1]) * (c[0] - d[0])) /\n ((a[0] - b[0]) * (c[1] - d[1]) - (a[1] - b[1]) * (c[0] - d[0]));\n const u =\n ((a[0] - c[0]) * (a[1] - b[1]) - (a[1] - c[1]) * (a[0] - b[0])) /\n ((a[0] - b[0]) * (c[1] - d[1]) - (a[1] - b[1]) * (c[0] - d[0]));\n\n // Check if lines actually intersect\n if (0 <= t && t <= 1 && 0 <= u && u <= 1) {\n return [a[0] + t * (b[0] - a[0]), a[1] + t * (b[1] - a[1])];\n }\n return undefined;\n}\n","/**\n * @module ol/geom/flat/intersectsextent\n */\nimport {\n createEmpty,\n extendFlatCoordinates,\n intersects,\n intersectsSegment,\n} from '../../extent.js';\nimport {linearRingContainsExtent, linearRingContainsXY} from './contains.js';\nimport {forEach as forEachSegment} from './segments.js';\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @param {import('../../extent.js').Extent} [coordinatesExtent] Coordinates extent\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLineString(\n flatCoordinates,\n offset,\n end,\n stride,\n extent,\n coordinatesExtent,\n) {\n coordinatesExtent =\n coordinatesExtent ??\n extendFlatCoordinates(createEmpty(), flatCoordinates, offset, end, stride);\n if (!intersects(extent, coordinatesExtent)) {\n return false;\n }\n if (\n (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2]) ||\n (coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3])\n ) {\n return true;\n }\n return forEachSegment(\n flatCoordinates,\n offset,\n end,\n stride,\n /**\n * @param {import(\"../../coordinate.js\").Coordinate} point1 Start point.\n * @param {import(\"../../coordinate.js\").Coordinate} point2 End point.\n * @return {boolean} `true` if the segment and the extent intersect,\n * `false` otherwise.\n */\n function (point1, point2) {\n return intersectsSegment(extent, point1, point2);\n },\n );\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLineStringArray(\n flatCoordinates,\n offset,\n ends,\n stride,\n extent,\n) {\n for (let i = 0, ii = ends.length; i < ii; ++i) {\n if (\n intersectsLineString(flatCoordinates, offset, ends[i], stride, extent)\n ) {\n return true;\n }\n offset = ends[i];\n }\n return false;\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRing(\n flatCoordinates,\n offset,\n end,\n stride,\n extent,\n) {\n if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {\n return true;\n }\n if (\n linearRingContainsXY(\n flatCoordinates,\n offset,\n end,\n stride,\n extent[0],\n extent[1],\n )\n ) {\n return true;\n }\n if (\n linearRingContainsXY(\n flatCoordinates,\n offset,\n end,\n stride,\n extent[0],\n extent[3],\n )\n ) {\n return true;\n }\n if (\n linearRingContainsXY(\n flatCoordinates,\n offset,\n end,\n stride,\n extent[2],\n extent[1],\n )\n ) {\n return true;\n }\n if (\n linearRingContainsXY(\n flatCoordinates,\n offset,\n end,\n stride,\n extent[2],\n extent[3],\n )\n ) {\n return true;\n }\n return false;\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRingArray(\n flatCoordinates,\n offset,\n ends,\n stride,\n extent,\n) {\n if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {\n return false;\n }\n if (ends.length === 1) {\n return true;\n }\n for (let i = 1, ii = ends.length; i < ii; ++i) {\n if (\n linearRingContainsExtent(\n flatCoordinates,\n ends[i - 1],\n ends[i],\n stride,\n extent,\n )\n ) {\n if (\n !intersectsLineString(\n flatCoordinates,\n ends[i - 1],\n ends[i],\n stride,\n extent,\n )\n ) {\n return false;\n }\n }\n }\n return true;\n}\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRingMultiArray(\n flatCoordinates,\n offset,\n endss,\n stride,\n extent,\n) {\n for (let i = 0, ii = endss.length; i < ii; ++i) {\n const ends = endss[i];\n if (\n intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent)\n ) {\n return true;\n }\n offset = ends[ends.length - 1];\n }\n return false;\n}\n","/**\n * @module ol/math\n */\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n * number within the bounds.\n */\nexport function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n const dx = x2 - x1;\n const dy = y2 - y1;\n if (dx !== 0 || dy !== 0) {\n const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n if (t > 1) {\n x1 = x2;\n y1 = y2;\n } else if (t > 0) {\n x1 += dx * t;\n y1 += dy * t;\n }\n }\n return squaredDistance(x, y, x1, y1);\n}\n\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredDistance(x1, y1, x2, y2) {\n const dx = x2 - x1;\n const dy = y2 - y1;\n return dx * dx + dy * dy;\n}\n\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n * in row-major order.\n * @return {Array<number>|null} The resulting vector.\n */\nexport function solveLinearSystem(mat) {\n const n = mat.length;\n\n for (let i = 0; i < n; i++) {\n // Find max in the i-th column (ignoring i - 1 first rows)\n let maxRow = i;\n let maxEl = Math.abs(mat[i][i]);\n for (let r = i + 1; r < n; r++) {\n const absValue = Math.abs(mat[r][i]);\n if (absValue > maxEl) {\n maxEl = absValue;\n maxRow = r;\n }\n }\n\n if (maxEl === 0) {\n return null; // matrix is singular\n }\n\n // Swap max row with i-th (current) row\n const tmp = mat[maxRow];\n mat[maxRow] = mat[i];\n mat[i] = tmp;\n\n // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n for (let j = i + 1; j < n; j++) {\n const coef = -mat[j][i] / mat[i][i];\n for (let k = i; k < n + 1; k++) {\n if (i == k) {\n mat[j][k] = 0;\n } else {\n mat[j][k] += coef * mat[i][k];\n }\n }\n }\n }\n\n // Solve Ax=b for upper triangular matrix A (mat)\n const x = new Array(n);\n for (let l = n - 1; l >= 0; l--) {\n x[l] = mat[l][n] / mat[l][l];\n for (let m = l - 1; m >= 0; m--) {\n mat[m][n] -= mat[m][l] * x[l];\n }\n }\n return x;\n}\n\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\nexport function toDegrees(angleInRadians) {\n return (angleInRadians * 180) / Math.PI;\n}\n\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\nexport function toRadians(angleInDegrees) {\n return (angleInDegrees * Math.PI) / 180;\n}\n\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\nexport function modulo(a, b) {\n const r = a % b;\n return r * b < 0 ? r + b : r;\n}\n\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\nexport function lerp(a, b, x) {\n return a + x * (b - a);\n}\n\n/**\n * Returns a number with a limited number of decimal digits.\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The input number with a limited number of decimal digits.\n */\nexport function toFixed(n, decimals) {\n const factor = Math.pow(10, decimals);\n return Math.round(n * factor) / factor;\n}\n\n/**\n * Rounds a number to the nearest integer value considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The nearest integer.\n */\nexport function round(n, decimals) {\n return Math.round(toFixed(n, decimals));\n}\n\n/**\n * Rounds a number to the next smaller integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next smaller integer.\n */\nexport function floor(n, decimals) {\n return Math.floor(toFixed(n, decimals));\n}\n\n/**\n * Rounds a number to the next bigger integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next bigger integer.\n */\nexport function ceil(n, decimals) {\n return Math.ceil(toFixed(n, decimals));\n}\n\n/**\n * Wraps a number between some minimum and maximum values.\n * @param {number} n The number to wrap.\n * @param {number} min The minimum of the range (inclusive).\n * @param {number} max The maximum of the range (exclusive).\n * @return {number} The wrapped number.\n */\nexport function wrap(n, min, max) {\n if (n >= min && n < max) {\n return n;\n }\n const range = max - min;\n return ((((n - min) % range) + range) % range) + min;\n}\n","/**\n * @module ol/size\n */\n\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array<number>} Size\n * @api\n */\n\n/**\n * Returns a buffered size.\n * @param {Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} The buffered size.\n */\nexport function buffer(size, num, dest) {\n if (dest === undefined) {\n dest = [0, 0];\n }\n dest[0] = size[0] + 2 * num;\n dest[1] = size[1] + 2 * num;\n return dest;\n}\n\n/**\n * Determines if a size has a positive area.\n * @param {Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\nexport function hasArea(size) {\n return size[0] > 0 && size[1] > 0;\n}\n\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {Size} size Size.\n * @param {number} ratio Ratio.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} The scaled size.\n */\nexport function scale(size, ratio, dest) {\n if (dest === undefined) {\n dest = [0, 0];\n }\n dest[0] = (size[0] * ratio + 0.5) | 0;\n dest[1] = (size[1] * ratio + 0.5) | 0;\n return dest;\n}\n\n/**\n * Returns an `Size` array for the passed in number (meaning: square) or\n * `Size` array.\n * (meaning: non-square),\n * @param {number|Size} size Width and height.\n * @param {Size} [dest] Optional reusable size array.\n * @return {Size} Size.\n * @api\n */\nexport function toSize(size, dest) {\n if (Array.isArray(size)) {\n return size;\n }\n if (dest === undefined) {\n dest = [size, size];\n } else {\n dest[0] = size;\n dest[1] = size;\n }\n return dest;\n}\n","/**\n * @module ol/tilecoord\n */\n\nimport {getUid} from './util.js';\n\n/**\n * An array of three numbers representing the location of a tile in a tile\n * grid. The order is `z` (zoom level), `x` (column), and `y` (row).\n * @typedef {Array<number>} TileCoord\n * @api\n */\n\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {TileCoord} [tileCoord] Tile coordinate.\n * @return {TileCoord} Tile coordinate.\n */\nexport function createOrUpdate(z, x, y, tileCoord) {\n if (tileCoord !== undefined) {\n tileCoord[0] = z;\n tileCoord[1] = x;\n tileCoord[2] = y;\n return tileCoord;\n }\n return [z, x, y];\n}\n\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {string} Key.\n */\nexport function getKeyZXY(z, x, y) {\n return z + '/' + x + '/' + y;\n}\n\n/**\n * Get the key for a tile coord.\n * @param {TileCoord} tileCoord The tile coord.\n * @return {string} Key.\n */\nexport function getKey(tileCoord) {\n return getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);\n}\n\n/**\n * Get the tile cache key for a tile key obtained through `tile.getKey()`.\n * @param {string} tileKey The tile key.\n * @return {string} The cache key.\n */\nexport function getCacheKeyForTileKey(tileKey) {\n const [z, x, y] = tileKey\n .substring(tileKey.lastIndexOf('/') + 1, tileKey.length)\n .split(',')\n .map(Number);\n return getKeyZXY(z, x, y);\n}\n\n/**\n * @param {import(\"./source/Tile.js\").default} source The tile source.\n * @param {string} sourceKey The source key.\n * @param {number} z The tile z level.\n * @param {number} x The tile x level.\n * @param {number} y The tile y level.\n * @return {string} The cache key.\n */\nexport function getCacheKey(source, sourceKey, z, x, y) {\n return `${getUid(source)},${sourceKey},${getKeyZXY(z, x, y)}`;\n}\n\n/**\n * Get a tile coord given a key.\n * @param {string} key The tile coord key.\n * @return {TileCoord} The tile coord.\n */\nexport function fromKey(key) {\n return key.split('/').map(Number);\n}\n\n/**\n * @param {TileCoord} tileCoord Tile coord.\n * @return {number} Hash.\n */\nexport function hash(tileCoord) {\n return hashZXY(tileCoord[0], tileCoord[1], tileCoord[2]);\n}\n\n/**\n * @param {number} z The tile z coordinate.\n * @param {number} x The tile x coordinate.\n * @param {number} y The tile y coordinate.\n * @return {number} Hash.\n */\nexport function hashZXY(z, x, y) {\n return (x << z) + y;\n}\n\n/**\n * @param {TileCoord} tileCoord Tile coordinate.\n * @param {!import(\"./tilegrid/TileGrid.js\").default} tileGrid Tile grid.\n * @return {boolean} Tile coordinate is within extent and zoom level range.\n */\nexport function withinExtentAndZ(tileCoord, tileGrid) {\n const z = tileCoord[0];\n const x = tileCoord[1];\n const y = tileCoord[2];\n\n if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {\n return false;\n }\n const tileRange = tileGrid.getFullTileRange(z);\n if (!tileRange) {\n return true;\n }\n return tileRange.containsXY(x, y);\n}\n","/**\n * @module ol/tilegrid/common\n */\n\n/**\n * Default maximum zoom for default tile grids.\n * @type {number}\n */\nexport const DEFAULT_MAX_ZOOM = 42;\n\n/**\n * Default tile size.\n * @type {number}\n */\nexport const DEFAULT_TILE_SIZE = 256;\n","/**\n * @module ol/tilegrid/TileGrid\n */\nimport TileRange, {\n createOrUpdate as createOrUpdateTileRange,\n} from '../TileRange.js';\nimport {isSorted, linearFindNearest} from '../array.js';\nimport {assert} from '../asserts.js';\nimport {createOrUpdate, getTopLeft} from '../extent.js';\nimport {intersectsLinearRing} from '../geom/flat/intersectsextent.js';\nimport {ceil, clamp, floor} from '../math.js';\nimport {toSize} from '../size.js';\nimport {createOrUpdate as createOrUpdateTileCoord} from '../tilecoord.js';\nimport {DEFAULT_TILE_SIZE} from './common.js';\n\n/**\n * @private\n * @type {import(\"../tilecoord.js\").TileCoord}\n */\nconst tmpTileCoord = [0, 0, 0];\n\n/**\n * Number of decimal digits to consider in integer values when rounding.\n * @type {number}\n */\nconst DECIMALS = 5;\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../extent.js\").Extent} [extent] Extent for the tile grid. No tiles outside this\n * extent will be requested by {@link module:ol/source/Tile~TileSource} sources. When no `origin` or\n * `origins` are configured, the `origin` will be set to the top-left corner of the extent.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {import(\"../coordinate.js\").Coordinate} [origin] The tile grid origin, i.e. where the `x`\n * and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left to right and downwards. If not\n * specified, `extent` or `origins` must be provided.\n * @property {Array<import(\"../coordinate.js\").Coordinate>} [origins] Tile grid origins, i.e. where\n * the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * origin. Tile coordinates increase left to right and downwards. If not specified, `extent` or\n * `origin` must be provided.\n * @property {!Array<number>} resolutions Resolutions. The array index of each resolution needs\n * to match the zoom level. This means that even if a `minZoom` is configured, the resolutions\n * array will have a length of `maxZoom + 1`.\n * @property {Array<import(\"../size.js\").Size>} [sizes] Number of tile rows and columns\n * of the grid for each zoom level. If specified the values\n * define each zoom level's extent together with the `origin` or `origins`.\n * A grid `extent` can be configured in addition, and will further limit the extent\n * for which tile requests are made by sources. If the bottom-left corner of\n * an extent is used as `origin` or `origins`, then the `y` value must be\n * negative because OpenLayers tile coordinates use the top left as the origin.\n * @property {number|import(\"../size.js\").Size} [tileSize] Tile size.\n * Default is `[256, 256]`.\n * @property {Array<number|import(\"../size.js\").Size>} [tileSizes] Tile sizes. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * tile size.\n */\n\n/**\n * @classdesc\n * Base class for setting the grid pattern for sources accessing tiled-image\n * servers.\n * @api\n */\nclass TileGrid {\n /**\n * @param {Options} options Tile grid options.\n */\n constructor(options) {\n /**\n * @protected\n * @type {number}\n */\n this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;\n\n /**\n * @private\n * @type {!Array<number>}\n */\n this.resolutions_ = options.resolutions;\n assert(\n isSorted(\n this.resolutions_,\n /**\n * @param {number} a First resolution\n * @param {number} b Second resolution\n * @return {number} Comparison result\n */\n (a, b) => b - a,\n true,\n ),\n '`resolutions` must be sorted in descending order',\n );\n\n // check if we've got a consistent zoom factor and origin\n let zoomFactor;\n if (!options.origins) {\n for (let i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {\n if (!zoomFactor) {\n zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];\n } else {\n if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {\n zoomFactor = undefined;\n break;\n }\n }\n }\n }\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.zoomFactor_ = zoomFactor;\n\n /**\n * @protected\n * @type {number}\n */\n this.maxZoom = this.resolutions_.length - 1;\n\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate|null}\n */\n this.origin_ = options.origin !== undefined ? options.origin : null;\n\n /**\n * @private\n * @type {Array<import(\"../coordinate.js\").Coordinate>}\n */\n this.origins_ = null;\n if (options.origins !== undefined) {\n this.origins_ = options.origins;\n assert(\n this.origins_.length == this.resolutions_.length,\n 'Number of `origins` and `resolutions` must be equal',\n );\n }\n\n const extent = options.extent;\n\n if (extent !== undefined && !this.origin_ && !this.origins_) {\n this.origin_ = getTopLeft(extent);\n }\n\n assert(\n (!this.origin_ && this.origins_) || (this.origin_ && !this.origins_),\n 'Either `origin` or `origins` must be configured, never both',\n );\n\n /**\n * @private\n * @type {Array<number|import(\"../size.js\").Size>}\n */\n this.tileSizes_ = null;\n if (options.tileSizes !== undefined) {\n this.tileSizes_ = options.tileSizes;\n assert(\n this.tileSizes_.length == this.resolutions_.length,\n 'Number of `tileSizes` and `resolutions` must be equal',\n );\n }\n\n /**\n * @private\n * @type {number|import(\"../size.js\").Size}\n */\n this.tileSize_ =\n options.tileSize !== undefined\n ? options.tileSize\n : !this.tileSizes_\n ? DEFAULT_TILE_SIZE\n : null;\n assert(\n (!this.tileSize_ && this.tileSizes_) ||\n (this.tileSize_ && !this.tileSizes_),\n 'Either `tileSize` or `tileSizes` must be configured, never both',\n );\n\n /**\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.extent_ = extent !== undefined ? extent : null;\n\n /**\n * @private\n * @type {Array<import(\"../TileRange.js\").default>}\n */\n this.fullTileRanges_ = null;\n\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n this.tmpSize_ = [0, 0];\n\n /**\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.tmpExtent_ = [0, 0, 0, 0];\n\n if (options.sizes !== undefined) {\n this.fullTileRanges_ = options.sizes.map((size, z) => {\n const tileRange = new TileRange(\n Math.min(0, size[0]),\n Math.max(size[0] - 1, -1),\n Math.min(0, size[1]),\n Math.max(size[1] - 1, -1),\n );\n if (extent) {\n const restrictedTileRange = this.getTileRangeForExtentAndZ(extent, z);\n tileRange.minX = Math.max(restrictedTileRange.minX, tileRange.minX);\n tileRange.maxX = Math.min(restrictedTileRange.maxX, tileRange.maxX);\n tileRange.minY = Math.max(restrictedTileRange.minY, tileRange.minY);\n tileRange.maxY = Math.min(restrictedTileRange.maxY, tileRange.maxY);\n }\n return tileRange;\n });\n } else if (extent) {\n this.calculateTileRanges_(extent);\n }\n }\n\n /**\n * Call a function with each tile coordinate for a given extent and zoom level.\n *\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} zoom Integer zoom level.\n * @param {function(import(\"../tilecoord.js\").TileCoord): void} callback Function called with each tile coordinate.\n * @api\n */\n forEachTileCoord(extent, zoom, callback) {\n const tileRange = this.getTileRangeForExtentAndZ(extent, zoom);\n for (let i = tileRange.minX, ii = tileRange.maxX; i <= ii; ++i) {\n for (let j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {\n callback([zoom, i, j]);\n }\n }\n }\n\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {function(number, import(\"../TileRange.js\").default): boolean} callback Callback.\n * @param {import(\"../TileRange.js\").default} [tempTileRange] Temporary import(\"../TileRange.js\").default object.\n * @param {import(\"../extent.js\").Extent} [tempExtent] Temporary import(\"../extent.js\").Extent object.\n * @return {boolean} Callback succeeded.\n */\n forEachTileCoordParentTileRange(\n tileCoord,\n callback,\n tempTileRange,\n tempExtent,\n ) {\n let tileRange, x, y;\n let tileCoordExtent = null;\n let z = tileCoord[0] - 1;\n if (this.zoomFactor_ === 2) {\n x = tileCoord[1];\n y = tileCoord[2];\n } else {\n tileCoordExtent = this.getTileCoordExtent(tileCoord, tempExtent);\n }\n while (z >= this.minZoom) {\n if (x !== undefined && y !== undefined) {\n x = Math.floor(x / 2);\n y = Math.floor(y / 2);\n tileRange = createOrUpdateTileRange(x, x, y, y, tempTileRange);\n } else {\n tileRange = this.getTileRangeForExtentAndZ(\n tileCoordExtent,\n z,\n tempTileRange,\n );\n }\n if (callback(z, tileRange)) {\n return true;\n }\n --z;\n }\n return false;\n }\n\n /**\n * Get the extent for this tile grid, if it was configured.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n getExtent() {\n return this.extent_;\n }\n\n /**\n * Get the maximum zoom level for the grid.\n * @return {number} Max zoom.\n * @api\n */\n getMaxZoom() {\n return this.maxZoom;\n }\n\n /**\n * Get the minimum zoom level for the grid.\n * @return {number} Min zoom.\n * @api\n */\n getMinZoom() {\n return this.minZoom;\n }\n\n /**\n * Get the origin for the grid at the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {import(\"../coordinate.js\").Coordinate} Origin.\n * @api\n */\n getOrigin(z) {\n if (this.origin_) {\n return this.origin_;\n }\n return this.origins_[z];\n }\n\n /**\n * Get the resolution for the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {number} Resolution.\n * @api\n */\n getResolution(z) {\n return this.resolutions_[z];\n }\n\n /**\n * Get the list of resolutions for the tile grid.\n * @return {Array<number>} Resolutions.\n * @api\n */\n getResolutions() {\n return this.resolutions_;\n }\n\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"../TileRange.js\").default} [tempTileRange] Temporary import(\"../TileRange.js\").default object.\n * @param {import(\"../extent.js\").Extent} [tempExtent] Temporary import(\"../extent.js\").Extent object.\n * @return {import(\"../TileRange.js\").default|null} Tile range.\n */\n getTileCoordChildTileRange(tileCoord, tempTileRange, tempExtent) {\n if (tileCoord[0] < this.maxZoom) {\n if (this.zoomFactor_ === 2) {\n const minX = tileCoord[1] * 2;\n const minY = tileCoord[2] * 2;\n return createOrUpdateTileRange(\n minX,\n minX + 1,\n minY,\n minY + 1,\n tempTileRange,\n );\n }\n const tileCoordExtent = this.getTileCoordExtent(\n tileCoord,\n tempExtent || this.tmpExtent_,\n );\n return this.getTileRangeForExtentAndZ(\n tileCoordExtent,\n tileCoord[0] + 1,\n tempTileRange,\n );\n }\n return null;\n }\n\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {number} z Integer zoom level.\n * @param {import(\"../TileRange.js\").default} [tempTileRange] Temporary import(\"../TileRange.js\").default object.\n * @return {import(\"../TileRange.js\").default|null} Tile range.\n */\n getTileRangeForTileCoordAndZ(tileCoord, z, tempTileRange) {\n if (z > this.maxZoom || z < this.minZoom) {\n return null;\n }\n\n const tileCoordZ = tileCoord[0];\n const tileCoordX = tileCoord[1];\n const tileCoordY = tileCoord[2];\n\n if (z === tileCoordZ) {\n return createOrUpdateTileRange(\n tileCoordX,\n tileCoordY,\n tileCoordX,\n tileCoordY,\n tempTileRange,\n );\n }\n\n if (this.zoomFactor_) {\n const factor = Math.pow(this.zoomFactor_, z - tileCoordZ);\n const minX = Math.floor(tileCoordX * factor);\n const minY = Math.floor(tileCoordY * factor);\n if (z < tileCoordZ) {\n return createOrUpdateTileRange(minX, minX, minY, minY, tempTileRange);\n }\n\n const maxX = Math.floor(factor * (tileCoordX + 1)) - 1;\n const maxY = Math.floor(factor * (tileCoordY + 1)) - 1;\n return createOrUpdateTileRange(minX, maxX, minY, maxY, tempTileRange);\n }\n\n const tileCoordExtent = this.getTileCoordExtent(tileCoord, this.tmpExtent_);\n return this.getTileRangeForExtentAndZ(tileCoordExtent, z, tempTileRange);\n }\n\n /**\n * Get a tile range for the given extent and integer zoom level.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} z Integer zoom level.\n * @param {import(\"../TileRange.js\").default} [tempTileRange] Temporary tile range object.\n * @return {import(\"../TileRange.js\").default} Tile range.\n */\n getTileRangeForExtentAndZ(extent, z, tempTileRange) {\n this.getTileCoordForXYAndZ_(extent[0], extent[3], z, false, tmpTileCoord);\n const minX = tmpTileCoord[1];\n const minY = tmpTileCoord[2];\n this.getTileCoordForXYAndZ_(extent[2], extent[1], z, true, tmpTileCoord);\n const maxX = tmpTileCoord[1];\n const maxY = tmpTileCoord[2];\n return createOrUpdateTileRange(minX, maxX, minY, maxY, tempTileRange);\n }\n\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @return {import(\"../coordinate.js\").Coordinate} Tile center.\n */\n getTileCoordCenter(tileCoord) {\n const origin = this.getOrigin(tileCoord[0]);\n const resolution = this.getResolution(tileCoord[0]);\n const tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n return [\n origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution,\n origin[1] - (tileCoord[2] + 0.5) * tileSize[1] * resolution,\n ];\n }\n\n /**\n * Get the extent of a tile coordinate.\n *\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"../extent.js\").Extent} [tempExtent] Temporary extent object.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n getTileCoordExtent(tileCoord, tempExtent) {\n const origin = this.getOrigin(tileCoord[0]);\n const resolution = this.getResolution(tileCoord[0]);\n const tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n const minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;\n const minY = origin[1] - (tileCoord[2] + 1) * tileSize[1] * resolution;\n const maxX = minX + tileSize[0] * resolution;\n const maxY = minY + tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, tempExtent);\n }\n\n /**\n * Get the tile coordinate for the given map coordinate and resolution. This\n * method considers that coordinates that intersect tile boundaries should be\n * assigned the higher tile coordinate.\n *\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Destination import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @api\n */\n getTileCoordForCoordAndResolution(coordinate, resolution, opt_tileCoord) {\n return this.getTileCoordForXYAndResolution_(\n coordinate[0],\n coordinate[1],\n resolution,\n false,\n opt_tileCoord,\n );\n }\n\n /**\n * Note that this method should not be called for resolutions that correspond\n * to an integer zoom level. Instead call the `getTileCoordForXYAndZ_` method.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} resolution Resolution (for a non-integer zoom level).\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Temporary import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @private\n */\n getTileCoordForXYAndResolution_(\n x,\n y,\n resolution,\n reverseIntersectionPolicy,\n opt_tileCoord,\n ) {\n const z = this.getZForResolution(resolution);\n const scale = resolution / this.getResolution(z);\n const origin = this.getOrigin(z);\n const tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n\n let tileCoordX = (scale * (x - origin[0])) / resolution / tileSize[0];\n let tileCoordY = (scale * (origin[1] - y)) / resolution / tileSize[1];\n\n if (reverseIntersectionPolicy) {\n tileCoordX = ceil(tileCoordX, DECIMALS) - 1;\n tileCoordY = ceil(tileCoordY, DECIMALS) - 1;\n } else {\n tileCoordX = floor(tileCoordX, DECIMALS);\n tileCoordY = floor(tileCoordY, DECIMALS);\n }\n\n return createOrUpdateTileCoord(z, tileCoordX, tileCoordY, opt_tileCoord);\n }\n\n /**\n * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,\n * they should have separate implementations. This method is for integer zoom\n * levels. The other method should only be called for resolutions corresponding\n * to non-integer zoom levels.\n * @param {number} x Map x coordinate.\n * @param {number} y Map y coordinate.\n * @param {number} z Integer zoom level.\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Temporary import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @private\n */\n getTileCoordForXYAndZ_(x, y, z, reverseIntersectionPolicy, opt_tileCoord) {\n const origin = this.getOrigin(z);\n const resolution = this.getResolution(z);\n const tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n\n let tileCoordX = (x - origin[0]) / resolution / tileSize[0];\n let tileCoordY = (origin[1] - y) / resolution / tileSize[1];\n\n if (reverseIntersectionPolicy) {\n tileCoordX = ceil(tileCoordX, DECIMALS) - 1;\n tileCoordY = ceil(tileCoordY, DECIMALS) - 1;\n } else {\n tileCoordX = floor(tileCoordX, DECIMALS);\n tileCoordY = floor(tileCoordY, DECIMALS);\n }\n\n return createOrUpdateTileCoord(z, tileCoordX, tileCoordY, opt_tileCoord);\n }\n\n /**\n * Get a tile coordinate given a map coordinate and zoom level.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {number} z Integer zoom level, e.g. the result of a `getZForResolution()` method call\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Destination import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @api\n */\n getTileCoordForCoordAndZ(coordinate, z, opt_tileCoord) {\n return this.getTileCoordForXYAndZ_(\n coordinate[0],\n coordinate[1],\n z,\n false,\n opt_tileCoord,\n );\n }\n\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @return {number} Tile resolution.\n */\n getTileCoordResolution(tileCoord) {\n return this.resolutions_[tileCoord[0]];\n }\n\n /**\n * Get the tile size for a zoom level. The type of the return value matches the\n * `tileSize` or `tileSizes` that the tile grid was configured with. To always\n * get an {@link import(\"../size.js\").Size}, run the result through {@link module:ol/size.toSize}.\n * @param {number} z Z.\n * @return {number|import(\"../size.js\").Size} Tile size.\n * @api\n */\n getTileSize(z) {\n if (this.tileSize_) {\n return this.tileSize_;\n }\n return this.tileSizes_[z];\n }\n\n /**\n * @param {number} z Zoom level.\n * @return {import(\"../TileRange.js\").default|null} Extent tile range for the specified zoom level.\n */\n getFullTileRange(z) {\n if (!this.fullTileRanges_) {\n return this.extent_\n ? this.getTileRangeForExtentAndZ(this.extent_, z)\n : null;\n }\n return this.fullTileRanges_[z];\n }\n\n /**\n * @param {number} resolution Resolution.\n * @param {number|import(\"../array.js\").NearestDirectionFunction} [opt_direction]\n * If 0, the nearest resolution will be used.\n * If 1, the nearest higher resolution (lower Z) will be used. If -1, the\n * nearest lower resolution (higher Z) will be used. Default is 0.\n * Use a {@link module:ol/array~NearestDirectionFunction} for more precise control.\n *\n * For example to change tile Z at the midpoint of zoom levels\n * ```js\n * function(value, high, low) {\n * return value - low * Math.sqrt(high / low);\n * }\n * ```\n * @return {number} Z.\n * @api\n */\n getZForResolution(resolution, opt_direction) {\n const z = linearFindNearest(\n this.resolutions_,\n resolution,\n opt_direction || 0,\n );\n return clamp(z, this.minZoom, this.maxZoom);\n }\n\n /**\n * The tile with the provided tile coordinate intersects the given viewport.\n * @param {import('../tilecoord.js').TileCoord} tileCoord Tile coordinate.\n * @param {Array<number>} viewport Viewport as returned from {@link module:ol/extent.getRotatedViewport}.\n * @return {boolean} The tile with the provided tile coordinate intersects the given viewport.\n */\n tileCoordIntersectsViewport(tileCoord, viewport) {\n return intersectsLinearRing(\n viewport,\n 0,\n viewport.length,\n 2,\n this.getTileCoordExtent(tileCoord),\n );\n }\n\n /**\n * @param {!import(\"../extent.js\").Extent} extent Extent for this tile grid.\n * @private\n */\n calculateTileRanges_(extent) {\n const length = this.resolutions_.length;\n const fullTileRanges = new Array(length);\n for (let z = this.minZoom; z < length; ++z) {\n fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);\n }\n this.fullTileRanges_ = fullTileRanges;\n }\n}\n\nexport default TileGrid;\n","/**\n * @module ol/proj/Units\n */\n\n/**\n * @typedef {'radians' | 'degrees' | 'ft' | 'm' | 'pixels' | 'tile-pixels' | 'us-ft'} Units\n * Projection units.\n */\n\n/**\n * See http://duff.ess.washington.edu/data/raster/drg/docs/geotiff.txt\n * @type {Object<number, Units>}\n */\nconst unitByCode = {\n '9001': 'm',\n '9002': 'ft',\n '9003': 'us-ft',\n '9101': 'radians',\n '9102': 'degrees',\n};\n\n/**\n * @param {number} code Unit code.\n * @return {Units} Units.\n */\nexport function fromCode(code) {\n return unitByCode[code];\n}\n\n/**\n * @typedef {Object} MetersPerUnitLookup\n * @property {number} radians Radians\n * @property {number} degrees Degrees\n * @property {number} ft Feet\n * @property {number} m Meters\n * @property {number} us-ft US feet\n */\n\n/**\n * Meters per unit lookup table.\n * @const\n * @type {MetersPerUnitLookup}\n * @api\n */\nexport const METERS_PER_UNIT = {\n // use the radius of the Normal sphere\n 'radians': 6370997 / (2 * Math.PI),\n 'degrees': (2 * Math.PI * 6370997) / 360,\n 'ft': 0.3048,\n 'm': 1,\n 'us-ft': 1200 / 3937,\n};\n","/**\n * @module ol/proj/Projection\n */\nimport {METERS_PER_UNIT} from './Units.js';\n\n/**\n * The function is called with a `number` view resolution and a\n * {@link module:ol/coordinate~Coordinate} as arguments, and returns the `number` resolution\n * in projection units at the passed coordinate.\n * @typedef {function(number, import(\"../coordinate.js\").Coordinate):number} GetPointResolution\n * @api\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import(\"./Units.js\").Units} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import(\"../extent.js\").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link METERS_PER_UNIT}\n * lookup table.\n * @property {import(\"../extent.js\").Extent} [worldExtent] The world extent for the SRS.\n * @property {GetPointResolution} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `number` view resolution and a {@link module:ol/coordinate~Coordinate} as arguments, and returns\n * the `number` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj.getPointResolution} function will be used.\n */\n\n/**\n * @classdesc\n * In most cases, you should not need to create instances of this class.\n * Instead, where projection information is required, you can use a string\n * projection code or identifier (e.g. `EPSG:4326`) instead of a projection\n * instance.\n *\n * The library includes support for transforming coordinates between the following\n * projections:\n *\n * WGS 84 / Geographic - Using codes `EPSG:4326`, `CRS:84`, `urn:ogc:def:crs:EPSG:6.6:4326`,\n * `urn:ogc:def:crs:OGC:1.3:CRS84`, `urn:ogc:def:crs:OGC:2:84`, `http://www.opengis.net/gml/srs/epsg.xml#4326`,\n * or `urn:x-ogc:def:crs:EPSG:4326`\n * WGS 84 / Spherical Mercator - Using codes `EPSG:3857`, `EPSG:102100`, `EPSG:102113`, `EPSG:900913`,\n * `urn:ogc:def:crs:EPSG:6.18:3:3857`, or `http://www.opengis.net/gml/srs/epsg.xml#3857`\n * WGS 84 / UTM zones - Using codes `EPSG:32601` through `EPSG:32660` for northern zones\n * and `EPSG:32701` through `EPSG:32760` for southern zones. Note that the built-in UTM transforms\n * are lower accuracy (with errors on the order of 0.1 m) than those that you might get in a\n * library like [proj4js](https://github.com/proj4js/proj4js).\n *\n * For additional projection support, or to use higher accuracy transforms than the built-in ones, you can use\n * the [proj4js](https://github.com/proj4js/proj4js) library. With `proj4js`, after adding any new projection\n * definitions, call the {@link module:ol/proj/proj4.register} function.\n *\n * You can use the {@link module:ol/proj.get} function to retrieve a projection instance\n * for one of the registered projections.\n *\n * @api\n */\nclass Projection {\n /**\n * @param {Options} options Projection options.\n */\n constructor(options) {\n /**\n * @private\n * @type {string}\n */\n this.code_ = options.code;\n\n /**\n * Units of projected coordinates. When set to `TILE_PIXELS`, a\n * `this.extent_` and `this.worldExtent_` must be configured properly for each\n * tile.\n * @private\n * @type {import(\"./Units.js\").Units}\n */\n this.units_ = /** @type {import(\"./Units.js\").Units} */ (options.units);\n\n /**\n * Validity extent of the projection in projected coordinates. For projections\n * with `TILE_PIXELS` units, this is the extent of the tile in\n * tile pixel space.\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.extent_ = options.extent !== undefined ? options.extent : null;\n\n /**\n * Extent of the world in EPSG:4326. For projections with\n * `TILE_PIXELS` units, this is the extent of the tile in\n * projected coordinate space.\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.worldExtent_ =\n options.worldExtent !== undefined ? options.worldExtent : null;\n\n /**\n * @private\n * @type {string}\n */\n this.axisOrientation_ =\n options.axisOrientation !== undefined ? options.axisOrientation : 'enu';\n\n /**\n * @private\n * @type {boolean}\n */\n this.global_ = options.global !== undefined ? options.global : false;\n\n /**\n * @private\n * @type {boolean}\n */\n this.canWrapX_ = !!(this.global_ && this.extent_);\n\n /**\n * @private\n * @type {GetPointResolution|undefined}\n */\n this.getPointResolutionFunc_ = options.getPointResolution;\n\n /**\n * @private\n * @type {import(\"../tilegrid/TileGrid.js\").default}\n */\n this.defaultTileGrid_ = null;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.metersPerUnit_ = options.metersPerUnit;\n }\n\n /**\n * @return {boolean} The projection is suitable for wrapping the x-axis\n */\n canWrapX() {\n return this.canWrapX_;\n }\n\n /**\n * Get the code for this projection, e.g. 'EPSG:4326'.\n * @return {string} Code.\n * @api\n */\n getCode() {\n return this.code_;\n }\n\n /**\n * Get the validity extent for this projection.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n getExtent() {\n return this.extent_;\n }\n\n /**\n * Get the units of this projection.\n * @return {import(\"./Units.js\").Units} Units.\n * @api\n */\n getUnits() {\n return this.units_;\n }\n\n /**\n * Get the amount of meters per unit of this projection. If the projection is\n * not configured with `metersPerUnit` or a units identifier, the return is\n * `undefined`.\n * @return {number|undefined} Meters.\n * @api\n */\n getMetersPerUnit() {\n return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];\n }\n\n /**\n * Get the world extent for this projection.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n getWorldExtent() {\n return this.worldExtent_;\n }\n\n /**\n * Get the axis orientation of this projection.\n * Example values are:\n * enu - the default easting, northing, elevation.\n * neu - northing, easting, up - useful for \"lat/long\" geographic coordinates,\n * or south orientated transverse mercator.\n * wnu - westing, northing, up - some planetary coordinate systems have\n * \"west positive\" coordinate systems\n * @return {string} Axis orientation.\n * @api\n */\n getAxisOrientation() {\n return this.axisOrientation_;\n }\n\n /**\n * Is this projection a global projection which spans the whole world?\n * @return {boolean} Whether the projection is global.\n * @api\n */\n isGlobal() {\n return this.global_;\n }\n\n /**\n * Set if the projection is a global projection which spans the whole world\n * @param {boolean} global Whether the projection is global.\n * @api\n */\n setGlobal(global) {\n this.global_ = global;\n this.canWrapX_ = !!(global && this.extent_);\n }\n\n /**\n * @return {import(\"../tilegrid/TileGrid.js\").default} The default tile grid.\n */\n getDefaultTileGrid() {\n return this.defaultTileGrid_;\n }\n\n /**\n * @param {import(\"../tilegrid/TileGrid.js\").default} tileGrid The default tile grid.\n */\n setDefaultTileGrid(tileGrid) {\n this.defaultTileGrid_ = tileGrid;\n }\n\n /**\n * Set the validity extent for this projection.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @api\n */\n setExtent(extent) {\n this.extent_ = extent;\n this.canWrapX_ = !!(this.global_ && extent);\n }\n\n /**\n * Set the world extent for this projection.\n * @param {import(\"../extent.js\").Extent} worldExtent World extent\n * [minlon, minlat, maxlon, maxlat].\n * @api\n */\n setWorldExtent(worldExtent) {\n this.worldExtent_ = worldExtent;\n }\n\n /**\n * Set the getPointResolution function (see {@link module:ol/proj.getPointResolution}\n * for this projection.\n * @param {function(number, import(\"../coordinate.js\").Coordinate):number} func Function\n * @api\n */\n setGetPointResolution(func) {\n this.getPointResolutionFunc_ = func;\n }\n\n /**\n * Get the custom point resolution function for this projection (if set).\n * @return {GetPointResolution|undefined} The custom point\n * resolution function (if set).\n */\n getPointResolutionFunc() {\n return this.getPointResolutionFunc_;\n }\n}\n\nexport default Projection;\n","/**\n * @module ol/proj/epsg3857\n */\nimport Projection from './Projection.js';\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n/**\n * @const\n * @type {number}\n */\nexport const HALF_SIZE = Math.PI * RADIUS;\n\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];\n\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const WORLD_EXTENT = [-180, -85, 180, 85];\n\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\nexport const MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));\n\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\nclass EPSG3857Projection extends Projection {\n /**\n * @param {string} code Code.\n */\n constructor(code) {\n super({\n code: code,\n units: 'm',\n extent: EXTENT,\n global: true,\n worldExtent: WORLD_EXTENT,\n getPointResolution: function (resolution, point) {\n return resolution / Math.cosh(point[1] / RADIUS);\n },\n });\n }\n}\n\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport const PROJECTIONS = [\n new EPSG3857Projection('EPSG:3857'),\n new EPSG3857Projection('EPSG:102100'),\n new EPSG3857Projection('EPSG:102113'),\n new EPSG3857Projection('EPSG:900913'),\n new EPSG3857Projection('http://www.opengis.net/def/crs/EPSG/0/3857'),\n new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857'),\n];\n\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension (default is `2`).\n * @param {number} [stride] Stride (default is `dimension`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function fromEPSG4326(input, output, dimension, stride) {\n const length = input.length;\n dimension = dimension > 1 ? dimension : 2;\n stride = stride ?? dimension;\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n for (let i = 0; i < length; i += stride) {\n output[i] = (HALF_SIZE * input[i]) / 180;\n let y = RADIUS * Math.log(Math.tan((Math.PI * (+input[i + 1] + 90)) / 360));\n if (y > MAX_SAFE_Y) {\n y = MAX_SAFE_Y;\n } else if (y < -MAX_SAFE_Y) {\n y = -MAX_SAFE_Y;\n }\n output[i + 1] = y;\n }\n return output;\n}\n\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @param {number} [dimension] Dimension (default is `2`).\n * @param {number} [stride] Stride (default is `dimension`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function toEPSG4326(input, output, dimension, stride) {\n const length = input.length;\n dimension = dimension > 1 ? dimension : 2;\n stride = stride ?? dimension;\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n for (let i = 0; i < length; i += stride) {\n output[i] = (180 * input[i]) / HALF_SIZE;\n output[i + 1] =\n (360 * Math.atan(Math.exp(input[i + 1] / RADIUS))) / Math.PI - 90;\n }\n return output;\n}\n","/**\n * @module ol/proj/epsg4326\n */\nimport Projection from './Projection.js';\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport const EXTENT = [-180, -90, 180, 90];\n\n/**\n * @const\n * @type {number}\n */\nexport const METERS_PER_UNIT = (Math.PI * RADIUS) / 180;\n\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\nclass EPSG4326Projection extends Projection {\n /**\n * @param {string} code Code.\n * @param {string} [axisOrientation] Axis orientation.\n */\n constructor(code, axisOrientation) {\n super({\n code: code,\n units: 'degrees',\n extent: EXTENT,\n axisOrientation: axisOrientation,\n global: true,\n metersPerUnit: METERS_PER_UNIT,\n worldExtent: EXTENT,\n });\n }\n}\n\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport const PROJECTIONS = [\n new EPSG4326Projection('CRS:84'),\n new EPSG4326Projection('EPSG:4326', 'neu'),\n new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),\n new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),\n new EPSG4326Projection('http://www.opengis.net/def/crs/OGC/1.3/CRS84'),\n new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),\n new EPSG4326Projection('http://www.opengis.net/def/crs/EPSG/0/4326', 'neu'),\n];\n","/**\n * @module ol/proj/transforms\n */\nimport {isEmpty} from '../obj.js';\n\n/**\n * @private\n * @type {!Object<string, Object<string, import(\"../proj.js\").TransformFunction>>}\n */\nlet transforms = {};\n\n/**\n * Clear the transform cache.\n */\nexport function clear() {\n transforms = {};\n}\n\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import(\"./Projection.js\").default} source Source.\n * @param {import(\"./Projection.js\").default} destination Destination.\n * @param {import(\"../proj.js\").TransformFunction} transformFn Transform.\n */\nexport function add(source, destination, transformFn) {\n const sourceCode = source.getCode();\n const destinationCode = destination.getCode();\n if (!(sourceCode in transforms)) {\n transforms[sourceCode] = {};\n }\n transforms[sourceCode][destinationCode] = transformFn;\n}\n\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection. This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import(\"./Projection.js\").default} source Source projection.\n * @param {import(\"./Projection.js\").default} destination Destination projection.\n * @return {import(\"../proj.js\").TransformFunction} transformFn The unregistered transform.\n */\nexport function remove(source, destination) {\n const sourceCode = source.getCode();\n const destinationCode = destination.getCode();\n const transform = transforms[sourceCode][destinationCode];\n delete transforms[sourceCode][destinationCode];\n if (isEmpty(transforms[sourceCode])) {\n delete transforms[sourceCode];\n }\n return transform;\n}\n\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import(\"../proj.js\").TransformFunction|null} The transform function (if found).\n */\nexport function get(sourceCode, destinationCode) {\n if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n return transforms[sourceCode][destinationCode];\n }\n return null;\n}\n","/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * a list of {@link module:ol/proj/Projection~Projection}\n * objects, one for each projection supported by the application\n * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4's registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don't\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get('EPSG:1234').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj.addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection~Projection} object for the new projection and add it with\n * {@link module:ol/proj.addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj.addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection~Projection} with\n * {@link module:ol/proj.addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\nimport {warn} from './console.js';\nimport {equals, getWorldsAway} from './coordinate.js';\nimport {applyTransform, getWidth} from './extent.js';\nimport {clamp, modulo} from './math.js';\nimport Projection from './proj/Projection.js';\nimport {METERS_PER_UNIT} from './proj/Units.js';\nimport {\n PROJECTIONS as EPSG3857_PROJECTIONS,\n fromEPSG4326,\n toEPSG4326,\n} from './proj/epsg3857.js';\nimport {PROJECTIONS as EPSG4326_PROJECTIONS} from './proj/epsg4326.js';\nimport {\n add as addProj,\n clear as clearProj,\n get as getProj,\n} from './proj/projections.js';\nimport {\n add as addTransformFunc,\n clear as clearTransformFuncs,\n get as getTransformFunc,\n} from './proj/transforms.js';\nimport {\n makeProjection as makeUTMProjection,\n makeTransforms as makeUTMTransforms,\n} from './proj/utm.js';\nimport {getDistance} from './sphere.js';\n\n/**\n * A projection as {@link module:ol/proj/Projection~Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n\n/**\n * @typedef {Object} Transforms\n * @property {TransformFunction} forward The forward transform (from geographic).\n * @property {TransformFunction} inverse The inverse transform (to geographic).\n */\n\n/**\n * @type {Array<function(Projection): Transforms|null>}\n */\nconst transformFactories = [makeUTMTransforms];\n\n/**\n * @type {Array<function(string): Projection|null>}\n */\nconst projectionFactories = [makeUTMProjection];\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2). The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @callback TransformFunction\n * @param {Array<number>} input\n * @param {Array<number>} [output]\n * @param {number} [dimension]\n * @param {number} [stride]\n * @return {Array<number>}\n *\n * @api\n */\n\nexport {METERS_PER_UNIT};\n\nexport {Projection};\n\nlet showCoordinateWarning = true;\n\n/**\n * @param {boolean} [disable] Disable console info about `useGeographic()`\n */\nexport function disableCoordinateWarning(disable) {\n const hide = disable === undefined ? true : disable;\n showCoordinateWarning = !hide;\n}\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n * values).\n */\nexport function cloneTransform(input, output) {\n if (output !== undefined) {\n for (let i = 0, ii = input.length; i < ii; ++i) {\n output[i] = input[i];\n }\n output = output;\n } else {\n output = input.slice();\n }\n return output;\n}\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [output] Output array of coordinate values.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\nexport function identityTransform(input, output) {\n if (output !== undefined && input !== output) {\n for (let i = 0, ii = input.length; i < ii; ++i) {\n output[i] = input[i];\n }\n input = output;\n }\n return input;\n}\n\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\nexport function addProjection(projection) {\n addProj(projection.getCode(), projection);\n addTransformFunc(projection, projection, cloneTransform);\n}\n\n/**\n * @param {Array<Projection>} projections Projections.\n */\nexport function addProjections(projections) {\n projections.forEach(addProjection);\n}\n\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n * a combination of authority and identifier such as \"EPSG:4326\", or an\n * existing projection object, or undefined.\n * @return {Projection|null} Projection object, or null if not in list.\n * @api\n */\nexport function get(projectionLike) {\n if (!(typeof projectionLike === 'string')) {\n return projectionLike;\n }\n const projection = getProj(projectionLike);\n if (projection) {\n return projection;\n }\n for (const makeProjection of projectionFactories) {\n const projection = makeProjection(projectionLike);\n if (projection) {\n return projection;\n }\n }\n return null;\n}\n\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the `point` pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import(\"./coordinate.js\").Coordinate} point Point to find adjusted resolution at.\n * @param {import(\"./proj/Units.js\").Units} [units] Units to get the point resolution in.\n * Default is the projection's units.\n * @return {number} Point resolution.\n * @api\n */\nexport function getPointResolution(projection, resolution, point, units) {\n projection = get(projection);\n let pointResolution;\n const getter = projection.getPointResolutionFunc();\n if (getter) {\n pointResolution = getter(resolution, point);\n if (units && units !== projection.getUnits()) {\n const metersPerUnit = projection.getMetersPerUnit();\n if (metersPerUnit) {\n pointResolution =\n (pointResolution * metersPerUnit) / METERS_PER_UNIT[units];\n }\n }\n } else {\n const projUnits = projection.getUnits();\n if ((projUnits == 'degrees' && !units) || units == 'degrees') {\n pointResolution = resolution;\n } else {\n // Estimate point resolution by transforming the center pixel to EPSG:4326,\n // measuring its width and height on the normal sphere, and taking the\n // average of the width and height.\n const toEPSG4326 = getTransformFromProjections(\n projection,\n get('EPSG:4326'),\n );\n if (!toEPSG4326 && projUnits !== 'degrees') {\n // no transform is available\n pointResolution = resolution * projection.getMetersPerUnit();\n } else {\n let vertices = [\n point[0] - resolution / 2,\n point[1],\n point[0] + resolution / 2,\n point[1],\n point[0],\n point[1] - resolution / 2,\n point[0],\n point[1] + resolution / 2,\n ];\n vertices = toEPSG4326(vertices, vertices, 2);\n const width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n const height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n pointResolution = (width + height) / 2;\n }\n const metersPerUnit = units\n ? METERS_PER_UNIT[units]\n : projection.getMetersPerUnit();\n if (metersPerUnit !== undefined) {\n pointResolution /= metersPerUnit;\n }\n }\n }\n return pointResolution;\n}\n\n/**\n * Registers transformation functions that don't alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\nexport function addEquivalentProjections(projections) {\n addProjections(projections);\n projections.forEach(function (source) {\n projections.forEach(function (destination) {\n if (source !== destination) {\n addTransformFunc(source, destination, cloneTransform);\n }\n });\n });\n}\n\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n * meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n * meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n * projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n * in projection2 to any projection in projection1..\n */\nexport function addEquivalentTransforms(\n projections1,\n projections2,\n forwardTransform,\n inverseTransform,\n) {\n projections1.forEach(function (projection1) {\n projections2.forEach(function (projection2) {\n addTransformFunc(projection1, projection2, forwardTransform);\n addTransformFunc(projection2, projection1, inverseTransform);\n });\n });\n}\n\n/**\n * Clear all cached projections and transforms.\n */\nexport function clearAllProjections() {\n clearProj();\n clearTransformFuncs();\n}\n\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\nexport function createProjection(projection, defaultCode) {\n if (!projection) {\n return get(defaultCode);\n }\n if (typeof projection === 'string') {\n return get(projection);\n }\n return /** @type {Projection} */ (projection);\n}\n\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} coordTransform Coordinate\n * transform.\n * @return {TransformFunction} Transform function.\n */\nexport function createTransformFromCoordinateTransform(coordTransform) {\n return (\n /**\n * @param {Array<number>} input Input.\n * @param {Array<number>} [output] Output.\n * @param {number} [dimension] Dimensions that should be transformed.\n * @param {number} [stride] Stride.\n * @return {Array<number>} Output.\n */\n function (input, output, dimension, stride) {\n const length = input.length;\n dimension = dimension !== undefined ? dimension : 2;\n stride = stride ?? dimension;\n output = output !== undefined ? output : new Array(length);\n for (let i = 0; i < length; i += stride) {\n const point = coordTransform(input.slice(i, i + dimension));\n const pointLength = point.length;\n for (let j = 0, jj = stride; j < jj; ++j) {\n output[i + j] = j >= pointLength ? input[i + j] : point[j];\n }\n }\n return output;\n }\n );\n}\n\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} forward The forward transform\n * function (that is, from the source projection to the destination\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} inverse The inverse transform\n * function (that is, from the destination projection to the source\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}. If the transform function can only\n * transform less dimensions than the input coordinate, it is supposeed to return a coordinate\n * with only the length it can transform. The other dimensions will be taken unchanged from the\n * source.\n * @api\n */\nexport function addCoordinateTransforms(source, destination, forward, inverse) {\n const sourceProj = get(source);\n const destProj = get(destination);\n addTransformFunc(\n sourceProj,\n destProj,\n createTransformFromCoordinateTransform(forward),\n );\n addTransformFunc(\n destProj,\n sourceProj,\n createTransformFromCoordinateTransform(inverse),\n );\n}\n\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n * an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike} [projection] Target projection. The\n * default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate projected to the target projection.\n * @api\n */\nexport function fromLonLat(coordinate, projection) {\n disableCoordinateWarning();\n return transform(\n coordinate,\n 'EPSG:4326',\n projection !== undefined ? projection : 'EPSG:3857',\n );\n}\n\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike} [projection] Projection of the coordinate.\n * The default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate as longitude and latitude, i.e. an array\n * with longitude as 1st and latitude as 2nd element.\n * @api\n */\nexport function toLonLat(coordinate, projection) {\n const lonLat = transform(\n coordinate,\n projection !== undefined ? projection : 'EPSG:3857',\n 'EPSG:4326',\n );\n const lon = lonLat[0];\n if (lon < -180 || lon > 180) {\n lonLat[0] = modulo(lon + 180, 360) - 180;\n }\n return lonLat;\n}\n\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\nexport function equivalent(projection1, projection2) {\n if (projection1 === projection2) {\n return true;\n }\n const equalUnits = projection1.getUnits() === projection2.getUnits();\n if (projection1.getCode() === projection2.getCode()) {\n return equalUnits;\n }\n const transformFunc = getTransformFromProjections(projection1, projection2);\n return transformFunc === cloneTransform && equalUnits;\n}\n\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} source Source Projection object.\n * @param {Projection} destination Destination Projection\n * object.\n * @return {TransformFunction|null} Transform function.\n */\nexport function getTransformFromProjections(source, destination) {\n const sourceCode = source.getCode();\n const destinationCode = destination.getCode();\n let transformFunc = getTransformFunc(sourceCode, destinationCode);\n if (transformFunc) {\n return transformFunc;\n }\n\n /**\n * @type {Transforms|null}\n */\n let sourceTransforms = null;\n\n /**\n * @type {Transforms|null}\n */\n let destinationTransforms = null;\n\n // lazily add projections if we have supported transforms\n for (const makeTransforms of transformFactories) {\n if (!sourceTransforms) {\n sourceTransforms = makeTransforms(source);\n }\n if (!destinationTransforms) {\n destinationTransforms = makeTransforms(destination);\n }\n }\n\n if (!sourceTransforms && !destinationTransforms) {\n return null;\n }\n\n const intermediateCode = 'EPSG:4326';\n if (!destinationTransforms) {\n const toDestination = getTransformFunc(intermediateCode, destinationCode);\n if (toDestination) {\n transformFunc = composeTransformFuncs(\n sourceTransforms.inverse,\n toDestination,\n );\n }\n } else if (!sourceTransforms) {\n const fromSource = getTransformFunc(sourceCode, intermediateCode);\n if (fromSource) {\n transformFunc = composeTransformFuncs(\n fromSource,\n destinationTransforms.forward,\n );\n }\n } else {\n transformFunc = composeTransformFuncs(\n sourceTransforms.inverse,\n destinationTransforms.forward,\n );\n }\n\n if (transformFunc) {\n addProjection(source);\n addProjection(destination);\n addTransformFunc(source, destination, transformFunc);\n }\n\n return transformFunc;\n}\n\n/**\n * @param {TransformFunction} t1 The first transform function.\n * @param {TransformFunction} t2 The second transform function.\n * @return {TransformFunction} The composed transform function.\n */\nfunction composeTransformFuncs(t1, t2) {\n return function (input, output, dimensions, stride) {\n output = t1(input, output, dimensions, stride);\n return t2(output, output, dimensions, stride);\n };\n}\n\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\nexport function getTransform(source, destination) {\n const sourceProjection = get(source);\n const destinationProjection = get(destination);\n return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original). If there\n * is no available transform between the two projection, the function will throw\n * an error.\n *\n * See {@link module:ol/proj.transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate.\n * @api\n */\nexport function transform(coordinate, source, destination) {\n const transformFunc = getTransform(source, destination);\n if (!transformFunc) {\n const sourceCode = get(source).getCode();\n const destinationCode = get(destination).getCode();\n throw new Error(\n `No transform available between ${sourceCode} and ${destinationCode}`,\n );\n }\n return transformFunc(coordinate, undefined, coordinate.length);\n}\n\n/**\n * Transforms an extent from source projection to destination projection. This\n * returns a new extent (and does not modify the original).\n *\n * @param {import(\"./extent.js\").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number} [stops] Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import(\"./extent.js\").Extent} The transformed extent.\n * @api\n */\nexport function transformExtent(extent, source, destination, stops) {\n const transformFunc = getTransform(source, destination);\n return applyTransform(extent, transformFunc, undefined, stops);\n}\n\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import(\"./coordinate.js\").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import(\"./coordinate.js\").Coordinate} Point.\n */\nexport function transformWithProjections(\n point,\n sourceProjection,\n destinationProjection,\n) {\n const transformFunc = getTransformFromProjections(\n sourceProjection,\n destinationProjection,\n );\n return transformFunc(point);\n}\n\n/**\n * @type {Projection|null}\n */\nlet userProjection = null;\n\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * This includes all API methods except for those interacting with tile grids,\n * plus {@link import(\"./Map.js\").FrameState} and {@link import(\"./View.js\").State}.\n * @param {ProjectionLike} projection The user projection.\n * @api\n */\nexport function setUserProjection(projection) {\n userProjection = get(projection);\n}\n\n/**\n * Clear the user projection if set.\n * @api\n */\nexport function clearUserProjection() {\n userProjection = null;\n}\n\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * @return {Projection|null} The user projection (or null if not set).\n * @api\n */\nexport function getUserProjection() {\n return userProjection;\n}\n\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods.\n * This includes all API methods except for those interacting with tile grids,\n * plus {@link import(\"./Map.js\").FrameState} and {@link import(\"./View.js\").State}.\n * @api\n */\nexport function useGeographic() {\n setUserProjection('EPSG:4326');\n}\n\n/**\n * Return a coordinate transformed into the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @return {Array<number>} The input coordinate in the user projection.\n */\nexport function toUserCoordinate(coordinate, sourceProjection) {\n if (!userProjection) {\n return coordinate;\n }\n return transform(coordinate, sourceProjection, userProjection);\n}\n\n/**\n * Return a coordinate transformed from the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {Array<number>} The input coordinate transformed.\n */\nexport function fromUserCoordinate(coordinate, destProjection) {\n if (!userProjection) {\n if (\n showCoordinateWarning &&\n !equals(coordinate, [0, 0]) &&\n coordinate[0] >= -180 &&\n coordinate[0] <= 180 &&\n coordinate[1] >= -90 &&\n coordinate[1] <= 90\n ) {\n showCoordinateWarning = false;\n warn(\n 'Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.',\n );\n }\n return coordinate;\n }\n return transform(coordinate, userProjection, destProjection);\n}\n\n/**\n * Return an extent transformed into the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @return {import(\"./extent.js\").Extent} The input extent in the user projection.\n */\nexport function toUserExtent(extent, sourceProjection) {\n if (!userProjection) {\n return extent;\n }\n return transformExtent(extent, sourceProjection, userProjection);\n}\n\n/**\n * Return an extent transformed from the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {import(\"./extent.js\").Extent} The input extent transformed.\n */\nexport function fromUserExtent(extent, destProjection) {\n if (!userProjection) {\n return extent;\n }\n return transformExtent(extent, userProjection, destProjection);\n}\n\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in input projection units per pixel.\n * @param {ProjectionLike} sourceProjection The input projection.\n * @return {number} Resolution in user projection units per pixel.\n */\nexport function toUserResolution(resolution, sourceProjection) {\n if (!userProjection) {\n return resolution;\n }\n const sourceMetersPerUnit = get(sourceProjection).getMetersPerUnit();\n const userMetersPerUnit = userProjection.getMetersPerUnit();\n return sourceMetersPerUnit && userMetersPerUnit\n ? (resolution * sourceMetersPerUnit) / userMetersPerUnit\n : resolution;\n}\n\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in user projection units per pixel.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {number} Resolution in destination projection units per pixel.\n */\nexport function fromUserResolution(resolution, destProjection) {\n if (!userProjection) {\n return resolution;\n }\n const destMetersPerUnit = get(destProjection).getMetersPerUnit();\n const userMetersPerUnit = userProjection.getMetersPerUnit();\n return destMetersPerUnit && userMetersPerUnit\n ? (resolution * userMetersPerUnit) / destMetersPerUnit\n : resolution;\n}\n\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * \"Safe\" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent's range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} transform Transform function (source to destination).\n * @return {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} Safe transform function (source to destination).\n */\nexport function createSafeCoordinateTransform(sourceProj, destProj, transform) {\n return function (coord) {\n let transformed, worldsAway;\n if (sourceProj.canWrapX()) {\n const sourceExtent = sourceProj.getExtent();\n const sourceExtentWidth = getWidth(sourceExtent);\n coord = coord.slice(0);\n worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n if (worldsAway) {\n // Move x to the real world\n coord[0] = coord[0] - worldsAway * sourceExtentWidth;\n }\n coord[0] = clamp(coord[0], sourceExtent[0], sourceExtent[2]);\n coord[1] = clamp(coord[1], sourceExtent[1], sourceExtent[3]);\n transformed = transform(coord);\n } else {\n transformed = transform(coord);\n }\n if (worldsAway && destProj.canWrapX()) {\n // Move transformed coordinate back to the offset world\n transformed[0] += worldsAway * getWidth(destProj.getExtent());\n }\n return transformed;\n };\n}\n\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857. This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\nexport function addCommon() {\n // Add transformations that don't alter coordinates to convert within set of\n // projections with equal meaning.\n addEquivalentProjections(EPSG3857_PROJECTIONS);\n addEquivalentProjections(EPSG4326_PROJECTIONS);\n // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n // coordinates and back.\n addEquivalentTransforms(\n EPSG4326_PROJECTIONS,\n EPSG3857_PROJECTIONS,\n fromEPSG4326,\n toEPSG4326,\n );\n}\n\naddCommon();\n","/**\n * @module ol/tilegrid/WMTS\n */\n\nimport {get as getProjection} from '../proj.js';\nimport TileGrid from './TileGrid.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../extent.js\").Extent} [extent] Extent for the tile grid. No tiles\n * outside this extent will be requested by {@link module:ol/source/Tile~TileSource} sources.\n * When no `origin` or `origins` are configured, the `origin` will be set to the\n * top-left corner of the extent.\n * @property {import(\"../coordinate.js\").Coordinate} [origin] The tile grid origin, i.e.\n * where the `x` and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left\n * to right and downwards. If not specified, `extent` or `origins` must be provided.\n * @property {Array<import(\"../coordinate.js\").Coordinate>} [origins] Tile grid origins,\n * i.e. where the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If\n * given, the array length should match the length of the `resolutions` array, i.e.\n * each resolution can have a different origin. Tile coordinates increase left to\n * right and downwards. If not specified, `extent` or `origin` must be provided.\n * @property {!Array<number>} resolutions Resolutions. The array index of each\n * resolution needs to match the zoom level. This means that even if a `minZoom`\n * is configured, the resolutions array will have a length of `maxZoom + 1`\n * @property {!Array<string>} matrixIds matrix IDs. The length of this array needs\n * to match the length of the `resolutions` array.\n * @property {Array<import(\"../size.js\").Size>} [sizes] Number of tile rows and columns\n * of the grid for each zoom level. The values here are the `TileMatrixWidth` and\n * `TileMatrixHeight` advertised in the GetCapabilities response of the WMTS, and\n * define each zoom level's extent together with the `origin` or `origins`.\n * A grid `extent` can be configured in addition, and will further limit the extent for\n * which tile requests are made by sources. If the bottom-left corner of\n * an extent is used as `origin` or `origins`, then the `y` value must be\n * negative because OpenLayers tile coordinates use the top left as the origin.\n * @property {number|import(\"../size.js\").Size} [tileSize] Tile size.\n * @property {Array<number|import(\"../size.js\").Size>} [tileSizes] Tile sizes. The length of\n * this array needs to match the length of the `resolutions` array.\n */\n\n/**\n * @classdesc\n * Set the grid pattern for sources accessing WMTS tiled-image servers.\n * @api\n */\nclass WMTSTileGrid extends TileGrid {\n /**\n * @param {Options} options WMTS options.\n */\n constructor(options) {\n super({\n extent: options.extent,\n origin: options.origin,\n origins: options.origins,\n resolutions: options.resolutions,\n tileSize: options.tileSize,\n tileSizes: options.tileSizes,\n sizes: options.sizes,\n });\n\n /**\n * @private\n * @type {!Array<string>}\n */\n this.matrixIds_ = options.matrixIds;\n }\n\n /**\n * @param {number} z Z.\n * @return {string} MatrixId..\n */\n getMatrixId(z) {\n return this.matrixIds_[z];\n }\n\n /**\n * Get the list of matrix identifiers.\n * @return {Array<string>} MatrixIds.\n * @api\n */\n getMatrixIds() {\n return this.matrixIds_;\n }\n}\n\nexport default WMTSTileGrid;\n\n/**\n * Create a tile grid from a WMTS capabilities matrix set and an\n * optional TileMatrixSetLimits.\n * @param {Object} matrixSet An object representing a matrixSet in the\n * capabilities document.\n * @param {import(\"../extent.js\").Extent} [extent] An optional extent to restrict the tile\n * ranges the server provides.\n * @param {Array<Object>} [matrixLimits] An optional object representing\n * the available matrices for tileGrid.\n * @return {WMTSTileGrid} WMTS tileGrid instance.\n * @api\n */\nexport function createFromCapabilitiesMatrixSet(\n matrixSet,\n extent,\n matrixLimits,\n) {\n /** @type {!Array<number>} */\n const resolutions = [];\n /** @type {!Array<string>} */\n const matrixIds = [];\n /** @type {!Array<import(\"../coordinate.js\").Coordinate>} */\n const origins = [];\n /** @type {!Array<number|import(\"../size.js\").Size>} */\n const tileSizes = [];\n /** @type {!Array<import(\"../size.js\").Size>} */\n const sizes = [];\n\n matrixLimits = matrixLimits !== undefined ? matrixLimits : [];\n\n const supportedCRSPropName = 'SupportedCRS';\n const matrixIdsPropName = 'TileMatrix';\n const identifierPropName = 'Identifier';\n const scaleDenominatorPropName = 'ScaleDenominator';\n const topLeftCornerPropName = 'TopLeftCorner';\n const tileWidthPropName = 'TileWidth';\n const tileHeightPropName = 'TileHeight';\n\n const code = matrixSet[supportedCRSPropName];\n const projection = getProjection(code);\n const metersPerUnit = projection.getMetersPerUnit();\n // swap origin x and y coordinates if axis orientation is lat/long\n const switchOriginXY = projection.getAxisOrientation().startsWith('ne');\n\n matrixSet[matrixIdsPropName].sort(function (a, b) {\n return b[scaleDenominatorPropName] - a[scaleDenominatorPropName];\n });\n\n matrixSet[matrixIdsPropName].forEach(function (elt) {\n let matrixAvailable;\n // use of matrixLimits to filter TileMatrices from GetCapabilities\n // TileMatrixSet from unavailable matrix levels.\n if (matrixLimits.length > 0) {\n matrixAvailable = matrixLimits.find(function (elt_ml) {\n if (elt[identifierPropName] == elt_ml[matrixIdsPropName]) {\n return true;\n }\n // Fallback for tileMatrix identifiers that don't get prefixed\n // by their tileMatrixSet identifiers.\n if (!elt[identifierPropName].includes(':')) {\n return (\n matrixSet[identifierPropName] + ':' + elt[identifierPropName] ===\n elt_ml[matrixIdsPropName]\n );\n }\n return false;\n });\n } else {\n matrixAvailable = true;\n }\n\n if (matrixAvailable) {\n matrixIds.push(elt[identifierPropName]);\n const resolution =\n (elt[scaleDenominatorPropName] * 0.28e-3) / metersPerUnit;\n const tileWidth = elt[tileWidthPropName];\n const tileHeight = elt[tileHeightPropName];\n if (switchOriginXY) {\n origins.push([\n elt[topLeftCornerPropName][1],\n elt[topLeftCornerPropName][0],\n ]);\n } else {\n origins.push(elt[topLeftCornerPropName]);\n }\n resolutions.push(resolution);\n tileSizes.push(\n tileWidth == tileHeight ? tileWidth : [tileWidth, tileHeight],\n );\n sizes.push([elt['MatrixWidth'], elt['MatrixHeight']]);\n }\n });\n\n return new WMTSTileGrid({\n extent: extent,\n origins: origins,\n resolutions: resolutions,\n matrixIds: matrixIds,\n tileSizes: tileSizes,\n sizes: sizes,\n });\n}\n","/** @module swissgeo/coordinates/ol */\n\nimport type { ViewOptions } from 'ol/View'\n\nimport TileGrid from 'ol/tilegrid/TileGrid'\nimport WMTSTileGrid from 'ol/tilegrid/WMTS'\n\nimport { LV95 } from '@/proj'\nimport { LV95_RESOLUTIONS } from '@/proj/SwissCoordinateSystem'\n\nfunction indexOfMaxResolution(layerMaxResolution: number): number {\n const resolutionSteps = LV95.getResolutionSteps()\n const matchResolutionStep = resolutionSteps.find(\n (step) => step.resolution === layerMaxResolution\n )\n if (!matchResolutionStep) {\n return resolutionSteps.length - 1\n }\n return resolutionSteps.indexOf(matchResolutionStep)\n}\n\nexport function getLV95WMSTileGrid(): TileGrid {\n return new TileGrid({\n resolutions: LV95.getResolutionSteps().map((step) => step.resolution),\n extent: LV95.bounds.flatten,\n origin: LV95.getTileOrigin(),\n tileSize: 512,\n })\n}\n\n/**\n * @param maxResolution Tells the max resolution step the layer can be displayed. Some of our layers\n * are able to be shown up to 0.1m/px, but others (most) are not available past 0.25m/px. Default\n * is 0.25m/px\n */\nexport function getLV95WMTSTileGrid(maxResolution = 0.25): WMTSTileGrid {\n const maxResolutionIndex = indexOfMaxResolution(maxResolution)\n let resolutionSteps = LV95.getResolutionSteps()\n if (resolutionSteps.length > maxResolutionIndex) {\n resolutionSteps = resolutionSteps.slice(0, maxResolutionIndex + 1)\n }\n return new WMTSTileGrid({\n resolutions: resolutionSteps.map((step) => step.resolution),\n origin: LV95.getTileOrigin(),\n matrixIds: resolutionSteps.map((_, index) => index.toString()),\n extent: LV95.bounds?.flatten,\n })\n}\n\nexport function getLV95ViewConfig(): ViewOptions {\n return {\n projection: LV95.epsg,\n center: LV95.bounds.center,\n zoom: LV95.getDefaultZoom(),\n minResolution: LV95_RESOLUTIONS[LV95_RESOLUTIONS.length - 1],\n resolutions: LV95_RESOLUTIONS,\n extent: LV95.bounds.flatten,\n constrainOnlyCenter: true,\n }\n}\n"],"names":["TileRange","minX","maxX","minY","maxY","tileCoord","tileRange","x","y","createOrUpdate","ascending","a","b","linearFindNearest","arr","target","direction","n","candidate","isSorted","func","strict","compare","currentVal","index","res","assert","assertion","errorMessage","Relationship","coordinateRelationship","extent","coordinate","relationship","createEmpty","dest","extendFlatCoordinates","flatCoordinates","offset","end","stride","extendXY","getTopLeft","intersects","extent1","extent2","intersectsSegment","start","startRel","endRel","startX","startY","endX","endY","slope","linearRingContainsXY","wn","x1","y1","x2","y2","forEach","callback","ret","intersectsLineString","coordinatesExtent","forEachSegment","point1","point2","intersectsLinearRing","clamp","value","min","max","toFixed","decimals","factor","floor","ceil","toSize","size","z","DEFAULT_TILE_SIZE","tmpTileCoord","DECIMALS","TileGrid","options","zoomFactor","ii","restrictedTileRange","zoom","i","j","jj","tempTileRange","tempExtent","tileCoordExtent","createOrUpdateTileRange","tileCoordZ","tileCoordX","tileCoordY","origin","resolution","tileSize","opt_tileCoord","reverseIntersectionPolicy","scale","createOrUpdateTileCoord","opt_direction","viewport","length","fullTileRanges","METERS_PER_UNIT","Projection","global","tileGrid","worldExtent","RADIUS","HALF_SIZE","EXTENT","WORLD_EXTENT","MAX_SAFE_Y","EPSG3857Projection","code","point","PROJECTIONS","fromEPSG4326","input","output","dimension","toEPSG4326","EPSG4326Projection","axisOrientation","transforms","add","source","destination","transformFn","sourceCode","destinationCode","cloneTransform","addProjection","projection","addProj","addTransformFunc","addProjections","projections","addEquivalentProjections","addEquivalentTransforms","projections1","projections2","forwardTransform","inverseTransform","projection1","projection2","addCommon","EPSG3857_PROJECTIONS","EPSG4326_PROJECTIONS","WMTSTileGrid","indexOfMaxResolution","layerMaxResolution","resolutionSteps","LV95","matchResolutionStep","step","getLV95WMSTileGrid","getLV95WMTSTileGrid","maxResolution","maxResolutionIndex","_","getLV95ViewConfig","LV95_RESOLUTIONS"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]}
|
package/index.html
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swissgeo/coordinates",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Projection definition and coordinates utils for SWISSGEO projects.",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"type": "module",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@microsoft/api-extractor": "^7.55.2",
|
|
26
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
26
27
|
"@turf/turf": "^7.3.1",
|
|
27
28
|
"@types/chai": "^5.2.3",
|
|
28
29
|
"@types/geojson": "^7946.0.16",
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"@vitejs/plugin-vue": "^6.0.3",
|
|
31
32
|
"chai": "^6.2.2",
|
|
32
33
|
"eslint": "^9.39.2",
|
|
34
|
+
"tailwindcss": "^4.1.18",
|
|
33
35
|
"typescript": "^5.9.3",
|
|
34
36
|
"unplugin-dts": "1.0.0-beta.6",
|
|
35
37
|
"vite": "7.2.2",
|
|
@@ -38,8 +40,8 @@
|
|
|
38
40
|
"vitest": "^4.0.16",
|
|
39
41
|
"vue": "^3.5.26",
|
|
40
42
|
"vue-tsc": "^3.2.2",
|
|
41
|
-
"@swissgeo/config-
|
|
42
|
-
"@swissgeo/config-
|
|
43
|
+
"@swissgeo/config-typescript": "1.0.0",
|
|
44
|
+
"@swissgeo/config-eslint": "1.0.0"
|
|
43
45
|
},
|
|
44
46
|
"peerDependencies": {
|
|
45
47
|
"proj4": "^2.20.2"
|
package/src/DevApp.vue
CHANGED
|
@@ -1,31 +1,51 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { View } from 'ol'
|
|
2
3
|
import OLTileLayer from 'ol/layer/Tile'
|
|
3
4
|
import OLMap from 'ol/Map'
|
|
5
|
+
import { register } from 'ol/proj/proj4'
|
|
6
|
+
import TileWMS from 'ol/source/TileWMS'
|
|
4
7
|
import XYZ from 'ol/source/XYZ'
|
|
5
8
|
import proj4 from 'proj4'
|
|
6
9
|
import { onMounted } from 'vue'
|
|
7
10
|
|
|
8
|
-
import {
|
|
11
|
+
import { getLV95WMTSTileGrid, getLV95ViewConfig, getLV95WMSTileGrid } from '@/ol'
|
|
9
12
|
import { LV95 } from '@/proj'
|
|
10
|
-
|
|
11
|
-
const pixelKarteFarbeURL = 'https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/2056/{z}/{x}/{y}.jpeg'
|
|
13
|
+
import registerProj4 from '@/registerProj4'
|
|
12
14
|
|
|
13
15
|
function setupOpenLayers() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
registerProj4(proj4)
|
|
17
|
+
register(proj4)
|
|
16
18
|
|
|
17
19
|
const pixelKarteFarbe = new OLTileLayer({
|
|
18
20
|
source: new XYZ({
|
|
19
|
-
url:
|
|
21
|
+
url: 'https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/2056/{z}/{x}/{y}.jpeg',
|
|
20
22
|
projection: LV95.epsg,
|
|
21
|
-
tileGrid:
|
|
22
|
-
})
|
|
23
|
+
tileGrid: getLV95WMTSTileGrid(),
|
|
24
|
+
}),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// a tiled WMS (one that defines a gutter in its layer config in https://api3.geo.admin.ch/rest/services/all/MapServer/layersConfig)
|
|
28
|
+
// It will also require the TileGrid to be properly configured to have the best look (no aliasing, etc...)
|
|
29
|
+
const windEnergieAnlagen = new OLTileLayer({
|
|
30
|
+
source: new TileWMS({
|
|
31
|
+
url: 'https://wms.geo.admin.ch/',
|
|
32
|
+
params: {
|
|
33
|
+
CRS: LV95.epsg,
|
|
34
|
+
FORMAT: 'image/png',
|
|
35
|
+
LAYERS: 'ch.bfe.windenergieanlagen',
|
|
36
|
+
VERSION: '1.3.0',
|
|
37
|
+
},
|
|
38
|
+
gutter: 15,
|
|
39
|
+
tileGrid: getLV95WMSTileGrid(),
|
|
40
|
+
}),
|
|
23
41
|
})
|
|
24
42
|
|
|
25
43
|
new OLMap({
|
|
26
44
|
target: 'ol-map',
|
|
27
|
-
layers: [pixelKarteFarbe],
|
|
28
|
-
view:
|
|
45
|
+
layers: [pixelKarteFarbe, windEnergieAnlagen],
|
|
46
|
+
view: new View({
|
|
47
|
+
...getLV95ViewConfig(),
|
|
48
|
+
}),
|
|
29
49
|
})
|
|
30
50
|
}
|
|
31
51
|
|
|
@@ -35,32 +55,13 @@ onMounted(() => {
|
|
|
35
55
|
</script>
|
|
36
56
|
|
|
37
57
|
<template>
|
|
38
|
-
<div class="
|
|
39
|
-
<div class="
|
|
58
|
+
<div class="absolute top-0 left-0 grid h-full w-full grid-rows-2">
|
|
59
|
+
<div class="flex flex-col">
|
|
40
60
|
<h2>OpenLayers</h2>
|
|
41
61
|
<div
|
|
42
62
|
id="ol-map"
|
|
43
|
-
class="
|
|
63
|
+
class="grow"
|
|
44
64
|
></div>
|
|
45
65
|
</div>
|
|
46
66
|
</div>
|
|
47
67
|
</template>
|
|
48
|
-
|
|
49
|
-
<style scoped lang="scss">
|
|
50
|
-
.dev-app {
|
|
51
|
-
position: absolute;
|
|
52
|
-
top: 0;
|
|
53
|
-
left: 0;
|
|
54
|
-
width: 100%;
|
|
55
|
-
height: 100%;
|
|
56
|
-
display: grid;
|
|
57
|
-
grid-template-rows: 1fr 1fr;
|
|
58
|
-
}
|
|
59
|
-
.map-container {
|
|
60
|
-
display: flex;
|
|
61
|
-
flex-direction: column;
|
|
62
|
-
&-element {
|
|
63
|
-
flex-grow: 1;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
</style>
|