@osmix/shared 0.0.1 → 0.0.6

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 (125) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +49 -19
  3. package/dist/src/assert.d.ts +24 -0
  4. package/dist/src/assert.d.ts.map +1 -0
  5. package/dist/src/assert.js +28 -0
  6. package/dist/src/assert.js.map +1 -0
  7. package/dist/src/bbox-intersects.d.ts +15 -0
  8. package/dist/src/bbox-intersects.d.ts.map +1 -0
  9. package/dist/src/bbox-intersects.js +24 -0
  10. package/dist/src/bbox-intersects.js.map +1 -0
  11. package/dist/src/bytes-to-stream.d.ts +18 -0
  12. package/dist/src/bytes-to-stream.d.ts.map +1 -0
  13. package/dist/src/bytes-to-stream.js +25 -0
  14. package/dist/src/bytes-to-stream.js.map +1 -0
  15. package/dist/src/concat-bytes.d.ts +5 -0
  16. package/dist/src/concat-bytes.d.ts.map +1 -0
  17. package/dist/src/concat-bytes.js +14 -0
  18. package/dist/src/concat-bytes.js.map +1 -0
  19. package/dist/src/coordinates.d.ts +28 -0
  20. package/dist/src/coordinates.d.ts.map +1 -0
  21. package/dist/src/coordinates.js +38 -0
  22. package/dist/src/coordinates.js.map +1 -0
  23. package/dist/src/haversine-distance.d.ts +16 -0
  24. package/dist/src/haversine-distance.d.ts.map +1 -0
  25. package/dist/src/haversine-distance.js +26 -0
  26. package/dist/src/haversine-distance.js.map +1 -0
  27. package/dist/src/lineclip.d.ts +2 -0
  28. package/dist/src/lineclip.d.ts.map +1 -0
  29. package/dist/src/lineclip.js +3 -0
  30. package/dist/src/lineclip.js.map +1 -0
  31. package/dist/src/progress.d.ts +40 -0
  32. package/dist/src/progress.d.ts.map +1 -0
  33. package/dist/src/progress.js +40 -0
  34. package/dist/src/progress.js.map +1 -0
  35. package/dist/src/relation-kind.d.ts +69 -0
  36. package/dist/src/relation-kind.d.ts.map +1 -0
  37. package/dist/src/relation-kind.js +375 -0
  38. package/dist/src/relation-kind.js.map +1 -0
  39. package/dist/src/relation-multipolygon.d.ts +43 -0
  40. package/dist/src/relation-multipolygon.d.ts.map +1 -0
  41. package/dist/src/relation-multipolygon.js +195 -0
  42. package/dist/src/relation-multipolygon.js.map +1 -0
  43. package/dist/src/stream-to-bytes.d.ts +18 -0
  44. package/dist/src/stream-to-bytes.d.ts.map +1 -0
  45. package/dist/src/stream-to-bytes.js +30 -0
  46. package/dist/src/stream-to-bytes.js.map +1 -0
  47. package/dist/src/test/fixtures.d.ts +36 -0
  48. package/dist/src/test/fixtures.d.ts.map +1 -0
  49. package/dist/src/test/fixtures.js +172 -0
  50. package/dist/src/test/fixtures.js.map +1 -0
  51. package/dist/src/throttle.d.ts +25 -0
  52. package/dist/src/throttle.d.ts.map +1 -0
  53. package/dist/src/throttle.js +34 -0
  54. package/dist/src/throttle.js.map +1 -0
  55. package/dist/src/tile.d.ts +34 -0
  56. package/dist/src/tile.d.ts.map +1 -0
  57. package/dist/src/tile.js +72 -0
  58. package/dist/src/tile.js.map +1 -0
  59. package/dist/src/transform-bytes.d.ts +24 -0
  60. package/dist/src/transform-bytes.d.ts.map +1 -0
  61. package/dist/src/transform-bytes.js +28 -0
  62. package/dist/src/transform-bytes.js.map +1 -0
  63. package/dist/src/types.d.ts +99 -0
  64. package/dist/src/types.d.ts.map +1 -0
  65. package/dist/src/types.js +9 -0
  66. package/dist/src/types.js.map +1 -0
  67. package/dist/src/utils.d.ts +30 -0
  68. package/dist/src/utils.d.ts.map +1 -0
  69. package/dist/src/utils.js +70 -0
  70. package/dist/src/utils.js.map +1 -0
  71. package/dist/src/way-is-area.d.ts +24 -0
  72. package/dist/src/way-is-area.d.ts.map +1 -0
  73. package/dist/src/way-is-area.js +104 -0
  74. package/dist/src/way-is-area.js.map +1 -0
  75. package/dist/src/zigzag.d.ts +33 -0
  76. package/dist/src/zigzag.d.ts.map +1 -0
  77. package/dist/src/zigzag.js +40 -0
  78. package/dist/src/zigzag.js.map +1 -0
  79. package/dist/test/haversine-distance.test.d.ts +2 -0
  80. package/dist/test/haversine-distance.test.d.ts.map +1 -0
  81. package/dist/test/haversine-distance.test.js +8 -0
  82. package/dist/test/haversine-distance.test.js.map +1 -0
  83. package/dist/test/relation-kind.test.d.ts +2 -0
  84. package/dist/test/relation-kind.test.d.ts.map +1 -0
  85. package/dist/test/relation-kind.test.js +367 -0
  86. package/dist/test/relation-kind.test.js.map +1 -0
  87. package/dist/test/relation-multipolygon.test.d.ts +2 -0
  88. package/dist/test/relation-multipolygon.test.d.ts.map +1 -0
  89. package/dist/test/relation-multipolygon.test.js +237 -0
  90. package/dist/test/relation-multipolygon.test.js.map +1 -0
  91. package/dist/test/utils.test.d.ts +2 -0
  92. package/dist/test/utils.test.d.ts.map +1 -0
  93. package/dist/test/utils.test.js +76 -0
  94. package/dist/test/utils.test.js.map +1 -0
  95. package/dist/test/way-is-area.test.d.ts +2 -0
  96. package/dist/test/way-is-area.test.d.ts.map +1 -0
  97. package/dist/test/way-is-area.test.js +31 -0
  98. package/dist/test/way-is-area.test.js.map +1 -0
  99. package/package.json +9 -7
  100. package/src/assert.ts +21 -1
  101. package/src/bbox-intersects.ts +30 -0
  102. package/src/bytes-to-stream.ts +17 -0
  103. package/src/coordinates.ts +45 -0
  104. package/src/haversine-distance.ts +10 -1
  105. package/src/progress.ts +55 -0
  106. package/src/relation-kind.ts +446 -0
  107. package/src/relation-multipolygon.ts +225 -0
  108. package/src/stream-to-bytes.ts +17 -0
  109. package/src/test/fixtures.ts +18 -14
  110. package/src/throttle.ts +37 -0
  111. package/src/tile.ts +89 -0
  112. package/src/transform-bytes.ts +23 -0
  113. package/src/types.ts +93 -1
  114. package/src/utils.ts +79 -0
  115. package/src/way-is-area.ts +107 -0
  116. package/src/zigzag.ts +42 -0
  117. package/test/haversine-distance.test.ts +2 -2
  118. package/test/relation-kind.test.ts +426 -0
  119. package/test/relation-multipolygon.test.ts +265 -0
  120. package/test/utils.test.ts +103 -0
  121. package/test/way-is-area.test.ts +42 -0
  122. package/tsconfig/base.json +2 -0
  123. package/tsconfig/test.json +1 -0
  124. package/src/spherical-mercator.test.ts +0 -42
  125. package/src/spherical-mercator.ts +0 -42
