Vytvoření zdroje dat (Android SDK)

Sada Azure Mapy Android SDK ukládá data do zdrojů dat. Použití zdrojů dat optimalizuje operace s daty pro dotazování a vykreslování. V současné době existují dva typy zdrojů dat:

  • Zdroj GeoJSON: Spravuje nezpracovaná data o poloze v místním formátu GeoJSON. Vhodné pro malé až střední datové sady (nahoru ze stovek tisíc obrazců).
  • Zdroj vektorové dlaždice: Načte data formátovaná jako vektorové dlaždice pro aktuální zobrazení mapy na základě systému provazování map. Ideální pro velké až masivní datové sady (miliony nebo miliardy obrazců).

Poznámka:

Vyřazení sady Azure Mapy Android SDK

Sada Azure Mapy Native SDK pro Android je teď zastaralá a bude vyřazena 31. 31. 25. Pokud se chcete vyhnout přerušení služeb, proveďte migraci do sady Azure Mapy Web SDK do 31. 31. 25. Další informace najdete v průvodci migrací sady Azure Mapy Android SDK.

Zdroj dat GeoJSON

Azure Mapy používá GeoJSON jako jeden z jeho primárních datových modelů. GeoJSON je otevřený geoprostorový standardní způsob reprezentace geoprostorových dat ve formátu JSON. Třídy GeoJSON dostupné v sadě Azure Mapy Android SDK usnadňují vytváření a serializaci dat GeoJSON. Načtěte a uložte data GeoJSON do DataSource třídy a vykreslujte je pomocí vrstev. Následující kód ukazuje, jak je možné v Azure Mapy vytvářet objekty GeoJSON.

/*
    Raw GeoJSON feature

    {
         "type": "Feature",
         "geometry": {
             "type": "Point",
             "coordinates": [-100, 45]
         },
         "properties": {
             "custom-property": "value"
         }
    }

*/

//Create a point feature.
Feature feature = Feature.fromGeometry(Point.fromLngLat(-100, 45));

//Add a property to the feature.
feature.addStringProperty("custom-property", "value");

//Add the feature to the data source.
source.add(feature);
/*
    Raw GeoJSON feature

    {
         "type": "Feature",
         "geometry": {
             "type": "Point",
             "coordinates": [-100, 45]
         },
         "properties": {
             "custom-property": "value"
         }
    }

*/

//Create a point feature.
val feature = Feature.fromGeometry(Point.fromLngLat(-100, 45))

//Add a property to the feature.
feature.addStringProperty("custom-property", "value")

//Add the feature to the data source.
source.add(feature)

Tip

Data GeoJSON lze přidat do DataSource instance pomocí jedné ze tří metod; add, importDataFromUrla setShapes. Metoda setShapes poskytuje efektivní způsob, jak přepsat všechna data ve zdroji dat. Pokud zavoláte clear metody add nahrazení všech dat ve zdroji dat, budou na mapě provedeny dvě volání vykreslení. Metoda setShape vymaže a přidá data do zdroje dat jedním voláním vykreslení do mapy.

Alternativně lze vlastnosti nejprve načíst do Objektu JsonObject a předat do funkce při jeho vytváření, jak je znázorněno v následujícím ukázkovém kódu.

//Create a JsonObject to store properties for the feature.
JsonObject properties = new JsonObject();
properties.addProperty("custom-property", "value");

Feature feature = Feature.fromGeometry(Point.fromLngLat(-100, 45), properties);
//Create a JsonObject to store properties for the feature.
val properties = JsonObject()
properties.addProperty("custom-property", "value")

val feature = Feature.fromGeometry(Point.fromLngLat(-100, 45), properties)

Jakmile vytvoříte funkci GeoJSON, můžete zdroj dat přidat do mapy prostřednictvím sources vlastnosti mapy. Následující kód ukazuje, jak vytvořit DataSource, přidat do mapy a přidat do zdroje dat funkci.

//Create a data source and add it to the map.
DataSource source = new DataSource();
map.sources.add(source);

//Add GeoJSON feature to the data source.
source.add(feature);

Následující kód ukazuje několik způsobů, jak vytvořit funkci GeoJSON, FeatureCollection a geometrie.

