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)
Related
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.
We are developing a web-based game. The map has a fixed size and is procedually generated.
At the moment, all these polygons are stored in one array and checked whether they should be drawn or not. This requires a lot of performance. Which is the best rendering / buffering solution for big maps?
What I've tried:
Quadtrees. Problem: Performance still not as great because there are so many polygons.
Drawing sections of the map to offscreen-canvases. A test run: http://norizon.ch/repo/buffered-map-rendering/ Problem: The browser crashes when trying to buffer that much data and such big images (maybe 2000x2000) still seem to perform badly on a canvas.
(posting comments as an answer for convenience)
One idea could be, when the user is translating the map, to re-use the part that will still be in view, and to draw only the stripe(s) that are no longer corrects.
I believe (do you confirm ?) that the most costly operation is the drawing, not to find which polygon to draw.
If so, you should use your QuadTree to find the polygons that are within the strips. Notice that, given Javascript's overhead, a simple 2D bucket that contains the polygons that are within a given (x,y) tile might be faster to use (if the cost of the quadtree is too high).
Now i have a doubt about the precise way you should do that, i'm afraid you'll have to experiment / benchmark, and maybe choose a prefered browser.
Problems :
• Copying a canvas on itself can be very slow depending on devices/Browsers. (might require to do 2 copy, in fact)
• Using an offscreen canvas can be very slow depending on devices/Browsers. (might not use hardware acceleration when off-screen).
If you are drawing things on top of the map, you can either use a secondary canvas on top of the map canvas, or you'll be forced to use an off-screen canvas that you'll copy on each frame.
I have tried a lot of things and this solution turned out to be the best for us.
Because our map has a fixed size, it is calculated server-side.
One big image atlas with all the required tiles will be loaded at the beginning of the game. For each image on the atlas, a seperate canvas is created. The client loads the whole map data into one two-dimensional array. The values determine, which tile has to be loaded. Maybe it would be even better if the map was drawn on a seperate canvas, so that only the stripes have to be painted. But the performance is really good, so we won't change that.
Three conclusions:
Images are fast. GetImageData is not!
JavaScript has not yet great support for multi threading, so we don't calculate the map client-side in game-time.
Quadtrees are fast. Arrays are faster.
I'm planning to commission a developer to help me create a simple mathematical art piece. I'm wondering if the following can be accomplished with JavaScript vector art, and if not, what approach you would recommend.
The image will start off with some intersecting lines forming a shape. This is essentially an image zoomed in 1000% or more, and the user can scroll to zoom out until the full image fits the width of the screen.
Naturally, an actual image of this size would be huge, so I'm thinking it would be better to draw it programmatically, which might also enable the line thickness to scale up a bit as you zoom out, so that they're not nearly invisible when zoomed all the way out. The image can not look pixellated when zoomed all the way in, but achieving this with some “trickery” like swapping out images is also ok.
Example:
Basically the reverse of zoom.it but at a significantly larger scale.
http://zoom.it/
Some libraries I've looked at are:
paper.js
fabric.js
leaflet.js
raphael.js
How can an extreme zoomout like this be accomplished?
You are definitely on the right track. I think what you want is very possible on the web using HTML5. You are correct in that the easiest/best performing implementation of this would be using vector graphics. You can use image tiles, however the preprocessing and bandwidth requirements for tiling get large very quickly.
Here are some of my thoughts from working with some of the libraries you listed:
Leaflet.js - Leaflet supports both drawing SVG elements as well as image tiling (if you wanted to go that approach). Leaflet is also "mobile first" in that it supports things such as pinch zooming and double tap to zoom out of the box. Scroll zooming is also supported out of the box. Getting something up and going with Leaflet is simple. As far as I know Leaflet is writing SVG to the DOM; which is something to keep in mind.
Raphael - Raphael is capable of what you want, however you may need to implement zooming aspects yourself. This is definitely possible to do and shouldn't be too difficult, but something to keep in mind. Raphael will write SVG elements to the DOM; which can get a bit unruly if you have many many SVG elements. However, you may be able to optimize this and create/destroy elements as you are zooming.
Paper and Fabric - These both appear to render SVG to Canvas (different than writing SVG to the DOM). These both look really powerful, and seem to have good APIs for zooming. You would likely still need to hook up scroll/touch gestures to get zooming to work the way you want. These both should perform very well as they are using lower level APIs which should bypass many issues you might have with doing this in the DOM.
Question
I want to display overlay containing spatial distribution of something on Google Map.
Here are results of my approach, and I want something similar:
For now I display about 10 000 instances maps.google.Rectangle, each is about 2km x 2km wide. This approach is quite slow (this map is rendered for couple of seconds).
Is there any way to render this faster? Best solutions would use javascript only (but I guess I could generate some KML on the fly).
Setup
I'm doing some prototyping work, so I don't use full blown server (any server altogether) but just ipython.org/notebook.html, that means that I can very easily call any python function, but there is no easy way to say path /path/ will output following KML. On the other hand everything is on my computer so file:// urls would work
Backend is written in python.
What I have tried
Outputting polygons (it is slow)
Using heatmaps. I had problems with scaling, basically when zoomed out it looks like that: http://imgur.com/6gYJYxm, and when scaled in it looks like that: http://imgur.com/Ifh7gkn.
You can download my class hilbert curve from phpclasses.org. It uses a space filling curve to subdivide the plane and reduce the dimension.
I'm currently reading up on the canvas, but I'm finding it hard to find practical benefits of using canvas, when a lot can be done using simple css overlays/JavaScript (+ jquery lib).
This is probably because I don't know the FULL practicalities of using canvas.
Looking at this game:
http://www.pirateslovedaisies.com/
Could someone help explain how and why canvas is being used as opposed to just css?
This is a 4k js/canvas demo I wrote to experiment with the 2d context (here is a video if your browser doesn't work). I tested it only on chrome, opera, firefox, safari and nexus one browser.
Note that no external resources are loaded (i.e. the texture and the raytraced envmap are built dynamically), so this is just a single self-contained 4096 bytes HTML file.
You can do something like that with DIVs?
But indeed I agree that the game you linked IMO could be done also with DIVs; apparently there are no transformations - not even in the falling daisy loading scene - and the action areas for the pirates are just circles. Not sure but could be that even shooting only happens at fixed angles.
Canvas could have been used instead for:
Drawing general sloped lines and polygons (the map could be created dinamically from a compact description or could have been generated randomly). Shooting could be done at any angle...
Procedural image creation (e.g. textures or special pixel effects)
Gradients, texture mapping
General 2d matrix transforms
Of course a game using an image+DIVs approach is probably way easier to make (a lot of photoshop and simple xy animation).
Creating tons of HTML elements is extremely slow and memory-hungry. The canvas object is made for graphics operations and thus optimized for it. Besides that.. how would you draw a curve with plain HTML/CSS? ;)
Using <canvas> you have a per-pixel control of what's shown on the screen. You don't have to deal with specific browser CSS or DOM compatibility.
Also, that's actually a pretty similar programming model to 2D non-browser games, like those created using SDL o DirectDraw.
Here's a game I wrote in a few hours using Canvas; note that the scaling of the tiles, the anti-aliasing of the lines, is perfect. This would not be the case with image tiles that were being resized by the browser.
Click the tiles to rotate them in an attempt to make all connections. Click the row of buttons at the top for a new board of a different size; click the row of buttons below that for a new board with different numbers of connections.
The game concept is not mine, only the implementation.