@nextgis/leaflet-map-adapter 1.18.3 → 1.18.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- /** Bundle of @nextgis/leaflet-map-adapter; version: 1.18.3; author: NextGIS */
1
+ /** Bundle of @nextgis/leaflet-map-adapter; version: 1.18.6; author: NextGIS */
2
2
  import { EventEmitter } from 'events';
3
- import { Control, DomEvent, GeoJSON, FeatureGroup, DivIcon, Marker, CircleMarker, ImageOverlay as ImageOverlay$1, Layer, Util, CRS, GridLayer, DomUtil, TileLayer as TileLayer$1, Map } from 'leaflet';
4
- import { debounce as debounce$1, defined } from '@nextgis/utils';
3
+ import { Control, DomEvent, GeoJSON, DivIcon, Marker, CircleMarker, FeatureGroup, ImageOverlay as ImageOverlay$1, Layer, Util, CRS, GridLayer, DomUtil, TileLayer as TileLayer$1, Map } from 'leaflet';
4
+ import { defined, debounce as debounce$1 } from '@nextgis/utils';
5
5
  import { isPaintCallback, isPaint } from '@nextgis/paint';
6
6
 
7
7
  function convertMapClickEvent(evt) {
@@ -173,19 +173,6 @@ function createFeaturePositionOptions(features) {
173
173
  };
174
174
  }
175
175
 