//GeoJSON Point Geometry
Point point = Point.fromLngLat(LONGITUDE, LATITUDE);

//GeoJSON Point Geometry
LineString linestring = LineString.fromLngLats(PointList);

//GeoJSON Polygon Geometry
Polygon polygon = Polygon.fromLngLats(listOfPointList);

Polygon polygonFromOuterInner = Polygon.fromOuterInner(outerLineStringObject,innerLineStringObject);

//GeoJSON MultiPoint Geometry
MultiPoint multiPoint = MultiPoint.fromLngLats(PointList);

//GeoJSON MultiLineString Geometry
MultiLineString multiLineStringFromLngLat = MultiLineString.fromLngLats(listOfPointList);

MultiLineString multiLineString = MultiLineString.fromLineString(singleLineString);

//GeoJSON MultiPolygon Geometry
MultiPolygon multiPolygon = MultiPolygon.fromLngLats(listOflistOfPointList);

MultiPolygon multiPolygonFromPolygon = MultiPolygon.fromPolygon(polygon);

MultiPolygon multiPolygonFromPolygons = MultiPolygon.fromPolygons(PolygonList);

//GeoJSON Feature
Feature pointFeature = Feature.fromGeometry(Point.fromLngLat(LONGITUDE, LATITUDE));

//GeoJSON FeatureCollection 
FeatureCollection featureCollectionFromSingleFeature = FeatureCollection.fromFeature(pointFeature);

FeatureCollection featureCollection = FeatureCollection.fromFeatures(listOfFeatures);
//GeoJSON Point Geometry
val point = Point.fromLngLat(LONGITUDE, LATITUDE)

//GeoJSON Point Geometry
val linestring = LineString.fromLngLats(PointList)

//GeoJSON Polygon Geometry
val polygon = Polygon.fromLngLats(listOfPointList)

val polygonFromOuterInner = Polygon.fromOuterInner(outerLineStringObject, innerLineStringObject)

//GeoJSON MultiPoint Geometry
val multiPoint = MultiPoint.fromLngLats(PointList)

//GeoJSON MultiLineString Geometry
val multiLineStringFromLngLat = MultiLineString.fromLngLats(listOfPointList)

val multiLineString = MultiLineString.fromLineString(singleLineString)

//GeoJSON MultiPolygon Geometry
val multiPolygon = MultiPolygon.fromLngLats(listOflistOfPointList)

val multiPolygonFromPolygon = MultiPolygon.fromPolygon(polygon)

val multiPolygonFromPolygons = MultiPolygon.fromPolygons(PolygonList)

//GeoJSON Feature
val pointFeature = Feature.fromGeometry(Point.fromLngLat(LONGITUDE, LATITUDE))

//GeoJSON FeatureCollection 
val featureCollectionFromSingleFeature = FeatureCollection.fromFeature(pointFeature)

val featureCollection = FeatureCollection.fromFeatures(listOfFeatures)

Serializace a deserializace GeoJSON

Kolekce funkcí, funkce a geometrie třídy mají všechny fromJson() a toJson() statické metody, které pomáhají se serializací. Formátovaný platný řetězec JSON předaný metodou fromJson() vytvoří objekt geometrie. Tato fromJson() metoda také znamená, že můžete použít Gson nebo jiné strategie serializace/deserializace. Následující kód ukazuje, jak vzít řetězcovou geoJSON funkci a deserializovat ji do třídy Feature a pak ji serializovat zpět do řetězce GeoJSON.

//Take a stringified GeoJSON object.
String GeoJSON_STRING = "{"
    + "      \"type\": \"Feature\","            
    + "      \"geometry\": {"
    + "            \"type\": \"Point\""
    + "            \"coordinates\": [-100, 45]"
    + "      },"
    + "      \"properties\": {"
    + "            \"custom-property\": \"value\""
    + "      },"
    + "}";

//Deserialize the JSON string into a feature.
Feature feature = Feature.fromJson(GeoJSON_STRING);

