@foodmarketmaker/mapag 0.0.14 → 0.0.16

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.
@@ -181,7 +181,56 @@ async function sampleTilesForLayers(pmtiles) {
181
181
  return [];
182
182
  }
183
183
  }
184
+ async function pmtilesPixelInfo(url, map, e) {
185
+ const pmtiles = new PMTiles(url.replace('pmtiles://', ''));
186
+ const lngLat = e.lngLat; // {lng, lat}
187
+ // Convert lat/lon to tile coordinates at a chosen zoom
188
+ const zoom = 10; // pick a zoom level for sampling
189
+ const x = Math.floor(((lngLat.lng + 180) / 360) * Math.pow(2, zoom));
190
+ const y = Math.floor(((1 -
191
+ Math.log(Math.tan((lngLat.lat * Math.PI) / 180) +
192
+ 1 / Math.cos((lngLat.lat * Math.PI) / 180)) /
193
+ Math.PI) /
194
+ 2) *
195
+ Math.pow(2, zoom));
196
+ // 5. Fetch the tile from PMTiles
197
+ const tile = await pmtiles.getZxy(zoom, x, y);
198
+ if (!tile) {
199
+ console.log("No tile found at this location");
200
+ return undefined;
201
+ }
202
+ // Decode the raster tile (PNG or WebP)
203
+ const blob = new Blob([tile.data]);
204
+ const bitmap = await createImageBitmap(blob);
205
+ // Draw to canvas to read pixel
206
+ const canvas = document.createElement("canvas");
207
+ canvas.width = bitmap.width;
208
+ canvas.height = bitmap.height;
209
+ const ctx = canvas.getContext("2d");
210
+ if (!ctx) {
211
+ console.error("Failed to get canvas context");
212
+ return undefined;
213
+ }
214
+ ctx.drawImage(bitmap, 0, 0);
215
+ // Convert lat/lon to pixel coordinates inside the tile
216
+ const px = Math.floor(((lngLat.lng + 180) / 360) * (256 * Math.pow(2, zoom))) % 256;
217
+ const py = Math.floor(((1 -
218
+ Math.log(Math.tan((lngLat.lat * Math.PI) / 180) +
219
+ 1 / Math.cos((lngLat.lat * Math.PI) / 180)) /
220
+ Math.PI) /
221
+ 2) *
222
+ (256 * Math.pow(2, zoom))) % 256;
223
+ const pixel = ctx.getImageData(px, py, 1, 1).data;
224
+ console.log(`Pixel RGBA at ${lngLat.lng},${lngLat.lat}:`, pixel);
225
+ // const r = pixel[0];
226
+ // const g = pixel[1];
227
+ // const b = pixel[2];
228
+ // const a = pixel[3];
229
+ return pixel;
230
+ }
184
231
 
232
+ const DEFAULT_GLYPHS = "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf";
233
+ // export const DEFAULT_GLYPHS = "'https://geoserveis.icgc.cat/contextmaps/glyphs/{fontstack}/{range}.pbf';"
185
234
  class Styles {
186
235
  style = signal(MapStyles["streetmap"], ...(ngDevMode ? [{ debugName: "style" }] : []));
187
236
  map;
@@ -252,7 +301,13 @@ class Styles {
252
301
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
253
302
  }
254
303
  const styleSpec = await response.json();
255
- styleSpec.glyphs = 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf';
304
+ console.debug("Glyphs property:", styleSpec.glyphs);
305
+ if (!styleSpec.glyphs) {
306
+ styleSpec.glyphs = DEFAULT_GLYPHS;
307
+ }
308
+ if (styleData.postFetch) {
309
+ styleData.postFetch(styleSpec);
310
+ }
256
311
  return styleSpec;
257
312
  }
