Да, вы можете использовать пользовательские плитки с Android Maps API v2 - вы можете увидеть полностью рабочий пример в нашем приложении OpenTripPlanner для Android на Github . (Вы также можете скачать приложение прямо из Google Play )
Мы поддерживаем следующих поставщиков плитки:
- LyrkOpenStreetMap
- MapQuestOpenStreetMap
- Mapnik
- CycleMap
- Google (обычный, спутниковый, гибридный, рельефный)
Наш класс CustomUrlTileProvider можно увидеть здесь, на Github , и я также вставил его ниже:
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;
}
}
А вот код, который переключается между поставщиками листов карты в зависимости от предпочтений пользователя:
/**
* 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));
}
}
}
Вот скриншот плиток MapQuest OpenStreetMap:
Для получения дополнительной информации о создании собственных плиток см. Документацию Google для TileOverlay, а также вики OpenStreetMap для «Создание собственных плиток» .
В частности, документация Google гласит:
Обратите внимание, что мир проецируется с использованием проекции Меркатора (см. Википедия) с левой (западной) стороной карты, соответствующей -180 градусам долготы, и правой (восточной) стороной карты, соответствующей 180 градусам долготы. Чтобы сделать карту квадратной, верхняя (северная) сторона карты соответствует 85.0511 градусам широты, а нижняя (южная) сторона карты соответствует -85.0511 градусам широты. Области за пределами этого диапазона широты не отображаются.
На каждом уровне масштабирования карта делится на фрагменты, и только фрагменты, которые перекрывают экран, загружаются и отображаются. Каждая плитка имеет квадратную форму, а карта разделена на плитки следующим образом:
На уровне масштабирования 0 одна плитка представляет весь мир. Координаты этой плитки: (x, y) = (0, 0).
На уровне масштабирования 1 мир делится на 4 плитки, расположенных в сетке 2 x 2. ...
- На уровне масштабирования N мир делится на 4N тайлов, расположенных в сетке 2N x 2N.
Обратите внимание, что минимальный уровень масштабирования, поддерживаемый камерой (который может зависеть от различных факторов), равен GoogleMap.getMinZoomLevel, а максимальный уровень масштабирования - GoogleMap.getMaxZoomLevel.
Координаты плиток измеряются от верхнего левого (северо-западного) угла карты. На уровне масштабирования N значения x координат элемента мозаичного изображения варьируются от 0 до 2N - 1 и увеличиваются с запада на восток, а значения y - от 0 до 2N - 1 и увеличиваются с севера на юг.
Отформатированные URL-адреса, которые используются в OTP Android для ссылки на каждого поставщика листов, выглядят следующим образом:
Таким образом, для вышеперечисленных поставщиков мозаичные изображения являются файлами PNG, расположенными в структуре каталогов, указанной в документации Google. Вы должны следовать аналогичному формату для создания собственных плиток карты, размещенных на вашем собственном сервере. Обратите внимание, что эти URL / изображения должны быть общедоступными для мобильного устройства (т. Е. Не могут быть защищены паролем).
Самое обширное решение, которое я нашел, находится в этом ответе StackOverflow :
В основном вам нужно реализовать свой собственный TileProvider и использовать его как TileOverlay
В нескольких приложениях мы использовали этот вид слоя для отображения плиток на карте, но мы обнаружили, что плитки занимают много места. Поэтому мы перешли на использование mbtiles и этой библиотеки для отображения данных с mbtiles на карте.
источник