@kahwee/sf-map-svg 0.3.0 → 1.0.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/CHANGELOG.md +26 -0
- package/LICENSE +23 -4
- package/README.md +213 -2
- package/SOURCES.md +4 -0
- package/{data → dist/data}/README.md +1 -0
- package/dist/data/bart-stations.json +134 -0
- package/dist/data/catalog.json +4718 -0
- package/dist/data/coast.json +36 -0
- package/dist/data/districts-2002.json +325 -0
- package/dist/data/districts-2012.json +325 -0
- package/dist/data/districts-2022.json +325 -0
- package/dist/data/highways.json +4138 -0
- package/dist/data/index.d.ts +26 -0
- package/{data → dist/data}/index.js +37 -39
- package/dist/data/key-roads.json +12662 -0
- package/dist/data/landmarks.json +167 -0
- package/dist/data/neighborhoods-analysis.json +817 -0
- package/dist/data/neighborhoods-realtor.json +1978 -0
- package/dist/data/neighborhoods.json +2267 -0
- package/dist/data/types.d.ts +117 -0
- package/dist/data/types.js +1 -0
- package/dist/src/data.d.ts +25 -0
- package/{src → dist/src}/data.js +17 -20
- package/dist/src/explorer-layout.d.ts +23 -0
- package/dist/src/explorer-layout.js +72 -0
- package/dist/src/explorer.d.ts +4 -0
- package/dist/src/explorer.js +955 -0
- package/dist/src/geometry.d.ts +5 -0
- package/dist/src/geometry.js +53 -0
- package/dist/src/immutable.d.ts +2 -0
- package/dist/src/immutable.js +9 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.js +125 -0
- package/dist/src/interactive.d.ts +4 -0
- package/dist/src/interactive.js +5 -0
- package/dist/src/layers.d.ts +36 -0
- package/dist/src/layers.js +64 -0
- package/dist/src/navigation.d.ts +6 -0
- package/dist/src/navigation.js +145 -0
- package/dist/src/overlays.d.ts +25 -0
- package/dist/src/overlays.js +15 -0
- package/dist/src/svg.d.ts +4 -0
- package/dist/src/svg.js +7 -0
- package/dist/src/types.d.ts +108 -0
- package/dist/src/types.js +1 -0
- package/dist/src/viewport.d.ts +5 -0
- package/dist/src/viewport.js +27 -0
- package/package.json +34 -24
- package/data/bart-stations.json +0 -134
- package/data/catalog.json +0 -4699
- package/data/coast.json +0 -36
- package/data/districts-2002.json +0 -325
- package/data/districts-2012.json +0 -325
- package/data/districts-2022.json +0 -325
- package/data/highways.json +0 -4138
- package/data/index.d.ts +0 -117
- package/data/landmarks.json +0 -167
- package/data/neighborhoods-analysis.json +0 -817
- package/data/neighborhoods-realtor.json +0 -1978
- package/data/neighborhoods.json +0 -2267
- package/src/geometry.d.ts +0 -8
- package/src/geometry.js +0 -51
- package/src/immutable.js +0 -8
- package/src/index.d.ts +0 -51
- package/src/index.js +0 -122
- package/src/layers.js +0 -54
- package/src/overlays.js +0 -18
- package/src/svg.js +0 -12
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Bounds } from '../data/types.js';
|
|
2
|
+
import type { MapPadding, MapViewport } from './types.js';
|
|
3
|
+
export declare function validateViewport(view: MapViewport): import("./explorer-layout.js").View;
|
|
4
|
+
/** Fit bounds in the unobscured screen area, then constrain to the city extent. */
|
|
5
|
+
export declare function fitViewport(bounds: Bounds, width: number, padding?: number | MapPadding): import("./explorer-layout.js").View;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { clampView } from './explorer-layout.js';
|
|
2
|
+
export function validateViewport(view) {
|
|
3
|
+
if (view.length !== 3 || !view.every(Number.isFinite) || view[2] <= 0)
|
|
4
|
+
throw new RangeError('Viewport must contain finite x, y, and a positive size.');
|
|
5
|
+
return clampView([...view]);
|
|
6
|
+
}
|
|
7
|
+
/** Fit bounds in the unobscured screen area, then constrain to the city extent. */
|
|
8
|
+
export function fitViewport(bounds, width, padding = 24) {
|
|
9
|
+
const p = typeof padding === 'number'
|
|
10
|
+
? { top: padding, right: padding, bottom: padding, left: padding }
|
|
11
|
+
: padding;
|
|
12
|
+
const { top = 0, right = 0, bottom = 0, left = 0 } = p;
|
|
13
|
+
if (![width, top, right, bottom, left, ...bounds].every(Number.isFinite) ||
|
|
14
|
+
Math.min(top, right, bottom, left) < 0 ||
|
|
15
|
+
width <= left + right ||
|
|
16
|
+
width <= top + bottom ||
|
|
17
|
+
bounds[0] > bounds[2] ||
|
|
18
|
+
bounds[1] > bounds[3])
|
|
19
|
+
throw new RangeError('Fit requires nonempty finite geometry and padding smaller than the viewport.');
|
|
20
|
+
const size = Math.max(800 / 12, Math.min(800, ((bounds[2] - bounds[0]) * width) / (width - left - right)));
|
|
21
|
+
const fittedSize = Math.max(size, Math.min(800, ((bounds[3] - bounds[1]) * width) / (width - top - bottom)));
|
|
22
|
+
return clampView([
|
|
23
|
+
(bounds[0] + bounds[2]) / 2 - fittedSize / 2 - ((left - right) * fittedSize) / width / 2,
|
|
24
|
+
(bounds[1] + bounds[3]) / 2 - fittedSize / 2 - ((top - bottom) * fittedSize) / width / 2,
|
|
25
|
+
fittedSize,
|
|
26
|
+
]);
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,47 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kahwee/sf-map-svg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Offline SVG maps of San Francisco with district boundaries, parks, landmarks, and BART stations.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./src/index.js",
|
|
7
|
-
"types": "./src/index.d.ts",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"types": "./src/index.d.ts",
|
|
11
|
-
"import": "./src/index.js"
|
|
10
|
+
"types": "./dist/src/index.d.ts",
|
|
11
|
+
"import": "./dist/src/index.js"
|
|
12
12
|
},
|
|
13
13
|
"./data": {
|
|
14
|
-
"types": "./data/index.d.ts",
|
|
15
|
-
"import": "./data/index.js"
|
|
14
|
+
"types": "./dist/data/index.d.ts",
|
|
15
|
+
"import": "./dist/data/index.js"
|
|
16
16
|
},
|
|
17
|
-
"./data/*.json": "./data/*.json",
|
|
17
|
+
"./data/*.json": "./dist/data/*.json",
|
|
18
18
|
"./geometry": {
|
|
19
|
-
"types": "./src/geometry.d.ts",
|
|
20
|
-
"import": "./src/geometry.js"
|
|
19
|
+
"types": "./dist/src/geometry.d.ts",
|
|
20
|
+
"import": "./dist/src/geometry.js"
|
|
21
|
+
},
|
|
22
|
+
"./explorer": {
|
|
23
|
+
"types": "./dist/src/explorer.d.ts",
|
|
24
|
+
"import": "./dist/src/explorer.js"
|
|
25
|
+
},
|
|
26
|
+
"./interactive": {
|
|
27
|
+
"types": "./dist/src/interactive.d.ts",
|
|
28
|
+
"import": "./dist/src/interactive.js"
|
|
21
29
|
}
|
|
22
30
|
},
|
|
23
31
|
"files": [
|
|
24
|
-
"
|
|
32
|
+
"dist",
|
|
25
33
|
"README.md",
|
|
26
34
|
"SOURCES.md",
|
|
27
|
-
"LICENSE"
|
|
28
|
-
"data"
|
|
35
|
+
"LICENSE"
|
|
29
36
|
],
|
|
30
37
|
"sideEffects": false,
|
|
31
38
|
"repository": {
|
|
32
39
|
"type": "git",
|
|
33
40
|
"url": "git+https://github.com/kahwee/sf-map-svg.git"
|
|
34
41
|
},
|
|
35
|
-
"license": "
|
|
42
|
+
"license": "MIT",
|
|
36
43
|
"engines": {
|
|
37
44
|
"node": ">=22.12.0"
|
|
38
45
|
},
|
|
39
46
|
"devDependencies": {
|
|
47
|
+
"@biomejs/biome": "2.5.14",
|
|
40
48
|
"@storybook/addon-docs": "^10.6.0",
|
|
41
49
|
"@storybook/html-vite": "^10.6.0",
|
|
42
50
|
"@xmldom/xmldom": "^0.9.12",
|
|
43
51
|
"polygon-clipping": "^0.15.7",
|
|
44
|
-
"prettier": "^3.9.9",
|
|
45
52
|
"storybook": "^10.6.0",
|
|
46
53
|
"typescript": "^7.0.2",
|
|
47
54
|
"vite": "^8.3.1"
|
|
@@ -62,16 +69,19 @@
|
|
|
62
69
|
"registry": "https://registry.npmjs.org/"
|
|
63
70
|
},
|
|
64
71
|
"scripts": {
|
|
65
|
-
"test": "node --test",
|
|
66
|
-
"demo": "node examples/build.mjs",
|
|
67
|
-
"format": "
|
|
68
|
-
"format:check": "
|
|
69
|
-
"check": "pnpm
|
|
70
|
-
"storybook": "storybook dev -p 6006 --host 127.0.0.1 --no-open",
|
|
71
|
-
"build-storybook": "storybook build",
|
|
72
|
+
"test": "pnpm build && node --test",
|
|
73
|
+
"demo": "pnpm build && node examples/build.mjs",
|
|
74
|
+
"format": "biome check --write .",
|
|
75
|
+
"format:check": "biome format .",
|
|
76
|
+
"check": "pnpm lint && pnpm data:check && pnpm typecheck && pnpm test",
|
|
77
|
+
"storybook": "pnpm build && storybook dev -p 6006 --host 127.0.0.1 --no-open",
|
|
78
|
+
"build-storybook": "pnpm build && storybook build",
|
|
72
79
|
"data:catalog": "node scripts/build-data-catalog.mjs",
|
|
73
80
|
"data:check": "node scripts/build-data-catalog.mjs --check",
|
|
74
|
-
"typecheck": "tsc",
|
|
75
|
-
"data:normalize-realtor": "node scripts/normalize-realtor.mjs"
|
|
81
|
+
"typecheck": "pnpm build && tsc -p tsconfig.json",
|
|
82
|
+
"data:normalize-realtor": "node scripts/normalize-realtor.mjs",
|
|
83
|
+
"test:package": "node scripts/smoke-package.mjs",
|
|
84
|
+
"build": "node scripts/build.mjs",
|
|
85
|
+
"lint": "biome check ."
|
|
76
86
|
}
|
|
77
87
|
}
|
package/data/bart-stations.json
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"type": "FeatureCollection",
|
|
3
|
-
"schemaVersion": 1,
|
|
4
|
-
"id": "bart-stations",
|
|
5
|
-
"title": "San Francisco BART stations",
|
|
6
|
-
"coordinateSystem": "WGS84 longitude, latitude (EPSG:4326)",
|
|
7
|
-
"definition": {
|
|
8
|
-
"kind": "station-centroids",
|
|
9
|
-
"description": "Eight station centroids within San Francisco. Entrances, tracks, and other cities are excluded."
|
|
10
|
-
},
|
|
11
|
-
"sources": [
|
|
12
|
-
{
|
|
13
|
-
"id": "bart-stations",
|
|
14
|
-
"title": "BART official geospatial data",
|
|
15
|
-
"url": "https://www.bart.gov/sites/default/files/2025-12/BART-Stations-tracks-entrances-121025.kmz_.zip",
|
|
16
|
-
"retrievedAt": "2026-09-25",
|
|
17
|
-
"licenseUrl": "https://www.bart.gov/schedules/developers/geo"
|
|
18
|
-
}
|
|
19
|
-
],
|
|
20
|
-
"features": [
|
|
21
|
-
{
|
|
22
|
-
"type": "Feature",
|
|
23
|
-
"id": "embarcadero",
|
|
24
|
-
"bbox": [
|
|
25
|
-
-122.3969009943399,
|
|
26
|
-
37.79285391372556,
|
|
27
|
-
-122.3969009943399,
|
|
28
|
-
37.79285391372556
|
|
29
|
-
],
|
|
30
|
-
"properties": {
|
|
31
|
-
"name": "Embarcadero"
|
|
32
|
-
},
|
|
33
|
-
"geometry": {"type":"Point","coordinates":[-122.3969009943399,37.79285391372556]}
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"type": "Feature",
|
|
37
|
-
"id": "montgomery-st",
|
|
38
|
-
"bbox": [
|
|
39
|
-
-122.4011747105981,
|
|
40
|
-
37.78944952039284,
|
|
41
|
-
-122.4011747105981,
|
|
42
|
-
37.78944952039284
|
|
43
|
-
],
|
|
44
|
-
"properties": {
|
|
45
|
-
"name": "Montgomery St"
|
|
46
|
-
},
|
|
47
|
-
"geometry": {"type":"Point","coordinates":[-122.4011747105981,37.78944952039284]}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"type": "Feature",
|
|
51
|
-
"id": "powell-st",
|
|
52
|
-
"bbox": [
|
|
53
|
-
-122.4070176588271,
|
|
54
|
-
37.78487089662774,
|
|
55
|
-
-122.4070176588271,
|
|
56
|
-
37.78487089662774
|
|
57
|
-
],
|
|
58
|
-
"properties": {
|
|
59
|
-
"name": "Powell St"
|
|
60
|
-
},
|
|
61
|
-
"geometry": {"type":"Point","coordinates":[-122.4070176588271,37.78487089662774]}
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"type": "Feature",
|
|
65
|
-
"id": "civic-center-un-plaza",
|
|
66
|
-
"bbox": [
|
|
67
|
-
-122.4139364152156,
|
|
68
|
-
37.77939386076284,
|
|
69
|
-
-122.4139364152156,
|
|
70
|
-
37.77939386076284
|
|
71
|
-
],
|
|
72
|
-
"properties": {
|
|
73
|
-
"name": "Civic Center/UN Plaza"
|
|
74
|
-
},
|
|
75
|
-
"geometry": {"type":"Point","coordinates":[-122.4139364152156,37.77939386076284]}
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"type": "Feature",
|
|
79
|
-
"id": "16th-st-mission",
|
|
80
|
-
"bbox": [
|
|
81
|
-
-122.4197081435103,
|
|
82
|
-
37.76505423932072,
|
|
83
|
-
-122.4197081435103,
|
|
84
|
-
37.76505423932072
|
|
85
|
-
],
|
|
86
|
-
"properties": {
|
|
87
|
-
"name": "16th St/Mission"
|
|
88
|
-
},
|
|
89
|
-
"geometry": {"type":"Point","coordinates":[-122.4197081435103,37.76505423932072]}
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
"type": "Feature",
|
|
93
|
-
"id": "24th-st-mission",
|
|
94
|
-
"bbox": [
|
|
95
|
-
-122.4184678760468,
|
|
96
|
-
37.75223145165559,
|
|
97
|
-
-122.4184678760468,
|
|
98
|
-
37.75223145165559
|
|
99
|
-
],
|
|
100
|
-
"properties": {
|
|
101
|
-
"name": "24th St/Mission"
|
|
102
|
-
},
|
|
103
|
-
"geometry": {"type":"Point","coordinates":[-122.4184678760468,37.75223145165559]}
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"type": "Feature",
|
|
107
|
-
"id": "glen-park",
|
|
108
|
-
"bbox": [
|
|
109
|
-
-122.4337900883829,
|
|
110
|
-
37.73311239451952,
|
|
111
|
-
-122.4337900883829,
|
|
112
|
-
37.73311239451952
|
|
113
|
-
],
|
|
114
|
-
"properties": {
|
|
115
|
-
"name": "Glen Park"
|
|
116
|
-
},
|
|
117
|
-
"geometry": {"type":"Point","coordinates":[-122.4337900883829,37.73311239451952]}
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
"type": "Feature",
|
|
121
|
-
"id": "balboa-park",
|
|
122
|
-
"bbox": [
|
|
123
|
-
-122.4475873574919,
|
|
124
|
-
37.72135058802738,
|
|
125
|
-
-122.4475873574919,
|
|
126
|
-
37.72135058802738
|
|
127
|
-
],
|
|
128
|
-
"properties": {
|
|
129
|
-
"name": "Balboa Park"
|
|
130
|
-
},
|
|
131
|
-
"geometry": {"type":"Point","coordinates":[-122.4475873574919,37.72135058802738]}
|
|
132
|
-
}
|
|
133
|
-
]
|
|
134
|
-
}
|