<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.stephanschlegel.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=79.240.31.241</id>
	<title>Wikizone - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.stephanschlegel.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=79.240.31.241"/>
	<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Spezial:Beitr%C3%A4ge/79.240.31.241"/>
	<updated>2026-05-06T20:00:05Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Android_Maps_Cache_-_TileProvider_mit_lokalen_Kacheln_(_local_tiles_)&amp;diff=20093</id>
		<title>Android Maps Cache - TileProvider mit lokalen Kacheln ( local tiles )</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Android_Maps_Cache_-_TileProvider_mit_lokalen_Kacheln_(_local_tiles_)&amp;diff=20093"/>
		<updated>2013-11-07T06:37:49Z</updated>

		<summary type="html">&lt;p&gt;79.240.31.241: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;Custom Tiles mit TileProvider&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/14784841/tileprovider-using-local-tiles (2013-11)&lt;br /&gt;
&lt;br /&gt;
Frage:&lt;br /&gt;
&lt;br /&gt;
I would like to use the &amp;#039;&amp;#039;&amp;#039;new TileProvider&amp;#039;&amp;#039;&amp;#039; functionality of the latest &amp;#039;&amp;#039;&amp;#039;Android Maps API (v2)&amp;#039;&amp;#039;&amp;#039; to overlay some &amp;#039;&amp;#039;&amp;#039;custom tiles&amp;#039;&amp;#039;&amp;#039; on the GoogleMap. However as my users will not have internet a lot of the time, I want to keep the &amp;#039;&amp;#039;&amp;#039;tiles stored&amp;#039;&amp;#039;&amp;#039; in a zipfile/folder structure on the device. I will be generating my tiles using Maptiler with geotiffs. My questions are:&lt;br /&gt;
&lt;br /&gt;
What would be the best way to store the tiles on the device?&lt;br /&gt;
How would I go about creating a TileProvider that returns local tiles?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# You can put tiles into assets folder (if it is acceptable for the app size) or download them all on first start and put them into device storage (SD card).&lt;br /&gt;
# You can implement TileProvider like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public class CustomMapTileProvider implements TileProvider {&lt;br /&gt;
    private static final int TILE_WIDTH = 256;&lt;br /&gt;
    private static final int TILE_HEIGHT = 256;&lt;br /&gt;
    private static final int BUFFER_SIZE = 16 * 1024;&lt;br /&gt;
&lt;br /&gt;
    private AssetManager mAssets;&lt;br /&gt;
