mmg
Version:
Simple markers for Modest Maps
130 lines (112 loc) • 3.76 kB
JavaScript
function mmg_csv(url, callback) {
// Extracted from d3
function csv_parse(text) {
var header;
return csv_parseRows(text, function(row, i) {
if (i) {
var o = {}, j = -1, m = header.length;
while (++j < m) o[header[j]] = row[j];
return o;
} else {
header = row;
return null;
}
});
}
function csv_parseRows (text, f) {
var EOL = {}, // sentinel value for end-of-line
EOF = {}, // sentinel value for end-of-file
rows = [], // output rows
re = /\r\n|[,\r\n]/g, // field separator regex
n = 0, // the current line number
t, // the current token
eol; // is the current token followed by EOL?
re.lastIndex = 0; // work-around bug in FF 3.6
/** @private Returns the next token. */
function token() {
if (re.lastIndex >= text.length) return EOF; // special case: end of file
if (eol) { eol = false; return EOL; } // special case: end of line
// special case: quotes
var j = re.lastIndex;
if (text.charCodeAt(j) === 34) {
var i = j;
while (i++ < text.length) {
if (text.charCodeAt(i) === 34) {
if (text.charCodeAt(i + 1) !== 34) break;
i++;
}
}
re.lastIndex = i + 2;
var c = text.charCodeAt(i + 1);
if (c === 13) {
eol = true;
if (text.charCodeAt(i + 2) === 10) re.lastIndex++;
} else if (c === 10) {
eol = true;
}
return text.substring(j + 1, i).replace(/""/g, "\"");
}
// common case
var m = re.exec(text);
if (m) {
eol = m[0].charCodeAt(0) !== 44;
return text.substring(j, m.index);
}
re.lastIndex = text.length;
return text.substring(j);
}
while ((t = token()) !== EOF) {
var a = [];
while ((t !== EOL) && (t !== EOF)) {
a.push(t);
t = token();
}
if (f && !(a = f(a, n++))) continue;
rows.push(a);
}
return rows;
}
if (!arguments.length) return urls;
if (typeof reqwest === 'undefined') throw 'reqwest is required for url loading';
var log = (typeof console !== 'undefined') ? function(x) { console.log(x); } : function() {};
function add_features(x) {
var features = [];
if (x.status >= 400) {
if (typeof console != 'undefined') throw 'URL returned 404';
return callback(features);
}
var parsed = csv_parse(x.responseText);
if (!parsed.length) return callback(features);
var latfield = '',
lonfield = '';
for (var f in parsed[0]) {
if (f.match(/^Lat/i)) latfield = f;
if (f.match(/^Lon/i)) lonfield = f;
}
for (var i = 0; i < parsed.length; i++) {
if (parsed[i][lonfield] !== undefined &&
parsed[i][lonfield] !== undefined) {
features.push({
type: 'Feature',
properties: parsed[i],
geometry: {
type: 'Point',
coordinates: [
parsed[i][lonfield],
parsed[i][latfield]]
}
});
} else {
log('Some points did not contain lat/lon data');
log(parsed[i]);
}
}
if (callback) callback(features);
}
reqwest({
url: url,
type: 'string',
success: add_features,
error: add_features
});
}