import { Layer_default, ZIndexContext_default, canvasPool } from "./chunk-JOOKRY6I.js"; import { BaseVector_default } from "./chunk-OVJRLVXU.js"; import { Icon_default, asColorLike, defaultFillStyle, defaultFont, defaultLineCap, defaultLineDash, defaultLineDashOffset, defaultLineJoin, defaultLineWidth, defaultMiterLimit, defaultPadding, defaultStrokeStyle, defaultTextAlign, defaultTextBaseline, drawImageOrLabel, getTextDimensions, measureAndCacheTextWidth, registerFont } from "./chunk-EMRMEHGR.js"; import { EventType_default, ViewHint_default } from "./chunk-S5OMZ56B.js"; import { createCanvasContext2D, releaseCanvas } from "./chunk-YWIWRQT2.js"; import { ImageState_default } from "./chunk-5TDNKDLD.js"; import { lineStringLength } from "./chunk-JFXZSSOM.js"; import { inflateCoordinates, inflateCoordinatesArray, inflateMultiCoordinatesArray, snap } from "./chunk-NLIGXLAR.js"; import { rotate, transform2D, transformGeom2D } from "./chunk-YUTQGDGI.js"; import { apply, compose, create, setFromArray } from "./chunk-JFONEOYG.js"; import { fromUserExtent, getTransformFromProjections, getUserProjection, toUserExtent, toUserResolution } from "./chunk-XZU4LSFD.js"; import { wrapX as wrapX2 } from "./chunk-3JZANJYE.js"; import { clamp, lerp, toFixed } from "./chunk-54BTDBAD.js"; import { Relationship_default, buffer, clone, containsCoordinate, containsExtent, coordinateRelationship, createEmpty, createOrUpdate, extendCoordinate, getHeight, getWidth, intersects, wrapX } from "./chunk-CKDBVGKM.js"; import { getUid } from "./chunk-H47PV7W6.js"; import { ascending, descending, equals, reverseSubArray } from "./chunk-FQY6EMA7.js"; import { isEmpty } from "./chunk-5RHQVMYD.js"; // node_modules/ol/render/VectorContext.js var VectorContext = class { /** * Render a geometry with a custom renderer. * * @param {import("../geom/SimpleGeometry.js").default} geometry Geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {Function} renderer Renderer. * @param {Function} hitDetectionRenderer Renderer. * @param {number} [index] Render order index. */ drawCustom(geometry, feature, renderer, hitDetectionRenderer, index) { } /** * Render a geometry. * * @param {import("../geom/Geometry.js").default} geometry The geometry to render. */ drawGeometry(geometry) { } /** * Set the rendering style. * * @param {import("../style/Style.js").default} style The rendering style. */ setStyle(style) { } /** * @param {import("../geom/Circle.js").default} circleGeometry Circle geometry. * @param {import("../Feature.js").default} feature Feature. * @param {number} [index] Render order index. */ drawCircle(circleGeometry, feature, index) { } /** * @param {import("../Feature.js").default} feature Feature. * @param {import("../style/Style.js").default} style Style. * @param {number} [index] Render order index. */ drawFeature(feature, style, index) { } /** * @param {import("../geom/GeometryCollection.js").default} geometryCollectionGeometry Geometry collection. * @param {import("../Feature.js").default} feature Feature. * @param {number} [index] Render order index. */ drawGeometryCollection(geometryCollectionGeometry, feature, index) { } /** * @param {import("../geom/LineString.js").default|import("./Feature.js").default} lineStringGeometry Line string geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawLineString(lineStringGeometry, feature, index) { } /** * @param {import("../geom/MultiLineString.js").default|import("./Feature.js").default} multiLineStringGeometry MultiLineString geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawMultiLineString(multiLineStringGeometry, feature, index) { } /** * @param {import("../geom/MultiPoint.js").default|import("./Feature.js").default} multiPointGeometry MultiPoint geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawMultiPoint(multiPointGeometry, feature, index) { } /** * @param {import("../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawMultiPolygon(multiPolygonGeometry, feature, index) { } /** * @param {import("../geom/Point.js").default|import("./Feature.js").default} pointGeometry Point geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawPoint(pointGeometry, feature, index) { } /** * @param {import("../geom/Polygon.js").default|import("./Feature.js").default} polygonGeometry Polygon geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawPolygon(polygonGeometry, feature, index) { } /** * @param {import("../geom/SimpleGeometry.js").default|import("./Feature.js").default} geometry Geometry. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. */ drawText(geometry, feature, index) { } /** * @param {import("../style/Fill.js").default} fillStyle Fill style. * @param {import("../style/Stroke.js").default} strokeStyle Stroke style. */ setFillStrokeStyle(fillStyle, strokeStyle) { } /** * @param {import("../style/Image.js").default} imageStyle Image style. * @param {import("../render/canvas.js").DeclutterImageWithText} [declutterImageWithText] Shared data for combined decluttering with a text style. */ setImageStyle(imageStyle, declutterImageWithText) { } /** * @param {import("../style/Text.js").default} textStyle Text style. * @param {import("../render/canvas.js").DeclutterImageWithText} [declutterImageWithText] Shared data for combined decluttering with an image style. */ setTextStyle(textStyle, declutterImageWithText) { } }; var VectorContext_default = VectorContext; // node_modules/ol/render/canvas/Instruction.js var Instruction = { BEGIN_GEOMETRY: 0, BEGIN_PATH: 1, CIRCLE: 2, CLOSE_PATH: 3, CUSTOM: 4, DRAW_CHARS: 5, DRAW_IMAGE: 6, END_GEOMETRY: 7, FILL: 8, MOVE_TO_LINE_TO: 9, SET_FILL_STYLE: 10, SET_STROKE_STYLE: 11, STROKE: 12 }; var fillInstruction = [Instruction.FILL]; var strokeInstruction = [Instruction.STROKE]; var beginPathInstruction = [Instruction.BEGIN_PATH]; var closePathInstruction = [Instruction.CLOSE_PATH]; var Instruction_default = Instruction; // node_modules/ol/render/canvas/Builder.js var CanvasBuilder = class extends VectorContext_default { /** * @param {number} tolerance Tolerance. * @param {import("../../extent.js").Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. */ constructor(tolerance, maxExtent, resolution, pixelRatio) { super(); this.tolerance = tolerance; this.maxExtent = maxExtent; this.pixelRatio = pixelRatio; this.maxLineWidth = 0; this.resolution = resolution; this.beginGeometryInstruction1_ = null; this.beginGeometryInstruction2_ = null; this.bufferedMaxExtent_ = null; this.instructions = []; this.coordinates = []; this.tmpCoordinate_ = []; this.hitDetectionInstructions = []; this.state = /** @type {import("../canvas.js").FillStrokeState} */ {}; } /** * @protected * @param {Array} dashArray Dash array. * @return {Array} Dash array with pixel ratio applied */ applyPixelRatio(dashArray) { const pixelRatio = this.pixelRatio; return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) { return dash * pixelRatio; }); } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} stride Stride. * @protected * @return {number} My end */ appendFlatPointCoordinates(flatCoordinates, stride) { const extent = this.getBufferedMaxExtent(); const tmpCoord = this.tmpCoordinate_; const coordinates = this.coordinates; let myEnd = coordinates.length; for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) { tmpCoord[0] = flatCoordinates[i]; tmpCoord[1] = flatCoordinates[i + 1]; if (containsCoordinate(extent, tmpCoord)) { coordinates[myEnd++] = tmpCoord[0]; coordinates[myEnd++] = tmpCoord[1]; } } return myEnd; } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. * @param {boolean} closed Last input coordinate equals first. * @param {boolean} skipFirst Skip first coordinate. * @protected * @return {number} My end. */ appendFlatLineCoordinates(flatCoordinates, offset, end, stride, closed, skipFirst) { const coordinates = this.coordinates; let myEnd = coordinates.length; const extent = this.getBufferedMaxExtent(); if (skipFirst) { offset += stride; } let lastXCoord = flatCoordinates[offset]; let lastYCoord = flatCoordinates[offset + 1]; const nextCoord = this.tmpCoordinate_; let skipped = true; let i, lastRel, nextRel; for (i = offset + stride; i < end; i += stride) { nextCoord[0] = flatCoordinates[i]; nextCoord[1] = flatCoordinates[i + 1]; nextRel = coordinateRelationship(extent, nextCoord); if (nextRel !== lastRel) { if (skipped) { coordinates[myEnd++] = lastXCoord; coordinates[myEnd++] = lastYCoord; skipped = false; } coordinates[myEnd++] = nextCoord[0]; coordinates[myEnd++] = nextCoord[1]; } else if (nextRel === Relationship_default.INTERSECTING) { coordinates[myEnd++] = nextCoord[0]; coordinates[myEnd++] = nextCoord[1]; skipped = false; } else { skipped = true; } lastXCoord = nextCoord[0]; lastYCoord = nextCoord[1]; lastRel = nextRel; } if (closed && skipped || i === offset + stride) { coordinates[myEnd++] = lastXCoord; coordinates[myEnd++] = lastYCoord; } return myEnd; } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {Array} ends Ends. * @param {number} stride Stride. * @param {Array} builderEnds Builder ends. * @return {number} Offset. */ drawCustomCoordinates_(flatCoordinates, offset, ends, stride, builderEnds) { for (let i = 0, ii = ends.length; i < ii; ++i) { const end = ends[i]; const builderEnd = this.appendFlatLineCoordinates( flatCoordinates, offset, end, stride, false, false ); builderEnds.push(builderEnd); offset = end; } return offset; } /** * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {Function} renderer Renderer. * @param {Function} hitDetectionRenderer Renderer. * @param {number} [index] Render order index. * @override */ drawCustom(geometry, feature, renderer, hitDetectionRenderer, index) { this.beginGeometry(geometry, feature, index); const type = geometry.getType(); const stride = geometry.getStride(); const builderBegin = this.coordinates.length; let flatCoordinates, builderEnd, builderEnds, builderEndss; let offset; switch (type) { case "MultiPolygon": flatCoordinates = /** @type {import("../../geom/MultiPolygon.js").default} */ geometry.getOrientedFlatCoordinates(); builderEndss = []; const endss = ( /** @type {import("../../geom/MultiPolygon.js").default} */ geometry.getEndss() ); offset = 0; for (let i = 0, ii = endss.length; i < ii; ++i) { const myEnds = []; offset = this.drawCustomCoordinates_( flatCoordinates, offset, endss[i], stride, myEnds ); builderEndss.push(myEnds); } this.instructions.push([ Instruction_default.CUSTOM, builderBegin, builderEndss, geometry, renderer, inflateMultiCoordinatesArray, index ]); this.hitDetectionInstructions.push([ Instruction_default.CUSTOM, builderBegin, builderEndss, geometry, hitDetectionRenderer || renderer, inflateMultiCoordinatesArray, index ]); break; case "Polygon": case "MultiLineString": builderEnds = []; flatCoordinates = type == "Polygon" ? ( /** @type {import("../../geom/Polygon.js").default} */ geometry.getOrientedFlatCoordinates() ) : geometry.getFlatCoordinates(); offset = this.drawCustomCoordinates_( flatCoordinates, 0, /** @type {import("../../geom/Polygon.js").default|import("../../geom/MultiLineString.js").default} */ geometry.getEnds(), stride, builderEnds ); this.instructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnds, geometry, renderer, inflateCoordinatesArray, index ]); this.hitDetectionInstructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnds, geometry, hitDetectionRenderer || renderer, inflateCoordinatesArray, index ]); break; case "LineString": case "Circle": flatCoordinates = geometry.getFlatCoordinates(); builderEnd = this.appendFlatLineCoordinates( flatCoordinates, 0, flatCoordinates.length, stride, false, false ); this.instructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnd, geometry, renderer, inflateCoordinates, index ]); this.hitDetectionInstructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnd, geometry, hitDetectionRenderer || renderer, inflateCoordinates, index ]); break; case "MultiPoint": flatCoordinates = geometry.getFlatCoordinates(); builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride); if (builderEnd > builderBegin) { this.instructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnd, geometry, renderer, inflateCoordinates, index ]); this.hitDetectionInstructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnd, geometry, hitDetectionRenderer || renderer, inflateCoordinates, index ]); } break; case "Point": flatCoordinates = geometry.getFlatCoordinates(); this.coordinates.push(flatCoordinates[0], flatCoordinates[1]); builderEnd = this.coordinates.length; this.instructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnd, geometry, renderer, void 0, index ]); this.hitDetectionInstructions.push([ Instruction_default.CUSTOM, builderBegin, builderEnd, geometry, hitDetectionRenderer || renderer, void 0, index ]); break; default: } this.endGeometry(feature); } /** * @protected * @param {import("../../geom/Geometry").default|import("../Feature.js").default} geometry The geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} index Render order index */ beginGeometry(geometry, feature, index) { this.beginGeometryInstruction1_ = [ Instruction_default.BEGIN_GEOMETRY, feature, 0, geometry, index ]; this.instructions.push(this.beginGeometryInstruction1_); this.beginGeometryInstruction2_ = [ Instruction_default.BEGIN_GEOMETRY, feature, 0, geometry, index ]; this.hitDetectionInstructions.push(this.beginGeometryInstruction2_); } /** * @return {import("../canvas.js").SerializableInstructions} the serializable instructions. */ finish() { return { instructions: this.instructions, hitDetectionInstructions: this.hitDetectionInstructions, coordinates: this.coordinates }; } /** * Reverse the hit detection instructions. */ reverseHitDetectionInstructions() { const hitDetectionInstructions = this.hitDetectionInstructions; hitDetectionInstructions.reverse(); let i; const n = hitDetectionInstructions.length; let instruction; let type; let begin = -1; for (i = 0; i < n; ++i) { instruction = hitDetectionInstructions[i]; type = /** @type {import("./Instruction.js").default} */ instruction[0]; if (type == Instruction_default.END_GEOMETRY) { begin = i; } else if (type == Instruction_default.BEGIN_GEOMETRY) { instruction[2] = i; reverseSubArray(this.hitDetectionInstructions, begin, i); begin = -1; } } } /** * @param {import("../../style/Fill.js").default} fillStyle Fill style. * @param {import('../canvas.js').FillStrokeState} [state] State. * @return {import('../canvas.js').FillStrokeState} State. */ fillStyleToState(fillStyle, state = ( /** @type {import('../canvas.js').FillStrokeState} */ {} )) { if (fillStyle) { const fillStyleColor = fillStyle.getColor(); state.fillPatternScale = fillStyleColor && typeof fillStyleColor === "object" && "src" in fillStyleColor ? this.pixelRatio : 1; state.fillStyle = asColorLike( fillStyleColor ? fillStyleColor : defaultFillStyle ); } else { state.fillStyle = void 0; } return state; } /** * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style. * @param {import("../canvas.js").FillStrokeState} state State. * @return {import("../canvas.js").FillStrokeState} State. */ strokeStyleToState(strokeStyle, state = ( /** @type {import('../canvas.js').FillStrokeState} */ {} )) { if (strokeStyle) { const strokeStyleColor = strokeStyle.getColor(); state.strokeStyle = asColorLike( strokeStyleColor ? strokeStyleColor : defaultStrokeStyle ); const strokeStyleLineCap = strokeStyle.getLineCap(); state.lineCap = strokeStyleLineCap !== void 0 ? strokeStyleLineCap : defaultLineCap; const strokeStyleLineDash = strokeStyle.getLineDash(); state.lineDash = strokeStyleLineDash ? strokeStyleLineDash.slice() : defaultLineDash; const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); state.lineDashOffset = strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset; const strokeStyleLineJoin = strokeStyle.getLineJoin(); state.lineJoin = strokeStyleLineJoin !== void 0 ? strokeStyleLineJoin : defaultLineJoin; const strokeStyleWidth = strokeStyle.getWidth(); state.lineWidth = strokeStyleWidth !== void 0 ? strokeStyleWidth : defaultLineWidth; const strokeStyleMiterLimit = strokeStyle.getMiterLimit(); state.miterLimit = strokeStyleMiterLimit !== void 0 ? strokeStyleMiterLimit : defaultMiterLimit; if (state.lineWidth > this.maxLineWidth) { this.maxLineWidth = state.lineWidth; this.bufferedMaxExtent_ = null; } } else { state.strokeStyle = void 0; state.lineCap = void 0; state.lineDash = null; state.lineDashOffset = void 0; state.lineJoin = void 0; state.lineWidth = void 0; state.miterLimit = void 0; } return state; } /** * @param {import("../../style/Fill.js").default} fillStyle Fill style. * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style. * @override */ setFillStrokeStyle(fillStyle, strokeStyle) { const state = this.state; this.fillStyleToState(fillStyle, state); this.strokeStyleToState(strokeStyle, state); } /** * @param {import("../canvas.js").FillStrokeState} state State. * @return {Array<*>} Fill instruction. */ createFill(state) { const fillStyle = state.fillStyle; const fillInstruction2 = [Instruction_default.SET_FILL_STYLE, fillStyle]; if (typeof fillStyle !== "string") { fillInstruction2.push(state.fillPatternScale); } return fillInstruction2; } /** * @param {import("../canvas.js").FillStrokeState} state State. */ applyStroke(state) { this.instructions.push(this.createStroke(state)); } /** * @param {import("../canvas.js").FillStrokeState} state State. * @return {Array<*>} Stroke instruction. */ createStroke(state) { return [ Instruction_default.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth * this.pixelRatio, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash ? this.applyPixelRatio(state.lineDash) : null, state.lineDashOffset * this.pixelRatio ]; } /** * @param {import("../canvas.js").FillStrokeState} state State. * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState):Array<*>} createFill Create fill. */ updateFillStyle(state, createFill) { const fillStyle = state.fillStyle; if (typeof fillStyle !== "string" || state.currentFillStyle != fillStyle) { this.instructions.push(createFill.call(this, state)); state.currentFillStyle = fillStyle; } } /** * @param {import("../canvas.js").FillStrokeState} state State. * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState): void} applyStroke Apply stroke. */ updateStrokeStyle(state, applyStroke) { const strokeStyle = state.strokeStyle; const lineCap = state.lineCap; const lineDash = state.lineDash; const lineDashOffset = state.lineDashOffset; const lineJoin = state.lineJoin; const lineWidth = state.lineWidth; const miterLimit = state.miterLimit; if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || lineDash != state.currentLineDash && !equals(state.currentLineDash, lineDash) || state.currentLineDashOffset != lineDashOffset || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) { applyStroke.call(this, state); state.currentStrokeStyle = strokeStyle; state.currentLineCap = lineCap; state.currentLineDash = lineDash; state.currentLineDashOffset = lineDashOffset; state.currentLineJoin = lineJoin; state.currentLineWidth = lineWidth; state.currentMiterLimit = miterLimit; } } /** * @param {import("../../Feature.js").FeatureLike} feature Feature. */ endGeometry(feature) { this.beginGeometryInstruction1_[2] = this.instructions.length; this.beginGeometryInstruction1_ = null; this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length; this.beginGeometryInstruction2_ = null; const endGeometryInstruction = [Instruction_default.END_GEOMETRY, feature]; this.instructions.push(endGeometryInstruction); this.hitDetectionInstructions.push(endGeometryInstruction); } /** * Get the buffered rendering extent. Rendering will be clipped to the extent * provided to the constructor. To account for symbolizers that may intersect * this extent, we calculate a buffered extent (e.g. based on stroke width). * @return {import("../../extent.js").Extent} The buffered rendering extent. * @protected */ getBufferedMaxExtent() { if (!this.bufferedMaxExtent_) { this.bufferedMaxExtent_ = clone(this.maxExtent); if (this.maxLineWidth > 0) { const width = this.resolution * (this.maxLineWidth + 1) / 2; buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_); } } return this.bufferedMaxExtent_; } }; var Builder_default = CanvasBuilder; // node_modules/ol/render/canvas/ImageBuilder.js var CanvasImageBuilder = class extends Builder_default { /** * @param {number} tolerance Tolerance. * @param {import("../../extent.js").Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. */ constructor(tolerance, maxExtent, resolution, pixelRatio) { super(tolerance, maxExtent, resolution, pixelRatio); this.hitDetectionImage_ = null; this.image_ = null; this.imagePixelRatio_ = void 0; this.anchorX_ = void 0; this.anchorY_ = void 0; this.height_ = void 0; this.opacity_ = void 0; this.originX_ = void 0; this.originY_ = void 0; this.rotateWithView_ = void 0; this.rotation_ = void 0; this.scale_ = void 0; this.width_ = void 0; this.declutterMode_ = void 0; this.declutterImageWithText_ = void 0; } /** * @param {import("../../geom/Point.js").default|import("../Feature.js").default} pointGeometry Point geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawPoint(pointGeometry, feature, index) { if (!this.image_ || this.maxExtent && !containsCoordinate(this.maxExtent, pointGeometry.getFlatCoordinates())) { return; } this.beginGeometry(pointGeometry, feature, index); const flatCoordinates = pointGeometry.getFlatCoordinates(); const stride = pointGeometry.getStride(); const myBegin = this.coordinates.length; const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride); this.instructions.push([ Instruction_default.DRAW_IMAGE, myBegin, myEnd, this.image_, // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_ * this.imagePixelRatio_, this.originY_ * this.imagePixelRatio_, this.rotateWithView_, this.rotation_, [ this.scale_[0] * this.pixelRatio / this.imagePixelRatio_, this.scale_[1] * this.pixelRatio / this.imagePixelRatio_ ], Math.ceil(this.width_ * this.imagePixelRatio_), this.declutterMode_, this.declutterImageWithText_ ]); this.hitDetectionInstructions.push([ Instruction_default.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_, // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_, this.anchorY_, this.height_, 1, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, this.scale_, this.width_, this.declutterMode_, this.declutterImageWithText_ ]); this.endGeometry(feature); } /** * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} multiPointGeometry MultiPoint geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawMultiPoint(multiPointGeometry, feature, index) { if (!this.image_) { return; } this.beginGeometry(multiPointGeometry, feature, index); const flatCoordinates = multiPointGeometry.getFlatCoordinates(); const filteredFlatCoordinates = []; for (let i = 0, ii = flatCoordinates.length; i < ii; i += multiPointGeometry.getStride()) { if (!this.maxExtent || containsCoordinate(this.maxExtent, flatCoordinates.slice(i, i + 2))) { filteredFlatCoordinates.push( flatCoordinates[i], flatCoordinates[i + 1] ); } } const myBegin = this.coordinates.length; const myEnd = this.appendFlatPointCoordinates(filteredFlatCoordinates, 2); this.instructions.push([ Instruction_default.DRAW_IMAGE, myBegin, myEnd, this.image_, // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_ * this.imagePixelRatio_, this.originY_ * this.imagePixelRatio_, this.rotateWithView_, this.rotation_, [ this.scale_[0] * this.pixelRatio / this.imagePixelRatio_, this.scale_[1] * this.pixelRatio / this.imagePixelRatio_ ], Math.ceil(this.width_ * this.imagePixelRatio_), this.declutterMode_, this.declutterImageWithText_ ]); this.hitDetectionInstructions.push([ Instruction_default.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_, // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_, this.anchorY_, this.height_, 1, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, this.scale_, this.width_, this.declutterMode_, this.declutterImageWithText_ ]); this.endGeometry(feature); } /** * @return {import("../canvas.js").SerializableInstructions} the serializable instructions. * @override */ finish() { this.reverseHitDetectionInstructions(); this.anchorX_ = void 0; this.anchorY_ = void 0; this.hitDetectionImage_ = null; this.image_ = null; this.imagePixelRatio_ = void 0; this.height_ = void 0; this.scale_ = void 0; this.opacity_ = void 0; this.originX_ = void 0; this.originY_ = void 0; this.rotateWithView_ = void 0; this.rotation_ = void 0; this.width_ = void 0; return super.finish(); } /** * @param {import("../../style/Image.js").default} imageStyle Image style. * @param {Object} [sharedData] Shared data. * @override */ setImageStyle(imageStyle, sharedData) { const anchor = imageStyle.getAnchor(); const size = imageStyle.getSize(); const origin = imageStyle.getOrigin(); this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio); this.anchorX_ = anchor[0]; this.anchorY_ = anchor[1]; this.hitDetectionImage_ = imageStyle.getHitDetectionImage(); this.image_ = imageStyle.getImage(this.pixelRatio); this.height_ = size[1]; this.opacity_ = imageStyle.getOpacity(); this.originX_ = origin[0]; this.originY_ = origin[1]; this.rotateWithView_ = imageStyle.getRotateWithView(); this.rotation_ = imageStyle.getRotation(); this.scale_ = imageStyle.getScaleArray(); this.width_ = size[0]; this.declutterMode_ = imageStyle.getDeclutterMode(); this.declutterImageWithText_ = sharedData; } }; var ImageBuilder_default = CanvasImageBuilder; // node_modules/ol/render/canvas/LineStringBuilder.js var CanvasLineStringBuilder = class extends Builder_default { /** * @param {number} tolerance Tolerance. * @param {import("../../extent.js").Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. */ constructor(tolerance, maxExtent, resolution, pixelRatio) { super(tolerance, maxExtent, resolution, pixelRatio); } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. * @private * @return {number} end. */ drawFlatCoordinates_(flatCoordinates, offset, end, stride) { const myBegin = this.coordinates.length; const myEnd = this.appendFlatLineCoordinates( flatCoordinates, offset, end, stride, false, false ); const moveToLineToInstruction = [ Instruction_default.MOVE_TO_LINE_TO, myBegin, myEnd ]; this.instructions.push(moveToLineToInstruction); this.hitDetectionInstructions.push(moveToLineToInstruction); return end; } /** * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} lineStringGeometry Line string geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawLineString(lineStringGeometry, feature, index) { const state = this.state; const strokeStyle = state.strokeStyle; const lineWidth = state.lineWidth; if (strokeStyle === void 0 || lineWidth === void 0) { return; } this.updateStrokeStyle(state, this.applyStroke); this.beginGeometry(lineStringGeometry, feature, index); this.hitDetectionInstructions.push( [ Instruction_default.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, defaultLineDash, defaultLineDashOffset ], beginPathInstruction ); const flatCoordinates = lineStringGeometry.getFlatCoordinates(); const stride = lineStringGeometry.getStride(); this.drawFlatCoordinates_( flatCoordinates, 0, flatCoordinates.length, stride ); this.hitDetectionInstructions.push(strokeInstruction); this.endGeometry(feature); } /** * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} multiLineStringGeometry MultiLineString geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawMultiLineString(multiLineStringGeometry, feature, index) { const state = this.state; const strokeStyle = state.strokeStyle; const lineWidth = state.lineWidth; if (strokeStyle === void 0 || lineWidth === void 0) { return; } this.updateStrokeStyle(state, this.applyStroke); this.beginGeometry(multiLineStringGeometry, feature, index); this.hitDetectionInstructions.push( [ Instruction_default.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, defaultLineDash, defaultLineDashOffset ], beginPathInstruction ); const ends = multiLineStringGeometry.getEnds(); const flatCoordinates = multiLineStringGeometry.getFlatCoordinates(); const stride = multiLineStringGeometry.getStride(); let offset = 0; for (let i = 0, ii = ends.length; i < ii; ++i) { offset = this.drawFlatCoordinates_( flatCoordinates, offset, /** @type {number} */ ends[i], stride ); } this.hitDetectionInstructions.push(strokeInstruction); this.endGeometry(feature); } /** * @return {import("../canvas.js").SerializableInstructions} the serializable instructions. * @override */ finish() { const state = this.state; if (state.lastStroke != void 0 && state.lastStroke != this.coordinates.length) { this.instructions.push(strokeInstruction); } this.reverseHitDetectionInstructions(); this.state = null; return super.finish(); } /** * @param {import("../canvas.js").FillStrokeState} state State. * @override */ applyStroke(state) { if (state.lastStroke != void 0 && state.lastStroke != this.coordinates.length) { this.instructions.push(strokeInstruction); state.lastStroke = this.coordinates.length; } state.lastStroke = 0; super.applyStroke(state); this.instructions.push(beginPathInstruction); } }; var LineStringBuilder_default = CanvasLineStringBuilder; // node_modules/ol/render/canvas/PolygonBuilder.js var CanvasPolygonBuilder = class extends Builder_default { /** * @param {number} tolerance Tolerance. * @param {import("../../extent.js").Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. */ constructor(tolerance, maxExtent, resolution, pixelRatio) { super(tolerance, maxExtent, resolution, pixelRatio); } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {Array} ends Ends. * @param {number} stride Stride. * @private * @return {number} End. */ drawFlatCoordinatess_(flatCoordinates, offset, ends, stride) { const state = this.state; const fill = state.fillStyle !== void 0; const stroke = state.strokeStyle !== void 0; const numEnds = ends.length; this.instructions.push(beginPathInstruction); this.hitDetectionInstructions.push(beginPathInstruction); for (let i = 0; i < numEnds; ++i) { const end = ends[i]; const myBegin = this.coordinates.length; const myEnd = this.appendFlatLineCoordinates( flatCoordinates, offset, end, stride, true, !stroke ); const moveToLineToInstruction = [ Instruction_default.MOVE_TO_LINE_TO, myBegin, myEnd ]; this.instructions.push(moveToLineToInstruction); this.hitDetectionInstructions.push(moveToLineToInstruction); if (stroke) { this.instructions.push(closePathInstruction); this.hitDetectionInstructions.push(closePathInstruction); } offset = end; } if (fill) { this.instructions.push(fillInstruction); this.hitDetectionInstructions.push(fillInstruction); } if (stroke) { this.instructions.push(strokeInstruction); this.hitDetectionInstructions.push(strokeInstruction); } return offset; } /** * @param {import("../../geom/Circle.js").default} circleGeometry Circle geometry. * @param {import("../../Feature.js").default} feature Feature. * @param {number} [index] Render order index. * @override */ drawCircle(circleGeometry, feature, index) { const state = this.state; const fillStyle = state.fillStyle; const strokeStyle = state.strokeStyle; if (fillStyle === void 0 && strokeStyle === void 0) { return; } this.setFillStrokeStyles_(); this.beginGeometry(circleGeometry, feature, index); if (state.fillStyle !== void 0) { this.hitDetectionInstructions.push([ Instruction_default.SET_FILL_STYLE, defaultFillStyle ]); } if (state.strokeStyle !== void 0) { this.hitDetectionInstructions.push([ Instruction_default.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, defaultLineDash, defaultLineDashOffset ]); } const flatCoordinates = circleGeometry.getFlatCoordinates(); const stride = circleGeometry.getStride(); const myBegin = this.coordinates.length; this.appendFlatLineCoordinates( flatCoordinates, 0, flatCoordinates.length, stride, false, false ); const circleInstruction = [Instruction_default.CIRCLE, myBegin]; this.instructions.push(beginPathInstruction, circleInstruction); this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction); if (state.fillStyle !== void 0) { this.instructions.push(fillInstruction); this.hitDetectionInstructions.push(fillInstruction); } if (state.strokeStyle !== void 0) { this.instructions.push(strokeInstruction); this.hitDetectionInstructions.push(strokeInstruction); } this.endGeometry(feature); } /** * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} polygonGeometry Polygon geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawPolygon(polygonGeometry, feature, index) { const state = this.state; const fillStyle = state.fillStyle; const strokeStyle = state.strokeStyle; if (fillStyle === void 0 && strokeStyle === void 0) { return; } this.setFillStrokeStyles_(); this.beginGeometry(polygonGeometry, feature, index); if (state.fillStyle !== void 0) { this.hitDetectionInstructions.push([ Instruction_default.SET_FILL_STYLE, defaultFillStyle ]); } if (state.strokeStyle !== void 0) { this.hitDetectionInstructions.push([ Instruction_default.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, defaultLineDash, defaultLineDashOffset ]); } const ends = polygonGeometry.getEnds(); const flatCoordinates = polygonGeometry.getOrientedFlatCoordinates(); const stride = polygonGeometry.getStride(); this.drawFlatCoordinatess_( flatCoordinates, 0, /** @type {Array} */ ends, stride ); this.endGeometry(feature); } /** * @param {import("../../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawMultiPolygon(multiPolygonGeometry, feature, index) { const state = this.state; const fillStyle = state.fillStyle; const strokeStyle = state.strokeStyle; if (fillStyle === void 0 && strokeStyle === void 0) { return; } this.setFillStrokeStyles_(); this.beginGeometry(multiPolygonGeometry, feature, index); if (state.fillStyle !== void 0) { this.hitDetectionInstructions.push([ Instruction_default.SET_FILL_STYLE, defaultFillStyle ]); } if (state.strokeStyle !== void 0) { this.hitDetectionInstructions.push([ Instruction_default.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, defaultLineDash, defaultLineDashOffset ]); } const endss = multiPolygonGeometry.getEndss(); const flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates(); const stride = multiPolygonGeometry.getStride(); let offset = 0; for (let i = 0, ii = endss.length; i < ii; ++i) { offset = this.drawFlatCoordinatess_( flatCoordinates, offset, endss[i], stride ); } this.endGeometry(feature); } /** * @return {import("../canvas.js").SerializableInstructions} the serializable instructions. * @override */ finish() { this.reverseHitDetectionInstructions(); this.state = null; const tolerance = this.tolerance; if (tolerance !== 0) { const coordinates = this.coordinates; for (let i = 0, ii = coordinates.length; i < ii; ++i) { coordinates[i] = snap(coordinates[i], tolerance); } } return super.finish(); } /** * @private */ setFillStrokeStyles_() { const state = this.state; this.updateFillStyle(state, this.createFill); this.updateStrokeStyle(state, this.applyStroke); } }; var PolygonBuilder_default = CanvasPolygonBuilder; // node_modules/ol/geom/flat/linechunk.js function lineChunk(chunkLength, flatCoordinates, offset, end, stride) { const chunks = []; let cursor = offset; let chunkM = 0; let currentChunk = flatCoordinates.slice(offset, 2); while (chunkM < chunkLength && cursor + stride < end) { const [x1, y1] = currentChunk.slice(-2); const x2 = flatCoordinates[cursor + stride]; const y2 = flatCoordinates[cursor + stride + 1]; const segmentLength = Math.sqrt( (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) ); chunkM += segmentLength; if (chunkM >= chunkLength) { const m = (chunkLength - chunkM + segmentLength) / segmentLength; const x = lerp(x1, x2, m); const y = lerp(y1, y2, m); currentChunk.push(x, y); chunks.push(currentChunk); currentChunk = [x, y]; if (chunkM == chunkLength) { cursor += stride; } chunkM = 0; } else if (chunkM < chunkLength) { currentChunk.push( flatCoordinates[cursor + stride], flatCoordinates[cursor + stride + 1] ); cursor += stride; } else { const missing = segmentLength - chunkM; const x = lerp(x1, x2, missing / segmentLength); const y = lerp(y1, y2, missing / segmentLength); currentChunk.push(x, y); chunks.push(currentChunk); currentChunk = [x, y]; chunkM = 0; cursor += stride; } } if (chunkM > 0) { chunks.push(currentChunk); } return chunks; } // node_modules/ol/geom/flat/straightchunk.js function matchingChunk(maxAngle, flatCoordinates, offset, end, stride) { let chunkStart = offset; let chunkEnd = offset; let chunkM = 0; let m = 0; let start = offset; let acos, i, m12, m23, x1, y1, x12, y12, x23, y23; for (i = offset; i < end; i += stride) { const x2 = flatCoordinates[i]; const y2 = flatCoordinates[i + 1]; if (x1 !== void 0) { x23 = x2 - x1; y23 = y2 - y1; m23 = Math.sqrt(x23 * x23 + y23 * y23); if (x12 !== void 0) { m += m12; acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23)); if (acos > maxAngle) { if (m > chunkM) { chunkM = m; chunkStart = start; chunkEnd = i; } m = 0; start = i - stride; } } m12 = m23; x12 = x23; y12 = y23; } x1 = x2; y1 = y2; } m += m23; return m > chunkM ? [start, i] : [chunkStart, chunkEnd]; } // node_modules/ol/render/canvas/TextBuilder.js var TEXT_ALIGN = { "left": 0, "center": 0.5, "right": 1, "top": 0, "middle": 0.5, "hanging": 0.2, "alphabetic": 0.8, "ideographic": 0.8, "bottom": 1 }; var CanvasTextBuilder = class extends Builder_default { /** * @param {number} tolerance Tolerance. * @param {import("../../extent.js").Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. */ constructor(tolerance, maxExtent, resolution, pixelRatio) { super(tolerance, maxExtent, resolution, pixelRatio); this.labels_ = null; this.text_ = ""; this.textOffsetX_ = 0; this.textOffsetY_ = 0; this.textRotateWithView_ = void 0; this.textKeepUpright_ = void 0; this.textRotation_ = 0; this.textFillState_ = null; this.fillStates = {}; this.fillStates[defaultFillStyle] = { fillStyle: defaultFillStyle }; this.textStrokeState_ = null; this.strokeStates = {}; this.textState_ = /** @type {import("../canvas.js").TextState} */ {}; this.textStates = {}; this.textKey_ = ""; this.fillKey_ = ""; this.strokeKey_ = ""; this.declutterMode_ = void 0; this.declutterImageWithText_ = void 0; } /** * @return {import("../canvas.js").SerializableInstructions} the serializable instructions. * @override */ finish() { const instructions = super.finish(); instructions.textStates = this.textStates; instructions.fillStates = this.fillStates; instructions.strokeStates = this.strokeStates; return instructions; } /** * @param {import("../../geom/SimpleGeometry.js").default|import("../Feature.js").default} geometry Geometry. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @param {number} [index] Render order index. * @override */ drawText(geometry, feature, index) { const fillState = this.textFillState_; const strokeState = this.textStrokeState_; const textState = this.textState_; if (this.text_ === "" || !textState || !fillState && !strokeState) { return; } const coordinates = this.coordinates; let begin = coordinates.length; const geometryType = geometry.getType(); let flatCoordinates = null; let stride = geometry.getStride(); if (textState.placement === "line" && (geometryType == "LineString" || geometryType == "MultiLineString" || geometryType == "Polygon" || geometryType == "MultiPolygon")) { if (!intersects(this.maxExtent, geometry.getExtent())) { return; } let ends; flatCoordinates = geometry.getFlatCoordinates(); if (geometryType == "LineString") { ends = [flatCoordinates.length]; } else if (geometryType == "MultiLineString") { ends = /** @type {import("../../geom/MultiLineString.js").default} */ geometry.getEnds(); } else if (geometryType == "Polygon") { ends = /** @type {import("../../geom/Polygon.js").default} */ geometry.getEnds().slice(0, 1); } else if (geometryType == "MultiPolygon") { const endss = ( /** @type {import("../../geom/MultiPolygon.js").default} */ geometry.getEndss() ); ends = []; for (let i = 0, ii = endss.length; i < ii; ++i) { ends.push(endss[i][0]); } } this.beginGeometry(geometry, feature, index); const repeat = textState.repeat; const textAlign = repeat ? void 0 : textState.textAlign; let flatOffset = 0; for (let o = 0, oo = ends.length; o < oo; ++o) { let chunks; if (repeat) { chunks = lineChunk( repeat * this.resolution, flatCoordinates, flatOffset, ends[o], stride ); } else { chunks = [flatCoordinates.slice(flatOffset, ends[o])]; } for (let c = 0, cc = chunks.length; c < cc; ++c) { const chunk = chunks[c]; let chunkBegin = 0; let chunkEnd = chunk.length; if (textAlign == void 0) { const range = matchingChunk( textState.maxAngle, chunk, 0, chunk.length, 2 ); chunkBegin = range[0]; chunkEnd = range[1]; } for (let i = chunkBegin; i < chunkEnd; i += stride) { coordinates.push(chunk[i], chunk[i + 1]); } const end = coordinates.length; flatOffset = ends[o]; this.drawChars_(begin, end); begin = end; } } this.endGeometry(feature); } else { let geometryWidths = textState.overflow ? null : []; switch (geometryType) { case "Point": case "MultiPoint": flatCoordinates = /** @type {import("../../geom/MultiPoint.js").default} */ geometry.getFlatCoordinates(); break; case "LineString": flatCoordinates = /** @type {import("../../geom/LineString.js").default} */ geometry.getFlatMidpoint(); break; case "Circle": flatCoordinates = /** @type {import("../../geom/Circle.js").default} */ geometry.getCenter(); break; case "MultiLineString": flatCoordinates = /** @type {import("../../geom/MultiLineString.js").default} */ geometry.getFlatMidpoints(); stride = 2; break; case "Polygon": flatCoordinates = /** @type {import("../../geom/Polygon.js").default} */ geometry.getFlatInteriorPoint(); if (!textState.overflow) { geometryWidths.push(flatCoordinates[2] / this.resolution); } stride = 3; break; case "MultiPolygon": const interiorPoints = ( /** @type {import("../../geom/MultiPolygon.js").default} */ geometry.getFlatInteriorPoints() ); flatCoordinates = []; for (let i = 0, ii = interiorPoints.length; i < ii; i += 3) { if (!textState.overflow) { geometryWidths.push(interiorPoints[i + 2] / this.resolution); } flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]); } if (flatCoordinates.length === 0) { return; } stride = 2; break; default: } const end = this.appendFlatPointCoordinates(flatCoordinates, stride); if (end === begin) { return; } if (geometryWidths && (end - begin) / 2 !== flatCoordinates.length / stride) { let beg = begin / 2; geometryWidths = geometryWidths.filter((w, i) => { const keep = coordinates[(beg + i) * 2] === flatCoordinates[i * stride] && coordinates[(beg + i) * 2 + 1] === flatCoordinates[i * stride + 1]; if (!keep) { --beg; } return keep; }); } this.saveTextStates_(); const backgroundFill = textState.backgroundFill ? this.createFill(this.fillStyleToState(textState.backgroundFill)) : null; const backgroundStroke = textState.backgroundStroke ? this.createStroke(this.strokeStyleToState(textState.backgroundStroke)) : null; this.beginGeometry(geometry, feature, index); let padding = textState.padding; if (padding != defaultPadding && (textState.scale[0] < 0 || textState.scale[1] < 0)) { let p0 = textState.padding[0]; let p12 = textState.padding[1]; let p22 = textState.padding[2]; let p32 = textState.padding[3]; if (textState.scale[0] < 0) { p12 = -p12; p32 = -p32; } if (textState.scale[1] < 0) { p0 = -p0; p22 = -p22; } padding = [p0, p12, p22, p32]; } const pixelRatio = this.pixelRatio; this.instructions.push([ Instruction_default.DRAW_IMAGE, begin, end, null, NaN, NaN, NaN, 1, 0, 0, this.textRotateWithView_, this.textRotation_, [1, 1], NaN, this.declutterMode_, this.declutterImageWithText_, padding == defaultPadding ? defaultPadding : padding.map(function(p) { return p * pixelRatio; }), backgroundFill, backgroundStroke, this.text_, this.textKey_, this.strokeKey_, this.fillKey_, this.textOffsetX_, this.textOffsetY_, geometryWidths ]); const scale = 1 / pixelRatio; const hitDetectionBackgroundFill = backgroundFill ? backgroundFill.slice(0) : null; if (hitDetectionBackgroundFill) { hitDetectionBackgroundFill[1] = defaultFillStyle; } this.hitDetectionInstructions.push([ Instruction_default.DRAW_IMAGE, begin, end, null, NaN, NaN, NaN, 1, 0, 0, this.textRotateWithView_, this.textRotation_, [scale, scale], NaN, this.declutterMode_, this.declutterImageWithText_, padding, hitDetectionBackgroundFill, backgroundStroke, this.text_, this.textKey_, this.strokeKey_, this.fillKey_ ? defaultFillStyle : this.fillKey_, this.textOffsetX_, this.textOffsetY_, geometryWidths ]); this.endGeometry(feature); } } /** * @private */ saveTextStates_() { const strokeState = this.textStrokeState_; const textState = this.textState_; const fillState = this.textFillState_; const strokeKey = this.strokeKey_; if (strokeState) { if (!(strokeKey in this.strokeStates)) { this.strokeStates[strokeKey] = { strokeStyle: strokeState.strokeStyle, lineCap: strokeState.lineCap, lineDashOffset: strokeState.lineDashOffset, lineWidth: strokeState.lineWidth, lineJoin: strokeState.lineJoin, miterLimit: strokeState.miterLimit, lineDash: strokeState.lineDash }; } } const textKey = this.textKey_; if (!(textKey in this.textStates)) { this.textStates[textKey] = { font: textState.font, textAlign: textState.textAlign || defaultTextAlign, justify: textState.justify, textBaseline: textState.textBaseline || defaultTextBaseline, scale: textState.scale }; } const fillKey = this.fillKey_; if (fillState) { if (!(fillKey in this.fillStates)) { this.fillStates[fillKey] = { fillStyle: fillState.fillStyle }; } } } /** * @private * @param {number} begin Begin. * @param {number} end End. */ drawChars_(begin, end) { const strokeState = this.textStrokeState_; const textState = this.textState_; const strokeKey = this.strokeKey_; const textKey = this.textKey_; const fillKey = this.fillKey_; this.saveTextStates_(); const pixelRatio = this.pixelRatio; const baseline = TEXT_ALIGN[textState.textBaseline]; const offsetY = this.textOffsetY_ * pixelRatio; const text = this.text_; const strokeWidth = strokeState ? strokeState.lineWidth * Math.abs(textState.scale[0]) / 2 : 0; this.instructions.push([ Instruction_default.DRAW_CHARS, begin, end, baseline, textState.overflow, fillKey, textState.maxAngle, pixelRatio, offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1, this.declutterMode_, this.textKeepUpright_ ]); this.hitDetectionInstructions.push([ Instruction_default.DRAW_CHARS, begin, end, baseline, textState.overflow, fillKey ? defaultFillStyle : fillKey, textState.maxAngle, pixelRatio, offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1 / pixelRatio, this.declutterMode_, this.textKeepUpright_ ]); } /** * @param {import("../../style/Text.js").default} textStyle Text style. * @param {Object} [sharedData] Shared data. * @override */ setTextStyle(textStyle, sharedData) { let textState, fillState, strokeState; if (!textStyle) { this.text_ = ""; } else { const textFillStyle = textStyle.getFill(); if (!textFillStyle) { fillState = null; this.textFillState_ = fillState; } else { fillState = this.textFillState_; if (!fillState) { fillState = /** @type {import("../canvas.js").FillState} */ {}; this.textFillState_ = fillState; } fillState.fillStyle = asColorLike( textFillStyle.getColor() || defaultFillStyle ); } const textStrokeStyle = textStyle.getStroke(); if (!textStrokeStyle) { strokeState = null; this.textStrokeState_ = strokeState; } else { strokeState = this.textStrokeState_; if (!strokeState) { strokeState = /** @type {import("../canvas.js").StrokeState} */ {}; this.textStrokeState_ = strokeState; } const lineDash = textStrokeStyle.getLineDash(); const lineDashOffset = textStrokeStyle.getLineDashOffset(); const lineWidth = textStrokeStyle.getWidth(); const miterLimit = textStrokeStyle.getMiterLimit(); strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap; strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash; strokeState.lineDashOffset = lineDashOffset === void 0 ? defaultLineDashOffset : lineDashOffset; strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin; strokeState.lineWidth = lineWidth === void 0 ? defaultLineWidth : lineWidth; strokeState.miterLimit = miterLimit === void 0 ? defaultMiterLimit : miterLimit; strokeState.strokeStyle = asColorLike( textStrokeStyle.getColor() || defaultStrokeStyle ); } textState = this.textState_; const font = textStyle.getFont() || defaultFont; registerFont(font); const textScale = textStyle.getScaleArray(); textState.overflow = textStyle.getOverflow(); textState.font = font; textState.maxAngle = textStyle.getMaxAngle(); textState.placement = textStyle.getPlacement(); textState.textAlign = textStyle.getTextAlign(); textState.repeat = textStyle.getRepeat(); textState.justify = textStyle.getJustify(); textState.textBaseline = textStyle.getTextBaseline() || defaultTextBaseline; textState.backgroundFill = textStyle.getBackgroundFill(); textState.backgroundStroke = textStyle.getBackgroundStroke(); textState.padding = textStyle.getPadding() || defaultPadding; textState.scale = textScale === void 0 ? [1, 1] : textScale; const textOffsetX = textStyle.getOffsetX(); const textOffsetY = textStyle.getOffsetY(); const textRotateWithView = textStyle.getRotateWithView(); const textKeepUpright = textStyle.getKeepUpright(); const textRotation = textStyle.getRotation(); this.text_ = textStyle.getText() || ""; this.textOffsetX_ = textOffsetX === void 0 ? 0 : textOffsetX; this.textOffsetY_ = textOffsetY === void 0 ? 0 : textOffsetY; this.textRotateWithView_ = textRotateWithView === void 0 ? false : textRotateWithView; this.textKeepUpright_ = textKeepUpright === void 0 ? true : textKeepUpright; this.textRotation_ = textRotation === void 0 ? 0 : textRotation; this.strokeKey_ = strokeState ? (typeof strokeState.strokeStyle == "string" ? strokeState.strokeStyle : getUid(strokeState.strokeStyle)) + strokeState.lineCap + strokeState.lineDashOffset + "|" + strokeState.lineWidth + strokeState.lineJoin + strokeState.miterLimit + "[" + strokeState.lineDash.join() + "]" : ""; this.textKey_ = textState.font + textState.scale + (textState.textAlign || "?") + (textState.repeat || "?") + (textState.justify || "?") + (textState.textBaseline || "?"); this.fillKey_ = fillState && fillState.fillStyle ? typeof fillState.fillStyle == "string" ? fillState.fillStyle : "|" + getUid(fillState.fillStyle) : ""; } this.declutterMode_ = textStyle.getDeclutterMode(); this.declutterImageWithText_ = sharedData; } }; var TextBuilder_default = CanvasTextBuilder; // node_modules/ol/render/canvas/BuilderGroup.js var BATCH_CONSTRUCTORS = { "Circle": PolygonBuilder_default, "Default": Builder_default, "Image": ImageBuilder_default, "LineString": LineStringBuilder_default, "Polygon": PolygonBuilder_default, "Text": TextBuilder_default }; var BuilderGroup = class { /** * @param {number} tolerance Tolerance. * @param {import("../../extent.js").Extent} maxExtent Max extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. */ constructor(tolerance, maxExtent, resolution, pixelRatio) { this.tolerance_ = tolerance; this.maxExtent_ = maxExtent; this.pixelRatio_ = pixelRatio; this.resolution_ = resolution; this.buildersByZIndex_ = {}; } /** * @return {!Object>} The serializable instructions */ finish() { const builderInstructions = {}; for (const zKey in this.buildersByZIndex_) { builderInstructions[zKey] = builderInstructions[zKey] || {}; const builders = this.buildersByZIndex_[zKey]; for (const builderKey in builders) { const builderInstruction = builders[builderKey].finish(); builderInstructions[zKey][builderKey] = builderInstruction; } } return builderInstructions; } /** * @param {number|undefined} zIndex Z index. * @param {import("../canvas.js").BuilderType} builderType Replay type. * @return {import("../VectorContext.js").default} Replay. */ getBuilder(zIndex, builderType) { const zIndexKey = zIndex !== void 0 ? zIndex.toString() : "0"; let replays = this.buildersByZIndex_[zIndexKey]; if (replays === void 0) { replays = {}; this.buildersByZIndex_[zIndexKey] = replays; } let replay = replays[builderType]; if (replay === void 0) { const Constructor = BATCH_CONSTRUCTORS[builderType]; replay = new Constructor( this.tolerance_, this.maxExtent_, this.resolution_, this.pixelRatio_ ); replays[builderType] = replay; } return replay; } }; var BuilderGroup_default = BuilderGroup; // node_modules/ol/geom/flat/textpath.js function drawTextOnPath(flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth2, font, cache, rotation, keepUpright = true) { let x2 = flatCoordinates[offset]; let y2 = flatCoordinates[offset + 1]; let x1 = 0; let y1 = 0; let segmentLength = 0; let segmentM = 0; function advance() { x1 = x2; y1 = y2; offset += stride; x2 = flatCoordinates[offset]; y2 = flatCoordinates[offset + 1]; segmentM += segmentLength; segmentLength = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); } do { advance(); } while (offset < end - stride && segmentM + segmentLength < startM); let interpolate = segmentLength === 0 ? 0 : (startM - segmentM) / segmentLength; const beginX = lerp(x1, x2, interpolate); const beginY = lerp(y1, y2, interpolate); const startOffset = offset - stride; const startLength = segmentM; const endM = startM + scale * measureAndCacheTextWidth2(font, text, cache); while (offset < end - stride && segmentM + segmentLength < endM) { advance(); } interpolate = segmentLength === 0 ? 0 : (endM - segmentM) / segmentLength; const endX = lerp(x1, x2, interpolate); const endY = lerp(y1, y2, interpolate); let reverse = false; if (keepUpright) { if (rotation) { const flat = [beginX, beginY, endX, endY]; rotate(flat, 0, 4, 2, rotation, flat, flat); reverse = flat[0] > flat[2]; } else { reverse = beginX > endX; } } const PI = Math.PI; const result = []; const singleSegment = startOffset + stride === offset; offset = startOffset; segmentLength = 0; segmentM = startLength; x2 = flatCoordinates[offset]; y2 = flatCoordinates[offset + 1]; let previousAngle; if (singleSegment) { advance(); previousAngle = Math.atan2(y2 - y1, x2 - x1); if (reverse) { previousAngle += previousAngle > 0 ? -PI : PI; } const x = (endX + beginX) / 2; const y = (endY + beginY) / 2; result[0] = [x, y, (endM - startM) / 2, previousAngle, text]; return result; } text = text.replace(/\n/g, " "); for (let i = 0, ii = text.length; i < ii; ) { advance(); let angle = Math.atan2(y2 - y1, x2 - x1); if (reverse) { angle += angle > 0 ? -PI : PI; } if (previousAngle !== void 0) { let delta = angle - previousAngle; delta += delta > PI ? -2 * PI : delta < -PI ? 2 * PI : 0; if (Math.abs(delta) > maxAngle) { return null; } } previousAngle = angle; const iStart = i; let charLength = 0; for (; i < ii; ++i) { const index = reverse ? ii - i - 1 : i; const len = scale * measureAndCacheTextWidth2(font, text[index], cache); if (offset + stride < end && segmentM + segmentLength < startM + charLength + len / 2) { break; } charLength += len; } if (i === iStart) { continue; } const chars = reverse ? text.substring(ii - iStart, ii - i) : text.substring(iStart, i); interpolate = segmentLength === 0 ? 0 : (startM + charLength / 2 - segmentM) / segmentLength; const x = lerp(x1, x2, interpolate); const y = lerp(y1, y2, interpolate); result.push([x, y, charLength / 2, angle, chars]); startM += charLength; } return result; } // node_modules/ol/render/canvas/Executor.js var tmpExtent = createEmpty(); var p1 = []; var p2 = []; var p3 = []; var p4 = []; function getDeclutterBox(replayImageOrLabelArgs) { return replayImageOrLabelArgs[3].declutterBox; } var rtlRegEx = new RegExp( /* eslint-disable prettier/prettier */ "[" + String.fromCharCode(1425) + "-" + String.fromCharCode(2303) + String.fromCharCode(64285) + "-" + String.fromCharCode(65023) + String.fromCharCode(65136) + "-" + String.fromCharCode(65276) + String.fromCharCode(67584) + "-" + String.fromCharCode(69631) + String.fromCharCode(124928) + "-" + String.fromCharCode(126975) + "]" /* eslint-enable prettier/prettier */ ); function horizontalTextAlign(text, align) { if (align === "start") { align = rtlRegEx.test(text) ? "right" : "left"; } else if (align === "end") { align = rtlRegEx.test(text) ? "left" : "right"; } return TEXT_ALIGN[align]; } function createTextChunks(acc, line, i) { if (i > 0) { acc.push("\n", ""); } acc.push(line, ""); return acc; } function richTextToPlainText(result, part, index) { if (index % 2 === 0) { result += part; } return result; } var Executor = class { /** * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @param {import("../canvas.js").SerializableInstructions} instructions The serializable instructions. * @param {boolean} [deferredRendering] Enable deferred rendering. */ constructor(resolution, pixelRatio, overlaps, instructions, deferredRendering) { this.overlaps = overlaps; this.pixelRatio = pixelRatio; this.resolution = resolution; this.alignAndScaleFill_; this.instructions = instructions.instructions; this.coordinates = instructions.coordinates; this.coordinateCache_ = {}; this.renderedTransform_ = create(); this.hitDetectionInstructions = instructions.hitDetectionInstructions; this.pixelCoordinates_ = null; this.viewRotation_ = 0; this.fillStates = instructions.fillStates || {}; this.strokeStates = instructions.strokeStates || {}; this.textStates = instructions.textStates || {}; this.widths_ = {}; this.labels_ = {}; this.zIndexContext_ = deferredRendering ? new ZIndexContext_default() : null; } /** * @return {ZIndexContext} ZIndex context. */ getZIndexContext() { return this.zIndexContext_; } /** * @param {string|Array} text Text. * @param {string} textKey Text style key. * @param {string} fillKey Fill style key. * @param {string} strokeKey Stroke style key. * @return {import("../canvas.js").Label} Label. */ createLabel(text, textKey, fillKey, strokeKey) { const key = text + textKey + fillKey + strokeKey; if (this.labels_[key]) { return this.labels_[key]; } const strokeState = strokeKey ? this.strokeStates[strokeKey] : null; const fillState = fillKey ? this.fillStates[fillKey] : null; const textState = this.textStates[textKey]; const pixelRatio = this.pixelRatio; const scale = [ textState.scale[0] * pixelRatio, textState.scale[1] * pixelRatio ]; const align = textState.justify ? TEXT_ALIGN[textState.justify] : horizontalTextAlign( Array.isArray(text) ? text[0] : text, textState.textAlign || defaultTextAlign ); const strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0; const chunks = Array.isArray(text) ? text : String(text).split("\n").reduce(createTextChunks, []); const { width, height, widths, heights, lineWidths } = getTextDimensions( textState, chunks ); const renderWidth = width + strokeWidth; const contextInstructions = []; const w = (renderWidth + 2) * scale[0]; const h = (height + strokeWidth) * scale[1]; const label = { width: w < 0 ? Math.floor(w) : Math.ceil(w), height: h < 0 ? Math.floor(h) : Math.ceil(h), contextInstructions }; if (scale[0] != 1 || scale[1] != 1) { contextInstructions.push("scale", scale); } if (strokeKey) { contextInstructions.push("strokeStyle", strokeState.strokeStyle); contextInstructions.push("lineWidth", strokeWidth); contextInstructions.push("lineCap", strokeState.lineCap); contextInstructions.push("lineJoin", strokeState.lineJoin); contextInstructions.push("miterLimit", strokeState.miterLimit); contextInstructions.push("setLineDash", [strokeState.lineDash]); contextInstructions.push("lineDashOffset", strokeState.lineDashOffset); } if (fillKey) { contextInstructions.push("fillStyle", fillState.fillStyle); } contextInstructions.push("textBaseline", "middle"); contextInstructions.push("textAlign", "center"); const leftRight = 0.5 - align; let x = align * renderWidth + leftRight * strokeWidth; const strokeInstructions = []; const fillInstructions = []; let lineHeight = 0; let lineOffset = 0; let widthHeightIndex = 0; let lineWidthIndex = 0; let previousFont; for (let i = 0, ii = chunks.length; i < ii; i += 2) { const text2 = chunks[i]; if (text2 === "\n") { lineOffset += lineHeight; lineHeight = 0; x = align * renderWidth + leftRight * strokeWidth; ++lineWidthIndex; continue; } const font = chunks[i + 1] || textState.font; if (font !== previousFont) { if (strokeKey) { strokeInstructions.push("font", font); } if (fillKey) { fillInstructions.push("font", font); } previousFont = font; } lineHeight = Math.max(lineHeight, heights[widthHeightIndex]); const fillStrokeArgs = [ text2, x + leftRight * widths[widthHeightIndex] + align * (widths[widthHeightIndex] - lineWidths[lineWidthIndex]), 0.5 * (strokeWidth + lineHeight) + lineOffset ]; x += widths[widthHeightIndex]; if (strokeKey) { strokeInstructions.push("strokeText", fillStrokeArgs); } if (fillKey) { fillInstructions.push("fillText", fillStrokeArgs); } ++widthHeightIndex; } Array.prototype.push.apply(contextInstructions, strokeInstructions); Array.prototype.push.apply(contextInstructions, fillInstructions); this.labels_[key] = label; return label; } /** * @param {CanvasRenderingContext2D} context Context. * @param {import("../../coordinate.js").Coordinate} p1 1st point of the background box. * @param {import("../../coordinate.js").Coordinate} p2 2nd point of the background box. * @param {import("../../coordinate.js").Coordinate} p3 3rd point of the background box. * @param {import("../../coordinate.js").Coordinate} p4 4th point of the background box. * @param {Array<*>} fillInstruction Fill instruction. * @param {Array<*>} strokeInstruction Stroke instruction. */ replayTextBackground_(context, p12, p22, p32, p42, fillInstruction2, strokeInstruction2) { context.beginPath(); context.moveTo.apply(context, p12); context.lineTo.apply(context, p22); context.lineTo.apply(context, p32); context.lineTo.apply(context, p42); context.lineTo.apply(context, p12); if (fillInstruction2) { this.alignAndScaleFill_ = /** @type {number} */ fillInstruction2[2]; context.fillStyle = /** @type {string} */ fillInstruction2[1]; this.fill_(context); } if (strokeInstruction2) { this.setStrokeStyle_( context, /** @type {Array<*>} */ strokeInstruction2 ); context.stroke(); } } /** * @private * @param {number} sheetWidth Width of the sprite sheet. * @param {number} sheetHeight Height of the sprite sheet. * @param {number} centerX X. * @param {number} centerY Y. * @param {number} width Width. * @param {number} height Height. * @param {number} anchorX Anchor X. * @param {number} anchorY Anchor Y. * @param {number} originX Origin X. * @param {number} originY Origin Y. * @param {number} rotation Rotation. * @param {import("../../size.js").Size} scale Scale. * @param {boolean} snapToPixel Snap to pixel. * @param {Array} padding Padding. * @param {boolean} fillStroke Background fill or stroke. * @param {import("../../Feature.js").FeatureLike} feature Feature. * @return {ImageOrLabelDimensions} Dimensions for positioning and decluttering the image or label. */ calculateImageOrLabelDimensions_(sheetWidth, sheetHeight, centerX, centerY, width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, fillStroke, feature) { anchorX *= scale[0]; anchorY *= scale[1]; let x = centerX - anchorX; let y = centerY - anchorY; const w = width + originX > sheetWidth ? sheetWidth - originX : width; const h = height + originY > sheetHeight ? sheetHeight - originY : height; const boxW = padding[3] + w * scale[0] + padding[1]; const boxH = padding[0] + h * scale[1] + padding[2]; const boxX = x - padding[3]; const boxY = y - padding[0]; if (fillStroke || rotation !== 0) { p1[0] = boxX; p4[0] = boxX; p1[1] = boxY; p2[1] = boxY; p2[0] = boxX + boxW; p3[0] = p2[0]; p3[1] = boxY + boxH; p4[1] = p3[1]; } let transform; if (rotation !== 0) { transform = compose( create(), centerX, centerY, 1, 1, rotation, -centerX, -centerY ); apply(transform, p1); apply(transform, p2); apply(transform, p3); apply(transform, p4); createOrUpdate( Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1]), tmpExtent ); } else { createOrUpdate( Math.min(boxX, boxX + boxW), Math.min(boxY, boxY + boxH), Math.max(boxX, boxX + boxW), Math.max(boxY, boxY + boxH), tmpExtent ); } if (snapToPixel) { x = Math.round(x); y = Math.round(y); } return { drawImageX: x, drawImageY: y, drawImageW: w, drawImageH: h, originX, originY, declutterBox: { minX: tmpExtent[0], minY: tmpExtent[1], maxX: tmpExtent[2], maxY: tmpExtent[3], value: feature }, canvasTransform: transform, scale }; } /** * @private * @param {CanvasRenderingContext2D} context Context. * @param {import('../../size.js').Size} scaledCanvasSize Scaled canvas size. * @param {import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image. * @param {ImageOrLabelDimensions} dimensions Dimensions. * @param {number} opacity Opacity. * @param {Array<*>} fillInstruction Fill instruction. * @param {Array<*>} strokeInstruction Stroke instruction. * @return {boolean} The image or label was rendered. */ replayImageOrLabel_(context, scaledCanvasSize, imageOrLabel, dimensions, opacity, fillInstruction2, strokeInstruction2) { const fillStroke = !!(fillInstruction2 || strokeInstruction2); const box = dimensions.declutterBox; const strokePadding = strokeInstruction2 ? strokeInstruction2[2] * dimensions.scale[0] / 2 : 0; const intersects2 = box.minX - strokePadding <= scaledCanvasSize[0] && box.maxX + strokePadding >= 0 && box.minY - strokePadding <= scaledCanvasSize[1] && box.maxY + strokePadding >= 0; if (intersects2) { if (fillStroke) { this.replayTextBackground_( context, p1, p2, p3, p4, /** @type {Array<*>} */ fillInstruction2, /** @type {Array<*>} */ strokeInstruction2 ); } drawImageOrLabel( context, dimensions.canvasTransform, opacity, imageOrLabel, dimensions.originX, dimensions.originY, dimensions.drawImageW, dimensions.drawImageH, dimensions.drawImageX, dimensions.drawImageY, dimensions.scale ); } return true; } /** * @private * @param {CanvasRenderingContext2D} context Context. */ fill_(context) { const alignAndScale = this.alignAndScaleFill_; if (alignAndScale) { const origin = apply(this.renderedTransform_, [0, 0]); const repeatSize = 512 * this.pixelRatio; context.save(); context.translate(origin[0] % repeatSize, origin[1] % repeatSize); if (alignAndScale !== 1) { context.scale(alignAndScale, alignAndScale); } context.rotate(this.viewRotation_); } context.fill(); if (alignAndScale) { context.restore(); } } /** * @private * @param {CanvasRenderingContext2D} context Context. * @param {Array<*>} instruction Instruction. */ setStrokeStyle_(context, instruction) { context.strokeStyle = /** @type {import("../../colorlike.js").ColorLike} */ instruction[1]; if (!instruction[1]) { return; } context.lineWidth = /** @type {number} */ instruction[2]; context.lineCap = /** @type {CanvasLineCap} */ instruction[3]; context.lineJoin = /** @type {CanvasLineJoin} */ instruction[4]; context.miterLimit = /** @type {number} */ instruction[5]; context.lineDashOffset = /** @type {number} */ instruction[7]; context.setLineDash( /** @type {Array} */ instruction[6] ); } /** * @private * @param {string|Array} text The text to draw. * @param {string} textKey The key of the text state. * @param {string} strokeKey The key for the stroke state. * @param {string} fillKey The key for the fill state. * @return {{label: import("../canvas.js").Label, anchorX: number, anchorY: number}} The text image and its anchor. */ drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey) { const textState = this.textStates[textKey]; const label = this.createLabel(text, textKey, fillKey, strokeKey); const strokeState = this.strokeStates[strokeKey]; const pixelRatio = this.pixelRatio; const align = horizontalTextAlign( Array.isArray(text) ? text[0] : text, textState.textAlign || defaultTextAlign ); const baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline]; const strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0; const width = label.width / pixelRatio - 2 * textState.scale[0]; const anchorX = align * width + 2 * (0.5 - align) * strokeWidth; const anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth; return { label, anchorX, anchorY }; } /** * @private * @param {CanvasRenderingContext2D} context Context. * @param {import('../../size.js').Size} scaledCanvasSize Scaled canvas size * @param {import("../../transform.js").Transform} transform Transform. * @param {Array<*>} instructions Instructions array. * @param {boolean} snapToPixel Snap point symbols and text to integer pixels. * @param {FeatureCallback} [featureCallback] Feature callback. * @param {import("../../extent.js").Extent} [hitExtent] Only check * features that intersect this extent. * @param {import("rbush").default} [declutterTree] Declutter tree. * @return {T|undefined} Callback result. * @template T */ execute_(context, scaledCanvasSize, transform, instructions, snapToPixel, featureCallback, hitExtent, declutterTree) { const zIndexContext = this.zIndexContext_; let pixelCoordinates; if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) { pixelCoordinates = this.pixelCoordinates_; } else { if (!this.pixelCoordinates_) { this.pixelCoordinates_ = []; } pixelCoordinates = transform2D( this.coordinates, 0, this.coordinates.length, 2, transform, this.pixelCoordinates_ ); setFromArray(this.renderedTransform_, transform); } let i = 0; const ii = instructions.length; let d = 0; let dd; let anchorX, anchorY, declutterMode, prevX, prevY, roundX, roundY, image, text, textKey, strokeKey, fillKey; let pendingFill = 0; let pendingStroke = 0; const coordinateCache = this.coordinateCache_; const viewRotation = this.viewRotation_; const viewRotationFromTransform = Math.round(Math.atan2(-transform[1], transform[0]) * 1e12) / 1e12; const state = ( /** @type {import("../../render.js").State} */ { context, pixelRatio: this.pixelRatio, resolution: this.resolution, rotation: viewRotation } ); const batchSize = this.instructions != instructions || this.overlaps ? 0 : 200; let feature; let x, y, currentGeometry; while (i < ii) { const instruction = instructions[i]; const type = ( /** @type {import("./Instruction.js").default} */ instruction[0] ); switch (type) { case Instruction_default.BEGIN_GEOMETRY: feature = /** @type {import("../../Feature.js").FeatureLike} */ instruction[1]; currentGeometry = instruction[3]; if (!feature.getGeometry()) { i = /** @type {number} */ instruction[2]; } else if (hitExtent !== void 0 && !intersects(hitExtent, currentGeometry.getExtent())) { i = /** @type {number} */ instruction[2] + 1; } else { ++i; } if (zIndexContext) { zIndexContext.zIndex = instruction[4]; } break; case Instruction_default.BEGIN_PATH: if (pendingFill > batchSize) { this.fill_(context); pendingFill = 0; } if (pendingStroke > batchSize) { context.stroke(); pendingStroke = 0; } if (!pendingFill && !pendingStroke) { context.beginPath(); prevX = NaN; prevY = NaN; } ++i; break; case Instruction_default.CIRCLE: d = /** @type {number} */ instruction[1]; const x1 = pixelCoordinates[d]; const y1 = pixelCoordinates[d + 1]; const x2 = pixelCoordinates[d + 2]; const y2 = pixelCoordinates[d + 3]; const dx = x2 - x1; const dy = y2 - y1; const r = Math.sqrt(dx * dx + dy * dy); context.moveTo(x1 + r, y1); context.arc(x1, y1, r, 0, 2 * Math.PI, true); ++i; break; case Instruction_default.CLOSE_PATH: context.closePath(); ++i; break; case Instruction_default.CUSTOM: d = /** @type {number} */ instruction[1]; dd = instruction[2]; const geometry = ( /** @type {import("../../geom/SimpleGeometry.js").default} */ instruction[3] ); const renderer = instruction[4]; const fn = instruction[5]; state.geometry = geometry; state.feature = feature; if (!(i in coordinateCache)) { coordinateCache[i] = []; } const coords = coordinateCache[i]; if (fn) { fn(pixelCoordinates, d, dd, 2, coords); } else { coords[0] = pixelCoordinates[d]; coords[1] = pixelCoordinates[d + 1]; coords.length = 2; } if (zIndexContext) { zIndexContext.zIndex = instruction[6]; } renderer(coords, state); ++i; break; case Instruction_default.DRAW_IMAGE: d = /** @type {number} */ instruction[1]; dd = /** @type {number} */ instruction[2]; image = /** @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} */ instruction[3]; anchorX = /** @type {number} */ instruction[4]; anchorY = /** @type {number} */ instruction[5]; let height = ( /** @type {number} */ instruction[6] ); const opacity = ( /** @type {number} */ instruction[7] ); const originX = ( /** @type {number} */ instruction[8] ); const originY = ( /** @type {number} */ instruction[9] ); const rotateWithView = ( /** @type {boolean} */ instruction[10] ); let rotation = ( /** @type {number} */ instruction[11] ); const scale = ( /** @type {import("../../size.js").Size} */ instruction[12] ); let width = ( /** @type {number} */ instruction[13] ); declutterMode = instruction[14] || "declutter"; const declutterImageWithText = ( /** @type {{args: import("../canvas.js").DeclutterImageWithText, declutterMode: import('../../style/Style.js').DeclutterMode}} */ instruction[15] ); if (!image && instruction.length >= 20) { text = /** @type {string} */ instruction[19]; textKey = /** @type {string} */ instruction[20]; strokeKey = /** @type {string} */ instruction[21]; fillKey = /** @type {string} */ instruction[22]; const labelWithAnchor = this.drawLabelWithPointPlacement_( text, textKey, strokeKey, fillKey ); image = labelWithAnchor.label; instruction[3] = image; const textOffsetX = ( /** @type {number} */ instruction[23] ); anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio; instruction[4] = anchorX; const textOffsetY = ( /** @type {number} */ instruction[24] ); anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio; instruction[5] = anchorY; height = image.height; instruction[6] = height; width = image.width; instruction[13] = width; } let geometryWidths; if (instruction.length > 25) { geometryWidths = /** @type {number} */ instruction[25]; } let padding, backgroundFillInstruction, backgroundStrokeInstruction; if (instruction.length > 17) { padding = /** @type {Array} */ instruction[16]; backgroundFillInstruction = /** @type {Array<*>} */ instruction[17]; backgroundStrokeInstruction = /** @type {Array<*>} */ instruction[18]; } else { padding = defaultPadding; backgroundFillInstruction = null; backgroundStrokeInstruction = null; } if (rotateWithView && viewRotationFromTransform) { rotation += viewRotation; } else if (!rotateWithView && !viewRotationFromTransform) { rotation -= viewRotation; } let widthIndex = 0; for (; d < dd; d += 2) { if (geometryWidths && geometryWidths[widthIndex++] < width / this.pixelRatio) { continue; } const dimensions = this.calculateImageOrLabelDimensions_( image.width, image.height, pixelCoordinates[d], pixelCoordinates[d + 1], width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, !!backgroundFillInstruction || !!backgroundStrokeInstruction, feature ); const args = [ context, scaledCanvasSize, image, dimensions, opacity, backgroundFillInstruction, backgroundStrokeInstruction ]; if (declutterTree) { let imageArgs, imageDeclutterMode, imageDeclutterBox; if (declutterImageWithText) { const index = dd - d; if (!declutterImageWithText[index]) { declutterImageWithText[index] = { args, declutterMode }; continue; } const imageDeclutter = declutterImageWithText[index]; imageArgs = imageDeclutter.args; imageDeclutterMode = imageDeclutter.declutterMode; delete declutterImageWithText[index]; imageDeclutterBox = getDeclutterBox(imageArgs); } let renderImage, renderText; if (imageArgs && (imageDeclutterMode !== "declutter" || !declutterTree.collides(imageDeclutterBox))) { renderImage = true; } if (declutterMode !== "declutter" || !declutterTree.collides(dimensions.declutterBox)) { renderText = true; } if (imageDeclutterMode === "declutter" && declutterMode === "declutter") { const render = renderImage && renderText; renderImage = render; renderText = render; } if (renderImage) { if (imageDeclutterMode !== "none") { declutterTree.insert(imageDeclutterBox); } this.replayImageOrLabel_.apply(this, imageArgs); } if (renderText) { if (declutterMode !== "none") { declutterTree.insert(dimensions.declutterBox); } this.replayImageOrLabel_.apply(this, args); } } else { this.replayImageOrLabel_.apply(this, args); } } ++i; break; case Instruction_default.DRAW_CHARS: const begin = ( /** @type {number} */ instruction[1] ); const end = ( /** @type {number} */ instruction[2] ); const baseline = ( /** @type {number} */ instruction[3] ); const overflow = ( /** @type {number} */ instruction[4] ); fillKey = /** @type {string} */ instruction[5]; const maxAngle = ( /** @type {number} */ instruction[6] ); const measurePixelRatio = ( /** @type {number} */ instruction[7] ); const offsetY = ( /** @type {number} */ instruction[8] ); strokeKey = /** @type {string} */ instruction[9]; const strokeWidth = ( /** @type {number} */ instruction[10] ); text = /** @type {string|Array} */ instruction[11]; if (Array.isArray(text)) { text = text.reduce(richTextToPlainText, ""); } textKey = /** @type {string} */ instruction[12]; const pixelRatioScale = [ /** @type {number} */ instruction[13], /** @type {number} */ instruction[13] ]; declutterMode = instruction[14] || "declutter"; const textKeepUpright = ( /** @type {boolean} */ instruction[15] ); const textState = this.textStates[textKey]; const font = textState.font; const textScale = [ textState.scale[0] * measurePixelRatio, textState.scale[1] * measurePixelRatio ]; let cachedWidths; if (font in this.widths_) { cachedWidths = this.widths_[font]; } else { cachedWidths = {}; this.widths_[font] = cachedWidths; } const pathLength = lineStringLength(pixelCoordinates, begin, end, 2); const textLength = Math.abs(textScale[0]) * measureAndCacheTextWidth(font, text, cachedWidths); if (overflow || textLength <= pathLength) { const textAlign = this.textStates[textKey].textAlign; const startM = (pathLength - textLength) * horizontalTextAlign(text, textAlign); const parts = drawTextOnPath( pixelCoordinates, begin, end, 2, text, startM, maxAngle, Math.abs(textScale[0]), measureAndCacheTextWidth, font, cachedWidths, viewRotationFromTransform ? 0 : this.viewRotation_, textKeepUpright ); drawChars: if (parts) { const replayImageOrLabelArgs = []; let c, cc, chars, label, part; if (strokeKey) { for (c = 0, cc = parts.length; c < cc; ++c) { part = parts[c]; chars = /** @type {string} */ part[4]; label = this.createLabel(chars, textKey, "", strokeKey); anchorX = /** @type {number} */ part[2] + (textScale[0] < 0 ? -strokeWidth : strokeWidth); anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth * textScale[1] / textScale[0] - offsetY; const dimensions = this.calculateImageOrLabelDimensions_( label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature ); if (declutterTree && declutterMode === "declutter" && declutterTree.collides(dimensions.declutterBox)) { break drawChars; } replayImageOrLabelArgs.push([ context, scaledCanvasSize, label, dimensions, 1, null, null ]); } } if (fillKey) { for (c = 0, cc = parts.length; c < cc; ++c) { part = parts[c]; chars = /** @type {string} */ part[4]; label = this.createLabel(chars, textKey, fillKey, ""); anchorX = /** @type {number} */ part[2]; anchorY = baseline * label.height - offsetY; const dimensions = this.calculateImageOrLabelDimensions_( label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature ); if (declutterTree && declutterMode === "declutter" && declutterTree.collides(dimensions.declutterBox)) { break drawChars; } replayImageOrLabelArgs.push([ context, scaledCanvasSize, label, dimensions, 1, null, null ]); } } if (declutterTree && declutterMode !== "none") { declutterTree.load(replayImageOrLabelArgs.map(getDeclutterBox)); } for (let i2 = 0, ii2 = replayImageOrLabelArgs.length; i2 < ii2; ++i2) { this.replayImageOrLabel_.apply(this, replayImageOrLabelArgs[i2]); } } } ++i; break; case Instruction_default.END_GEOMETRY: if (featureCallback !== void 0) { feature = /** @type {import("../../Feature.js").FeatureLike} */ instruction[1]; const result = featureCallback( feature, currentGeometry, declutterMode ); if (result) { return result; } } ++i; break; case Instruction_default.FILL: if (batchSize) { pendingFill++; } else { this.fill_(context); } ++i; break; case Instruction_default.MOVE_TO_LINE_TO: d = /** @type {number} */ instruction[1]; dd = /** @type {number} */ instruction[2]; x = pixelCoordinates[d]; y = pixelCoordinates[d + 1]; context.moveTo(x, y); prevX = x + 0.5 | 0; prevY = y + 0.5 | 0; for (d += 2; d < dd; d += 2) { x = pixelCoordinates[d]; y = pixelCoordinates[d + 1]; roundX = x + 0.5 | 0; roundY = y + 0.5 | 0; if (d == dd - 2 || roundX !== prevX || roundY !== prevY) { context.lineTo(x, y); prevX = roundX; prevY = roundY; } } ++i; break; case Instruction_default.SET_FILL_STYLE: this.alignAndScaleFill_ = instruction[2]; if (pendingFill) { this.fill_(context); pendingFill = 0; if (pendingStroke) { context.stroke(); pendingStroke = 0; } } context.fillStyle = instruction[1]; ++i; break; case Instruction_default.SET_STROKE_STYLE: if (pendingStroke) { context.stroke(); pendingStroke = 0; } this.setStrokeStyle_( context, /** @type {Array<*>} */ instruction ); ++i; break; case Instruction_default.STROKE: if (batchSize) { pendingStroke++; } else { context.stroke(); } ++i; break; default: ++i; break; } } if (pendingFill) { this.fill_(context); } if (pendingStroke) { context.stroke(); } return void 0; } /** * @param {CanvasRenderingContext2D} context Context. * @param {import('../../size.js').Size} scaledCanvasSize Scaled canvas size. * @param {import("../../transform.js").Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {boolean} snapToPixel Snap point symbols and text to integer pixels. * @param {import("rbush").default} [declutterTree] Declutter tree. */ execute(context, scaledCanvasSize, transform, viewRotation, snapToPixel, declutterTree) { this.viewRotation_ = viewRotation; this.execute_( context, scaledCanvasSize, transform, this.instructions, snapToPixel, void 0, void 0, declutterTree ); } /** * @param {CanvasRenderingContext2D} context Context. * @param {import("../../transform.js").Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {FeatureCallback} [featureCallback] Feature callback. * @param {import("../../extent.js").Extent} [hitExtent] Only check * features that intersect this extent. * @return {T|undefined} Callback result. * @template T */ executeHitDetection(context, transform, viewRotation, featureCallback, hitExtent) { this.viewRotation_ = viewRotation; return this.execute_( context, [context.canvas.width, context.canvas.height], transform, this.hitDetectionInstructions, true, featureCallback, hitExtent ); } }; var Executor_default = Executor; // node_modules/ol/render/canvas/ExecutorGroup.js var ALL = [ "Polygon", "Circle", "LineString", "Image", "Text", "Default" ]; var DECLUTTER = ["Image", "Text"]; var NON_DECLUTTER = ALL.filter( (builderType) => !DECLUTTER.includes(builderType) ); var ExecutorGroup = class { /** * @param {import("../../extent.js").Extent} maxExtent Max extent for clipping. When a * `maxExtent` was set on the Builder for this executor group, the same `maxExtent` * should be set here, unless the target context does not exceed that extent (which * can be the case when rendering to tiles). * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The executor group can have overlapping geometries. * @param {!Object>} allInstructions * The serializable instructions. * @param {number} [renderBuffer] Optional rendering buffer. * @param {boolean} [deferredRendering] Enable deferred rendering with renderDeferred(). */ constructor(maxExtent, resolution, pixelRatio, overlaps, allInstructions, renderBuffer, deferredRendering) { this.maxExtent_ = maxExtent; this.overlaps_ = overlaps; this.pixelRatio_ = pixelRatio; this.resolution_ = resolution; this.renderBuffer_ = renderBuffer; this.executorsByZIndex_ = {}; this.hitDetectionContext_ = null; this.hitDetectionTransform_ = create(); this.renderedContext_ = null; this.deferredZIndexContexts_ = {}; this.createExecutors_(allInstructions, deferredRendering); } /** * @param {CanvasRenderingContext2D} context Context. * @param {import("../../transform.js").Transform} transform Transform. */ clip(context, transform) { const flatClipCoords = this.getClipCoords(transform); context.beginPath(); context.moveTo(flatClipCoords[0], flatClipCoords[1]); context.lineTo(flatClipCoords[2], flatClipCoords[3]); context.lineTo(flatClipCoords[4], flatClipCoords[5]); context.lineTo(flatClipCoords[6], flatClipCoords[7]); context.clip(); } /** * Create executors and populate them using the provided instructions. * @private * @param {!Object>} allInstructions The serializable instructions * @param {boolean} deferredRendering Enable deferred rendering. */ createExecutors_(allInstructions, deferredRendering) { for (const zIndex in allInstructions) { let executors = this.executorsByZIndex_[zIndex]; if (executors === void 0) { executors = {}; this.executorsByZIndex_[zIndex] = executors; } const instructionByZindex = allInstructions[zIndex]; for (const builderType in instructionByZindex) { const instructions = instructionByZindex[builderType]; executors[builderType] = new Executor_default( this.resolution_, this.pixelRatio_, this.overlaps_, instructions, deferredRendering ); } } } /** * @param {Array} executors Executors. * @return {boolean} Has executors of the provided types. */ hasExecutors(executors) { for (const zIndex in this.executorsByZIndex_) { const candidates = this.executorsByZIndex_[zIndex]; for (let i = 0, ii = executors.length; i < ii; ++i) { if (executors[i] in candidates) { return true; } } } return false; } /** * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate. * @param {number} resolution Resolution. * @param {number} rotation Rotation. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default, number): T} callback Feature callback. * @param {Array} declutteredFeatures Decluttered features. * @return {T|undefined} Callback result. * @template T */ forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, callback, declutteredFeatures) { hitTolerance = Math.round(hitTolerance); const contextSize = hitTolerance * 2 + 1; const transform = compose( this.hitDetectionTransform_, hitTolerance + 0.5, hitTolerance + 0.5, 1 / resolution, -1 / resolution, -rotation, -coordinate[0], -coordinate[1] ); const newContext = !this.hitDetectionContext_; if (newContext) { this.hitDetectionContext_ = createCanvasContext2D( contextSize, contextSize ); } const context = this.hitDetectionContext_; if (context.canvas.width !== contextSize || context.canvas.height !== contextSize) { context.canvas.width = contextSize; context.canvas.height = contextSize; } else if (!newContext) { context.clearRect(0, 0, contextSize, contextSize); } let hitExtent; if (this.renderBuffer_ !== void 0) { hitExtent = createEmpty(); extendCoordinate(hitExtent, coordinate); buffer( hitExtent, resolution * (this.renderBuffer_ + hitTolerance), hitExtent ); } const indexes = getPixelIndexArray(hitTolerance); let builderType; function featureCallback(feature, geometry, declutterMode) { const imageData = context.getImageData( 0, 0, contextSize, contextSize ).data; for (let i2 = 0, ii = indexes.length; i2 < ii; i2++) { if (imageData[indexes[i2]] > 0) { if (!declutteredFeatures || declutterMode === "none" || builderType !== "Image" && builderType !== "Text" || declutteredFeatures.includes(feature)) { const idx = (indexes[i2] - 3) / 4; const x = hitTolerance - idx % contextSize; const y = hitTolerance - (idx / contextSize | 0); const result2 = callback(feature, geometry, x * x + y * y); if (result2) { return result2; } } context.clearRect(0, 0, contextSize, contextSize); break; } } return void 0; } const zs = Object.keys(this.executorsByZIndex_).map(Number); zs.sort(ascending); let i, j, executors, executor, result; for (i = zs.length - 1; i >= 0; --i) { const zIndexKey = zs[i].toString(); executors = this.executorsByZIndex_[zIndexKey]; for (j = ALL.length - 1; j >= 0; --j) { builderType = ALL[j]; executor = executors[builderType]; if (executor !== void 0) { result = executor.executeHitDetection( context, transform, rotation, featureCallback, hitExtent ); if (result) { return result; } } } } return void 0; } /** * @param {import("../../transform.js").Transform} transform Transform. * @return {Array|null} Clip coordinates. */ getClipCoords(transform) { const maxExtent = this.maxExtent_; if (!maxExtent) { return null; } const minX = maxExtent[0]; const minY = maxExtent[1]; const maxX = maxExtent[2]; const maxY = maxExtent[3]; const flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY]; transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords); return flatClipCoords; } /** * @return {boolean} Is empty. */ isEmpty() { return isEmpty(this.executorsByZIndex_); } /** * @param {CanvasRenderingContext2D} targetContext Context. * @param {import('../../size.js').Size} scaledCanvasSize Scale of the context. * @param {import("../../transform.js").Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {boolean} snapToPixel Snap point symbols and test to integer pixel. * @param {Array} [builderTypes] Ordered replay types to replay. * Default is {@link module:ol/render/replay~ALL} * @param {import("rbush").default|null} [declutterTree] Declutter tree. * When set to null, no decluttering is done, even when the executor group has a `ZIndexContext`. */ execute(targetContext, scaledCanvasSize, transform, viewRotation, snapToPixel, builderTypes, declutterTree) { const zs = Object.keys(this.executorsByZIndex_).map(Number); zs.sort(declutterTree ? descending : ascending); builderTypes = builderTypes ? builderTypes : ALL; const maxBuilderTypes = ALL.length; for (let i = 0, ii = zs.length; i < ii; ++i) { const zIndexKey = zs[i].toString(); const replays = this.executorsByZIndex_[zIndexKey]; for (let j = 0, jj = builderTypes.length; j < jj; ++j) { const builderType = builderTypes[j]; const replay = replays[builderType]; if (replay !== void 0) { const zIndexContext = declutterTree === null ? void 0 : replay.getZIndexContext(); const context = zIndexContext ? zIndexContext.getContext() : targetContext; const requireClip = this.maxExtent_ && builderType !== "Image" && builderType !== "Text"; if (requireClip) { context.save(); this.clip(context, transform); } if (!zIndexContext || builderType === "Text" || builderType === "Image") { replay.execute( context, scaledCanvasSize, transform, viewRotation, snapToPixel, declutterTree ); } else { zIndexContext.pushFunction( (context2) => replay.execute( context2, scaledCanvasSize, transform, viewRotation, snapToPixel, declutterTree ) ); } if (requireClip) { context.restore(); } if (zIndexContext) { zIndexContext.offset(); const index = zs[i] * maxBuilderTypes + ALL.indexOf(builderType); if (!this.deferredZIndexContexts_[index]) { this.deferredZIndexContexts_[index] = []; } this.deferredZIndexContexts_[index].push(zIndexContext); } } } } this.renderedContext_ = targetContext; } getDeferredZIndexContexts() { return this.deferredZIndexContexts_; } getRenderedContext() { return this.renderedContext_; } renderDeferred() { const deferredZIndexContexts = this.deferredZIndexContexts_; const zs = Object.keys(deferredZIndexContexts).map(Number).sort(ascending); for (let i = 0, ii = zs.length; i < ii; ++i) { deferredZIndexContexts[zs[i]].forEach((zIndexContext) => { zIndexContext.draw(this.renderedContext_); zIndexContext.clear(); }); deferredZIndexContexts[zs[i]].length = 0; } } }; var circlePixelIndexArrayCache = {}; function getPixelIndexArray(radius) { if (circlePixelIndexArrayCache[radius] !== void 0) { return circlePixelIndexArrayCache[radius]; } const size = radius * 2 + 1; const maxDistanceSq = radius * radius; const distances = new Array(maxDistanceSq + 1); for (let i = 0; i <= radius; ++i) { for (let j = 0; j <= radius; ++j) { const distanceSq = i * i + j * j; if (distanceSq > maxDistanceSq) { break; } let distance = distances[distanceSq]; if (!distance) { distance = []; distances[distanceSq] = distance; } distance.push(((radius + i) * size + (radius + j)) * 4 + 3); if (i > 0) { distance.push(((radius - i) * size + (radius + j)) * 4 + 3); } if (j > 0) { distance.push(((radius + i) * size + (radius - j)) * 4 + 3); if (i > 0) { distance.push(((radius - i) * size + (radius - j)) * 4 + 3); } } } } const pixelIndex = []; for (let i = 0, ii = distances.length; i < ii; ++i) { if (distances[i]) { pixelIndex.push(...distances[i]); } } circlePixelIndexArrayCache[radius] = pixelIndex; return pixelIndex; } var ExecutorGroup_default = ExecutorGroup; // node_modules/ol/render/canvas/Immediate.js var CanvasImmediateRenderer = class extends VectorContext_default { /** * @param {CanvasRenderingContext2D} context Context. * @param {number} pixelRatio Pixel ratio. * @param {import("../../extent.js").Extent} extent Extent. * @param {import("../../transform.js").Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {number} [squaredTolerance] Optional squared tolerance for simplification. * @param {import("../../proj.js").TransformFunction} [userTransform] Transform from user to view projection. */ constructor(context, pixelRatio, extent, transform, viewRotation, squaredTolerance, userTransform) { super(); this.context_ = context; this.pixelRatio_ = pixelRatio; this.extent_ = extent; this.transform_ = transform; this.transformRotation_ = transform ? toFixed(Math.atan2(transform[1], transform[0]), 10) : 0; this.viewRotation_ = viewRotation; this.squaredTolerance_ = squaredTolerance; this.userTransform_ = userTransform; this.contextFillState_ = null; this.contextStrokeState_ = null; this.contextTextState_ = null; this.fillState_ = null; this.strokeState_ = null; this.image_ = null; this.imageAnchorX_ = 0; this.imageAnchorY_ = 0; this.imageHeight_ = 0; this.imageOpacity_ = 0; this.imageOriginX_ = 0; this.imageOriginY_ = 0; this.imageRotateWithView_ = false; this.imageRotation_ = 0; this.imageScale_ = [0, 0]; this.imageWidth_ = 0; this.text_ = ""; this.textOffsetX_ = 0; this.textOffsetY_ = 0; this.textRotateWithView_ = false; this.textRotation_ = 0; this.textScale_ = [0, 0]; this.textFillState_ = null; this.textStrokeState_ = null; this.textState_ = null; this.pixelCoordinates_ = []; this.tmpLocalTransform_ = create(); } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. * @private */ drawImages_(flatCoordinates, offset, end, stride) { if (!this.image_) { return; } const pixelCoordinates = transform2D( flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_ ); const context = this.context_; const localTransform = this.tmpLocalTransform_; const alpha = context.globalAlpha; if (this.imageOpacity_ != 1) { context.globalAlpha = alpha * this.imageOpacity_; } let rotation = this.imageRotation_; if (this.transformRotation_ === 0) { rotation -= this.viewRotation_; } if (this.imageRotateWithView_) { rotation += this.viewRotation_; } for (let i = 0, ii = pixelCoordinates.length; i < ii; i += 2) { const x = pixelCoordinates[i] - this.imageAnchorX_; const y = pixelCoordinates[i + 1] - this.imageAnchorY_; if (rotation !== 0 || this.imageScale_[0] != 1 || this.imageScale_[1] != 1) { const centerX = x + this.imageAnchorX_; const centerY = y + this.imageAnchorY_; compose( localTransform, centerX, centerY, 1, 1, rotation, -centerX, -centerY ); context.save(); context.transform.apply(context, localTransform); context.translate(centerX, centerY); context.scale(this.imageScale_[0], this.imageScale_[1]); context.drawImage( this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, -this.imageAnchorX_, -this.imageAnchorY_, this.imageWidth_, this.imageHeight_ ); context.restore(); } else { context.drawImage( this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, x, y, this.imageWidth_, this.imageHeight_ ); } } if (this.imageOpacity_ != 1) { context.globalAlpha = alpha; } } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. * @private */ drawText_(flatCoordinates, offset, end, stride) { if (!this.textState_ || this.text_ === "") { return; } if (this.textFillState_) { this.setContextFillState_(this.textFillState_); } if (this.textStrokeState_) { this.setContextStrokeState_(this.textStrokeState_); } this.setContextTextState_(this.textState_); const pixelCoordinates = transform2D( flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_ ); const context = this.context_; let rotation = this.textRotation_; if (this.transformRotation_ === 0) { rotation -= this.viewRotation_; } if (this.textRotateWithView_) { rotation += this.viewRotation_; } for (; offset < end; offset += stride) { const x = pixelCoordinates[offset] + this.textOffsetX_; const y = pixelCoordinates[offset + 1] + this.textOffsetY_; if (rotation !== 0 || this.textScale_[0] != 1 || this.textScale_[1] != 1) { context.save(); context.translate(x - this.textOffsetX_, y - this.textOffsetY_); context.rotate(rotation); context.translate(this.textOffsetX_, this.textOffsetY_); context.scale(this.textScale_[0], this.textScale_[1]); if (this.textStrokeState_) { context.strokeText(this.text_, 0, 0); } if (this.textFillState_) { context.fillText(this.text_, 0, 0); } context.restore(); } else { if (this.textStrokeState_) { context.strokeText(this.text_, x, y); } if (this.textFillState_) { context.fillText(this.text_, x, y); } } } } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. * @param {boolean} close Close. * @private * @return {number} end End. */ moveToLineTo_(flatCoordinates, offset, end, stride, close) { const context = this.context_; const pixelCoordinates = transform2D( flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_ ); context.moveTo(pixelCoordinates[0], pixelCoordinates[1]); let length = pixelCoordinates.length; if (close) { length -= 2; } for (let i = 2; i < length; i += 2) { context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]); } if (close) { context.closePath(); } return end; } /** * @param {Array} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {Array} ends Ends. * @param {number} stride Stride. * @private * @return {number} End. */ drawRings_(flatCoordinates, offset, ends, stride) { for (let i = 0, ii = ends.length; i < ii; ++i) { offset = this.moveToLineTo_( flatCoordinates, offset, ends[i], stride, true ); } return offset; } /** * Render a circle geometry into the canvas. Rendering is immediate and uses * the current fill and stroke styles. * * @param {import("../../geom/Circle.js").default} geometry Circle geometry. * @api * @override */ drawCircle(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/Circle.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } if (!intersects(this.extent_, geometry.getExtent())) { return; } if (this.fillState_ || this.strokeState_) { if (this.fillState_) { this.setContextFillState_(this.fillState_); } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); } const pixelCoordinates = transformGeom2D( geometry, this.transform_, this.pixelCoordinates_ ); const dx = pixelCoordinates[2] - pixelCoordinates[0]; const dy = pixelCoordinates[3] - pixelCoordinates[1]; const radius = Math.sqrt(dx * dx + dy * dy); const context = this.context_; context.beginPath(); context.arc( pixelCoordinates[0], pixelCoordinates[1], radius, 0, 2 * Math.PI ); if (this.fillState_) { context.fill(); } if (this.strokeState_) { context.stroke(); } } if (this.text_ !== "") { this.drawText_(geometry.getCenter(), 0, 2, 2); } } /** * Set the rendering style. Note that since this is an immediate rendering API, * any `zIndex` on the provided style will be ignored. * * @param {import("../../style/Style.js").default} style The rendering style. * @api * @override */ setStyle(style) { this.setFillStrokeStyle(style.getFill(), style.getStroke()); this.setImageStyle(style.getImage()); this.setTextStyle(style.getText()); } /** * @param {import("../../transform.js").Transform} transform Transform. */ setTransform(transform) { this.transform_ = transform; } /** * Render a geometry into the canvas. Call * {@link module:ol/render/canvas/Immediate~CanvasImmediateRenderer#setStyle renderer.setStyle()} first to set the rendering style. * * @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry The geometry to render. * @api * @override */ drawGeometry(geometry) { const type = geometry.getType(); switch (type) { case "Point": this.drawPoint( /** @type {import("../../geom/Point.js").default} */ geometry ); break; case "LineString": this.drawLineString( /** @type {import("../../geom/LineString.js").default} */ geometry ); break; case "Polygon": this.drawPolygon( /** @type {import("../../geom/Polygon.js").default} */ geometry ); break; case "MultiPoint": this.drawMultiPoint( /** @type {import("../../geom/MultiPoint.js").default} */ geometry ); break; case "MultiLineString": this.drawMultiLineString( /** @type {import("../../geom/MultiLineString.js").default} */ geometry ); break; case "MultiPolygon": this.drawMultiPolygon( /** @type {import("../../geom/MultiPolygon.js").default} */ geometry ); break; case "GeometryCollection": this.drawGeometryCollection( /** @type {import("../../geom/GeometryCollection.js").default} */ geometry ); break; case "Circle": this.drawCircle( /** @type {import("../../geom/Circle.js").default} */ geometry ); break; default: } } /** * Render a feature into the canvas. Note that any `zIndex` on the provided * style will be ignored - features are rendered immediately in the order that * this method is called. If you need `zIndex` support, you should be using an * {@link module:ol/layer/Vector~VectorLayer} instead. * * @param {import("../../Feature.js").default} feature Feature. * @param {import("../../style/Style.js").default} style Style. * @api * @override */ drawFeature(feature, style) { const geometry = style.getGeometryFunction()(feature); if (!geometry) { return; } this.setStyle(style); this.drawGeometry(geometry); } /** * Render a GeometryCollection to the canvas. Rendering is immediate and * uses the current styles appropriate for each geometry in the collection. * * @param {import("../../geom/GeometryCollection.js").default} geometry Geometry collection. * @override */ drawGeometryCollection(geometry) { const geometries = geometry.getGeometriesArray(); for (let i = 0, ii = geometries.length; i < ii; ++i) { this.drawGeometry(geometries[i]); } } /** * Render a Point geometry into the canvas. Rendering is immediate and uses * the current style. * * @param {import("../../geom/Point.js").default|import("../Feature.js").default} geometry Point geometry. * @override */ drawPoint(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/Point.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } const flatCoordinates = geometry.getFlatCoordinates(); const stride = geometry.getStride(); if (this.image_) { this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride); } if (this.text_ !== "") { this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride); } } /** * Render a MultiPoint geometry into the canvas. Rendering is immediate and * uses the current style. * * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} geometry MultiPoint geometry. * @override */ drawMultiPoint(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/MultiPoint.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } const flatCoordinates = geometry.getFlatCoordinates(); const stride = geometry.getStride(); if (this.image_) { this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride); } if (this.text_ !== "") { this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride); } } /** * Render a LineString into the canvas. Rendering is immediate and uses * the current style. * * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} geometry LineString geometry. * @override */ drawLineString(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/LineString.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } if (!intersects(this.extent_, geometry.getExtent())) { return; } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); const context = this.context_; const flatCoordinates = geometry.getFlatCoordinates(); context.beginPath(); this.moveToLineTo_( flatCoordinates, 0, flatCoordinates.length, geometry.getStride(), false ); context.stroke(); } if (this.text_ !== "") { const flatMidpoint = geometry.getFlatMidpoint(); this.drawText_(flatMidpoint, 0, 2, 2); } } /** * Render a MultiLineString geometry into the canvas. Rendering is immediate * and uses the current style. * * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} geometry MultiLineString geometry. * @override */ drawMultiLineString(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/MultiLineString.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } const geometryExtent = geometry.getExtent(); if (!intersects(this.extent_, geometryExtent)) { return; } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); const context = this.context_; const flatCoordinates = geometry.getFlatCoordinates(); let offset = 0; const ends = ( /** @type {Array} */ geometry.getEnds() ); const stride = geometry.getStride(); context.beginPath(); for (let i = 0, ii = ends.length; i < ii; ++i) { offset = this.moveToLineTo_( flatCoordinates, offset, ends[i], stride, false ); } context.stroke(); } if (this.text_ !== "") { const flatMidpoints = geometry.getFlatMidpoints(); this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2); } } /** * Render a Polygon geometry into the canvas. Rendering is immediate and uses * the current style. * * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} geometry Polygon geometry. * @override */ drawPolygon(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/Polygon.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } if (!intersects(this.extent_, geometry.getExtent())) { return; } if (this.strokeState_ || this.fillState_) { if (this.fillState_) { this.setContextFillState_(this.fillState_); } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); } const context = this.context_; context.beginPath(); this.drawRings_( geometry.getOrientedFlatCoordinates(), 0, /** @type {Array} */ geometry.getEnds(), geometry.getStride() ); if (this.fillState_) { context.fill(); } if (this.strokeState_) { context.stroke(); } } if (this.text_ !== "") { const flatInteriorPoint = geometry.getFlatInteriorPoint(); this.drawText_(flatInteriorPoint, 0, 2, 2); } } /** * Render MultiPolygon geometry into the canvas. Rendering is immediate and * uses the current style. * @param {import("../../geom/MultiPolygon.js").default} geometry MultiPolygon geometry. * @override */ drawMultiPolygon(geometry) { if (this.squaredTolerance_) { geometry = /** @type {import("../../geom/MultiPolygon.js").default} */ geometry.simplifyTransformed( this.squaredTolerance_, this.userTransform_ ); } if (!intersects(this.extent_, geometry.getExtent())) { return; } if (this.strokeState_ || this.fillState_) { if (this.fillState_) { this.setContextFillState_(this.fillState_); } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); } const context = this.context_; const flatCoordinates = geometry.getOrientedFlatCoordinates(); let offset = 0; const endss = geometry.getEndss(); const stride = geometry.getStride(); context.beginPath(); for (let i = 0, ii = endss.length; i < ii; ++i) { const ends = endss[i]; offset = this.drawRings_(flatCoordinates, offset, ends, stride); } if (this.fillState_) { context.fill(); } if (this.strokeState_) { context.stroke(); } } if (this.text_ !== "") { const flatInteriorPoints = geometry.getFlatInteriorPoints(); this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2); } } /** * @param {import("../canvas.js").FillState} fillState Fill state. * @private */ setContextFillState_(fillState) { const context = this.context_; const contextFillState = this.contextFillState_; if (!contextFillState) { context.fillStyle = fillState.fillStyle; this.contextFillState_ = { fillStyle: fillState.fillStyle }; } else { if (contextFillState.fillStyle != fillState.fillStyle) { contextFillState.fillStyle = fillState.fillStyle; context.fillStyle = fillState.fillStyle; } } } /** * @param {import("../canvas.js").StrokeState} strokeState Stroke state. * @private */ setContextStrokeState_(strokeState) { const context = this.context_; const contextStrokeState = this.contextStrokeState_; if (!contextStrokeState) { context.lineCap = strokeState.lineCap; context.setLineDash(strokeState.lineDash); context.lineDashOffset = strokeState.lineDashOffset; context.lineJoin = strokeState.lineJoin; context.lineWidth = strokeState.lineWidth; context.miterLimit = strokeState.miterLimit; context.strokeStyle = strokeState.strokeStyle; this.contextStrokeState_ = { lineCap: strokeState.lineCap, lineDash: strokeState.lineDash, lineDashOffset: strokeState.lineDashOffset, lineJoin: strokeState.lineJoin, lineWidth: strokeState.lineWidth, miterLimit: strokeState.miterLimit, strokeStyle: strokeState.strokeStyle }; } else { if (contextStrokeState.lineCap != strokeState.lineCap) { contextStrokeState.lineCap = strokeState.lineCap; context.lineCap = strokeState.lineCap; } if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) { context.setLineDash( contextStrokeState.lineDash = strokeState.lineDash ); } if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) { contextStrokeState.lineDashOffset = strokeState.lineDashOffset; context.lineDashOffset = strokeState.lineDashOffset; } if (contextStrokeState.lineJoin != strokeState.lineJoin) { contextStrokeState.lineJoin = strokeState.lineJoin; context.lineJoin = strokeState.lineJoin; } if (contextStrokeState.lineWidth != strokeState.lineWidth) { contextStrokeState.lineWidth = strokeState.lineWidth; context.lineWidth = strokeState.lineWidth; } if (contextStrokeState.miterLimit != strokeState.miterLimit) { contextStrokeState.miterLimit = strokeState.miterLimit; context.miterLimit = strokeState.miterLimit; } if (contextStrokeState.strokeStyle != strokeState.strokeStyle) { contextStrokeState.strokeStyle = strokeState.strokeStyle; context.strokeStyle = strokeState.strokeStyle; } } } /** * @param {import("../canvas.js").TextState} textState Text state. * @private */ setContextTextState_(textState) { const context = this.context_; const contextTextState = this.contextTextState_; const textAlign = textState.textAlign ? textState.textAlign : defaultTextAlign; if (!contextTextState) { context.font = textState.font; context.textAlign = textAlign; context.textBaseline = textState.textBaseline; this.contextTextState_ = { font: textState.font, textAlign, textBaseline: textState.textBaseline }; } else { if (contextTextState.font != textState.font) { contextTextState.font = textState.font; context.font = textState.font; } if (contextTextState.textAlign != textAlign) { contextTextState.textAlign = textAlign; context.textAlign = textAlign; } if (contextTextState.textBaseline != textState.textBaseline) { contextTextState.textBaseline = textState.textBaseline; context.textBaseline = textState.textBaseline; } } } /** * Set the fill and stroke style for subsequent draw operations. To clear * either fill or stroke styles, pass null for the appropriate parameter. * * @param {import("../../style/Fill.js").default} fillStyle Fill style. * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style. * @override */ setFillStrokeStyle(fillStyle, strokeStyle) { if (!fillStyle) { this.fillState_ = null; } else { const fillStyleColor = fillStyle.getColor(); this.fillState_ = { fillStyle: asColorLike( fillStyleColor ? fillStyleColor : defaultFillStyle ) }; } if (!strokeStyle) { this.strokeState_ = null; } else { const strokeStyleColor = strokeStyle.getColor(); const strokeStyleLineCap = strokeStyle.getLineCap(); const strokeStyleLineDash = strokeStyle.getLineDash(); const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); const strokeStyleLineJoin = strokeStyle.getLineJoin(); const strokeStyleWidth = strokeStyle.getWidth(); const strokeStyleMiterLimit = strokeStyle.getMiterLimit(); const lineDash = strokeStyleLineDash ? strokeStyleLineDash : defaultLineDash; this.strokeState_ = { lineCap: strokeStyleLineCap !== void 0 ? strokeStyleLineCap : defaultLineCap, lineDash: this.pixelRatio_ === 1 ? lineDash : lineDash.map((n) => n * this.pixelRatio_), lineDashOffset: (strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset) * this.pixelRatio_, lineJoin: strokeStyleLineJoin !== void 0 ? strokeStyleLineJoin : defaultLineJoin, lineWidth: (strokeStyleWidth !== void 0 ? strokeStyleWidth : defaultLineWidth) * this.pixelRatio_, miterLimit: strokeStyleMiterLimit !== void 0 ? strokeStyleMiterLimit : defaultMiterLimit, strokeStyle: asColorLike( strokeStyleColor ? strokeStyleColor : defaultStrokeStyle ) }; } } /** * Set the image style for subsequent draw operations. Pass null to remove * the image style. * * @param {import("../../style/Image.js").default} imageStyle Image style. * @override */ setImageStyle(imageStyle) { let imageSize; if (!imageStyle || !(imageSize = imageStyle.getSize())) { this.image_ = null; return; } const imagePixelRatio = imageStyle.getPixelRatio(this.pixelRatio_); const imageAnchor = imageStyle.getAnchor(); const imageOrigin = imageStyle.getOrigin(); this.image_ = imageStyle.getImage(this.pixelRatio_); this.imageAnchorX_ = imageAnchor[0] * imagePixelRatio; this.imageAnchorY_ = imageAnchor[1] * imagePixelRatio; this.imageHeight_ = imageSize[1] * imagePixelRatio; this.imageOpacity_ = imageStyle.getOpacity(); this.imageOriginX_ = imageOrigin[0]; this.imageOriginY_ = imageOrigin[1]; this.imageRotateWithView_ = imageStyle.getRotateWithView(); this.imageRotation_ = imageStyle.getRotation(); const imageScale = imageStyle.getScaleArray(); this.imageScale_ = [ imageScale[0] * this.pixelRatio_ / imagePixelRatio, imageScale[1] * this.pixelRatio_ / imagePixelRatio ]; this.imageWidth_ = imageSize[0] * imagePixelRatio; } /** * Set the text style for subsequent draw operations. Pass null to * remove the text style. * * @param {import("../../style/Text.js").default} textStyle Text style. * @override */ setTextStyle(textStyle) { if (!textStyle) { this.text_ = ""; } else { const textFillStyle = textStyle.getFill(); if (!textFillStyle) { this.textFillState_ = null; } else { const textFillStyleColor = textFillStyle.getColor(); this.textFillState_ = { fillStyle: asColorLike( textFillStyleColor ? textFillStyleColor : defaultFillStyle ) }; } const textStrokeStyle = textStyle.getStroke(); if (!textStrokeStyle) { this.textStrokeState_ = null; } else { const textStrokeStyleColor = textStrokeStyle.getColor(); const textStrokeStyleLineCap = textStrokeStyle.getLineCap(); const textStrokeStyleLineDash = textStrokeStyle.getLineDash(); const textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset(); const textStrokeStyleLineJoin = textStrokeStyle.getLineJoin(); const textStrokeStyleWidth = textStrokeStyle.getWidth(); const textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit(); this.textStrokeState_ = { lineCap: textStrokeStyleLineCap !== void 0 ? textStrokeStyleLineCap : defaultLineCap, lineDash: textStrokeStyleLineDash ? textStrokeStyleLineDash : defaultLineDash, lineDashOffset: textStrokeStyleLineDashOffset ? textStrokeStyleLineDashOffset : defaultLineDashOffset, lineJoin: textStrokeStyleLineJoin !== void 0 ? textStrokeStyleLineJoin : defaultLineJoin, lineWidth: textStrokeStyleWidth !== void 0 ? textStrokeStyleWidth : defaultLineWidth, miterLimit: textStrokeStyleMiterLimit !== void 0 ? textStrokeStyleMiterLimit : defaultMiterLimit, strokeStyle: asColorLike( textStrokeStyleColor ? textStrokeStyleColor : defaultStrokeStyle ) }; } const textFont = textStyle.getFont(); const textOffsetX = textStyle.getOffsetX(); const textOffsetY = textStyle.getOffsetY(); const textRotateWithView = textStyle.getRotateWithView(); const textRotation = textStyle.getRotation(); const textScale = textStyle.getScaleArray(); const textText = textStyle.getText(); const textTextAlign = textStyle.getTextAlign(); const textTextBaseline = textStyle.getTextBaseline(); this.textState_ = { font: textFont !== void 0 ? textFont : defaultFont, textAlign: textTextAlign !== void 0 ? textTextAlign : defaultTextAlign, textBaseline: textTextBaseline !== void 0 ? textTextBaseline : defaultTextBaseline }; this.text_ = textText !== void 0 ? Array.isArray(textText) ? textText.reduce((acc, t, i) => acc += i % 2 ? " " : t, "") : textText : ""; this.textOffsetX_ = textOffsetX !== void 0 ? this.pixelRatio_ * textOffsetX : 0; this.textOffsetY_ = textOffsetY !== void 0 ? this.pixelRatio_ * textOffsetY : 0; this.textRotateWithView_ = textRotateWithView !== void 0 ? textRotateWithView : false; this.textRotation_ = textRotation !== void 0 ? textRotation : 0; this.textScale_ = [ this.pixelRatio_ * textScale[0], this.pixelRatio_ * textScale[1] ]; } } }; var Immediate_default = CanvasImmediateRenderer; // node_modules/ol/render/canvas/hitdetect.js var HIT_DETECT_RESOLUTION = 0.5; function createHitDetectionImageData(size, transforms, features, styleFunction, extent, resolution, rotation, squaredTolerance, projection) { const userExtent = projection ? toUserExtent(extent, projection) : extent; const width = size[0] * HIT_DETECT_RESOLUTION; const height = size[1] * HIT_DETECT_RESOLUTION; const context = createCanvasContext2D(width, height); context.imageSmoothingEnabled = false; const canvas = context.canvas; const renderer = new Immediate_default( context, HIT_DETECT_RESOLUTION, extent, null, rotation, squaredTolerance, projection ? getTransformFromProjections(getUserProjection(), projection) : null ); const featureCount = features.length; const indexFactor = Math.floor((256 * 256 * 256 - 1) / featureCount); const featuresByZIndex = {}; for (let i = 1; i <= featureCount; ++i) { const feature = features[i - 1]; const featureStyleFunction = feature.getStyleFunction() || styleFunction; if (!featureStyleFunction) { continue; } let styles = featureStyleFunction(feature, resolution); if (!styles) { continue; } if (!Array.isArray(styles)) { styles = [styles]; } const index = i * indexFactor; const color = index.toString(16).padStart(7, "#00000"); for (let j = 0, jj = styles.length; j < jj; ++j) { const originalStyle = styles[j]; const geometry = originalStyle.getGeometryFunction()(feature); if (!geometry || !intersects(userExtent, geometry.getExtent())) { continue; } const style = originalStyle.clone(); const fill = style.getFill(); if (fill) { fill.setColor(color); } const stroke = style.getStroke(); if (stroke) { stroke.setColor(color); stroke.setLineDash(null); } style.setText(void 0); const image = originalStyle.getImage(); if (image) { const imgSize = image.getImageSize(); if (!imgSize) { continue; } const imgContext = createCanvasContext2D( imgSize[0], imgSize[1], void 0, { alpha: false } ); const img = imgContext.canvas; imgContext.fillStyle = color; imgContext.fillRect(0, 0, img.width, img.height); style.setImage( new Icon_default({ img, anchor: image.getAnchor(), anchorXUnits: "pixels", anchorYUnits: "pixels", offset: image.getOrigin(), opacity: 1, size: image.getSize(), scale: image.getScale(), rotation: image.getRotation(), rotateWithView: image.getRotateWithView() }) ); } const zIndex = style.getZIndex() || 0; let byGeometryType = featuresByZIndex[zIndex]; if (!byGeometryType) { byGeometryType = {}; featuresByZIndex[zIndex] = byGeometryType; byGeometryType["Polygon"] = []; byGeometryType["Circle"] = []; byGeometryType["LineString"] = []; byGeometryType["Point"] = []; } const type = geometry.getType(); if (type === "GeometryCollection") { const geometries = ( /** @type {import("../../geom/GeometryCollection.js").default} */ geometry.getGeometriesArrayRecursive() ); for (let i2 = 0, ii = geometries.length; i2 < ii; ++i2) { const geometry2 = geometries[i2]; byGeometryType[geometry2.getType().replace("Multi", "")].push( geometry2, style ); } } else { byGeometryType[type.replace("Multi", "")].push(geometry, style); } } } const zIndexKeys = Object.keys(featuresByZIndex).map(Number).sort(ascending); for (let i = 0, ii = zIndexKeys.length; i < ii; ++i) { const byGeometryType = featuresByZIndex[zIndexKeys[i]]; for (const type in byGeometryType) { const geomAndStyle = byGeometryType[type]; for (let j = 0, jj = geomAndStyle.length; j < jj; j += 2) { renderer.setStyle(geomAndStyle[j + 1]); for (let k = 0, kk = transforms.length; k < kk; ++k) { renderer.setTransform(transforms[k]); renderer.drawGeometry(geomAndStyle[j]); } } } } return context.getImageData(0, 0, canvas.width, canvas.height); } function hitDetect(pixel, features, imageData) { const resultFeatures = []; if (imageData) { const x = Math.floor(Math.round(pixel[0]) * HIT_DETECT_RESOLUTION); const y = Math.floor(Math.round(pixel[1]) * HIT_DETECT_RESOLUTION); const index = (clamp(x, 0, imageData.width - 1) + clamp(y, 0, imageData.height - 1) * imageData.width) * 4; const r = imageData.data[index]; const g = imageData.data[index + 1]; const b = imageData.data[index + 2]; const i = b + 256 * (g + 256 * r); const indexFactor = Math.floor((256 * 256 * 256 - 1) / features.length); if (i && i % indexFactor === 0) { resultFeatures.push(features[i / indexFactor - 1]); } } return resultFeatures; } // node_modules/ol/renderer/vector.js var SIMPLIFY_TOLERANCE = 0.5; var GEOMETRY_RENDERERS = { "Point": renderPointGeometry, "LineString": renderLineStringGeometry, "Polygon": renderPolygonGeometry, "MultiPoint": renderMultiPointGeometry, "MultiLineString": renderMultiLineStringGeometry, "MultiPolygon": renderMultiPolygonGeometry, "GeometryCollection": renderGeometryCollectionGeometry, "Circle": renderCircleGeometry }; function defaultOrder(feature1, feature2) { return parseInt(getUid(feature1), 10) - parseInt(getUid(feature2), 10); } function getSquaredTolerance(resolution, pixelRatio) { const tolerance = getTolerance(resolution, pixelRatio); return tolerance * tolerance; } function getTolerance(resolution, pixelRatio) { return SIMPLIFY_TOLERANCE * resolution / pixelRatio; } function renderCircleGeometry(builderGroup, geometry, style, feature, index) { const fillStyle = style.getFill(); const strokeStyle = style.getStroke(); if (fillStyle || strokeStyle) { const circleReplay = builderGroup.getBuilder(style.getZIndex(), "Circle"); circleReplay.setFillStrokeStyle(fillStyle, strokeStyle); circleReplay.drawCircle(geometry, feature, index); } const textStyle = style.getText(); if (textStyle && textStyle.getText()) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } function renderFeature(replayGroup, feature, style, squaredTolerance, listener, transform, declutter, index) { const loadingPromises = []; const imageStyle = style.getImage(); if (imageStyle) { let loading2 = true; const imageState = imageStyle.getImageState(); if (imageState == ImageState_default.LOADED || imageState == ImageState_default.ERROR) { loading2 = false; } else { if (imageState == ImageState_default.IDLE) { imageStyle.load(); } } if (loading2) { loadingPromises.push(imageStyle.ready()); } } const fillStyle = style.getFill(); if (fillStyle && fillStyle.loading()) { loadingPromises.push(fillStyle.ready()); } const loading = loadingPromises.length > 0; if (loading) { Promise.all(loadingPromises).then(() => listener(null)); } renderFeatureInternal( replayGroup, feature, style, squaredTolerance, transform, declutter, index ); return loading; } function renderFeatureInternal(replayGroup, feature, style, squaredTolerance, transform, declutter, index) { const geometry = style.getGeometryFunction()(feature); if (!geometry) { return; } const simplifiedGeometry = geometry.simplifyTransformed( squaredTolerance, transform ); const renderer = style.getRenderer(); if (renderer) { renderGeometry(replayGroup, simplifiedGeometry, style, feature, index); } else { const geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()]; geometryRenderer( replayGroup, simplifiedGeometry, style, feature, index, declutter ); } } function renderGeometry(replayGroup, geometry, style, feature, index) { if (geometry.getType() == "GeometryCollection") { const geometries = ( /** @type {import("../geom/GeometryCollection.js").default} */ geometry.getGeometries() ); for (let i = 0, ii = geometries.length; i < ii; ++i) { renderGeometry(replayGroup, geometries[i], style, feature, index); } return; } const replay = replayGroup.getBuilder(style.getZIndex(), "Default"); replay.drawCustom( /** @type {import("../geom/SimpleGeometry.js").default} */ geometry, feature, style.getRenderer(), style.getHitDetectionRenderer(), index ); } function renderGeometryCollectionGeometry(replayGroup, geometry, style, feature, declutterBuilderGroup, index) { const geometries = geometry.getGeometriesArray(); let i, ii; for (i = 0, ii = geometries.length; i < ii; ++i) { const geometryRenderer = GEOMETRY_RENDERERS[geometries[i].getType()]; geometryRenderer( replayGroup, geometries[i], style, feature, declutterBuilderGroup, index ); } } function renderLineStringGeometry(builderGroup, geometry, style, feature, index) { const strokeStyle = style.getStroke(); if (strokeStyle) { const lineStringReplay = builderGroup.getBuilder( style.getZIndex(), "LineString" ); lineStringReplay.setFillStrokeStyle(null, strokeStyle); lineStringReplay.drawLineString(geometry, feature, index); } const textStyle = style.getText(); if (textStyle && textStyle.getText()) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature, index); } } function renderMultiLineStringGeometry(builderGroup, geometry, style, feature, index) { const strokeStyle = style.getStroke(); if (strokeStyle) { const lineStringReplay = builderGroup.getBuilder( style.getZIndex(), "LineString" ); lineStringReplay.setFillStrokeStyle(null, strokeStyle); lineStringReplay.drawMultiLineString(geometry, feature, index); } const textStyle = style.getText(); if (textStyle && textStyle.getText()) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature, index); } } function renderMultiPolygonGeometry(builderGroup, geometry, style, feature, index) { const fillStyle = style.getFill(); const strokeStyle = style.getStroke(); if (strokeStyle || fillStyle) { const polygonReplay = builderGroup.getBuilder(style.getZIndex(), "Polygon"); polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle); polygonReplay.drawMultiPolygon(geometry, feature, index); } const textStyle = style.getText(); if (textStyle && textStyle.getText()) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature, index); } } function renderPointGeometry(builderGroup, geometry, style, feature, index, declutter) { const imageStyle = style.getImage(); const textStyle = style.getText(); const hasText = textStyle && textStyle.getText(); const declutterImageWithText = declutter && imageStyle && hasText ? {} : void 0; if (imageStyle) { if (imageStyle.getImageState() != ImageState_default.LOADED) { return; } const imageReplay = builderGroup.getBuilder(style.getZIndex(), "Image"); imageReplay.setImageStyle(imageStyle, declutterImageWithText); imageReplay.drawPoint(geometry, feature, index); } if (hasText) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle, declutterImageWithText); textReplay.drawText(geometry, feature, index); } } function renderMultiPointGeometry(builderGroup, geometry, style, feature, index, declutter) { const imageStyle = style.getImage(); const hasImage = imageStyle && imageStyle.getOpacity() !== 0; const textStyle = style.getText(); const hasText = textStyle && textStyle.getText(); const declutterImageWithText = declutter && hasImage && hasText ? {} : void 0; if (hasImage) { if (imageStyle.getImageState() != ImageState_default.LOADED) { return; } const imageReplay = builderGroup.getBuilder(style.getZIndex(), "Image"); imageReplay.setImageStyle(imageStyle, declutterImageWithText); imageReplay.drawMultiPoint(geometry, feature, index); } if (hasText) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle, declutterImageWithText); textReplay.drawText(geometry, feature, index); } } function renderPolygonGeometry(builderGroup, geometry, style, feature, index) { const fillStyle = style.getFill(); const strokeStyle = style.getStroke(); if (fillStyle || strokeStyle) { const polygonReplay = builderGroup.getBuilder(style.getZIndex(), "Polygon"); polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle); polygonReplay.drawPolygon(geometry, feature, index); } const textStyle = style.getText(); if (textStyle && textStyle.getText()) { const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text"); textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature, index); } } // node_modules/ol/renderer/canvas/VectorLayer.js var CanvasVectorLayerRenderer = class extends Layer_default { /** * @param {import("../../layer/BaseVector.js").default} vectorLayer Vector layer. */ constructor(vectorLayer) { super(vectorLayer); this.boundHandleStyleImageChange_ = this.handleStyleImageChange_.bind(this); this.animatingOrInteracting_; this.hitDetectionImageData_ = null; this.clipped_ = false; this.renderedFeatures_ = null; this.renderedRevision_ = -1; this.renderedResolution_ = NaN; this.renderedExtent_ = createEmpty(); this.wrappedRenderedExtent_ = createEmpty(); this.renderedRotation_; this.renderedCenter_ = null; this.renderedProjection_ = null; this.renderedPixelRatio_ = 1; this.renderedRenderOrder_ = null; this.renderedFrameDeclutter_; this.replayGroup_ = null; this.replayGroupChanged = true; this.clipping = true; this.targetContext_ = null; this.opacity_ = 1; } /** * @param {ExecutorGroup} executorGroup Executor group. * @param {import("../../Map.js").FrameState} frameState Frame state. * @param {boolean} [declutterable] `true` to only render declutterable items, * `false` to only render non-declutterable items, `undefined` to render all. */ renderWorlds(executorGroup, frameState, declutterable) { const extent = frameState.extent; const viewState = frameState.viewState; const center = viewState.center; const resolution = viewState.resolution; const projection = viewState.projection; const rotation = viewState.rotation; const projectionExtent = projection.getExtent(); const vectorSource = this.getLayer().getSource(); const declutter = this.getLayer().getDeclutter(); const pixelRatio = frameState.pixelRatio; const viewHints = frameState.viewHints; const snapToPixel = !(viewHints[ViewHint_default.ANIMATING] || viewHints[ViewHint_default.INTERACTING]); const context = this.context; const width = Math.round(getWidth(extent) / resolution * pixelRatio); const height = Math.round(getHeight(extent) / resolution * pixelRatio); const multiWorld = vectorSource.getWrapX() && projection.canWrapX(); const worldWidth = multiWorld ? getWidth(projectionExtent) : null; const endWorld = multiWorld ? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1 : 1; let world = multiWorld ? Math.floor((extent[0] - projectionExtent[0]) / worldWidth) : 0; do { let transform = this.getRenderTransform( center, resolution, 0, pixelRatio, width, height, world * worldWidth ); if (frameState.declutter) { transform = transform.slice(0); } executorGroup.execute( context, [context.canvas.width, context.canvas.height], transform, rotation, snapToPixel, declutterable === void 0 ? ALL : declutterable ? DECLUTTER : NON_DECLUTTER, declutterable ? declutter && frameState.declutter[declutter] : void 0 ); } while (++world < endWorld); } /** * @private */ setDrawContext_() { if (this.opacity_ !== 1) { this.targetContext_ = this.context; this.context = createCanvasContext2D( this.context.canvas.width, this.context.canvas.height, canvasPool ); } } /** * @private */ resetDrawContext_() { if (this.opacity_ !== 1 && this.targetContext_) { const alpha = this.targetContext_.globalAlpha; this.targetContext_.globalAlpha = this.opacity_; this.targetContext_.drawImage(this.context.canvas, 0, 0); this.targetContext_.globalAlpha = alpha; releaseCanvas(this.context); canvasPool.push(this.context.canvas); this.context = this.targetContext_; this.targetContext_ = null; } } /** * Render declutter items for this layer * @param {import("../../Map.js").FrameState} frameState Frame state. */ renderDeclutter(frameState) { if (!this.replayGroup_ || !this.getLayer().getDeclutter()) { return; } this.renderWorlds(this.replayGroup_, frameState, true); } /** * Render deferred instructions. * @param {import("../../Map.js").FrameState} frameState Frame state. * @override */ renderDeferredInternal(frameState) { if (!this.replayGroup_) { return; } this.replayGroup_.renderDeferred(); if (this.clipped_) { this.context.restore(); } this.resetDrawContext_(); } /** * Render the layer. * @param {import("../../Map.js").FrameState} frameState Frame state. * @param {HTMLElement|null} target Target that may be used to render content to. * @return {HTMLElement} The rendered element. * @override */ renderFrame(frameState, target) { const layerState = frameState.layerStatesArray[frameState.layerIndex]; this.opacity_ = layerState.opacity; const viewState = frameState.viewState; this.prepareContainer(frameState, target); const context = this.context; const replayGroup = this.replayGroup_; let render = replayGroup && !replayGroup.isEmpty(); if (!render) { const hasRenderListeners = this.getLayer().hasListener(EventType_default.PRERENDER) || this.getLayer().hasListener(EventType_default.POSTRENDER); if (!hasRenderListeners) { return this.container; } } this.setDrawContext_(); this.preRender(context, frameState); const projection = viewState.projection; this.clipped_ = false; if (render && layerState.extent && this.clipping) { const layerExtent = fromUserExtent(layerState.extent, projection); render = intersects(layerExtent, frameState.extent); this.clipped_ = render && !containsExtent(layerExtent, frameState.extent); if (this.clipped_) { this.clipUnrotated(context, frameState, layerExtent); } } if (render) { this.renderWorlds( replayGroup, frameState, this.getLayer().getDeclutter() ? false : void 0 ); } if (!frameState.declutter && this.clipped_) { context.restore(); } this.postRender(context, frameState); if (this.renderedRotation_ !== viewState.rotation) { this.renderedRotation_ = viewState.rotation; this.hitDetectionImageData_ = null; } if (!frameState.declutter) { this.resetDrawContext_(); } return this.container; } /** * Asynchronous layer level hit detection. * @param {import("../../pixel.js").Pixel} pixel Pixel. * @return {Promise>} Promise * that resolves with an array of features. * @override */ getFeatures(pixel) { return new Promise((resolve) => { if (this.frameState && !this.hitDetectionImageData_ && !this.animatingOrInteracting_) { const size = this.frameState.size.slice(); const center = this.renderedCenter_; const resolution = this.renderedResolution_; const rotation = this.renderedRotation_; const projection = this.renderedProjection_; const extent = this.wrappedRenderedExtent_; const layer = this.getLayer(); const transforms = []; const width = size[0] * HIT_DETECT_RESOLUTION; const height = size[1] * HIT_DETECT_RESOLUTION; transforms.push( this.getRenderTransform( center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, 0 ).slice() ); const source = layer.getSource(); const projectionExtent = projection.getExtent(); if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) { let startX = extent[0]; const worldWidth = getWidth(projectionExtent); let world = 0; let offsetX; while (startX < projectionExtent[0]) { --world; offsetX = worldWidth * world; transforms.push( this.getRenderTransform( center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, offsetX ).slice() ); startX += worldWidth; } world = 0; startX = extent[2]; while (startX > projectionExtent[2]) { ++world; offsetX = worldWidth * world; transforms.push( this.getRenderTransform( center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, offsetX ).slice() ); startX -= worldWidth; } } const userProjection = getUserProjection(); this.hitDetectionImageData_ = createHitDetectionImageData( size, transforms, this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation, getSquaredTolerance(resolution, this.renderedPixelRatio_), userProjection ? projection : null ); } resolve( hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_) ); }); } /** * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate. * @param {import("../../Map.js").FrameState} frameState Frame state. * @param {number} hitTolerance Hit tolerance in pixels. * @param {import("../vector.js").FeatureCallback} callback Feature callback. * @param {Array>} matches The hit detected matches with tolerance. * @return {T|undefined} Callback result. * @template T * @override */ forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, matches) { var _a, _b; if (!this.replayGroup_) { return void 0; } const resolution = frameState.viewState.resolution; const rotation = frameState.viewState.rotation; const layer = this.getLayer(); const features = {}; const featureCallback = function(feature, geometry, distanceSq) { const key = getUid(feature); const match = features[key]; if (!match) { if (distanceSq === 0) { features[key] = true; return callback(feature, layer, geometry); } matches.push( features[key] = { feature, layer, geometry, distanceSq, callback } ); } else if (match !== true && distanceSq < match.distanceSq) { if (distanceSq === 0) { features[key] = true; matches.splice(matches.lastIndexOf(match), 1); return callback(feature, layer, geometry); } match.geometry = geometry; match.distanceSq = distanceSq; } return void 0; }; const declutter = this.getLayer().getDeclutter(); return this.replayGroup_.forEachFeatureAtCoordinate( coordinate, resolution, rotation, hitTolerance, featureCallback, declutter ? (_b = (_a = frameState.declutter) == null ? void 0 : _a[declutter]) == null ? void 0 : _b.all().map((item) => item.value) : null ); } /** * Perform action necessary to get the layer rendered after new fonts have loaded * @override */ handleFontsChanged() { const layer = this.getLayer(); if (layer.getVisible() && this.replayGroup_) { layer.changed(); } } /** * Handle changes in image style state. * @param {import("../../events/Event.js").default} event Image style change event. * @private */ handleStyleImageChange_(event) { this.renderIfReadyAndVisible(); } /** * Determine whether render should be called. * @param {import("../../Map.js").FrameState} frameState Frame state. * @return {boolean} Layer is ready to be rendered. * @override */ prepareFrame(frameState) { const vectorLayer = this.getLayer(); const vectorSource = vectorLayer.getSource(); if (!vectorSource) { return false; } const animating = frameState.viewHints[ViewHint_default.ANIMATING]; const interacting = frameState.viewHints[ViewHint_default.INTERACTING]; const updateWhileAnimating = vectorLayer.getUpdateWhileAnimating(); const updateWhileInteracting = vectorLayer.getUpdateWhileInteracting(); if (this.ready && !updateWhileAnimating && animating || !updateWhileInteracting && interacting) { this.animatingOrInteracting_ = true; return true; } this.animatingOrInteracting_ = false; const frameStateExtent = frameState.extent; const viewState = frameState.viewState; const projection = viewState.projection; const resolution = viewState.resolution; const pixelRatio = frameState.pixelRatio; const vectorLayerRevision = vectorLayer.getRevision(); const vectorLayerRenderBuffer = vectorLayer.getRenderBuffer(); let vectorLayerRenderOrder = vectorLayer.getRenderOrder(); if (vectorLayerRenderOrder === void 0) { vectorLayerRenderOrder = defaultOrder; } const center = viewState.center.slice(); const extent = buffer( frameStateExtent, vectorLayerRenderBuffer * resolution ); const renderedExtent = extent.slice(); const loadExtents = [extent.slice()]; const projectionExtent = projection.getExtent(); if (vectorSource.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, frameState.extent)) { const worldWidth = getWidth(projectionExtent); const gutter = Math.max(getWidth(extent) / 2, worldWidth); extent[0] = projectionExtent[0] - gutter; extent[2] = projectionExtent[2] + gutter; wrapX2(center, projection); const loadExtent = wrapX(loadExtents[0], projection); if (loadExtent[0] < projectionExtent[0] && loadExtent[2] < projectionExtent[2]) { loadExtents.push([ loadExtent[0] + worldWidth, loadExtent[1], loadExtent[2] + worldWidth, loadExtent[3] ]); } else if (loadExtent[0] > projectionExtent[0] && loadExtent[2] > projectionExtent[2]) { loadExtents.push([ loadExtent[0] - worldWidth, loadExtent[1], loadExtent[2] - worldWidth, loadExtent[3] ]); } } if (this.ready && this.renderedResolution_ == resolution && this.renderedRevision_ == vectorLayerRevision && this.renderedRenderOrder_ == vectorLayerRenderOrder && this.renderedFrameDeclutter_ === !!frameState.declutter && containsExtent(this.wrappedRenderedExtent_, extent)) { if (!equals(this.renderedExtent_, renderedExtent)) { this.hitDetectionImageData_ = null; this.renderedExtent_ = renderedExtent; } this.renderedCenter_ = center; this.replayGroupChanged = false; return true; } this.replayGroup_ = null; const replayGroup = new BuilderGroup_default( getTolerance(resolution, pixelRatio), extent, resolution, pixelRatio ); const userProjection = getUserProjection(); let userTransform; if (userProjection) { for (let i = 0, ii = loadExtents.length; i < ii; ++i) { const extent2 = loadExtents[i]; const userExtent2 = toUserExtent(extent2, projection); vectorSource.loadFeatures( userExtent2, toUserResolution(resolution, projection), userProjection ); } userTransform = getTransformFromProjections(userProjection, projection); } else { for (let i = 0, ii = loadExtents.length; i < ii; ++i) { vectorSource.loadFeatures(loadExtents[i], resolution, projection); } } const squaredTolerance = getSquaredTolerance(resolution, pixelRatio); let ready = true; const render = ( /** * @param {import("../../Feature.js").default} feature Feature. * @param {number} index Index. */ (feature, index) => { let styles; const styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction(); if (styleFunction) { styles = styleFunction(feature, resolution); } if (styles) { const dirty = this.renderFeature( feature, squaredTolerance, styles, replayGroup, userTransform, this.getLayer().getDeclutter(), index ); ready = ready && !dirty; } } ); const userExtent = toUserExtent(extent, projection); const features = vectorSource.getFeaturesInExtent(userExtent); if (vectorLayerRenderOrder) { features.sort(vectorLayerRenderOrder); } for (let i = 0, ii = features.length; i < ii; ++i) { render(features[i], i); } this.renderedFeatures_ = features; this.ready = ready; const replayGroupInstructions = replayGroup.finish(); const executorGroup = new ExecutorGroup_default( extent, resolution, pixelRatio, vectorSource.getOverlaps(), replayGroupInstructions, vectorLayer.getRenderBuffer(), !!frameState.declutter ); this.renderedResolution_ = resolution; this.renderedRevision_ = vectorLayerRevision; this.renderedRenderOrder_ = vectorLayerRenderOrder; this.renderedFrameDeclutter_ = !!frameState.declutter; this.renderedExtent_ = renderedExtent; this.wrappedRenderedExtent_ = extent; this.renderedCenter_ = center; this.renderedProjection_ = projection; this.renderedPixelRatio_ = pixelRatio; this.replayGroup_ = executorGroup; this.hitDetectionImageData_ = null; this.replayGroupChanged = true; return true; } /** * @param {import("../../Feature.js").default} feature Feature. * @param {number} squaredTolerance Squared render tolerance. * @param {import("../../style/Style.js").default|Array} styles The style or array of styles. * @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Builder group. * @param {import("../../proj.js").TransformFunction} [transform] Transform from user to view projection. * @param {boolean} [declutter] Enable decluttering. * @param {number} [index] Render order index. * @return {boolean} `true` if an image is loading. */ renderFeature(feature, squaredTolerance, styles, builderGroup, transform, declutter, index) { if (!styles) { return false; } let loading = false; if (Array.isArray(styles)) { for (let i = 0, ii = styles.length; i < ii; ++i) { loading = renderFeature( builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, transform, declutter, index ) || loading; } } else { loading = renderFeature( builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, transform, declutter, index ); } return loading; } }; var VectorLayer_default = CanvasVectorLayerRenderer; // node_modules/ol/layer/Vector.js var VectorLayer = class extends BaseVector_default { /** * @param {Options} [options] Options. */ constructor(options) { super(options); } /** * @override */ createRenderer() { return new VectorLayer_default(this); } }; var Vector_default = VectorLayer; export { Immediate_default, getSquaredTolerance, renderFeature, BuilderGroup_default, DECLUTTER, ExecutorGroup_default, HIT_DETECT_RESOLUTION, createHitDetectionImageData, hitDetect, VectorLayer_default, Vector_default }; //# sourceMappingURL=chunk-2RRPH7ER.js.map