Verwenden von benutzerdefinierten Kartenkacheln mit Google Map API V2 für Android.

10

Ich suche nach einer Möglichkeit, benutzerdefinierte Kartenkacheln mit der Google Map API V2 für Android zu verwenden.

Ich schreibe eine Anwendung, die ihre eigenen Karten in Echtzeit mit Daten erstellt, die von einem Roboter kommen.

Die Anwendung muss dem Bediener diese Karte anzeigen. Der Bediener muss mit dieser Karte interagieren und Wegpunkte usw. zulassen.

Ich möchte die GoogleMap-Engine verwenden, um dasselbe wie auf dieser Seite zu tun:

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

Das Problem ist, dass er die Javascript-API verwendet hat, wenn ich die Android-API verwenden möchte

Gibt es eine Möglichkeit, die benutzerdefinierte Kachelkarte auf Android mit der Google Maps Engine zu verwenden?

Ich sehe mir bereits die Verwendung von ArcGIS an, bevorzuge jedoch die Verwendung einer API, ohne eine Lizenz zu bezahlen.

MonkeyJLuffy
quelle

Antworten:

8

Ja, Sie können benutzerdefinierte Kacheln mit der Android Maps API v2 verwenden. Ein voll funktionsfähiges Beispiel finden Sie in unserer OpenTripPlanner für Android-App auf Github . (Sie können die App auch direkt von Google Play herunterladen. )

Wir unterstützen folgende Fliesenanbieter:

  • LyrkOpenStreetMap
  • MapQuestOpenStreetMap
  • Mapnik
  • CycleMap
  • Google (normal, Satellit, Hybrid, Gelände)

Unsere CustomUrlTileProvider-Klasse ist hier auf Github zu sehen , und ich habe sie auch unten eingefügt:

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;
    }
}

Und hier ist der Code , der je nach Benutzerpräferenz zwischen Kartenkachelanbietern wechselt:

/**
 * 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));
        }
    }
}

Hier ist ein Screenshot der MapQuest OpenStreetMap-Kacheln: Geben Sie hier die Bildbeschreibung ein

Weitere Informationen zum Erstellen eigener Kacheln finden Sie in der Google-Dokumentation für TileOverlay sowie im OpenStreetMap-Wiki zum Erstellen eigener Kacheln .

In der Google-Dokumentation heißt es insbesondere:

Beachten Sie, dass die Welt mithilfe der Mercator-Projektion (siehe Wikipedia) projiziert wird, wobei die linke (West-) Seite der Karte -180 Längengraden und die rechte (Ost-) Seite der Karte 180 Längengraden entspricht. Um die Karte quadratisch zu machen, entspricht die obere (Nord-) Seite der Karte 85,0511 Breitengraden und die untere (Süd-) Seite der Karte -85,0511 Breitengraden. Bereiche außerhalb dieses Breitengrads werden nicht gerendert.

Bei jeder Zoomstufe wird die Karte in Kacheln unterteilt und nur die Kacheln, die den Bildschirm überlappen, werden heruntergeladen und gerendert. Jede Kachel ist quadratisch und die Karte ist wie folgt in Kacheln unterteilt:

  • Bei Zoomstufe 0 repräsentiert eine Kachel die ganze Welt. Die Koordinaten dieser Kachel sind (x, y) = (0, 0).

  • Bei Zoomstufe 1 ist die Welt in 4 Kacheln unterteilt, die in einem 2 x 2-Raster angeordnet sind. ...

  • Bei Zoomstufe N ist die Welt in 4N-Kacheln unterteilt, die in einem 2N x 2N-Raster angeordnet sind.

Beachten Sie, dass die von der Kamera unterstützte minimale Zoomstufe (die von verschiedenen Faktoren abhängen kann) GoogleMap.getMinZoomLevel und die maximale Zoomstufe GoogleMap.getMaxZoomLevel ist.

Die Koordinaten der Kacheln werden in der oberen linken (nordwestlichen) Ecke der Karte gemessen. Bei der Zoomstufe N reichen die x-Werte der Kachelkoordinaten von 0 bis 2N - 1 und nehmen von West nach Ost zu, und die y-Werte reichen von 0 bis 2N - 1 und nehmen von Nord nach Süd zu.

Die formatierten URLs, die in OTP Android verwendet werden, um auf jeden Kachelanbieter zu verweisen, sehen folgendermaßen aus:

Für die oben genannten Anbieter sind die Kachelbilder PNG-Dateien, die in der in der Google-Dokumentation angegebenen Verzeichnisstruktur angeordnet sind. Sie würden einem ähnlichen Format folgen, um Ihre eigenen Kartenkacheln zu erstellen, die auf Ihrem eigenen Server gehostet werden. Beachten Sie, dass diese URLs / Bilder für das mobile Gerät öffentlich zugänglich sein müssen (dh nicht kennwortgeschützt sein können).

Sean Barbeau
quelle
Vielen Dank für Ihre Zeit. Ist es möglich, von mir vollständig erstellte Bilder in einem persönlichen Repository zu verwenden? Was ist das Format dieser Kachel? Und die Arboreszenz?
MonkeyJLuffy
@MonkeyJLuffy Ich habe gerade einige Informationen am Ende meiner Antwort hinzugefügt. Bitte lassen Sie mich wissen, wenn Sie nach dem Lesen noch Fragen haben.
Sean Barbeau
0

Die umfangreichste Lösung, die ich gefunden habe, ist in dieser StackOverflow- Antwort :

Grundsätzlich müssen Sie Ihren eigenen TileProvider implementieren und diesen als TileOverlay verwenden

In einigen Anwendungen haben wir diese Art von Ebene verwendet, um Kacheln auf der Karte anzuzeigen, aber wir haben festgestellt, dass die Kacheln viel Platz beanspruchen. Daher haben wir uns der Verwendung von mbtiles und dieser Bibliothek zugewandt , um die Daten von mbtiles auf der Karte anzuzeigen.

Devdatta Tengshe
quelle