iKatastr.cz pro mobilní web

Pár poznámek k nové mobilní verzi iKatastr.cz.

To co je na této verzi zajimavé je, že jsem se nakonec rozhodl ignorovat všechna možná pokušení o využití JavaScriptovych knihoven, tedy kromě základní mapové komponenty – ta je založena na Leafletu v 1.0.3, kde jsem ještě musel udělat pár úprav, aby vše fungovalo správně. Leaflet má v komprimované formě 48KB. Využívám i komponentu Mapy API ale jen pro vyhledávání a navíc je tato část nahrána až když uživatel opravdu klikne na hledání.

Vlastní kód iKatastru má v komprimované formě pouze 13.3 KB. Celý výkonný kód, včetně HTML, CSS a fontu (který je také na míru vyroben) zabere při studeném startu (bez cache) pod 70 KB.  Zbytek je už vlastní obsah  – data  – hlavně dlaždice ze zdrojů Mapy.cz a ČÚZK.

Při každém dotazu do mapy aplikace vyšle požadavky na webové služby ČÚZK, ty zaberou v jedné odpovědi pod 10 KB.

 Uživatelské rozhraní 

Vertikální menu ve stylu rozbalovacích panelů nakonec zvítězilo a myslim si, že je hbité, pěkné a funkční. Opět nechtěl jsem dělat tendenční UI ani animace, které nakonec  berou čas uživateli. Na mobilu se dovoluje kvůli místu mít pouze jeden panel rozbalený, navíc funguje libovolné tapnutí do mapy k tomu aby se panel zabalil – to je navýkové a pohodlné. Ovšem panely se dají zavírat více způsoby – samotnou ikonou co je otevíra a samozřejmě křížkem vpravo.

Informace z katastru nemovitostí:

Tohle byl asi největší problém – tedy ne samotné informace – ty jsou úplně na jiné úrovni než před 8 lety, kdy iKatastr začínal, spíš problém jak do mapy tapnout – dlouze, nebo krátce ? Dlouhý stisk je zavedený v mobilnich aplikacích, krátký klik je zase pohodlný a rychlý na webu.  Nakonec má uživatel k dispozici oboje (a k mému údivu to šlo vyřešit) a navíc může si zvolit, jestli se má na jedno tapnutí přímo zobrazit nahlížení (tedy tak jak byl zvyklý z minulých verzí) . To otevírá poměrně hladkou cestu na přenesení této mobilní verze na desktop. Ona tam funguje, dokonce i na Internet Exploreru (jen si stěžuje že  potřebuje pomoci s povolením otevřít popup okno …opět) a na EDGE prohlížeči nefungují některé dotazy – je to chybou v EDGE prohlížeči, naštěstí se rozjedou vždy záložní dotazy, které fungují, takže z pohledu uživatele se pouze nezvýrazní parcely/budovy.

Budu rád pokud mi sem napíšete vaše postřehy, připomínky k této mobilní verzi – co funguje, co se lébi/nelébi a jak používate vlastně iKatastr a při jaké práci.

 

Advertisements

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

WMS with Google Maps on iOS

Screen Shot 2014-04-21 at 00.49.02Sample 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.

Mobile Reports from visionmobile.com

How can HTML5 compete with Native?

http://www.visionmobile.com/product/how-can-html5-compete-with-native/

HTML5 performance is fine, what we are missing is tools

http://www.visionmobile.com/blog/2013/12/html5-performance-is-fine-what-we-are-missing-is-tools/

How do developers prioritise platforms? iOS vs Android vs HTML5

http://www.visionmobile.com/blog/2013/12/developers-prioritise-platforms-ios-vs-android-vs-html5/

Developer Economics Q3 2013: State of the Developer Nation

http://www.visionmobile.com/product/developer-economics-q3-2013-state-of-the-developer-nation/

App Developer Atlas

http://www.appdeveloperatlas.com

 

Mobile Considerations

Quite good (and lengthy) chapter worth of weekend reading for mobile development
Aral Balkan, the author,  describes many important  concerns or considerations before you start mobile development :
http://mobile.smashingmagazine.com/2012/06/18/mobile-considerations-in-user-experience-design-web-or-native/

My favourites quotes from the article:
If your choice of platforms and technologies is based simply on your perceived short-term business needs or on the current competencies of your team, then you are making a decision that solves your own problems, not the user’s problems. This may have short-term advantages, but you will not be able to compete in the long term with those who solve the user’s problems first. Your choice of technologies and platforms should be based on how best you can meet the user’s needs, not on ideological bias or on obtaining short-term gain at the risk of long-term loss.

A common mistake I see many designers make is to assume that by using cross-platform authoring technologies they will be able to write once, run anywhere. This is a myth. And acting on the myth can lead to rather costly underestimations. Your application might run on multiple platforms, but this rarely—if ever—means that it will run well on multiple platforms.

Designers who do not take the unique cultures, customs, language and norms of their respective platforms into consideration risk making their applications look and sound out of place. The applications will appear noticeably foreign, unnecessarily loud and usually rather arrogant, simply because they are culturally insensitive.

The worst thing you could do, of course, is disrespect all of your users by creating a lowest-common-denominator application that gives every user on every platform an unoptimized user experience. At that point, you would be at your most vulnerable.

Supporting multiple platforms is not a feature unless you can support them all well. You may have first-to-market advantage, but that will last only until you are outdone by your best-in-market competitor.

So, write once, run anywhere is a dangerous myth. Cross-platform applications that compete successfully are write once, optimize everywhere. You must understand the implications this will have on your budget and schedule and plan for optimizing, testing and supporting your application on every platform you choose to support.

In summary, be careful when creating native binaries that simply wrap applications that do not use native components. These apps have a tendency to look like native applications, but they cannot behave like native applications because they do not use native components in native frameworks. A PhoneGap application that uses the jQTouch framework might display what looks like an iOS table view when running on an iPhone, but this is simply an HTML look alike brought to life by clever use of CSS and JavaScript. It pretends to be an iOS table view, but it cannot meet the behavioral characteristics of a real table view component from the Cocoa Touch framework, and thus it ends up creating expectations that it cannot meet.

The advantages of building native applications using native technologies are numerous. For one thing, you have complete flexibility in optimizing the application and user experience. When you use native components and adhere to the human interface guidelines for your chosen platform, your application will conform to the culture, language and norms of that platform. It will be easier for users to learn and use.

Apple A7 faster than my desktop cpu

I am developing for iOS on 2.5  years old  white MacBook (mid 2010) which has a Geekbench3 64 bit  mutli core result of average 2395 (mac scores  ) This Mac is powered by  Intel Core 2 Duo P8600 2400 MHz (2 cores), runs quite well  as it has upgraded SSD disk  (OWC Mercury Extreme 6G) and 8GB RAM , now with Maverick OS X even better in performance  than previous OS X cats.

Now latest Apple A7 64 bit processor has scored  2564 in the same benchmark  posted here

So yes, Apple A7 is a desktop-class processor, that in my case could teoretically run instead of my current Intel CPU  to handle all development  tasks I do on daily basis.

here is a snapshot of my over-tableted working place.

Fotografie-0001