@geowiki/map 0.16.9-dev.7 → 0.16.9-dev.9

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/index.d.mts CHANGED
@@ -615,11 +615,7 @@ declare const WaybackTimelineMap: (props: {
615
615
 
616
616
  interface MapLibreProps extends React__default.HTMLAttributes<HTMLDivElement> {
617
617
  baseLayers?: {
618
- name: string;
619
- type: string;
620
- layer_type?: "hillshade" | "terrainSource";
621
- url?: string;
622
- tileSize?: number;
618
+ layer_type?: "hillshade" | "terrainSource" | "satellite";
623
619
  }[];
624
620
  customLayers?: {
625
621
  id: string;
@@ -634,18 +630,26 @@ interface MapLibreProps extends React__default.HTMLAttributes<HTMLDivElement> {
634
630
  }[];
635
631
  mapControls?: {
636
632
  type: "zoom" | "projection" | "toggle_layers";
633
+ get_bounds?: (arg: any) => any;
637
634
  }[];
638
635
  sourceData?: {
639
636
  name: string;
640
637
  type: "geojson";
641
638
  data: any;
639
+ custom_cluster?: boolean;
642
640
  is_cluster?: boolean;
643
641
  show_cluster_count?: boolean;
644
642
  style?: {
645
643
  cluster_color: string;
646
644
  cluster_stroke_color: string;
645
+ pin_color: string;
647
646
  };
648
647
  }[];
648
+ show_popup?: boolean;
649
+ popup?: {
650
+ click?: (arg: any) => void;
651
+ style?: {};
652
+ };
649
653
  }
650
654
  declare const MapLibre: React__default.ForwardRefExoticComponent<MapLibreProps & React__default.RefAttributes<HTMLDivElement>>;
651
655
 
package/dist/index.d.ts CHANGED
@@ -615,11 +615,7 @@ declare const WaybackTimelineMap: (props: {
615
615
 
616
616
  interface MapLibreProps extends React__default.HTMLAttributes<HTMLDivElement> {
617
617
  baseLayers?: {
618
- name: string;
619
- type: string;
620
- layer_type?: "hillshade" | "terrainSource";
621
- url?: string;
622
- tileSize?: number;
618
+ layer_type?: "hillshade" | "terrainSource" | "satellite";
623
619
  }[];
624
620
  customLayers?: {
625
621
  id: string;
@@ -634,18 +630,26 @@ interface MapLibreProps extends React__default.HTMLAttributes<HTMLDivElement> {
634
630
  }[];
635
631
  mapControls?: {
636
632
  type: "zoom" | "projection" | "toggle_layers";
633
+ get_bounds?: (arg: any) => any;
637
634
  }[];
638
635
  sourceData?: {
639
636
  name: string;
640
637
  type: "geojson";
641
638
  data: any;
639
+ custom_cluster?: boolean;
642
640
  is_cluster?: boolean;
643
641
  show_cluster_count?: boolean;
644
642
  style?: {
645
643
  cluster_color: string;
646
644
  cluster_stroke_color: string;
645
+ pin_color: string;
647
646
  };
648
647
  }[];
648
+ show_popup?: boolean;
649
+ popup?: {
650
+ click?: (arg: any) => void;
651
+ style?: {};
652
+ };
649
653
  }
650
654
  declare const MapLibre: React__default.ForwardRefExoticComponent<MapLibreProps & React__default.RefAttributes<HTMLDivElement>>;
651
655
 
package/dist/index.js CHANGED
@@ -17037,6 +17037,7 @@ var WaybackTimelineMap = (props) => {
17037
17037
  var import_react66 = require("react");
17038
17038
  var import_react67 = require("react");
17039
17039
  var import_maplibre_gl = __toESM(require("maplibre-gl"));
17040
+ var import_maplibre_gl2 = require("maplibre-gl/dist/maplibre-gl.css");
17040
17041
  var import_MapPinIcon4 = __toESM(require("@heroicons/react/24/solid/MapPinIcon"));
17041
17042
  var import_server8 = require("react-dom/server");
17042
17043
 
@@ -20097,44 +20098,50 @@ MapControlToolbar.displayName = "MapControlToolbar";
20097
20098
  // src/Components/Map/MapLibre.tsx
20098
20099
  var import_ui46 = require("@geowiki/ui");
20099
20100
  var import_jsx_runtime81 = require("react/jsx-runtime");
20100
- var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapControls, sourceData }, ref) => {
20101
+ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapControls, sourceData, show_popup, popup }, ref) => {
20101
20102
  const mapContainer = ref;
20102
20103
  const mapRef = (0, import_react66.useRef)(null);
20104
+ const map = mapRef.current;
20103
20105
  const changeMapProjection = () => {
20104
20106
  var _a;
20105
20107
  if (!mapRef.current)
20106
20108
  return;
20107
- const map = mapRef.current;
20108
- const currentProjection = (_a = map.getProjection()) == null ? void 0 : _a.type;
20109
+ const map2 = mapRef.current;
20110
+ const currentProjection = (_a = map2.getProjection()) == null ? void 0 : _a.type;
20109
20111
  const newProjection = currentProjection === "mercator" ? "globe" : "mercator";
20110
- map.setProjection({
20112
+ map2.setProjection({
20111
20113
  type: newProjection
20112
20114
  });
20113
20115
  };
20114
20116
  const zoomIn = () => {
20115
20117
  if (!mapRef.current)
20116
20118
  return;
20117
- const map = mapRef.current;
20118
- map.zoomIn();
20119
+ const map2 = mapRef.current;
20120
+ map2.zoomIn();
20121
+ return map2.getBounds();
20119
20122
  };
20120
20123
  const zoomOut = () => {
20121
20124
  if (!mapRef.current)
20122
20125
  return;
20123
- const map = mapRef.current;
20124
- map.zoomOut();
20126
+ const map2 = mapRef.current;
20127
+ map2.zoomOut();
20128
+ return map2.getBounds();
20125
20129
  };
20126
- function getLayersByPattern(map, pattern) {
20127
- return map.getStyle().layers.filter((layer) => pattern.test(layer.id)).map((layer) => layer.id);
20130
+ function getLayersByPattern(pattern) {
20131
+ if (!mapRef.current)
20132
+ return;
20133
+ const map2 = mapRef.current;
20134
+ return map2 == null ? void 0 : map2.getStyle().layers.filter((layer) => pattern.test(layer.id)).map((layer) => layer.id);
20128
20135
  }
20129
20136
  const handleToggle = (layerId) => {
20130
20137
  if (!mapRef.current)
20131
20138
  return;
20132
- const map = mapRef.current;
20133
- const layers = getLayersByPattern(map, new RegExp(layerId));
20134
- layers.forEach((id) => {
20135
- const visibility = map.getLayoutProperty(id, "visibility");
20139
+ const map2 = mapRef.current;
20140
+ const layers = getLayersByPattern(new RegExp(layerId));
20141
+ layers == null ? void 0 : layers.forEach((id) => {
20142
+ const visibility = map2 == null ? void 0 : map2.getLayoutProperty(id, "visibility");
20136
20143
  const newVisibility = visibility === "none" ? "visible" : "none";
20137
- map.setLayoutProperty(id, "visibility", newVisibility);
20144
+ map2 == null ? void 0 : map2.setLayoutProperty(id, "visibility", newVisibility);
20138
20145
  });
20139
20146
  };
20140
20147
  const buildControls = (controls) => {
@@ -20157,7 +20164,11 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20157
20164
  {
20158
20165
  id: "zoomIn",
20159
20166
  icon: import_ui46.PlusIcon,
20160
- onClick: zoomIn,
20167
+ onClick: () => {
20168
+ var _a;
20169
+ const bounds = zoomIn();
20170
+ (_a = c.get_bounds) == null ? void 0 : _a.call(c, bounds);
20171
+ },
20161
20172
  position: "topright",
20162
20173
  isOpen: true,
20163
20174
  isDisplayOnly: false,
@@ -20167,7 +20178,11 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20167
20178
  {
20168
20179
  id: "zoomOut",
20169
20180
  icon: import_ui46.MinusIcon,
20170
- onClick: zoomOut,
20181
+ onClick: () => {
20182
+ var _a;
20183
+ const bounds = zoomOut();
20184
+ (_a = c.get_bounds) == null ? void 0 : _a.call(c, bounds);
20185
+ },
20171
20186
  position: "topright",
20172
20187
  isOpen: true,
20173
20188
  isDisplayOnly: false,
@@ -20196,6 +20211,7 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20196
20211
  }
20197
20212
  ),
20198
20213
  position: "topleft",
20214
+ title: "OVERLAY MAPS",
20199
20215
  isOpen: false,
20200
20216
  isDisplayOnly: false,
20201
20217
  popoverDirection: "right",
@@ -20206,8 +20222,39 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20206
20222
  }
20207
20223
  }).flat();
20208
20224
  };
20225
+ const buildBaseLayers = (baselayers) => {
20226
+ return baselayers.map((c) => {
20227
+ switch (c.layer_type) {
20228
+ case "satellite":
20229
+ return {
20230
+ name: "satellite",
20231
+ type: "raster",
20232
+ url: "https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg",
20233
+ tileSize: 256,
20234
+ layer_type: "satellite"
20235
+ };
20236
+ case "terrainSource":
20237
+ return {
20238
+ name: "terrainSource",
20239
+ type: "raster-dem",
20240
+ url: "https://tiles.mapterhorn.com/tilejson.json",
20241
+ tileSize: 256,
20242
+ layer_type: "terrainSource"
20243
+ };
20244
+ case "hillshade":
20245
+ return {
20246
+ name: "hillshadeSource",
20247
+ type: "raster-dem",
20248
+ url: "https://tiles.mapterhorn.com/tilejson.json",
20249
+ tileSize: 256,
20250
+ layer_type: "hillshade"
20251
+ };
20252
+ default:
20253
+ return null;
20254
+ }
20255
+ }).flat();
20256
+ };
20209
20257
  const [mapControl, setMapControl] = (0, import_react66.useState)(() => buildControls(mapControls));
20210
- console.log(mapControl);
20211
20258
  const toggleControl = (id) => {
20212
20259
  setMapControl((prevControls) => prevControls.map((control) => {
20213
20260
  if (control.id === id) {
@@ -20216,93 +20263,95 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20216
20263
  return control;
20217
20264
  }));
20218
20265
  };
20219
- (0, import_react66.useEffect)(() => {
20220
- if (typeof mapContainer === "function")
20221
- return;
20222
- if (!(mapContainer == null ? void 0 : mapContainer.current))
20223
- return;
20224
- if (!sourceData)
20266
+ const loadSvgImage = (color) => __async(void 0, null, function* () {
20267
+ let svgText = (0, import_server8.renderToStaticMarkup)(
20268
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_MapPinIcon4.default, { className: "w-6 h-6" })
20269
+ );
20270
+ svgText = svgText.replace('fill="currentColor"', `fill="${color}"`);
20271
+ const img = new Image();
20272
+ img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgText);
20273
+ img.width = 35;
20274
+ img.height = 35;
20275
+ yield img.decode();
20276
+ return img;
20277
+ });
20278
+ const updatePinImage = (source) => __async(void 0, null, function* () {
20279
+ const img = yield loadSvgImage(source.style.pin_color);
20280
+ const imgName = `${source.name}-pin`;
20281
+ if (map == null ? void 0 : map.hasImage(imgName))
20282
+ map == null ? void 0 : map.removeImage(imgName);
20283
+ map == null ? void 0 : map.addImage(imgName, img);
20284
+ });
20285
+ const updateClusterColors = (source) => {
20286
+ const layerId = `${source.name}-cluster-circles`;
20287
+ if (!(map == null ? void 0 : map.getLayer(layerId)))
20225
20288
  return;
20226
- const map = new import_maplibre_gl.default.Map({
20227
- container: mapContainer == null ? void 0 : mapContainer.current,
20228
- style: {
20229
- version: 8,
20230
- sources: {
20231
- osm: {
20232
- type: "raster",
20233
- tiles: ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"],
20234
- tileSize: 256,
20235
- attribution: "&copy; OpenStreetMap Contributors",
20236
- maxzoom: 19
20237
- }
20238
- },
20239
- layers: [
20240
- {
20241
- id: "osm",
20242
- type: "raster",
20243
- source: "osm"
20289
+ const current = map == null ? void 0 : map.getPaintProperty(layerId, "circle-color");
20290
+ if (current !== source.style.cluster_color) {
20291
+ map == null ? void 0 : map.setPaintProperty(layerId, "circle-color", source.style.cluster_color);
20292
+ map == null ? void 0 : map.setPaintProperty(layerId, "circle-stroke-color", source.style.cluster_stroke_color);
20293
+ }
20294
+ };
20295
+ const loadBaseLayers = () => {
20296
+ if (baseLayers && (baseLayers == null ? void 0 : baseLayers.length) > 0) {
20297
+ const base_layers = buildBaseLayers(baseLayers);
20298
+ base_layers == null ? void 0 : base_layers.forEach((layer) => {
20299
+ if (!(map == null ? void 0 : map.getLayer(layer.name))) {
20300
+ if (!(map == null ? void 0 : map.getSource(layer == null ? void 0 : layer.name))) {
20301
+ if ((layer == null ? void 0 : layer.layer_type) == "satellite")
20302
+ map == null ? void 0 : map.addSource(layer == null ? void 0 : layer.name, {
20303
+ type: layer == null ? void 0 : layer.type,
20304
+ tiles: [layer == null ? void 0 : layer.url],
20305
+ tileSize: layer == null ? void 0 : layer.tileSize
20306
+ });
20307
+ else
20308
+ map == null ? void 0 : map.addSource(layer == null ? void 0 : layer.name, {
20309
+ type: layer == null ? void 0 : layer.type,
20310
+ url: layer == null ? void 0 : layer.url,
20311
+ tileSize: layer == null ? void 0 : layer.tileSize
20312
+ });
20313
+ if ((layer == null ? void 0 : layer.layer_type) == "terrainSource")
20314
+ map == null ? void 0 : map.setTerrain({
20315
+ source: "terrainSource",
20316
+ exaggeration: 1
20317
+ });
20318
+ if ((layer == null ? void 0 : layer.layer_type) == "hillshade")
20319
+ map == null ? void 0 : map.addLayer({
20320
+ id: layer == null ? void 0 : layer.name,
20321
+ type: layer == null ? void 0 : layer.layer_type,
20322
+ source: layer == null ? void 0 : layer.name,
20323
+ paint: { "hillshade-shadow-color": "#473B24" },
20324
+ layout: { visibility: "visible" }
20325
+ });
20326
+ if ((layer == null ? void 0 : layer.layer_type) == "satellite")
20327
+ map == null ? void 0 : map.addLayer({ id: layer == null ? void 0 : layer.name, type: layer == null ? void 0 : layer.type, source: layer == null ? void 0 : layer.name });
20244
20328
  }
20245
- ],
20246
- sky: {}
20247
- },
20248
- center: [16.3713, 48.2081],
20249
- zoom: 3,
20250
- minZoom: 1.5,
20251
- renderWorldCopies: false,
20252
- canvasContextAttributes: { antialias: true }
20253
- });
20254
- mapRef.current = map;
20255
- map.scrollZoom.disable();
20256
- mapRef.current.getContainer().addEventListener("mouseenter", () => map.scrollZoom.enable());
20257
- mapRef.current.getContainer().addEventListener("mouseleave", () => map.scrollZoom.disable());
20258
- function loadSvgImage() {
20259
- return __async(this, null, function* () {
20260
- let svgText = (0, import_server8.renderToStaticMarkup)(
20261
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_MapPinIcon4.default, { className: "w-6 h-6" })
20262
- );
20263
- svgText = svgText.replace('fill="currentColor"', 'fill="#06b6d4"');
20264
- const img = new Image();
20265
- img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgText);
20266
- img.width = 35;
20267
- img.height = 35;
20268
- yield img.decode();
20269
- return img;
20329
+ }
20270
20330
  });
20271
20331
  }
20272
- map.on("load", () => __async(void 0, null, function* () {
20273
- changeMapProjection();
20274
- baseLayers == null ? void 0 : baseLayers.forEach((layer) => {
20275
- map.addSource(layer.name, {
20276
- type: layer.type,
20277
- url: layer.url,
20278
- tileSize: layer.tileSize
20279
- });
20280
- if (layer.layer_type == "terrainSource")
20281
- map.setTerrain({
20282
- source: "terrainSource",
20283
- exaggeration: 1
20284
- });
20285
- if (layer.layer_type == "hillshade")
20286
- map.addLayer({
20287
- id: layer.name,
20288
- type: layer.layer_type,
20289
- source: layer.name,
20290
- paint: { "hillshade-shadow-color": "#473B24" },
20291
- layout: { visibility: "visible" }
20292
- });
20293
- });
20294
- sourceData == null ? void 0 : sourceData.forEach((source) => __async(void 0, null, function* () {
20332
+ };
20333
+ const loadSourceData = () => {
20334
+ sourceData == null ? void 0 : sourceData.forEach((source) => __async(void 0, null, function* () {
20335
+ const existing_data = map == null ? void 0 : map.getSource(source.name);
20336
+ if (!existing_data) {
20295
20337
  if (source.is_cluster) {
20296
- map.addSource(source.name, {
20338
+ map == null ? void 0 : map.addSource(source.name, {
20297
20339
  type: source.type,
20298
20340
  data: source.data,
20299
20341
  cluster: true,
20300
20342
  clusterMaxZoom: 10,
20301
20343
  clusterRadius: 50
20302
20344
  });
20303
- }
20345
+ } else
20346
+ map == null ? void 0 : map.addSource(source.name, {
20347
+ type: source.type,
20348
+ data: source.data
20349
+ // cluster: true,
20350
+ // clusterMaxZoom: 10,
20351
+ // clusterRadius: 50,
20352
+ });
20304
20353
  if (source.show_cluster_count) {
20305
- map.addLayer({
20354
+ map == null ? void 0 : map.addLayer({
20306
20355
  id: `${source.name}-cluster-circles`,
20307
20356
  type: "circle",
20308
20357
  source: source.name,
@@ -20315,7 +20364,7 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20315
20364
  "circle-stroke-color": source.style.cluster_stroke_color
20316
20365
  }
20317
20366
  });
20318
- map.addLayer({
20367
+ map == null ? void 0 : map.addLayer({
20319
20368
  id: `${source.name}-cluster-count`,
20320
20369
  type: "symbol",
20321
20370
  source: source.name,
@@ -20329,32 +20378,204 @@ var MapLibre = (0, import_react67.forwardRef)(({ baseLayers, customLayers, mapCo
20329
20378
  "text-color": "#f7f2f2"
20330
20379
  }
20331
20380
  });
20332
- if (!map.hasImage("pin")) {
20333
- const img = yield loadSvgImage();
20334
- map.addImage("pin", img);
20381
+ if (!(map == null ? void 0 : map.hasImage(`${source.name}-pin`))) {
20382
+ const img = yield loadSvgImage(source.style.pin_color);
20383
+ map == null ? void 0 : map.addImage(`${source.name}-pin`, img);
20335
20384
  }
20336
- map.addLayer({
20337
- id: source.name + "-count",
20385
+ map == null ? void 0 : map.addLayer({
20386
+ id: `${source.name}-pins`,
20338
20387
  type: "symbol",
20339
20388
  source: source.name,
20340
20389
  filter: ["!", ["has", "point_count"]],
20341
20390
  layout: {
20342
- "icon-image": "pin",
20391
+ "icon-image": `${source.name}-pin`,
20392
+ "icon-size": 1,
20393
+ "icon-allow-overlap": true,
20394
+ "icon-anchor": "bottom"
20395
+ }
20396
+ });
20397
+ } else if (source.custom_cluster) {
20398
+ map == null ? void 0 : map.addLayer({
20399
+ id: `${source.name}-cluster-circles`,
20400
+ type: "circle",
20401
+ source: source.name,
20402
+ filter: [">", ["get", "count"], 1],
20403
+ paint: {
20404
+ "circle-color": source.style.cluster_color,
20405
+ "circle-opacity": 1,
20406
+ "circle-radius": 20,
20407
+ "circle-stroke-width": 4,
20408
+ "circle-stroke-color": source.style.cluster_stroke_color
20409
+ // "circle-radius": [
20410
+ // "step",
20411
+ // ["get", "count"],
20412
+ // 20, 100, 30, 750, 40
20413
+ // ]
20414
+ }
20415
+ });
20416
+ map == null ? void 0 : map.addLayer({
20417
+ id: `${source.name}-cluster-count`,
20418
+ type: "symbol",
20419
+ source: source.name,
20420
+ filter: [">", ["get", "count"], 1],
20421
+ layout: {
20422
+ "text-field": "{count}",
20423
+ "text-font": ["Open Sans Bold"],
20424
+ "text-size": 14
20425
+ },
20426
+ paint: {
20427
+ "text-color": "#f7f2f2"
20428
+ }
20429
+ });
20430
+ if (!(map == null ? void 0 : map.hasImage(`${source.name}-pin`))) {
20431
+ const img = yield loadSvgImage(source.style.pin_color);
20432
+ map == null ? void 0 : map.addImage(`${source.name}-pin`, img);
20433
+ }
20434
+ map == null ? void 0 : map.addLayer({
20435
+ id: source.name + "-pins",
20436
+ type: "symbol",
20437
+ source: source.name,
20438
+ //filter: ["!", ["has", "point_count"]],
20439
+ filter: ["==", ["get", "count"], null],
20440
+ layout: {
20441
+ "icon-image": `${source.name}-pin`,
20343
20442
  "icon-size": 1,
20344
20443
  "icon-allow-overlap": true,
20345
20444
  "icon-anchor": "bottom"
20346
20445
  }
20347
20446
  });
20348
20447
  }
20349
- }));
20448
+ } else {
20449
+ existing_data.setData(source.data);
20450
+ updateClusterColors(source);
20451
+ updatePinImage(source);
20452
+ }
20350
20453
  }));
20454
+ };
20455
+ (0, import_react66.useEffect)(() => {
20456
+ if (typeof mapContainer === "function")
20457
+ return;
20458
+ if (!(mapContainer == null ? void 0 : mapContainer.current))
20459
+ return;
20460
+ if (!sourceData)
20461
+ return;
20462
+ const map2 = new import_maplibre_gl.default.Map({
20463
+ container: mapContainer == null ? void 0 : mapContainer.current,
20464
+ style: {
20465
+ version: 8,
20466
+ sources: {
20467
+ osm: {
20468
+ type: "raster",
20469
+ tiles: ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"],
20470
+ tileSize: 256,
20471
+ attribution: "&copy; OpenStreetMap Contributors",
20472
+ maxzoom: 19
20473
+ }
20474
+ },
20475
+ layers: [
20476
+ {
20477
+ id: "osm",
20478
+ type: "raster",
20479
+ source: "osm"
20480
+ }
20481
+ ],
20482
+ sky: {}
20483
+ },
20484
+ center: [16.3713, 48.2081],
20485
+ zoom: 3,
20486
+ minZoom: 1.5,
20487
+ renderWorldCopies: false,
20488
+ canvasContextAttributes: { antialias: true }
20489
+ });
20490
+ mapRef.current = map2;
20491
+ map2.scrollZoom.disable();
20492
+ mapRef.current.getContainer().addEventListener("mouseenter", () => map2.scrollZoom.enable());
20493
+ mapRef.current.getContainer().addEventListener("mouseleave", () => map2.scrollZoom.disable());
20494
+ map2.on("load", () => __async(void 0, null, function* () {
20495
+ changeMapProjection();
20496
+ }));
20497
+ return () => {
20498
+ map2.remove();
20499
+ mapRef.current = null;
20500
+ };
20501
+ }, []);
20502
+ (0, import_react66.useEffect)(() => {
20503
+ if (!map)
20504
+ return;
20505
+ const init = () => {
20506
+ loadBaseLayers();
20507
+ };
20508
+ const zoom = () => {
20509
+ const bounds = map.getBounds();
20510
+ mapControls == null ? void 0 : mapControls.forEach((control) => {
20511
+ var _a;
20512
+ if (control.get_bounds)
20513
+ (_a = control.get_bounds) == null ? void 0 : _a.call(control, bounds);
20514
+ });
20515
+ };
20516
+ if (map.isStyleLoaded()) {
20517
+ init();
20518
+ map.on("zoomend", zoom);
20519
+ } else
20520
+ map.once("load", () => {
20521
+ init();
20522
+ map.on("zoomend", zoom);
20523
+ });
20524
+ }, [map]);
20525
+ (0, import_react66.useEffect)(() => {
20526
+ var _a, _b, _c;
20527
+ if (!map || !sourceData)
20528
+ return;
20529
+ if (map.isStyleLoaded()) {
20530
+ loadSourceData();
20531
+ return;
20532
+ }
20533
+ const handler = () => loadSourceData();
20534
+ map.once("load", handler);
20535
+ if (show_popup && customLayers) {
20536
+ map.on("mouseenter", ((_a = customLayers[0]) == null ? void 0 : _a.layerName) + "-pins", () => {
20537
+ map.getCanvas().style.cursor = "pointer";
20538
+ });
20539
+ map.on("mouseleave", ((_b = customLayers[0]) == null ? void 0 : _b.layerName) + "-pins", () => {
20540
+ map.getCanvas().style.cursor = "";
20541
+ });
20542
+ map.on("click", ((_c = customLayers[0]) == null ? void 0 : _c.layerName) + "-pins", (e) => {
20543
+ var _a2, _b2, _c2, _d;
20544
+ if (e.features) {
20545
+ const properties = (_a2 = e.features[0]) == null ? void 0 : _a2.properties;
20546
+ const coordinates = (_c2 = (_b2 = e.features[0]) == null ? void 0 : _b2.geometry) == null ? void 0 : _c2.coordinates.slice();
20547
+ const description = `
20548
+ <a class="popup-link text-primary text-xs hover:cursor-pointer">${(_d = e.features[0]) == null ? void 0 : _d.properties.description}</a>
20549
+ `;
20550
+ const popup_element = new import_maplibre_gl.default.Popup().setLngLat([coordinates[0], coordinates[1]]).setHTML(description).addTo(map);
20551
+ setTimeout(() => {
20552
+ const link = popup_element.getElement().querySelector(".popup-link");
20553
+ if (link && popup && popup.click) {
20554
+ link.onclick = (ev) => {
20555
+ ev.preventDefault();
20556
+ popup.click(properties);
20557
+ };
20558
+ }
20559
+ }, 0);
20560
+ }
20561
+ });
20562
+ }
20351
20563
  return () => {
20352
- map.remove();
20564
+ map.off("load", handler);
20353
20565
  };
20354
- }, [sourceData, mapControls]);
20566
+ }, [sourceData]);
20567
+ (0, import_react66.useEffect)(() => {
20568
+ if (!map || !sourceData)
20569
+ return;
20570
+ sourceData.forEach((source) => {
20571
+ const source_layer = map.getSource(source.name);
20572
+ if (source_layer)
20573
+ source_layer.setData(source.data);
20574
+ });
20575
+ }, [sourceData]);
20355
20576
  if (!sourceData)
20356
20577
  return;
20357
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "relative", style: { width: "100%", height: "100vh" }, children: [
20578
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "relative", style: { width: "100%", height: "100%" }, children: [
20358
20579
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { ref: mapContainer, className: "w-full h-full" }),
20359
20580
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(MapControlToolbar, { controls: mapControl, onToggleControl: (id) => toggleControl(id) })
20360
20581
  ] });
package/dist/index.mjs CHANGED
@@ -5716,6 +5716,7 @@ var WaybackTimelineMap = (props) => {
5716
5716
  import { useEffect as useEffect21, useRef as useRef12, useState as useState17 } from "react";
5717
5717
  import { forwardRef as forwardRef5 } from "react";
5718
5718
  import maplibregl from "maplibre-gl";
5719
+ import "maplibre-gl/dist/maplibre-gl.css";
5719
5720
  import MapPinIcon3 from "@heroicons/react/24/solid/MapPinIcon";
5720
5721
  import { renderToStaticMarkup } from "react-dom/server";
5721
5722
 
@@ -8788,44 +8789,50 @@ MapControlToolbar.displayName = "MapControlToolbar";
8788
8789
  // src/Components/Map/MapLibre.tsx
8789
8790
  import { GlobeIcon as GlobeIcon2, PlusIcon as PlusIcon3, MinusIcon as MinusIcon3, LayerGroupIcon as LayerGroupIcon5 } from "@geowiki/ui";
8790
8791
  import { jsx as jsx48, jsxs as jsxs35 } from "react/jsx-runtime";
8791
- var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData }, ref) => {
8792
+ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData, show_popup, popup }, ref) => {
8792
8793
  const mapContainer = ref;
8793
8794
  const mapRef = useRef12(null);
8795
+ const map = mapRef.current;
8794
8796
  const changeMapProjection = () => {
8795
8797
  var _a;
8796
8798
  if (!mapRef.current)
8797
8799
  return;
8798
- const map = mapRef.current;
8799
- const currentProjection = (_a = map.getProjection()) == null ? void 0 : _a.type;
8800
+ const map2 = mapRef.current;
8801
+ const currentProjection = (_a = map2.getProjection()) == null ? void 0 : _a.type;
8800
8802
  const newProjection = currentProjection === "mercator" ? "globe" : "mercator";
8801
- map.setProjection({
8803
+ map2.setProjection({
8802
8804
  type: newProjection
8803
8805
  });
8804
8806
  };
8805
8807
  const zoomIn = () => {
8806
8808
  if (!mapRef.current)
8807
8809
  return;
8808
- const map = mapRef.current;
8809
- map.zoomIn();
8810
+ const map2 = mapRef.current;
8811
+ map2.zoomIn();
8812
+ return map2.getBounds();
8810
8813
  };
8811
8814
  const zoomOut = () => {
8812
8815
  if (!mapRef.current)
8813
8816
  return;
8814
- const map = mapRef.current;
8815
- map.zoomOut();
8817
+ const map2 = mapRef.current;
8818
+ map2.zoomOut();
8819
+ return map2.getBounds();
8816
8820
  };
8817
- function getLayersByPattern(map, pattern) {
8818
- return map.getStyle().layers.filter((layer) => pattern.test(layer.id)).map((layer) => layer.id);
8821
+ function getLayersByPattern(pattern) {
8822
+ if (!mapRef.current)
8823
+ return;
8824
+ const map2 = mapRef.current;
8825
+ return map2 == null ? void 0 : map2.getStyle().layers.filter((layer) => pattern.test(layer.id)).map((layer) => layer.id);
8819
8826
  }
8820
8827
  const handleToggle = (layerId) => {
8821
8828
  if (!mapRef.current)
8822
8829
  return;
8823
- const map = mapRef.current;
8824
- const layers = getLayersByPattern(map, new RegExp(layerId));
8825
- layers.forEach((id) => {
8826
- const visibility = map.getLayoutProperty(id, "visibility");
8830
+ const map2 = mapRef.current;
8831
+ const layers = getLayersByPattern(new RegExp(layerId));
8832
+ layers == null ? void 0 : layers.forEach((id) => {
8833
+ const visibility = map2 == null ? void 0 : map2.getLayoutProperty(id, "visibility");
8827
8834
  const newVisibility = visibility === "none" ? "visible" : "none";
8828
- map.setLayoutProperty(id, "visibility", newVisibility);
8835
+ map2 == null ? void 0 : map2.setLayoutProperty(id, "visibility", newVisibility);
8829
8836
  });
8830
8837
  };
8831
8838
  const buildControls = (controls) => {
@@ -8848,7 +8855,11 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
8848
8855
  {
8849
8856
  id: "zoomIn",
8850
8857
  icon: PlusIcon3,
8851
- onClick: zoomIn,
8858
+ onClick: () => {
8859
+ var _a;
8860
+ const bounds = zoomIn();
8861
+ (_a = c.get_bounds) == null ? void 0 : _a.call(c, bounds);
8862
+ },
8852
8863
  position: "topright",
8853
8864
  isOpen: true,
8854
8865
  isDisplayOnly: false,
@@ -8858,7 +8869,11 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
8858
8869
  {
8859
8870
  id: "zoomOut",
8860
8871
  icon: MinusIcon3,
8861
- onClick: zoomOut,
8872
+ onClick: () => {
8873
+ var _a;
8874
+ const bounds = zoomOut();
8875
+ (_a = c.get_bounds) == null ? void 0 : _a.call(c, bounds);
8876
+ },
8862
8877
  position: "topright",
8863
8878
  isOpen: true,
8864
8879
  isDisplayOnly: false,
@@ -8887,6 +8902,7 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
8887
8902
  }
8888
8903
  ),
8889
8904
  position: "topleft",
8905
+ title: "OVERLAY MAPS",
8890
8906
  isOpen: false,
8891
8907
  isDisplayOnly: false,
8892
8908
  popoverDirection: "right",
@@ -8897,8 +8913,39 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
8897
8913
  }
8898
8914
  }).flat();
8899
8915
  };
8916
+ const buildBaseLayers = (baselayers) => {
8917
+ return baselayers.map((c) => {
8918
+ switch (c.layer_type) {
8919
+ case "satellite":
8920
+ return {
8921
+ name: "satellite",
8922
+ type: "raster",
8923
+ url: "https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg",
8924
+ tileSize: 256,
8925
+ layer_type: "satellite"
8926
+ };
8927
+ case "terrainSource":
8928
+ return {
8929
+ name: "terrainSource",
8930
+ type: "raster-dem",
8931
+ url: "https://tiles.mapterhorn.com/tilejson.json",
8932
+ tileSize: 256,
8933
+ layer_type: "terrainSource"
8934
+ };
8935
+ case "hillshade":
8936
+ return {
8937
+ name: "hillshadeSource",
8938
+ type: "raster-dem",
8939
+ url: "https://tiles.mapterhorn.com/tilejson.json",
8940
+ tileSize: 256,
8941
+ layer_type: "hillshade"
8942
+ };
8943
+ default:
8944
+ return null;
8945
+ }
8946
+ }).flat();
8947
+ };
8900
8948
  const [mapControl, setMapControl] = useState17(() => buildControls(mapControls));
8901
- console.log(mapControl);
8902
8949
  const toggleControl = (id) => {
8903
8950
  setMapControl((prevControls) => prevControls.map((control) => {
8904
8951
  if (control.id === id) {
@@ -8907,93 +8954,95 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
8907
8954
  return control;
8908
8955
  }));
8909
8956
  };
8910
- useEffect21(() => {
8911
- if (typeof mapContainer === "function")
8912
- return;
8913
- if (!(mapContainer == null ? void 0 : mapContainer.current))
8914
- return;
8915
- if (!sourceData)
8957
+ const loadSvgImage = (color) => __async(void 0, null, function* () {
8958
+ let svgText = renderToStaticMarkup(
8959
+ /* @__PURE__ */ jsx48(MapPinIcon3, { className: "w-6 h-6" })
8960
+ );
8961
+ svgText = svgText.replace('fill="currentColor"', `fill="${color}"`);
8962
+ const img = new Image();
8963
+ img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgText);
8964
+ img.width = 35;
8965
+ img.height = 35;
8966
+ yield img.decode();
8967
+ return img;
8968
+ });
8969
+ const updatePinImage = (source) => __async(void 0, null, function* () {
8970
+ const img = yield loadSvgImage(source.style.pin_color);
8971
+ const imgName = `${source.name}-pin`;
8972
+ if (map == null ? void 0 : map.hasImage(imgName))
8973
+ map == null ? void 0 : map.removeImage(imgName);
8974
+ map == null ? void 0 : map.addImage(imgName, img);
8975
+ });
8976
+ const updateClusterColors = (source) => {
8977
+ const layerId = `${source.name}-cluster-circles`;
8978
+ if (!(map == null ? void 0 : map.getLayer(layerId)))
8916
8979
  return;
8917
- const map = new maplibregl.Map({
8918
- container: mapContainer == null ? void 0 : mapContainer.current,
8919
- style: {
8920
- version: 8,
8921
- sources: {
8922
- osm: {
8923
- type: "raster",
8924
- tiles: ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"],
8925
- tileSize: 256,
8926
- attribution: "&copy; OpenStreetMap Contributors",
8927
- maxzoom: 19
8928
- }
8929
- },
8930
- layers: [
8931
- {
8932
- id: "osm",
8933
- type: "raster",
8934
- source: "osm"
8980
+ const current = map == null ? void 0 : map.getPaintProperty(layerId, "circle-color");
8981
+ if (current !== source.style.cluster_color) {
8982
+ map == null ? void 0 : map.setPaintProperty(layerId, "circle-color", source.style.cluster_color);
8983
+ map == null ? void 0 : map.setPaintProperty(layerId, "circle-stroke-color", source.style.cluster_stroke_color);
8984
+ }
8985
+ };
8986
+ const loadBaseLayers = () => {
8987
+ if (baseLayers && (baseLayers == null ? void 0 : baseLayers.length) > 0) {
8988
+ const base_layers = buildBaseLayers(baseLayers);
8989
+ base_layers == null ? void 0 : base_layers.forEach((layer) => {
8990
+ if (!(map == null ? void 0 : map.getLayer(layer.name))) {
8991
+ if (!(map == null ? void 0 : map.getSource(layer == null ? void 0 : layer.name))) {
8992
+ if ((layer == null ? void 0 : layer.layer_type) == "satellite")
8993
+ map == null ? void 0 : map.addSource(layer == null ? void 0 : layer.name, {
8994
+ type: layer == null ? void 0 : layer.type,
8995
+ tiles: [layer == null ? void 0 : layer.url],
8996
+ tileSize: layer == null ? void 0 : layer.tileSize
8997
+ });
8998
+ else
8999
+ map == null ? void 0 : map.addSource(layer == null ? void 0 : layer.name, {
9000
+ type: layer == null ? void 0 : layer.type,
9001
+ url: layer == null ? void 0 : layer.url,
9002
+ tileSize: layer == null ? void 0 : layer.tileSize
9003
+ });
9004
+ if ((layer == null ? void 0 : layer.layer_type) == "terrainSource")
9005
+ map == null ? void 0 : map.setTerrain({
9006
+ source: "terrainSource",
9007
+ exaggeration: 1
9008
+ });
9009
+ if ((layer == null ? void 0 : layer.layer_type) == "hillshade")
9010
+ map == null ? void 0 : map.addLayer({
9011
+ id: layer == null ? void 0 : layer.name,
9012
+ type: layer == null ? void 0 : layer.layer_type,
9013
+ source: layer == null ? void 0 : layer.name,
9014
+ paint: { "hillshade-shadow-color": "#473B24" },
9015
+ layout: { visibility: "visible" }
9016
+ });
9017
+ if ((layer == null ? void 0 : layer.layer_type) == "satellite")
9018
+ map == null ? void 0 : map.addLayer({ id: layer == null ? void 0 : layer.name, type: layer == null ? void 0 : layer.type, source: layer == null ? void 0 : layer.name });
8935
9019
  }
8936
- ],
8937
- sky: {}
8938
- },
8939
- center: [16.3713, 48.2081],
8940
- zoom: 3,
8941
- minZoom: 1.5,
8942
- renderWorldCopies: false,
8943
- canvasContextAttributes: { antialias: true }
8944
- });
8945
- mapRef.current = map;
8946
- map.scrollZoom.disable();
8947
- mapRef.current.getContainer().addEventListener("mouseenter", () => map.scrollZoom.enable());
8948
- mapRef.current.getContainer().addEventListener("mouseleave", () => map.scrollZoom.disable());
8949
- function loadSvgImage() {
8950
- return __async(this, null, function* () {
8951
- let svgText = renderToStaticMarkup(
8952
- /* @__PURE__ */ jsx48(MapPinIcon3, { className: "w-6 h-6" })
8953
- );
8954
- svgText = svgText.replace('fill="currentColor"', 'fill="#06b6d4"');
8955
- const img = new Image();
8956
- img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgText);
8957
- img.width = 35;
8958
- img.height = 35;
8959
- yield img.decode();
8960
- return img;
9020
+ }
8961
9021
  });
8962
9022
  }
8963
- map.on("load", () => __async(void 0, null, function* () {
8964
- changeMapProjection();
8965
- baseLayers == null ? void 0 : baseLayers.forEach((layer) => {
8966
- map.addSource(layer.name, {
8967
- type: layer.type,
8968
- url: layer.url,
8969
- tileSize: layer.tileSize
8970
- });
8971
- if (layer.layer_type == "terrainSource")
8972
- map.setTerrain({
8973
- source: "terrainSource",
8974
- exaggeration: 1
8975
- });
8976
- if (layer.layer_type == "hillshade")
8977
- map.addLayer({
8978
- id: layer.name,
8979
- type: layer.layer_type,
8980
- source: layer.name,
8981
- paint: { "hillshade-shadow-color": "#473B24" },
8982
- layout: { visibility: "visible" }
8983
- });
8984
- });
8985
- sourceData == null ? void 0 : sourceData.forEach((source) => __async(void 0, null, function* () {
9023
+ };
9024
+ const loadSourceData = () => {
9025
+ sourceData == null ? void 0 : sourceData.forEach((source) => __async(void 0, null, function* () {
9026
+ const existing_data = map == null ? void 0 : map.getSource(source.name);
9027
+ if (!existing_data) {
8986
9028
  if (source.is_cluster) {
8987
- map.addSource(source.name, {
9029
+ map == null ? void 0 : map.addSource(source.name, {
8988
9030
  type: source.type,
8989
9031
  data: source.data,
8990
9032
  cluster: true,
8991
9033
  clusterMaxZoom: 10,
8992
9034
  clusterRadius: 50
8993
9035
  });
8994
- }
9036
+ } else
9037
+ map == null ? void 0 : map.addSource(source.name, {
9038
+ type: source.type,
9039
+ data: source.data
9040
+ // cluster: true,
9041
+ // clusterMaxZoom: 10,
9042
+ // clusterRadius: 50,
9043
+ });
8995
9044
  if (source.show_cluster_count) {
8996
- map.addLayer({
9045
+ map == null ? void 0 : map.addLayer({
8997
9046
  id: `${source.name}-cluster-circles`,
8998
9047
  type: "circle",
8999
9048
  source: source.name,
@@ -9006,7 +9055,7 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
9006
9055
  "circle-stroke-color": source.style.cluster_stroke_color
9007
9056
  }
9008
9057
  });
9009
- map.addLayer({
9058
+ map == null ? void 0 : map.addLayer({
9010
9059
  id: `${source.name}-cluster-count`,
9011
9060
  type: "symbol",
9012
9061
  source: source.name,
@@ -9020,32 +9069,204 @@ var MapLibre = forwardRef5(({ baseLayers, customLayers, mapControls, sourceData
9020
9069
  "text-color": "#f7f2f2"
9021
9070
  }
9022
9071
  });
9023
- if (!map.hasImage("pin")) {
9024
- const img = yield loadSvgImage();
9025
- map.addImage("pin", img);
9072
+ if (!(map == null ? void 0 : map.hasImage(`${source.name}-pin`))) {
9073
+ const img = yield loadSvgImage(source.style.pin_color);
9074
+ map == null ? void 0 : map.addImage(`${source.name}-pin`, img);
9026
9075
  }
9027
- map.addLayer({
9028
- id: source.name + "-count",
9076
+ map == null ? void 0 : map.addLayer({
9077
+ id: `${source.name}-pins`,
9029
9078
  type: "symbol",
9030
9079
  source: source.name,
9031
9080
  filter: ["!", ["has", "point_count"]],
9032
9081
  layout: {
9033
- "icon-image": "pin",
9082
+ "icon-image": `${source.name}-pin`,
9083
+ "icon-size": 1,
9084
+ "icon-allow-overlap": true,
9085
+ "icon-anchor": "bottom"
9086
+ }
9087
+ });
9088
+ } else if (source.custom_cluster) {
9089
+ map == null ? void 0 : map.addLayer({
9090
+ id: `${source.name}-cluster-circles`,
9091
+ type: "circle",
9092
+ source: source.name,
9093
+ filter: [">", ["get", "count"], 1],
9094
+ paint: {
9095
+ "circle-color": source.style.cluster_color,
9096
+ "circle-opacity": 1,
9097
+ "circle-radius": 20,
9098
+ "circle-stroke-width": 4,
9099
+ "circle-stroke-color": source.style.cluster_stroke_color
9100
+ // "circle-radius": [
9101
+ // "step",
9102
+ // ["get", "count"],
9103
+ // 20, 100, 30, 750, 40
9104
+ // ]
9105
+ }
9106
+ });
9107
+ map == null ? void 0 : map.addLayer({
9108
+ id: `${source.name}-cluster-count`,
9109
+ type: "symbol",
9110
+ source: source.name,
9111
+ filter: [">", ["get", "count"], 1],
9112
+ layout: {
9113
+ "text-field": "{count}",
9114
+ "text-font": ["Open Sans Bold"],
9115
+ "text-size": 14
9116
+ },
9117
+ paint: {
9118
+ "text-color": "#f7f2f2"
9119
+ }
9120
+ });
9121
+ if (!(map == null ? void 0 : map.hasImage(`${source.name}-pin`))) {
9122
+ const img = yield loadSvgImage(source.style.pin_color);
9123
+ map == null ? void 0 : map.addImage(`${source.name}-pin`, img);
9124
+ }
9125
+ map == null ? void 0 : map.addLayer({
9126
+ id: source.name + "-pins",
9127
+ type: "symbol",
9128
+ source: source.name,
9129
+ //filter: ["!", ["has", "point_count"]],
9130
+ filter: ["==", ["get", "count"], null],
9131
+ layout: {
9132
+ "icon-image": `${source.name}-pin`,
9034
9133
  "icon-size": 1,
9035
9134
  "icon-allow-overlap": true,
9036
9135
  "icon-anchor": "bottom"
9037
9136
  }
9038
9137
  });
9039
9138
  }
9040
- }));
9139
+ } else {
9140
+ existing_data.setData(source.data);
9141
+ updateClusterColors(source);
9142
+ updatePinImage(source);
9143
+ }
9144
+ }));
9145
+ };
9146
+ useEffect21(() => {
9147
+ if (typeof mapContainer === "function")
9148
+ return;
9149
+ if (!(mapContainer == null ? void 0 : mapContainer.current))
9150
+ return;
9151
+ if (!sourceData)
9152
+ return;
9153
+ const map2 = new maplibregl.Map({
9154
+ container: mapContainer == null ? void 0 : mapContainer.current,
9155
+ style: {
9156
+ version: 8,
9157
+ sources: {
9158
+ osm: {
9159
+ type: "raster",
9160
+ tiles: ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"],
9161
+ tileSize: 256,
9162
+ attribution: "&copy; OpenStreetMap Contributors",
9163
+ maxzoom: 19
9164
+ }
9165
+ },
9166
+ layers: [
9167
+ {
9168
+ id: "osm",
9169
+ type: "raster",
9170
+ source: "osm"
9171
+ }
9172
+ ],
9173
+ sky: {}
9174
+ },
9175
+ center: [16.3713, 48.2081],
9176
+ zoom: 3,
9177
+ minZoom: 1.5,
9178
+ renderWorldCopies: false,
9179
+ canvasContextAttributes: { antialias: true }
9180
+ });
9181
+ mapRef.current = map2;
9182
+ map2.scrollZoom.disable();
9183
+ mapRef.current.getContainer().addEventListener("mouseenter", () => map2.scrollZoom.enable());
9184
+ mapRef.current.getContainer().addEventListener("mouseleave", () => map2.scrollZoom.disable());
9185
+ map2.on("load", () => __async(void 0, null, function* () {
9186
+ changeMapProjection();
9041
9187
  }));
9042
9188
  return () => {
9043
- map.remove();
9189
+ map2.remove();
9190
+ mapRef.current = null;
9191
+ };
9192
+ }, []);
9193
+ useEffect21(() => {
9194
+ if (!map)
9195
+ return;
9196
+ const init = () => {
9197
+ loadBaseLayers();
9044
9198
  };
9045
- }, [sourceData, mapControls]);
9199
+ const zoom = () => {
9200
+ const bounds = map.getBounds();
9201
+ mapControls == null ? void 0 : mapControls.forEach((control) => {
9202
+ var _a;
9203
+ if (control.get_bounds)
9204
+ (_a = control.get_bounds) == null ? void 0 : _a.call(control, bounds);
9205
+ });
9206
+ };
9207
+ if (map.isStyleLoaded()) {
9208
+ init();
9209
+ map.on("zoomend", zoom);
9210
+ } else
9211
+ map.once("load", () => {
9212
+ init();
9213
+ map.on("zoomend", zoom);
9214
+ });
9215
+ }, [map]);
9216
+ useEffect21(() => {
9217
+ var _a, _b, _c;
9218
+ if (!map || !sourceData)
9219
+ return;
9220
+ if (map.isStyleLoaded()) {
9221
+ loadSourceData();
9222
+ return;
9223
+ }
9224
+ const handler = () => loadSourceData();
9225
+ map.once("load", handler);
9226
+ if (show_popup && customLayers) {
9227
+ map.on("mouseenter", ((_a = customLayers[0]) == null ? void 0 : _a.layerName) + "-pins", () => {
9228
+ map.getCanvas().style.cursor = "pointer";
9229
+ });
9230
+ map.on("mouseleave", ((_b = customLayers[0]) == null ? void 0 : _b.layerName) + "-pins", () => {
9231
+ map.getCanvas().style.cursor = "";
9232
+ });
9233
+ map.on("click", ((_c = customLayers[0]) == null ? void 0 : _c.layerName) + "-pins", (e) => {
9234
+ var _a2, _b2, _c2, _d;
9235
+ if (e.features) {
9236
+ const properties = (_a2 = e.features[0]) == null ? void 0 : _a2.properties;
9237
+ const coordinates = (_c2 = (_b2 = e.features[0]) == null ? void 0 : _b2.geometry) == null ? void 0 : _c2.coordinates.slice();
9238
+ const description = `
9239
+ <a class="popup-link text-primary text-xs hover:cursor-pointer">${(_d = e.features[0]) == null ? void 0 : _d.properties.description}</a>
9240
+ `;
9241
+ const popup_element = new maplibregl.Popup().setLngLat([coordinates[0], coordinates[1]]).setHTML(description).addTo(map);
9242
+ setTimeout(() => {
9243
+ const link = popup_element.getElement().querySelector(".popup-link");
9244
+ if (link && popup && popup.click) {
9245
+ link.onclick = (ev) => {
9246
+ ev.preventDefault();
9247
+ popup.click(properties);
9248
+ };
9249
+ }
9250
+ }, 0);
9251
+ }
9252
+ });
9253
+ }
9254
+ return () => {
9255
+ map.off("load", handler);
9256
+ };
9257
+ }, [sourceData]);
9258
+ useEffect21(() => {
9259
+ if (!map || !sourceData)
9260
+ return;
9261
+ sourceData.forEach((source) => {
9262
+ const source_layer = map.getSource(source.name);
9263
+ if (source_layer)
9264
+ source_layer.setData(source.data);
9265
+ });
9266
+ }, [sourceData]);
9046
9267
  if (!sourceData)
9047
9268
  return;
9048
- return /* @__PURE__ */ jsxs35("div", { className: "relative", style: { width: "100%", height: "100vh" }, children: [
9269
+ return /* @__PURE__ */ jsxs35("div", { className: "relative", style: { width: "100%", height: "100%" }, children: [
9049
9270
  /* @__PURE__ */ jsx48("div", { ref: mapContainer, className: "w-full h-full" }),
9050
9271
  /* @__PURE__ */ jsx48(MapControlToolbar, { controls: mapControl, onToggleControl: (id) => toggleControl(id) })
9051
9272
  ] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geowiki/map",
3
- "version": "0.16.9-dev.7",
3
+ "version": "0.16.9-dev.9",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -24,11 +24,11 @@
24
24
  "react-hotkeys-hook": "^4.5.0",
25
25
  "react-leaflet": "^4.2.1",
26
26
  "zod": "^3.25.7",
27
- "@geowiki/cms-proxy": "0.16.9-dev.7",
28
- "@geowiki/core": "0.16.9-dev.7",
29
- "@geowiki/evoland-api-proxy": "0.16.9-dev.7",
30
- "@geowiki/design-system": "0.16.9-dev.7",
31
- "@geowiki/ui": "0.16.9-dev.7"
27
+ "@geowiki/cms-proxy": "0.16.9-dev.9",
28
+ "@geowiki/ui": "0.16.9-dev.9",
29
+ "@geowiki/design-system": "0.16.9-dev.9",
30
+ "@geowiki/evoland-api-proxy": "0.16.9-dev.9",
31
+ "@geowiki/core": "0.16.9-dev.9"
32
32
  },
33
33
  "dependencies": {
34
34
  "@dnd-kit/core": "^6.3.1",
@@ -87,9 +87,9 @@
87
87
  "tailwindcss-animate": "^1.0.7",
88
88
  "tsup": "^8.0.2",
89
89
  "typescript": "5.4.2",
90
+ "tsconfig": "0.0.0",
90
91
  "eslint-config-custom": "0.0.0",
91
- "tailwind-config": "0.0.0",
92
- "tsconfig": "0.0.0"
92
+ "tailwind-config": "0.0.0"
93
93
  },
94
94
  "scripts": {
95
95
  "build": "tsup && tailwindcss -i styles.css -o dist/styles.css --minify",