Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e98617f
Showing
5 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
## geocodemany | ||
|
||
given an array of objects and a transform into a geocodable string, geocode | ||
them if possible. | ||
|
||
### example | ||
|
||
```js | ||
var data = [{ | ||
city: 'Chester', | ||
state: 'New Jersey' | ||
}, { | ||
city: 'Washington', | ||
state: 'DC' | ||
}]; | ||
|
||
function transform(obj) { | ||
return obj.city + ', ' + obj.state; | ||
} | ||
|
||
function progress() { | ||
console.log(arguments); | ||
} | ||
|
||
function done() { | ||
console.log(arguments); | ||
} | ||
|
||
var geocoder = geocodemany('tmcw.map-u4ca5hnt'); | ||
|
||
geocoder(data, transform, progress, done); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
function geocodemany(mapid, throttle) { | ||
throttle = (throttle === undefined) ? 200 : throttle; | ||
return function(list, transform, progress, callback) { | ||
|
||
var q = queue(1), | ||
todo = list.length, | ||
out = [], | ||
left = [], | ||
statuses = d3.range(todo).map(function() { return undefined; }), | ||
done = 0; | ||
|
||
function error(err, callback) { | ||
statuses[done] = false; | ||
progress({ | ||
todo: todo, | ||
done: ++done, | ||
statuses: statuses | ||
}); | ||
callback(err); | ||
} | ||
|
||
// forgive me | ||
function copy(o) { return JSON.parse(JSON.stringify(o)); } | ||
|
||
function run(obj, callback) { | ||
var str = transform(obj); | ||
var output = copy(obj); | ||
d3.json('http://api.tiles.mapbox.com/v3/' + mapid + '/geocode/' + | ||
encodeURIComponent(str) + '.json') | ||
.on('load', function(data) { | ||
if (data && data.results && data.results.length && | ||
data.results[0].length) { | ||
|
||
var ll = data.results[0][0]; | ||
output.latitude = ll.lat; | ||
output.longitude = ll.lon; | ||
statuses[done] = true; | ||
progress({ | ||
todo: todo, | ||
done: ++done, | ||
statuses: statuses | ||
}); | ||
setTimeout(function() { | ||
callback(null, output); | ||
}, throttle); | ||
|
||
} else { | ||
error({ | ||
error: new Error('Location not found'), | ||
data: output | ||
}, callback); | ||
} | ||
}) | ||
.on('error', function(err) { | ||
error({ | ||
error: err, | ||
data: output | ||
}, callback); | ||
}) | ||
.get(); | ||
} | ||
|
||
function enqueue(obj) { | ||
q.defer(run, obj); | ||
} | ||
|
||
list.forEach(enqueue); | ||
|
||
q.awaitAll(callback); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title></title> | ||
<link rel='stylesheet' type='text/css' href='css/style.css' /> | ||
<meta http-equiv='content-type' content='text/html; charset=utf-8' /> | ||
<meta name='viewport' content='initial-scale=1.0 maximum-scale=1.0'> | ||
</head> | ||
<body> | ||
<script src='js/d3.v3.min.js'></script> | ||
<script src='js/queue.js'></script> | ||
<script src='geocodemany.js'></script> | ||
<script> | ||
var data = [{ | ||
city: 'Chester', | ||
state: 'New Jersey' | ||
}, { | ||
city: 'Washington', | ||
state: 'DC' | ||
}]; | ||
|
||
function transform(obj) { | ||
return obj.city + ', ' + obj.state; | ||
} | ||
|
||
function progress() { | ||
console.log(arguments); | ||
} | ||
|
||
function done() { | ||
console.log(arguments); | ||
} | ||
|
||
var geocoder = geocodemany('tmcw.map-u4ca5hnt'); | ||
|
||
geocoder(data, transform, progress, done); | ||
</script> | ||
</body> | ||
</html> |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
(function() { | ||
if (typeof module === "undefined") self.queue = queue; | ||
else module.exports = queue; | ||
queue.version = "1.0.4"; | ||
|
||
var slice = [].slice; | ||
|
||
function queue(parallelism) { | ||
var q, | ||
tasks = [], | ||
started = 0, // number of tasks that have been started (and perhaps finished) | ||
active = 0, // number of tasks currently being executed (started but not finished) | ||
remaining = 0, // number of tasks not yet finished | ||
popping, // inside a synchronous task callback? | ||
error = null, | ||
await = noop, | ||
all; | ||
|
||
if (!parallelism) parallelism = Infinity; | ||
|
||
function pop() { | ||
while (popping = started < tasks.length && active < parallelism) { | ||
var i = started++, | ||
t = tasks[i], | ||
a = slice.call(t, 1); | ||
a.push(callback(i)); | ||
++active; | ||
t[0].apply(null, a); | ||
} | ||
} | ||
|
||
function callback(i) { | ||
return function(e, r) { | ||
--active; | ||
if (error != null) return; | ||
if (e != null) { | ||
error = e; // ignore new tasks and squelch active callbacks | ||
started = remaining = NaN; // stop queued tasks from starting | ||
notify(); | ||
} else { | ||
tasks[i] = r; | ||
if (--remaining) popping || pop(); | ||
else notify(); | ||
} | ||
}; | ||
} | ||
|
||
function notify() { | ||
if (error != null) await(error); | ||
else if (all) await(error, tasks); | ||
else await.apply(null, [error].concat(tasks)); | ||
} | ||
|
||
return q = { | ||
defer: function() { | ||
if (!error) { | ||
tasks.push(arguments); | ||
++remaining; | ||
pop(); | ||
} | ||
return q; | ||
}, | ||
await: function(f) { | ||
await = f; | ||
all = false; | ||
if (!remaining) notify(); | ||
return q; | ||
}, | ||
awaitAll: function(f) { | ||
await = f; | ||
all = true; | ||
if (!remaining) notify(); | ||
return q; | ||
} | ||
}; | ||
} | ||
|
||
function noop() {} | ||
})(); |