osmfeatures 0.1.0
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/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/geojson-feature.d.ts +25 -0
- package/dist/geojson-feature.js +108 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.js +497 -0
- package/dist/preset/buildings-min-area.d.ts +3 -0
- package/dist/preset/buildings-min-area.js +30 -0
- package/dist/preset/catalog.d.ts +13 -0
- package/dist/preset/catalog.js +127 -0
- package/dist/preset/index.d.ts +30 -0
- package/dist/preset/index.js +30 -0
- package/dist/preset/public-transport-zoom.d.ts +4 -0
- package/dist/preset/public-transport-zoom.js +39 -0
- package/dist/preset/resolve.d.ts +35 -0
- package/dist/preset/resolve.js +133 -0
- package/dist/preset/roads-paths-zoom.d.ts +4 -0
- package/dist/preset/roads-paths-zoom.js +37 -0
- package/dist/preset/waterways-zoom.d.ts +4 -0
- package/dist/preset/waterways-zoom.js +22 -0
- package/package.json +54 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in OSM Features layer presets + zoom detail policies.
|
|
3
|
+
*
|
|
4
|
+
* Use nothing from here if you want raw tag queries only.
|
|
5
|
+
*
|
|
6
|
+
* Catalog (full detail; no zoom floors; no bbox)
|
|
7
|
+
* OSM_FEATURES_LAYER_PRESETS / OSM_FEATURES_LAYER_PRESET_ORDER
|
|
8
|
+
* getPreset(id)
|
|
9
|
+
*
|
|
10
|
+
* Resolve
|
|
11
|
+
* resolvePresetFromQuery({ preset, bbox, zoom? })
|
|
12
|
+
* resolveCustomLayerFromQuery({ tags?/or_tags?/not_tags?, bbox })
|
|
13
|
+
* resolveLayerFromQuery(...) — preset if set, else custom tags
|
|
14
|
+
* bbox required — zoom optional (omit for full catalog detail)
|
|
15
|
+
*
|
|
16
|
+
* Policies (callable alone; omit zoom = no-op / full detail)
|
|
17
|
+
* applyRoadsPathsZoomPolicy(preset, zoom?)
|
|
18
|
+
* applyWaterwaysZoomPolicy(preset, zoom?)
|
|
19
|
+
* applyPublicTransportZoomPolicy(preset, zoom?)
|
|
20
|
+
* resolveBuildingsMinAreaM2(presetId, bbox, zoom?) → optional min_area_m2
|
|
21
|
+
* ROADS_PATHS_FULL_DETAIL_ZOOM — z at/above this keeps all highway tags
|
|
22
|
+
* WATERWAYS_FULL_DETAIL_ZOOM — z at/above this keeps all waterway classes
|
|
23
|
+
* PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM — z at/above this keeps all transport tags
|
|
24
|
+
*/
|
|
25
|
+
export { OSM_FEATURES_LAYER_PRESETS, OSM_FEATURES_LAYER_PRESET_ORDER, type OSMFeaturesLayerPreset, type OSMFeaturesPresetId, } from './catalog.js';
|
|
26
|
+
export { applyRoadsPathsZoomPolicy, ROADS_PATHS_FULL_DETAIL_ZOOM, } from './roads-paths-zoom.js';
|
|
27
|
+
export { applyWaterwaysZoomPolicy, WATERWAYS_FULL_DETAIL_ZOOM, } from './waterways-zoom.js';
|
|
28
|
+
export { applyPublicTransportZoomPolicy, PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM, } from './public-transport-zoom.js';
|
|
29
|
+
export { resolveBuildingsMinAreaM2 } from './buildings-min-area.js';
|
|
30
|
+
export { getPreset, resolvePresetFromQuery, resolveCustomLayerFromQuery, resolveLayerFromQuery, type PresetQuery, type ResolvedCustomLayer, type ResolvedDemoLayer, type ResolvedPresetLayer, } from './resolve.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in OSM Features layer presets + zoom detail policies.
|
|
3
|
+
*
|
|
4
|
+
* Use nothing from here if you want raw tag queries only.
|
|
5
|
+
*
|
|
6
|
+
* Catalog (full detail; no zoom floors; no bbox)
|
|
7
|
+
* OSM_FEATURES_LAYER_PRESETS / OSM_FEATURES_LAYER_PRESET_ORDER
|
|
8
|
+
* getPreset(id)
|
|
9
|
+
*
|
|
10
|
+
* Resolve
|
|
11
|
+
* resolvePresetFromQuery({ preset, bbox, zoom? })
|
|
12
|
+
* resolveCustomLayerFromQuery({ tags?/or_tags?/not_tags?, bbox })
|
|
13
|
+
* resolveLayerFromQuery(...) — preset if set, else custom tags
|
|
14
|
+
* bbox required — zoom optional (omit for full catalog detail)
|
|
15
|
+
*
|
|
16
|
+
* Policies (callable alone; omit zoom = no-op / full detail)
|
|
17
|
+
* applyRoadsPathsZoomPolicy(preset, zoom?)
|
|
18
|
+
* applyWaterwaysZoomPolicy(preset, zoom?)
|
|
19
|
+
* applyPublicTransportZoomPolicy(preset, zoom?)
|
|
20
|
+
* resolveBuildingsMinAreaM2(presetId, bbox, zoom?) → optional min_area_m2
|
|
21
|
+
* ROADS_PATHS_FULL_DETAIL_ZOOM — z at/above this keeps all highway tags
|
|
22
|
+
* WATERWAYS_FULL_DETAIL_ZOOM — z at/above this keeps all waterway classes
|
|
23
|
+
* PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM — z at/above this keeps all transport tags
|
|
24
|
+
*/
|
|
25
|
+
export { OSM_FEATURES_LAYER_PRESETS, OSM_FEATURES_LAYER_PRESET_ORDER, } from './catalog.js';
|
|
26
|
+
export { applyRoadsPathsZoomPolicy, ROADS_PATHS_FULL_DETAIL_ZOOM, } from './roads-paths-zoom.js';
|
|
27
|
+
export { applyWaterwaysZoomPolicy, WATERWAYS_FULL_DETAIL_ZOOM, } from './waterways-zoom.js';
|
|
28
|
+
export { applyPublicTransportZoomPolicy, PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM, } from './public-transport-zoom.js';
|
|
29
|
+
export { resolveBuildingsMinAreaM2 } from './buildings-min-area.js';
|
|
30
|
+
export { getPreset, resolvePresetFromQuery, resolveCustomLayerFromQuery, resolveLayerFromQuery, } from './resolve.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { OSMFeaturesLayerPreset } from './catalog.js';
|
|
2
|
+
export declare const PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM = 13.8;
|
|
3
|
+
/** Opt-in: drop stop/platform clutter on public_transport as map zooms out. Omit zoom for full detail. */
|
|
4
|
+
export declare function applyPublicTransportZoomPolicy<T extends OSMFeaturesLayerPreset>(preset: T, zoom?: number): T;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// public_transport detail floors (omit zoom = full detail, same as z >= FULL):
|
|
2
|
+
// z >= 14 — full catalog (stops, platforms, bus routes, …)
|
|
3
|
+
// 12 <= z < 14 — rail network + urban rail + major stops (no bus-stop clutter)
|
|
4
|
+
// z < 12 — mainline rail + stations only
|
|
5
|
+
// Roughly matches OpenMapTiles railway class floors (rail early; subway/tram/stops later).
|
|
6
|
+
export const PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM = 13.8;
|
|
7
|
+
const PUBLIC_TRANSPORT_MAJOR_ZOOM = 11.8;
|
|
8
|
+
const PUBLIC_TRANSPORT_MAJOR_OR_TAGS = [
|
|
9
|
+
'railway=rail',
|
|
10
|
+
'railway=station',
|
|
11
|
+
'route=train',
|
|
12
|
+
];
|
|
13
|
+
const PUBLIC_TRANSPORT_MID_OR_TAGS = [
|
|
14
|
+
...PUBLIC_TRANSPORT_MAJOR_OR_TAGS,
|
|
15
|
+
'railway=narrow_gauge',
|
|
16
|
+
'railway=light_rail',
|
|
17
|
+
'railway=subway',
|
|
18
|
+
'railway=tram',
|
|
19
|
+
'railway=halt',
|
|
20
|
+
'amenity=bus_station',
|
|
21
|
+
'route=subway',
|
|
22
|
+
'route=light_rail',
|
|
23
|
+
'route=tram',
|
|
24
|
+
];
|
|
25
|
+
/** Opt-in: drop stop/platform clutter on public_transport as map zooms out. Omit zoom for full detail. */
|
|
26
|
+
export function applyPublicTransportZoomPolicy(preset, zoom) {
|
|
27
|
+
if (preset.id !== 'public_transport' || zoom == null || zoom >= PUBLIC_TRANSPORT_FULL_DETAIL_ZOOM) {
|
|
28
|
+
return preset;
|
|
29
|
+
}
|
|
30
|
+
const orTags = zoom < PUBLIC_TRANSPORT_MAJOR_ZOOM
|
|
31
|
+
? PUBLIC_TRANSPORT_MAJOR_OR_TAGS
|
|
32
|
+
: PUBLIC_TRANSPORT_MID_OR_TAGS;
|
|
33
|
+
return {
|
|
34
|
+
...preset,
|
|
35
|
+
tags: undefined,
|
|
36
|
+
orTags: [...orTags],
|
|
37
|
+
notTags: preset.notTags,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type OSMFeaturesLayerPreset } from './catalog.js';
|
|
2
|
+
type QueryValue = unknown;
|
|
3
|
+
export type PresetQuery = Record<string, QueryValue>;
|
|
4
|
+
/** Catalog preset + required bbox for an upstream query. */
|
|
5
|
+
export type ResolvedPresetLayer = OSMFeaturesLayerPreset & {
|
|
6
|
+
bbox: string;
|
|
7
|
+
};
|
|
8
|
+
/** Tag filters + bbox for a custom (non-preset) upstream query. */
|
|
9
|
+
export type ResolvedCustomLayer = {
|
|
10
|
+
bbox: string;
|
|
11
|
+
tags?: string[];
|
|
12
|
+
orTags?: string[];
|
|
13
|
+
notTags?: string[];
|
|
14
|
+
type?: string;
|
|
15
|
+
shape?: 'line' | 'polygon' | 'all';
|
|
16
|
+
};
|
|
17
|
+
export type ResolvedDemoLayer = ResolvedPresetLayer | ResolvedCustomLayer;
|
|
18
|
+
/** Catalog lookup only. No zoom policies. */
|
|
19
|
+
export declare function getPreset(id: string): OSMFeaturesLayerPreset | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Opt-in helper: resolve `preset` + required `bbox` (+ optional `zoom`) from a query map.
|
|
22
|
+
* Applies known zoom tag policies (roads_paths, waterways, public_transport). Does not set min_area_m2.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolvePresetFromQuery(query: PresetQuery): ResolvedPresetLayer;
|
|
25
|
+
/**
|
|
26
|
+
* Custom layer: `tags` / `or_tags` / `not_tags` + required `bbox`.
|
|
27
|
+
* Optional `type` / `shape`. Needs at least one positive filter (`tags` or `or_tags`).
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveCustomLayerFromQuery(query: PresetQuery): ResolvedCustomLayer;
|
|
30
|
+
/**
|
|
31
|
+
* Demo / relay helper: `preset`+bbox, or custom `tags`/`or_tags`/`not_tags`+bbox.
|
|
32
|
+
* Preset wins when both are present.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveLayerFromQuery(query: PresetQuery): ResolvedDemoLayer;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import createHttpError from 'http-errors';
|
|
2
|
+
import { OSM_FEATURES_LAYER_PRESETS, } from './catalog.js';
|
|
3
|
+
import { applyPublicTransportZoomPolicy } from './public-transport-zoom.js';
|
|
4
|
+
import { applyRoadsPathsZoomPolicy } from './roads-paths-zoom.js';
|
|
5
|
+
import { applyWaterwaysZoomPolicy } from './waterways-zoom.js';
|
|
6
|
+
function appError(status, code, detail) {
|
|
7
|
+
const err = createHttpError(status, detail);
|
|
8
|
+
err.code = code;
|
|
9
|
+
return err;
|
|
10
|
+
}
|
|
11
|
+
function optionalString(query, key) {
|
|
12
|
+
const raw = query[key];
|
|
13
|
+
if (raw == null || raw === '') {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
if (Array.isArray(raw)) {
|
|
17
|
+
const first = raw[0];
|
|
18
|
+
if (first == null || first === '') {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return String(first);
|
|
22
|
+
}
|
|
23
|
+
return String(raw);
|
|
24
|
+
}
|
|
25
|
+
function optionalNumber(query, key) {
|
|
26
|
+
const raw = query[key];
|
|
27
|
+
if (raw == null || raw === '') {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
if (typeof raw === 'number') {
|
|
31
|
+
return Number.isFinite(raw) ? raw : undefined;
|
|
32
|
+
}
|
|
33
|
+
const text = optionalString(query, key);
|
|
34
|
+
if (text == null) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
const parsed = Number.parseFloat(text);
|
|
38
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
39
|
+
}
|
|
40
|
+
/** Repeatable query params (`tags=a&tags=b`) or one value. */
|
|
41
|
+
function stringList(query, key) {
|
|
42
|
+
const raw = query[key];
|
|
43
|
+
if (raw == null || raw === '') {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
const values = Array.isArray(raw) ? raw : [raw];
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const value of values) {
|
|
49
|
+
if (value == null || value === '') {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const trimmed = String(value).trim();
|
|
53
|
+
if (trimmed) {
|
|
54
|
+
out.push(trimmed);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
function requireBbox(query) {
|
|
60
|
+
const bbox = optionalString(query, 'bbox');
|
|
61
|
+
if (bbox == null) {
|
|
62
|
+
throw appError(400, 'invalid_bbox', 'bbox is required.');
|
|
63
|
+
}
|
|
64
|
+
return bbox;
|
|
65
|
+
}
|
|
66
|
+
/** Catalog lookup only. No zoom policies. */
|
|
67
|
+
export function getPreset(id) {
|
|
68
|
+
return OSM_FEATURES_LAYER_PRESETS[id];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Opt-in helper: resolve `preset` + required `bbox` (+ optional `zoom`) from a query map.
|
|
72
|
+
* Applies known zoom tag policies (roads_paths, waterways, public_transport). Does not set min_area_m2.
|
|
73
|
+
*/
|
|
74
|
+
export function resolvePresetFromQuery(query) {
|
|
75
|
+
const rawPreset = query['preset'];
|
|
76
|
+
if (typeof rawPreset !== 'string' || rawPreset.trim() === '') {
|
|
77
|
+
throw appError(400, 'invalid_preset', 'preset is required.');
|
|
78
|
+
}
|
|
79
|
+
const presetId = rawPreset.trim();
|
|
80
|
+
const preset = getPreset(presetId);
|
|
81
|
+
if (!preset) {
|
|
82
|
+
throw appError(400, 'invalid_preset', `Unknown preset: ${presetId}`);
|
|
83
|
+
}
|
|
84
|
+
const withBbox = { ...preset, bbox: requireBbox(query) };
|
|
85
|
+
const zoom = optionalNumber(query, 'zoom');
|
|
86
|
+
// Zoom optional: omit / invalid → catalog tags as-is (full detail).
|
|
87
|
+
if (zoom == null) {
|
|
88
|
+
return withBbox;
|
|
89
|
+
}
|
|
90
|
+
return applyPublicTransportZoomPolicy(applyWaterwaysZoomPolicy(applyRoadsPathsZoomPolicy(withBbox, zoom), zoom), zoom);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Custom layer: `tags` / `or_tags` / `not_tags` + required `bbox`.
|
|
94
|
+
* Optional `type` / `shape`. Needs at least one positive filter (`tags` or `or_tags`).
|
|
95
|
+
*/
|
|
96
|
+
export function resolveCustomLayerFromQuery(query) {
|
|
97
|
+
const tags = stringList(query, 'tags');
|
|
98
|
+
const orTags = stringList(query, 'or_tags');
|
|
99
|
+
const notTags = stringList(query, 'not_tags');
|
|
100
|
+
if (tags.length === 0 && orTags.length === 0) {
|
|
101
|
+
throw appError(400, 'invalid_tags', 'tags or or_tags is required for a custom layer.');
|
|
102
|
+
}
|
|
103
|
+
const layer = { bbox: requireBbox(query) };
|
|
104
|
+
if (tags.length > 0) {
|
|
105
|
+
layer.tags = tags;
|
|
106
|
+
}
|
|
107
|
+
if (orTags.length > 0) {
|
|
108
|
+
layer.orTags = orTags;
|
|
109
|
+
}
|
|
110
|
+
if (notTags.length > 0) {
|
|
111
|
+
layer.notTags = notTags;
|
|
112
|
+
}
|
|
113
|
+
const type = optionalString(query, 'type');
|
|
114
|
+
if (type) {
|
|
115
|
+
layer.type = type;
|
|
116
|
+
}
|
|
117
|
+
const shape = optionalString(query, 'shape');
|
|
118
|
+
if (shape === 'line' || shape === 'polygon' || shape === 'all') {
|
|
119
|
+
layer.shape = shape;
|
|
120
|
+
}
|
|
121
|
+
return layer;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Demo / relay helper: `preset`+bbox, or custom `tags`/`or_tags`/`not_tags`+bbox.
|
|
125
|
+
* Preset wins when both are present.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveLayerFromQuery(query) {
|
|
128
|
+
const rawPreset = query['preset'];
|
|
129
|
+
if (typeof rawPreset === 'string' && rawPreset.trim() !== '') {
|
|
130
|
+
return resolvePresetFromQuery(query);
|
|
131
|
+
}
|
|
132
|
+
return resolveCustomLayerFromQuery(query);
|
|
133
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { OSMFeaturesLayerPreset } from './catalog.js';
|
|
2
|
+
export declare const ROADS_PATHS_FULL_DETAIL_ZOOM = 13.5;
|
|
3
|
+
/** Opt-in: drop path / minor-road clutter on roads_paths as map zooms out. Omit zoom for full detail. */
|
|
4
|
+
export declare function applyRoadsPathsZoomPolicy<T extends OSMFeaturesLayerPreset>(preset: T, zoom?: number): T;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// roads_paths detail floors (omit zoom = full detail, same as z >= FULL):
|
|
2
|
+
// z >= 13 — full highway set
|
|
3
|
+
// 11 <= z < 13 — arteries + neighbourhood roads (whitelist; no service/track/paths)
|
|
4
|
+
// z < 11 — major roads only (whitelist)
|
|
5
|
+
export const ROADS_PATHS_FULL_DETAIL_ZOOM = 13.5;
|
|
6
|
+
const ROADS_PATHS_MAJOR_ZOOM = 12.4;
|
|
7
|
+
const ROADS_PATHS_MAJOR_OR_TAGS = [
|
|
8
|
+
'highway=motorway',
|
|
9
|
+
'highway=motorway_link',
|
|
10
|
+
'highway=trunk',
|
|
11
|
+
'highway=trunk_link',
|
|
12
|
+
'highway=primary',
|
|
13
|
+
'highway=primary_link',
|
|
14
|
+
];
|
|
15
|
+
const ROADS_PATHS_MID_OR_TAGS = [
|
|
16
|
+
...ROADS_PATHS_MAJOR_OR_TAGS,
|
|
17
|
+
'highway=secondary',
|
|
18
|
+
'highway=secondary_link',
|
|
19
|
+
'highway=tertiary',
|
|
20
|
+
'highway=tertiary_link',
|
|
21
|
+
'highway=unclassified',
|
|
22
|
+
'highway=residential',
|
|
23
|
+
'highway=living_street',
|
|
24
|
+
];
|
|
25
|
+
/** Opt-in: drop path / minor-road clutter on roads_paths as map zooms out. Omit zoom for full detail. */
|
|
26
|
+
export function applyRoadsPathsZoomPolicy(preset, zoom) {
|
|
27
|
+
if (preset.id !== 'roads_paths' || zoom == null || zoom >= ROADS_PATHS_FULL_DETAIL_ZOOM) {
|
|
28
|
+
return preset;
|
|
29
|
+
}
|
|
30
|
+
const orTags = zoom < ROADS_PATHS_MAJOR_ZOOM ? ROADS_PATHS_MAJOR_OR_TAGS : ROADS_PATHS_MID_OR_TAGS;
|
|
31
|
+
return {
|
|
32
|
+
...preset,
|
|
33
|
+
tags: undefined,
|
|
34
|
+
orTags: [...orTags],
|
|
35
|
+
notTags: preset.notTags,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { OSMFeaturesLayerPreset } from './catalog.js';
|
|
2
|
+
export declare const WATERWAYS_FULL_DETAIL_ZOOM = 13;
|
|
3
|
+
/** Opt-in: drop minor waterways on waterways as map zooms out. Omit zoom for full detail. */
|
|
4
|
+
export declare function applyWaterwaysZoomPolicy<T extends OSMFeaturesLayerPreset>(preset: T, zoom?: number): T;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// waterways detail floors (omit zoom = full detail, same as z >= FULL):
|
|
2
|
+
// z >= 13 — river + canal + stream + drain + ditch
|
|
3
|
+
// z == 12 — river + canal
|
|
4
|
+
// z < 12 — river only
|
|
5
|
+
// Matches OpenMapTiles waterway class generalization (OSM data; no Natural Earth).
|
|
6
|
+
export const WATERWAYS_FULL_DETAIL_ZOOM = 13;
|
|
7
|
+
const WATERWAYS_CANAL_ZOOM = 12;
|
|
8
|
+
const WATERWAYS_RIVER_OR_TAGS = ['waterway=river'];
|
|
9
|
+
const WATERWAYS_RIVER_CANAL_OR_TAGS = [...WATERWAYS_RIVER_OR_TAGS, 'waterway=canal'];
|
|
10
|
+
/** Opt-in: drop minor waterways on waterways as map zooms out. Omit zoom for full detail. */
|
|
11
|
+
export function applyWaterwaysZoomPolicy(preset, zoom) {
|
|
12
|
+
if (preset.id !== 'waterways' || zoom == null || zoom >= WATERWAYS_FULL_DETAIL_ZOOM) {
|
|
13
|
+
return preset;
|
|
14
|
+
}
|
|
15
|
+
const orTags = zoom < WATERWAYS_CANAL_ZOOM ? WATERWAYS_RIVER_OR_TAGS : WATERWAYS_RIVER_CANAL_OR_TAGS;
|
|
16
|
+
return {
|
|
17
|
+
...preset,
|
|
18
|
+
tags: undefined,
|
|
19
|
+
orTags: [...orTags],
|
|
20
|
+
notTags: preset.notTags,
|
|
21
|
+
};
|
|
22
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "osmfeatures",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official client for the MapLark OSM Features API (GeoJSON, FlatGeobuf, GeoParquet, CSV)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json",
|
|
21
|
+
"test": "tsx src/index.test.ts && tsx src/geojson-feature.test.ts && tsx src/preset/preset.test.ts",
|
|
22
|
+
"prepare": "npm run build",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"openstreetmap",
|
|
27
|
+
"osm",
|
|
28
|
+
"geojson",
|
|
29
|
+
"flatgeobuf",
|
|
30
|
+
"geoparquet",
|
|
31
|
+
"overpass",
|
|
32
|
+
"maplark",
|
|
33
|
+
"geospatial",
|
|
34
|
+
"maps"
|
|
35
|
+
],
|
|
36
|
+
"homepage": "https://maplark.com",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/MapLark/osmfeatures-typescript.git"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"http-errors": "^2.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/http-errors": "^2.0.5",
|
|
50
|
+
"@types/node": "^22.10.0",
|
|
51
|
+
"tsx": "^4.19.0",
|
|
52
|
+
"typescript": "^5.7.0"
|
|
53
|
+
}
|
|
54
|
+
}
|