תוכנית השירות של מפות Google למפת חום ב-Android

בחירת פלטפורמה: Android iOS JavaScript

מפות חום שימושיות כדי לייצג את ההתפלגות והצפיפות של נקודות נתונים במפה.

מבוא

Maps SDK for Android Utility Library כולל כלי עזר עם מפת חום, שאפשר להשתמש בו כדי להוסיף מפות חום אחת או יותר למפה של Google באפליקציה.

בסרטון הזה אנחנו מסבירים איך להשתמש במפות חום כחלופה לסמנים, במקרים שבהם צריך להציג מספר גדול של נקודות נתונים במפה.

מפות חום עוזרות לצופים להבין את ההתפלגות ואת העוצמה היחסית של נקודות נתונים במפה. במקום להציב סמן בכל מיקום, במפות חום נעשה שימוש בצבע שמייצג את התפלגות הנתונים.

בדוגמה הבאה, הצבע האדום מייצג אזורים שבהם יש ריכוז גבוה של תחנות משטרה בוויקטוריה שבאוסטרליה.

מפה עם מפת חום שמציגה את המיקום של תחנות משטרה
מפת חום במפה

אם עדיין לא הגדרת את ה-SDK של מפות Google לספריית Android Utility, פעלו לפי מדריך ההגדרה לפני שתקראו את הדף הזה.

הוספה של מפת חום פשוטה

כדי להוסיף מפת חום למפה, צריך מערך נתונים שמכיל את הקואורדינטות של כל מיקום רצוי. קודם כול יוצרים HeatmapTileProvider ומעבירים לו את האוסף של LatLng אובייקטים. אחר כך יוצרים TileOverlay חדש, מעבירים אותו לספק של המשבצת של מפת החום ומוסיפים למפה את שכבת-העל של משבצות.

כלי העזר מספק את המחלקה HeatmapTileProvider, שמטמיעה את הממשק של TileProvider כדי לספק את תמונות המשבצת של מפת החום. אפשר להשתמש באוסף של LatLng אובייקטים ב-HeatmapTileProvider (או WeightedLatLng אובייקטים, כפי שמתואר בהמשך). היא יוצרת את תמונות המשבצת עבור רמות שונות של מרחק התצוגה, על סמך אפשרויות הרדיוס, ההדרגתיות והשקיפות שיתקבלו. תוכלו לשנות את ערכי ברירת המחדל של האפשרויות האלה.

סקירה מפורטת של השלבים:

  1. באמצעות HeatmapTileProvider.Builder(), מעבירים לו אוסף של LatLng אובייקטים, כדי להוסיף HeatmapTileProvider חדש.
  2. יוצרים אובייקט חדש TileOverlayOptions עם האפשרויות הרלוונטיות, כולל האובייקט HeatmapTileProvider.
  3. אפשר להתקשר GoogleMap.addTileOverlay() כדי להוסיף את שכבת-העל למפה.

Kotlin



private fun addHeatMap() {
    var latLngs: List<LatLng?>? = null

    // Get the data: latitude/longitude positions of police stations.
    try {
        latLngs = readItems(R.raw.police_stations)
    } catch (e: JSONException) {
        Toast.makeText(context, "Problem reading list of locations.", Toast.LENGTH_LONG)
            .show()
    }

    // Create a heat map tile provider, passing it the latlngs of the police stations.
    val provider = HeatmapTileProvider.Builder()
        .data(latLngs)
        .build()

    // Add a tile overlay to the map, using the heat map tile provider.
    val overlay = map.addTileOverlay(TileOverlayOptions().tileProvider(provider))
}

@Throws(JSONException::class)
private fun readItems(@RawRes resource: Int): List<LatLng?> {
    val result: MutableList<LatLng?> = ArrayList()
    val inputStream = context.resources.openRawResource(resource)
    val json = Scanner(inputStream).useDelimiter("\\A").next()
    val array = JSONArray(json)
    for (i in 0 until array.length()) {
        val `object` = array.getJSONObject(i)
        val lat = `object`.getDouble("lat")
        val lng = `object`.getDouble("lng")
        result.add(LatLng(lat, lng))
    }
    return result
}

      

