-
-
Save bmount/1680715 to your computer and use it in GitHub Desktop.
var spawn = require('child_process').spawn; | |
var fs = require('fs'); | |
var path = require('path'); | |
var seq = require('seq'); | |
var findit = require('findit'); | |
var BufferedStream = require('morestreams').BufferedStream; | |
module.exports = function (inStream) { | |
var id = Math.floor(Math.random() * (1<<30)).toString(16); | |
var tmpDir = path.join('/tmp', id); | |
var zipFile = path.join('/tmp', id + '.zip'); | |
var outStream = new BufferedStream; | |
outStream.readable = true; | |
outStream.writable = true; | |
var zipStream = fs.createWriteStream(zipFile); | |
inStream.pipe(zipStream); | |
zipStream.on('error', outStream.emit.bind(outStream, 'error')); | |
seq() | |
.par(function () { fs.mkdir(tmpDir, 0700, this) }) | |
.par(function () { | |
if (zipStream.closed) this() | |
else zipStream.on('close', this.ok) | |
}) | |
.seq_(function (next) { | |
var ps = spawn('unzip', [ '-d', tmpDir, zipFile ]); | |
ps.on('exit', function (code) { | |
next(code < 3 ? null : 'error in unzip: code ' + code) | |
}); | |
}) | |
.seq_(function (next) { | |
var s = findit(tmpDir); | |
var files = []; | |
s.on('file', function (file) { | |
if (file.match(/doc\.kml$/i)) files.push(file); | |
}); | |
s.on('end', next.ok.bind(null, files)); | |
}) | |
.seq(function (files) { | |
if (files.length === 0) { | |
this('no .shp files found in the archive'); | |
} | |
else if (files.length > 1) { | |
this('multiple .shp files found in the archive,' | |
+ ' expecting a single file') | |
} | |
else { | |
var ps = spawn('ogr2ogr', [ | |
'-f', 'GeoJSON', | |
'-skipfailures', | |
'-t_srs', | |
'EPSG:4326', | |
'-a_srs', | |
'EPSG:4326', | |
'stdout', | |
files[0], | |
]); | |
ps.stdout.pipe(outStream, { end : false }); | |
ps.stderr.pipe(outStream, { end : false }); | |
var pending = 2; | |
function onend () { if (--pending === 0) outStream.end() } | |
ps.stdout.on('end', onend); | |
ps.stderr.on('end', onend); | |
} | |
}) | |
.catch(function (err) { | |
outStream.emit('error', err); | |
}) | |
; | |
return outStream; | |
}; |
I think this is a 6 char pull request, line 37, kmz ogr interface almost identical to zipped shp, and deflates in predictable way. 1 gut endpoint for 2 most common formats! Plus now shp can just stand for shape as it should have all along :)
Here is pull request: https://github.com/substack/shp2json/pull/2
Thing about kmz is that a lot of the time it isn't what it seems. Actually enf explained to me part of the deal with google map exports is that they didn't originally own a lot of their own underlying data, and so they have these restrictions on redistributing it. So for example if you are using fusion tables and you export your map, you get a kmz file that has basically all cdata fields with some sort of lookup key and is basically useless (hence DataCouch!). But for the really common case a lot of people do awesome re-purposeable things in google earth like this: http://maps.google.com/maps/ms?msid=215897248572401818539.00045c2a66d756ac5e226&msa=0&ll=37.756533,-122.41456&spn=0.039291,0.074759 -- or this: -- http://www.flickr.com/photos/octoferret/6644839279/in/photostream On the other hand there is stuff like this: http://www.google.com/fusiontables/DataSource?dsrcid=433634 , export to kml and see what I mean about the geometrylessness.
Bottom line I think unofficial official support is probably the best that can be achieved. My rough guess is that about half of the kmz out there contain usable data, but a lot of it is the best, most personal half so maybe worth trying a la the above.
nice! now make it into a https://github.com/maxogden/gut server :D