Skip to content

Upgrade from SDK 1x

Nutiteq edited this page Jun 24, 2013 · 8 revisions

Following are some typical code samples compared in old SDK and new.

Init of map

Old SDK had two objects: BasicMapComponent which handled map-specific things, and Android-specific MapView, which is higher level container for BasicMapComponent. In the new API there is just MapView which has all the map control features.

a) Old SDK:

// 1. define object
        this.theMap = new BasicMapComponent(this.mgmapsLicenseKey, 
                                            new AppContext(this), 
                                            1, 
                                            1, 
                                            new WgsPoint(0, 0), 
                                            12);  
// 2. set base map
        this.theMap.setMap(new CloudMade(this.cloudMadeApiKey, "", 256, 1)); 

// 3. some options
        this.theMap.setPanningStrategy(new ThreadDrivenPanning()); 
        this.theMap.setControlKeysHandler(new AndroidKeysHandler());
        this.theMap.setTouchClickTolerance(200);
// 4. caching
        this.theMap.setNetworkCache(this.getCachingChain());
// 5. start map
        this.theMap.startMapping();

b) new SDK

Note that it has some new features, so there is more code

// enable SDK logging (to logcat with given tag) for easier troubleshooting
        Log.enableAll();
        Log.setTag("upgraded");

// 1. Map object is created from Layout XML
        this.theMap = (MapView) findViewById(R.id.map);

// 2. set base map
        this.proj = new EPSG3857();
        this.theMap.getLayers().setBaseLayer(new TMSMapLayer(this.proj, 0, 20, 11,
                "http://b.tile.cloudmade.com/8ee2a50541944fb9bcedded5165f09d9/1/256/", "/", ".png"));

// 3. set some needed options
 // define new configuration holder object
        this.theMap.setComponents(new Components());
        
        // set sky bitmap
        this.theMap.getOptions().setSkyDrawMode(Options.DRAW_BITMAP);
        this.theMap.getOptions().setSkyOffset(4.86f);
        this.theMap.getOptions().setSkyBitmap(
                UnscaledBitmapLoader.decodeResource(getResources(),
                        R.drawable.sky_small));

        // Map background, visible if no map tiles loaded
        this.theMap.getOptions().setBackgroundPlaneDrawMode(Options.DRAW_BITMAP);
        this.theMap.getOptions().setBackgroundPlaneBitmap(
                UnscaledBitmapLoader.decodeResource(getResources(),
                        R.drawable.background_plane));
          
        this.theMap.getOptions().setClearColor(Color.WHITE);

        // Modify mapview options to make it smoother 
        this.theMap.getOptions().setPreloading(true);
        this.theMap.getOptions().setSeamlessHorizontalPan(false);
        this.theMap.getOptions().setTileFading(true);
        this.theMap.getOptions().setKineticPanning(true);
        this.theMap.getOptions().setDoubleClickZoomIn(true);
        this.theMap.getOptions().setDualClickZoomOut(true);

        // set memory usage limits
        this.theMap.getOptions().setTextureMemoryCacheSize(40 * 1024 * 1024);
        this.theMap.getOptions().setCompressedMemoryCacheSize(8 * 1024 * 1024);

// 4. caching - we allocate 1GB, but not more than 50% of free SDCARD memory for persistent cache
        File cacheDir = this.getDatabasePath("mapcache");
        StatFs statFs = new StatFs("/sdcard");
        long freespace = (long)statFs.getAvailableBlocks() *  (long)statFs.getBlockSize();
        Log.debug("Free space of " + cacheDir.getAbsolutePath() + " is " + freespace);
        int cacheSizeWish = 1000 * 1024 * 1024; // 1 GB

        // do not take more than 50% of free space for caches
        long cacheSize = (cacheSizeWish * 2) >= freespace ? freespace / 2  : cacheSizeWish;
        Log.debug("File cache set to  " + cacheSize);
        this.theMap.getOptions().setPersistentCachePath(cacheDir.getPath());
        this.theMap.getOptions().setPersistentCacheSize((int) cacheSize);

