tileserver-gl-light 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +3 -2
- package/Dockerfile_test +2 -1
- package/docker-entrypoint.sh +13 -1
- package/docs/conf.py +4 -4
- package/docs/installation.rst +23 -4
- package/docs/usage.rst +4 -2
- package/package.json +11 -11
- package/public/resources/L.TileLayer.NoGap.js +243 -0
- package/public/resources/leaflet.css +657 -0
- package/public/resources/leaflet.js +6 -0
- package/public/resources/leaflet.js.map +1 -0
- package/public/resources/maplibre-gl-compat.css +1 -0
- package/public/resources/maplibre-gl-compat.js +45 -0
- package/public/resources/maplibre-gl-compat.js.map +1 -0
- package/public/resources/maplibre-gl-inspect-compat.min.js +1 -0
- package/public/resources/maplibre-gl-inspect.css +39 -0
- package/public/resources/maplibre-gl-inspect.min.js +1 -0
- package/public/resources/maplibre-gl.css +1 -0
- package/public/resources/maplibre-gl.js +44 -0
- package/public/resources/maplibre-gl.js.map +1 -0
- package/public/templates/data.tmpl +54 -15
- package/public/templates/viewer.tmpl +68 -14
- package/publish.js +2 -1
- package/src/main.js +4 -2
- package/src/serve_rendered.js +23 -22
- package/src/serve_style.js +1 -1
- package/public/resources/mapbox-gl-inspect.css +0 -40
- package/public/resources/mapbox-gl-inspect.min.js +0 -1
- package/public/resources/mapbox-gl.css +0 -1
- package/public/resources/mapbox-gl.js +0 -40
- package/public/resources/mapbox.css +0 -1
- package/public/resources/mapbox.js +0 -67
package/Dockerfile
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM node:
|
|
1
|
+
FROM node:16-bullseye
|
|
2
2
|
|
|
3
3
|
ENV NODE_ENV="production"
|
|
4
4
|
ENV CHOKIDAR_USEPOLLING=1
|
|
@@ -6,8 +6,9 @@ ENV CHOKIDAR_INTERVAL=500
|
|
|
6
6
|
EXPOSE 80
|
|
7
7
|
VOLUME /data
|
|
8
8
|
WORKDIR /data
|
|
9
|
-
ENTRYPOINT ["
|
|
9
|
+
ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
|
|
10
10
|
|
|
11
11
|
RUN mkdir -p /usr/src/app
|
|
12
12
|
COPY / /usr/src/app
|
|
13
13
|
RUN cd /usr/src/app && npm install --production
|
|
14
|
+
RUN ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"]
|
package/Dockerfile_test
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Simply run "docker build -f Dockerfile_test ."
|
|
3
3
|
# WARNING: sometimes it fails with a core dumped exception
|
|
4
4
|
|
|
5
|
-
FROM node:
|
|
5
|
+
FROM node:16-bullseye
|
|
6
6
|
|
|
7
7
|
RUN apt-get -qq update \
|
|
8
8
|
&& DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
|
@@ -17,6 +17,7 @@ RUN apt-get -qq update \
|
|
|
17
17
|
libllvm3.9 \
|
|
18
18
|
libprotobuf-dev \
|
|
19
19
|
libxxf86vm-dev \
|
|
20
|
+
libopengl0 \
|
|
20
21
|
xvfb \
|
|
21
22
|
&& apt-get clean
|
|
22
23
|
|
package/docker-entrypoint.sh
CHANGED
|
@@ -10,12 +10,24 @@ handle() {
|
|
|
10
10
|
|
|
11
11
|
trap handle INT TERM
|
|
12
12
|
|
|
13
|
+
refresh() {
|
|
14
|
+
SIGNAL=$(( $? - 128 ))
|
|
15
|
+
echo "Caught signal ${SIGNAL}, refreshing"
|
|
16
|
+
kill -s ${SIGNAL} $(pidof node) 2>/dev/null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
trap refresh HUP
|
|
20
|
+
|
|
13
21
|
if ! which -- "${1}"; then
|
|
14
22
|
# first arg is not an executable
|
|
15
|
-
|
|
23
|
+
node /usr/src/app/ -p 80 "$@" &
|
|
16
24
|
# Wait exits immediately on signals which have traps set. Store return value and wait
|
|
17
25
|
# again for all jobs to actually complete before continuing.
|
|
18
26
|
wait $! || RETVAL=$?
|
|
27
|
+
while [ ${RETVAL} = 129 ] ; do
|
|
28
|
+
# Refressh signal HUP received. Continue waiting for signals.
|
|
29
|
+
wait $! || RETVAL=$?
|
|
30
|
+
done
|
|
19
31
|
wait
|
|
20
32
|
exit ${RETVAL}
|
|
21
33
|
fi
|
package/docs/conf.py
CHANGED
|
@@ -44,7 +44,7 @@ master_doc = 'index'
|
|
|
44
44
|
|
|
45
45
|
# General information about the project.
|
|
46
46
|
project = u'TileServer GL'
|
|
47
|
-
copyright = u'
|
|
47
|
+
copyright = u'2022, MapTiler.com'
|
|
48
48
|
|
|
49
49
|
# The version info for the project you're documenting, acts as replacement for
|
|
50
50
|
# |version| and |release|, also used in various other places throughout the
|
|
@@ -197,7 +197,7 @@ latex_elements = {
|
|
|
197
197
|
# author, documentclass [howto, manual, or own class]).
|
|
198
198
|
latex_documents = [
|
|
199
199
|
('index', 'TileServerGL.tex', u'TileServer GL Documentation',
|
|
200
|
-
u'
|
|
200
|
+
u'MapTiler.com', 'manual'),
|
|
201
201
|
]
|
|
202
202
|
|
|
203
203
|
# The name of an image file (relative to this directory) to place at the top of
|
|
@@ -227,7 +227,7 @@ latex_documents = [
|
|
|
227
227
|
# (source start file, name, description, authors, manual section).
|
|
228
228
|
man_pages = [
|
|
229
229
|
('index', 'tileservergl', u'TileServer GL Documentation',
|
|
230
|
-
[u'
|
|
230
|
+
[u'MapTiler.com'], 1)
|
|
231
231
|
]
|
|
232
232
|
|
|
233
233
|
# If true, show URL addresses after external links.
|
|
@@ -241,7 +241,7 @@ man_pages = [
|
|
|
241
241
|
# dir menu entry, description, category)
|
|
242
242
|
texinfo_documents = [
|
|
243
243
|
('index', 'TileServerGL', u'TileServer GL Documentation',
|
|
244
|
-
u'
|
|
244
|
+
u'MapTiler.com', 'TileServerGL', 'One line description of project.',
|
|
245
245
|
'Miscellaneous'),
|
|
246
246
|
]
|
|
247
247
|
|
package/docs/installation.rst
CHANGED
|
@@ -26,11 +26,30 @@ Native dependencies
|
|
|
26
26
|
There are some native dependencies that you need to make sure are installed if you plan to run the TileServer GL natively without docker.
|
|
27
27
|
The precise package names you need to install may differ on various platforms.
|
|
28
28
|
|
|
29
|
-
These are required on Debian
|
|
30
|
-
* ``
|
|
29
|
+
These are required on Debian 11:
|
|
30
|
+
* ``libgles2-mesa``
|
|
31
|
+
* ``libegl1``
|
|
32
|
+
* ``xvfb``
|
|
33
|
+
* ``xauth``
|
|
34
|
+
* ``libopengl0``
|
|
35
|
+
* ``libcurl4``
|
|
36
|
+
* ``curl``
|
|
37
|
+
* ``libuv1-dev``
|
|
38
|
+
* ``libc6-dev``
|
|
39
|
+
* ``http://archive.ubuntu.com/ubuntu/pool/main/libj/libjpeg-turbo/libjpeg-turbo8_2.0.3-0ubuntu1_amd64.deb``
|
|
40
|
+
* ``http://archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu66_66.1-2ubuntu2_amd64.deb``
|
|
41
|
+
|
|
42
|
+
These are required on Ubuntu 20.04:
|
|
31
43
|
* ``libcairo2-dev``
|
|
32
|
-
* ``
|
|
33
|
-
|
|
44
|
+
* ``libjpeg8-dev``
|
|
45
|
+
* ``libpango1.0-dev``
|
|
46
|
+
* ``libgif-dev``
|
|
47
|
+
* ``build-essential``
|
|
48
|
+
* ``g++``
|
|
49
|
+
* ``xvfb``
|
|
50
|
+
* ``libgles2-mesa-dev``
|
|
51
|
+
* ``libgbm-dev``
|
|
52
|
+
* ``libxxf86vm-dev``
|
|
34
53
|
|
|
35
54
|
``tileserver-gl-light`` on npm
|
|
36
55
|
==============================
|
package/docs/usage.rst
CHANGED
|
@@ -29,8 +29,10 @@ Default preview style and configuration
|
|
|
29
29
|
- If no configuration file is specified, a default preview style (compatible with openmaptiles) is used.
|
|
30
30
|
- If no mbtiles file is specified (and is not found in the current working directory), a sample file is downloaded (showing the Zurich area)
|
|
31
31
|
|
|
32
|
-
Reloading configuration
|
|
32
|
+
Reloading the configuration
|
|
33
33
|
======
|
|
34
34
|
|
|
35
35
|
It is possible to reload the configuration file without restarting the whole process by sending a SIGHUP signal to the node process.
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
- The `docker kill -s HUP tileserver-gl` command can be used when running the tileserver-gl docker container.
|
|
38
|
+
- The `docker-compose kill -s HUP tileserver-gl-service-name` can be used when tileserver-gl is run as a docker-compose service.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tileserver-gl-light",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Map tile server for JSON GL styles - serving vector tiles",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"bin": "src/main.js",
|
|
@@ -18,23 +18,23 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@mapbox/glyph-pbf-composite": "0.0.3",
|
|
21
|
-
"@
|
|
22
|
-
"@mapbox/mbtiles": "0.
|
|
23
|
-
"@mapbox/sphericalmercator": "1.
|
|
21
|
+
"@maplibre/maplibre-gl-style-spec": "17.0.1",
|
|
22
|
+
"@mapbox/mbtiles": "0.12.1",
|
|
23
|
+
"@mapbox/sphericalmercator": "1.2.0",
|
|
24
24
|
"@mapbox/vector-tile": "1.3.1",
|
|
25
25
|
"advanced-pool": "0.3.3",
|
|
26
|
-
"chokidar": "3.3
|
|
26
|
+
"chokidar": "3.5.3",
|
|
27
27
|
"clone": "2.1.2",
|
|
28
|
-
"color": "
|
|
29
|
-
"commander": "4.
|
|
28
|
+
"color": "4.2.3",
|
|
29
|
+
"commander": "9.4.0",
|
|
30
30
|
"cors": "2.8.5",
|
|
31
31
|
"esm": "3.2.25",
|
|
32
|
-
"express": "4.
|
|
33
|
-
"handlebars": "4.7.
|
|
32
|
+
"express": "4.18.1",
|
|
33
|
+
"handlebars": "4.7.7",
|
|
34
34
|
"http-shutdown": "1.2.2",
|
|
35
|
-
"morgan": "1.
|
|
35
|
+
"morgan": "1.10.0",
|
|
36
36
|
"pbf": "3.2.1",
|
|
37
|
-
"proj4": "2.
|
|
37
|
+
"proj4": "2.8.0",
|
|
38
38
|
"request": "2.88.2",
|
|
39
39
|
"tileserver-gl-styles": "2.0.0"
|
|
40
40
|
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// @class TileLayer
|
|
2
|
+
|
|
3
|
+
L.TileLayer.mergeOptions({
|
|
4
|
+
// @option keepBuffer
|
|
5
|
+
// The amount of tiles outside the visible map area to be kept in the stitched
|
|
6
|
+
// `TileLayer`.
|
|
7
|
+
|
|
8
|
+
// @option dumpToCanvas: Boolean = true
|
|
9
|
+
// Whether to dump loaded tiles to a `<canvas>` to prevent some rendering
|
|
10
|
+
// artifacts. (Disabled by default in IE)
|
|
11
|
+
dumpToCanvas: L.Browser.canvas && !L.Browser.ie,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
L.TileLayer.include({
|
|
15
|
+
_onUpdateLevel: function(z, zoom) {
|
|
16
|
+
if (this.options.dumpToCanvas) {
|
|
17
|
+
this._levels[z].canvas.style.zIndex =
|
|
18
|
+
this.options.maxZoom - Math.abs(zoom - z);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
_onRemoveLevel: function(z) {
|
|
23
|
+
if (this.options.dumpToCanvas) {
|
|
24
|
+
L.DomUtil.remove(this._levels[z].canvas);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
_onCreateLevel: function(level) {
|
|
29
|
+
if (this.options.dumpToCanvas) {
|
|
30
|
+
level.canvas = L.DomUtil.create(
|
|
31
|
+
"canvas",
|
|
32
|
+
"leaflet-tile-container leaflet-zoom-animated",
|
|
33
|
+
this._container
|
|
34
|
+
);
|
|
35
|
+
level.ctx = level.canvas.getContext("2d");
|
|
36
|
+
this._resetCanvasSize(level);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
_removeTile: function(key) {
|
|
41
|
+
if (this.options.dumpToCanvas) {
|
|
42
|
+
var tile = this._tiles[key];
|
|
43
|
+
var level = this._levels[tile.coords.z];
|
|
44
|
+
var tileSize = this.getTileSize();
|
|
45
|
+
|
|
46
|
+
if (level) {
|
|
47
|
+
// Where in the canvas should this tile go?
|
|
48
|
+
var offset = L.point(tile.coords.x, tile.coords.y)
|
|
49
|
+
.subtract(level.canvasRange.min)
|
|
50
|
+
.scaleBy(this.getTileSize());
|
|
51
|
+
|
|
52
|
+
level.ctx.clearRect(offset.x, offset.y, tileSize.x, tileSize.y);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
L.GridLayer.prototype._removeTile.call(this, key);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
_resetCanvasSize: function(level) {
|
|
60
|
+
var buff = this.options.keepBuffer,
|
|
61
|
+
pixelBounds = this._getTiledPixelBounds(this._map.getCenter()),
|
|
62
|
+
tileRange = this._pxBoundsToTileRange(pixelBounds),
|
|
63
|
+
tileSize = this.getTileSize();
|
|
64
|
+
|
|
65
|
+
tileRange.min = tileRange.min.subtract([buff, buff]); // This adds the no-prune buffer
|
|
66
|
+
tileRange.max = tileRange.max.add([buff + 1, buff + 1]);
|
|
67
|
+
|
|
68
|
+
var pixelRange = L.bounds(
|
|
69
|
+
tileRange.min.scaleBy(tileSize),
|
|
70
|
+
tileRange.max.add([1, 1]).scaleBy(tileSize) // This prevents an off-by-one when checking if tiles are inside
|
|
71
|
+
),
|
|
72
|
+
mustRepositionCanvas = false,
|
|
73
|
+
neededSize = pixelRange.max.subtract(pixelRange.min);
|
|
74
|
+
|
|
75
|
+
// Resize the canvas, if needed, and only to make it bigger.
|
|
76
|
+
if (
|
|
77
|
+
neededSize.x > level.canvas.width ||
|
|
78
|
+
neededSize.y > level.canvas.height
|
|
79
|
+
) {
|
|
80
|
+
// Resizing canvases erases the currently drawn content, I'm afraid.
|
|
81
|
+
// To keep it, dump the pixels to another canvas, then display it on
|
|
82
|
+
// top. This could be done with getImageData/putImageData, but that
|
|
83
|
+
// would break for tainted canvases (in non-CORS tilesets)
|
|
84
|
+
var oldSize = { x: level.canvas.width, y: level.canvas.height };
|
|
85
|
+
// console.info('Resizing canvas from ', oldSize, 'to ', neededSize);
|
|
86
|
+
|
|
87
|
+
var tmpCanvas = L.DomUtil.create("canvas");
|
|
88
|
+
tmpCanvas.style.width = (tmpCanvas.width = oldSize.x) + "px";
|
|
89
|
+
tmpCanvas.style.height = (tmpCanvas.height = oldSize.y) + "px";
|
|
90
|
+
tmpCanvas.getContext("2d").drawImage(level.canvas, 0, 0);
|
|
91
|
+
// var data = level.ctx.getImageData(0, 0, oldSize.x, oldSize.y);
|
|
92
|
+
|
|
93
|
+
level.canvas.style.width = (level.canvas.width = neededSize.x) + "px";
|
|
94
|
+
level.canvas.style.height = (level.canvas.height = neededSize.y) + "px";
|
|
95
|
+
level.ctx.drawImage(tmpCanvas, 0, 0);
|
|
96
|
+
// level.ctx.putImageData(data, 0, 0, 0, 0, oldSize.x, oldSize.y);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Translate the canvas contents if it's moved around
|
|
100
|
+
if (level.canvasRange) {
|
|
101
|
+
var offset = level.canvasRange.min
|
|
102
|
+
.subtract(tileRange.min)
|
|
103
|
+
.scaleBy(this.getTileSize());
|
|
104
|
+
|
|
105
|
+
// console.info('Offsetting by ', offset);
|
|
106
|
+
|
|
107
|
+
if (!L.Browser.safari) {
|
|
108
|
+
// By default, canvases copy things "on top of" existing pixels, but we want
|
|
109
|
+
// this to *replace* the existing pixels when doing a drawImage() call.
|
|
110
|
+
// This will also clear the sides, so no clearRect() calls are needed to make room
|
|
111
|
+
// for the new tiles.
|
|
112
|
+
level.ctx.globalCompositeOperation = "copy";
|
|
113
|
+
level.ctx.drawImage(level.canvas, offset.x, offset.y);
|
|
114
|
+
level.ctx.globalCompositeOperation = "source-over";
|
|
115
|
+
} else {
|
|
116
|
+
// Safari clears the canvas when copying from itself :-(
|
|
117
|
+
if (!this._tmpCanvas) {
|
|
118
|
+
var t = (this._tmpCanvas = L.DomUtil.create("canvas"));
|
|
119
|
+
t.width = level.canvas.width;
|
|
120
|
+
t.height = level.canvas.height;
|
|
121
|
+
this._tmpContext = t.getContext("2d");
|
|
122
|
+
}
|
|
123
|
+
this._tmpContext.clearRect(
|
|
124
|
+
0,
|
|
125
|
+
0,
|
|
126
|
+
level.canvas.width,
|
|
127
|
+
level.canvas.height
|
|
128
|
+
);
|
|
129
|
+
this._tmpContext.drawImage(level.canvas, 0, 0);
|
|
130
|
+
level.ctx.clearRect(0, 0, level.canvas.width, level.canvas.height);
|
|
131
|
+
level.ctx.drawImage(this._tmpCanvas, offset.x, offset.y);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
mustRepositionCanvas = true; // Wait until new props are set
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
level.canvasRange = tileRange;
|
|
138
|
+
level.canvasPxRange = pixelRange;
|
|
139
|
+
level.canvasOrigin = pixelRange.min;
|
|
140
|
+
|
|
141
|
+
// console.log('Canvas tile range: ', level, tileRange.min, tileRange.max );
|
|
142
|
+
// console.log('Canvas pixel range: ', pixelRange.min, pixelRange.max );
|
|
143
|
+
// console.log('Level origin: ', level.origin );
|
|
144
|
+
|
|
145
|
+
if (mustRepositionCanvas) {
|
|
146
|
+
this._setCanvasZoomTransform(
|
|
147
|
+
level,
|
|
148
|
+
this._map.getCenter(),
|
|
149
|
+
this._map.getZoom()
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
/// set transform/position of canvas, in addition to the transform/position of the individual tile container
|
|
155
|
+
_setZoomTransform: function(level, center, zoom) {
|
|
156
|
+
L.GridLayer.prototype._setZoomTransform.call(this, level, center, zoom);
|
|
157
|
+
if (this.options.dumpToCanvas) {
|
|
158
|
+
this._setCanvasZoomTransform(level, center, zoom);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// This will get called twice:
|
|
163
|
+
// * From _setZoomTransform
|
|
164
|
+
// * When the canvas has shifted due to a new tile being loaded
|
|
165
|
+
_setCanvasZoomTransform: function(level, center, zoom) {
|
|
166
|
+
// console.log('_setCanvasZoomTransform', level, center, zoom);
|
|
167
|
+
if (!level.canvasOrigin) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
var scale = this._map.getZoomScale(zoom, level.zoom),
|
|
171
|
+
translate = level.canvasOrigin
|
|
172
|
+
.multiplyBy(scale)
|
|
173
|
+
.subtract(this._map._getNewPixelOrigin(center, zoom))
|
|
174
|
+
.round();
|
|
175
|
+
|
|
176
|
+
if (L.Browser.any3d) {
|
|
177
|
+
L.DomUtil.setTransform(level.canvas, translate, scale);
|
|
178
|
+
} else {
|
|
179
|
+
L.DomUtil.setPosition(level.canvas, translate);
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
_onOpaqueTile: function(tile) {
|
|
184
|
+
if (!this.options.dumpToCanvas) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Guard against an NS_ERROR_NOT_AVAILABLE (or similar) exception
|
|
189
|
+
// when a non-image-tile has been loaded (e.g. a WMS error).
|
|
190
|
+
// Checking for tile.el.complete is not enough, as it has been
|
|
191
|
+
// already marked as loaded and ready somehow.
|
|
192
|
+
try {
|
|
193
|
+
this.dumpPixels(tile.coords, tile.el);
|
|
194
|
+
} catch (ex) {
|
|
195
|
+
return this.fire("tileerror", {
|
|
196
|
+
error: "Could not copy tile pixels: " + ex,
|
|
197
|
+
tile: tile,
|
|
198
|
+
coods: tile.coords,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// If dumping the pixels was successful, then hide the tile.
|
|
203
|
+
// Do not remove the tile itself, as it is needed to check if the whole
|
|
204
|
+
// level (and its canvas) should be removed (via level.el.children.length)
|
|
205
|
+
tile.el.style.display = "none";
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
// @section Extension methods
|
|
209
|
+
// @uninheritable
|
|
210
|
+
|
|
211
|
+
// @method dumpPixels(coords: Object, imageSource: CanvasImageSource): this
|
|
212
|
+
// Dumps pixels from the given `CanvasImageSource` into the layer, into
|
|
213
|
+
// the space for the tile represented by the `coords` tile coordinates (an object
|
|
214
|
+
// like `{x: Number, y: Number, z: Number}`; the image source must have the
|
|
215
|
+
// same size as the `tileSize` option for the layer. Has no effect if `dumpToCanvas`
|
|
216
|
+
// is `false`.
|
|
217
|
+
dumpPixels: function(coords, imageSource) {
|
|
218
|
+
var level = this._levels[coords.z],
|
|
219
|
+
tileSize = this.getTileSize();
|
|
220
|
+
|
|
221
|
+
if (!level.canvasRange || !this.options.dumpToCanvas) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Check if the tile is inside the currently visible map bounds
|
|
226
|
+
// There is a possible race condition when tiles are loaded after they
|
|
227
|
+
// have been panned outside of the map.
|
|
228
|
+
if (!level.canvasRange.contains(coords)) {
|
|
229
|
+
this._resetCanvasSize(level);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Where in the canvas should this tile go?
|
|
233
|
+
var offset = L.point(coords.x, coords.y)
|
|
234
|
+
.subtract(level.canvasRange.min)
|
|
235
|
+
.scaleBy(this.getTileSize());
|
|
236
|
+
|
|
237
|
+
level.ctx.drawImage(imageSource, offset.x, offset.y, tileSize.x, tileSize.y);
|
|
238
|
+
|
|
239
|
+
// TODO: Clear the pixels of other levels' canvases where they overlap
|
|
240
|
+
// this newly dumped tile.
|
|
241
|
+
return this;
|
|
242
|
+
},
|
|
243
|
+
});
|