@@ -0,0 +1,103 @@
1
+ import { describe, expect, it } from "bun:test"
2
+ import type {
3
+ OsmNode,
4
+ OsmRelation,
5
+ OsmRelationMember,
6
+ OsmWay,
7
+ } from "../src/types"
8
+ import {
9
+ entityPropertiesEqual,
10
+ getEntityType,
11
+ isMultipolygonRelation,
12
+ isNode,
13
+ isNodeEqual,
14
+ isRelation,
15
+ isRelationEqual,
16
+ isWay,
17
+ isWayEqual,
18
+ } from "../src/utils"
19
+
20
+ describe("utils", () => {
21
+ const node: OsmNode = {
22
+ id: 1,
23
+ lat: 10,
24
+ lon: 20,
25
+ tags: { name: "node" },
26
+ }
27
+ const way: OsmWay = {
28
+ id: 2,
29
+ refs: [1, 2, 3],
30
+ tags: { highway: "residential" },
31
+ }
32
+ const members: OsmRelationMember[] = [
33
+ {
34
+ type: "node",
35
+ ref: 1,
36
+ },
37
+ ]
38
+ const relation: OsmRelation = {
39
+ id: 3,
40
+ members,
41
+ tags: { type: "multipolygon" },
42
+ }
43
+
44
+ it("narrows entity types", () => {
45
+ expect(isNode(node)).toBe(true)
46
+ expect(isWay(way)).toBe(true)
47
+ expect(isRelation(relation)).toBe(true)
48
+ })
49
+
50
+ it("compares entity equality", () => {
51
+ expect(isNodeEqual(node, { ...node })).toBe(true)
52
+ expect(isWayEqual(way, { ...way })).toBe(true)
53
+ expect(isRelationEqual(relation, { ...relation })).toBe(true)
54
+ })
55
+
56
+ it("detects property differences", () => {
57
+ expect(
58
+ entityPropertiesEqual(node, { ...node, tags: { name: "changed" } }),
59
+ ).toBe(false)
60
+ expect(entityPropertiesEqual(way, { ...way, refs: [1, 2, 4] })).toBe(false)
61
+ expect(
62
+ entityPropertiesEqual(relation, {
63
+ ...relation,
64
+ members: [{ type: "node", ref: 2 }],
65
+ }),
66
+ ).toBe(false)
67
+ })
68
+
69
+ it("provides entity type", () => {
70
+ expect(getEntityType(node)).toBe("node")
71
+ expect(getEntityType(way)).toBe("way")
72
+ expect(getEntityType(relation)).toBe("relation")
73
+ })
74
+
75
+ describe("isMultipolygonRelation", () => {
76
+ it("identifies multipolygon relations", () => {
77
+ const relation: OsmRelation = {
78
+ id: 1,
79
+ tags: { type: "multipolygon" },
80
+ members: [],
81
+ }
82
+ expect(isMultipolygonRelation(relation)).toBe(true)
83
+ })
84
+
85
+ it("rejects non-multipolygon relations", () => {
86
+ const relation: OsmRelation = {
87
+ id: 1,
88
+ tags: { type: "route" },
89
+ members: [],
90
+ }
91
+ expect(isMultipolygonRelation(relation)).toBe(false)
92
+ })
93
+
94
+ it("rejects relations without type tag", () => {
95
+ const relation: OsmRelation = {
96
+ id: 1,
97
+ tags: { name: "test" },
98
+ members: [],
99
+ }
100
+ expect(isMultipolygonRelation(relation)).toBe(false)
101
+ })
102
+ })
103
+ })
@@ -0,0 +1,42 @@
1
+ import { describe, expect, it } from "bun:test"
2
+ import { wayIsArea } from "../src/way-is-area"
3
+
4
+ describe("wayIsArea", () => {
5
+ it("returns false for open ways", () => {
6
+ const refs = [1, 2, 3]
7
+ expect(wayIsArea({ id: 0, refs, tags: { building: "yes" } })).toBe(false)
8
+ })
9
+
10
+ it("returns true for closed way without tags", () => {
11
+ const refs = [1, 2, 3, 1]
12
+ expect(wayIsArea({ id: 0, refs })).toBe(true)
13
+ })
14
+
15
+ it("honors explicit area override", () => {
16
+ const refs = [1, 2, 3, 1]
17
+ expect(
18
+ wayIsArea({ id: 0, refs, tags: { area: "no", building: "yes" } }),
19
+ ).toBe(false)
20
+ expect(wayIsArea({ id: 0, refs, tags: { area: "yes" } })).toBe(true)
21
+ })
22
+
23
+ it("treats implied tags as areas", () => {
24
+ const refs = [1, 2, 3, 1]
25
+ expect(wayIsArea({ id: 0, refs, tags: { building: "yes" } })).toBe(true)
26
+ })
27
+
28
+ it("considers included values", () => {
29
+ const refs = [1, 2, 3, 1]
30
+ expect(wayIsArea({ id: 0, refs, tags: { highway: "rest_area" } })).toBe(
31
+ true,
32
+ )
33
+ expect(wayIsArea({ id: 0, refs, tags: { highway: "primary" } })).toBe(false)
34
+ })
35
+
36
+ it("rejects excluded values", () => {
37
+ const refs = [1, 2, 3, 1]
38
+ expect(wayIsArea({ id: 0, refs, tags: { natural: "coastline" } })).toBe(
39
+ false,
40
+ )
41
+ })
42
+ })
@@ -17,9 +17,11 @@
17
17
  "isolatedModules": true,
