-
Notifications
You must be signed in to change notification settings - Fork 29
/
index.js
90 lines (78 loc) · 2.97 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
'use strict';
var vt = require('vector-tile');
var request = require('request');
var Protobuf = require('pbf');
var format = require('util').format;
var fs = require('fs');
var url = require('url');
var zlib = require('zlib');
module.exports = function(args, callback) {
if (!args.uri) return callback(new Error('No URI found. Please provide a valid URI to your vector tile.'));
// handle zxy stuffs
if (args.x === undefined || args.y === undefined || args.z === undefined) {
var zxy = args.uri.match(/\/(\d+)\/(\d+)\/(\d+)/);
if (!zxy || zxy.length < 4) {
return callback(new Error(format("Could not determine tile z, x, and y from %s; specify manually with -z <z> -x <x> -y <y>", JSON.stringify(args.uri))));
} else {
args.z = zxy[1];
args.x = zxy[2];
args.y = zxy[3];
}
}
var parsed = url.parse(args.uri);
if (parsed.protocol && (parsed.protocol === 'http:' || parsed.protocol === 'https:')) {
request.get({
url: args.uri,
gzip: true,
encoding: null
}, function (err, response, body) {
if (err) {
return callback(err);
}
if (response.statusCode === 401) {
return callback(new Error('Invalid Token'));
}
if (response.statusCode !== 200) {
return callback(new Error(format('Error retrieving data from %s. Server responded with code: %s', JSON.stringify(args.uri), response.statusCode)));
}
readTile(args, body, callback);
});
} else {
if (parsed.protocol && parsed.protocol === 'file:') {
args.uri = parsed.host + parsed.pathname;
}
fs.lstat(args.uri, function(err, stats) {
if (err) throw err;
if (stats.isFile()) {
fs.readFile(args.uri, function(err, data) {
if (err) throw err;
readTile(args, data, callback);
});
}
});
}
};
function readTile(args, buffer, callback) {
// handle zipped buffers
if (buffer[0] === 0x78 && buffer[1] === 0x9C) {
buffer = zlib.inflateSync(buffer);
} else if (buffer[0] === 0x1F && buffer[1] === 0x8B) {
buffer = zlib.gunzipSync(buffer);
}
var tile = new vt.VectorTile(new Protobuf(buffer));
var layers = args.layer || Object.keys(tile.layers);
if (!Array.isArray(layers))
layers = [layers]
var collection = {type: 'FeatureCollection', features: []};
layers.forEach(function (layerID) {
var layer = tile.layers[layerID];
if (layer) {
for (var i = 0; i < layer.length; i++) {
var feature = layer.feature(i).toGeoJSON(args.x, args.y, args.z);
if (layers.length > 1) feature.properties.vt_layer = layerID;
collection.features.push(feature);
}
}
});
callback(null, collection);
}