//Serialize a feature collection to a string.
String featureString = feature.toJson();
//Take a stringified GeoJSON object.
val GeoJSON_STRING = ("{"
        + "      \"type\": \"Feature\","
        + "      \"geometry\": {"
        + "            \"type\": \"Point\""
        + "            \"coordinates\": [-100, 45]"
        + "      },"
        + "      \"properties\": {"
        + "            \"custom-property\": \"value\""
        + "      },"
        + "}")

//Deserialize the JSON string into a feature.
val feature = Feature.fromJson(GeoJSON_STRING)

//Serialize a feature collection to a string.
val featureString = feature.toJson()

Import dat GeoJSON z webové složky nebo složky assetů

Většina souborů GeoJSON obsahuje FeatureCollection. Přečtěte si soubory GeoJSON jako řetězce a použili metodu FeatureCollection.fromJson k deserializaci.

Třída DataSource má integrovanou metodu, importDataFromUrl která může načíst soubory GeoJSON pomocí adresy URL k souboru na webu nebo ve složce asset. Tato metoda musí být volána před přidáním zdroje dat do mapy.

zone_pivot_groups: azure-maps-android

//Create a data source and add it to the map.
DataSource source = new DataSource();

//Import the geojson data and add it to the data source.
source.importDataFromUrl("URL_or_FilePath_to_GeoJSON_data");

//Examples:
//source.importDataFromUrl("asset://sample_file.json");
//source.importDataFromUrl("https://example.com/sample_file.json");

//Add data source to the map.
map.sources.add(source);
//Create a data source and add it to the map.
var source = new DataSource()

//Import the geojson data and add it to the data source.
source.importDataFromUrl("URL_or_FilePath_to_GeoJSON_data")

//Examples:
//source.importDataFromUrl("asset://sample_file.json")
//source.importDataFromUrl("https://example.com/sample_file.json")

//Add data source to the map.
map.sources.add(source)

Tato importDataFromUrl metoda poskytuje snadný způsob, jak načíst geoJSON kanál do zdroje dat, ale poskytuje omezenou kontrolu nad tím, jak se data načtou a co se stane po načtení. Následující kód je opakovaně použitelná třída pro import dat z webové složky nebo složky assetů a vrácení do vlákna uživatelského rozhraní prostřednictvím funkce zpětného volání. V dalším kroku přidejte do zpětného volání další logiku po načtení, která zpracuje data, přidáte je do mapy, vypočítáte jeho ohraničující pole a aktualizujete kameru mapy.

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.webkit.URLUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.HttpsURLConnection;

public class Utils {

    interface SimpleCallback {
        void notify(String result);
    }

    /**
     * Imports data from a web url or asset file name and returns it to a callback.
     * @param urlOrFileName A web url or asset file name that points to data to load.
     * @param context The context of the app.
     * @param callback The callback function to return the data to.
     */
    public static void importData(String urlOrFileName, Context context, SimpleCallback callback){
        importData(urlOrFileName, context, callback, null);
    }

    /**
     * Imports data from a web url or asset file name and returns it to a callback.
     * @param urlOrFileName A web url or asset file name that points to data to load.
     * @param context The context of the app.
     * @param callback The callback function to return the data to.
     * @param error A callback function to return errors to.
     */
    public static void importData(String urlOrFileName, Context context, SimpleCallback callback, SimpleCallback error){
        if(urlOrFileName != null && callback != null) {
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Handler handler = new Handler(Looper.getMainLooper());

            executor.execute(() -> {
                String data = null;

                try {

                    if(URLUtil.isNetworkUrl(urlOrFileName)){
                        data = importFromWeb(urlOrFileName);
                    } else {
                        //Assume file is in assets folder.
                        data = importFromAssets(context, urlOrFileName);
                    }

                    final String result = data;

                    handler.post(() -> {
                        //Ensure the resulting data string is not null or empty.
                        if (result != null && !result.isEmpty()) {
                            callback.notify(result);
                        } else {
                            error.notify("No data imported.");
                        }
                    });
                } catch(Exception e) {
                    if(error != null){
                        error.notify(e.getMessage());
                    }
                }
            });
        }
    }

