svgmapviewer-tools-osm 0.0.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/.vscode/settings.json +5 -0
- package/LICENSE +15 -0
- package/__pycache__/common.cpython-312.pyc +0 -0
- package/dist/geojsonToTs.js +15 -0
- package/eslint.config.js +58 -0
- package/oxlintrc.json +4 -0
- package/package.json +35 -0
- package/prettier.config.js +14 -0
- package/rslib.config.ts +22 -0
- package/rstest.config.ts +5 -0
- package/scripts/__pycache__/common.cpython-312.pyc +0 -0
- package/scripts/classifyGeometries.py +56 -0
- package/scripts/common.py +969 -0
- package/scripts/copy.sh +36 -0
- package/scripts/extractAreas.py +41 -0
- package/scripts/extractAreas.sh +20 -0
- package/scripts/extractLinesByIds.py +48 -0
- package/scripts/extractMultiLineStringsByIds.py +48 -0
- package/scripts/extractPointsByIds.py +42 -0
- package/scripts/extractPolygonsByIds.py +42 -0
- package/scripts/geojson2ts.py +79 -0
- package/scripts/getOsm.sh +62 -0
- package/scripts/initQgisPrj.py +44 -0
- package/scripts/makeAreas.py +21 -0
- package/scripts/makeAreas.sh +20 -0
- package/scripts/makeExtent.py +21 -0
- package/scripts/makeMeasures.py +25 -0
- package/scripts/makeOrigin.py +30 -0
- package/scripts/makeViewbox.py +22 -0
- package/scripts/osmconf.ini +122 -0
- package/scripts/pyqgis-Ubuntu.sh +36 -0
- package/scripts/pyqgis-macOS.sh +40 -0
- package/scripts/pyqgis.sh +34 -0
- package/scripts/readOsm.py +37 -0
- package/scripts/readOsm.sh +27 -0
- package/scripts/regen.sh +21 -0
- package/scripts/run-common.sh +3 -0
- package/scripts/tagAddresses.py +51 -0
- package/scripts/update.sh +53 -0
- package/src/geojsonToTs.ts +15 -0
- package/src/lib/geojson/geojson-print.test.ts +60 -0
- package/src/lib/geojson/geojson-print.ts +211 -0
- package/src/lib/geojson/geojson-schema.test.ts +42 -0
- package/src/lib/geojson/geojson-schema.ts +151 -0
- package/src/lib/geojson/geojson-types.ts +116 -0
- package/src/lib/osm.test.ts +17 -0
- package/src/lib/osm.ts +18 -0
- package/src/lib/print-utils.test.ts +12 -0
- package/src/lib/print-utils.ts +22 -0
- package/src/lib/print.ts +122 -0
- package/test/geojson.json +22 -0
- package/tsconfig.app.json +34 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node-browser.json +27 -0
- package/tsconfig.node.json +24 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Doc } from '@effect/printer'
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
_Coordinates,
|
|
5
|
+
_Crs,
|
|
6
|
+
_Feature,
|
|
7
|
+
_FeatureCollection,
|
|
8
|
+
_Features,
|
|
9
|
+
_GeoJSON,
|
|
10
|
+
_Geometry,
|
|
11
|
+
_Properties,
|
|
12
|
+
_Tuple,
|
|
13
|
+
_Value,
|
|
14
|
+
} from './geojson-types'
|
|
15
|
+
|
|
16
|
+
//// value
|
|
17
|
+
|
|
18
|
+
// XXX
|
|
19
|
+
export function truncNumber(n: number): number {
|
|
20
|
+
return Math.round(n * 1000000) / 1000000
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function printValue(v: _Value, comma: boolean): Doc.Doc<never> {
|
|
24
|
+
return v === null
|
|
25
|
+
? Doc.text('null,')
|
|
26
|
+
: typeof v === 'number'
|
|
27
|
+
? Doc.text(`${truncNumber(v)}${comma ? ',' : ''}`)
|
|
28
|
+
: Doc.text(`'${v}'${comma ? ',' : ''}`)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//// tuple (for prettier)
|
|
32
|
+
|
|
33
|
+
export function isTuple(obj: _Coordinates): obj is _Tuple {
|
|
34
|
+
return (
|
|
35
|
+
obj instanceof Array &&
|
|
36
|
+
obj.length === 2 &&
|
|
37
|
+
typeof obj[0] !== 'object' &&
|
|
38
|
+
typeof obj[1] !== 'object'
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function printTuple([a, b]: _Tuple): Doc.Doc<never> {
|
|
43
|
+
return Doc.hcat([
|
|
44
|
+
Doc.text(`[`),
|
|
45
|
+
printValue(a, true),
|
|
46
|
+
printValue(b, false),
|
|
47
|
+
Doc.text(`],`),
|
|
48
|
+
])
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//// type
|
|
52
|
+
|
|
53
|
+
export function printType(type: string): Doc.Doc<never> {
|
|
54
|
+
return Doc.text(`type: '${type}',`)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//// properties
|
|
58
|
+
|
|
59
|
+
export function printProperties1(obj: Readonly<_Properties>): Doc.Doc<never> {
|
|
60
|
+
return Doc.vsep([
|
|
61
|
+
Doc.text(`properties: {`),
|
|
62
|
+
Doc.indent(
|
|
63
|
+
Doc.vsep(
|
|
64
|
+
Object.entries(obj).map(([k, v]) =>
|
|
65
|
+
Doc.hcat([Doc.text(`${k}: `), printValue(v, true)])
|
|
66
|
+
)
|
|
67
|
+
),
|
|
68
|
+
2
|
|
69
|
+
),
|
|
70
|
+
Doc.text(`},`),
|
|
71
|
+
])
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function printProperties(obj: Readonly<_Properties>): Doc.Doc<never> {
|
|
75
|
+
return Object.keys(obj).length === 0
|
|
76
|
+
? Doc.text(`properties: {},`)
|
|
77
|
+
: printProperties1(obj)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//// crs
|
|
81
|
+
|
|
82
|
+
export function printCrs(obj: Readonly<_Crs>): Doc.Doc<never> {
|
|
83
|
+
return Doc.vsep([
|
|
84
|
+
Doc.text(`crs: {`),
|
|
85
|
+
Doc.indent(
|
|
86
|
+
Doc.vsep([printType(obj.type), printProperties(obj.properties)]),
|
|
87
|
+
2
|
|
88
|
+
),
|
|
89
|
+
Doc.text(`},`),
|
|
90
|
+
])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//// coordinates
|
|
94
|
+
|
|
95
|
+
export function printCoordinates1(
|
|
96
|
+
objs: Readonly<_Coordinates>,
|
|
97
|
+
top: boolean
|
|
98
|
+
): Doc.Doc<never> {
|
|
99
|
+
return isTuple(objs)
|
|
100
|
+
? Doc.hcat([Doc.text(top ? `coordinates: ` : ``), printTuple(objs)])
|
|
101
|
+
: Doc.vsep([
|
|
102
|
+
Doc.text(top ? `coordinates: [` : `[`),
|
|
103
|
+
Doc.indent(
|
|
104
|
+
Doc.vsep(
|
|
105
|
+
objs.map((obj) =>
|
|
106
|
+
isTuple(obj) ? printTuple(obj) : printCoordinates(obj, false)
|
|
107
|
+
)
|
|
108
|
+
),
|
|
109
|
+
2
|
|
110
|
+
),
|
|
111
|
+
Doc.text(`],`),
|
|
112
|
+
])
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function printCoordinates(
|
|
116
|
+
objs: Readonly<_Coordinates>,
|
|
117
|
+
top: boolean
|
|
118
|
+
): Doc.Doc<never> {
|
|
119
|
+
return objs.length === 0
|
|
120
|
+
? Doc.text(`${top ? 'coordinates: ' : ''}[],`)
|
|
121
|
+
: printCoordinates1(objs, top)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//// geometry
|
|
125
|
+
|
|
126
|
+
export function printGeometry(obj: Readonly<_Geometry>): Doc.Doc<never> {
|
|
127
|
+
return Doc.vsep([
|
|
128
|
+
Doc.text(`geometry: {`),
|
|
129
|
+
Doc.indent(
|
|
130
|
+
Doc.vsep([printType(obj.type), printCoordinates(obj.coordinates, true)]),
|
|
131
|
+
2
|
|
132
|
+
),
|
|
133
|
+
Doc.text(`},`),
|
|
134
|
+
])
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//// features
|
|
138
|
+
|
|
139
|
+
export function printFeature(obj: Readonly<_Feature>): Doc.Doc<never> {
|
|
140
|
+
return Doc.vsep([
|
|
141
|
+
Doc.text(`{`),
|
|
142
|
+
Doc.indent(
|
|
143
|
+
Doc.vsep([
|
|
144
|
+
printType(obj.type),
|
|
145
|
+
printProperties(obj.properties),
|
|
146
|
+
printGeometry(obj.geometry),
|
|
147
|
+
]),
|
|
148
|
+
2
|
|
149
|
+
),
|
|
150
|
+
Doc.text(`},`),
|
|
151
|
+
])
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function printFeatureCollection(
|
|
155
|
+
obj: Readonly<_FeatureCollection>
|
|
156
|
+
): Doc.Doc<never> {
|
|
157
|
+
return Doc.vsep([
|
|
158
|
+
Doc.text(`{`),
|
|
159
|
+
Doc.indent(
|
|
160
|
+
Doc.vsep([
|
|
161
|
+
printType(obj.type),
|
|
162
|
+
Doc.text(`features: [`),
|
|
163
|
+
Doc.indent(Doc.vsep(obj.features.map((o) => printFeature(o))), 2),
|
|
164
|
+
Doc.text(`],`),
|
|
165
|
+
]),
|
|
166
|
+
2
|
|
167
|
+
),
|
|
168
|
+
Doc.text(`},`),
|
|
169
|
+
])
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function printFeatures1(objs: Readonly<_Features>): Doc.Doc<never> {
|
|
173
|
+
return Doc.vsep([
|
|
174
|
+
Doc.text(`features: [`),
|
|
175
|
+
Doc.indent(
|
|
176
|
+
Doc.vsep(
|
|
177
|
+
objs.map((obj) =>
|
|
178
|
+
obj.type === 'Feature'
|
|
179
|
+
? printFeature(obj)
|
|
180
|
+
: printFeatureCollection(obj)
|
|
181
|
+
)
|
|
182
|
+
),
|
|
183
|
+
2
|
|
184
|
+
),
|
|
185
|
+
Doc.text(`],`),
|
|
186
|
+
])
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function printFeatures(objs: Readonly<_Features>): Doc.Doc<never> {
|
|
190
|
+
return objs.length === 0 ? Doc.text(`features: [],`) : printFeatures1(objs)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
//// GeoJSON
|
|
194
|
+
|
|
195
|
+
export function printGeoJSON(obj: Readonly<_GeoJSON>): Doc.Doc<never> {
|
|
196
|
+
return Doc.vsep([
|
|
197
|
+
Doc.text(`{`),
|
|
198
|
+
Doc.indent(
|
|
199
|
+
Doc.vsep(
|
|
200
|
+
[
|
|
201
|
+
[printType(obj.type)],
|
|
202
|
+
[Doc.text(`name: '${obj.name}',`)],
|
|
203
|
+
obj.crs === undefined ? [] : [printCrs(obj.crs)],
|
|
204
|
+
[printFeatures(obj.features)],
|
|
205
|
+
].flat()
|
|
206
|
+
),
|
|
207
|
+
2
|
|
208
|
+
),
|
|
209
|
+
Doc.text(`}`),
|
|
210
|
+
])
|
|
211
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { expect, test } from '@rstest/core'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
3
|
+
|
|
4
|
+
import { decodeGeoJSON, decodeProperties } from './geojson-schema'
|
|
5
|
+
|
|
6
|
+
test('decodeProperties', () => {
|
|
7
|
+
const o = {
|
|
8
|
+
a: 1,
|
|
9
|
+
b: 'b',
|
|
10
|
+
c: null,
|
|
11
|
+
}
|
|
12
|
+
const x = decodeProperties(o)
|
|
13
|
+
expect(x).toEqual(o)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('decodeGeoJSON', () => {
|
|
17
|
+
exampleGeoJsonFiles.forEach((p) => {
|
|
18
|
+
try {
|
|
19
|
+
const content = fs.readFileSync(p)
|
|
20
|
+
const o = JSON.parse(content.toString())
|
|
21
|
+
const x = decodeGeoJSON(o)
|
|
22
|
+
expect(x).toEqual(o)
|
|
23
|
+
} catch (e) {
|
|
24
|
+
console.error(p, e)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const exampleGeoJsonFiles = [
|
|
30
|
+
'../example-osm/src/data/areas_extent.json',
|
|
31
|
+
'../example-osm/src/data/areas.json',
|
|
32
|
+
'../example-osm/src/data/internals_extent.json',
|
|
33
|
+
'../example-osm/src/data/internals.json',
|
|
34
|
+
'../example-osm/src/data/map-lines.json',
|
|
35
|
+
'../example-osm/src/data/map-multilinestrings.json',
|
|
36
|
+
'../example-osm/src/data/map-multipolygons.json',
|
|
37
|
+
'../example-osm/src/data/map-other_relations.json',
|
|
38
|
+
'../example-osm/src/data/map-points.json',
|
|
39
|
+
'../example-osm/src/data/measures.json',
|
|
40
|
+
'../example-osm/src/data/origin.json',
|
|
41
|
+
'../example-osm/src/data/viewbox.json',
|
|
42
|
+
] as const
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { ParseOptions } from 'effect/SchemaAST'
|
|
2
|
+
|
|
3
|
+
import { Schema } from 'effect'
|
|
4
|
+
|
|
5
|
+
import type { _Crs, _Features, _Properties } from './geojson-types'
|
|
6
|
+
|
|
7
|
+
const PropertiesSchema = Schema.Record({
|
|
8
|
+
key: Schema.String,
|
|
9
|
+
value: Schema.Union(Schema.Null, Schema.Number, Schema.String),
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const PointType = Schema.Literal('Point')
|
|
13
|
+
const MultiPointType = Schema.Literal('MultiPoint')
|
|
14
|
+
const LineStringType = Schema.Literal('LineString')
|
|
15
|
+
const MultiLineStringType = Schema.Literal('MultiLineString')
|
|
16
|
+
const PolygonType = Schema.Literal('Polygon')
|
|
17
|
+
const MultiPolygonType = Schema.Literal('MultiPolygon')
|
|
18
|
+
// XXX const GeometryCollectionType = Schema.Literal('GeometryCollection')
|
|
19
|
+
const FeatureType = Schema.Literal('Feature')
|
|
20
|
+
const FeatureCollectionType = Schema.Literal('FeatureCollection')
|
|
21
|
+
|
|
22
|
+
const PointCoordinate = Schema.Tuple(Schema.Number, Schema.Number)
|
|
23
|
+
const MultiPointCoordinate = Schema.Array(PointCoordinate)
|
|
24
|
+
const LineStringCoordinate = Schema.Array(PointCoordinate)
|
|
25
|
+
const MultiLineStringCoordinate = Schema.Array(LineStringCoordinate)
|
|
26
|
+
const PolygonCoordinate = Schema.Array(LineStringCoordinate)
|
|
27
|
+
const MultiPolygonCoordinate = Schema.Array(PolygonCoordinate)
|
|
28
|
+
|
|
29
|
+
////
|
|
30
|
+
|
|
31
|
+
const PointGeometry = Schema.Struct({
|
|
32
|
+
type: PointType,
|
|
33
|
+
coordinates: PointCoordinate,
|
|
34
|
+
})
|
|
35
|
+
const MultiPointGeometry = Schema.Struct({
|
|
36
|
+
type: MultiPointType,
|
|
37
|
+
coordinates: MultiPointCoordinate,
|
|
38
|
+
})
|
|
39
|
+
const LineStringGeometry = Schema.Struct({
|
|
40
|
+
type: LineStringType,
|
|
41
|
+
coordinates: LineStringCoordinate,
|
|
42
|
+
})
|
|
43
|
+
const MultiLineStringGeometry = Schema.Struct({
|
|
44
|
+
type: MultiLineStringType,
|
|
45
|
+
coordinates: MultiLineStringCoordinate,
|
|
46
|
+
})
|
|
47
|
+
const PolygonGeometry = Schema.Struct({
|
|
48
|
+
type: PolygonType,
|
|
49
|
+
coordinates: PolygonCoordinate,
|
|
50
|
+
})
|
|
51
|
+
const MultiPolygonGeometry = Schema.Struct({
|
|
52
|
+
type: MultiPolygonType,
|
|
53
|
+
coordinates: MultiPolygonCoordinate,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
////
|
|
57
|
+
|
|
58
|
+
const PointFeature = Schema.Struct({
|
|
59
|
+
type: FeatureType,
|
|
60
|
+
properties: PropertiesSchema,
|
|
61
|
+
geometry: PointGeometry,
|
|
62
|
+
})
|
|
63
|
+
const MultiPointFeature = Schema.Struct({
|
|
64
|
+
type: FeatureType,
|
|
65
|
+
properties: PropertiesSchema,
|
|
66
|
+
geometry: MultiPointGeometry,
|
|
67
|
+
})
|
|
68
|
+
const LineStringFeature = Schema.Struct({
|
|
69
|
+
type: FeatureType,
|
|
70
|
+
properties: PropertiesSchema,
|
|
71
|
+
geometry: LineStringGeometry,
|
|
72
|
+
})
|
|
73
|
+
const MultiLineStringFeature = Schema.Struct({
|
|
74
|
+
type: FeatureType,
|
|
75
|
+
properties: PropertiesSchema,
|
|
76
|
+
geometry: MultiLineStringGeometry,
|
|
77
|
+
})
|
|
78
|
+
const PolygonFeature = Schema.Struct({
|
|
79
|
+
type: FeatureType,
|
|
80
|
+
properties: PropertiesSchema,
|
|
81
|
+
geometry: PolygonGeometry,
|
|
82
|
+
})
|
|
83
|
+
const MultiPolygonFeature = Schema.Struct({
|
|
84
|
+
type: FeatureType,
|
|
85
|
+
properties: PropertiesSchema,
|
|
86
|
+
geometry: MultiPolygonGeometry,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const FeatureSchema = Schema.Union(
|
|
90
|
+
PointFeature,
|
|
91
|
+
MultiPointFeature,
|
|
92
|
+
LineStringFeature,
|
|
93
|
+
MultiLineStringFeature,
|
|
94
|
+
PolygonFeature,
|
|
95
|
+
MultiPolygonFeature
|
|
96
|
+
)
|
|
97
|
+
const FeatureCollectionSchema = Schema.Struct({
|
|
98
|
+
type: FeatureCollectionType,
|
|
99
|
+
features: Schema.Array(FeatureSchema),
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
const Features = Schema.Array(
|
|
103
|
+
Schema.Union(FeatureSchema, FeatureCollectionSchema)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
////
|
|
107
|
+
|
|
108
|
+
const CrsNameType = Schema.Literal('name')
|
|
109
|
+
const CrsLinkType = Schema.Literal('link')
|
|
110
|
+
|
|
111
|
+
const CrsName = Schema.Struct({
|
|
112
|
+
type: CrsNameType,
|
|
113
|
+
properties: Schema.Struct({
|
|
114
|
+
name: Schema.String,
|
|
115
|
+
}),
|
|
116
|
+
})
|
|
117
|
+
const CrsLink = Schema.Struct({
|
|
118
|
+
type: CrsLinkType,
|
|
119
|
+
properties: Schema.Struct({
|
|
120
|
+
href: Schema.String,
|
|
121
|
+
type: Schema.String,
|
|
122
|
+
}),
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const CrsSchema = Schema.Union(CrsName, CrsLink)
|
|
126
|
+
|
|
127
|
+
////
|
|
128
|
+
|
|
129
|
+
const GeoJSONSchema = Schema.Struct({
|
|
130
|
+
type: Schema.String,
|
|
131
|
+
name: Schema.String,
|
|
132
|
+
crs: Schema.Union(Schema.Undefined, CrsSchema),
|
|
133
|
+
features: Features,
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
////
|
|
137
|
+
|
|
138
|
+
export const decodeProperties: (
|
|
139
|
+
u: unknown,
|
|
140
|
+
overrideOptions?: ParseOptions
|
|
141
|
+
) => _Properties = Schema.decodeUnknownSync(PropertiesSchema)
|
|
142
|
+
|
|
143
|
+
export const decodeGeoJSON: (
|
|
144
|
+
u: unknown,
|
|
145
|
+
overrideOptions?: ParseOptions
|
|
146
|
+
) => {
|
|
147
|
+
readonly type: string
|
|
148
|
+
readonly features: _Features
|
|
149
|
+
readonly name: string
|
|
150
|
+
readonly crs: undefined | _Crs
|
|
151
|
+
} = Schema.decodeUnknownSync(GeoJSONSchema)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
//// value, tuple
|
|
2
|
+
|
|
3
|
+
export type _Value = null | number | string
|
|
4
|
+
export type _Tuple = readonly [number, number]
|
|
5
|
+
|
|
6
|
+
//// properties
|
|
7
|
+
|
|
8
|
+
export type _Properties = {
|
|
9
|
+
readonly [x: string]: _Value
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//// coordinates
|
|
13
|
+
|
|
14
|
+
export type _PointCoordinates = readonly [number, number]
|
|
15
|
+
export type _MultiPointCoordinates = readonly _PointCoordinates[]
|
|
16
|
+
export type _LineCoordinates = _MultiPointCoordinates
|
|
17
|
+
export type _MultiLineCoordinates = readonly _LineCoordinates[]
|
|
18
|
+
export type _PolygonCoordinates = _MultiLineCoordinates
|
|
19
|
+
export type _MultiPolygonCoordinates = readonly _PolygonCoordinates[]
|
|
20
|
+
|
|
21
|
+
export type _Coordinates =
|
|
22
|
+
| _PointCoordinates
|
|
23
|
+
| _MultiPointCoordinates
|
|
24
|
+
//| _LineCoordinates
|
|
25
|
+
| _MultiLineCoordinates
|
|
26
|
+
//| _PolygonCoordinates
|
|
27
|
+
| _MultiPolygonCoordinates
|
|
28
|
+
|
|
29
|
+
//// geometry
|
|
30
|
+
|
|
31
|
+
type __Geometry<t, c> = {
|
|
32
|
+
readonly type: t
|
|
33
|
+
readonly coordinates: c
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type _PointGeometry = __Geometry<'Point', _PointCoordinates>
|
|
37
|
+
export type _MultiPointGeometry = __Geometry<
|
|
38
|
+
'MultiPoint',
|
|
39
|
+
_MultiPointCoordinates
|
|
40
|
+
>
|
|
41
|
+
export type _LineStringGeometry = __Geometry<'LineString', _LineCoordinates>
|
|
42
|
+
export type _MultiLineStringGeometry = __Geometry<
|
|
43
|
+
'MultiLineString',
|
|
44
|
+
_MultiLineCoordinates
|
|
45
|
+
>
|
|
46
|
+
export type _PolygonGeometry = __Geometry<'Polygon', _PolygonCoordinates>
|
|
47
|
+
export type _MultiPolygonGeometry = __Geometry<
|
|
48
|
+
'MultiPolygon',
|
|
49
|
+
_MultiPolygonCoordinates
|
|
50
|
+
>
|
|
51
|
+
|
|
52
|
+
export type _Geometry =
|
|
53
|
+
| _PointGeometry
|
|
54
|
+
| _MultiPointGeometry
|
|
55
|
+
| _LineStringGeometry
|
|
56
|
+
| _MultiLineStringGeometry
|
|
57
|
+
| _PolygonGeometry
|
|
58
|
+
| _MultiPolygonGeometry
|
|
59
|
+
|
|
60
|
+
//// features
|
|
61
|
+
|
|
62
|
+
export type __Feature<G = _Geometry> = {
|
|
63
|
+
readonly type: 'Feature'
|
|
64
|
+
readonly properties: _Properties
|
|
65
|
+
readonly geometry: G
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type _PointFeature = __Feature<_PointGeometry>
|
|
69
|
+
export type _MultiPointFeature = __Feature<_MultiPointGeometry>
|
|
70
|
+
export type _LineStringFeature = __Feature<_LineStringGeometry>
|
|
71
|
+
export type _MultiLineStringFeature = __Feature<_MultiLineStringGeometry>
|
|
72
|
+
export type _PolygonFeature = __Feature<_PolygonGeometry>
|
|
73
|
+
export type _MultiPolygonFeature = __Feature<_MultiPolygonGeometry>
|
|
74
|
+
|
|
75
|
+
export type _Feature =
|
|
76
|
+
| _PointFeature
|
|
77
|
+
| _MultiPointFeature
|
|
78
|
+
| _LineStringFeature
|
|
79
|
+
| _MultiLineStringFeature
|
|
80
|
+
| _PolygonFeature
|
|
81
|
+
| _MultiPolygonFeature
|
|
82
|
+
|
|
83
|
+
export type _FeatureCollection = {
|
|
84
|
+
readonly type: 'FeatureCollection'
|
|
85
|
+
readonly features: readonly _Feature[]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type _GeometryCollection = {
|
|
89
|
+
readonly type: 'GeometryCollection'
|
|
90
|
+
readonly geometries: readonly _Geometry[]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type _Features = readonly (_Feature | _FeatureCollection)[]
|
|
94
|
+
|
|
95
|
+
//// crs
|
|
96
|
+
|
|
97
|
+
export type _CrsName = {
|
|
98
|
+
readonly type: 'name'
|
|
99
|
+
readonly properties: _Properties
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type _CrsLink = {
|
|
103
|
+
readonly type: 'link'
|
|
104
|
+
readonly properties: _Properties
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export type _Crs = _CrsName | _CrsLink
|
|
108
|
+
|
|
109
|
+
//// GeoJSON
|
|
110
|
+
|
|
111
|
+
export type _GeoJSON = {
|
|
112
|
+
readonly type: string
|
|
113
|
+
readonly name: string
|
|
114
|
+
readonly crs?: _Crs
|
|
115
|
+
readonly features: _Features
|
|
116
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { expect, test } from '@rstest/core'
|
|
2
|
+
|
|
3
|
+
import { splitOtherTags } from './osm'
|
|
4
|
+
|
|
5
|
+
test('split other_tags', () => {
|
|
6
|
+
const v = `"a"=>"a","b"=>"1","c"=>"1.23","d"=>"null"`
|
|
7
|
+
const x = {
|
|
8
|
+
a: 'a',
|
|
9
|
+
b: 1,
|
|
10
|
+
c: 1.23,
|
|
11
|
+
d: null,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const p = splitOtherTags(v)
|
|
15
|
+
|
|
16
|
+
expect(p).toEqual(x)
|
|
17
|
+
})
|
package/src/lib/osm.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Array, Record } from 'effect'
|
|
2
|
+
|
|
3
|
+
import type { _Properties, _Value } from './geojson/geojson-types'
|
|
4
|
+
|
|
5
|
+
function expandVal(s: string): _Value {
|
|
6
|
+
return s === 'null' ? null : !isNaN(Number(s)) ? Number(s) : s
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function splitOtherTags(s: string): _Properties {
|
|
10
|
+
const kvs = s
|
|
11
|
+
.split(/"=>"/g)
|
|
12
|
+
.flatMap((s) => s.replace(/^"/, '').replace(/"$/, '').split(/","/))
|
|
13
|
+
const range = Array.range(0, kvs.length / 2 - 1)
|
|
14
|
+
const pairs = range
|
|
15
|
+
.map((i) => [kvs[i * 2], kvs[i * 2 + 1]] as [string, string])
|
|
16
|
+
.map(([k, v]) => [k, expandVal(v)] as [string, _Value])
|
|
17
|
+
return Record.fromEntries(pairs)
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { expect, test } from '@rstest/core'
|
|
2
|
+
|
|
3
|
+
import { splitTypes } from './print-utils'
|
|
4
|
+
|
|
5
|
+
test('split types', () => {
|
|
6
|
+
const s = 'a<b<c, d>, e<f, g>, h>'
|
|
7
|
+
|
|
8
|
+
const t = splitTypes(s)
|
|
9
|
+
const x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
|
|
10
|
+
|
|
11
|
+
expect(t).toEqual(x)
|
|
12
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Array, Order, pipe } from 'effect'
|
|
2
|
+
|
|
3
|
+
function uncomma(s: string): string[] {
|
|
4
|
+
return Array.fromIterable(s.split(/,/)).map((ss) => ss.trim())
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function splitTypes1(t: string): string[] {
|
|
8
|
+
const re = /<([^<>]*)>/g
|
|
9
|
+
if (t.match(re)) {
|
|
10
|
+
const all = t.matchAll(re)
|
|
11
|
+
const aaa = Array.fromIterable(all).map((m) => uncomma(m[1]))
|
|
12
|
+
const rest = t.replaceAll(re, '')
|
|
13
|
+
const bbb = splitTypes(rest)
|
|
14
|
+
return aaa.concat(bbb).flat()
|
|
15
|
+
} else {
|
|
16
|
+
return uncomma(t)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function splitTypes(t: string): string[] {
|
|
21
|
+
return pipe(t, splitTypes1, Array.sort(Order.string))
|
|
22
|
+
}
|