brendankenny / CanvasLayer

A <canvas> map layer for the Google Maps JavaScript API v3 for 2d and WebGL data visualization
Apache License 2.0
147 stars 52 forks source link

Canvas shifts if map dragged to right #8

Open michelwehrli opened 8 years ago

michelwehrli commented 8 years ago

If you drag this map to the right, at some point the canvas shifts to the following left map. Is there a way to prevent this behavior?

donmccurdy commented 7 years ago

Is this the same issue seen when panning the 2D demo to the east? When the top-left corner of the canvas crosses the international dateline, the red square disappears:

3f5e4df6-9380-4454-9fe4-b7fcf0de103a-73672-0000b7120e335917

I'm not very familiar with the projection math, but you can add a hack to work around this, modifying these lines in the demo as follows:

var topLeft = canvasLayer.getTopLeft();
var offset = mapProjection.fromLatLngToPoint(topLeft);
if (topLeft.lng() > 0) {
  offset.x = offset.x - 256;
}
context.translate(-offset.x, -offset.y);

Not a great fix... i'll keep looking at this. :/

michelwehrli commented 7 years ago

Yes it is, this is exactly what happened in my demo (which I fixed now btw).

I added your work around and it seems to work as long as you don't zoom out too much. (https://wehrli.me/canvaslayer/)

Maybe I just limit the top 3 zoom levels or so... Let me know when you find the solution, I will also look into this once more as soon as I have time.

brendankenny commented 7 years ago

yeah, unfortunately the discontinuity is fundamentally difficult to work around. There are some brute force approaches, though, like just rendering everything twice, once with an offset to keep it to the left and then one two keep it to the right. Usually demos using canvaslayer are pixel-fillrate-limited, so the performance hit isn't too bad since the vast majority of the sprites (or whatever) are offscreen and so never make it to the pixel shader stage.

(if you do everything just twice, however, you do have to limit how far you can zoom out depending on the map container's size and aspect ratio, otherwise you might need to render three or more times :)

If on the other hand you're visualizing mostly local-scale data, you can also hack around the problem by just limiting zoom and how far the user can pan.

pjsg commented 7 years ago

In my app, I have to be able to deal with zoomed-out maps -- I've been wondering whether to just attach the canvas multiple times to the map (one per duplication of the world). However, this doesn't really work very well when you are zoomed in near the international date line....

pjsg commented 7 years ago

Actually, I just fixed my problem as I'm computing the color based on the latlng of the pixel. In my case, the longitude may exceed 360 (or more) but it is continuously increasing to the right.