Grid system for a 3D Earth - javascript

So basically, I am tasked with "recreating" a 3D Earth, comprised of (very small) tiles made of NASA Landsat 8 images (png). Each point on Earth is imaged once every 16 days or so, and the API I'm using serves the latest images (ie they can't be compiled offline and used statically) .
These tiles are ~150kb each, and have a width and height of 0.025 lat/long. This means that I'll probably have to use a static mesh for low zoom levels, and as a user zooms in, Landsat tiles will be dynamically generated based on their viewport.
Have any of you built a 3D Earth with custom tiling before? I was looking at the WebGL Earth API, but it's very limited. I've also taken a look at Cesium, but I'm not sure if it's capable of what I want to do.
Basically, I'm looking for a 3D model of Earth (or even just a sphere) that will allow me to "stick" images to specific lat/lon points. Otherwise, I suppose I'll just have to make a sphere in ThreeJs and do the calculations myself, but I'm afraid that without using a pre-existing map system (like Leaflet), the whole thing will come out totally inaccurate.

Cesium can already do exactly what you want quite easily. Depending on the API you are using, there's a good chance we already have an Imagery Provider that can ingest it, most imagery like you describe is usually using one of the major standards. If not, implementing a custom provider is only a couple dozen lines of code.
I would recommend you check out the Imagery Layers tutorial to get started and don't hesitate to ask questions on our forum.
If you can provide more details, I can give you more specific advice.

Related

Leaflet for using custom NOT geo-maps

I just started getting familiar with the Leaflet library. I need to figure out how to load large amounts of abstract data into a Leaflet. Not a geo-map.
Let it be a "map" that displays a million digits of Pi in color. It is not so important what it displays. It is important that I have a page that loads some array of bytes in chunks and shows it as colored pixels. Ideally, you need 10x10 chunks. The user goes to the page with the map and sees, for example, 100 chunks, i.e. 10x10 chunks of 10x10 pixels, which represent the PI number. Using the mouse, the user moves left-right and the application requests the pixels not yet loaded from the backend.
Can Leaflet's capabilities solve similar problems? Or plugins written
for Leaflet?
In theory, it seems to me that this is possible. But in practice, all guides and documentation are for working with geo-maps or raster large images.
Your question is a little generic, but I think what you're talking about is making your own GridLayer. This is leaflet's underlying class for creating a tiled grid of any HTML element you can think of. Whether its a <div> with text in it, or a <canvas>, or whatever you like. I'm not sure what exactly you mean by "a page that loads some array of bytes in chunks and shows it as colored pixels", but that sounds like something that can be done by writing to a canvas using putImageData, and then applied to a GridLayer.
I recommend reading the tutorial on extending leaflet - extending layers. Once you understand this, you'll see that leaflet is built to render zoomable, pannable grids of whatever you want. The links that Ivan Sanchez left are great examples of the crazy stuff you can do with GridLayers (formly called L.TileLayer.Canvas in older leaflet versions)

How to migrate map from tile size 256 to 512 in d3-geo-tile and ArcGIS

We have a developed a map using d3-map-tile and using ArcGIS services which is having tile-size 256X256. We were able to render our map and plot the latitude longitude properly.
Now we have to move to the service where tile size is 512X512. Rendering of lat-long is not working properly by just merely changing the services.
Can someone tell me how I can do it in my existing code. what are the things I need to change apart from services.
Strictly speaking (as of August 2017), no. The size is fixed within the tile module:
Computes the set of 256x256 quadtree tiles to display given the
current layout extent, scale and translate. (API docs)
And Mike states:
It currently is limited to 256 [px] (discussion)
However, as coincidence has it, work is occurring to address multiple tile sizes.
See the discussion here. In fact, it seems that a possible implementation has been developed, see this thread, and this block for an example using the possible implementation.

How to rotate a map in Javascript(Meteor/famo.us)

In my Meteor/Cordova/famo.us App I need a map that can be rotated with two fingers, zoomed in and out and (ideally) the names (street, city etc.) should stay horizontally aligned.
The reason is that I haven't found a (free) map like leaflet.js, Google Maps etc. that can rotate in JS. Google Maps SDK for Android and iOS respectively can do this, but the corresponding plugin (plugin.google.maps) led to trouble with famo.us.
The rotation could be done with a famo.us Surface, and I've been told that in leaflet one could pull separately the map tiles and the names (vector/jpeg?).
I apprechiate your help.
Map rotation isn't possible in Leaflet. Read this answer: https://stackoverflow.com/a/22938733/2019281. However, it is possible in openlayers but it would also rotate the labels since they are embedded in the maptiles. See this example: http://openlayers.org/en/master/examples/rotation.html. You could use a tilelayer without labels and add create your own separate layer with vectorlabels and counterrotate those. This would be a very complex solution and i guess will put an enormous strain on your performance since you're talking about a mobile solution. I would rethink the concept.

