@osm-editor-kit/osm-editor-links 0.0.0-stage → 0.1.0-alpha.1
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/README.md +69 -2
- package/dist/editor-template.d.ts +14 -0
- package/dist/editors.d.ts +43 -0
- package/dist/history.d.ts +6 -0
- package/dist/hosts.d.ts +23 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +419 -0
- package/dist/josm.d.ts +8 -0
- package/dist/link-lists.d.ts +47 -0
- package/dist/map-download-url.d.ts +2 -0
- package/dist/mapillary.d.ts +19 -0
- package/dist/osm-object.d.ts +11 -0
- package/dist/osm-type.d.ts +6 -0
- package/dist/osmcha.d.ts +26 -0
- package/dist/tilda/features-param.d.ts +20 -0
- package/dist/tilda/index.d.ts +3 -0
- package/dist/tilda/inspector.d.ts +44 -0
- package/dist/tilda/sources.d.ts +8 -0
- package/package.json +50 -4
package/README.md
CHANGED
|
@@ -1,3 +1,70 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@osm-editor-kit/osm-editor-links`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> [!NOTE]
|
|
4
|
+
> This package is an **alpha** release and still under active development. APIs may change; install with the npm `alpha` dist-tag.
|
|
5
|
+
|
|
6
|
+
## What it does
|
|
7
|
+
|
|
8
|
+
- Link lists for one OSM element, one changeset or one user: the OSM website, history, editors, viewers and JOSM, with a stable `id` and an English label per link
|
|
9
|
+
- `linksIn` keeps the links offered at a country (for example TILDA only in Germany)
|
|
10
|
+
- Deep links to osm.org element and changeset pages, web editors (iD, Rapid), JOSM remote control, OSM API map downloads, Mapillary, OSM Deep History, OSMCha and TILDA inspector URLs
|
|
11
|
+
- OSM type helpers and a JOSM link-click handler
|
|
12
|
+
|
|
13
|
+
## Link lists
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { elementLinks, changesetLinks, userLinks, linksIn } from '@osm-editor-kit/osm-editor-links'
|
|
17
|
+
|
|
18
|
+
elementLinks({ type: 'way', id: 123, loc: { lat: 52.5, lng: 13.4 } })
|
|
19
|
+
// osm-history, osm, deep-history, pewu, id, rapid, josm, level0,
|
|
20
|
+
// mapillary, panoramax, tilda (tilda only with countries ['de'])
|
|
21
|
+
|
|
22
|
+
changesetLinks({ id: 42 }) // osm-changeset, osmcha, achavi, resultmaps, osm-revert, josm, level0
|
|
23
|
+
userLinks({ name: 'Anna Müller' }) // osm-user, hdyc, osmcha-user, missingmaps
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Each link is `{ id, label, url, countries?, josm? }`. Apps translate by `id` and fall back to `label`. A link with `josm: true` opens with `handleJosmLinkClick` (JOSM remote control) instead of a new tab.
|
|
27
|
+
|
|
28
|
+
Pass `server` to edit on another OSM website, for example the development server `https://master.apis.dev.openstreetmap.org`. The default is `https://www.openstreetmap.org`. Other servers get only their own links (element history and object page, changeset page, user profile); third-party tools only read production data.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const links = elementLinks({ type: 'way', id: 123, loc: { lat: 52.5, lng: 13.4 } })
|
|
32
|
+
const offered = linksIn(links, ['de']) // keeps TILDA; with ['fr'] it is dropped
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Other helpers
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import {
|
|
39
|
+
osmOrgUrl,
|
|
40
|
+
osmEditIdUrl,
|
|
41
|
+
josmLoadObjectUrl,
|
|
42
|
+
idEditorUrl,
|
|
43
|
+
getUrl,
|
|
44
|
+
mapillaryUrl,
|
|
45
|
+
osmchaChangesetUrl,
|
|
46
|
+
tildaInspectorUrl,
|
|
47
|
+
handleJosmLinkClick,
|
|
48
|
+
osmProdUrl,
|
|
49
|
+
} from '@osm-editor-kit/osm-editor-links'
|
|
50
|
+
|
|
51
|
+
osmOrgUrl({ osmType: 'way', osmId: 123 }) // → https://www.openstreetmap.org/way/123
|
|
52
|
+
osmEditIdUrl({ osmType: 'way', osmId: 123, hashtags: 'TILDA' })
|
|
53
|
+
|
|
54
|
+
josmLoadObjectUrl({ osmType: 'way', osmId: 123 }) // http://127.0.0.1:8111/load_object?…
|
|
55
|
+
idEditorUrl({ center: { lat: 52.47, lng: 13.44 }, zoom: 16 })
|
|
56
|
+
|
|
57
|
+
getUrl({ west: 13.4, south: 52.4, east: 13.5, north: 52.5 }, false) // OSM API map bbox URL
|
|
58
|
+
mapillaryUrl({ lat: 52.47, lng: 13.44 }, { dateFrom: '2024-01-01' })
|
|
59
|
+
|
|
60
|
+
osmchaChangesetUrl(12345)
|
|
61
|
+
tildaInspectorUrl({
|
|
62
|
+
regionSlug: 'radinfra',
|
|
63
|
+
map: { zoom: 16, lat: 52.47, lng: 13.44 },
|
|
64
|
+
features: { sourceId: 'atlas_bikelanes', featureId: 123, coords: [13.44, 52.47] },
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
await handleJosmLinkClick(event) // JOSM remote-control link click (fetches the link, no navigation)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Depends on `@osm-editor-kit/osm-data` for shared map bounds and OSM object types.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LatLngLiteral } from '@osm-editor-kit/osm-data';
|
|
2
|
+
import type { OsmObjectType } from './osm-type';
|
|
3
|
+
export type EditorUrlTemplateVars = {
|
|
4
|
+
zoom?: number;
|
|
5
|
+
center: LatLngLiteral;
|
|
6
|
+
osmType?: OsmObjectType | null;
|
|
7
|
+
osmId?: number | string | null;
|
|
8
|
+
editorId?: string | number | null;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Fill `{zoom}`, `{latitude}`, `{longitude}`, `{short_osm_type}`, `{long_osm_type}`,
|
|
12
|
+
* `{editor_id}`, `{osm_id}` placeholders in an editor URL template (TILDA-style).
|
|
13
|
+
*/
|
|
14
|
+
export declare function fillEditorUrlTemplate(urlTemplate: string, vars: EditorUrlTemplateVars): string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { LatLngLiteral } from '@osm-editor-kit/osm-data';
|
|
2
|
+
import { type OsmNode, type OsmRelation, type OsmWay } from '@osm-editor-kit/osm-data';
|
|
3
|
+
import { josmUrl } from './hosts';
|
|
4
|
+
import type { OsmObjectType } from './osm-type';
|
|
5
|
+
export { josmUrl };
|
|
6
|
+
type IdEditorUrlProps = {
|
|
7
|
+
center?: LatLngLiteral;
|
|
8
|
+
zoom?: number;
|
|
9
|
+
background?: string;
|
|
10
|
+
osmObjectType?: OsmRelation['type'] | OsmWay['type'] | OsmNode['type'];
|
|
11
|
+
osmObjectId?: number | string;
|
|
12
|
+
};
|
|
13
|
+
/** iD hosted on ideditor-release.netlify.app (parking-lanes default). */
|
|
14
|
+
export declare function idEditorUrl({ center, zoom, background, osmObjectType, osmObjectId, }: IdEditorUrlProps): string;
|
|
15
|
+
type OsmEditIdUrlProps = {
|
|
16
|
+
osmType: OsmObjectType | null | undefined;
|
|
17
|
+
osmId: number | string | null | undefined;
|
|
18
|
+
comment?: string;
|
|
19
|
+
hashtags?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Official OSM.org iD edit URL (TILDA-style, with optional hashtags). */
|
|
23
|
+
export declare function osmEditIdUrl({ osmType, osmId, comment, hashtags, source, }: OsmEditIdUrlProps): string | undefined;
|
|
24
|
+
export declare function osmEditRapidUrl(options: {
|
|
25
|
+
osmType: OsmObjectType | null | undefined;
|
|
26
|
+
osmId: number | string | null | undefined;
|
|
27
|
+
hashtags?: string;
|
|
28
|
+
locale?: string;
|
|
29
|
+
}): string | undefined;
|
|
30
|
+
export declare function osmEditKyleKiwiIdUrl(options: {
|
|
31
|
+
osmType: OsmObjectType | null | undefined;
|
|
32
|
+
osmId: number | string | null | undefined;
|
|
33
|
+
hashtags?: string;
|
|
34
|
+
locale?: string;
|
|
35
|
+
}): string | undefined;
|
|
36
|
+
/** JOSM remote control `load_object` for a single OSM element. */
|
|
37
|
+
export declare function josmLoadObjectUrl(options: {
|
|
38
|
+
osmType: OsmObjectType | null | undefined;
|
|
39
|
+
osmId: number | string | null | undefined;
|
|
40
|
+
changesetHashtags?: string;
|
|
41
|
+
}): string | undefined;
|
|
42
|
+
/** Prefix for JOSM `import?url=` (Overpass / map download). Same as `josmUrl`. */
|
|
43
|
+
export declare function josmImportUrl(): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OsmObjectType } from './osm-type';
|
|
2
|
+
/** OSM Deep History viewer (TILDA “Änderungshistorie”). */
|
|
3
|
+
export declare function osmDeepHistoryUrl(options: {
|
|
4
|
+
osmType: OsmObjectType | null | undefined;
|
|
5
|
+
osmId: number | string | null | undefined;
|
|
6
|
+
}): string | undefined;
|
package/dist/hosts.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** JOSM remote-control base for `import?url=` (Overpass / map download). */
|
|
2
|
+
export declare const josmRemoteBase = "http://127.0.0.1:8111";
|
|
3
|
+
/** @deprecated Prefer `josmImportUrl` / `josmLoadObjectUrl`; kept for existing callers. */
|
|
4
|
+
export declare const josmUrl = "http://127.0.0.1:8111/import?url=";
|
|
5
|
+
export declare const osmProdUrl = "https://www.openstreetmap.org";
|
|
6
|
+
/** Production OSM API host (OAuth, map downloads, changeset upload). */
|
|
7
|
+
export declare const osmProdApiUrl = "https://api.openstreetmap.org";
|
|
8
|
+
export declare const osmDevUrl = "https://master.apis.dev.openstreetmap.org";
|
|
9
|
+
export declare const osmchaBase = "https://osmcha.org";
|
|
10
|
+
export declare const tildaGeoBase = "https://tilda-geo.de";
|
|
11
|
+
export declare const osmDeepHistoryBase = "https://osmlab.github.io/osm-deep-history";
|
|
12
|
+
/** Third-party viewers and editors, used by the link lists. */
|
|
13
|
+
export declare const pewuHistoryBase = "https://pewu.github.io/osm-history";
|
|
14
|
+
export declare const rapidBase = "https://rapideditor.org";
|
|
15
|
+
export declare const level0Base = "http://level0.osmz.ru";
|
|
16
|
+
export declare const mapillaryBase = "https://www.mapillary.com";
|
|
17
|
+
export declare const panoramaxBase = "https://api.panoramax.xyz";
|
|
18
|
+
export declare const tildaViewerBase = "https://viewer.tilda-geo.de";
|
|
19
|
+
export declare const achaviBase = "https://overpass-api.de/achavi";
|
|
20
|
+
export declare const resultMapsBase = "https://resultmaps.neis-one.org";
|
|
21
|
+
export declare const osmRevertBase = "https://revert.monicz.dev";
|
|
22
|
+
export declare const hdycBase = "https://hdyc.neis-one.org";
|
|
23
|
+
export declare const missingMapsBase = "https://www.missingmaps.org";
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { fillEditorUrlTemplate, type EditorUrlTemplateVars } from './editor-template';
|
|
2
|
+
export { idEditorUrl, josmImportUrl, josmLoadObjectUrl, josmUrl, osmEditIdUrl, osmEditKyleKiwiIdUrl, osmEditRapidUrl, } from './editors';
|
|
3
|
+
export { osmDeepHistoryUrl } from './history';
|
|
4
|
+
export { josmRemoteBase, osmchaBase, osmDeepHistoryBase, osmDevUrl, osmProdApiUrl, osmProdUrl, tildaGeoBase, } from './hosts';
|
|
5
|
+
export { handleJosmLinkClick } from './josm';
|
|
6
|
+
export { changesetLinks, elementLinks, linksIn, userLinks, type ChangesetLinksOptions, type ElementLinksOptions, type OsmLink, type UserLinksOptions, } from './link-lists';
|
|
7
|
+
export { getUrl } from './map-download-url';
|
|
8
|
+
export { mapillaryRecentPanosUrl, mapillaryUrl, type MapillaryUrlOptions } from './mapillary';
|
|
9
|
+
export { osmChangesetUrl, osmObjectHistoryUrl, osmOrgUrl, type OsmTypeId } from './osm-object';
|
|
10
|
+
export { longOsmType, shortOsmType, toLongOsmType, toShortOsmType, type OsmObjectType, type OsmShortType, } from './osm-type';
|
|
11
|
+
export { osmchaChangesetUrl, osmchaFiltersUrl, type OsmchaFiltersInput, type OsmchaFilterValue, } from './osmcha';
|
|
12
|
+
export { serializeTildaFeaturesParam, TILDA_INFRA_PRESETS, TILDA_SOURCE_NUMERIC_IDS, tildaInfraSourceNumericId, tildaInspectorUrl, tildaInspectorUrlForInfra, tildaSourceIdFromNumeric, tildaSourceNumericId, type TildaFeatureCoord, type TildaFeatureParam, type TildaInfra, type TildaInfraPreset, type TildaInspectorForInfraOptions, type TildaInspectorUrlOptions, type TildaMapPosition, } from './tilda';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
// src/osm-type.ts
|
|
2
|
+
var longOsmType = {
|
|
3
|
+
W: "way",
|
|
4
|
+
N: "node",
|
|
5
|
+
R: "relation",
|
|
6
|
+
w: "way",
|
|
7
|
+
n: "node",
|
|
8
|
+
r: "relation",
|
|
9
|
+
way: "way",
|
|
10
|
+
node: "node",
|
|
11
|
+
relation: "relation"
|
|
12
|
+
};
|
|
13
|
+
var shortOsmType = {
|
|
14
|
+
way: "w",
|
|
15
|
+
node: "n",
|
|
16
|
+
relation: "r",
|
|
17
|
+
w: "w",
|
|
18
|
+
n: "n",
|
|
19
|
+
r: "r",
|
|
20
|
+
W: "w",
|
|
21
|
+
N: "n",
|
|
22
|
+
R: "r"
|
|
23
|
+
};
|
|
24
|
+
function toLongOsmType(type) {
|
|
25
|
+
return longOsmType[type];
|
|
26
|
+
}
|
|
27
|
+
function toShortOsmType(type) {
|
|
28
|
+
return shortOsmType[type];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/editor-template.ts
|
|
32
|
+
function fillEditorUrlTemplate(urlTemplate, vars) {
|
|
33
|
+
const short = vars.osmType ? toShortOsmType(vars.osmType) ?? "" : "";
|
|
34
|
+
return urlTemplate.replaceAll("{zoom}", vars.zoom?.toString() ?? "19").replaceAll("{latitude}", String(vars.center.lat)).replaceAll("{longitude}", String(vars.center.lng)).replaceAll("{short_osm_type}", short).replaceAll("{long_osm_type}", vars.osmType ?? "").replaceAll("{editor_id}", vars.editorId != null ? String(vars.editorId) : "").replaceAll("{osm_id}", vars.osmId != null ? String(vars.osmId) : "");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/hosts.ts
|
|
38
|
+
var josmRemoteBase = "http://127.0.0.1:8111";
|
|
39
|
+
var josmUrl = `${josmRemoteBase}/import?url=`;
|
|
40
|
+
var osmProdUrl = "https://www.openstreetmap.org";
|
|
41
|
+
var osmProdApiUrl = "https://api.openstreetmap.org";
|
|
42
|
+
var osmDevUrl = "https://master.apis.dev.openstreetmap.org";
|
|
43
|
+
var osmchaBase = "https://osmcha.org";
|
|
44
|
+
var tildaGeoBase = "https://tilda-geo.de";
|
|
45
|
+
var osmDeepHistoryBase = "https://osmlab.github.io/osm-deep-history";
|
|
46
|
+
var pewuHistoryBase = "https://pewu.github.io/osm-history";
|
|
47
|
+
var rapidBase = "https://rapideditor.org";
|
|
48
|
+
var level0Base = "http://level0.osmz.ru";
|
|
49
|
+
var mapillaryBase = "https://www.mapillary.com";
|
|
50
|
+
var panoramaxBase = "https://api.panoramax.xyz";
|
|
51
|
+
var tildaViewerBase = "https://viewer.tilda-geo.de";
|
|
52
|
+
var achaviBase = "https://overpass-api.de/achavi";
|
|
53
|
+
var resultMapsBase = "https://resultmaps.neis-one.org";
|
|
54
|
+
var osmRevertBase = "https://revert.monicz.dev";
|
|
55
|
+
var hdycBase = "https://hdyc.neis-one.org";
|
|
56
|
+
var missingMapsBase = "https://www.missingmaps.org";
|
|
57
|
+
|
|
58
|
+
// src/editors.ts
|
|
59
|
+
function idEditorUrl({
|
|
60
|
+
center,
|
|
61
|
+
zoom,
|
|
62
|
+
background,
|
|
63
|
+
osmObjectType,
|
|
64
|
+
osmObjectId
|
|
65
|
+
}) {
|
|
66
|
+
const params = {
|
|
67
|
+
disable_features: "boundaries",
|
|
68
|
+
photo_overlay: "streetside,mapillary,kartaview"
|
|
69
|
+
};
|
|
70
|
+
if (zoom && center) params.map = `${zoom}/${center.lat}/${center.lng}`;
|
|
71
|
+
if (background) params.background = background;
|
|
72
|
+
if (osmObjectType && osmObjectId) params.id = `${osmObjectType.charAt(0)}${osmObjectId}`;
|
|
73
|
+
const hashUrlParams = new URLSearchParams(params);
|
|
74
|
+
return `https://ideditor-release.netlify.app/#${hashUrlParams.toString()}`;
|
|
75
|
+
}
|
|
76
|
+
function osmEditIdUrl({
|
|
77
|
+
osmType,
|
|
78
|
+
osmId,
|
|
79
|
+
comment,
|
|
80
|
+
hashtags,
|
|
81
|
+
source
|
|
82
|
+
}) {
|
|
83
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
84
|
+
const url = new URL("https://www.openstreetmap.org/edit");
|
|
85
|
+
url.searchParams.append(osmType, String(osmId));
|
|
86
|
+
const hashParams = new URLSearchParams();
|
|
87
|
+
if (comment) hashParams.append("comment", comment);
|
|
88
|
+
if (source) hashParams.append("source", source);
|
|
89
|
+
if (hashtags) hashParams.append("hashtags", hashtags);
|
|
90
|
+
const hash = hashParams.toString();
|
|
91
|
+
return hash ? `${url.toString()}#${hash}` : url.toString();
|
|
92
|
+
}
|
|
93
|
+
function osmEditRapidUrl(options) {
|
|
94
|
+
const { osmType, osmId, hashtags = "TILDA", locale = "de" } = options;
|
|
95
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
96
|
+
const short = toShortOsmType(osmType);
|
|
97
|
+
if (!short) return void 0;
|
|
98
|
+
return `https://rapideditor.org/edit#id=${short}${osmId}&disable_features=boundaries&locale=${locale}&hashtags=${hashtags}`;
|
|
99
|
+
}
|
|
100
|
+
function osmEditKyleKiwiIdUrl(options) {
|
|
101
|
+
const { osmType, osmId, hashtags = "TILDA", locale = "en" } = options;
|
|
102
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
103
|
+
const short = toShortOsmType(osmType);
|
|
104
|
+
if (!short) return void 0;
|
|
105
|
+
return `https://kyle.kiwi/iD/#id=${short}${osmId}&locale=${locale}&disable_features=boundaries&hashtags=${hashtags}`;
|
|
106
|
+
}
|
|
107
|
+
function josmLoadObjectUrl(options) {
|
|
108
|
+
const { osmType, osmId, changesetHashtags = "TILDA" } = options;
|
|
109
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
110
|
+
const short = toShortOsmType(osmType);
|
|
111
|
+
if (!short) return void 0;
|
|
112
|
+
const url = new URL(`${josmRemoteBase}/load_object`);
|
|
113
|
+
url.searchParams.set("objects", `${short}${osmId}`);
|
|
114
|
+
if (changesetHashtags) url.searchParams.set("changeset_hashtags", changesetHashtags);
|
|
115
|
+
return url.toString();
|
|
116
|
+
}
|
|
117
|
+
function josmImportUrl() {
|
|
118
|
+
return josmUrl;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/history.ts
|
|
122
|
+
function osmDeepHistoryUrl(options) {
|
|
123
|
+
const { osmType, osmId } = options;
|
|
124
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
125
|
+
return `${osmDeepHistoryBase}/#/${osmType}/${osmId}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/josm.ts
|
|
129
|
+
async function handleJosmLinkClick(e) {
|
|
130
|
+
const anchor = e.target instanceof Element ? e.target.closest("a") : null;
|
|
131
|
+
if (!anchor) return;
|
|
132
|
+
await fetch(anchor.href);
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/osm-object.ts
|
|
137
|
+
function osmOrgUrl({ osmType, osmId }, server = osmProdUrl) {
|
|
138
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
139
|
+
return `${server}/${osmType}/${osmId}`;
|
|
140
|
+
}
|
|
141
|
+
function osmObjectHistoryUrl({ osmType, osmId }, server = osmProdUrl) {
|
|
142
|
+
if (!osmType || osmId == null || osmId === "") return void 0;
|
|
143
|
+
return `${server}/${osmType}/${osmId}/history`;
|
|
144
|
+
}
|
|
145
|
+
function osmChangesetUrl(changesetId, server = osmProdUrl) {
|
|
146
|
+
return `${server}/changeset/${changesetId}`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/osmcha.ts
|
|
150
|
+
function osmchaChangesetUrl(changesetId) {
|
|
151
|
+
return `${osmchaBase}/changesets/${changesetId}`;
|
|
152
|
+
}
|
|
153
|
+
function toFilterEntries(value) {
|
|
154
|
+
if (typeof value === "string") {
|
|
155
|
+
return [{ label: value, value }];
|
|
156
|
+
}
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
function osmchaFiltersUrl(filters) {
|
|
160
|
+
const encoded = {};
|
|
161
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
162
|
+
if (value == null) continue;
|
|
163
|
+
encoded[key] = toFilterEntries(value);
|
|
164
|
+
}
|
|
165
|
+
const json = JSON.stringify(encoded);
|
|
166
|
+
return `${osmchaBase}/?filters=${encodeURIComponent(json)}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/link-lists.ts
|
|
170
|
+
function link(id, label, url, extra) {
|
|
171
|
+
return url === void 0 ? void 0 : { id, label, url, ...extra };
|
|
172
|
+
}
|
|
173
|
+
function present(links) {
|
|
174
|
+
return links.filter((item) => item !== void 0);
|
|
175
|
+
}
|
|
176
|
+
function website(server) {
|
|
177
|
+
const base = (server ?? osmProdUrl).replace(/\/+$/, "");
|
|
178
|
+
return { base, production: base === osmProdUrl };
|
|
179
|
+
}
|
|
180
|
+
function elementLinks({ type, id, loc, zoom = 17, server }) {
|
|
181
|
+
const { base, production } = website(server);
|
|
182
|
+
const object = { osmType: type, osmId: id };
|
|
183
|
+
const links = [
|
|
184
|
+
link("osm-history", "OpenStreetMap history", osmObjectHistoryUrl(object, base)),
|
|
185
|
+
link("osm", "OpenStreetMap", osmOrgUrl(object, base))
|
|
186
|
+
];
|
|
187
|
+
if (production) {
|
|
188
|
+
links.push(
|
|
189
|
+
link("deep-history", "OSM Deep History", osmDeepHistoryUrl(object)),
|
|
190
|
+
link("pewu", "PeWu history", id === "" ? void 0 : `${pewuHistoryBase}/#/${type}/${id}`),
|
|
191
|
+
link("id", "iD", osmEditIdUrl(object)),
|
|
192
|
+
link(
|
|
193
|
+
"rapid",
|
|
194
|
+
"Rapid",
|
|
195
|
+
id === "" ? void 0 : `${rapidBase}/edit#id=${shortOsmType[type]}${id}`
|
|
196
|
+
),
|
|
197
|
+
link("josm", "JOSM", josmLoadObjectUrl({ osmType: type, osmId: id, changesetHashtags: "" }), {
|
|
198
|
+
josm: true
|
|
199
|
+
}),
|
|
200
|
+
link("level0", "Level0", id === "" ? void 0 : `${level0Base}/?url=${type}/${id}`)
|
|
201
|
+
);
|
|
202
|
+
if (loc) {
|
|
203
|
+
const { lat, lng } = loc;
|
|
204
|
+
links.push(
|
|
205
|
+
link(
|
|
206
|
+
"mapillary",
|
|
207
|
+
"Mapillary",
|
|
208
|
+
`${mapillaryBase}/app/?${new URLSearchParams({ lat: String(lat), lng: String(lng), z: String(zoom) })}`
|
|
209
|
+
),
|
|
210
|
+
link("panoramax", "Panoramax", `${panoramaxBase}/?focus=map&map=${zoom}/${lat}/${lng}`),
|
|
211
|
+
link("tilda", "TILDA Viewer", `${tildaViewerBase}/?map=${zoom}/${lat}/${lng}`, {
|
|
212
|
+
countries: ["de"]
|
|
213
|
+
})
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return present(links);
|
|
218
|
+
}
|
|
219
|
+
function changesetLinks({ id, server }) {
|
|
220
|
+
if (id === "") return [];
|
|
221
|
+
const { base, production } = website(server);
|
|
222
|
+
const links = [
|
|
223
|
+
link("osm-changeset", "OpenStreetMap changeset", osmChangesetUrl(id, base))
|
|
224
|
+
];
|
|
225
|
+
if (production) {
|
|
226
|
+
links.push(
|
|
227
|
+
link("osmcha", "OSMCha", osmchaChangesetUrl(id)),
|
|
228
|
+
link("achavi", "achavi", `${achaviBase}/?changeset=${id}&relations=true`),
|
|
229
|
+
link("resultmaps", "ResultMaps", `${resultMapsBase}/osm-change-viz?c=${id}`),
|
|
230
|
+
link("osm-revert", "osm-revert", `${osmRevertBase}/?changesets=${id}`),
|
|
231
|
+
link("josm", "JOSM", `${josmImportUrl()}${osmProdUrl}/api/0.6/changeset/${id}/download`, {
|
|
232
|
+
josm: true
|
|
233
|
+
}),
|
|
234
|
+
link("level0", "Level0", `${level0Base}/?url=changeset/${id}`)
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
return present(links);
|
|
238
|
+
}
|
|
239
|
+
function userLinks({ name, server }) {
|
|
240
|
+
if (name === "") return [];
|
|
241
|
+
const { base, production } = website(server);
|
|
242
|
+
const encoded = encodeURIComponent(name);
|
|
243
|
+
const links = [
|
|
244
|
+
link("osm-user", "OpenStreetMap profile", `${base}/user/${encoded}`)
|
|
245
|
+
];
|
|
246
|
+
if (production) {
|
|
247
|
+
links.push(
|
|
248
|
+
link("hdyc", "How did you contribute", `${hdycBase}/?${encoded}`),
|
|
249
|
+
link("osmcha-user", "OSMCha changesets", osmchaFiltersUrl({ users: name })),
|
|
250
|
+
link("missingmaps", "Missing Maps", `${missingMapsBase}/users/#/${encoded}`)
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
return present(links);
|
|
254
|
+
}
|
|
255
|
+
function linksIn(links, countryCodes) {
|
|
256
|
+
const codes = new Set(countryCodes.map((code) => code.toLowerCase()));
|
|
257
|
+
return links.filter(
|
|
258
|
+
(item) => !item.countries || item.countries.some((code) => codes.has(code.toLowerCase()))
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/map-download-url.ts
|
|
263
|
+
function getUrl(bounds, useDevServer) {
|
|
264
|
+
const bbox = [bounds.west, bounds.south, bounds.east, bounds.north].join(",");
|
|
265
|
+
return (useDevServer ? osmDevUrl : osmProdApiUrl) + "/api/0.6/map?bbox=" + bbox;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/mapillary.ts
|
|
269
|
+
var MAPILLARY_RECENT_PANOS_YEARS = 3;
|
|
270
|
+
function mapillaryUrl(center, options) {
|
|
271
|
+
const trafficSign = options?.trafficSign === false ? void 0 : options?.trafficSign ?? "all";
|
|
272
|
+
const params = new URLSearchParams({
|
|
273
|
+
lat: String(center.lat),
|
|
274
|
+
lng: String(center.lng),
|
|
275
|
+
z: String(options?.zoom ?? 17),
|
|
276
|
+
focus: "map"
|
|
277
|
+
});
|
|
278
|
+
if (trafficSign) params.set("trafficSign", trafficSign);
|
|
279
|
+
if (options?.dateFrom) params.set("dateFrom", options.dateFrom);
|
|
280
|
+
if (options?.dateTo) params.set("dateTo", options.dateTo);
|
|
281
|
+
if (options?.panosOnly) params.set("panos", "true");
|
|
282
|
+
return `https://www.mapillary.com/app/?${params.toString()}`;
|
|
283
|
+
}
|
|
284
|
+
function mapillaryRecentPanosUrl(center, options) {
|
|
285
|
+
const referenceDate = options?.referenceDate ?? /* @__PURE__ */ new Date();
|
|
286
|
+
const years = options?.years ?? MAPILLARY_RECENT_PANOS_YEARS;
|
|
287
|
+
const dateTo = formatMapillaryUtcDate(referenceDate);
|
|
288
|
+
const dateFromDate = new Date(referenceDate);
|
|
289
|
+
dateFromDate.setUTCFullYear(dateFromDate.getUTCFullYear() - years);
|
|
290
|
+
return mapillaryUrl(center, {
|
|
291
|
+
dateFrom: formatMapillaryUtcDate(dateFromDate),
|
|
292
|
+
dateTo,
|
|
293
|
+
panosOnly: true
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
function formatMapillaryUtcDate(date) {
|
|
297
|
+
return date.toISOString().slice(0, 10);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/tilda/sources.ts
|
|
301
|
+
var TILDA_SOURCE_NUMERIC_IDS = {
|
|
302
|
+
1: "osm_notes",
|
|
303
|
+
2: "lars_parking",
|
|
304
|
+
3: "lars_parking_debug",
|
|
305
|
+
4: "lars_parking_points",
|
|
306
|
+
5: "lars_parking_areas",
|
|
307
|
+
6: "lars_parking_stats",
|
|
308
|
+
7: "atlas_boundaries",
|
|
309
|
+
8: "atlas_presenceStats",
|
|
310
|
+
9: "accidents_unfallatlas",
|
|
311
|
+
10: "atlas_bikelanes",
|
|
312
|
+
11: "atlas_bikeroutes",
|
|
313
|
+
12: "atlas_roads",
|
|
314
|
+
13: "atlas_roadsPathClasses",
|
|
315
|
+
14: "atlas_publicTransport",
|
|
316
|
+
15: "atlas_poiClassification",
|
|
317
|
+
16: "atlas_places",
|
|
318
|
+
17: "atlas_barriers",
|
|
319
|
+
18: "atlas_landuse",
|
|
320
|
+
19: "atlas_bicycleParking",
|
|
321
|
+
20: "atlas_trafficSigns",
|
|
322
|
+
21: "mapillary_coverage",
|
|
323
|
+
22: "atlas_bikelanesPresence",
|
|
324
|
+
23: "atlas_bikeSuitability",
|
|
325
|
+
24: "atlas_todos_lines",
|
|
326
|
+
25: "atlas_aggregated_lengths",
|
|
327
|
+
26: "tilda_parkings",
|
|
328
|
+
27: "tilda_parkings_cutouts",
|
|
329
|
+
28: "tilda_parkings_quantized",
|
|
330
|
+
30: "tilda_parkings_no",
|
|
331
|
+
31: "tilda_parkings_off_street",
|
|
332
|
+
32: "tilda_parkings_off_street_quantized"
|
|
333
|
+
};
|
|
334
|
+
var sourceIdToNumeric = new Map(
|
|
335
|
+
Object.entries(TILDA_SOURCE_NUMERIC_IDS).map(([id, name]) => [name, Number(id)])
|
|
336
|
+
);
|
|
337
|
+
function tildaSourceNumericId(sourceId) {
|
|
338
|
+
return sourceIdToNumeric.get(sourceId);
|
|
339
|
+
}
|
|
340
|
+
function tildaSourceIdFromNumeric(numericId) {
|
|
341
|
+
return TILDA_SOURCE_NUMERIC_IDS[numericId];
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// src/tilda/features-param.ts
|
|
345
|
+
var COORD_PRECISION = 6;
|
|
346
|
+
function roundCoord(n) {
|
|
347
|
+
const factor = 10 ** COORD_PRECISION;
|
|
348
|
+
return String(Math.round(n * factor) / factor);
|
|
349
|
+
}
|
|
350
|
+
function resolveNumericSourceId(sourceId) {
|
|
351
|
+
if (typeof sourceId === "number") return sourceId;
|
|
352
|
+
if (/^\d+$/.test(sourceId)) return Number(sourceId);
|
|
353
|
+
return tildaSourceNumericId(sourceId);
|
|
354
|
+
}
|
|
355
|
+
function serializeOneFeature(feature) {
|
|
356
|
+
const numericId = resolveNumericSourceId(feature.sourceId);
|
|
357
|
+
if (numericId == null) return void 0;
|
|
358
|
+
const id = String(feature.featureId);
|
|
359
|
+
if (feature.coords.kind === "point") {
|
|
360
|
+
const { lon, lat } = feature.coords;
|
|
361
|
+
return `${numericId}|${id}|${roundCoord(lon)}|${roundCoord(lat)}`;
|
|
362
|
+
}
|
|
363
|
+
const { minLon, minLat, maxLon, maxLat } = feature.coords;
|
|
364
|
+
return `${numericId}|${id}|${roundCoord(minLon)}|${roundCoord(minLat)}|${roundCoord(maxLon)}|${roundCoord(maxLat)}`;
|
|
365
|
+
}
|
|
366
|
+
function serializeTildaFeaturesParam(features) {
|
|
367
|
+
const list = Array.isArray(features) ? features : [features];
|
|
368
|
+
const parts = list.map(serializeOneFeature).filter((p) => p != null);
|
|
369
|
+
if (parts.length === 0) return void 0;
|
|
370
|
+
return parts.join(",");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/tilda/inspector.ts
|
|
374
|
+
var TILDA_INFRA_PRESETS = {
|
|
375
|
+
bikelanes: {
|
|
376
|
+
regionSlug: "radinfra",
|
|
377
|
+
sourceId: "atlas_bikelanes",
|
|
378
|
+
defaultConfig: "1v92rco.7h39.4pt3i8"
|
|
379
|
+
},
|
|
380
|
+
parking: {
|
|
381
|
+
regionSlug: "parkraum",
|
|
382
|
+
sourceId: "lars_parking",
|
|
383
|
+
defaultConfig: "12nl2cs.16lxxh"
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
function tildaInspectorUrl(options) {
|
|
387
|
+
const base = options.baseUrl ?? tildaGeoBase;
|
|
388
|
+
const url = new URL(`${base}/regionen/${options.regionSlug}`);
|
|
389
|
+
const { zoom, lat, lng } = options.map;
|
|
390
|
+
url.searchParams.set("map", `${zoom}/${lat}/${lng}`);
|
|
391
|
+
if (options.config) url.searchParams.set("config", options.config);
|
|
392
|
+
if (options.features) {
|
|
393
|
+
const f = serializeTildaFeaturesParam(options.features);
|
|
394
|
+
if (f) url.searchParams.set("f", f);
|
|
395
|
+
}
|
|
396
|
+
url.searchParams.set("v", String(options.version ?? 2));
|
|
397
|
+
return url.toString();
|
|
398
|
+
}
|
|
399
|
+
function tildaInspectorUrlForInfra(infra, options) {
|
|
400
|
+
const preset = TILDA_INFRA_PRESETS[infra];
|
|
401
|
+
const features = options.featureId != null && options.coords != null ? {
|
|
402
|
+
sourceId: preset.sourceId,
|
|
403
|
+
featureId: options.featureId,
|
|
404
|
+
coords: options.coords
|
|
405
|
+
} : void 0;
|
|
406
|
+
return tildaInspectorUrl({
|
|
407
|
+
regionSlug: preset.regionSlug,
|
|
408
|
+
map: options.map,
|
|
409
|
+
config: options.config ?? preset.defaultConfig,
|
|
410
|
+
features,
|
|
411
|
+
version: options.version,
|
|
412
|
+
baseUrl: options.baseUrl
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function tildaInfraSourceNumericId(infra) {
|
|
416
|
+
return tildaSourceNumericId(TILDA_INFRA_PRESETS[infra].sourceId);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export { TILDA_INFRA_PRESETS, TILDA_SOURCE_NUMERIC_IDS, changesetLinks, elementLinks, fillEditorUrlTemplate, getUrl, handleJosmLinkClick, idEditorUrl, josmImportUrl, josmLoadObjectUrl, josmRemoteBase, josmUrl, linksIn, longOsmType, mapillaryRecentPanosUrl, mapillaryUrl, osmChangesetUrl, osmDeepHistoryBase, osmDeepHistoryUrl, osmDevUrl, osmEditIdUrl, osmEditKyleKiwiIdUrl, osmEditRapidUrl, osmObjectHistoryUrl, osmOrgUrl, osmProdApiUrl, osmProdUrl, osmchaBase, osmchaChangesetUrl, osmchaFiltersUrl, serializeTildaFeaturesParam, shortOsmType, tildaGeoBase, tildaInfraSourceNumericId, tildaInspectorUrl, tildaInspectorUrlForInfra, tildaSourceIdFromNumeric, tildaSourceNumericId, toLongOsmType, toShortOsmType, userLinks };
|
package/dist/josm.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Click handler for a JOSM remote-control link (`http://127.0.0.1:8111/...`).
|
|
3
|
+
*
|
|
4
|
+
* JOSM answers the request itself, so the browser should not navigate away: the link is fetched
|
|
5
|
+
* instead, and the default action is cancelled. JOSM sends CORS headers, so the fetch works from
|
|
6
|
+
* any page. The promise rejects when JOSM is not running, as the request fails.
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleJosmLinkClick(e: Event): Promise<void>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type OsmObjectType } from './osm-type';
|
|
2
|
+
/** One link of a list. `id` is stable: apps use it for their own translated label. */
|
|
3
|
+
export type OsmLink = {
|
|
4
|
+
/** Stable id, e.g. `osm-history`. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** English default label. */
|
|
7
|
+
label: string;
|
|
8
|
+
url: string;
|
|
9
|
+
/** ISO 3166 codes (lower case) where this link is offered, e.g. `['de']`; absent = everywhere. */
|
|
10
|
+
countries?: readonly string[];
|
|
11
|
+
/** JOSM remote control: open with `handleJosmLinkClick` instead of a new tab. */
|
|
12
|
+
josm?: true;
|
|
13
|
+
};
|
|
14
|
+
export type ElementLinksOptions = {
|
|
15
|
+
type: OsmObjectType;
|
|
16
|
+
id: number | string;
|
|
17
|
+
/** Place for the imagery and TILDA links. Without it those links are left out. */
|
|
18
|
+
loc?: {
|
|
19
|
+
lat: number;
|
|
20
|
+
lng: number;
|
|
21
|
+
};
|
|
22
|
+
/** Map zoom for the place links. Default 17. */
|
|
23
|
+
zoom?: number;
|
|
24
|
+
/** OSM website the app edits on. Default `osmProdUrl`. */
|
|
25
|
+
server?: string;
|
|
26
|
+
};
|
|
27
|
+
export type ChangesetLinksOptions = {
|
|
28
|
+
id: number | string;
|
|
29
|
+
/** OSM website the app edits on. Default `osmProdUrl`. */
|
|
30
|
+
server?: string;
|
|
31
|
+
};
|
|
32
|
+
export type UserLinksOptions = {
|
|
33
|
+
name: string;
|
|
34
|
+
/** OSM website the app edits on. Default `osmProdUrl`. */
|
|
35
|
+
server?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Links for one OSM element: history, object page, editors, viewers and imagery. */
|
|
38
|
+
export declare function elementLinks({ type, id, loc, zoom, server }: ElementLinksOptions): OsmLink[];
|
|
39
|
+
/** Links for one changeset. */
|
|
40
|
+
export declare function changesetLinks({ id, server }: ChangesetLinksOptions): OsmLink[];
|
|
41
|
+
/** Links for one OSM user, by display name. */
|
|
42
|
+
export declare function userLinks({ name, server }: UserLinksOptions): OsmLink[];
|
|
43
|
+
/**
|
|
44
|
+
* Links offered at a place: those without `countries`, and those whose `countries` contain one of
|
|
45
|
+
* the codes. Codes are compared case-insensitively.
|
|
46
|
+
*/
|
|
47
|
+
export declare function linksIn(links: readonly OsmLink[], countryCodes: readonly string[]): OsmLink[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LatLngLiteral } from '@osm-editor-kit/osm-data';
|
|
2
|
+
export type MapillaryUrlOptions = {
|
|
3
|
+
/** UTC calendar date (`YYYY-MM-DD`) for Mapillary's `dateFrom` filter. */
|
|
4
|
+
dateFrom?: string;
|
|
5
|
+
/** UTC calendar date (`YYYY-MM-DD`) for Mapillary's `dateTo` filter. */
|
|
6
|
+
dateTo?: string;
|
|
7
|
+
/** When true, adds `panos=true` (360° imagery only). */
|
|
8
|
+
panosOnly?: boolean;
|
|
9
|
+
/** Map zoom; defaults to 17. */
|
|
10
|
+
zoom?: number;
|
|
11
|
+
/** When set, adds `trafficSign=` (default `all` when omitted from options entirely uses `all`). */
|
|
12
|
+
trafficSign?: 'all' | false;
|
|
13
|
+
};
|
|
14
|
+
export declare function mapillaryUrl(center: LatLngLiteral, options?: MapillaryUrlOptions): string;
|
|
15
|
+
/** Panorama imagery from the last few years — useful for kerbside parking signs. */
|
|
16
|
+
export declare function mapillaryRecentPanosUrl(center: LatLngLiteral, options?: {
|
|
17
|
+
years?: number;
|
|
18
|
+
referenceDate?: Date;
|
|
19
|
+
}): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OsmObjectType } from './osm-type';
|
|
2
|
+
export type OsmTypeId = {
|
|
3
|
+
osmType: OsmObjectType | null | undefined;
|
|
4
|
+
osmId: number | string | null | undefined;
|
|
5
|
+
};
|
|
6
|
+
/** `https://www.openstreetmap.org/{type}/{id}` (or the same path on `server`). */
|
|
7
|
+
export declare function osmOrgUrl({ osmType, osmId }: OsmTypeId, server?: string): string | undefined;
|
|
8
|
+
/** OSM website object history page (`…/{type}/{id}/history`, or on `server`). */
|
|
9
|
+
export declare function osmObjectHistoryUrl({ osmType, osmId }: OsmTypeId, server?: string): string | undefined;
|
|
10
|
+
/** `https://www.openstreetmap.org/changeset/{id}` (or the same path on `server`). */
|
|
11
|
+
export declare function osmChangesetUrl(changesetId: number | string, server?: string): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type OsmObjectType = 'way' | 'node' | 'relation';
|
|
2
|
+
export type OsmShortType = 'w' | 'n' | 'r';
|
|
3
|
+
export declare const longOsmType: Record<string, OsmObjectType>;
|
|
4
|
+
export declare const shortOsmType: Record<string, OsmShortType>;
|
|
5
|
+
export declare function toLongOsmType(type: string): OsmObjectType | undefined;
|
|
6
|
+
export declare function toShortOsmType(type: string): OsmShortType | undefined;
|
package/dist/osmcha.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Single OSMCha changeset page. */
|
|
2
|
+
export declare function osmchaChangesetUrl(changesetId: number | string): string;
|
|
3
|
+
export type OsmchaFilterValue = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* OSMCha frontend filter keys (subset). Each value is an array of `{label,value}`
|
|
9
|
+
* as required by https://github.com/OSMCha/osmcha-frontend deep links.
|
|
10
|
+
*/
|
|
11
|
+
export type OsmchaFiltersInput = {
|
|
12
|
+
in_bbox?: string | OsmchaFilterValue[];
|
|
13
|
+
date__gte?: string | OsmchaFilterValue[];
|
|
14
|
+
date__lte?: string | OsmchaFilterValue[];
|
|
15
|
+
users?: string | OsmchaFilterValue[];
|
|
16
|
+
uids?: string | OsmchaFilterValue[];
|
|
17
|
+
ids?: string | OsmchaFilterValue[];
|
|
18
|
+
tag_changes?: string | OsmchaFilterValue[];
|
|
19
|
+
all_tag_changes?: string | OsmchaFilterValue[];
|
|
20
|
+
comment?: string | OsmchaFilterValue[];
|
|
21
|
+
metadata?: string | OsmchaFilterValue[];
|
|
22
|
+
area_lt?: string | OsmchaFilterValue[];
|
|
23
|
+
[key: string]: string | OsmchaFilterValue[] | undefined;
|
|
24
|
+
};
|
|
25
|
+
/** Build `https://osmcha.org/?filters=<JSON>` deep link. */
|
|
26
|
+
export declare function osmchaFiltersUrl(filters: OsmchaFiltersInput): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type TildaFeatureCoord = {
|
|
2
|
+
kind: 'point';
|
|
3
|
+
lon: number;
|
|
4
|
+
lat: number;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'bbox';
|
|
7
|
+
minLon: number;
|
|
8
|
+
minLat: number;
|
|
9
|
+
maxLon: number;
|
|
10
|
+
maxLat: number;
|
|
11
|
+
};
|
|
12
|
+
export type TildaFeatureParam = {
|
|
13
|
+
/** TILDA source name (e.g. `atlas_bikelanes`) or numeric id. */
|
|
14
|
+
sourceId: string | number;
|
|
15
|
+
/** Feature id: `way/123` or numeric Lars id. */
|
|
16
|
+
featureId: string | number;
|
|
17
|
+
coords: TildaFeatureCoord;
|
|
18
|
+
};
|
|
19
|
+
/** Build TILDA `f` query value from one or more features. */
|
|
20
|
+
export declare function serializeTildaFeaturesParam(features: TildaFeatureParam | TildaFeatureParam[]): string | undefined;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { serializeTildaFeaturesParam, type TildaFeatureCoord, type TildaFeatureParam, } from './features-param';
|
|
2
|
+
export { TILDA_INFRA_PRESETS, tildaInfraSourceNumericId, tildaInspectorUrl, tildaInspectorUrlForInfra, type TildaInfra, type TildaInfraPreset, type TildaInspectorForInfraOptions, type TildaInspectorUrlOptions, type TildaMapPosition, } from './inspector';
|
|
3
|
+
export { TILDA_SOURCE_NUMERIC_IDS, tildaSourceIdFromNumeric, tildaSourceNumericId } from './sources';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type TildaFeatureCoord, type TildaFeatureParam } from './features-param';
|
|
2
|
+
export type TildaInfra = 'bikelanes' | 'parking';
|
|
3
|
+
export type TildaInfraPreset = {
|
|
4
|
+
regionSlug: string;
|
|
5
|
+
sourceId: string;
|
|
6
|
+
/** Layer visibility config; drifts in TILDA — override per call if needed. */
|
|
7
|
+
defaultConfig: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Infra → public TILDA region presets.
|
|
11
|
+
* Roads (width/surface/lanes) have no public region — omit those callers.
|
|
12
|
+
*/
|
|
13
|
+
export declare const TILDA_INFRA_PRESETS: Record<TildaInfra, TildaInfraPreset>;
|
|
14
|
+
export type TildaMapPosition = {
|
|
15
|
+
zoom: number;
|
|
16
|
+
lat: number;
|
|
17
|
+
lng: number;
|
|
18
|
+
};
|
|
19
|
+
export type TildaInspectorUrlOptions = {
|
|
20
|
+
regionSlug: string;
|
|
21
|
+
map: TildaMapPosition;
|
|
22
|
+
config?: string;
|
|
23
|
+
features?: TildaFeatureParam | TildaFeatureParam[];
|
|
24
|
+
version?: number;
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
};
|
|
27
|
+
/** Full TILDA region inspector deeplink (`map` + optional `config` + `f` + `v`). */
|
|
28
|
+
export declare function tildaInspectorUrl(options: TildaInspectorUrlOptions): string;
|
|
29
|
+
export type TildaInspectorForInfraOptions = {
|
|
30
|
+
map: TildaMapPosition;
|
|
31
|
+
/** Required for feature-level `f`; omit for viewport-only links. */
|
|
32
|
+
featureId?: string | number;
|
|
33
|
+
coords?: TildaFeatureCoord;
|
|
34
|
+
config?: string;
|
|
35
|
+
version?: number;
|
|
36
|
+
baseUrl?: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Build inspector URL for a known infra preset.
|
|
40
|
+
* Returns viewport-only URL when `featureId`/`coords` are omitted.
|
|
41
|
+
* Returns `null` only when map position is incomplete (should not happen with typed input).
|
|
42
|
+
*/
|
|
43
|
+
export declare function tildaInspectorUrlForInfra(infra: TildaInfra, options: TildaInspectorForInfraOptions): string;
|
|
44
|
+
export declare function tildaInfraSourceNumericId(infra: TildaInfra): number | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TILDA `f` parameter sourceNumericId ↔ source name.
|
|
3
|
+
* Mirrors tilda-geo `useFeaturesParam/url.ts` (atlas / Lars / Mapillary / TILDA parking).
|
|
4
|
+
*/
|
|
5
|
+
export declare const TILDA_SOURCE_NUMERIC_IDS: Record<number, string>;
|
|
6
|
+
/** Resolve TILDA source name → compact numeric id used in `f=`. */
|
|
7
|
+
export declare function tildaSourceNumericId(sourceId: string): number | undefined;
|
|
8
|
+
export declare function tildaSourceIdFromNumeric(numericId: number): string | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osm-editor-kit/osm-editor-links",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "OpenStreetMap link lists for elements, changesets and users (editors, history, viewers, imagery), with JOSM remote-control helpers.",
|
|
5
|
+
"homepage": "https://github.com/osmberlin/street-space-editor/tree/main/packages/osm-editor-links",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Tobias Jordans",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/osmberlin/street-space-editor.git",
|
|
11
|
+
"directory": "packages/osm-editor-links"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"tag": "alpha"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup && rm -f .tsbuildinfo && tsc -p tsconfig.build.json",
|
|
31
|
+
"type-check": "tsc --noEmit",
|
|
32
|
+
"test-run": "bun test src/test",
|
|
33
|
+
"prepublishOnly": "bun run build && bun ../../scripts/package-exports-for-publish.ts",
|
|
34
|
+
"postpublish": "bun ../../scripts/package-exports-restore.ts",
|
|
35
|
+
"prepack": "bun ../../scripts/package-exports-for-publish.ts",
|
|
36
|
+
"postpack": "bun ../../scripts/package-exports-restore.ts"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@osm-editor-kit/osm-data": "^0.1.0-alpha.1"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"bun-types": "^1.2.20",
|
|
43
|
+
"typescript": "^7.0.0"
|
|
44
|
+
},
|
|
45
|
+
"publishExports": {
|
|
46
|
+
".": {
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"import": "./dist/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
}
|
|
52
|
+
}
|