C R E A T I N G    M O D E R N   D A T A & G E O   V I S U A L I Z A T I O N S

Posted in Uncategorized | Leave a comment

PC web vs. Mobile app usage

This chart shows real usage (sessions)  of iKatastr app over 5 years of running  as app on iOS, Android and on PC as web page  in CZ.  Tiny Windows Store app  and  Windows Phone app usage couldn’t be rendered at all.

ikatastrSessions

Posted in iKatastr, iOS, Uncategorized | Tagged | Leave a comment

Google Trends – close to reality ?

or no ? … how to explain this picture ? iKatastr was indeed attempt to introduce new term for accessing cadastral data in Czech Republic, and it launched on iOS, Android and web 5 years ago, no public advertising, no ads at all…  Anyway I like this picture, and it is kind of surprising that GISCloud nor mangomap doesn’t enjoy the same level of trending according to Google Trends. I think reality is different

 

googlwTrends

..let’s look on another measure – site visits using simlarweb.com

similarweb

similarwebmango

Looks like Google Trends takes into consideration # of visits and is more weighted than media coverage ? Or does the mobile presence of app iKatastr adds so much ‘ads’ to the final chart  ?

 

Posted in iKatastr | Tagged , , , | Leave a comment

Průkopníkům

…před 20 lety jsem tuto knihu  našel na stole v jednom starém, opuštěném  domě v Brně, dodnes se k ní vracím jako k pokladu…

pujdeto

Breviář PŮJDE TO ! ING J. SOLAR, Praha 1938, 3. vydání

Posted in motivation | Leave a comment

iKatastr.cz 20M clicks

First time 100K visits over month period.  20M clicks & reaching 3M sessions overall.

 

bitlystat

Posted in iKatastr, Uncategorized | Tagged | Leave a comment

Joy of Open Source

I have got great, absolutely amazing  joy today from my own open source experiment. In 2014, nearly 2 years ago,  I have published on GitHub (gist)  L.CanvasOverlay a small class  to handle generic drawing on top of Leaflet, I was thinking let’s try to  contribute back to the open source with this little snippet –  I thought would be useful so I have added little description. Original blog post here: https://blog.sumbera.com/2014/04/20/leaflet-canvas/

After few months later I found it is used on http://windyty.com   one of the best 2015 geo-visualization with huge popularity. It is a small part of this great app, but makes me feel so good like I am part of it, I am looking on something where is my small piece, small share…meaning of the effort, sense of publishing and open sourcing.

Screen Shot 2016-02-02 at 23.16.13

And today I have got echo it is used also in Marine National Facility here: http://www.cmar.csiro.au/data/underway.test/

This makes me so happy … and just came across this quote : “Revenue is a lagging indicator, usage is a leading indicator,” can’t remember, who just said that ? :)

 

Posted in OpenSource | Tagged , , | Leave a comment

SVG fast scaled overlay on Leaflet 1.0 and 0.7

SVGScaled SVG can be drawn on map in much more faster way than traditional approaches, at least for points. Traditional approach re-position each element to fit into the view of the map, however SVG is “scalable” so we can use it and it performs much more faster for zoom-in/out.

Few considerations:

  1. SVG itself define viewport by its coordinate space, all outside of this viewport is usually  clipped, so it is important to keep SVG viewport in-line with the viewport of the map. There are approaches that resizes SVG as you zoom-in (here), and while it works, it has a problems in deep-zooms when you need to move on map (actually you move  giant SVG based on the zoom )
  2. translating LatLon to absolute pixel values (like here used for WebGL) is possible solution, however IE and FF has problems with large numbers for transoform (>1 M), So we need to get SVG elements in view coordinates and translate them.
  3. Having some track of bounding box of all elements like again used here should be avoided (SVG or its group element knows about extension of the elements it holds)
  4. So while we keep SVG in the viewport, we need to compensate any shift and zoom by translating <g> (group) of all elements.
  5. So in leaflet when map  moves, SVG is translated back to its original position while <g> is translated forward to reflect the map movement
  6. We need to keep track of LatLon position of either map center or one of the corner – we use topLeft corner.
  7. Leaflet doesn’t do  precise enlargement and rounds view points because of some CSS troubles on some devices (noted here). We need to patch two translating functions in Leaflet to get this right (so SVG enlargement will be aligned with map)… but I need to look on this again, best would be to not patch Leaflet of course.

