Utilizzo di riquadri di mappe personalizzati con Google Map API V2 per Android.?


10

Sto cercando un modo per utilizzare i riquadri di mappe personalizzati con l'API V2 di Google Map per Android.

Sto scrivendo un'applicazione che creerà le proprie mappe in tempo reale con i dati che provengono da un robot.

L'applicazione deve mostrare all'operatore questa mappa. L'operatore deve interagire con questa mappa, lasciando punti intermedi, ecc.

Voglio utilizzare il motore GoogleMap per fare lo stesso che questa pagina:

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

Il problema è che ha usato l' API Javascript quando voglio usare l' API Android

Esiste un modo per utilizzare la mappa dei riquadri personalizzati su Android con Google Maps Engine?

Sto già cercando come utilizzare ArcGIS, ma preferisco usare un'API senza pagare una licenza.

Risposte:


8

Sì, puoi utilizzare i riquadri personalizzati con l' API Android Maps v2 : puoi vedere un esempio perfettamente funzionante nella nostra app OpenTripPlanner per Android su Github . (Puoi anche scaricare l'app direttamente da Google Play )

Supportiamo i seguenti fornitori di piastrelle:

  • LyrkOpenStreetMap
  • MapQuestOpenStreetMap
  • Mapnik
  • CycleMap
  • Google (normale, satellite, ibrido, terreno)

La nostra classe CustomUrlTileProvider può essere vista qui su Github e l'ho incollata di seguito:

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

Ed ecco il codice che cambia tra i provider di tessere mappa, in base alle preferenze dell'utente:

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

Ecco uno screenshot dei riquadri MapQuest OpenStreetMap: inserisci qui la descrizione dell'immagine

Per ulteriori informazioni sulla creazione di riquadri personalizzati, consultare la documentazione di Google per TileOverlay e il wiki OpenStreetMap per "Creazione di riquadri personalizzati" .

In particolare, la documentazione di Google dice:

Si noti che il mondo viene proiettato usando la proiezione di Mercatore (vedi Wikipedia) con il lato sinistro (ovest) della mappa corrispondente a -180 gradi di longitudine e il lato destro (est) della mappa corrispondente a 180 gradi di longitudine. Per rendere quadrata la mappa, il lato superiore (nord) della mappa corrisponde a 85,0511 gradi di latitudine e il lato inferiore (sud) della mappa corrisponde a -85,0511 gradi di latitudine. Le aree al di fuori di questo intervallo di latitudine non vengono visualizzate.

Ad ogni livello di zoom, la mappa è divisa in riquadri e solo le tessere che si sovrappongono allo schermo vengono scaricate e renderizzate. Ogni tessera è quadrata e la mappa è divisa in tessere come segue:

  • Al livello di zoom 0, una tessera rappresenta il mondo intero. Le coordinate di quella tessera sono (x, y) = (0, 0).

  • Al livello di zoom 1, il mondo è diviso in 4 tessere disposte in una griglia 2 x 2. ...

  • Al livello di zoom N, il mondo è diviso in riquadri 4N disposti in una griglia 2N x 2N.

Si noti che il livello di zoom minimo supportato dalla fotocamera (che può dipendere da vari fattori) è GoogleMap.getMinZoomLevel e il livello di zoom massimo è GoogleMap.getMaxZoomLevel.

Le coordinate delle tessere sono misurate dall'angolo in alto a sinistra (nord-ovest) della mappa. Al livello di zoom N, i valori x delle coordinate della piastrella vanno da 0 a 2N - 1 e aumentano da ovest a est e i valori y vanno da 0 a 2N - 1 e aumentano da nord a sud.

Gli URL formattati utilizzati in OTP Android per fare riferimento a ciascun provider di tessere sono simili:

Pertanto, per i provider sopra indicati le immagini dei riquadri sono file PNG disposti nella struttura di directory indicata dalla documentazione di Google. Seguiresti un formato simile per creare i tuoi riquadri di mappe ospitati sul tuo server. Tieni presente che questi URL / immagini devono essere accessibili pubblicamente al dispositivo mobile (ad esempio, non possono essere protetti da password).


Grazie per il tuo tempo È possibile utilizzare le immagini completamente create da me in un repository personale? Qual è il formato di quella tessera? E l'arborescenza?
MonkeyJLuffy,

@MonkeyJLuffy Ho appena aggiunto alcune informazioni in fondo alla mia risposta per questo. Per favore fatemi sapere se avete ancora domande dopo aver letto questo.
Sean Barbeau,

1

La soluzione più ampia che ho trovato è in questa risposta StackOverflow :

Fondamentalmente è necessario implementare il proprio TileProvider e utilizzarlo come TileOverlay

In un paio di applicazioni abbiamo usato questo tipo di strato per mostrare le tessere sulla mappa, ma abbiamo scoperto che le tessere occupavano molto spazio. Quindi siamo passati all'utilizzo di mbtiles e di questa libreria per visualizzare i dati di mbtiles sulla mappa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.