18
18
  "erasableSyntaxOnly": true,
19
19
  "skipLibCheck": true,
20
+ "forceConsistentCasingInFileNames": true,
20
21
 
21
22
  "strict": true,
22
23
  "noFallthroughCasesInSwitch": true,
24
+ "noImplicitOverride": true,
23
25
  "noUncheckedIndexedAccess": true,
24
26
  "noUnusedLocals": true,
25
27
  "noUnusedParameters": true,
@@ -2,6 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/tsconfig",
3
3
  "display": "@osmix/tsconfig/test",
4
4
  "extends": "./base.json",
5
+ "exclude": ["node_modules", "dist"],
5
6
  "compilerOptions": {
6
7
  "noEmit": true,
7
8
 
@@ -1,42 +0,0 @@
1
- import { describe, expect, it } from "vitest"
2
- import SphericalMercatorTile from "./spherical-mercator"
3
- import type { Tile } from "./types"
4
-
5
- function lonLatForPixel(
6
- merc: SphericalMercatorTile,
7
- tileIndex: Tile,
8
- tileSize: number,
9
- px: number,
10
- py: number,
11
- ): [number, number] {
12
- const [x, y, z] = tileIndex
13
- return merc.ll([x * tileSize + px, y * tileSize + py], z) as [number, number]
14
- }
15
-
16
- describe("SphericalMercatorTile", () => {
17
- it("projects lon/lat to tile-local pixels", () => {
18
- const tile: Tile = [300, 300, 10]
19
- const [tx, ty, tz] = tile
20
- const tileSize = 256
21
- const merc = new SphericalMercatorTile({ size: tileSize, tile })
22
-
23
- const insideLonLat = lonLatForPixel(merc, tile, tileSize, 32, 16)
24
- expect(merc.llToTilePx(insideLonLat)).toEqual([32, 16])
25
-
26
- const outsideTopLeft = merc.ll(
27
- [tx * tileSize - 10, ty * tileSize - 10],
28
- tz,
29
- ) as [number, number]
30
- expect(outsideTopLeft).toEqual([-74.54498291015625, 59.54128017205441])
31
- expect(merc.llToTilePx(outsideTopLeft)).toEqual([-10, -10])
32
-
33
- const outsideBottomRight = merc.ll(
34
- [(tx + 1) * tileSize + 10, (ty + 1) * tileSize + 10],
35
- tz,
36
- ) as [number, number]
37
- expect(merc.llToTilePx(outsideBottomRight, tile)).toEqual([
38
- tileSize + 10,
39
- tileSize + 10,
40
- ])
41
- })
42
- })
@@ -1,42 +0,0 @@
1
- import { SphericalMercator } from "@mapbox/sphericalmercator"
2
- import type { GeoBbox2D, LonLat, Tile, XY } from "./types"
3
-
4
- /**
5
- * Extends the SphericalMercator class to provide tile-local pixel coordinate calculations and clamping.
6
- */
7
- export default class SphericalMercatorTile extends SphericalMercator {
8
- tileSize: number
9
- tile?: Tile
10
- constructor(
11
- options: ConstructorParameters<typeof SphericalMercator>[0] & {
12
- tile?: Tile
13
- },
14
- ) {
15
- super(options)
16
- this.tile = options?.tile
17
- this.tileSize = options?.size ?? 256
18
- }
19
-
20
- llToTilePx(ll: LonLat, tile?: Tile): XY {
21
- if (tile == null && this.tile == null)
22
- throw Error("Tile must be set on construction or passed as an argument.")
23
- const [tx, ty, tz] = (tile ?? this.tile)!
24
- const merc = this.px(ll, tz)
25
- const x = merc[0] - tx * this.tileSize
26
- const y = merc[1] - ty * this.tileSize
27
- return [x, y]
28
- }
29
-
30
- clampAndRoundPx(px: XY, bbox?: GeoBbox2D): XY {
31
- const [minX, minY, maxX, maxY] = bbox ?? [
32
- 0,
33
- 0,
34
- this.tileSize,
35
- this.tileSize,
36
- ]
37
- return [
38
- Math.max(minX, Math.min(maxX, Math.round(px[0]))),
39
- Math.max(minY, Math.min(maxY, Math.round(px[1]))),
40
- ]
41
- }
42
- }