@foodmarketmaker/mapag 0.0.5 → 0.0.8

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.
@@ -32,16 +32,18 @@ function SaveMap(map) {
32
32
  }
33
33
  function AddLayer(map, layer, afterId) {
34
34
  if (!map)
35
- return;
35
+ return false;
36
36
  try {
37
37
  if (map.getLayer(layer.id)) {
38
38
  console.log(`Layer ${layer.id} already exists`);
39
- return;
39
+ return false;
40
40
  }
41
41
  map.addLayer(layer, afterId);
42
+ return true;
42
43
  }
43
44
  catch (error) {
44
45
  console.debug(`Error adding layer ${layer.id}`);
46
+ return false;
45
47
  }
46
48
  }
47
49
  function RemoveLayer(map, layerId) {
@@ -61,7 +63,6 @@ function AddSource(map, sourceId, source) {
61
63
  return;
62
64
  try {
63
65
  if (map.getSource(sourceId)) {
64
- console.log(`Source ${sourceId} already exists`);
65
66
  return;
66
67
  }
67
68
  map.addSource(sourceId, source);
@@ -14105,6 +14106,7 @@ class MapComponent {
14105
14106
  mapper = input(new MapboxMapperGroup(), ...(ngDevMode ? [{ debugName: "mapper" }] : []));
14106
14107
  mapContainer = viewChild('map', ...(ngDevMode ? [{ debugName: "mapContainer" }] : []));
14107
14108
  id = input('mapid', ...(ngDevMode ? [{ debugName: "id" }] : []));
14109
+ onMap = output();
14108
14110
  // accessToken = input.required<string>();
14109
14111
  // FontAwesome icons
14110
14112
  faPrint = faPrint;
@@ -14134,7 +14136,7 @@ class MapComponent {
14134
14136
  // style = 'https://demotiles.maplibre.org/style.json'
14135
14137
  if (container) {
14136
14138
  // @ts-ignore - Type conflict between different maplibre-gl versions
14137
- this.map = new maplibregl.Map({
14139
+ const map = new maplibregl.Map({
14138
14140
  container: container.nativeElement,
14139
14141
  // style: this.basemap(),
14140
14142
  style: this.styles.style().url, // Default style
@@ -14142,36 +14144,43 @@ class MapComponent {
14142
14144
  minZoom: 1,
14143
14145
  zoom: 3,
14144
14146
  });
14147
+ this.map = map;
14145
14148
  // disable map rotation using right click + drag
14146
- if (this.map) {
14147
- this.map.dragRotate.disable();
14148
- this.map.on('styledata', (e) => {
14149
- console.log('= MAP STYLE DATA ===', e);
14150
- if (!this.map)
14151
- return;
14152
- this.mapper().onStyleChange(this.map, this.svc);
14149
+ map.dragRotate.disable();
14150
+ // Forward style change events to the mapper
14151
+ map.on('styledata', (e) => {
14152
+ this.zone.runOutsideAngular(() => {
14153
+ this.mapper().onStyleChange(map, this.svc);
14153
14154
  });
14154
- this.map.on('idle', () => {
14155
- console.log('= MAP IDLE ===');
14156
- if (!this.map)
14157
- return;
14158
- this.mapper().onStyleChange(this.map, this.svc);
14155
+ });
14156
+ // Forward style change events to the mapper
14157
+ this.map.on('idle', () => {
14158
+ this.zone.runOutsideAngular(() => {
14159
+ this.mapper().onStyleChange(map, this.svc);
14159
14160
  });
14160
- this.map.on('load', () => {
14161
- if (!this.map)
14162
- return;
14163
- console.log('Map loaded successfully');
14164
- this.styles.initializeMap(this.map);
14165
- // Setup the mapper
14166
- const mapper = this.mapper();
14167
- // Set the map in the services
14168
- this.svc.setMap(this.map);
14169
- this.svc.setMapper(mapper);
14170
- this.selectionSvc.setMap(this.map);
14171
- this.selectionSvc.setMapper(mapper);
14172
- this.map.addControl(new maplibregl.NavigationControl());
14161
+ });
14162
+ // Process when the map has finished loading
14163
+ this.map.on('load', () => {
14164
+ this.styles.initializeMap(map);
14165
+ // Setup the mapper
14166
+ const mapper = this.mapper();
14167
+ // Set the map in the services
14168
+ this.svc.setMap(map);
14169
+ this.svc.setMapper(mapper);
14170
+ this.selectionSvc.setMap(map);
14171
+ this.selectionSvc.setMapper(mapper);
14172
+ // Just create our standard Layers
14173
+ const std = new StandardLayersMapper();
14174
+ std.onReady(map, this.svc);
14175
+ // Notify that the map is ready
14176
+ this.zone.runOutsideAngular(() => {
14177
+ this.onMap.emit(map);
14173
14178
  });
14174
- }
14179
+ // Initialize the mapper(s)
14180
+ this.zone.runOutsideAngular(() => {
14181
+ this.mapper().onReady(map, this.svc);
14182
+ });
14183
+ });
14175
14184
  }
14176
14185
  });
14177
14186
  }
@@ -14191,7 +14200,7 @@ class MapComponent {
14191
14200
  this.map.triggerRepaint();
14192
14201
  }
14193
14202
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: MapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14194
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: MapComponent, isStandalone: true, selector: "mapag-map", inputs: { mapper: { classPropertyName: "mapper", publicName: "mapper", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["map"], descendants: true, isSignal: true }], ngImport: i0, template: `
14203
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: MapComponent, isStandalone: true, selector: "mapag-map", inputs: { mapper: { classPropertyName: "mapper", publicName: "mapper", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onMap: "onMap" }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["map"], descendants: true, isSignal: true }], ngImport: i0, template: `
14195
14204
  <div class="mapcontainer" #map>
14196
14205
  @if (mapper().legends.length) { @for (legend of mapper().legends; track
14197
14206
  legend) {
@@ -14242,7 +14251,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
14242
14251
  </div>
14243
14252
  <ng-content></ng-content>
14244
14253
  `, styles: [":host{height:100%;position:relative;overflow:hidden}.mapcontainer{margin:0;padding:0;height:100%;width:100%}.legend{position:absolute;top:10px;right:10px;background:#fff;padding:10px;border-radius:5px;box-shadow:0 2px 4px #0003;z-index:1000}.buttons{position:absolute;top:10px;left:10px;z-index:1000}.buttons>button{border-radius:5px;border:1px solid #ccc;background:#fff;color:#333;padding:8px 12px;cursor:pointer;box-shadow:0 2px 4px #0003}.buttons>button:hover{background-color:#f0f0f0}.legend-row{display:grid;grid-template-columns:auto 1fr;gap:8px;padding:4px 0;align-items:center}.legend-title{font-weight:700;text-align:center;margin-bottom:8px}.legend-item{height:15px;width:15px;border:1px solid #ccc}\n"] }]
14245
- }], ctorParameters: () => [], propDecorators: { mapper: [{ type: i0.Input, args: [{ isSignal: true, alias: "mapper", required: false }] }], mapContainer: [{ type: i0.ViewChild, args: ['map', { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
14254
+ }], ctorParameters: () => [], propDecorators: { mapper: [{ type: i0.Input, args: [{ isSignal: true, alias: "mapper", required: false }] }], mapContainer: [{ type: i0.ViewChild, args: ['map', { isSignal: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], onMap: [{ type: i0.Output, args: ["onMap"] }] } });
14246
14255
  // Define map styles
14247
14256
  const mapStyles = {
14248
14257
  'carto-positron': {
@@ -14601,118 +14610,224 @@ class CensusTractMapper {
14601
14610
  };
14602
14611
  }
14603
14612
 
14613
+ class LayerSettings {
14614
+ visible = true;
14615
+ }
14616
+ class PolygonLayerSettings extends LayerSettings {
14617
+ fillColor = '#888888';
14618
+ fillOpacity = 0.5;
14619
+ opacity = 0.7;
14620
+ borderColor = '#ffffff';
14621
+ borderWidth = 0.5;
14622
+ borderOpacity = 0.8;
14623
+ }
14624
+ class DiscreteColors {
14625
+ colors = {};
14626
+ }
14627
+
14604
14628
  class HardinessMapper {
14629
+ LAYER_ID = 'hardiness-layer';
14630
+ SOURCE_ID = 'hardinessSource';
14631
+ SOURCE_LAYER = 'hardiness2023';
14632
+ PMTILES_URL = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/hardiness2023.pmtiles';
14605
14633
  current = null;
14606
14634
  currentFeatureID = undefined;
14607
14635
  over = signal(null, ...(ngDevMode ? [{ debugName: "over" }] : []));
14636
+ settings = signal(new HardinessSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
14608
14637
  async onStyleChange(map, svc) {
14609
14638
  console.log('=== MAP ON STYLE CHANGE - MapboxMapperGroup ===');
14610
14639
  // await this.onReady(map, svc);
14611
14640
  }
14612
- async onReady(map, svc) {
14613
- this.map = map;
14614
- const PMTILES_URL = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/hardiness2023.pmtiles';
14641
+ constructor() {
14642
+ const _ = effect(() => {
14643
+ const settings = this.settings();
14644
+ // this._update(settings);
14645
+ this.create();
14646
+ }, ...(ngDevMode ? [{ debugName: "_" }] : []));
14647
+ }
14648
+ async create() {
14649
+ if (!this.map) {
14650
+ return;
14651
+ }
14652
+ const map = this.map;
14615
14653
  // Method 1: Get available layers from PMTiles metadata
14616
- const layers = await discoverLayers(PMTILES_URL);
14654
+ const layers = await discoverLayers(this.PMTILES_URL);
14617
14655
  console.log('Discovered layers:', layers);
14618
- map.addSource('hardinessSource', {
14656
+ AddSource(map, this.SOURCE_ID, {
14619
14657
  type: 'vector',
14620
- url: PMTILES_URL,
14658
+ url: this.PMTILES_URL,
14621
14659
  });
14622
- map.addLayer({
14623
- id: 'hardiness-layer',
14624
- source: 'hardinessSource',
14625
- 'source-layer': 'hardiness2023',
14660
+ const added = AddLayer(map, {
14661
+ id: this.LAYER_ID,
14662
+ source: this.SOURCE_ID,
14663
+ 'source-layer': this.SOURCE_LAYER,
14626
14664
  type: 'fill',
14627
- paint: {
14628
- 'fill-color': [
14629
- 'case',
14630
- ['==', ['get', 'zone'], '1a'], '#1a237e',
14631
- ['==', ['get', 'zone'], '1b'], '#283593',
14632
- ['==', ['get', 'zone'], '2a'], '#3949ab',
14633
- ['==', ['get', 'zone'], '2b'], '#3f51b5',
14634
- ['==', ['get', 'zone'], '3a'], '#5c6bc0',
14635
- ['==', ['get', 'zone'], '3b'], '#7986cb',
14636
- ['==', ['get', 'zone'], '4a'], '#42a5f5',
14637
- ['==', ['get', 'zone'], '4b'], '#29b6f6',
14638
- ['==', ['get', 'zone'], '5a'], '#26c6da',
14639
- ['==', ['get', 'zone'], '5b'], '#26a69a',
14640
- ['==', ['get', 'zone'], '6a'], '#66bb6a',
14641
- ['==', ['get', 'zone'], '6b'], '#9ccc65',
14642
- ['==', ['get', 'zone'], '7a'], '#d4e157',
14643
- ['==', ['get', 'zone'], '7b'], '#ffee58',
14644
- ['==', ['get', 'zone'], '8a'], '#ffca28',
14645
- ['==', ['get', 'zone'], '8b'], '#ffa726',
14646
- ['==', ['get', 'zone'], '9a'], '#ff8a65',
14647
- ['==', ['get', 'zone'], '9b'], '#ff7043',
14648
- ['==', ['get', 'zone'], '10a'], '#f4511e',
14649
- ['==', ['get', 'zone'], '10b'], '#e53935',
14650
- ['==', ['get', 'zone'], '11a'], '#c62828',
14651
- ['==', ['get', 'zone'], '11b'], '#ad1457',
14652
- ['==', ['get', 'zone'], '12a'], '#8e24aa',
14653
- ['==', ['get', 'zone'], '12b'], '#7b1fa2',
14654
- ['==', ['get', 'zone'], '13a'], '#6a1b9a',
14655
- ['==', ['get', 'zone'], '13b'], '#4a148c',
14656
- '#cccccc' // default color for unknown zones
14657
- ],
14658
- 'fill-opacity': 0.7,
14659
- },
14660
- maxzoom: 14,
14661
14665
  }, StandardLayersMapper.POLYGONS_BACKGROUND);
14662
- // map.showTileBoundaries = true;
14663
- // map.addLayer(
14664
- // {
14665
- // id: 'hardiness-layer-line',
14666
- // source: 'hardinessSource',
14667
- // 'source-layer': 'hardiness2023',
14668
- // type: 'line',
14669
- // paint: {
14670
- // 'line-color': '#ffffff',
14671
- // 'line-width': 0.5,
14672
- // 'line-opacity': 0.8,
14673
- // },
14674
- // maxzoom: 14,
14675
- // },
14676
- // StandardLayersMapper.POLYGONS_BACKGROUND
14677
- // );
14678
- map.on('mousemove', 'hardiness-layer', (e) => {
14679
- this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
14680
- });
14681
- map.on('click', 'hardiness-layer', (e) => {
14682
- // Publish
14683
- this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
14684
- if (e.features && e.features.length > 0) {
14685
- const feature = e.features[0];
14686
- const coordinates = e.lngLat;
14687
- console.log('Feature properties:', feature.properties);
14688
- const name = feature.properties
14689
- ? feature.properties['zone']
14690
- : 'Unknown';
14691
- // Ensure that if the popup is already open, we don't create a new one
14692
- if (this.popup) {
14693
- this.popup.remove();
14666
+ this._update(this.settings());
14667
+ if (added) {
14668
+ map.on('mousemove', this.LAYER_ID, (e) => {
14669
+ this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
14670
+ });
14671
+ map.on('click', this.LAYER_ID, (e) => {
14672
+ // Publish
14673
+ this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
14674
+ if (e.features && e.features.length > 0) {
14675
+ const feature = e.features[0];
14676
+ const coordinates = e.lngLat;
14677
+ console.log('Feature properties:', feature.properties);
14678
+ const name = feature.properties
14679
+ ? feature.properties['zone']
14680
+ : 'Unknown';
14681
+ // Ensure that if the popup is already open, we don't create a new one
14682
+ if (this.popup) {
14683
+ this.popup.remove();
14684
+ }
14685
+ const fields = feature.properties
14686
+ ? Object.entries(feature.properties)
14687
+ .map(([key, value]) => `<strong>${key}:</strong> ${value}`)
14688
+ .join('<br/>')
14689
+ : '';
14690
+ this.currentFeatureID = feature?.properties?.['globalid'];
14691
+ this.popup = new Popup({ maxWidth: '400px' })
14692
+ .setLngLat(coordinates)
14693
+ .setHTML(`<strong>Hardiness:</strong> ${name}<hr /><br/>${fields}`)
14694
+ .addTo(map);
14694
14695
  }
14695
- const fields = feature.properties
14696
- ? Object.entries(feature.properties)
14697
- .map(([key, value]) => `<strong>${key}:</strong> ${value}`)
14698
- .join('<br/>')
14699
- : '';
14700
- this.currentFeatureID = feature?.properties?.['globalid'];
14701
- this.popup = new Popup({ maxWidth: '400px' })
14702
- .setLngLat(coordinates)
14703
- .setHTML(`<strong>Hardiness:</strong> ${name}<hr /><br/>${fields}`)
14704
- .addTo(map);
14705
- }
14706
- });
14696
+ });
14697
+ }
14698
+ }
14699
+ update(newSettings) {
14700
+ this.settings.set({ ...newSettings });
14701
+ }
14702
+ _update(settings) {
14703
+ if (!this.map) {
14704
+ return;
14705
+ }
14706
+ // Visiblitiy
14707
+ if (settings.visible) {
14708
+ this.map.setLayoutProperty(this.LAYER_ID, 'visibility', 'visible');
14709
+ }
14710
+ else {
14711
+ this.map.setLayoutProperty(this.LAYER_ID, 'visibility', 'none');
14712
+ }
14713
+ // Update paint properties
14714
+ this.map.setPaintProperty(this.LAYER_ID, 'fill-color', [
14715
+ 'case',
14716
+ ['==', ['get', 'zone'], '1a'], settings.zone1a,
14717
+ ['==', ['get', 'zone'], '1b'], settings.zone1b,
14718
+ ['==', ['get', 'zone'], '2a'], settings.zone2a,
14719
+ ['==', ['get', 'zone'], '2b'], settings.zone2b,
14720
+ ['==', ['get', 'zone'], '3a'], settings.zone3a,
14721
+ ['==', ['get', 'zone'], '3b'], settings.zone3b,
14722
+ ['==', ['get', 'zone'], '4a'], settings.zone4a,
14723
+ ['==', ['get', 'zone'], '4b'], settings.zone4b,
14724
+ ['==', ['get', 'zone'], '5a'], settings.zone5a,
14725
+ ['==', ['get', 'zone'], '5b'], settings.zone5b,
14726
+ ['==', ['get', 'zone'], '6a'], settings.zone6a,
14727
+ ['==', ['get', 'zone'], '6b'], settings.zone6b,
14728
+ ['==', ['get', 'zone'], '7a'], settings.zone7a,
14729
+ ['==', ['get', 'zone'], '7b'], settings.zone7b,
14730
+ ['==', ['get', 'zone'], '8a'], settings.zone8a,
14731
+ ['==', ['get', 'zone'], '8b'], settings.zone8b,
14732
+ ['==', ['get', 'zone'], '9a'], settings.zone9a,
14733
+ ['==', ['get', 'zone'], '9b'], settings.zone9b,
14734
+ ['==', ['get', 'zone'], '10a'], settings.zone10a,
14735
+ ['==', ['get', 'zone'], '10b'], settings.zone10b,
14736
+ ['==', ['get', 'zone'], '11a'], settings.zone11a,
14737
+ ['==', ['get', 'zone'], '11b'], settings.zone11b,
14738
+ ['==', ['get', 'zone'], '12a'], settings.zone12a,
14739
+ ['==', ['get', 'zone'], '12b'], settings.zone12b,
14740
+ ['==', ['get', 'zone'], '13a'], settings.zone13a,
14741
+ ['==', ['get', 'zone'], '13b'], settings.zone13b,
14742
+ settings.fillColor,
14743
+ ]);
14744
+ this.map.setPaintProperty(this.LAYER_ID, 'fill-opacity', settings.fillOpacity);
14745
+ // Set up the legend
14746
+ if (settings.visible) {
14747
+ this.legends = [
14748
+ {
14749
+ title: 'USDA Plant Hardiness Zones',
14750
+ items: [
14751
+ { value: settings.zone1a, label: 'Zone 1a' },
14752
+ { value: settings.zone1b, label: 'Zone 1b' },
14753
+ { value: settings.zone2a, label: 'Zone 2a' },
14754
+ { value: settings.zone2b, label: 'Zone 2b' },
14755
+ { value: settings.zone3a, label: 'Zone 3a' },
14756
+ { value: settings.zone3b, label: 'Zone 3b' },
14757
+ { value: settings.zone4a, label: 'Zone 4a' },
14758
+ { value: settings.zone4b, label: 'Zone 4b' },
14759
+ { value: settings.zone5a, label: 'Zone 5a' },
14760
+ { value: settings.zone5b, label: 'Zone 5b' },
14761
+ { value: settings.zone6a, label: 'Zone 6a' },
14762
+ { value: settings.zone6b, label: 'Zone 6b' },
14763
+ { value: settings.zone7a, label: 'Zone 7a' },
14764
+ { value: settings.zone7b, label: 'Zone 7b' },
14765
+ { value: settings.zone8a, label: 'Zone 8a' },
14766
+ { value: settings.zone8b, label: 'Zone 8b' },
14767
+ { value: settings.zone9a, label: 'Zone 9a' },
14768
+ { value: settings.zone9b, label: 'Zone 9b' },
14769
+ { value: settings.zone10a, label: 'Zone 10a' },
14770
+ { value: settings.zone10b, label: 'Zone 10b' },
14771
+ { value: settings.zone11a, label: 'Zone 11a' },
14772
+ { value: settings.zone11b, label: 'Zone 11b' },
14773
+ { value: settings.zone12a, label: 'Zone 12a' },
14774
+ { value: settings.zone12b, label: 'Zone 12b' },
14775
+ { value: settings.zone13a, label: 'Zone 13a' },
14776
+ { value: settings.zone13b, label: 'Zone 13b' },
14777
+ ],
14778
+ },
14779
+ ];
14780
+ }
14781
+ else {
14782
+ this.legends = undefined;
14783
+ }
14784
+ }
14785
+ async onReady(map, svc) {
14786
+ this.map = map;
14787
+ this.create();
14707
14788
  }
14708
14789
  reset() { }
14709
- clear() { }
14790
+ clear() {
14791
+ RemoveLayer(this.map, this.LAYER_ID);
14792
+ RemoveSource(this.map, this.SOURCE_ID);
14793
+ }
14710
14794
  legends;
14711
14795
  count = 0;
14712
14796
  total = 0;
14713
14797
  map;
14714
14798
  popup = null;
14715
14799
  }
14800
+ class HardinessSettings extends PolygonLayerSettings {
14801
+ zone1a = '#1a237e';
14802
+ zone1b = '#283593';
14803
+ zone2a = '#3949ab';
14804
+ zone2b = '#3f51b5';
14805
+ zone3a = '#5c6bc0';
14806
+ zone3b = '#7986cb';
14807
+ zone4a = '#42a5f5';
14808
+ zone4b = '#29b6f6';
14809
+ zone5a = '#26c6da';
14810
+ zone5b = '#26a69a';
14811
+ zone6a = '#66bb6a';
14812
+ zone6b = '#9ccc65';
14813
+ zone7a = '#d4e157';
14814
+ zone7b = '#ffee58';
14815
+ zone8a = '#ffca28';
14816
+ zone8b = '#ffa726';
14817
+ zone9a = '#ff8a65';
14818
+ zone9b = '#ff7043';
14819
+ zone10a = '#f4511e';
14820
+ zone10b = '#e53935';
14821
+ zone11a = '#c62828';
14822
+ zone11b = '#ad1457';
14823
+ zone12a = '#8e24aa';
14824
+ zone12b = '#7b1fa2';
14825
+ zone13a = '#6a1b9a';
14826
+ zone13b = '#4a148c';
14827
+ fillColor = '#cccccc'; // default color for unknown zones
14828
+ fillOpacity = 0.7;
14829
+ borderOpacity = 0;
14830
+ }
14716
14831
 
14717
14832
  class VectorTileServerMapper {
14718
14833
  src;
@@ -14824,43 +14939,73 @@ class VectorTileServerMapper {
14824
14939
  // }
14825
14940
 
14826
14941
  class WatershedMapper {
14942
+ FILL_LAYER_ID = 'watershed-layer';
14943
+ LINE_LAYER_ID = 'watershed-layer-line';
14944
+ SOURCE_ID = 'watershedSource';
14945
+ SOURCE_LAYER = 'watershedhu6';
14946
+ settings = signal(new WatershedSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
14827
14947
  current = null;
14828
14948
  currentFeatureID = undefined;
14829
14949
  over = signal(null, ...(ngDevMode ? [{ debugName: "over" }] : []));
14830
- async onReady(map, svc) {
14831
- this.map = map;
14950
+ constructor() {
14951
+ const _ = effect(() => {
14952
+ const settings = this.settings();
14953
+ this._update(settings);
14954
+ }, ...(ngDevMode ? [{ debugName: "_" }] : []));
14955
+ }
14956
+ update(settings) {
14957
+ this.settings.set({ ...settings });
14958
+ }
14959
+ _update(settings) {
14960
+ if (!this.map) {
14961
+ return;
14962
+ }
14963
+ const map = this.map;
14964
+ if (settings.visible) {
14965
+ map.setLayoutProperty(this.FILL_LAYER_ID, 'visibility', 'visible');
14966
+ map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'visible');
14967
+ }
14968
+ else {
14969
+ map.setLayoutProperty(this.FILL_LAYER_ID, 'visibility', 'none');
14970
+ map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'none');
14971
+ }
14972
+ map.setPaintProperty(this.FILL_LAYER_ID, 'fill-color', settings.fillColor);
14973
+ map.setPaintProperty(this.FILL_LAYER_ID, 'fill-opacity', settings.fillOpacity);
14974
+ map.setPaintProperty(this.LINE_LAYER_ID, 'line-color', settings.borderColor);
14975
+ map.setPaintProperty(this.LINE_LAYER_ID, 'line-width', settings.borderWidth);
14976
+ map.setPaintProperty(this.LINE_LAYER_ID, 'line-opacity', settings.borderOpacity);
14977
+ }
14978
+ create() {
14979
+ if (!this.map) {
14980
+ return;
14981
+ }
14982
+ const map = this.map;
14832
14983
  const PMTILES_URL = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/watershedhu6.pmtiles';
14833
- map.addSource('pmTileSourceName', {
14984
+ AddSource(map, this.SOURCE_ID, {
14834
14985
  type: 'vector',
14835
14986
  url: PMTILES_URL,
14836
14987
  });
14837
- map.addLayer({
14838
- id: 'watershed-layer',
14839
- source: 'pmTileSourceName',
14840
- 'source-layer': 'watershedhu6',
14988
+ const addedFill = AddLayer(map, {
14989
+ id: this.FILL_LAYER_ID,
14990
+ source: this.SOURCE_ID,
14991
+ "source-layer": this.SOURCE_LAYER,
14841
14992
  type: 'fill',
14842
- paint: {
14843
- 'fill-color': 'steelblue',
14844
- 'fill-opacity': 0.1,
14845
- },
14846
- maxzoom: 14,
14847
14993
  }, StandardLayersMapper.POLYGONS_BACKGROUND);
14848
14994
  // map.showTileBoundaries = true;
14849
- map.addLayer({
14850
- id: 'watershed-layer-line',
14851
- source: 'pmTileSourceName',
14852
- 'source-layer': 'watershedhu6',
14995
+ AddLayer(map, {
14996
+ id: this.LINE_LAYER_ID,
14997
+ source: this.SOURCE_ID,
14998
+ "source-layer": this.SOURCE_LAYER,
14853
14999
  type: 'line',
14854
- paint: {
14855
- 'line-color': 'steelblue',
14856
- 'line-width': 1,
14857
- },
14858
- maxzoom: 14,
14859
15000
  }, StandardLayersMapper.POLYGONS_BACKGROUND);
14860
- map.on('mousemove', 'watershed-layer', (e) => {
15001
+ this._update(this.settings());
15002
+ if (!addedFill) {
15003
+ return;
15004
+ }
15005
+ map.on('mousemove', this.FILL_LAYER_ID, (e) => {
14861
15006
  this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
14862
15007
  });
14863
- map.on('click', 'watershed-layer', (e) => {
15008
+ map.on('click', this.FILL_LAYER_ID, (e) => {
14864
15009
  // Publish
14865
15010
  this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
14866
15011
  if (e.features && e.features.length > 0) {
@@ -14887,14 +15032,32 @@ class WatershedMapper {
14887
15032
  }
14888
15033
  });
14889
15034
  }
15035
+ async onReady(map, svc) {
15036
+ this.map = map;
15037
+ this.create();
15038
+ }
14890
15039
  reset() { }
14891
- clear() { }
15040
+ clear() {
15041
+ if (this.map) {
15042
+ this.map.removeLayer(this.FILL_LAYER_ID);
15043
+ this.map.removeLayer(this.LINE_LAYER_ID);
15044
+ this.map.removeSource(this.SOURCE_ID);
15045
+ }
15046
+ }
14892
15047
  legends;
14893
15048
  count = 0;
14894
15049
  total = 0;
14895
15050
  map;
14896
15051
  popup = null;
14897
15052
  }
15053
+ class WatershedSettings {
15054
+ visible = true;
15055
+ fillColor = '#0000ff';
15056
+ fillOpacity = 0.1;
15057
+ borderColor = '#01018bff';
15058
+ borderWidth = 1;
15059
+ borderOpacity = 1.0;
15060
+ }
14898
15061
 
14899
15062
  class HttpBoundaryLoader {
14900
15063
  static NewCustom(http, path) {
@@ -14998,5 +15161,5 @@ class HttpBoundaryLoader {
14998
15161
  * Generated bundle index. Do not edit.
14999
15162
  */
15000
15163
 
15001
- export { AddLayer, AddSource, AreaMapperMapper, BackgroundMaskMapper, BaseMapLight, BasemapSelect, BasemapSelectMenu, CensusTractMapper, DrawingMapper, HardinessMapper, HttpBoundaryLoader, MapAreaSelectComponent, MapComponent, MapSelectionService, MapService, MapStyles, MapboxMapperGroup, NoOpMapper, RemoveLayer, RemoveSource, SaveMap, SelectMode, StandardLayersMapper, Styles, VectorTileServerMapper, WatershedMapper, discoverLayers, isGeoloader, isMultiPolygon, isNumber2DArray, isNumber3DArray, isPolygon, mapboxLoadImages, mapboxloadImage, sampleTilesForLayers, simpleClone, toMultiPolygon, trySync };
15164
+ export { AddLayer, AddSource, AreaMapperMapper, BackgroundMaskMapper, BaseMapLight, BasemapSelect, BasemapSelectMenu, CensusTractMapper, DrawingMapper, HardinessMapper, HardinessSettings, HttpBoundaryLoader, MapAreaSelectComponent, MapComponent, MapSelectionService, MapService, MapStyles, MapboxMapperGroup, NoOpMapper, RemoveLayer, RemoveSource, SaveMap, SelectMode, StandardLayersMapper, Styles, VectorTileServerMapper, WatershedMapper, WatershedSettings, discoverLayers, isGeoloader, isMultiPolygon, isNumber2DArray, isNumber3DArray, isPolygon, mapboxLoadImages, mapboxloadImage, sampleTilesForLayers, simpleClone, toMultiPolygon, trySync };
15002
15165
  //# sourceMappingURL=foodmarketmaker-mapag.mjs.map