Mapbox GL JS : Large Image Overlay Issues - javascript

I am using Mapbox GL JS to overlay an image of satellite data over Texas. The image is big enough to cover Texas, but even when using 100% correct geo-coords, the image is not in the correct place. I have to split the image into 6 long (west-east) images like such, and stack them vertically in separate image overlays :
This produces the desired result :
When using the 6 stacked image overlays (each 2 degrees tall and very wide to cover the state's width, by the way), the placement of the clouds is exactly perfect with zero issues. It's perfect except that having to make 6 image overlays to build this is not at all ideal and it adding processing constraints.
If I merge all the images into one big picture and overlay it using the same coords - the effect is wrong. Even though the image is exactly the same. I have highlighted the coastline so you can see that when using one large image overlay for the whole state, it becomes inaccurate. For a storm chaser (my target audience) this would not be unacceptable. I have tried manually adjusting the images but it is no good and I have wasted days of my life tracking this issue down, and it is absolutely Mapbox. I have ruled out the other possibilities like bugs in the software I use to get the data.
Here is the bad result with one overlay as opposed to splitting it vertically :
Are there any ideas to what may be causing this, and a solution? I am completely lost.

I had solved this long ago but since others have the same problem, it deserves an answer here. The problem has to do with projection. Images can be sliced and diced exactly by coordinates but they must match the projection of the map they are being overlaid on. In the case of Mapbox, it uses web mercator and images must be reprojected to EPSG:3857.
A utility to convert images (such as geoTIF) to this projection is GDAL (https://gdal.org/). A command using GDAL tools to convert an image would be something like :
gdalwarp -t_srs EPSG:3857 input.tif input-projected.tif
Hopefully this clears things up. These issues are basic knowledge in the GIS community. If you want to work with data like this, I can say that I recommend doing what I did : learn basic GIS tools and how they work. It will save you.

Related

Splitting an SVG into Multiple SVGs

I have an SVG that I am overlaying on a Google Map. The SVG is 50mb large, so it takes 10 seconds or so to load in the browser.
I can get the SVG split into 171 separate SVG files that make up this big SVG. What is my best strategy to improve load time? I am trying to keep a high resolution at lower zoom levels.
Things I have tried
-Converting Image to PNG and JPG- resolution is not adequate
-Optimizing SVG File- still can't reduce it enough to impact load time
Things I am thinking about trying
- layer SVGs in a certain order on page load, grass first, then cars, then buildings (although with so many, I really do not want to do this)
- there is a library called PolyMaps, not sure if this could help
-utilizing GZIP format of the SVG, but I am not sure what the best way to do this would be to achieve the desired result or how i would do that
Basically, I am just looking from some general direction from devs more experienced with loading a large amount of SVGs onto the google maps api/canvas
this is for an interactive map, there are infowindows that are custom and are already created(not svg), and as of right now, just using standard marker icons(svg). besides the infowindows and markers its really as simple as overlaying a lot of svg data onto the map,
Any help would be appreciated.
thanks
i ended up layering the smaller svgs in the file and completely removing any of the larger ones that I didn't absolutely need.

How do I use collision detection to fix overlapping images with d3.js?

I'm trying to display a large number of images on a d3 display using T-SNE. The x and y coordinates are pre-calculated, the location on the svg area is adjusted using using translate/zoom.
At the moment they all display using the precalculated coordinates.
and they remain in place as zooming/panning.
I'm looking to use collision detection (like this example) to adjust the images locations slightly so that they don't overlap, but as much as possible maintain the rough global structure.
Here's my attempt so far
https://gist.github.com/GerHarte/329af8ee5ffd8a1f87c5
With this it loads as in the image above, but as soon as I pan or zoom, all the points expand out hugely to a completely different location on the canvas and look like this, they don't seem to overlap, but they're extremely far apart.
Is there something wrong in my code or is there a better way to approach this?
Update:
I followed Lar's answer here, with the slight addition of setting the raw data points to where Lar's code settles since the points are translated when zooming or panning. The results look great (see below), but for a larger number of points (5000+) it seems to crash before converging on a final result.
Are there any suggestions to improve the efficiency with this approach? Going to try the Multi-Foci Forced Directed approach.

Google Charts line thickness(& Sharpness) differ

I just found that there are some difference in the line thickness (and sharpness) even tough their line thickness property has be set to the same. I have searched all over the Google Charts webpage. But I could find nothing. How to solve this kind of error ?
Check all the lines you find the difference. Some will blur and other will be sharp.
This isn't really specific to Google charts, its an artefact of Anti aliasing. In brief, the pixels in most computer displays are relatively large, which makes precise display difficult. Anti aliasing uses shading to make an image look like it was rendered with more pixels than are actually available, at the cost of being blurry. When you have some lines that match the real pixels, you will see the difference.
There doesn't seem to be an option to turn off antialiasing that I can see in the Google Charts documentation.
If you are exporting images (e.g. PNGs) you could export at a larger size and reduce the image back at a non-integral scale: that way all lines will be blurred roughly equally as no source pixel will exactly line up with a destination pixel.
If you are trying to display SVGs, you might be able to turn off antialiasing using CSS styles. (Maybe try this)

How to draw/load part of a page that is currently looked at?

I am currently working on a map generator application based on javascript, and I have wrote more than 400 lines of code, that creates a hexagonal map, adds coordinates to tiles, adds textures on tiles like grass, ocean and elements like castles, units etc.
I have added quite a few useful functions to this offline map editor, like zoom in and zoom out, turning grid on/off, dragging the map, and a few others, and I'm currently studying on how to add save and load functionality to this offline game map editor.
It sort of looks like a paint application, except that instated of drawing pixels, you use it to draw a map with hex tiles. You simply click on Generate a new map and you give your desired map size (e.g 64 tiles width by 64 tiles height) and the map is drawn for you, the tiles are simple divs that have the relative background image as texture. Tiles are drawn one by one using a simple for loop. But as the code grows in size so does my worries.
Because the map I create on my own map editor will be used on an online multiplayer game, it will be huge! for example to support at least 20000 users on the upcoming game there should be at least 20000 tiles, only for the users to occupy, not to mention the territory they will own, mountains, jungles, barbarian tribes, and so on..
I have made the calculations and found out that a 512 by 512 (about 262000 tiles) map will sufficiently answer the needs of that many users. However, the map will be huge. so I decided to test and see how much load time does it take to make such a map using the codes I have created with the least process possible and I found out that it takes nearly a minute or more, which is not acceptable, from a gamers perspective.
A zoom in for example in such a huge map will mean looping through every 262000 tile to change their size. although the process takes less time than drawing/loading the map from scratch, but it is still slow.
I was thinking with a map that huge which won't even fit in a browser's window, why should I draw the entire map? why not instead load the part which the user is currently looking at. Loading/drawing only the part that is needed, this way reducing load time and increasing performance. But this is proving to be a real challenge, and there are very limited resources online about implementing such a functionality. Where to start? How to approach the problem and respective solution?
I would start out by separating your concerns a little more. You're able to view WxH number of pixels, and the top left of the user's screen sits at (x,y) coordinates.
Loading the entire map, as you have pointed out, is crazy. But by knowing how large the game world is, and by knowing the user's coordinates in that world, you can easily select the subset of items that are in view.
Keep in mind that at a zoomed out resolution you shouldn't be using the full-sized images. Loading 262000 images (for just the map!) is going to be too heavy and probably crash. You should have different images for different zoom levels. This is a much bigger question and you should buy a book and do more research on google. But at least the thinking about the "where the user is" vs "where the items in the world are" is a place that I would start at.
Hope that helps.

Draw Zoomable Time Line With Scroll Bars On Html5 Canvas

I need a Time Line For My Web Project.
Something like this - I read the code of this Time Line but did not understand it because it is not documented enough.
My problem is the math behind all of this (not the interaction with the canvas).
I have read several articles about the math of the scroll bars, but none of them talk about zoom.
Some
articles suggest to hold canvas element with very large width value - and to display just the
View Port.
I don't think that's the right way to do it - I want to draw just the correct viewport.
In my project, I have array of n points.
Each point holds time value represented in seconds, but not all of the points are within the Viewp Port.
Considering the current zoom level, how do I calculate:
What points should be drawn and where to draw them?
What is the size and position of the thumb?
Any articles / tutorials about such a thing?
You might be able to use something like Flot which handles the placement of points, as well as zooming and panning. Here's an example of that.
There are a bunch of other drawing libraries, here a good list.
You always have Raphealjs.com , one of the most used library to play with SVG, with this you can write your own js to generate the timeline.

Categories