Category Archives: iPhone

Relation between MKMapRect and Spherical Mercator Resolution

MKMapRect projected coordinate system used in iOS MapKit  is not the same as Spherical Mercator used by Google, Bing and others. However there is a close linear relationship of the resolution in official spherical mercator and scale used by MapKit and that is   0.149291.

this number is constant for this relation :spherical mercator resolution (e.g. used by OpenLayers)  * zoomscale (used in MapKit)

spherical mercator resolution calculated as : spherical mercator width / view width

zoomscale in MapKit is calculated as : view width / mkMapRect.size.width

that is : spherical mercator width / mkMapRect.size.width = 0.149291  always.

So now any resolution from Spherical Mercator can be directly mapped into the MapKit internal coordinate system (mkMapRect) and vice versa without heavy calculations from mkMapRect to WGS84 and then to Spherical Mercator.

more about projection used in MapKit can be found here : LocationAwarenessPG


How to disable base Google Maps in MapKit

I have searched this and couldn’t find any answer, so here is my own research so far on this subject. You can disable MapKit base layers using 3 approaches:

#1 remove subview from MKMapView (quite bad as you will loose all overlays too)

#2 use undocumented function (bad too as this will be rejected by Apple approval process):

// get MKMapTileView from view hierarchy

UIView * mkMapTileView = [((UIView*) [ ((UIView*)[self.subviews objectAtIndex:0]).

subviews objectAtIndex:0]).subviews objectAtIndex:0];

// call undocumented method

if ( [mkMapTileView respondsToSelector:@selector(setDrawingEnabled:)]){

[mkMapTileView performSelector:@selector(setDrawingEnabled:) withObject:(id) NO];

#3 use method swizzle

inspired by http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html

http://atastypixel.com/blog/making-uitoolbar-and-uinavigationbars-background-totally-transparent/

this method is fine as it is official method and enables you to ‘subclass’ a class that you don’t have access in compile time.

#import <objc/runtime.h>

// original method declaration

static void (*_origDrawLayerInContext)(id, SEL, CALayer*, CGContextRef);

// set up subclass in runtime..in some entering method

UIView * mkMapTileView = [((UIView*) [ ((UIView*)[self.subviews objectAtIndex:0]). subviews objectAtIndex:0]).subviews objectAtIndex:0];

Method  origMethod = class_getInstanceMethod([mkMapTileView class], @selector(drawLayer:inContext:));

_origDrawLayerInContext = (void *)method_getImplementation(origMethod);

if(!class_addMethod([mkMapTileView class], @selector(drawLayer:inContext:), (IMP)OverrideDrawLayerInContext, method_getTypeEncoding(origMethod)))

method_setImplementation(origMethod, (IMP)OverrideDrawLayerInContext);

// implement our Override

static void OverrideDrawLayerInContext(UIView *self, SEL _cmd, CALayer *layer, CGContextRef context) {

// possibly call original method if you leave it empty base google maps will not be displayed. You can draw custom content here as well…

//  _origDrawLayerInContext(self, _cmd, layer, context);

}


iKatastr awarded in Mobile Application of the 2011 challange in Czech

 

This is a great unexpected surprise as judging panel of the Mobile Application of the 2011 year in Czech selected iKatastr. This is a great satisfaction as unlike previous idea “MapShake” that has been realized on www.mapshake.cz  generated no attraction, iKatastr is complete opposite. With MapShake, however, I have realized something important - simplicity. Although MapShake.cz and  the iPhone application “WhateverMap 1.0″ released in 2009  enabled to view cadastral maps , it was not straightforward, not explicit. With Jiri Kaminek working on Whatevermap 2.0 engine in the whole year 2010 we were about to do the same mistake for iPhone – release a universal map composition app. In fall 2010, Jirka was in Sweden and was finalizing Whatevermap 2.0 with some great demos. Fortunately MapShake failure warned me just in time and we agreed to make the iKatastr as pilot of the Whatevermap 2.0 engine. The idea was simple - let’s take the universal Whatevermap 2.0 engine and create single purpose map application of iOS. Jirka has done a great job. And another great thing is that Whatevermap 2.0 is working fine, is configurable remotely (all map definitions are stored on server so we can update them independently from the AppStore upgrade process) and moreover if you know how to define your own map composition – you can load into iKatastr literally whatever map :).

 


Who is suing whom ?

Who is suing whom

Who is suing whom in mobile world


iKatastr rocks !

This is somehow very encouraging

#1 iKatastr is still on top in the category Navigation in Czech app store after 4 months ! on iPhone it keeps 2nd place right after Mapy CZ provided by largest internet search in CZ Seznam.  On iPad, however, iKatastr is still 1st in category Navigation.

#2 Users of iKatastr has reported quite lot positive feedbacks, see here : http://appcomments.com/app/id396352287/iKatastr_reviews?country=143489&show=show_all_comments&sort=sort_recent&sortorder=sort_ascend&page=1

#3 IKatastr has been mentioned in Czech magazine “Mobility” 1/2011, on page 85.

 Quoted from the magazine press:

“There are just few  high quality applications in the Czech App Store. Even fewer of them are for free.
 iKatastr developed at Mendel University in Brno belongs to this narrow group with functionality that is also unique in the international comparison. “

