Skip to content

Commit 5ad1f68

Browse files
committed
fix baselayer
1 parent 71b649e commit 5ad1f68

File tree

4 files changed

+250
-0
lines changed

4 files changed

+250
-0
lines changed

css/main.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,11 @@ header .search form input[type='submit'] {
807807
visibility: visible;
808808
}
809809

810+
/* workaround for subpixel lines https://github.com/Leaflet/Leaflet/issues/3575#issuecomment-688644225 */
811+
.leaflet-tile-container img {
812+
width: 256.5px !important;
813+
height: 256.5px !important;
814+
}
810815

811816
@media only screen and (min-width: 900px) {
812817
}

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ <h3>Report Recovery</h3>
378378
<script type="text/javascript" language="javascript" src="js/leaflet.js"></script>
379379
<script type="text/javascript" language="javascript" src="js/Leaflet.fullscreen.min.js"></script>
380380
<script type="text/javascript" language="javascript" src="js/L.Terminator.js"></script>
381+
<script type="text/javascript" language="javascript" src="js/L.TileLayer.NoGap.js"></script>
381382
<script type="text/javascript" language="javascript" src="js/paho-mqtt.js"></script>
382383
<script src="https://xc5dqkj2cgb1.statuspage.io/embed/script.js" async defer></script>
383384
<!--

js/L.TileLayer.NoGap.js

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
});

js/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ function load_hash(no_refresh) {
9696
switch(k) {
9797
case "mt":
9898
if( baseMaps.hasOwnProperty(v) ) {
99+
map.removeLayer(baseMaps[selectedLayer]);
99100
selectedLayer = v;
100101
map.addLayer(baseMaps[v]);
101102
}

0 commit comments

Comments
 (0)