// 5. start map - same as old SDK
        this.theMap.startMapping();

Set base map

a) Old SDK:

    //  Three TYPES OF MAPS
    public void setMapOnLine() {
        this.getTheMap().setMap(new CloudMade(this.cloudMadeApiKey, "", 256, 1)); 
    }
    public void setMapOnBoard() {
        this.getTheMap().setMap(new JaredOpenStreetMap(new StringCopyright("CC-By-SA by OpenStreetMap"), "/res/raw/", 256, 12, 15));
    }
    //  Additionale map for the new app
    public void setMapTerrain() {
        this.getTheMap().setMap(new GoogleStaticMap("dummy", 256, 0, 19, GoogleStaticMap.IMAGE_FORMAT_PNG_32, GoogleStaticMap.MAP_TYPE_TERRAIN, true)); 
    }

b) New SDK:

   public void setMapOnLine() {
        this.theMap.getLayers().setBaseLayer(new TMSMapLayer(this.proj, 0, 20, 11,
                "http://b.tile.cloudmade.com/8ee2a50541944fb9bcedded5165f09d9/1/256/", "/", ".png"));

    }
    public void setMapOnBoard() {
        this.theMap.getLayers().setBaseLayer(new PackagedMapLayer(this.proj, 0, 4, 14, "t", this));

    }
    //  Here Bing maps is used. Google Static Maps TOS does not allow to use it outside web browser.
    public void setMapTerrain() {
        this.theMap.getLayers().setBaseLayer(new QuadKeyLayer(this.proj, 0, 19, 13, "http://ecn.t3.tiles.virtualearth.net/tiles/r",".png?g=1&mkt=en-US&shading=hill&n=z"));
    }

Layers

In old SDK objects were added to BasicMapComponent. In new SDK the information is organized to Layers. One of them defined as Base Layer which is mandatory. You can add other Layers to this, typical overlay layers MarkerLayers to show locations, and you can have also GeometryLayers with Points, Lines and Polygons, or RasterLayers with half-transparent raster info, or even 3D model Layers. So instead of adding objects to MapView you need to add a Layer to MapView and add your objects there.

GPS Location

To use a marker for user location you need to create a MarkerLayer with a Marker, and then can change Marker position. Marker position is mutable, so no need to create new one. See following sample:

// call this once
   private Marker userPlace;

    private void initMarkerLayer(){
        Bitmap olMarker = UnscaledBitmapLoader.decodeResource(getResources(), R.drawable.olmarker);
        MarkerStyle markerStyle = MarkerStyle.builder().setBitmap(olMarker).setSize(0.2f).setColor(Color.WHITE).build();
        // define label what is shown when you click on marker
        Label markerLabel = new DefaultLabel("Tu sei qui!");
        MapPos markerLocation = this.proj.fromWgs84(0,0);
        this.userPlace = new Marker(markerLocation, markerLabel, markerStyle, null);
        MarkerLayer markerLayer = new MarkerLayer(this.proj);
        this.theMap.getLayers().addLayer(markerLayer);
        markerLayer.add(this.userPlace);
    }

  // Called when a new location is found by the network location provider.
  public void onLocationChanged(Location location) {
        MapPos mapPos = this.proj.fromWgs84(location.getLongitude(), location.getLatitude());
        this.theMap.setFocusPoint(mapPos, 500);
        this.userPlace.setMapPos(mapPos);
    }

Routing and Geocoding services

New SDK does not have Services in the core part, like routing and geocoding. However, there are similar implementations in AdvancedMap3D project. See https://github.com/nutiteq/hellomap3d/wiki#routing section of the Wiki main page for online (CloudMade and MapQuest) and offline (Graphhopper) route samples.

Map Listeners

Old SDK had several listeners: OnMapElementListener, MapListener, PlaceListener etc. New SDK has it combined to single MapListener, which has similar methods like elementClicked (instead of onVectorElementClicked), onLabelClicked, also onMapMoved etc. See https://github.com/nutiteq/hellomap3d/wiki/Listen-and-handle-map-events for basic sample.

Clone this wiki locally