176
- function createMouseEvent({ layer, source, }) {
177
- const layer_ = source.target;
178
- const feature = layer_.feature;
179
- const opt = {
180
- layer,
181
- feature,
182
- event: convertMapClickEvent(source),
183
- source,
184
- ...createFeaturePositionOptions(feature),
185
- };
186
- return opt;
187
- }
188
-
189
176
  function findMostFrequentGeomType(arr) {
190
177
  const counts = {};
191
178
  for (let fry = 0; fry < arr.length; fry++) {
@@ -240,6 +227,201 @@ class BaseAdapter {
240
227
  }
241
228
  }
242
229
 
230
+ function createMouseEvent({ layer, source, }) {
231
+ const layer_ = source.target;
232
+ const feature = layer_.feature;
233
+ const opt = {
234
+ layer,
235
+ feature,
236
+ event: convertMapClickEvent(source),
237
+ source,
238
+ ...createFeaturePositionOptions(feature),
239
+ };
240
+ return opt;
241
+ }
242
+
243
+ class GeoJsonEvents {
244
+ constructor(layer) {
245
+ this.layer = layer;
246
+ }
247
+ handleMouseEvents(layer) {
248
+ const { onClick, onLayerClick, onMouseOut, onMouseOver } = this.layer.options;
249
+ // TODO: remove backward compatibility for onLayerClick
250
+ const onClick_ = onClick || onLayerClick;
251
+ if (onClick_) {
252
+ this._onclick = (e) => {
253
+ const selected = !!this.layer._getSelected(layer);
254
+ onClick_({
255
+ selected,
256
+ ...this._createMouseEvent(e),
257
+ });
258
+ };
259
+ layer.on('click', this._onclick, this);
260
+ }
261
+ if (onMouseOut) {
262
+ this._mouseout = (e) => {
263
+ onMouseOut(this._createMouseEvent(e));
264
+ };
265
+ layer.on('mouseout', this._mouseout, this);
266
+ }
267
+ if (onMouseOver) {
268
+ this._mouseover = (e) => {
269
+ onMouseOver(this._createMouseEvent(e));
270
+ };
271
+ layer.on('mouseover', this._mouseover, this);
272
+ }
273
+ }
274
+ stopMouseEvents(layer) {
275
+ if (this._mouseover) {
276
+ layer.off('mouseover', this._mouseover, this);
277
+ }
278
+ if (this._mouseout) {
279
+ layer.off('mouseout', this._mouseout, this);
280
+ }
281
+ if (this._onclick) {
282
+ layer.off('click', this._onclick, this);
283
+ }
284
+ }
285
+ _createMouseEvent(source) {
286
+ return createMouseEvent({
287
+ layer: this.layer,
288
+ source: source,
289
+ });
290
+ }
291
+ }
292
+
293
+ class GeoJsonPaint {
294
+ constructor(layer) {
295
+ this.layer = layer;
296
+ }
297
+ setPaintEachLayer(paint) {
298
+ this.layer._layers.forEach((layerDef) => {
299
+ this.setPaint(layerDef, paint);
300
+ });
301
+ }
302
+ setPaint(layerDef, paint) {
303
+ let style = undefined;
304
+ const { layer, feature } = layerDef;
305
+ if (layer && feature) {
306
+ if (isPaintCallback(paint)) {
307
+ style = paint(feature);
308
+ }
309
+ else if (isPaint(paint)) {
310
+ style = paint;
311
+ }
312
+ if (style) {
313
+ if (this.layer.type === 'point' && style.type === 'icon') {
314
+ const marker = layer;
315
+ const divIcon = this._createDivIcon(style);
316
+ setTimeout(() => {
317
+ marker.setIcon(divIcon);
318
+ }, 10);
319
+ }
320
+ else if ('setStyle' in layer) {
321
+ layer.setStyle(this.preparePaint(style));
322
+ }
323
+ }
324
+ }
325
+ }
326
+ preparePaint(paint) {
327
+ if (paint.type !== 'get-paint') {
328
+ const paintAliases = [
329
+ ['color', 'strokeColor'],
330
+ ['opacity', 'strokeOpacity'],
331
+ ['stroke', 'stroke'],
332
+ ['fillColor', 'fillColor'],
333
+ ['fillOpacity', 'fillOpacity'],
334
+ ['fill', 'fill'],
335
+ ['weight', 'weight'],
336
+ ];
337
+ const aliases = this.layer.type === 'line'
338
+ ? [
339
+ ['color', 'strokeColor'],
340
+ ['opacity', 'strokeOpacity'],
341
+ ['weight', 'weight'],
342
+ ]
343
+ : paintAliases;
344
+ const readyPaint = {};
345
+ if ('radius' in paint && typeof paint.radius === 'number') {
346
+ readyPaint.radius = paint.radius;
347
+ }
348
+ for (const [to, from] of aliases) {
349
+ const opacity = this.layer.options.opacity;
350
+ let paintProp = paint[from];
351
+ if (defined(opacity) && from.toLowerCase().indexOf('opacity') !== -1) {
352
+ paintProp = Number(paintProp) * opacity;
353
+ }
354
+ if (paintProp !== undefined) {
355
+ Object.defineProperty(readyPaint, to, {
356
+ enumerable: true,
357
+ value: paintProp,
358
+ });
359
+ }
360
+ }
361
+ return readyPaint;
362
+ }
363
+ return PAINT;
364
+ }
365
+ _createDivIcon(icon) {
366
+ const { html, rotate, className, ...toLIconOpt } = icon;
367
+ const element = document.createElement('div');
368
+ if (className) {
369
+ element.className = className;
370
+ }
371
+ if (rotate) {
372
+ element.style.transform = `rotateZ(${rotate}deg)`;
373
+ }
374
+ if (html) {
375
+ element.innerHTML = html;
376
+ }
377
+ const divIcon = new DivIcon({
378
+ className: '',
379
+ ...toLIconOpt,
380
+ html: element,
381
+ });
382
+ return divIcon;
383
+ }
384
+ createPaintToLayer(icon) {
385
+ if (icon && icon.type) {
386
+ if (icon.type === 'icon') {
387
+ const iconClassName = icon.className;
388
+ const html = icon.html;
389
+ if (iconClassName || html) {
390
+ return (_, latlng) => {
391
+ const divIcon = this._createDivIcon(icon);
392
+ return new Marker(latlng, { icon: divIcon });
393
+ };
394
+ }
395
+ }
396
+ else if (icon.type === 'pin') {
397
+ return (_, latlng) => {
398
+ return new Marker(latlng);
399
+ };
400
+ }
401
+ }
402
+ return (_, latlng) => {
403
+ const p = PAINT;
404
+ return new CircleMarker(latlng, this.preparePaint({ ...p, ...icon }));
405
+ };
406
+ }
407
+ createPaintOptions(paint) {
408
+ const geoJsonOptions = {};
409
+ const newPaint = this.preparePaint(paint);
410
+ if (paint) {
411
+ geoJsonOptions.style = () => {
412
+ return newPaint;
413
+ };
414
+ }
415
+ if (this.layer.type === 'point') {
416
+ geoJsonOptions.pointToLayer = this.createPaintToLayer(paint);
417
+ }
418
+ else if (this.layer.type === 'line') {
419
+ newPaint.stroke = true;
420
+ }
421
+ return geoJsonOptions;
422
+ }
423
+ }
424
+
243
425
  class GeoJsonAdapter extends BaseAdapter {
244
426
  constructor(map, options) {
245
427
  super(map, options);
@@ -254,6 +436,8 @@ class GeoJsonAdapter extends BaseAdapter {
254
436
  this.$unselect = () => {
255
437
  this.unselect();
256
438
  };
439
+ this._events = new GeoJsonEvents(this);
440
+ this._paint = new GeoJsonPaint(this);
257
441
  }
258
442
  addLayer(options) {
259
443
  Object.assign(this.options, options);
@@ -284,7 +468,7 @@ class GeoJsonAdapter extends BaseAdapter {
284
468
  else if (!this.selected) {
285
469
  this.selected = true;
286
470
  if (this.selectedPaint) {
287
- this._setPaintEachLayer(this.selectedPaint);
471
+ this._paint.setPaintEachLayer(this.selectedPaint);
288
472
  }
289
473
  }
290
474
  }
@@ -300,7 +484,7 @@ class GeoJsonAdapter extends BaseAdapter {
300
484
  this._removePopup(p[0]);
301
485
  }
302
486
  if (this.paint) {
303
- this._setPaintEachLayer(this.paint);
487
+ this._paint.setPaintEachLayer(this.paint);
304
488
  }
305
489
  this._selectedLayers.length = 0;
306
490
  this.selected = false;
@@ -471,7 +655,7 @@ class GeoJsonAdapter extends BaseAdapter {
471
655
  if (paint) {
472
656
  this.paint = paint;
473
657
  for (const l of this._layers) {
474
- this._setPaint(l, paint);
658
+ this._paint.setPaint(l, paint);
475
659
  }
476
660
  }
477
661
  }
@@ -479,22 +663,25 @@ class GeoJsonAdapter extends BaseAdapter {
479
663
  if (paint) {
480
664
  this.selectedPaint = paint;
481
665
  for (const l of this._selectedLayers) {
482
- this._setPaint(l, paint);
666
+ this._paint.setPaint(l, paint);
483
667
  }
484
668
  }
485
669
  }
486
670
  updatePaint(paint) {
487
671
  this.paint = { ...this.paint, ...paint };
488
672
  for (const l of this._layers) {
489
- this._setPaint(l, this.paint);
673
+ this._paint.setPaint(l, this.paint);
490
674
  }
491
675
  }
492
676
  updateSelectedPaint(paint) {
493
677
  this.selectedPaint = { ...this.selectedPaint, ...paint };
494
678
  for (const l of this._selectedLayers) {
495
- this._setPaint(l, this.selectedPaint);
679
+ this._paint.setPaint(l, this.selectedPaint);
496
680
  }
497
681
  }
682
+ _getSelected(layer) {
683
+ return this._selectedLayers.find((x) => x.layer === layer);
684
+ }
498
685
  _updateTooltip(layerDef) {
499
686
  const { feature, layer } = layerDef;
500
687
  if (feature && layer && feature.properties && this.options.labelField) {
@@ -584,77 +771,6 @@ class GeoJsonAdapter extends BaseAdapter {
584
771
  }
585
772
  }
586
773
  }
587
- _setPaintEachLayer(paint) {
588
- this._layers.forEach((l) => {
589
- this._setPaint(l, paint);
590
- });
591
- }
592
- _setPaint(def, paint) {
593
- let style = undefined;
594
- const { layer, feature } = def;
595
- if (layer && feature) {
596
- if (isPaintCallback(paint)) {
597
- style = paint(feature);
598
- }
599
- else if (isPaint(paint)) {
600
- style = paint;
601
- }
602
- if (style) {
603
- if (this.type === 'point' && style.type === 'icon') {
604
- const marker = layer;
605
- const divIcon = this._createDivIcon(style);
606
- marker.setIcon(divIcon);
607
- }
608
- else if ('setStyle' in layer) {
609
- layer.setStyle(this._preparePaint(style));
610
- }
611
- }
612
- }
613
- }
614
- _preparePaint(paint) {
615
- if (paint.type !== 'get-paint') {
616
- // const path: CircleMarkerOptions | PathOptions = paint as CircleMarkerOptions | PathOptions;
617
- // if (path.opacity) {
618
- // path.fillOpacity = path.opacity;
619
- // }
620
- const paintAliases = [
621
- // ['color', 'color'],
622
- ['color', 'strokeColor'],
623
- ['opacity', 'strokeOpacity'],
624
- ['stroke', 'stroke'],
625
- ['fillColor', 'fillColor'],
626
- ['fillOpacity', 'fillOpacity'],
627
- ['fill', 'fill'],
628
- ['weight', 'weight'],
629
- ];
630
- const aliases = this.type === 'line'
631
- ? [
632
- ['color', 'strokeColor'],
633
- ['opacity', 'strokeOpacity'],
634
- ['weight', 'weight'],
635
- ]
636
- : paintAliases;
637
- const readyPaint = {};
638
- if ('radius' in paint && typeof paint.radius === 'number') {
639
- readyPaint.radius = paint.radius;
640
- }
641
- for (const [to, from] of aliases) {
642
- let paintProp = paint[from];
643
- if (defined(this.options.opacity) &&
644
- from.toLowerCase().indexOf('opacity') !== -1) {
645
- paintProp = Number(paintProp) * this.options.opacity;
646
- }
647
- if (paintProp !== undefined) {
648
- Object.defineProperty(readyPaint, to, {
649
- enumerable: true,
650
- value: paintProp,
651
- });
652
- }
653
- }
654
- return readyPaint;
655
- }
656
- return PAINT;
657
- }
658
774
  _getGeoJsonOptions(options, type) {
659
775
  const paint = options.paint;
660
776
  let lopt = {};
@@ -663,7 +779,7 @@ class GeoJsonAdapter extends BaseAdapter {
663
779
  // TODO: fix types (@geoman-io/leaflet-geoman-free)
664
780
  lopt.pointToLayer = (feature, latLng) => {
665
781
  const iconOpt = paint(feature);
666
- const pointToLayer = this._createPaintToLayer(iconOpt);
782
+ const pointToLayer = this._paint.createPaintToLayer(iconOpt);
667
783
  return pointToLayer(feature, latLng);
668
784
  };
669
785
  }
@@ -671,17 +787,17 @@ class GeoJsonAdapter extends BaseAdapter {
671
787
  lopt = {
672
788
  style: (feature) => {
673
789
  if (feature) {
674
- return this._preparePaint({ ...PAINT, ...paint(feature) });
790
+ return this._paint.preparePaint({ ...PAINT, ...paint(feature) });
675
791
  }
676
792
  else {
677
- return this._preparePaint({ ...PAINT, type: 'path' });
793
+ return this._paint.preparePaint({ ...PAINT, type: 'path' });
678
794
  }
679
795
  },
680
796
  };
681
797
  }
682
798
  }
683
799
  else {
684
- lopt = this._createPaintOptions(paint, type);
800
+ lopt = this._paint.createPaintOptions(paint);
685
801
  }
686
802
  lopt.onEachFeature = (feature, layer) => {
687
803
  this._onEachFeature(feature, layer);
@@ -697,7 +813,6 @@ class GeoJsonAdapter extends BaseAdapter {
697
813
  layer,
698
814
  ...createFeaturePositionOptions(feature),
699
815
  };
700
- // @ts-ignore
701
816
  layer.options.pane = this.pane;
702
817
  this._layers.push(def);
703
818
  let ok = true;
@@ -722,7 +837,7 @@ class GeoJsonAdapter extends BaseAdapter {
722
837
  layer.on('click', (e) => this._selectOnLayerClick(e), this);
723
838
  }
724
839
  }
725
- this._handleMouseEvents(layer);
840
+ this._events.handleMouseEvents(layer);
726
841
  // The timeout is needed to display the popup immediately when adding a layer to the map.
727
842
  // Without a timeout, the layer may not yet have a _map object
728
843
  setTimeout(() => {
@@ -739,39 +854,6 @@ class GeoJsonAdapter extends BaseAdapter {
739
854
  }
740
855
  }
741
856
  }
742
- _handleMouseEvents(layer) {
743
- const { onClick, onLayerClick, onMouseOut, onMouseOver } = this.options;
744
- // TODO: remove backward compatibility for onLayerClick
745
- const onClick_ = onClick || onLayerClick;
746
- if (onClick_) {
747
- layer.on('click', (e) => {
748
- const selected = !!this._getSelected(layer);
749
- onClick_({
750
- selected,
751
- ...this._createMouseEvent(e),
752
- });
753
- }, this);
754
- }
755
- if (onMouseOut) {
756
- layer.on('mouseout', (e) => {
757
- onMouseOut(this._createMouseEvent(e));
758
- }, this);
759
- }
760
- if (onMouseOver) {
761
- layer.on('mouseover', (e) => {
762
- onMouseOver(this._createMouseEvent(e));
763
- }, this);
764
- }
765
- }
766
- _createMouseEvent(source) {
767
- return createMouseEvent({
768
- layer: this,
769
- source: source,
770
- });
771
- }
772
- _getSelected(layer) {
773
- return this._selectedLayers.find((x) => x.layer === layer);
774
- }
775
857
  _selectOnLayerClick(e) {
776
858
  DomEvent.stopPropagation(e);
777
859
  const layer = e.target;
@@ -805,7 +887,7 @@ class GeoJsonAdapter extends BaseAdapter {
805
887
  this.selected = true;
806
888
  const { selectedPaint, popupOnSelect, popupOptions } = this.options;
807
889
  if (selectedPaint && def.layer) {
808
- this._setPaint(def, selectedPaint);
890
+ this._paint.setPaint(def, selectedPaint);
809
891
  }
810
892
  if (popupOnSelect) {
811
893
  this._openPopup(def, popupOptions, type, latlng);
@@ -826,7 +908,7 @@ class GeoJsonAdapter extends BaseAdapter {
826
908
  this._selectedLayers.splice(index, 1);
827
909
  if (this.options) {
828
910
  if (this.options.paint) {
829
- this._setPaint(def, this.options.paint);
911
+ this._paint.setPaint(def, this.options.paint);
830
912
  }
831
913
  if (this.options.popupOnSelect && def.layer) {
832
914
  this._removePopup(def.layer);
@@ -835,50 +917,6 @@ class GeoJsonAdapter extends BaseAdapter {
835
917
  }
836
918
  this.selected = this._selectedLayers.length > 0;
837
919
  }
838
- _createDivIcon(icon) {
839
- const { ...toLIconOpt } = icon;
840
- return new DivIcon({ className: '', ...toLIconOpt });
841
- }
842
- _createPaintToLayer(icon) {
843
- if (icon && icon.type) {
844
- if (icon.type === 'icon') {
845
- const iconClassName = icon.className;
846
- const html = icon.html;
847
- if (iconClassName || html) {
848
- return (geoJsonPoint, latlng) => {
849
- const divIcon = this._createDivIcon(icon);
850
- return new Marker(latlng, { icon: divIcon });
851
- };
852
- }
853
- }
854
- else if (icon.type === 'pin') {
855
- return (geoJsonPoint, latlng) => {
856
- // const divIcon = this.createDivIcon(icon);
857
- return new Marker(latlng);
858
- };
859
- }
860
- }
861
- return (geoJsonPoint, latlng) => {
862
- const p = PAINT;
863
- return new CircleMarker(latlng, this._preparePaint({ ...p, ...icon }));
864
- };
865
- }
866
- _createPaintOptions(paintOptions, type) {
867
- const geoJsonOptions = {};
868
- const paint = (paintOptions && this._preparePaint(paintOptions)) || {};
869
- if (paintOptions) {
870
- geoJsonOptions.style = () => {
871
- return paint;
872
- };
873
- }
874
- if (type === 'point') {
875
- geoJsonOptions.pointToLayer = this._createPaintToLayer(paintOptions);
876
- }
877
- else if (type === 'line') {
878
- paint.stroke = true;
879
- }
880
- return geoJsonOptions;
881
- }
882
920
  _addMapClickListener() {
883
921
  const map = this.map;
884
922
  if (map) {