Skip to content

Commit

Permalink
First
Browse files Browse the repository at this point in the history
  • Loading branch information
tmcw committed Aug 3, 2013
0 parents commit e98617f
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 0 deletions.
32 changes: 32 additions & 0 deletions README.md
@@ -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);
```
71 changes: 71 additions & 0 deletions geocodemany.js
@@ -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);
};
}
40 changes: 40 additions & 0 deletions index.html
@@ -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>
5 changes: 5 additions & 0 deletions js/d3.v3.min.js

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions js/queue.js
@@ -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() {}
})();

0 comments on commit e98617f

Please sign in to comment.