Skip to content

Commit

Permalink
feat: Generator methods, removed CLI
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the cli that was previously installed along with togeojson has been removed, and will be installable as @tmcw/togeojson-cli

Other changes in this pass:

- Switch from microbundle to rollup to build
- Remove dependencies
- Remove reliance on XMLSerializer. This will make togeojson work in worker contexts.
  • Loading branch information
tmcw committed Mar 8, 2019
1 parent 169cf82 commit f37a30b
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 2,256 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ The output is a JavaScript object of GeoJSON data. You can convert it to a strin
with [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
or use it directly in libraries.

### `toGeoJSON.kmlGen(doc)`

Convert KML to GeoJSON incrementally, returning a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
that yields output feature by feature.

### `toGeoJSON.gpx(doc)`

Convert a GPX document to GeoJSON. The first argument, `doc`, must be a GPX
Expand All @@ -35,6 +40,11 @@ holding an XML DOM.

The output is a JavaScript object of GeoJSON data, same as `.kml` outputs.

### `toGeoJSON.gpxGen(doc)`

Convert GPX to GeoJSON incrementally, returning a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
that yields output feature by feature.

## CLI

Install it into your path with `npm install -g @tmcw/togeojson`.
Expand Down
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { gpx } from "./lib/gpx";
export { kml } from "./lib/kml";
export { gpx, gpxGen } from "./lib/gpx";
export { kml, kmlGen } from "./lib/kml";
36 changes: 18 additions & 18 deletions lib/gpx.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function initializeArray(arr, size) {
}
return arr;
}
//

