Использование пользовательских листов карты с Google Map API V2 для Android.

10

Я ищу способ использования пользовательских листов карты с Google Map API V2 для Android.

Я пишу приложение, которое будет создавать свои собственные карты в режиме реального времени с данными, поступающими от робота.

В приложении необходимо показать оператору эту карту. Оператору необходимо взаимодействовать с этой картой, указывать путевые точки и т. Д.

Я хочу использовать движок GoogleMap, чтобы сделать то же самое, что эта страница:

http://cdn.mikecouturier.com/blog.mikecouturier.com/tilesgenerator/index.html

Проблема в том, что он использовал Javascript API, когда я хочу использовать Android API

Есть ли способ использовать пользовательскую карту тайлов на андроиде с Google Maps Engine?

Я уже смотрю на то, как использовать ArcGIS, но я предпочитаю использовать API без оплаты лицензии.

MonkeyJLuffy
источник

Ответы:

8

Да, вы можете использовать пользовательские плитки с 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 / изображения должны быть общедоступными для мобильного устройства (т. Е. Не могут быть защищены паролем).

Шон Барбо
источник
Спасибо за ваше время. Можно ли использовать полностью созданные мной изображения в личном репозитории? Каков формат этой плитки? И древовидность?
MonkeyJLuffy
@MonkeyJLuffy Я только добавил немного информации в конец моего ответа для этого. Пожалуйста, дайте мне знать, если у вас остались вопросы после прочтения.
Шон Барбо,
1

Самое обширное решение, которое я нашел, находится в этом ответе StackOverflow :

В основном вам нужно реализовать свой собственный TileProvider и использовать его как TileOverlay

В нескольких приложениях мы использовали этот вид слоя для отображения плиток на карте, но мы обнаружили, что плитки занимают много места. Поэтому мы перешли на использование mbtiles и этой библиотеки для отображения данных с mbtiles на карте.

Девдатта Тенгше
источник