Skip to content

Commit 5d525a3

Browse files
committed
Basic implementation
1 parent d374433 commit 5d525a3

25 files changed

+2337
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
dist/

LICENSE

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ISC License
2+
3+
Copyright 2024 OpenStreetMap US
4+
5+
Permission to use, copy, modify, and/or distribute this software for any purpose
6+
with or without fee is hereby granted, provided that the above copyright notice
7+
and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
13+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
15+
THIS SOFTWARE.

README.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# osm-changeset-xml-parser
2+
3+
Parse OpenStreetMap Changeset metadata XML documents into plain JavaScript objects.
4+
5+
**Note: you may not need this package.** The OSM API is capable of returning this metadata in JSON natively if you append `.json` to the endpoint URL, like this:
6+
7+
```
8+
curl -i 'https://api.openstreetmap.org/api/0.6/changeset/133061984.json'
9+
```
10+
11+
## Installation
12+
13+
```
14+
npm install @osmcha/osm-changeset-xml-parser
15+
```
16+
17+
## Usage
18+
19+
```js
20+
import parseChangesetXML from "@osmcha/osm-changeset-xml-parser";
21+
let changeset = await parseChangesetXML(xmlString);
22+
```
23+
24+
## Example input & output
25+
26+
Input:
27+
28+
```xml
29+
<?xml version="1.0" encoding="UTF-8"?>
30+
<osm version="0.6" generator="openstreetmap-cgimap 2.0.1 (1849 spike-07.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
31+
<changeset id="155530622" created_at="2024-08-20T21:36:16Z" closed_at="2024-08-20T21:36:17Z" open="false" user="jake-low" uid="8794039" min_lat="47.6647943" min_lon="-121.2881568" max_lat="47.6647943" max_lon="-121.2881568" comments_count="0" changes_count="1">
32+
<tag k="changesets_count" v="1992"/>
33+
<tag k="comment" v="Skykomish, WA: add name, operator, and website to Necklace Valley Trailhead"/>
34+
<tag k="created_by" v="iD 2.29.0"/>
35+
<tag k="host" v="https://www.openstreetmap.org/edit"/>
36+
<tag k="imagery_used" v="Bing Maps Aerial"/>
37+
<tag k="locale" v="en-US"/>
38+
</changeset>
39+
</osm>
40+
```
41+
42+
Output:
43+
44+
```json
45+
{
46+
"version": "0.6",
47+
"generator": "openstreetmap-cgimap 2.0.1 (1849 spike-07.openstreetmap.org)",
48+
"copyright": "OpenStreetMap and contributors",
49+
"attribution": "http://www.openstreetmap.org/copyright",
50+
"license": "http://opendatacommons.org/licenses/odbl/1-0/",
51+
"changeset": {
52+
"id": 155530622,
53+
"created_at": "2024-08-20T21:36:16Z",
54+
"closed_at": "2024-08-20T21:36:17Z",
55+
"open": false,
56+
"user": "jake-low",
57+
"uid": 8794039,
58+
"min_lat": 47.6647943,
59+
"min_lon": -121.2881568,
60+
"max_lat": 47.6647943,
61+
"max_lon": -121.2881568,
62+
"comments_count": 0,
63+
"changes_count": 1,
64+
"tags": {
65+
"changesets_count": "1992",
66+
"comment": "Skykomish, WA: add name, operator, and website to Necklace Valley Trailhead",
67+
"created_by": "iD 2.29.0",
68+
"host": "https://www.openstreetmap.org/edit",
69+
"imagery_used": "Bing Maps Aerial",
70+
"locale": "en-US"
71+
}
72+
}
73+
}
74+
```

index.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import sax from "sax";
2+
3+
const TYPED_ATTRS = [
4+
"id",
5+
"uid",
6+
"min_lon",
7+
"min_lat",
8+
"max_lon",
9+
"max_lat",
10+
"comments_count",
11+
"changes_count",
12+
"open",
13+
];
14+
15+
/*
16+
* Parse OSM Changeset Metadata XML, of the form returned by
17+
* https://www.openstreetmap.org/api/0.6/changeset/:id
18+
* (Contains changeset's bbox, timestamp, comment, and authorship)
19+
*/
20+
function parseChangesetXML(xmlString) {
21+
return new Promise((resolve, reject) => {
22+
let parser = sax.parser(true /* strict mode */, { lowercase: true });
23+
let result = {};
24+
25+
parser.onopentag = (node) => {
26+
let name = node.name, attrs = node.attributes;
27+
switch (name) {
28+
case "osm":
29+
Object.assign(result, attrs);
30+
break;
31+
case "changeset":
32+
Object.assign((result.changeset ||= {}), attrs);
33+
break;
34+
case "tag":
35+
Object.assign((result.changeset.tags ||= {}), { [attrs.k]: attrs.v });
36+
break;
37+
}
38+
};
39+
40+
parser.onend = () => {
41+
let { changeset } = result;
42+
for (let attr of TYPED_ATTRS) {
43+
changeset[attr] = JSON.parse(changeset[attr]);
44+
}
45+
resolve(result);
46+
};
47+
48+
parser.onerror = reject;
49+
50+
parser.write(xmlString);
51+
parser.close();
52+
});
53+
}
54+
55+
export default parseChangesetXML;

0 commit comments

Comments
 (0)