@foodmarketmaker/mapag 0.0.23 → 0.0.25

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, effect, input, Input, Component, ChangeDetectionStrategy, inject, NgZone, Injectable, output, viewChild } from '@angular/core';
2
+ import { signal, effect, input, Input, Component, viewChild, ChangeDetectionStrategy, inject, NgZone, Injectable, output } from '@angular/core';
3
3
  import { PMTiles, Protocol } from 'pmtiles';
4
4
  import * as i1 from '@angular/common';
5
5
  import { CommonModule } from '@angular/common';
@@ -277,7 +277,8 @@ class TableRow {
277
277
  }
278
278
  }
279
279
 
280
- const DEFAULT_GLYPHS = "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf";
280
+ const DEFAULT_GLYPHS2 = "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf";
281
+ const DEFAULT_GLYPHS = "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf";
281
282
  // export const DEFAULT_GLYPHS = "'https://geoserveis.icgc.cat/contextmaps/glyphs/{fontstack}/{range}.pbf';"
282
283
  class Styles {
283
284
  style = signal(MapStyles["streetmap"], ...(ngDevMode ? [{ debugName: "style" }] : []));
@@ -350,6 +351,7 @@ class Styles {
350
351
  }
351
352
  const styleSpec = await response.json();
352
353
  console.debug("Glyphs property:", styleSpec.glyphs);
354
+ // Only set a default glyphs URL when the fetched style doesn't include one.
353
355
  if (!styleSpec.glyphs) {
354
356
  styleSpec.glyphs = DEFAULT_GLYPHS;
355
357
  }
@@ -650,89 +652,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
650
652
 
651
653
  class BasemapSelectMenu {
652
654
  map = input.required(...(ngDevMode ? [{ debugName: "map" }] : []));
653
- isPopoverVisible = false;
655
+ styleDialog = viewChild.required('styleDialog');
654
656
  mapStylesArray = Object.values(MapStyles);
655
- popoverTimeout;
656
- constructor() {
657
- }
658
657
  get currentStyle() {
659
658
  return this.map().styles.style();
660
659
  }
661
660
  getBackgroundImage() {
662
661
  const currentStyle = this.map().styles.style();
663
- // Try different path approaches for debugging
664
662
  const originalPath = currentStyle.image;
665
- // Return the original path first to test
666
663
  return `url(${originalPath})`;
667
664
  }
668
- showPopover() {
669
- if (this.popoverTimeout) {
670
- clearTimeout(this.popoverTimeout);
671
- }
672
- this.isPopoverVisible = true;
673
- }
674
- hidePopover() {
675
- this.popoverTimeout = window.setTimeout(() => {
676
- this.isPopoverVisible = false;
677
- }, 200); // Small delay to allow moving to popover
665
+ openDialog(event) {
666
+ event.stopPropagation();
667
+ const dialog = this.styleDialog().nativeElement;
668
+ dialog.showModal();
678
669
  }
679
- keepPopoverOpen() {
680
- if (this.popoverTimeout) {
681
- clearTimeout(this.popoverTimeout);
682
- this.popoverTimeout = undefined;
683
- }
670
+ closeDialog() {
671
+ const dialog = this.styleDialog().nativeElement;
672
+ dialog.close();
684
673
  }
685
674
  selectStyle(style) {
686
675
  const s = this.map().styles;
687
676
  if (s) {
688
677
  s.style.set(style);
689
678
  }
690
- this.isPopoverVisible = false;
691
- }
692
- onClick() {
693
- // Keep the original cycling behavior as fallback
694
- const s = this.map().styles;
695
- const current = this.map().styles.style();
696
- const next = this.nextStyle(current);
697
- s.style.set(next);
698
- }
699
- nextStyle(current) {
700
- const s = this.map().styles;
701
- if (!current) {
702
- // If no current style, return the first one
703
- const firstKey = Object.keys(MapStyles)[0];
704
- return MapStyles[firstKey];
705
- }
706
- // Get all the keys from MapStyles
707
- const styleKeys = Object.keys(MapStyles);
708
- // Find the current style's index
709
- const currentIndex = styleKeys.findIndex(key => MapStyles[key].code === current.code);
710
- // If current style not found, return the first one
711
- if (currentIndex === -1) {
712
- return MapStyles[styleKeys[0]];
713
- }
714
- // Get the next index, wrapping around to 0 if we're at the end
715
- const nextIndex = (currentIndex + 1) % styleKeys.length;
716
- // Return the next style
717
- return MapStyles[styleKeys[nextIndex]];
679
+ this.closeDialog();
718
680
  }
719
681
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: BasemapSelectMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
720
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.10", type: BasemapSelectMenu, isStandalone: true, selector: "mapag-basemap-select-menu", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
682
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.10", type: BasemapSelectMenu, isStandalone: true, selector: "mapag-basemap-select-menu", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "styleDialog", first: true, predicate: ["styleDialog"], descendants: true, isSignal: true }], ngImport: i0, template: `
721
683
  <div class="basemap-container"
722
- (mouseenter)="showPopover()"
723
- (mouseleave)="hidePopover()"
724
- (click)="onClick()"
725
684
  [style.background-image]="getBackgroundImage()">
726
685
  <div class="basemap-title" [style.color]="currentStyle?.nameColor || '#ffffff'">
727
686
  {{ currentStyle?.name || 'No Style Selected' }}
728
687
  </div>
729
- <!-- <div class="basemap-overlay"></div> -->
688
+ <button class="dialog-button"
689
+ (click)="openDialog($event)"
690
+ title="Choose basemap style">
691
+ ...
692
+ </button>
730
693
  </div>
731
694
 
732
- <div class="style-popover"
733
- [class.show]="isPopoverVisible"
734
- (mouseenter)="keepPopoverOpen()"
735
- (mouseleave)="hidePopover()">
695
+ <dialog #styleDialog class="style-dialog">
696
+ <div class="dialog-header">
697
+ <h3>Select Basemap Style</h3>
698
+ <button class="close-button" (click)="closeDialog()">✕</button>
699
+ </div>
736
700
  <div class="style-grid">
737
701
  <div *ngFor="let style of mapStylesArray"
738
702
  class="style-item"
@@ -740,27 +704,29 @@ class BasemapSelectMenu {
740
704
  <mapag-basemap-select [styleData]="style" [styles]="map().styles"></mapag-basemap-select>
741
705
  </div>
742
706
  </div>
743
- </div>
744
- `, isInline: true, styles: [":host{display:block;width:200px;height:80px;position:relative}.basemap-container{position:relative;width:100%;height:100%;border-radius:12px;background-size:cover;background-position:center;background-repeat:no-repeat;background-color:#f5f5f5;overflow:hidden;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease;box-shadow:0 2px 8px #00000026;display:flex;align-items:center;justify-content:center}.basemap-container:hover{box-shadow:0 4px 16px #0003}.basemap-overlay{position:absolute;inset:0;background:linear-gradient(135deg,#0000001a,#0000004d);border-radius:12px;pointer-events:none}.basemap-title{position:relative;z-index:2;color:#fff;font-size:19px;font-weight:600;text-align:center;padding:8px 16px;background:#0000;border-radius:8px;-webkit-user-select:none;user-select:none;text-shadow:0 2px 4px rgba(0,0,0,.8);max-width:90%;word-wrap:break-word;line-height:1.2}.basemap-container:not([style*=\"background-image: url\"]){background:linear-gradient(135deg,#667eea,#764ba2)}.basemap-container:not([style*=\"background-image: url\"]) .basemap-overlay{background:#0000001a}.style-popover{padding:16px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #00000026;border:1px solid rgba(0,0,0,.1);opacity:0;visibility:hidden;transform:translateY(-10px);transition:opacity .2s ease,transform .2s ease,visibility .2s ease;position:absolute;top:calc(100% + 8px);left:0;z-index:1000;max-width:90vw;max-height:80vh;overflow-y:auto;min-width:100%}.style-popover.show{opacity:1;visibility:visible;transform:translateY(0)}.style-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;min-width:380px;max-width:600px}.style-item{cursor:pointer;transition:transform .2s ease}.style-item:hover{transform:scale(1.05)}@media (max-width: 768px){.style-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));min-width:300px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: BasemapSelect, selector: "mapag-basemap-select", inputs: ["styleData", "styles"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
707
+ </dialog>
708
+ `, isInline: true, styles: [":host{display:block;width:200px;height:60px;position:relative}.basemap-container{position:relative;width:100%;height:100%;border-radius:12px;background-size:cover;background-position:center;background-repeat:no-repeat;background-color:#f5f5f5;overflow:hidden;box-shadow:0 2px 8px #00000026;display:flex;align-items:center;justify-content:center}.basemap-title{position:relative;z-index:1;color:#fff;font-size:19px;font-weight:600;text-align:center;padding:8px 16px;background:#0000;border-radius:8px;-webkit-user-select:none;user-select:none;text-shadow:0 2px 4px rgba(0,0,0,.8);max-width:90%;word-wrap:break-word;line-height:1.2}.dialog-button{position:absolute;top:50%;transform:translateY(-50%);right:8px;background:#ffffffe6;border:none;border-radius:6px;padding:4px 10px;font-size:18px;font-weight:700;cursor:pointer;z-index:2;transition:background-color .2s ease,transform .2s ease;box-shadow:0 2px 4px #0003;letter-spacing:1px}.dialog-button:hover{background:#fff;transform:translateY(-50%) scale(1.1)}.dialog-button:active{transform:translateY(-50%) scale(.95)}.basemap-container:not([style*=\"background-image: url\"]){background:linear-gradient(135deg,#667eea,#764ba2)}.style-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);margin:0;border:none;border-radius:12px;padding:0;max-width:90vw;max-height:80vh;box-shadow:0 8px 32px #00000040;background:#fff}.style-dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.dialog-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid rgba(0,0,0,.1)}.dialog-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.close-button{background:transparent;border:none;font-size:24px;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;color:#666;transition:background-color .2s ease,color .2s ease}.close-button:hover{background-color:#0000000d;color:#333}.style-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;padding:20px;min-width:380px;max-width:600px;overflow-y:auto}.style-item{cursor:pointer;transition:transform .2s ease}.style-item:hover{transform:scale(1.05)}@media (max-width: 768px){.style-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));min-width:300px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: BasemapSelect, selector: "mapag-basemap-select", inputs: ["styleData", "styles"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
745
709
  }
746
710
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: BasemapSelectMenu, decorators: [{
747
711
  type: Component,
748
712
  args: [{ selector: 'mapag-basemap-select-menu', imports: [CommonModule, BasemapSelect], changeDetection: ChangeDetectionStrategy.OnPush, template: `
749
713
  <div class="basemap-container"
750
- (mouseenter)="showPopover()"
751
- (mouseleave)="hidePopover()"
752
- (click)="onClick()"
753
714
  [style.background-image]="getBackgroundImage()">
754
715
  <div class="basemap-title" [style.color]="currentStyle?.nameColor || '#ffffff'">
755
716
  {{ currentStyle?.name || 'No Style Selected' }}
756
717
  </div>
757
- <!-- <div class="basemap-overlay"></div> -->
718
+ <button class="dialog-button"
719
+ (click)="openDialog($event)"
720
+ title="Choose basemap style">
721
+ ...
722
+ </button>
758
723
  </div>
759
724
 
760
- <div class="style-popover"
761
- [class.show]="isPopoverVisible"
762
- (mouseenter)="keepPopoverOpen()"
763
- (mouseleave)="hidePopover()">
725
+ <dialog #styleDialog class="style-dialog">
726
+ <div class="dialog-header">
727
+ <h3>Select Basemap Style</h3>
728
+ <button class="close-button" (click)="closeDialog()">✕</button>
729
+ </div>
764
730
  <div class="style-grid">
765
731
  <div *ngFor="let style of mapStylesArray"
766
732
  class="style-item"
@@ -768,9 +734,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
768
734
  <mapag-basemap-select [styleData]="style" [styles]="map().styles"></mapag-basemap-select>
769
735
  </div>
770
736
  </div>
771
- </div>
772
- `, styles: [":host{display:block;width:200px;height:80px;position:relative}.basemap-container{position:relative;width:100%;height:100%;border-radius:12px;background-size:cover;background-position:center;background-repeat:no-repeat;background-color:#f5f5f5;overflow:hidden;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease;box-shadow:0 2px 8px #00000026;display:flex;align-items:center;justify-content:center}.basemap-container:hover{box-shadow:0 4px 16px #0003}.basemap-overlay{position:absolute;inset:0;background:linear-gradient(135deg,#0000001a,#0000004d);border-radius:12px;pointer-events:none}.basemap-title{position:relative;z-index:2;color:#fff;font-size:19px;font-weight:600;text-align:center;padding:8px 16px;background:#0000;border-radius:8px;-webkit-user-select:none;user-select:none;text-shadow:0 2px 4px rgba(0,0,0,.8);max-width:90%;word-wrap:break-word;line-height:1.2}.basemap-container:not([style*=\"background-image: url\"]){background:linear-gradient(135deg,#667eea,#764ba2)}.basemap-container:not([style*=\"background-image: url\"]) .basemap-overlay{background:#0000001a}.style-popover{padding:16px;background:#fff;border-radius:12px;box-shadow:0 8px 32px #00000026;border:1px solid rgba(0,0,0,.1);opacity:0;visibility:hidden;transform:translateY(-10px);transition:opacity .2s ease,transform .2s ease,visibility .2s ease;position:absolute;top:calc(100% + 8px);left:0;z-index:1000;max-width:90vw;max-height:80vh;overflow-y:auto;min-width:100%}.style-popover.show{opacity:1;visibility:visible;transform:translateY(0)}.style-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;min-width:380px;max-width:600px}.style-item{cursor:pointer;transition:transform .2s ease}.style-item:hover{transform:scale(1.05)}@media (max-width: 768px){.style-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));min-width:300px}}\n"] }]
773
- }], ctorParameters: () => [], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }] } });
737
+ </dialog>
738
+ `, styles: [":host{display:block;width:200px;height:60px;position:relative}.basemap-container{position:relative;width:100%;height:100%;border-radius:12px;background-size:cover;background-position:center;background-repeat:no-repeat;background-color:#f5f5f5;overflow:hidden;box-shadow:0 2px 8px #00000026;display:flex;align-items:center;justify-content:center}.basemap-title{position:relative;z-index:1;color:#fff;font-size:19px;font-weight:600;text-align:center;padding:8px 16px;background:#0000;border-radius:8px;-webkit-user-select:none;user-select:none;text-shadow:0 2px 4px rgba(0,0,0,.8);max-width:90%;word-wrap:break-word;line-height:1.2}.dialog-button{position:absolute;top:50%;transform:translateY(-50%);right:8px;background:#ffffffe6;border:none;border-radius:6px;padding:4px 10px;font-size:18px;font-weight:700;cursor:pointer;z-index:2;transition:background-color .2s ease,transform .2s ease;box-shadow:0 2px 4px #0003;letter-spacing:1px}.dialog-button:hover{background:#fff;transform:translateY(-50%) scale(1.1)}.dialog-button:active{transform:translateY(-50%) scale(.95)}.basemap-container:not([style*=\"background-image: url\"]){background:linear-gradient(135deg,#667eea,#764ba2)}.style-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);margin:0;border:none;border-radius:12px;padding:0;max-width:90vw;max-height:80vh;box-shadow:0 8px 32px #00000040;background:#fff}.style-dialog::backdrop{background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.dialog-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid rgba(0,0,0,.1)}.dialog-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.close-button{background:transparent;border:none;font-size:24px;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;color:#666;transition:background-color .2s ease,color .2s ease}.close-button:hover{background-color:#0000000d;color:#333}.style-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;padding:20px;min-width:380px;max-width:600px;overflow-y:auto}.style-item{cursor:pointer;transition:transform .2s ease}.style-item:hover{transform:scale(1.05)}@media (max-width: 768px){.style-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));min-width:300px}}\n"] }]
739
+ }], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }], styleDialog: [{ type: i0.ViewChild, args: ['styleDialog', { isSignal: true }] }] } });
774
740
 
775
741
  const BaseMapLight = {
776
742
  "version": 8,
@@ -14230,9 +14196,6 @@ class MapComponent {
14230
14196
  async initializeMap() {
14231
14197
  this.zone.runOutsideAngular(async () => {
14232
14198
  const container = this.mapContainer();
14233
- // let style =
14234
- // 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json';
14235
- // // style = 'https://demotiles.maplibre.org/style.json'
14236
14199
  let style = await this.styles.FetchStyleDefinition(this.styles.style());
14237
14200
  if (container) {
14238
14201
  // @ts-ignore - Type conflict between different maplibre-gl versions
@@ -16241,6 +16204,369 @@ const Codes = [
16241
16204
  return (a.Category + ' - ' + a.Name).localeCompare(b.Category + ' - ' + b.Name);
16242
16205
  });
16243
16206
 
16207
+ class RailroadsMapper {
16208
+ static PMTILES = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/railroads.pmtiles';
16209
+ LINE_LAYER_ID = 'ust-railroads-layer-line';
16210
+ LABEL_LAYER_ID = 'ust-railroads-layer-label';
16211
+ SOURCE_ID = 'ust-railroads-source';
16212
+ SOURCE_LAYER = 'railroads';
16213
+ settings = signal(new RailroadSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
16214
+ current = null;
16215
+ currentFeatureID = undefined;
16216
+ over = signal(null, ...(ngDevMode ? [{ debugName: "over" }] : []));
16217
+ constructor(settings) {
16218
+ if (settings) {
16219
+ this.settings.set({
16220
+ ...this.settings(),
16221
+ ...settings
16222
+ });
16223
+ }
16224
+ const _ = effect(() => {
16225
+ const settings = this.settings();
16226
+ this._update(settings);
16227
+ }, ...(ngDevMode ? [{ debugName: "_" }] : []));
16228
+ }
16229
+ update(settings) {
16230
+ this.settings.set({ ...this.settings(), ...settings });
16231
+ }
16232
+ updateUsageSettings(key, usageSettings) {
16233
+ const s = this.settings();
16234
+ s[key] = { ...s[key], ...usageSettings };
16235
+ this.settings.set({ ...s });
16236
+ }
16237
+ _update(settings) {
16238
+ if (!this.map) {
16239
+ return;
16240
+ }
16241
+ const map = this.map;
16242
+ if (settings.visible) {
16243
+ map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'visible');
16244
+ }
16245
+ else {
16246
+ map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'none');
16247
+ }
16248
+ this.filterByUsage();
16249
+ map.setPaintProperty(this.LINE_LAYER_ID, 'line-color', this.lineColorSteps());
16250
+ map.setPaintProperty(this.LINE_LAYER_ID, 'line-width', this.lineWidthSteps());
16251
+ map.setPaintProperty(this.LINE_LAYER_ID, 'line-opacity', this.lineOpacitySteps());
16252
+ const labelsVisible = settings.visible && settings.labelsVisible;
16253
+ map.setLayoutProperty(this.LABEL_LAYER_ID, 'visibility', labelsVisible ? 'visible' : 'none');
16254
+ map.setPaintProperty(this.LABEL_LAYER_ID, 'text-color', settings.labelsColor);
16255
+ map.setPaintProperty(this.LABEL_LAYER_ID, 'text-halo-color', settings.labelsHaloColor);
16256
+ map.setPaintProperty(this.LABEL_LAYER_ID, 'text-halo-width', settings.labelsHaloWidth);
16257
+ map.setPaintProperty(this.LABEL_LAYER_ID, 'text-opacity', settings.labelsOpacity);
16258
+ map.setLayoutProperty(this.LABEL_LAYER_ID, 'text-size', settings.labelsSize);
16259
+ map.setLayoutProperty(this.LABEL_LAYER_ID, 'text-allow-overlap', settings.labelOverlap);
16260
+ this.legends = this.getLegends();
16261
+ }
16262
+ create() {
16263
+ if (!this.map) {
16264
+ return;
16265
+ }
16266
+ const map = this.map;
16267
+ let PMTILES_URL = RailroadsMapper.PMTILES;
16268
+ AddSource(map, this.SOURCE_ID, {
16269
+ type: 'vector',
16270
+ url: PMTILES_URL,
16271
+ });
16272
+ const added = AddLayer(map, {
16273
+ id: this.LINE_LAYER_ID,
16274
+ source: this.SOURCE_ID,
16275
+ "source-layer": this.SOURCE_LAYER,
16276
+ type: 'line',
16277
+ }, StandardLayersMapper.POLYGONS_BACKGROUND);
16278
+ // Add labels (symbol) layer only if the style exposes a glyphs endpoint.
16279
+ // Some raster-only styles (or styles lacking a `glyphs` URL) will cause
16280
+ // MapLibre to attempt to fetch glyph PBFs from an undefined/invalid URL
16281
+ // which can produce PBF parsing errors (eg. "Unimplemented type: 3").
16282
+ const style = map.getStyle && map.getStyle();
16283
+ const hasGlyphs = !!(style && style.glyphs);
16284
+ if (hasGlyphs) {
16285
+ AddLayer(map, {
16286
+ id: this.LABEL_LAYER_ID,
16287
+ source: this.SOURCE_ID,
16288
+ "source-layer": this.SOURCE_LAYER,
16289
+ type: 'symbol',
16290
+ layout: {
16291
+ 'text-field': ['get', 'name'],
16292
+ 'text-font': ['Open Sans Semibold'], //,'Open Sans Regular'
16293
+ 'text-size': this.settings().labelsSize,
16294
+ 'text-allow-overlap': this.settings().labelOverlap,
16295
+ },
16296
+ paint: {
16297
+ 'text-color': this.settings().labelsColor,
16298
+ 'text-halo-color': this.settings().labelsHaloColor,
16299
+ 'text-halo-width': this.settings().labelsHaloWidth,
16300
+ },
16301
+ }, StandardLayersMapper.POLYGONS_BACKGROUND);
16302
+ }
16303
+ else {
16304
+ console.warn('RailroadsMapper: style has no `glyphs` URL — skipping labels layer to avoid PBF/glyph parse errors. Switch to a style with glyphs to enable labels.');
16305
+ }
16306
+ this._update(this.settings());
16307
+ if (!added) {
16308
+ return;
16309
+ }
16310
+ map.on('click', this.LINE_LAYER_ID, (e) => {
16311
+ // Publish
16312
+ this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
16313
+ if (e.features && e.features.length > 0) {
16314
+ const feature = e.features[0];
16315
+ const coordinates = e.lngLat;
16316
+ if (this.popup) {
16317
+ this.popup.remove();
16318
+ }
16319
+ const name = feature.properties['name'];
16320
+ const tb = new TableBuilder();
16321
+ tb.add('Length', this.fmtDistance(feature.properties['lengthkm']));
16322
+ tb.add('Owner', feature.properties['railowner'] ?? '');
16323
+ tb.add('Owner Code', feature.properties['railownercode'] ?? '');
16324
+ tb.add('Usage', this.usageLabel(feature.properties['railusage'] ?? 0));
16325
+ tb.add('Source', feature.properties['source_datadesc'] ?? '');
16326
+ tb.add('Originator', feature.properties['source_originator'] ?? '');
16327
+ tb.add('Load Date', feature.properties['loaddate'] ?? '');
16328
+ const fieldsHtml = tb.toHtml();
16329
+ let html = "";
16330
+ if (name) {
16331
+ html += `<strong>${name}</strong><br/>`;
16332
+ }
16333
+ html += fieldsHtml;
16334
+ this.currentFeatureID = feature?.properties?.['globalid'];
16335
+ this.popup = new Popup({ maxWidth: '400px' })
16336
+ .setLngLat(coordinates)
16337
+ .setHTML(html)
16338
+ .addTo(map);
16339
+ }
16340
+ });
16341
+ }
16342
+ fmtDistance(km) {
16343
+ if (!km) {
16344
+ return "";
16345
+ }
16346
+ return km.toFixed(1) + ' km / ' + (km * 0.621371).toFixed(1) + ' mi';
16347
+ }
16348
+ async onReady(map, svc) {
16349
+ this.map = map;
16350
+ this.create();
16351
+ }
16352
+ reset() { }
16353
+ clear() {
16354
+ if (this.map) {
16355
+ this.map.removeLayer(this.LINE_LAYER_ID);
16356
+ this.map.removeLayer(this.LABEL_LAYER_ID);
16357
+ this.map.removeSource(this.SOURCE_ID);
16358
+ }
16359
+ }
16360
+ filterByUsage() {
16361
+ if (!this.map) {
16362
+ return;
16363
+ }
16364
+ const map = this.map;
16365
+ if (!map.getLayer(this.LINE_LAYER_ID)) {
16366
+ return;
16367
+ }
16368
+ const settings = this.settings();
16369
+ if (!settings.perUsageDisplay) {
16370
+ this.map.setFilter(this.LINE_LAYER_ID, null);
16371
+ return;
16372
+ }
16373
+ map.setFilter(this.LINE_LAYER_ID, [
16374
+ "match",
16375
+ ["get", "railusage"],
16376
+ "F", settings.freight.visible,
16377
+ "P", settings.passenger.visible,
16378
+ "M", settings.mixed.visible,
16379
+ "I", settings.inactive.visible,
16380
+ "O", settings.other.visible,
16381
+ "Y", settings.yard.visible,
16382
+ "U", settings.unknown.visible,
16383
+ false
16384
+ ]);
16385
+ }
16386
+ lineColorSteps() {
16387
+ const settings = this.settings();
16388
+ if (!settings.perUsageDisplay) {
16389
+ return settings.lineColor;
16390
+ }
16391
+ return [
16392
+ "match",
16393
+ ["get", "railusage"],
16394
+ "F", settings.freight.lineColor, // Freight = blue
16395
+ "P", settings.passenger.lineColor, // Passenger = orange
16396
+ "M", settings.mixed.lineColor, // Both = green
16397
+ "I", settings.inactive.lineColor, // Inactive = gray
16398
+ "O", settings.other.lineColor, // Other = red
16399
+ "Y", settings.yard.lineColor, // Yard = purple
16400
+ "U", settings.unknown.lineColor, // Unknown = brown
16401
+ "#000000" // Default = black
16402
+ ];
16403
+ }
16404
+ lineOpacitySteps() {
16405
+ const settings = this.settings();
16406
+ if (!settings.perUsageDisplay) {
16407
+ return settings.lineOpacity;
16408
+ }
16409
+ return [
16410
+ "match",
16411
+ ["get", "railusage"],
16412
+ "F", settings.freight.lineOpacity, // Freight = blue
16413
+ "P", settings.passenger.lineOpacity, // Passenger = orange
16414
+ "M", settings.mixed.lineOpacity, // Both = green
16415
+ "I", settings.inactive.lineOpacity, // Inactive = gray
16416
+ "O", settings.other.lineOpacity, // Other = red
16417
+ "Y", settings.yard.lineOpacity, // Yard = purple
16418
+ "U", settings.unknown.lineOpacity, // Unknown = brown
16419
+ settings.lineOpacity // Default = black
16420
+ ];
16421
+ }
16422
+ lineWidthSteps() {
16423
+ const settings = this.settings();
16424
+ if (!settings.perUsageDisplay) {
16425
+ return settings.lineWidth;
16426
+ }
16427
+ return [
16428
+ "match",
16429
+ ["get", "railusage"],
16430
+ "F", settings.freight.lineWidth, // Freight = blue
16431
+ "P", settings.passenger.lineWidth, // Passenger = orange
16432
+ "M", settings.mixed.lineWidth, // Both = green
16433
+ "I", settings.inactive.lineWidth, // Inactive = gray
16434
+ "O", settings.other.lineWidth, // Other = red
16435
+ "Y", settings.yard.lineWidth, // Yard = purple
16436
+ "U", settings.unknown.lineWidth, // Unknown = brown
16437
+ settings.lineWidth // Default = black
16438
+ ];
16439
+ }
16440
+ usageLabel(usage) {
16441
+ switch (usage) {
16442
+ case "F":
16443
+ return "Freight rail line";
16444
+ case "P":
16445
+ return "Passenger rail line";
16446
+ case "M":
16447
+ return "Mixed use (freight and passenger)";
16448
+ case "O":
16449
+ return "Other (yard, spur, industrial, or special use)";
16450
+ case "I":
16451
+ return "Inactive or abandoned";
16452
+ case "Y":
16453
+ return "Yard tracks";
16454
+ case "U":
16455
+ return "Unknown or unspecified";
16456
+ default:
16457
+ return `Unrecognized code (${usage})`;
16458
+ }
16459
+ }
16460
+ getLegends() {
16461
+ const settings = this.settings();
16462
+ const items = [];
16463
+ if (!settings.perUsageDisplay) {
16464
+ items.push({
16465
+ value: settings.lineColor,
16466
+ label: 'Railroads',
16467
+ });
16468
+ }
16469
+ else {
16470
+ items.push({ value: settings.freight.lineColor, label: settings.freight.description });
16471
+ items.push({ value: settings.passenger.lineColor, label: settings.passenger.description });
16472
+ items.push({ value: settings.mixed.lineColor, label: settings.mixed.description });
16473
+ items.push({ value: settings.inactive.lineColor, label: settings.inactive.description });
16474
+ items.push({ value: settings.other.lineColor, label: settings.other.description });
16475
+ items.push({ value: settings.yard.lineColor, label: settings.yard.description });
16476
+ items.push({ value: settings.unknown.lineColor, label: settings.unknown.description });
16477
+ }
16478
+ const l = {
16479
+ title: 'Railroads',
16480
+ items: items
16481
+ };
16482
+ // Implementation for generating legends based on settings
16483
+ return [l];
16484
+ }
16485
+ legends;
16486
+ count = 0;
16487
+ total = 0;
16488
+ map;
16489
+ popup = null;
16490
+ }
16491
+ class RailroadSettings {
16492
+ perUsageDisplay = false;
16493
+ visible = true;
16494
+ lineColor = '#000000';
16495
+ lineWidth = 1;
16496
+ lineOpacity = 0.5;
16497
+ labelsVisible = false;
16498
+ labelsSize = 10;
16499
+ labelsColor = '#000000';
16500
+ labelsHaloColor = '#ffffff';
16501
+ labelsHaloWidth = 1;
16502
+ labelsOpacity = 1.0;
16503
+ labelOverlap = false;
16504
+ freight = {
16505
+ code: "F",
16506
+ description: "Freight rail line",
16507
+ visible: true,
16508
+ lineColor: "#1f77b4",
16509
+ lineWidth: 2,
16510
+ lineOpacity: 0.8
16511
+ };
16512
+ passenger = {
16513
+ code: "P",
16514
+ description: "Passenger rail line",
16515
+ visible: true,
16516
+ lineColor: "#ff7f0e",
16517
+ lineWidth: 2,
16518
+ lineOpacity: 0.8
16519
+ };
16520
+ mixed = {
16521
+ code: "M",
16522
+ description: "Mixed use (freight and passenger)",
16523
+ visible: true,
16524
+ lineColor: "#2ca02c",
16525
+ lineWidth: 2,
16526
+ lineOpacity: 0.8
16527
+ };
16528
+ inactive = {
16529
+ code: "I",
16530
+ description: "Inactive or abandoned",
16531
+ visible: false,
16532
+ lineColor: "#7f7f7f",
16533
+ lineWidth: 2,
16534
+ lineOpacity: 0.5
16535
+ };
16536
+ other = {
16537
+ code: "O",
16538
+ description: "Other (yard, spur, industrial, or special use)",
16539
+ visible: true,
16540
+ lineColor: "#d62728",
16541
+ lineWidth: 2,
16542
+ lineOpacity: 0.5
16543
+ };
16544
+ yard = {
16545
+ code: "Y",
16546
+ description: "Yard tracks",
16547
+ visible: true,
16548
+ lineColor: "#9467bd",
16549
+ lineWidth: 2,
16550
+ lineOpacity: 0.5
16551
+ };
16552
+ unknown = {
16553
+ code: "U",
16554
+ description: "Unknown or unspecified",
16555
+ visible: false,
16556
+ lineColor: "#8c564b",
16557
+ lineWidth: 2,
16558
+ lineOpacity: 0.5
16559
+ };
16560
+ }
16561
+ class RailroadUsageSettings {
16562
+ code = "";
16563
+ description = "";
16564
+ visible = true;
16565
+ lineColor = '#000000';
16566
+ lineWidth = 1;
16567
+ lineOpacity = 0.5;
16568
+ }
16569
+
16244
16570
  class SimpleMapper {
16245
16571
  reset() {
16246
16572
  if (this.map) {
@@ -16514,7 +16840,8 @@ class WatershedMapper {
16514
16840
  type: 'symbol',
16515
16841
  layout: {
16516
16842
  'text-field': ['get', 'name'],
16517
- 'text-font': ['Open Sans Regular'],
16843
+ // 'text-font': ['Open Sans Regular'],
16844
+ 'text-font': ['Open Sans Semibold'], //,'Open Sans Regular'
16518
16845
  'text-size': this.settings().labelsSize,
16519
16846
  'text-allow-overlap': this.settings().labelOverlap,
16520
16847
  },
@@ -16778,5 +17105,5 @@ class HttpBoundaryLoader {
16778
17105
  * Generated bundle index. Do not edit.
16779
17106
  */
16780
17107
 
16781
- export { AddLayer, AddSource, AreaMapperMapper, BackgroundMaskMapper, BackgroundMaskSettings, BaseMapLight, BasemapSelect, BasemapSelectMenu, CensusTractMapper, Codes, CropSequenceMapper, CropSequenceSettings, CroplandDataLayerMapper, CroplandDataLayerSettings, CroplandLegend, DEFAULT_GLYPHS, DrawingMapper, EsriMapper, EsriSettings, HardinessMapper, HardinessSettings, HttpBoundaryLoader, MapAreaSelectComponent, MapComponent, MapSelectionService, MapService, MapStyles, MapboxMapperGroup, NAASMapper, NAASSettings, NaicsMapper, NaicsMapperSettings, NoOpMapper, RemoveLayer, RemoveSource, SaveMap, SelectMode, SimpleMapper, StandardLayersMapper, Styles, TableBuilder, TableRow, VectorTileServerMapper, WatershedMapper, WatershedSettings, discoverLayers, isGeoloader, isMultiPolygon, isNumber2DArray, isNumber3DArray, isPolygon, mapboxLoadImages, mapboxloadImage, pmtilesPixelInfo, propertiesToTableHtml, sampleTilesForLayers, simpleClone, toMultiPolygon, trySync };
17108
+ export { AddLayer, AddSource, AreaMapperMapper, BackgroundMaskMapper, BackgroundMaskSettings, BaseMapLight, BasemapSelect, BasemapSelectMenu, CensusTractMapper, Codes, CropSequenceMapper, CropSequenceSettings, CroplandDataLayerMapper, CroplandDataLayerSettings, CroplandLegend, DEFAULT_GLYPHS, DEFAULT_GLYPHS2, DrawingMapper, EsriMapper, EsriSettings, HardinessMapper, HardinessSettings, HttpBoundaryLoader, MapAreaSelectComponent, MapComponent, MapSelectionService, MapService, MapStyles, MapboxMapperGroup, NAASMapper, NAASSettings, NaicsMapper, NaicsMapperSettings, NoOpMapper, RailroadSettings, RailroadUsageSettings, RailroadsMapper, RemoveLayer, RemoveSource, SaveMap, SelectMode, SimpleMapper, StandardLayersMapper, Styles, TableBuilder, TableRow, VectorTileServerMapper, WatershedMapper, WatershedSettings, discoverLayers, isGeoloader, isMultiPolygon, isNumber2DArray, isNumber3DArray, isPolygon, mapboxLoadImages, mapboxloadImage, pmtilesPixelInfo, propertiesToTableHtml, sampleTilesForLayers, simpleClone, toMultiPolygon, trySync };
16782
17109
  //# sourceMappingURL=foodmarketmaker-mapag.mjs.map