zenit-sdk 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-R73LRYVJ.mjs → chunk-LX2N2BXV.mjs} +270 -72
- package/dist/chunk-LX2N2BXV.mjs.map +1 -0
- package/dist/{index-Da0hFqDL.d.mts → index-kGwfqTc_.d.mts} +5 -0
- package/dist/{index-Da0hFqDL.d.ts → index-kGwfqTc_.d.ts} +5 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +269 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +269 -71
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +1 -1
- package/package.json +7 -27
- package/dist/chunk-R73LRYVJ.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MapDto, N as NormalizedMapLayer, G as GeoJsonFeature, B as Bbox, a as GeoJsonFeatureCollection, F as FilterMultipleMetadata, L as LayerFilters, b as GeoJsonRequestOptions, c as GeoJsonPolygon } from './index-
|
|
2
|
-
export { E as ApiEnvelope, I as ApiResponseData, ae as ChatRequestDto, a9 as ChatRequestOptions, ag as ChatResponseDto, a8 as ChatServiceConfig, aa as ChatStreamCallbacks, D as DEFAULT_MAX_FEATURES_FULL_GEOJSON, a4 as EffectiveLayerState, a0 as FilterMultipleLayerMeta, a1 as FilterMultipleWithFallbackResult, $ as FilterValue, an as FloatingChatBox, ao as FloatingChatBoxProps, K as GeoJsonBBoxRequest, A as GeoJsonGeometryCollection, O as GeoJsonIntersectRequest, z as GeoJsonPoint, l as HttpClient, H as HttpClientOptions, P as LayerAoi, a2 as LayerBaseState, C as LayerDataStrategy, x as LayerDto, Y as LayerFeatureCatalogItem, _ as LayerFeaturesCatalogDto, J as LayerMetadata, a3 as LayerOverrideState, aj as LayerSnapshot, ar as LayerStyle, y as LayerSummary, W as LoadLayerDataParams, X as LoadLayerDataResult, e as LoginRequest, f as LoginResponse, o as MapLayerConfig, n as MapSettings, g as MeResponse, R as RefreshResponse, Q as ResolveLayerStrategyParams, T as ResolveLayerStrategyResult, i as SdkTokenExchangeResponse, S as SdkTokenValidateResponse, af as SuggestedAction, U as UserSummary, V as ValidateResponse, h as ZenitAuthClient, d as ZenitClient, am as ZenitFeatureFilterPanel, al as ZenitLayerManager, w as ZenitLayersClient, ah as ZenitMap, ak as ZenitMapProps, ai as ZenitMapRef, m as ZenitMapsClient, j as ZenitSdkAuthClient, Z as ZenitSdkConfig, k as ZenitSdkError, aw as ZoomOpacityOptions, a6 as applyLayerOverrides, t as buildAoiFromFeatureCollection, q as buildFilterMultipleParams, p as buildLayerFilters, v as buildLimitedMessage, ax as clampNumber, ay as clampOpacity, ad as createChatService, av as getAccentByLayerId, aC as getEffectiveLayerOpacity, at as getLayerColor, aB as getLayerZoomOpacityFactor, au as getStyleByLayerId, aA as getZoomOpacityFactor, a5 as initLayerStates, az as isPolygonLayer, a7 as resetOverrides, as as resolveLayerAccent, u as resolveLayerStrategy, ab as sendMessage, ac as sendMessageStream, r as shouldSkipGeojsonDownload, s as shouldUseFilterMultiple, ap as useSendMessage, aq as useSendMessageStream } from './index-
|
|
1
|
+
import { M as MapDto, N as NormalizedMapLayer, G as GeoJsonFeature, B as Bbox, a as GeoJsonFeatureCollection, F as FilterMultipleMetadata, L as LayerFilters, b as GeoJsonRequestOptions, c as GeoJsonPolygon } from './index-kGwfqTc_.js';
|
|
2
|
+
export { E as ApiEnvelope, I as ApiResponseData, ae as ChatRequestDto, a9 as ChatRequestOptions, ag as ChatResponseDto, a8 as ChatServiceConfig, aa as ChatStreamCallbacks, D as DEFAULT_MAX_FEATURES_FULL_GEOJSON, a4 as EffectiveLayerState, a0 as FilterMultipleLayerMeta, a1 as FilterMultipleWithFallbackResult, $ as FilterValue, an as FloatingChatBox, ao as FloatingChatBoxProps, K as GeoJsonBBoxRequest, A as GeoJsonGeometryCollection, O as GeoJsonIntersectRequest, z as GeoJsonPoint, l as HttpClient, H as HttpClientOptions, P as LayerAoi, a2 as LayerBaseState, C as LayerDataStrategy, x as LayerDto, Y as LayerFeatureCatalogItem, _ as LayerFeaturesCatalogDto, J as LayerMetadata, a3 as LayerOverrideState, aj as LayerSnapshot, ar as LayerStyle, y as LayerSummary, W as LoadLayerDataParams, X as LoadLayerDataResult, e as LoginRequest, f as LoginResponse, o as MapLayerConfig, n as MapSettings, g as MeResponse, R as RefreshResponse, Q as ResolveLayerStrategyParams, T as ResolveLayerStrategyResult, i as SdkTokenExchangeResponse, S as SdkTokenValidateResponse, af as SuggestedAction, U as UserSummary, V as ValidateResponse, h as ZenitAuthClient, d as ZenitClient, am as ZenitFeatureFilterPanel, al as ZenitLayerManager, w as ZenitLayersClient, ah as ZenitMap, ak as ZenitMapProps, ai as ZenitMapRef, m as ZenitMapsClient, j as ZenitSdkAuthClient, Z as ZenitSdkConfig, k as ZenitSdkError, aw as ZoomOpacityOptions, a6 as applyLayerOverrides, t as buildAoiFromFeatureCollection, q as buildFilterMultipleParams, p as buildLayerFilters, v as buildLimitedMessage, ax as clampNumber, ay as clampOpacity, ad as createChatService, av as getAccentByLayerId, aC as getEffectiveLayerOpacity, at as getLayerColor, aB as getLayerZoomOpacityFactor, au as getStyleByLayerId, aA as getZoomOpacityFactor, a5 as initLayerStates, az as isPolygonLayer, a7 as resetOverrides, as as resolveLayerAccent, u as resolveLayerStrategy, ab as sendMessage, ac as sendMessageStream, r as shouldSkipGeojsonDownload, s as shouldUseFilterMultiple, ap as useSendMessage, aq as useSendMessageStream } from './index-kGwfqTc_.js';
|
|
3
3
|
export { ChevronLeft, ChevronRight, Eye, EyeOff, Layers, Upload, X, ZoomIn } from 'lucide-react';
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'leaflet';
|
package/dist/index.js
CHANGED
|
@@ -1403,7 +1403,7 @@ function normalizeBbox(input) {
|
|
|
1403
1403
|
}
|
|
1404
1404
|
|
|
1405
1405
|
// src/react/ZenitMap.tsx
|
|
1406
|
-
var import_react = require("react");
|
|
1406
|
+
var import_react = __toESM(require("react"));
|
|
1407
1407
|
var import_react_leaflet = require("react-leaflet");
|
|
1408
1408
|
var import_leaflet = __toESM(require("leaflet"));
|
|
1409
1409
|
|
|
@@ -1518,6 +1518,121 @@ function getFeatureLayerId(feature) {
|
|
|
1518
1518
|
function escapeHtml(value) {
|
|
1519
1519
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1520
1520
|
}
|
|
1521
|
+
var DESCRIPTION_KEYS = /* @__PURE__ */ new Set(["descripcion", "description"]);
|
|
1522
|
+
function normalizeDescriptionValue(value) {
|
|
1523
|
+
if (value === void 0 || value === null) return null;
|
|
1524
|
+
if (typeof value === "string") {
|
|
1525
|
+
const trimmed = value.trim();
|
|
1526
|
+
return trimmed ? trimmed : null;
|
|
1527
|
+
}
|
|
1528
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
1529
|
+
return String(value);
|
|
1530
|
+
}
|
|
1531
|
+
return null;
|
|
1532
|
+
}
|
|
1533
|
+
function extractDescriptionValue(properties) {
|
|
1534
|
+
if (!properties) return null;
|
|
1535
|
+
const matches = Object.entries(properties).find(
|
|
1536
|
+
([key]) => DESCRIPTION_KEYS.has(key.toLowerCase())
|
|
1537
|
+
);
|
|
1538
|
+
if (!matches) return null;
|
|
1539
|
+
return normalizeDescriptionValue(matches[1]);
|
|
1540
|
+
}
|
|
1541
|
+
function safeJsonStringify(value) {
|
|
1542
|
+
try {
|
|
1543
|
+
const json = JSON.stringify(value, null, 2);
|
|
1544
|
+
if (json !== void 0) return json;
|
|
1545
|
+
} catch {
|
|
1546
|
+
}
|
|
1547
|
+
return String(value);
|
|
1548
|
+
}
|
|
1549
|
+
function renderPropertyValue(value) {
|
|
1550
|
+
if (value === null || value === void 0) {
|
|
1551
|
+
return '<span class="prop-empty">\u2014</span>';
|
|
1552
|
+
}
|
|
1553
|
+
if (typeof value === "object") {
|
|
1554
|
+
const json = safeJsonStringify(value);
|
|
1555
|
+
return `<pre class="prop-json">${escapeHtml(json)}</pre>`;
|
|
1556
|
+
}
|
|
1557
|
+
return `<span class="prop-text">${escapeHtml(String(value))}</span>`;
|
|
1558
|
+
}
|
|
1559
|
+
var POPUP_TITLE_KEYS = ["name", "title", "nombre", "label", "id"];
|
|
1560
|
+
var POPUP_CHIP_KEYS = /* @__PURE__ */ new Set(["churn", "color", "sector"]);
|
|
1561
|
+
function isChipValue(value) {
|
|
1562
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1563
|
+
}
|
|
1564
|
+
function getSanitizedChipColor(value) {
|
|
1565
|
+
if (typeof value !== "string") return null;
|
|
1566
|
+
const trimmed = value.trim();
|
|
1567
|
+
if (/^#([0-9a-fA-F]{3}){1,2}$/.test(trimmed)) {
|
|
1568
|
+
return trimmed;
|
|
1569
|
+
}
|
|
1570
|
+
if (/^rgb\((\s*\d+\s*,){2}\s*\d+\s*\)$/.test(trimmed)) {
|
|
1571
|
+
return trimmed;
|
|
1572
|
+
}
|
|
1573
|
+
if (/^rgba\((\s*\d+\s*,){3}\s*(0|1|0?\.\d+)\s*\)$/.test(trimmed)) {
|
|
1574
|
+
return trimmed;
|
|
1575
|
+
}
|
|
1576
|
+
return null;
|
|
1577
|
+
}
|
|
1578
|
+
function getPopupTitle(entries) {
|
|
1579
|
+
for (const candidate of POPUP_TITLE_KEYS) {
|
|
1580
|
+
const match = entries.find((entry) => entry.normalized === candidate);
|
|
1581
|
+
if (!match || match.value === null || match.value === void 0) continue;
|
|
1582
|
+
const value = String(match.value).trim();
|
|
1583
|
+
if (!value) continue;
|
|
1584
|
+
return { title: value, key: match.key };
|
|
1585
|
+
}
|
|
1586
|
+
return null;
|
|
1587
|
+
}
|
|
1588
|
+
function renderProperties(properties) {
|
|
1589
|
+
const description = extractDescriptionValue(properties);
|
|
1590
|
+
const entries = Object.entries(properties).filter(([key]) => !DESCRIPTION_KEYS.has(key.toLowerCase())).map(([key, value]) => ({
|
|
1591
|
+
key,
|
|
1592
|
+
value,
|
|
1593
|
+
normalized: key.trim().toLowerCase()
|
|
1594
|
+
}));
|
|
1595
|
+
if (!description && entries.length === 0) return "";
|
|
1596
|
+
const titleEntry = getPopupTitle(entries);
|
|
1597
|
+
const titleText = titleEntry?.title ?? "Detalle del elemento";
|
|
1598
|
+
const chipEntries = entries.filter(
|
|
1599
|
+
(entry) => POPUP_CHIP_KEYS.has(entry.normalized) && isChipValue(entry.value)
|
|
1600
|
+
);
|
|
1601
|
+
const listEntries = entries.filter((entry) => {
|
|
1602
|
+
if (titleEntry && entry.key === titleEntry.key) return false;
|
|
1603
|
+
if (chipEntries.find((chip) => chip.key === entry.key)) return false;
|
|
1604
|
+
return true;
|
|
1605
|
+
});
|
|
1606
|
+
const descriptionHtml = description ? `<div class="popup-description">${escapeHtml(description)}</div>` : "";
|
|
1607
|
+
const chipsHtml = chipEntries.length ? `<div class="popup-chip-row">${chipEntries.map((entry) => {
|
|
1608
|
+
const label = escapeHtml(entry.key.replace(/_/g, " "));
|
|
1609
|
+
const value = escapeHtml(String(entry.value));
|
|
1610
|
+
const color = getSanitizedChipColor(entry.value);
|
|
1611
|
+
const colorStyle = color ? ` style="--chip-color: ${color}"` : "";
|
|
1612
|
+
return `<span class="popup-chip"${colorStyle}><span class="popup-chip-label">${label}</span><span class="popup-chip-value">${value}</span></span>`;
|
|
1613
|
+
}).join("")}</div>` : "";
|
|
1614
|
+
const rowsHtml = listEntries.map((entry) => {
|
|
1615
|
+
const label = escapeHtml(entry.key.replace(/_/g, " "));
|
|
1616
|
+
const valueHtml = renderPropertyValue(entry.value);
|
|
1617
|
+
return `<div class="prop-key">${label}</div><div class="prop-value">${valueHtml}</div>`;
|
|
1618
|
+
}).join("");
|
|
1619
|
+
const listHtml = rowsHtml ? `<div class="prop-list">${rowsHtml}</div>` : "";
|
|
1620
|
+
return `
|
|
1621
|
+
<div class="feature-popup">
|
|
1622
|
+
<div class="feature-popup-card">
|
|
1623
|
+
<div class="feature-popup-header">
|
|
1624
|
+
<p class="popup-eyebrow">Informaci\xF3n</p>
|
|
1625
|
+
<h3 class="popup-title">${escapeHtml(titleText)}</h3>
|
|
1626
|
+
</div>
|
|
1627
|
+
<div class="feature-popup-body">
|
|
1628
|
+
${descriptionHtml}
|
|
1629
|
+
${chipsHtml}
|
|
1630
|
+
${listHtml}
|
|
1631
|
+
</div>
|
|
1632
|
+
</div>
|
|
1633
|
+
</div>
|
|
1634
|
+
`;
|
|
1635
|
+
}
|
|
1521
1636
|
function withAlpha(color, alpha) {
|
|
1522
1637
|
const trimmed = color.trim();
|
|
1523
1638
|
if (trimmed.startsWith("#")) {
|
|
@@ -1586,40 +1701,39 @@ function getFeatureStyleOverrides(feature) {
|
|
|
1586
1701
|
function buildFeaturePopupHtml(feature) {
|
|
1587
1702
|
const properties = feature?.properties;
|
|
1588
1703
|
if (!properties) return null;
|
|
1589
|
-
const
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
if (
|
|
1615
|
-
const
|
|
1616
|
-
|
|
1617
|
-
const val = escapeHtml(String(value));
|
|
1618
|
-
return `<div><strong>${label}:</strong> ${val}</div>`;
|
|
1619
|
-
}).join("");
|
|
1620
|
-
parts.push(`<div style="font-size:12px;line-height:1.4;">${rows}</div>`);
|
|
1704
|
+
const rendered = renderProperties(properties);
|
|
1705
|
+
return rendered ? rendered : null;
|
|
1706
|
+
}
|
|
1707
|
+
var POINT_GEOMETRY_TYPES = /* @__PURE__ */ new Set(["Point", "MultiPoint"]);
|
|
1708
|
+
function getGeometryType(feature) {
|
|
1709
|
+
const t = feature?.geometry?.type;
|
|
1710
|
+
return typeof t === "string" ? t : null;
|
|
1711
|
+
}
|
|
1712
|
+
function isPointGeometry(feature) {
|
|
1713
|
+
const geometryType = getGeometryType(feature);
|
|
1714
|
+
return geometryType !== null && POINT_GEOMETRY_TYPES.has(geometryType);
|
|
1715
|
+
}
|
|
1716
|
+
function isNonPointGeometry(feature) {
|
|
1717
|
+
const geometryType = getGeometryType(feature);
|
|
1718
|
+
return geometryType !== null && !POINT_GEOMETRY_TYPES.has(geometryType);
|
|
1719
|
+
}
|
|
1720
|
+
function buildFeatureCollection(features) {
|
|
1721
|
+
return {
|
|
1722
|
+
type: "FeatureCollection",
|
|
1723
|
+
features
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
function pickIntersectFeature(baseFeature, candidates) {
|
|
1727
|
+
if (!Array.isArray(candidates) || candidates.length === 0) return null;
|
|
1728
|
+
const baseId = baseFeature?.id;
|
|
1729
|
+
if (baseId !== void 0 && baseId !== null) {
|
|
1730
|
+
const matchById = candidates.find((candidate) => candidate?.id === baseId);
|
|
1731
|
+
if (matchById) return matchById;
|
|
1621
1732
|
}
|
|
1622
|
-
|
|
1733
|
+
const matchWithDescription = candidates.find(
|
|
1734
|
+
(candidate) => extractDescriptionValue(candidate?.properties)
|
|
1735
|
+
);
|
|
1736
|
+
return matchWithDescription ?? candidates[0];
|
|
1623
1737
|
}
|
|
1624
1738
|
function normalizeCenterTuple(center) {
|
|
1625
1739
|
if (!center) return null;
|
|
@@ -1740,6 +1854,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
1740
1854
|
const [loadingMap, setLoadingMap] = (0, import_react.useState)(false);
|
|
1741
1855
|
const [mapError, setMapError] = (0, import_react.useState)(null);
|
|
1742
1856
|
const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
|
|
1857
|
+
const [panesReady, setPanesReady] = (0, import_react.useState)(false);
|
|
1743
1858
|
const [currentZoom, setCurrentZoom] = (0, import_react.useState)(initialZoom ?? DEFAULT_ZOOM);
|
|
1744
1859
|
const [isMobile, setIsMobile] = (0, import_react.useState)(() => {
|
|
1745
1860
|
if (typeof window === "undefined") return false;
|
|
@@ -2054,16 +2169,23 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2054
2169
|
(targetMap, targetLayers) => {
|
|
2055
2170
|
const baseZIndex = 400;
|
|
2056
2171
|
targetLayers.forEach((layer) => {
|
|
2057
|
-
const paneName = `zenit-layer-${layer.layerId}`;
|
|
2058
|
-
const pane = targetMap.getPane(paneName) ?? targetMap.createPane(paneName);
|
|
2059
2172
|
const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;
|
|
2060
|
-
|
|
2173
|
+
const fillPaneName = `zenit-layer-${layer.layerId}-fill`;
|
|
2174
|
+
const pointPaneName = `zenit-layer-${layer.layerId}-points`;
|
|
2175
|
+
const labelPaneName = `zenit-layer-${layer.layerId}-labels`;
|
|
2176
|
+
const fillPane = targetMap.getPane(fillPaneName) ?? targetMap.createPane(fillPaneName);
|
|
2177
|
+
const pointPane = targetMap.getPane(pointPaneName) ?? targetMap.createPane(pointPaneName);
|
|
2178
|
+
const labelPane = targetMap.getPane(labelPaneName) ?? targetMap.createPane(labelPaneName);
|
|
2179
|
+
fillPane.style.zIndex = String(baseZIndex + order);
|
|
2180
|
+
pointPane.style.zIndex = String(baseZIndex + order + 1e3);
|
|
2181
|
+
labelPane.style.zIndex = String(baseZIndex + order + 2e3);
|
|
2061
2182
|
});
|
|
2062
2183
|
},
|
|
2063
2184
|
[]
|
|
2064
2185
|
);
|
|
2065
2186
|
const handleMapReady = (0, import_react.useCallback)(
|
|
2066
2187
|
(instance) => {
|
|
2188
|
+
setPanesReady(false);
|
|
2067
2189
|
setMapInstance(instance);
|
|
2068
2190
|
onMapReady?.(instance);
|
|
2069
2191
|
},
|
|
@@ -2071,6 +2193,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2071
2193
|
);
|
|
2072
2194
|
(0, import_react.useEffect)(() => {
|
|
2073
2195
|
if (!mapInstance) {
|
|
2196
|
+
setPanesReady(false);
|
|
2074
2197
|
return;
|
|
2075
2198
|
}
|
|
2076
2199
|
if (orderedLayers.length === 0) {
|
|
@@ -2081,6 +2204,11 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2081
2204
|
displayOrder: layer.displayOrder
|
|
2082
2205
|
}));
|
|
2083
2206
|
ensureLayerPanes(mapInstance, layerTargets);
|
|
2207
|
+
const first = layerTargets[0];
|
|
2208
|
+
const testPane = mapInstance.getPane(`zenit-layer-${first.layerId}-labels`);
|
|
2209
|
+
if (testPane) {
|
|
2210
|
+
setPanesReady(true);
|
|
2211
|
+
}
|
|
2084
2212
|
}, [mapInstance, orderedLayers, ensureLayerPanes]);
|
|
2085
2213
|
const overlayOnEachFeature = (0, import_react.useMemo)(() => {
|
|
2086
2214
|
return (feature, layer) => {
|
|
@@ -2098,7 +2226,14 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2098
2226
|
if (featureInfoMode === "popup") {
|
|
2099
2227
|
const content = buildFeaturePopupHtml(feature);
|
|
2100
2228
|
if (content) {
|
|
2101
|
-
layer.bindPopup(content, {
|
|
2229
|
+
layer.bindPopup(content, {
|
|
2230
|
+
maxWidth: 420,
|
|
2231
|
+
minWidth: 280,
|
|
2232
|
+
className: "zenit-feature-popup-shell",
|
|
2233
|
+
autoPan: true,
|
|
2234
|
+
closeButton: true,
|
|
2235
|
+
offset: import_leaflet.default.point(0, -24)
|
|
2236
|
+
});
|
|
2102
2237
|
}
|
|
2103
2238
|
}
|
|
2104
2239
|
if (isPointFeature && layer.bindTooltip) {
|
|
@@ -2109,7 +2244,37 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2109
2244
|
className: "zenit-map-tooltip"
|
|
2110
2245
|
});
|
|
2111
2246
|
}
|
|
2112
|
-
layer.on("click", () =>
|
|
2247
|
+
layer.on("click", () => {
|
|
2248
|
+
if (featureInfoMode === "popup" && client && layerId !== void 0 && !extractDescriptionValue(feature?.properties) && feature?.geometry) {
|
|
2249
|
+
const trackedFeature = feature;
|
|
2250
|
+
if (!trackedFeature.__zenit_popup_loaded) {
|
|
2251
|
+
trackedFeature.__zenit_popup_loaded = true;
|
|
2252
|
+
client.layers.getLayerGeoJsonIntersect({
|
|
2253
|
+
id: layerId,
|
|
2254
|
+
geometry: feature.geometry
|
|
2255
|
+
}).then((response) => {
|
|
2256
|
+
const candidates = response.data?.features ?? [];
|
|
2257
|
+
const resolved = pickIntersectFeature(feature, candidates);
|
|
2258
|
+
if (!resolved?.properties) return;
|
|
2259
|
+
const mergedProperties = {
|
|
2260
|
+
...trackedFeature.properties ?? {},
|
|
2261
|
+
...resolved.properties
|
|
2262
|
+
};
|
|
2263
|
+
trackedFeature.properties = mergedProperties;
|
|
2264
|
+
const updatedHtml = buildFeaturePopupHtml({
|
|
2265
|
+
...feature,
|
|
2266
|
+
properties: mergedProperties
|
|
2267
|
+
});
|
|
2268
|
+
if (updatedHtml && layer.setPopupContent) {
|
|
2269
|
+
layer.setPopupContent(updatedHtml);
|
|
2270
|
+
}
|
|
2271
|
+
}).catch(() => {
|
|
2272
|
+
trackedFeature.__zenit_popup_loaded = false;
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
onFeatureClick?.(feature, layerId);
|
|
2277
|
+
});
|
|
2113
2278
|
layer.on("mouseover", () => {
|
|
2114
2279
|
if (layer instanceof import_leaflet.default.Path && originalStyle) {
|
|
2115
2280
|
layer.setStyle({
|
|
@@ -2133,7 +2298,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2133
2298
|
}
|
|
2134
2299
|
});
|
|
2135
2300
|
};
|
|
2136
|
-
}, [featureInfoMode, onFeatureClick, onFeatureHover]);
|
|
2301
|
+
}, [client, featureInfoMode, onFeatureClick, onFeatureHover]);
|
|
2137
2302
|
const buildLayerStyle = (layerId, baseOpacity, feature, layerType) => {
|
|
2138
2303
|
const style = resolveLayerStyle(layerId);
|
|
2139
2304
|
const featureStyleOverrides = getFeatureStyleOverrides(feature);
|
|
@@ -2314,22 +2479,50 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2314
2479
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ZoomBasedOpacityHandler, { onZoomChange: handleZoomChange }),
|
|
2315
2480
|
orderedLayers.map((layerState) => {
|
|
2316
2481
|
const baseOpacity = layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;
|
|
2317
|
-
const
|
|
2482
|
+
const fillPaneName = `zenit-layer-${layerState.mapLayer.layerId}-fill`;
|
|
2483
|
+
const pointsPaneName = `zenit-layer-${layerState.mapLayer.layerId}-points`;
|
|
2484
|
+
const labelPaneName = `zenit-layer-${layerState.mapLayer.layerId}-labels`;
|
|
2318
2485
|
const layerType = layerState.layer?.layerType ?? layerState.mapLayer.layerType ?? void 0;
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2486
|
+
const data = layerState.data?.features ?? [];
|
|
2487
|
+
const fillFeatures = data.filter(isNonPointGeometry);
|
|
2488
|
+
const pointFeatures = data.filter(isPointGeometry);
|
|
2489
|
+
const fillData = fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null;
|
|
2490
|
+
const pointsData = pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null;
|
|
2491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [
|
|
2492
|
+
fillData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2493
|
+
import_react_leaflet.GeoJSON,
|
|
2494
|
+
{
|
|
2495
|
+
data: fillData,
|
|
2496
|
+
pane: panesReady && mapInstance?.getPane(fillPaneName) ? fillPaneName : void 0,
|
|
2497
|
+
style: (feature) => buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),
|
|
2498
|
+
onEachFeature: overlayOnEachFeature
|
|
2499
|
+
}
|
|
2500
|
+
),
|
|
2501
|
+
pointsData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2502
|
+
import_react_leaflet.GeoJSON,
|
|
2503
|
+
{
|
|
2504
|
+
data: pointsData,
|
|
2505
|
+
pane: panesReady && mapInstance?.getPane(pointsPaneName) ? pointsPaneName : void 0,
|
|
2506
|
+
pointToLayer: (feature, latlng) => import_leaflet.default.circleMarker(latlng, {
|
|
2507
|
+
radius: isMobile ? 8 : 6,
|
|
2508
|
+
...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)
|
|
2509
|
+
}),
|
|
2510
|
+
onEachFeature: overlayOnEachFeature
|
|
2511
|
+
}
|
|
2512
|
+
),
|
|
2513
|
+
panesReady && mapInstance?.getPane(labelPaneName) ? labelMarkers.filter(
|
|
2514
|
+
(marker) => String(marker.layerId) === String(layerState.mapLayer.layerId)
|
|
2515
|
+
).map((marker) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2516
|
+
import_react_leaflet.Marker,
|
|
2517
|
+
{
|
|
2518
|
+
position: marker.position,
|
|
2519
|
+
icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
|
|
2520
|
+
interactive: false,
|
|
2521
|
+
pane: labelPaneName
|
|
2522
|
+
},
|
|
2523
|
+
marker.key
|
|
2524
|
+
)) : null
|
|
2525
|
+
] }, layerState.mapLayer.layerId.toString());
|
|
2333
2526
|
}),
|
|
2334
2527
|
overlayGeojson && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2335
2528
|
import_react_leaflet.GeoJSON,
|
|
@@ -2339,16 +2532,7 @@ var ZenitMap = (0, import_react.forwardRef)(({
|
|
|
2339
2532
|
onEachFeature: overlayOnEachFeature
|
|
2340
2533
|
},
|
|
2341
2534
|
"zenit-overlay-geojson"
|
|
2342
|
-
)
|
|
2343
|
-
labelMarkers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2344
|
-
import_react_leaflet.Marker,
|
|
2345
|
-
{
|
|
2346
|
-
position: marker.position,
|
|
2347
|
-
icon: buildLabelIcon(marker.label, marker.opacity, marker.color),
|
|
2348
|
-
interactive: false
|
|
2349
|
-
},
|
|
2350
|
-
marker.key
|
|
2351
|
-
))
|
|
2535
|
+
)
|
|
2352
2536
|
]
|
|
2353
2537
|
},
|
|
2354
2538
|
String(mapId)
|
|
@@ -3630,9 +3814,19 @@ var FloatingChatBox = ({
|
|
|
3630
3814
|
getAccessToken,
|
|
3631
3815
|
onActionClick,
|
|
3632
3816
|
onOpenChange,
|
|
3633
|
-
hideButton
|
|
3817
|
+
hideButton,
|
|
3818
|
+
open: openProp
|
|
3634
3819
|
}) => {
|
|
3635
|
-
const
|
|
3820
|
+
const isControlled = openProp !== void 0;
|
|
3821
|
+
const [internalOpen, setInternalOpen] = (0, import_react4.useState)(false);
|
|
3822
|
+
const open = isControlled ? openProp : internalOpen;
|
|
3823
|
+
const setOpen = (0, import_react4.useCallback)((value) => {
|
|
3824
|
+
const newValue = typeof value === "function" ? value(open) : value;
|
|
3825
|
+
if (!isControlled) {
|
|
3826
|
+
setInternalOpen(newValue);
|
|
3827
|
+
}
|
|
3828
|
+
onOpenChange?.(newValue);
|
|
3829
|
+
}, [isControlled, open, onOpenChange]);
|
|
3636
3830
|
const [expanded, setExpanded] = (0, import_react4.useState)(false);
|
|
3637
3831
|
const [messages, setMessages] = (0, import_react4.useState)([]);
|
|
3638
3832
|
const [inputValue, setInputValue] = (0, import_react4.useState)("");
|
|
@@ -3649,9 +3843,6 @@ var FloatingChatBox = ({
|
|
|
3649
3843
|
}, [accessToken, baseUrl, getAccessToken]);
|
|
3650
3844
|
const { sendMessage: sendMessage2, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);
|
|
3651
3845
|
const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;
|
|
3652
|
-
(0, import_react4.useEffect)(() => {
|
|
3653
|
-
onOpenChange?.(open);
|
|
3654
|
-
}, [open, onOpenChange]);
|
|
3655
3846
|
(0, import_react4.useEffect)(() => {
|
|
3656
3847
|
if (open && isMobile) {
|
|
3657
3848
|
setExpanded(true);
|
|
@@ -3804,6 +3995,13 @@ var FloatingChatBox = ({
|
|
|
3804
3995
|
] }, index)) })
|
|
3805
3996
|
] });
|
|
3806
3997
|
};
|
|
3998
|
+
const handleActionClick = (0, import_react4.useCallback)((action) => {
|
|
3999
|
+
if (isStreaming) return;
|
|
4000
|
+
setOpen(false);
|
|
4001
|
+
requestAnimationFrame(() => {
|
|
4002
|
+
onActionClick?.(action);
|
|
4003
|
+
});
|
|
4004
|
+
}, [isStreaming, setOpen, onActionClick]);
|
|
3807
4005
|
const renderActions = (response) => {
|
|
3808
4006
|
if (!response?.suggestedActions?.length) return null;
|
|
3809
4007
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles.actionsSection, children: [
|
|
@@ -3817,7 +4015,7 @@ var FloatingChatBox = ({
|
|
|
3817
4015
|
opacity: isStreaming ? 0.5 : 1,
|
|
3818
4016
|
cursor: isStreaming ? "not-allowed" : "pointer"
|
|
3819
4017
|
},
|
|
3820
|
-
onClick: () =>
|
|
4018
|
+
onClick: () => handleActionClick(action),
|
|
3821
4019
|
disabled: isStreaming,
|
|
3822
4020
|
onMouseEnter: (e) => {
|
|
3823
4021
|
if (!isStreaming) {
|