Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@max-mapper
Created November 24, 2012 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save max-mapper/4137801 to your computer and use it in GitHub Desktop.
Save max-mapper/4137801 to your computer and use it in GitHub Desktop.
geohash point indexer for leveldb (experimental)
var plumbdb = require('plumbdb')
var shp2json = require('shp2json')
var tako = require('tako')
var geohash = require('geohash').GeoHash
var JSONStream = require('JSONStream')
var async = require('async')
var gju = require('geostuff')
var t = tako()
t.plumb = plumbdb('data', function(err, db) {
t.db = db
})
t.route('/', function (req, resp) {
if (!req.qs) return resp.end()
var lat = +req.qs.lat
var lon = +req.qs.lon
var radius = +req.qs.radius
if (!lat || !lon || !radius) return resp.end()
var range = geohashRange(lat, lon, radius)
var circle = gju.drawCircle(radius, {type: "Point", coordinates: [lon, lat]})
resp.write('{"rows": [')
var sep = ""
t.plumb.rangeStream(range[0], range[1])
.on('data', function(key, value) {
var hash = geohash.decodeGeoHash(key)
var point = {type: "Point", coordinates: [hash.longitude[2], hash.latitude[2]]}
if (!gju.pointInPolygon(point, circle)) return
resp.write(sep + JSON.stringify(point))
sep = ","
})
.on('end', function() {
resp.end("]}")
})
})
function geohashRange(lat, lon, radius) {
var diff = radius / 111034 // convert to degrees
diff = diff / 2 // square diameter -> radius
var upper = geohash.encodeGeoHash(lat + diff, lon + diff)
var lower = geohash.encodeGeoHash(lat - diff, lon - diff)
return [lower, upper]
}
t.route('/upload', function (req, resp) {
var parser = JSONStream.parse(['features', /./])
shp2json(req).pipe(parser)
var q = queue(
store,
function(err) {
if (err) resp.end(err)
resp.end('ok')
}
)
parser.on('data', function(feature) {
q.push(feature, function(err) {
if (err) console.log(err)
})
})
})
function queue(save, cb) {
var q = async.queue(save, 1)
q.drain = cb
return q
}
function store(feature, cb) {
var type = feature.geometry.type
if (type === "Polygon") feature = preparePoly(feature)
if (type === "Point") feature = preparePoint(feature)
cb(false)
t.plumb._store(feature, function(err, json) {
if (err) cb(err)
cb(false, json)
})
}
function preparePoly(feature) {
var extent = gju.polygonExtent(feature.geometry)
console.log('extent', extent)
return feature
}
function preparePoint(feature) {
var lat = feature.geometry.coordinates[1]
var lon = feature.geometry.coordinates[0]
feature._id = geohash.encodeGeoHash(lat, lon)
return feature
}
t.httpServer.listen(8000, function () {
console.log('dun runnin')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment