WMS on MapKit with iOS7

Updated WMS over MapKit sample code for iOS7 , available on github  I have added cadastral maps of Czech Republic, used camera API to set the view and tested, check also WMS on Google  Maps SDK on iOS mentioned here

iOS7 introduced new class MKTileOverlay sample derives from this class WMSTileOverlay

Key method to custom tile loading (and cache control) is loadTileAtPath:result

- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))  result

this method is called by MapKit (or better by MKTileOverlayRenderer ) when it needs to draw a tile . It asks for NSData (and error) from x,y,z tile coordinates. In this method you can  load NSData either from local cache or from NSURLConnection and pass resulting NSData (when ready)  back to MapKit, for example like this (reading from cache)

result ([NSData dataWithContentsOfFile:filePath], nil);

if you do not need to use cache and you do not provide loadTileAtPath method , you can use another hook (callback) that is provided by MKTileOverlay, URLForTilePath:path

- (NSURL *)URLForTilePath:(MKTileOverlayPath)path

this method enables to custom format URL required to load tile, thus you can use WMS HTTP-GET parameters, for example :

NSString * resolvedUrl = [NSString stringWithFormat:@"%@&BBOX=%f,%f,%f,%f",self.url,left,bottom,right,top];

if there is neither method in the derived class, then you probably do not need to derive at all from MKTileOverlay and directly use it with initWithUrlTemplate (not case for WMS, but for any other x,y,z  sources)

IMG_0021

Bad news is that  MapKit on iOS7 doesn’t support   tilt/pinch in Satellite/Hybrid mode in MapKit on iOS7

Data Visualisation with d3.js Cookbook

bought this great book on  d3.js (Data-Driven documents), written by  Nick Qi Zhu

D3 can plot map in various projections, however do not expect to get same set of (overlapping) functionality as Leaflet or OpenLayers. D3 can extend these mapping frameworks. For OL3 simple  example is here for Leaflet, my favourite is  hexbins or check my own experiment here.

While D3 is kind of ‘base’ charting library (lot of utility functions, helpers) , there is upper , high level library too  that can provide lot of ‘boilerplate’ for common charts. Here comes great news:

Nick Qi Zhu   is also author of the open source javascript  lib dc.js   (Dimensional Charting) library  that is using crossfilter (Fast Multidimensional Filtering for Coordinated Views) . Part of the dc.js lib is set of most common charts and one of them is choropleth map .

Other resources:

D3 Animation : http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/

Design selections: http://www.awwwards.com/fresh-ui-inspiration-in-the-era-of-google-material-and-design-patterns.html

Why you should visit cemeteries

I really like this post from Avdi Grimm called “The Passion Gospel“. This remembers me a first chapter in a book: “The Art Of Thinking Clearly” from Rolf Dobelli:

..”no journalist is interested in failures – with exception of fallen superstars.This makes the cemetery invisible to outsiders. In daily life, because triumph is made more visible than failure, you systematically overestimate your chances of succeeding.”

..”The media is not interested in digging around in the graveyards of the unsuccessful. Nor is this its job.”

I think same  bias applies to blogs, twitters, facebook and press releases of companies or marketing in general. And to this blog too 🙂

…you should recognize that survivorship bias is at work, distorting the probability of success like cut glass..

..Survivorship bias means this: people systematically overestimate their chances of success. Guard against it by frequently visiting the graves of once-promising projects, investments and careers. It is a sad walk, but one that should clear your mind.”

 

 

WMS with Google Maps on iOS

Sample for using WMS sources in Google Maps SDK for iOS. available on github here: https://github.com/Sumbera/WMS_iOS_GoogleMapSDK
Provide your API key in the WMSController.h

  • Google Maps for iOS used : 1.7.2 (April 2014)
  • used XCode 5.1.1 (April 2014)
  • iPad Air, iOS 7.1 (should run in iOS6.0 too)

 

There are two ways of overlaying WMS in the Google Maps for iOS SDK:

“Method B”: use GMSTileURLConstructor

   // -- method B. WMS tile layer with GMSTileURLConstructor
      GMSTileURLConstructor urls = 
         ^(NSUInteger x, NSUInteger y, NSUInteger z) {
           BBox bbox = bboxFromXYZ(x,y,z);
           NSString *urlKN = 
             [NSString stringWithFormat:@"Your WMS url&BBOX=%f,%f,%f,%f",
                                           bbox.left,
                                           bbox.bottom,
                                           bbox.right,
                                           bbox.top];

          return [NSURL URLWithString:urlKN];
      };

