Skip to content
Merged
27 changes: 16 additions & 11 deletions packages/cli-vector/schema/pois.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "pois",
"metadata": {
"attributes": [
"leisure",
"building",
"store_item",
"man_made",
Expand All @@ -18,7 +17,6 @@
"barrier",
"historic",
"ref",
"ladder",
"fortification_type",
"power",
"farmyard",
Expand Down Expand Up @@ -565,7 +563,7 @@
"id": "50286",
"name": "50286-nz-historic-site-points-topo-150k",
"source": "s3://linz-lds-cache/50286/",
"tags": { "historic": "yes" },
"tags": { "historic": "site" },
"attributes": { "descriptn": "ref" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
Expand All @@ -580,7 +578,7 @@
"id": "50291",
"name": "50291-nz-ladder-points-topo-150k",
"source": "s3://linz-lds-cache/50291/",
"tags": { "ladder": "yes" },
"tags": { "man_made": "ladder" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
Expand Down Expand Up @@ -688,13 +686,6 @@
"tags": { "historic": "redoubt" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
"id": "50326",
"name": "50326-nz-rifle-range-polygons-topo-150k",
"source": "s3://linz-lds-cache/50326/",
"tags": { "leisure": "shooting_ground" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
"id": "50336",
"name": "50336-nz-satellite-station-points-topo-150k",
Expand Down Expand Up @@ -806,6 +797,20 @@
"source": "s3://linz-lds-cache/50246/",
"tags": { "building": "building" },
"style": { "minZoom": 14, "maxZoom": 15 }
},
{
"id": "50275",
"name": "50275-nz-ford-points-topo-150k",
"source": "s3://linz-lds-cache/50275/",
"tags": { "waterway": "ford" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
"id": "50080",
"name": "50080-nz-chatham-island-ford-points-topo-150k",
"source": "s3://linz-lds-cache/50080/",
"tags": { "waterway": "ford" },
"style": { "minZoom": 12, "maxZoom": 15 }
}
]
}
7 changes: 7 additions & 0 deletions packages/cli-vector/schema/sites.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
"source": "s3://linz-lds-cache/52276/",
"tags": { "kind": "sports_field" },
"style": { "minZoom": 0, "maxZoom": 15 }
},
{
"id": "50326",
"name": "50326-nz-rifle-range-polygons-topo-150k",
"source": "s3://linz-lds-cache/50326/",
"tags": { "kind": "rifle_range" },
"style": { "minZoom": 12, "maxZoom": 15 }
}
]
}
91 changes: 0 additions & 91 deletions packages/cli-vector/schema/streets.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,83 +174,6 @@
{ "style": { "minZoom": 11, "maxZoom": 15 } }
]
},
{
"id": "50237",
"name": "50237-nz-airport-polygons-topo-150k",
"source": "s3://linz-lds-cache/50237/",
"tags": { "kind": "aerodrome" },
"style": { "minZoom": 10, "maxZoom": 15 }
},
{
"id": "50063",
"name": "50063-nz-chatham-island-airport-polygons-topo-150k",
"source": "s3://linz-lds-cache/50063/",
"tags": { "kind": "aerodrome" },
"style": { "minZoom": 10, "maxZoom": 15 }
},
{
"id": "52231",
"name": "52231-cook-islands-airport-polygons-topo-125k-zone4",
"source": "s3://linz-lds-cache/52231/",
"tags": { "kind": "aerodrome" },
"style": { "minZoom": 0, "maxZoom": 15 }
},
{
"id": "52168",
"name": "52168-niue-airport-polygons-topo-150k",
"source": "s3://linz-lds-cache/52168/",
"tags": { "kind": "aerodrome" },
"style": { "minZoom": 0, "maxZoom": 15 }
},
{
"id": "50333",
"name": "50333-nz-runway-polygons-topo-150k",
"source": "s3://linz-lds-cache/50333/",
"tags": { "kind": "runway" },
"style": { "minZoom": 10, "maxZoom": 15 }
},
{
"id": "50914",
"name": "50914-nz-kermadec-is-runway-polygons-topo-125k",
"source": "s3://linz-lds-cache/50914/",
"tags": { "kind": "runway" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
"id": "52302",
"name": "52302-cook-islands-runway-polygons-topo-125k-zone3",
"source": "s3://linz-lds-cache/52302/",
"tags": { "kind": "runway" },
"style": { "minZoom": 13, "maxZoom": 15 }
},
{
"id": "52268",
"name": "52268-cook-islands-runway-polygons-topo-125k-zone4",
"source": "s3://linz-lds-cache/52268/",
"tags": { "kind": "runway" },
"style": { "minZoom": 13, "maxZoom": 15 }
},
{
"id": "52211",
"name": "52211-cook-islands-runway-polygons-topo-150k-zone4",
"source": "s3://linz-lds-cache/52211/",
"tags": { "kind": "runway" },
"style": { "minZoom": 13, "maxZoom": 15 }
},
{
"id": "52190",
"name": "52190-niue-runway-polygons-topo-150k",
"source": "s3://linz-lds-cache/52190/",
"tags": { "kind": "runway" },
"style": { "minZoom": 13, "maxZoom": 15 }
},
{
"id": "50103",
"name": "50103-nz-chatham-island-runway-polygons-topo-150k",
"source": "s3://linz-lds-cache/50103/",
"tags": { "kind": "runway" },
"style": { "minZoom": 10, "maxZoom": 15 }
},
{
"id": "50244",
"name": "50244-nz-bridge-centrelines-topo-150k",
Expand Down Expand Up @@ -279,20 +202,6 @@
"tags": { "kind": "secondary", "bridge": "true" },
"style": { "minZoom": 10, "maxZoom": 15 }
},
{
"id": "50275",
"name": "50275-nz-ford-points-topo-150k",
"source": "s3://linz-lds-cache/50275/",
"tags": { "kind": "secondary", "ford": "true" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
"id": "50080",
"name": "50080-nz-chatham-island-ford-points-topo-150k",
"source": "s3://linz-lds-cache/50080/",
"tags": { "kind": "secondary", "ford": "true" },
"style": { "minZoom": 12, "maxZoom": 15 }
},
{
"id": "50366",
"name": "50366-nz-tunnel-centrelines-topo-150k",
Expand Down
107 changes: 44 additions & 63 deletions packages/cli-vector/src/modify/layers/place_labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@ import { LogType } from '@basemaps/shared';
import { z } from 'zod';

import { VectorGeoFeature } from '../../types/VectorGeoFeature.js';
import {
zPlaceLabelsProperties,
zPlaceLabelsTippecanoe,
zTypePlaceLabelsProperties,
zTypePlaceLabelsTippecanoe,
} from '../parser.js';
import { zPlaceLabelsProperties } from '../parser.js';
import { VectorGeoPlaceLabelsFeature } from '../schema.js';

export const PlaceLabelsFeatures = new Map<string, VectorGeoPlaceLabelsFeature>();

/**
* Processes a 'place_labels' layer feature. Specifically, features of the gazatteer dataset.
* Processes a 'place_labels' layer feature of the gazatteer dataset.
*
* The gazatteer dataset contains multiple features that technically describe the same feature, such that:
* - 1. One feature will contain all of the expected properties.
* - 2. The other features will have 'null' values for all expected properties, except `label` and `zoom_level`.
* - 3. All of the features describing the same feature will have the same `label` value, but different `zoom_level` values.
* - 1. Many features have the same `label` value.
* - a. The 1st feature always contains the properties.
* - b. The 2nd, 3rd, ... features always define the `label`, `zoom_level` and `style` properties. But, all others properties will be `null`.
* - 2. All features with the same `label` value have different `zoom_level` values.
*
* @param feature - the feature to process
* @param options - the layer's options
Expand All @@ -27,34 +23,29 @@ export const PlaceLabelsFeatures = new Map<string, VectorGeoPlaceLabelsFeature>(
*/
export function handleLayerPlaceLabels(feature: VectorGeoFeature, logger: LogType): VectorGeoFeature | null {
logger.trace({}, 'HandlePlaceLabels:Start');
feature = structuredClone(feature);

// read the 'label' and 'zoom_level' properties (required)
const label = feature.properties['label'];
if (typeof label !== 'string') throw new Error('Label property is not a string');
const newFeature = createNewFeature(feature, logger);
const name = newFeature.properties.name;

const zoomLevel = feature.properties['zoom_level'];
if (typeof zoomLevel !== 'number') throw new Error('Zoom level is not a number');

//DATA PROBLEM: We need to store the first feature which have all the propertie values, the duplicate features will only have null values in the properties
const storedFeature = PlaceLabelsFeatures.get(label);
// DATA PROBLEM: Multiple features will have the same `label` value. However, only the first feature will
// contain all of the expected properties. All other features with the same `label` value will have null
// values for the expected properties. So, as we encounter each of the 'other' features, we need to copy
// the expected properties from the first feature to it, before returning it.
const storedFeature = PlaceLabelsFeatures.get(name);
if (storedFeature == null) {
const newFeature = createNewFeature(feature, label, zoomLevel, logger);
if (newFeature == null) return null;

PlaceLabelsFeatures.set(label, newFeature);
PlaceLabelsFeatures.set(name, newFeature);

logger.trace({}, 'HandlePlaceLabels:End');
return newFeature;
}

// update the stored feature's 'minzoom' value
storedFeature.tippecanoe.minzoom = zoomLevel;
storedFeature.tippecanoe.minzoom = newFeature.tippecanoe.minzoom;
// update the stored feature's 'maxzoom' value
storedFeature.tippecanoe.maxzoom = zoomLevel;
storedFeature.tippecanoe.maxzoom = newFeature.tippecanoe.minzoom;

logger.trace({}, 'HandlePlaceLabels:End');
return storedFeature;
return structuredClone(storedFeature);
}

/**
Expand All @@ -66,54 +57,44 @@ export function handleLayerPlaceLabels(feature: VectorGeoFeature, logger: LogTyp
* @param logger - a logger instance
* @returns a VectorGeoPlaceLabelsFeature object
*/
function createNewFeature(
feature: VectorGeoFeature,
label: string,
zoomLevel: number,
logger: LogType,
): VectorGeoPlaceLabelsFeature | null {
let properties: zTypePlaceLabelsProperties;
let tippecanoe: zTypePlaceLabelsTippecanoe;

function createNewFeature(feature: VectorGeoFeature, logger: LogType): VectorGeoPlaceLabelsFeature {
try {
properties = zPlaceLabelsProperties.parse({
label,
const properties = zPlaceLabelsProperties.parse({
label: feature.properties['label'],
zoom_level: feature.properties['zoom_level'],
style: feature.properties['style'],
place: feature.properties['place'],
adminlevel: feature.properties['adminlevel'],
natural: feature.properties['natural'],
place: feature.properties['place'],
water: feature.properties['water'],
});

tippecanoe = zPlaceLabelsTippecanoe.parse({
const tippecanoe = {
layer: 'place_labels',
minzoom: zoomLevel,
maxzoom: zoomLevel,
});
minzoom: properties.zoom_level,
maxzoom: properties.zoom_level,
};

const newFeature = {
type: feature.type,
properties: {
name: properties.label,
kind: convertStyleToKind(properties.style, tippecanoe.minzoom),
natural: properties.natural,
place: properties.place,
water: properties.water,
},
geometry: feature.geometry,
tippecanoe,
};

return newFeature;
} catch (e) {
if (e instanceof z.ZodError) {
logger.trace({ label }, 'Failed to parse expected properties. Discarding feature.');
return null;
} else {
throw new Error('An unexpected error occurred.');
logger.trace({ properties: feature.properties }, 'Failed to parse required properties.');
}
}

const newFeature = {
type: feature.type,
properties: {
name: properties.label,
kind: convertStyleToKind(properties.style, tippecanoe.minzoom),
place: properties.place,
adminlevel: properties.adminlevel,
natural: properties.natural,
water: properties.water,
},
geometry: feature.geometry,
tippecanoe,
};

return newFeature;
throw e;
}
}

/**
Expand Down
11 changes: 3 additions & 8 deletions packages/cli-vector/src/modify/layers/pois.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { LogType } from '@basemaps/shared';
import { Point } from 'geojson';

import { VectorGeoFeature } from '../../types/VectorGeoFeature.js';
import { getCoordinates, polylabel } from '../shared.js';
import { getInaccessibilityPole } from '../shared.js';

/**
* Processes a 'pois' layer feature.
Expand All @@ -27,13 +26,9 @@ export function handleLayerPois(feature: VectorGeoFeature, logger: LogType): Vec

feature.properties['building'] = bldgUse;

// Covert the building polygon to a point for 50246-nz-building-polygons-topo-150k
// Convert the building polygon to a point for 50246-nz-building-polygons-topo-150k
if (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiPolygon') {
const coordinates = getCoordinates(feature.geometry, logger);
const inaccessibilityPole = polylabel(coordinates);

const point: Point = { type: 'Point', coordinates: inaccessibilityPole };
feature.geometry = point;
feature.geometry = getInaccessibilityPole(feature.geometry, logger);
}
}

Expand Down
12 changes: 2 additions & 10 deletions packages/cli-vector/src/modify/layers/public_transport.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { LogType } from '@basemaps/shared';
import { Point } from 'geojson';

import { VectorCreationOptions } from '../../stac.js';
import { VectorGeoFeature } from '../../types/VectorGeoFeature.js';
import { getCoordinates, polylabel } from '../shared.js';
import { getInaccessibilityPole } from '../shared.js';

/**
* Processes a 'public_transport' layer feature.
Expand Down Expand Up @@ -42,14 +41,7 @@ function handleKindAerodrome(feature: VectorGeoFeature, logger: LogType): Vector
logger.trace({}, 'HandleKindAerodrome:Start');
feature = structuredClone(feature);

const coordinates = getCoordinates(feature.geometry, logger);
// REVIEW: the following resource suggests using a precision value of 0.000001 for geo-coords:
// https://github.com/mapbox/polylabel?tab=readme-ov-file#javascript-usage
// currently, we use the default value of 1.0
const inaccessibilityPole = polylabel(coordinates);

const point: Point = { type: 'Point', coordinates: inaccessibilityPole };
feature.geometry = point;
feature.geometry = getInaccessibilityPole(feature.geometry, logger);

logger.trace({}, 'HandleKindAerodrome:End');
return feature;
Expand Down
Loading