Permalink
Browse files

Support everything, tests

  • Loading branch information...
1 parent 5c54581 commit ba6927c11fa1d9b9814661afeffe21aa63336121 @tmcw tmcw committed Oct 9, 2013
View
@@ -0,0 +1,2 @@
+tokml.js:
+ browserify -s tokml index.js > tokml.js
View
@@ -4,12 +4,38 @@
Convert [GeoJSON](http://geojson.org/) to [KML](https://developers.google.com/kml/documentation/).
-## usage
+## Usage
npm install --save tokml
-## api
+as a binary:
+
+ npm install -g tokml
+ tokml file.geojson > file.kml
+ tokml < file.geojson > file.kml
+
+## Example
```js
var kml = tokml(geojsonObject);
```
+
+## API
+
+### `tokml(geojsonObject)`
+
+Given [GeoJSON](http://geojson.org/) data as an object, return KML data as a
+string of XML.
+
+## Development
+
+Requires [node.js](http://nodejs.org/) and [browserify](https://github.com/substack/node-browserify):
+
+To build `tokml.js`:
+
+ make
+
+To run tests:
+
+ npm install
+ npm test
View
@@ -1,32 +1,62 @@
-module.exports = tokml;
-
-var header = '<?xml version="1.0" encoding="UTF-8"?>' +
- '<kml xmlns="http://www.opengis.net/kml/2.2">',
- footer = '</kml>';
-
+module.exports = function tokml(geojson) {
+ return '<?xml version="1.0" encoding="UTF-8"?>' +
+ tag('kml',
+ tag('Document',
+ geojson.features.map(feature).join('')
+ ), [['xmlns', 'http://www.opengis.net/kml/2.2']]);
+};
// ## Geometry Types
//
// https://developers.google.com/kml/documentation/kmlreference#geometry
-function point(_) {
- return tag('Point', tag('coordinates', _.coordinates.join(',')));
-}
-
-function linestring(_) {
- return tag('LineString', tag('coordinates', linearring(_.coordinates)));
-}
+var geometry = {
+ Point: function(_) {
+ return tag('Point', tag('coordinates', _.coordinates.join(',')));
+ },
+ LineString: function(_) {
+ return tag('LineString', tag('coordinates', linearring(_.coordinates)));
+ },
+ Polygon: function(_) {
+ var outer = _.coordinates[0],
+ inner = _.coordinates.slice(1),
+ outerRing = tag('outerBoundaryIs',
+ tag('LinearRing', tag('coordinates', linearring(outer)))),
+ innerRings = inner.map(function(i) {
+ return tag('innerBoundaryIs',
+ tag('LinearRing', tag('coordinates', linearring(i))));
+ }).join('');
+ return tag('Polygon', outerRing + innerRings);
+ },
+ MultiPoint: function(_) {
+ return tag('MultiGeometry', _.coordinates.map(function(c) {
+ return geometry.Point({ coordinates: c });
+ }).join(''));
+ },
+ MultiPolygon: function(_) {
+ return tag('MultiGeometry', _.coordinates.map(function(c) {
+ return geometry.Polygon({ coordinates: c });
+ }).join(''));
+ },
+ MultiLineString: function(_) {
+ return tag('MultiGeometry', _.coordinates.map(function(c) {
+ return geometry.LineString({ coordinates: c });
+ }).join(''));
+ },
+ GeometryCollection: function(_) {
+ return tag('MultiGeometry',
+ _.geometries.map(geometry.any).join(''));
+ },
+ any: function(_) {
+ if (geometry[_.type]) {
+ return geometry[_.type](_);
+ } else { }
+ }
+};
function linearring(_) {
return _.map(function(cds) { return cds.join(','); }).join(' ');
}
-function polygon(_) {
- return tag('Polygon',
- tag('outerBoundaryIs',
- tag('LinearRing',
- tag('coordinates', linearring(_.coordinates[0])))));
-}
-
// ## Data
function extendeddata(_) {
return tag('ExtendedData', pairs(_).map(data).join(''));
@@ -36,25 +66,12 @@ function data(_) {
return tag('Data', _[1], [['name', _[0]]]);
}
-var geometry = {
- Point: point,
- LineString: linestring,
- Polygon: polygon
-};
-
function feature(_) {
return tag('Placemark',
- geometry[_.geometry.type](_.geometry) +
+ geometry.any(_.geometry) +
extendeddata(_.properties));
}
-// # tokml
-function tokml(geojson) {
- return header +
- geojson.features.map(feature).join('') +
- footer;
-}
-
// ## Helpers
function pairs(_) {
var o = [];
View
@@ -19,9 +19,12 @@
"license": "BSD-2-Clause",
"devDependencies": {
"expect.js": "~0.2.0",
- "mocha": "~1.13.0"
+ "mocha": "~1.13.0",
+ "glob": "~3.2.6"
},
"dependencies": {
- "minimist": "0.0.5"
+ "minimist": "0.0.5",
+ "concat-stream": "~1.0.1",
+ "sharkdown": "0.0.1"
}
}
@@ -0,0 +1,7 @@
+var tokml = require('../'),
+ fs = require('fs'),
+ glob = require('glob');
+
+glob.sync('test/data/*.geojson').forEach(function(g) {
+ fs.writeFileSync(g.replace('.geojson', '.kml'), tokml(JSON.parse(fs.readFileSync(g))));
+});
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><Point><coordinates>102,0.5</coordinates></Point><ExtendedData><Data name="prop0">value0</Data></ExtendedData></Placemark><Placemark><LineString><coordinates>102,0 103,1 104,0 105,1</coordinates></LineString><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">0</Data></ExtendedData></Placemark><Placemark><Polygon><outerBoundaryIs><LinearRing><coordinates>100,0 101,0 101,1 100,1 100,0</coordinates></LinearRing></outerBoundaryIs></Polygon><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
@@ -0,0 +1,20 @@
+{ "type": "FeatureCollection",
+ "features": [{
+ "type": "Feature",
+ "geometry": { "type": "GeometryCollection",
+ "geometries": [
+ { "type": "Point",
+ "coordinates": [100.0, 0.0]
+ },
+ { "type": "LineString",
+ "coordinates": [ [101.0, 0.0], [102.0, 1.0] ]
+ }
+ ]
+ },
+ "properties": {
+ "prop0": "value0",
+ "prop1": "val2"
+ }
+ }
+ ]
+}
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><MultiGeometry><Point><coordinates>100,0</coordinates></Point><LineString><coordinates>101,0 102,1</coordinates></LineString></MultiGeometry><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Placemark><LineString><coordinates>100,0 101,1</coordinates></LineString><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></kml>
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><LineString><coordinates>100,0 101,1</coordinates></LineString><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
@@ -0,0 +1,16 @@
+{ "type": "FeatureCollection",
+ "features": [{
+ "type": "Feature",
+ "geometry": { "type": "MultiLineString",
+ "coordinates": [
+ [ [100.0, 0.0], [101.0, 1.0] ],
+ [ [102.0, 2.0], [103.0, 3.0] ]
+ ]
+ },
+ "properties": {
+ "prop0": "value0",
+ "prop1": "val2"
+ }
+ }
+ ]
+}
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><MultiGeometry><LineString><coordinates>100,0 101,1</coordinates></LineString><LineString><coordinates>102,2 103,3</coordinates></LineString></MultiGeometry><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
@@ -0,0 +1,13 @@
+{ "type": "FeatureCollection",
+ "features": [{
+ "type": "Feature",
+ "geometry": { "type": "MultiPoint",
+ "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
+ },
+ "properties": {
+ "prop0": "value0",
+ "prop1": "val2"
+ }
+ }
+ ]
+}
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><MultiGeometry><Point><coordinates>100,0</coordinates></Point><Point><coordinates>101,1</coordinates></Point></MultiGeometry><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
@@ -0,0 +1,17 @@
+{ "type": "FeatureCollection",
+ "features": [{
+ "type": "Feature",
+ "geometry": { "type": "MultiPolygon",
+ "coordinates": [
+ [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
+ [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
+ [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
+ ]
+ },
+ "properties": {
+ "prop0": "value0",
+ "prop1": "val2"
+ }
+ }
+ ]
+}
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>102,2 103,2 103,3 102,3 102,2</coordinates></LinearRing></outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing><coordinates>100,0 101,0 101,1 100,1 100,0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs><LinearRing><coordinates>100.2,0.2 100.8,0.2 100.8,0.8 100.2,0.8 100.2,0.2</coordinates></LinearRing></innerBoundaryIs></Polygon></MultiGeometry><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
View
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Placemark><Point><coordinates>100,0</coordinates></Point><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></kml>
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><Point><coordinates>100,0</coordinates></Point><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Placemark><Polygon><outerBoundaryIs><LinearRing><coordinates>100,0 101,0 101,1 100,1 100,0</coordinates></LinearRing></outerBoundaryIs></Polygon><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></kml>
+<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"><Document><Placemark><Polygon><outerBoundaryIs><LinearRing><coordinates>100,0 101,0 101,1 100,1 100,0</coordinates></LinearRing></outerBoundaryIs></Polygon><ExtendedData><Data name="prop0">value0</Data><Data name="prop1">val2</Data></ExtendedData></Placemark></Document></kml>
View
@@ -12,6 +12,15 @@ describe('tokml', function() {
it('linestring', function() {
expect(tokml(file('linestring.geojson'))).to.eql(output('linestring.kml'));
});
+ it('multilinestring', function() {
+ expect(tokml(file('multilinestring.geojson'))).to.eql(output('multilinestring.kml'));
+ });
+ it('multipoint', function() {
+ expect(tokml(file('multipoint.geojson'))).to.eql(output('multipoint.kml'));
+ });
+ it('multipolygon', function() {
+ expect(tokml(file('multipolygon.geojson'))).to.eql(output('multipolygon.kml'));
+ });
});
function file(f) {
View
13 tokml 100644 → 100755
@@ -1,9 +1,16 @@
#!/usr/bin/env node
var tokml = require('./'),
+ sharkdown = require('sharkdown'),
+ concat = require('concat-stream'),
fs = require('fs'),
argv = require('minimist')(process.argv.slice(2));
-process.stdout.write(
- tokml(JSON.parse(fs.readFileSync(argv._[0])))
-);
+if (process.stdin.isTTY && !argv._[0]) {
+ process.stdout.write(sharkdown(fs.readFileSync(__dirname + '/README.md')));
+ process.exit(1);
+}
+
+(argv._.length ? fs.createReadStream(argv._[0]) : process.stdin).pipe(concat(convert));
+
+function convert(data) { process.stdout.write(tokml(JSON.parse(data))); }
Oops, something went wrong.

0 comments on commit ba6927c

Please sign in to comment.