258
313
  async fetchAndCacheStyle(styleData) {
@@ -271,9 +326,13 @@ class Styles {
271
326
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
272
327
  }
273
328
  const styleSpec = await response.json();
329
+ if (styleData.postFetch) {
330
+ styleData.postFetch(styleSpec);
331
+ }
274
332
  // Add Glyphs
333
+ console.debug("Glyphs property:", styleSpec.glyphs);
275
334
  if (!styleSpec.glyphs) {
276
- styleSpec.glyphs = 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf';
335
+ styleSpec.glyphs = DEFAULT_GLYPHS;
277
336
  }
278
337
  // Extract source and layer IDs
279
338
  const sourceIds = Object.keys(styleSpec.sources || {});
@@ -450,6 +509,25 @@ const MapStyles = {
450
509
  url: "https://geoserveis.icgc.cat/contextmaps/icgc_orto_hibrida.json",
451
510
  image: "assets/mapag/src/assets/map_icgc_ortho_hybrid.png",
452
511
  },
512
+ // "natgeo" : {
513
+ // name: "National Geographic",
514
+ // code: "natgeo",
515
+ // // url: "https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/natgeo.json",
516
+ // // url: "https://www.arcgis.com/sharing/rest/content/items/cdd1ca79ffc74237bd6f76e5d9803e2e/resources/styles/root.json",
517
+ // url :"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/styles/root.json",
518
+ // image: "assets/mapag/src/assets/map_natgeo.png",
519
+ // postFetch: (styleJson: StyleSpecification ) => {
520
+ // styleJson.sprite = "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/sprites/sprite"
521
+ // styleJson.sources["esri"] = {
522
+ // type: "vector",
523
+ // tiles: [
524
+ // "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/tile/{z}/{y}/{x}.pbf"
525
+ // ],
526
+ // minzoom: 0,
527
+ // maxzoom: 23
528
+ // }
529
+ // }
530
+ // }
453
531
  };
454
532
 