most important things happen in moveEnd event:

 


 var bounds = this._map.getBounds(); // -- latLng bounds of map viewport
 var topLeftLatLng = new L.LatLng(bounds.getNorth(), bounds.getWest()); // -- topLeft corner of the viewport
 var topLeftLayerPoint = this._map.latLngToLayerPoint(topLeftLatLng); // -- translating to view coord
 var lastLeftLayerPoint = this._map.latLngToLayerPoint(this._lastTopLeftlatLng); 

 var zoom = this._map.getZoom();
 var scaleDelta = this._map.getZoomScale(zoom, this._lastZoom); // -- amount of scale from previous state e.g. 0.5 or 2
 var scaleDiff = this.getScaleDiff(zoom); // -- diff of how far we are from initial scale 

 this._lastZoom = zoom; // -- we need to keep track of last zoom
 var delta = lastLeftLayerPoint.subtract(topLeftLayerPoint); // -- get incremental delta in view coord

 this._lastTopLeftlatLng = topLeftLatLng; // -- we need to keep track of last top left corner, with this we do not need to track center of enlargement
 L.DomUtil.setPosition(this._svg, topLeftLayerPoint); // -- reset svg to keep it inside map viewport

 this._shift._multiplyBy(scaleDelta)._add(delta); // -- compute new relative shift from initial position
 // -- set group element to compensate for svg translation, and scale</pre>
 this._g.setAttribute("transform", "translate(" + this._shift.x + "," + this._shift.y + ") scale(" + scaleDiff + ")");

Test page / Gist : http://bl.ocks.org/Sumbera/7e8e57368175a1433791

To better illustrate movement of SVG inside the map, here is a small diagram of basic SVG states:svgpositioning

Posted in Code, D3, Data Visualization, Leaflet, SVG | Tagged , , | Leave a comment

Smart M.App

  Recent months I have been authoring  “Green Space Analyzer” web app that shows modern  approach to visualize and  query   multi temporal geospatial data.  User see information in a form he can interact with and discover new patterns, phenomena or information just by very fast ‘feed-back’ of the UI response on the user input.  When user selects for example certain area, all graphs instantly animates transition to reflect selection made, this helps to  better  understand  dynamics of the change. Animation can be seen everywhere – from labels on bar chart, through colors change of the choropleth up to title summary. it creates subtle feeling of control or knowing what has changed and how it has changed. At HxGN 15 conference in   hexagon geospatial keynote, CEO Mladen Stojic showcased it as part of the  vision  called Smart M.App, worth to look at (at 52:40 starts Smart M.App demo):

 

my Smart M.App  ‘world tour’:

 

 

 

Posted in D3, Data Visualization, JavaScript, SVG, UserInterface | Tagged , , , | Leave a comment

Drawing Shape File on MapKit

Simple & strightforward test of loading shape file and drawing it on MapKit on iOS8 using drawMapRect

GitHub:https://github.com/Sumbera/SHPonMapKit

 

  • draws only polygons so far
  • primitive optimization, no scale optimisation

Reading of shape file is performed by shapelib

//------------------------------------------------------------
NS_INLINE NSArray *getPolygonsFromShapeFile(NSString *shpFilePath){
   
    const char *path = [shpFilePath cStringUsingEncoding:NSUTF8StringEncoding];
    SHPHandle shp = SHPOpen(path, "rb");
    int numEntities;
    int shapeType;
    
    SHPGetInfo(shp, &numEntities, &shapeType, NULL, NULL);
    
    NSMutableArray *allPolygons = [[NSMutableArray alloc]init];
    for (int i=0; i<numEntities; i++){
       SHPObject *shpObject = SHPReadObject(shp, i);
       if (shpObject->nSHPType == SHPT_POLYGON ||
           shpObject->nSHPType == SHPT_POLYGONZ ||
           shpObject->nSHPType == SHPT_POLYGONM){

        
            int numParts = shpObject->nParts;
            int totalVertexCount = shpObject->nVertices;

            for (int n=0; n<numParts; n++)
            {
                int startVertex = shpObject->panPartStart[n];
                int partVertexCount = (n == numParts - 1) ? totalVertexCount - startVertex : shpObject->panPartStart[n+1] - startVertex;
                int endIndex = startVertex + partVertexCount;
                
                CLLocationCoordinate2D coords[partVertexCount];
                for (int pv = startVertex, i = 0; pv < endIndex; pv++,i++) {
                    coords[i] =CLLocationCoordinate2DMake(shpObject->padfY[pv],
                                                          shpObject->padfX[pv]);
                }
                // -- this actually converts lat lon to mkmappoints projection
                MKPolygon *singlePolygon = [MKPolygon polygonWithCoordinates:coords count:partVertexCount];
                [allPolygons addObject:singlePolygon];
            }
       }
       
     SHPDestroyObject(shpObject);
       
  }
    SHPClose(shp);
    
    return [allPolygons copy];
}

credits/inspiration:

drawing : http://stackoverflow.com/questions/17673410/mkmapview-with-multiple-overlays-memory-issue
parsing : http://www.al-tyus.com/blog/2013/10/14/mapkit-and-esri-shapefiles
shapelib: http://shapelib.maptools.org
dala: http://www.geoportalpraha.cz

Posted in Code, iOS, iPhone, MapKit, Mobile, Objective-C | Tagged , , , | 1 Comment

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

Posted in Canvas, JavaScript, Leaflet | Tagged , , , , | 8 Comments