Java


private void addHeatMap() {
    List<LatLng> latLngs = null;

    // Get the data: latitude/longitude positions of police stations.
    try {
        latLngs = readItems(R.raw.police_stations);
    } catch (JSONException e) {
        Toast.makeText(context, "Problem reading list of locations.", Toast.LENGTH_LONG).show();
    }

    // Create a heat map tile provider, passing it the latlngs of the police stations.
    HeatmapTileProvider provider = new HeatmapTileProvider.Builder()
        .data(latLngs)
        .build();

    // Add a tile overlay to the map, using the heat map tile provider.
    TileOverlay overlay = map.addTileOverlay(new TileOverlayOptions().tileProvider(provider));
}

private List<LatLng> readItems(@RawRes int resource) throws JSONException {
    List<LatLng> result = new ArrayList<>();
    InputStream inputStream = context.getResources().openRawResource(resource);
    String json = new Scanner(inputStream).useDelimiter("\\A").next();
    JSONArray array = new JSONArray(json);
    for (int i = 0; i < array.length(); i++) {
        JSONObject object = array.getJSONObject(i);
        double lat = object.getDouble("lat");
        double lng = object.getDouble("lng");
        result.add(new LatLng(lat, lng));
    }
    return result;
}

      

בדוגמה הזו, הנתונים מאוחסנים בקובץ JSON, police_stations.json. הנה תמצית מהקובץ:

[
{"lat" : -37.1886, "lng" : 145.708 } ,
{"lat" : -37.8361, "lng" : 144.845 } ,
{"lat" : -38.4034, "lng" : 144.192 } ,
{"lat" : -38.7597, "lng" : 143.67 } ,
{"lat" : -36.9672, "lng" : 141.083 }
]

שימוש בנקודות קו אורך/רוחב משוקללות

כשיוצרים HeatmapTileProvider, אפשר להעביר לו אוסף של קואורדינטות של קווי אורך ורוחב משוקללים. האפשרות הזו שימושית אם רוצים להדגים את החשיבות של קבוצת מיקומים מסוימת.

כדי להחיל שקלול על מיקומים ספציפיים:

  1. צריך ליצור ערך חדש WeightedLatLng לכל מיקום שדורש שקלול. עוברים את LatLng ו-double שמייצגים את העוצמה הנדרשת. העוצמה מציינת את החשיבות או הערך היחסי של המיקום הזה. ערך גבוה יותר יגרום לצבע בעוצמה גבוהה יותר בהדרגתיות של מפת החום. כברירת מחדל, הצבע בעוצמה הגבוהה ביותר הוא אדום.
  2. אפשר להתקשר אל HeatmapTileProvider.Builder().weightedData(), במקום אל HeatmapTileProvider.Builder().data(), כדי ליצור את מפת החום.

התאמה אישית של מפת החום

יש כמה מאפיינים של מפת החום שניתן להתאים אישית. אפשר להגדיר את האפשרויות בזמן היצירה, באמצעות פונקציות של Builder. לחלופין, אפשר לשנות אפשרות בכל שלב על ידי קריאה לרכיב המגדיר הרלוונטי ב-HeatmapTileProvider, ואז לנקות את מטמון המשבצות של שכבת-העל כדי שיהיה שרטוט מחדש של כל המשבצות עם האפשרויות החדשות.