function getLineStyle(extensions) {
const style = {};
if (extensions) {
Expand All @@ -23,6 +23,7 @@ function getLineStyle(extensions) {
}
return style;
}

// get the contents of multiple text nodes, if present
function getMulti(x, ys) {
const o = {};
Expand Down Expand Up @@ -176,28 +177,27 @@ function getPoint(node) {
};
}

export function gpx(doc) {
let i;
export function* gpxGen(doc) {
const tracks = doc.getElementsByTagName("trk");
const routes = doc.getElementsByTagName("rte");
const waypoints = doc.getElementsByTagName("wpt");
// a feature collection
const gj = {
type: "FeatureCollection",
features: []
};
let feature;
for (i = 0; i < tracks.length; i++) {
feature = getTrack(tracks[i]);
if (feature) gj.features.push(feature);

for (let i = 0; i < tracks.length; i++) {
const feature = getTrack(tracks[i]);
if (feature) yield feature;
}
for (i = 0; i < routes.length; i++) {
feature = getRoute(routes[i]);
if (feature) gj.features.push(feature);
for (let i = 0; i < routes.length; i++) {
const feature = getRoute(routes[i]);
if (feature) yield feature;
}
for (i = 0; i < waypoints.length; i++) {
gj.features.push(getPoint(waypoints[i]));
for (let i = 0; i < waypoints.length; i++) {
yield getPoint(waypoints[i]);
}
}

return gj;
export function gpx(doc) {
return {
type: "FeatureCollection",
features: Array.from(gpxGen(doc))
};
}
65 changes: 34 additions & 31 deletions lib/kml.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,25 @@ function coord(v) {
.map(coord1);
}

let serializer;

if (typeof XMLSerializer !== "undefined") {
/* istanbul ignore next */
serializer = new XMLSerializer();
} else {
const isNodeEnv = typeof process === "object" && !process.browser;
const isTitaniumEnv = typeof Titanium === "object";
if (typeof exports === "object" && (isNodeEnv || isTitaniumEnv)) {
serializer = new (require("xmldom")).XMLSerializer();
} else {
throw new Error("Unable to initialize serializer");
function xml2str(node) {
if (node.xml !== undefined) return node.xml;
if (node.tagName) {
let output = node.tagName;
for (let i = 0; i < node.attributes.length; i++) {
output += node.attributes[i].name + node.attributes[i].value;
}
for (let i = 0; i < node.childNodes.length; i++) {
output += xml2str(node.childNodes[i]);
}
return output;
}
}

function xml2str(str) {
// IE9 will create a new XMLSerializer but it'll crash immediately.
// This line is ignored because we don't run coverage tests in IE9
/* istanbul ignore next */
if (str.xml !== undefined) return str.xml;
return serializer.serializeToString(str);
if (node.nodeName === "#text") {
return (node.nodeValue || node.value || "").trim();
}
if (node.nodeName === "#cdata-section") {
return node.nodeValue;
}
return "";
}

const geotypes = ["Polygon", "LineString", "Point", "Track", "gx:Track"];
Expand Down Expand Up @@ -171,7 +169,7 @@ function getPlacemark(root, styleIndex, styleMapIndex, styleByHash) {
let polyStyle = get1(root, "PolyStyle");
const visibility = get1(root, "visibility");

if (!geomsAndTimes.geoms.length) return [];
if (!geomsAndTimes.geoms.length) return;
if (name) properties.name = name;
if (address) properties.address = address;
if (styleUrl) {
Expand Down Expand Up @@ -269,15 +267,11 @@ function getPlacemark(root, styleIndex, styleMapIndex, styleByHash) {
properties: properties
};
if (root.getAttribute("id")) feature.id = root.getAttribute("id");
return [feature];
return feature;
}

export function kml(doc) {
const gj = {
type: "FeatureCollection",
features: []
};
// styleindex keeps track of hashed styles in order to match featurej
export function* kmlGen(doc) {
// styleindex keeps track of hashed styles in order to match feature
const styleIndex = {};
const styleByHash = {};
// stylemapindex keeps track of style maps to expose in properties
Expand Down Expand Up @@ -308,10 +302,19 @@ export function kml(doc) {
styleMapIndex["#" + styleMaps[l].getAttribute("id")] = pairsMap;
}
for (let j = 0; j < placemarks.length; j++) {
gj.features = gj.features.concat(
getPlacemark(placemarks[j], styleIndex, styleMapIndex, styleByHash)
const feature = getPlacemark(
placemarks[j],
styleIndex,
styleMapIndex,
styleByHash
);
if (feature) yield feature;
}
}

return gj;
export function kml(doc) {
return {
type: "FeatureCollection",
features: Array.from(kmlGen(doc))
};
}
19 changes: 6 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "@tmcw/togeojson",
"version": "1.0.0",
"description": "convert KML and GPX to GeoJSON",
"source": "index.js",
"umd:main": "dist/togeojson.umd.js",
"unpkg": "dist/togeojson.umd.js",
"browser": "dist/togeojson.umd.js",
Expand All @@ -14,7 +13,7 @@
],
"scripts": {
"test": "eslint lib && jest",
"prepare": "microbundle",
"prepare": "rollup -c rollup.config.js",
"release": "standard-version"
},
"devDependencies": {
Expand All @@ -23,24 +22,18 @@
"babel-preset-env": "^1.7.0",
"cz-conventional-changelog": "^2.1.0",
"eslint": "^5.12.1",
"glob": "^7.0.5",
"jest": "^23.6.0",
"microbundle": "^0.9.0",
"standard-version": "^4.4.0"
},
"bin": {
"togeojson": "togeojson"
"rollup": "^1.4.0",
"rollup-plugin-terser": "^4.0.4",
"standard-version": "^4.4.0",
"xmldom": "^0.1.27"
},
"repository": {
"type": "git",
"url": "git://github.com/tmcw/togeojson.git"
},
"license": "BSD-2-Clause",
"dependencies": {
"get-stdin": "^6.0.0",
"minimist": "1.2.0",
"xmldom": "~0.1.19"
},
"dependencies": {},
"keywords": [
"kml",
"geojson",
Expand Down
33 changes: 33 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { terser } from "rollup-plugin-terser";

const input = "index.js";
const sourcemap = true;

export default [
{
input,
output: {
file: "dist/togeojson.es.js",
format: "es",
sourcemap
}
},
{
input,
output: {
file: "dist/togeojson.js",
format: "cjs",
sourcemap
}
},
{
input,
output: {
file: "dist/togeojsons.min.js",
format: "umd",
name: "toGeoJSON",
sourcemap
},
plugins: [terser()]
}
];
28 changes: 14 additions & 14 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9082,7 +9082,7 @@ Object {
"name": "
12/04/2014 11:24 AM (départ)
",
"styleHash": "1a92f2da",
"styleHash": "7f350914",
"styleUrl": "#start",
"timestamp": "2014-04-12T14:26:16.702Z",
},
Expand Down Expand Up @@ -9278,7 +9278,7 @@ Object {
"stroke": "#ff0000",
"stroke-opacity": 0.4980392156862745,
"stroke-width": 4,
"styleHash": "23ae7d4c",
"styleHash": "-7aff0fa",
"styleUrl": "#track",
"type": "
course à pied
Expand Down Expand Up @@ -9323,7 +9323,7 @@ Date d'enregistrement : 12/04/2014 11:24 AM
"name": "
12/04/2014 11:24 AM (fin)
",
"styleHash": "-8cb39ad",
"styleHash": "-16b4bba1",
"styleUrl": "#end",
"timestamp": "2014-04-12T15:38:07.678Z",
},
Expand Down Expand Up @@ -9941,7 +9941,7 @@ Object {
"properties": Object {
"icon": "http://maps.google.com/mapfiles/kml/paddle/grn-circle.png",
"name": "8/8/2013 17:20 (Start)",
"styleHash": "5a145216",
"styleHash": "7f350914",
"styleUrl": "#start",
"timestamp": "2013-08-08T15:20:40.000Z",
},
Expand Down Expand Up @@ -10058,7 +10058,7 @@ Object {
"stroke": "#ff0000",
"stroke-opacity": 0.4980392156862745,
"stroke-width": 4,
"styleHash": "66da7df6",
"styleHash": "-7aff0fa",
"styleUrl": "#track",
"type": "walking",
},
Expand All @@ -10076,7 +10076,7 @@ Object {
"properties": Object {
"icon": "http://maps.google.com/mapfiles/kml/paddle/red-circle.png",
"name": "8/8/2013 17:20 (End)",
"styleHash": "-77e98803",
"styleHash": "-16b4bba1",
"styleUrl": "#end",
"timestamp": "2013-08-08T16:25:57.000Z",
},
Expand Down Expand Up @@ -41569,7 +41569,7 @@ Object {
"properties": Object {
"icon": "http://maps.google.com/mapfiles/kml/paddle/grn-circle.png",
"name": "8/8/2013 17:20 (Start)",
"styleHash": "5a145216",
"styleHash": "7f350914",
"styleUrl": "#start",
"timestamp": "2013-08-08T15:20:40.000Z",
},
Expand Down Expand Up @@ -41686,7 +41686,7 @@ Object {
"stroke": "#ff0000",
"stroke-opacity": 0.4980392156862745,
"stroke-width": 4,
"styleHash": "66da7df6",
"styleHash": "-7aff0fa",
"styleUrl": "#track",
"type": "walking",
},
Expand All @@ -41704,7 +41704,7 @@ Object {
"properties": Object {
"icon": "http://maps.google.com/mapfiles/kml/paddle/red-circle.png",
"name": "8/8/2013 17:20 (End)",
"styleHash": "-77e98803",
"styleHash": "-16b4bba1",
"styleUrl": "#end",
"timestamp": "2013-08-08T16:25:57.000Z",
},
Expand Down Expand Up @@ -73993,7 +73993,7 @@ Object {
"TrailHeadName": "Pi in the sky",
"TrailLength": "3.14159",
"name": "Easy trail",
"styleHash": "721d7249",
"styleHash": "-584e03c9",
"styleUrl": "#trailhead-balloon-template",
},
"type": "Feature",
Expand All @@ -74011,7 +74011,7 @@ Object {
"TrailHeadName": "Mount Everest",
"TrailLength": "347.45",
"name": "Difficult trail",
"styleHash": "721d7249",
"styleHash": "-584e03c9",
"styleUrl": "#trailhead-balloon-template",
},
"type": "Feature",
Expand Down Expand Up @@ -75829,7 +75829,7 @@ Object {
"description": "Here is some descriptive text",
"icon": "http://myserver.com/icon.jpg",
"name": "Google Earth - New Polygon",
"styleHash": "-1d694122",
"styleHash": "34215c41",
"styleUrl": "#a",
},
"type": "Feature",
Expand All @@ -75846,7 +75846,7 @@ Object {
"properties": Object {
"icon": "http://myserver.com/icon.jpg",
"name": "Google Earth - New Path",
"styleHash": "-5b6ad921",
"styleHash": "149ab242",
"styleUrl": "#b",
},
"type": "Feature",
Expand Down Expand Up @@ -75967,7 +75967,7 @@ Object {
"fill-opacity": 0.49019607843137253,
"name": "Building 41",
"stroke-width": 1.5,
"styleHash": "-109facd6",
"styleHash": "-25ae1a08",
"styleUrl": "#transBluePoly",
},
"type": "Feature",
Expand Down

0 comments on commit f37a30b

Please sign in to comment.