Sim, você pode usar blocos personalizados com a API do Android Maps v2 - você pode ver um exemplo completo no nosso aplicativo OpenTripPlanner para Android no Github . (Você também pode baixar o aplicativo diretamente do Google Play )
Apoiamos os seguintes fornecedores de bloco:
- LyrkOpenStreetMap
- MapQuestOpenStreetMap
- Mapnik
- CycleMap
- Google (normal, satélite, híbrido, terreno)
Nossa classe CustomUrlTileProvider pode ser vista aqui no Github , e eu também a colei abaixo:
public class CustomUrlTileProvider extends UrlTileProvider {
private String baseUrl;
public CustomUrlTileProvider(int width, int height, String url) {
super(width, height);
this.baseUrl = url;
}
@Override
public URL getTileUrl(int x, int y, int zoom) {
try {
return new URL(baseUrl.replace("{z}", "" + zoom).replace("{x}", "" + x)
.replace("{y}", "" + y));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
E aqui está o código que alterna entre os provedores de bloco de mapa, com base na preferência do usuário:
/**
* Changes the tiles used to display the map and sets max zoom level.
*
* @param overlayString tiles URL for custom tiles or description for
* Google ones
*/
public void updateOverlay(String overlayString) {
int tile_width = OTPApp.CUSTOM_MAP_TILE_SMALL_WIDTH;
int tile_height = OTPApp.CUSTOM_MAP_TILE_SMALL_HEIGHT;
if (overlayString == null) {
overlayString = mPrefs.getString(OTPApp.PREFERENCE_KEY_MAP_TILE_SOURCE,
mApplicationContext.getResources()
.getString(R.string.map_tiles_default_server));
}
if (mSelectedTileOverlay != null) {
mSelectedTileOverlay.remove();
}
if (overlayString.startsWith(OTPApp.MAP_TILE_GOOGLE)) {
int mapType = GoogleMap.MAP_TYPE_NORMAL;
if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_HYBRID)) {
mapType = GoogleMap.MAP_TYPE_HYBRID;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_NORMAL)) {
mapType = GoogleMap.MAP_TYPE_NORMAL;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_TERRAIN)) {
mapType = GoogleMap.MAP_TYPE_TERRAIN;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_SATELLITE)) {
mapType = GoogleMap.MAP_TYPE_SATELLITE;
}
mMap.setMapType(mapType);
mMaxZoomLevel = mMap.getMaxZoomLevel();
} else {
if (overlayString.equals(getResources().getString(R.string.tiles_mapnik))) {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_mapnik_max_zoom);
} else if (overlayString.equals(getResources().getString(R.string.tiles_lyrk))) {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_lyrk_max_zoom);
tile_width = OTPApp.CUSTOM_MAP_TILE_BIG_WIDTH;
tile_height = OTPApp.CUSTOM_MAP_TILE_BIG_HEIGHT;
} else {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_maquest_max_zoom);
}
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
CustomUrlTileProvider mTileProvider = new CustomUrlTileProvider(
tile_width,
tile_height, overlayString);
mSelectedTileOverlay = mMap.addTileOverlay(
new TileOverlayOptions().tileProvider(mTileProvider)
.zIndex(OTPApp.CUSTOM_MAP_TILE_Z_INDEX));
if (mMap.getCameraPosition().zoom > mMaxZoomLevel) {
mMap.moveCamera(CameraUpdateFactory.zoomTo(mMaxZoomLevel));
}
}
}
Aqui está uma captura de tela dos blocos do MapQuest OpenStreetMap:
Para obter mais informações sobre como criar seus próprios blocos, consulte a documentação do Google para TileOverlay , bem como o wiki do OpenStreetMap para "Criando seus próprios blocos" .
Especificamente, a documentação do Google diz:
Observe que o mundo é projetado usando a projeção Mercator (consulte a Wikipedia) com o lado esquerdo (oeste) do mapa correspondente a -180 graus de longitude e o lado direito (leste) do mapa correspondente a 180 graus de longitude. Para tornar o mapa quadrado, o lado superior (norte) do mapa corresponde a 85,0511 graus de latitude e o lado inferior (sul) do mapa corresponde a -85,0511 graus de latitude. Áreas fora desse intervalo de latitude não são renderizadas.
Em cada nível de zoom, o mapa é dividido em blocos e apenas os blocos que se sobrepõem à tela são baixados e renderizados. Cada bloco é quadrado e o mapa é dividido em blocos da seguinte maneira:
No nível de zoom 0, um bloco representa o mundo inteiro. As coordenadas desse bloco são (x, y) = (0, 0).
No nível 1 de zoom, o mundo é dividido em 4 blocos dispostos em uma grade 2 x 2. ...
- No nível de zoom N, o mundo é dividido em blocos 4N dispostos em uma grade 2N x 2N.
Observe que o nível mínimo de zoom suportado pela câmera (que pode depender de vários fatores) é GoogleMap.getMinZoomLevel e o nível máximo de zoom é GoogleMap.getMaxZoomLevel.
As coordenadas dos blocos são medidas no canto superior esquerdo (noroeste) do mapa. No nível de zoom N, os valores x das coordenadas do bloco variam de 0 a 2N - 1 e aumentam de oeste para leste e os valores y variam de 0 a 2N - 1 e aumentam de norte a sul.
Os URLs formatados usados no OTP Android para referenciar cada provedor de bloco são semelhantes a:
Portanto, para os provedores acima, as imagens de bloco são arquivos PNG organizados na estrutura de diretórios indicada pela documentação do Google. Você seguiria um formato semelhante para criar seus próprios blocos de mapa hospedados em seu próprio servidor. Observe que esses URLs / imagens devem estar acessíveis ao público para o dispositivo móvel (ou seja, não podem ser protegidos por senha).
A solução mais extensa que encontrei está nesta resposta do StackOverflow :
Basicamente, você precisa implementar seu próprio TileProvider e usá-lo como um TileOverlay
Em algumas aplicações, usamos esse tipo de camada para mostrar blocos no mapa, mas descobrimos que os blocos ocupavam muito espaço. Por isso, passamos a usar mbtiles e esta biblioteca para exibir os dados de mbtiles no mapa.
fonte