forked from mapbox/tilelive-overlay
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
123 lines (107 loc) · 3.03 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
var util = require('util'),
mapnik = require('@kartotherian/mapnik'),
sm = new (require('@mapbox/sphericalmercator'))(),
mapnikify = require('@kartotherian/geojson-mapnikify'),
url = require('url'),
fs = require('fs'),
ErrorHTTP = require('./lib/errorhttp'),
os = require('os'),
path = require('path');
if (mapnik.register_default_input_plugins) {
mapnik.register_default_input_plugins();
}
module.exports = Source;
require('util').inherits(Source, require('events').EventEmitter);
/**
* Create a new source that returns tiles from a simplestyle-supporting
* GeoJSON object.
*
* @param {string} uri
* @param {function} callback
* @returns {undefined}
*/
function Source(id, callback) {
var uri = url.parse(id);
if (!uri || (uri.protocol && uri.protocol !== 'overlaydata:')) {
return callback('Only the overlaydata protocol is supported');
}
var data = id.replace('overlaydata://', '');
var retina = false;
var legacy = false;
if (data.indexOf('2x:') === 0) {
retina = true;
data = data.replace(/^2x:/, '');
}
if (data.indexOf('legacy:') === 0) {
legacy = true;
data = data.replace(/^legacy:/, '');
}
var parsed;
try {
parsed = JSON.parse(data);
} catch(e) {
return callback('invalid geojson');
}
mapnikify(parsed, retina, function(err, xml) {
if (err) return callback(err);
this._xml = xml;
this._size = retina && !legacy ? 512 : 256;
this._bufferSize = retina ? 128 : 64;
callback(null, this);
}.bind(this));
}
/**
* Gets a tile from this source.
*
* @param {number} z
* @param {number} x
* @param {number} y
* @param {function} callback
*/
Source.prototype.getTile = function(z, x, y, callback) {
var size = this._size;
var map = new mapnik.Map(size, size);
map.bufferSize = this._bufferSize;
try {
map.fromString(this._xml, {}, function(err) {
if (err) return callback(err);
map.extent = sm.bbox(x, y, z, false, '900913');
map.render(new mapnik.Image(size, size), {}, onrender);
});
} catch(e) {
callback(e);
}
function onrender(err, im) {
if (err) return callback(err);
im.encode('png8:m=h:z=1', function(err, res) {
callback(err, res);
});
}
};
/**
* Gets a grid from this source: this will always fail, because
* this source does not provide grids.
*
* @param {number} z
* @param {number} x
* @param {number} y
* @param {function} callback
*/
Source.prototype.getGrid = function(z, x, y, callback) {
callback('This source does not provide grids');
};
/**
* Gets info from this source: this will always fail, because
* this source does not provide info.
*
* @param {function} callback
*/
Source.prototype.getInfo = function(callback) {
callback('This source does not provide info');
};
/**
* @param {object} tilelive
*/
Source.registerProtocols = function(tilelive) {
tilelive.protocols['overlaydata:'] = Source;
};