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

Geometric proof of vector dot product

dotProof Source: colorful introduction to Linear Algebra (may 2014) Cosine Similarity – understanding it as volume of parallelepiped cosineSimilarity Another good source for understanding dot product : http://betterexplained.com/articles/vector-calculus-understanding-the-dot-product/ dot_product_components dot_product_rotation

other resources:

Significance &Application of Cross product and Dot product. http://visualizingmathsandphysics.blogspot.cz/2013/06/vectors-significance-of-cross-product.html

Independence of  Perpendicular components of the motion http://www.physicsclassroom.com/Class/vectors/u3l1g.cfm

Math Insight: http://mathinsight.org/dot_product

\frac{a\cdot b}{\left \| a\right \|}= cos\alpha \left \| b \right \|

“projection” of vector b on a equals cosine of angle between them times the length of b or vice versa projection of a on b:

dot_product_projection

Dot product Identities, some pictures taken from http://gamemath.com/

dotProductIdentities2

WMS overlay with MapBox-gl-js 0.5.2

alt textQuick and dirty test of the WMS capabilities of the new MapBox-gl-js 0.5.2 API. First of all, yes ! it is possible to overlay (legacy) WMS over the vector WebGL rendered base map … however the way is not straightforward:

 

  • Needs some ‘hacks’ as current version of the API doesn’t have enough events to supply custom URL before it is loaded. But check latest version of mapbox, it might have better support for this.
  • Another issue is that WMS server has to provide HTTP header with Access-Control-Allow-Origin:* to avoid WebGL CORS failure when loading image (gl.texImage2D). Usually WMS servers don’t care about this, as for normal img tags CORS doesn’t apply. Here WebGL has access to raw image data so WMS provider has to explicitly agree with this.
  • Build process of mapbox-gl-js tend to be as many other large js projects complicated, slow, complex. And specifically on Windows platform it is more difficult to get mapbox-gl-js install and build running then on Mac.

Code is documented to guide you through the process, few highlights:


 // -- rutine originaly found in GlobalMercator.js, simplified
 // -- calculates spherical mercator coordinates from tile coordinates
 function tileBounds(tx, ty, zoom, tileSize) {
    function pixelsToMeters(px, py, zoom) {
     var res = (2 * Math.PI * 6378137 / 256) / Math.pow(2, zoom),
         originShift = 2 * Math.PI * 6378137 / 2,
         x = px * res - originShift,
         y = py * res - originShift;
     return [Math.abs(x), Math.abs(y)];
     };
   var min = pixelsToMeters(tx * tileSize, ty * tileSize, zoom),
         max = pixelsToMeters((tx + 1) * tileSize, (ty + 1) * tileSize, zoom);
return min.concat(max);
}

 
]

// -- save orig _loadTile function so we can call it later
 // -- there was no good pre-load event at mapbox API to get hooked and patch url
// -- we need to use undocumented _loadTile
 var origFunc = sourceObj._loadTile;
    // -- replace _loadTile with own implementation
 sourceObj._loadTile = function (id) {
    // -- we have to patch sourceObj.url, dirty !
    // -- we basically change url on the fly with correct BBOX coordinates
    // -- and leave rest on original _loadTile processing
     var origUrl =sourceObj.tiles[0]
                      .substring(0,sourceObj.tiles[0].indexOf('&BBOX'));
     var origUrl = origUrl +"&BBOX={mleft},{mbottom},{mright},{mtop}";
     sourceObj.tiles[0] = patchUrl(id, [origUrl]);
     // -- call original method
     return  origFunc.call(sourceObj, id);
 }

 

 

gist available here

Declarative vs. imperative mismatch

Notes from Jenkov.com : http://tutorials.jenkov.com/angularjs/critique.html about AngularJS Declarative vs Imperative. Couldn’t say this better…the art is to find right balance. Neither XAML , nor AngularJS found it yet (too declarative):

Quoted from the source:

Using declarative HTML templates with a bit of data binding injected is not a new idea. It has been tried before in JSP (JavaServer Pages). Here is an example:

<span><%=myObject.getMyProperty()%></span>

In AngularJS it would look like this:

<span>{{myObject.getMyProperty()}}</span>

The Declarative / Imperative Paradigm Mismatch