Classify lon/lat coordinate into geojson polygon using Javascript

I have a geojson object defining Neighborhoods in Los Angeles using lon/lat polygons. In my web application, the client has to process a live stream of spatial events, basically a list of lon/lat coordinates. How can I classify these coordinates into neighborhoods using Javascript on the client (in the browser)?
I am willing to assume neighborhoods are exclusive. So once a coordinate as been classified as neighborhood X, there is no need to further test it for other neighborhoods.
There's a great set of answers here on how to solve the general problem of determining whether a point is contained by a polygon. The two options there that sound the most interesting in your case:
As #Bubbles mentioned, do a bounding box check first. This is very fast, and I believe should work fine with either projected or unprotected coordinates. If you have SVG paths for the neighborhoods, you can use the native .getBBox() method to quickly get the bounding box.
the next thing I'd try for complex polygons, especially if you can use D3 v3, is rendering to an off-screen canvas and checking pixel color. D3 v3 offers a geo path helper that can produce canvas paths as well as SVG paths, and I suspect if you can pre-render the neighborhoods this could be very fast indeed.
Update: I thought this was an interesting problem, so I came up with a generalized raster-based plugin here: http://bl.ocks.org/4246925
This works with D3 and a canvas element to do raster-based geocoding. Once the features are drawn to the canvas, the actual geocoding is O(1), so it should be very fast - a quick in-browser test could geocode 1000 points in ~0.5 sec. If you were using this in practice, you'd need to deal with edge-cases better than I do here.
If you're not working in a browser, you may still be able to do this with node-canvas.
I've seen a few libraries out there that do this, but most of them are canvas libraries that may rely on approximations more than you'd want, and might be hard to adapt to a project which has no direct need to rely on them for intersections.
The only other half-decent option I can think of is implementing ray casting in javascript. This algorithm isn't technically perfect since it's for Euclidean geometry and lat/long coordinates are not (as they denote points on a curved surface), but for areas as small as a neighbourhood in a city I doubt this will matter.
Here's a google maps extension that essentially does this algorithm. You'd have to adapt it a bit, but the principles are quite similar. The big thing is you'd have to preprocess your coordinates into paths of just two coordinates, but that should be doable.*
This is by no means cheap - for every point you have to classify, you must test every line segment in the neighborhood polygons. If you expect a user to be reusing the same coordinates over and over between sessions, I'd be tempted to store their neighborhood as part of it's data. Otherwise, if you are testing against many, many neighborhoods, there are a few simple timesavers you can implement. For example, you can preprocess every neighborhoods extreme coordinates (get their northmost, eastmost, southmost, and westmost points), and use these to define a rectangle that inscribes the town. Then, you can first check the points for candidate neighborhoods by checking if it lies inside the rectangle, then run the full ray casting algorithm.
*If you decide to go this route and have any trouble adapting this code, I'd be happy to help

OpenLayers as a large (changing and growing) image viewer

Basically, what I'm trying to do is use a map viewer as an image viewer with the same sort of efficient tile-loading, zoom/pan awesomeness without having to build it myself.
Specifically, I need an image viewer that will allow the image to grow and change while not altering the coordinates of any older (unchanged) tiles. This means that the center point (0,0), where the image started growing from, must always remain (0,0). So I'm looking for a library that will allow me to use a very basic Cartesian coordinate system (no map projection!), which will ask for tiles infinitely in all directions with no repetition (as opposed to how map libraries just ignore y-axis above and below the map, but the x axis repeats).
There's another catch. I need zoom level 0 to be zoomed in all the way. Since the image is constantly growing, there's no way to tell what the max zoom level will be, and the coordinates need to be based on the base image layer tiles so that every tile in zoom level z contains 2^z base layer tiles.
I am wondering if this is possible with OpenLayers and how to do it. If it's not, any suggestions of other (open-source javascript) libraries that can do this would be very appreciated! I've tried playing around with Polymaps, but the documentation is lacking too much for me to be able to tell if it will work. So far no luck.
Please let me know if none of this made sense, and I'll try to include some images or better explanations. Thanks!
I ended up using Polymaps after all, since I like it more than OpenLayers, because it's faster and has much smoother scrolling and panning. I wasn't able to do exactly what I wanted, but what I did was close enough.
I ended up writing my own layer (based on the po.image() layer), which disabled infinite horizontal looping of the map. I then wrote my own version of po.url() that modified the requests going to the server for tiles so that zooming was reversed (I just arbitrarily picked a 'max' zoom of 20, then when making a request subtract the zoom level from 20) and the x and y coordinates were converted to cartesian coordinates from the standard row, column coordinates Polymaps uses, based on the zoom level and the map centered at (0,0).
If anyone is interested in the code I can post it here. Let me know!
EDIT: I've posted the code on github at https://github.com/camupod/polymaps
The relevant files are src/Backwards* and examples/backwards (though it actually doesn't work, you might be able to clean some information about how it should work).

Categories

Resources