gy-map
Version:
gy
19,038 lines • 563 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { defineComponent, onMounted, watch, onBeforeUnmount, ref, getCurrentInstance, computed, onBeforeMount, markRaw } from "vue-demi";
import { Style as Style$1, Stroke as Stroke$2, Fill as Fill$2, Icon as Icon$2, Circle as Circle$1, Text as Text$2 } from "ol/style";
import VectorLayer$2 from "ol/layer/Vector";
import VectorSource$2 from "ol/source/Vector";
import GeoJSON from "ol/format/GeoJSON";
import LineString from "ol/geom/LineString";
import feature from "ol/Feature";
import { fromLonLat as fromLonLat$1, toLonLat as toLonLat$1 } from "ol/proj";
import * as turf from "@turf/turf";
import { Point as Point$3 } from "ol/geom";
import { Vector as Vector$1, Heatmap } from "ol/layer";
import Map from "ol/Map";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import View$2 from "ol/View";
import Overlay from "ol/Overlay";
import { Draw, Snap, Modify, defaults as defaults$1 } from "ol/interaction";
import { Vector } from "ol/source";
import { singleClick as singleClick$1, altKeyOnly } from "ol/events/condition";
import Point$2 from "ol/geom/Point";
const x_PI = 3.141592653589793 * 3e3 / 180;
const PI = 3.141592653589793;
const a = 6378245;
const ee = 0.006693421622965943;
function bd09togcj02(bd_lon, bd_lat) {
let x_pi = 3.141592653589793 * 3e3 / 180;
let x = bd_lon - 65e-4;
let y = bd_lat - 6e-3;
let z = Math.sqrt(x * x + y * y) - 2e-5 * Math.sin(y * x_pi);
let theta = Math.atan2(y, x) - 3e-6 * Math.cos(x * x_pi);
let gg_lng = z * Math.cos(theta);
let gg_lat = z * Math.sin(theta);
return [gg_lng, gg_lat];
}
function gcj02tobd09(lng, lat) {
let z = Math.sqrt(lng * lng + lat * lat) + 2e-5 * Math.sin(lat * x_PI);
let theta = Math.atan2(lat, lng) + 3e-6 * Math.cos(lng * x_PI);
let bd_lng = z * Math.cos(theta) + 65e-4;
let bd_lat = z * Math.sin(theta) + 6e-3;
return [bd_lng, bd_lat];
}
function wgs84togcj02(lng, lat) {
if (outOfChina(lng, lat)) {
return [lng, lat];
} else {
let dlat = transformlat(lng - 105, lat - 35);
let dlng = transformlng(lng - 105, lat - 35);
let radlat = lat / 180 * PI;
let magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = dlat * 180 / (a * (1 - ee) / (magic * sqrtmagic) * PI);
dlng = dlng * 180 / (a / sqrtmagic * Math.cos(radlat) * PI);
const mglat = lat + dlat;
const mglng = lng + dlng;
return [mglng, mglat];
}
}
function gcj02towgs84(lng, lat) {
if (outOfChina(lng, lat)) {
return [lng, lat];
} else {
let dlat = transformlat(lng - 105, lat - 35);
let dlng = transformlng(lng - 105, lat - 35);
let radlat = lat / 180 * PI;
let magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
let sqrtmagic = Math.sqrt(magic);
dlat = dlat * 180 / (a * (1 - ee) / (magic * sqrtmagic) * PI);
dlng = dlng * 180 / (a / sqrtmagic * Math.cos(radlat) * PI);
const mglat = lat + dlat;
const mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat];
}
}
function bd09towgs84(lng, lat) {
const gcj02 = bd09togcj02(lng, lat);
const result = gcj02towgs84(gcj02[0], gcj02[1]);
return result;
}
function wgs84tobd09(lng, lat) {
const gcj02 = wgs84togcj02(lng, lat);
const result = gcj02tobd09(gcj02[0], gcj02[1]);
return result;
}
function transformlat(lng, lat) {
let ret = -100 + 2 * lng + 3 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20 * Math.sin(6 * lng * PI) + 20 * Math.sin(2 * lng * PI)) * 2 / 3;
ret += (20 * Math.sin(lat * PI) + 40 * Math.sin(lat / 3 * PI)) * 2 / 3;
ret += (160 * Math.sin(lat / 12 * PI) + 320 * Math.sin(lat * PI / 30)) * 2 / 3;
return ret;
}
function transformlng(lng, lat) {
let ret = 300 + lng + 2 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20 * Math.sin(6 * lng * PI) + 20 * Math.sin(2 * lng * PI)) * 2 / 3;
ret += (20 * Math.sin(lng * PI) + 40 * Math.sin(lng / 3 * PI)) * 2 / 3;
ret += (150 * Math.sin(lng / 12 * PI) + 300 * Math.sin(lng / 30 * PI)) * 2 / 3;
return ret;
}
function outOfChina(lng, lat) {
return lng < 72.004 || lng > 137.8347 || (lat < 0.8293 || lat > 55.8271 || false);
}
let gyMapLonLatType = "WGS84";
const setMapLonLatType = (type) => {
gyMapLonLatType = type;
};
const getMapLonLatType = () => {
return gyMapLonLatType;
};
const formatLonLatToPosition = (lon, lat) => {
if (Array.isArray(lon)) {
return formatLonLatToPosition(lon[0], lon[1]);
} else {
if (!lat) {
console.error("\u8BF7\u4F20\u5165\u6B63\u786E\u7684\u53C2\u6570\uFF01");
return [];
}
return fromLonLat$1(wGS84ToLonlat(lon, lat, getMapLonLatType()));
}
};
const flortAdd = (num1, num2) => {
let r1, r2, m;
try {
r1 = num1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = num2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return Math.round(num1 * m + num2 * m) / m;
};
const lonlatToWGS84 = (lon, lat, type) => {
lon = +lon;
lat = +lat;
type = type.toUpperCase();
if (type === "GCJ02") {
return gcj02towgs84(lon, lat);
} else if (type === "BD09") {
return bd09towgs84(lon, lat);
} else {
return [lon, lat];
}
};
const wGS84ToLonlat = (lon, lat, type) => {
lon = +lon;
lat = +lat;
type = type.toUpperCase();
if (type === "GCJ02") {
return gcj02towgs84(lon, lat);
} else if (type === "BD09") {
return bd09towgs84(lon, lat);
} else {
return [lon, lat];
}
};
const getBufferArea = (positionArr, radius = 200) => {
if (positionArr.length === 0 || radius === 0) {
return [];
}
let geojsonObj;
if (positionArr.length === 1) {
geojsonObj = turf.point(positionArr[0]);
} else {
if (positionArr[0][0] === positionArr[positionArr.length - 1][0] && positionArr[0][1] === positionArr[positionArr.length - 1][1]) {
geojsonObj = turf.polygon([positionArr]);
} else {
geojsonObj = turf.lineString(positionArr);
}
}
let buffer2 = turf.buffer(geojsonObj, radius, { units: "meters" });
if (buffer2.geometry.type === "Polygon") {
return buffer2.geometry.coordinates[0];
}
if (buffer2.geometry.type === "MultiPolygon") {
return buffer2.geometry.coordinates[0][0];
}
return [];
};
const gyMapUtils = {
formatLonLatToPosition,
flortAdd,
gcj02towgs84,
bd09towgs84,
wgs84tobd09,
wgs84togcj02,
lonlatToWGS84,
wGS84ToLonlat,
setMapLonLatType,
getBufferArea
};
const __vue2_script$b = defineComponent({
name: "Gymap",
props: {
mapOpt: {
type: Object,
default: () => ({})
},
center: {
type: Array,
default: () => []
},
maplayerIndex: {
type: Number,
default: 0
},
zoom: {
type: Number,
default: 0
},
layerOpacity: {
type: Number,
default: 1
},
mapId: {
type: String,
default: "map"
},
lonlatType: {
type: String,
default: "WGS84"
},
interactionsObj: {
type: Object,
default: () => ({})
},
isShowControls: {
type: Boolean,
default: false
}
},
setup(props) {
const gyMapObj = gyMap$1(props.mapId).value;
setMapLonLatType(props.lonlatType);
onMounted(() => {
gyMapObj.init(props.mapId, {
...props.mapOpt,
maplayerIndex: props.maplayerIndex,
zoom: props.zoom,
centerPoint: props.center,
layerOpacity: props.layerOpacity,
interactionsObj: props.interactionsObj,
isShowControls: props.isShowControls
});
});
const mouseenterFun = () => {
const contentIdDom = document.getElementById(props.mapId);
if (contentIdDom) {
contentIdDom.focus();
}
};
watch(() => props.zoom, (n) => {
gyMapObj && gyMapObj.zoomSetFun(n);
});
watch(() => props.maplayerIndex, (n) => {
gyMapObj && gyMapObj.changeMapLayer(n);
});
watch(() => props.center, (n) => {
gyMapObj && gyMapObj.changeCenterPoint(n);
});
watch(() => props.layerOpacity, (n) => {
gyMapObj && gyMapObj.setLayerOpacity(n);
});
onBeforeUnmount(() => {
gyMapObj && gyMapObj.destory();
});
return {
id: props.mapId,
gyMapObj,
mouseenterFun
};
}
});
var render$b = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", {
staticClass: "map divMap",
attrs: {
"id": _vm.mapId,
"tabindex": "0"
},
on: {
"mouseenter": _vm.mouseenterFun
}
}, [_vm._t("default")], 2);
};
var staticRenderFns$b = [];
const Gymap_vue_vue_type_style_index_0_scoped_true_lang = "";
function normalizeComponent(scriptExports, render2, staticRenderFns2, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) {
var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports;
if (render2) {
options.render = render2;
options.staticRenderFns = staticRenderFns2;
options._compiled = true;
}
if (functionalTemplate) {
options.functional = true;
}
if (scopeId) {
options._scopeId = "data-v-" + scopeId;
}
var hook;
if (moduleIdentifier) {
hook = function(context) {
context = context || this.$vnode && this.$vnode.ssrContext || this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext;
if (!context && typeof __VUE_SSR_CONTEXT__ !== "undefined") {
context = __VUE_SSR_CONTEXT__;
}
if (injectStyles) {
injectStyles.call(this, context);
}
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
options._ssrRegister = hook;
} else if (injectStyles) {
hook = shadowMode ? function() {
injectStyles.call(
this,
(options.functional ? this.parent : this).$root.$options.shadowRoot
);
} : injectStyles;
}
if (hook) {
if (options.functional) {
options._injectStyles = hook;
var originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
} else {
var existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return {
exports: scriptExports,
options
};
}
const __cssModules$b = {};
var __component__$b = /* @__PURE__ */ normalizeComponent(
__vue2_script$b,
render$b,
staticRenderFns$b,
false,
__vue2_injectStyles$b,
"5c0faef4",
null,
null
);
function __vue2_injectStyles$b(context) {
for (let o in __cssModules$b) {
this[o] = __cssModules$b[o];
}
}
const Gymap = /* @__PURE__ */ function() {
return __component__$b.exports;
}();
const __vue2_script$a = defineComponent({
name: "GymapHtml",
props: {
offset: {
type: Array,
default: () => [0, 0]
},
position: {
type: Array,
default: () => []
},
stopEvent: {
type: Boolean,
default: true
},
className: {
type: String,
default: ""
},
maxZoom: {
type: Number,
default: 18
},
minZoom: {
type: Number,
default: 0
},
mapId: {
type: String,
default: ""
}
},
setup(props) {
const htmlDom = ref(null);
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const gyMapObj = gyMap$1(mapId).value;
const mapFinish = computed(() => gyMapObj && gyMapObj.mapFinish);
const zoom = computed(() => gyMapObj && gyMapObj.zoom);
let isDraw = false;
watch(mapFinish, () => {
drawDom();
});
let isUndefined = false;
const changeZoomFun = (val) => {
if (val > props.maxZoom || val < props.minZoom) {
isUndefined = true;
overlay && overlay.setPosition(void 0);
} else if (isUndefined) {
isUndefined = false;
setOverLayerPosition(props.position);
}
};
watch(zoom, (val) => {
changeZoomFun(val);
});
let overlay = null;
const drawDom = () => {
if (mapFinish.value && !isDraw) {
isDraw = true;
overlay = gyMapObj.drawHtmlToMap(htmlDom.value, {
offset: props.offset,
position: props.position,
stopEvent: props.stopEvent,
className: props.className
});
changeZoomFun(zoom.value);
const runTask = proxy.$parent.runTask;
if (runTask) {
runTask(overlay, props);
}
}
};
onMounted(() => {
drawDom();
});
const setOverLayerPosition = (p) => {
let pos = gyMapUtils.formatLonLatToPosition(p);
overlay && overlay.setPosition(pos);
};
watch(() => props.position, (p) => {
setOverLayerPosition(p);
changeZoomFun(zoom.value);
});
watch(() => props.offset, (p) => {
overlay && overlay.setOffset(p);
});
onBeforeUnmount(() => {
overlay && gyMapObj && gyMapObj.removeOverlay(overlay);
const destoryTask = proxy.$parent.destory;
if (destoryTask) {
destoryTask();
}
});
return {
htmlDom,
mapId,
gyMapObj,
mapFinish
};
}
});
var render$a = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", {
ref: "htmlDom",
staticClass: "GymapHtml"
}, [_vm._t("default")], 2);
};
var staticRenderFns$a = [];
const __cssModules$a = {};
var __component__$a = /* @__PURE__ */ normalizeComponent(
__vue2_script$a,
render$a,
staticRenderFns$a,
false,
__vue2_injectStyles$a,
null,
null,
null
);
function __vue2_injectStyles$a(context) {
for (let o in __cssModules$a) {
this[o] = __cssModules$a[o];
}
}
const GymapHtml = /* @__PURE__ */ function() {
return __component__$a.exports;
}();
const __vue2_script$9 = defineComponent({
name: "GymapPolygon",
props: {
positionList: {
type: Array,
default: () => []
},
className: {
type: String
},
fillColor: {
type: String,
default: "rgba(0, 0, 255, 0.1)"
},
strokeColor: {
type: String,
default: ""
},
strokeWidth: {
type: Number,
default: 3
},
minZoom: {
type: Number,
default: 1
},
maxZoom: {
type: Number,
default: 18
},
opacity: {
type: Number,
default: 1
},
mapId: {
type: String,
default: ""
}
},
emits: ["clickFun"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const gyMapObj = gyMap$1(mapId);
const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
let polygonLayer = null;
let isDraw = false;
watch(mapFinish, () => {
drawPolygon();
});
onMounted(() => {
drawPolygon();
});
const getFeatures = () => {
let positionList = props.positionList;
let firstValue = positionList[0];
let lonlatArr = [];
if (firstValue && !Array.isArray(firstValue[0])) {
lonlatArr = [positionList];
} else {
lonlatArr = positionList;
}
let features = lonlatArr.map((v) => {
let coordinates2 = v.map((v2) => {
return gyMapUtils.formatLonLatToPosition(v2);
});
return {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
coordinates2
]
}
};
});
return features;
};
const getSource = () => {
const features = getFeatures();
if (!features) {
return;
}
const geojsonObject = {
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:3857"
}
},
"features": features
};
const source = new VectorSource$2({
features: new GeoJSON().readFeatures(geojsonObject)
});
let feature2 = source.getFeatures()[0] || null;
if (feature2) {
feature2.on("click", (e) => {
emit("clickFun", e);
});
}
return source;
};
const getStyle = () => {
return new Style$1({
stroke: props.strokeColor ? new Stroke$2({
color: props.strokeColor,
width: props.strokeWidth
}) : null,
fill: props.fillColor ? new Fill$2({
color: props.fillColor
}) : null
});
};
const drawPolygon = () => {
if (!mapFinish.value || isDraw) {
return;
}
isDraw = true;
const source = getSource();
if (!source) {
return;
}
const stylePol = getStyle();
polygonLayer = new VectorLayer$2({
source,
style: [stylePol],
minZoom: props.minZoom,
maxZoom: props.maxZoom,
opacity: props.opacity
});
gyMapObj.value.map.addLayer(polygonLayer);
};
watch(() => props.positionList, () => {
const source = getSource();
if (!source) {
return;
}
polygonLayer && polygonLayer.setSource(source);
}, {
deep: true
});
watch([() => props.strokeColor, () => props.strokeWidth, () => props.fillColor], () => {
const stylePol = getStyle();
polygonLayer && polygonLayer.setStyle(stylePol);
});
watch(() => props.opacity, (n) => {
polygonLayer && polygonLayer.setOpacity(n);
});
watch(() => props.minZoom, (n) => {
polygonLayer && polygonLayer.setMinZoom(n);
});
watch(() => props.maxZoom, (n) => {
polygonLayer && polygonLayer.setMaxZoom(n);
});
const destory = () => {
if (polygonLayer) {
gyMapObj.value && gyMapObj.value.map.removeLayer(polygonLayer);
polygonLayer = null;
}
};
onBeforeUnmount(() => {
destory();
});
}
});
var render$9 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div");
};
var staticRenderFns$9 = [];
const __cssModules$9 = {};
var __component__$9 = /* @__PURE__ */ normalizeComponent(
__vue2_script$9,
render$9,
staticRenderFns$9,
false,
__vue2_injectStyles$9,
null,
null,
null
);
function __vue2_injectStyles$9(context) {
for (let o in __cssModules$9) {
this[o] = __cssModules$9[o];
}
}
const GymapPolygon = /* @__PURE__ */ function() {
return __component__$9.exports;
}();
const arrowIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAATCAMAAACTKxybAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAHJQTFRF//////8A//8A/6pV/79A/8wz/9Ur/9Eu/8Q7/8wz/9It/8k2/9Eu/8o1/9Av/8o1/84x/8wz/8wz/8wz/8wz/8wz/8s0/8wz/8s0/8wz/8wz/8wz/8wz/8s0/8wz/8wz/8wz/8wz/8wz/8wz/8wz/8wzo2lg3QAAACV0Uk5TAAECAwQFBgsNDxETFhgbHUNGm6Ckqa2usrW+w8fLztLV1tnc9jtYQ+sAAABdSURBVAjXZc9HDsAwCARAp/fee+X/X8wesIQVbiMELEqVU6B0VS8tocZARGvE8Edoi1leD+0Jy+2gI2U5LXRmLLuB7pxl1dBT6N4Fzf+OnJHb5B2ZwMhmpDb+kZ9+tBQLxwwvvoMAAAAASUVORK5CYII=";
const __vue2_script$8 = defineComponent({
name: "GymapLine",
props: {
positionList: {
type: Array,
default: () => []
},
strokeColor: {
type: String,
default: "blue"
},
strokeWidth: {
type: Number,
default: 3
},
minZoom: {
type: Number,
default: 1
},
maxZoom: {
type: Number,
default: 18
},
opacity: {
type: Number,
default: 1
},
arrow: {
type: [Boolean, String],
default: false
},
arrowAnchor: {
type: Array,
default: () => [0.75, 0.5]
},
animate: {
type: Boolean,
default: false
},
step: {
type: Number,
default: 1e-3
},
loop: {
type: Boolean,
default: false
},
arrowStep: {
type: Number,
default: 20
},
mapId: {
type: String,
default: ""
}
},
emits: ["clickFun"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const gyMapObj = gyMap$1(mapId);
const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
let lineLayer = null;
let lineFeatures = null;
let isDraw = false;
let style = null;
let lineAllGeometry = null;
let lineGeometry = null;
let animCoordinates = [];
let aId = null;
let lineIndex = 0;
let lineFeature = null;
watch(mapFinish, () => {
drawLine();
});
onMounted(() => {
drawLine();
});
const getCoordinates = (positionList) => {
let coordinates2 = positionList.map((v) => {
return gyMapUtils.formatLonLatToPosition(v);
});
return new LineString(coordinates2);
};
const getFeatures = () => {
let positionList = props.positionList;
if (props.animate) {
positionList = [];
}
lineGeometry = getCoordinates(positionList);
lineFeature = new feature({
type: "lineStyle",
geometry: lineGeometry
});
lineFeature.on("click", (e) => {
emit("clickFun", e);
});
return lineFeature;
};
const getSource = () => {
lineFeatures = getFeatures();
lineFeatures.setStyle(style);
if (!lineFeatures) {
return;
}
return new VectorSource$2({
features: [lineFeatures]
});
};
const styleFunction = function(feature2) {
const geometry = feature2.getGeometry();
const styles = [
new Style$1({
stroke: new Stroke$2({
color: props.strokeColor,
width: props.strokeWidth
})
})
];
if (props.arrow) {
let i = 0;
let step = props.step;
step = Math.min(step, 0.01);
geometry.forEachSegment(function(start, end) {
const dx = end[0] - start[0];
const dy = end[1] - start[1];
const rotation = Math.atan2(dy, dx);
i++;
let arrowStep = Math.min(props.arrowStep, 1 / step);
if (!props.animate || i % (1 / step / arrowStep) == 0) {
let icon = null;
if (typeof props.arrow === "boolean") {
icon = arrowIcon;
} else {
icon = props.arrow;
}
styles.push(
new Style$1({
geometry: new Point$2(end),
image: new Icon$2({
src: icon,
anchor: props.arrowAnchor,
rotateWithView: true,
rotation: -rotation
})
})
);
}
});
}
return styles;
};
const drawLine = () => {
if (!mapFinish.value || isDraw) {
return;
}
isDraw = true;
style = styleFunction;
clearTimer();
const source = getSource();
if (!source) {
return;
}
lineLayer = new VectorLayer$2({
source,
minZoom: props.minZoom,
maxZoom: props.maxZoom,
opacity: props.opacity
});
gyMapObj.value.map.addLayer(lineLayer);
if (props.animate) {
lineAllGeometry = getCoordinates(props.positionList);
animate();
}
};
const animate = () => {
animCoordinates.push(lineAllGeometry.getCoordinateAt(Math.min(lineIndex, 1)));
updateLine();
if (lineIndex > 1) {
clearTimer();
if (props.loop) {
animCoordinates = [];
lineIndex = 0;
animate();
}
return;
}
let step = props.step;
step = Math.min(step, 0.01);
lineIndex += step;
aId = window.requestAnimationFrame(animate);
};
const updateLine = () => {
let line = null;
if (props.animate) {
line = new LineString(animCoordinates);
} else {
line = getCoordinates(props.positionList);
}
lineFeature && lineFeature.setGeometry(line);
};
const destory = () => {
if (lineLayer) {
gyMapObj.value && gyMapObj.value.map.removeLayer(lineLayer);
lineLayer = null;
}
clearTimer();
};
const clearTimer = () => {
aId && window.cancelAnimationFrame(aId);
};
watch(() => props.positionList, (n) => {
updateLine();
});
watch(() => props.opacity, (n) => {
lineLayer && lineLayer.setOpacity(n);
});
watch(() => props.animate, (n) => {
isDraw = false;
destory();
drawLine();
});
watch(() => props.minZoom, (n) => {
lineLayer && lineLayer.setMinZoom(n);
});
watch(() => props.maxZoom, (n) => {
lineLayer && lineLayer.setMaxZoom(n);
});
watch([() => props.strokeColor, () => props.strokeColor, () => props.arrow], () => {
style = styleFunction;
lineFeatures && lineFeatures.setStyle(style);
});
onBeforeUnmount(() => {
destory();
});
}
});
var render$8 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div");
};
var staticRenderFns$8 = [];
const __cssModules$8 = {};
var __component__$8 = /* @__PURE__ */ normalizeComponent(
__vue2_script$8,
render$8,
staticRenderFns$8,
false,
__vue2_injectStyles$8,
null,
null,
null
);
function __vue2_injectStyles$8(context) {
for (let o in __cssModules$8) {
this[o] = __cssModules$8[o];
}
}
const GymapLine = /* @__PURE__ */ function() {
return __component__$8.exports;
}();
const __vue2_script$7 = defineComponent({
name: "GymapTask",
props: {
mapId: {
type: String,
default: ""
},
positionList: {
type: Array,
default: () => []
},
loop: {
type: Boolean,
default: false
},
step: {
type: Number,
default: 1e-3
},
taskStatus: {
type: String,
default: "play"
},
delay: {
type: Number,
default: 3e3
},
animateDataType: {
type: String,
default: "LONLAT"
}
},
emits: ["animate"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
let canPlay = true;
let noComponents = false;
let childrenWatch = null;
let layer = null;
let timer = void 0;
const runTask = (childLayerObj, childProps) => {
if (!canPlay) {
return;
}
if (!noComponents) {
if (!childrenWatch) {
childrenWatch = watch(() => childProps.position, () => {
animIndex = 0;
destory();
});
}
layer = childLayerObj;
}
if (props.taskStatus === "play") {
startTask();
}
if (props.delay !== 0) {
timer = setTimeout(() => {
startTask();
}, props.delay);
}
};
watch(() => props.taskStatus, (n) => {
if (n === "play") {
startTask();
} else if (n === "stop") {
animIndex = 0;
stopTask();
} else if (n === "pause") {
stopTask();
}
});
const getAllCoordinates = (positions) => {
let coordinates2 = positions.map((v) => {
return gyMapUtils.formatLonLatToPosition(v);
});
let linestring = new LineString(coordinates2);
return linestring;
};
let lineGeometry = null;
const startTask = () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
if (noComponents ? false : !layer) {
return;
}
if (aId) {
return;
}
if (!lineGeometry) {
lineGeometry = getAllCoordinates(props.positionList);
}
animate();
};
let animIndex = 0;
let aId = null;
const animate = () => {
let coordinate = lineGeometry.getCoordinateAt(Math.min(animIndex, 1));
if (!noComponents) {
if (layer.geometry) {
layer.geometry.setCoordinates(coordinate);
} else {
layer.setPosition(coordinate);
}
}
if (props.animateDataType === "LONLAT") {
coordinate = toLonLat$1(coordinate);
}
emit("animate", coordinate, animIndex);
if (animIndex > 1) {
stopTask();
if (props.loop) {
animIndex = 0;
animate();
}
return;
}
let step = props.step;
animIndex = gyMapUtils.flortAdd(animIndex, step);
aId = window.requestAnimationFrame(animate);
};
const stopTask = () => {
childrenWatch && childrenWatch();
aId && window.cancelAnimationFrame(aId);
aId = null;
};
const destory = () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
stopTask();
};
onBeforeMount(() => {
let defaultStr = proxy.$slots.default;
if (defaultStr) {
let children = proxy.$slots.default();
let len = 0;
for (let i = 0; i < children.length; i++) {
let child = children[i];
if (typeof child.type !== "symbol") {
len++;
if (len > 1) {
canPlay = false;
console.error("GymapTask\u7EC4\u4EF6\u4E2D\u53EA\u5141\u8BB8\u5B58\u5728\u4E00\u4E2A\u9700\u8981\u6267\u884C\u52A8\u753B\u7684\u7EC4\u4EF6\u3002");
break;
}
}
}
} else if (!defaultStr) {
noComponents = true;
runTask();
}
});
onMounted(() => {
if (noComponents) {
runTask();
}
});
return {
id: mapId,
runTask,
destory
};
}
});
var render$7 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", [_vm._t("default")], 2);
};
var staticRenderFns$7 = [];
const __cssModules$7 = {};
var __component__$7 = /* @__PURE__ */ normalizeComponent(
__vue2_script$7,
render$7,
staticRenderFns$7,
false,
__vue2_injectStyles$7,
null,
null,
null
);
function __vue2_injectStyles$7(context) {
for (let o in __cssModules$7) {
this[o] = __cssModules$7[o];
}
}
const GymapTask = /* @__PURE__ */ function() {
return __component__$7.exports;
}();
class createOlLayer {
constructor(id, stylesObj, emit, clusterSource, otherOpts) {
__publicField(this, "style");
__publicField(this, "geometry");
__publicField(this, "feature");
__publicField(this, "mapId");
__publicField(this, "source");
__publicField(this, "layer");
__publicField(this, "clusterSource");
__publicField(this, "minZoom");
__publicField(this, "maxZoom");
__publicField(this, "olPositions");
__publicField(this, "opacity");
__publicField(this, "declutter");
__publicField(this, "zIndex");
__publicField(this, "stylesObj");
__publicField(this, "gyMapObj");
__publicField(this, "mapFinish");
__publicField(this, "isDraw");
__publicField(this, "emit");
__publicField(this, "otherOpts");
this.style = void 0;
this.geometry = void 0;
this.feature = new feature();
this.mapId = "";
this.source = void 0;
this.layer = null;
this.clusterSource = clusterSource;
this.otherOpts = otherOpts || {};
this.minZoom = computed(() => stylesObj.minZoom);
this.maxZoom = computed(() => stylesObj.maxZoom);
this.opacity = computed(() => stylesObj.opacity);
this.olPositions = computed(() => stylesObj.position);
this.declutter = stylesObj.declutter;
this.stylesObj = stylesObj;
this.zIndex = void 0;
this.gyMapObj = gyMap$1(id);
this.mapFinish = computed(() => this.gyMapObj.value && this.gyMapObj.value.mapFinish);
this.isDraw = false;
this.emit = emit || null;
}
init() {
}
draw() {
this.geometry = this.getGeometry();
this.addFeature();
this.setStyle();
this.addSource();
this.addLayer();
this.addWatchFun();
this.addLayerToMap();
}
addFeature() {
this.feature = new feature({
geometry: this.geometry
});
this.feature.on("click", (e) => {
this.emit && this.emit("clickFun", e);
});
}
addSource() {
this.source = new VectorSource$2({
features: [this.feature]
});
}
addLayer() {
this.layer = new VectorLayer$2({
source: this.source,
declutter: this.declutter,
minZoom: this.minZoom.value,
maxZoom: this.maxZoom.value,
opacity: this.opacity.value
});
}
addLayerToMap() {
var _a, _b, _c;
if (!this.isDraw && this.mapFinish.value) {
let imageSource = this.otherOpts && this.otherOpts.imageSource;
if (imageSource) {
let imageFeature = imageSource.getFeatures()[0];
let imageStyle = imageFeature.getStyle();
let textStyle = (_a = this.getStyle()) == null ? void 0 : _a.getText();
if (imageStyle && textStyle) {
imageStyle.setText(textStyle);
}
} else if (this.clusterSource) {
this.clusterSource.addFeature(this.feature);
} else {
this.isDraw = true;
(_c = (_b = this.gyMapObj.value) == null ? void 0 : _b.map) == null ? void 0 : _c.addLayer(this.layer);
}
}
}
addWatchFun() {
watch(this.mapFinish, (n) => {
this.addLayerToMap();
});
this.addLayerWatch();
this.addPropsWatch();
}
addLayerWatch() {
watch(this.minZoom, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setMinZoom(n);
});
watch(this.maxZoom, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setMaxZoom(n);
});
watch(this.opacity, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setOpacity(n);
});
watch(this.olPositions, (n) => {
this.setGeoPosition(n);
});
}
addPropsWatch() {
watch(this.stylesObj, () => {
this.setStyle();
});
}
getGeometry() {
return void 0;
}
setGeoPosition(position) {
}
getStyle() {
return void 0;
}
setStyle() {
this.style = this.getStyle();
if (this.style && this.feature)
this.feature.setStyle(this.style);
}
destory() {
var _a, _b;
(_b = (_a = this.gyMapObj.value) == null ? void 0 : _a.map) == null ? void 0 : _b.removeLayer(this.layer);
this.layer = null;
this.isDraw = false;
}
}
const layerProps$4 = {
isAuto: {
type: Boolean,
default: false
},
declutter: {
type: Boolean,
default: false
},
minZoom: {
type: Number,
default: 1
},
maxZoom: {
type: Number,
default: 18
},
opacity: {
type: Number,
default: 1
}
};
class CreateCircleLayer extends createOlLayer {
constructor(id, position, stylesObj, emit, clusterSource) {
super(id, stylesObj, emit, clusterSource);
__publicField(this, "position");
__publicField(this, "fillColor");
__publicField(this, "strokeColor");
__publicField(this, "strokeWidth");
__publicField(this, "lineDash");
__publicField(this, "radius");
__publicField(this, "scale");
__publicField(this, "rotation");
__publicField(this, "isAuto");
this.position = computed(() => gyMapUtils.formatLonLatToPosition(position));
this.fillColor = computed(() => stylesObj.fillColor);
this.strokeColor = computed(() => stylesObj.strokeColor);
this.strokeWidth = computed(() => stylesObj.strokeWidth);
this.radius = computed(() => stylesObj.radius);
this.lineDash = computed(() => stylesObj.lineDash);
this.scale = computed(() => stylesObj.scale);
this.rotation = computed(() => stylesObj.rotation);
this.isAuto = computed(() => stylesObj.isAuto);
this.draw();
}
getGeometry() {
return new Point$3(this.position.value);
}
setGeoPosition(position) {
this.geometry.setCoordinates(gyMapUtils.formatLonLatToPosition(position));
}
getStyle() {
const s = new Style$1({
image: new Circle$1({
radius: this.radius.value || 5,
fill: this.fillColor.value ? new Fill$2({
color: this.fillColor.value
}) : void 0,
stroke: this.strokeColor.value ? new Stroke$2({
color: this.strokeColor.value,
width: this.strokeWidth.value
}) : void 0,
scale: this.scale.value,
rotation: this.rotation.value
})
});
return this.isAuto.value ? (feature2, resolution) => {
s.getImage().setScale(1 / Math.pow(resolution, 1));
return s;
} : s;
}
}
const layerProps$3 = {
...layerProps$4,
position: {
type: Array,
default: () => []
},
fillColor: {
type: String,
default: ""
},
strokeColor: {
type: String,
default: ""
},
strokeWidth: {
type: Number,
default: 3
},
scale: {
type: [Number, Array],
default: 1
},
radius: {
type: Number,
default: 5
},
rotation: {
type: Number,
default: 0
},
mapId: {
type: String,
default: ""
}
};
const __vue2_script$6 = defineComponent({
name: "GymapCircle",
props: {
...layerProps$3
},
emits: ["clickFun"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const clusterSource = proxy.$parent.clusterSource;
const setParentStylesByLayer = proxy.$parent.setParentStylesByLayer;
let layerObj = null;
onMounted(() => {
layerObj = new CreateCircleLayer(mapId, props.position, props, emit, clusterSource);
const runTask = proxy.$parent.runTask;
if (runTask) {
runTask(layerObj, props);
}
setParentStylesByLayer && setParentStylesByLayer(layerObj);
});
const destory = () => {
layerObj == null ? void 0 : layerObj.destory();
layerObj = null;
};
onBeforeUnmount(() => {
destory();
const destoryTask = proxy.$parent.destory;
if (destoryTask) {
destoryTask();
}
});
}
});
var render$6 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div");
};
var staticRenderFns$6 = [];
const __cssModules$6 = {};
var __component__$6 = /* @__PURE__ */ normalizeComponent(
__vue2_script$6,
render$6,
staticRenderFns$6,
false,
__vue2_injectStyles$6,
null,
null,
null
);
function __vue2_injectStyles$6(context) {
for (let o in __cssModules$6) {
this[o] = __cssModules$6[o];
}
}
const GymapCircle = /* @__PURE__ */ function() {
return __component__$6.exports;
}();
class CreateTextLayer extends createOlLayer {
constructor(id, position, stylesObj, emit, clusterSource, otherOpts) {
super(id, stylesObj, emit, clusterSource, otherOpts);
__publicField(this, "position");
__publicField(this, "text");
__publicField(this, "font");
__publicField(this, "offsetX");
__publicField(this, "offsetY");
__publicField(this, "scale");
__publicField(this, "rotation");
__publicField(this, "textAlign");
__publicField(this, "textBaseline");
__publicField(this, "fillColor");
__publicField(this, "strokeColor");
__publicField(this, "strokeWidth");
__publicField(this, "backgroundFillColor");
__publicField(this, "backgroundStrokeColor");
__publicField(this, "backgroundStrokeWidth");
__publicField(this, "padding");
__publicField(this, "isAuto");
this.position = computed(() => {
if (!position.length)
return [];
return gyMapUtils.formatLonLatToPosition(position);
});
this.text = computed(() => stylesObj.text);
this.font = computed(() => stylesObj.font);
this.offsetX = computed(() => stylesObj.offsetX);
this.offsetY = computed(() => stylesObj.offsetY);
this.scale = computed(() => stylesObj.scale);
this.rotation = computed(() => stylesObj.rotation);
this.textAlign = computed(() => stylesObj.textAlign);
this.textBaseline = computed(() => stylesObj.textBaseline);
this.fillColor = computed(() => stylesObj.fillColor);
this.strokeColor = computed(() => stylesObj.strokeColor);
this.strokeWidth = computed(() => stylesObj.strokeWidth);
this.backgroundFillColor = computed(() => stylesObj.backgroundFillColor);
this.backgroundStrokeColor = computed(() => stylesObj.backgroundStrokeColor);
this.backgroundStrokeWidth = computed(() => stylesObj.backgroundStrokeWidth);
this.padding = computed(() => stylesObj.padding);
this.isAuto = computed(() => stylesObj.isAuto);
this.draw();
}
getGeometry() {
return new Point$3(this.position.value);
}
setGeoPosition(position) {
this.geometry.setCoordinates(gyMapUtils.formatLonLatToPosition(position));
}
getStyle() {
const s = new Style$1({
text: new Text$2({
text: this.text.value,
font: this.font.value,
offsetX: this.offsetX.value,
offsetY: this.offsetY.value,
placement: "point",
scale: this.scale.value,
rotation: this.rotation.value,
textAlign: this.textAlign.value,
textBaseline: this.textBaseline.value,
fill: this.fillColor.value ? new Fill$2({
color: this.fillColor.value
}) : void 0,
stroke: this.strokeColor.value ? new Stroke$2({
color: this.strokeColor.value,
width: this.strokeWidth.value
}) : void 0,
backgroundFill: this.backgroundFillColor.value ? new Fill$2({
color: this.backgroundFillColor.value
}) : void 0,
backgroundStroke: this.backgroundStrokeColor.value ? new Stroke$2({
color: this.backgroundStrokeColor.value,
width: this.backgroundStrokeWidth.value
}) : void 0,
padding: this.padding.value
})
});
return this.isAuto.value ? (feature2, resolution) => {
s.getText().setScale(1 / Math.pow(resolution, 1));
return s;
} : s;
}
}
const layerProps$2 = {
...layerProps$4,
position: {
type: Array,
default: () => []
},
text: {
type: String,
default: ""
},
font: {
type: String,
default: ""
},
offsetX: {
type: Number,
default: 0
},
offsetY: {
type: Number,
default: 0
},
scale: {
type: Number,
default: 1
},
rotation: {
type: Number,
default: 0
},
textAlign: {
type: String,
default: ""
},
textBaseline: {
type: String,
default: ""
},
fillColor: {
type: String,
default: ""
},
strokeColor: {
type: String,
default: ""
},
strokeWidth: {
type: Number,
default: 5
},
backgroundFillColor: {
type: String,
default: ""
},
backgroundStrokeColor: {
type: String,
default: ""
},
backgroundStrokeWidth: {
type: Number,
default: 5
},
padding: {
type: Array,
default: () => [0, 0, 0, 0]
},
mapId: {
type: String,
default: ""
}
};
const __vue2_script$5 = defineComponent({
name: "GymapText",
props: {
...layerProps$2
},
emits: ["clickFun"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const clusterSource = proxy.$parent.clusterSource;
const imageSource = proxy.$parent.imageSource;
const setParentStylesByLayer = proxy.$parent.setParentStylesByLayer;
let layerObj = null;
layerObj = new CreateTextLayer(mapId, props.position, props, emit, clusterSource, { imageSource });
onMounted(() => {
const runTask = proxy.$parent.runTask;
if (runTask) {
runTask(layerObj, props);
}
setParentStylesByLayer && setParentStylesByLayer(layerObj);
});
const destory = () => {
layerObj.destory();
layerObj = null;
};
onBeforeUnmount(() => {
destory();
const destoryTask = proxy.$parent.destory;
if (destoryTask) {
destoryTask();
}
});
}
});
var render$5 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div");
};
var staticRenderFns$5 = [];
const __cssModules$5 = {};
var __component__$5 = /* @__PURE__ */ normalizeComponent(
__vue2_script$5,
render$5,
staticRenderFns$5,
false,
__vue2_injectStyles$5,
null,
null,
null
);
function __vue2_injectStyles$5(context) {
for (let o in __cssModules$5) {
this[o] = __cssModules$5[o];
}
}
const GymapText = /* @__PURE__ */ function() {
return __component__$5.exports;
}();
class CreateImageLayer extends createOlLayer {
constructor(id, position, stylesObj, emit, clusterSource) {
super(id, stylesObj, emit, clusterSource);
__publicField(this, "position");
__publicField(this, "src");
__publicField(this, "anchor");
__publicField(this, "displacement");
__publicField(this, "scale");
__publicField(this, "rotation");
__publicField(this, "isAuto");
this.position = computed(() => gyMapUtils.formatLonLatToPosition(position));
this.src = computed(() => stylesObj.src);
this.anchor = computed(() => stylesObj.anchor);
this.displacement = computed(() => stylesObj.displacement);
this.scale = computed(() => stylesObj.scale);
this.rotation = computed(() => stylesObj.rotation);
this.isAuto = computed(() => stylesObj.isAuto);
this.draw();
}
getGeometry() {
return new Point$3(this.position.value);
}
setGeoPosition(position) {
this.geometry.setCoordinates(gyMapUtils.formatLonLatToPosition(position));
}
getStyle() {
const s = new Style$1({
image: new Icon$2({
crossOrigin: "anonymous",
src: this.src.value,
anchor: this.anchor.value,
displacement: this.displacement.value,
scale: this.scale.value,
rotation: this.rotation.value
})
});
return this.isAuto.value ? (feature2, resolution) => {
s.getImage().setScale(1 / Math.pow(resolution, 1));
return s;
} : s;
}
}
const layerProps$1 = {
...layerProps$4,
position: {
type: Array,
default: () => []
},
src: {
type: String,
default: ""
},
anchor: {
type: Array,
default: () => [0.5, 0.5]
},
displacement: {
type: Array,
default: () => [0, 0]
},
scale: {
type: Number,
default: 1
},
rotation: {
type: Number,
default: 0
},
mapId: {
type: String,
default: ""
}
};
const __vue2_script$4 = defineComponent({
name: "GymapImage",
props: {
...layerProps$1
},
emits: ["clickFun"],
setup(props, { emit, expose }) {
const showSlot = ref(false);
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const clusterSource = proxy.$parent.clusterSource;
const setParentStylesByLayer = proxy.$parent.setParentStylesByLayer;
let layerObj = null;
layerObj = new CreateImageLayer(mapId, props.position, props, emit, clusterSource);
const source = layerObj.source;
onMounted(() => {
showSlot.value = true;
const runTask = proxy.$parent.runTask;
if (runTask) {
runTask(layerObj, props);
}
setParentStylesByLayer && setParentStylesByLayer(layerObj);
});
const destory = () => {
layerObj.destory();
layerObj = null;
};
onBeforeUnmount(() => {
destory();
const destoryTask = proxy.$parent.destory;
if (destoryTask) {
destoryTask();
}
});
return {
id: mapId,
imageSource: source,
showSlot
};
}
});
var render$4 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", [_vm.showSlot ? _vm._t("default") : _vm._e()], 2);
};
var staticRenderFns$4 = [];
const __cssModules$4 = {};
var __component__$4 = /* @__PURE__ */ normalizeComponent(
__vue2_script$4,
render$4,
staticRenderFns$4,
false,
__vue2_injectStyles$4,
null,
null,
null
);
function __vue2_injectStyles$4(context) {
for (let o in __cssModules$4) {
this[o] = __cssModules$4[o];
}
}
const GymapImage = /* @__PURE__ */ function() {
return __component__$4.exports;
}();
const __vue2_script$3 = defineComponent({
name: "GymapDraw",
props: {
canInsertVertexCondition: {
type: Boolean,
default: true
},
drawTypeList: {
type: Array,
default: () => {
return [
"Point",
"LineString",
"Circle",
"Polygon"
];
}
},
drawTypeCnameList: {
type: Array,
default: () => {
return [
"\u70B9",
"\u7EBF",
"\u5706",
"\u591A\u8FB9\u5F62"
];
}
},
btnBackground: {
type: String,
default: "rgb(102, 102, 102)"
},
btnColor: {
type: String,
default: "#fff"
},
btnActiveBackground: {
type: String,
default: "rgb(142, 142, 142)"
},
btnActiveColor: {
type: String,
default: "#fff"
},
deleteActiveBackground: {
type: String,
default: "rgb(28 137 189)"
},
deleteActiveColor: {
type: String,
default: "#fff"
},
fillColor: {
type: String,
default: "rgba(255, 255, 255, 0.2)"
},
strokeColor: {
type: String,
default: "#ffcc33"
},
strokeWidth: {
type: Number,
default: 3
},
pointRadius: {
type: Number,
default: 7
}
},
emits: ["drawFinish"],
setup(props, { emit }) {
const drawCon = ref(null);
const { proxy } = getCurrentInstance();
const mapId = proxy.$parent.id;
const gyMapObj = gyMap$1(mapId);
const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
let drawObj = null;
let snapObj = null;
let modify = null;
let source = ref(null);
let layer = null;
let isInit = false;
const drawType = ref("Point");
const status = ref("");
const hasFeature = computed(() => source.value && source.value.getFeatures().length != 0);
const startDraw = () => {
if (status.value === "start") {
return;
}
status.value = "start";
if (!source.value) {
source.value = new Vector();
}
if (!isInit) {
isInit = true;
layer = new Vector$1({
source: source.value,
style: {
"fill-color": props.fillColor,
"stroke-color": props.strokeColor,
"stroke-width": props.strokeWidth,
"circle-radius": props.pointRadius,
"circle-fill-color": props.strokeColor
}
});
gyMapObj.value.map.addLayer(layer);
gyMapObj.value.map.on("singleclick", (e) => {
if (status.value === "delete" && singleClick$1(e)) {
gyMapObj.value.map.forEachFeatureAtPixel(e.pixel, (feature2) => {
layer.getSource().removeFeature(feature2);
if (!hasFeature.value) {
startDraw();
}
return true;
}, {
hitTolerance: 0
});
}
});
}
drawObj = new Draw({
source: source.value,
type: drawType.value
});
snapObj = new Snap({
source: source.value
});
modify = new Modify({
source: source.value,
deleteCondition: (e) => {
return altKeyOnly(e) && singleClick$1(e);
},
insertVertexCondition: (e) => {
return props.canInsertVertexCondition;
},
snapToPointer: false
});
gyMapObj.value.map.addInteraction(modify);
gyMapObj.value.map.addInteraction(drawObj);
gyMapObj.value.map.addInteraction(snapObj);
};
const deleteDraw = () => {
if (status.value === "start") {
endDraw();
}
status.value = "delete";
};
const changeDrawType = (type) => {
drawType.value = type;
if (status.value !== "end") {
endDraw();
startDraw();
}
};
const endDraw = (finish) => {
if (status.value !== "end") {
status.value = "end";
destory();
finish && submitData();
}
};
const submitData = () => {
const features = source.value.getFeatures();
let data = [];
features.forEach((feature2) => {
let geometry = feature2.getGeometry();
let type = geometry.getType();
let coordinates2 = geometry.getCoordinates();
switch (type) {
case "Circle":
coordinates2 = [geometry.getCenter()];
break;
case "Point":
coordinates2 = [coordinates2];
break;
case "Polygon":
coordinates2 = coordinates2[0];
break;
}
let lonlats = [];
coordinates2.forEach((coordinate) => {
lonlats.push(toLonLat$1(coordinate));
});
let obj = {
coordinates: lonlats,
type
};
if (type === "Circle") {
let radius = geometry.getRadius();
obj.radius = radius;
}
data.push(obj);
});
emit("drawFinish", data);
};
const destory = () => {
gyMapObj.value.map.removeInteraction(modify);
gyMapObj.value.map.removeInteraction(drawObj);
gyMapObj.value.map.removeInteraction(snapObj);
};
onMounted(() => {
drawCon.value.style.setProperty("--btnBackground", props.btnBackground);
drawCon.value.style.setProperty("--btnColor", props.btnColor);
drawCon.value.style.setProperty("--deleteActiveBackground", props.deleteActiveBackground);
drawCon.value.style.setProperty("--deleteActiveColor", props.deleteActiveColor);
drawCon.value.style.setProperty("--btnActiveBackground", props.btnActiveBackground);
drawCon.value.style.setProperty("--btnActiveColor", props.btnActiveColor);
});
onBeforeUnmount(() => {
destory();
});
return {
drawCon,
drawType,
status,
gyMapObj,
mapFinish,
hasFeature,
startDraw,
deleteDraw,
changeDrawType,
endDraw,
submitData,
destory
};
}
});
var render$3 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.mapFinish,
expression: "mapFinish"
}],
ref: "drawCon",
staticClass: "draw-btns-list"
}, [_c("div", {
directives: [{
name: "show",
rawName: "v-show",
value: !_vm.status || _vm.status === "end",
expression: "!status || status === 'end'"
}],
staticClass: "draw-start draw-btn",
on: {
"click": _vm.startDraw
}
}, [_vm._v("\u5F00\u59CB\u7ED8\u5236")]), _c("div", {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.status && _vm.status !== "end",
expression: "status && status !== 'end'"
}],
staticClass: "draw-type draw-btn draw-type-select"
}, [_vm._v(" \u7ED8\u5236\u7C7B\u578B "), _c("div", {
staticClass: "draw-type-select-con"
}, _vm._l(_vm.drawTypeList, function(item, index2) {
return _c("div", {
key: "type" + index2,
class: ["draw-type-option", {
"active": _vm.drawType === item
}],
on: {
"click": function($event) {
return _vm.changeDrawType(item);
}
}
}, [_vm._v(" " + _vm._s(_vm.drawTypeCnameList[index2] || "\u5F85\u5B9A") + " ")]);
}), 0)]), _c("div", {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.status && _vm.status !== "end",
expression: "status && status !== 'end'"
}],
staticClass: "draw-end draw-btn",
on: {
"click": function($event) {
return _vm.endDraw(true);
}
}
}, [_vm._v("\u7ED8\u5236\u5B8C\u6210")]), _c("div", {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.hasFeature && _vm.status && _vm.status !== "end",
expression: "hasFeature && (status && status !== 'end')"
}],
class: ["draw-end", "draw-btn", {
"active": _vm.status === "delete"
}],
on: {
"click": _vm.deleteDraw
}
}, [_vm._v("\u5220\u9664\u56FE\u5F62 ")])]);
};
var staticRenderFns$3 = [];
const GymapDraw_vue_vue_type_style_index_0_scoped_true_lang = "";
const __cssModules$3 = {};
var __component__$3 = /* @__PURE__ */ normalizeComponent(
__vue2_script$3,
render$3,
staticRenderFns$3,
false,
__vue2_injectStyles$3,
"408c15a3",
null,
null
);
function __vue2_injectStyles$3(context) {
for (let o in __cssModules$3) {
this[o] = __cssModules$3[o];
}
}
const GymapDraw = /* @__PURE__ */ function() {
return __component__$3.exports;
}();
class CreateHeatMapLayer extends createOlLayer {
constructor(id, position, stylesObj, emit) {
super(id, stylesObj, emit);
__publicField(this, "visible");
__publicField(this, "gradien");
__publicField(this, "radius");
__publicField(this, "blur");
__publicField(this, "weight");
__publicField(this, "heatMapData");
__publicField(this, "maxValue");
__publicField(this, "minValue");
__publicField(this, "subValue");
this.gradien = stylesObj.gradien;
this.weight = stylesObj.weight;
this.maxValue = stylesObj.maxValue;
this.minValue = stylesObj.minValue;
this.heatMapData = computed(() => stylesObj.data);
this.visible = computed(() => stylesObj.visible);
this.radius = computed(() => stylesObj.radius);
this.blur = computed(() => stylesObj.blur);
this.minZoom = computed(() => stylesObj.minZoom);
this.maxZoom = computed(() => stylesObj.maxZoom);
this.opacity = computed(() => stylesObj.opacity);
this.subValue = 0;
this.formatMinMaxValue();
this.draw();
}
formatMinMaxValue() {
if (this.minValue < 0) {
this.subValue = Math.abs(this.minValue);
this.minValue = 0;
this.maxValue = gyMapUtils.flortAdd(this.maxValue, this.subValue);
}
}
checkData() {
if (this.heatMapData.value.length !== 0) {
let fitstData = this.heatMapData.value[0];
if (Array.isArray(fitstData)) {
if (fitstData.length < 3) {
console.error("\u8BF7\u4F20\u5165\u6B63\u786E\u7684\u6570\u636E\u683C\u5F0F\uFF01");
return false;
}
return true;
} else {
console.error("\u8BF7\u4F20\u5165\u6B63\u786E\u7684\u6570\u636E\u683C\u5F0F\uFF01");
return false;
}
}
return true;
}
addFeature() {
}
addFeatures() {
let features = [];
if (this.checkData()) {
features = this.heatMapData.value.map((data) => {
let lonlat = [data[0], data[1]];
const geo = new Point$3(gyMapUtils.formatLonLatToPosition(lonlat));
return new feature({
geometry: geo,
data
});
});
}
return features;
}
addSource() {
}
addLayer() {
let weightHandler = this.weight ? (feature2) => this.weight(feature2.get("data"), feature2) : (feature2) => {
const item = feature2.get("data") || [];
let value = item[2];
if (this.subValue !== 0) {
value = gyMapUtils.flortAdd(value, this.subValue);
}
if (value > this.maxValue) {
return 1;
} else if (value < this.minValue) {
return 0;
} else {
return value / this.maxValue;
}
};
let features = this.addFeatures();
let source = new VectorSource$2({
features
});
this.layer = new Heatmap({
source,
blur: this.blur.value,
radius: this.radius.value,
visible: this.visible.value,
gradient: this.gradien,
weight: weightHandler,
minZoom: this.minZoom.value,
maxZoom: this.maxZoom.value,
opacity: this.opacity.value
});
}
addLayerWatch() {
watch(this.heatMapData, (n) => {
this.destory();
this.addLayer();
this.addLayerToMap();
});
watch(this.visible, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setVisible(n);
});
watch(this.radius, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setRadius(n);
});
watch(this.blur, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setBlur(n);
});
watch(this.minZoom, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setMinZoom(n);
});
watch(this.maxZoom, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setMaxZoom(n);
});
watch(this.opacity, (n) => {
var _a;
(_a = this.layer) == null ? void 0 : _a.setOpacity(n);
});
}
addPropsWatch() {
watch(this.stylesObj, () => {
});
}
}
const layerProps = {
data: {
type: Array,
default: () => []
},
visible: {
type: Boolean,
default: true
},
gradien: {
type: Array,
default: () => ["#00f", "#0ff", "#0f0", "#ff0", "#f00"]
},
radius: {
type: Number,
default: 100
},
blur: {
type: Number,
default: 100
},
maxValue: {
type: Number,
default: 1
},
minValue: {
type: Number,
default: 0
},
subValue: {
type: Number,
default: 0
},
weight: {
type: [String, Function],
default: ""
},
minZoom: {
type: Number,
default: 1
},
maxZoom: {
type: Number,
default: 18
},
opacity: {
type: Number,
default: 1
},
mapId: {
type: String,
default: ""
}
};
const __vue2_script$2 = defineComponent({
name: "GymapHeat",
props: {
...layerProps
},
setup(props) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
let layerObj = null;
onMounted(() => {
layerObj = new CreateHeatMapLayer(mapId, props.position, props);
});
const destory = () => {
layerObj.destory();
layerObj = null;
};
onBeforeUnmount(() => {
destory();
});
}
});
var render$2 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div");
};
var staticRenderFns$2 = [];
const __cssModules$2 = {};
var __component__$2 = /* @__PURE__ */ normalizeComponent(
__vue2_script$2,
render$2,
staticRenderFns$2,
false,
__vue2_injectStyles$2,
null,
null,
null
);
function __vue2_injectStyles$2(context) {
for (let o in __cssModules$2) {
this[o] = __cssModules$2[o];
}
}
const GymapHeat = /* @__PURE__ */ function() {
return __component__$2.exports;
}();
const __vue2_script$1 = defineComponent({
name: "GymapLonlat",
props: {
showCon: {
type: Boolean,
default: true
},
className: {
type: String,
default: ""
}
},
emits: ["getLonlat"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = proxy.$parent.id;
const gyMapObj = gyMap$1(mapId);
const mapFinish = computed(() => gyMapObj.value && gyMapObj.value.mapFinish);
let isOn = false;
const lonlat = ref("");
const getLonLat = (e) => {
let coordinate = e.coordinate;
let l = toLonLat$1(coordinate);
lonlat.value = l.join(",");
emit("getLonlat", lonlat.value);
};
const addEvent = () => {
if (mapFinish.value && !isOn) {
gyMapObj.value.map.on("click", getLonLat);
}
};
watch(mapFinish, () => {
addEvent();
});
onMounted(() => {
addEvent();
});
const destory = () => {
gyMapObj.value.map && gyMapObj.value.map.un("click", getLonLat);
};
onBeforeUnmount(() => {
destory();
});
return {
className: props.className,
lonlat
};
}
});
var render$1 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.showCon,
expression: "showCon"
}],
class: ["GySjmapLonlat-con", _vm.className]
}, [_vm._v(" " + _vm._s(_vm.lonlat) + " ")]);
};
var staticRenderFns$1 = [];
const GymapLonlat_vue_vue_type_style_index_0_scoped_true_lang = "";
const __cssModules$1 = {};
var __component__$1 = /* @__PURE__ */ normalizeComponent(
__vue2_script$1,
render$1,
staticRenderFns$1,
false,
__vue2_injectStyles$1,
"f531d402",
null,
null
);
function __vue2_injectStyles$1(context) {
for (let o in __cssModules$1) {
this[o] = __cssModules$1[o];
}
}
const GymapLonlat = /* @__PURE__ */ function() {
return __component__$1.exports;
}();
const ObjectEventType = {
PROPERTYCHANGE: "propertychange"
};
const EventType = {
CHANGE: "change",
ERROR: "error",
BLUR: "blur",
CLEAR: "clear",
CONTEXTMENU: "contextmenu",
CLICK: "click",
DBLCLICK: "dblclick",
DRAGENTER: "dragenter",
DRAGOVER: "dragover",
DROP: "drop",
FOCUS: "focus",
KEYDOWN: "keydown",
KEYPRESS: "keypress",
LOAD: "load",
RESIZE: "resize",
TOUCHMOVE: "touchmove",
WHEEL: "wheel"
};
class Disposable {
constructor() {
this.disposed = false;
}
dispose() {
if (!this.disposed) {
this.disposed = true;
this.disposeInternal();
}
}
disposeInternal() {
}
}
const Disposable$1 = Disposable;
function binarySearch(haystack, needle, comparator) {
let mid, cmp;
comparator = comparator || ascending;
let low = 0;
let high = haystack.length;
let found = false;
while (low < high) {
mid = low + (high - low >> 1);
cmp = +comparator(haystack[mid], needle);
if (cmp < 0) {
low = mid + 1;
} else {
high = mid;
found = !cmp;
}
}
return found ? low : ~low;
}
function ascending(a3, b) {
return a3 > b ? 1 : a3 < b ? -1 : 0;
}
function descending(a3, b) {
return a3 < b ? 1 : a3 > b ? -1 : 0;
}
function linearFindNearest(arr, target, direction) {
if (arr[0] <= target) {
return 0;
}
const n = arr.length;
if (target <= arr[n - 1]) {
return n - 1;
}
if (typeof direction === "function") {
for (let i = 1; i < n; ++i) {
const candidate = arr[i];
if (candidate === target) {
return i;
}
if (candidate < target) {
if (direction(target, arr[i - 1], candidate) > 0) {
return i - 1;
}
return i;
}
}
return n - 1;
}
if (direction > 0) {
for (let i = 1; i < n; ++i) {
if (arr[i] < target) {
return i - 1;
}
}
return n - 1;
}
if (direction < 0) {
for (let i = 1; i < n; ++i) {
if (arr[i] <= target) {
return i;
}
}
return n - 1;
}
for (let i = 1; i < n; ++i) {
if (arr[i] == target) {
return i;
}
if (arr[i] < target) {
if (arr[i - 1] - target < target - arr[i]) {
return i - 1;
}
return i;
}
}
return n - 1;
}
function reverseSubArray(arr, begin, end) {
while (begin < end) {
const tmp = arr[begin];
arr[begin] = arr[end];
arr[end] = tmp;
++begin;
--end;
}
}
function extend$2(arr, data) {
const extension = Array.isArray(data) ? data : [data];
const length = extension.length;
for (let i = 0; i < length; i++) {
arr[arr.length] = extension[i];
}
}
function equals$2(arr1, arr2) {
const len1 = arr1.length;
if (len1 !== arr2.length) {
return false;
}
for (let i = 0; i < len1; i++) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
function TRUE() {
return true;
}
function FALSE() {
return false;
}
function VOID() {
}
function memoizeOne(fn) {
let lastResult;
let lastArgs;
let lastThis;
return function() {
const nextArgs = Array.prototype.slice.call(arguments);
if (!lastArgs || this !== lastThis || !equals$2(nextArgs, lastArgs)) {
lastThis = this;
lastArgs = nextArgs;
lastResult = fn.apply(this, arguments);
}
return lastResult;
};
}
function toPromise(getter) {
function promiseGetter() {
let value;
try {
value = getter();
} catch (err) {
return Promise.reject(err);
}
if (value instanceof Promise) {
return value;
}
return Promise.resolve(value);
}
return promiseGetter();
}
function clear(object) {
for (const property in object) {
delete object[property];
}
}
function isEmpty$1(object) {
let property;
for (property in object) {
return false;
}
return !property;
}
class BaseEvent {
constructor(type) {
this.propagationStopped;
this.defaultPrevented;
this.type = type;
this.target = null;
}
preventDefault() {
this.defaultPrevented = true;
}
stopPropagation() {
this.propagationStopped = true;
}
}
const Event = BaseEvent;
class Target extends Disposable$1 {
constructor(target) {
super();
this.eventTarget_ = target;
this.pendingRemovals_ = null;
this.dispatching_ = null;
this.listeners_ = null;
}
addEventListener(type, listener) {
if (!type || !listener) {
return;
}
const listeners = this.listeners_ || (this.listeners_ = {});
const listenersForType = listeners[type] || (listeners[type] = []);
if (!listenersForType.includes(listener)) {
listenersForType.push(listener);
}
}
dispatchEvent(event) {
const isString = typeof event === "string";
const type = isString ? event : event.type;
const listeners = this.listeners_ && this.listeners_[type];
if (!listeners) {
return;
}
const evt = isString ? new Event(event) : event;
if (!evt.target) {
evt.target = this.eventTarget_ || this;
}
const dispatching = this.dispatching_ || (this.dispatching_ = {});
const pendingRemovals = this.pendingRemovals_ || (this.pendingRemovals_ = {});
if (!(type in dispatching)) {
dispatching[type] = 0;
pendingRemovals[type] = 0;
}
++dispatching[type];
let propagate;
for (let i = 0, ii = listeners.length; i < ii; ++i) {
if ("handleEvent" in listeners[i]) {
propagate = listeners[i].handleEvent(evt);
} else {
propagate = listeners[i].call(this, evt);
}
if (propagate === false || evt.propagationStopped) {
propagate = false;
break;
}
}
if (--dispatching[type] === 0) {
let pr = pendingRemovals[type];
delete pendingRemovals[type];
while (pr--) {
this.removeEventListener(type, VOID);
}
delete dispatching[type];
}
return propagate;
}
disposeInternal() {
this.listeners_ && clear(this.listeners_);
}
getListeners(type) {
return this.listeners_ && this.listeners_[type] || void 0;
}
hasListener(type) {
if (!this.listeners_) {
return false;
}
return type ? type in this.listeners_ : Object.keys(this.listeners_).length > 0;
}
removeEventListener(type, listener) {
if (!this.listeners_) {
return;
}
const listeners = this.listeners_[type];
if (!listeners) {
return;
}
const index2 = listeners.indexOf(listener);
if (index2 !== -1) {
if (this.pendingRemovals_ && type in this.pendingRemovals_) {
listeners[index2] = VOID;
++this.pendingRemovals_[type];
} else {
listeners.splice(index2, 1);
if (listeners.length === 0) {
delete this.listeners_[type];
}
}
}
}
}
const EventTarget = Target;
function listen(target, type, listener, thisArg, once) {
if (once) {
const originalListener = listener;
listener = function(event) {
target.removeEventListener(type, listener);
return originalListener.call(thisArg != null ? thisArg : this, event);
};
} else if (thisArg && thisArg !== target) {
listener = listener.bind(thisArg);
}
const eventsKey = {
target,
type,
listener
};
target.addEventListener(type, listener);
return eventsKey;
}
function listenOnce(target, type, listener, thisArg) {
return listen(target, type, listener, thisArg, true);
}
function unlistenByKey(key) {
if (key && key.target) {
key.target.removeEventListener(key.type, key.listener);
clear(key);
}
}
class Observable extends EventTarget {
constructor() {
super();
this.on = this.onInternal;
this.once = this.onceInternal;
this.un = this.unInternal;
this.revision_ = 0;
}
changed() {
++this.revision_;
this.dispatchEvent(EventType.CHANGE);
}
getRevision() {
return this.revision_;
}
onInternal(type, listener) {
if (Array.isArray(type)) {
const len = type.length;
const keys = new Array(len);
for (let i = 0; i < len; ++i) {
keys[i] = listen(this, type[i], listener);
}
return keys;
}
return listen(this, type, listener);
}
onceInternal(type, listener) {
let key;
if (Array.isArray(type)) {
const len = type.length;
key = new Array(len);
for (let i = 0; i < len; ++i) {
key[i] = listenOnce(this, type[i], listener);
}
} else {
key = listenOnce(this, type, listener);
}
listener.ol_key = key;
return key;
}
unInternal(type, listener) {
const key = listener.ol_key;
if (key) {
unByKey(key);
} else if (Array.isArray(type)) {
for (let i = 0, ii = type.length; i < ii; ++i) {
this.removeEventListener(type[i], listener);
}
} else {
this.removeEventListener(type, listener);
}
}
}
Observable.prototype.on;
Observable.prototype.once;
Observable.prototype.un;
function unByKey(key) {
if (Array.isArray(key)) {
for (let i = 0, ii = key.length; i < ii; ++i) {
unlistenByKey(key[i]);
}
} else {
unlistenByKey(key);
}
}
const Observable$1 = Observable;
function abstract() {
throw new Error("Unimplemented abstract method.");
}
let uidCounter_ = 0;
function getUid(obj) {
return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));
}
class ObjectEvent extends Event {
constructor(type, key, oldValue) {
super(type);
this.key = key;
this.oldValue = oldValue;
}
}
class BaseObject extends Observable$1 {
constructor(values) {
super();
this.on;
this.once;
this.un;
getUid(this);
this.values_ = null;
if (values !== void 0) {
this.setProperties(values);
}
}
get(key) {
let value;
if (this.values_ && this.values_.hasOwnProperty(key)) {
value = this.values_[key];
}
return value;
}
getKeys() {
return this.values_ && Object.keys(this.values_) || [];
}
getProperties() {
return this.values_ && Object.assign({}, this.values_) || {};
}
getPropertiesInternal() {
return this.values_;
}
hasProperties() {
return !!this.values_;
}
notify(key, oldValue) {
let eventType;
eventType = `change:${key}`;
if (this.hasListener(eventType)) {
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
}
eventType = ObjectEventType.PROPERTYCHANGE;
if (this.hasListener(eventType)) {
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
}
}
addChangeListener(key, listener) {
this.addEventListener(`change:${key}`, listener);
}
removeChangeListener(key, listener) {
this.removeEventListener(`change:${key}`, listener);
}
set(key, value, silent) {
const values = this.values_ || (this.values_ = {});
if (silent) {
values[key] = value;
} else {
const oldValue = values[key];
values[key] = value;
if (oldValue !== value) {
this.notify(key, oldValue);
}
}
}
setProperties(values, silent) {
for (const key in values) {
this.set(key, values[key], silent);
}
}
applyProperties(source) {
if (!source.values_) {
return;
}
Object.assign(this.values_ || (this.values_ = {}), source.values_);
}
unset(key, silent) {
if (this.values_ && key in this.values_) {
const oldValue = this.values_[key];
delete this.values_[key];
if (isEmpty$1(this.values_)) {
this.values_ = null;
}
if (!silent) {
this.notify(key, oldValue);
}
}
}
}
const BaseObject$1 = BaseObject;
function assert(assertion, errorMessage) {
if (!assertion) {
throw new Error(errorMessage);
}
}
class Feature extends BaseObject$1 {
constructor(geometryOrProperties) {
super();
this.on;
this.once;
this.un;
this.id_ = void 0;
this.geometryName_ = "geometry";
this.style_ = null;
this.styleFunction_ = void 0;
this.geometryChangeKey_ = null;
this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
if (geometryOrProperties) {
if (typeof geometryOrProperties.getSimplifiedGeometry === "function") {
const geometry = geometryOrProperties;
this.setGeometry(geometry);
} else {
const properties = geometryOrProperties;
this.setProperties(properties);
}
}
}
clone() {
const clone2 = new Feature(this.hasProperties() ? this.getProperties() : null);
clone2.setGeometryName(this.getGeometryName());
const geometry = this.getGeometry();
if (geometry) {
clone2.setGeometry(geometry.clone());
}
const style = this.getStyle();
if (style) {
clone2.setStyle(style);
}
return clone2;
}
getGeometry() {
return this.get(this.geometryName_);
}
getId() {
return this.id_;
}
getGeometryName() {
return this.geometryName_;
}
getStyle() {
return this.style_;
}
getStyleFunction() {
return this.styleFunction_;
}
handleGeometryChange_() {
this.changed();
}
handleGeometryChanged_() {
if (this.geometryChangeKey_) {
unlistenByKey(this.geometryChangeKey_);
this.geometryChangeKey_ = null;
}
const geometry = this.getGeometry();
if (geometry) {
this.geometryChangeKey_ = listen(
geometry,
EventType.CHANGE,
this.handleGeometryChange_,
this
);
}
this.changed();
}
setGeometry(geometry) {
this.set(this.geometryName_, geometry);
}
setStyle(style) {
this.style_ = style;
this.styleFunction_ = !style ? void 0 : createStyleFunction(style);
this.changed();
}
setId(id) {
this.id_ = id;
this.changed();
}
setGeometryName(name) {
this.removeChangeListener(this.geometryName_, this.handleGeometryChanged_);
this.geometryName_ = name;
this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);
this.handleGeometryChanged_();
}
}
function createStyleFunction(obj) {
if (typeof obj === "function") {
return obj;
}
let styles;
if (Array.isArray(obj)) {
styles = obj;
} else {
assert(
typeof obj.getZIndex === "function",
"Expected an `ol/style/Style` or an array of `ol/style/Style.js`"
);
const style = obj;
styles = [style];
}
return function() {
return styles;
};
}
const Feature$1 = Feature;
const Relationship = {
UNKNOWN: 0,
INTERSECTING: 1,
ABOVE: 2,
RIGHT: 4,
BELOW: 8,
LEFT: 16
};
function buffer(extent, value, dest) {
if (dest) {
dest[0] = extent[0] - value;
dest[1] = extent[1] - value;
dest[2] = extent[2] + value;
dest[3] = extent[3] + value;
return dest;
}
return [
extent[0] - value,
extent[1] - value,
extent[2] + value,
extent[3] + value
];
}
function clone(extent, dest) {
if (dest) {
dest[0] = extent[0];
dest[1] = extent[1];
dest[2] = extent[2];
dest[3] = extent[3];
return dest;
}
return extent.slice();
}
function closestSquaredDistanceXY(extent, x, y) {
let dx, dy;
if (x < extent[0]) {
dx = extent[0] - x;
} else if (extent[2] < x) {
dx = x - extent[2];
} else {
dx = 0;
}
if (y < extent[1]) {
dy = extent[1] - y;
} else if (extent[3] < y) {
dy = y - extent[3];
} else {
dy = 0;
}
return dx * dx + dy * dy;
}
function containsCoordinate(extent, coordinate) {
return containsXY(extent, coordinate[0], coordinate[1]);
}
function containsExtent(extent1, extent2) {
return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && extent1[1] <= extent2[1] && extent2[3] <= extent1[3];
}
function containsXY(extent, x, y) {
return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];
}
function coordinateRelationship(extent, coordinate) {
const minX = extent[0];
const minY = extent[1];
const maxX = extent[2];
const maxY = extent[3];
const x = coordinate[0];
const y = coordinate[1];
let relationship = Relationship.UNKNOWN;
if (x < minX) {
relationship = relationship | Relationship.LEFT;
} else if (x > maxX) {
relationship = relationship | Relationship.RIGHT;
}
if (y < minY) {
relationship = relationship | Relationship.BELOW;
} else if (y > maxY) {
relationship = relationship | Relationship.ABOVE;
}
if (relationship === Relationship.UNKNOWN) {
relationship = Relationship.INTERSECTING;
}
return relationship;
}
function createEmpty() {
return [Infinity, Infinity, -Infinity, -Infinity];
}
function createOrUpdate(minX, minY, maxX, maxY, dest) {
if (dest) {
dest[0] = minX;
dest[1] = minY;
dest[2] = maxX;
dest[3] = maxY;
return dest;
}
return [minX, minY, maxX, maxY];
}
function createOrUpdateEmpty(dest) {
return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, dest);
}
function createOrUpdateFromCoordinate(coordinate, dest) {
const x = coordinate[0];
const y = coordinate[1];
return createOrUpdate(x, y, x, y, dest);
}
function createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, dest) {
const extent = createOrUpdateEmpty(dest);
return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);
}
function equals$1(extent1, extent2) {
return extent1[0] == extent2[0] && extent1[2] == extent2[2] && extent1[1] == extent2[1] && extent1[3] == extent2[3];
}
function extend$1(extent1, extent2) {
if (extent2[0] < extent1[0]) {
extent1[0] = extent2[0];
}
if (extent2[2] > extent1[2]) {
extent1[2] = extent2[2];
}
if (extent2[1] < extent1[1]) {
extent1[1] = extent2[1];
}
if (extent2[3] > extent1[3]) {
extent1[3] = extent2[3];
}
return extent1;
}
function extendCoordinate(extent, coordinate) {
if (coordinate[0] < extent[0]) {
extent[0] = coordinate[0];
}
if (coordinate[0] > extent[2]) {
extent[2] = coordinate[0];
}
if (coordinate[1] < extent[1]) {
extent[1] = coordinate[1];
}
if (coordinate[1] > extent[3]) {
extent[3] = coordinate[1];
}
}
function extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {
for (; offset < end; offset += stride) {
extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);
}
return extent;
}
function extendXY(extent, x, y) {
extent[0] = Math.min(extent[0], x);
extent[1] = Math.min(extent[1], y);
extent[2] = Math.max(extent[2], x);
extent[3] = Math.max(extent[3], y);
}
function forEachCorner(extent, callback) {
let val;
val = callback(getBottomLeft(extent));
if (val) {
return val;
}
val = callback(getBottomRight(extent));
if (val) {
return val;
}
val = callback(getTopRight(extent));
if (val) {
return val;
}
val = callback(getTopLeft(extent));
if (val) {
return val;
}
return false;
}
function getBottomLeft(extent) {
return [extent[0], extent[1]];
}
function getBottomRight(extent) {
return [extent[2], extent[1]];
}
function getCenter(extent) {
return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];
}
function getForViewAndSize(center, resolution, rotation, size, dest) {
const [x0, y0, x1, y1, x2, y2, x3, y3] = getRotatedViewport(
center,
resolution,
rotation,
size
);
return createOrUpdate(
Math.min(x0, x1, x2, x3),
Math.min(y0, y1, y2, y3),
Math.max(x0, x1, x2, x3),
Math.max(y0, y1, y2, y3),
dest
);
}
function getRotatedViewport(center, resolution, rotation, size) {
const dx = resolution * size[0] / 2;
const dy = resolution * size[1] / 2;
const cosRotation = Math.cos(rotation);
const sinRotation = Math.sin(rotation);
const xCos = dx * cosRotation;
const xSin = dx * sinRotation;
const yCos = dy * cosRotation;
const ySin = dy * sinRotation;
const x = center[0];
const y = center[1];
return [
x - xCos + ySin,
y - xSin - yCos,
x - xCos - ySin,
y - xSin + yCos,
x + xCos - ySin,
y + xSin + yCos,
x + xCos + ySin,
y + xSin - yCos,
x - xCos + ySin,
y - xSin - yCos
];
}
function getHeight(extent) {
return extent[3] - extent[1];
}
function getTopLeft(extent) {
return [extent[0], extent[3]];
}
function getTopRight(extent) {
return [extent[2], extent[3]];
}
function getWidth(extent) {
return extent[2] - extent[0];
}
function intersects$1(extent1, extent2) {
return extent1[0] <= extent2[2] && extent1[2] >= extent2[0] && extent1[1] <= extent2[3] && extent1[3] >= extent2[1];
}
function isEmpty(extent) {
return extent[2] < extent[0] || extent[3] < extent[1];
}
function returnOrUpdate(extent, dest) {
if (dest) {
dest[0] = extent[0];
dest[1] = extent[1];
dest[2] = extent[2];
dest[3] = extent[3];
return dest;
}
return extent;
}
function intersectsSegment(extent, start, end) {
let intersects2 = false;
const startRel = coordinateRelationship(extent, start);
const endRel = coordinateRelationship(extent, end);
if (startRel === Relationship.INTERSECTING || endRel === Relationship.INTERSECTING) {
intersects2 = true;
} else {
const minX = extent[0];
const minY = extent[1];
const maxX = extent[2];
const maxY = extent[3];
const startX = start[0];
const startY = start[1];
const endX = end[0];
const endY = end[1];
const slope = (endY - startY) / (endX - startX);
let x, y;
if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {
x = endX - (endY - maxY) / slope;
intersects2 = x >= minX && x <= maxX;
}
if (!intersects2 && !!(endRel & Relationship.RIGHT) && !(startRel & Relationship.RIGHT)) {
y = endY - (endX - maxX) * slope;
intersects2 = y >= minY && y <= maxY;
}
if (!intersects2 && !!(endRel & Relationship.BELOW) && !(startRel & Relationship.BELOW)) {
x = endX - (endY - minY) / slope;
intersects2 = x >= minX && x <= maxX;
}
if (!intersects2 && !!(endRel & Relationship.LEFT) && !(startRel & Relationship.LEFT)) {
y = endY - (endX - minX) * slope;
intersects2 = y >= minY && y <= maxY;
}
}
return intersects2;
}
function wrapX$1(extent, projection) {
const projectionExtent = projection.getExtent();
const center = getCenter(extent);
if (projection.canWrapX() && (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])) {
const worldWidth = getWidth(projectionExtent);
const worldsAway = Math.floor(
(center[0] - projectionExtent[0]) / worldWidth
);
const offset = worldsAway * worldWidth;
extent[0] -= offset;
extent[2] -= offset;
}
return extent;
}
function wrapAndSliceX(extent, projection, multiWorld) {
if (projection.canWrapX()) {
const projectionExtent = projection.getExtent();
if (!isFinite(extent[0]) || !isFinite(extent[2])) {
return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];
}
wrapX$1(extent, projection);
const worldWidth = getWidth(projectionExtent);
if (getWidth(extent) > worldWidth && !multiWorld) {
return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];
}
if (extent[0] < projectionExtent[0]) {
return [
[extent[0] + worldWidth, extent[1], projectionExtent[2], extent[3]],
[projectionExtent[0], extent[1], extent[2], extent[3]]
];
}
if (extent[2] > projectionExtent[2]) {
return [
[extent[0], extent[1], projectionExtent[2], extent[3]],
[projectionExtent[0], extent[1], extent[2] - worldWidth, extent[3]]
];
}
}
return [extent];
}
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function squaredSegmentDistance(x, y, x1, y1, x2, y2) {
const dx = x2 - x1;
const dy = y2 - y1;
if (dx !== 0 || dy !== 0) {
const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
if (t > 1) {
x1 = x2;
y1 = y2;
} else if (t > 0) {
x1 += dx * t;
y1 += dy * t;
}
}
return squaredDistance(x, y, x1, y1);
}
function squaredDistance(x1, y1, x2, y2) {
const dx = x2 - x1;
const dy = y2 - y1;
return dx * dx + dy * dy;
}
function toDegrees(angleInRadians) {
return angleInRadians * 180 / Math.PI;
}
function toRadians(angleInDegrees) {
return angleInDegrees * Math.PI / 180;
}
function modulo(a3, b) {
const r = a3 % b;
return r * b < 0 ? r + b : r;
}
function lerp(a3, b, x) {
return a3 + x * (b - a3);
}
function toFixed(n, decimals) {
const factor = Math.pow(10, decimals);
return Math.round(n * factor) / factor;
}
function wrap(n, min, max) {
if (n >= min && n < max) {
return n;
}
const range = max - min;
return ((n - min) % range + range) % range + min;
}
function add$2(coordinate, delta) {
coordinate[0] += +delta[0];
coordinate[1] += +delta[1];
return coordinate;
}
function equals(coordinate1, coordinate2) {
let equals2 = true;
for (let i = coordinate1.length - 1; i >= 0; --i) {
if (coordinate1[i] != coordinate2[i]) {
equals2 = false;
break;
}
}
return equals2;
}
function rotate$1(coordinate, angle) {
const cosAngle = Math.cos(angle);
const sinAngle = Math.sin(angle);
const x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
const y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
coordinate[0] = x;
coordinate[1] = y;
return coordinate;
}
function scale$1(coordinate, scale2) {
coordinate[0] *= scale2;
coordinate[1] *= scale2;
return coordinate;
}
function wrapX(coordinate, projection) {
if (projection.canWrapX()) {
const worldWidth = getWidth(projection.getExtent());
const worldsAway = getWorldsAway(coordinate, projection, worldWidth);
if (worldsAway) {
coordinate[0] -= worldsAway * worldWidth;
}
}
return coordinate;
}
function getWorldsAway(coordinate, projection, sourceExtentWidth) {
const projectionExtent = projection.getExtent();
let worldsAway = 0;
if (projection.canWrapX() && (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])) {
sourceExtentWidth = sourceExtentWidth || getWidth(projectionExtent);
worldsAway = Math.floor(
(coordinate[0] - projectionExtent[0]) / sourceExtentWidth
);
}
return worldsAway;
}
const levels = {
info: 1,
warn: 2,
error: 3,
none: 4
};
let level = levels.info;
function warn(...args) {
if (level > levels.warn) {
return;
}
console.warn(...args);
}
const METERS_PER_UNIT$1 = {
"radians": 6370997 / (2 * Math.PI),
"degrees": 2 * Math.PI * 6370997 / 360,
"ft": 0.3048,
"m": 1,
"us-ft": 1200 / 3937
};
class Projection {
constructor(options) {
this.code_ = options.code;
this.units_ = options.units;
this.extent_ = options.extent !== void 0 ? options.extent : null;
this.worldExtent_ = options.worldExtent !== void 0 ? options.worldExtent : null;
this.axisOrientation_ = options.axisOrientation !== void 0 ? options.axisOrientation : "enu";
this.global_ = options.global !== void 0 ? options.global : false;
this.canWrapX_ = !!(this.global_ && this.extent_);
this.getPointResolutionFunc_ = options.getPointResolution;
this.defaultTileGrid_ = null;
this.metersPerUnit_ = options.metersPerUnit;
}
canWrapX() {
return this.canWrapX_;
}
getCode() {
return this.code_;
}
getExtent() {
return this.extent_;
}
getUnits() {
return this.units_;
}
getMetersPerUnit() {
return this.metersPerUnit_ || METERS_PER_UNIT$1[this.units_];
}
getWorldExtent() {
return this.worldExtent_;
}
getAxisOrientation() {
return this.axisOrientation_;
}
isGlobal() {
return this.global_;
}
setGlobal(global) {
this.global_ = global;
this.canWrapX_ = !!(global && this.extent_);
}
getDefaultTileGrid() {
return this.defaultTileGrid_;
}
setDefaultTileGrid(tileGrid) {
this.defaultTileGrid_ = tileGrid;
}
setExtent(extent) {
this.extent_ = extent;
this.canWrapX_ = !!(this.global_ && extent);
}
setWorldExtent(worldExtent) {
this.worldExtent_ = worldExtent;
}
setGetPointResolution(func) {
this.getPointResolutionFunc_ = func;
}
getPointResolutionFunc() {
return this.getPointResolutionFunc_;
}
}
const Projection$1 = Projection;
const RADIUS$1 = 6378137;
const HALF_SIZE = Math.PI * RADIUS$1;
const EXTENT$1 = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];
const WORLD_EXTENT = [-180, -85, 180, 85];
const MAX_SAFE_Y = RADIUS$1 * Math.log(Math.tan(Math.PI / 2));
class EPSG3857Projection extends Projection$1 {
constructor(code) {
super({
code,
units: "m",
extent: EXTENT$1,
global: true,
worldExtent: WORLD_EXTENT,
getPointResolution: function(resolution, point) {
return resolution / Math.cosh(point[1] / RADIUS$1);
}
});
}
}
const PROJECTIONS$1 = [
new EPSG3857Projection("EPSG:3857"),
new EPSG3857Projection("EPSG:102100"),
new EPSG3857Projection("EPSG:102113"),
new EPSG3857Projection("EPSG:900913"),
new EPSG3857Projection("http://www.opengis.net/def/crs/EPSG/0/3857"),
new EPSG3857Projection("http://www.opengis.net/gml/srs/epsg.xml#3857")
];
function fromEPSG4326(input, output, dimension, stride) {
const length = input.length;
dimension = dimension > 1 ? dimension : 2;
stride = stride != null ? stride : dimension;
if (output === void 0) {
if (dimension > 2) {
output = input.slice();
} else {
output = new Array(length);
}
}
for (let i = 0; i < length; i += stride) {
output[i] = HALF_SIZE * input[i] / 180;
let y = RADIUS$1 * Math.log(Math.tan(Math.PI * (+input[i + 1] + 90) / 360));
if (y > MAX_SAFE_Y) {
y = MAX_SAFE_Y;
} else if (y < -MAX_SAFE_Y) {
y = -MAX_SAFE_Y;
}
output[i + 1] = y;
}
return output;
}
function toEPSG4326(input, output, dimension, stride) {
const length = input.length;
dimension = dimension > 1 ? dimension : 2;
stride = stride != null ? stride : dimension;
if (output === void 0) {
if (dimension > 2) {
output = input.slice();
} else {
output = new Array(length);
}
}
for (let i = 0; i < length; i += stride) {
output[i] = 180 * input[i] / HALF_SIZE;
output[i + 1] = 360 * Math.atan(Math.exp(input[i + 1] / RADIUS$1)) / Math.PI - 90;
}
return output;
}
const RADIUS = 6378137;
const EXTENT = [-180, -90, 180, 90];
const METERS_PER_UNIT = Math.PI * RADIUS / 180;
class EPSG4326Projection extends Projection$1 {
constructor(code, axisOrientation) {
super({
code,
units: "degrees",
extent: EXTENT,
axisOrientation,
global: true,
metersPerUnit: METERS_PER_UNIT,
worldExtent: EXTENT
});
}
}
const PROJECTIONS = [
new EPSG4326Projection("CRS:84"),
new EPSG4326Projection("EPSG:4326", "neu"),
new EPSG4326Projection("urn:ogc:def:crs:OGC:1.3:CRS84"),
new EPSG4326Projection("urn:ogc:def:crs:OGC:2:84"),
new EPSG4326Projection("http://www.opengis.net/def/crs/OGC/1.3/CRS84"),
new EPSG4326Projection("http://www.opengis.net/gml/srs/epsg.xml#4326", "neu"),
new EPSG4326Projection("http://www.opengis.net/def/crs/EPSG/0/4326", "neu")
];
let cache$1 = {};
function get$3(code) {
return cache$1[code] || cache$1[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\w+)$/, "EPSG:$3")] || null;
}
function add$1(code, projection) {
cache$1[code] = projection;
}
let transforms = {};
function add(source, destination, transformFn) {
const sourceCode = source.getCode();
const destinationCode = destination.getCode();
if (!(sourceCode in transforms)) {
transforms[sourceCode] = {};
}
transforms[sourceCode][destinationCode] = transformFn;
}
function get$2(sourceCode, destinationCode) {
if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {
return transforms[sourceCode][destinationCode];
}
return null;
}
const K0 = 0.9996;
const E = 669438e-8;
const E2 = E * E;
const E3 = E2 * E;
const E_P2 = E / (1 - E);
const SQRT_E = Math.sqrt(1 - E);
const _E = (1 - SQRT_E) / (1 + SQRT_E);
const _E2 = _E * _E;
const _E3 = _E2 * _E;
const _E4 = _E3 * _E;
const _E5 = _E4 * _E;
const M1 = 1 - E / 4 - 3 * E2 / 64 - 5 * E3 / 256;
const M2 = 3 * E / 8 + 3 * E2 / 32 + 45 * E3 / 1024;
const M3 = 15 * E2 / 256 + 45 * E3 / 1024;
const M4 = 35 * E3 / 3072;
const P2 = 3 / 2 * _E - 27 / 32 * _E3 + 269 / 512 * _E5;
const P3 = 21 / 16 * _E2 - 55 / 32 * _E4;
const P4 = 151 / 96 * _E3 - 417 / 128 * _E5;
const P5 = 1097 / 512 * _E4;
const R = 6378137;
function toLonLat(easting, northing, zone) {
const x = easting - 5e5;
const y = zone.north ? northing : northing - 1e7;
const m = y / K0;
const mu = m / (R * M1);
const pRad = mu + P2 * Math.sin(2 * mu) + P3 * Math.sin(4 * mu) + P4 * Math.sin(6 * mu) + P5 * Math.sin(8 * mu);
const pSin = Math.sin(pRad);
const pSin2 = pSin * pSin;
const pCos = Math.cos(pRad);
const pTan = pSin / pCos;
const pTan2 = pTan * pTan;
const pTan4 = pTan2 * pTan2;
const epSin = 1 - E * pSin2;
const epSinSqrt = Math.sqrt(1 - E * pSin2);
const n = R / epSinSqrt;
const r = (1 - E) / epSin;
const c = E_P2 * pCos ** 2;
const c2 = c * c;
const d = x / (n * K0);
const d2 = d * d;
const d3 = d2 * d;
const d4 = d3 * d;
const d5 = d4 * d;
const d6 = d5 * d;
const latitude = pRad - pTan / r * (d2 / 2 - d4 / 24 * (5 + 3 * pTan2 + 10 * c - 4 * c2 - 9 * E_P2)) + d6 / 720 * (61 + 90 * pTan2 + 298 * c + 45 * pTan4 - 252 * E_P2 - 3 * c2);
let longitude = (d - d3 / 6 * (1 + 2 * pTan2 + c) + d5 / 120 * (5 - 2 * c + 28 * pTan2 - 3 * c2 + 8 * E_P2 + 24 * pTan4)) / pCos;
longitude = wrap(
longitude + toRadians(zoneToCentralLongitude(zone.number)),
-Math.PI,
Math.PI
);
return [toDegrees(longitude), toDegrees(latitude)];
}
const MIN_LATITUDE = -80;
const MAX_LATITUDE = 84;
const MIN_LONGITUDE = -180;
const MAX_LONGITUDE = 180;
function fromLonLat(longitude, latitude, zone) {
longitude = wrap(longitude, MIN_LONGITUDE, MAX_LONGITUDE);
if (latitude < MIN_LATITUDE) {
latitude = MIN_LATITUDE;
} else if (latitude > MAX_LATITUDE) {
latitude = MAX_LATITUDE;
}
const latRad = toRadians(latitude);
const latSin = Math.sin(latRad);
const latCos = Math.cos(latRad);
const latTan = latSin / latCos;
const latTan2 = latTan * latTan;
const latTan4 = latTan2 * latTan2;
const lonRad = toRadians(longitude);
const centralLon = zoneToCentralLongitude(zone.number);
const centralLonRad = toRadians(centralLon);
const n = R / Math.sqrt(1 - E * latSin ** 2);
const c = E_P2 * latCos ** 2;
const a3 = latCos * wrap(lonRad - centralLonRad, -Math.PI, Math.PI);
const a22 = a3 * a3;
const a32 = a22 * a3;
const a4 = a32 * a3;
const a5 = a4 * a3;
const a6 = a5 * a3;
const m = R * (M1 * latRad - M2 * Math.sin(2 * latRad) + M3 * Math.sin(4 * latRad) - M4 * Math.sin(6 * latRad));
const easting = K0 * n * (a3 + a32 / 6 * (1 - latTan2 + c) + a5 / 120 * (5 - 18 * latTan2 + latTan4 + 72 * c - 58 * E_P2)) + 5e5;
let northing = K0 * (m + n * latTan * (a22 / 2 + a4 / 24 * (5 - latTan2 + 9 * c + 4 * c ** 2) + a6 / 720 * (61 - 58 * latTan2 + latTan4 + 600 * c - 330 * E_P2)));
if (!zone.north) {
northing += 1e7;
}
return [easting, northing];
}
function zoneToCentralLongitude(zone) {
return (zone - 1) * 6 - 180 + 3;
}
const epsgRegExes = [
/^EPSG:(\d+)$/,
/^urn:ogc:def:crs:EPSG::(\d+)$/,
/^http:\/\/www\.opengis\.net\/def\/crs\/EPSG\/0\/(\d+)$/
];
function zoneFromCode(code) {
let epsgId = 0;
for (const re of epsgRegExes) {
const match = code.match(re);
if (match) {
epsgId = parseInt(match[1]);
break;
}
}
if (!epsgId) {
return null;
}
let number = 0;
let north = false;
if (epsgId > 32700 && epsgId < 32761) {
number = epsgId - 32700;
} else if (epsgId > 32600 && epsgId < 32661) {
north = true;
number = epsgId - 32600;
}
if (!number) {
return null;
}
return { number, north };
}
function makeTransformFunction(transformer, zone) {
return function(input, output, dimension, stride) {
const length = input.length;
dimension = dimension > 1 ? dimension : 2;
stride = stride != null ? stride : dimension;
if (!output) {
if (dimension > 2) {
output = input.slice();
} else {
output = new Array(length);
}
}
for (let i = 0; i < length; i += stride) {
const x = input[i];
const y = input[i + 1];
const coord = transformer(x, y, zone);
output[i] = coord[0];
output[i + 1] = coord[1];
}
return output;
};
}
function makeProjection(code) {
const zone = zoneFromCode(code);
if (!zone) {
return null;
}
return new Projection$1({ code, units: "m" });
}
function makeTransforms(projection) {
const zone = zoneFromCode(projection.getCode());
if (!zone) {
return null;
}
return {
forward: makeTransformFunction(fromLonLat, zone),
inverse: makeTransformFunction(toLonLat, zone)
};
}
const transformFactories = [makeTransforms];
const projectionFactories = [makeProjection];
let showCoordinateWarning = true;
function disableCoordinateWarning(disable2) {
const hide = disable2 === void 0 ? true : disable2;
showCoordinateWarning = !hide;
}
function cloneTransform(input, output) {
if (output !== void 0) {
for (let i = 0, ii = input.length; i < ii; ++i) {
output[i] = input[i];
}
output = output;
} else {
output = input.slice();
}
return output;
}
function addProjection(projection) {
add$1(projection.getCode(), projection);
add(projection, projection, cloneTransform);
}
function addProjections(projections) {
projections.forEach(addProjection);
}
function get$1(projectionLike) {
if (!(typeof projectionLike === "string")) {
return projectionLike;
}
const projection = get$3(projectionLike);
if (projection) {
return projection;
}
for (const makeProjection2 of projectionFactories) {
const projection2 = makeProjection2(projectionLike);
if (projection2) {
return projection2;
}
}
return null;
}
function addEquivalentProjections(projections) {
addProjections(projections);
projections.forEach(function(source) {
projections.forEach(function(destination) {
if (source !== destination) {
add(source, destination, cloneTransform);
}
});
});
}
function addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {
projections1.forEach(function(projection1) {
projections2.forEach(function(projection2) {
add(projection1, projection2, forwardTransform);
add(projection2, projection1, inverseTransform);
});
});
}
function createProjection(projection, defaultCode) {
if (!projection) {
return get$1(defaultCode);
}
if (typeof projection === "string") {
return get$1(projection);
}
return projection;
}
function getTransformFromProjections(source, destination) {
const sourceCode = source.getCode();
const destinationCode = destination.getCode();
let transformFunc = get$2(sourceCode, destinationCode);
if (transformFunc) {
return transformFunc;
}
let sourceTransforms = null;
let destinationTransforms = null;
for (const makeTransforms2 of transformFactories) {
if (!sourceTransforms) {
sourceTransforms = makeTransforms2(source);
}
if (!destinationTransforms) {
destinationTransforms = makeTransforms2(destination);
}
}
if (!sourceTransforms && !destinationTransforms) {
return null;
}
const intermediateCode = "EPSG:4326";
if (!destinationTransforms) {
const toDestination = get$2(intermediateCode, destinationCode);
if (toDestination) {
transformFunc = composeTransformFuncs(
sourceTransforms.inverse,
toDestination
);
}
} else if (!sourceTransforms) {
const fromSource = get$2(sourceCode, intermediateCode);
if (fromSource) {
transformFunc = composeTransformFuncs(
fromSource,
destinationTransforms.forward
);
}
} else {
transformFunc = composeTransformFuncs(
sourceTransforms.inverse,
destinationTransforms.forward
);
}
if (transformFunc) {
addProjection(source);
addProjection(destination);
add(source, destination, transformFunc);
}
return transformFunc;
}
function composeTransformFuncs(t1, t2) {
return function(input, output, dimensions, stride) {
output = t1(input, output, dimensions, stride);
return t2(output, output, dimensions, stride);
};
}
function getTransform(source, destination) {
const sourceProjection = get$1(source);
const destinationProjection = get$1(destination);
return getTransformFromProjections(sourceProjection, destinationProjection);
}
let userProjection = null;
function getUserProjection() {
return userProjection;
}
function toUserCoordinate(coordinate, sourceProjection) {
{
return coordinate;
}
}
function fromUserCoordinate(coordinate, destProjection) {
{
if (showCoordinateWarning && !equals(coordinate, [0, 0]) && coordinate[0] >= -180 && coordinate[0] <= 180 && coordinate[1] >= -90 && coordinate[1] <= 90) {
showCoordinateWarning = false;
warn(
"Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates."
);
}
return coordinate;
}
}
function toUserExtent(extent, sourceProjection) {
{
return extent;
}
}
function fromUserExtent(extent, destProjection) {
{
return extent;
}
}
function addCommon() {
addEquivalentProjections(PROJECTIONS$1);
addEquivalentProjections(PROJECTIONS);
addEquivalentTransforms(
PROJECTIONS,
PROJECTIONS$1,
fromEPSG4326,
toEPSG4326
);
}
addCommon();
new Array(6);
function create() {
return [1, 0, 0, 1, 0, 0];
}
function setFromArray(transform1, transform2) {
transform1[0] = transform2[0];
transform1[1] = transform2[1];
transform1[2] = transform2[2];
transform1[3] = transform2[3];
transform1[4] = transform2[4];
transform1[5] = transform2[5];
return transform1;
}
function apply(transform, coordinate) {
const x = coordinate[0];
const y = coordinate[1];
coordinate[0] = transform[0] * x + transform[2] * y + transform[4];
coordinate[1] = transform[1] * x + transform[3] * y + transform[5];
return coordinate;
}
function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {
const sin = Math.sin(angle);
const cos = Math.cos(angle);
transform[0] = sx * cos;
transform[1] = sy * sin;
transform[2] = -sx * sin;
transform[3] = sy * cos;
transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;
transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;
return transform;
}
function makeInverse(target, source) {
const det = determinant(source);
assert(det !== 0, "Transformation matrix cannot be inverted");
const a3 = source[0];
const b = source[1];
const c = source[2];
const d = source[3];
const e = source[4];
const f = source[5];
target[0] = d / det;
target[1] = -b / det;
target[2] = -c / det;
target[3] = a3 / det;
target[4] = (c * f - d * e) / det;
target[5] = -(a3 * f - b * e) / det;
return target;
}
function determinant(mat) {
return mat[0] * mat[3] - mat[1] * mat[2];
}
const matrixPrecision = [1e5, 1e5, 1e5, 1e5, 2, 2];
function toString$1(mat) {
const transformString = "matrix(" + mat.join(", ") + ")";
return transformString;
}
function fromString$1(cssTransform) {
const values = cssTransform.substring(7, cssTransform.length - 1).split(",");
return values.map(parseFloat);
}
function equivalent(cssTransform1, cssTransform2) {
const mat1 = fromString$1(cssTransform1);
const mat2 = fromString$1(cssTransform2);
for (let i = 0; i < 6; ++i) {
if (Math.round((mat1[i] - mat2[i]) * matrixPrecision[i]) !== 0) {
return false;
}
}
return true;
}
function transform2D(flatCoordinates, offset, end, stride, transform, dest, destinationStride) {
dest = dest ? dest : [];
destinationStride = destinationStride ? destinationStride : 2;
let i = 0;
for (let j = offset; j < end; j += stride) {
const x = flatCoordinates[j];
const y = flatCoordinates[j + 1];
dest[i++] = transform[0] * x + transform[2] * y + transform[4];
dest[i++] = transform[1] * x + transform[3] * y + transform[5];
for (let k = 2; k < destinationStride; k++) {
dest[i++] = flatCoordinates[j + k];
}
}
if (dest && dest.length != i) {
dest.length = i;
}
return dest;
}
function rotate(flatCoordinates, offset, end, stride, angle, anchor, dest) {
dest = dest ? dest : [];
const cos = Math.cos(angle);
const sin = Math.sin(angle);
const anchorX = anchor[0];
const anchorY = anchor[1];
let i = 0;
for (let j = offset; j < end; j += stride) {
const deltaX = flatCoordinates[j] - anchorX;
const deltaY = flatCoordinates[j + 1] - anchorY;
dest[i++] = anchorX + deltaX * cos - deltaY * sin;
dest[i++] = anchorY + deltaX * sin + deltaY * cos;
for (let k = j + 2; k < j + stride; ++k) {
dest[i++] = flatCoordinates[k];
}
}
if (dest && dest.length != i) {
dest.length = i;
}
return dest;
}
function scale(flatCoordinates, offset, end, stride, sx, sy, anchor, dest) {
dest = dest ? dest : [];
const anchorX = anchor[0];
const anchorY = anchor[1];
let i = 0;
for (let j = offset; j < end; j += stride) {
const deltaX = flatCoordinates[j] - anchorX;
const deltaY = flatCoordinates[j + 1] - anchorY;
dest[i++] = anchorX + sx * deltaX;
dest[i++] = anchorY + sy * deltaY;
for (let k = j + 2; k < j + stride; ++k) {
dest[i++] = flatCoordinates[k];
}
}
if (dest && dest.length != i) {
dest.length = i;
}
return dest;
}
function translate(flatCoordinates, offset, end, stride, deltaX, deltaY, dest) {
dest = dest ? dest : [];
let i = 0;
for (let j = offset; j < end; j += stride) {
dest[i++] = flatCoordinates[j] + deltaX;
dest[i++] = flatCoordinates[j + 1] + deltaY;
for (let k = j + 2; k < j + stride; ++k) {
dest[i++] = flatCoordinates[k];
}
}
if (dest && dest.length != i) {
dest.length = i;
}
return dest;
}
const tmpTransform$1 = create();
const tmpPoint = [NaN, NaN];
class Geometry extends BaseObject$1 {
constructor() {
super();
this.extent_ = createEmpty();
this.extentRevision_ = -1;
this.simplifiedGeometryMaxMinSquaredTolerance = 0;
this.simplifiedGeometryRevision = 0;
this.simplifyTransformedInternal = memoizeOne(
(revision, squaredTolerance, transform) => {
if (!transform) {
return this.getSimplifiedGeometry(squaredTolerance);
}
const clone2 = this.clone();
clone2.applyTransform(transform);
return clone2.getSimplifiedGeometry(squaredTolerance);
}
);
}
simplifyTransformed(squaredTolerance, transform) {
return this.simplifyTransformedInternal(
this.getRevision(),
squaredTolerance,
transform
);
}
clone() {
return abstract();
}
closestPointXY(x, y, closestPoint, minSquaredDistance) {
return abstract();
}
containsXY(x, y) {
return this.closestPointXY(x, y, tmpPoint, Number.MIN_VALUE) === 0;
}
getClosestPoint(point, closestPoint) {
closestPoint = closestPoint ? closestPoint : [NaN, NaN];
this.closestPointXY(point[0], point[1], closestPoint, Infinity);
return closestPoint;
}
intersectsCoordinate(coordinate) {
return this.containsXY(coordinate[0], coordinate[1]);
}
computeExtent(extent) {
return abstract();
}
getExtent(extent) {
if (this.extentRevision_ != this.getRevision()) {
const extent2 = this.computeExtent(this.extent_);
if (isNaN(extent2[0]) || isNaN(extent2[1])) {
createOrUpdateEmpty(extent2);
}
this.extentRevision_ = this.getRevision();
}
return returnOrUpdate(this.extent_, extent);
}
rotate(angle, anchor) {
abstract();
}
scale(sx, sy, anchor) {
abstract();
}
simplify(tolerance) {
return this.getSimplifiedGeometry(tolerance * tolerance);
}
getSimplifiedGeometry(squaredTolerance) {
return abstract();
}
getType() {
return abstract();
}
applyTransform(transformFn) {
abstract();
}
intersectsExtent(extent) {
return abstract();
}
translate(deltaX, deltaY) {
abstract();
}
transform(source, destination) {
const sourceProj = get$1(source);
const transformFn = sourceProj.getUnits() == "tile-pixels" ? function(inCoordinates, outCoordinates, stride) {
const pixelExtent = sourceProj.getExtent();
const projectedExtent = sourceProj.getWorldExtent();
const scale2 = getHeight(projectedExtent) / getHeight(pixelExtent);
compose(
tmpTransform$1,
projectedExtent[0],
projectedExtent[3],
scale2,
-scale2,
0,
0,
0
);
const transformed = transform2D(
inCoordinates,
0,
inCoordinates.length,
stride,
tmpTransform$1,
outCoordinates
);
const projTransform = getTransform(sourceProj, destination);
if (projTransform) {
return projTransform(transformed, transformed, stride);
}
return transformed;
} : getTransform(sourceProj, destination);
this.applyTransform(transformFn);
return this;
}
}
const Geometry$1 = Geometry;
class SimpleGeometry extends Geometry$1 {
constructor() {
super();
this.layout = "XY";
this.stride = 2;
this.flatCoordinates;
}
computeExtent(extent) {
return createOrUpdateFromFlatCoordinates(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride,
extent
);
}
getCoordinates() {
return abstract();
}
getFirstCoordinate() {
return this.flatCoordinates.slice(0, this.stride);
}
getFlatCoordinates() {
return this.flatCoordinates;
}
getLastCoordinate() {
return this.flatCoordinates.slice(
this.flatCoordinates.length - this.stride
);
}
getLayout() {
return this.layout;
}
getSimplifiedGeometry(squaredTolerance) {
if (this.simplifiedGeometryRevision !== this.getRevision()) {
this.simplifiedGeometryMaxMinSquaredTolerance = 0;
this.simplifiedGeometryRevision = this.getRevision();
}
if (squaredTolerance < 0 || this.simplifiedGeometryMaxMinSquaredTolerance !== 0 && squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance) {
return this;
}
const simplifiedGeometry = this.getSimplifiedGeometryInternal(squaredTolerance);
const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
return simplifiedGeometry;
}
this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
return this;
}
getSimplifiedGeometryInternal(squaredTolerance) {
return this;
}
getStride() {
return this.stride;
}
setFlatCoordinates(layout, flatCoordinates) {
this.stride = getStrideForLayout(layout);
this.layout = layout;
this.flatCoordinates = flatCoordinates;
}
setCoordinates(coordinates2, layout) {
abstract();
}
setLayout(layout, coordinates2, nesting) {
let stride;
if (layout) {
stride = getStrideForLayout(layout);
} else {
for (let i = 0; i < nesting; ++i) {
if (coordinates2.length === 0) {
this.layout = "XY";
this.stride = 2;
return;
}
coordinates2 = coordinates2[0];
}
stride = coordinates2.length;
layout = getLayoutForStride(stride);
}
this.layout = layout;
this.stride = stride;
}
applyTransform(transformFn) {
if (this.flatCoordinates) {
transformFn(
this.flatCoordinates,
this.flatCoordinates,
this.layout.startsWith("XYZ") ? 3 : 2,
this.stride
);
this.changed();
}
}
rotate(angle, anchor) {
const flatCoordinates = this.getFlatCoordinates();
if (flatCoordinates) {
const stride = this.getStride();
rotate(
flatCoordinates,
0,
flatCoordinates.length,
stride,
angle,
anchor,
flatCoordinates
);
this.changed();
}
}
scale(sx, sy, anchor) {
if (sy === void 0) {
sy = sx;
}
if (!anchor) {
anchor = getCenter(this.getExtent());
}
const flatCoordinates = this.getFlatCoordinates();
if (flatCoordinates) {
const stride = this.getStride();
scale(
flatCoordinates,
0,
flatCoordinates.length,
stride,
sx,
sy,
anchor,
flatCoordinates
);
this.changed();
}
}
translate(deltaX, deltaY) {
const flatCoordinates = this.getFlatCoordinates();
if (flatCoordinates) {
const stride = this.getStride();
translate(
flatCoordinates,
0,
flatCoordinates.length,
stride,
deltaX,
deltaY,
flatCoordinates
);
this.changed();
}
}
}
function getLayoutForStride(stride) {
let layout;
if (stride == 2) {
layout = "XY";
} else if (stride == 3) {
layout = "XYZ";
} else if (stride == 4) {
layout = "XYZM";
}
return layout;
}
function getStrideForLayout(layout) {
let stride;
if (layout == "XY") {
stride = 2;
} else if (layout == "XYZ" || layout == "XYM") {
stride = 3;
} else if (layout == "XYZM") {
stride = 4;
}
return stride;
}
function transformGeom2D(simpleGeometry, transform, dest) {
const flatCoordinates = simpleGeometry.getFlatCoordinates();
if (!flatCoordinates) {
return null;
}
const stride = simpleGeometry.getStride();
return transform2D(
flatCoordinates,
0,
flatCoordinates.length,
stride,
transform,
dest
);
}
const SimpleGeometry$1 = SimpleGeometry;
function deflateCoordinate(flatCoordinates, offset, coordinate, stride) {
for (let i = 0, ii = coordinate.length; i < ii; ++i) {
flatCoordinates[offset++] = coordinate[i];
}
return offset;
}
function deflateCoordinates(flatCoordinates, offset, coordinates2, stride) {
for (let i = 0, ii = coordinates2.length; i < ii; ++i) {
const coordinate = coordinates2[i];
for (let j = 0; j < stride; ++j) {
flatCoordinates[offset++] = coordinate[j];
}
}
return offset;
}
function deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, ends) {
ends = ends ? ends : [];
let i = 0;
for (let j = 0, jj = coordinatess.length; j < jj; ++j) {
const end = deflateCoordinates(
flatCoordinates,
offset,
coordinatess[j],
stride
);
ends[i++] = end;
offset = end;
}
ends.length = i;
return ends;
}
class Point extends SimpleGeometry$1 {
constructor(coordinates2, layout) {
super();
this.setCoordinates(coordinates2, layout);
}
clone() {
const point = new Point(this.flatCoordinates.slice(), this.layout);
point.applyProperties(this);
return point;
}
closestPointXY(x, y, closestPoint, minSquaredDistance) {
const flatCoordinates = this.flatCoordinates;
const squaredDistance$1 = squaredDistance(
x,
y,
flatCoordinates[0],
flatCoordinates[1]
);
if (squaredDistance$1 < minSquaredDistance) {
const stride = this.stride;
for (let i = 0; i < stride; ++i) {
closestPoint[i] = flatCoordinates[i];
}
closestPoint.length = stride;
return squaredDistance$1;
}
return minSquaredDistance;
}
getCoordinates() {
return this.flatCoordinates.slice();
}
computeExtent(extent) {
return createOrUpdateFromCoordinate(this.flatCoordinates, extent);
}
getType() {
return "Point";
}
intersectsExtent(extent) {
return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);
}
setCoordinates(coordinates2, layout) {
this.setLayout(layout, coordinates2, 0);
if (!this.flatCoordinates) {
this.flatCoordinates = [];
}
this.flatCoordinates.length = deflateCoordinate(
this.flatCoordinates,
0,
coordinates2,
this.stride
);
this.changed();
}
}
const Point$1 = Point;
const CollectionEventType = {
ADD: "add",
REMOVE: "remove"
};
const Property$1 = {
LENGTH: "length"
};
class CollectionEvent extends Event {
constructor(type, element, index2) {
super(type);
this.element = element;
this.index = index2;
}
}
class Collection extends BaseObject$1 {
constructor(array, options) {
super();
this.on;
this.once;
this.un;
options = options || {};
this.unique_ = !!options.unique;
this.array_ = array ? array : [];
if (this.unique_) {
for (let i = 0, ii = this.array_.length; i < ii; ++i) {
this.assertUnique_(this.array_[i], i);
}
}
this.updateLength_();
}
clear() {
while (this.getLength() > 0) {
this.pop();
}
}
extend(arr) {
for (let i = 0, ii = arr.length; i < ii; ++i) {
this.push(arr[i]);
}
return this;
}
forEach(f) {
const array = this.array_;
for (let i = 0, ii = array.length; i < ii; ++i) {
f(array[i], i, array);
}
}
getArray() {
return this.array_;
}
item(index2) {
return this.array_[index2];
}
getLength() {
return this.get(Property$1.LENGTH);
}
insertAt(index2, elem) {
if (index2 < 0 || index2 > this.getLength()) {
throw new Error("Index out of bounds: " + index2);
}
if (this.unique_) {
this.assertUnique_(elem);
}
this.array_.splice(index2, 0, elem);
this.updateLength_();
this.dispatchEvent(
new CollectionEvent(CollectionEventType.ADD, elem, index2)
);
}
pop() {
return this.removeAt(this.getLength() - 1);
}
push(elem) {
if (this.unique_) {
this.assertUnique_(elem);
}
const n = this.getLength();
this.insertAt(n, elem);
return this.getLength();
}
remove(elem) {
const arr = this.array_;
for (let i = 0, ii = arr.length; i < ii; ++i) {
if (arr[i] === elem) {
return this.removeAt(i);
}
}
return void 0;
}
removeAt(index2) {
if (index2 < 0 || index2 >= this.getLength()) {
return void 0;
}
const prev = this.array_[index2];
this.array_.splice(index2, 1);
this.updateLength_();
this.dispatchEvent(
new CollectionEvent(CollectionEventType.REMOVE, prev, index2)
);
return prev;
}
setAt(index2, elem) {
const n = this.getLength();
if (index2 >= n) {
this.insertAt(index2, elem);
return;
}
if (index2 < 0) {
throw new Error("Index out of bounds: " + index2);
}
if (this.unique_) {
this.assertUnique_(elem, index2);
}
const prev = this.array_[index2];
this.array_[index2] = elem;
this.dispatchEvent(
new CollectionEvent(CollectionEventType.REMOVE, prev, index2)
);
this.dispatchEvent(
new CollectionEvent(CollectionEventType.ADD, elem, index2)
);
}
updateLength_() {
this.set(Property$1.LENGTH, this.array_.length);
}
assertUnique_(elem, except) {
for (let i = 0, ii = this.array_.length; i < ii; ++i) {
if (this.array_[i] === elem && i !== except) {
throw new Error("Duplicate item added to a unique collection");
}
}
}
}
const Collection$1 = Collection;
let withCredentials = false;
function loadFeaturesXhr(url, format, extent, resolution, projection, success, failure) {
const xhr2 = new XMLHttpRequest();
xhr2.open(
"GET",
typeof url === "function" ? url(extent, resolution, projection) : url,
true
);
if (format.getType() == "arraybuffer") {
xhr2.responseType = "arraybuffer";
}
xhr2.withCredentials = withCredentials;
xhr2.onload = function(event) {
if (!xhr2.status || xhr2.status >= 200 && xhr2.status < 300) {
const type = format.getType();
try {
let source;
if (type == "text" || type == "json") {
source = xhr2.responseText;
} else if (type == "xml") {
source = xhr2.responseXML || xhr2.responseText;
} else if (type == "arraybuffer") {
source = xhr2.response;
}
if (source) {
success(
format.readFeatures(source, {
extent,
featureProjection: projection
}),
format.readProjection(source)
);
} else {
failure();
}
} catch {
failure();
}
} else {
failure();
}
};
xhr2.onerror = failure;
xhr2.send();
}
function xhr(url, format) {
return function(extent, resolution, projection, success, failure) {
loadFeaturesXhr(
url,
format,
extent,
resolution,
projection,
(features, dataProjection) => {
this.addFeatures(features);
if (success !== void 0) {
success(features);
}
},
() => {
this.changed();
if (failure !== void 0) {
failure();
}
}
);
};
}
function all(extent, resolution) {
return [[-Infinity, -Infinity, Infinity, Infinity]];
}
function linearRingss(flatCoordinates, offset, endss, stride) {
const flatCenters = [];
let extent = createEmpty();
for (let i = 0, ii = endss.length; i < ii; ++i) {
const ends = endss[i];
extent = createOrUpdateFromFlatCoordinates(
flatCoordinates,
offset,
ends[0],
stride
);
flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);
offset = ends[ends.length - 1];
}
return flatCenters;
}
function linearRingContainsExtent(flatCoordinates, offset, end, stride, extent) {
const outside = forEachCorner(
extent,
function(coordinate) {
return !linearRingContainsXY(
flatCoordinates,
offset,
end,
stride,
coordinate[0],
coordinate[1]
);
}
);
return !outside;
}
function linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {
let wn = 0;
let x1 = flatCoordinates[end - stride];
let y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) {
const x2 = flatCoordinates[offset];
const y2 = flatCoordinates[offset + 1];
if (y1 <= y) {
if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {
wn++;
}
} else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {
wn--;
}
x1 = x2;
y1 = y2;
}
return wn !== 0;
}
function linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {
if (ends.length === 0) {
return false;
}
if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {
return false;
}
for (let i = 1, ii = ends.length; i < ii; ++i) {
if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {
return false;
}
}
return true;
}
function getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, flatCentersOffset, dest) {
let i, ii, x, x1, x2, y1, y2;
const y = flatCenters[flatCentersOffset + 1];
const intersections = [];
for (let r = 0, rr = ends.length; r < rr; ++r) {
const end = ends[r];
x1 = flatCoordinates[end - stride];
y1 = flatCoordinates[end - stride + 1];
for (i = offset; i < end; i += stride) {
x2 = flatCoordinates[i];
y2 = flatCoordinates[i + 1];
if (y <= y1 && y2 <= y || y1 <= y && y <= y2) {
x = (y - y1) / (y2 - y1) * (x2 - x1) + x1;
intersections.push(x);
}
x1 = x2;
y1 = y2;
}
}
let pointX = NaN;
let maxSegmentLength = -Infinity;
intersections.sort(ascending);
x1 = intersections[0];
for (i = 1, ii = intersections.length; i < ii; ++i) {
x2 = intersections[i];
const segmentLength = Math.abs(x2 - x1);
if (segmentLength > maxSegmentLength) {
x = (x1 + x2) / 2;
if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {
pointX = x;
maxSegmentLength = segmentLength;
}
}
x1 = x2;
}
if (isNaN(pointX)) {
pointX = flatCenters[flatCentersOffset];
}
if (dest) {
dest.push(pointX, y, maxSegmentLength);
return dest;
}
return [pointX, y, maxSegmentLength];
}
function getInteriorPointsOfMultiArray(flatCoordinates, offset, endss, stride, flatCenters) {
let interiorPoints = [];
for (let i = 0, ii = endss.length; i < ii; ++i) {
const ends = endss[i];
interiorPoints = getInteriorPointOfArray(
flatCoordinates,
offset,
ends,
stride,
flatCenters,
2 * i,
interiorPoints
);
offset = ends[ends.length - 1];
}
return interiorPoints;
}
function interpolatePoint(flatCoordinates, offset, end, stride, fraction, dest, dimension) {
let o, t;
const n = (end - offset) / stride;
if (n === 1) {
o = offset;
} else if (n === 2) {
o = offset;
t = fraction;
} else if (n !== 0) {
let x1 = flatCoordinates[offset];
let y1 = flatCoordinates[offset + 1];
let length = 0;
const cumulativeLengths = [0];
for (let i = offset + stride; i < end; i += stride) {
const x2 = flatCoordinates[i];
const y2 = flatCoordinates[i + 1];
length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
cumulativeLengths.push(length);
x1 = x2;
y1 = y2;
}
const target = fraction * length;
const index2 = binarySearch(cumulativeLengths, target);
if (index2 < 0) {
t = (target - cumulativeLengths[-index2 - 2]) / (cumulativeLengths[-index2 - 1] - cumulativeLengths[-index2 - 2]);
o = offset + (-index2 - 2) * stride;
} else {
o = offset + index2 * stride;
}
}
dimension = dimension > 1 ? dimension : 2;
dest = dest ? dest : new Array(dimension);
for (let i = 0; i < dimension; ++i) {
dest[i] = o === void 0 ? NaN : t === void 0 ? flatCoordinates[o + i] : lerp(flatCoordinates[o + i], flatCoordinates[o + stride + i], t);
}
return dest;
}
function coordinates(flatCoordinates, offset, end, stride) {
while (offset < end - stride) {
for (let i = 0; i < stride; ++i) {
const tmp = flatCoordinates[offset + i];
flatCoordinates[offset + i] = flatCoordinates[end - stride + i];
flatCoordinates[end - stride + i] = tmp;
}
offset += stride;
end -= stride;
}
}
function linearRingIsClockwise(flatCoordinates, offset, end, stride) {
let edge = 0;
let x1 = flatCoordinates[end - stride];
let y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) {
const x2 = flatCoordinates[offset];
const y2 = flatCoordinates[offset + 1];
edge += (x2 - x1) * (y2 + y1);
x1 = x2;
y1 = y2;
}
return edge === 0 ? void 0 : edge > 0;
}
function linearRingsAreOriented(flatCoordinates, offset, ends, stride, right) {
right = right !== void 0 ? right : false;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
const isClockwise = linearRingIsClockwise(
flatCoordinates,
offset,
end,
stride
);
if (i === 0) {
if (right && isClockwise || !right && !isClockwise) {
return false;
}
} else {
if (right && !isClockwise || !right && isClockwise) {
return false;
}
}
offset = end;
}
return true;
}
function orientLinearRings(flatCoordinates, offset, ends, stride, right) {
right = right !== void 0 ? right : false;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
const isClockwise = linearRingIsClockwise(
flatCoordinates,
offset,
end,
stride
);
const reverse = i === 0 ? right && isClockwise || !right && !isClockwise : right && !isClockwise || !right && isClockwise;
if (reverse) {
coordinates(flatCoordinates, offset, end, stride);
}
offset = end;
}
return offset;
}
function inflateEnds(flatCoordinates, ends) {
const endss = [];
let offset = 0;
let prevEndIndex = 0;
let startOrientation;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
const orientation = linearRingIsClockwise(flatCoordinates, offset, end, 2);
if (startOrientation === void 0) {
startOrientation = orientation;
}
if (orientation === startOrientation) {
endss.push(ends.slice(prevEndIndex, i + 1));
} else {
if (endss.length === 0) {
continue;
}
endss[endss.length - 1].push(ends[prevEndIndex]);
}
prevEndIndex = i + 1;
offset = end;
}
return endss;
}
function douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {
const n = (end - offset) / stride;
if (n < 3) {
for (; offset < end; offset += stride) {
simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];
simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + 1];
}
return simplifiedOffset;
}
const markers = new Array(n);
markers[0] = 1;
markers[n - 1] = 1;
const stack = [offset, end - stride];
let index2 = 0;
while (stack.length > 0) {
const last = stack.pop();
const first = stack.pop();
let maxSquaredDistance = 0;
const x1 = flatCoordinates[first];
const y1 = flatCoordinates[first + 1];
const x2 = flatCoordinates[last];
const y2 = flatCoordinates[last + 1];
for (let i = first + stride; i < last; i += stride) {
const x = flatCoordinates[i];
const y = flatCoordinates[i + 1];
const squaredDistance2 = squaredSegmentDistance(x, y, x1, y1, x2, y2);
if (squaredDistance2 > maxSquaredDistance) {
index2 = i;
maxSquaredDistance = squaredDistance2;
}
}
if (maxSquaredDistance > squaredTolerance) {
markers[(index2 - offset) / stride] = 1;
if (first + stride < index2) {
stack.push(first, index2);
}
if (index2 + stride < last) {
stack.push(index2, last);
}
}
}
for (let i = 0; i < n; ++i) {
if (markers[i]) {
simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride];
simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride + 1];
}
}
return simplifiedOffset;
}
function douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
simplifiedOffset = douglasPeucker(
flatCoordinates,
offset,
end,
stride,
squaredTolerance,
simplifiedFlatCoordinates,
simplifiedOffset
);
simplifiedEnds.push(simplifiedOffset);
offset = end;
}
return simplifiedOffset;
}
function snap(value, tolerance) {
return tolerance * Math.round(value / tolerance);
}
function quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset) {
if (offset == end) {
return simplifiedOffset;
}
let x1 = snap(flatCoordinates[offset], tolerance);
let y1 = snap(flatCoordinates[offset + 1], tolerance);
offset += stride;
simplifiedFlatCoordinates[simplifiedOffset++] = x1;
simplifiedFlatCoordinates[simplifiedOffset++] = y1;
let x2, y2;
do {
x2 = snap(flatCoordinates[offset], tolerance);
y2 = snap(flatCoordinates[offset + 1], tolerance);
offset += stride;
if (offset == end) {
simplifiedFlatCoordinates[simplifiedOffset++] = x2;
simplifiedFlatCoordinates[simplifiedOffset++] = y2;
return simplifiedOffset;
}
} while (x2 == x1 && y2 == y1);
while (offset < end) {
const x3 = snap(flatCoordinates[offset], tolerance);
const y3 = snap(flatCoordinates[offset + 1], tolerance);
offset += stride;
if (x3 == x2 && y3 == y2) {
continue;
}
const dx1 = x2 - x1;
const dy1 = y2 - y1;
const dx2 = x3 - x1;
const dy2 = y3 - y1;
if (dx1 * dy2 == dy1 * dx2 && (dx1 < 0 && dx2 < dx1 || dx1 == dx2 || dx1 > 0 && dx2 > dx1) && (dy1 < 0 && dy2 < dy1 || dy1 == dy2 || dy1 > 0 && dy2 > dy1)) {
x2 = x3;
y2 = y3;
continue;
}
simplifiedFlatCoordinates[simplifiedOffset++] = x2;
simplifiedFlatCoordinates[simplifiedOffset++] = y2;
x1 = x2;
y1 = y2;
x2 = x3;
y2 = y3;
}
simplifiedFlatCoordinates[simplifiedOffset++] = x2;
simplifiedFlatCoordinates[simplifiedOffset++] = y2;
return simplifiedOffset;
}
function quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
simplifiedOffset = quantize(
flatCoordinates,
offset,
end,
stride,
tolerance,
simplifiedFlatCoordinates,
simplifiedOffset
);
simplifiedEnds.push(simplifiedOffset);
offset = end;
}
return simplifiedOffset;
}
function linearRing(flatCoordinates, offset, end, stride) {
let twiceArea = 0;
const x0 = flatCoordinates[end - stride];
const y0 = flatCoordinates[end - stride + 1];
let dx1 = 0;
let dy1 = 0;
for (; offset < end; offset += stride) {
const dx2 = flatCoordinates[offset] - x0;
const dy2 = flatCoordinates[offset + 1] - y0;
twiceArea += dy1 * dx2 - dx1 * dy2;
dx1 = dx2;
dy1 = dy2;
}
return twiceArea / 2;
}
function linearRings(flatCoordinates, offset, ends, stride) {
let area = 0;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
area += linearRing(flatCoordinates, offset, end, stride);
offset = end;
}
return area;
}
function assignClosest(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {
const x1 = flatCoordinates[offset1];
const y1 = flatCoordinates[offset1 + 1];
const dx = flatCoordinates[offset2] - x1;
const dy = flatCoordinates[offset2 + 1] - y1;
let offset;
if (dx === 0 && dy === 0) {
offset = offset1;
} else {
const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
if (t > 1) {
offset = offset2;
} else if (t > 0) {
for (let i = 0; i < stride; ++i) {
closestPoint[i] = lerp(
flatCoordinates[offset1 + i],
flatCoordinates[offset2 + i],
t
);
}
closestPoint.length = stride;
return;
} else {
offset = offset1;
}
}
for (let i = 0; i < stride; ++i) {
closestPoint[i] = flatCoordinates[offset + i];
}
closestPoint.length = stride;
}
function maxSquaredDelta(flatCoordinates, offset, end, stride, max) {
let x1 = flatCoordinates[offset];
let y1 = flatCoordinates[offset + 1];
for (offset += stride; offset < end; offset += stride) {
const x2 = flatCoordinates[offset];
const y2 = flatCoordinates[offset + 1];
const squaredDelta = squaredDistance(x1, y1, x2, y2);
if (squaredDelta > max) {
max = squaredDelta;
}
x1 = x2;
y1 = y2;
}
return max;
}
function arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max) {
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
max = maxSquaredDelta(flatCoordinates, offset, end, stride, max);
offset = end;
}
return max;
}
function assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint2) {
if (offset == end) {
return minSquaredDistance;
}
let i, squaredDistance$1;
if (maxDelta === 0) {
squaredDistance$1 = squaredDistance(
x,
y,
flatCoordinates[offset],
flatCoordinates[offset + 1]
);
if (squaredDistance$1 < minSquaredDistance) {
for (i = 0; i < stride; ++i) {
closestPoint[i] = flatCoordinates[offset + i];
}
closestPoint.length = stride;
return squaredDistance$1;
}
return minSquaredDistance;
}
tmpPoint2 = tmpPoint2 ? tmpPoint2 : [NaN, NaN];
let index2 = offset + stride;
while (index2 < end) {
assignClosest(
flatCoordinates,
index2 - stride,
index2,
stride,
x,
y,
tmpPoint2
);
squaredDistance$1 = squaredDistance(x, y, tmpPoint2[0], tmpPoint2[1]);
if (squaredDistance$1 < minSquaredDistance) {
minSquaredDistance = squaredDistance$1;
for (i = 0; i < stride; ++i) {
closestPoint[i] = tmpPoint2[i];
}
closestPoint.length = stride;
index2 += stride;
} else {
index2 += stride * Math.max(
(Math.sqrt(squaredDistance$1) - Math.sqrt(minSquaredDistance)) / maxDelta | 0,
1
);
}
}
if (isRing) {
assignClosest(
flatCoordinates,
end - stride,
offset,
stride,
x,
y,
tmpPoint2
);
squaredDistance$1 = squaredDistance(x, y, tmpPoint2[0], tmpPoint2[1]);
if (squaredDistance$1 < minSquaredDistance) {
minSquaredDistance = squaredDistance$1;
for (i = 0; i < stride; ++i) {
closestPoint[i] = tmpPoint2[i];
}
closestPoint.length = stride;
}
}
return minSquaredDistance;
}
function assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint2) {
tmpPoint2 = tmpPoint2 ? tmpPoint2 : [NaN, NaN];
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
minSquaredDistance = assignClosestPoint(
flatCoordinates,
offset,
end,
stride,
maxDelta,
isRing,
x,
y,
closestPoint,
minSquaredDistance,
tmpPoint2
);
offset = end;
}
return minSquaredDistance;
}
function inflateCoordinates(flatCoordinates, offset, end, stride, coordinates2) {
coordinates2 = coordinates2 !== void 0 ? coordinates2 : [];
let i = 0;
for (let j = offset; j < end; j += stride) {
coordinates2[i++] = flatCoordinates.slice(j, j + stride);
}
coordinates2.length = i;
return coordinates2;
}
function inflateCoordinatesArray(flatCoordinates, offset, ends, stride, coordinatess) {
coordinatess = coordinatess !== void 0 ? coordinatess : [];
let i = 0;
for (let j = 0, jj = ends.length; j < jj; ++j) {
const end = ends[j];
coordinatess[i++] = inflateCoordinates(
flatCoordinates,
offset,
end,
stride,
coordinatess[i]
);
offset = end;
}
coordinatess.length = i;
return coordinatess;
}
function inflateMultiCoordinatesArray(flatCoordinates, offset, endss, stride, coordinatesss) {
coordinatesss = coordinatesss !== void 0 ? coordinatesss : [];
let i = 0;
for (let j = 0, jj = endss.length; j < jj; ++j) {
const ends = endss[j];
coordinatesss[i++] = ends.length === 1 && ends[0] === offset ? [] : inflateCoordinatesArray(
flatCoordinates,
offset,
ends,
stride,
coordinatesss[i]
);
offset = ends[ends.length - 1];
}
coordinatesss.length = i;
return coordinatesss;
}
class LinearRing extends SimpleGeometry$1 {
constructor(coordinates2, layout) {
super();
this.maxDelta_ = -1;
this.maxDeltaRevision_ = -1;
if (layout !== void 0 && !Array.isArray(coordinates2[0])) {
this.setFlatCoordinates(
layout,
coordinates2
);
} else {
this.setCoordinates(
coordinates2,
layout
);
}
}
clone() {
return new LinearRing(this.flatCoordinates.slice(), this.layout);
}
closestPointXY(x, y, closestPoint, minSquaredDistance) {
if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
return minSquaredDistance;
}
if (this.maxDeltaRevision_ != this.getRevision()) {
this.maxDelta_ = Math.sqrt(
maxSquaredDelta(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride,
0
)
);
this.maxDeltaRevision_ = this.getRevision();
}
return assignClosestPoint(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride,
this.maxDelta_,
true,
x,
y,
closestPoint,
minSquaredDistance
);
}
getArea() {
return linearRing(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride
);
}
getCoordinates() {
return inflateCoordinates(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride
);
}
getSimplifiedGeometryInternal(squaredTolerance) {
const simplifiedFlatCoordinates = [];
simplifiedFlatCoordinates.length = douglasPeucker(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride,
squaredTolerance,
simplifiedFlatCoordinates,
0
);
return new LinearRing(simplifiedFlatCoordinates, "XY");
}
getType() {
return "LinearRing";
}
intersectsExtent(extent) {
return false;
}
setCoordinates(coordinates2, layout) {
this.setLayout(layout, coordinates2, 1);
if (!this.flatCoordinates) {
this.flatCoordinates = [];
}
this.flatCoordinates.length = deflateCoordinates(
this.flatCoordinates,
0,
coordinates2,
this.stride
);
this.changed();
}
}
const LinearRing$1 = LinearRing;
function forEach(flatCoordinates, offset, end, stride, callback) {
let ret;
offset += stride;
for (; offset < end; offset += stride) {
ret = callback(
flatCoordinates.slice(offset - stride, offset),
flatCoordinates.slice(offset, offset + stride)
);
if (ret) {
return ret;
}
}
return false;
}
function intersectsLineString(flatCoordinates, offset, end, stride, extent, coordinatesExtent) {
coordinatesExtent = coordinatesExtent != null ? coordinatesExtent : extendFlatCoordinates(createEmpty(), flatCoordinates, offset, end, stride);
if (!intersects$1(extent, coordinatesExtent)) {
return false;
}
if (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2] || coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3]) {
return true;
}
return forEach(
flatCoordinates,
offset,
end,
stride,
function(point1, point2) {
return intersectsSegment(extent, point1, point2);
}
);
}
function intersectsLinearRing(flatCoordinates, offset, end, stride, extent) {
if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {
return true;
}
if (linearRingContainsXY(
flatCoordinates,
offset,
end,
stride,
extent[0],
extent[1]
)) {
return true;
}
if (linearRingContainsXY(
flatCoordinates,
offset,
end,
stride,
extent[0],
extent[3]
)) {
return true;
}
if (linearRingContainsXY(
flatCoordinates,
offset,
end,
stride,
extent[2],
extent[1]
)) {
return true;
}
if (linearRingContainsXY(
flatCoordinates,
offset,
end,
stride,
extent[2],
extent[3]
)) {
return true;
}
return false;
}
function intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent) {
if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {
return false;
}
if (ends.length === 1) {
return true;
}
for (let i = 1, ii = ends.length; i < ii; ++i) {
if (linearRingContainsExtent(
flatCoordinates,
ends[i - 1],
ends[i],
stride,
extent
)) {
if (!intersectsLineString(
flatCoordinates,
ends[i - 1],
ends[i],
stride,
extent
)) {
return false;
}
}
}
return true;
}
function lineStringLength(flatCoordinates, offset, end, stride) {
let x1 = flatCoordinates[offset];
let y1 = flatCoordinates[offset + 1];
let length = 0;
for (let i = offset + stride; i < end; i += stride) {
const x2 = flatCoordinates[i];
const y2 = flatCoordinates[i + 1];
length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
x1 = x2;
y1 = y2;
}
return length;
}
class Polygon extends SimpleGeometry$1 {
constructor(coordinates2, layout, ends) {
super();
this.ends_ = [];
this.flatInteriorPointRevision_ = -1;
this.flatInteriorPoint_ = null;
this.maxDelta_ = -1;
this.maxDeltaRevision_ = -1;
this.orientedRevision_ = -1;
this.orientedFlatCoordinates_ = null;
if (layout !== void 0 && ends) {
this.setFlatCoordinates(
layout,
coordinates2
);
this.ends_ = ends;
} else {
this.setCoordinates(
coordinates2,
layout
);
}
}
appendLinearRing(linearRing2) {
if (!this.flatCoordinates) {
this.flatCoordinates = linearRing2.getFlatCoordinates().slice();
} else {
extend$2(this.flatCoordinates, linearRing2.getFlatCoordinates());
}
this.ends_.push(this.flatCoordinates.length);
this.changed();
}
clone() {
const polygon = new Polygon(
this.flatCoordinates.slice(),
this.layout,
this.ends_.slice()
);
polygon.applyProperties(this);
return polygon;
}
closestPointXY(x, y, closestPoint, minSquaredDistance) {
if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {
return minSquaredDistance;
}
if (this.maxDeltaRevision_ != this.getRevision()) {
this.maxDelta_ = Math.sqrt(
arrayMaxSquaredDelta(
this.flatCoordinates,
0,
this.ends_,
this.stride,
0
)
);
this.maxDeltaRevision_ = this.getRevision();
}
return assignClosestArrayPoint(
this.flatCoordinates,
0,
this.ends_,
this.stride,
this.maxDelta_,
true,
x,
y,
closestPoint,
minSquaredDistance
);
}
containsXY(x, y) {
return linearRingsContainsXY(
this.getOrientedFlatCoordinates(),
0,
this.ends_,
this.stride,
x,
y
);
}
getArea() {
return linearRings(
this.getOrientedFlatCoordinates(),
0,
this.ends_,
this.stride
);
}
getCoordinates(right) {
let flatCoordinates;
if (right !== void 0) {
flatCoordinates = this.getOrientedFlatCoordinates().slice();
orientLinearRings(flatCoordinates, 0, this.ends_, this.stride, right);
} else {
flatCoordinates = this.flatCoordinates;
}
return inflateCoordinatesArray(flatCoordinates, 0, this.ends_, this.stride);
}
getEnds() {
return this.ends_;
}
getFlatInteriorPoint() {
if (this.flatInteriorPointRevision_ != this.getRevision()) {
const flatCenter = getCenter(this.getExtent());
this.flatInteriorPoint_ = getInteriorPointOfArray(
this.getOrientedFlatCoordinates(),
0,
this.ends_,
this.stride,
flatCenter,
0
);
this.flatInteriorPointRevision_ = this.getRevision();
}
return this.flatInteriorPoint_;
}
getInteriorPoint() {
return new Point$1(this.getFlatInteriorPoint(), "XYM");
}
getLinearRingCount() {
return this.ends_.length;
}
getLinearRing(index2) {
if (index2 < 0 || this.ends_.length <= index2) {
return null;
}
return new LinearRing$1(
this.flatCoordinates.slice(
index2 === 0 ? 0 : this.ends_[index2 - 1],
this.ends_[index2]
),
this.layout
);
}
getLinearRings() {
const layout = this.layout;
const flatCoordinates = this.flatCoordinates;
const ends = this.ends_;
const linearRings2 = [];
let offset = 0;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
const linearRing2 = new LinearRing$1(
flatCoordinates.slice(offset, end),
layout
);
linearRings2.push(linearRing2);
offset = end;
}
return linearRings2;
}
getOrientedFlatCoordinates() {
if (this.orientedRevision_ != this.getRevision()) {
const flatCoordinates = this.flatCoordinates;
if (linearRingsAreOriented(flatCoordinates, 0, this.ends_, this.stride)) {
this.orientedFlatCoordinates_ = flatCoordinates;
} else {
this.orientedFlatCoordinates_ = flatCoordinates.slice();
this.orientedFlatCoordinates_.length = orientLinearRings(
this.orientedFlatCoordinates_,
0,
this.ends_,
this.stride
);
}
this.orientedRevision_ = this.getRevision();
}
return this.orientedFlatCoordinates_;
}
getSimplifiedGeometryInternal(squaredTolerance) {
const simplifiedFlatCoordinates = [];
const simplifiedEnds = [];
simplifiedFlatCoordinates.length = quantizeArray(
this.flatCoordinates,
0,
this.ends_,
this.stride,
Math.sqrt(squaredTolerance),
simplifiedFlatCoordinates,
0,
simplifiedEnds
);
return new Polygon(simplifiedFlatCoordinates, "XY", simplifiedEnds);
}
getType() {
return "Polygon";
}
intersectsExtent(extent) {
return intersectsLinearRingArray(
this.getOrientedFlatCoordinates(),
0,
this.ends_,
this.stride,
extent
);
}
setCoordinates(coordinates2, layout) {
this.setLayout(layout, coordinates2, 2);
if (!this.flatCoordinates) {
this.flatCoordinates = [];
}
const ends = deflateCoordinatesArray(
this.flatCoordinates,
0,
coordinates2,
this.stride,
this.ends_
);
this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];
this.changed();
}
}
function fromExtent(extent) {
if (isEmpty(extent)) {
throw new Error("Cannot create polygon from empty extent");
}
const minX = extent[0];
const minY = extent[1];
const maxX = extent[2];
const maxY = extent[3];
const flatCoordinates = [
minX,
minY,
minX,
maxY,
maxX,
maxY,
maxX,
minY,
minX,
minY
];
return new Polygon(flatCoordinates, "XY", [flatCoordinates.length]);
}
const tmpTransform = create();
class RenderFeature {
constructor(type, flatCoordinates, ends, stride, properties, id) {
this.styleFunction;
this.extent_;
this.id_ = id;
this.type_ = type;
this.flatCoordinates_ = flatCoordinates;
this.flatInteriorPoints_ = null;
this.flatMidpoints_ = null;
this.ends_ = ends || null;
this.properties_ = properties;
this.squaredTolerance_;
this.stride_ = stride;
this.simplifiedGeometry_;
}
get(key) {
return this.properties_[key];
}
getExtent() {
if (!this.extent_) {
this.extent_ = this.type_ === "Point" ? createOrUpdateFromCoordinate(this.flatCoordinates_) : createOrUpdateFromFlatCoordinates(
this.flatCoordinates_,
0,
this.flatCoordinates_.length,
2
);
}
return this.extent_;
}
getFlatInteriorPoint() {
if (!this.flatInteriorPoints_) {
const flatCenter = getCenter(this.getExtent());
this.flatInteriorPoints_ = getInteriorPointOfArray(
this.flatCoordinates_,
0,
this.ends_,
2,
flatCenter,
0
);
}
return this.flatInteriorPoints_;
}
getFlatInteriorPoints() {
if (!this.flatInteriorPoints_) {
const ends = inflateEnds(this.flatCoordinates_, this.ends_);
const flatCenters = linearRingss(this.flatCoordinates_, 0, ends, 2);
this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(
this.flatCoordinates_,
0,
ends,
2,
flatCenters
);
}
return this.flatInteriorPoints_;
}
getFlatMidpoint() {
if (!this.flatMidpoints_) {
this.flatMidpoints_ = interpolatePoint(
this.flatCoordinates_,
0,
this.flatCoordinates_.length,
2,
0.5
);
}
return this.flatMidpoints_;
}
getFlatMidpoints() {
if (!this.flatMidpoints_) {
this.flatMidpoints_ = [];
const flatCoordinates = this.flatCoordinates_;
let offset = 0;
const ends = this.ends_;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
const midpoint = interpolatePoint(flatCoordinates, offset, end, 2, 0.5);
extend$2(this.flatMidpoints_, midpoint);
offset = end;
}
}
return this.flatMidpoints_;
}
getId() {
return this.id_;
}
getOrientedFlatCoordinates() {
return this.flatCoordinates_;
}
getGeometry() {
return this;
}
getSimplifiedGeometry(squaredTolerance) {
return this;
}
simplifyTransformed(squaredTolerance, transform) {
return this;
}
getProperties() {
return this.properties_;
}
getPropertiesInternal() {
return this.properties_;
}
getStride() {
return this.stride_;
}
getStyleFunction() {
return this.styleFunction;
}
getType() {
return this.type_;
}
transform(projection) {
projection = get$1(projection);
const pixelExtent = projection.getExtent();
const projectedExtent = projection.getWorldExtent();
if (pixelExtent && projectedExtent) {
const scale2 = getHeight(projectedExtent) / getHeight(pixelExtent);
compose(
tmpTransform,
projectedExtent[0],
projectedExtent[3],
scale2,
-scale2,
0,
0,
0
);
transform2D(
this.flatCoordinates_,
0,
this.flatCoordinates_.length,
2,
tmpTransform,
this.flatCoordinates_
);
}
}
applyTransform(transformFn) {
transformFn(this.flatCoordinates_, this.flatCoordinates_, this.stride_);
}
clone() {
var _a;
return new RenderFeature(
this.type_,
this.flatCoordinates_.slice(),
(_a = this.ends_) == null ? void 0 : _a.slice(),
this.stride_,
Object.assign({}, this.properties_),
this.id_
);
}
getEnds() {
return this.ends_;
}
enableSimplifyTransformed() {
this.simplifyTransformed = memoizeOne((squaredTolerance, transform) => {
if (squaredTolerance === this.squaredTolerance_) {
return this.simplifiedGeometry_;
}
this.simplifiedGeometry_ = this.clone();
if (transform) {
this.simplifiedGeometry_.applyTransform(transform);
}
const simplifiedFlatCoordinates = this.simplifiedGeometry_.getFlatCoordinates();
let simplifiedEnds;
switch (this.type_) {
case "LineString":
simplifiedFlatCoordinates.length = douglasPeucker(
simplifiedFlatCoordinates,
0,
this.simplifiedGeometry_.flatCoordinates_.length,
this.simplifiedGeometry_.stride_,
squaredTolerance,
simplifiedFlatCoordinates,
0
);
simplifiedEnds = [simplifiedFlatCoordinates.length];
break;
case "MultiLineString":
simplifiedEnds = [];
simplifiedFlatCoordinates.length = douglasPeuckerArray(
simplifiedFlatCoordinates,
0,
this.simplifiedGeometry_.ends_,
this.simplifiedGeometry_.stride_,
squaredTolerance,
simplifiedFlatCoordinates,
0,
simplifiedEnds
);
break;
case "Polygon":
simplifiedEnds = [];
simplifiedFlatCoordinates.length = quantizeArray(
simplifiedFlatCoordinates,
0,
this.simplifiedGeometry_.ends_,
this.simplifiedGeometry_.stride_,
Math.sqrt(squaredTolerance),
simplifiedFlatCoordinates,
0,
simplifiedEnds
);
break;
}
if (simplifiedEnds) {
this.simplifiedGeometry_ = new RenderFeature(
this.type_,
simplifiedFlatCoordinates,
simplifiedEnds,
2,
this.properties_,
this.id_
);
}
this.squaredTolerance_ = squaredTolerance;
return this.simplifiedGeometry_;
});
return this;
}
}
RenderFeature.prototype.getFlatCoordinates = RenderFeature.prototype.getOrientedFlatCoordinates;
const RenderFeature$1 = RenderFeature;
function quickselect(arr, k, left = 0, right = arr.length - 1, compare = defaultCompare) {
while (right > left) {
if (right - left > 600) {
const n = right - left + 1;
const m = k - left + 1;
const z = Math.log(n);
const s = 0.5 * Math.exp(2 * z / 3);
const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
quickselect(arr, k, newLeft, newRight, compare);
}
const t = arr[k];
let i = left;
let j = right;
swap(arr, left, k);
if (compare(arr[right], t) > 0)
swap(arr, left, right);
while (i < j) {
swap(arr, i, j);
i++;
j--;
while (compare(arr[i], t) < 0)
i++;
while (compare(arr[j], t) > 0)
j--;
}
if (compare(arr[left], t) === 0)
swap(arr, left, j);
else {
j++;
swap(arr, j, right);
}
if (j <= k)
left = j + 1;
if (k <= j)
right = j - 1;
}
}
function swap(arr, i, j) {
const tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
function defaultCompare(a3, b) {
return a3 < b ? -1 : a3 > b ? 1 : 0;
}
class RBush$2 {
constructor(maxEntries = 9) {
this._maxEntries = Math.max(4, maxEntries);
this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
this.clear();
}
all() {
return this._all(this.data, []);
}
search(bbox) {
let node = this.data;
const result = [];
if (!intersects(bbox, node))
return result;
const toBBox = this.toBBox;
const nodesToSearch = [];
while (node) {
for (let i = 0; i < node.children.length; i++) {
const child = node.children[i];
const childBBox = node.leaf ? toBBox(child) : child;
if (intersects(bbox, childBBox)) {
if (node.leaf)
result.push(child);
else if (contains(bbox, childBBox))
this._all(child, result);
else
nodesToSearch.push(child);
}
}
node = nodesToSearch.pop();
}
return result;
}
collides(bbox) {
let node = this.data;
if (!intersects(bbox, node))
return false;
const nodesToSearch = [];
while (node) {
for (let i = 0; i < node.children.length; i++) {
const child = node.children[i];
const childBBox = node.leaf ? this.toBBox(child) : child;
if (intersects(bbox, childBBox)) {
if (node.leaf || contains(bbox, childBBox))
return true;
nodesToSearch.push(child);
}
}
node = nodesToSearch.pop();
}
return false;
}
load(data) {
if (!(data && data.length))
return this;
if (data.length < this._minEntries) {
for (let i = 0; i < data.length; i++) {
this.insert(data[i]);
}
return this;
}
let node = this._build(data.slice(), 0, data.length - 1, 0);
if (!this.data.children.length) {
this.data = node;
} else if (this.data.height === node.height) {
this._splitRoot(this.data, node);
} else {
if (this.data.height < node.height) {
const tmpNode = this.data;
this.data = node;
node = tmpNode;
}
this._insert(node, this.data.height - node.height - 1, true);
}
return this;
}
insert(item) {
if (item)
this._insert(item, this.data.height - 1);
return this;
}
clear() {
this.data = createNode([]);
return this;
}
remove(item, equalsFn) {
if (!item)
return this;
let node = this.data;
const bbox = this.toBBox(item);
const path = [];
const indexes = [];
let i, parent, goingUp;
while (node || path.length) {
if (!node) {
node = path.pop();
parent = path[path.length - 1];
i = indexes.pop();
goingUp = true;
}
if (node.leaf) {
const index2 = findItem(item, node.children, equalsFn);
if (index2 !== -1) {
node.children.splice(index2, 1);
path.push(node);
this._condense(path);
return this;
}
}
if (!goingUp && !node.leaf && contains(node, bbox)) {
path.push(node);
indexes.push(i);
i = 0;
parent = node;
node = node.children[0];
} else if (parent) {
i++;
node = parent.children[i];
goingUp = false;
} else
node = null;
}
return this;
}
toBBox(item) {
return item;
}
compareMinX(a3, b) {
return a3.minX - b.minX;
}
compareMinY(a3, b) {
return a3.minY - b.minY;
}
toJSON() {
return this.data;
}
fromJSON(data) {
this.data = data;
return this;
}
_all(node, result) {
const nodesToSearch = [];
while (node) {
if (node.leaf)
result.push(...node.children);
else
nodesToSearch.push(...node.children);
node = nodesToSearch.pop();
}
return result;
}
_build(items, left, right, height) {
const N = right - left + 1;
let M = this._maxEntries;
let node;
if (N <= M) {
node = createNode(items.slice(left, right + 1));
calcBBox(node, this.toBBox);
return node;
}
if (!height) {
height = Math.ceil(Math.log(N) / Math.log(M));
M = Math.ceil(N / Math.pow(M, height - 1));
}
node = createNode([]);
node.leaf = false;
node.height = height;
const N2 = Math.ceil(N / M);
const N1 = N2 * Math.ceil(Math.sqrt(M));
multiSelect(items, left, right, N1, this.compareMinX);
for (let i = left; i <= right; i += N1) {
const right2 = Math.min(i + N1 - 1, right);
multiSelect(items, i, right2, N2, this.compareMinY);
for (let j = i; j <= right2; j += N2) {
const right3 = Math.min(j + N2 - 1, right2);
node.children.push(this._build(items, j, right3, height - 1));
}
}
calcBBox(node, this.toBBox);
return node;
}
_chooseSubtree(bbox, node, level2, path) {
while (true) {
path.push(node);
if (node.leaf || path.length - 1 === level2)
break;
let minArea = Infinity;
let minEnlargement = Infinity;
let targetNode;
for (let i = 0; i < node.children.length; i++) {
const child = node.children[i];
const area = bboxArea(child);
const enlargement = enlargedArea(bbox, child) - area;
if (enlargement < minEnlargement) {
minEnlargement = enlargement;
minArea = area < minArea ? area : minArea;
targetNode = child;
} else if (enlargement === minEnlargement) {
if (area < minArea) {
minArea = area;
targetNode = child;
}
}
}
node = targetNode || node.children[0];
}
return node;
}
_insert(item, level2, isNode) {
const bbox = isNode ? item : this.toBBox(item);
const insertPath = [];
const node = this._chooseSubtree(bbox, this.data, level2, insertPath);
node.children.push(item);
extend(node, bbox);
while (level2 >= 0) {
if (insertPath[level2].children.length > this._maxEntries) {
this._split(insertPath, level2);
level2--;
} else
break;
}
this._adjustParentBBoxes(bbox, insertPath, level2);
}
_split(insertPath, level2) {
const node = insertPath[level2];
const M = node.children.length;
const m = this._minEntries;
this._chooseSplitAxis(node, m, M);
const splitIndex = this._chooseSplitIndex(node, m, M);
const newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
newNode.height = node.height;
newNode.leaf = node.leaf;
calcBBox(node, this.toBBox);
calcBBox(newNode, this.toBBox);
if (level2)
insertPath[level2 - 1].children.push(newNode);
else
this._splitRoot(node, newNode);
}
_splitRoot(node, newNode) {
this.data = createNode([node, newNode]);
this.data.height = node.height + 1;
this.data.leaf = false;
calcBBox(this.data, this.toBBox);
}
_chooseSplitIndex(node, m, M) {
let index2;
let minOverlap = Infinity;
let minArea = Infinity;
for (let i = m; i <= M - m; i++) {
const bbox1 = distBBox(node, 0, i, this.toBBox);
const bbox2 = distBBox(node, i, M, this.toBBox);
const overlap = intersectionArea(bbox1, bbox2);
const area = bboxArea(bbox1) + bboxArea(bbox2);
if (overlap < minOverlap) {
minOverlap = overlap;
index2 = i;
minArea = area < minArea ? area : minArea;
} else if (overlap === minOverlap) {
if (area < minArea) {
minArea = area;
index2 = i;
}
}
}
return index2 || M - m;
}
_chooseSplitAxis(node, m, M) {
const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;
const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;
const xMargin = this._allDistMargin(node, m, M, compareMinX);
const yMargin = this._allDistMargin(node, m, M, compareMinY);
if (xMargin < yMargin)
node.children.sort(compareMinX);
}
_allDistMargin(node, m, M, compare) {
node.children.sort(compare);
const toBBox = this.toBBox;
const leftBBox = distBBox(node, 0, m, toBBox);
const rightBBox = distBBox(node, M - m, M, toBBox);
let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);
for (let i = m; i < M - m; i++) {
const child = node.children[i];
extend(leftBBox, node.leaf ? toBBox(child) : child);
margin += bboxMargin(leftBBox);
}
for (let i = M - m - 1; i >= m; i--) {
const child = node.children[i];
extend(rightBBox, node.leaf ? toBBox(child) : child);
margin += bboxMargin(rightBBox);
}
return margin;
}
_adjustParentBBoxes(bbox, path, level2) {
for (let i = level2; i >= 0; i--) {
extend(path[i], bbox);
}
}
_condense(path) {
for (let i = path.length - 1, siblings; i >= 0; i--) {
if (path[i].children.length === 0) {
if (i > 0) {
siblings = path[i - 1].children;
siblings.splice(siblings.indexOf(path[i]), 1);
} else
this.clear();
} else
calcBBox(path[i], this.toBBox);
}
}
}
function findItem(item, items, equalsFn) {
if (!equalsFn)
return items.indexOf(item);
for (let i = 0; i < items.length; i++) {
if (equalsFn(item, items[i]))
return i;
}
return -1;
}
function calcBBox(node, toBBox) {
distBBox(node, 0, node.children.length, toBBox, node);
}
function distBBox(node, k, p, toBBox, destNode) {
if (!destNode)
destNode = createNode(null);
destNode.minX = Infinity;
destNode.minY = Infinity;
destNode.maxX = -Infinity;
destNode.maxY = -Infinity;
for (let i = k; i < p; i++) {
const child = node.children[i];
extend(destNode, node.leaf ? toBBox(child) : child);
}
return destNode;
}
function extend(a3, b) {
a3.minX = Math.min(a3.minX, b.minX);
a3.minY = Math.min(a3.minY, b.minY);
a3.maxX = Math.max(a3.maxX, b.maxX);
a3.maxY = Math.max(a3.maxY, b.maxY);
return a3;
}
function compareNodeMinX(a3, b) {
return a3.minX - b.minX;
}
function compareNodeMinY(a3, b) {
return a3.minY - b.minY;
}
function bboxArea(a3) {
return (a3.maxX - a3.minX) * (a3.maxY - a3.minY);
}
function bboxMargin(a3) {
return a3.maxX - a3.minX + (a3.maxY - a3.minY);
}
function enlargedArea(a3, b) {
return (Math.max(b.maxX, a3.maxX) - Math.min(b.minX, a3.minX)) * (Math.max(b.maxY, a3.maxY) - Math.min(b.minY, a3.minY));
}
function intersectionArea(a3, b) {
const minX = Math.max(a3.minX, b.minX);
const minY = Math.max(a3.minY, b.minY);
const maxX = Math.min(a3.maxX, b.maxX);
const maxY = Math.min(a3.maxY, b.maxY);
return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
}
function contains(a3, b) {
return a3.minX <= b.minX && a3.minY <= b.minY && b.maxX <= a3.maxX && b.maxY <= a3.maxY;
}
function intersects(a3, b) {
return b.minX <= a3.maxX && b.minY <= a3.maxY && b.maxX >= a3.minX && b.maxY >= a3.minY;
}
function createNode(children) {
return {
children,
height: 1,
leaf: true,
minX: Infinity,
minY: Infinity,
maxX: -Infinity,
maxY: -Infinity
};
}
function multiSelect(arr, left, right, n, compare) {
const stack = [left, right];
while (stack.length) {
right = stack.pop();
left = stack.pop();
if (right - left <= n)
continue;
const mid = left + Math.ceil((right - left) / n / 2) * n;
quickselect(arr, mid, left, right, compare);
stack.push(left, mid, mid, right);
}
}
class RBush {
constructor(maxEntries) {
this.rbush_ = new RBush$2(maxEntries);
this.items_ = {};
}
insert(extent, value) {
const item = {
minX: extent[0],
minY: extent[1],
maxX: extent[2],
maxY: extent[3],
value
};
this.rbush_.insert(item);
this.items_[getUid(value)] = item;
}
load(extents, values) {
const items = new Array(values.length);
for (let i = 0, l = values.length; i < l; i++) {
const extent = extents[i];
const value = values[i];
const item = {
minX: extent[0],
minY: extent[1],
maxX: extent[2],
maxY: extent[3],
value
};
items[i] = item;
this.items_[getUid(value)] = item;
}
this.rbush_.load(items);
}
remove(value) {
const uid = getUid(value);
const item = this.items_[uid];
delete this.items_[uid];
return this.rbush_.remove(item) !== null;
}
update(extent, value) {
const item = this.items_[getUid(value)];
const bbox = [item.minX, item.minY, item.maxX, item.maxY];
if (!equals$1(bbox, extent)) {
this.remove(value);
this.insert(extent, value);
}
}
getAll() {
const items = this.rbush_.all();
return items.map(function(item) {
return item.value;
});
}
getInExtent(extent) {
const bbox = {
minX: extent[0],
minY: extent[1],
maxX: extent[2],
maxY: extent[3]
};
const items = this.rbush_.search(bbox);
return items.map(function(item) {
return item.value;
});
}
forEach(callback) {
return this.forEach_(this.getAll(), callback);
}
forEachInExtent(extent, callback) {
return this.forEach_(this.getInExtent(extent), callback);
}
forEach_(values, callback) {
let result;
for (let i = 0, l = values.length; i < l; i++) {
result = callback(values[i]);
if (result) {
return result;
}
}
return result;
}
isEmpty() {
return isEmpty$1(this.items_);
}
clear() {
this.rbush_.clear();
this.items_ = {};
}
getExtent(extent) {
const data = this.rbush_.toJSON();
return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, extent);
}
concat(rbush) {
this.rbush_.load(rbush.rbush_.all());
for (const i in rbush.items_) {
this.items_[i] = rbush.items_[i];
}
}
}
const RBush$1 = RBush;
class Source extends BaseObject$1 {
constructor(options) {
var _a;
super();
this.projection = get$1(options.projection);
this.attributions_ = adaptAttributions(options.attributions);
this.attributionsCollapsible_ = (_a = options.attributionsCollapsible) != null ? _a : true;
this.loading = false;
this.state_ = options.state !== void 0 ? options.state : "ready";
this.wrapX_ = options.wrapX !== void 0 ? options.wrapX : false;
this.interpolate_ = !!options.interpolate;
this.viewResolver = null;
this.viewRejector = null;
const self2 = this;
this.viewPromise_ = new Promise(function(resolve, reject) {
self2.viewResolver = resolve;
self2.viewRejector = reject;
});
}
getAttributions() {
return this.attributions_;
}
getAttributionsCollapsible() {
return this.attributionsCollapsible_;
}
getProjection() {
return this.projection;
}
getResolutions(projection) {
return null;
}
getView() {
return this.viewPromise_;
}
getState() {
return this.state_;
}
getWrapX() {
return this.wrapX_;
}
getInterpolate() {
return this.interpolate_;
}
refresh() {
this.changed();
}
setAttributions(attributions) {
this.attributions_ = adaptAttributions(attributions);
this.changed();
}
setState(state) {
this.state_ = state;
this.changed();
}
}
function adaptAttributions(attributionLike) {
if (!attributionLike) {
return null;
}
if (typeof attributionLike === "function") {
return attributionLike;
}
if (!Array.isArray(attributionLike)) {
attributionLike = [attributionLike];
}
return (frameState) => attributionLike;
}
const Source$1 = Source;
const VectorEventType = {
ADDFEATURE: "addfeature",
CHANGEFEATURE: "changefeature",
CLEAR: "clear",
REMOVEFEATURE: "removefeature",
FEATURESLOADSTART: "featuresloadstart",
FEATURESLOADEND: "featuresloadend",
FEATURESLOADERROR: "featuresloaderror"
};
class VectorSourceEvent extends Event {
constructor(type, feature2, features) {
super(type);
this.feature = feature2;
this.features = features;
}
}
class VectorSource extends Source$1 {
constructor(options) {
options = options || {};
super({
attributions: options.attributions,
interpolate: true,
projection: void 0,
state: "ready",
wrapX: options.wrapX !== void 0 ? options.wrapX : true
});
this.on;
this.once;
this.un;
this.loader_ = VOID;
this.format_ = options.format || null;
this.overlaps_ = options.overlaps === void 0 ? true : options.overlaps;
this.url_ = options.url;
if (options.loader !== void 0) {
this.loader_ = options.loader;
} else if (this.url_ !== void 0) {
assert(this.format_, "`format` must be set when `url` is set");
this.loader_ = xhr(this.url_, this.format_);
}
this.strategy_ = options.strategy !== void 0 ? options.strategy : all;
const useSpatialIndex = options.useSpatialIndex !== void 0 ? options.useSpatialIndex : true;
this.featuresRtree_ = useSpatialIndex ? new RBush$1() : null;
this.loadedExtentsRtree_ = new RBush$1();
this.loadingExtentsCount_ = 0;
this.nullGeometryFeatures_ = {};
this.idIndex_ = {};
this.uidIndex_ = {};
this.featureChangeKeys_ = {};
this.featuresCollection_ = null;
let collection;
let features;
if (Array.isArray(options.features)) {
features = options.features;
} else if (options.features) {
collection = options.features;
features = collection.getArray();
}
if (!useSpatialIndex && collection === void 0) {
collection = new Collection$1(features);
}
if (features !== void 0) {
this.addFeaturesInternal(features);
}
if (collection !== void 0) {
this.bindFeaturesCollection_(collection);
}
}
addFeature(feature2) {
this.addFeatureInternal(feature2);
this.changed();
}
addFeatureInternal(feature2) {
const featureKey = getUid(feature2);
if (!this.addToIndex_(featureKey, feature2)) {
if (this.featuresCollection_) {
this.featuresCollection_.remove(feature2);
}
return;
}
this.setupChangeEvents_(featureKey, feature2);
const geometry = feature2.getGeometry();
if (geometry) {
const extent = geometry.getExtent();
if (this.featuresRtree_) {
this.featuresRtree_.insert(extent, feature2);
}
} else {
this.nullGeometryFeatures_[featureKey] = feature2;
}
this.dispatchEvent(
new VectorSourceEvent(VectorEventType.ADDFEATURE, feature2)
);
}
setupChangeEvents_(featureKey, feature2) {
if (feature2 instanceof RenderFeature$1) {
return;
}
this.featureChangeKeys_[featureKey] = [
listen(feature2, EventType.CHANGE, this.handleFeatureChange_, this),
listen(
feature2,
ObjectEventType.PROPERTYCHANGE,
this.handleFeatureChange_,
this
)
];
}
addToIndex_(featureKey, feature2) {
let valid = true;
if (feature2.getId() !== void 0) {
const id = String(feature2.getId());
if (!(id in this.idIndex_)) {
this.idIndex_[id] = feature2;
} else if (feature2 instanceof RenderFeature$1) {
const indexedFeature = this.idIndex_[id];
if (!(indexedFeature instanceof RenderFeature$1)) {
valid = false;
} else if (!Array.isArray(indexedFeature)) {
this.idIndex_[id] = [indexedFeature, feature2];
} else {
indexedFeature.push(feature2);
}
} else {
valid = false;
}
}
if (valid) {
assert(
!(featureKey in this.uidIndex_),
"The passed `feature` was already added to the source"
);
this.uidIndex_[featureKey] = feature2;
}
return valid;
}
addFeatures(features) {
this.addFeaturesInternal(features);
this.changed();
}
addFeaturesInternal(features) {
const extents = [];
const newFeatures = [];
const geometryFeatures = [];
for (let i = 0, length = features.length; i < length; i++) {
const feature2 = features[i];
const featureKey = getUid(feature2);
if (this.addToIndex_(featureKey, feature2)) {
newFeatures.push(feature2);
}
}
for (let i = 0, length = newFeatures.length; i < length; i++) {
const feature2 = newFeatures[i];
const featureKey = getUid(feature2);
this.setupChangeEvents_(featureKey, feature2);
const geometry = feature2.getGeometry();
if (geometry) {
const extent = geometry.getExtent();
extents.push(extent);
geometryFeatures.push(feature2);
} else {
this.nullGeometryFeatures_[featureKey] = feature2;
}
}
if (this.featuresRtree_) {
this.featuresRtree_.load(extents, geometryFeatures);
}
if (this.hasListener(VectorEventType.ADDFEATURE)) {
for (let i = 0, length = newFeatures.length; i < length; i++) {
this.dispatchEvent(
new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i])
);
}
}
}
bindFeaturesCollection_(collection) {
let modifyingCollection = false;
this.addEventListener(
VectorEventType.ADDFEATURE,
function(evt) {
if (!modifyingCollection) {
modifyingCollection = true;
collection.push(evt.feature);
modifyingCollection = false;
}
}
);
this.addEventListener(
VectorEventType.REMOVEFEATURE,
function(evt) {
if (!modifyingCollection) {
modifyingCollection = true;
collection.remove(evt.feature);
modifyingCollection = false;
}
}
);
collection.addEventListener(
CollectionEventType.ADD,
(evt) => {
if (!modifyingCollection) {
modifyingCollection = true;
this.addFeature(evt.element);
modifyingCollection = false;
}
}
);
collection.addEventListener(
CollectionEventType.REMOVE,
(evt) => {
if (!modifyingCollection) {
modifyingCollection = true;
this.removeFeature(evt.element);
modifyingCollection = false;
}
}
);
this.featuresCollection_ = collection;
}
clear(fast) {
if (fast) {
for (const featureId in this.featureChangeKeys_) {
const keys = this.featureChangeKeys_[featureId];
keys.forEach(unlistenByKey);
}
if (!this.featuresCollection_) {
this.featureChangeKeys_ = {};
this.idIndex_ = {};
this.uidIndex_ = {};
}
} else {
if (this.featuresRtree_) {
this.featuresRtree_.forEach((feature2) => {
this.removeFeatureInternal(feature2);
});
for (const id in this.nullGeometryFeatures_) {
this.removeFeatureInternal(this.nullGeometryFeatures_[id]);
}
}
}
if (this.featuresCollection_) {
this.featuresCollection_.clear();
}
if (this.featuresRtree_) {
this.featuresRtree_.clear();
}
this.nullGeometryFeatures_ = {};
const clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);
this.dispatchEvent(clearEvent);
this.changed();
}
forEachFeature(callback) {
if (this.featuresRtree_) {
return this.featuresRtree_.forEach(callback);
}
if (this.featuresCollection_) {
this.featuresCollection_.forEach(callback);
}
}
forEachFeatureAtCoordinateDirect(coordinate, callback) {
const extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];
return this.forEachFeatureInExtent(extent, function(feature2) {
const geometry = feature2.getGeometry();
if (geometry instanceof RenderFeature$1 || geometry.intersectsCoordinate(coordinate)) {
return callback(feature2);
}
return void 0;
});
}
forEachFeatureInExtent(extent, callback) {
if (this.featuresRtree_) {
return this.featuresRtree_.forEachInExtent(extent, callback);
}
if (this.featuresCollection_) {
this.featuresCollection_.forEach(callback);
}
}
forEachFeatureIntersectingExtent(extent, callback) {
return this.forEachFeatureInExtent(
extent,
function(feature2) {
const geometry = feature2.getGeometry();
if (geometry instanceof RenderFeature$1 || geometry.intersectsExtent(extent)) {
const result = callback(feature2);
if (result) {
return result;
}
}
}
);
}
getFeaturesCollection() {
return this.featuresCollection_;
}
getFeatures() {
let features;
if (this.featuresCollection_) {
features = this.featuresCollection_.getArray().slice(0);
} else if (this.featuresRtree_) {
features = this.featuresRtree_.getAll();
if (!isEmpty$1(this.nullGeometryFeatures_)) {
extend$2(features, Object.values(this.nullGeometryFeatures_));
}
}
return features;
}
getFeaturesAtCoordinate(coordinate) {
const features = [];
this.forEachFeatureAtCoordinateDirect(coordinate, function(feature2) {
features.push(feature2);
});
return features;
}
getFeaturesInExtent(extent, projection) {
if (this.featuresRtree_) {
const multiWorld = projection && projection.canWrapX() && this.getWrapX();
if (!multiWorld) {
return this.featuresRtree_.getInExtent(extent);
}
const extents = wrapAndSliceX(extent, projection);
return [].concat(
...extents.map((anExtent) => this.featuresRtree_.getInExtent(anExtent))
);
}
if (this.featuresCollection_) {
return this.featuresCollection_.getArray().slice(0);
}
return [];
}
getClosestFeatureToCoordinate(coordinate, filter) {
const x = coordinate[0];
const y = coordinate[1];
let closestFeature = null;
const closestPoint = [NaN, NaN];
let minSquaredDistance = Infinity;
const extent = [-Infinity, -Infinity, Infinity, Infinity];
filter = filter ? filter : TRUE;
this.featuresRtree_.forEachInExtent(
extent,
function(feature2) {
if (filter(feature2)) {
const geometry = feature2.getGeometry();
const previousMinSquaredDistance = minSquaredDistance;
minSquaredDistance = geometry instanceof RenderFeature$1 ? 0 : geometry.closestPointXY(x, y, closestPoint, minSquaredDistance);
if (minSquaredDistance < previousMinSquaredDistance) {
closestFeature = feature2;
const minDistance = Math.sqrt(minSquaredDistance);
extent[0] = x - minDistance;
extent[1] = y - minDistance;
extent[2] = x + minDistance;
extent[3] = y + minDistance;
}
}
}
);
return closestFeature;
}
getExtent(extent) {
return this.featuresRtree_.getExtent(extent);
}
getFeatureById(id) {
const feature2 = this.idIndex_[id.toString()];
return feature2 !== void 0 ? feature2 : null;
}
getFeatureByUid(uid) {
const feature2 = this.uidIndex_[uid];
return feature2 !== void 0 ? feature2 : null;
}
getFormat() {
return this.format_;
}
getOverlaps() {
return this.overlaps_;
}
getUrl() {
return this.url_;
}
handleFeatureChange_(event) {
const feature2 = event.target;
const featureKey = getUid(feature2);
const geometry = feature2.getGeometry();
if (!geometry) {
if (!(featureKey in this.nullGeometryFeatures_)) {
if (this.featuresRtree_) {
this.featuresRtree_.remove(feature2);
}
this.nullGeometryFeatures_[featureKey] = feature2;
}
} else {
const extent = geometry.getExtent();
if (featureKey in this.nullGeometryFeatures_) {
delete this.nullGeometryFeatures_[featureKey];
if (this.featuresRtree_) {
this.featuresRtree_.insert(extent, feature2);
}
} else {
if (this.featuresRtree_) {
this.featuresRtree_.update(extent, feature2);
}
}
}
const id = feature2.getId();
if (id !== void 0) {
const sid = id.toString();
if (this.idIndex_[sid] !== feature2) {
this.removeFromIdIndex_(feature2);
this.idIndex_[sid] = feature2;
}
} else {
this.removeFromIdIndex_(feature2);
this.uidIndex_[featureKey] = feature2;
}
this.changed();
this.dispatchEvent(
new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature2)
);
}
hasFeature(feature2) {
const id = feature2.getId();
if (id !== void 0) {
return id in this.idIndex_;
}
return getUid(feature2) in this.uidIndex_;
}
isEmpty() {
if (this.featuresRtree_) {
return this.featuresRtree_.isEmpty() && isEmpty$1(this.nullGeometryFeatures_);
}
if (this.featuresCollection_) {
return this.featuresCollection_.getLength() === 0;
}
return true;
}
loadFeatures(extent, resolution, projection) {
const loadedExtentsRtree = this.loadedExtentsRtree_;
const extentsToLoad = this.strategy_(extent, resolution, projection);
for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
const extentToLoad = extentsToLoad[i];
const alreadyLoaded = loadedExtentsRtree.forEachInExtent(
extentToLoad,
function(object) {
return containsExtent(object.extent, extentToLoad);
}
);
if (!alreadyLoaded) {
++this.loadingExtentsCount_;
this.dispatchEvent(
new VectorSourceEvent(VectorEventType.FEATURESLOADSTART)
);
this.loader_.call(
this,
extentToLoad,
resolution,
projection,
(features) => {
--this.loadingExtentsCount_;
this.dispatchEvent(
new VectorSourceEvent(
VectorEventType.FEATURESLOADEND,
void 0,
features
)
);
},
() => {
--this.loadingExtentsCount_;
this.dispatchEvent(
new VectorSourceEvent(VectorEventType.FEATURESLOADERROR)
);
}
);
loadedExtentsRtree.insert(extentToLoad, { extent: extentToLoad.slice() });
}
}
this.loading = this.loader_.length < 4 ? false : this.loadingExtentsCount_ > 0;
}
refresh() {
this.clear(true);
this.loadedExtentsRtree_.clear();
super.refresh();
}
removeLoadedExtent(extent) {
const loadedExtentsRtree = this.loadedExtentsRtree_;
const obj = loadedExtentsRtree.forEachInExtent(extent, function(object) {
if (equals$1(object.extent, extent)) {
return object;
}
});
if (obj) {
loadedExtentsRtree.remove(obj);
}
}
removeFeatures(features) {
let removed = false;
for (let i = 0, ii = features.length; i < ii; ++i) {
removed = this.removeFeatureInternal(features[i]) || removed;
}
if (removed) {
this.changed();
}
}
removeFeature(feature2) {
if (!feature2) {
return;
}
const removed = this.removeFeatureInternal(feature2);
if (removed) {
this.changed();
}
}
removeFeatureInternal(feature2) {
const featureKey = getUid(feature2);
if (!(featureKey in this.uidIndex_)) {
return false;
}
if (featureKey in this.nullGeometryFeatures_) {
delete this.nullGeometryFeatures_[featureKey];
} else {
if (this.featuresRtree_) {
this.featuresRtree_.remove(feature2);
}
}
const featureChangeKeys = this.featureChangeKeys_[featureKey];
featureChangeKeys == null ? void 0 : featureChangeKeys.forEach(unlistenByKey);
delete this.featureChangeKeys_[featureKey];
const id = feature2.getId();
if (id !== void 0) {
const idString = id.toString();
const indexedFeature = this.idIndex_[idString];
if (indexedFeature === feature2) {
delete this.idIndex_[idString];
} else if (Array.isArray(indexedFeature)) {
indexedFeature.splice(indexedFeature.indexOf(feature2), 1);
if (indexedFeature.length === 1) {
this.idIndex_[idString] = indexedFeature[0];
}
}
}
delete this.uidIndex_[featureKey];
if (this.hasListener(VectorEventType.REMOVEFEATURE)) {
this.dispatchEvent(
new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature2)
);
}
return true;
}
removeFromIdIndex_(feature2) {
for (const id in this.idIndex_) {
if (this.idIndex_[id] === feature2) {
delete this.idIndex_[id];
break;
}
}
}
setLoader(loader) {
this.loader_ = loader;
}
setUrl(url) {
assert(this.format_, "`format` must be set when `url` is set");
this.url_ = url;
this.setLoader(xhr(url, this.format_));
}
setOverlaps(overlaps) {
this.overlaps_ = overlaps;
this.changed();
}
}
const VectorSource$1 = VectorSource;
class Cluster extends VectorSource$1 {
constructor(options) {
options = options || {};
super({
attributions: options.attributions,
wrapX: options.wrapX
});
this.resolution = void 0;
this.distance = options.distance !== void 0 ? options.distance : 20;
this.minDistance = options.minDistance || 0;
this.interpolationRatio = 0;
this.features = [];
this.geometryFunction = options.geometryFunction || function(feature2) {
const geometry = feature2.getGeometry();
assert(
!geometry || geometry.getType() === "Point",
"The default `geometryFunction` can only handle `Point` or null geometries"
);
return geometry;
};
this.createCustomCluster_ = options.createCluster;
this.source = null;
this.boundRefresh_ = this.refresh.bind(this);
this.updateDistance(this.distance, this.minDistance);
this.setSource(options.source || null);
}
clear(fast) {
this.features.length = 0;
super.clear(fast);
}
getDistance() {
return this.distance;
}
getSource() {
return this.source;
}
loadFeatures(extent, resolution, projection) {
var _a;
(_a = this.source) == null ? void 0 : _a.loadFeatures(extent, resolution, projection);
if (resolution !== this.resolution) {
this.resolution = resolution;
this.refresh();
}
}
setDistance(distance) {
this.updateDistance(distance, this.minDistance);
}
setMinDistance(minDistance) {
this.updateDistance(this.distance, minDistance);
}
getMinDistance() {
return this.minDistance;
}
setSource(source) {
if (this.source) {
this.source.removeEventListener(EventType.CHANGE, this.boundRefresh_);
}
this.source = source;
if (source) {
source.addEventListener(EventType.CHANGE, this.boundRefresh_);
}
this.refresh();
}
refresh() {
this.clear();
this.cluster();
this.addFeatures(this.features);
}
updateDistance(distance, minDistance) {
const ratio = distance === 0 ? 0 : Math.min(minDistance, distance) / distance;
const changed = distance !== this.distance || this.interpolationRatio !== ratio;
this.distance = distance;
this.minDistance = minDistance;
this.interpolationRatio = ratio;
if (changed) {
this.refresh();
}
}
cluster() {
if (this.resolution === void 0 || !this.source) {
return;
}
const extent = createEmpty();
const mapDistance = this.distance * this.resolution;
const features = this.source.getFeatures();
const clustered = {};
for (let i = 0, ii = features.length; i < ii; i++) {
const feature2 = features[i];
if (!(getUid(feature2) in clustered)) {
const geometry = this.geometryFunction(feature2);
if (geometry) {
const coordinates2 = geometry.getCoordinates();
createOrUpdateFromCoordinate(coordinates2, extent);
buffer(extent, mapDistance, extent);
const neighbors = this.source.getFeaturesInExtent(extent).filter(function(neighbor) {
const uid = getUid(neighbor);
if (uid in clustered) {
return false;
}
clustered[uid] = true;
return true;
});
this.features.push(this.createCluster(neighbors, extent));
}
}
}
}
createCluster(features, extent) {
const centroid = [0, 0];
for (let i = features.length - 1; i >= 0; --i) {
const geometry2 = this.geometryFunction(features[i]);
if (geometry2) {
add$2(centroid, geometry2.getCoordinates());
} else {
features.splice(i, 1);
}
}
scale$1(centroid, 1 / features.length);
const searchCenter = getCenter(extent);
const ratio = this.interpolationRatio;
const geometry = new Point$1([
centroid[0] * (1 - ratio) + searchCenter[0] * ratio,
centroid[1] * (1 - ratio) + searchCenter[1] * ratio
]);
if (this.createCustomCluster_) {
return this.createCustomCluster_(geometry, features);
}
return new Feature$1({
geometry,
features
});
}
}
const Cluster$1 = Cluster;
const MapBrowserEventType = {
SINGLECLICK: "singleclick",
CLICK: EventType.CLICK,
DBLCLICK: EventType.DBLCLICK,
POINTERDRAG: "pointerdrag",
POINTERMOVE: "pointermove",
POINTERDOWN: "pointerdown",
POINTERUP: "pointerup",
POINTEROVER: "pointerover",
POINTEROUT: "pointerout",
POINTERENTER: "pointerenter",
POINTERLEAVE: "pointerleave",
POINTERCANCEL: "pointercancel"
};
const ua = typeof navigator !== "undefined" && typeof navigator.userAgent !== "undefined" ? navigator.userAgent.toLowerCase() : "";
const SAFARI = ua.includes("safari") && !ua.includes("chrom");
SAFARI && (ua.includes("version/15.4") || /cpu (os|iphone os) 15_4 like mac os x/.test(ua));
ua.includes("webkit") && !ua.includes("edge");
ua.includes("macintosh");
const WORKER_OFFSCREEN_CANVAS = typeof WorkerGlobalScope !== "undefined" && typeof OffscreenCanvas !== "undefined" && self instanceof WorkerGlobalScope;
const IMAGE_DECODE = typeof Image !== "undefined" && Image.prototype.decode;
(function() {
let passive = false;
try {
const options = Object.defineProperty({}, "passive", {
get: function() {
passive = true;
}
});
window.addEventListener("_", null, options);
window.removeEventListener("_", null, options);
} catch {
}
return passive;
})();
const never = FALSE;
const singleClick = function(mapBrowserEvent) {
return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;
};
const shiftKeyOnly = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent;
return !originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;
};
const ViewHint = {
ANIMATING: 0,
INTERACTING: 1
};
function createCanvasContext2D(width, height, canvasPool2, settings) {
let canvas;
if (canvasPool2 && canvasPool2.length) {
canvas = canvasPool2.shift();
} else if (WORKER_OFFSCREEN_CANVAS) {
canvas = new OffscreenCanvas(width || 300, height || 300);
} else {
canvas = document.createElement("canvas");
}
if (width) {
canvas.width = width;
}
if (height) {
canvas.height = height;
}
return canvas.getContext("2d", settings);
}
let sharedCanvasContext;
function getSharedCanvasContext2D() {
if (!sharedCanvasContext) {
sharedCanvasContext = createCanvasContext2D(1, 1);
}
return sharedCanvasContext;
}
function releaseCanvas(context) {
const canvas = context.canvas;
canvas.width = 1;
canvas.height = 1;
context.clearRect(0, 0, 1, 1);
}
function replaceNode(newNode, oldNode) {
const parent = oldNode.parentNode;
if (parent) {
parent.replaceChild(newNode, oldNode);
}
}
function removeChildren(node) {
while (node.lastChild) {
node.lastChild.remove();
}
}
const RenderEventType = {
PRERENDER: "prerender",
POSTRENDER: "postrender",
PRECOMPOSE: "precompose",
POSTCOMPOSE: "postcompose",
RENDERCOMPLETE: "rendercomplete"
};
const ImageState = {
IDLE: 0,
LOADING: 1,
LOADED: 2,
ERROR: 3,
EMPTY: 4
};
const NO_COLOR = [NaN, NaN, NaN, 0];
let colorParseContext;
function getColorParseContext() {
if (!colorParseContext) {
colorParseContext = createCanvasContext2D(1, 1, void 0, {
willReadFrequently: true,
desynchronized: true
});
}
return colorParseContext;
}
const rgbModernRegEx = /^rgba?\(\s*(\d+%?)\s+(\d+%?)\s+(\d+%?)(?:\s*\/\s*(\d+%|\d*\.\d+|[01]))?\s*\)$/i;
const rgbLegacyAbsoluteRegEx = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(\d+%|\d*\.\d+|[01]))?\s*\)$/i;
const rgbLegacyPercentageRegEx = /^rgba?\(\s*(\d+%)\s*,\s*(\d+%)\s*,\s*(\d+%)(?:\s*,\s*(\d+%|\d*\.\d+|[01]))?\s*\)$/i;
const hexRegEx = /^#([\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i;
function toColorComponent(s, divider) {
return s.endsWith("%") ? Number(s.substring(0, s.length - 1)) / divider : Number(s);
}
function throwInvalidColor(color) {
throw new Error('failed to parse "' + color + '" as color');
}
function parseRgba(color) {
if (color.toLowerCase().startsWith("rgb")) {
const rgb = color.match(rgbLegacyAbsoluteRegEx) || color.match(rgbModernRegEx) || color.match(rgbLegacyPercentageRegEx);
if (rgb) {
const alpha = rgb[4];
const rgbDivider = 100 / 255;
return [
clamp(toColorComponent(rgb[1], rgbDivider) + 0.5 | 0, 0, 255),
clamp(toColorComponent(rgb[2], rgbDivider) + 0.5 | 0, 0, 255),
clamp(toColorComponent(rgb[3], rgbDivider) + 0.5 | 0, 0, 255),
alpha !== void 0 ? clamp(toColorComponent(alpha, 100), 0, 1) : 1
];
}
throwInvalidColor(color);
}
if (color.startsWith("#")) {
if (hexRegEx.test(color)) {
const hex = color.substring(1);
const step = hex.length <= 4 ? 1 : 2;
const colorFromHex = [0, 0, 0, 255];
for (let i = 0, ii = hex.length; i < ii; i += step) {
let colorComponent = parseInt(hex.substring(i, i + step), 16);
if (step === 1) {
colorComponent += colorComponent << 4;
}
colorFromHex[i / step] = colorComponent;
}
colorFromHex[3] = colorFromHex[3] / 255;
return colorFromHex;
}
throwInvalidColor(color);
}
const context = getColorParseContext();
context.fillStyle = "#abcdef";
let invalidCheckFillStyle = context.fillStyle;
context.fillStyle = color;
if (context.fillStyle === invalidCheckFillStyle) {
context.fillStyle = "#fedcba";
invalidCheckFillStyle = context.fillStyle;
context.fillStyle = color;
if (context.fillStyle === invalidCheckFillStyle) {
throwInvalidColor(color);
}
}
const colorString = context.fillStyle;
if (colorString.startsWith("#") || colorString.startsWith("rgba")) {
return parseRgba(colorString);
}
context.clearRect(0, 0, 1, 1);
context.fillRect(0, 0, 1, 1);
const colorFromImage = Array.from(context.getImageData(0, 0, 1, 1).data);
colorFromImage[3] = toFixed(colorFromImage[3] / 255, 3);
return colorFromImage;
}
function asString(color) {
if (typeof color === "string") {
return color;
}
return toString(color);
}
const MAX_CACHE_SIZE = 1024;
const cache = {};
let cacheSize = 0;
function withAlpha(color) {
if (color.length === 4) {
return color;
}
const output = color.slice();
output[3] = 1;
return output;
}
function b1(v) {
return v > 31308e-7 ? Math.pow(v, 1 / 2.4) * 269.025 - 14.025 : v * 3294.6;
}
function b2(v) {
return v > 0.2068965 ? Math.pow(v, 3) : (v - 4 / 29) * (108 / 841);
}
function a1(v) {
return v > 10.314724 ? Math.pow((v + 14.025) / 269.025, 2.4) : v / 3294.6;
}
function a2(v) {
return v > 88564e-7 ? Math.pow(v, 1 / 3) : v / (108 / 841) + 4 / 29;
}
function rgbaToLcha(color) {
const r = a1(color[0]);
const g = a1(color[1]);
const b = a1(color[2]);
const y = a2(r * 0.222488403 + g * 0.716873169 + b * 0.06060791);
const l = 500 * (a2(r * 0.452247074 + g * 0.399439023 + b * 0.148375274) - y);
const q = 200 * (y - a2(r * 0.016863605 + g * 0.117638439 + b * 0.865350722));
const h = Math.atan2(q, l) * (180 / Math.PI);
return [
116 * y - 16,
Math.sqrt(l * l + q * q),
h < 0 ? h + 360 : h,
color[3]
];
}
function lchaToRgba(color) {
const l = (color[0] + 16) / 116;
const c = color[1];
const h = color[2] * Math.PI / 180;
const y = b2(l);
const x = b2(l + c / 500 * Math.cos(h));
const z = b2(l - c / 200 * Math.sin(h));
const r = b1(x * 3.021973625 - y * 1.617392459 - z * 0.404875592);
const g = b1(x * -0.943766287 + y * 1.916279586 + z * 0.027607165);
const b = b1(x * 0.069407491 - y * 0.22898585 + z * 1.159737864);
return [
clamp(r + 0.5 | 0, 0, 255),
clamp(g + 0.5 | 0, 0, 255),
clamp(b + 0.5 | 0, 0, 255),
color[3]
];
}
function fromString(s) {
if (s === "none") {
return NO_COLOR;
}
if (cache.hasOwnProperty(s)) {
return cache[s];
}
if (cacheSize >= MAX_CACHE_SIZE) {
let i = 0;
for (const key in cache) {
if ((i++ & 3) === 0) {
delete cache[key];
--cacheSize;
}
}
}
const color = parseRgba(s);
if (color.length !== 4) {
throwInvalidColor(s);
}
for (const c of color) {
if (isNaN(c)) {
throwInvalidColor(s);
}
}
cache[s] = color;
++cacheSize;
return color;
}
function asArray(color) {
if (Array.isArray(color)) {
return color;
}
return fromString(color);
}
function toString(color) {
let r = color[0];
if (r != (r | 0)) {
r = r + 0.5 | 0;
}
let g = color[1];
if (g != (g | 0)) {
g = g + 0.5 | 0;
}
let b = color[2];
if (b != (b | 0)) {
b = b + 0.5 | 0;
}
const a3 = color[3] === void 0 ? 1 : Math.round(color[3] * 1e3) / 1e3;
return "rgba(" + r + "," + g + "," + b + "," + a3 + ")";
}
function load(image, src) {
return new Promise((resolve, reject) => {
function handleLoad() {
unlisten();
resolve(image);
}
function handleError() {
unlisten();
reject(new Error("Image load error"));
}
function unlisten() {
image.removeEventListener("load", handleLoad);
image.removeEventListener("error", handleError);
}
image.addEventListener("load", handleLoad);
image.addEventListener("error", handleError);
if (src) {
image.src = src;
}
});
}
function decodeFallback(image, src) {
if (src) {
image.src = src;
}
return image.src && IMAGE_DECODE ? new Promise(
(resolve, reject) => image.decode().then(() => resolve(image)).catch(
(e) => image.complete && image.width ? resolve(image) : reject(e)
)
) : load(image);
}
class IconImageCache {
constructor() {
this.cache_ = {};
this.patternCache_ = {};
this.cacheSize_ = 0;
this.maxCacheSize_ = 1024;
}
clear() {
this.cache_ = {};
this.patternCache_ = {};
this.cacheSize_ = 0;
}
canExpireCache() {
return this.cacheSize_ > this.maxCacheSize_;
}
expire() {
if (this.canExpireCache()) {
let i = 0;
for (const key in this.cache_) {
const iconImage = this.cache_[key];
if ((i++ & 3) === 0 && !iconImage.hasListener()) {
delete this.cache_[key];
delete this.patternCache_[key];
--this.cacheSize_;
}
}
}
}
get(src, crossOrigin, color) {
const key = getCacheKey(src, crossOrigin, color);
return key in this.cache_ ? this.cache_[key] : null;
}
getPattern(src, crossOrigin, color) {
const key = getCacheKey(src, crossOrigin, color);
return key in this.patternCache_ ? this.patternCache_[key] : null;
}
set(src, crossOrigin, color, iconImage, pattern) {
const key = getCacheKey(src, crossOrigin, color);
const update = key in this.cache_;
this.cache_[key] = iconImage;
if (pattern) {
if (iconImage.getImageState() === ImageState.IDLE) {
iconImage.load();
}
if (iconImage.getImageState() === ImageState.LOADING) {
iconImage.ready().then(() => {
this.patternCache_[key] = getSharedCanvasContext2D().createPattern(
iconImage.getImage(1),
"repeat"
);
});
} else {
this.patternCache_[key] = getSharedCanvasContext2D().createPattern(
iconImage.getImage(1),
"repeat"
);
}
}
if (!update) {
++this.cacheSize_;
}
}
setSize(maxCacheSize) {
this.maxCacheSize_ = maxCacheSize;
this.expire();
}
}
function getCacheKey(src, crossOrigin, color) {
const colorString = color ? asArray(color) : "null";
return crossOrigin + ":" + src + ":" + colorString;
}
const shared = new IconImageCache();
let taintedTestContext = null;
class IconImage extends EventTarget {
constructor(image, src, crossOrigin, imageState, color) {
super();
this.hitDetectionImage_ = null;
this.image_ = image;
this.crossOrigin_ = crossOrigin;
this.canvas_ = {};
this.color_ = color;
this.imageState_ = imageState === void 0 ? ImageState.IDLE : imageState;
this.size_ = image && image.width && image.height ? [image.width, image.height] : null;
this.src_ = src;
this.tainted_;
this.ready_ = null;
}
initializeImage_() {
this.image_ = new Image();
if (this.crossOrigin_ !== null) {
this.image_.crossOrigin = this.crossOrigin_;
}
}
isTainted_() {
if (this.tainted_ === void 0 && this.imageState_ === ImageState.LOADED) {
if (!taintedTestContext) {
taintedTestContext = createCanvasContext2D(1, 1, void 0, {
willReadFrequently: true
});
}
taintedTestContext.drawImage(this.image_, 0, 0);
try {
taintedTestContext.getImageData(0, 0, 1, 1);
this.tainted_ = false;
} catch {
taintedTestContext = null;
this.tainted_ = true;
}
}
return this.tainted_ === true;
}
dispatchChangeEvent_() {
this.dispatchEvent(EventType.CHANGE);
}
handleImageError_() {
this.imageState_ = ImageState.ERROR;
this.dispatchChangeEvent_();
}
handleImageLoad_() {
this.imageState_ = ImageState.LOADED;
this.size_ = [this.image_.width, this.image_.height];
this.dispatchChangeEvent_();
}
getImage(pixelRatio) {
if (!this.image_) {
this.initializeImage_();
}
this.replaceColor_(pixelRatio);
return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;
}
getPixelRatio(pixelRatio) {
this.replaceColor_(pixelRatio);
return this.canvas_[pixelRatio] ? pixelRatio : 1;
}
getImageState() {
return this.imageState_;
}
getHitDetectionImage() {
if (!this.image_) {
this.initializeImage_();
}
if (!this.hitDetectionImage_) {
if (this.isTainted_()) {
const width = this.size_[0];
const height = this.size_[1];
const context = createCanvasContext2D(width, height);
context.fillRect(0, 0, width, height);
this.hitDetectionImage_ = context.canvas;
} else {
this.hitDetectionImage_ = this.image_;
}
}
return this.hitDetectionImage_;
}
getSize() {
return this.size_;
}
getSrc() {
return this.src_;
}
load() {
if (this.imageState_ !== ImageState.IDLE) {
return;
}
if (!this.image_) {
this.initializeImage_();
}
this.imageState_ = ImageState.LOADING;
try {
if (this.src_ !== void 0) {
this.image_.src = this.src_;
}
} catch {
this.handleImageError_();
}
if (this.image_ instanceof HTMLImageElement) {
decodeFallback(this.image_, this.src_).then((image) => {
this.image_ = image;
this.handleImageLoad_();
}).catch(this.handleImageError_.bind(this));
}
}
replaceColor_(pixelRatio) {
if (!this.color_ || this.canvas_[pixelRatio] || this.imageState_ !== ImageState.LOADED) {
return;
}
const image = this.image_;
const ctx = createCanvasContext2D(
Math.ceil(image.width * pixelRatio),
Math.ceil(image.height * pixelRatio)
);
const canvas = ctx.canvas;
ctx.scale(pixelRatio, pixelRatio);
ctx.drawImage(image, 0, 0);
ctx.globalCompositeOperation = "multiply";
ctx.fillStyle = asString(this.color_);
ctx.fillRect(0, 0, canvas.width / pixelRatio, canvas.height / pixelRatio);
ctx.globalCompositeOperation = "destination-in";
ctx.drawImage(image, 0, 0);
this.canvas_[pixelRatio] = canvas;
}
ready() {
if (!this.ready_) {
this.ready_ = new Promise((resolve) => {
if (this.imageState_ === ImageState.LOADED || this.imageState_ === ImageState.ERROR) {
resolve();
} else {
const onChange = () => {
if (this.imageState_ === ImageState.LOADED || this.imageState_ === ImageState.ERROR) {
this.removeEventListener(EventType.CHANGE, onChange);
resolve();
}
};
this.addEventListener(EventType.CHANGE, onChange);
}
});
}
return this.ready_;
}
}
function get(image, cacheKey, crossOrigin, imageState, color, pattern) {
let iconImage = cacheKey === void 0 ? void 0 : shared.get(cacheKey, crossOrigin, color);
if (!iconImage) {
iconImage = new IconImage(
image,
image && "src" in image ? image.src || void 0 : cacheKey,
crossOrigin,
imageState,
color
);
shared.set(cacheKey, crossOrigin, color, iconImage, pattern);
}
if (pattern && iconImage && !shared.getPattern(cacheKey, crossOrigin, color)) {
shared.set(cacheKey, crossOrigin, color, iconImage, pattern);
}
return iconImage;
}
function asColorLike(color) {
if (!color) {
return null;
}
if (Array.isArray(color)) {
return toString(color);
}
if (typeof color === "object" && "src" in color) {
return asCanvasPattern(color);
}
return color;
}
function asCanvasPattern(pattern) {
if (!pattern.offset || !pattern.size) {
return shared.getPattern(pattern.src, "anonymous", pattern.color);
}
const cacheKey = pattern.src + ":" + pattern.offset;
const canvasPattern = shared.getPattern(
cacheKey,
void 0,
pattern.color
);
if (canvasPattern) {
return canvasPattern;
}
const iconImage = shared.get(pattern.src, "anonymous", null);
if (iconImage.getImageState() !== ImageState.LOADED) {
return null;
}
const patternCanvasContext = createCanvasContext2D(
pattern.size[0],
pattern.size[1]
);
patternCanvasContext.drawImage(
iconImage.getImage(1),
pattern.offset[0],
pattern.offset[1],
pattern.size[0],
pattern.size[1],
0,
0,
pattern.size[0],
pattern.size[1]
);
get(
patternCanvasContext.canvas,
cacheKey,
void 0,
ImageState.LOADED,
pattern.color,
true
);
return shared.getPattern(cacheKey, void 0, pattern.color);
}
class VectorContext {
drawCustom(geometry, feature2, renderer, hitDetectionRenderer, index2) {
}
drawGeometry(geometry) {
}
setStyle(style) {
}
drawCircle(circleGeometry, feature2, index2) {
}
drawFeature(feature2, style, index2) {
}
drawGeometryCollection(geometryCollectionGeometry, feature2, index2) {
}
drawLineString(lineStringGeometry, feature2, index2) {
}
drawMultiLineString(multiLineStringGeometry, feature2, index2) {
}
drawMultiPoint(multiPointGeometry, feature2, index2) {
}
drawMultiPolygon(multiPolygonGeometry, feature2, index2) {
}
drawPoint(pointGeometry, feature2, index2) {
}
drawPolygon(polygonGeometry, feature2, index2) {
}
drawText(geometry, feature2, index2) {
}
setFillStrokeStyle(fillStyle, strokeStyle) {
}
setImageStyle(imageStyle, declutterImageWithText) {
}
setTextStyle(textStyle, declutterImageWithText) {
}
}
const VectorContext$1 = VectorContext;
const CLASS_HIDDEN = "ol-hidden";
const CLASS_UNSELECTABLE = "ol-unselectable";
const CLASS_CONTROL = "ol-control";
const CLASS_COLLAPSED = "ol-collapsed";
const fontRegEx = new RegExp(
[
"^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)",
"(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)",
"(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)",
"(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?",
"(?:small|large)|medium|smaller|larger|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))",
"(?:\\s*\\/\\s*(normal|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])?))",
`?\\s*([-,\\"\\'\\sa-z0-9]+?)\\s*$`
].join(""),
"i"
);
const fontRegExMatchIndex = [
"style",
"variant",
"weight",
"size",
"lineHeight",
"family"
];
const fontWeights = {
normal: 400,
bold: 700
};
const getFontParameters = function(fontSpec) {
const match = fontSpec.match(fontRegEx);
if (!match) {
return null;
}
const style = {
lineHeight: "normal",
size: "1.2em",
style: "normal",
weight: "400",
variant: "normal"
};
for (let i = 0, ii = fontRegExMatchIndex.length; i < ii; ++i) {
const value = match[i + 1];
if (value !== void 0) {
style[fontRegExMatchIndex[i]] = typeof value === "string" ? value.trim() : value;
}
}
if (isNaN(Number(style.weight)) && style.weight in fontWeights) {
style.weight = fontWeights[style.weight];
}
style.families = style.family.split(/,\s?/).map((f) => f.trim().replace(/^['"]|['"]$/g, ""));
return style;
};
const defaultFont = "10px sans-serif";
const defaultFillStyle = "#000";
const defaultLineCap = "round";
const defaultLineDash = [];
const defaultLineDashOffset = 0;
const defaultLineJoin = "round";
const defaultMiterLimit = 10;
const defaultStrokeStyle = "#000";
const defaultTextAlign = "center";
const defaultTextBaseline = "middle";
const defaultPadding = [0, 0, 0, 0];
const defaultLineWidth = 1;
const checkedFonts = new BaseObject$1();
let measureContext = null;
let measureFont;
const textHeights = {};
const genericFontFamilies = /* @__PURE__ */ new Set([
"serif",
"sans-serif",
"monospace",
"cursive",
"fantasy",
"system-ui",
"ui-serif",
"ui-sans-serif",
"ui-monospace",
"ui-rounded",
"emoji",
"math",
"fangsong"
]);
function getFontKey(style, weight, family) {
return `${style} ${weight} 16px "${family}"`;
}
const registerFont = function() {
const retries = 100;
let timeout, fontFaceSet;
async function isAvailable(fontSpec) {
await fontFaceSet.ready;
const fontFaces = await fontFaceSet.load(fontSpec);
if (fontFaces.length === 0) {
return false;
}
const font = getFontParameters(fontSpec);
const checkFamily = font.families[0].toLowerCase();
const checkWeight = font.weight;
return fontFaces.some(
(f) => {
const family = f.family.replace(/^['"]|['"]$/g, "").toLowerCase();
const weight = fontWeights[f.weight] || f.weight;
return family === checkFamily && f.style === font.style && weight == checkWeight;
}
);
}
async function check() {
await fontFaceSet.ready;
let done = true;
const checkedFontsProperties = checkedFonts.getProperties();
const fonts = Object.keys(checkedFontsProperties).filter(
(key) => checkedFontsProperties[key] < retries
);
for (let i = fonts.length - 1; i >= 0; --i) {
const font = fonts[i];
let currentRetries = checkedFontsProperties[font];
if (currentRetries < retries) {
if (await isAvailable(font)) {
clear(textHeights);
checkedFonts.set(font, retries);
} else {
currentRetries += 10;
checkedFonts.set(font, currentRetries, true);
if (currentRetries < retries) {
done = false;
}
}
}
}
timeout = void 0;
if (!done) {
timeout = setTimeout(check, 100);
}
}
return async function(fontSpec) {
if (!fontFaceSet) {
fontFaceSet = WORKER_OFFSCREEN_CANVAS ? self.fonts : document.fonts;
}
const font = getFontParameters(fontSpec);
if (!font) {
return;
}
const families = font.families;
let needCheck = false;
for (const family of families) {
if (genericFontFamilies.has(family)) {
continue;
}
const key = getFontKey(font.style, font.weight, family);
if (checkedFonts.get(key) !== void 0) {
continue;
}
checkedFonts.set(key, 0, true);
needCheck = true;
}
if (needCheck) {
clearTimeout(timeout);
timeout = setTimeout(check, 100);
}
};
}();
const measureTextHeight = function() {
let measureElement;
return function(fontSpec) {
let height = textHeights[fontSpec];
if (height == void 0) {
if (WORKER_OFFSCREEN_CANVAS) {
const font = getFontParameters(fontSpec);
const metrics = measureText(fontSpec, "\u017Dg");
const lineHeight = isNaN(Number(font.lineHeight)) ? 1.2 : Number(font.lineHeight);
height = lineHeight * (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);
} else {
if (!measureElement) {
measureElement = document.createElement("div");
measureElement.innerHTML = "M";
measureElement.style.minHeight = "0";
measureElement.style.maxHeight = "none";
measureElement.style.height = "auto";
measureElement.style.padding = "0";
measureElement.style.border = "none";
measureElement.style.position = "absolute";
measureElement.style.display = "block";
measureElement.style.left = "-99999px";
}
measureElement.style.font = fontSpec;
document.body.appendChild(measureElement);
height = measureElement.offsetHeight;
document.body.removeChild(measureElement);
}
textHeights[fontSpec] = height;
}
return height;
};
}();
function measureText(font, text) {
if (!measureContext) {
measureContext = createCanvasContext2D(1, 1);
}
if (font != measureFont) {
measureContext.font = font;
measureFont = measureContext.font;
}
return measureContext.measureText(text);
}
function measureTextWidth(font, text) {
return measureText(font, text).width;
}
function measureAndCacheTextWidth(font, text, cache2) {
if (text in cache2) {
return cache2[text];
}
const width = text.split("\n").reduce((prev, curr) => Math.max(prev, measureTextWidth(font, curr)), 0);
cache2[text] = width;
return width;
}
function getTextDimensions(baseStyle, chunks) {
const widths = [];
const heights = [];
const lineWidths = [];
let width = 0;
let lineWidth = 0;
let height = 0;
let lineHeight = 0;
for (let i = 0, ii = chunks.length; i <= ii; i += 2) {
const text = chunks[i];
if (text === "\n" || i === ii) {
width = Math.max(width, lineWidth);
lineWidths.push(lineWidth);
lineWidth = 0;
height += lineHeight;
lineHeight = 0;
continue;
}
const font = chunks[i + 1] || baseStyle.font;
const currentWidth = measureTextWidth(font, text);
widths.push(currentWidth);
lineWidth += currentWidth;
const currentHeight = measureTextHeight(font);
heights.push(currentHeight);
lineHeight = Math.max(lineHeight, currentHeight);
}
return { width, height, widths, heights, lineWidths };
}
function drawImageOrLabel(context, transform, opacity, labelOrImage, originX, originY, w, h, x, y, scale2) {
context.save();
if (opacity !== 1) {
if (context.globalAlpha === void 0) {
context.globalAlpha = (context2) => context2.globalAlpha *= opacity;
} else {
context.globalAlpha *= opacity;
}
}
if (transform) {
context.transform.apply(context, transform);
}
if (labelOrImage.contextInstructions) {
context.translate(x, y);
context.scale(scale2[0], scale2[1]);
executeLabelInstructions(labelOrImage, context);
} else if (scale2[0] < 0 || scale2[1] < 0) {
context.translate(x, y);
context.scale(scale2[0], scale2[1]);
context.drawImage(
labelOrImage,
originX,
originY,
w,
h,
0,
0,
w,
h
);
} else {
context.drawImage(
labelOrImage,
originX,
originY,
w,
h,
x,
y,
w * scale2[0],
h * scale2[1]
);
}
context.restore();
}
function executeLabelInstructions(label, context) {
const contextInstructions = label.contextInstructions;
for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
if (Array.isArray(contextInstructions[i + 1])) {
context[contextInstructions[i]].apply(
context,
contextInstructions[i + 1]
);
} else {
context[contextInstructions[i]] = contextInstructions[i + 1];
}
}
}
const 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
};
const fillInstruction = [Instruction.FILL];
const strokeInstruction = [Instruction.STROKE];
const beginPathInstruction = [Instruction.BEGIN_PATH];
const closePathInstruction = [Instruction.CLOSE_PATH];
const CanvasInstruction = Instruction;
class CanvasBuilder extends VectorContext$1 {
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 = {};
}
applyPixelRatio(dashArray) {
const pixelRatio = this.pixelRatio;
return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) {
return dash * pixelRatio;
});
}
appendFlatPointCoordinates(flatCoordinates, stride) {
const extent = this.getBufferedMaxExtent();
const tmpCoord = this.tmpCoordinate_;
const coordinates2 = this.coordinates;
let myEnd = coordinates2.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)) {
coordinates2[myEnd++] = tmpCoord[0];
coordinates2[myEnd++] = tmpCoord[1];
}
}
return myEnd;
}
appendFlatLineCoordinates(flatCoordinates, offset, end, stride, closed, skipFirst) {
const coordinates2 = this.coordinates;
let myEnd = coordinates2.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) {
coordinates2[myEnd++] = lastXCoord;
coordinates2[myEnd++] = lastYCoord;
skipped = false;
}
coordinates2[myEnd++] = nextCoord[0];
coordinates2[myEnd++] = nextCoord[1];
} else if (nextRel === Relationship.INTERSECTING) {
coordinates2[myEnd++] = nextCoord[0];
coordinates2[myEnd++] = nextCoord[1];
skipped = false;
} else {
skipped = true;
}
lastXCoord = nextCoord[0];
lastYCoord = nextCoord[1];
lastRel = nextRel;
}
if (closed && skipped || i === offset + stride) {
coordinates2[myEnd++] = lastXCoord;
coordinates2[myEnd++] = lastYCoord;
}
return myEnd;
}
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;
}
drawCustom(geometry, feature2, renderer, hitDetectionRenderer, index2) {
this.beginGeometry(geometry, feature2, index2);
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 = geometry.getOrientedFlatCoordinates();
builderEndss = [];
const endss = 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([
CanvasInstruction.CUSTOM,
builderBegin,
builderEndss,
geometry,
renderer,
inflateMultiCoordinatesArray,
index2
]);
this.hitDetectionInstructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEndss,
geometry,
hitDetectionRenderer || renderer,
inflateMultiCoordinatesArray,
index2
]);
break;
case "Polygon":
case "MultiLineString":
builderEnds = [];
flatCoordinates = type == "Polygon" ? geometry.getOrientedFlatCoordinates() : geometry.getFlatCoordinates();
offset = this.drawCustomCoordinates_(
flatCoordinates,
0,
geometry.getEnds(),
stride,
builderEnds
);
this.instructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnds,
geometry,
renderer,
inflateCoordinatesArray,
index2
]);
this.hitDetectionInstructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnds,
geometry,
hitDetectionRenderer || renderer,
inflateCoordinatesArray,
index2
]);
break;
case "LineString":
case "Circle":
flatCoordinates = geometry.getFlatCoordinates();
builderEnd = this.appendFlatLineCoordinates(
flatCoordinates,
0,
flatCoordinates.length,
stride,
false,
false
);
this.instructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
renderer,
inflateCoordinates,
index2
]);
this.hitDetectionInstructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
hitDetectionRenderer || renderer,
inflateCoordinates,
index2
]);
break;
case "MultiPoint":
flatCoordinates = geometry.getFlatCoordinates();
builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
if (builderEnd > builderBegin) {
this.instructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
renderer,
inflateCoordinates,
index2
]);
this.hitDetectionInstructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
hitDetectionRenderer || renderer,
inflateCoordinates,
index2
]);
}
break;
case "Point":
flatCoordinates = geometry.getFlatCoordinates();
this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);
builderEnd = this.coordinates.length;
this.instructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
renderer,
void 0,
index2
]);
this.hitDetectionInstructions.push([
CanvasInstruction.CUSTOM,
builderBegin,
builderEnd,
geometry,
hitDetectionRenderer || renderer,
void 0,
index2
]);
break;
}
this.endGeometry(feature2);
}
beginGeometry(geometry, feature2, index2) {
this.beginGeometryInstruction1_ = [
CanvasInstruction.BEGIN_GEOMETRY,
feature2,
0,
geometry,
index2
];
this.instructions.push(this.beginGeometryInstruction1_);
this.beginGeometryInstruction2_ = [
CanvasInstruction.BEGIN_GEOMETRY,
feature2,
0,
geometry,
index2
];
this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);
}
finish() {
return {
instructions: this.instructions,
hitDetectionInstructions: this.hitDetectionInstructions,
coordinates: this.coordinates
};
}
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 = instruction[0];
if (type == CanvasInstruction.END_GEOMETRY) {
begin = i;
} else if (type == CanvasInstruction.BEGIN_GEOMETRY) {
instruction[2] = i;
reverseSubArray(this.hitDetectionInstructions, begin, i);
begin = -1;
}
}
}
fillStyleToState(fillStyle, state = {}) {
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;
}
strokeStyleToState(strokeStyle, state = {}) {
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;
}
setFillStrokeStyle(fillStyle, strokeStyle) {
const state = this.state;
this.fillStyleToState(fillStyle, state);
this.strokeStyleToState(strokeStyle, state);
}
createFill(state) {
const fillStyle = state.fillStyle;
const fillInstruction2 = [CanvasInstruction.SET_FILL_STYLE, fillStyle];
if (typeof fillStyle !== "string") {
fillInstruction2.push(state.fillPatternScale);
}
return fillInstruction2;
}
applyStroke(state) {
this.instructions.push(this.createStroke(state));
}
createStroke(state) {
return [
CanvasInstruction.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
];
}
updateFillStyle(state, createFill) {
const fillStyle = state.fillStyle;
if (typeof fillStyle !== "string" || state.currentFillStyle != fillStyle) {
this.instructions.push(createFill.call(this, state));
state.currentFillStyle = fillStyle;
}
}
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$2(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;
}
}
endGeometry(feature2) {
this.beginGeometryInstruction1_[2] = this.instructions.length;
this.beginGeometryInstruction1_ = null;
this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;
this.beginGeometryInstruction2_ = null;
const endGeometryInstruction = [CanvasInstruction.END_GEOMETRY, feature2];
this.instructions.push(endGeometryInstruction);
this.hitDetectionInstructions.push(endGeometryInstruction);
}
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_;
}
}
const Builder = CanvasBuilder;
class CanvasImageBuilder extends Builder {
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;
}
drawPoint(pointGeometry, feature2, index2) {
if (!this.image_ || this.maxExtent && !containsCoordinate(this.maxExtent, pointGeometry.getFlatCoordinates())) {
return;
}
this.beginGeometry(pointGeometry, feature2, index2);
const flatCoordinates = pointGeometry.getFlatCoordinates();
const stride = pointGeometry.getStride();
const myBegin = this.coordinates.length;
const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
this.instructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.image_,
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([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.hitDetectionImage_,
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(feature2);
}
drawMultiPoint(multiPointGeometry, feature2, index2) {
if (!this.image_) {
return;
}
this.beginGeometry(multiPointGeometry, feature2, index2);
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([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.image_,
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([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.hitDetectionImage_,
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(feature2);
}
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();
}
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;
}
}
const ImageBuilder = CanvasImageBuilder;
class CanvasLineStringBuilder extends Builder {
constructor(tolerance, maxExtent, resolution, pixelRatio) {
super(tolerance, maxExtent, resolution, pixelRatio);
}
drawFlatCoordinates_(flatCoordinates, offset, end, stride) {
const myBegin = this.coordinates.length;
const myEnd = this.appendFlatLineCoordinates(
flatCoordinates,
offset,
end,
stride,
false,
false
);
const moveToLineToInstruction = [
CanvasInstruction.MOVE_TO_LINE_TO,
myBegin,
myEnd
];
this.instructions.push(moveToLineToInstruction);
this.hitDetectionInstructions.push(moveToLineToInstruction);
return end;
}
drawLineString(lineStringGeometry, feature2, index2) {
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, feature2, index2);
this.hitDetectionInstructions.push(
[
CanvasInstruction.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(feature2);
}
drawMultiLineString(multiLineStringGeometry, feature2, index2) {
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, feature2, index2);
this.hitDetectionInstructions.push(
[
CanvasInstruction.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,
ends[i],
stride
);
}
this.hitDetectionInstructions.push(strokeInstruction);
this.endGeometry(feature2);
}
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();
}
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);
}
}
const LineStringBuilder = CanvasLineStringBuilder;
class CanvasPolygonBuilder extends Builder {
constructor(tolerance, maxExtent, resolution, pixelRatio) {
super(tolerance, maxExtent, resolution, pixelRatio);
}
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 = [
CanvasInstruction.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;
}
drawCircle(circleGeometry, feature2, index2) {
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, feature2, index2);
if (state.fillStyle !== void 0) {
this.hitDetectionInstructions.push([
CanvasInstruction.SET_FILL_STYLE,
defaultFillStyle
]);
}
if (state.strokeStyle !== void 0) {
this.hitDetectionInstructions.push([
CanvasInstruction.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 = [CanvasInstruction.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(feature2);
}
drawPolygon(polygonGeometry, feature2, index2) {
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, feature2, index2);
if (state.fillStyle !== void 0) {
this.hitDetectionInstructions.push([
CanvasInstruction.SET_FILL_STYLE,
defaultFillStyle
]);
}
if (state.strokeStyle !== void 0) {
this.hitDetectionInstructions.push([
CanvasInstruction.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,
ends,
stride
);
this.endGeometry(feature2);
}
drawMultiPolygon(multiPolygonGeometry, feature2, index2) {
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, feature2, index2);
if (state.fillStyle !== void 0) {
this.hitDetectionInstructions.push([
CanvasInstruction.SET_FILL_STYLE,
defaultFillStyle
]);
}
if (state.strokeStyle !== void 0) {
this.hitDetectionInstructions.push([
CanvasInstruction.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(feature2);
}
finish() {
this.reverseHitDetectionInstructions();
this.state = null;
const tolerance = this.tolerance;
if (tolerance !== 0) {
const coordinates2 = this.coordinates;
for (let i = 0, ii = coordinates2.length; i < ii; ++i) {
coordinates2[i] = snap(coordinates2[i], tolerance);
}
}
return super.finish();
}
setFillStrokeStyles_() {
const state = this.state;
this.updateFillStyle(state, this.createFill);
this.updateStrokeStyle(state, this.applyStroke);
}
}
const PolygonBuilder = CanvasPolygonBuilder;
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;
}
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];
}
const 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
};
class CanvasTextBuilder extends Builder {
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_ = {};
this.textStates = {};
this.textKey_ = "";
this.fillKey_ = "";
this.strokeKey_ = "";
this.declutterMode_ = void 0;
this.declutterImageWithText_ = void 0;
}
finish() {
const instructions = super.finish();
instructions.textStates = this.textStates;
instructions.fillStates = this.fillStates;
instructions.strokeStates = this.strokeStates;
return instructions;
}
drawText(geometry, feature2, index2) {
const fillState = this.textFillState_;
const strokeState = this.textStrokeState_;
const textState = this.textState_;
if (this.text_ === "" || !textState || !fillState && !strokeState) {
return;
}
const coordinates2 = this.coordinates;
let begin = coordinates2.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$1(this.maxExtent, geometry.getExtent())) {
return;
}
let ends;
flatCoordinates = geometry.getFlatCoordinates();
if (geometryType == "LineString") {
ends = [flatCoordinates.length];
} else if (geometryType == "MultiLineString") {
ends = geometry.getEnds();
} else if (geometryType == "Polygon") {
ends = geometry.getEnds().slice(0, 1);
} else if (geometryType == "MultiPolygon") {
const endss = geometry.getEndss();
ends = [];
for (let i = 0, ii = endss.length; i < ii; ++i) {
ends.push(endss[i][0]);
}
}
this.beginGeometry(geometry, feature2, index2);
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) {
coordinates2.push(chunk[i], chunk[i + 1]);
}
const end = coordinates2.length;
flatOffset = ends[o];
this.drawChars_(begin, end);
begin = end;
}
}
this.endGeometry(feature2);
} else {
let geometryWidths = textState.overflow ? null : [];
switch (geometryType) {
case "Point":
case "MultiPoint":
flatCoordinates = geometry.getFlatCoordinates();
break;
case "LineString":
flatCoordinates = geometry.getFlatMidpoint();
break;
case "Circle":
flatCoordinates = geometry.getCenter();
break;
case "MultiLineString":
flatCoordinates = geometry.getFlatMidpoints();
stride = 2;
break;
case "Polygon":
flatCoordinates = geometry.getFlatInteriorPoint();
if (!textState.overflow) {
geometryWidths.push(flatCoordinates[2] / this.resolution);
}
stride = 3;
break;
case "MultiPolygon":
const interiorPoints = 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;
}
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 = coordinates2[(beg + i) * 2] === flatCoordinates[i * stride] && coordinates2[(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, feature2, index2);
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([
CanvasInstruction.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 scale2 = 1 / pixelRatio;
const hitDetectionBackgroundFill = backgroundFill ? backgroundFill.slice(0) : null;
if (hitDetectionBackgroundFill) {
hitDetectionBackgroundFill[1] = defaultFillStyle;
}
this.hitDetectionInstructions.push([
CanvasInstruction.DRAW_IMAGE,
begin,
end,
null,
NaN,
NaN,
NaN,
1,
0,
0,
this.textRotateWithView_,
this.textRotation_,
[scale2, scale2],
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(feature2);
}
}
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
};
}
}
}
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([
CanvasInstruction.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([
CanvasInstruction.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_
]);
}
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 = {};
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 = {};
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;
}
}
const BATCH_CONSTRUCTORS = {
"Circle": PolygonBuilder,
"Default": Builder,
"Image": ImageBuilder,
"LineString": LineStringBuilder,
"Polygon": PolygonBuilder,
"Text": CanvasTextBuilder
};
class BuilderGroup {
constructor(tolerance, maxExtent, resolution, pixelRatio) {
this.tolerance_ = tolerance;
this.maxExtent_ = maxExtent;
this.pixelRatio_ = pixelRatio;
this.resolution_ = resolution;
this.buildersByZIndex_ = {};
}
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;
}
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;
}
}
const CanvasBuilderGroup = BuilderGroup;
function drawTextOnPath(flatCoordinates, offset, end, stride, text, startM, maxAngle, scale2, measureAndCacheTextWidth2, font, cache2, 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 + scale2 * measureAndCacheTextWidth2(font, text, cache2);
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 PI2 = 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 ? -PI2 : PI2;
}
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 ? -PI2 : PI2;
}
if (previousAngle !== void 0) {
let delta = angle - previousAngle;
delta += delta > PI2 ? -2 * PI2 : delta < -PI2 ? 2 * PI2 : 0;
if (Math.abs(delta) > maxAngle) {
return null;
}
}
previousAngle = angle;
const iStart = i;
let charLength = 0;
for (; i < ii; ++i) {
const index2 = reverse ? ii - i - 1 : i;
const len = scale2 * measureAndCacheTextWidth2(font, text[index2], cache2);
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;
}
class ZIndexContext {
constructor() {
__publicField(this, "pushMethodArgs_", (...args) => {
this.push_(args);
return this;
});
this.instructions_ = [];
this.zIndex = 0;
this.offset_ = 0;
this.context_ = new Proxy(getSharedCanvasContext2D(), {
get: (target, property) => {
if (typeof getSharedCanvasContext2D()[property] !== "function") {
return void 0;
}
this.push_(property);
return this.pushMethodArgs_;
},
set: (target, property, value) => {
this.push_(property, value);
return true;
}
});
}
push_(...args) {
const instructions = this.instructions_;
const index2 = this.zIndex + this.offset_;
if (!instructions[index2]) {
instructions[index2] = [];
}
instructions[index2].push(...args);
}
pushFunction(render2) {
this.push_(render2);
}
getContext() {
return this.context_;
}
draw(context) {
this.instructions_.forEach((instructionsAtIndex) => {
for (let i = 0, ii = instructionsAtIndex.length; i < ii; ++i) {
const property = instructionsAtIndex[i];
if (typeof property === "function") {
property(context);
continue;
}
const instructionAtIndex = instructionsAtIndex[++i];
if (typeof context[property] === "function") {
context[property](...instructionAtIndex);
} else {
if (typeof instructionAtIndex === "function") {
context[property] = instructionAtIndex(context);
continue;
}
context[property] = instructionAtIndex;
}
}
});
}
clear() {
this.instructions_.length = 0;
this.zIndex = 0;
this.offset_ = 0;
}
offset() {
this.offset_ = this.instructions_.length;
this.zIndex = 0;
}
}
const ZIndexContext$1 = ZIndexContext;
const tmpExtent = createEmpty();
const p1 = [];
const p2 = [];
const p3 = [];
const p4 = [];
function getDeclutterBox(replayImageOrLabelArgs) {
return replayImageOrLabelArgs[3].declutterBox;
}
const rtlRegEx = new RegExp(
"[" + 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) + "]"
);
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, index2) {
if (index2 % 2 === 0) {
result += part;
}
return result;
}
class Executor {
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$1() : null;
}
getZIndexContext() {
return this.zIndexContext_;
}
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 scale2 = [
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) * scale2[0];
const h = (height + strokeWidth) * scale2[1];
const label = {
width: w < 0 ? Math.floor(w) : Math.ceil(w),
height: h < 0 ? Math.floor(h) : Math.ceil(h),
contextInstructions
};
if (scale2[0] != 1 || scale2[1] != 1) {
contextInstructions.push("scale", scale2);
}
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;
}
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_ = fillInstruction2[2];
context.fillStyle = fillInstruction2[1];
this.fill_(context);
}
if (strokeInstruction2) {
this.setStrokeStyle_(
context,
strokeInstruction2
);
context.stroke();
}
}
calculateImageOrLabelDimensions_(sheetWidth, sheetHeight, centerX, centerY, width, height, anchorX, anchorY, originX, originY, rotation, scale2, snapToPixel, padding, fillStroke, feature2) {
anchorX *= scale2[0];
anchorY *= scale2[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 * scale2[0] + padding[1];
const boxH = padding[0] + h * scale2[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: feature2
},
canvasTransform: transform,
scale: scale2
};
}
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,
fillInstruction2,
strokeInstruction2
);
}
drawImageOrLabel(
context,
dimensions.canvasTransform,
opacity,
imageOrLabel,
dimensions.originX,
dimensions.originY,
dimensions.drawImageW,
dimensions.drawImageH,
dimensions.drawImageX,
dimensions.drawImageY,
dimensions.scale
);
}
return true;
}
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();
}
}
setStrokeStyle_(context, instruction) {
context.strokeStyle = instruction[1];
if (!instruction[1]) {
return;
}
context.lineWidth = instruction[2];
context.lineCap = instruction[3];
context.lineJoin = instruction[4];
context.miterLimit = instruction[5];
context.lineDashOffset = instruction[7];
context.setLineDash(instruction[6]);
}
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
};
}
execute_(context, scaledCanvasSize, transform, instructions, snapToPixel, featureCallback, hitExtent, declutterTree) {
const zIndexContext = this.zIndexContext_;
let pixelCoordinates;
if (this.pixelCoordinates_ && equals$2(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 = {
context,
pixelRatio: this.pixelRatio,
resolution: this.resolution,
rotation: viewRotation
};
const batchSize = this.instructions != instructions || this.overlaps ? 0 : 200;
let feature2;
let x, y, currentGeometry;
while (i < ii) {
const instruction = instructions[i];
const type = instruction[0];
switch (type) {
case CanvasInstruction.BEGIN_GEOMETRY:
feature2 = instruction[1];
currentGeometry = instruction[3];
if (!feature2.getGeometry()) {
i = instruction[2];
} else if (hitExtent !== void 0 && !intersects$1(hitExtent, currentGeometry.getExtent())) {
i = instruction[2] + 1;
} else {
++i;
}
if (zIndexContext) {
zIndexContext.zIndex = instruction[4];
}
break;
case CanvasInstruction.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 CanvasInstruction.CIRCLE:
d = 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 CanvasInstruction.CLOSE_PATH:
context.closePath();
++i;
break;
case CanvasInstruction.CUSTOM:
d = instruction[1];
dd = instruction[2];
const geometry = instruction[3];
const renderer = instruction[4];
const fn = instruction[5];
state.geometry = geometry;
state.feature = feature2;
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 CanvasInstruction.DRAW_IMAGE:
d = instruction[1];
dd = instruction[2];
image = instruction[3];
anchorX = instruction[4];
anchorY = instruction[5];
let height = instruction[6];
const opacity = instruction[7];
const originX = instruction[8];
const originY = instruction[9];
const rotateWithView = instruction[10];
let rotation = instruction[11];
const scale2 = instruction[12];
let width = instruction[13];
declutterMode = instruction[14] || "declutter";
const declutterImageWithText = instruction[15];
if (!image && instruction.length >= 20) {
text = instruction[19];
textKey = instruction[20];
strokeKey = instruction[21];
fillKey = instruction[22];
const labelWithAnchor = this.drawLabelWithPointPlacement_(
text,
textKey,
strokeKey,
fillKey
);
image = labelWithAnchor.label;
instruction[3] = image;
const textOffsetX = instruction[23];
anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio;
instruction[4] = anchorX;
const textOffsetY = 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 = instruction[25];
}
let padding, backgroundFillInstruction, backgroundStrokeInstruction;
if (instruction.length > 17) {
padding = instruction[16];
backgroundFillInstruction = instruction[17];
backgroundStrokeInstruction = 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,
scale2,
snapToPixel,
padding,
!!backgroundFillInstruction || !!backgroundStrokeInstruction,
feature2
);
const args = [
context,
scaledCanvasSize,
image,
dimensions,
opacity,
backgroundFillInstruction,
backgroundStrokeInstruction
];
if (declutterTree) {
let imageArgs, imageDeclutterMode, imageDeclutterBox;
if (declutterImageWithText) {
const index2 = dd - d;
if (!declutterImageWithText[index2]) {
declutterImageWithText[index2] = { args, declutterMode };
continue;
}
const imageDeclutter = declutterImageWithText[index2];
imageArgs = imageDeclutter.args;
imageDeclutterMode = imageDeclutter.declutterMode;
delete declutterImageWithText[index2];
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 render2 = renderImage && renderText;
renderImage = render2;
renderText = render2;
}
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 CanvasInstruction.DRAW_CHARS:
const begin = instruction[1];
const end = instruction[2];
const baseline = instruction[3];
const overflow = instruction[4];
fillKey = instruction[5];
const maxAngle = instruction[6];
const measurePixelRatio = instruction[7];
const offsetY = instruction[8];
strokeKey = instruction[9];
const strokeWidth = instruction[10];
text = instruction[11];
if (Array.isArray(text)) {
text = text.reduce(richTextToPlainText, "");
}
textKey = instruction[12];
const pixelRatioScale = [
instruction[13],
instruction[13]
];
declutterMode = instruction[14] || "declutter";
const textKeepUpright = 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 = part[4];
label = this.createLabel(chars, textKey, "", strokeKey);
anchorX = 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,
feature2
);
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 = part[4];
label = this.createLabel(chars, textKey, fillKey, "");
anchorX = 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,
feature2
);
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 CanvasInstruction.END_GEOMETRY:
if (featureCallback !== void 0) {
feature2 = instruction[1];
const result = featureCallback(
feature2,
currentGeometry,
declutterMode
);
if (result) {
return result;
}
}
++i;
break;
case CanvasInstruction.FILL:
if (batchSize) {
pendingFill++;
} else {
this.fill_(context);
}
++i;
break;
case CanvasInstruction.MOVE_TO_LINE_TO:
d = instruction[1];
dd = 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 CanvasInstruction.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 CanvasInstruction.SET_STROKE_STYLE:
if (pendingStroke) {
context.stroke();
pendingStroke = 0;
}
this.setStrokeStyle_(context, instruction);
++i;
break;
case CanvasInstruction.STROKE:
if (batchSize) {
pendingStroke++;
} else {
context.stroke();
}
++i;
break;
default:
++i;
break;
}
}
if (pendingFill) {
this.fill_(context);
}
if (pendingStroke) {
context.stroke();
}
return void 0;
}
execute(context, scaledCanvasSize, transform, viewRotation, snapToPixel, declutterTree) {
this.viewRotation_ = viewRotation;
this.execute_(
context,
scaledCanvasSize,
transform,
this.instructions,
snapToPixel,
void 0,
void 0,
declutterTree
);
}
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
);
}
}
const Executor$1 = Executor;
const ALL = [
"Polygon",
"Circle",
"LineString",
"Image",
"Text",
"Default"
];
const DECLUTTER = ["Image", "Text"];
const NON_DECLUTTER = ALL.filter(
(builderType) => !DECLUTTER.includes(builderType)
);
class ExecutorGroup {
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);
}
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();
}
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$1(
this.resolution_,
this.pixelRatio_,
this.overlaps_,
instructions,
deferredRendering
);
}
}
}
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;
}
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(feature2, 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(feature2)) {
const idx = (indexes[i2] - 3) / 4;
const x = hitTolerance - idx % contextSize;
const y = hitTolerance - (idx / contextSize | 0);
const result2 = callback(feature2, 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;
}
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;
}
isEmpty() {
return isEmpty$1(this.executorsByZIndex_);
}
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 index2 = zs[i] * maxBuilderTypes + ALL.indexOf(builderType);
if (!this.deferredZIndexContexts_[index2]) {
this.deferredZIndexContexts_[index2] = [];
}
this.deferredZIndexContexts_[index2].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;
}
}
}
const 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;
}
const ExecutorGroup$1 = ExecutorGroup;
function toSize(size, dest) {
if (Array.isArray(size)) {
return size;
}
if (dest === void 0) {
dest = [size, size];
} else {
dest[0] = size;
dest[1] = size;
}
return dest;
}
class ImageStyle {
constructor(options) {
this.opacity_ = options.opacity;
this.rotateWithView_ = options.rotateWithView;
this.rotation_ = options.rotation;
this.scale_ = options.scale;
this.scaleArray_ = toSize(options.scale);
this.displacement_ = options.displacement;
this.declutterMode_ = options.declutterMode;
}
clone() {
const scale2 = this.getScale();
return new ImageStyle({
opacity: this.getOpacity(),
scale: Array.isArray(scale2) ? scale2.slice() : scale2,
rotation: this.getRotation(),
rotateWithView: this.getRotateWithView(),
displacement: this.getDisplacement().slice(),
declutterMode: this.getDeclutterMode()
});
}
getOpacity() {
return this.opacity_;
}
getRotateWithView() {
return this.rotateWithView_;
}
getRotation() {
return this.rotation_;
}
getScale() {
return this.scale_;
}
getScaleArray() {
return this.scaleArray_;
}
getDisplacement() {
return this.displacement_;
}
getDeclutterMode() {
return this.declutterMode_;
}
getAnchor() {
return abstract();
}
getImage(pixelRatio) {
return abstract();
}
getHitDetectionImage() {
return abstract();
}
getPixelRatio(pixelRatio) {
return 1;
}
getImageState() {
return abstract();
}
getImageSize() {
return abstract();
}
getOrigin() {
return abstract();
}
getSize() {
return abstract();
}
setDisplacement(displacement) {
this.displacement_ = displacement;
}
setOpacity(opacity) {
this.opacity_ = opacity;
}
setRotateWithView(rotateWithView) {
this.rotateWithView_ = rotateWithView;
}
setRotation(rotation) {
this.rotation_ = rotation;
}
setScale(scale2) {
this.scale_ = scale2;
this.scaleArray_ = toSize(scale2);
}
listenImageChange(listener) {
abstract();
}
load() {
abstract();
}
unlistenImageChange(listener) {
abstract();
}
ready() {
return Promise.resolve();
}
}
const ImageStyle$1 = ImageStyle;
class RegularShape extends ImageStyle$1 {
constructor(options) {
super({
opacity: 1,
rotateWithView: options.rotateWithView !== void 0 ? options.rotateWithView : false,
rotation: options.rotation !== void 0 ? options.rotation : 0,
scale: options.scale !== void 0 ? options.scale : 1,
displacement: options.displacement !== void 0 ? options.displacement : [0, 0],
declutterMode: options.declutterMode
});
this.hitDetectionCanvas_ = null;
this.fill_ = options.fill !== void 0 ? options.fill : null;
this.origin_ = [0, 0];
this.points_ = options.points;
this.radius = options.radius;
this.radius2_ = options.radius2;
this.angle_ = options.angle !== void 0 ? options.angle : 0;
this.stroke_ = options.stroke !== void 0 ? options.stroke : null;
this.size_;
this.renderOptions_;
this.imageState_ = this.fill_ && this.fill_.loading() ? ImageState.LOADING : ImageState.LOADED;
if (this.imageState_ === ImageState.LOADING) {
this.ready().then(() => this.imageState_ = ImageState.LOADED);
}
this.render();
}
clone() {
const scale2 = this.getScale();
const style = new RegularShape({
fill: this.getFill() ? this.getFill().clone() : void 0,
points: this.getPoints(),
radius: this.getRadius(),
radius2: this.getRadius2(),
angle: this.getAngle(),
stroke: this.getStroke() ? this.getStroke().clone() : void 0,
rotation: this.getRotation(),
rotateWithView: this.getRotateWithView(),
scale: Array.isArray(scale2) ? scale2.slice() : scale2,
displacement: this.getDisplacement().slice(),
declutterMode: this.getDeclutterMode()
});
style.setOpacity(this.getOpacity());
return style;
}
getAnchor() {
const size = this.size_;
const displacement = this.getDisplacement();
const scale2 = this.getScaleArray();
return [
size[0] / 2 - displacement[0] / scale2[0],
size[1] / 2 + displacement[1] / scale2[1]
];
}
getAngle() {
return this.angle_;
}
getFill() {
return this.fill_;
}
setFill(fill) {
this.fill_ = fill;
this.render();
}
getHitDetectionImage() {
if (!this.hitDetectionCanvas_) {
this.hitDetectionCanvas_ = this.createHitDetectionCanvas_(
this.renderOptions_
);
}
return this.hitDetectionCanvas_;
}
getImage(pixelRatio) {
var _a, _b;
const fillKey = (_a = this.fill_) == null ? void 0 : _a.getKey();
const cacheKey = `${pixelRatio},${this.angle_},${this.radius},${this.radius2_},${this.points_},${fillKey}` + Object.values(this.renderOptions_).join(",");
let image = (_b = shared.get(cacheKey, null, null)) == null ? void 0 : _b.getImage(1);
if (!image) {
const renderOptions = this.renderOptions_;
const size = Math.ceil(renderOptions.size * pixelRatio);
const context = createCanvasContext2D(size, size);
this.draw_(renderOptions, context, pixelRatio);
image = context.canvas;
shared.set(
cacheKey,
null,
null,
new IconImage(image, void 0, null, ImageState.LOADED, null)
);
}
return image;
}
getPixelRatio(pixelRatio) {
return pixelRatio;
}
getImageSize() {
return this.size_;
}
getImageState() {
return this.imageState_;
}
getOrigin() {
return this.origin_;
}
getPoints() {
return this.points_;
}
getRadius() {
return this.radius;
}
getRadius2() {
return this.radius2_;
}
getSize() {
return this.size_;
}
getStroke() {
return this.stroke_;
}
setStroke(stroke) {
this.stroke_ = stroke;
this.render();
}
listenImageChange(listener) {
}
load() {
}
unlistenImageChange(listener) {
}
calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit) {
if (strokeWidth === 0 || this.points_ === Infinity || lineJoin !== "bevel" && lineJoin !== "miter") {
return strokeWidth;
}
let r1 = this.radius;
let r2 = this.radius2_ === void 0 ? r1 : this.radius2_;
if (r1 < r2) {
const tmp = r1;
r1 = r2;
r2 = tmp;
}
const points = this.radius2_ === void 0 ? this.points_ : this.points_ * 2;
const alpha = 2 * Math.PI / points;
const a3 = r2 * Math.sin(alpha);
const b = Math.sqrt(r2 * r2 - a3 * a3);
const d = r1 - b;
const e = Math.sqrt(a3 * a3 + d * d);
const miterRatio = e / a3;
if (lineJoin === "miter" && miterRatio <= miterLimit) {
return miterRatio * strokeWidth;
}
const k = strokeWidth / 2 / miterRatio;
const l = strokeWidth / 2 * (d / e);
const maxr = Math.sqrt((r1 + k) * (r1 + k) + l * l);
const bevelAdd = maxr - r1;
if (this.radius2_ === void 0 || lineJoin === "bevel") {
return bevelAdd * 2;
}
const aa = r1 * Math.sin(alpha);
const bb = Math.sqrt(r1 * r1 - aa * aa);
const dd = r2 - bb;
const ee2 = Math.sqrt(aa * aa + dd * dd);
const innerMiterRatio = ee2 / aa;
if (innerMiterRatio <= miterLimit) {
const innerLength = innerMiterRatio * strokeWidth / 2 - r2 - r1;
return 2 * Math.max(bevelAdd, innerLength);
}
return bevelAdd * 2;
}
createRenderOptions() {
var _a, _b, _c, _d, _e, _f;
let lineCap = defaultLineCap;
let lineJoin = defaultLineJoin;
let miterLimit = 0;
let lineDash = null;
let lineDashOffset = 0;
let strokeStyle;
let strokeWidth = 0;
if (this.stroke_) {
strokeStyle = asColorLike((_a = this.stroke_.getColor()) != null ? _a : defaultStrokeStyle);
strokeWidth = (_b = this.stroke_.getWidth()) != null ? _b : defaultLineWidth;
lineDash = this.stroke_.getLineDash();
lineDashOffset = (_c = this.stroke_.getLineDashOffset()) != null ? _c : 0;
lineJoin = (_d = this.stroke_.getLineJoin()) != null ? _d : defaultLineJoin;
lineCap = (_e = this.stroke_.getLineCap()) != null ? _e : defaultLineCap;
miterLimit = (_f = this.stroke_.getMiterLimit()) != null ? _f : defaultMiterLimit;
}
const add2 = this.calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit);
const maxRadius = Math.max(this.radius, this.radius2_ || 0);
const size = Math.ceil(2 * maxRadius + add2);
return {
strokeStyle,
strokeWidth,
size,
lineCap,
lineDash,
lineDashOffset,
lineJoin,
miterLimit
};
}
render() {
this.renderOptions_ = this.createRenderOptions();
const size = this.renderOptions_.size;
this.hitDetectionCanvas_ = null;
this.size_ = [size, size];
}
draw_(renderOptions, context, pixelRatio) {
context.scale(pixelRatio, pixelRatio);
context.translate(renderOptions.size / 2, renderOptions.size / 2);
this.createPath_(context);
if (this.fill_) {
let color = this.fill_.getColor();
if (color === null) {
color = defaultFillStyle;
}
context.fillStyle = asColorLike(color);
context.fill();
}
if (renderOptions.strokeStyle) {
context.strokeStyle = renderOptions.strokeStyle;
context.lineWidth = renderOptions.strokeWidth;
if (renderOptions.lineDash) {
context.setLineDash(renderOptions.lineDash);
context.lineDashOffset = renderOptions.lineDashOffset;
}
context.lineCap = renderOptions.lineCap;
context.lineJoin = renderOptions.lineJoin;
context.miterLimit = renderOptions.miterLimit;
context.stroke();
}
}
createHitDetectionCanvas_(renderOptions) {
let context;
if (this.fill_) {
let color = this.fill_.getColor();
let opacity = 0;
if (typeof color === "string") {
color = asArray(color);
}
if (color === null) {
opacity = 1;
} else if (Array.isArray(color)) {
opacity = color.length === 4 ? color[3] : 1;
}
if (opacity === 0) {
context = createCanvasContext2D(renderOptions.size, renderOptions.size);
this.drawHitDetectionCanvas_(renderOptions, context);
}
}
return context ? context.canvas : this.getImage(1);
}
createPath_(context) {
let points = this.points_;
const radius = this.radius;
if (points === Infinity) {
context.arc(0, 0, radius, 0, 2 * Math.PI);
} else {
const radius2 = this.radius2_ === void 0 ? radius : this.radius2_;
if (this.radius2_ !== void 0) {
points *= 2;
}
const startAngle = this.angle_ - Math.PI / 2;
const step = 2 * Math.PI / points;
for (let i = 0; i < points; i++) {
const angle0 = startAngle + i * step;
const radiusC = i % 2 === 0 ? radius : radius2;
context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0));
}
context.closePath();
}
}
drawHitDetectionCanvas_(renderOptions, context) {
context.translate(renderOptions.size / 2, renderOptions.size / 2);
this.createPath_(context);
context.fillStyle = defaultFillStyle;
context.fill();
if (renderOptions.strokeStyle) {
context.strokeStyle = renderOptions.strokeStyle;
context.lineWidth = renderOptions.strokeWidth;
if (renderOptions.lineDash) {
context.setLineDash(renderOptions.lineDash);
context.lineDashOffset = renderOptions.lineDashOffset;
}
context.lineJoin = renderOptions.lineJoin;
context.miterLimit = renderOptions.miterLimit;
context.stroke();
}
}
ready() {
return this.fill_ ? this.fill_.ready() : Promise.resolve();
}
}
const RegularShape$1 = RegularShape;
class CircleStyle extends RegularShape$1 {
constructor(options) {
options = options ? options : { radius: 5 };
super({
points: Infinity,
fill: options.fill,
radius: options.radius,
stroke: options.stroke,
scale: options.scale !== void 0 ? options.scale : 1,
rotation: options.rotation !== void 0 ? options.rotation : 0,
rotateWithView: options.rotateWithView !== void 0 ? options.rotateWithView : false,
displacement: options.displacement !== void 0 ? options.displacement : [0, 0],
declutterMode: options.declutterMode
});
}
clone() {
const scale2 = this.getScale();
const style = new CircleStyle({
fill: this.getFill() ? this.getFill().clone() : void 0,
stroke: this.getStroke() ? this.getStroke().clone() : void 0,
radius: this.getRadius(),
scale: Array.isArray(scale2) ? scale2.slice() : scale2,
rotation: this.getRotation(),
rotateWithView: this.getRotateWithView(),
displacement: this.getDisplacement().slice(),
declutterMode: this.getDeclutterMode()
});
style.setOpacity(this.getOpacity());
return style;
}
setRadius(radius) {
this.radius = radius;
this.render();
}
}
const Circle = CircleStyle;
class Fill {
constructor(options) {
options = options || {};
this.patternImage_ = null;
this.color_ = null;
if (options.color !== void 0) {
this.setColor(options.color);
}
}
clone() {
const color = this.getColor();
return new Fill({
color: Array.isArray(color) ? color.slice() : color || void 0
});
}
getColor() {
return this.color_;
}
setColor(color) {
if (color !== null && typeof color === "object" && "src" in color) {
const patternImage = get(
null,
color.src,
"anonymous",
void 0,
color.offset ? null : color.color ? color.color : null,
!(color.offset && color.size)
);
patternImage.ready().then(() => {
this.patternImage_ = null;
});
if (patternImage.getImageState() === ImageState.IDLE) {
patternImage.load();
}
if (patternImage.getImageState() === ImageState.LOADING) {
this.patternImage_ = patternImage;
}
}
this.color_ = color;
}
getKey() {
const fill = this.getColor();
if (!fill) {
return "";
}
return fill instanceof CanvasPattern || fill instanceof CanvasGradient ? getUid(fill) : typeof fill === "object" && "src" in fill ? fill.src + ":" + fill.offset : asArray(fill).toString();
}
loading() {
return !!this.patternImage_;
}
ready() {
return this.patternImage_ ? this.patternImage_.ready() : Promise.resolve();
}
}
const Fill$1 = Fill;
function calculateScale(width, height, wantedWidth, wantedHeight) {
if (wantedWidth !== void 0 && wantedHeight !== void 0) {
return [wantedWidth / width, wantedHeight / height];
}
if (wantedWidth !== void 0) {
return wantedWidth / width;
}
if (wantedHeight !== void 0) {
return wantedHeight / height;
}
return 1;
}
class Icon extends ImageStyle$1 {
constructor(options) {
options = options || {};
const opacity = options.opacity !== void 0 ? options.opacity : 1;
const rotation = options.rotation !== void 0 ? options.rotation : 0;
const scale2 = options.scale !== void 0 ? options.scale : 1;
const rotateWithView = options.rotateWithView !== void 0 ? options.rotateWithView : false;
super({
opacity,
rotation,
scale: scale2,
displacement: options.displacement !== void 0 ? options.displacement : [0, 0],
rotateWithView,
declutterMode: options.declutterMode
});
this.anchor_ = options.anchor !== void 0 ? options.anchor : [0.5, 0.5];
this.normalizedAnchor_ = null;
this.anchorOrigin_ = options.anchorOrigin !== void 0 ? options.anchorOrigin : "top-left";
this.anchorXUnits_ = options.anchorXUnits !== void 0 ? options.anchorXUnits : "fraction";
this.anchorYUnits_ = options.anchorYUnits !== void 0 ? options.anchorYUnits : "fraction";
this.crossOrigin_ = options.crossOrigin !== void 0 ? options.crossOrigin : null;
const image = options.img !== void 0 ? options.img : null;
let cacheKey = options.src;
assert(
!(cacheKey !== void 0 && image),
"`image` and `src` cannot be provided at the same time"
);
if ((cacheKey === void 0 || cacheKey.length === 0) && image) {
cacheKey = image.src || getUid(image);
}
assert(
cacheKey !== void 0 && cacheKey.length > 0,
"A defined and non-empty `src` or `image` must be provided"
);
assert(
!((options.width !== void 0 || options.height !== void 0) && options.scale !== void 0),
"`width` or `height` cannot be provided together with `scale`"
);
let imageState;
if (options.src !== void 0) {
imageState = ImageState.IDLE;
} else if (image !== void 0) {
if ("complete" in image) {
if (image.complete) {
imageState = image.src ? ImageState.LOADED : ImageState.IDLE;
} else {
imageState = ImageState.LOADING;
}
} else {
imageState = ImageState.LOADED;
}
}
this.color_ = options.color !== void 0 ? asArray(options.color) : null;
this.iconImage_ = get(
image,
cacheKey,
this.crossOrigin_,
imageState,
this.color_
);
this.offset_ = options.offset !== void 0 ? options.offset : [0, 0];
this.offsetOrigin_ = options.offsetOrigin !== void 0 ? options.offsetOrigin : "top-left";
this.origin_ = null;
this.size_ = options.size !== void 0 ? options.size : null;
this.initialOptions_;
if (options.width !== void 0 || options.height !== void 0) {
let width, height;
if (options.size) {
[width, height] = options.size;
} else {
const image2 = this.getImage(1);
if (image2.width && image2.height) {
width = image2.width;
height = image2.height;
} else if (image2 instanceof HTMLImageElement) {
this.initialOptions_ = options;
const onload = () => {
this.unlistenImageChange(onload);
if (!this.initialOptions_) {
return;
}
const imageSize = this.iconImage_.getSize();
this.setScale(
calculateScale(
imageSize[0],
imageSize[1],
options.width,
options.height
)
);
};
this.listenImageChange(onload);
return;
}
}
if (width !== void 0) {
this.setScale(
calculateScale(width, height, options.width, options.height)
);
}
}
}
clone() {
let scale2, width, height;
if (this.initialOptions_) {
width = this.initialOptions_.width;
height = this.initialOptions_.height;
} else {
scale2 = this.getScale();
scale2 = Array.isArray(scale2) ? scale2.slice() : scale2;
}
return new Icon({
anchor: this.anchor_.slice(),
anchorOrigin: this.anchorOrigin_,
anchorXUnits: this.anchorXUnits_,
anchorYUnits: this.anchorYUnits_,
color: this.color_ && this.color_.slice ? this.color_.slice() : this.color_ || void 0,
crossOrigin: this.crossOrigin_,
offset: this.offset_.slice(),
offsetOrigin: this.offsetOrigin_,
opacity: this.getOpacity(),
rotateWithView: this.getRotateWithView(),
rotation: this.getRotation(),
scale: scale2,
width,
height,
size: this.size_ !== null ? this.size_.slice() : void 0,
src: this.getSrc(),
displacement: this.getDisplacement().slice(),
declutterMode: this.getDeclutterMode()
});
}
getAnchor() {
let anchor = this.normalizedAnchor_;
if (!anchor) {
anchor = this.anchor_;
const size = this.getSize();
if (this.anchorXUnits_ == "fraction" || this.anchorYUnits_ == "fraction") {
if (!size) {
return null;
}
anchor = this.anchor_.slice();
if (this.anchorXUnits_ == "fraction") {
anchor[0] *= size[0];
}
if (this.anchorYUnits_ == "fraction") {
anchor[1] *= size[1];
}
}
if (this.anchorOrigin_ != "top-left") {
if (!size) {
return null;
}
if (anchor === this.anchor_) {
anchor = this.anchor_.slice();
}
if (this.anchorOrigin_ == "top-right" || this.anchorOrigin_ == "bottom-right") {
anchor[0] = -anchor[0] + size[0];
}
if (this.anchorOrigin_ == "bottom-left" || this.anchorOrigin_ == "bottom-right") {
anchor[1] = -anchor[1] + size[1];
}
}
this.normalizedAnchor_ = anchor;
}
const displacement = this.getDisplacement();
const scale2 = this.getScaleArray();
return [
anchor[0] - displacement[0] / scale2[0],
anchor[1] + displacement[1] / scale2[1]
];
}
setAnchor(anchor) {
this.anchor_ = anchor;
this.normalizedAnchor_ = null;
}
getColor() {
return this.color_;
}
getImage(pixelRatio) {
return this.iconImage_.getImage(pixelRatio);
}
getPixelRatio(pixelRatio) {
return this.iconImage_.getPixelRatio(pixelRatio);
}
getImageSize() {
return this.iconImage_.getSize();
}
getImageState() {
return this.iconImage_.getImageState();
}
getHitDetectionImage() {
return this.iconImage_.getHitDetectionImage();
}
getOrigin() {
if (this.origin_) {
return this.origin_;
}
let offset = this.offset_;
if (this.offsetOrigin_ != "top-left") {
const size = this.getSize();
const iconImageSize = this.iconImage_.getSize();
if (!size || !iconImageSize) {
return null;
}
offset = offset.slice();
if (this.offsetOrigin_ == "top-right" || this.offsetOrigin_ == "bottom-right") {
offset[0] = iconImageSize[0] - size[0] - offset[0];
}
if (this.offsetOrigin_ == "bottom-left" || this.offsetOrigin_ == "bottom-right") {
offset[1] = iconImageSize[1] - size[1] - offset[1];
}
}
this.origin_ = offset;
return this.origin_;
}
getSrc() {
return this.iconImage_.getSrc();
}
getSize() {
return !this.size_ ? this.iconImage_.getSize() : this.size_;
}
getWidth() {
const scale2 = this.getScaleArray();
if (this.size_) {
return this.size_[0] * scale2[0];
}
if (this.iconImage_.getImageState() == ImageState.LOADED) {
return this.iconImage_.getSize()[0] * scale2[0];
}
return void 0;
}
getHeight() {
const scale2 = this.getScaleArray();
if (this.size_) {
return this.size_[1] * scale2[1];
}
if (this.iconImage_.getImageState() == ImageState.LOADED) {
return this.iconImage_.getSize()[1] * scale2[1];
}
return void 0;
}
setScale(scale2) {
delete this.initialOptions_;
super.setScale(scale2);
}
listenImageChange(listener) {
this.iconImage_.addEventListener(EventType.CHANGE, listener);
}
load() {
this.iconImage_.load();
}
unlistenImageChange(listener) {
this.iconImage_.removeEventListener(EventType.CHANGE, listener);
}
ready() {
return this.iconImage_.ready();
}
}
const Icon$1 = Icon;
class Stroke {
constructor(options) {
options = options || {};
this.color_ = options.color !== void 0 ? options.color : null;
this.lineCap_ = options.lineCap;
this.lineDash_ = options.lineDash !== void 0 ? options.lineDash : null;
this.lineDashOffset_ = options.lineDashOffset;
this.lineJoin_ = options.lineJoin;
this.miterLimit_ = options.miterLimit;
this.width_ = options.width;
}
clone() {
const color = this.getColor();
return new Stroke({
color: Array.isArray(color) ? color.slice() : color || void 0,
lineCap: this.getLineCap(),
lineDash: this.getLineDash() ? this.getLineDash().slice() : void 0,
lineDashOffset: this.getLineDashOffset(),
lineJoin: this.getLineJoin(),
miterLimit: this.getMiterLimit(),
width: this.getWidth()
});
}
getColor() {
return this.color_;
}
getLineCap() {
return this.lineCap_;
}
getLineDash() {
return this.lineDash_;
}
getLineDashOffset() {
return this.lineDashOffset_;
}
getLineJoin() {
return this.lineJoin_;
}
getMiterLimit() {
return this.miterLimit_;
}
getWidth() {
return this.width_;
}
setColor(color) {
this.color_ = color;
}
setLineCap(lineCap) {
this.lineCap_ = lineCap;
}
setLineDash(lineDash) {
this.lineDash_ = lineDash;
}
setLineDashOffset(lineDashOffset) {
this.lineDashOffset_ = lineDashOffset;
}
setLineJoin(lineJoin) {
this.lineJoin_ = lineJoin;
}
setMiterLimit(miterLimit) {
this.miterLimit_ = miterLimit;
}
setWidth(width) {
this.width_ = width;
}
}
const Stroke$1 = Stroke;
class Style {
constructor(options) {
options = options || {};
this.geometry_ = null;
this.geometryFunction_ = defaultGeometryFunction;
if (options.geometry !== void 0) {
this.setGeometry(options.geometry);
}
this.fill_ = options.fill !== void 0 ? options.fill : null;
this.image_ = options.image !== void 0 ? options.image : null;
this.renderer_ = options.renderer !== void 0 ? options.renderer : null;
this.hitDetectionRenderer_ = options.hitDetectionRenderer !== void 0 ? options.hitDetectionRenderer : null;
this.stroke_ = options.stroke !== void 0 ? options.stroke : null;
this.text_ = options.text !== void 0 ? options.text : null;
this.zIndex_ = options.zIndex;
}
clone() {
var _a;
let geometry = this.getGeometry();
if (geometry && typeof geometry === "object") {
geometry = geometry.clone();
}
return new Style({
geometry: geometry != null ? geometry : void 0,
fill: this.getFill() ? this.getFill().clone() : void 0,
image: this.getImage() ? this.getImage().clone() : void 0,
renderer: (_a = this.getRenderer()) != null ? _a : void 0,
stroke: this.getStroke() ? this.getStroke().clone() : void 0,
text: this.getText() ? this.getText().clone() : void 0,
zIndex: this.getZIndex()
});
}
getRenderer() {
return this.renderer_;
}
setRenderer(renderer) {
this.renderer_ = renderer;
}
setHitDetectionRenderer(renderer) {
this.hitDetectionRenderer_ = renderer;
}
getHitDetectionRenderer() {
return this.hitDetectionRenderer_;
}
getGeometry() {
return this.geometry_;
}
getGeometryFunction() {
return this.geometryFunction_;
}
getFill() {
return this.fill_;
}
setFill(fill) {
this.fill_ = fill;
}
getImage() {
return this.image_;
}
setImage(image) {
this.image_ = image;
}
getStroke() {
return this.stroke_;
}
setStroke(stroke) {
this.stroke_ = stroke;
}
getText() {
return this.text_;
}
setText(text) {
this.text_ = text;
}
getZIndex() {
return this.zIndex_;
}
setGeometry(geometry) {
if (typeof geometry === "function") {
this.geometryFunction_ = geometry;
} else if (typeof geometry === "string") {
this.geometryFunction_ = function(feature2) {
return feature2.get(geometry);
};
} else if (!geometry) {
this.geometryFunction_ = defaultGeometryFunction;
} else if (geometry !== void 0) {
this.geometryFunction_ = function() {
return geometry;
};
}
this.geometry_ = geometry;
}
setZIndex(zIndex) {
this.zIndex_ = zIndex;
}
}
function toFunction(obj) {
let styleFunction;
if (typeof obj === "function") {
styleFunction = obj;
} else {
let styles;
if (Array.isArray(obj)) {
styles = obj;
} else {
assert(
typeof obj.getZIndex === "function",
"Expected an `Style` or an array of `Style`"
);
const style = obj;
styles = [style];
}
styleFunction = function() {
return styles;
};
}
return styleFunction;
}
let defaultStyles = null;
function createDefaultStyle(feature2, resolution) {
if (!defaultStyles) {
const fill = new Fill$1({
color: "rgba(255,255,255,0.4)"
});
const stroke = new Stroke$1({
color: "#3399CC",
width: 1.25
});
defaultStyles = [
new Style({
image: new Circle({
fill,
stroke,
radius: 5
}),
fill,
stroke
})
];
}
return defaultStyles;
}
function createEditingStyle() {
const styles = {};
const white = [255, 255, 255, 1];
const blue = [0, 153, 255, 1];
const width = 3;
styles["Polygon"] = [
new Style({
fill: new Fill$1({
color: [255, 255, 255, 0.5]
})
})
];
styles["MultiPolygon"] = styles["Polygon"];
styles["LineString"] = [
new Style({
stroke: new Stroke$1({
color: white,
width: width + 2
})
}),
new Style({
stroke: new Stroke$1({
color: blue,
width
})
})
];
styles["MultiLineString"] = styles["LineString"];
styles["Circle"] = styles["Polygon"].concat(styles["LineString"]);
styles["Point"] = [
new Style({
image: new Circle({
radius: width * 2,
fill: new Fill$1({
color: blue
}),
stroke: new Stroke$1({
color: white,
width: width / 2
})
}),
zIndex: Infinity
})
];
styles["MultiPoint"] = styles["Point"];
styles["GeometryCollection"] = styles["Polygon"].concat(
styles["LineString"],
styles["Point"]
);
return styles;
}
function defaultGeometryFunction(feature2) {
return feature2.getGeometry();
}
const DEFAULT_FILL_COLOR = "#333";
class Text {
constructor(options) {
options = options || {};
this.font_ = options.font;
this.rotation_ = options.rotation;
this.rotateWithView_ = options.rotateWithView;
this.keepUpright_ = options.keepUpright;
this.scale_ = options.scale;
this.scaleArray_ = toSize(options.scale !== void 0 ? options.scale : 1);
this.text_ = options.text;
this.textAlign_ = options.textAlign;
this.justify_ = options.justify;
this.repeat_ = options.repeat;
this.textBaseline_ = options.textBaseline;
this.fill_ = options.fill !== void 0 ? options.fill : new Fill$1({ color: DEFAULT_FILL_COLOR });
this.maxAngle_ = options.maxAngle !== void 0 ? options.maxAngle : Math.PI / 4;
this.placement_ = options.placement !== void 0 ? options.placement : "point";
this.overflow_ = !!options.overflow;
this.stroke_ = options.stroke !== void 0 ? options.stroke : null;
this.offsetX_ = options.offsetX !== void 0 ? options.offsetX : 0;
this.offsetY_ = options.offsetY !== void 0 ? options.offsetY : 0;
this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;
this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;
this.padding_ = options.padding === void 0 ? null : options.padding;
this.declutterMode_ = options.declutterMode;
}
clone() {
const scale2 = this.getScale();
return new Text({
font: this.getFont(),
placement: this.getPlacement(),
repeat: this.getRepeat(),
maxAngle: this.getMaxAngle(),
overflow: this.getOverflow(),
rotation: this.getRotation(),
rotateWithView: this.getRotateWithView(),
keepUpright: this.getKeepUpright(),
scale: Array.isArray(scale2) ? scale2.slice() : scale2,
text: this.getText(),
textAlign: this.getTextAlign(),
justify: this.getJustify(),
textBaseline: this.getTextBaseline(),
fill: this.getFill() ? this.getFill().clone() : void 0,
stroke: this.getStroke() ? this.getStroke().clone() : void 0,
offsetX: this.getOffsetX(),
offsetY: this.getOffsetY(),
backgroundFill: this.getBackgroundFill() ? this.getBackgroundFill().clone() : void 0,
backgroundStroke: this.getBackgroundStroke() ? this.getBackgroundStroke().clone() : void 0,
padding: this.getPadding() || void 0,
declutterMode: this.getDeclutterMode()
});
}
getOverflow() {
return this.overflow_;
}
getFont() {
return this.font_;
}
getMaxAngle() {
return this.maxAngle_;
}
getPlacement() {
return this.placement_;
}
getRepeat() {
return this.repeat_;
}
getOffsetX() {
return this.offsetX_;
}
getOffsetY() {
return this.offsetY_;
}
getFill() {
return this.fill_;
}
getRotateWithView() {
return this.rotateWithView_;
}
getKeepUpright() {
return this.keepUpright_;
}
getRotation() {
return this.rotation_;
}
getScale() {
return this.scale_;
}
getScaleArray() {
return this.scaleArray_;
}
getStroke() {
return this.stroke_;
}
getText() {
return this.text_;
}
getTextAlign() {
return this.textAlign_;
}
getJustify() {
return this.justify_;
}
getTextBaseline() {
return this.textBaseline_;
}
getBackgroundFill() {
return this.backgroundFill_;
}
getBackgroundStroke() {
return this.backgroundStroke_;
}
getPadding() {
return this.padding_;
}
getDeclutterMode() {
return this.declutterMode_;
}
setOverflow(overflow) {
this.overflow_ = overflow;
}
setFont(font) {
this.font_ = font;
}
setMaxAngle(maxAngle) {
this.maxAngle_ = maxAngle;
}
setOffsetX(offsetX) {
this.offsetX_ = offsetX;
}
setOffsetY(offsetY) {
this.offsetY_ = offsetY;
}
setPlacement(placement) {
this.placement_ = placement;
}
setRepeat(repeat) {
this.repeat_ = repeat;
}
setRotateWithView(rotateWithView) {
this.rotateWithView_ = rotateWithView;
}
setKeepUpright(keepUpright) {
this.keepUpright_ = keepUpright;
}
setFill(fill) {
this.fill_ = fill;
}
setRotation(rotation) {
this.rotation_ = rotation;
}
setScale(scale2) {
this.scale_ = scale2;
this.scaleArray_ = toSize(scale2 !== void 0 ? scale2 : 1);
}
setStroke(stroke) {
this.stroke_ = stroke;
}
setText(text) {
this.text_ = text;
}
setTextAlign(textAlign) {
this.textAlign_ = textAlign;
}
setJustify(justify) {
this.justify_ = justify;
}
setTextBaseline(textBaseline) {
this.textBaseline_ = textBaseline;
}
setBackgroundFill(fill) {
this.backgroundFill_ = fill;
}
setBackgroundStroke(stroke) {
this.backgroundStroke_ = stroke;
}
setPadding(padding) {
this.padding_ = padding;
}
}
const Text$1 = Text;
class CanvasImmediateRenderer extends VectorContext$1 {
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();
}
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;
}
}
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);
}
}
}
}
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;
}
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;
}
drawCircle(geometry) {
if (this.squaredTolerance_) {
geometry = geometry.simplifyTransformed(
this.squaredTolerance_,
this.userTransform_
);
}
if (!intersects$1(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);
}
}
setStyle(style) {
this.setFillStrokeStyle(style.getFill(), style.getStroke());
this.setImageStyle(style.getImage());
this.setTextStyle(style.getText());
}
setTransform(transform) {
this.transform_ = transform;
}
drawGeometry(geometry) {
const type = geometry.getType();
switch (type) {
case "Point":
this.drawPoint(
geometry
);
break;
case "LineString":
this.drawLineString(
geometry
);
break;
case "Polygon":
this.drawPolygon(
geometry
);
break;
case "MultiPoint":
this.drawMultiPoint(
geometry
);
break;
case "MultiLineString":
this.drawMultiLineString(
geometry
);
break;
case "MultiPolygon":
this.drawMultiPolygon(
geometry
);
break;
case "GeometryCollection":
this.drawGeometryCollection(
geometry
);
break;
case "Circle":
this.drawCircle(
geometry
);
break;
}
}
drawFeature(feature2, style) {
const geometry = style.getGeometryFunction()(feature2);
if (!geometry) {
return;
}
this.setStyle(style);
this.drawGeometry(geometry);
}
drawGeometryCollection(geometry) {
const geometries = geometry.getGeometriesArray();
for (let i = 0, ii = geometries.length; i < ii; ++i) {
this.drawGeometry(geometries[i]);
}
}
drawPoint(geometry) {
if (this.squaredTolerance_) {
geometry = 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);
}
}
drawMultiPoint(geometry) {
if (this.squaredTolerance_) {
geometry = 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);
}
}
drawLineString(geometry) {
if (this.squaredTolerance_) {
geometry = geometry.simplifyTransformed(
this.squaredTolerance_,
this.userTransform_
);
}
if (!intersects$1(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);
}
}
drawMultiLineString(geometry) {
if (this.squaredTolerance_) {
geometry = geometry.simplifyTransformed(
this.squaredTolerance_,
this.userTransform_
);
}
const geometryExtent = geometry.getExtent();
if (!intersects$1(this.extent_, geometryExtent)) {
return;
}
if (this.strokeState_) {
this.setContextStrokeState_(this.strokeState_);
const context = this.context_;
const flatCoordinates = geometry.getFlatCoordinates();
let offset = 0;
const ends = 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);
}
}
drawPolygon(geometry) {
if (this.squaredTolerance_) {
geometry = geometry.simplifyTransformed(
this.squaredTolerance_,
this.userTransform_
);
}
if (!intersects$1(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,
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);
}
}
drawMultiPolygon(geometry) {
if (this.squaredTolerance_) {
geometry = geometry.simplifyTransformed(
this.squaredTolerance_,
this.userTransform_
);
}
if (!intersects$1(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);
}
}
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;
}
}
}
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$2(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;
}
}
}
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;
}
}
}
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
)
};
}
}
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;
}
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]
];
}
}
}
const CanvasImmediateRenderer$1 = CanvasImmediateRenderer;
const HIT_DETECT_RESOLUTION = 0.5;
function createHitDetectionImageData(size, transforms2, features, styleFunction, extent, resolution, rotation, squaredTolerance, projection) {
const userExtent = projection ? toUserExtent(extent) : 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 CanvasImmediateRenderer$1(
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 feature2 = features[i - 1];
const featureStyleFunction = feature2.getStyleFunction() || styleFunction;
if (!featureStyleFunction) {
continue;
}
let styles = featureStyleFunction(feature2, resolution);
if (!styles) {
continue;
}
if (!Array.isArray(styles)) {
styles = [styles];
}
const index2 = i * indexFactor;
const color = index2.toString(16).padStart(7, "#00000");
for (let j = 0, jj = styles.length; j < jj; ++j) {
const originalStyle = styles[j];
const geometry = originalStyle.getGeometryFunction()(feature2);
if (!geometry || !intersects$1(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$1({
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 = 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 = transforms2.length; k < kk; ++k) {
renderer.setTransform(transforms2[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 index2 = (clamp(x, 0, imageData.width - 1) + clamp(y, 0, imageData.height - 1) * imageData.width) * 4;
const r = imageData.data[index2];
const g = imageData.data[index2 + 1];
const b = imageData.data[index2 + 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;
}
const SIMPLIFY_TOLERANCE = 0.5;
const 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, feature2, index2) {
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, feature2, index2);
}
const textStyle = style.getText();
if (textStyle && textStyle.getText()) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle);
textReplay.drawText(geometry, feature2);
}
}
function renderFeature(replayGroup, feature2, style, squaredTolerance, listener, transform, declutter, index2) {
const loadingPromises = [];
const imageStyle = style.getImage();
if (imageStyle) {
let loading2 = true;
const imageState = imageStyle.getImageState();
if (imageState == ImageState.LOADED || imageState == ImageState.ERROR) {
loading2 = false;
} else {
if (imageState == ImageState.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,
feature2,
style,
squaredTolerance,
transform,
declutter,
index2
);
return loading;
}
function renderFeatureInternal(replayGroup, feature2, style, squaredTolerance, transform, declutter, index2) {
const geometry = style.getGeometryFunction()(feature2);
if (!geometry) {
return;
}
const simplifiedGeometry = geometry.simplifyTransformed(
squaredTolerance,
transform
);
const renderer = style.getRenderer();
if (renderer) {
renderGeometry(replayGroup, simplifiedGeometry, style, feature2, index2);
} else {
const geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];
geometryRenderer(
replayGroup,
simplifiedGeometry,
style,
feature2,
index2,
declutter
);
}
}
function renderGeometry(replayGroup, geometry, style, feature2, index2) {
if (geometry.getType() == "GeometryCollection") {
const geometries = geometry.getGeometries();
for (let i = 0, ii = geometries.length; i < ii; ++i) {
renderGeometry(replayGroup, geometries[i], style, feature2, index2);
}
return;
}
const replay = replayGroup.getBuilder(style.getZIndex(), "Default");
replay.drawCustom(
geometry,
feature2,
style.getRenderer(),
style.getHitDetectionRenderer(),
index2
);
}
function renderGeometryCollectionGeometry(replayGroup, geometry, style, feature2, declutterBuilderGroup, index2) {
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,
feature2,
declutterBuilderGroup,
index2
);
}
}
function renderLineStringGeometry(builderGroup, geometry, style, feature2, index2) {
const strokeStyle = style.getStroke();
if (strokeStyle) {
const lineStringReplay = builderGroup.getBuilder(
style.getZIndex(),
"LineString"
);
lineStringReplay.setFillStrokeStyle(null, strokeStyle);
lineStringReplay.drawLineString(geometry, feature2, index2);
}
const textStyle = style.getText();
if (textStyle && textStyle.getText()) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle);
textReplay.drawText(geometry, feature2, index2);
}
}
function renderMultiLineStringGeometry(builderGroup, geometry, style, feature2, index2) {
const strokeStyle = style.getStroke();
if (strokeStyle) {
const lineStringReplay = builderGroup.getBuilder(
style.getZIndex(),
"LineString"
);
lineStringReplay.setFillStrokeStyle(null, strokeStyle);
lineStringReplay.drawMultiLineString(geometry, feature2, index2);
}
const textStyle = style.getText();
if (textStyle && textStyle.getText()) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle);
textReplay.drawText(geometry, feature2, index2);
}
}
function renderMultiPolygonGeometry(builderGroup, geometry, style, feature2, index2) {
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, feature2, index2);
}
const textStyle = style.getText();
if (textStyle && textStyle.getText()) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle);
textReplay.drawText(geometry, feature2, index2);
}
}
function renderPointGeometry(builderGroup, geometry, style, feature2, index2, 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.LOADED) {
return;
}
const imageReplay = builderGroup.getBuilder(style.getZIndex(), "Image");
imageReplay.setImageStyle(imageStyle, declutterImageWithText);
imageReplay.drawPoint(geometry, feature2, index2);
}
if (hasText) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle, declutterImageWithText);
textReplay.drawText(geometry, feature2, index2);
}
}
function renderMultiPointGeometry(builderGroup, geometry, style, feature2, index2, 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.LOADED) {
return;
}
const imageReplay = builderGroup.getBuilder(style.getZIndex(), "Image");
imageReplay.setImageStyle(imageStyle, declutterImageWithText);
imageReplay.drawMultiPoint(geometry, feature2, index2);
}
if (hasText) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle, declutterImageWithText);
textReplay.drawText(geometry, feature2, index2);
}
}
function renderPolygonGeometry(builderGroup, geometry, style, feature2, index2) {
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, feature2, index2);
}
const textStyle = style.getText();
if (textStyle && textStyle.getText()) {
const textReplay = builderGroup.getBuilder(style.getZIndex(), "Text");
textReplay.setTextStyle(textStyle);
textReplay.drawText(geometry, feature2, index2);
}
}
class RenderEvent extends Event {
constructor(type, inversePixelTransform, frameState, context) {
super(type);
this.inversePixelTransform = inversePixelTransform;
this.frameState = frameState;
this.context = context;
}
}
const RenderEvent$1 = RenderEvent;
const maxStaleKeys = 5;
class LayerRenderer extends Observable$1 {
constructor(layer) {
super();
this.ready = true;
this.boundHandleImageChange_ = this.handleImageChange_.bind(this);
this.layer_ = layer;
this.staleKeys_ = new Array();
this.maxStaleKeys = maxStaleKeys;
}
getStaleKeys() {
return this.staleKeys_;
}
prependStaleKey(key) {
this.staleKeys_.unshift(key);
if (this.staleKeys_.length > this.maxStaleKeys) {
this.staleKeys_.length = this.maxStaleKeys;
}
}
getFeatures(pixel) {
return abstract();
}
getData(pixel) {
return null;
}
prepareFrame(frameState) {
return abstract();
}
renderFrame(frameState, target) {
return abstract();
}
forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, matches) {
return void 0;
}
getLayer() {
return this.layer_;
}
handleFontsChanged() {
}
handleImageChange_(event) {
const image = event.target;
if (image.getState() === ImageState.LOADED || image.getState() === ImageState.ERROR) {
this.renderIfReadyAndVisible();
}
}
loadImage(image) {
let imageState = image.getState();
if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {
image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);
}
if (imageState == ImageState.IDLE) {
image.load();
imageState = image.getState();
}
return imageState == ImageState.LOADED;
}
renderIfReadyAndVisible() {
const layer = this.getLayer();
if (layer && layer.getVisible() && layer.getSourceState() === "ready") {
layer.changed();
}
}
renderDeferred(frameState) {
}
disposeInternal() {
delete this.layer_;
super.disposeInternal();
}
}
const LayerRenderer$1 = LayerRenderer;
const canvasPool = [];
let pixelContext = null;
function createPixelContext() {
pixelContext = createCanvasContext2D(1, 1, void 0, {
willReadFrequently: true
});
}
class CanvasLayerRenderer extends LayerRenderer$1 {
constructor(layer) {
super(layer);
this.container = null;
this.renderedResolution;
this.tempTransform = create();
this.pixelTransform = create();
this.inversePixelTransform = create();
this.context = null;
this.deferredContext_ = null;
this.containerReused = false;
this.frameState = null;
}
getImageData(image, col, row) {
if (!pixelContext) {
createPixelContext();
}
pixelContext.clearRect(0, 0, 1, 1);
let data;
try {
pixelContext.drawImage(image, col, row, 1, 1, 0, 0, 1, 1);
data = pixelContext.getImageData(0, 0, 1, 1).data;
} catch {
pixelContext = null;
return null;
}
return data;
}
getBackground(frameState) {
const layer = this.getLayer();
let background = layer.getBackground();
if (typeof background === "function") {
background = background(frameState.viewState.resolution);
}
return background || void 0;
}
useContainer(target, transform, backgroundColor) {
const layerClassName = this.getLayer().getClassName();
let container, context;
if (target && target.className === layerClassName && (!backgroundColor || target && target.style.backgroundColor && equals$2(
asArray(target.style.backgroundColor),
asArray(backgroundColor)
))) {
const canvas = target.firstElementChild;
if (canvas instanceof HTMLCanvasElement) {
context = canvas.getContext("2d");
}
}
if (context && equivalent(context.canvas.style.transform, transform)) {
this.container = target;
this.context = context;
this.containerReused = true;
} else if (this.containerReused) {
this.container = null;
this.context = null;
this.containerReused = false;
} else if (this.container) {
this.container.style.backgroundColor = null;
}
if (!this.container) {
container = document.createElement("div");
container.className = layerClassName;
let style = container.style;
style.position = "absolute";
style.width = "100%";
style.height = "100%";
context = createCanvasContext2D();
const canvas = context.canvas;
container.appendChild(canvas);
style = canvas.style;
style.position = "absolute";
style.left = "0";
style.transformOrigin = "top left";
this.container = container;
this.context = context;
}
if (!this.containerReused && backgroundColor && !this.container.style.backgroundColor) {
this.container.style.backgroundColor = backgroundColor;
}
}
clipUnrotated(context, frameState, extent) {
const topLeft = getTopLeft(extent);
const topRight = getTopRight(extent);
const bottomRight = getBottomRight(extent);
const bottomLeft = getBottomLeft(extent);
apply(frameState.coordinateToPixelTransform, topLeft);
apply(frameState.coordinateToPixelTransform, topRight);
apply(frameState.coordinateToPixelTransform, bottomRight);
apply(frameState.coordinateToPixelTransform, bottomLeft);
const inverted = this.inversePixelTransform;
apply(inverted, topLeft);
apply(inverted, topRight);
apply(inverted, bottomRight);
apply(inverted, bottomLeft);
context.save();
context.beginPath();
context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));
context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));
context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));
context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));
context.clip();
}
prepareContainer(frameState, target) {
const extent = frameState.extent;
const resolution = frameState.viewState.resolution;
const rotation = frameState.viewState.rotation;
const pixelRatio = frameState.pixelRatio;
const width = Math.round(getWidth(extent) / resolution * pixelRatio);
const height = Math.round(getHeight(extent) / resolution * pixelRatio);
compose(
this.pixelTransform,
frameState.size[0] / 2,
frameState.size[1] / 2,
1 / pixelRatio,
1 / pixelRatio,
rotation,
-width / 2,
-height / 2
);
makeInverse(this.inversePixelTransform, this.pixelTransform);
const canvasTransform = toString$1(this.pixelTransform);
this.useContainer(target, canvasTransform, this.getBackground(frameState));
if (!this.containerReused) {
const canvas = this.context.canvas;
if (canvas.width != width || canvas.height != height) {
canvas.width = width;
canvas.height = height;
} else {
this.context.clearRect(0, 0, width, height);
}
if (canvasTransform !== canvas.style.transform) {
canvas.style.transform = canvasTransform;
}
}
}
dispatchRenderEvent_(type, context, frameState) {
const layer = this.getLayer();
if (layer.hasListener(type)) {
const event = new RenderEvent$1(
type,
this.inversePixelTransform,
frameState,
context
);
layer.dispatchEvent(event);
}
}
preRender(context, frameState) {
this.frameState = frameState;
if (frameState.declutter) {
return;
}
this.dispatchRenderEvent_(RenderEventType.PRERENDER, context, frameState);
}
postRender(context, frameState) {
if (frameState.declutter) {
return;
}
this.dispatchRenderEvent_(RenderEventType.POSTRENDER, context, frameState);
}
renderDeferredInternal(frameState) {
}
getRenderContext(frameState) {
if (frameState.declutter && !this.deferredContext_) {
this.deferredContext_ = new ZIndexContext$1();
}
return frameState.declutter ? this.deferredContext_.getContext() : this.context;
}
renderDeferred(frameState) {
if (!frameState.declutter) {
return;
}
this.dispatchRenderEvent_(
RenderEventType.PRERENDER,
this.context,
frameState
);
if (frameState.declutter && this.deferredContext_) {
this.deferredContext_.draw(this.context);
this.deferredContext_.clear();
}
this.renderDeferredInternal(frameState);
this.dispatchRenderEvent_(
RenderEventType.POSTRENDER,
this.context,
frameState
);
}
getRenderTransform(center, resolution, rotation, pixelRatio, width, height, offsetX) {
const dx1 = width / 2;
const dy1 = height / 2;
const sx = pixelRatio / resolution;
const sy = -sx;
const dx2 = -center[0] + offsetX;
const dy2 = -center[1];
return compose(
this.tempTransform,
dx1,
dy1,
sx,
sy,
-rotation,
dx2,
dy2
);
}
disposeInternal() {
delete this.frameState;
super.disposeInternal();
}
}
const CanvasLayerRenderer$1 = CanvasLayerRenderer;
class CanvasVectorLayerRenderer extends CanvasLayerRenderer$1 {
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;
}
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.ANIMATING] || viewHints[ViewHint.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);
}
setDrawContext_() {
if (this.opacity_ !== 1) {
this.targetContext_ = this.context;
this.context = createCanvasContext2D(
this.context.canvas.width,
this.context.canvas.height,
canvasPool
);
}
}
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;
}
}
renderDeclutter(frameState) {
if (!this.replayGroup_ || !this.getLayer().getDeclutter()) {
return;
}
this.renderWorlds(this.replayGroup_, frameState, true);
}
renderDeferredInternal(frameState) {
if (!this.replayGroup_) {
return;
}
this.replayGroup_.renderDeferred();
if (this.clipped_) {
this.context.restore();
}
this.resetDrawContext_();
}
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 render2 = replayGroup && !replayGroup.isEmpty();
if (!render2) {
const hasRenderListeners = this.getLayer().hasListener(RenderEventType.PRERENDER) || this.getLayer().hasListener(RenderEventType.POSTRENDER);
if (!hasRenderListeners) {
return this.container;
}
}
this.setDrawContext_();
this.preRender(context, frameState);
viewState.projection;
this.clipped_ = false;
if (render2 && layerState.extent && this.clipping) {
const layerExtent = fromUserExtent(layerState.extent);
render2 = intersects$1(layerExtent, frameState.extent);
this.clipped_ = render2 && !containsExtent(layerExtent, frameState.extent);
if (this.clipped_) {
this.clipUnrotated(context, frameState, layerExtent);
}
}
if (render2) {
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;
}
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 transforms2 = [];
const width = size[0] * HIT_DETECT_RESOLUTION;
const height = size[1] * HIT_DETECT_RESOLUTION;
transforms2.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;
transforms2.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;
transforms2.push(
this.getRenderTransform(
center,
resolution,
rotation,
HIT_DETECT_RESOLUTION,
width,
height,
offsetX
).slice()
);
startX -= worldWidth;
}
}
this.hitDetectionImageData_ = createHitDetectionImageData(
size,
transforms2,
this.renderedFeatures_,
layer.getStyleFunction(),
extent,
resolution,
rotation,
getSquaredTolerance(resolution, this.renderedPixelRatio_),
null
);
}
resolve(
hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_)
);
});
}
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(feature2, geometry, distanceSq) {
const key = getUid(feature2);
const match = features[key];
if (!match) {
if (distanceSq === 0) {
features[key] = true;
return callback(feature2, layer, geometry);
}
matches.push(
features[key] = {
feature: feature2,
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(feature2, 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
);
}
handleFontsChanged() {
const layer = this.getLayer();
if (layer.getVisible() && this.replayGroup_) {
layer.changed();
}
}
handleStyleImageChange_(event) {
this.renderIfReadyAndVisible();
}
prepareFrame(frameState) {
const vectorLayer = this.getLayer();
const vectorSource = vectorLayer.getSource();
if (!vectorSource) {
return false;
}
const animating = frameState.viewHints[ViewHint.ANIMATING];
const interacting = frameState.viewHints[ViewHint.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;
wrapX(center, projection);
const loadExtent = wrapX$1(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$2(this.renderedExtent_, renderedExtent)) {
this.hitDetectionImageData_ = null;
this.renderedExtent_ = renderedExtent;
}
this.renderedCenter_ = center;
this.replayGroupChanged = false;
return true;
}
this.replayGroup_ = null;
const replayGroup = new CanvasBuilderGroup(
getTolerance(resolution, pixelRatio),
extent,
resolution,
pixelRatio
);
let userTransform;
{
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 render2 = (feature2, index2) => {
let styles;
const styleFunction = feature2.getStyleFunction() || vectorLayer.getStyleFunction();
if (styleFunction) {
styles = styleFunction(feature2, resolution);
}
if (styles) {
const dirty = this.renderFeature(
feature2,
squaredTolerance,
styles,
replayGroup,
userTransform,
this.getLayer().getDeclutter(),
index2
);
ready = ready && !dirty;
}
};
const userExtent = toUserExtent(extent);
const features = vectorSource.getFeaturesInExtent(userExtent);
if (vectorLayerRenderOrder) {
features.sort(vectorLayerRenderOrder);
}
for (let i = 0, ii = features.length; i < ii; ++i) {
render2(features[i], i);
}
this.renderedFeatures_ = features;
this.ready = ready;
const replayGroupInstructions = replayGroup.finish();
const executorGroup = new ExecutorGroup$1(
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;
}
renderFeature(feature2, squaredTolerance, styles, builderGroup, transform, declutter, index2) {
if (!styles) {
return false;
}
let loading = false;
if (Array.isArray(styles)) {
for (let i = 0, ii = styles.length; i < ii; ++i) {
loading = renderFeature(
builderGroup,
feature2,
styles[i],
squaredTolerance,
this.boundHandleStyleImageChange_,
transform,
declutter,
index2
) || loading;
}
} else {
loading = renderFeature(
builderGroup,
feature2,
styles,
squaredTolerance,
this.boundHandleStyleImageChange_,
transform,
declutter,
index2
);
}
return loading;
}
}
const CanvasVectorLayerRenderer$1 = CanvasVectorLayerRenderer;
let numTypes = 0;
const BooleanType = 1 << numTypes++;
const NumberType = 1 << numTypes++;
const StringType = 1 << numTypes++;
const ColorType = 1 << numTypes++;
const NumberArrayType = 1 << numTypes++;
const SizeType = 1 << numTypes++;
const AnyType = Math.pow(2, numTypes) - 1;
const typeNames = {
[BooleanType]: "boolean",
[NumberType]: "number",
[StringType]: "string",
[ColorType]: "color",
[NumberArrayType]: "number[]",
[SizeType]: "size"
};
const namedTypes = Object.keys(typeNames).map(Number).sort(ascending);
function isSpecific(type) {
return type in typeNames;
}
function typeName(type) {
const names = [];
for (const namedType of namedTypes) {
if (includesType(type, namedType)) {
names.push(typeNames[namedType]);
}
}
if (names.length === 0) {
return "untyped";
}
if (names.length < 3) {
return names.join(" or ");
}
return names.slice(0, -1).join(", ") + ", or " + names[names.length - 1];
}
function includesType(broad, specific) {
return (broad & specific) === specific;
}
function isType(type, expected) {
return type === expected;
}
class LiteralExpression {
constructor(type, value) {
if (!isSpecific(type)) {
throw new Error(
`literal expressions must have a specific type, got ${typeName(type)}`
);
}
this.type = type;
this.value = value;
}
}
class CallExpression {
constructor(type, operator, ...args) {
this.type = type;
this.operator = operator;
this.args = args;
}
}
function newParsingContext() {
return {
variables: /* @__PURE__ */ new Set(),
properties: /* @__PURE__ */ new Set(),
featureId: false,
geometryType: false,
mapState: false
};
}
function parse(encoded, expectedType, context) {
switch (typeof encoded) {
case "boolean": {
if (isType(expectedType, StringType)) {
return new LiteralExpression(StringType, encoded ? "true" : "false");
}
if (!includesType(expectedType, BooleanType)) {
throw new Error(
`got a boolean, but expected ${typeName(expectedType)}`
);
}
return new LiteralExpression(BooleanType, encoded);
}
case "number": {
if (isType(expectedType, SizeType)) {
return new LiteralExpression(SizeType, toSize(encoded));
}
if (isType(expectedType, BooleanType)) {
return new LiteralExpression(BooleanType, !!encoded);
}
if (isType(expectedType, StringType)) {
return new LiteralExpression(StringType, encoded.toString());
}
if (!includesType(expectedType, NumberType)) {
throw new Error(`got a number, but expected ${typeName(expectedType)}`);
}
return new LiteralExpression(NumberType, encoded);
}
case "string": {
if (isType(expectedType, ColorType)) {
return new LiteralExpression(ColorType, fromString(encoded));
}
if (isType(expectedType, BooleanType)) {
return new LiteralExpression(BooleanType, !!encoded);
}
if (!includesType(expectedType, StringType)) {
throw new Error(`got a string, but expected ${typeName(expectedType)}`);
}
return new LiteralExpression(StringType, encoded);
}
}
if (!Array.isArray(encoded)) {
throw new Error("expression must be an array or a primitive value");
}
if (encoded.length === 0) {
throw new Error("empty expression");
}
if (typeof encoded[0] === "string") {
return parseCallExpression(encoded, expectedType, context);
}
for (const item of encoded) {
if (typeof item !== "number") {
throw new Error("expected an array of numbers");
}
}
if (isType(expectedType, SizeType)) {
if (encoded.length !== 2) {
throw new Error(
`expected an array of two values for a size, got ${encoded.length}`
);
}
return new LiteralExpression(SizeType, encoded);
}
if (isType(expectedType, ColorType)) {
if (encoded.length === 3) {
return new LiteralExpression(ColorType, [...encoded, 1]);
}
if (encoded.length === 4) {
return new LiteralExpression(ColorType, encoded);
}
throw new Error(
`expected an array of 3 or 4 values for a color, got ${encoded.length}`
);
}
if (!includesType(expectedType, NumberArrayType)) {
throw new Error(
`got an array of numbers, but expected ${typeName(expectedType)}`
);
}
return new LiteralExpression(NumberArrayType, encoded);
}
const Ops = {
Get: "get",
Var: "var",
Concat: "concat",
GeometryType: "geometry-type",
LineMetric: "line-metric",
Any: "any",
All: "all",
Not: "!",
Resolution: "resolution",
Zoom: "zoom",
Time: "time",
Equal: "==",
NotEqual: "!=",
GreaterThan: ">",
GreaterThanOrEqualTo: ">=",
LessThan: "<",
LessThanOrEqualTo: "<=",
Multiply: "*",
Divide: "/",
Add: "+",
Subtract: "-",
Clamp: "clamp",
Mod: "%",
Pow: "^",
Abs: "abs",
Floor: "floor",
Ceil: "ceil",
Round: "round",
Sin: "sin",
Cos: "cos",
Atan: "atan",
Sqrt: "sqrt",
Match: "match",
Between: "between",
Interpolate: "interpolate",
Coalesce: "coalesce",
Case: "case",
In: "in",
Number: "number",
String: "string",
Array: "array",
Color: "color",
Id: "id",
Band: "band",
Palette: "palette",
ToString: "to-string",
Has: "has"
};
const parsers = {
[Ops.Get]: createCallExpressionParser(hasArgsCount(1, Infinity), withGetArgs),
[Ops.Var]: createCallExpressionParser(hasArgsCount(1, 1), withVarArgs),
[Ops.Has]: createCallExpressionParser(hasArgsCount(1, Infinity), withGetArgs),
[Ops.Id]: createCallExpressionParser(usesFeatureId, withNoArgs),
[Ops.Concat]: createCallExpressionParser(
hasArgsCount(2, Infinity),
withArgsOfType(StringType)
),
[Ops.GeometryType]: createCallExpressionParser(usesGeometryType, withNoArgs),
[Ops.LineMetric]: createCallExpressionParser(withNoArgs),
[Ops.Resolution]: createCallExpressionParser(usesMapState, withNoArgs),
[Ops.Zoom]: createCallExpressionParser(usesMapState, withNoArgs),
[Ops.Time]: createCallExpressionParser(usesMapState, withNoArgs),
[Ops.Any]: createCallExpressionParser(
hasArgsCount(2, Infinity),
withArgsOfType(BooleanType)
),
[Ops.All]: createCallExpressionParser(
hasArgsCount(2, Infinity),
withArgsOfType(BooleanType)
),
[Ops.Not]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(BooleanType)
),
[Ops.Equal]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(AnyType)
),
[Ops.NotEqual]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(AnyType)
),
[Ops.GreaterThan]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.GreaterThanOrEqualTo]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.LessThan]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.LessThanOrEqualTo]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.Multiply]: createCallExpressionParser(
hasArgsCount(2, Infinity),
withArgsOfReturnType
),
[Ops.Coalesce]: createCallExpressionParser(
hasArgsCount(2, Infinity),
withArgsOfReturnType
),
[Ops.Divide]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.Add]: createCallExpressionParser(
hasArgsCount(2, Infinity),
withArgsOfType(NumberType)
),
[Ops.Subtract]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.Clamp]: createCallExpressionParser(
hasArgsCount(3, 3),
withArgsOfType(NumberType)
),
[Ops.Mod]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.Pow]: createCallExpressionParser(
hasArgsCount(2, 2),
withArgsOfType(NumberType)
),
[Ops.Abs]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Floor]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Ceil]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Round]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Sin]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Cos]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Atan]: createCallExpressionParser(
hasArgsCount(1, 2),
withArgsOfType(NumberType)
),
[Ops.Sqrt]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(NumberType)
),
[Ops.Match]: createCallExpressionParser(
hasArgsCount(4, Infinity),
hasEvenArgs,
withMatchArgs
),
[Ops.Between]: createCallExpressionParser(
hasArgsCount(3, 3),
withArgsOfType(NumberType)
),
[Ops.Interpolate]: createCallExpressionParser(
hasArgsCount(6, Infinity),
hasEvenArgs,
withInterpolateArgs
),
[Ops.Case]: createCallExpressionParser(
hasArgsCount(3, Infinity),
hasOddArgs,
withCaseArgs
),
[Ops.In]: createCallExpressionParser(hasArgsCount(2, 2), withInArgs),
[Ops.Number]: createCallExpressionParser(
hasArgsCount(1, Infinity),
withArgsOfType(AnyType)
),
[Ops.String]: createCallExpressionParser(
hasArgsCount(1, Infinity),
withArgsOfType(AnyType)
),
[Ops.Array]: createCallExpressionParser(
hasArgsCount(1, Infinity),
withArgsOfType(NumberType)
),
[Ops.Color]: createCallExpressionParser(
hasArgsCount(1, 4),
withArgsOfType(NumberType)
),
[Ops.Band]: createCallExpressionParser(
hasArgsCount(1, 3),
withArgsOfType(NumberType)
),
[Ops.Palette]: createCallExpressionParser(
hasArgsCount(2, 2),
withPaletteArgs
),
[Ops.ToString]: createCallExpressionParser(
hasArgsCount(1, 1),
withArgsOfType(BooleanType | NumberType | StringType | ColorType)
)
};
function withGetArgs(encoded, returnType, context) {
const argsCount = encoded.length - 1;
const args = new Array(argsCount);
for (let i = 0; i < argsCount; ++i) {
const key = encoded[i + 1];
switch (typeof key) {
case "number": {
args[i] = new LiteralExpression(NumberType, key);
break;
}
case "string": {
args[i] = new LiteralExpression(StringType, key);
break;
}
default: {
throw new Error(
`expected a string key or numeric array index for a get operation, got ${key}`
);
}
}
if (i === 0) {
context.properties.add(String(key));
}
}
return args;
}
function withVarArgs(encoded, returnType, context) {
const name = encoded[1];
if (typeof name !== "string") {
throw new Error("expected a string argument for var operation");
}
context.variables.add(name);
return [new LiteralExpression(StringType, name)];
}
function usesFeatureId(encoded, returnType, context) {
context.featureId = true;
}
function usesGeometryType(encoded, returnType, context) {
context.geometryType = true;
}
function usesMapState(encoded, returnType, context) {
context.mapState = true;
}
function withNoArgs(encoded, returnType, context) {
const operation = encoded[0];
if (encoded.length !== 1) {
throw new Error(`expected no arguments for ${operation} operation`);
}
return [];
}
function hasArgsCount(minArgs, maxArgs) {
return function(encoded, returnType, context) {
const operation = encoded[0];
const argCount = encoded.length - 1;
if (minArgs === maxArgs) {
if (argCount !== minArgs) {
const plural = minArgs === 1 ? "" : "s";
throw new Error(
`expected ${minArgs} argument${plural} for ${operation}, got ${argCount}`
);
}
} else if (argCount < minArgs || argCount > maxArgs) {
const range = maxArgs === Infinity ? `${minArgs} or more` : `${minArgs} to ${maxArgs}`;
throw new Error(
`expected ${range} arguments for ${operation}, got ${argCount}`
);
}
};
}
function withArgsOfReturnType(encoded, returnType, context) {
const argCount = encoded.length - 1;
const args = new Array(argCount);
for (let i = 0; i < argCount; ++i) {
const expression = parse(encoded[i + 1], returnType, context);
args[i] = expression;
}
return args;
}
function withArgsOfType(argType) {
return function(encoded, returnType, context) {
const argCount = encoded.length - 1;
const args = new Array(argCount);
for (let i = 0; i < argCount; ++i) {
const expression = parse(encoded[i + 1], argType, context);
args[i] = expression;
}
return args;
};
}
function hasOddArgs(encoded, returnType, context) {
const operation = encoded[0];
const argCount = encoded.length - 1;
if (argCount % 2 === 0) {
throw new Error(
`expected an odd number of arguments for ${operation}, got ${argCount} instead`
);
}
}
function hasEvenArgs(encoded, returnType, context) {
const operation = encoded[0];
const argCount = encoded.length - 1;
if (argCount % 2 === 1) {
throw new Error(
`expected an even number of arguments for operation ${operation}, got ${argCount} instead`
);
}
}
function withMatchArgs(encoded, returnType, context) {
const argsCount = encoded.length - 1;
const inputType = StringType | NumberType | BooleanType;
const input = parse(encoded[1], inputType, context);
const fallback = parse(encoded[encoded.length - 1], returnType, context);
const args = new Array(argsCount - 2);
for (let i = 0; i < argsCount - 2; i += 2) {
try {
const match = parse(encoded[i + 2], input.type, context);
args[i] = match;
} catch (err) {
throw new Error(
`failed to parse argument ${i + 1} of match expression: ${err.message}`
);
}
try {
const output = parse(encoded[i + 3], fallback.type, context);
args[i + 1] = output;
} catch (err) {
throw new Error(
`failed to parse argument ${i + 2} of match expression: ${err.message}`
);
}
}
return [input, ...args, fallback];
}
function withInterpolateArgs(encoded, returnType, context) {
const interpolationType = encoded[1];
let base;
switch (interpolationType[0]) {
case "linear":
base = 1;
break;
case "exponential":
const b = interpolationType[1];
if (typeof b !== "number" || b <= 0) {
throw new Error(
`expected a number base for exponential interpolation, got ${JSON.stringify(b)} instead`
);
}
base = b;
break;
default:
throw new Error(
`invalid interpolation type: ${JSON.stringify(interpolationType)}`
);
}
const interpolation = new LiteralExpression(NumberType, base);
let input;
try {
input = parse(encoded[2], NumberType, context);
} catch (err) {
throw new Error(
`failed to parse argument 1 in interpolate expression: ${err.message}`
);
}
const args = new Array(encoded.length - 3);
for (let i = 0; i < args.length; i += 2) {
try {
const stop = parse(encoded[i + 3], NumberType, context);
args[i] = stop;
} catch (err) {
throw new Error(
`failed to parse argument ${i + 2} for interpolate expression: ${err.message}`
);
}
try {
const output = parse(encoded[i + 4], returnType, context);
args[i + 1] = output;
} catch (err) {
throw new Error(
`failed to parse argument ${i + 3} for interpolate expression: ${err.message}`
);
}
}
return [interpolation, input, ...args];
}
function withCaseArgs(encoded, returnType, context) {
const fallback = parse(encoded[encoded.length - 1], returnType, context);
const args = new Array(encoded.length - 1);
for (let i = 0; i < args.length - 1; i += 2) {
try {
const condition = parse(encoded[i + 1], BooleanType, context);
args[i] = condition;
} catch (err) {
throw new Error(
`failed to parse argument ${i} of case expression: ${err.message}`
);
}
try {
const output = parse(encoded[i + 2], fallback.type, context);
args[i + 1] = output;
} catch (err) {
throw new Error(
`failed to parse argument ${i + 1} of case expression: ${err.message}`
);
}
}
args[args.length - 1] = fallback;
return args;
}
function withInArgs(encoded, returnType, context) {
let haystack = encoded[2];
if (!Array.isArray(haystack)) {
throw new Error(
`the second argument for the "in" operator must be an array`
);
}
let needleType;
if (typeof haystack[0] === "string") {
if (haystack[0] !== "literal") {
throw new Error(
`for the "in" operator, a string array should be wrapped in a "literal" operator to disambiguate from expressions`
);
}
if (!Array.isArray(haystack[1])) {
throw new Error(
`failed to parse "in" expression: the literal operator must be followed by an array`
);
}
haystack = haystack[1];
needleType = StringType;
} else {
needleType = NumberType;
}
const args = new Array(haystack.length);
for (let i = 0; i < args.length; i++) {
try {
const arg = parse(haystack[i], needleType, context);
args[i] = arg;
} catch (err) {
throw new Error(
`failed to parse haystack item ${i} for "in" expression: ${err.message}`
);
}
}
const needle = parse(encoded[1], needleType, context);
return [needle, ...args];
}
function withPaletteArgs(encoded, returnType, context) {
let index2;
try {
index2 = parse(encoded[1], NumberType, context);
} catch (err) {
throw new Error(
`failed to parse first argument in palette expression: ${err.message}`
);
}
const colors = encoded[2];
if (!Array.isArray(colors)) {
throw new Error("the second argument of palette must be an array");
}
const parsedColors = new Array(colors.length);
for (let i = 0; i < parsedColors.length; i++) {
let color;
try {
color = parse(colors[i], ColorType, context);
} catch (err) {
throw new Error(
`failed to parse color at index ${i} in palette expression: ${err.message}`
);
}
if (!(color instanceof LiteralExpression)) {
throw new Error(
`the palette color at index ${i} must be a literal value`
);
}
parsedColors[i] = color;
}
return [index2, ...parsedColors];
}
function createCallExpressionParser(...validators) {
return function(encoded, returnType, context) {
const operator = encoded[0];
let args;
for (let i = 0; i < validators.length; i++) {
const parsed = validators[i](encoded, returnType, context);
if (i == validators.length - 1) {
if (!parsed) {
throw new Error(
"expected last argument validator to return the parsed args"
);
}
args = parsed;
}
}
return new CallExpression(returnType, operator, ...args);
};
}
function parseCallExpression(encoded, returnType, context) {
const operator = encoded[0];
const parser = parsers[operator];
if (!parser) {
throw new Error(`unknown operator: ${operator}`);
}
return parser(encoded, returnType, context);
}
function computeGeometryType(geometry) {
if (!geometry) {
return "";
}
const type = geometry.getType();
switch (type) {
case "Point":
case "LineString":
case "Polygon":
return type;
case "MultiPoint":
case "MultiLineString":
case "MultiPolygon":
return type.substring(5);
case "Circle":
return "Polygon";
case "GeometryCollection":
return computeGeometryType(
geometry.getGeometries()[0]
);
default:
return "";
}
}
function newEvaluationContext() {
return {
variables: {},
properties: {},
resolution: NaN,
featureId: null,
geometryType: ""
};
}
function buildExpression(encoded, type, context) {
const expression = parse(encoded, type, context);
return compileExpression(expression);
}
function compileExpression(expression, context) {
if (expression instanceof LiteralExpression) {
if (expression.type === ColorType && typeof expression.value === "string") {
const colorValue = fromString(expression.value);
return function() {
return colorValue;
};
}
return function() {
return expression.value;
};
}
const operator = expression.operator;
switch (operator) {
case Ops.Number:
case Ops.String:
case Ops.Coalesce: {
return compileAssertionExpression(expression);
}
case Ops.Get:
case Ops.Var:
case Ops.Has: {
return compileAccessorExpression(expression);
}
case Ops.Id: {
return (context2) => context2.featureId;
}
case Ops.GeometryType: {
return (context2) => context2.geometryType;
}
case Ops.Concat: {
const args = expression.args.map((e) => compileExpression(e));
return (context2) => "".concat(...args.map((arg) => arg(context2).toString()));
}
case Ops.Resolution: {
return (context2) => context2.resolution;
}
case Ops.Any:
case Ops.All:
case Ops.Between:
case Ops.In:
case Ops.Not: {
return compileLogicalExpression(expression);
}
case Ops.Equal:
case Ops.NotEqual:
case Ops.LessThan:
case Ops.LessThanOrEqualTo:
case Ops.GreaterThan:
case Ops.GreaterThanOrEqualTo: {
return compileComparisonExpression(expression);
}
case Ops.Multiply:
case Ops.Divide:
case Ops.Add:
case Ops.Subtract:
case Ops.Clamp:
case Ops.Mod:
case Ops.Pow:
case Ops.Abs:
case Ops.Floor:
case Ops.Ceil:
case Ops.Round:
case Ops.Sin:
case Ops.Cos:
case Ops.Atan:
case Ops.Sqrt: {
return compileNumericExpression(expression);
}
case Ops.Case: {
return compileCaseExpression(expression);
}
case Ops.Match: {
return compileMatchExpression(expression);
}
case Ops.Interpolate: {
return compileInterpolateExpression(expression);
}
case Ops.ToString: {
return compileConvertExpression(expression);
}
default: {
throw new Error(`Unsupported operator ${operator}`);
}
}
}
function compileAssertionExpression(expression, context) {
const type = expression.operator;
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
switch (type) {
case Ops.Coalesce: {
return (context2) => {
for (let i = 0; i < length; ++i) {
const value = args[i](context2);
if (typeof value !== "undefined" && value !== null) {
return value;
}
}
throw new Error("Expected one of the values to be non-null");
};
}
case Ops.Number:
case Ops.String: {
return (context2) => {
for (let i = 0; i < length; ++i) {
const value = args[i](context2);
if (typeof value === type) {
return value;
}
}
throw new Error(`Expected one of the values to be a ${type}`);
};
}
default: {
throw new Error(`Unsupported assertion operator ${type}`);
}
}
}
function compileAccessorExpression(expression, context) {
const nameExpression = expression.args[0];
const name = nameExpression.value;
switch (expression.operator) {
case Ops.Get: {
return (context2) => {
const args = expression.args;
let value = context2.properties[name];
for (let i = 1, ii = args.length; i < ii; ++i) {
const keyExpression = args[i];
const key = keyExpression.value;
value = value[key];
}
return value;
};
}
case Ops.Var: {
return (context2) => context2.variables[name];
}
case Ops.Has: {
return (context2) => {
const args = expression.args;
if (!(name in context2.properties)) {
return false;
}
let value = context2.properties[name];
for (let i = 1, ii = args.length; i < ii; ++i) {
const keyExpression = args[i];
const key = keyExpression.value;
if (!value || !Object.hasOwn(value, key)) {
return false;
}
value = value[key];
}
return true;
};
}
default: {
throw new Error(`Unsupported accessor operator ${expression.operator}`);
}
}
}
function compileComparisonExpression(expression, context) {
const op = expression.operator;
const left = compileExpression(expression.args[0]);
const right = compileExpression(expression.args[1]);
switch (op) {
case Ops.Equal: {
return (context2) => left(context2) === right(context2);
}
case Ops.NotEqual: {
return (context2) => left(context2) !== right(context2);
}
case Ops.LessThan: {
return (context2) => left(context2) < right(context2);
}
case Ops.LessThanOrEqualTo: {
return (context2) => left(context2) <= right(context2);
}
case Ops.GreaterThan: {
return (context2) => left(context2) > right(context2);
}
case Ops.GreaterThanOrEqualTo: {
return (context2) => left(context2) >= right(context2);
}
default: {
throw new Error(`Unsupported comparison operator ${op}`);
}
}
}
function compileLogicalExpression(expression, context) {
const op = expression.operator;
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
switch (op) {
case Ops.Any: {
return (context2) => {
for (let i = 0; i < length; ++i) {
if (args[i](context2)) {
return true;
}
}
return false;
};
}
case Ops.All: {
return (context2) => {
for (let i = 0; i < length; ++i) {
if (!args[i](context2)) {
return false;
}
}
return true;
};
}
case Ops.Between: {
return (context2) => {
const value = args[0](context2);
const min = args[1](context2);
const max = args[2](context2);
return value >= min && value <= max;
};
}
case Ops.In: {
return (context2) => {
const value = args[0](context2);
for (let i = 1; i < length; ++i) {
if (value === args[i](context2)) {
return true;
}
}
return false;
};
}
case Ops.Not: {
return (context2) => !args[0](context2);
}
default: {
throw new Error(`Unsupported logical operator ${op}`);
}
}
}
function compileNumericExpression(expression, context) {
const op = expression.operator;
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
switch (op) {
case Ops.Multiply: {
return (context2) => {
let value = 1;
for (let i = 0; i < length; ++i) {
value *= args[i](context2);
}
return value;
};
}
case Ops.Divide: {
return (context2) => args[0](context2) / args[1](context2);
}
case Ops.Add: {
return (context2) => {
let value = 0;
for (let i = 0; i < length; ++i) {
value += args[i](context2);
}
return value;
};
}
case Ops.Subtract: {
return (context2) => args[0](context2) - args[1](context2);
}
case Ops.Clamp: {
return (context2) => {
const value = args[0](context2);
const min = args[1](context2);
if (value < min) {
return min;
}
const max = args[2](context2);
if (value > max) {
return max;
}
return value;
};
}
case Ops.Mod: {
return (context2) => args[0](context2) % args[1](context2);
}
case Ops.Pow: {
return (context2) => Math.pow(args[0](context2), args[1](context2));
}
case Ops.Abs: {
return (context2) => Math.abs(args[0](context2));
}
case Ops.Floor: {
return (context2) => Math.floor(args[0](context2));
}
case Ops.Ceil: {
return (context2) => Math.ceil(args[0](context2));
}
case Ops.Round: {
return (context2) => Math.round(args[0](context2));
}
case Ops.Sin: {
return (context2) => Math.sin(args[0](context2));
}
case Ops.Cos: {
return (context2) => Math.cos(args[0](context2));
}
case Ops.Atan: {
if (length === 2) {
return (context2) => Math.atan2(args[0](context2), args[1](context2));
}
return (context2) => Math.atan(args[0](context2));
}
case Ops.Sqrt: {
return (context2) => Math.sqrt(args[0](context2));
}
default: {
throw new Error(`Unsupported numeric operator ${op}`);
}
}
}
function compileCaseExpression(expression, context) {
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
return (context2) => {
for (let i = 0; i < length - 1; i += 2) {
const condition = args[i](context2);
if (condition) {
return args[i + 1](context2);
}
}
return args[length - 1](context2);
};
}
function compileMatchExpression(expression, context) {
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
return (context2) => {
const value = args[0](context2);
for (let i = 1; i < length - 1; i += 2) {
if (value === args[i](context2)) {
return args[i + 1](context2);
}
}
return args[length - 1](context2);
};
}
function compileInterpolateExpression(expression, context) {
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
return (context2) => {
const base = args[0](context2);
const value = args[1](context2);
let previousInput;
let previousOutput;
for (let i = 2; i < length; i += 2) {
const input = args[i](context2);
let output = args[i + 1](context2);
const isColor = Array.isArray(output);
if (isColor) {
output = withAlpha(output);
}
if (input >= value) {
if (i === 2) {
return output;
}
if (isColor) {
return interpolateColor(
base,
value,
previousInput,
previousOutput,
input,
output
);
}
return interpolateNumber(
base,
value,
previousInput,
previousOutput,
input,
output
);
}
previousInput = input;
previousOutput = output;
}
return previousOutput;
};
}
function compileConvertExpression(expression, context) {
const op = expression.operator;
const length = expression.args.length;
const args = new Array(length);
for (let i = 0; i < length; ++i) {
args[i] = compileExpression(expression.args[i]);
}
switch (op) {
case Ops.ToString: {
return (context2) => {
const value = args[0](context2);
if (expression.args[0].type === ColorType) {
return toString(value);
}
return value.toString();
};
}
default: {
throw new Error(`Unsupported convert operator ${op}`);
}
}
}
function interpolateNumber(base, value, input1, output1, input2, output2) {
const delta = input2 - input1;
if (delta === 0) {
return output1;
}
const along = value - input1;
const factor = base === 1 ? along / delta : (Math.pow(base, along) - 1) / (Math.pow(base, delta) - 1);
return output1 + factor * (output2 - output1);
}
function interpolateColor(base, value, input1, rgba1, input2, rgba2) {
const delta = input2 - input1;
if (delta === 0) {
return rgba1;
}
const lcha1 = rgbaToLcha(rgba1);
const lcha2 = rgbaToLcha(rgba2);
let deltaHue = lcha2[2] - lcha1[2];
if (deltaHue > 180) {
deltaHue -= 360;
} else if (deltaHue < -180) {
deltaHue += 360;
}
const lcha = [
interpolateNumber(base, value, input1, lcha1[0], input2, lcha2[0]),
interpolateNumber(base, value, input1, lcha1[1], input2, lcha2[1]),
lcha1[2] + interpolateNumber(base, value, input1, 0, input2, deltaHue),
interpolateNumber(base, value, input1, rgba1[3], input2, rgba2[3])
];
return lchaToRgba(lcha);
}
function always(context) {
return true;
}
function rulesToStyleFunction(rules) {
const parsingContext = newParsingContext();
const evaluator = buildRuleSet(rules, parsingContext);
const evaluationContext = newEvaluationContext();
return function(feature2, resolution) {
evaluationContext.properties = feature2.getPropertiesInternal();
evaluationContext.resolution = resolution;
if (parsingContext.featureId) {
const id = feature2.getId();
if (id !== void 0) {
evaluationContext.featureId = id;
} else {
evaluationContext.featureId = null;
}
}
if (parsingContext.geometryType) {
evaluationContext.geometryType = computeGeometryType(
feature2.getGeometry()
);
}
return evaluator(evaluationContext);
};
}
function flatStylesToStyleFunction(flatStyles) {
const parsingContext = newParsingContext();
const length = flatStyles.length;
const evaluators = new Array(length);
for (let i = 0; i < length; ++i) {
evaluators[i] = buildStyle(flatStyles[i], parsingContext);
}
const evaluationContext = newEvaluationContext();
const styles = new Array(length);
return function(feature2, resolution) {
evaluationContext.properties = feature2.getPropertiesInternal();
evaluationContext.resolution = resolution;
if (parsingContext.featureId) {
const id = feature2.getId();
if (id !== void 0) {
evaluationContext.featureId = id;
} else {
evaluationContext.featureId = null;
}
}
let nonNullCount = 0;
for (let i = 0; i < length; ++i) {
const style = evaluators[i](evaluationContext);
if (style) {
styles[nonNullCount] = style;
nonNullCount += 1;
}
}
styles.length = nonNullCount;
return styles;
};
}
function buildRuleSet(rules, context) {
const length = rules.length;
const compiledRules = new Array(length);
for (let i = 0; i < length; ++i) {
const rule = rules[i];
const filter = "filter" in rule ? buildExpression(rule.filter, BooleanType, context) : always;
let styles;
if (Array.isArray(rule.style)) {
const styleLength = rule.style.length;
styles = new Array(styleLength);
for (let j = 0; j < styleLength; ++j) {
styles[j] = buildStyle(rule.style[j], context);
}
} else {
styles = [buildStyle(rule.style, context)];
}
compiledRules[i] = { filter, styles };
}
return function(context2) {
const styles = [];
let someMatched = false;
for (let i = 0; i < length; ++i) {
const filterEvaluator = compiledRules[i].filter;
if (!filterEvaluator(context2)) {
continue;
}
if (rules[i].else && someMatched) {
continue;
}
someMatched = true;
for (const styleEvaluator of compiledRules[i].styles) {
const style = styleEvaluator(context2);
if (!style) {
continue;
}
styles.push(style);
}
}
return styles;
};
}
function buildStyle(flatStyle, context) {
const evaluateFill = buildFill(flatStyle, "", context);
const evaluateStroke = buildStroke(flatStyle, "", context);
const evaluateText = buildText(flatStyle, context);
const evaluateImage = buildImage(flatStyle, context);
const evaluateZIndex = numberEvaluator(flatStyle, "z-index", context);
if (!evaluateFill && !evaluateStroke && !evaluateText && !evaluateImage && !isEmpty$1(flatStyle)) {
throw new Error(
"No fill, stroke, point, or text symbolizer properties in style: " + JSON.stringify(flatStyle)
);
}
const style = new Style();
return function(context2) {
let empty = true;
if (evaluateFill) {
const fill = evaluateFill(context2);
if (fill) {
empty = false;
}
style.setFill(fill);
}
if (evaluateStroke) {
const stroke = evaluateStroke(context2);
if (stroke) {
empty = false;
}
style.setStroke(stroke);
}
if (evaluateText) {
const text = evaluateText(context2);
if (text) {
empty = false;
}
style.setText(text);
}
if (evaluateImage) {
const image = evaluateImage(context2);
if (image) {
empty = false;
}
style.setImage(image);
}
if (evaluateZIndex) {
style.setZIndex(evaluateZIndex(context2));
}
if (empty) {
return null;
}
return style;
};
}
function buildFill(flatStyle, prefix, context) {
let evaluateColor;
if (prefix + "fill-pattern-src" in flatStyle) {
evaluateColor = patternEvaluator(flatStyle, prefix + "fill-", context);
} else {
if (flatStyle[prefix + "fill-color"] === "none") {
return (context2) => null;
}
evaluateColor = colorLikeEvaluator(
flatStyle,
prefix + "fill-color",
context
);
}
if (!evaluateColor) {
return null;
}
const fill = new Fill$1();
return function(context2) {
const color = evaluateColor(context2);
if (color === NO_COLOR) {
return null;
}
fill.setColor(color);
return fill;
};
}
function buildStroke(flatStyle, prefix, context) {
const evaluateWidth = numberEvaluator(
flatStyle,
prefix + "stroke-width",
context
);
const evaluateColor = colorLikeEvaluator(
flatStyle,
prefix + "stroke-color",
context
);
if (!evaluateWidth && !evaluateColor) {
return null;
}
const evaluateLineCap = stringEvaluator(
flatStyle,
prefix + "stroke-line-cap",
context
);
const evaluateLineJoin = stringEvaluator(
flatStyle,
prefix + "stroke-line-join",
context
);
const evaluateLineDash = numberArrayEvaluator(
flatStyle,
prefix + "stroke-line-dash",
context
);
const evaluateLineDashOffset = numberEvaluator(
flatStyle,
prefix + "stroke-line-dash-offset",
context
);
const evaluateMiterLimit = numberEvaluator(
flatStyle,
prefix + "stroke-miter-limit",
context
);
const stroke = new Stroke$1();
return function(context2) {
if (evaluateColor) {
const color = evaluateColor(context2);
if (color === NO_COLOR) {
return null;
}
stroke.setColor(color);
}
if (evaluateWidth) {
stroke.setWidth(evaluateWidth(context2));
}
if (evaluateLineCap) {
const lineCap = evaluateLineCap(context2);
if (lineCap !== "butt" && lineCap !== "round" && lineCap !== "square") {
throw new Error("Expected butt, round, or square line cap");
}
stroke.setLineCap(lineCap);
}
if (evaluateLineJoin) {
const lineJoin = evaluateLineJoin(context2);
if (lineJoin !== "bevel" && lineJoin !== "round" && lineJoin !== "miter") {
throw new Error("Expected bevel, round, or miter line join");
}
stroke.setLineJoin(lineJoin);
}
if (evaluateLineDash) {
stroke.setLineDash(evaluateLineDash(context2));
}
if (evaluateLineDashOffset) {
stroke.setLineDashOffset(evaluateLineDashOffset(context2));
}
if (evaluateMiterLimit) {
stroke.setMiterLimit(evaluateMiterLimit(context2));
}
return stroke;
};
}
function buildText(flatStyle, context) {
const prefix = "text-";
const evaluateValue = stringEvaluator(flatStyle, prefix + "value", context);
if (!evaluateValue) {
return null;
}
const evaluateFill = buildFill(flatStyle, prefix, context);
const evaluateBackgroundFill = buildFill(
flatStyle,
prefix + "background-",
context
);
const evaluateStroke = buildStroke(flatStyle, prefix, context);
const evaluateBackgroundStroke = buildStroke(
flatStyle,
prefix + "background-",
context
);
const evaluateFont = stringEvaluator(flatStyle, prefix + "font", context);
const evaluateMaxAngle = numberEvaluator(
flatStyle,
prefix + "max-angle",
context
);
const evaluateOffsetX = numberEvaluator(
flatStyle,
prefix + "offset-x",
context
);
const evaluateOffsetY = numberEvaluator(
flatStyle,
prefix + "offset-y",
context
);
const evaluateOverflow = booleanEvaluator(
flatStyle,
prefix + "overflow",
context
);
const evaluatePlacement = stringEvaluator(
flatStyle,
prefix + "placement",
context
);
const evaluateRepeat = numberEvaluator(flatStyle, prefix + "repeat", context);
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
const evaluateRotateWithView = booleanEvaluator(
flatStyle,
prefix + "rotate-with-view",
context
);
const evaluateRotation = numberEvaluator(
flatStyle,
prefix + "rotation",
context
);
const evaluateAlign = stringEvaluator(flatStyle, prefix + "align", context);
const evaluateJustify = stringEvaluator(
flatStyle,
prefix + "justify",
context
);
const evaluateBaseline = stringEvaluator(
flatStyle,
prefix + "baseline",
context
);
const evaluateKeepUpright = booleanEvaluator(
flatStyle,
prefix + "keep-upright",
context
);
const evaluatePadding = numberArrayEvaluator(
flatStyle,
prefix + "padding",
context
);
const declutterMode = optionalDeclutterMode(
flatStyle,
prefix + "declutter-mode"
);
const text = new Text$1({ declutterMode });
return function(context2) {
text.setText(evaluateValue(context2));
if (evaluateFill) {
text.setFill(evaluateFill(context2));
}
if (evaluateBackgroundFill) {
text.setBackgroundFill(evaluateBackgroundFill(context2));
}
if (evaluateStroke) {
text.setStroke(evaluateStroke(context2));
}
if (evaluateBackgroundStroke) {
text.setBackgroundStroke(evaluateBackgroundStroke(context2));
}
if (evaluateFont) {
text.setFont(evaluateFont(context2));
}
if (evaluateMaxAngle) {
text.setMaxAngle(evaluateMaxAngle(context2));
}
if (evaluateOffsetX) {
text.setOffsetX(evaluateOffsetX(context2));
}
if (evaluateOffsetY) {
text.setOffsetY(evaluateOffsetY(context2));
}
if (evaluateOverflow) {
text.setOverflow(evaluateOverflow(context2));
}
if (evaluatePlacement) {
const placement = evaluatePlacement(context2);
if (placement !== "point" && placement !== "line") {
throw new Error("Expected point or line for text-placement");
}
text.setPlacement(placement);
}
if (evaluateRepeat) {
text.setRepeat(evaluateRepeat(context2));
}
if (evaluateScale) {
text.setScale(evaluateScale(context2));
}
if (evaluateRotateWithView) {
text.setRotateWithView(evaluateRotateWithView(context2));
}
if (evaluateRotation) {
text.setRotation(evaluateRotation(context2));
}
if (evaluateAlign) {
const textAlign = evaluateAlign(context2);
if (textAlign !== "left" && textAlign !== "center" && textAlign !== "right" && textAlign !== "end" && textAlign !== "start") {
throw new Error(
"Expected left, right, center, start, or end for text-align"
);
}
text.setTextAlign(textAlign);
}
if (evaluateJustify) {
const justify = evaluateJustify(context2);
if (justify !== "left" && justify !== "right" && justify !== "center") {
throw new Error("Expected left, right, or center for text-justify");
}
text.setJustify(justify);
}
if (evaluateBaseline) {
const textBaseline = evaluateBaseline(context2);
if (textBaseline !== "bottom" && textBaseline !== "top" && textBaseline !== "middle" && textBaseline !== "alphabetic" && textBaseline !== "hanging") {
throw new Error(
"Expected bottom, top, middle, alphabetic, or hanging for text-baseline"
);
}
text.setTextBaseline(textBaseline);
}
if (evaluatePadding) {
text.setPadding(evaluatePadding(context2));
}
if (evaluateKeepUpright) {
text.setKeepUpright(evaluateKeepUpright(context2));
}
return text;
};
}
function buildImage(flatStyle, context) {
if ("icon-src" in flatStyle) {
return buildIcon(flatStyle, context);
}
if ("shape-points" in flatStyle) {
return buildShape(flatStyle, context);
}
if ("circle-radius" in flatStyle) {
return buildCircle(flatStyle, context);
}
return null;
}
function buildIcon(flatStyle, context) {
const prefix = "icon-";
const srcName = prefix + "src";
const src = requireString(flatStyle[srcName], srcName);
const evaluateAnchor = coordinateEvaluator(
flatStyle,
prefix + "anchor",
context
);
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
const evaluateOpacity = numberEvaluator(
flatStyle,
prefix + "opacity",
context
);
const evaluateDisplacement = coordinateEvaluator(
flatStyle,
prefix + "displacement",
context
);
const evaluateRotation = numberEvaluator(
flatStyle,
prefix + "rotation",
context
);
const evaluateRotateWithView = booleanEvaluator(
flatStyle,
prefix + "rotate-with-view",
context
);
const anchorOrigin = optionalIconOrigin(flatStyle, prefix + "anchor-origin");
const anchorXUnits = optionalIconAnchorUnits(
flatStyle,
prefix + "anchor-x-units"
);
const anchorYUnits = optionalIconAnchorUnits(
flatStyle,
prefix + "anchor-y-units"
);
const color = optionalColorLike(flatStyle, prefix + "color");
const crossOrigin = optionalString(flatStyle, prefix + "cross-origin");
const offset = optionalNumberArray(flatStyle, prefix + "offset");
const offsetOrigin = optionalIconOrigin(flatStyle, prefix + "offset-origin");
const width = optionalNumber(flatStyle, prefix + "width");
const height = optionalNumber(flatStyle, prefix + "height");
const size = optionalSize(flatStyle, prefix + "size");
const declutterMode = optionalDeclutterMode(
flatStyle,
prefix + "declutter-mode"
);
const icon = new Icon$1({
src,
anchorOrigin,
anchorXUnits,
anchorYUnits,
color,
crossOrigin,
offset,
offsetOrigin,
height,
width,
size,
declutterMode
});
return function(context2) {
if (evaluateOpacity) {
icon.setOpacity(evaluateOpacity(context2));
}
if (evaluateDisplacement) {
icon.setDisplacement(evaluateDisplacement(context2));
}
if (evaluateRotation) {
icon.setRotation(evaluateRotation(context2));
}
if (evaluateRotateWithView) {
icon.setRotateWithView(evaluateRotateWithView(context2));
}
if (evaluateScale) {
icon.setScale(evaluateScale(context2));
}
if (evaluateAnchor) {
icon.setAnchor(evaluateAnchor(context2));
}
return icon;
};
}
function buildShape(flatStyle, context) {
const prefix = "shape-";
const pointsName = prefix + "points";
const radiusName = prefix + "radius";
const points = requireNumber(flatStyle[pointsName], pointsName);
const radius = requireNumber(flatStyle[radiusName], radiusName);
const evaluateFill = buildFill(flatStyle, prefix, context);
const evaluateStroke = buildStroke(flatStyle, prefix, context);
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
const evaluateDisplacement = coordinateEvaluator(
flatStyle,
prefix + "displacement",
context
);
const evaluateRotation = numberEvaluator(
flatStyle,
prefix + "rotation",
context
);
const evaluateRotateWithView = booleanEvaluator(
flatStyle,
prefix + "rotate-with-view",
context
);
const radius2 = optionalNumber(flatStyle, prefix + "radius2");
const angle = optionalNumber(flatStyle, prefix + "angle");
const declutterMode = optionalDeclutterMode(
flatStyle,
prefix + "declutter-mode"
);
const shape = new RegularShape$1({
points,
radius,
radius2,
angle,
declutterMode
});
return function(context2) {
if (evaluateFill) {
shape.setFill(evaluateFill(context2));
}
if (evaluateStroke) {
shape.setStroke(evaluateStroke(context2));
}
if (evaluateDisplacement) {
shape.setDisplacement(evaluateDisplacement(context2));
}
if (evaluateRotation) {
shape.setRotation(evaluateRotation(context2));
}
if (evaluateRotateWithView) {
shape.setRotateWithView(evaluateRotateWithView(context2));
}
if (evaluateScale) {
shape.setScale(evaluateScale(context2));
}
return shape;
};
}
function buildCircle(flatStyle, context) {
const prefix = "circle-";
const evaluateFill = buildFill(flatStyle, prefix, context);
const evaluateStroke = buildStroke(flatStyle, prefix, context);
const evaluateRadius = numberEvaluator(flatStyle, prefix + "radius", context);
const evaluateScale = sizeLikeEvaluator(flatStyle, prefix + "scale", context);
const evaluateDisplacement = coordinateEvaluator(
flatStyle,
prefix + "displacement",
context
);
const evaluateRotation = numberEvaluator(
flatStyle,
prefix + "rotation",
context
);
const evaluateRotateWithView = booleanEvaluator(
flatStyle,
prefix + "rotate-with-view",
context
);
const declutterMode = optionalDeclutterMode(
flatStyle,
prefix + "declutter-mode"
);
const circle = new Circle({
radius: 5,
declutterMode
});
return function(context2) {
if (evaluateRadius) {
circle.setRadius(evaluateRadius(context2));
}
if (evaluateFill) {
circle.setFill(evaluateFill(context2));
}
if (evaluateStroke) {
circle.setStroke(evaluateStroke(context2));
}
if (evaluateDisplacement) {
circle.setDisplacement(evaluateDisplacement(context2));
}
if (evaluateRotation) {
circle.setRotation(evaluateRotation(context2));
}
if (evaluateRotateWithView) {
circle.setRotateWithView(evaluateRotateWithView(context2));
}
if (evaluateScale) {
circle.setScale(evaluateScale(context2));
}
return circle;
};
}
function numberEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return void 0;
}
const evaluator = buildExpression(flatStyle[name], NumberType, context);
return function(context2) {
return requireNumber(evaluator(context2), name);
};
}
function stringEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(flatStyle[name], StringType, context);
return function(context2) {
return requireString(evaluator(context2), name);
};
}
function patternEvaluator(flatStyle, prefix, context) {
const srcEvaluator = stringEvaluator(
flatStyle,
prefix + "pattern-src",
context
);
const offsetEvaluator = sizeEvaluator(
flatStyle,
prefix + "pattern-offset",
context
);
const patternSizeEvaluator = sizeEvaluator(
flatStyle,
prefix + "pattern-size",
context
);
const colorEvaluator = colorLikeEvaluator(
flatStyle,
prefix + "color",
context
);
return function(context2) {
return {
src: srcEvaluator(context2),
offset: offsetEvaluator && offsetEvaluator(context2),
size: patternSizeEvaluator && patternSizeEvaluator(context2),
color: colorEvaluator && colorEvaluator(context2)
};
};
}
function booleanEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(flatStyle[name], BooleanType, context);
return function(context2) {
const value = evaluator(context2);
if (typeof value !== "boolean") {
throw new Error(`Expected a boolean for ${name}`);
}
return value;
};
}
function colorLikeEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(flatStyle[name], ColorType, context);
return function(context2) {
return requireColorLike(evaluator(context2), name);
};
}
function numberArrayEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
return function(context2) {
return requireNumberArray(evaluator(context2), name);
};
}
function coordinateEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
return function(context2) {
const array = requireNumberArray(evaluator(context2), name);
if (array.length !== 2) {
throw new Error(`Expected two numbers for ${name}`);
}
return array;
};
}
function sizeEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(flatStyle[name], NumberArrayType, context);
return function(context2) {
return requireSize(evaluator(context2), name);
};
}
function sizeLikeEvaluator(flatStyle, name, context) {
if (!(name in flatStyle)) {
return null;
}
const evaluator = buildExpression(
flatStyle[name],
NumberArrayType | NumberType,
context
);
return function(context2) {
return requireSizeLike(evaluator(context2), name);
};
}
function optionalNumber(flatStyle, property) {
const value = flatStyle[property];
if (value === void 0) {
return void 0;
}
if (typeof value !== "number") {
throw new Error(`Expected a number for ${property}`);
}
return value;
}
function optionalSize(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
if (typeof encoded === "number") {
return toSize(encoded);
}
if (!Array.isArray(encoded)) {
throw new Error(`Expected a number or size array for ${property}`);
}
if (encoded.length !== 2 || typeof encoded[0] !== "number" || typeof encoded[1] !== "number") {
throw new Error(`Expected a number or size array for ${property}`);
}
return encoded;
}
function optionalString(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
if (typeof encoded !== "string") {
throw new Error(`Expected a string for ${property}`);
}
return encoded;
}
function optionalIconOrigin(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
if (encoded !== "bottom-left" && encoded !== "bottom-right" && encoded !== "top-left" && encoded !== "top-right") {
throw new Error(
`Expected bottom-left, bottom-right, top-left, or top-right for ${property}`
);
}
return encoded;
}
function optionalIconAnchorUnits(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
if (encoded !== "pixels" && encoded !== "fraction") {
throw new Error(`Expected pixels or fraction for ${property}`);
}
return encoded;
}
function optionalNumberArray(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
return requireNumberArray(encoded, property);
}
function optionalDeclutterMode(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
if (typeof encoded !== "string") {
throw new Error(`Expected a string for ${property}`);
}
if (encoded !== "declutter" && encoded !== "obstacle" && encoded !== "none") {
throw new Error(`Expected declutter, obstacle, or none for ${property}`);
}
return encoded;
}
function optionalColorLike(flatStyle, property) {
const encoded = flatStyle[property];
if (encoded === void 0) {
return void 0;
}
return requireColorLike(encoded, property);
}
function requireNumberArray(value, property) {
if (!Array.isArray(value)) {
throw new Error(`Expected an array for ${property}`);
}
const length = value.length;
for (let i = 0; i < length; ++i) {
if (typeof value[i] !== "number") {
throw new Error(`Expected an array of numbers for ${property}`);
}
}
return value;
}
function requireString(value, property) {
if (typeof value !== "string") {
throw new Error(`Expected a string for ${property}`);
}
return value;
}
function requireNumber(value, property) {
if (typeof value !== "number") {
throw new Error(`Expected a number for ${property}`);
}
return value;
}
function requireColorLike(value, property) {
if (typeof value === "string") {
return value;
}
const array = requireNumberArray(value, property);
const length = array.length;
if (length < 3 || length > 4) {
throw new Error(`Expected a color with 3 or 4 values for ${property}`);
}
return array;
}
function requireSize(value, property) {
const size = requireNumberArray(value, property);
if (size.length !== 2) {
throw new Error(`Expected an array of two numbers for ${property}`);
}
return size;
}
function requireSizeLike(value, property) {
if (typeof value === "number") {
return value;
}
return requireSize(value, property);
}
const ViewProperty = {
CENTER: "center",
RESOLUTION: "resolution",
ROTATION: "rotation"
};
function createExtent(extent, onlyCenter, smooth) {
return function(center, resolution, size, isMoving, centerShift) {
if (!center) {
return void 0;
}
if (!resolution && !onlyCenter) {
return center;
}
const viewWidth = onlyCenter ? 0 : size[0] * resolution;
const viewHeight = onlyCenter ? 0 : size[1] * resolution;
const shiftX = centerShift ? centerShift[0] : 0;
const shiftY = centerShift ? centerShift[1] : 0;
let minX = extent[0] + viewWidth / 2 + shiftX;
let maxX = extent[2] - viewWidth / 2 + shiftX;
let minY = extent[1] + viewHeight / 2 + shiftY;
let maxY = extent[3] - viewHeight / 2 + shiftY;
if (minX > maxX) {
minX = (maxX + minX) / 2;
maxX = minX;
}
if (minY > maxY) {
minY = (maxY + minY) / 2;
maxY = minY;
}
let x = clamp(center[0], minX, maxX);
let y = clamp(center[1], minY, maxY);
if (isMoving && smooth && resolution) {
const ratio = 30 * resolution;
x += -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) + ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);
y += -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) + ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);
}
return [x, y];
};
}
function none$1(center) {
return center;
}
function easeIn(t) {
return Math.pow(t, 3);
}
function easeOut(t) {
return 1 - easeIn(1 - t);
}
function inAndOut(t) {
return 3 * t * t - 2 * t * t * t;
}
function getViewportClampedResolution(resolution, maxExtent, viewportSize, showFullExtent) {
const xResolution = getWidth(maxExtent) / viewportSize[0];
const yResolution = getHeight(maxExtent) / viewportSize[1];
if (showFullExtent) {
return Math.min(resolution, Math.max(xResolution, yResolution));
}
return Math.min(resolution, Math.min(xResolution, yResolution));
}
function getSmoothClampedResolution(resolution, maxResolution, minResolution) {
let result = Math.min(resolution, maxResolution);
const ratio = 50;
result *= Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio + 1;
if (minResolution) {
result = Math.max(result, minResolution);
result /= Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) / ratio + 1;
}
return clamp(result, minResolution / 2, maxResolution * 2);
}
function createSnapToResolutions(resolutions, smooth, maxExtent, showFullExtent) {
smooth = smooth !== void 0 ? smooth : true;
return function(resolution, direction, size, isMoving) {
if (resolution !== void 0) {
const maxResolution = resolutions[0];
const minResolution = resolutions[resolutions.length - 1];
const cappedMaxRes = maxExtent ? getViewportClampedResolution(
maxResolution,
maxExtent,
size,
showFullExtent
) : maxResolution;
if (isMoving) {
if (!smooth) {
return clamp(resolution, minResolution, cappedMaxRes);
}
return getSmoothClampedResolution(
resolution,
cappedMaxRes,
minResolution
);
}
const capped = Math.min(cappedMaxRes, resolution);
const z = Math.floor(linearFindNearest(resolutions, capped, direction));
if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {
return resolutions[z + 1];
}
return resolutions[z];
}
return void 0;
};
}
function createSnapToPower(power, maxResolution, minResolution, smooth, maxExtent, showFullExtent) {
smooth = smooth !== void 0 ? smooth : true;
minResolution = minResolution !== void 0 ? minResolution : 0;
return function(resolution, direction, size, isMoving) {
if (resolution !== void 0) {
const cappedMaxRes = maxExtent ? getViewportClampedResolution(
maxResolution,
maxExtent,
size,
showFullExtent
) : maxResolution;
if (isMoving) {
if (!smooth) {
return clamp(resolution, minResolution, cappedMaxRes);
}
return getSmoothClampedResolution(
resolution,
cappedMaxRes,
minResolution
);
}
const tolerance = 1e-9;
const minZoomLevel = Math.ceil(
Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance
);
const offset = -direction * (0.5 - tolerance) + 0.5;
const capped = Math.min(cappedMaxRes, resolution);
const cappedZoomLevel = Math.floor(
Math.log(maxResolution / capped) / Math.log(power) + offset
);
const zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);
const newResolution = maxResolution / Math.pow(power, zoomLevel);
return clamp(newResolution, minResolution, cappedMaxRes);
}
return void 0;
};
}
function createMinMaxResolution(maxResolution, minResolution, smooth, maxExtent, showFullExtent) {
smooth = smooth !== void 0 ? smooth : true;
return function(resolution, direction, size, isMoving) {
if (resolution !== void 0) {
const cappedMaxRes = maxExtent ? getViewportClampedResolution(
maxResolution,
maxExtent,
size,
showFullExtent
) : maxResolution;
if (!smooth || !isMoving) {
return clamp(resolution, minResolution, cappedMaxRes);
}
return getSmoothClampedResolution(
resolution,
cappedMaxRes,
minResolution
);
}
return void 0;
};
}
function disable(rotation) {
if (rotation !== void 0) {
return 0;
}
return void 0;
}
function none(rotation) {
if (rotation !== void 0) {
return rotation;
}
return void 0;
}
function createSnapToN(n) {
const theta = 2 * Math.PI / n;
return function(rotation, isMoving) {
if (isMoving) {
return rotation;
}
if (rotation !== void 0) {
rotation = Math.floor(rotation / theta + 0.5) * theta;
return rotation;
}
return void 0;
};
}
function createSnapToZero(tolerance) {
const t = tolerance === void 0 ? toRadians(5) : tolerance;
return function(rotation, isMoving) {
if (isMoving || rotation === void 0) {
return rotation;
}
if (Math.abs(rotation) <= t) {
return 0;
}
return rotation;
};
}
const DEFAULT_TILE_SIZE = 256;
const DEFAULT_MIN_ZOOM = 0;
class View extends BaseObject$1 {
constructor(options) {
super();
this.on;
this.once;
this.un;
options = Object.assign({}, options);
this.hints_ = [0, 0];
this.animations_ = [];
this.updateAnimationKey_;
this.projection_ = createProjection(options.projection, "EPSG:3857");
this.viewportSize_ = [100, 100];
this.targetCenter_ = null;
this.targetResolution_;
this.targetRotation_;
this.nextCenter_ = null;
this.nextResolution_;
this.nextRotation_;
this.cancelAnchor_ = void 0;
if (options.projection) {
disableCoordinateWarning();
}
if (options.center) {
options.center = fromUserCoordinate(options.center, this.projection_);
}
if (options.extent) {
options.extent = fromUserExtent(options.extent, this.projection_);
}
this.applyOptions_(options);
}
applyOptions_(options) {
const properties = Object.assign({}, options);
for (const key in ViewProperty) {
delete properties[key];
}
this.setProperties(properties, true);
const resolutionConstraintInfo = createResolutionConstraint(options);
this.maxResolution_ = resolutionConstraintInfo.maxResolution;
this.minResolution_ = resolutionConstraintInfo.minResolution;
this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;
this.resolutions_ = options.resolutions;
this.padding_ = options.padding;
this.minZoom_ = resolutionConstraintInfo.minZoom;
const centerConstraint = createCenterConstraint(options);
const resolutionConstraint = resolutionConstraintInfo.constraint;
const rotationConstraint = createRotationConstraint(options);
this.constraints_ = {
center: centerConstraint,
resolution: resolutionConstraint,
rotation: rotationConstraint
};
this.setRotation(options.rotation !== void 0 ? options.rotation : 0);
this.setCenterInternal(
options.center !== void 0 ? options.center : null
);
if (options.resolution !== void 0) {
this.setResolution(options.resolution);
} else if (options.zoom !== void 0) {
this.setZoom(options.zoom);
}
}
get padding() {
return this.padding_;
}
set padding(padding) {
let oldPadding = this.padding_;
this.padding_ = padding;
const center = this.getCenterInternal();
if (center) {
const newPadding = padding || [0, 0, 0, 0];
oldPadding = oldPadding || [0, 0, 0, 0];
const resolution = this.getResolution();
const offsetX = resolution / 2 * (newPadding[3] - oldPadding[3] + oldPadding[1] - newPadding[1]);
const offsetY = resolution / 2 * (newPadding[0] - oldPadding[0] + oldPadding[2] - newPadding[2]);
this.setCenterInternal([center[0] + offsetX, center[1] - offsetY]);
}
}
getUpdatedOptions_(newOptions) {
const options = this.getProperties();
if (options.resolution !== void 0) {
options.resolution = this.getResolution();
} else {
options.zoom = this.getZoom();
}
options.center = this.getCenterInternal();
options.rotation = this.getRotation();
return Object.assign({}, options, newOptions);
}
animate(var_args) {
if (this.isDef() && !this.getAnimating()) {
this.resolveConstraints(0);
}
const args = new Array(arguments.length);
for (let i = 0; i < args.length; ++i) {
let options = arguments[i];
if (options.center) {
options = Object.assign({}, options);
options.center = fromUserCoordinate(
options.center,
this.getProjection()
);
}
if (options.anchor) {
options = Object.assign({}, options);
options.anchor = fromUserCoordinate(
options.anchor,
this.getProjection()
);
}
args[i] = options;
}
this.animateInternal.apply(this, args);
}
animateInternal(var_args) {
let animationCount = arguments.length;
let callback;
if (animationCount > 1 && typeof arguments[animationCount - 1] === "function") {
callback = arguments[animationCount - 1];
--animationCount;
}
let i = 0;
for (; i < animationCount && !this.isDef(); ++i) {
const state = arguments[i];
if (state.center) {
this.setCenterInternal(state.center);
}
if (state.zoom !== void 0) {
this.setZoom(state.zoom);
} else if (state.resolution) {
this.setResolution(state.resolution);
}
if (state.rotation !== void 0) {
this.setRotation(state.rotation);
}
}
if (i === animationCount) {
if (callback) {
animationCallback(callback, true);
}
return;
}
let start = Date.now();
let center = this.targetCenter_.slice();
let resolution = this.targetResolution_;
let rotation = this.targetRotation_;
const series = [];
for (; i < animationCount; ++i) {
const options = arguments[i];
const animation = {
start,
complete: false,
anchor: options.anchor,
duration: options.duration !== void 0 ? options.duration : 1e3,
easing: options.easing || inAndOut,
callback
};
if (options.center) {
animation.sourceCenter = center;
animation.targetCenter = options.center.slice();
center = animation.targetCenter;
}
if (options.zoom !== void 0) {
animation.sourceResolution = resolution;
animation.targetResolution = this.getResolutionForZoom(options.zoom);
resolution = animation.targetResolution;
} else if (options.resolution) {
animation.sourceResolution = resolution;
animation.targetResolution = options.resolution;
resolution = animation.targetResolution;
}
if (options.rotation !== void 0) {
animation.sourceRotation = rotation;
const delta = modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;
animation.targetRotation = rotation + delta;
rotation = animation.targetRotation;
}
if (isNoopAnimation(animation)) {
animation.complete = true;
} else {
start += animation.duration;
}
series.push(animation);
}
this.animations_.push(series);
this.setHint(ViewHint.ANIMATING, 1);
this.updateAnimations_();
}
getAnimating() {
return this.hints_[ViewHint.ANIMATING] > 0;
}
getInteracting() {
return this.hints_[ViewHint.INTERACTING] > 0;
}
cancelAnimations() {
this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);
let anchor;
for (let i = 0, ii = this.animations_.length; i < ii; ++i) {
const series = this.animations_[i];
if (series[0].callback) {
animationCallback(series[0].callback, false);
}
if (!anchor) {
for (let j = 0, jj = series.length; j < jj; ++j) {
const animation = series[j];
if (!animation.complete) {
anchor = animation.anchor;
break;
}
}
}
}
this.animations_.length = 0;
this.cancelAnchor_ = anchor;
this.nextCenter_ = null;
this.nextResolution_ = NaN;
this.nextRotation_ = NaN;
}
updateAnimations_() {
if (this.updateAnimationKey_ !== void 0) {
cancelAnimationFrame(this.updateAnimationKey_);
this.updateAnimationKey_ = void 0;
}
if (!this.getAnimating()) {
return;
}
const now = Date.now();
let more = false;
for (let i = this.animations_.length - 1; i >= 0; --i) {
const series = this.animations_[i];
let seriesComplete = true;
for (let j = 0, jj = series.length; j < jj; ++j) {
const animation = series[j];
if (animation.complete) {
continue;
}
const elapsed = now - animation.start;
let fraction = animation.duration > 0 ? elapsed / animation.duration : 1;
if (fraction >= 1) {
animation.complete = true;
fraction = 1;
} else {
seriesComplete = false;
}
const progress = animation.easing(fraction);
if (animation.sourceCenter) {
const x0 = animation.sourceCenter[0];
const y0 = animation.sourceCenter[1];
const x1 = animation.targetCenter[0];
const y1 = animation.targetCenter[1];
this.nextCenter_ = animation.targetCenter;
const x = x0 + progress * (x1 - x0);
const y = y0 + progress * (y1 - y0);
this.targetCenter_ = [x, y];
}
if (animation.sourceResolution && animation.targetResolution) {
const resolution = progress === 1 ? animation.targetResolution : animation.sourceResolution + progress * (animation.targetResolution - animation.sourceResolution);
if (animation.anchor) {
const size = this.getViewportSize_(this.getRotation());
const constrainedResolution = this.constraints_.resolution(
resolution,
0,
size,
true
);
this.targetCenter_ = this.calculateCenterZoom(
constrainedResolution,
animation.anchor
);
}
this.nextResolution_ = animation.targetResolution;
this.targetResolution_ = resolution;
this.applyTargetState_(true);
}
if (animation.sourceRotation !== void 0 && animation.targetRotation !== void 0) {
const rotation = progress === 1 ? modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI : animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);
if (animation.anchor) {
const constrainedRotation = this.constraints_.rotation(
rotation,
true
);
this.targetCenter_ = this.calculateCenterRotate(
constrainedRotation,
animation.anchor
);
}
this.nextRotation_ = animation.targetRotation;
this.targetRotation_ = rotation;
}
this.applyTargetState_(true);
more = true;
if (!animation.complete) {
break;
}
}
if (seriesComplete) {
this.animations_[i] = null;
this.setHint(ViewHint.ANIMATING, -1);
this.nextCenter_ = null;
this.nextResolution_ = NaN;
this.nextRotation_ = NaN;
const callback = series[0].callback;
if (callback) {
animationCallback(callback, true);
}
}
}
this.animations_ = this.animations_.filter(Boolean);
if (more && this.updateAnimationKey_ === void 0) {
this.updateAnimationKey_ = requestAnimationFrame(
this.updateAnimations_.bind(this)
);
}
}
calculateCenterRotate(rotation, anchor) {
let center;
const currentCenter = this.getCenterInternal();
if (currentCenter !== void 0) {
center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];
rotate$1(center, rotation - this.getRotation());
add$2(center, anchor);
}
return center;
}
calculateCenterZoom(resolution, anchor) {
let center;
const currentCenter = this.getCenterInternal();
const currentResolution = this.getResolution();
if (currentCenter !== void 0 && currentResolution !== void 0) {
const x = anchor[0] - resolution * (anchor[0] - currentCenter[0]) / currentResolution;
const y = anchor[1] - resolution * (anchor[1] - currentCenter[1]) / currentResolution;
center = [x, y];
}
return center;
}
getViewportSize_(rotation) {
const size = this.viewportSize_;
if (rotation) {
const w = size[0];
const h = size[1];
return [
Math.abs(w * Math.cos(rotation)) + Math.abs(h * Math.sin(rotation)),
Math.abs(w * Math.sin(rotation)) + Math.abs(h * Math.cos(rotation))
];
}
return size;
}
setViewportSize(size) {
this.viewportSize_ = Array.isArray(size) ? size.slice() : [100, 100];
if (!this.getAnimating()) {
this.resolveConstraints(0);
}
}
getCenter() {
const center = this.getCenterInternal();
if (!center) {
return center;
}
return toUserCoordinate(center, this.getProjection());
}
getCenterInternal() {
return this.get(ViewProperty.CENTER);
}
getConstraints() {
return this.constraints_;
}
getConstrainResolution() {
return this.get("constrainResolution");
}
getHints(hints) {
if (hints !== void 0) {
hints[0] = this.hints_[0];
hints[1] = this.hints_[1];
return hints;
}
return this.hints_.slice();
}
calculateExtent(size) {
const extent = this.calculateExtentInternal(size);
return toUserExtent(extent, this.getProjection());
}
calculateExtentInternal(size) {
size = size || this.getViewportSizeMinusPadding_();
const center = this.getCenterInternal();
assert(center, "The view center is not defined");
const resolution = this.getResolution();
assert(resolution !== void 0, "The view resolution is not defined");
const rotation = this.getRotation();
assert(rotation !== void 0, "The view rotation is not defined");
return getForViewAndSize(center, resolution, rotation, size);
}
getMaxResolution() {
return this.maxResolution_;
}
getMinResolution() {
return this.minResolution_;
}
getMaxZoom() {
return this.getZoomForResolution(this.minResolution_);
}
setMaxZoom(zoom) {
this.applyOptions_(this.getUpdatedOptions_({ maxZoom: zoom }));
}
getMinZoom() {
return this.getZoomForResolution(this.maxResolution_);
}
setMinZoom(zoom) {
this.applyOptions_(this.getUpdatedOptions_({ minZoom: zoom }));
}
setConstrainResolution(enabled) {
this.applyOptions_(this.getUpdatedOptions_({ constrainResolution: enabled }));
}
getProjection() {
return this.projection_;
}
getResolution() {
return this.get(ViewProperty.RESOLUTION);
}
getResolutions() {
return this.resolutions_;
}
getResolutionForExtent(extent, size) {
return this.getResolutionForExtentInternal(
fromUserExtent(extent, this.getProjection()),
size
);
}
getResolutionForExtentInternal(extent, size) {
size = size || this.getViewportSizeMinusPadding_();
const xResolution = getWidth(extent) / size[0];
const yResolution = getHeight(extent) / size[1];
return Math.max(xResolution, yResolution);
}
getResolutionForValueFunction(power) {
power = power || 2;
const maxResolution = this.getConstrainedResolution(this.maxResolution_);
const minResolution = this.minResolution_;
const max = Math.log(maxResolution / minResolution) / Math.log(power);
return function(value) {
const resolution = maxResolution / Math.pow(power, value * max);
return resolution;
};
}
getRotation() {
return this.get(ViewProperty.ROTATION);
}
getValueForResolutionFunction(power) {
const logPower = Math.log(power || 2);
const maxResolution = this.getConstrainedResolution(this.maxResolution_);
const minResolution = this.minResolution_;
const max = Math.log(maxResolution / minResolution) / logPower;
return function(resolution) {
const value = Math.log(maxResolution / resolution) / logPower / max;
return value;
};
}
getViewportSizeMinusPadding_(rotation) {
let size = this.getViewportSize_(rotation);
const padding = this.padding_;
if (padding) {
size = [
size[0] - padding[1] - padding[3],
size[1] - padding[0] - padding[2]
];
}
return size;
}
getState() {
const projection = this.getProjection();
const resolution = this.getResolution();
const rotation = this.getRotation();
let center = this.getCenterInternal();
const padding = this.padding_;
if (padding) {
const reducedSize = this.getViewportSizeMinusPadding_();
center = calculateCenterOn(
center,
this.getViewportSize_(),
[reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],
resolution,
rotation
);
}
return {
center: center.slice(0),
projection: projection !== void 0 ? projection : null,
resolution,
nextCenter: this.nextCenter_,
nextResolution: this.nextResolution_,
nextRotation: this.nextRotation_,
rotation,
zoom: this.getZoom()
};
}
getViewStateAndExtent() {
return {
viewState: this.getState(),
extent: this.calculateExtent()
};
}
getZoom() {
let zoom;
const resolution = this.getResolution();
if (resolution !== void 0) {
zoom = this.getZoomForResolution(resolution);
}
return zoom;
}
getZoomForResolution(resolution) {
let offset = this.minZoom_ || 0;
let max, zoomFactor;
if (this.resolutions_) {
const nearest = linearFindNearest(this.resolutions_, resolution, 1);
offset = nearest;
max = this.resolutions_[nearest];
if (nearest == this.resolutions_.length - 1) {
zoomFactor = 2;
} else {
zoomFactor = max / this.resolutions_[nearest + 1];
}
} else {
max = this.maxResolution_;
zoomFactor = this.zoomFactor_;
}
return offset + Math.log(max / resolution) / Math.log(zoomFactor);
}
getResolutionForZoom(zoom) {
var _a;
if ((_a = this.resolutions_) == null ? void 0 : _a.length) {
if (this.resolutions_.length === 1) {
return this.resolutions_[0];
}
const baseLevel = clamp(
Math.floor(zoom),
0,
this.resolutions_.length - 2
);
const zoomFactor = this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];
return this.resolutions_[baseLevel] / Math.pow(zoomFactor, clamp(zoom - baseLevel, 0, 1));
}
return this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_);
}
fit(geometryOrExtent, options) {
let geometry;
assert(
Array.isArray(geometryOrExtent) || typeof geometryOrExtent.getSimplifiedGeometry === "function",
"Invalid extent or geometry provided as `geometry`"
);
if (Array.isArray(geometryOrExtent)) {
assert(
!isEmpty(geometryOrExtent),
"Cannot fit empty extent provided as `geometry`"
);
const extent = fromUserExtent(geometryOrExtent, this.getProjection());
geometry = fromExtent(extent);
} else if (geometryOrExtent.getType() === "Circle") {
const extent = fromUserExtent(
geometryOrExtent.getExtent(),
this.getProjection()
);
geometry = fromExtent(extent);
geometry.rotate(this.getRotation(), getCenter(extent));
} else {
{
geometry = geometryOrExtent;
}
}
this.fitInternal(geometry, options);
}
rotatedExtentForGeometry(geometry) {
const rotation = this.getRotation();
const cosAngle = Math.cos(rotation);
const sinAngle = Math.sin(-rotation);
const coords = geometry.getFlatCoordinates();
const stride = geometry.getStride();
let minRotX = Infinity;
let minRotY = Infinity;
let maxRotX = -Infinity;
let maxRotY = -Infinity;
for (let i = 0, ii = coords.length; i < ii; i += stride) {
const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;
const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;
minRotX = Math.min(minRotX, rotX);
minRotY = Math.min(minRotY, rotY);
maxRotX = Math.max(maxRotX, rotX);
maxRotY = Math.max(maxRotY, rotY);
}
return [minRotX, minRotY, maxRotX, maxRotY];
}
fitInternal(geometry, options) {
options = options || {};
let size = options.size;
if (!size) {
size = this.getViewportSizeMinusPadding_();
}
const padding = options.padding !== void 0 ? options.padding : [0, 0, 0, 0];
const nearest = options.nearest !== void 0 ? options.nearest : false;
let minResolution;
if (options.minResolution !== void 0) {
minResolution = options.minResolution;
} else if (options.maxZoom !== void 0) {
minResolution = this.getResolutionForZoom(options.maxZoom);
} else {
minResolution = 0;
}
const rotatedExtent = this.rotatedExtentForGeometry(geometry);
let resolution = this.getResolutionForExtentInternal(rotatedExtent, [
size[0] - padding[1] - padding[3],
size[1] - padding[0] - padding[2]
]);
resolution = isNaN(resolution) ? minResolution : Math.max(resolution, minResolution);
resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1);
const rotation = this.getRotation();
const sinAngle = Math.sin(rotation);
const cosAngle = Math.cos(rotation);
const centerRot = getCenter(rotatedExtent);
centerRot[0] += (padding[1] - padding[3]) / 2 * resolution;
centerRot[1] += (padding[0] - padding[2]) / 2 * resolution;
const centerX = centerRot[0] * cosAngle - centerRot[1] * sinAngle;
const centerY = centerRot[1] * cosAngle + centerRot[0] * sinAngle;
const center = this.getConstrainedCenter([centerX, centerY], resolution);
const callback = options.callback ? options.callback : VOID;
if (options.duration !== void 0) {
this.animateInternal(
{
resolution,
center,
duration: options.duration,
easing: options.easing
},
callback
);
} else {
this.targetResolution_ = resolution;
this.targetCenter_ = center;
this.applyTargetState_(false, true);
animationCallback(callback, true);
}
}
centerOn(coordinate, size, position) {
this.centerOnInternal(
fromUserCoordinate(coordinate, this.getProjection()),
size,
position
);
}
centerOnInternal(coordinate, size, position) {
this.setCenterInternal(
calculateCenterOn(
coordinate,
size,
position,
this.getResolution(),
this.getRotation()
)
);
}
calculateCenterShift(center, resolution, rotation, size) {
let centerShift;
const padding = this.padding_;
if (padding && center) {
const reducedSize = this.getViewportSizeMinusPadding_(-rotation);
const shiftedCenter = calculateCenterOn(
center,
size,
[reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],
resolution,
rotation
);
centerShift = [
center[0] - shiftedCenter[0],
center[1] - shiftedCenter[1]
];
}
return centerShift;
}
isDef() {
return !!this.getCenterInternal() && this.getResolution() !== void 0;
}
adjustCenter(deltaCoordinates) {
const center = toUserCoordinate(this.targetCenter_, this.getProjection());
this.setCenter([
center[0] + deltaCoordinates[0],
center[1] + deltaCoordinates[1]
]);
}
adjustCenterInternal(deltaCoordinates) {
const center = this.targetCenter_;
this.setCenterInternal([
center[0] + deltaCoordinates[0],
center[1] + deltaCoordinates[1]
]);
}
adjustResolution(ratio, anchor) {
anchor = anchor && fromUserCoordinate(anchor, this.getProjection());
this.adjustResolutionInternal(ratio, anchor);
}
adjustResolutionInternal(ratio, anchor) {
const isMoving = this.getAnimating() || this.getInteracting();
const size = this.getViewportSize_(this.getRotation());
const newResolution = this.constraints_.resolution(
this.targetResolution_ * ratio,
0,
size,
isMoving
);
if (anchor) {
this.targetCenter_ = this.calculateCenterZoom(newResolution, anchor);
}
this.targetResolution_ *= ratio;
this.applyTargetState_();
}
adjustZoom(delta, anchor) {
this.adjustResolution(Math.pow(this.zoomFactor_, -delta), anchor);
}
adjustRotation(delta, anchor) {
if (anchor) {
anchor = fromUserCoordinate(anchor, this.getProjection());
}
this.adjustRotationInternal(delta, anchor);
}
adjustRotationInternal(delta, anchor) {
const isMoving = this.getAnimating() || this.getInteracting();
const newRotation = this.constraints_.rotation(
this.targetRotation_ + delta,
isMoving
);
if (anchor) {
this.targetCenter_ = this.calculateCenterRotate(newRotation, anchor);
}
this.targetRotation_ += delta;
this.applyTargetState_();
}
setCenter(center) {
this.setCenterInternal(
center ? fromUserCoordinate(center, this.getProjection()) : center
);
}
setCenterInternal(center) {
this.targetCenter_ = center;
this.applyTargetState_();
}
setHint(hint, delta) {
this.hints_[hint] += delta;
this.changed();
return this.hints_[hint];
}
setResolution(resolution) {
this.targetResolution_ = resolution;
this.applyTargetState_();
}
setRotation(rotation) {
this.targetRotation_ = rotation;
this.applyTargetState_();
}
setZoom(zoom) {
this.setResolution(this.getResolutionForZoom(zoom));
}
applyTargetState_(doNotCancelAnims, forceMoving) {
const isMoving = this.getAnimating() || this.getInteracting() || forceMoving;
const newRotation = this.constraints_.rotation(
this.targetRotation_,
isMoving
);
const size = this.getViewportSize_(newRotation);
const newResolution = this.constraints_.resolution(
this.targetResolution_,
0,
size,
isMoving
);
const newCenter = this.constraints_.center(
this.targetCenter_,
newResolution,
size,
isMoving,
this.calculateCenterShift(
this.targetCenter_,
newResolution,
newRotation,
size
)
);
if (this.get(ViewProperty.ROTATION) !== newRotation) {
this.set(ViewProperty.ROTATION, newRotation);
}
if (this.get(ViewProperty.RESOLUTION) !== newResolution) {
this.set(ViewProperty.RESOLUTION, newResolution);
this.set("zoom", this.getZoom(), true);
}
if (!newCenter || !this.get(ViewProperty.CENTER) || !equals(this.get(ViewProperty.CENTER), newCenter)) {
this.set(ViewProperty.CENTER, newCenter);
}
if (this.getAnimating() && !doNotCancelAnims) {
this.cancelAnimations();
}
this.cancelAnchor_ = void 0;
}
resolveConstraints(duration, resolutionDirection, anchor) {
duration = duration !== void 0 ? duration : 200;
const direction = resolutionDirection || 0;
const newRotation = this.constraints_.rotation(this.targetRotation_);
const size = this.getViewportSize_(newRotation);
const newResolution = this.constraints_.resolution(
this.targetResolution_,
direction,
size
);
const newCenter = this.constraints_.center(
this.targetCenter_,
newResolution,
size,
false,
this.calculateCenterShift(
this.targetCenter_,
newResolution,
newRotation,
size
)
);
if (duration === 0 && !this.cancelAnchor_) {
this.targetResolution_ = newResolution;
this.targetRotation_ = newRotation;
this.targetCenter_ = newCenter;
this.applyTargetState_();
return;
}
anchor = anchor || (duration === 0 ? this.cancelAnchor_ : void 0);
this.cancelAnchor_ = void 0;
if (this.getResolution() !== newResolution || this.getRotation() !== newRotation || !this.getCenterInternal() || !equals(this.getCenterInternal(), newCenter)) {
if (this.getAnimating()) {
this.cancelAnimations();
}
this.animateInternal({
rotation: newRotation,
center: newCenter,
resolution: newResolution,
duration,
easing: easeOut,
anchor
});
}
}
beginInteraction() {
this.resolveConstraints(0);
this.setHint(ViewHint.INTERACTING, 1);
}
endInteraction(duration, resolutionDirection, anchor) {
anchor = anchor && fromUserCoordinate(anchor, this.getProjection());
this.endInteractionInternal(duration, resolutionDirection, anchor);
}
endInteractionInternal(duration, resolutionDirection, anchor) {
if (!this.getInteracting()) {
return;
}
this.setHint(ViewHint.INTERACTING, -1);
this.resolveConstraints(duration, resolutionDirection, anchor);
}
getConstrainedCenter(targetCenter, targetResolution) {
const size = this.getViewportSize_(this.getRotation());
return this.constraints_.center(
targetCenter,
targetResolution || this.getResolution(),
size
);
}
getConstrainedZoom(targetZoom, direction) {
const targetRes = this.getResolutionForZoom(targetZoom);
return this.getZoomForResolution(
this.getConstrainedResolution(targetRes, direction)
);
}
getConstrainedResolution(targetResolution, direction) {
direction = direction || 0;
const size = this.getViewportSize_(this.getRotation());
return this.constraints_.resolution(targetResolution, direction, size);
}
}
function animationCallback(callback, returnValue) {
setTimeout(function() {
callback(returnValue);
}, 0);
}
function createCenterConstraint(options) {
if (options.extent !== void 0) {
const smooth = options.smoothExtentConstraint !== void 0 ? options.smoothExtentConstraint : true;
return createExtent(options.extent, options.constrainOnlyCenter, smooth);
}
const projection = createProjection(options.projection, "EPSG:3857");
if (options.multiWorld !== true && projection.isGlobal()) {
const extent = projection.getExtent().slice();
extent[0] = -Infinity;
extent[2] = Infinity;
return createExtent(extent, false, false);
}
return none$1;
}
function createResolutionConstraint(options) {
let resolutionConstraint;
let maxResolution;
let minResolution;
const defaultMaxZoom = 28;
const defaultZoomFactor = 2;
let minZoom = options.minZoom !== void 0 ? options.minZoom : DEFAULT_MIN_ZOOM;
let maxZoom = options.maxZoom !== void 0 ? options.maxZoom : defaultMaxZoom;
const zoomFactor = options.zoomFactor !== void 0 ? options.zoomFactor : defaultZoomFactor;
const multiWorld = options.multiWorld !== void 0 ? options.multiWorld : false;
const smooth = options.smoothResolutionConstraint !== void 0 ? options.smoothResolutionConstraint : true;
const showFullExtent = options.showFullExtent !== void 0 ? options.showFullExtent : false;
const projection = createProjection(options.projection, "EPSG:3857");
const projExtent = projection.getExtent();
let constrainOnlyCenter = options.constrainOnlyCenter;
let extent = options.extent;
if (!multiWorld && !extent && projection.isGlobal()) {
constrainOnlyCenter = false;
extent = projExtent;
}
if (options.resolutions !== void 0) {
const resolutions = options.resolutions;
maxResolution = resolutions[minZoom];
minResolution = resolutions[maxZoom] !== void 0 ? resolutions[maxZoom] : resolutions[resolutions.length - 1];
if (options.constrainResolution) {
resolutionConstraint = createSnapToResolutions(
resolutions,
smooth,
!constrainOnlyCenter && extent,
showFullExtent
);
} else {
resolutionConstraint = createMinMaxResolution(
maxResolution,
minResolution,
smooth,
!constrainOnlyCenter && extent,
showFullExtent
);
}
} else {
const size = !projExtent ? 360 * METERS_PER_UNIT$1.degrees / projection.getMetersPerUnit() : Math.max(getWidth(projExtent), getHeight(projExtent));
const defaultMaxResolution = size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);
const defaultMinResolution = defaultMaxResolution / Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM);
maxResolution = options.maxResolution;
if (maxResolution !== void 0) {
minZoom = 0;
} else {
maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);
}
minResolution = options.minResolution;
if (minResolution === void 0) {
if (options.maxZoom !== void 0) {
if (options.maxResolution !== void 0) {
minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);
} else {
minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);
}
} else {
minResolution = defaultMinResolution;
}
}
maxZoom = minZoom + Math.floor(
Math.log(maxResolution / minResolution) / Math.log(zoomFactor)
);
minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);
if (options.constrainResolution) {
resolutionConstraint = createSnapToPower(
zoomFactor,
maxResolution,
minResolution,
smooth,
!constrainOnlyCenter && extent,
showFullExtent
);
} else {
resolutionConstraint = createMinMaxResolution(
maxResolution,
minResolution,
smooth,
!constrainOnlyCenter && extent,
showFullExtent
);
}
}
return {
constraint: resolutionConstraint,
maxResolution,
minResolution,
minZoom,
zoomFactor
};
}
function createRotationConstraint(options) {
const enableRotation = options.enableRotation !== void 0 ? options.enableRotation : true;
if (enableRotation) {
const constrainRotation = options.constrainRotation;
if (constrainRotation === void 0 || constrainRotation === true) {
return createSnapToZero();
}
if (constrainRotation === false) {
return none;
}
if (typeof constrainRotation === "number") {
return createSnapToN(constrainRotation);
}
return none;
}
return disable;
}
function isNoopAnimation(animation) {
if (animation.sourceCenter && animation.targetCenter) {
if (!equals(animation.sourceCenter, animation.targetCenter)) {
return false;
}
}
if (animation.sourceResolution !== animation.targetResolution) {
return false;
}
if (animation.sourceRotation !== animation.targetRotation) {
return false;
}
return true;
}
function calculateCenterOn(coordinate, size, position, resolution, rotation) {
const cosAngle = Math.cos(-rotation);
let sinAngle = Math.sin(-rotation);
let rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;
let rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;
rotX += (size[0] / 2 - position[0]) * resolution;
rotY += (position[1] - size[1] / 2) * resolution;
sinAngle = -sinAngle;
const centerX = rotX * cosAngle - rotY * sinAngle;
const centerY = rotY * cosAngle + rotX * sinAngle;
return [centerX, centerY];
}
const View$1 = View;
const LayerProperty = {
OPACITY: "opacity",
VISIBLE: "visible",
EXTENT: "extent",
Z_INDEX: "zIndex",
MAX_RESOLUTION: "maxResolution",
MIN_RESOLUTION: "minResolution",
MAX_ZOOM: "maxZoom",
MIN_ZOOM: "minZoom",
SOURCE: "source",
MAP: "map"
};
class BaseLayer extends BaseObject$1 {
constructor(options) {
super();
this.on;
this.once;
this.un;
this.background_ = options.background;
const properties = Object.assign({}, options);
if (typeof options.properties === "object") {
delete properties.properties;
Object.assign(properties, options.properties);
}
properties[LayerProperty.OPACITY] = options.opacity !== void 0 ? options.opacity : 1;
assert(
typeof properties[LayerProperty.OPACITY] === "number",
"Layer opacity must be a number"
);
properties[LayerProperty.VISIBLE] = options.visible !== void 0 ? options.visible : true;
properties[LayerProperty.Z_INDEX] = options.zIndex;
properties[LayerProperty.MAX_RESOLUTION] = options.maxResolution !== void 0 ? options.maxResolution : Infinity;
properties[LayerProperty.MIN_RESOLUTION] = options.minResolution !== void 0 ? options.minResolution : 0;
properties[LayerProperty.MIN_ZOOM] = options.minZoom !== void 0 ? options.minZoom : -Infinity;
properties[LayerProperty.MAX_ZOOM] = options.maxZoom !== void 0 ? options.maxZoom : Infinity;
this.className_ = properties.className !== void 0 ? properties.className : "ol-layer";
delete properties.className;
this.setProperties(properties);
this.state_ = null;
}
getBackground() {
return this.background_;
}
getClassName() {
return this.className_;
}
getLayerState(managed) {
const state = this.state_ || {
layer: this,
managed: managed === void 0 ? true : managed
};
const zIndex = this.getZIndex();
state.opacity = clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);
state.visible = this.getVisible();
state.extent = this.getExtent();
state.zIndex = zIndex === void 0 && !state.managed ? Infinity : zIndex;
state.maxResolution = this.getMaxResolution();
state.minResolution = Math.max(this.getMinResolution(), 0);
state.minZoom = this.getMinZoom();
state.maxZoom = this.getMaxZoom();
this.state_ = state;
return state;
}
getLayersArray(array) {
return abstract();
}
getLayerStatesArray(states) {
return abstract();
}
getExtent() {
return this.get(LayerProperty.EXTENT);
}
getMaxResolution() {
return this.get(LayerProperty.MAX_RESOLUTION);
}
getMinResolution() {
return this.get(LayerProperty.MIN_RESOLUTION);
}
getMinZoom() {
return this.get(LayerProperty.MIN_ZOOM);
}
getMaxZoom() {
return this.get(LayerProperty.MAX_ZOOM);
}
getOpacity() {
return this.get(LayerProperty.OPACITY);
}
getSourceState() {
return abstract();
}
getVisible() {
return this.get(LayerProperty.VISIBLE);
}
getZIndex() {
return this.get(LayerProperty.Z_INDEX);
}
setBackground(background) {
this.background_ = background;
this.changed();
}
setExtent(extent) {
this.set(LayerProperty.EXTENT, extent);
}
setMaxResolution(maxResolution) {
this.set(LayerProperty.MAX_RESOLUTION, maxResolution);
}
setMinResolution(minResolution) {
this.set(LayerProperty.MIN_RESOLUTION, minResolution);
}
setMaxZoom(maxZoom) {
this.set(LayerProperty.MAX_ZOOM, maxZoom);
}
setMinZoom(minZoom) {
this.set(LayerProperty.MIN_ZOOM, minZoom);
}
setOpacity(opacity) {
assert(typeof opacity === "number", "Layer opacity must be a number");
this.set(LayerProperty.OPACITY, opacity);
}
setVisible(visible) {
this.set(LayerProperty.VISIBLE, visible);
}
setZIndex(zindex) {
this.set(LayerProperty.Z_INDEX, zindex);
}
disposeInternal() {
if (this.state_) {
this.state_.layer = null;
this.state_ = null;
}
super.disposeInternal();
}
}
const BaseLayer$1 = BaseLayer;
class Layer extends BaseLayer$1 {
constructor(options) {
const baseOptions = Object.assign({}, options);
delete baseOptions.source;
super(baseOptions);
this.on;
this.once;
this.un;
this.mapPrecomposeKey_ = null;
this.mapRenderKey_ = null;
this.sourceChangeKey_ = null;
this.renderer_ = null;
this.sourceReady_ = false;
this.rendered = false;
if (options.render) {
this.render = options.render;
}
if (options.map) {
this.setMap(options.map);
}
this.addChangeListener(
LayerProperty.SOURCE,
this.handleSourcePropertyChange_
);
const source = options.source ? options.source : null;
this.setSource(source);
}
getLayersArray(array) {
array = array ? array : [];
array.push(this);
return array;
}
getLayerStatesArray(states) {
states = states ? states : [];
states.push(this.getLayerState());
return states;
}
getSource() {
return this.get(LayerProperty.SOURCE) || null;
}
getRenderSource() {
return this.getSource();
}
getSourceState() {
const source = this.getSource();
return !source ? "undefined" : source.getState();
}
handleSourceChange_() {
this.changed();
if (this.sourceReady_ || this.getSource().getState() !== "ready") {
return;
}
this.sourceReady_ = true;
this.dispatchEvent("sourceready");
}
handleSourcePropertyChange_() {
if (this.sourceChangeKey_) {
unlistenByKey(this.sourceChangeKey_);
this.sourceChangeKey_ = null;
}
this.sourceReady_ = false;
const source = this.getSource();
if (source) {
this.sourceChangeKey_ = listen(
source,
EventType.CHANGE,
this.handleSourceChange_,
this
);
if (source.getState() === "ready") {
this.sourceReady_ = true;
setTimeout(() => {
this.dispatchEvent("sourceready");
}, 0);
}
}
this.changed();
}
getFeatures(pixel) {
if (!this.renderer_) {
return Promise.resolve([]);
}
return this.renderer_.getFeatures(pixel);
}
getData(pixel) {
if (!this.renderer_ || !this.rendered) {
return null;
}
return this.renderer_.getData(pixel);
}
isVisible(view) {
let frameState;
const map = this.getMapInternal();
if (!view && map) {
view = map.getView();
}
if (view instanceof View$1) {
frameState = {
viewState: view.getState(),
extent: view.calculateExtent()
};
} else {
frameState = view;
}
if (!frameState.layerStatesArray && map) {
frameState.layerStatesArray = map.getLayerGroup().getLayerStatesArray();
}
let layerState;
if (frameState.layerStatesArray) {
layerState = frameState.layerStatesArray.find(
(layerState2) => layerState2.layer === this
);
if (!layerState) {
return false;
}
} else {
layerState = this.getLayerState();
}
const layerExtent = this.getExtent();
return inView(layerState, frameState.viewState) && (!layerExtent || intersects$1(layerExtent, frameState.extent));
}
getAttributions(view) {
var _a;
if (!this.isVisible(view)) {
return [];
}
const getAttributions = (_a = this.getSource()) == null ? void 0 : _a.getAttributions();
if (!getAttributions) {
return [];
}
const frameState = view instanceof View$1 ? view.getViewStateAndExtent() : view;
let attributions = getAttributions(frameState);
if (!Array.isArray(attributions)) {
attributions = [attributions];
}
return attributions;
}
render(frameState, target) {
const layerRenderer = this.getRenderer();
if (layerRenderer.prepareFrame(frameState)) {
this.rendered = true;
return layerRenderer.renderFrame(frameState, target);
}
return null;
}
unrender() {
this.rendered = false;
}
getDeclutter() {
return void 0;
}
renderDeclutter(frameState, layerState) {
}
renderDeferred(frameState) {
const layerRenderer = this.getRenderer();
if (!layerRenderer) {
return;
}
layerRenderer.renderDeferred(frameState);
}
setMapInternal(map) {
if (!map) {
this.unrender();
}
this.set(LayerProperty.MAP, map);
}
getMapInternal() {
return this.get(LayerProperty.MAP);
}
setMap(map) {
if (this.mapPrecomposeKey_) {
unlistenByKey(this.mapPrecomposeKey_);
this.mapPrecomposeKey_ = null;
}
if (!map) {
this.changed();
}
if (this.mapRenderKey_) {
unlistenByKey(this.mapRenderKey_);
this.mapRenderKey_ = null;
}
if (map) {
this.mapPrecomposeKey_ = listen(
map,
RenderEventType.PRECOMPOSE,
this.handlePrecompose_,
this
);
this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);
this.changed();
}
}
handlePrecompose_(renderEvent) {
const layerStatesArray = renderEvent.frameState.layerStatesArray;
const layerState = this.getLayerState(false);
assert(
!layerStatesArray.some(
(arrayLayerState) => arrayLayerState.layer === layerState.layer
),
"A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both."
);
layerStatesArray.push(layerState);
}
setSource(source) {
this.set(LayerProperty.SOURCE, source);
}
getRenderer() {
if (!this.renderer_) {
this.renderer_ = this.createRenderer();
}
return this.renderer_;
}
hasRenderer() {
return !!this.renderer_;
}
createRenderer() {
return null;
}
clearRenderer() {
if (this.renderer_) {
this.renderer_.dispose();
delete this.renderer_;
}
}
disposeInternal() {
this.clearRenderer();
this.setSource(null);
super.disposeInternal();
}
}
function inView(layerState, viewState) {
if (!layerState.visible) {
return false;
}
const resolution = viewState.resolution;
if (resolution < layerState.minResolution || resolution >= layerState.maxResolution) {
return false;
}
const zoom = viewState.zoom;
return zoom > layerState.minZoom && zoom <= layerState.maxZoom;
}
const Layer$1 = Layer;
const Property = {
RENDER_ORDER: "renderOrder"
};
class BaseVectorLayer extends Layer$1 {
constructor(options) {
options = options ? options : {};
const baseOptions = Object.assign({}, options);
delete baseOptions.style;
delete baseOptions.renderBuffer;
delete baseOptions.updateWhileAnimating;
delete baseOptions.updateWhileInteracting;
super(baseOptions);
this.declutter_ = options.declutter ? String(options.declutter) : void 0;
this.renderBuffer_ = options.renderBuffer !== void 0 ? options.renderBuffer : 100;
this.style_ = null;
this.styleFunction_ = void 0;
this.setStyle(options.style);
this.updateWhileAnimating_ = options.updateWhileAnimating !== void 0 ? options.updateWhileAnimating : false;
this.updateWhileInteracting_ = options.updateWhileInteracting !== void 0 ? options.updateWhileInteracting : false;
}
getDeclutter() {
return this.declutter_;
}
getFeatures(pixel) {
return super.getFeatures(pixel);
}
getRenderBuffer() {
return this.renderBuffer_;
}
getRenderOrder() {
return this.get(Property.RENDER_ORDER);
}
getStyle() {
return this.style_;
}
getStyleFunction() {
return this.styleFunction_;
}
getUpdateWhileAnimating() {
return this.updateWhileAnimating_;
}
getUpdateWhileInteracting() {
return this.updateWhileInteracting_;
}
renderDeclutter(frameState, layerState) {
const declutterGroup = this.getDeclutter();
if (declutterGroup in frameState.declutter === false) {
frameState.declutter[declutterGroup] = new RBush$2(9);
}
this.getRenderer().renderDeclutter(frameState, layerState);
}
setRenderOrder(renderOrder) {
this.set(Property.RENDER_ORDER, renderOrder);
}
setStyle(style) {
this.style_ = style === void 0 ? createDefaultStyle : style;
const styleLike = toStyleLike(style);
this.styleFunction_ = style === null ? void 0 : toFunction(styleLike);
this.changed();
}
setDeclutter(declutter) {
this.declutter_ = declutter ? String(declutter) : void 0;
this.changed();
}
}
function toStyleLike(style) {
if (style === void 0) {
return createDefaultStyle;
}
if (!style) {
return null;
}
if (typeof style === "function") {
return style;
}
if (style instanceof Style) {
return style;
}
if (!Array.isArray(style)) {
return flatStylesToStyleFunction([style]);
}
if (style.length === 0) {
return [];
}
const length = style.length;
const first = style[0];
if (first instanceof Style) {
const styles = new Array(length);
for (let i = 0; i < length; ++i) {
const candidate = style[i];
if (!(candidate instanceof Style)) {
throw new Error("Expected a list of style instances");
}
styles[i] = candidate;
}
return styles;
}
if ("style" in first) {
const rules = new Array(length);
for (let i = 0; i < length; ++i) {
const candidate = style[i];
if (!("style" in candidate)) {
throw new Error("Expected a list of rules with a style property");
}
rules[i] = candidate;
}
return rulesToStyleFunction(rules);
}
const flatStyles = style;
return flatStylesToStyleFunction(flatStyles);
}
const BaseVectorLayer$1 = BaseVectorLayer;
class VectorLayer extends BaseVectorLayer$1 {
constructor(options) {
super(options);
}
createRenderer() {
return new CanvasVectorLayerRenderer$1(this);
}
}
const VectorLayer$1 = VectorLayer;
const InteractionProperty = {
ACTIVE: "active"
};
class Interaction extends BaseObject$1 {
constructor(options) {
super();
this.on;
this.once;
this.un;
if (options && options.handleEvent) {
this.handleEvent = options.handleEvent;
}
this.map_ = null;
this.setActive(true);
}
getActive() {
return this.get(InteractionProperty.ACTIVE);
}
getMap() {
return this.map_;
}
handleEvent(mapBrowserEvent) {
return true;
}
setActive(active) {
this.set(InteractionProperty.ACTIVE, active);
}
setMap(map) {
this.map_ = map;
}
}
const Interaction$1 = Interaction;
const SelectEventType = {
SELECT: "select"
};
class SelectEvent extends Event {
constructor(type, selected, deselected, mapBrowserEvent) {
super(type);
this.selected = selected;
this.deselected = deselected;
this.mapBrowserEvent = mapBrowserEvent;
}
}
const originalFeatureStyles = {};
class Select extends Interaction$1 {
constructor(options) {
super();
this.on;
this.once;
this.un;
options = options ? options : {};
this.boundAddFeature_ = this.addFeature_.bind(this);
this.boundRemoveFeature_ = this.removeFeature_.bind(this);
this.condition_ = options.condition ? options.condition : singleClick;
this.addCondition_ = options.addCondition ? options.addCondition : never;
this.removeCondition_ = options.removeCondition ? options.removeCondition : never;
this.toggleCondition_ = options.toggleCondition ? options.toggleCondition : shiftKeyOnly;
this.multi_ = options.multi ? options.multi : false;
this.filter_ = options.filter ? options.filter : TRUE;
this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;
this.style_ = options.style !== void 0 ? options.style : getDefaultStyleFunction();
this.features_ = options.features || new Collection$1();
let layerFilter;
if (options.layers) {
if (typeof options.layers === "function") {
layerFilter = options.layers;
} else {
const layers = options.layers;
layerFilter = function(layer) {
return layers.includes(layer);
};
}
} else {
layerFilter = TRUE;
}
this.layerFilter_ = layerFilter;
this.featureLayerAssociation_ = {};
}
addFeatureLayerAssociation_(feature2, layer) {
this.featureLayerAssociation_[getUid(feature2)] = layer;
}
getFeatures() {
return this.features_;
}
getHitTolerance() {
return this.hitTolerance_;
}
getLayer(feature2) {
return this.featureLayerAssociation_[getUid(feature2)];
}
setHitTolerance(hitTolerance) {
this.hitTolerance_ = hitTolerance;
}
setMap(map) {
const currentMap = this.getMap();
if (currentMap && this.style_) {
this.features_.forEach(this.restorePreviousStyle_.bind(this));
}
super.setMap(map);
if (map) {
this.features_.addEventListener(
CollectionEventType.ADD,
this.boundAddFeature_
);
this.features_.addEventListener(
CollectionEventType.REMOVE,
this.boundRemoveFeature_
);
if (this.style_) {
this.features_.forEach(this.applySelectedStyle_.bind(this));
}
} else {
this.features_.removeEventListener(
CollectionEventType.ADD,
this.boundAddFeature_
);
this.features_.removeEventListener(
CollectionEventType.REMOVE,
this.boundRemoveFeature_
);
}
}
addFeature_(evt) {
const feature2 = evt.element;
if (this.style_) {
this.applySelectedStyle_(feature2);
}
if (!this.getLayer(feature2)) {
const layer = this.getMap().getAllLayers().find(function(layer2) {
if (layer2 instanceof VectorLayer$1 && layer2.getSource() && layer2.getSource().hasFeature(feature2)) {
return layer2;
}
});
if (layer) {
this.addFeatureLayerAssociation_(feature2, layer);
}
}
}
removeFeature_(evt) {
if (this.style_) {
this.restorePreviousStyle_(evt.element);
}
}
getStyle() {
return this.style_;
}
applySelectedStyle_(feature2) {
const key = getUid(feature2);
if (!(key in originalFeatureStyles)) {
originalFeatureStyles[key] = feature2.getStyle();
}
feature2.setStyle(this.style_);
}
restorePreviousStyle_(feature2) {
const interactions = this.getMap().getInteractions().getArray();
for (let i = interactions.length - 1; i >= 0; --i) {
const interaction = interactions[i];
if (interaction !== this && interaction instanceof Select && interaction.getStyle() && interaction.getFeatures().getArray().lastIndexOf(feature2) !== -1) {
feature2.setStyle(interaction.getStyle());
return;
}
}
const key = getUid(feature2);
feature2.setStyle(originalFeatureStyles[key]);
delete originalFeatureStyles[key];
}
removeFeatureLayerAssociation_(feature2) {
delete this.featureLayerAssociation_[getUid(feature2)];
}
handleEvent(mapBrowserEvent) {
if (!this.condition_(mapBrowserEvent)) {
return true;
}
const add2 = this.addCondition_(mapBrowserEvent);
const remove = this.removeCondition_(mapBrowserEvent);
const toggle = this.toggleCondition_(mapBrowserEvent);
const set = !add2 && !remove && !toggle;
const map = mapBrowserEvent.map;
const features = this.getFeatures();
const deselected = [];
const selected = [];
if (set) {
clear(this.featureLayerAssociation_);
map.forEachFeatureAtPixel(
mapBrowserEvent.pixel,
(feature2, layer) => {
if (!(feature2 instanceof Feature$1) || !this.filter_(feature2, layer)) {
return;
}
this.addFeatureLayerAssociation_(feature2, layer);
selected.push(feature2);
return !this.multi_;
},
{
layerFilter: this.layerFilter_,
hitTolerance: this.hitTolerance_
}
);
for (let i = features.getLength() - 1; i >= 0; --i) {
const feature2 = features.item(i);
const index2 = selected.indexOf(feature2);
if (index2 > -1) {
selected.splice(index2, 1);
} else {
features.remove(feature2);
deselected.push(feature2);
}
}
if (selected.length !== 0) {
features.extend(selected);
}
} else {
map.forEachFeatureAtPixel(
mapBrowserEvent.pixel,
(feature2, layer) => {
if (!(feature2 instanceof Feature$1) || !this.filter_(feature2, layer)) {
return;
}
if ((add2 || toggle) && !features.getArray().includes(feature2)) {
this.addFeatureLayerAssociation_(feature2, layer);
selected.push(feature2);
} else if ((remove || toggle) && features.getArray().includes(feature2)) {
deselected.push(feature2);
this.removeFeatureLayerAssociation_(feature2);
}
return !this.multi_;
},
{
layerFilter: this.layerFilter_,
hitTolerance: this.hitTolerance_
}
);
for (let j = deselected.length - 1; j >= 0; --j) {
features.remove(deselected[j]);
}
features.extend(selected);
}
if (selected.length > 0 || deselected.length > 0) {
this.dispatchEvent(
new SelectEvent(
SelectEventType.SELECT,
selected,
deselected,
mapBrowserEvent
)
);
}
return true;
}
}
function getDefaultStyleFunction() {
const styles = createEditingStyle();
extend$2(styles["Polygon"], styles["LineString"]);
extend$2(styles["GeometryCollection"], styles["LineString"]);
return function(feature2) {
if (!feature2.getGeometry()) {
return null;
}
return styles[feature2.getGeometry().getType()];
};
}
const Select$1 = Select;
class CreateClusterLayer {
constructor(id, points, props = {}) {
__publicField(this, "gyMapObj");
__publicField(this, "mapFinish");
__publicField(this, "layer");
__publicField(this, "oneStyle");
__publicField(this, "clusterSource");
__publicField(this, "props");
__publicField(this, "currentResolution");
__publicField(this, "maxFeatureCount");
__publicField(this, "isDraw");
__publicField(this, "points");
this.layer = null;
this.clusterSource = null;
this.oneStyle = null;
this.gyMapObj = gyMap$1(id);
this.isDraw = false;
this.points = points;
this.props = props;
this.mapFinish = computed(() => this.gyMapObj.value && this.gyMapObj.value.mapFinish);
this.currentResolution = 0;
this.maxFeatureCount = 0;
this.draw();
}
draw() {
this.createLayer();
this.addWatchFun();
this.addLayerToMap();
}
calculateClusterInfo(resolution) {
const features = this.layer.getSource().getFeatures();
let feature2, radius;
for (let i = features.length - 1; i >= 0; --i) {
feature2 = features[i];
const originalFeatures = feature2.get("features");
const extent = createEmpty();
let j, jj;
for (j = 0, jj = originalFeatures.length; j < jj; ++j) {
extend$1(extent, originalFeatures[j].getGeometry().getExtent());
}
this.maxFeatureCount = Math.max(this.maxFeatureCount, jj);
radius = this.props.radiusMultiplier * (getWidth(extent) + getHeight(extent)) / resolution;
feature2.set("radius", radius);
}
}
styleFunction(feature2, resolution) {
if (resolution != this.currentResolution) {
this.calculateClusterInfo(resolution);
this.currentResolution = resolution;
}
let style;
let size = feature2.get("features").length;
if (size > 1) {
style = new Style$1({
image: new Circle$1({
radius: feature2.get("radius"),
fill: this.props.clusterFullColor ? new Fill$2({
color: this.props.clusterFullColor
}) : new Fill$2({
color: [255, 153, 0, Math.min(0.9, 0.5 + size / this.maxFeatureCount)]
}),
stroke: this.props.clusterStrokeWidth === 0 ? null : new Stroke$2({
color: this.props.clusterStrokeColor || "rgb(0,0,0)",
width: this.props.clusterStrokeWidth || 1
})
}),
text: new Text$2({
text: size.toString(),
fill: new Fill$2({
color: this.props.clusterTextColor || "#fff"
})
})
});
} else {
let originalFeature = feature2.get("features")[0];
style = this.createPolygonStyle(originalFeature);
}
return style;
}
createPolygonStyle(feature2) {
let style;
if (this.oneStyle) {
style = this.oneStyle.clone();
style.setGeometry(feature2.getGeometry());
} else {
style = new Style$1({
geometry: feature2.getGeometry(),
image: new Circle$1({
radius: 5,
fill: new Fill$2({
color: [255, 255, 255, 0.5]
}),
stroke: new Stroke$2({
color: "#31d3f0",
width: 1
})
})
});
}
return style;
}
setOneSyle(style) {
this.oneStyle = style;
}
createLayer() {
this.clusterSource = new VectorSource$2({
features: []
});
const cluster = new Cluster$1({
distance: this.props.distance || 30,
source: this.clusterSource
});
this.layer = new VectorLayer$2({
source: cluster,
style: this.styleFunction.bind(this),
minZoom: this.props.minZoom,
maxZoom: this.props.maxZoom,
opacity: this.props.opacity
});
}
addLayerToMap() {
var _a, _b;
if (!this.isDraw && this.mapFinish.value) {
this.isDraw = true;
(_b = (_a = this.gyMapObj.value) == null ? void 0 : _a.map) == null ? void 0 : _b.addLayer(this.layer);
this.addSelectFeatureFun();
}
}
addWatchFun() {
watch(this.mapFinish, () => {
this.addLayerToMap();
});
}
selectStyleFunction(feature2) {
const styles = [
new Style$1({
image: new Circle$1({
radius: 10,
fill: new Fill$2({
color: "rgba(255, 255, 255, 0)"
})
})
})
];
const originalFeatures = feature2.get("features");
let originalFeature;
for (let i = originalFeatures.length - 1; i >= 0; --i) {
originalFeature = originalFeatures[i];
styles.push(this.createPolygonStyle(originalFeature));
}
return styles;
}
addSelectFeatureFun() {
var _a, _b;
if (!this.props.isSelect) {
return;
}
const select = new Select$1({
condition: function(evt) {
return evt.type == "pointermove" || evt.type == "singleclick";
},
style: this.selectStyleFunction.bind(this)
});
(_b = (_a = this.gyMapObj.value) == null ? void 0 : _a.map) == null ? void 0 : _b.addInteraction(select);
}
}
const __vue2_script = defineComponent({
name: "GymapClusters",
props: {
mapId: {
type: String,
default: ""
},
isSelect: {
type: Boolean,
default: false
},
distance: {
type: Number,
default: 30
},
radiusMultiplier: {
type: Number,
default: 0.5
},
clusterFullColor: {
type: String,
default: ""
},
clusterStrokeColor: {
type: String,
default: ""
},
clusterTextColor: {
type: String,
default: ""
},
clusterStrokeWidth: {
type: Number,
default: 1
},
minZoom: {
type: Number,
default: 1
},
maxZoom: {
type: Number,
default: 18
},
opacity: {
type: Number,
default: 1
}
},
emits: ["clickFun"],
setup(props, { emit }) {
const { proxy } = getCurrentInstance();
const mapId = props.mapId || proxy.$parent.id;
const clusters = new CreateClusterLayer(mapId, props.points, props);
const clusterSource = clusters.clusterSource;
const setParentStylesByLayer = (layer) => {
clusters.setOneSyle(layer.getStyle());
};
onMounted(() => {
});
onBeforeUnmount(() => {
});
return {
id: mapId,
clusterSource,
setParentStylesByLayer
};
}
});
var render = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", [_vm._t("default")], 2);
};
var staticRenderFns = [];
const __cssModules = {};
var __component__ = /* @__PURE__ */ normalizeComponent(
__vue2_script,
render,
staticRenderFns,
false,
__vue2_injectStyles,
null,
null,
null
);
function __vue2_injectStyles(context) {
for (let o in __cssModules) {
this[o] = __cssModules[o];
}
}
const GymapClusters = /* @__PURE__ */ function() {
return __component__.exports;
}();
const components = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
Gymap,
GymapHtml,
GymapPolygon,
GymapLine,
GymapTask,
GymapCircle,
GymapText,
GymapImage,
GymapDraw,
GymapHeat,
GymapLonlat,
GymapClusters
}, Symbol.toStringTag, { value: "Module" }));
const MapEventType = {
POSTRENDER: "postrender",
MOVESTART: "movestart",
MOVEEND: "moveend",
LOADSTART: "loadstart",
LOADEND: "loadend"
};
class Control extends BaseObject$1 {
constructor(options) {
super();
const element = options.element;
if (element && !options.target && !element.style.pointerEvents) {
element.style.pointerEvents = "auto";
}
this.element = element ? element : null;
this.target_ = null;
this.map_ = null;
this.listenerKeys = [];
if (options.render) {
this.render = options.render;
}
if (options.target) {
this.setTarget(options.target);
}
}
disposeInternal() {
var _a;
(_a = this.element) == null ? void 0 : _a.remove();
super.disposeInternal();
}
getMap() {
return this.map_;
}
setMap(map) {
var _a, _b;
if (this.map_) {
(_a = this.element) == null ? void 0 : _a.remove();
}
for (let i = 0, ii = this.listenerKeys.length; i < ii; ++i) {
unlistenByKey(this.listenerKeys[i]);
}
this.listenerKeys.length = 0;
this.map_ = map;
if (map) {
const target = (_b = this.target_) != null ? _b : map.getOverlayContainerStopEvent();
if (this.element) {
target.appendChild(this.element);
}
if (this.render !== VOID) {
this.listenerKeys.push(
listen(map, MapEventType.POSTRENDER, this.render, this)
);
}
map.render();
}
}
render(mapEvent) {
}
setTarget(target) {
this.target_ = typeof target === "string" ? document.getElementById(target) : target;
}
}
const Control$1 = Control;
class Attribution extends Control$1 {
constructor(options) {
options = options ? options : {};
super({
element: document.createElement("div"),
render: options.render,
target: options.target
});
this.ulElement_ = document.createElement("ul");
this.collapsed_ = options.collapsed !== void 0 ? options.collapsed : true;
this.userCollapsed_ = this.collapsed_;
this.overrideCollapsible_ = options.collapsible !== void 0;
this.collapsible_ = options.collapsible !== void 0 ? options.collapsible : true;
if (!this.collapsible_) {
this.collapsed_ = false;
}
this.attributions_ = options.attributions;
const className = options.className !== void 0 ? options.className : "ol-attribution";
const tipLabel = options.tipLabel !== void 0 ? options.tipLabel : "Attributions";
const expandClassName = options.expandClassName !== void 0 ? options.expandClassName : className + "-expand";
const collapseLabel = options.collapseLabel !== void 0 ? options.collapseLabel : "\u203A";
const collapseClassName = options.collapseClassName !== void 0 ? options.collapseClassName : className + "-collapse";
if (typeof collapseLabel === "string") {
this.collapseLabel_ = document.createElement("span");
this.collapseLabel_.textContent = collapseLabel;
this.collapseLabel_.className = collapseClassName;
} else {
this.collapseLabel_ = collapseLabel;
}
const label = options.label !== void 0 ? options.label : "i";
if (typeof label === "string") {
this.label_ = document.createElement("span");
this.label_.textContent = label;
this.label_.className = expandClassName;
} else {
this.label_ = label;
}
const activeLabel = this.collapsible_ && !this.collapsed_ ? this.collapseLabel_ : this.label_;
this.toggleButton_ = document.createElement("button");
this.toggleButton_.setAttribute("type", "button");
this.toggleButton_.setAttribute("aria-expanded", String(!this.collapsed_));
this.toggleButton_.title = tipLabel;
this.toggleButton_.appendChild(activeLabel);
this.toggleButton_.addEventListener(
EventType.CLICK,
this.handleClick_.bind(this),
false
);
const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL + (this.collapsed_ && this.collapsible_ ? " " + CLASS_COLLAPSED : "") + (this.collapsible_ ? "" : " ol-uncollapsible");
const element = this.element;
element.className = cssClasses;
element.appendChild(this.toggleButton_);
element.appendChild(this.ulElement_);
this.renderedAttributions_ = [];
this.renderedVisible_ = true;
}
collectSourceAttributions_(frameState) {
const layers = this.getMap().getAllLayers();
const visibleAttributions = new Set(
layers.flatMap((layer) => layer.getAttributions(frameState))
);
if (this.attributions_ !== void 0) {
Array.isArray(this.attributions_) ? this.attributions_.forEach((item) => visibleAttributions.add(item)) : visibleAttributions.add(this.attributions_);
}
if (!this.overrideCollapsible_) {
const collapsible = !layers.some(
(layer) => {
var _a;
return ((_a = layer.getSource()) == null ? void 0 : _a.getAttributionsCollapsible()) === false;
}
);
this.setCollapsible(collapsible);
}
return Array.from(visibleAttributions);
}
async updateElement_(frameState) {
if (!frameState) {
if (this.renderedVisible_) {
this.element.style.display = "none";
this.renderedVisible_ = false;
}
return;
}
const attributions = await Promise.all(
this.collectSourceAttributions_(frameState).map(
(attribution) => toPromise(() => attribution)
)
);
const visible = attributions.length > 0;
if (this.renderedVisible_ != visible) {
this.element.style.display = visible ? "" : "none";
this.renderedVisible_ = visible;
}
if (equals$2(attributions, this.renderedAttributions_)) {
return;
}
removeChildren(this.ulElement_);
for (let i = 0, ii = attributions.length; i < ii; ++i) {
const element = document.createElement("li");
element.innerHTML = attributions[i];
this.ulElement_.appendChild(element);
}
this.renderedAttributions_ = attributions;
}
handleClick_(event) {
event.preventDefault();
this.handleToggle_();
this.userCollapsed_ = this.collapsed_;
}
handleToggle_() {
this.element.classList.toggle(CLASS_COLLAPSED);
if (this.collapsed_) {
replaceNode(this.collapseLabel_, this.label_);
} else {
replaceNode(this.label_, this.collapseLabel_);
}
this.collapsed_ = !this.collapsed_;
this.toggleButton_.setAttribute("aria-expanded", String(!this.collapsed_));
}
getCollapsible() {
return this.collapsible_;
}
setCollapsible(collapsible) {
if (this.collapsible_ === collapsible) {
return;
}
this.collapsible_ = collapsible;
this.element.classList.toggle("ol-uncollapsible");
if (this.userCollapsed_) {
this.handleToggle_();
}
}
setCollapsed(collapsed) {
this.userCollapsed_ = collapsed;
if (!this.collapsible_ || this.collapsed_ === collapsed) {
return;
}
this.handleToggle_();
}
getCollapsed() {
return this.collapsed_;
}
render(mapEvent) {
this.updateElement_(mapEvent.frameState);
}
}
const Attribution$1 = Attribution;
class Rotate extends Control$1 {
constructor(options) {
options = options ? options : {};
super({
element: document.createElement("div"),
render: options.render,
target: options.target
});
const className = options.className !== void 0 ? options.className : "ol-rotate";
const label = options.label !== void 0 ? options.label : "\u21E7";
const compassClassName = options.compassClassName !== void 0 ? options.compassClassName : "ol-compass";
this.label_ = null;
if (typeof label === "string") {
this.label_ = document.createElement("span");
this.label_.className = compassClassName;
this.label_.textContent = label;
} else {
this.label_ = label;
this.label_.classList.add(compassClassName);
}
const tipLabel = options.tipLabel ? options.tipLabel : "Reset rotation";
const button = document.createElement("button");
button.className = className + "-reset";
button.setAttribute("type", "button");
button.title = tipLabel;
button.appendChild(this.label_);
button.addEventListener(
EventType.CLICK,
this.handleClick_.bind(this),
false
);
const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;
const element = this.element;
element.className = cssClasses;
element.appendChild(button);
this.callResetNorth_ = options.resetNorth ? options.resetNorth : void 0;
this.duration_ = options.duration !== void 0 ? options.duration : 250;
this.autoHide_ = options.autoHide !== void 0 ? options.autoHide : true;
this.rotation_ = void 0;
if (this.autoHide_) {
this.element.classList.add(CLASS_HIDDEN);
}
}
handleClick_(event) {
event.preventDefault();
if (this.callResetNorth_ !== void 0) {
this.callResetNorth_();
} else {
this.resetNorth_();
}
}
resetNorth_() {
const map = this.getMap();
const view = map.getView();
if (!view) {
return;
}
const rotation = view.getRotation();
if (rotation !== void 0) {
if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {
view.animate({
rotation: 0,
duration: this.duration_,
easing: easeOut
});
} else {
view.setRotation(0);
}
}
}
render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
return;
}
const rotation = frameState.viewState.rotation;
if (rotation != this.rotation_) {
const transform = "rotate(" + rotation + "rad)";
if (this.autoHide_) {
const contains2 = this.element.classList.contains(CLASS_HIDDEN);
if (!contains2 && rotation === 0) {
this.element.classList.add(CLASS_HIDDEN);
} else if (contains2 && rotation !== 0) {
this.element.classList.remove(CLASS_HIDDEN);
}
}
this.label_.style.transform = transform;
}
this.rotation_ = rotation;
}
}
const Rotate$1 = Rotate;
class Zoom extends Control$1 {
constructor(options) {
options = options ? options : {};
super({
element: document.createElement("div"),
target: options.target
});
const className = options.className !== void 0 ? options.className : "ol-zoom";
const delta = options.delta !== void 0 ? options.delta : 1;
const zoomInClassName = options.zoomInClassName !== void 0 ? options.zoomInClassName : className + "-in";
const zoomOutClassName = options.zoomOutClassName !== void 0 ? options.zoomOutClassName : className + "-out";
const zoomInLabel = options.zoomInLabel !== void 0 ? options.zoomInLabel : "+";
const zoomOutLabel = options.zoomOutLabel !== void 0 ? options.zoomOutLabel : "\u2013";
const zoomInTipLabel = options.zoomInTipLabel !== void 0 ? options.zoomInTipLabel : "Zoom in";
const zoomOutTipLabel = options.zoomOutTipLabel !== void 0 ? options.zoomOutTipLabel : "Zoom out";
const inElement = document.createElement("button");
inElement.className = zoomInClassName;
inElement.setAttribute("type", "button");
inElement.title = zoomInTipLabel;
inElement.appendChild(
typeof zoomInLabel === "string" ? document.createTextNode(zoomInLabel) : zoomInLabel
);
inElement.addEventListener(
EventType.CLICK,
this.handleClick_.bind(this, delta),
false
);
const outElement = document.createElement("button");
outElement.className = zoomOutClassName;
outElement.setAttribute("type", "button");
outElement.title = zoomOutTipLabel;
outElement.appendChild(
typeof zoomOutLabel === "string" ? document.createTextNode(zoomOutLabel) : zoomOutLabel
);
outElement.addEventListener(
EventType.CLICK,
this.handleClick_.bind(this, -delta),
false
);
const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;
const element = this.element;
element.className = cssClasses;
element.appendChild(inElement);
element.appendChild(outElement);
this.duration_ = options.duration !== void 0 ? options.duration : 250;
}
handleClick_(delta, event) {
event.preventDefault();
this.zoomByDelta_(delta);
}
zoomByDelta_(delta) {
const map = this.getMap();
const view = map.getView();
if (!view) {
return;
}
const currentZoom = view.getZoom();
if (currentZoom !== void 0) {
const newZoom = view.getConstrainedZoom(currentZoom + delta);
if (this.duration_ > 0) {
if (view.getAnimating()) {
view.cancelAnimations();
}
view.animate({
zoom: newZoom,
duration: this.duration_,
easing: easeOut
});
} else {
view.setZoom(newZoom);
}
}
}
}
const Zoom$1 = Zoom;
function defaults(options) {
options = options ? options : {};
const controls = new Collection$1();
const zoomControl = options.zoom !== void 0 ? options.zoom : true;
if (zoomControl) {
controls.push(new Zoom$1(options.zoomOptions));
}
const rotateControl = options.rotate !== void 0 ? options.rotate : true;
if (rotateControl) {
controls.push(new Rotate$1(options.rotateOptions));
}
const attributionControl = options.attribution !== void 0 ? options.attribution : true;
if (attributionControl) {
controls.push(new Attribution$1(options.attributionOptions));
}
return controls;
}
let gyMapResultObj = {};
const gyMapInit = (type) => {
type = type || "";
if (type && gyMapResultObj[type]) {
return gyMapResultObj[type];
}
const getRightZoom = (zoom2) => {
return Math.max(mapOpt.minZoom, Math.min(Number(zoom2 || 0), mapOpt.maxZoom));
};
const formatOpt = () => {
mapOpt.minZoom = Math.min(1, mapOpt.minZoom);
mapOpt.maxZoom = Math.max(18, mapOpt.maxZoom);
zoom.value = getRightZoom(mapOpt.zoom);
};
let map = ref(null);
let view = ref(null);
let mapOpt = {
layerOpacity: 1,
maplayerIndex: 0,
centerPoint: [116.40531, 39.896884],
minZoom: 1,
maxZoom: 18,
zoom: 16,
extent: void 0,
stopPropagation: true,
mapUrlList: [
"http://wprd01.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}"
]
};
let zoom = ref(getRightZoom(mapOpt.zoom));
let contentId = "";
let tileLayerList = [];
let layerIndex = -1;
({
...gyMapUtils
});
let mapFinish = ref(false);
const init = (id, opt) => {
if (!id) {
console.error(`not find ${id}`);
return;
}
initOptions(id, opt);
initTileLayerList();
initMap();
changeMapLayer(mapOpt.maplayerIndex);
};
let initOptions = (id, opt) => {
contentId = id;
mapOpt = Object.assign({}, mapOpt, opt);
formatOpt();
let extent = mapOpt.extent || void 0;
if (extent) {
let lonlat1 = extent[0];
let lonlat2 = extent[1];
if (lonlat1 && lonlat2) {
let c1 = gyMapUtils.formatLonLatToPosition(lonlat1);
let c2 = gyMapUtils.formatLonLatToPosition(lonlat2);
let ex = [
Math.min(c1[0], c2[0]),
Math.min(c1[1], c2[1]),
Math.max(c1[0], c2[0]),
Math.max(c1[1], c2[1])
];
mapOpt.extent = ex;
} else {
mapOpt.extent = void 0;
}
}
};
const initMap = () => {
view.value = markRaw(new View$2({
center: gyMapUtils.formatLonLatToPosition(mapOpt.centerPoint),
zoom: zoom.value,
minZoom: mapOpt.minZoom,
maxZoom: mapOpt.maxZoom,
extent: mapOpt.extent
}));
map.value = markRaw(new Map({
layers: tileLayerList,
target: contentId,
view: view.value,
controls: defaults({
zoom: mapOpt.isShowControls,
attribution: false,
rotate: true
}),
interactions: defaults$1(
mapOpt.interactionsObj || {}
)
}));
mapFinish.value = true;
map.value.on("click", (e) => {
map.value.forEachFeatureAtPixel(e.pixel, function(feature2) {
feature2.dispatchEvent({ type: "click", e });
return mapOpt.stopPropagation;
});
});
map.value.on("moveend", function(e) {
zoom.value = map.value.getView().getZoom();
});
};
const initTileLayerList = () => {
tileLayerList = [];
let mapUrlList = mapOpt.mapUrlList;
if (!Array.isArray(mapUrlList)) {
mapUrlList = [mapUrlList];
}
mapUrlList.forEach((v) => {
tileLayerList.push(
new TileLayer({
visible: false,
opacity: mapOpt.layerOpacity,
source: new XYZ({
maxZoom: 18,
url: v
})
})
);
});
};
const zoomSetFun = (val) => {
let zoomVal = getRightZoom(Number(val));
if (zoomVal === zoom.value) {
return;
}
view.value && view.value.animate({ zoom: zoomVal, duration: 800 });
zoom.value = zoomVal;
};
const zoomAddFun = () => {
zoomSetFun(zoom.value + 1);
};
const zoomSubFun = () => {
zoomSetFun(zoom.value - 1);
};
const changeMapLayer = (index2) => {
var _a, _b;
index2 = Number(index2 || 0);
if (layerIndex === index2) {
return;
}
let len = tileLayerList.length;
let i = Math.max(0, Math.min(index2, len));
if (layerIndex !== -1) {
(_a = tileLayerList[layerIndex]) == null ? void 0 : _a.setVisible(false);
}
(_b = tileLayerList[i]) == null ? void 0 : _b.setVisible(true);
layerIndex = i;
};
const changeCenterPoint = (center) => {
let point = gyMapUtils.formatLonLatToPosition(center);
view.value && view.value.animate({ center: point, duration: 800 });
};
const drawHtmlToMap = (id, {
position,
offset = [0, 0],
stopEvent = true,
className = ""
}) => {
let dom = null;
if (typeof id === "object") {
if (id instanceof HTMLElement) {
dom = [id];
} else {
console.error(`\u8BF7\u4F20\u5165\u6B63\u786E\u7684dom\u5BF9\u8C61\uFF01`);
return null;
}
} else if (typeof id === "string") {
dom = document.querySelectorAll(id);
if (dom.length === 0) {
console.error(`not find ${id}`);
return null;
}
}
if (!Array.isArray(position)) {
console.error(`position \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5E94\u8BE5\u4E3A [\u7ECF\u5EA6\uFF0C\u7EAC\u5EA6]`);
return null;
}
let overlayList = [];
Array.prototype.forEach.call(dom, (v) => {
let overlay = new Overlay({
element: v,
position: gyMapUtils.formatLonLatToPosition(position),
insertFirst: false,
autoPan: false,
stopEvent,
className: "ol-overlay-container ol-selectable " + className,
offset
});
map.value && map.value.addOverlay(overlay);
overlayList.push(overlay);
});
if (overlayList.length === 1) {
return overlayList[0];
} else {
return overlayList;
}
};
const removeOverlay = (overlay) => {
overlay && map.value && map.value.removeOverlay(overlay);
};
const setLayerOpacity = (val) => {
let layer = tileLayerList[layerIndex];
layer && layer.setOpacity(val);
};
const destory = () => {
delete gyMapResultObj[type];
};
let result = ref({
contentId: type,
map,
view,
mapFinish,
zoom,
init,
zoomSetFun,
zoomAddFun,
zoomSubFun,
changeMapLayer,
changeCenterPoint,
drawHtmlToMap,
removeOverlay,
setLayerOpacity,
destory
});
gyMapResultObj[type] = result;
return result;
};
const gyMap = (type) => {
if (gyMapResultObj[type]) {
return gyMapResultObj[type];
}
return gyMapInit.call(void 0, type);
};
const gyMap$1 = gyMap;
let install = (Vue) => {
if (!install.installed) {
const _components = Object.keys(components).map(
(key) => components[key]
);
_components.forEach((component) => {
if ((component.hasOwnProperty("name") || component.hasOwnProperty("__name")) && component.hasOwnProperty("setup")) {
Vue.component(component.name || component.__name, component);
}
});
}
};
const index = {
install
};
export {
Gymap,
GymapCircle,
GymapClusters,
GymapDraw,
GymapHeat,
GymapHtml,
GymapImage,
GymapLine,
GymapLonlat,
GymapPolygon,
GymapTask,
GymapText,
index as default,
gyMap$1 as gyMap,
gyMapUtils,
install
};