Declarative languages (such as HTML and XML) are good a modeling state such as documents, or the overall composition of a GUI. Imperative languages (such as JavaScript, Java, C etc.) are good a modeling operations. The syntaxes of both declarative and imperative languages were designed to support their specific purposes. Therefore, when you try to use a declarative language to mimic imperative mechanisms it may work for simple cases, but as the cases get more advanced the code tend to become clumsy

The same is true the other way around. Using an imperative language will often also get clumsy. Anyone who has tried writing an HTML document using JavaScript’s document.write() function, or wired up a Java Swing GUI using Java, or an SWT GUI for that matter, knows how clumsy this code can get.

It is easy to think that the declarative / imperative mismatch can be avoided with a programming language that is designed to handle both paradigms. But the problem goes deeper than the language syntax.

It is not the syntax of a programming language that decides if the language is declarative or imperative. It is the semantic meaning of what the language describes that decides between declarative and imperative. You could invent a more Java-like syntax to describe HTML elements. Or a more HTML-like syntax to describe Java instructions. But such syntaxes would not change the fact that one language describes state (HTML documents) and the other language describe commands (operations). Thus, a Java-like syntax for describing HTML documents would still be declarative, and a more HTML-like syntax for describing Java-operations would still be imperative.

 

JavaScript – best coding pattern

this or that ? bind or not-bind(this), prototype of prototype ? ehm..all the interesting   things, however better without them in your  code in JavaScript. There is perfect style finally – found in d3, check here: http://bost.ocks.org/mike/chart/ and used in dc.js as well , well described in the d3-cookbok book by Nick Qui Zhu sample code here similar post appeard here “javascript without this”

..it is worth to study the pattern, it will make your code beautiful, modern and readable. You will not need CoffeScript nor TypeScript nor whateverScript.  You even don’t need many other infrastructure or abstractions to get modules or classes  out of JavaScript. It is very elegant.

It is very simple:

function SimpleWidget(spec) {
  var instance = {}; //-- actual instance variable
  var description; // -- private variable

 //-- public API method
instance.foo = function () {
   return instance; //-- returns instance for chaining
 };

 //-- public API method
 instance.boo = function (d) {
   //-- getter of private variable
   if (!arguments.length) return description;

    description = d;  //-- setter of private var
    return instance; //-- returns instance for chaining
 }

 return instance; //-- returns instance for chaining
 }
 // usage
