أداة خريطة التمثيل اللوني لأجهزة Android في "خرائط Google"

اختيار النظام الأساسي: Android iOS

تكون الخرائط الحرارية مفيدة لتمثيل توزيع وكثافة نقاط البيانات على الخريطة.

مقدمة

تتضمّن مكتبة أدوات "حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android" أداة خريطة الكثافة التي يمكنك استخدامها لإضافة خريطة كثافة واحدة أو أكثر إلى خريطة Google في تطبيقك.

يناقش هذا الفيديو استخدام الخرائط الحرارية كبديل عن العلامات عندما تتطلّب بياناتك عددًا كبيرًا من نقاط البيانات على الخريطة.

تسهّل خرائط التمثيل اللوني على المشاهدين فهم توزيع نقاط البيانات وكثافتها النسبية على الخريطة. بدلاً من وضع علامة في كل موقع جغرافي، تستخدم خرائط التمثيل اللوني اللون لتمثيل توزيع البيانات.

في المثال أدناه، يمثّل اللون الأحمر المناطق التي تتضمّن عددًا كبيرًا من مراكز الشرطة في ولاية فيكتوريا، أستراليا.

خريطة تتضمّن خريطة تمثيل لوني تعرض الموقع الجغرافي لمراكز الشرطة
خريطة حرارية على خريطة

إذا لم يسبق لك إعداد مكتبة أدوات "حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android"، اتّبِع دليل الإعداد قبل قراءة بقية هذه الصفحة.

إضافة خريطة حرارية بسيطة

لإضافة خريطة كثافة إلى خريطتك، ستحتاج إلى مجموعة بيانات تتألف من الإحداثيات الخاصة بكل موقع جغرافي يهمّك. أنشئ أولاً HeatmapTileProvider، مع تمرير مجموعة عناصر LatLng إليه. بعد ذلك، أنشئ TileOverlay جديدًا، مع تمرير موفّر مربّعات الخريطة الحرارية إليه، وأضِف طبقة المربّعات إلى الخريطة.

توفر الأداة المساعدة الفئة HeatmapTileProvider التي تنفّذ الواجهة TileProvider لتوفير صور المربّعات لخريطة الكثافة. يقبل HeatmapTileProvider مجموعة من عناصر LatLng (أو عناصر 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() في أداة الإنشاء لضبط القيمة عند إنشاء خريطة الكثافة، أو غيِّر القيمة لاحقًا باستخدام 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 في التطبيق التجريبي الذي يتم تضمينه في مكتبة الأدوات المساعدة. يوضّح لك دليل الإعداد كيفية تشغيل التطبيق التجريبي.