&lt;br /&gt;
    public CustomMapTileProvider(AssetManager assets) {&lt;br /&gt;
        mAssets = assets;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
        byte[] image = readTileImage(x, y, zoom);&lt;br /&gt;
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private byte[] readTileImage(int x, int y, int zoom) {&lt;br /&gt;
        InputStream in = null;&lt;br /&gt;
        ByteArrayOutputStream buffer = null;&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            in = mAssets.open(getTileFilename(x, y, zoom));&lt;br /&gt;
            buffer = new ByteArrayOutputStream();&lt;br /&gt;
&lt;br /&gt;
            int nRead;&lt;br /&gt;
            byte[] data = new byte[BUFFER_SIZE];&lt;br /&gt;
&lt;br /&gt;
            while ((nRead = in.read(data, 0, BUFFER_SIZE)) != -1) {&lt;br /&gt;
                buffer.write(data, 0, nRead);&lt;br /&gt;
            }&lt;br /&gt;
            buffer.flush();&lt;br /&gt;
&lt;br /&gt;
            return buffer.toByteArray();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
            return null;&lt;br /&gt;
        } catch (OutOfMemoryError e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
            return null;&lt;br /&gt;
        } finally {&lt;br /&gt;
            if (in != null) try { in.close(); } catch (Exception ignored) {}&lt;br /&gt;
            if (buffer != null) try { buffer.close(); } catch (Exception ignored) {}&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private String getTileFilename(int x, int y, int zoom) {&lt;br /&gt;
        return &amp;quot;map/&amp;quot; + zoom + &amp;#039;/&amp;#039; + x + &amp;#039;/&amp;#039; + y + &amp;quot;.png&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And now you can use it with your GoogleMap instance:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private void setUpMap() {&lt;br /&gt;
    mMap.setMapType(GoogleMap.MAP_TYPE_NONE);&lt;br /&gt;
&lt;br /&gt;
    mMap.addTileOverlay(new TileOverlayOptions().tileProvider(new CustomMapTileProvider(getResources().getAssets())));&lt;br /&gt;
&lt;br /&gt;
    CameraUpdate upd = CameraUpdateFactory.newLatLngZoom(new LatLng(LAT, LON), ZOOM);&lt;br /&gt;
    mMap.moveCamera(upd);&lt;br /&gt;
}&lt;br /&gt;
In my case I also had a problem with y coordinate of tiles generated by MapTiler, but I managed it by adding this method into CustomMapTileProvider:&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Fixing tile&amp;#039;s y index (reversing order)&lt;br /&gt;
 */&lt;br /&gt;
private int fixYCoordinate(int y, int zoom) {&lt;br /&gt;
    int size = 1 &amp;lt;&amp;lt; zoom; // size = 2^zoom&lt;br /&gt;
    return size - 1 - y;&lt;br /&gt;
}&lt;br /&gt;
and callig it from getTile() method like this:&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
    y = fixYCoordinate(y, zoom);&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[Update]&lt;br /&gt;
&lt;br /&gt;
If you know exac area of your custom map, you should return NO_TILE for missing tiles from getTile(...) method.&lt;br /&gt;
&lt;br /&gt;
This is how I did it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private static final SparseArray&amp;lt;Rect&amp;gt; TILE_ZOOMS = new SparseArray&amp;lt;Rect&amp;gt;() {{&lt;br /&gt;
    put(8,  new Rect(135,  180,  135,  181 ));&lt;br /&gt;
    put(9,  new Rect(270,  361,  271,  363 ));&lt;br /&gt;
    put(10, new Rect(541,  723,  543,  726 ));&lt;br /&gt;
    put(11, new Rect(1082, 1447, 1086, 1452));&lt;br /&gt;
    put(12, new Rect(2165, 2894, 2172, 2905));&lt;br /&gt;
    put(13, new Rect(4330, 5789, 4345, 5810));&lt;br /&gt;
    put(14, new Rect(8661, 11578, 8691, 11621));&lt;br /&gt;
}};&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
    y = fixYCoordinate(y, zoom);&lt;br /&gt;
&lt;br /&gt;
    if (hasTile(x, y, zoom)) {&lt;br /&gt;
        byte[] image = readTileImage(x, y, zoom);&lt;br /&gt;
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);&lt;br /&gt;
    } else {&lt;br /&gt;
        return NO_TILE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private boolean hasTile(int x, int y, int zoom) {&lt;br /&gt;
    Rect b = TILE_ZOOMS.get(zoom);&lt;br /&gt;
    return b == null ? false : (b.left &amp;lt;= x &amp;amp;&amp;amp; x &amp;lt;= b.right &amp;amp;&amp;amp; b.top &amp;lt;= y &amp;amp;&amp;amp; y &amp;lt;= b.bottom);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>79.240.31.241</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Android_Maps_Cache_-_TileProvider_mit_lokalen_Kacheln_(_local_tiles_)&amp;diff=20092</id>
		<title>Android Maps Cache - TileProvider mit lokalen Kacheln ( local tiles )</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Android_Maps_Cache_-_TileProvider_mit_lokalen_Kacheln_(_local_tiles_)&amp;diff=20092"/>
		<updated>2013-11-07T06:36:55Z</updated>

		<summary type="html">&lt;p&gt;79.240.31.241: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Betrifft Google Maps API v2 &lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/14784841/tileprovider-using-local-tiles (2013-11)&lt;br /&gt;
&lt;br /&gt;
Frage:&lt;br /&gt;
&lt;br /&gt;
I would like to use the &amp;#039;&amp;#039;&amp;#039;new TileProvider&amp;#039;&amp;#039;&amp;#039; functionality of the latest &amp;#039;&amp;#039;&amp;#039;Android Maps API (v2)&amp;#039;&amp;#039;&amp;#039; to overlay some &amp;#039;&amp;#039;&amp;#039;custom tiles&amp;#039;&amp;#039;&amp;#039; on the GoogleMap. However as my users will not have internet a lot of the time, I want to keep the &amp;#039;&amp;#039;&amp;#039;tiles stored&amp;#039;&amp;#039;&amp;#039; in a zipfile/folder structure on the device. I will be generating my tiles using Maptiler with geotiffs. My questions are:&lt;br /&gt;
&lt;br /&gt;
What would be the best way to store the tiles on the device?&lt;br /&gt;
How would I go about creating a TileProvider that returns local tiles?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# You can put tiles into assets folder (if it is acceptable for the app size) or download them all on first start and put them into device storage (SD card).&lt;br /&gt;
# You can implement TileProvider like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public class CustomMapTileProvider implements TileProvider {&lt;br /&gt;
    private static final int TILE_WIDTH = 256;&lt;br /&gt;
    private static final int TILE_HEIGHT = 256;&lt;br /&gt;
    private static final int BUFFER_SIZE = 16 * 1024;&lt;br /&gt;
&lt;br /&gt;
    private AssetManager mAssets;&lt;br /&gt;
&lt;br /&gt;
    public CustomMapTileProvider(AssetManager assets) {&lt;br /&gt;
        mAssets = assets;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
        byte[] image = readTileImage(x, y, zoom);&lt;br /&gt;
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private byte[] readTileImage(int x, int y, int zoom) {&lt;br /&gt;
        InputStream in = null;&lt;br /&gt;
        ByteArrayOutputStream buffer = null;&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            in = mAssets.open(getTileFilename(x, y, zoom));&lt;br /&gt;
            buffer = new ByteArrayOutputStream();&lt;br /&gt;
&lt;br /&gt;
            int nRead;&lt;br /&gt;
            byte[] data = new byte[BUFFER_SIZE];&lt;br /&gt;
&lt;br /&gt;
            while ((nRead = in.read(data, 0, BUFFER_SIZE)) != -1) {&lt;br /&gt;
                buffer.write(data, 0, nRead);&lt;br /&gt;
            }&lt;br /&gt;
            buffer.flush();&lt;br /&gt;
&lt;br /&gt;
            return buffer.toByteArray();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
            return null;&lt;br /&gt;
        } catch (OutOfMemoryError e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
            return null;&lt;br /&gt;
        } finally {&lt;br /&gt;
            if (in != null) try { in.close(); } catch (Exception ignored) {}&lt;br /&gt;
            if (buffer != null) try { buffer.close(); } catch (Exception ignored) {}&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private String getTileFilename(int x, int y, int zoom) {&lt;br /&gt;
        return &amp;quot;map/&amp;quot; + zoom + &amp;#039;/&amp;#039; + x + &amp;#039;/&amp;#039; + y + &amp;quot;.png&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And now you can use it with your GoogleMap instance:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private void setUpMap() {&lt;br /&gt;
    mMap.setMapType(GoogleMap.MAP_TYPE_NONE);&lt;br /&gt;
&lt;br /&gt;
    mMap.addTileOverlay(new TileOverlayOptions().tileProvider(new CustomMapTileProvider(getResources().getAssets())));&lt;br /&gt;
&lt;br /&gt;
    CameraUpdate upd = CameraUpdateFactory.newLatLngZoom(new LatLng(LAT, LON), ZOOM);&lt;br /&gt;
    mMap.moveCamera(upd);&lt;br /&gt;
}&lt;br /&gt;
In my case I also had a problem with y coordinate of tiles generated by MapTiler, but I managed it by adding this method into CustomMapTileProvider:&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Fixing tile&amp;#039;s y index (reversing order)&lt;br /&gt;
 */&lt;br /&gt;
private int fixYCoordinate(int y, int zoom) {&lt;br /&gt;
    int size = 1 &amp;lt;&amp;lt; zoom; // size = 2^zoom&lt;br /&gt;
    return size - 1 - y;&lt;br /&gt;
}&lt;br /&gt;
and callig it from getTile() method like this:&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
    y = fixYCoordinate(y, zoom);&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[Update]&lt;br /&gt;
&lt;br /&gt;
If you know exac area of your custom map, you should return NO_TILE for missing tiles from getTile(...) method.&lt;br /&gt;
&lt;br /&gt;
This is how I did it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private static final SparseArray&amp;lt;Rect&amp;gt; TILE_ZOOMS = new SparseArray&amp;lt;Rect&amp;gt;() {{&lt;br /&gt;
    put(8,  new Rect(135,  180,  135,  181 ));&lt;br /&gt;
    put(9,  new Rect(270,  361,  271,  363 ));&lt;br /&gt;
    put(10, new Rect(541,  723,  543,  726 ));&lt;br /&gt;
    put(11, new Rect(1082, 1447, 1086, 1452));&lt;br /&gt;
    put(12, new Rect(2165, 2894, 2172, 2905));&lt;br /&gt;
    put(13, new Rect(4330, 5789, 4345, 5810));&lt;br /&gt;
    put(14, new Rect(8661, 11578, 8691, 11621));&lt;br /&gt;
}};&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
    y = fixYCoordinate(y, zoom);&lt;br /&gt;
&lt;br /&gt;
    if (hasTile(x, y, zoom)) {&lt;br /&gt;
        byte[] image = readTileImage(x, y, zoom);&lt;br /&gt;
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);&lt;br /&gt;
    } else {&lt;br /&gt;
        return NO_TILE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private boolean hasTile(int x, int y, int zoom) {&lt;br /&gt;
    Rect b = TILE_ZOOMS.get(zoom);&lt;br /&gt;
    return b == null ? false : (b.left &amp;lt;= x &amp;amp;&amp;amp; x &amp;lt;= b.right &amp;amp;&amp;amp; b.top &amp;lt;= y &amp;amp;&amp;amp; y &amp;lt;= b.bottom);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>79.240.31.241</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Android_Maps_Cache_-_TileProvider_mit_lokalen_Kacheln_(_local_tiles_)&amp;diff=20091</id>
		<title>Android Maps Cache - TileProvider mit lokalen Kacheln ( local tiles )</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Android_Maps_Cache_-_TileProvider_mit_lokalen_Kacheln_(_local_tiles_)&amp;diff=20091"/>
		<updated>2013-11-07T06:34:19Z</updated>

		<summary type="html">&lt;p&gt;79.240.31.241: Die Seite wurde neu angelegt: „Betrifft Google Maps API v2   http://stackoverflow.com/questions/14784841/tileprovider-using-local-tiles (2013-11)  # You can put tiles into assets folder (if it …“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Betrifft Google Maps API v2 &lt;br /&gt;
&lt;br /&gt;
http://stackoverflow.com/questions/14784841/tileprovider-using-local-tiles (2013-11)&lt;br /&gt;
&lt;br /&gt;
# You can put tiles into assets folder (if it is acceptable for the app size) or download them all on first start and put them into device storage (SD card).&lt;br /&gt;
# You can implement TileProvider like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public class CustomMapTileProvider implements TileProvider {&lt;br /&gt;
    private static final int TILE_WIDTH = 256;&lt;br /&gt;
    private static final int TILE_HEIGHT = 256;&lt;br /&gt;
    private static final int BUFFER_SIZE = 16 * 1024;&lt;br /&gt;
&lt;br /&gt;
    private AssetManager mAssets;&lt;br /&gt;
&lt;br /&gt;
    public CustomMapTileProvider(AssetManager assets) {&lt;br /&gt;
        mAssets = assets;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
        byte[] image = readTileImage(x, y, zoom);&lt;br /&gt;
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private byte[] readTileImage(int x, int y, int zoom) {&lt;br /&gt;
        InputStream in = null;&lt;br /&gt;
        ByteArrayOutputStream buffer = null;&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            in = mAssets.open(getTileFilename(x, y, zoom));&lt;br /&gt;
            buffer = new ByteArrayOutputStream();&lt;br /&gt;
&lt;br /&gt;
            int nRead;&lt;br /&gt;
            byte[] data = new byte[BUFFER_SIZE];&lt;br /&gt;
&lt;br /&gt;
            while ((nRead = in.read(data, 0, BUFFER_SIZE)) != -1) {&lt;br /&gt;
                buffer.write(data, 0, nRead);&lt;br /&gt;
            }&lt;br /&gt;
            buffer.flush();&lt;br /&gt;
&lt;br /&gt;
            return buffer.toByteArray();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
            return null;&lt;br /&gt;
        } catch (OutOfMemoryError e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
            return null;&lt;br /&gt;
        } finally {&lt;br /&gt;
            if (in != null) try { in.close(); } catch (Exception ignored) {}&lt;br /&gt;
            if (buffer != null) try { buffer.close(); } catch (Exception ignored) {}&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private String getTileFilename(int x, int y, int zoom) {&lt;br /&gt;
        return &amp;quot;map/&amp;quot; + zoom + &amp;#039;/&amp;#039; + x + &amp;#039;/&amp;#039; + y + &amp;quot;.png&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And now you can use it with your GoogleMap instance:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private void setUpMap() {&lt;br /&gt;
    mMap.setMapType(GoogleMap.MAP_TYPE_NONE);&lt;br /&gt;
&lt;br /&gt;
    mMap.addTileOverlay(new TileOverlayOptions().tileProvider(new CustomMapTileProvider(getResources().getAssets())));&lt;br /&gt;
&lt;br /&gt;
    CameraUpdate upd = CameraUpdateFactory.newLatLngZoom(new LatLng(LAT, LON), ZOOM);&lt;br /&gt;
    mMap.moveCamera(upd);&lt;br /&gt;
}&lt;br /&gt;
In my case I also had a problem with y coordinate of tiles generated by MapTiler, but I managed it by adding this method into CustomMapTileProvider:&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Fixing tile&amp;#039;s y index (reversing order)&lt;br /&gt;
 */&lt;br /&gt;
private int fixYCoordinate(int y, int zoom) {&lt;br /&gt;
    int size = 1 &amp;lt;&amp;lt; zoom; // size = 2^zoom&lt;br /&gt;
    return size - 1 - y;&lt;br /&gt;
}&lt;br /&gt;
and callig it from getTile() method like this:&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
    y = fixYCoordinate(y, zoom);&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[Update]&lt;br /&gt;
&lt;br /&gt;
If you know exac area of your custom map, you should return NO_TILE for missing tiles from getTile(...) method.&lt;br /&gt;
&lt;br /&gt;
This is how I did it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
private static final SparseArray&amp;lt;Rect&amp;gt; TILE_ZOOMS = new SparseArray&amp;lt;Rect&amp;gt;() {{&lt;br /&gt;
    put(8,  new Rect(135,  180,  135,  181 ));&lt;br /&gt;
    put(9,  new Rect(270,  361,  271,  363 ));&lt;br /&gt;
    put(10, new Rect(541,  723,  543,  726 ));&lt;br /&gt;
    put(11, new Rect(1082, 1447, 1086, 1452));&lt;br /&gt;
    put(12, new Rect(2165, 2894, 2172, 2905));&lt;br /&gt;
    put(13, new Rect(4330, 5789, 4345, 5810));&lt;br /&gt;
    put(14, new Rect(8661, 11578, 8691, 11621));&lt;br /&gt;
}};&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public Tile getTile(int x, int y, int zoom) {&lt;br /&gt;
    y = fixYCoordinate(y, zoom);&lt;br /&gt;
&lt;br /&gt;
    if (hasTile(x, y, zoom)) {&lt;br /&gt;
        byte[] image = readTileImage(x, y, zoom);&lt;br /&gt;
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);&lt;br /&gt;
    } else {&lt;br /&gt;
        return NO_TILE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private boolean hasTile(int x, int y, int zoom) {&lt;br /&gt;
    Rect b = TILE_ZOOMS.get(zoom);&lt;br /&gt;
    return b == null ? false : (b.left &amp;lt;= x &amp;amp;&amp;amp; x &amp;lt;= b.right &amp;amp;&amp;amp; b.top &amp;lt;= y &amp;amp;&amp;amp; y &amp;lt;= b.bottom);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>79.240.31.241</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Android_Development_-_Maps&amp;diff=20090</id>
		<title>Android Development - Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Android_Development_-_Maps&amp;diff=20090"/>
		<updated>2013-11-07T06:31:57Z</updated>

		<summary type="html">&lt;p&gt;79.240.31.241: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Links ==&lt;br /&gt;
Javascript Connection to Webview&lt;br /&gt;
*https://github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb2/&lt;br /&gt;
&lt;br /&gt;
*http://android-coding.blogspot.de/2011/06/mapview-and-mapactivity.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Android Development - Google Maps]]&lt;br /&gt;
&lt;br /&gt;
[[Android Development - OpenStreetMaps]] -&amp;gt; osmdroid&lt;br /&gt;
&lt;br /&gt;
[[Android Maps Cache -  TileProvider mit lokalen Kacheln ( local tiles )]]&lt;/div&gt;</summary>
		<author><name>79.240.31.241</name></author>
	</entry>
	<entry>
		<id>https://wiki.stephanschlegel.de/index.php?title=Android_Development_-_Maps&amp;diff=20089</id>
		<title>Android Development - Maps</title>
		<link rel="alternate" type="text/html" href="https://wiki.stephanschlegel.de/index.php?title=Android_Development_-_Maps&amp;diff=20089"/>
		<updated>2013-11-07T06:29:56Z</updated>

		<summary type="html">&lt;p&gt;79.240.31.241: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Links ==&lt;br /&gt;
Javascript Connection to Webview&lt;br /&gt;
*https://github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb2/&lt;br /&gt;
&lt;br /&gt;
*http://android-coding.blogspot.de/2011/06/mapview-and-mapactivity.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Android Development - Google Maps]]&lt;br /&gt;
&lt;br /&gt;
[[Android Development - OpenStreetMaps]] -&amp;gt; osmdroid&lt;/div&gt;</summary>
		<author><name>79.240.31.241</name></author>
	</entry>
</feed>