@foodmarketmaker/mapag 0.0.22 → 0.0.24
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/fesm2022/foodmarketmaker-mapag.mjs +242 -235
- package/fesm2022/foodmarketmaker-mapag.mjs.map +1 -1
- package/index.d.ts +59 -49
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, effect, input, Input, Component, ChangeDetectionStrategy, inject, NgZone, Injectable, output
|
|
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';
|
|
@@ -228,6 +228,54 @@ async function pmtilesPixelInfo(url, map, e) {
|
|
|
228
228
|
// const a = pixel[3];
|
|
229
229
|
return pixel;
|
|
230
230
|
}
|
|
231
|
+
function propertiesToTableHtml(properties) {
|
|
232
|
+
let html = '<table style="border-collapse: collapse; width: 100%; border: none; font-size: 9px;">';
|
|
233
|
+
for (const key in properties) {
|
|
234
|
+
if (properties.hasOwnProperty(key)) {
|
|
235
|
+
html += `<tr>
|
|
236
|
+
<td style="padding: 2px; font-weight: bold;">${key}</td>
|
|
237
|
+
<td style="padding: 2px;">${properties[key]}</td>
|
|
238
|
+
</tr>`;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
html += '</table>';
|
|
242
|
+
return html;
|
|
243
|
+
}
|
|
244
|
+
class TableBuilder {
|
|
245
|
+
rows = [];
|
|
246
|
+
headerStyle = `style="padding: 2px; padding-top:6ps; font-size: 9px; font-weight: bold;"`;
|
|
247
|
+
rowStyle1 = `style="padding: 2px; font-size: 9px; font-weight: bold;"`;
|
|
248
|
+
rowStyle2 = `style="padding: 2px; font-size: 9px;`;
|
|
249
|
+
addHeader(...cells) {
|
|
250
|
+
this.rows.push(new TableRow(cells, true));
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
add(...cells) {
|
|
254
|
+
this.rows.push(new TableRow(cells));
|
|
255
|
+
return this;
|
|
256
|
+
}
|
|
257
|
+
toHtml() {
|
|
258
|
+
const rowHtml = this.rows.map(row => row.toHtml()).join('');
|
|
259
|
+
return `<table style="border-collapse: collapse; width: 100%; font-size: 9px;">${rowHtml}</table>`;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
class TableRow {
|
|
263
|
+
isHeader;
|
|
264
|
+
cells;
|
|
265
|
+
headerStyle = `padding: 2px; padding-top:6px; font-size: 9px; font-weight: bold; text-align: left;`;
|
|
266
|
+
rowStyle1 = `padding: 2px; font-size: 9px; font-weight: bold;`;
|
|
267
|
+
rowStyle2 = `padding: 2px; font-size: 9px;`;
|
|
268
|
+
constructor(cells, isHeader = false) {
|
|
269
|
+
this.cells = cells;
|
|
270
|
+
this.isHeader = isHeader;
|
|
271
|
+
}
|
|
272
|
+
toHtml() {
|
|
273
|
+
if (this.isHeader) {
|
|
274
|
+
return `<tr>${this.cells.map(cell => `<th style="${this.headerStyle}">${cell}</th>`).join('\n')}</tr>`;
|
|
275
|
+
}
|
|
276
|
+
return `<tr>${this.cells.map((cell, index) => `<td style="${index == 0 ? this.rowStyle1 : this.rowStyle2}">${cell}</td>`).join('')}</tr>`;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
231
279
|
|
|
232
280
|
const DEFAULT_GLYPHS = "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf";
|
|
233
281
|
// export const DEFAULT_GLYPHS = "'https://geoserveis.icgc.cat/contextmaps/glyphs/{fontstack}/{range}.pbf';"
|
|
@@ -602,89 +650,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
|
|
|
602
650
|
|
|
603
651
|
class BasemapSelectMenu {
|
|
604
652
|
map = input.required(...(ngDevMode ? [{ debugName: "map" }] : []));
|
|
605
|
-
|
|
653
|
+
styleDialog = viewChild.required('styleDialog');
|
|
606
654
|
mapStylesArray = Object.values(MapStyles);
|
|
607
|
-
popoverTimeout;
|
|
608
|
-
constructor() {
|
|
609
|
-
}
|
|
610
655
|
get currentStyle() {
|
|
611
656
|
return this.map().styles.style();
|
|
612
657
|
}
|
|
613
658
|
getBackgroundImage() {
|
|
614
659
|
const currentStyle = this.map().styles.style();
|
|
615
|
-
// Try different path approaches for debugging
|
|
616
660
|
const originalPath = currentStyle.image;
|
|
617
|
-
// Return the original path first to test
|
|
618
661
|
return `url(${originalPath})`;
|
|
619
662
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
this.isPopoverVisible = true;
|
|
625
|
-
}
|
|
626
|
-
hidePopover() {
|
|
627
|
-
this.popoverTimeout = window.setTimeout(() => {
|
|
628
|
-
this.isPopoverVisible = false;
|
|
629
|
-
}, 200); // Small delay to allow moving to popover
|
|
663
|
+
openDialog(event) {
|
|
664
|
+
event.stopPropagation();
|
|
665
|
+
const dialog = this.styleDialog().nativeElement;
|
|
666
|
+
dialog.showModal();
|
|
630
667
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
this.popoverTimeout = undefined;
|
|
635
|
-
}
|
|
668
|
+
closeDialog() {
|
|
669
|
+
const dialog = this.styleDialog().nativeElement;
|
|
670
|
+
dialog.close();
|
|
636
671
|
}
|
|
637
672
|
selectStyle(style) {
|
|
638
673
|
const s = this.map().styles;
|
|
639
674
|
if (s) {
|
|
640
675
|
s.style.set(style);
|
|
641
676
|
}
|
|
642
|
-
this.
|
|
643
|
-
}
|
|
644
|
-
onClick() {
|
|
645
|
-
// Keep the original cycling behavior as fallback
|
|
646
|
-
const s = this.map().styles;
|
|
647
|
-
const current = this.map().styles.style();
|
|
648
|
-
const next = this.nextStyle(current);
|
|
649
|
-
s.style.set(next);
|
|
650
|
-
}
|
|
651
|
-
nextStyle(current) {
|
|
652
|
-
const s = this.map().styles;
|
|
653
|
-
if (!current) {
|
|
654
|
-
// If no current style, return the first one
|
|
655
|
-
const firstKey = Object.keys(MapStyles)[0];
|
|
656
|
-
return MapStyles[firstKey];
|
|
657
|
-
}
|
|
658
|
-
// Get all the keys from MapStyles
|
|
659
|
-
const styleKeys = Object.keys(MapStyles);
|
|
660
|
-
// Find the current style's index
|
|
661
|
-
const currentIndex = styleKeys.findIndex(key => MapStyles[key].code === current.code);
|
|
662
|
-
// If current style not found, return the first one
|
|
663
|
-
if (currentIndex === -1) {
|
|
664
|
-
return MapStyles[styleKeys[0]];
|
|
665
|
-
}
|
|
666
|
-
// Get the next index, wrapping around to 0 if we're at the end
|
|
667
|
-
const nextIndex = (currentIndex + 1) % styleKeys.length;
|
|
668
|
-
// Return the next style
|
|
669
|
-
return MapStyles[styleKeys[nextIndex]];
|
|
677
|
+
this.closeDialog();
|
|
670
678
|
}
|
|
671
679
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: BasemapSelectMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
672
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
680
|
+
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: `
|
|
673
681
|
<div class="basemap-container"
|
|
674
|
-
(mouseenter)="showPopover()"
|
|
675
|
-
(mouseleave)="hidePopover()"
|
|
676
|
-
(click)="onClick()"
|
|
677
682
|
[style.background-image]="getBackgroundImage()">
|
|
678
683
|
<div class="basemap-title" [style.color]="currentStyle?.nameColor || '#ffffff'">
|
|
679
684
|
{{ currentStyle?.name || 'No Style Selected' }}
|
|
680
685
|
</div>
|
|
681
|
-
|
|
686
|
+
<button class="dialog-button"
|
|
687
|
+
(click)="openDialog($event)"
|
|
688
|
+
title="Choose basemap style">
|
|
689
|
+
...
|
|
690
|
+
</button>
|
|
682
691
|
</div>
|
|
683
692
|
|
|
684
|
-
<
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
693
|
+
<dialog #styleDialog class="style-dialog">
|
|
694
|
+
<div class="dialog-header">
|
|
695
|
+
<h3>Select Basemap Style</h3>
|
|
696
|
+
<button class="close-button" (click)="closeDialog()">✕</button>
|
|
697
|
+
</div>
|
|
688
698
|
<div class="style-grid">
|
|
689
699
|
<div *ngFor="let style of mapStylesArray"
|
|
690
700
|
class="style-item"
|
|
@@ -692,27 +702,29 @@ class BasemapSelectMenu {
|
|
|
692
702
|
<mapag-basemap-select [styleData]="style" [styles]="map().styles"></mapag-basemap-select>
|
|
693
703
|
</div>
|
|
694
704
|
</div>
|
|
695
|
-
</
|
|
696
|
-
`, isInline: true, styles: [":host{display:block;width:200px;height:
|
|
705
|
+
</dialog>
|
|
706
|
+
`, 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 });
|
|
697
707
|
}
|
|
698
708
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: BasemapSelectMenu, decorators: [{
|
|
699
709
|
type: Component,
|
|
700
710
|
args: [{ selector: 'mapag-basemap-select-menu', imports: [CommonModule, BasemapSelect], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
701
711
|
<div class="basemap-container"
|
|
702
|
-
(mouseenter)="showPopover()"
|
|
703
|
-
(mouseleave)="hidePopover()"
|
|
704
|
-
(click)="onClick()"
|
|
705
712
|
[style.background-image]="getBackgroundImage()">
|
|
706
713
|
<div class="basemap-title" [style.color]="currentStyle?.nameColor || '#ffffff'">
|
|
707
714
|
{{ currentStyle?.name || 'No Style Selected' }}
|
|
708
715
|
</div>
|
|
709
|
-
|
|
716
|
+
<button class="dialog-button"
|
|
717
|
+
(click)="openDialog($event)"
|
|
718
|
+
title="Choose basemap style">
|
|
719
|
+
...
|
|
720
|
+
</button>
|
|
710
721
|
</div>
|
|
711
722
|
|
|
712
|
-
<
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
723
|
+
<dialog #styleDialog class="style-dialog">
|
|
724
|
+
<div class="dialog-header">
|
|
725
|
+
<h3>Select Basemap Style</h3>
|
|
726
|
+
<button class="close-button" (click)="closeDialog()">✕</button>
|
|
727
|
+
</div>
|
|
716
728
|
<div class="style-grid">
|
|
717
729
|
<div *ngFor="let style of mapStylesArray"
|
|
718
730
|
class="style-item"
|
|
@@ -720,9 +732,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
|
|
|
720
732
|
<mapag-basemap-select [styleData]="style" [styles]="map().styles"></mapag-basemap-select>
|
|
721
733
|
</div>
|
|
722
734
|
</div>
|
|
723
|
-
</
|
|
724
|
-
`, styles: [":host{display:block;width:200px;height:
|
|
725
|
-
}],
|
|
735
|
+
</dialog>
|
|
736
|
+
`, 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"] }]
|
|
737
|
+
}], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }], styleDialog: [{ type: i0.ViewChild, args: ['styleDialog', { isSignal: true }] }] } });
|
|
726
738
|
|
|
727
739
|
const BaseMapLight = {
|
|
728
740
|
"version": 8,
|
|
@@ -14625,168 +14637,6 @@ class CensusTractMapper {
|
|
|
14625
14637
|
};
|
|
14626
14638
|
}
|
|
14627
14639
|
|
|
14628
|
-
class CropSequenceMapper {
|
|
14629
|
-
static PMTILES = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/NationalCSB_2017_2024_rev23.pmtiles';
|
|
14630
|
-
FILL_LAYER_ID = 'cropsequence-layer';
|
|
14631
|
-
LINE_LAYER_ID = 'cropsequence-layer-line';
|
|
14632
|
-
LABEL_LAYER_ID = 'cropsequence-layer-label';
|
|
14633
|
-
SOURCE_ID = 'cropsequence-source';
|
|
14634
|
-
SOURCE_LAYER = 'NationalCSB_2017_2024_rev23';
|
|
14635
|
-
settings = signal(new CropSequenceSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
|
|
14636
|
-
current = null;
|
|
14637
|
-
currentFeatureID = undefined;
|
|
14638
|
-
over = signal(null, ...(ngDevMode ? [{ debugName: "over" }] : []));
|
|
14639
|
-
constructor(settings) {
|
|
14640
|
-
if (settings) {
|
|
14641
|
-
this.settings.set({
|
|
14642
|
-
...this.settings(),
|
|
14643
|
-
...settings
|
|
14644
|
-
});
|
|
14645
|
-
}
|
|
14646
|
-
const _ = effect(() => {
|
|
14647
|
-
const settings = this.settings();
|
|
14648
|
-
this._update(settings);
|
|
14649
|
-
}, ...(ngDevMode ? [{ debugName: "_" }] : []));
|
|
14650
|
-
}
|
|
14651
|
-
update(settings) {
|
|
14652
|
-
this.settings.set({ ...this.settings(), ...settings });
|
|
14653
|
-
}
|
|
14654
|
-
_update(settings) {
|
|
14655
|
-
if (!this.map) {
|
|
14656
|
-
return;
|
|
14657
|
-
}
|
|
14658
|
-
const map = this.map;
|
|
14659
|
-
if (settings.visible) {
|
|
14660
|
-
map.setLayoutProperty(this.FILL_LAYER_ID, 'visibility', 'visible');
|
|
14661
|
-
map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'visible');
|
|
14662
|
-
}
|
|
14663
|
-
else {
|
|
14664
|
-
map.setLayoutProperty(this.FILL_LAYER_ID, 'visibility', 'none');
|
|
14665
|
-
map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'none');
|
|
14666
|
-
}
|
|
14667
|
-
map.setPaintProperty(this.FILL_LAYER_ID, 'fill-color', settings.fillColor);
|
|
14668
|
-
map.setPaintProperty(this.FILL_LAYER_ID, 'fill-opacity', settings.fillOpacity);
|
|
14669
|
-
map.setPaintProperty(this.LINE_LAYER_ID, 'line-color', settings.borderColor);
|
|
14670
|
-
map.setPaintProperty(this.LINE_LAYER_ID, 'line-width', settings.borderWidth);
|
|
14671
|
-
map.setPaintProperty(this.LINE_LAYER_ID, 'line-opacity', settings.borderOpacity);
|
|
14672
|
-
const labelsVisible = settings.visible && settings.labelsVisible;
|
|
14673
|
-
map.setLayoutProperty(this.LABEL_LAYER_ID, 'visibility', labelsVisible ? 'visible' : 'none');
|
|
14674
|
-
map.setPaintProperty(this.LABEL_LAYER_ID, 'text-color', settings.labelsColor);
|
|
14675
|
-
map.setPaintProperty(this.LABEL_LAYER_ID, 'text-halo-color', settings.labelsHaloColor);
|
|
14676
|
-
map.setPaintProperty(this.LABEL_LAYER_ID, 'text-halo-width', settings.labelsHaloWidth);
|
|
14677
|
-
map.setPaintProperty(this.LABEL_LAYER_ID, 'text-opacity', settings.labelsOpacity);
|
|
14678
|
-
map.setLayoutProperty(this.LABEL_LAYER_ID, 'text-size', settings.labelsSize);
|
|
14679
|
-
map.setLayoutProperty(this.LABEL_LAYER_ID, 'text-allow-overlap', settings.labelOverlap);
|
|
14680
|
-
}
|
|
14681
|
-
create() {
|
|
14682
|
-
if (!this.map) {
|
|
14683
|
-
return;
|
|
14684
|
-
}
|
|
14685
|
-
const map = this.map;
|
|
14686
|
-
let PMTILES_URL = CropSequenceMapper.PMTILES;
|
|
14687
|
-
AddSource(map, this.SOURCE_ID, {
|
|
14688
|
-
type: 'vector',
|
|
14689
|
-
url: PMTILES_URL,
|
|
14690
|
-
});
|
|
14691
|
-
const addedFill = AddLayer(map, {
|
|
14692
|
-
id: this.FILL_LAYER_ID,
|
|
14693
|
-
source: this.SOURCE_ID,
|
|
14694
|
-
"source-layer": this.SOURCE_LAYER,
|
|
14695
|
-
type: 'fill',
|
|
14696
|
-
}, StandardLayersMapper.POLYGONS_BACKGROUND);
|
|
14697
|
-
map.showTileBoundaries = true;
|
|
14698
|
-
AddLayer(map, {
|
|
14699
|
-
id: this.LINE_LAYER_ID,
|
|
14700
|
-
source: this.SOURCE_ID,
|
|
14701
|
-
"source-layer": this.SOURCE_LAYER,
|
|
14702
|
-
type: 'line',
|
|
14703
|
-
}, StandardLayersMapper.POLYGONS_BACKGROUND);
|
|
14704
|
-
AddLayer(map, {
|
|
14705
|
-
id: this.LABEL_LAYER_ID,
|
|
14706
|
-
source: this.SOURCE_ID,
|
|
14707
|
-
"source-layer": this.SOURCE_LAYER,
|
|
14708
|
-
type: 'symbol',
|
|
14709
|
-
layout: {
|
|
14710
|
-
'text-field': ['get', 'name'],
|
|
14711
|
-
'text-font': ['Open Sans Regular'],
|
|
14712
|
-
'text-size': this.settings().labelsSize,
|
|
14713
|
-
'text-allow-overlap': this.settings().labelOverlap,
|
|
14714
|
-
},
|
|
14715
|
-
paint: {
|
|
14716
|
-
'text-color': this.settings().labelsColor,
|
|
14717
|
-
'text-halo-color': this.settings().labelsHaloColor,
|
|
14718
|
-
'text-halo-width': this.settings().labelsHaloWidth,
|
|
14719
|
-
},
|
|
14720
|
-
}, StandardLayersMapper.POLYGONS_BACKGROUND);
|
|
14721
|
-
this._update(this.settings());
|
|
14722
|
-
if (!addedFill) {
|
|
14723
|
-
return;
|
|
14724
|
-
}
|
|
14725
|
-
map.on('mousemove', this.FILL_LAYER_ID, (e) => {
|
|
14726
|
-
this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
|
|
14727
|
-
});
|
|
14728
|
-
map.on('click', this.FILL_LAYER_ID, (e) => {
|
|
14729
|
-
// Publish
|
|
14730
|
-
this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
|
|
14731
|
-
if (e.features && e.features.length > 0) {
|
|
14732
|
-
const feature = e.features[0];
|
|
14733
|
-
const coordinates = e.lngLat;
|
|
14734
|
-
console.log('Feature properties:', feature.properties);
|
|
14735
|
-
const name = feature.properties
|
|
14736
|
-
? feature.properties['name']
|
|
14737
|
-
: 'Unknown';
|
|
14738
|
-
// Ensure that if the popup is already open, we don't create a new one
|
|
14739
|
-
if (this.popup) {
|
|
14740
|
-
this.popup.remove();
|
|
14741
|
-
}
|
|
14742
|
-
const fields = feature.properties
|
|
14743
|
-
? Object.entries(feature.properties)
|
|
14744
|
-
.map(([key, value]) => `<strong>${key}:</strong> ${value}`)
|
|
14745
|
-
.join('<br/>')
|
|
14746
|
-
: '';
|
|
14747
|
-
this.currentFeatureID = feature?.properties?.['globalid'];
|
|
14748
|
-
this.popup = new Popup({ maxWidth: '400px' })
|
|
14749
|
-
.setLngLat(coordinates)
|
|
14750
|
-
.setHTML(`<strong>Watershed:</strong> ${name}<hr /><br/>${fields}`)
|
|
14751
|
-
.addTo(map);
|
|
14752
|
-
}
|
|
14753
|
-
});
|
|
14754
|
-
}
|
|
14755
|
-
async onReady(map, svc) {
|
|
14756
|
-
this.map = map;
|
|
14757
|
-
this.create();
|
|
14758
|
-
}
|
|
14759
|
-
reset() { }
|
|
14760
|
-
clear() {
|
|
14761
|
-
if (this.map) {
|
|
14762
|
-
this.map.removeLayer(this.FILL_LAYER_ID);
|
|
14763
|
-
this.map.removeLayer(this.LINE_LAYER_ID);
|
|
14764
|
-
this.map.removeLayer(this.LABEL_LAYER_ID);
|
|
14765
|
-
this.map.removeSource(this.SOURCE_ID);
|
|
14766
|
-
}
|
|
14767
|
-
}
|
|
14768
|
-
legends;
|
|
14769
|
-
count = 0;
|
|
14770
|
-
total = 0;
|
|
14771
|
-
map;
|
|
14772
|
-
popup = null;
|
|
14773
|
-
}
|
|
14774
|
-
class CropSequenceSettings {
|
|
14775
|
-
visible = true;
|
|
14776
|
-
fillColor = '#0000ff';
|
|
14777
|
-
fillOpacity = 0.1;
|
|
14778
|
-
borderColor = '#01018b';
|
|
14779
|
-
borderWidth = 1;
|
|
14780
|
-
borderOpacity = 1.0;
|
|
14781
|
-
labelsVisible = true;
|
|
14782
|
-
labelsSize = 10;
|
|
14783
|
-
labelsColor = '#000000';
|
|
14784
|
-
labelsHaloColor = '#ffffff';
|
|
14785
|
-
labelsHaloWidth = 1;
|
|
14786
|
-
labelsOpacity = 1.0;
|
|
14787
|
-
labelOverlap = false;
|
|
14788
|
-
}
|
|
14789
|
-
|
|
14790
14640
|
class CroplandDataLayerMapper {
|
|
14791
14641
|
static PMTILES = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/cdl_2024_30m.pmtiles';
|
|
14792
14642
|
LAYER_ID = 'cropland-data-layer';
|
|
@@ -15320,6 +15170,163 @@ Dbl Crop Barley/Soybeans 254 433 47.5% 52.5% 0.47
|
|
|
15320
15170
|
|
|
15321
15171
|
*/
|
|
15322
15172
|
|
|
15173
|
+
class CropSequenceMapper {
|
|
15174
|
+
static PMTILES = 'pmtiles://https://foodmarketmaker-upload-data.s3.us-west-2.amazonaws.com/tiles/NationalCSB_2017_2024_rev23.pmtiles';
|
|
15175
|
+
FILL_LAYER_ID = 'cropsequence-layer';
|
|
15176
|
+
LINE_LAYER_ID = 'cropsequence-layer-line';
|
|
15177
|
+
SOURCE_ID = 'cropsequence-source';
|
|
15178
|
+
SOURCE_LAYER = 'NationalCSB_2017_2024_rev23';
|
|
15179
|
+
settings = signal(new CropSequenceSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
|
|
15180
|
+
current = null;
|
|
15181
|
+
currentFeatureID = undefined;
|
|
15182
|
+
over = signal(null, ...(ngDevMode ? [{ debugName: "over" }] : []));
|
|
15183
|
+
constructor(settings) {
|
|
15184
|
+
if (settings) {
|
|
15185
|
+
this.settings.set({
|
|
15186
|
+
...this.settings(),
|
|
15187
|
+
...settings
|
|
15188
|
+
});
|
|
15189
|
+
}
|
|
15190
|
+
const _ = effect(() => {
|
|
15191
|
+
const settings = this.settings();
|
|
15192
|
+
this._update(settings);
|
|
15193
|
+
}, ...(ngDevMode ? [{ debugName: "_" }] : []));
|
|
15194
|
+
}
|
|
15195
|
+
update(settings) {
|
|
15196
|
+
this.settings.set({ ...this.settings(), ...settings });
|
|
15197
|
+
}
|
|
15198
|
+
_update(settings) {
|
|
15199
|
+
if (!this.map) {
|
|
15200
|
+
return;
|
|
15201
|
+
}
|
|
15202
|
+
const map = this.map;
|
|
15203
|
+
if (settings.visible) {
|
|
15204
|
+
map.setLayoutProperty(this.FILL_LAYER_ID, 'visibility', 'visible');
|
|
15205
|
+
map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'visible');
|
|
15206
|
+
}
|
|
15207
|
+
else {
|
|
15208
|
+
map.setLayoutProperty(this.FILL_LAYER_ID, 'visibility', 'none');
|
|
15209
|
+
map.setLayoutProperty(this.LINE_LAYER_ID, 'visibility', 'none');
|
|
15210
|
+
}
|
|
15211
|
+
map.setPaintProperty(this.FILL_LAYER_ID, 'fill-color', settings.fillColor);
|
|
15212
|
+
map.setPaintProperty(this.FILL_LAYER_ID, 'fill-opacity', settings.fillOpacity);
|
|
15213
|
+
map.setPaintProperty(this.LINE_LAYER_ID, 'line-color', settings.borderColor);
|
|
15214
|
+
map.setPaintProperty(this.LINE_LAYER_ID, 'line-width', settings.borderWidth);
|
|
15215
|
+
map.setPaintProperty(this.LINE_LAYER_ID, 'line-opacity', settings.borderOpacity);
|
|
15216
|
+
}
|
|
15217
|
+
create() {
|
|
15218
|
+
if (!this.map) {
|
|
15219
|
+
return;
|
|
15220
|
+
}
|
|
15221
|
+
const map = this.map;
|
|
15222
|
+
let PMTILES_URL = CropSequenceMapper.PMTILES;
|
|
15223
|
+
AddSource(map, this.SOURCE_ID, {
|
|
15224
|
+
type: 'vector',
|
|
15225
|
+
url: PMTILES_URL,
|
|
15226
|
+
});
|
|
15227
|
+
const addedFill = AddLayer(map, {
|
|
15228
|
+
id: this.FILL_LAYER_ID,
|
|
15229
|
+
source: this.SOURCE_ID,
|
|
15230
|
+
"source-layer": this.SOURCE_LAYER,
|
|
15231
|
+
type: 'fill',
|
|
15232
|
+
}, StandardLayersMapper.POLYGONS_BACKGROUND);
|
|
15233
|
+
AddLayer(map, {
|
|
15234
|
+
id: this.LINE_LAYER_ID,
|
|
15235
|
+
source: this.SOURCE_ID,
|
|
15236
|
+
"source-layer": this.SOURCE_LAYER,
|
|
15237
|
+
type: 'line',
|
|
15238
|
+
}, StandardLayersMapper.POLYGONS_BACKGROUND);
|
|
15239
|
+
this._update(this.settings());
|
|
15240
|
+
if (!addedFill) {
|
|
15241
|
+
return;
|
|
15242
|
+
}
|
|
15243
|
+
map.on('mousemove', this.FILL_LAYER_ID, (e) => {
|
|
15244
|
+
this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
|
|
15245
|
+
});
|
|
15246
|
+
map.on('click', this.FILL_LAYER_ID, (e) => {
|
|
15247
|
+
// Publish
|
|
15248
|
+
this.over.set(e.features && e.features.length > 0 ? e.features[0] : null);
|
|
15249
|
+
if (e.features && e.features.length > 0) {
|
|
15250
|
+
const feature = e.features[0];
|
|
15251
|
+
const coordinates = e.lngLat;
|
|
15252
|
+
if (this.popup) {
|
|
15253
|
+
this.popup.remove();
|
|
15254
|
+
}
|
|
15255
|
+
const tb = new TableBuilder();
|
|
15256
|
+
const crop2017 = this.lookupClass(feature.properties ? feature.properties['CDL2017'] : null);
|
|
15257
|
+
const crop2018 = this.lookupClass(feature.properties ? feature.properties['CDL2018'] : null);
|
|
15258
|
+
const crop2019 = this.lookupClass(feature.properties ? feature.properties['CDL2019'] : null);
|
|
15259
|
+
const crop2020 = this.lookupClass(feature.properties ? feature.properties['CDL2020'] : null);
|
|
15260
|
+
const crop2021 = this.lookupClass(feature.properties ? feature.properties['CDL2021'] : null);
|
|
15261
|
+
const crop2022 = this.lookupClass(feature.properties ? feature.properties['CDL2022'] : null);
|
|
15262
|
+
const crop2023 = this.lookupClass(feature.properties ? feature.properties['CDL2023'] : null);
|
|
15263
|
+
const crop2024 = this.lookupClass(feature.properties ? feature.properties['CDL2024'] : null);
|
|
15264
|
+
tb.addHeader('Year', 'Crop Type');
|
|
15265
|
+
tb.add('2024', crop2024 ?? 'Unknown');
|
|
15266
|
+
tb.add('2023', crop2023 ?? 'Unknown');
|
|
15267
|
+
tb.add('2022', crop2022 ?? 'Unknown');
|
|
15268
|
+
tb.add('2021', crop2021 ?? 'Unknown');
|
|
15269
|
+
tb.add('2020', crop2020 ?? 'Unknown');
|
|
15270
|
+
tb.add('2019', crop2019 ?? 'Unknown');
|
|
15271
|
+
tb.add('2018', crop2018 ?? 'Unknown');
|
|
15272
|
+
tb.add('2017', crop2017 ?? 'Unknown');
|
|
15273
|
+
tb.addHeader('Location', "");
|
|
15274
|
+
tb.add('State FIPS', feature.properties ? feature.properties['STATEFIPS'] : 'Unknown');
|
|
15275
|
+
tb.add('County', feature.properties ? feature.properties['CNTY'] : 'Unknown');
|
|
15276
|
+
tb.add('County FIPS', feature.properties ? feature.properties['CNTYFIPS'] : 'Unknown');
|
|
15277
|
+
tb.add('ASD', feature.properties ? feature.properties['ASD'] : 'Unknown');
|
|
15278
|
+
tb.add('Area (M²)', feature.properties ? feature.properties['Shape_Area'] : 'Unknown');
|
|
15279
|
+
const fieldsHtml = tb.toHtml();
|
|
15280
|
+
this.currentFeatureID = feature?.properties?.['globalid'];
|
|
15281
|
+
this.popup = new Popup({ maxWidth: '400px' })
|
|
15282
|
+
.setLngLat(coordinates)
|
|
15283
|
+
.setHTML(`<strong>Crop Sequence</strong><br/>${fieldsHtml}`)
|
|
15284
|
+
.addTo(map);
|
|
15285
|
+
}
|
|
15286
|
+
});
|
|
15287
|
+
}
|
|
15288
|
+
lookupClass(code) {
|
|
15289
|
+
const found = CroplandLegend.find((item) => {
|
|
15290
|
+
return item.code == code;
|
|
15291
|
+
});
|
|
15292
|
+
if (found) {
|
|
15293
|
+
return found.class;
|
|
15294
|
+
}
|
|
15295
|
+
return undefined;
|
|
15296
|
+
}
|
|
15297
|
+
lookup(code) {
|
|
15298
|
+
const found = CroplandLegend.find((item) => {
|
|
15299
|
+
return item.code == code;
|
|
15300
|
+
});
|
|
15301
|
+
return found;
|
|
15302
|
+
}
|
|
15303
|
+
async onReady(map, svc) {
|
|
15304
|
+
this.map = map;
|
|
15305
|
+
this.create();
|
|
15306
|
+
}
|
|
15307
|
+
reset() { }
|
|
15308
|
+
clear() {
|
|
15309
|
+
if (this.map) {
|
|
15310
|
+
this.map.removeLayer(this.FILL_LAYER_ID);
|
|
15311
|
+
this.map.removeLayer(this.LINE_LAYER_ID);
|
|
15312
|
+
this.map.removeSource(this.SOURCE_ID);
|
|
15313
|
+
}
|
|
15314
|
+
}
|
|
15315
|
+
legends;
|
|
15316
|
+
count = 0;
|
|
15317
|
+
total = 0;
|
|
15318
|
+
map;
|
|
15319
|
+
popup = null;
|
|
15320
|
+
}
|
|
15321
|
+
class CropSequenceSettings {
|
|
15322
|
+
visible = true;
|
|
15323
|
+
fillColor = '#1aac39';
|
|
15324
|
+
fillOpacity = 0.2;
|
|
15325
|
+
borderColor = '#006e16';
|
|
15326
|
+
borderWidth = 1;
|
|
15327
|
+
borderOpacity = 0.5;
|
|
15328
|
+
}
|
|
15329
|
+
|
|
15323
15330
|
class EsriMapper {
|
|
15324
15331
|
jsonUrl = 'https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/styles/root.json';
|
|
15325
15332
|
SOURCE_ID = 'esri';
|
|
@@ -16735,5 +16742,5 @@ class HttpBoundaryLoader {
|
|
|
16735
16742
|
* Generated bundle index. Do not edit.
|
|
16736
16743
|
*/
|
|
16737
16744
|
|
|
16738
|
-
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, VectorTileServerMapper, WatershedMapper, WatershedSettings, discoverLayers, isGeoloader, isMultiPolygon, isNumber2DArray, isNumber3DArray, isPolygon, mapboxLoadImages, mapboxloadImage, pmtilesPixelInfo, sampleTilesForLayers, simpleClone, toMultiPolygon, trySync };
|
|
16745
|
+
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 };
|
|
16739
16746
|
//# sourceMappingURL=foodmarketmaker-mapag.mjs.map
|