“Method A”: use custom TileLayer derived from GMSTileLayer

  1. your derived class from GMSTileLayer (here WMSTileLayer.h) will receive tile request
     -(void)requestTileForX:(NSUInteger)x 
    y:(NSUInteger)y
    zoom:(NSUInteger)z
    receiver:(id<GMSTileReceiver>)receiver

  2. WMSTileLayer first checks for cached tile and if found calls :
      [self drawTileAtX:x y:y zoom:z Url:urlStr Receiver:receiver] ;

  3. if tile is not cached we download it, save it to the file system (using MD5 hash) and call to draw it
      [data  writeToFile: filePath  atomically:YES];
    [self drawTileAtX:x y: y zoom: z Url:urlStr Receiver:receiver] ;

  4. drawTileAtX is very simple:
      -(void) drawTileAtX: (NSUInteger) x 
    y:(NSUInteger) y
    zoom:(NSUInteger)zoom
    Url:(NSString*) url
    Receiver: (id<GMSTileReceiver>) receiver {
    UIImage *image = TileLoad(url,NO);
    [receiver receiveTileWithX:x y:y zoom:zoom image:image];
    }

}

both ways are used in this sample.

Leaflet Canvas Overlay

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   : &lt;canvas>,
                                bounds   : &lt;bounds in WGS84>
                                size     : &lt;view size>,
                                zoomScale: &lt;zoom scale is  1/resolution>,
                                zoom     : &lt;current zoom>,
                                options  : &lt;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

Many points with d3 and leaflet

Update 07/2025: recovered brushing demo here: https://www.sumbera.com/gist/js/d3/brushing.html

recovered d3 and leaflet demo: https://www.sumbera.com/gist/js/leaflet/svg/ManyPointsd3.html

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

manypoints

Testing SVG limits of plotting points on map using D3, Leaflet following this base sample:http://bost.ocks.org/mike/leaflet. However instead of scaling SVG in deep zooms, I am using Enter/Update/Exit pattern from D3 to dynamically update points on map. This has been prototyped also here http://bl.ocks.org/sumbera/9972460 with brushing of 100T points.

For zooming out (causing all points to be displayed), I am filtering out points that can’t be effectively visible, thus reducing number of points in SVG. (check console for log output).

This sample is using real data of 24T coordinates where points are clustered around cities, rather than artifically randomized. Real number of rendered points / removed points can be seen in console

Test page : http://bl.ocks.org/sumbera/10463358

From .NET to iOS developer

What it takes to transfer from Microsoft .NET to Apple iOS  developer ?

Update 2015: more longer and similar story/explanation  found  here

So this was me ‘before’ with all my friends:  Windows, C#, .NET, Visual Studio, MSDN :

transcript:
– easy ‘managed’ life,
– can smile and make ceremony
– implicit friends and friends of friends you can’t get rid of them
– shallow water, no deep dive
– few freezes
– slightly detuned, but good enough for many
– moon shots

…and me ‘after’  passing through the  fire of iOS, Objective-C, Cocoa Touch, XCode, Documentation, Mac, Certificates, AppStore

transcript:
– different game, different rules
– lot of explosive material (resources)
– focused, not distracted by ‘friends’
– intelligence and luck needed
– dangerous and too explicit
– very rewarding

Leaflet 0.7 vs. OpenLayers 3 beta 1 on iOS

Made 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

Czech oblique images

I have put together simple web app that overlays cadastral maps with otrophoto , if you zoom more you will  see bird’s eye high quality images, that you can rotate (left upper corner arrows) it is not possible yet to overlay in the bird’s eye WMS overlay with cadastral info, however I was amazed with the quality of the images covering whole Czech Republic and in better quality than Google (provider called Seznam is local big Google rival) Rendering is not great either as their rendering is proprietary and not of the quality as OpenLayers or Leaflet. Anyway the information coming from oblique images , or let’s say ‘predefined camera positions’ is very useful of understanding spatial situation in the respective area. May be the fact that user doesn’t need to move fully in 3D space but is limited somehow is better than full 3D ‘free form’ , ‘game-like’ navigation – one can be easily lost there. Also I found it equal or even better than information provided by street view data (what google provides) as street view is ‘too close’ and I have found myself quite often lost in the ‘street-view’

page is available here (click on image):

Screen Shot 2014-01-13 at 10.42.43

if you zoom in you will see this :

Screen Shot 2014-01-13 at 10.40.07

Code available here: https://github.com/Sumbera/iKatastr

Demo here: http://www.ikatastr.cz/uKatastr.html