אלו האפשרויות הזמינות:

  1. רדיוס: גודל הטשטוש הגאוסיאני שחל על מפת החום, מבוטא בפיקסלים. ברירת המחדל היא 20. חייב להיות בין 10 ל-50. צריך להשתמש ב-radius() של הבונה כדי להגדיר את הערך כשיוצרים את מפת החום, או לשנות את הערך מאוחר יותר באמצעות setRadius().
  2. הצבע: טווח צבעים שמשמש את מפת החום כדי ליצור את מפת הצבעים, מהעוצמה הנמוכה ביותר ועד הגבוהה ביותר. הדרגתי נוצר באמצעות שני מערכים: מערך מספר שלם שמכיל את הצבעים, ומערך צף שמציין את נקודת ההתחלה של כל צבע, הנתון כאחוז מהעוצמה המקסימלית, ומבוטאת כשבר בין 0 ל-1. עליך לציין רק צבע אחד עבור הדרגתי של צבע יחיד, או לפחות שני צבעים עבור הדרגה של צבעים מרובים. מפת הצבעים נוצרת באמצעות אינטרפולציה בין הצבעים האלה. ברירת המחדל של צבע ההדרגתיות כוללת שני צבעים. אפשר להשתמש ב-gradient() של Builder כדי להגדיר את הערך כשיוצרים את מפת החום, או לשנות את הערך מאוחר יותר באמצעות setGradient().
  3. אטימות: זוהי מידת האטימות של כל שכבת מפת החום, והטווח נע בין 0 ל-1. ברירת המחדל היא 0.7. אפשר להשתמש ב-opacity() של הבונה כדי להגדיר את הערך כשיוצרים את מפת החום, או לשנות את הערך מאוחר יותר באמצעות setOpacity().

לדוגמה, אפשר ליצור Gradient כדי להגדיר את ההדרגתיות לפני ההוספה של מפת החום:

Kotlin



// Create the gradient.
val colors = intArrayOf(
    Color.rgb(102, 225, 0),  // green
    Color.rgb(255, 0, 0) // red
)
val startPoints = floatArrayOf(0.2f, 1f)
val gradient = Gradient(colors, startPoints)

// Create the tile provider.
val provider = HeatmapTileProvider.Builder()
    .data(latLngs)
    .gradient(gradient)
    .build()

// Add the tile overlay to the map.
val tileOverlay = map.addTileOverlay(
    TileOverlayOptions()
        .tileProvider(provider)
)

      

Java


// Create the gradient.
int[] colors = {
    Color.rgb(102, 225, 0), // green
    Color.rgb(255, 0, 0)    // red
};

float[] startPoints = {
    0.2f, 1f
};

Gradient gradient = new Gradient(colors, startPoints);

// Create the tile provider.
HeatmapTileProvider provider = new HeatmapTileProvider.Builder()
    .data(latLngs)
    .gradient(gradient)
    .build();

// Add the tile overlay to the map.
TileOverlay tileOverlay = map.addTileOverlay(new TileOverlayOptions().tileProvider(provider));

      

כדי לשנות את מידת השקיפות של מפת חום קיימת:

Kotlin



provider.setOpacity(0.7)
tileOverlay?.clearTileCache()

      

Java


provider.setOpacity(0.7);
tileOverlay.clearTileCache();

      

שינוי מערך הנתונים

כדי לשנות את מערך הנתונים שעליו מתבססת מפת חום, צריך להשתמש בפונקציה HeatmapTileProvider.setData() או HeatmapTileProvider.setWeightedData() ל-WeightedLatLng נקודות. הערה: אם רוצים להוסיף נקודות למפת החום, או להסיר נקודות ממפת החום, צריך לעדכן את איסוף הנתונים ואז להשתמש ב-setData() או ב-setWeightedData().

Kotlin



val data: List<WeightedLatLng> = ArrayList()
provider.setWeightedData(data)
tileOverlay?.clearTileCache()

      

Java


List<WeightedLatLng> data = new ArrayList<>();
provider.setWeightedData(data);
tileOverlay.clearTileCache();

      

הסרה של מפת חום

כדי להסיר את מפת החום, צריך להסיר את שכבת-העל של כרטיס המידע:

Kotlin



tileOverlay?.remove()

      

Java


tileOverlay.remove();

      

לצפייה באפליקציית ההדגמה

דוגמה נוספת להטמעה של מפת חום אפשר לראות את HeatmapsDemoActivity באפליקציית ההדגמה שכלולה בספריית כלי השירות. במדריך ההגדרה מוסבר איך להפעיל את אפליקציית ההדגמה.