——————-
 Jiri Kaminek (developer of the iKatastr) will reveal more statistics about usage of iKatastr in his upcoming thesis.  I can tell here just the following interesting observation : iPhone usage of iKatastr is approximately 10x higher than of the web  (www.ikatastr.cz


Whatevermap engine v iKatastru

iKatastr pro iPad/iPhone je poháněn Whatevermap enginem, ten toho dokaze vic, nez  se na prvni pohled zda. Jirka Kaminek predvedl ‘kouzlo’ s Mapy.cz  http://mapserver.mendelu.cz/wordpress/?p=204 bezici v aplikaci iKatastr !

 


iKatastr ranks

 

iKatastr HD is reaching 1 month of #1 in Navigation category in Czech Republic store : http://www.appannie.com/ikatastr-hd/ranking/history/#store_id=143489

iKatastr is following:

http://www.appannie.com/ikatastr/ranking/history/#store_id=143489

both have been featured in “What is Hot” in Czech Republic store.

Jiri Kaminek will reveal more statistics details of iKatastr application as part of his upcoming PhD thesis.


Android vs iPhone development

this is interesting comparison of OS versions runing on Android and iOS and ‘developer friendly environments’ from the SDK perspective:
“The number of devices per OS is a great marketing number for Google and Apple to fight over but as a developer—who wants to get the most out of the SDK—I care about the version of the OS on the devices. If I want to use the latest and greatest SDK’s I’ll take Apple’s 80% of 21% over Google’s 30% of 28%.”

http://jeffreysambells.com/posts/2010/05/20/android-vs-iphone-development-decisions

“The iPhone has another big advantage and it solves the problem of distribution as I alluded to earlier. iPhone users use iTunes to sync their devices and add content. The process of syncing the device also checks for updates and allows all iPhone OS devices (iPhones, iPod Touches, iPads) to download the latests version of the OS. As a result the March 2010 iPhone Platform Versions stats look very developer friendly”

“More than 50% of the Android install base is still using version 1.6 or less. As a developer what should I do? If I choose to take advantage of the latest and greatest SDK I get less than half of the devices! But still, the bigger problem is there is no clear and easy upgrade path for those bottom 50% to get the newer OS version”


OpenLayers or GoogleMap v3 for mobile web app ?

I have experimented with OpenLayers 2.9 using touch.js extension for capturing touch events from iPhone/iPad. Although stripped down version of OL is about 184KB, the performance is very bad. If you have iPhone/iPad check this experiment: http://www.sumbera.com/lab/iphone/katastr.htm (note it will not work from desktop browser)

 OL team is working on v3 of OL to be more lighter, faster even for mobile devices, see here: http://trac.osgeo.org/openlayers/wiki/three  or here : http://openlayers.org/blog/2010/06/30/openlayers-3-on-github/

 Meanwhile I have tested new GoogleMaps v3 how it works on iPhone/iPad. despite few problems (stability, problems with cached tiles or disconnected JavaScirpt  to load new tiles -iPad)  it works pretty well . Check yourself this page from your mobile touch device (iPhone.iPad,Android): http://www.ikatastr.cz/iKatastrM.htm

Conclusion : Google Maps v3 wins on mobile over the Openlayers 2.9

 

[2011 September] UPDATE : new Openlayers 2.11 works quite well on iPad/iPhone.


Tiled WMS overlay on Google Map v3

this is the third sample of the tiled WMS overlay over the Spherical Mercator, this time over the new Google Map v3. Previsous post talked about overlyaing WMS in  Silverlight Bing maps (http://blog.sumbera.com/2010/02/25/overlay-wms-on-google-in-silverlight-bing/ ) and OpenLayers (http://blog.sumbera.com/2010/02/17/overlay-wms-on-google-in-openlayers/).

Sample application can be found here: http://www.sumbera.com/lab/GoogleV3/tiledWMSoverlayGoogleV3.htm You can try to run it on your mobile device as well – suprisingly it run very well on my iPhone (sometimes it just crash Safari :), however on the iPad there are some more serious issues that will be hopefuly resolved with new iOS update (JavaScript stops to run).

For the new Google Map v3 you have to do the following :

//Define custom WMS tiled layer
var SLPLayer =
 new google.maps.ImageMapType (
 {
  getTileUrl:
    function (coord, zoom) { 
      var proj = map.getProjection(); 
      var zfactor = Math.pow(2, zoom); 
       // get Long Lat coordinates
      var top = proj.fromPointToLatLng(
             new google.maps.Point(coord.x * 256 / zfactor, coord.y * 256 / zfactor) ); 
      var bot = proj.fromPointToLatLng(
            new google.maps.Point((coord.x + 1) * 256 / zfactor, (coord.y + 1) * 256 / zfactor)); 
      //corrections for the slight shift of the SLP (mapserver)
       var deltaX = 0.0013; 
       var deltaY = 0.00058; 
     
      //create the Bounding box string
       var bbox = (top.lng() + deltaX) + “,” +(bot.lat() + deltaY) +“,”
                           +(bot.lng() + deltaX) +“,” +(top.lat() + deltaY);
      
       //base WMS URL
        var url =
       “http://mapserver-slp.mendelu.cz/cgi-bin/mapserv?map=/var/local/slp/krtinyWMS.map&” ;
       url +=“&REQUEST=GetMap”; //WMS operation
       url +=“&SERVICE=WMS”; //WMS service
       url +=”&VERSION=1.1.1″; //WMS version 
       url +=“&LAYERS=” + “typologie,hm2003″; //WMS layers
       url +=“&FORMAT=image/png”; //WMS format
       url +=“&BGCOLOR=0xFFFFFF” ;
       url +=“&TRANSPARENT=TRUE” ;
       url +=“&SRS=EPSG:4326″; //set WGS84 
       url +=“&BBOX=”+ bbox; // set bounding box
       url +=“&WIDTH=256″; //tile size in google
       url +=“&HEIGHT=256″ ; 
       return url; // return URL for the tile    
     }, //getTileURL
 tileSize: new google.maps.Size(256, 256),
 isPng: true
 }); 
 //add WMS layer 
 map.overlayMapTypes.push(SLPLayer); 

 
 
 

Follow

Get every new post delivered to your Inbox.