@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.
Files changed (68) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +23 -4
  3. package/README.md +213 -2
  4. package/SOURCES.md +4 -0
  5. package/{data → dist/data}/README.md +1 -0
  6. package/dist/data/bart-stations.json +134 -0
  7. package/dist/data/catalog.json +4718 -0
  8. package/dist/data/coast.json +36 -0
  9. package/dist/data/districts-2002.json +325 -0
  10. package/dist/data/districts-2012.json +325 -0
  11. package/dist/data/districts-2022.json +325 -0
  12. package/dist/data/highways.json +4138 -0
  13. package/dist/data/index.d.ts +26 -0
  14. package/{data → dist/data}/index.js +37 -39
  15. package/dist/data/key-roads.json +12662 -0
  16. package/dist/data/landmarks.json +167 -0
  17. package/dist/data/neighborhoods-analysis.json +817 -0
  18. package/dist/data/neighborhoods-realtor.json +1978 -0
  19. package/dist/data/neighborhoods.json +2267 -0
  20. package/dist/data/types.d.ts +117 -0
  21. package/dist/data/types.js +1 -0
  22. package/dist/src/data.d.ts +25 -0
  23. package/{src → dist/src}/data.js +17 -20
  24. package/dist/src/explorer-layout.d.ts +23 -0
  25. package/dist/src/explorer-layout.js +72 -0
  26. package/dist/src/explorer.d.ts +4 -0
  27. package/dist/src/explorer.js +955 -0
  28. package/dist/src/geometry.d.ts +5 -0
  29. package/dist/src/geometry.js +53 -0
  30. package/dist/src/immutable.d.ts +2 -0
  31. package/dist/src/immutable.js +9 -0
  32. package/dist/src/index.d.ts +13 -0
  33. package/dist/src/index.js +125 -0
  34. package/dist/src/interactive.d.ts +4 -0
  35. package/dist/src/interactive.js +5 -0
  36. package/dist/src/layers.d.ts +36 -0
  37. package/dist/src/layers.js +64 -0
  38. package/dist/src/navigation.d.ts +6 -0
  39. package/dist/src/navigation.js +145 -0
  40. package/dist/src/overlays.d.ts +25 -0
  41. package/dist/src/overlays.js +15 -0
  42. package/dist/src/svg.d.ts +4 -0
  43. package/dist/src/svg.js +7 -0
  44. package/dist/src/types.d.ts +108 -0
  45. package/dist/src/types.js +1 -0
  46. package/dist/src/viewport.d.ts +5 -0
  47. package/dist/src/viewport.js +27 -0
  48. package/package.json +34 -24
  49. package/data/bart-stations.json +0 -134
  50. package/data/catalog.json +0 -4699
  51. package/data/coast.json +0 -36
  52. package/data/districts-2002.json +0 -325
  53. package/data/districts-2012.json +0 -325
  54. package/data/districts-2022.json +0 -325
  55. package/data/highways.json +0 -4138
  56. package/data/index.d.ts +0 -117
  57. package/data/landmarks.json +0 -167
  58. package/data/neighborhoods-analysis.json +0 -817
  59. package/data/neighborhoods-realtor.json +0 -1978
  60. package/data/neighborhoods.json +0 -2267
  61. package/src/geometry.d.ts +0 -8
  62. package/src/geometry.js +0 -51
  63. package/src/immutable.js +0 -8
  64. package/src/index.d.ts +0 -51
  65. package/src/index.js +0 -122
  66. package/src/layers.js +0 -54
  67. package/src/overlays.js +0 -18
  68. 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.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
- "src",
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": "UNLICENSED",
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": "prettier --write .",
68
- "format:check": "prettier --check .",
69
- "check": "pnpm format:check && pnpm data:check && pnpm typecheck && pnpm test",
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
  }
@@ -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
- }