455
533
  class BasemapSelect {
@@ -14075,6 +14153,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
14075
14153
  // Set up PMTiles protocol for MapLibre
14076
14154
  const protocol = new Protocol();
14077
14155
  maplibregl.addProtocol('pmtiles', protocol.tile);
14156
+ // maplibregl.addProtocol('pmtiles', protocol.add);
14078
14157
  class MapComponent {
14079
14158
  styles = new Styles();
14080
14159
  zone = inject(NgZone);
@@ -14585,6 +14664,109 @@ class CensusTractMapper {
14585
14664
  };
14586
14665
  }
14587
14666
 
14667
+ class EsriMapper {
14668
+ jsonUrl = 'https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/styles/root.json';
14669
+ SOURCE_ID = 'esri';
14670
+ map = undefined;
14671
+ legends = undefined;
14672
+ count = 0;
14673
+ total = 0;
14674
+ current = [];
14675
+ settings = signal(new EsriSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
14676
+ constructor(settings) {
14677
+ if (settings) {
14678
+ this.settings.set({
14679
+ ...this.settings(),
14680
+ ...settings
14681
+ });
14682
+ }
14683
+ else {
14684
+ this.makeSettings();
14685
+ }
14686
+ const _ = effect(() => {
14687
+ const settings = this.settings();
14688
+ this._update(settings);
14689
+ }, ...(ngDevMode ? [{ debugName: "_" }] : []));
14690
+ }
14691
+ async makeSettings() {
14692
+ const settings = new EsriSettings();
14693
+ const data = await fetch(this.jsonUrl)
14694
+ .then(response => response.json());
14695
+ const accepted = [];
14696
+ const rawLawers = data.layers;
14697
+ for (const layer of rawLawers) {
14698
+ const l = layer;
14699
+ accepted.push(l);
14700
+ }
14701
+ settings.options = accepted;
14702
+ settings.layers = new Map();
14703
+ this.settings.set(settings);
14704
+ return settings;
14705
+ }
14706
+ update(settings) {
14707
+ this.settings.set({ ...this.settings(), ...settings });
14708
+ }
14709
+ _update(settings) {
14710
+ this.clear();
14711
+ for (const layerSpec of settings.layers.values()) {
14712
+ if (!this.map) {
14713
+ return;
14714
+ }
14715
+ const map = this.map;
14716
+ const layerId = layerSpec.id;
14717
+ if (map.getLayer(layerId)) {
14718
+ continue; // Layer already exists
14719
+ }
14720
+ try {
14721
+ map.addLayer(layerSpec);
14722
+ this.current.push(layerId);
14723
+ }
14724
+ catch (error) {
14725
+ console.error(`Failed to add layer ${layerId}:`, error);
14726
+ }
14727
+ }
14728
+ }
14729
+ onReady(map, svc) {
14730
+ this.map = map;
14731
+ map.addSource("esri", {
14732
+ type: "vector",
14733
+ tiles: [
14734
+ "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/tile/{z}/{y}/{x}.pbf"
14735
+ ],
14736
+ minzoom: 0,
14737
+ maxzoom: 23
14738
+ });
14739
+ // map.addLayer({
14740
+ // id: "urban-area",
14741
+ // type: "fill",
14742
+ // source: "esri",
14743
+ // "source-layer": "Urban area", // must match the actual layer name in the vector tiles
14744
+ // minzoom: 5,
14745
+ // maxzoom: 12,
14746
+ // paint: {
14747
+ // "fill-color": "#8b1650",
14748
+ // "fill-opacity": 0.8
14749
+ // }
14750
+ // });
14751
+ // Additional setup if needed
14752
+ }
14753
+ clear() {
14754
+ for (const layerId of this.current) {
14755
+ if (this.map?.getLayer(layerId)) {
14756
+ this.map.removeLayer(layerId);
14757
+ }
14758
+ }
14759
+ this.current = [];
14760
+ }
14761
+ reset() {
14762
+ this.clear();
14763
+ }
14764
+ }
14765
+ class EsriSettings {
14766
+ options = [];
14767
+ layers = new Map();
14768
+ }
14769
+
14588
14770
  class LayerSettings {
14589
14771
  visible = true;
14590
14772
  }
@@ -14809,6 +14991,134 @@ class HardinessSettings extends PolygonLayerSettings {
14809
14991
  borderOpacity = 0;
14810
14992
  }
14811
14993
 
14994
+ class NAASMapper {
14995
+ LAYER_ID = 'naas-layer';
14996
+ SOURCE_ID = 'naas-source';
14997
+ settings = signal(new NAASSettings(), ...(ngDevMode ? [{ debugName: "settings" }] : []));
14998
+ current = null;
14999
+ currentFeatureID = undefined;
15000
+ over = signal(null, ...(ngDevMode ? [{ debugName: "over" }] : []));
15001
+ map = undefined;
15002
+ legends;
15003
+ count = 0;
15004
+ total = 0;
15005
+ constructor(settings) {
15006
+ if (settings) {
15007
+ this.settings.set({
15008
+ ...this.settings(),
15009
+ ...settings
15010
+ });
15011
+ }
15012
+ const _ = effect(() => {
15013
+ const settings = this.settings();
15014
+ this._update(settings);
15015
+ }, ...(ngDevMode ? [{ debugName: "_" }] : []));
15016
+ }
15017
+ update(settings) {
15018
+ this.settings.set({ ...this.settings(), ...settings });
15019
+ }
15020
+ _update(settings) {
15021
+ if (!this.map) {
15022
+ return;
15023
+ }
15024
+ const map = this.map;
15025
+ if (settings.visible) {
15026
+ map.setLayoutProperty(this.LAYER_ID, 'visibility', 'visible');
15027
+ }
15028
+ else {
15029
+ map.setLayoutProperty(this.LAYER_ID, 'visibility', 'none');
15030
+ }
15031
+ }
15032
+ create() {
15033
+ if (!this.map) {
15034
+ return;
15035
+ }
15036
+ const map = this.map;
15037
+ AddSource(map, this.SOURCE_ID, {
15038
+ type: 'vector',
15039
+ url: 'mapbox://examples.8fgz4egr' // Example vector tile source
15040
+ });
15041
+ const addedFill = AddLayer(map, {
15042
+ id: this.LAYER_ID,
15043
+ source: this.SOURCE_ID,
15044
+ 'source-layer': 'naas-data', // Example source layer
15045
+ type: 'fill',
15046
+ paint: {
15047
+ 'fill-color': '#888888',
15048
+ 'fill-opacity': 0.5
15049
+ }
15050
+ }, StandardLayersMapper.POLYGONS_BACKGROUND);
15051
+ this._update(this.settings());
15052
+ if (!addedFill) {
15053
+ console.error('Failed to add NAAS layer');
15054
+ }
15055
+ }
15056
+ onReady(map, svc) {
15057
+ }
15058
+ reset() {
15059
+ }
15060
+ clear() {
15061
+ }
15062
+ }
15063
+ class NAASSettings {
15064
+ url = '';
15065
+ visible = true;
15066
+ fillColor = '#0000ff';
15067
+ fillOpacity = 0.1;
15068
+ borderColor = '#01018b';
15069
+ borderWidth = 1;
15070
+ borderOpacity = 1.0;
15071
+ labelsVisible = true;
15072
+ labelsSize = 10;
15073
+ labelsColor = '#000000';
15074
+ labelsHaloColor = '#ffffff';
15075
+ labelsHaloWidth = 1;
15076
+ labelsOpacity = 1.0;
15077
+ labelOverlap = false;
15078
+ autoSelectLayer = false;
15079
+ }
15080
+
15081
+ class SimpleMapper {
15082
+ reset() {
15083
+ if (this.map) {
15084
+ // Remove existing layers and sources
15085
+ if (this.map.getLayer('esri-natgeo-layer')) {
15086
+ this.map.removeLayer('esri-natgeo-layer');
15087
+ }
15088
+ if (this.map.getSource('esri-natgeo')) {
15089
+ this.map.removeSource('esri-natgeo');
15090
+ }
15091
+ this.count = 0;
15092
+ this.total = 0;
15093
+ }
15094
+ }
15095
+ clear() {
15096
+ this.reset();
15097
+ }
15098
+ legends = undefined;
15099
+ count = 0;
15100
+ total = 0;
15101
+ // Implementation of a simple mapper
15102
+ map = undefined;
15103
+ onReady(map, svc) {
15104
+ this.map = map;
15105
+ map.addSource('esri-natgeo', {
15106
+ type: 'raster',
15107
+ tiles: [
15108
+ // 'https://services.arcgisonline.com/ArcGIS/rest/services/NatGeoStyleBase/MapServer/tile/{z}/{y}/{x}',
15109
+ 'https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/NatGeoStyleBase/MapServer/tile/{z}/{y}/{x}',
15110
+ ],
15111
+ tileSize: 256,
15112
+ });
15113
+ map.addLayer({
15114
+ id: 'esri-natgeo-layer',
15115
+ type: 'raster',
15116
+ source: 'esri-natgeo',
15117
+ });
15118
+ // Additional setup if needed
15119
+ }
15120
+ }
15121
+
14812
15122
  class VectorTileServerMapper {
14813
15123
  src;
14814
15124
  legends;
@@ -15041,6 +15351,7 @@ class WatershedMapper {
15041
15351
  type: 'symbol',
15042
15352
  layout: {
15043
15353
  'text-field': ['get', 'name'],
15354
+ 'text-font': ['Open Sans Regular'],
15044
15355
  'text-size': this.settings().labelsSize,
15045
15356
  'text-allow-overlap': this.settings().labelOverlap,
15046
15357
  },
@@ -15239,6 +15550,8 @@ class HttpBoundaryLoader {
15239
15550
  /*
15240
15551
  * Public API Surface of mapag
15241
15552
  */
15553
+ // export * from './lib/mappers/cropland-data-layer';
15554
+ // export * from './lib/models/census-blocks';
15242
15555
  // export * from './lib/models/census-zipcodes';
15243
15556
  // export * from './lib/models/census-counties';
15244
15557
  // export * from './lib/models/census-states';
@@ -15250,5 +15563,5 @@ class HttpBoundaryLoader {
15250
15563
  * Generated bundle index. Do not edit.
15251
15564
  */
15252
15565
 
15253
- 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 };
15566
+ export { AddLayer, AddSource, AreaMapperMapper, BackgroundMaskMapper, BaseMapLight, BasemapSelect, BasemapSelectMenu, CensusTractMapper, DEFAULT_GLYPHS, DrawingMapper, EsriMapper, EsriSettings, HardinessMapper, HardinessSettings, HttpBoundaryLoader, MapAreaSelectComponent, MapComponent, MapSelectionService, MapService, MapStyles, MapboxMapperGroup, NAASMapper, NAASSettings, NoOpMapper, RemoveLayer, RemoveSource, SaveMap, SelectMode, SimpleMapper, StandardLayersMapper, Styles, VectorTileServerMapper, WatershedMapper, WatershedSettings, discoverLayers, isGeoloader, isMultiPolygon, isNumber2DArray, isNumber3DArray, isPolygon, mapboxLoadImages, mapboxloadImage, pmtilesPixelInfo, sampleTilesForLayers, simpleClone, toMultiPolygon, trySync };
15254
15567
  //# sourceMappingURL=foodmarketmaker-mapag.mjs.map