    /**
     * Imports data from an assets file as a string.
     * @param context The context of the app.
     * @param fileName The asset file name.
     * @return
     * @throws IOException
     */
    private static String importFromAssets(Context context, String fileName) throws IOException {
        InputStream stream = null;

        try {
            stream = context.getAssets().open(fileName);

            if(stream != null) {
                return readStreamAsString(stream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close Stream and disconnect HTTPS connection.
            if (stream != null) {
                stream.close();
            }
        }

        return null;
    }

    /**
     * Imports data from the web as a string.
     * @param url URL to the data.
     * @return
     * @throws IOException
     */
    private static String importFromWeb(String url) throws IOException {
        InputStream stream = null;
        HttpsURLConnection connection = null;
        String result = null;

        try {
            connection = (HttpsURLConnection) new URL(url).openConnection();

            //For this use case, set HTTP method to GET.
            connection.setRequestMethod("GET");

            //Open communications link (network traffic occurs here).
            connection.connect();

            int responseCode = connection.getResponseCode();
            if (responseCode != HttpsURLConnection.HTTP_OK) {
                throw new IOException("HTTP error code: " + responseCode);
            }

            //Retrieve the response body as an InputStream.
            stream = connection.getInputStream();

            if (stream != null) {
                return readStreamAsString(stream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close Stream and disconnect HTTPS connection.
            if (stream != null) {
                stream.close();
            }
            if (connection != null) {
                connection.disconnect();
            }
        }

        return result;
    }

    /**
     * Reads an input stream as a string.
     * @param stream Stream to convert.
     * @return
     * @throws IOException
     */
    private static String readStreamAsString(InputStream stream) throws IOException {
        //Convert the contents of an InputStream to a String.
        BufferedReader in = new BufferedReader(new InputStreamReader(stream, "UTF-8"));

        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }

        in.close();

        return response.toString();
    }
}
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.webkit.URLUtil
import java.net.URL
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class Utils {
    companion object {

        /**
            * Imports data from a web url or asset file name and returns it to a callback.
            * @param urlOrFileName A web url or asset file name that points to data to load.
            * @param context The context of the app.
            * @param callback The callback function to return the data to.
            */
        fun importData(urlOrFileName: String?, context: Context, callback: (String?) -> Unit) {
            importData(urlOrFileName, context, callback, null)
        }

        /**
            * Imports data from a web url or asset file name and returns it to a callback.
            * @param urlOrFileName A web url or asset file name that points to data to load.
            * @param context The context of the app.
            * @param callback The callback function to return the data to.
            * @param error A callback function to return errors to.
            */
        public fun importData(urlOrFileName: String?, context: Context, callback: (String?) -> Unit, error: ((String?) -> Unit)?) {
            if (urlOrFileName != null && callback != null) {
                val executor: ExecutorService = Executors.newSingleThreadExecutor()
                val handler = Handler(Looper.getMainLooper())
                executor.execute {
                    var data: String? = null

                    try {
                        data = if (URLUtil.isNetworkUrl(urlOrFileName)) {
                            URL(urlOrFileName).readText()
                        } else { //Assume file is in assets folder.
                            context.assets.open(urlOrFileName).bufferedReader().use{
                                it.readText()
                            }
                        }

                        handler.post {
                            //Ensure the resulting data string is not null or empty.
                            if (data != null && !data.isEmpty()) {
                                callback(data)
                            } else {
                                error!!("No data imported.")
                            }
                        }
                    } catch (e: Exception) {
                        error!!(e.message)
                    }
                }
            }
        }
    }
}

Následující kód ukazuje, jak pomocí tohoto nástroje importovat data GeoJSON jako řetězec a vrátit je do vlákna uživatelského rozhraní prostřednictvím zpětného volání. V zpětném volání lze řetězcová data serializovat do kolekce funkcí GeoJSON a přidat do zdroje dat. Volitelně můžete aktualizovat kameru mapy, aby se fokus zaměřil na data.

//Create a data source and add it to the map.
DataSource source = new DataSource();
map.sources.add(source);

//Import the geojson data and add it to the data source.
Utils.importData("URL_or_FilePath_to_GeoJSON_data",
    this,
    (String result) -> {
        //Parse the data as a GeoJSON Feature Collection.
        FeatureCollection fc = FeatureCollection.fromJson(result);

        //Add the feature collection to the data source.
        source.add(fc);

        //Optionally, update the maps camera to focus in on the data.

        //Calculate the bounding box of all the data in the Feature Collection.
        BoundingBox bbox = MapMath.fromData(fc);

        //Update the maps camera so it is focused on the data.
        map.setCamera(
            bounds(bbox),
            padding(20));
    });
//Create a data source and add it to the map.
DataSource source = new DataSource();
map.sources.add(source);

//Import the GeoJSON data and add it to the data source.
Utils.importData("SamplePoiDataSet.json", this) { 
    result: String? ->
        //Parse the data as a GeoJSON Feature Collection.
            val fc = FeatureCollection.fromJson(result!!)

        //Add the feature collection to the data source.
        source.add(fc)

        //Optionally, update the maps camera to focus in on the data.

        //Calculate the bounding box of all the data in the Feature Collection.
        val bbox = MapMath.fromData(fc);

        //Update the maps camera so it is focused on the data.
        map.setCamera(
            bounds(bbox),

            //Padding added to account for pixel size of rendered points.
            padding(20)
        )
    }

Aktualizace funkce

Třída DataSource usnadňuje přidávání a odebírání funkcí. Aktualizace geometrie nebo vlastností funkce vyžaduje nahrazení funkce ve zdroji dat. Existují dvě metody, které lze použít k aktualizaci funkcí:

  1. Vytvořte nové funkce s požadovanými aktualizacemi a nahraďte všechny funkce ve zdroji dat metodou setShapes . Tato metoda funguje dobře, když chcete aktualizovat všechny funkce ve zdroji dat.
DataSource source;

private void onReady(AzureMap map) {
    //Create a data source and add it to the map.
    source = new DataSource();
    map.sources.add(source);

    //Create a feature and add it to the data source.
    Feature myFeature = Feature.fromGeometry(Point.fromLngLat(0,0));
    myFeature.addStringProperty("Name", "Original value");

    source.add(myFeature);
}

private void updateFeature(){
    //Create a new replacement feature with an updated geometry and property value.
    Feature myNewFeature = Feature.fromGeometry(Point.fromLngLat(-10, 10));
    myNewFeature.addStringProperty("Name", "New value");

    //Replace all features to the data source with the new one.
    source.setShapes(myNewFeature);
}
var source: DataSource? = null

private fun onReady(map: AzureMap) {
    //Create a data source and add it to the map.
    source = DataSource()
    map.sources.add(source)

    //Create a feature and add it to the data source.
    val myFeature = Feature.fromGeometry(Point.fromLngLat(0.0, 0.0))
    myFeature.addStringProperty("Name", "Original value")
    source!!.add(myFeature)
}

private fun updateFeature() {
    //Create a new replacement feature with an updated geometry and property value.
    val myNewFeature = Feature.fromGeometry(Point.fromLngLat(-10.0, 10.0))
    myNewFeature.addStringProperty("Name", "New value")

    //Replace all features to the data source with the new one.
    source!!.setShapes(myNewFeature)
}
  1. Sledujte instanci funkce v proměnné a předejte ji do metody zdrojů remove dat, abyste ji odebrali. Vytvořte nové funkce s požadovanými aktualizacemi, aktualizujte odkaz na proměnnou a přidejte ji do zdroje dat pomocí add metody.
DataSource source;
Feature myFeature;

private void onReady(AzureMap map) {
    //Create a data source and add it to the map.
    source = new DataSource();
    map.sources.add(source);

    //Create a feature and add it to the data source.
    myFeature = Feature.fromGeometry(Point.fromLngLat(0,0));
    myFeature.addStringProperty("Name", "Original value");

    source.add(myFeature);
}

private void updateFeature(){
    //Remove the feature instance from the data source.
    source.remove(myFeature);

    //Get properties from original feature.
    JsonObject props = myFeature.properties();

    //Update a property.
    props.addProperty("Name", "New value");

    //Create a new replacement feature with an updated geometry.
    myFeature = Feature.fromGeometry(Point.fromLngLat(-10, 10), props);

    //Re-add the feature to the data source.
    source.add(myFeature);
}
var source: DataSource? = null
var myFeature: Feature? = null

private fun onReady(map: AzureMap) {
    //Create a data source and add it to the map.
    source = DataSource()
    map.sources.add(source)

    //Create a feature and add it to the data source.
    myFeature = Feature.fromGeometry(Point.fromLngLat(0.0, 0.0))
    myFeature.addStringProperty("Name", "Original value")
    source!!.add(myFeature)
}

private fun updateFeature() {
    //Remove the feature instance from the data source.
    source!!.remove(myFeature)

    //Get properties from original feature.
    val props = myFeature!!.properties()

    //Update a property.
    props!!.addProperty("Name", "New value")

    //Create a new replacement feature with an updated geometry.
    myFeature = Feature.fromGeometry(Point.fromLngLat(-10.0, 10.0), props)

    //Re-add the feature to the data source.
    source!!.add(myFeature)
}

Tip

Pokud máte nějaká data, která se budou pravidelně aktualizovat, a jiná data, která se zřídka změní, je nejlepší je rozdělit na samostatné instance zdroje dat. Když dojde k aktualizaci ve zdroji dat, vynutí mapování překreslit všechny funkce ve zdroji dat. Rozdělením těchto dat by se při aktualizaci v jednom zdroji dat překreslily pouze funkce, které se pravidelně aktualizují, zatímco funkce v druhém zdroji dat by se nemusely překreslit. To pomáhá s výkonem.

Zdroj vektorové dlaždice

Zdroj vektorové dlaždice popisuje, jak získat přístup k vrstvě vektorové dlaždice. VectorTileSource Pomocí třídy vytvořte instanci zdroje vektorové dlaždice. Vrstvy vektorových dlaždic jsou podobné vrstvě dlaždic, ale nejsou stejné. Vrstva dlaždice je rastrový obrázek. Vrstvy vektorových dlaždic jsou komprimovaný soubor ve formátu PBF . Tento komprimovaný soubor obsahuje data vektorového mapování a jednu nebo více vrstev. Soubor lze vykreslit a stylovat v klientovi na základě stylu každé vrstvy. Data v dlaždici vektoru obsahují geografické funkce ve formě bodů, čar a mnohoúhelníku. Použití vrstev vektorových dlaždic místo rastrových vrstev dlaždic má několik výhod:

  • Velikost souboru vektorové dlaždice je obvykle mnohem menší než ekvivalentní rastrová dlaždice. Proto se používá menší šířka pásma. To znamená nižší latenci, rychlejší mapování a lepší uživatelské prostředí.
  • Vzhledem k tomu, že se vektorové dlaždice vykreslují na klientovi, přizpůsobí se rozlišení zařízení, na kterém se zobrazují. V důsledku toho se vykreslené mapy zobrazují jasněji definované s krystalickými popisky.
  • Změna stylu dat v vektorových mapách nevyžaduje opětovné stažení dat, protože nový styl lze použít v klientovi. Změna stylu rastrové vrstvy dlaždic naproti tomu obvykle vyžaduje načtení dlaždic ze serveru a následné použití nového stylu.
  • Vzhledem k tomu, že data jsou dodávána ve formě vektoru, je k přípravě dat potřeba méně zpracování na straně serveru. V důsledku toho je možné novější data zpřístupnit rychleji.

Azure Mapy dodržuje specifikaci vektorové dlaždice Mapbox, otevřeného standardu. Azure Mapy poskytuje jako součást platformy následující služby vektorových dlaždic:

Tip

Při použití vektorových nebo rastrových dlaždic obrázků ze služby Azure Mapy render pomocí webové sady SDK můžete nahradit atlas.microsoft.com zástupným symbolem azmapsdomain.invalid. Tento zástupný symbol se nahradí stejnou doménou, kterou mapa používá, a automaticky připojí stejné ověřovací údaje. To výrazně zjednodušuje ověřování pomocí služby render při použití ověřování Microsoft Entra.

Pokud chcete zobrazit data ze zdroje vektorové dlaždice na mapě, připojte zdroj k jedné z vrstev vykreslování dat. Všechny vrstvy, které používají vektorový zdroj, musí v možnostech zadat sourceLayer hodnotu. Následující kód načte službu dlaždic vektoru toku provozu Azure Mapy jako zdroj vektorové dlaždice a pak ji zobrazí na mapě pomocí vrstvy čáry. Tento zdroj vektorové dlaždice má jednu sadu dat ve zdrojové vrstvě s názvem "Tok provozu". Řádková data v této sadě dat mají vlastnost, traffic_level která se používá v tomto kódu k výběru barvy a měřítka velikosti řádků.

//Formatted URL to the traffic flow vector tiles, with the maps subscription key appended to it.
String trafficFlowUrl = "https://azmapsdomain.invalid/traffic/flow/tile/pbf?api-version=1.0&style=relative&zoom={z}&x={x}&y={y}";

//Create a vector tile source and add it to the map.
VectorTileSource source = new VectorTileSource(
    tiles(new String[] { trafficFlowUrl }),
    maxSourceZoom(22)
);
map.sources.add(source);

//Create a layer for traffic flow lines.
LineLayer layer = new LineLayer(source,
    //The name of the data layer within the data source to pass into this rendering layer.
    sourceLayer("Traffic flow"),

    //Color the roads based on the traffic_level property.
    strokeColor(
        interpolate(
            linear(),
            get("traffic_level"),
            stop(0, color(Color.RED)),
            stop(0.33, color(Color.YELLOW)),
            stop(0.66, color(Color.GREEN))
        )
    ),

    //Scale the width of roads based on the traffic_level property.
    strokeWidth(
        interpolate(
            linear(),
            get("traffic_level"),
            stop(0, 6),
            stop(1,1)
        )
    )
);

//Add the traffic flow layer below the labels to make the map clearer.
map.layers.add(layer, "labels");
//Formatted URL to the traffic flow vector tiles, with the maps subscription key appended to it.
val trafficFlowUrl = "https://azmapsdomain.invalid/traffic/flow/tile/pbf?api-version=1.0&style=relative&zoom={z}&x={x}&y={y}"

//Create a vector tile source and add it to the map.
val source = VectorTileSource(
    tiles(arrayOf(trafficFlowUrl)),
    maxSourceZoom(22)
)
map.sources.add(source)

//Create a layer for traffic flow lines.
val layer = LineLayer(
    source,  //The name of the data layer within the data source to pass into this rendering layer.
    sourceLayer("Traffic flow"),  //Color the roads based on the traffic_level property.
    strokeColor(
        interpolate(
            linear(),
            get("traffic_level"),
            stop(0, color(Color.RED)),
            stop(0.33, color(Color.YELLOW)),
            stop(0.66, color(Color.GREEN))
        )
    ),  //Scale the width of roads based on the traffic_level property.
    strokeWidth(
        interpolate(
            linear(),
            get("traffic_level"),
            stop(0, 6),
            stop(1, 1)
        )
    )
)

//Add the traffic flow layer below the labels to make the map clearer.
map.layers.add(layer, "labels")

Mapa s barevnými směrovými čárami zobrazující úrovně toku provozu

Připojení zdroje dat do vrstvy

Data se na mapě vykreslují pomocí vykreslovacích vrstev. Jedna nebo více vrstev vykreslování může odkazovat na jeden zdroj dat. Následující vrstvy vykreslování vyžadují zdroj dat:

  • Bublinová vrstva – vykreslí data bodů jako škálované kruhy na mapě.
  • Vrstva symbolu – vykreslí data bodů jako ikony nebo text.
  • Vrstva heat mapy – vykresluje data bodů jako heat mapu hustoty.
  • Vrstva čáry – vykreslení čáry a vykreslení obrysu mnohoúhelníku
  • Polygonová vrstva – vyplní oblast mnohoúhelníku plnou barvou nebo vzorem obrázku.

Následující kód ukazuje, jak vytvořit zdroj dat, přidat ho do mapy a připojit ho k bublinové vrstvě. Potom naimportujte data bodu GeoJSON ze vzdáleného umístění do zdroje dat.

//Create a data source and add it to the map.
DataSource source = new DataSource();

//Import the geojson data and add it to the data source.
source.importDataFromUrl("URL_or_FilePath_to_GeoJSON_data");

//Add data source to the map.
map.sources.add(source);

//Create a layer that defines how to render points in the data source and add it to the map.
BubbleLayer layer = new BubbleLayer(source);
map.layers.add(layer);
//Create a data source and add it to the map.
val source = DataSource()

//Import the geojson data and add it to the data source.
source.importDataFromUrl("URL_or_FilePath_to_GeoJSON_data")

//Add data source to the map.
map.sources.add(source)

Existují další vrstvy vykreslování, které se k těmto zdrojům dat nepřipojují, ale přímo načítají data pro vykreslování.

  • Vrstva dlaždic – superimpozizuje rastrovou vrstvu dlaždic v horní části mapy.

Jeden zdroj dat s více vrstvami

K jednomu zdroji dat je možné připojit více vrstev. Tato možnost je užitečná v mnoha různých scénářích. Představte si například scénář, ve kterém uživatel nakreslí mnohoúhelník. Měli bychom vykreslit a vyplnit mnohoúhelník, protože uživatel přidává body do mapy. Když přidáte stylovanou čáru k obrysu mnohoúhelníku, bude se snadněji zobrazovat okraje mnohoúhelníku, jak uživatel nakreslí. Pokud chceme pohodlně upravit jednotlivou pozici v mnohoúhelníku, můžeme nad každou pozici přidat úchyt, například špendlík nebo značku.

Mapa zobrazující více vrstev vykreslující data z jednoho zdroje dat

Ve většině mapovacích platforem byste potřebovali polygonový objekt, spojnicový objekt a špendlík pro každou pozici v mnohoúhelníku. Při úpravě mnohoúhelníku byste museli ručně aktualizovat čáru a špendlíky, což se může rychle stát složitým.

S Azure Mapy stačí jen jeden mnohoúhelník ve zdroji dat, jak je znázorněno v následujícím kódu.

//Create a data source and add it to the map.
DataSource source = new DataSource();
map.sources.add(source);

//Create a polygon and add it to the data source.
source.add(Polygon.fromLngLats(/* List of points */));

//Create a polygon layer to render the filled in area of the polygon.
PolygonLayer polygonLayer = new PolygonLayer(source,
    fillColor("rgba(255,165,0,0.2)")
);

//Create a line layer for greater control of rendering the outline of the polygon.
LineLayer lineLayer = new LineLayer(source,
    strokeColor("orange"),
    strokeWidth(2f)
);

//Create a bubble layer to render the vertices of the polygon as scaled circles.
BubbleLayer bubbleLayer = new BubbleLayer(source,
    bubbleColor("orange"),
    bubbleRadius(5f),
    bubbleStrokeColor("white"),
    bubbleStrokeWidth(2f)
);

//Add all layers to the map.
map.layers.add(new Layer[] { polygonLayer, lineLayer, bubbleLayer });
//Create a data source and add it to the map.
val source = DataSource()
map.sources.add(source)

//Create a polygon and add it to the data source.
source.add(Polygon.fromLngLats())

//Create a polygon layer to render the filled in area of the polygon.
val polygonLayer = PolygonLayer(
    source,
    fillColor("rgba(255,165,0,0.2)")
)

//Create a line layer for greater control of rendering the outline of the polygon.
val lineLayer = LineLayer(
    source,
    strokeColor("orange"),
    strokeWidth(2f)
)

//Create a bubble layer to render the vertices of the polygon as scaled circles.
val bubbleLayer = BubbleLayer(
    source,
    bubbleColor("orange"),
    bubbleRadius(5f),
    bubbleStrokeColor("white"),
    bubbleStrokeWidth(2f)
)

//Add all layers to the map.
map.layers.add(arrayOf<Layer>(polygonLayer, lineLayer, bubbleLayer))

Tip

Při přidávání vrstev do mapy pomocí map.layers.add metody lze ID nebo instance existující vrstvy předat jako druhý parametr. To by řeklo, že mapa vloží novou vrstvu, která se přidá pod existující vrstvu. Kromě předávání ID vrstvy tato metoda podporuje také následující hodnoty.

  • "labels" - Vloží novou vrstvu pod vrstvy popisků mapy.
  • "transit" - Vloží novou vrstvu pod vrstvu silniční a tranzitní vrstvy mapy.

Další kroky

Další ukázky kódu pro přidání do map najdete v následujících článcích: