geojson-vt on leaflet

update Sept 2015: nice explanation of how geojson-vt works here

Mapbox technologies used in their webgl and opengl libraries are being extracted into standalone pieces. Vladimir Agafonkin,creator of leaflet.js, earcut.js provided slicing and polygon simplification library for geojson called Goejson-vt.Geojson-vt can slice geosjon into tiles aka mapbox tiles.
Quick test and sample of using geojson-vt on leaflet with canvas drawing available here: http://bl.ocks.org/sumbera/c67e5551b21c68dc8299

2 videos:

Overview of various geojson samples

 

folowing video shows 280 MB large geojson !

 

for comparison here is WebGL version on the same data. This version is loading all data into GPU and leaves everything on WebGL (no optimization). It also takes slightly more time to tessellate all polygons, but once done all seems to run fine. Code used is available here

Advertisements

Modern data visualization on map

hxgn14 For this year HxGN14  conference  I have prepared a web app  of modern data vizualisation, I have got  inspired by great ideas from Victor Bret and his research and talks for general concept (high interactivity, visualization ) of this app.

It is exciting to see what is possible to do today inside browser and interactivity provided by various open source projects (e.g. leaflet,d3  and its plugins)  and WebGL technology .

Leaflet WebGL many points rendering

WebGL is funny – programming in very low level style in JavaScript. This sample plots 86T points using this technology.  .

 

 

 

The code is very straightforward, the only thing is to how points are initially loaded and scaled (instead of reloading each time when map moves).

All points are initially transformed to tile size of 256 x 256 pixels at zoom level 0  and then re-scaled/re-shifted based on the current position of the map. drawingOnCanvas is called from L.CanvasOverlay each time map needs to be drawn (move, zoom)

 


function drawingOnCanvas(canvasOverlay, params) {
  gl.clear(gl.COLOR_BUFFER_BIT);
  // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
 mapMatrix.set(pixelsToWebGLMatrix);
  var bounds = leafletMap.getBounds();
  var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest());
  var offset = LatLongToPixelXY(topLeft.lat, topLeft.lng);
  // -- Scale to current zoom
  var scale = Math.pow(2, leafletMap.getZoom());
 scaleMatrix(mapMatrix, scale, scale);
 translateMatrix(mapMatrix, -offset.x, -offset.y);
  // -- attach matrix value to 'mapMatrix' uniform in shader
  gl.uniformMatrix4fv(u_matLoc, false, mapMatrix);
 gl.drawArrays(gl.POINTS, 0, numPoints);
}

More information and insipiration I took from this site

demo here: http://bl.ocks.org/sumbera/c6fed35c377a46ff74c3

For polygons rendering check here and for polyline rendering here

Some good intros to WebGL that might help you to understand the code: http://aerotwist.com/presentations/custom-filters/#/6

There is a nice intro book to WebGL  WebGL Programming Guide by Kouchi Matsuda and Rodger Lea

To illustrate how variables are passed from JavaScript to shaders used in above example, here are two figures from the book-  figure 5.7 on p. 149, and figure 5.3 on p.144.

strideoffset
Stride and Offset

This figure shows single buffer (interleaved)that is used fro both coordinates and size. In similar way single buffer is constructed in the example here:

 

 

 

var vertBuffer = gl.createBuffer();
var vertArray = new Float32Array(verts);
var fsize = vertArray.BYTES_PER_ELEMENT;

gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.STATIC_DRAW);
gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false,fsize*5,0);
gl.enableVertexAttribArray(vertLoc);
// -- offset for color buffer
gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, fsize*5, fsize*2);
gl.enableVertexAttribArray(colorLoc);

 

shadervariables2
behavior of a varying variable

Leaflet Canvas Overlay

canvas

Updates:

July 2016: refactored and moved to github here

August 2015: check also “scaled”- based fast SVG rendering on top of Leaflet here it might be surprising in performance on Chrome.

May 2015: Geojson-vt sample here is using Canvas overlay as well

