react-spatial 1.11.5-beta.7 → 1.11.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -124,13 +124,17 @@ const propTypes = {
|
|
|
124
124
|
paddingBottom: PropTypes.number,
|
|
125
125
|
paddingBackground: PropTypes.number
|
|
126
126
|
})
|
|
127
|
-
})
|
|
127
|
+
}),
|
|
128
|
+
/**
|
|
129
|
+
* Return the file name of the image to download.
|
|
130
|
+
*/
|
|
131
|
+
getDownloadImageName: PropTypes.func
|
|
128
132
|
};
|
|
129
133
|
const getMargin = (destCanvas) => {
|
|
130
134
|
const newMargin = destCanvas.width / 100;
|
|
131
135
|
return newMargin;
|
|
132
136
|
};
|
|
133
|
-
const
|
|
137
|
+
const getDefaultDownloadImageName = (format) => {
|
|
134
138
|
const fileExt = format === "image/jpeg" ? "jpg" : "png";
|
|
135
139
|
return `${window.document.title.replace(/ /g, "_").toLowerCase()}.${fileExt}`;
|
|
136
140
|
};
|
|
@@ -378,7 +382,7 @@ const createCanvasImage = (mapToExport, extraData, scale, extent, coordinates, m
|
|
|
378
382
|
mapToExport.renderSync();
|
|
379
383
|
});
|
|
380
384
|
};
|
|
381
|
-
const downloadCanvasImage = (canvas, format) => {
|
|
385
|
+
const downloadCanvasImage = (canvas, format, getDownloadImageName) => {
|
|
382
386
|
const promise = new Promise((resolve) => {
|
|
383
387
|
if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {
|
|
384
388
|
const url = canvas.toDataURL(format);
|
|
@@ -422,6 +426,7 @@ function CanvasSaveButton({
|
|
|
422
426
|
extent = null,
|
|
423
427
|
coordinates = null,
|
|
424
428
|
scale = 1,
|
|
429
|
+
getDownloadImageName = getDefaultDownloadImageName,
|
|
425
430
|
onSaveStart = (mapp) => {
|
|
426
431
|
return Promise.resolve(mapp);
|
|
427
432
|
},
|
|
@@ -447,9 +452,11 @@ function CanvasSaveButton({
|
|
|
447
452
|
padding
|
|
448
453
|
).then((canvas) => {
|
|
449
454
|
if (autoDownload) {
|
|
450
|
-
downloadCanvasImage(canvas, format).then(
|
|
451
|
-
|
|
452
|
-
|
|
455
|
+
downloadCanvasImage(canvas, format, getDownloadImageName).then(
|
|
456
|
+
(blob) => {
|
|
457
|
+
onSaveEnd(mapToExport, canvas, blob);
|
|
458
|
+
}
|
|
459
|
+
);
|
|
453
460
|
} else {
|
|
454
461
|
onSaveEnd(mapToExport, canvas);
|
|
455
462
|
}
|
|
@@ -472,7 +479,8 @@ function CanvasSaveButton({
|
|
|
472
479
|
onSaveEnd,
|
|
473
480
|
onSaveStart,
|
|
474
481
|
padding,
|
|
475
|
-
scale
|
|
482
|
+
scale,
|
|
483
|
+
getDownloadImageName
|
|
476
484
|
]
|
|
477
485
|
);
|
|
478
486
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, React.Children.map(children, (child) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/CanvasSaveButton/CanvasSaveButton.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-param-reassign */\nimport React, { useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport OLMap from \"ol/Map\";\nimport { getTopLeft, getBottomRight } from \"ol/extent\";\nimport NorthArrowSimple from \"../../images/northArrow.url.svg\";\nimport NorthArrowCircle from \"../../images/northArrowCircle.url.svg\";\n\nconst extraDataImgPropType = PropTypes.shape({\n src: PropTypes.string,\n width: PropTypes.number,\n height: PropTypes.number,\n rotation: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),\n circled: PropTypes.bool,\n});\n\n// support server-side rendering where `Element` will not be defined\nconst CanvasPatternType =\n typeof CanvasPattern === \"undefined\" ? Function : CanvasPattern;\n\nconst propTypes = {\n /**\n * Automatically download the image saved.\n */\n autoDownload: PropTypes.bool,\n\n /**\n * Children content of the button.\n */\n children: PropTypes.node,\n\n /**\n * Output format of the image.\n */\n format: PropTypes.oneOf([\"image/jpeg\", \"image/png\"]),\n\n /** An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). */\n map: PropTypes.instanceOf(OLMap),\n\n /**\n * Space (in pixels) between the border of the canvas and the elements.\n * Default to 1% of the canvas width.\n */\n margin: PropTypes.number,\n\n /**\n * Space (in pixels) between elements.\n * Default to 5px.\n */\n padding: PropTypes.number,\n\n /**\n * Extent for the export. If no extent is given, the whole map is exported.\n */\n extent: PropTypes.arrayOf(PropTypes.number),\n\n /**\n * Array of 4 [ol/Coordinate](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~Coordinate).\n * If no coordinates and no extent are given, the whole map is exported.\n * This property must be used to export rotated map.\n * If you don't need to export rotated map the extent property can be used as well.\n * If extent is specified, coordinates property is ignored.\n */\n coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),\n\n /**\n * Scale the map for better quality. Possible values: 1, 2 or 3.\n * WARNING: The tiled layer with a WMTS or XYZ source must provides an url\n * for each scale in the config file.\n */\n scale: PropTypes.number,\n\n /**\n * Function called before the dowload process begins.\n */\n onSaveStart: PropTypes.func,\n\n /**\n * Function called after the dowload process ends.\n *\n * @param {object} error Error message the process fails.\n */\n onSaveEnd: PropTypes.func,\n\n /**\n * Extra data, such as copyright, north arrow configuration.\n * All extra data is optional.\n *\n * Example 1:\n *\n {\n copyright: {\n text: 'Example copyright', // Copyright text or function\n font: '10px Arial', // Font, default is '12px Arial'\n fillStyle: 'blue', // Fill style, default is 'black'\n },\n northArrow, // True if the north arrow\n // should be placed with default configuration\n // (default image, rotation=0, circled=false)\n }\n * Example 2:\n *\n {\n northArrow: {\n src: NorthArrowCustom,\n width: 60, // Width in px, default is 80\n height: 100, // Height in px, default is 80\n rotation: 25, // Absolute rotation in degrees as number or function\n\n }\n }\n * Example 3:\n *\n {\n copyright: {\n text: () => { // Copyright as function\n return this.copyright;\n },\n },\n northArrow: {\n rotation: () => { // Rotation as function\n return NorthArrow.radToDeg(this.map.getView().getRotation());\n },\n circled, // Display circle around the north arrow (Does not work for custom src)\n },\n }\n */\n extraData: PropTypes.shape({\n logo: extraDataImgPropType,\n northArrow: extraDataImgPropType,\n qrCode: extraDataImgPropType,\n copyright: PropTypes.shape({\n text: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n font: PropTypes.string,\n fillStyle: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.instanceOf(CanvasPatternType),\n ]),\n background: PropTypes.bool,\n maxWidth: PropTypes.number,\n paddingBottom: PropTypes.number,\n paddingBackground: PropTypes.number,\n }),\n }),\n};\n\nconst getMargin = (destCanvas) => {\n const newMargin = destCanvas.width / 100; // 1% of the canvas width\n return newMargin;\n};\n\nconst getDownloadImageName = (format) => {\n const fileExt = format === \"image/jpeg\" ? \"jpg\" : \"png\";\n return `${window.document.title.replace(/ /g, \"_\").toLowerCase()}.${fileExt}`;\n};\n\nlet multilineCopyright = false;\nlet copyrightY = 0;\n\n// Ensure the font size fita with the image width.\nconst decreaseFontSize = (destContext, maxWidth, copyright, scale) => {\n const minFontSize = 8;\n let sizeMatch;\n let fontSize;\n do {\n sizeMatch = destContext.font.match(/[0-9]+(?:\\.[0-9]+)?(px)/i);\n fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], \"\"), 10);\n\n // eslint-disable-next-line no-param-reassign\n destContext.font = destContext.font.replace(fontSize, fontSize - 1);\n\n multilineCopyright = false;\n\n if (fontSize - 1 === minFontSize) {\n multilineCopyright = true;\n }\n } while (\n fontSize - 1 > minFontSize &&\n destContext.measureText(copyright).width * scale > maxWidth\n );\n\n return destContext.font;\n};\n\n// eslint-disable-next-line class-methods-use-this\nconst drawTextBackground = (\n destContext,\n x,\n y,\n width,\n height,\n styleOptions = {},\n) => {\n destContext.save();\n // Dflt is a white background\n destContext.fillStyle = \"rgba(255,255,255,.8)\";\n\n // To simplify usability the user could pass a boolean to use only default values.\n if (typeof styleOptions === \"object\") {\n Object.entries(styleOptions).forEach(([key, value]) => {\n destContext[key] = value;\n });\n }\n\n /// draw background rect assuming height of font\n destContext.fillRect(x, y, width, height);\n destContext.restore();\n};\n\nconst drawCopyright = (\n destContext,\n destCanvas,\n maxWidth,\n extraData,\n scale,\n margin,\n padding,\n) => {\n const { text, font, fillStyle, background } = extraData.copyright;\n const { paddingBottom = padding, paddingBackground = 2 } =\n extraData.copyright;\n\n let copyright = typeof text === \"function\" ? text() : text?.trim();\n\n if (Array.isArray(copyright)) {\n copyright = copyright.join();\n }\n\n destContext.save();\n destContext.scale(scale, scale);\n destContext.font = font || \"12px Arial\";\n destContext.font = decreaseFontSize(destContext, maxWidth, copyright, scale);\n destContext.textBaseline = \"bottom\";\n destContext.scale(scale, scale);\n destContext.fillStyle = fillStyle || \"black\";\n\n // We search if the display on 2 line is necessary\n let firstLine = copyright;\n let firstLineMetrics = destContext.measureText(firstLine);\n\n // If the text is bigger than the max width we split it into 2 lines\n if (multilineCopyright) {\n const wordNumber = copyright.split(\" \").length;\n for (let i = 0; i < wordNumber; i += 1) {\n // Stop removing word when fits within one line.\n if (firstLineMetrics.width * scale < maxWidth) {\n break;\n }\n firstLine = firstLine.substring(0, firstLine.lastIndexOf(\" \"));\n firstLineMetrics = destContext.measureText(firstLine);\n }\n }\n\n // Define second line if necessary\n const secondLine = copyright.replace(firstLine, \"\").trim();\n\n // At this point we the number of lines to display.\n const lines = [firstLine, secondLine].filter((l) => !!l).reverse();\n\n // We draw from bottom to top because textBaseline is 'bottom\n let lineX = margin;\n let lineY = destCanvas.height - paddingBottom; // we apply the margin only on the left side\n\n lines.forEach((line) => {\n const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } =\n destContext.measureText(line);\n const height = fontBoundingBoxAscent + fontBoundingBoxDescent; // we include paddingBackground to have a bit of distance between lines\n let lineTop = lineY - height;\n\n if (background) {\n const backgroundX = margin;\n lineTop -= paddingBackground * 2;\n drawTextBackground(\n destContext,\n backgroundX,\n lineTop,\n width + paddingBackground * 2,\n height + paddingBackground * 2,\n background,\n );\n lineX += paddingBackground;\n lineY -= paddingBackground;\n }\n\n destContext.fillText(line, lineX, lineY);\n lineY = lineTop;\n });\n\n copyrightY = lineY;\n destContext.restore();\n};\n\nconst drawElement = (\n data,\n destCanvas,\n scale,\n margin,\n padding,\n previousItemSize = [0, 0],\n side = \"right\",\n) => {\n const destContext = destCanvas.getContext(\"2d\");\n const { src, width, height, rotation } = data;\n\n return new Promise((resolve) => {\n const img = new Image();\n img.crossOrigin = \"Anonymous\";\n img.src = src;\n img.onload = () => {\n destContext.save();\n const elementWidth = (width || 80) * scale;\n const elementHeight = (height || 80) * scale;\n const left =\n side === \"left\"\n ? margin + elementWidth / 2\n : destCanvas.width - margin - elementWidth / 2;\n const top =\n (side === \"left\" && copyrightY\n ? copyrightY - padding\n : destCanvas.height) -\n margin -\n elementHeight / 2 -\n previousItemSize[1];\n\n destContext.translate(left, top);\n\n if (rotation) {\n const angle = typeof rotation === \"function\" ? rotation() : rotation;\n destContext.rotate(angle * (Math.PI / 180));\n }\n\n destContext.drawImage(\n img,\n -elementWidth / 2,\n -elementHeight / 2,\n elementWidth,\n elementHeight,\n );\n destContext.restore();\n\n // Return the pixels width of the arrow and the margin right,\n // that must not be occupied by the copyright.\n resolve([elementWidth + 2 * padding, elementHeight + 2 * padding]);\n };\n\n img.onerror = () => {\n resolve();\n };\n });\n};\n\nconst calculatePixelsToExport = (mapToExport, extent, coordinates) => {\n let firstCoordinate;\n let oppositeCoordinate;\n\n if (extent) {\n firstCoordinate = getTopLeft(extent);\n oppositeCoordinate = getBottomRight(extent);\n } else if (coordinates) {\n // In case of coordinates coming from DragBox interaction:\n // firstCoordinate is the first coordinate drawn by the user.\n // oppositeCoordinate is the coordinate of the point dragged by the user.\n [firstCoordinate, , oppositeCoordinate] = coordinates;\n }\n\n if (firstCoordinate && oppositeCoordinate) {\n const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);\n const oppositePixel =\n mapToExport.getPixelFromCoordinate(oppositeCoordinate);\n const pixelTopLeft = [\n firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n const pixelBottomRight = [\n firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n\n return {\n x: pixelTopLeft[0],\n y: pixelTopLeft[1],\n w: pixelBottomRight[0] - pixelTopLeft[0],\n h: pixelBottomRight[1] - pixelTopLeft[1],\n };\n }\n return null;\n};\n\nconst createCanvasImage = (\n mapToExport,\n extraData,\n scale,\n extent,\n coordinates,\n margin,\n padding,\n) => {\n return new Promise((resolve) => {\n mapToExport.once(\"rendercomplete\", () => {\n // Find all layer canvases and add it to dest canvas.\n const canvases = mapToExport\n .getTargetElement()\n .getElementsByTagName(\"canvas\");\n\n // Create the canvas to export with the good size.\n let destCanvas;\n let destContext;\n\n // canvases is an HTMLCollection, we don't try to transform to array because some compilers like cra doesn't translate it right.\n for (let i = 0; i < canvases.length; i += 1) {\n const canvas = canvases[i];\n if (!canvas.width || !canvas.height) {\n // eslint-disable-next-line no-continue\n continue;\n }\n const clip = calculatePixelsToExport(\n mapToExport,\n extent,\n coordinates,\n ) || {\n x: 0,\n y: 0,\n w: canvas.width,\n h: canvas.height,\n };\n\n if (!destCanvas) {\n destCanvas = document.createElement(\"canvas\");\n destCanvas.width = clip.w;\n destCanvas.height = clip.h;\n destContext = destCanvas.getContext(\"2d\");\n }\n\n // Draw canvas to the canvas to export.\n destContext.drawImage(\n canvas,\n clip.x,\n clip.y,\n clip.w,\n clip.h,\n 0,\n 0,\n destCanvas.width,\n destCanvas.height,\n );\n }\n\n margin = margin || getMargin(destCanvas);\n\n // Custom info\n let logoPromise = Promise.resolve();\n if (destContext && extraData && extraData.logo) {\n logoPromise = drawElement(\n extraData.logo,\n destCanvas,\n scale,\n margin,\n padding,\n );\n }\n\n logoPromise.then((logoSize = [0, 0]) => {\n // North arrow\n let arrowPromise = Promise.resolve();\n if (destContext && extraData && extraData.northArrow) {\n arrowPromise = drawElement(\n {\n src: extraData.northArrow.circled\n ? NorthArrowCircle\n : NorthArrowSimple,\n ...extraData.northArrow,\n },\n destCanvas,\n scale,\n margin,\n padding,\n logoSize,\n );\n }\n\n // Copyright\n arrowPromise.then((arrowSize = [0, 0]) => {\n const widestElement = Math.max(logoSize[0], arrowSize[0]);\n if (\n destContext &&\n extraData &&\n extraData.copyright &&\n extraData.copyright.text\n ) {\n const maxWidth =\n extraData.copyright.maxWidth ||\n (widestElement\n ? destContext.canvas.width - widestElement - margin\n : destContext.canvas.width);\n drawCopyright(\n destContext,\n destCanvas,\n maxWidth,\n extraData,\n scale,\n margin,\n padding,\n );\n }\n let qrCodePromise = Promise.resolve();\n if (destContext && extraData && extraData.qrCode) {\n qrCodePromise = drawElement(\n extraData.qrCode,\n destCanvas,\n scale,\n margin,\n padding,\n undefined,\n \"left\",\n );\n }\n qrCodePromise.then(() => {\n return resolve(destCanvas);\n });\n });\n });\n });\n mapToExport.renderSync();\n });\n};\n\nconst downloadCanvasImage = (canvas, format) => {\n // Use blob for large images\n const promise = new Promise((resolve) => {\n if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {\n // ie 9 and 10\n const url = canvas.toDataURL(format);\n const w = window.open(\"about:blank\", \"\");\n w.document.write(`<img src=\"${url}\" alt=\"from canvas\"/>`);\n resolve(url);\n }\n if (window.navigator.msSaveBlob) {\n // ie 11 and higher\n let image;\n try {\n image = canvas.msToBlob();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log(e);\n }\n const blob = new Blob([image], {\n type: format,\n });\n resolve(blob);\n window.navigator.msSaveBlob(blob, getDownloadImageName(format));\n } else {\n canvas.toBlob((blob) => {\n const link = document.createElement(\"a\");\n link.download = getDownloadImageName(format);\n link.href = URL.createObjectURL(blob);\n // append child to document for firefox to be able to download.\n document.body.appendChild(link);\n link.click();\n resolve(blob);\n }, format);\n }\n });\n return promise;\n};\n\n/**\n * The CanvasSaveButton component creates a button to save\n * an [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html)\n * canvas as an image.\n */\nfunction CanvasSaveButton({\n margin = null,\n padding = 5,\n autoDownload = true,\n children = null,\n map = null,\n format = \"image/png\",\n extraData = null,\n extent = null,\n coordinates = null,\n scale = 1,\n onSaveStart = (mapp) => {\n return Promise.resolve(mapp);\n },\n onSaveEnd = () => {},\n}) {\n const onClick = useCallback(\n (evt) => {\n if (window.navigator.msSaveBlob) {\n // ie only\n evt.preventDefault();\n evt.stopPropagation();\n }\n multilineCopyright = false;\n copyrightY = 0;\n onSaveStart(map).then((mapToExport) => {\n return createCanvasImage(\n mapToExport || map,\n extraData,\n scale,\n extent,\n coordinates,\n margin,\n padding,\n )\n .then((canvas) => {\n if (autoDownload) {\n downloadCanvasImage(canvas, format).then((blob) => {\n onSaveEnd(mapToExport, canvas, blob);\n });\n } else {\n onSaveEnd(mapToExport, canvas);\n }\n })\n .catch((err) => {\n if (err) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n onSaveEnd(mapToExport, err);\n });\n });\n },\n [\n autoDownload,\n coordinates,\n extent,\n extraData,\n format,\n map,\n margin,\n onSaveEnd,\n onSaveStart,\n padding,\n scale,\n ],\n );\n\n return (\n <>\n {React.Children.map(children, (child) => {\n return React.cloneElement(child, { onClick });\n })}\n </>\n );\n}\n\nCanvasSaveButton.propTypes = propTypes;\n\nexport default CanvasSaveButton;\n"],
|
|
5
|
-
"mappings": "AACA,OAAO,SAAS,mBAAmB;AACnC,OAAO,eAAe;AACtB,OAAO,WAAW;AAClB,SAAS,YAAY,sBAAsB;AAC3C,OAAO,sBAAsB;AAC7B,OAAO,sBAAsB;AAE7B,MAAM,uBAAuB,UAAU,MAAM;AAAA,EAC3C,KAAK,UAAU;AAAA,EACf,OAAO,UAAU;AAAA,EACjB,QAAQ,UAAU;AAAA,EAClB,UAAU,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,IAAI,CAAC;AAAA,EAChE,SAAS,UAAU;AACrB,CAAC;AAGD,MAAM,oBACJ,OAAO,kBAAkB,cAAc,WAAW;AAEpD,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA,EAIhB,cAAc,UAAU;AAAA;AAAA;AAAA;AAAA,EAKxB,UAAU,UAAU;AAAA;AAAA;AAAA;AAAA,EAKpB,QAAQ,UAAU,MAAM,CAAC,cAAc,WAAW,CAAC;AAAA;AAAA,EAGnD,KAAK,UAAU,WAAW,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,QAAQ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,SAAS,UAAU;AAAA;AAAA;AAAA;AAAA,EAKnB,QAAQ,UAAU,QAAQ,UAAU,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1C,aAAa,UAAU,QAAQ,UAAU,QAAQ,UAAU,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlE,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,EAKjB,aAAa,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOvB,WAAW,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6CrB,WAAW,UAAU,MAAM;AAAA,IACzB,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,WAAW,UAAU,MAAM;AAAA,MACzB,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC5D,MAAM,UAAU;AAAA,MAChB,WAAW,UAAU,UAAU;AAAA,QAC7B,UAAU;AAAA,QACV,UAAU,WAAW,iBAAiB;AAAA,MACxC,CAAC;AAAA,MACD,YAAY,UAAU;AAAA,MACtB,UAAU,UAAU;AAAA,MACpB,eAAe,UAAU;AAAA,MACzB,mBAAmB,UAAU;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-param-reassign */\nimport React, { useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport OLMap from \"ol/Map\";\nimport { getTopLeft, getBottomRight } from \"ol/extent\";\nimport NorthArrowSimple from \"../../images/northArrow.url.svg\";\nimport NorthArrowCircle from \"../../images/northArrowCircle.url.svg\";\n\nconst extraDataImgPropType = PropTypes.shape({\n src: PropTypes.string,\n width: PropTypes.number,\n height: PropTypes.number,\n rotation: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),\n circled: PropTypes.bool,\n});\n\n// support server-side rendering where `Element` will not be defined\nconst CanvasPatternType =\n typeof CanvasPattern === \"undefined\" ? Function : CanvasPattern;\n\nconst propTypes = {\n /**\n * Automatically download the image saved.\n */\n autoDownload: PropTypes.bool,\n\n /**\n * Children content of the button.\n */\n children: PropTypes.node,\n\n /**\n * Output format of the image.\n */\n format: PropTypes.oneOf([\"image/jpeg\", \"image/png\"]),\n\n /** An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). */\n map: PropTypes.instanceOf(OLMap),\n\n /**\n * Space (in pixels) between the border of the canvas and the elements.\n * Default to 1% of the canvas width.\n */\n margin: PropTypes.number,\n\n /**\n * Space (in pixels) between elements.\n * Default to 5px.\n */\n padding: PropTypes.number,\n\n /**\n * Extent for the export. If no extent is given, the whole map is exported.\n */\n extent: PropTypes.arrayOf(PropTypes.number),\n\n /**\n * Array of 4 [ol/Coordinate](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~Coordinate).\n * If no coordinates and no extent are given, the whole map is exported.\n * This property must be used to export rotated map.\n * If you don't need to export rotated map the extent property can be used as well.\n * If extent is specified, coordinates property is ignored.\n */\n coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),\n\n /**\n * Scale the map for better quality. Possible values: 1, 2 or 3.\n * WARNING: The tiled layer with a WMTS or XYZ source must provides an url\n * for each scale in the config file.\n */\n scale: PropTypes.number,\n\n /**\n * Function called before the dowload process begins.\n */\n onSaveStart: PropTypes.func,\n\n /**\n * Function called after the dowload process ends.\n *\n * @param {object} error Error message the process fails.\n */\n onSaveEnd: PropTypes.func,\n\n /**\n * Extra data, such as copyright, north arrow configuration.\n * All extra data is optional.\n *\n * Example 1:\n *\n {\n copyright: {\n text: 'Example copyright', // Copyright text or function\n font: '10px Arial', // Font, default is '12px Arial'\n fillStyle: 'blue', // Fill style, default is 'black'\n },\n northArrow, // True if the north arrow\n // should be placed with default configuration\n // (default image, rotation=0, circled=false)\n }\n * Example 2:\n *\n {\n northArrow: {\n src: NorthArrowCustom,\n width: 60, // Width in px, default is 80\n height: 100, // Height in px, default is 80\n rotation: 25, // Absolute rotation in degrees as number or function\n\n }\n }\n * Example 3:\n *\n {\n copyright: {\n text: () => { // Copyright as function\n return this.copyright;\n },\n },\n northArrow: {\n rotation: () => { // Rotation as function\n return NorthArrow.radToDeg(this.map.getView().getRotation());\n },\n circled, // Display circle around the north arrow (Does not work for custom src)\n },\n }\n */\n extraData: PropTypes.shape({\n logo: extraDataImgPropType,\n northArrow: extraDataImgPropType,\n qrCode: extraDataImgPropType,\n copyright: PropTypes.shape({\n text: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n font: PropTypes.string,\n fillStyle: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.instanceOf(CanvasPatternType),\n ]),\n background: PropTypes.bool,\n maxWidth: PropTypes.number,\n paddingBottom: PropTypes.number,\n paddingBackground: PropTypes.number,\n }),\n }),\n\n /**\n * Return the file name of the image to download.\n */\n getDownloadImageName: PropTypes.func,\n};\n\nconst getMargin = (destCanvas) => {\n const newMargin = destCanvas.width / 100; // 1% of the canvas width\n return newMargin;\n};\n\nconst getDefaultDownloadImageName = (format) => {\n const fileExt = format === \"image/jpeg\" ? \"jpg\" : \"png\";\n return `${window.document.title.replace(/ /g, \"_\").toLowerCase()}.${fileExt}`;\n};\n\nlet multilineCopyright = false;\nlet copyrightY = 0;\n\n// Ensure the font size fita with the image width.\nconst decreaseFontSize = (destContext, maxWidth, copyright, scale) => {\n const minFontSize = 8;\n let sizeMatch;\n let fontSize;\n do {\n sizeMatch = destContext.font.match(/[0-9]+(?:\\.[0-9]+)?(px)/i);\n fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], \"\"), 10);\n\n // eslint-disable-next-line no-param-reassign\n destContext.font = destContext.font.replace(fontSize, fontSize - 1);\n\n multilineCopyright = false;\n\n if (fontSize - 1 === minFontSize) {\n multilineCopyright = true;\n }\n } while (\n fontSize - 1 > minFontSize &&\n destContext.measureText(copyright).width * scale > maxWidth\n );\n\n return destContext.font;\n};\n\n// eslint-disable-next-line class-methods-use-this\nconst drawTextBackground = (\n destContext,\n x,\n y,\n width,\n height,\n styleOptions = {},\n) => {\n destContext.save();\n // Dflt is a white background\n destContext.fillStyle = \"rgba(255,255,255,.8)\";\n\n // To simplify usability the user could pass a boolean to use only default values.\n if (typeof styleOptions === \"object\") {\n Object.entries(styleOptions).forEach(([key, value]) => {\n destContext[key] = value;\n });\n }\n\n /// draw background rect assuming height of font\n destContext.fillRect(x, y, width, height);\n destContext.restore();\n};\n\nconst drawCopyright = (\n destContext,\n destCanvas,\n maxWidth,\n extraData,\n scale,\n margin,\n padding,\n) => {\n const { text, font, fillStyle, background } = extraData.copyright;\n const { paddingBottom = padding, paddingBackground = 2 } =\n extraData.copyright;\n\n let copyright = typeof text === \"function\" ? text() : text?.trim();\n\n if (Array.isArray(copyright)) {\n copyright = copyright.join();\n }\n\n destContext.save();\n destContext.scale(scale, scale);\n destContext.font = font || \"12px Arial\";\n destContext.font = decreaseFontSize(destContext, maxWidth, copyright, scale);\n destContext.textBaseline = \"bottom\";\n destContext.scale(scale, scale);\n destContext.fillStyle = fillStyle || \"black\";\n\n // We search if the display on 2 line is necessary\n let firstLine = copyright;\n let firstLineMetrics = destContext.measureText(firstLine);\n\n // If the text is bigger than the max width we split it into 2 lines\n if (multilineCopyright) {\n const wordNumber = copyright.split(\" \").length;\n for (let i = 0; i < wordNumber; i += 1) {\n // Stop removing word when fits within one line.\n if (firstLineMetrics.width * scale < maxWidth) {\n break;\n }\n firstLine = firstLine.substring(0, firstLine.lastIndexOf(\" \"));\n firstLineMetrics = destContext.measureText(firstLine);\n }\n }\n\n // Define second line if necessary\n const secondLine = copyright.replace(firstLine, \"\").trim();\n\n // At this point we the number of lines to display.\n const lines = [firstLine, secondLine].filter((l) => !!l).reverse();\n\n // We draw from bottom to top because textBaseline is 'bottom\n let lineX = margin;\n let lineY = destCanvas.height - paddingBottom; // we apply the margin only on the left side\n\n lines.forEach((line) => {\n const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } =\n destContext.measureText(line);\n const height = fontBoundingBoxAscent + fontBoundingBoxDescent; // we include paddingBackground to have a bit of distance between lines\n let lineTop = lineY - height;\n\n if (background) {\n const backgroundX = margin;\n lineTop -= paddingBackground * 2;\n drawTextBackground(\n destContext,\n backgroundX,\n lineTop,\n width + paddingBackground * 2,\n height + paddingBackground * 2,\n background,\n );\n lineX += paddingBackground;\n lineY -= paddingBackground;\n }\n\n destContext.fillText(line, lineX, lineY);\n lineY = lineTop;\n });\n\n copyrightY = lineY;\n destContext.restore();\n};\n\nconst drawElement = (\n data,\n destCanvas,\n scale,\n margin,\n padding,\n previousItemSize = [0, 0],\n side = \"right\",\n) => {\n const destContext = destCanvas.getContext(\"2d\");\n const { src, width, height, rotation } = data;\n\n return new Promise((resolve) => {\n const img = new Image();\n img.crossOrigin = \"Anonymous\";\n img.src = src;\n img.onload = () => {\n destContext.save();\n const elementWidth = (width || 80) * scale;\n const elementHeight = (height || 80) * scale;\n const left =\n side === \"left\"\n ? margin + elementWidth / 2\n : destCanvas.width - margin - elementWidth / 2;\n const top =\n (side === \"left\" && copyrightY\n ? copyrightY - padding\n : destCanvas.height) -\n margin -\n elementHeight / 2 -\n previousItemSize[1];\n\n destContext.translate(left, top);\n\n if (rotation) {\n const angle = typeof rotation === \"function\" ? rotation() : rotation;\n destContext.rotate(angle * (Math.PI / 180));\n }\n\n destContext.drawImage(\n img,\n -elementWidth / 2,\n -elementHeight / 2,\n elementWidth,\n elementHeight,\n );\n destContext.restore();\n\n // Return the pixels width of the arrow and the margin right,\n // that must not be occupied by the copyright.\n resolve([elementWidth + 2 * padding, elementHeight + 2 * padding]);\n };\n\n img.onerror = () => {\n resolve();\n };\n });\n};\n\nconst calculatePixelsToExport = (mapToExport, extent, coordinates) => {\n let firstCoordinate;\n let oppositeCoordinate;\n\n if (extent) {\n firstCoordinate = getTopLeft(extent);\n oppositeCoordinate = getBottomRight(extent);\n } else if (coordinates) {\n // In case of coordinates coming from DragBox interaction:\n // firstCoordinate is the first coordinate drawn by the user.\n // oppositeCoordinate is the coordinate of the point dragged by the user.\n [firstCoordinate, , oppositeCoordinate] = coordinates;\n }\n\n if (firstCoordinate && oppositeCoordinate) {\n const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);\n const oppositePixel =\n mapToExport.getPixelFromCoordinate(oppositeCoordinate);\n const pixelTopLeft = [\n firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n const pixelBottomRight = [\n firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n\n return {\n x: pixelTopLeft[0],\n y: pixelTopLeft[1],\n w: pixelBottomRight[0] - pixelTopLeft[0],\n h: pixelBottomRight[1] - pixelTopLeft[1],\n };\n }\n return null;\n};\n\nconst createCanvasImage = (\n mapToExport,\n extraData,\n scale,\n extent,\n coordinates,\n margin,\n padding,\n) => {\n return new Promise((resolve) => {\n mapToExport.once(\"rendercomplete\", () => {\n // Find all layer canvases and add it to dest canvas.\n const canvases = mapToExport\n .getTargetElement()\n .getElementsByTagName(\"canvas\");\n\n // Create the canvas to export with the good size.\n let destCanvas;\n let destContext;\n\n // canvases is an HTMLCollection, we don't try to transform to array because some compilers like cra doesn't translate it right.\n for (let i = 0; i < canvases.length; i += 1) {\n const canvas = canvases[i];\n if (!canvas.width || !canvas.height) {\n // eslint-disable-next-line no-continue\n continue;\n }\n const clip = calculatePixelsToExport(\n mapToExport,\n extent,\n coordinates,\n ) || {\n x: 0,\n y: 0,\n w: canvas.width,\n h: canvas.height,\n };\n\n if (!destCanvas) {\n destCanvas = document.createElement(\"canvas\");\n destCanvas.width = clip.w;\n destCanvas.height = clip.h;\n destContext = destCanvas.getContext(\"2d\");\n }\n\n // Draw canvas to the canvas to export.\n destContext.drawImage(\n canvas,\n clip.x,\n clip.y,\n clip.w,\n clip.h,\n 0,\n 0,\n destCanvas.width,\n destCanvas.height,\n );\n }\n\n margin = margin || getMargin(destCanvas);\n\n // Custom info\n let logoPromise = Promise.resolve();\n if (destContext && extraData && extraData.logo) {\n logoPromise = drawElement(\n extraData.logo,\n destCanvas,\n scale,\n margin,\n padding,\n );\n }\n\n logoPromise.then((logoSize = [0, 0]) => {\n // North arrow\n let arrowPromise = Promise.resolve();\n if (destContext && extraData && extraData.northArrow) {\n arrowPromise = drawElement(\n {\n src: extraData.northArrow.circled\n ? NorthArrowCircle\n : NorthArrowSimple,\n ...extraData.northArrow,\n },\n destCanvas,\n scale,\n margin,\n padding,\n logoSize,\n );\n }\n\n // Copyright\n arrowPromise.then((arrowSize = [0, 0]) => {\n const widestElement = Math.max(logoSize[0], arrowSize[0]);\n if (\n destContext &&\n extraData &&\n extraData.copyright &&\n extraData.copyright.text\n ) {\n const maxWidth =\n extraData.copyright.maxWidth ||\n (widestElement\n ? destContext.canvas.width - widestElement - margin\n : destContext.canvas.width);\n drawCopyright(\n destContext,\n destCanvas,\n maxWidth,\n extraData,\n scale,\n margin,\n padding,\n );\n }\n let qrCodePromise = Promise.resolve();\n if (destContext && extraData && extraData.qrCode) {\n qrCodePromise = drawElement(\n extraData.qrCode,\n destCanvas,\n scale,\n margin,\n padding,\n undefined,\n \"left\",\n );\n }\n qrCodePromise.then(() => {\n return resolve(destCanvas);\n });\n });\n });\n });\n mapToExport.renderSync();\n });\n};\n\nconst downloadCanvasImage = (canvas, format, getDownloadImageName) => {\n // Use blob for large images\n const promise = new Promise((resolve) => {\n if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {\n // ie 9 and 10\n const url = canvas.toDataURL(format);\n const w = window.open(\"about:blank\", \"\");\n w.document.write(`<img src=\"${url}\" alt=\"from canvas\"/>`);\n resolve(url);\n }\n if (window.navigator.msSaveBlob) {\n // ie 11 and higher\n let image;\n try {\n image = canvas.msToBlob();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log(e);\n }\n const blob = new Blob([image], {\n type: format,\n });\n resolve(blob);\n window.navigator.msSaveBlob(blob, getDownloadImageName(format));\n } else {\n canvas.toBlob((blob) => {\n const link = document.createElement(\"a\");\n link.download = getDownloadImageName(format);\n link.href = URL.createObjectURL(blob);\n // append child to document for firefox to be able to download.\n document.body.appendChild(link);\n link.click();\n resolve(blob);\n }, format);\n }\n });\n return promise;\n};\n\n/**\n * The CanvasSaveButton component creates a button to save\n * an [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html)\n * canvas as an image.\n */\nfunction CanvasSaveButton({\n margin = null,\n padding = 5,\n autoDownload = true,\n children = null,\n map = null,\n format = \"image/png\",\n extraData = null,\n extent = null,\n coordinates = null,\n scale = 1,\n getDownloadImageName = getDefaultDownloadImageName,\n onSaveStart = (mapp) => {\n return Promise.resolve(mapp);\n },\n onSaveEnd = () => {},\n}) {\n const onClick = useCallback(\n (evt) => {\n if (window.navigator.msSaveBlob) {\n // ie only\n evt.preventDefault();\n evt.stopPropagation();\n }\n multilineCopyright = false;\n copyrightY = 0;\n onSaveStart(map).then((mapToExport) => {\n return createCanvasImage(\n mapToExport || map,\n extraData,\n scale,\n extent,\n coordinates,\n margin,\n padding,\n )\n .then((canvas) => {\n if (autoDownload) {\n downloadCanvasImage(canvas, format, getDownloadImageName).then(\n (blob) => {\n onSaveEnd(mapToExport, canvas, blob);\n },\n );\n } else {\n onSaveEnd(mapToExport, canvas);\n }\n })\n .catch((err) => {\n if (err) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n onSaveEnd(mapToExport, err);\n });\n });\n },\n [\n autoDownload,\n coordinates,\n extent,\n extraData,\n format,\n map,\n margin,\n onSaveEnd,\n onSaveStart,\n padding,\n scale,\n getDownloadImageName,\n ],\n );\n\n return (\n <>\n {React.Children.map(children, (child) => {\n return React.cloneElement(child, { onClick });\n })}\n </>\n );\n}\n\nCanvasSaveButton.propTypes = propTypes;\n\nexport default CanvasSaveButton;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
package/utils/KML.js
CHANGED
|
@@ -119,15 +119,10 @@ const sanitizeFeature = (feature, doNotRevert32pxScaling = false) => {
|
|
|
119
119
|
if (/\n/.test(name)) {
|
|
120
120
|
const array = [];
|
|
121
121
|
const split = name.split("\n");
|
|
122
|
-
split.forEach((
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
} else {
|
|
126
|
-
if (idx === 0) {
|
|
127
|
-
array.push("\u200B", "");
|
|
128
|
-
}
|
|
122
|
+
split.forEach((txt, idx) => {
|
|
123
|
+
array.push(txt || "\u200B", txt ? font : "");
|
|
124
|
+
if (idx < split.length - 1) {
|
|
129
125
|
array.push("\n", "");
|
|
130
|
-
array.push("\u200B", "");
|
|
131
126
|
}
|
|
132
127
|
});
|
|
133
128
|
name = array;
|
|
@@ -136,7 +131,7 @@ const sanitizeFeature = (feature, doNotRevert32pxScaling = false) => {
|
|
|
136
131
|
}
|
|
137
132
|
text = new Text({
|
|
138
133
|
font: font.replace(/bold/g, "normal"),
|
|
139
|
-
// We
|
|
134
|
+
// We manage bold in textArray
|
|
140
135
|
text: name,
|
|
141
136
|
fill: style.getText().getFill(),
|
|
142
137
|
// rotation unsupported by KML, taken instead from custom field.
|
|
@@ -355,10 +350,10 @@ const writeFeatures = (layer, featureProjection, mapResolution) => {
|
|
|
355
350
|
clone.set("textArray", JSON.stringify(text));
|
|
356
351
|
kmlText = text.map((t, idx) => {
|
|
357
352
|
return idx % 2 === 0 ? t : "";
|
|
358
|
-
}).join("");
|
|
353
|
+
}).join("").replaceAll("\u200B", "");
|
|
359
354
|
}
|
|
360
355
|
if (kmlText) {
|
|
361
|
-
if (
|
|
356
|
+
if (/^(\s|\n)|(\n|\s)$/g.test(kmlText)) {
|
|
362
357
|
clone.set("name", `\u200B${kmlText}\u200B`);
|
|
363
358
|
} else {
|
|
364
359
|
clone.set("name", kmlText);
|
package/utils/KML.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/KML.js"],
|
|
4
|
-
"sourcesContent": ["import KML from \"ol/format/KML\";\nimport { Feature, getUid } from \"ol\";\nimport Point from \"ol/geom/Point\";\nimport MultiPoint from \"ol/geom/MultiPoint\";\nimport GeometryCollection from \"ol/geom/GeometryCollection\";\nimport { Style, Text, Icon, Circle, Fill, Stroke } from \"ol/style\";\nimport { asString } from \"ol/color\";\nimport { parse } from \"ol/xml\";\nimport { fromCircle } from \"ol/geom/Polygon\";\nimport { transform, get } from \"ol/proj\";\nimport CircleGeom from \"ol/geom/Circle\";\nimport { kmlStyle } from \"./Styles\";\nimport getPolygonPattern from \"./getPolygonPattern\";\n\nconst CIRCLE_GEOMETRY_CENTER = \"circleGeometryCenter\";\nconst CIRCLE_GEOMETRY_RADIUS = \"circleGeometryRadius\";\nconst EPSG_4326 = get(\"EPSG:4326\");\n\n// Comes from ol >= 6.7,\n// https://github.com/openlayers/openlayers/blob/main/src/ol/format/KML.js#L320\nconst scaleForSize = (size) => {\n return 32 / Math.min(size[0], size[1]);\n};\n\nconst applyTextStyleForIcon = (olIcon, olText) => {\n const size = olIcon.getSize() || [48, 48];\n const scale = olIcon.getScale() || 1;\n const anchor = olIcon.getAnchor() || [\n (size[0] * scale) / 2,\n (size[1] * scale) / 2,\n ];\n const offset = [\n scale * (size[0] - anchor[0]) + 5,\n scale * (size[1] / 2 - anchor[1]),\n ];\n olText.setOffsetX(offset[0]);\n olText.setOffsetY(offset[1]);\n olText.setTextAlign(\"left\");\n};\n\nconst getVertexCoord = (geom, start = true, index = 0) => {\n const coords = geom.getCoordinates();\n const len = coords.length - 1;\n return start ? coords[index] : coords[len - index];\n};\n\nconst getLineIcon = (feature, icon, color, start = true) => {\n const geom = feature.getGeometry();\n const coordA = getVertexCoord(geom, start, 1);\n const coordB = getVertexCoord(geom, start);\n const dx = start ? coordA[0] - coordB[0] : coordB[0] - coordA[0];\n const dy = start ? coordA[1] - coordB[1] : coordB[1] - coordA[1];\n const rotation = Math.atan2(dy, dx);\n\n return new Style({\n geometry: (feat) => {\n const ge = feat.getGeometry();\n return new Point(getVertexCoord(ge, start));\n },\n image: new Icon({\n src: icon.url,\n color,\n rotation: -rotation,\n rotateWithView: true,\n scale: icon.scale,\n size: icon.size, // ie 11\n }),\n zIndex: icon.zIndex,\n });\n};\n\n// Clean the unneeded feature's style and properties created by the KML parser.\nconst sanitizeFeature = (feature, doNotRevert32pxScaling = false) => {\n const geom = feature.getGeometry();\n let styles = feature.getStyleFunction();\n\n // Store maxZoom in properties\n if (feature.get(\"maxZoom\")) {\n feature.set(\"maxZoom\", parseFloat(feature.get(\"maxZoom\"), 10));\n }\n\n // Store minZoom in properties\n if (feature.get(\"minZoom\")) {\n feature.set(\"minZoom\", parseFloat(feature.get(\"minZoom\"), 10));\n }\n\n // The use of clone is part of the scale fix for OL > 6.7\n // If an IconStyle has no gx:w and gx:h defined, a scale factor is applied\n // after the image is loaded. To avoided having the scale factor applied we\n // clone the style and keep the scale as it is.\n // Having gx:w and gx:h not defined should not happen, using the last version of the parser/reader.\n const tmpStyles = styles(feature);\n const style = (Array.isArray(tmpStyles) ? tmpStyles[0] : tmpStyles).clone();\n\n let stroke = style.getStroke();\n\n if (feature.get(\"lineCap\")) {\n stroke?.setLineCap(feature.get(\"lineCap\"));\n }\n\n if (feature.get(\"lineJoin\")) {\n stroke?.setLineJoin(feature.get(\"lineJoin\"));\n }\n\n if (feature.get(\"lineDash\")) {\n stroke?.setLineDash(\n feature\n .get(\"lineDash\")\n .split(\",\")\n .map((l) => {\n return parseInt(l, 10);\n }),\n );\n }\n\n if (feature.get(\"lineDashOffset\")) {\n stroke?.setLineDashOffset(parseInt(feature.get(\"lineDashOffset\"), 10));\n }\n\n if (feature.get(\"miterLimit\")) {\n stroke?.setMiterLimit(parseInt(feature.get(\"miterLimit\"), 10));\n }\n\n // The canvas draws a stroke width=1 by default if width=0, so we\n // remove the stroke style in that case.\n if (stroke && stroke.getWidth() === 0) {\n stroke = undefined;\n }\n\n if (feature.get(\"zIndex\")) {\n style.setZIndex(parseInt(feature.get(\"zIndex\"), 10));\n }\n\n // if the feature is a Point and we are offline, we use default vector\n // style.\n // if the feature is a Point and has a name with a text style, we\n // create a correct text style.\n // TODO Handle GeometryCollection displaying name on the first Point\n // geometry.\n if (style && (geom instanceof Point || geom instanceof MultiPoint)) {\n let image = style.getImage();\n let text = null;\n let fill = style.getFill();\n\n // If the feature has name we display it on the map as Google does\n if (\n feature.get(\"name\") &&\n style.getText() &&\n style.getText().getScale() !== 0\n ) {\n if (image && image.getScale() === 0) {\n // transparentCircle is used to allow selection\n image = new Circle({\n radius: 1,\n fill: new Fill({ color: [0, 0, 0, 0] }),\n stroke: new Stroke({ color: [0, 0, 0, 0] }),\n });\n }\n\n // We replace empty white spaces used to keep normal spaces before and after the name.\n let name = feature.get(\"name\");\n if (/\\u200B/g.test(name)) {\n name = name.replace(/\\u200B/g, \"\");\n feature.set(\"name\", name);\n }\n\n // For backward compatibility we translate the bold and italic textFont property to a textArray prop\n const font = feature.get(\"textFont\") || \"normal 16px Helvetica\";\n\n // Since we use rich text in mapset editor we use a text array instead,\n // it's only necessary when there is ne wlines in the text\n // Manage new lines\n if (/\\n/.test(name)) {\n const array = [];\n const split = name.split(\"\\n\");\n split.forEach((n, idx) => {\n if (n) {\n array.push(n, n ? font : \"\");\n } else {\n if (idx === 0) {\n array.push(\"\\u200B\", \"\");\n }\n array.push(\"\\n\", \"\");\n // if (idx === split.length - 1) {\n array.push(\"\\u200B\", \"\");\n // }\n }\n });\n name = array;\n } else {\n name = [name, font];\n }\n\n text = new Text({\n font: font.replace(/bold/g, \"normal\"), // We mange bold in textArray\n text: name,\n fill: style.getText().getFill(),\n // rotation unsupported by KML, taken instead from custom field.\n rotation: feature.get(\"textRotation\") || 0,\n // since ol 6.3.1 : https://github.com/openlayers/openlayers/pull/10613/files#diff-1883da8b57e690db7ea0c35ce53c880aR925\n // a default textstroke is added to mimic google earth.\n // it was not the case before, the stroke was always null. So to keep\n // the same behavior we don't copy the stroke style.\n // TODO : maybe we should use this functionnality in the futur.\n // stroke: style.getText().getStroke(),\n scale: style.getText().getScale(),\n });\n\n if (feature.get(\"textArray\")) {\n try {\n const textArray = JSON.parse(feature.get(\"textArray\"));\n text.setText(textArray);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\n \"Error parsing textArray\",\n feature.get(\"textArray\"),\n err,\n );\n }\n }\n\n if (feature.get(\"textStrokeColor\") && feature.get(\"textStrokeWidth\")) {\n text.setStroke(\n new Stroke({\n color: feature.get(\"textStrokeColor\"),\n width: parseFloat(feature.get(\"textStrokeWidth\")),\n }),\n );\n }\n\n if (feature.get(\"textAlign\")) {\n text.setTextAlign(feature.get(\"textAlign\"));\n }\n\n if (feature.get(\"textOffsetX\")) {\n text.setOffsetX(parseFloat(feature.get(\"textOffsetX\")));\n }\n\n if (feature.get(\"textOffsetY\")) {\n text.setOffsetY(parseFloat(feature.get(\"textOffsetY\")));\n }\n\n if (feature.get(\"textBackgroundFillColor\")) {\n text.setBackgroundFill(\n new Fill({\n color: feature.get(\"textBackgroundFillColor\"),\n }),\n );\n }\n\n if (feature.get(\"textPadding\")) {\n text.setPadding(\n feature\n .get(\"textPadding\")\n .split(\",\")\n .map((n) => {\n return parseFloat(n);\n }),\n );\n }\n if (image instanceof Icon) {\n applyTextStyleForIcon(image, text);\n }\n }\n\n if (image instanceof Icon) {\n /* Apply icon rotation if defined (by default only written as\n * <heading> tag, which is not read as rotation value by the ol KML module)\n */\n image.setRotation(parseFloat(feature.get(\"iconRotation\")) || 0);\n\n if (feature.get(\"iconScale\")) {\n image.setScale(parseFloat(feature.get(\"iconScale\")) || 0);\n\n // We fix the 32px scaling introduced by OL 6.7 only if the image has a size defined.\n } else if (!doNotRevert32pxScaling && image.getSize()) {\n const resizeScale = scaleForSize(image.getSize());\n image.setScale(image.getScaleArray()[0] / resizeScale);\n }\n }\n\n fill = undefined;\n stroke = undefined;\n\n styles = (feat, resolution) => {\n /* Options to be used for picture scaling with map, should have at least\n * a resolution attribute (this is the map resolution at the zoom level when\n * the picture is created), can take an optional constant for further scale\n * adjustment.\n * e.g. { resolution: 0.123, defaultScale: 1 / 6 }\n */\n\n if (feat.get(\"pictureOptions\")) {\n let pictureOptions = feat.get(\"pictureOptions\");\n if (typeof pictureOptions === \"string\") {\n pictureOptions = JSON.parse(pictureOptions);\n }\n feat.set(\"pictureOptions\", pictureOptions);\n if (pictureOptions.resolution) {\n image.setScale(\n (pictureOptions.resolution / resolution) *\n pictureOptions.defaultScale || 1,\n );\n }\n }\n\n return new Style({\n fill,\n stroke,\n image,\n text,\n zIndex: style.getZIndex(),\n });\n };\n }\n\n // Remove image and text styles for polygons and lines\n if (\n !(\n geom instanceof Point ||\n geom instanceof MultiPoint ||\n geom instanceof GeometryCollection\n )\n ) {\n styles = [\n new Style({\n fill: style.getFill(),\n stroke,\n image: null,\n text: null,\n zIndex: style.getZIndex(),\n }),\n ];\n\n // Parse the fillPattern json string and store parsed object\n let fillPattern = feature.get(\"fillPattern\");\n if (fillPattern) {\n fillPattern = JSON.parse(fillPattern);\n feature.set(\"fillPattern\", fillPattern);\n\n /* We set the fill pattern for polygons */\n if (!style.getFill()) {\n styles[0].setFill(new Fill());\n }\n const patternOrColor = fillPattern.empty\n ? [0, 0, 0, 0]\n : getPolygonPattern(fillPattern.id, fillPattern.color);\n styles[0].getFill().setColor(patternOrColor);\n }\n\n // Add line's icons styles\n if (feature.get(\"lineStartIcon\")) {\n styles.push(\n getLineIcon(\n feature,\n JSON.parse(feature.get(\"lineStartIcon\")),\n stroke.getColor(),\n ),\n );\n }\n\n if (feature.get(\"lineEndIcon\")) {\n styles.push(\n getLineIcon(\n feature,\n JSON.parse(feature.get(\"lineEndIcon\")),\n stroke.getColor(),\n false,\n ),\n );\n }\n }\n feature.setStyle(styles);\n};\n\n/**\n * Read a KML string.\n * @param {String} kmlString A string representing a KML file.\n * @param {<ol.Projection|String>} featureProjection The projection used by the map.\n * @param {<boolean>} doNotRevert32pxScaling Set it to true if you use ol < 6.7 and last version of react-spatial, Fix the 32px scaling, introduced by (ol >= 6.7), see https://github.com/openlayers/openlayers/pull/12695.\n */\nconst readFeatures = (\n kmlString,\n featureProjection,\n doNotRevert32pxScaling = false,\n) => {\n // Since ol 6.7, the KML follows better the spec and GoogleEarth interpretation, see https://github.com/openlayers/openlayers/pull/12695.\n // so the <scale> value is interpreted using an image size of 32px.\n // So when revert32pxScaling is true we fix back the scale, to use only, if you use an OL < 6.7.\n // Now the writeFeatures function use the iconScale extended data to set the image's scale.\n // If the extended data is not found it will look at this boolean to define if we must revert the scale or not.\n const features = new KML().readFeatures(kmlString, {\n featureProjection,\n });\n features.forEach((feature) => {\n // Transform back polygon to circle geometry\n const {\n [CIRCLE_GEOMETRY_CENTER]: circleGeometryCenter,\n [CIRCLE_GEOMETRY_RADIUS]: circleGeometryRadius,\n } = feature?.getProperties() || {};\n if (circleGeometryCenter && circleGeometryRadius) {\n const circle = new CircleGeom(\n transform(\n JSON.parse(circleGeometryCenter),\n EPSG_4326,\n featureProjection || EPSG_4326,\n ),\n parseFloat(circleGeometryRadius, 10),\n );\n circle.setProperties(feature.getGeometry().getProperties());\n feature.setGeometry(circle);\n }\n\n sanitizeFeature(feature, doNotRevert32pxScaling);\n });\n return features;\n};\n\n/**\n * Create a KML string.\n * @param {VectorLayer} layer A react-spatial VectorLayer.\n * @param {<ol.Projection|String>} featureProjection The current projection used by the features.\n * @param {<boolean>} fixGxyAndGxh If the KML contains gx:w and gx:h, (ol >= 6.7), it will fix the bug introduced by https://github.com/openlayers/openlayers/pull/12695.\n */\nconst writeFeatures = (layer, featureProjection, mapResolution) => {\n let featString;\n const { olLayer } = layer;\n const exportFeatures = [];\n\n [...olLayer.getSource().getFeatures()]\n .sort((a, b) => {\n // The order of features must be kept.\n // We could use the useSpatialIndex = false property on the layer\n // but we prefer to sort feature by ol uid because ol uid is an integer\n // increased on each creation of a feature.\n // So we will keep the order of creation made by the the KML parser.\n // Ideally we should order by the zIndex of the style only.\n if (getUid(a) <= getUid(b)) {\n return -1;\n }\n return 1;\n })\n .forEach((feature) => {\n const clone = feature.clone();\n if (clone.getGeometry().getType() === \"Circle\") {\n // We transform circle elements into polygons\n // because circle not supported in KML spec and in ol KML parser\n const circleGeom = feature.getGeometry();\n clone.setGeometry(fromCircle(circleGeom, 100));\n clone.set(\n CIRCLE_GEOMETRY_CENTER,\n JSON.stringify(\n transform(circleGeom.getCenter(), featureProjection, EPSG_4326),\n ),\n );\n clone.set(CIRCLE_GEOMETRY_RADIUS, circleGeom.getRadius());\n }\n clone.setId(feature.getId());\n clone.getGeometry().transform(featureProjection, EPSG_4326);\n\n // We remove all ExtendedData not related to style.\n Object.keys(feature.getProperties()).forEach((key) => {\n if (\n ![\n \"geometry\",\n \"name\",\n \"description\",\n CIRCLE_GEOMETRY_CENTER,\n CIRCLE_GEOMETRY_RADIUS,\n ].includes(key)\n ) {\n clone.unset(key, true);\n }\n });\n\n let styles;\n\n if (feature.getStyleFunction()) {\n styles = feature.getStyleFunction()(feature, mapResolution);\n } else if (olLayer && olLayer.getStyleFunction()) {\n styles = olLayer.getStyleFunction()(feature, mapResolution);\n }\n\n const mainStyle = styles[0] || styles;\n\n const newStyle = {\n fill: mainStyle.getFill(),\n stroke: mainStyle.getStroke(),\n text: mainStyle.getText(),\n image: mainStyle.getImage(),\n zIndex: mainStyle.getZIndex(),\n };\n\n if (newStyle.zIndex) {\n clone.set(\"zIndex\", newStyle.zIndex);\n }\n\n const text = newStyle.text?.getText();\n\n if (text) {\n let kmlText = text;\n\n if (Array.isArray(text)) {\n // text can be a string or an array of strings\n clone.set(\"textArray\", JSON.stringify(text));\n\n // in the KML we just add the text without the bold or italic information\n kmlText = text\n .map((t, idx) => {\n return idx % 2 === 0 ? t : \"\";\n })\n .join(\"\");\n }\n\n // We add the current text as features's name so it will be added as Placemark's name in the kml\n if (kmlText) {\n // If we see spaces at the beginning or at the end we add a empty\n // white space at the beginning and at the end.\n if (/^\\s|\\s$/g.test(kmlText)) {\n clone.set(\"name\", `\\u200B${kmlText}\\u200B`);\n } else {\n clone.set(\"name\", kmlText);\n }\n }\n }\n\n // Set custom properties to be converted in extendedData in KML.\n if (newStyle.text?.getRotation()) {\n clone.set(\"textRotation\", newStyle.text.getRotation());\n }\n\n if (newStyle.text?.getFont()) {\n clone.set(\"textFont\", newStyle.text.getFont());\n }\n\n if (newStyle.text?.getTextAlign()) {\n clone.set(\"textAlign\", newStyle.text.getTextAlign());\n }\n\n if (newStyle.text?.getOffsetX()) {\n clone.set(\"textOffsetX\", newStyle.text.getOffsetX());\n }\n\n if (newStyle.text?.getOffsetY()) {\n clone.set(\"textOffsetY\", newStyle.text.getOffsetY());\n }\n\n if (newStyle.text?.getStroke()) {\n if (newStyle.text.getStroke().getColor()) {\n clone.set(\n \"textStrokeColor\",\n asString(newStyle.text.getStroke().getColor()),\n );\n }\n\n if (newStyle.text.getStroke().getWidth()) {\n clone.set(\"textStrokeWidth\", newStyle.text.getStroke().getWidth());\n }\n }\n\n if (newStyle.text?.getBackgroundFill()) {\n clone.set(\n \"textBackgroundFillColor\",\n asString(newStyle.text.getBackgroundFill().getColor()),\n );\n }\n\n if (newStyle.text?.getPadding()) {\n clone.set(\"textPadding\", newStyle.text.getPadding().join());\n }\n\n if (newStyle.stroke?.getLineCap()) {\n clone.set(\"lineCap\", newStyle.stroke.getLineCap());\n }\n\n if (newStyle.stroke?.getLineJoin()) {\n clone.set(\"lineJoin\", newStyle.stroke.getLineJoin());\n }\n\n if (newStyle.stroke?.getLineDash()) {\n clone.set(\"lineDash\", newStyle.stroke.getLineDash().join(\",\"));\n }\n\n if (newStyle.stroke?.getLineDashOffset()) {\n clone.set(\"lineDashOffset\", newStyle.stroke.getLineDashOffset());\n }\n\n if (newStyle.stroke?.getMiterLimit()) {\n clone.set(\"miterLimit\", newStyle.stroke.getMiterLimit());\n }\n\n if (newStyle.image instanceof Circle) {\n newStyle.image = null;\n }\n\n if (newStyle.image) {\n const imgSource = newStyle.image.getSrc();\n if (!/(http(s?)):\\/\\//gi.test(imgSource)) {\n // eslint-disable-next-line no-console\n console.log(\n \"Local image source not supported for KML export.\" +\n \"Should use remote web server\",\n );\n }\n\n if (newStyle.image.getRotation()) {\n // We set the icon rotation as extended data\n clone.set(\"iconRotation\", newStyle.image.getRotation());\n }\n\n if (newStyle.image.getScale()) {\n // We set the scale as extended metadata because the <scale> in the KML is related to a 32px img, since ol >= 6.10.\n clone.set(\"iconScale\", newStyle.image.getScale());\n }\n\n // Set map resolution to use for icon-to-map proportional scaling\n if (feature.get(\"pictureOptions\")) {\n clone.set(\n \"pictureOptions\",\n JSON.stringify(feature.get(\"pictureOptions\")),\n );\n }\n }\n\n // In case a fill pattern should be applied (use fillPattern attribute to store pattern id, color etc)\n if (feature.get(\"fillPattern\")) {\n clone.set(\"fillPattern\", JSON.stringify(feature.get(\"fillPattern\")));\n newStyle.fill = null;\n }\n\n // maxZoom: maximum zoom level at which the feature is displayed\n if (feature.get(\"maxZoom\")) {\n clone.set(\"maxZoom\", parseFloat(feature.get(\"maxZoom\"), 10));\n }\n\n // minZoom: minimum zoom level at which the feature is displayed\n if (feature.get(\"minZoom\")) {\n clone.set(\"minZoom\", parseFloat(feature.get(\"minZoom\"), 10));\n }\n\n // If only text is displayed we must specify an\n // image style with scale=0\n if (newStyle.text && !newStyle.image) {\n newStyle.image = new Icon({\n src: \"noimage\",\n scale: 0,\n });\n }\n\n // In case we use line's icon .\n const extraLineStyles = (Array.isArray(styles) && styles.slice(1)) || [];\n extraLineStyles.forEach((extraLineStyle) => {\n if (\n extraLineStyle &&\n extraLineStyle.getImage() instanceof Icon &&\n extraLineStyle.getGeometry()\n ) {\n const coord = extraLineStyle.getGeometry()(feature).getCoordinates();\n const startCoord = feature.getGeometry().getFirstCoordinate();\n if (coord[0] === startCoord[0] && coord[1] === startCoord[1]) {\n clone.set(\n \"lineStartIcon\",\n JSON.stringify({\n url: extraLineStyle.getImage().getSrc(),\n scale: extraLineStyle.getImage().getScale(),\n size: extraLineStyle.getImage().getSize(),\n zIndex: extraLineStyle.getZIndex(),\n }),\n );\n } else {\n clone.set(\n \"lineEndIcon\",\n JSON.stringify({\n url: extraLineStyle.getImage().getSrc(),\n scale: extraLineStyle.getImage().getScale(),\n size: extraLineStyle.getImage().getSize(),\n zIndex: extraLineStyle.getZIndex(),\n }),\n );\n }\n }\n });\n\n const olStyle = new Style(newStyle);\n clone.setStyle(olStyle);\n\n if (\n !(\n clone.getGeometry() instanceof Point &&\n olStyle.getText() &&\n !olStyle.getText().getText()\n )\n ) {\n exportFeatures.push(clone);\n }\n });\n\n if (exportFeatures.length > 0) {\n if (exportFeatures.length === 1) {\n // force the add of a <Document> node\n exportFeatures.push(new Feature());\n }\n\n featString = new KML({\n extractStyles: true,\n defaultStyle: [kmlStyle],\n }).writeFeatures(exportFeatures);\n\n // Remove no image hack\n featString = featString.replace(\n /<Icon>\\s*<href>noimage<\\/href>\\s*<\\/Icon>/g,\n \"\",\n );\n\n // Remove empty placemark added to have\n // <Document> tag\n featString = featString.replace(/<Placemark\\/>/g, \"\");\n\n // Add KML document name\n if (layer.name) {\n featString = featString.replace(\n /<Document>/,\n `<Document><name>${layer.name}</name>`,\n );\n }\n }\n\n return featString;\n};\n\n/**\n * Removes the <Camera> tag from a KML string. Returns the KML string with removed <Camera> tag.\n * @param {String} kmlString A string representing a KML file.\n */\nconst removeDocumentCamera = (kmlString) => {\n const kmlDoc = parse(kmlString);\n // Remove old Camera node\n const oldCameraNode = kmlDoc.getElementsByTagName(\"Camera\")[0];\n if (oldCameraNode) {\n oldCameraNode.remove();\n }\n return new XMLSerializer().serializeToString(kmlDoc);\n};\n\n/**\n * Write the <Camera> tag into a KML string. Returns the KML string with added <Camera> tag.\n * @param {String} kmlString A string representing a KML file.\n * @param {Object} cameraAttributes Object containing the camera tags (longitude, latitude, altitude, heading, tilt, altitudeMode, roll)\n * as keys with corresponding values. See https://developers.google.com/kml/documentation/kmlreference#camera\n */\nconst writeDocumentCamera = (kmlString, cameraAttributes) => {\n const kmlDoc = parse(removeDocumentCamera(kmlString));\n\n if (cameraAttributes) {\n // Create Camera node with child attributes if the cameraAttributes object is defined\n const cameraNode = kmlDoc.createElement(\"Camera\");\n Object.keys(cameraAttributes).forEach((key) => {\n const cameraAttribute = kmlDoc.createElement(\n `${key.charAt(0).toUpperCase() + key.slice(1)}`,\n );\n cameraAttribute.innerHTML = cameraAttributes[key];\n cameraNode.appendChild(cameraAttribute);\n });\n const documentNode = kmlDoc.getElementsByTagName(\"Document\")[0];\n documentNode.appendChild(cameraNode);\n }\n\n return new XMLSerializer().serializeToString(kmlDoc);\n};\n\nexport default {\n readFeatures,\n writeFeatures,\n writeDocumentCamera,\n removeDocumentCamera,\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import KML from \"ol/format/KML\";\nimport { Feature, getUid } from \"ol\";\nimport Point from \"ol/geom/Point\";\nimport MultiPoint from \"ol/geom/MultiPoint\";\nimport GeometryCollection from \"ol/geom/GeometryCollection\";\nimport { Style, Text, Icon, Circle, Fill, Stroke } from \"ol/style\";\nimport { asString } from \"ol/color\";\nimport { parse } from \"ol/xml\";\nimport { fromCircle } from \"ol/geom/Polygon\";\nimport { transform, get } from \"ol/proj\";\nimport CircleGeom from \"ol/geom/Circle\";\nimport { kmlStyle } from \"./Styles\";\nimport getPolygonPattern from \"./getPolygonPattern\";\n\nconst CIRCLE_GEOMETRY_CENTER = \"circleGeometryCenter\";\nconst CIRCLE_GEOMETRY_RADIUS = \"circleGeometryRadius\";\nconst EPSG_4326 = get(\"EPSG:4326\");\n\n// Comes from ol >= 6.7,\n// https://github.com/openlayers/openlayers/blob/main/src/ol/format/KML.js#L320\nconst scaleForSize = (size) => {\n return 32 / Math.min(size[0], size[1]);\n};\n\nconst applyTextStyleForIcon = (olIcon, olText) => {\n const size = olIcon.getSize() || [48, 48];\n const scale = olIcon.getScale() || 1;\n const anchor = olIcon.getAnchor() || [\n (size[0] * scale) / 2,\n (size[1] * scale) / 2,\n ];\n const offset = [\n scale * (size[0] - anchor[0]) + 5,\n scale * (size[1] / 2 - anchor[1]),\n ];\n olText.setOffsetX(offset[0]);\n olText.setOffsetY(offset[1]);\n olText.setTextAlign(\"left\");\n};\n\nconst getVertexCoord = (geom, start = true, index = 0) => {\n const coords = geom.getCoordinates();\n const len = coords.length - 1;\n return start ? coords[index] : coords[len - index];\n};\n\nconst getLineIcon = (feature, icon, color, start = true) => {\n const geom = feature.getGeometry();\n const coordA = getVertexCoord(geom, start, 1);\n const coordB = getVertexCoord(geom, start);\n const dx = start ? coordA[0] - coordB[0] : coordB[0] - coordA[0];\n const dy = start ? coordA[1] - coordB[1] : coordB[1] - coordA[1];\n const rotation = Math.atan2(dy, dx);\n\n return new Style({\n geometry: (feat) => {\n const ge = feat.getGeometry();\n return new Point(getVertexCoord(ge, start));\n },\n image: new Icon({\n src: icon.url,\n color,\n rotation: -rotation,\n rotateWithView: true,\n scale: icon.scale,\n size: icon.size, // ie 11\n }),\n zIndex: icon.zIndex,\n });\n};\n\n// Clean the unneeded feature's style and properties created by the KML parser.\nconst sanitizeFeature = (feature, doNotRevert32pxScaling = false) => {\n const geom = feature.getGeometry();\n let styles = feature.getStyleFunction();\n\n // Store maxZoom in properties\n if (feature.get(\"maxZoom\")) {\n feature.set(\"maxZoom\", parseFloat(feature.get(\"maxZoom\"), 10));\n }\n\n // Store minZoom in properties\n if (feature.get(\"minZoom\")) {\n feature.set(\"minZoom\", parseFloat(feature.get(\"minZoom\"), 10));\n }\n\n // The use of clone is part of the scale fix for OL > 6.7\n // If an IconStyle has no gx:w and gx:h defined, a scale factor is applied\n // after the image is loaded. To avoided having the scale factor applied we\n // clone the style and keep the scale as it is.\n // Having gx:w and gx:h not defined should not happen, using the last version of the parser/reader.\n const tmpStyles = styles(feature);\n const style = (Array.isArray(tmpStyles) ? tmpStyles[0] : tmpStyles).clone();\n\n let stroke = style.getStroke();\n\n if (feature.get(\"lineCap\")) {\n stroke?.setLineCap(feature.get(\"lineCap\"));\n }\n\n if (feature.get(\"lineJoin\")) {\n stroke?.setLineJoin(feature.get(\"lineJoin\"));\n }\n\n if (feature.get(\"lineDash\")) {\n stroke?.setLineDash(\n feature\n .get(\"lineDash\")\n .split(\",\")\n .map((l) => {\n return parseInt(l, 10);\n }),\n );\n }\n\n if (feature.get(\"lineDashOffset\")) {\n stroke?.setLineDashOffset(parseInt(feature.get(\"lineDashOffset\"), 10));\n }\n\n if (feature.get(\"miterLimit\")) {\n stroke?.setMiterLimit(parseInt(feature.get(\"miterLimit\"), 10));\n }\n\n // The canvas draws a stroke width=1 by default if width=0, so we\n // remove the stroke style in that case.\n if (stroke && stroke.getWidth() === 0) {\n stroke = undefined;\n }\n\n if (feature.get(\"zIndex\")) {\n style.setZIndex(parseInt(feature.get(\"zIndex\"), 10));\n }\n\n // if the feature is a Point and we are offline, we use default vector\n // style.\n // if the feature is a Point and has a name with a text style, we\n // create a correct text style.\n // TODO Handle GeometryCollection displaying name on the first Point\n // geometry.\n if (style && (geom instanceof Point || geom instanceof MultiPoint)) {\n let image = style.getImage();\n let text = null;\n let fill = style.getFill();\n\n // If the feature has name we display it on the map as Google does\n if (\n feature.get(\"name\") &&\n style.getText() &&\n style.getText().getScale() !== 0\n ) {\n if (image && image.getScale() === 0) {\n // transparentCircle is used to allow selection\n image = new Circle({\n radius: 1,\n fill: new Fill({ color: [0, 0, 0, 0] }),\n stroke: new Stroke({ color: [0, 0, 0, 0] }),\n });\n }\n\n // We replace empty white spaces used to keep normal spaces before and after the name.\n let name = feature.get(\"name\");\n if (/\\u200B/g.test(name)) {\n name = name.replace(/\\u200B/g, \"\");\n feature.set(\"name\", name);\n }\n\n // For backward compatibility we translate the bold and italic textFont property to a textArray prop\n const font = feature.get(\"textFont\") || \"normal 16px Helvetica\";\n\n // Since we use rich text in mapset editor we use a text array instead,\n // it's only necessary when there is new lines in the text\n // Manage new lines\n if (/\\n/.test(name)) {\n const array = [];\n const split = name.split(\"\\n\");\n split.forEach((txt, idx) => {\n array.push(txt || \"\\u200B\", txt ? font : \"\");\n\n if (idx < split.length - 1) {\n array.push(\"\\n\", \"\");\n }\n });\n name = array;\n } else {\n name = [name, font];\n }\n\n text = new Text({\n font: font.replace(/bold/g, \"normal\"), // We manage bold in textArray\n text: name,\n fill: style.getText().getFill(),\n // rotation unsupported by KML, taken instead from custom field.\n rotation: feature.get(\"textRotation\") || 0,\n // since ol 6.3.1 : https://github.com/openlayers/openlayers/pull/10613/files#diff-1883da8b57e690db7ea0c35ce53c880aR925\n // a default textstroke is added to mimic google earth.\n // it was not the case before, the stroke was always null. So to keep\n // the same behavior we don't copy the stroke style.\n // TODO : maybe we should use this functionnality in the futur.\n // stroke: style.getText().getStroke(),\n scale: style.getText().getScale(),\n });\n\n if (feature.get(\"textArray\")) {\n try {\n const textArray = JSON.parse(feature.get(\"textArray\"));\n text.setText(textArray);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\n \"Error parsing textArray\",\n feature.get(\"textArray\"),\n err,\n );\n }\n }\n\n if (feature.get(\"textStrokeColor\") && feature.get(\"textStrokeWidth\")) {\n text.setStroke(\n new Stroke({\n color: feature.get(\"textStrokeColor\"),\n width: parseFloat(feature.get(\"textStrokeWidth\")),\n }),\n );\n }\n\n if (feature.get(\"textAlign\")) {\n text.setTextAlign(feature.get(\"textAlign\"));\n }\n\n if (feature.get(\"textOffsetX\")) {\n text.setOffsetX(parseFloat(feature.get(\"textOffsetX\")));\n }\n\n if (feature.get(\"textOffsetY\")) {\n text.setOffsetY(parseFloat(feature.get(\"textOffsetY\")));\n }\n\n if (feature.get(\"textBackgroundFillColor\")) {\n text.setBackgroundFill(\n new Fill({\n color: feature.get(\"textBackgroundFillColor\"),\n }),\n );\n }\n\n if (feature.get(\"textPadding\")) {\n text.setPadding(\n feature\n .get(\"textPadding\")\n .split(\",\")\n .map((n) => {\n return parseFloat(n);\n }),\n );\n }\n if (image instanceof Icon) {\n applyTextStyleForIcon(image, text);\n }\n }\n\n if (image instanceof Icon) {\n /* Apply icon rotation if defined (by default only written as\n * <heading> tag, which is not read as rotation value by the ol KML module)\n */\n image.setRotation(parseFloat(feature.get(\"iconRotation\")) || 0);\n\n if (feature.get(\"iconScale\")) {\n image.setScale(parseFloat(feature.get(\"iconScale\")) || 0);\n\n // We fix the 32px scaling introduced by OL 6.7 only if the image has a size defined.\n } else if (!doNotRevert32pxScaling && image.getSize()) {\n const resizeScale = scaleForSize(image.getSize());\n image.setScale(image.getScaleArray()[0] / resizeScale);\n }\n }\n\n fill = undefined;\n stroke = undefined;\n\n styles = (feat, resolution) => {\n /* Options to be used for picture scaling with map, should have at least\n * a resolution attribute (this is the map resolution at the zoom level when\n * the picture is created), can take an optional constant for further scale\n * adjustment.\n * e.g. { resolution: 0.123, defaultScale: 1 / 6 }\n */\n\n if (feat.get(\"pictureOptions\")) {\n let pictureOptions = feat.get(\"pictureOptions\");\n if (typeof pictureOptions === \"string\") {\n pictureOptions = JSON.parse(pictureOptions);\n }\n feat.set(\"pictureOptions\", pictureOptions);\n if (pictureOptions.resolution) {\n image.setScale(\n (pictureOptions.resolution / resolution) *\n pictureOptions.defaultScale || 1,\n );\n }\n }\n\n return new Style({\n fill,\n stroke,\n image,\n text,\n zIndex: style.getZIndex(),\n });\n };\n }\n\n // Remove image and text styles for polygons and lines\n if (\n !(\n geom instanceof Point ||\n geom instanceof MultiPoint ||\n geom instanceof GeometryCollection\n )\n ) {\n styles = [\n new Style({\n fill: style.getFill(),\n stroke,\n image: null,\n text: null,\n zIndex: style.getZIndex(),\n }),\n ];\n\n // Parse the fillPattern json string and store parsed object\n let fillPattern = feature.get(\"fillPattern\");\n if (fillPattern) {\n fillPattern = JSON.parse(fillPattern);\n feature.set(\"fillPattern\", fillPattern);\n\n /* We set the fill pattern for polygons */\n if (!style.getFill()) {\n styles[0].setFill(new Fill());\n }\n const patternOrColor = fillPattern.empty\n ? [0, 0, 0, 0]\n : getPolygonPattern(fillPattern.id, fillPattern.color);\n styles[0].getFill().setColor(patternOrColor);\n }\n\n // Add line's icons styles\n if (feature.get(\"lineStartIcon\")) {\n styles.push(\n getLineIcon(\n feature,\n JSON.parse(feature.get(\"lineStartIcon\")),\n stroke.getColor(),\n ),\n );\n }\n\n if (feature.get(\"lineEndIcon\")) {\n styles.push(\n getLineIcon(\n feature,\n JSON.parse(feature.get(\"lineEndIcon\")),\n stroke.getColor(),\n false,\n ),\n );\n }\n }\n feature.setStyle(styles);\n};\n\n/**\n * Read a KML string.\n * @param {String} kmlString A string representing a KML file.\n * @param {<ol.Projection|String>} featureProjection The projection used by the map.\n * @param {<boolean>} doNotRevert32pxScaling Set it to true if you use ol < 6.7 and last version of react-spatial, Fix the 32px scaling, introduced by (ol >= 6.7), see https://github.com/openlayers/openlayers/pull/12695.\n */\nconst readFeatures = (\n kmlString,\n featureProjection,\n doNotRevert32pxScaling = false,\n) => {\n // Since ol 6.7, the KML follows better the spec and GoogleEarth interpretation, see https://github.com/openlayers/openlayers/pull/12695.\n // so the <scale> value is interpreted using an image size of 32px.\n // So when revert32pxScaling is true we fix back the scale, to use only, if you use an OL < 6.7.\n // Now the writeFeatures function use the iconScale extended data to set the image's scale.\n // If the extended data is not found it will look at this boolean to define if we must revert the scale or not.\n const features = new KML().readFeatures(kmlString, {\n featureProjection,\n });\n features.forEach((feature) => {\n // Transform back polygon to circle geometry\n const {\n [CIRCLE_GEOMETRY_CENTER]: circleGeometryCenter,\n [CIRCLE_GEOMETRY_RADIUS]: circleGeometryRadius,\n } = feature?.getProperties() || {};\n if (circleGeometryCenter && circleGeometryRadius) {\n const circle = new CircleGeom(\n transform(\n JSON.parse(circleGeometryCenter),\n EPSG_4326,\n featureProjection || EPSG_4326,\n ),\n parseFloat(circleGeometryRadius, 10),\n );\n circle.setProperties(feature.getGeometry().getProperties());\n feature.setGeometry(circle);\n }\n\n sanitizeFeature(feature, doNotRevert32pxScaling);\n });\n return features;\n};\n\n/**\n * Create a KML string.\n * @param {VectorLayer} layer A react-spatial VectorLayer.\n * @param {<ol.Projection|String>} featureProjection The current projection used by the features.\n * @param {<boolean>} fixGxyAndGxh If the KML contains gx:w and gx:h, (ol >= 6.7), it will fix the bug introduced by https://github.com/openlayers/openlayers/pull/12695.\n */\nconst writeFeatures = (layer, featureProjection, mapResolution) => {\n let featString;\n const { olLayer } = layer;\n const exportFeatures = [];\n\n [...olLayer.getSource().getFeatures()]\n .sort((a, b) => {\n // The order of features must be kept.\n // We could use the useSpatialIndex = false property on the layer\n // but we prefer to sort feature by ol uid because ol uid is an integer\n // increased on each creation of a feature.\n // So we will keep the order of creation made by the the KML parser.\n // Ideally we should order by the zIndex of the style only.\n if (getUid(a) <= getUid(b)) {\n return -1;\n }\n return 1;\n })\n .forEach((feature) => {\n const clone = feature.clone();\n if (clone.getGeometry().getType() === \"Circle\") {\n // We transform circle elements into polygons\n // because circle not supported in KML spec and in ol KML parser\n const circleGeom = feature.getGeometry();\n clone.setGeometry(fromCircle(circleGeom, 100));\n clone.set(\n CIRCLE_GEOMETRY_CENTER,\n JSON.stringify(\n transform(circleGeom.getCenter(), featureProjection, EPSG_4326),\n ),\n );\n clone.set(CIRCLE_GEOMETRY_RADIUS, circleGeom.getRadius());\n }\n clone.setId(feature.getId());\n clone.getGeometry().transform(featureProjection, EPSG_4326);\n\n // We remove all ExtendedData not related to style.\n Object.keys(feature.getProperties()).forEach((key) => {\n if (\n ![\n \"geometry\",\n \"name\",\n \"description\",\n CIRCLE_GEOMETRY_CENTER,\n CIRCLE_GEOMETRY_RADIUS,\n ].includes(key)\n ) {\n clone.unset(key, true);\n }\n });\n\n let styles;\n\n if (feature.getStyleFunction()) {\n styles = feature.getStyleFunction()(feature, mapResolution);\n } else if (olLayer && olLayer.getStyleFunction()) {\n styles = olLayer.getStyleFunction()(feature, mapResolution);\n }\n\n const mainStyle = styles[0] || styles;\n\n const newStyle = {\n fill: mainStyle.getFill(),\n stroke: mainStyle.getStroke(),\n text: mainStyle.getText(),\n image: mainStyle.getImage(),\n zIndex: mainStyle.getZIndex(),\n };\n\n if (newStyle.zIndex) {\n clone.set(\"zIndex\", newStyle.zIndex);\n }\n\n const text = newStyle.text?.getText();\n\n if (text) {\n let kmlText = text;\n\n if (Array.isArray(text)) {\n // text can be a string or an array of strings\n clone.set(\"textArray\", JSON.stringify(text));\n\n // in the KML we just add the text without the bold or italic information\n kmlText = text\n .map((t, idx) => {\n return idx % 2 === 0 ? t : \"\";\n })\n\n .join(\"\")\n .replaceAll(\"\\u200B\", \"\");\n }\n\n // We add the current text as features's name so it will be added as Placemark's name in the kml\n if (kmlText) {\n // If we see spaces at the beginning or at the end we add a empty\n // white space at the beginning and at the end.\n if (/^(\\s|\\n)|(\\n|\\s)$/g.test(kmlText)) {\n clone.set(\"name\", `\\u200B${kmlText}\\u200B`);\n } else {\n clone.set(\"name\", kmlText);\n }\n }\n }\n\n // Set custom properties to be converted in extendedData in KML.\n if (newStyle.text?.getRotation()) {\n clone.set(\"textRotation\", newStyle.text.getRotation());\n }\n\n if (newStyle.text?.getFont()) {\n clone.set(\"textFont\", newStyle.text.getFont());\n }\n\n if (newStyle.text?.getTextAlign()) {\n clone.set(\"textAlign\", newStyle.text.getTextAlign());\n }\n\n if (newStyle.text?.getOffsetX()) {\n clone.set(\"textOffsetX\", newStyle.text.getOffsetX());\n }\n\n if (newStyle.text?.getOffsetY()) {\n clone.set(\"textOffsetY\", newStyle.text.getOffsetY());\n }\n\n if (newStyle.text?.getStroke()) {\n if (newStyle.text.getStroke().getColor()) {\n clone.set(\n \"textStrokeColor\",\n asString(newStyle.text.getStroke().getColor()),\n );\n }\n\n if (newStyle.text.getStroke().getWidth()) {\n clone.set(\"textStrokeWidth\", newStyle.text.getStroke().getWidth());\n }\n }\n\n if (newStyle.text?.getBackgroundFill()) {\n clone.set(\n \"textBackgroundFillColor\",\n asString(newStyle.text.getBackgroundFill().getColor()),\n );\n }\n\n if (newStyle.text?.getPadding()) {\n clone.set(\"textPadding\", newStyle.text.getPadding().join());\n }\n\n if (newStyle.stroke?.getLineCap()) {\n clone.set(\"lineCap\", newStyle.stroke.getLineCap());\n }\n\n if (newStyle.stroke?.getLineJoin()) {\n clone.set(\"lineJoin\", newStyle.stroke.getLineJoin());\n }\n\n if (newStyle.stroke?.getLineDash()) {\n clone.set(\"lineDash\", newStyle.stroke.getLineDash().join(\",\"));\n }\n\n if (newStyle.stroke?.getLineDashOffset()) {\n clone.set(\"lineDashOffset\", newStyle.stroke.getLineDashOffset());\n }\n\n if (newStyle.stroke?.getMiterLimit()) {\n clone.set(\"miterLimit\", newStyle.stroke.getMiterLimit());\n }\n\n if (newStyle.image instanceof Circle) {\n newStyle.image = null;\n }\n\n if (newStyle.image) {\n const imgSource = newStyle.image.getSrc();\n if (!/(http(s?)):\\/\\//gi.test(imgSource)) {\n // eslint-disable-next-line no-console\n console.log(\n \"Local image source not supported for KML export.\" +\n \"Should use remote web server\",\n );\n }\n\n if (newStyle.image.getRotation()) {\n // We set the icon rotation as extended data\n clone.set(\"iconRotation\", newStyle.image.getRotation());\n }\n\n if (newStyle.image.getScale()) {\n // We set the scale as extended metadata because the <scale> in the KML is related to a 32px img, since ol >= 6.10.\n clone.set(\"iconScale\", newStyle.image.getScale());\n }\n\n // Set map resolution to use for icon-to-map proportional scaling\n if (feature.get(\"pictureOptions\")) {\n clone.set(\n \"pictureOptions\",\n JSON.stringify(feature.get(\"pictureOptions\")),\n );\n }\n }\n\n // In case a fill pattern should be applied (use fillPattern attribute to store pattern id, color etc)\n if (feature.get(\"fillPattern\")) {\n clone.set(\"fillPattern\", JSON.stringify(feature.get(\"fillPattern\")));\n newStyle.fill = null;\n }\n\n // maxZoom: maximum zoom level at which the feature is displayed\n if (feature.get(\"maxZoom\")) {\n clone.set(\"maxZoom\", parseFloat(feature.get(\"maxZoom\"), 10));\n }\n\n // minZoom: minimum zoom level at which the feature is displayed\n if (feature.get(\"minZoom\")) {\n clone.set(\"minZoom\", parseFloat(feature.get(\"minZoom\"), 10));\n }\n\n // If only text is displayed we must specify an\n // image style with scale=0\n if (newStyle.text && !newStyle.image) {\n newStyle.image = new Icon({\n src: \"noimage\",\n scale: 0,\n });\n }\n\n // In case we use line's icon .\n const extraLineStyles = (Array.isArray(styles) && styles.slice(1)) || [];\n extraLineStyles.forEach((extraLineStyle) => {\n if (\n extraLineStyle &&\n extraLineStyle.getImage() instanceof Icon &&\n extraLineStyle.getGeometry()\n ) {\n const coord = extraLineStyle.getGeometry()(feature).getCoordinates();\n const startCoord = feature.getGeometry().getFirstCoordinate();\n if (coord[0] === startCoord[0] && coord[1] === startCoord[1]) {\n clone.set(\n \"lineStartIcon\",\n JSON.stringify({\n url: extraLineStyle.getImage().getSrc(),\n scale: extraLineStyle.getImage().getScale(),\n size: extraLineStyle.getImage().getSize(),\n zIndex: extraLineStyle.getZIndex(),\n }),\n );\n } else {\n clone.set(\n \"lineEndIcon\",\n JSON.stringify({\n url: extraLineStyle.getImage().getSrc(),\n scale: extraLineStyle.getImage().getScale(),\n size: extraLineStyle.getImage().getSize(),\n zIndex: extraLineStyle.getZIndex(),\n }),\n );\n }\n }\n });\n\n const olStyle = new Style(newStyle);\n clone.setStyle(olStyle);\n\n if (\n !(\n clone.getGeometry() instanceof Point &&\n olStyle.getText() &&\n !olStyle.getText().getText()\n )\n ) {\n exportFeatures.push(clone);\n }\n });\n\n if (exportFeatures.length > 0) {\n if (exportFeatures.length === 1) {\n // force the add of a <Document> node\n exportFeatures.push(new Feature());\n }\n\n featString = new KML({\n extractStyles: true,\n defaultStyle: [kmlStyle],\n }).writeFeatures(exportFeatures);\n\n // Remove no image hack\n featString = featString.replace(\n /<Icon>\\s*<href>noimage<\\/href>\\s*<\\/Icon>/g,\n \"\",\n );\n\n // Remove empty placemark added to have\n // <Document> tag\n featString = featString.replace(/<Placemark\\/>/g, \"\");\n\n // Add KML document name\n if (layer.name) {\n featString = featString.replace(\n /<Document>/,\n `<Document><name>${layer.name}</name>`,\n );\n }\n }\n\n return featString;\n};\n\n/**\n * Removes the <Camera> tag from a KML string. Returns the KML string with removed <Camera> tag.\n * @param {String} kmlString A string representing a KML file.\n */\nconst removeDocumentCamera = (kmlString) => {\n const kmlDoc = parse(kmlString);\n // Remove old Camera node\n const oldCameraNode = kmlDoc.getElementsByTagName(\"Camera\")[0];\n if (oldCameraNode) {\n oldCameraNode.remove();\n }\n return new XMLSerializer().serializeToString(kmlDoc);\n};\n\n/**\n * Write the <Camera> tag into a KML string. Returns the KML string with added <Camera> tag.\n * @param {String} kmlString A string representing a KML file.\n * @param {Object} cameraAttributes Object containing the camera tags (longitude, latitude, altitude, heading, tilt, altitudeMode, roll)\n * as keys with corresponding values. See https://developers.google.com/kml/documentation/kmlreference#camera\n */\nconst writeDocumentCamera = (kmlString, cameraAttributes) => {\n const kmlDoc = parse(removeDocumentCamera(kmlString));\n\n if (cameraAttributes) {\n // Create Camera node with child attributes if the cameraAttributes object is defined\n const cameraNode = kmlDoc.createElement(\"Camera\");\n Object.keys(cameraAttributes).forEach((key) => {\n const cameraAttribute = kmlDoc.createElement(\n `${key.charAt(0).toUpperCase() + key.slice(1)}`,\n );\n cameraAttribute.innerHTML = cameraAttributes[key];\n cameraNode.appendChild(cameraAttribute);\n });\n const documentNode = kmlDoc.getElementsByTagName(\"Document\")[0];\n documentNode.appendChild(cameraNode);\n }\n\n return new XMLSerializer().serializeToString(kmlDoc);\n};\n\nexport default {\n readFeatures,\n writeFeatures,\n writeDocumentCamera,\n removeDocumentCamera,\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|