var widget = SimpleWidget({color: &quot;#6495ed&quot;})
            .boo(&quot;argument&quot;)
            .foo();

 

 

 

*** update 1

just came across this great presentation from JSConf.eu : http://2014.jsconf.eu/speakers/sebastian-markbage-minimal-api-surface-area-learning-patterns-instead-of-frameworks.html and this is exactly the way to think about all of the ‘abstracted stuff’ and syntax sugar or salt that is available today for JavaScript.

“It’s much easier to recover from no abstraction than the wrong abstraction.”

*** update 2

NPM and Browserify  is worth to look at, the way how the complex code is done for example in  MapBox-GL-JS . While I don’t like convoluted modules of modules and source maps with concatenated sources, the syntax and modularization is working well.

WebGL polyline tessellation with MapBox-GL-JS

update 09/20015 : test of tesspathy.js library here . Other sources to look:

  1.  http://mattdesl.svbtle.com/drawing-lines-is-hard
  2.  https://github.com/mattdesl/extrude-polyline
  3. https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader

*** original post ***

This post attempted to use pixi.js tessellation of the polyline, this time let’s look on how mapbox-gl-js can do this. In short much more better than pixi.js.

it took slightly more time to get the right routines from mapbox-gl-js and find-out where the tessellation is calculated and drawn. It is actually on two places – in LinBucket.js  and in line shader. FireFox shader editor helped a lot to simplify and extract needed calculations and bring it into the JavaScript (for simplification, note however that shader based approach is the right one as you can influence dynamically thickness of lines, while having precaluclated mesh means each time you need to change thickness of line you have to recalculate whol e mesh and update buffers )

 

// — module require mockups so we can use orig files unmodified
 module = {};
 reqMap = {
‘./elementgroups.js’: ‘ElementGroups’,
‘./buffer.js’ : ‘Buffer’
};
require = function (jsFile) { return eval(reqMap[jsFile]); };

 

   &lt;!-- all mapbox dependency for tesselation of the polyline --&gt;
 &lt;script src=&quot;http://www.sumbera.com/gist/js/mapbox/pointGeometry.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;http://www.sumbera.com/gist/js/mapbox/buffer.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;http://www.sumbera.com/gist/js/mapbox/linevertexbuffer.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;http://www.sumbera.com/gist/js/mapbox/lineelementbuffer.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;http://www.sumbera.com/gist/js/mapbox/elementgroups.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;http://www.sumbera.com/gist/js/mapbox/linebucket.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;http://www.sumbera.com/gist/data/route.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
 // -- we don't use these buffers, override them later, just set them for addLine func
 var bucket = new LineBucket({}, {
 lineVertex: (LineVertexBuffer.prototype.defaultLength = 16, new LineVertexBuffer()),
 lineElement: (LineElementBuffer.prototype.defaultLength = 16, new LineElementBuffer())
 });

var u_linewidth = { x: 0.00015 };
// override .add to get calculated points
LineVertexBuffer.prototype.add = function (point, extrude, tx, ty, linesofar) {
    point.x = point.x + (u_linewidth.x * LineVertexBuffer.extrudeScale * extrude.x * 0.015873);
    point.y = point.y + (u_linewidth.x * LineVertexBuffer.extrudeScale * extrude.y * 0.015873);
    verts.push( point.x, point.y);
    return this.index;
};

// — pass vertexes into the addLine func that will calculate points
bucket.addLine(rawVerts,“miter”,“butt”,2,1);

prototype  code posted here

 

WebGL polyline tessellation with pixi.js

update 09/2015  : another triangulation methods (mapbox, tesspathy) mentioned here

pixi.js is a 2D open source library for gaming that includes WebGL support for primitives rendering. Why not to utilize it for polyline renderings on map ? It turned out, however, that the  tesselation of the polylines is not handled well.

most important code snippets:

<script src="Pixi.js"></script>
<script src="Point.js"></script>
<script src="WebGLGraphics.js"></script>

//--data
<script src="route.js" charset="utf-8"></script>

var graphicsData = {
 points: verts,
 lineWidth: 0.00015,
 lineColor: 0x33FF00,
 lineAlpha: 0.8
};
var webGLData = {
   points: [],
   indices: []
 };
 // -- from pixi/utils
 PIXI.hex2rgb = function (hex) {
   return [(hex >> 16 & 0xFF) / 255,
           (hex >> 8 & 0xFF) / 255,
           (hex & 0xFF) / 255];
  };

PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);

I have put sample here:

Another implementaiton of polyline tessellation (seems like more functional) is in mapbox-gl-js  in LineBucket  .Mapbox-gl-js code took quite more time to get it running and debug on Windows platform,I  had to run npm install  from VS command shell and read carefully what all the npm errors are saying (e.g. Python version should be < 3). Then FireFox for some reason haven’t triggered breakpoint on LineBucket.addLine, this took another time to find out that I should debug thiOstravaRailwayss rather in Chrome.   See the blog here.Anyway good  experience with all the messy npm modules, their install requirements and unnecessary complexity. Also all the npm modules takes more than 200 MB, but some of them are optional in the install.

After all basic LINE draw in WebGL (without the thicknes and styling) is useful too, as on picture above you can see railways in CZ city Ostrava.

 

TypeScript: Bringing Sanity to JavaScript

Great summary of the TypeScript features…

Didactic Code

TypeScriptAs much as I’d prefer to be working in F#, I’ve found myself doing quite a bit of JavaScript lately. I’m hardly a JavaScript expert but I like to think my skills areabove average(although that could merely be wishful thinking).I won’t deny that JavaScript has its problems but I think that it has traditionally been maligned by things that aren’t necessarily the language’s fault; for instance, DOM inconsistencies are hardly under JavaScript’scontrol. Generally speaking, I really do enjoy working with JavaScript. That said, there are things such as prototypal inheritance that I always struggle with and I know I’m definitely not alone. That’s why I decided to take a look at TypeScript now that it has finally earned a 1.0 moniker.

By introducingarrow function expressions, static typing, and class/interface based object-oriented programming, TypeScript bringssanity to JavaScript’s more troublesome areas and gently guides us to writing manageable code using familiar paradigms…

View original post 4,109 more words