Search code examples
androidarcgisosmdroidesri

OSMDroid app using custom ARCGis tile server - tiles are shuffled


I am developing an android mapping app using OSMDroid. I am attempting to use free custom aerial imagery, completely independent of google and/or bing api's. Please, do not propose ANY solution that uses their mapping api's.

I have managed to display satellite imagery by including this code:

mapView.setTileSource(TileSourceFactory.MAPQUESTAERIAL);

BUT, tile server does not offer tiling above 11 zoom and i need to get wee closer than that (say 15-16?).

Using ARCGis tile server, I manage to display satellite imagery even to 16 layer zoom level, but tiles are shuffled around.

mapControl = (MapController) mapView.getController();
mapControl.setZoom(11);
String[] urlArray = {"http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/"};
mapView.setTileSource(new XYTileSource("ArcGisOnline", null, 0, 18, 256, ".png",urlArray ));

Basemap tiles are shuffled and do not correspond to lat/lon, but overlay is ok.

Basemap tiles are shuffled


Solution

  • The tile server probably uses a different scheme for retrieving tiles. Try flipping the X and Y coordinates. Slippy map servers (osm) use the Z/X/Y.ext format. ArgGis and several others use Z/Y/X.ext format. All other coordinates are the same. This means the solution is simple, override the getTileURLString method and supply the coordinates in whatever format the server wants.

    Osmdroid has an example for doing exactly this.

    https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/samplefragments/SampleCustomTileSource.java

    The relevant bit a code this

    mMapView.setTileSource(new OnlineTileSourceBase("USGS Topo", 0, 18, 256, "", 
               new String[] { "http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSTopo/MapServer/tile/" }) {
               @Override
               public String getTileURLString(MapTile aTile) {
                    return getBaseUrl() + aTile.getZoomLevel() + "/" + aTile.getY() + "/" + aTile.getX()
                + mImageFilenameEnding;
               }
          });
    

    You'll also want to purge the cache after this change since it has the wrong coordinates