June 2014: WebGL sample drawing 86T points using this canvasOverlay available here.

Leaflet full view Canvas Overlay  is a straightforward full screen canvas overlay class (L.CanvasOverlay.js) that calls custom user function for drawing. Available here: http://bl.ocks.org/sumbera/11114288

For inspiration I have used Leaflet.heat and extracted generic Canvas drawing class that is not tight to data or processing but rather call user defined function. (I am still thinking in iOS view delegates and it make sense to apply it here too).

You can use L.CanvasOverlay.js for you custom drawing in your Leaflet map. The sample is using 24T points available here: http://www.sumbera.com/gist/data.js

Usage example of the demo here:

    //Example:
    L.canvasOverlay()
       .params({data: points})     // optional add any custom data that will be passed to draw function
           .drawing(drawingOnCanvas)   // set drawing function
           .addTo(leafletMap);         // add this layer to leaflet map


    //Custom drawing function:
        function drawingOnCanvas(canvasOverlay, params) {
                var ctx = params.canvas.getContext('2d');
                params.options.data.map(function (d, i) {
                  // canvas drawing goes here
                });
            };

    // parameters passed to custom draw function :
     {
                                canvas   : <canvas>,
                                bounds   : <bounds in WGS84>
                                size     : <view size>,
                                zoomScale: <zoom scale is  1/resolution>,
                                zoom     : <current zoom>,
                                options  : <options passed >
             };

Other useful full view Leaflet Canvas sources here:

– leaflet.heat https://github.com/Leaflet/Leaflet.heat
– Full Canvas https://github.com/cyrilcherian/Leaflet-Fullcanvas
– CartoDb Leaflet.Canvas : https://github.com/CartoDB/Leaflet.CanvasLayer

Leaflet 0.7 vs. OpenLayers 3 beta 1 on iOS

leafol2Made quick test of these 2 +1 HTML5 renderers on iOS running inside iOS app in the WebView, that is without Nitro acceleration.  All run on iPad Air

Leaflet 0.7 : great , works fine, everywhere, doesn’t load while dragging map (on mobile only) , runs on Microsoft  Surface too.

OpenLayers 3 beta 1 : runs fine too, loads map during dragging, seems like smaller framerate, can over zoom OSM, doesn’t run in Microsoft Surface well.

Seznam Mapy Api v 4 – proprietary renderer from Seznam , bad rendering  on iOS, missing tiles, nice map sources

Videos and original web pages used: – screencasted by AirPlay – that is directly from iPad Air:

B. OpenLayers 3 beta1
C. Mapy Api v 4.8

SVG map sample and Canavas in OpenLayers

Update August 2015: check “scaled”- based fast SVG rendering on top of Leaflet here

Updated May 2014: check leaflet Canvas test here, SVG with d3 here   and WebGL here

Canvas map sample.

Thesis on Canvas and Open Layers (August 2010) “Evaluation of HTML5 for its Use in the Web Mapping Client OpenLayers”

OpenLayers with Canavas  (partialy deprecated) http://trac.osgeo.org/openlayers/wiki/Future/OpenLayersWithCanvas

SVG vs Canvas comparison by Jeffrey Warren from : http://unterbahn.com/2009/08/svg-vs/

“Well, SVG doesn’t scale well to large numbers of objects, but Canvas doesn’t
scale well to large screens”

“SVG performance degrades quickly (exponentially on Safari?) in the number of
objects, but Canvas performance remains at a near-constant low. This makes
sense, since Canvas is just a bitmap buffer, while SVG has to maintain
additional references to each object that it renders. Also, though not pictured,
note that performance in clearing an SVG element also decreases in the number of
drawn objects.”

[UPDATE] PDC2010 video by Patrick Dengler : http://videoaz.microsoftpdc.com/vod/downloads/vod/CD53_PatrickDengler/CD53_PatrickDengler_PDC_WMV_High_1280x720_2500k.wmv