المفاهيم المتقدّمة

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

جارٍ الحصول على البيانات

هناك عدة طرق للحصول على بيانات الموقع التي تم جمعها. نوضح هنا طريقتين للحصول على البيانات لاستخدامها مع ميزة محاذاة إلى الطرق من Roads API.

GPX

GPX هو تنسيق مفتوح يستند إلى XML لمشاركة المسارات والمسارات ونقاط الطرق التي تلتقطها أجهزة GPS. يستخدم هذا المثال المحلل اللغوي XmlPull، وهو محلل XML خفيف الوزن متوفر لكل من خادم جافا وبيئات الجوال.

/**
 * Parses the waypoint (wpt tags) data into native objects from a GPX stream.
 */
private List<LatLng> loadGpxData(XmlPullParser parser, InputStream gpxIn)
        throws XmlPullParserException, IOException {
    // We use a List<> as we need subList for paging later
    List<LatLng> latLngs = new ArrayList<>();
    parser.setInput(gpxIn, null);
    parser.nextTag();

    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }

        if (parser.getName().equals("wpt")) {
            // Save the discovered latitude/longitude attributes in each <wpt>.
            latLngs.add(new LatLng(
                    Double.valueOf(parser.getAttributeValue(null, "lat")),
                    Double.valueOf(parser.getAttributeValue(null, "lon"))));
        }
        // Otherwise, skip irrelevant data
    }

    return latLngs;
}

إليك بعض بيانات GPX الأولية التي تم تحميلها على الخريطة.

بيانات GPX الأولية على الخريطة

خدمات الموقع الجغرافي على Android

تختلف أفضل طريقة لالتقاط بيانات نظام تحديد المواقع العالمي (GPS) من جهاز Android بناءً على حالة الاستخدام. ألقِ نظرة على صف تدريب Android حول تلقي تحديثات الموقع، بالإضافة إلى نماذج مواقع Google Play على GitHub.

معالجة المسارات الطويلة

نظرًا لأن ميزة محاذاة إلى الطرق تستنتج الموقع استنادًا إلى المسار بالكامل، بدلاً من النقاط الفردية، ستحتاج إلى الاهتمام عند معالجة المسارات الطويلة (أي المسارات التي تتجاوز حد 100 نقطة لكل طلب).

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

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

/**
 * Snaps the points to their most likely position on roads using the Roads API.
 */
private List<SnappedPoint> snapToRoads(GeoApiContext context) throws Exception {
    List<SnappedPoint> snappedPoints = new ArrayList<>();

    int offset = 0;
    while (offset < mCapturedLocations.size()) {
        // Calculate which points to include in this request. We can't exceed the API's
        // maximum and we want to ensure some overlap so the API can infer a good location for
        // the first few points in each request.
        if (offset > 0) {
            offset -= PAGINATION_OVERLAP;   // Rewind to include some previous points.
        }
        int lowerBound = offset;
        int upperBound = Math.min(offset + PAGE_SIZE_LIMIT, mCapturedLocations.size());

        // Get the data we need for this page.
        LatLng[] page = mCapturedLocations
                .subList(lowerBound, upperBound)
                .toArray(new LatLng[upperBound - lowerBound]);

        // Perform the request. Because we have interpolate=true, we will get extra data points
        // between our originally requested path. To ensure we can concatenate these points, we
        // only start adding once we've hit the first new point (that is, skip the overlap).
        SnappedPoint[] points = RoadsApi.snapToRoads(context, true, page).await();
        boolean passedOverlap = false;
        for (SnappedPoint point : points) {
            if (offset == 0 || point.originalIndex >= PAGINATION_OVERLAP - 1) {
                passedOverlap = true;
            }
            if (passedOverlap) {
                snappedPoints.add(point);
            }
        }

        offset = upperBound;
    }

    return snappedPoints;
}

في ما يلي البيانات الواردة أعلاه بعد تشغيل المحاذاة إلى طلبات الطرق. الخط الأحمر هو البيانات الأولية والخط الأزرق هو البيانات التي تم طيها.

مثال على بيانات تم قطعها إلى الطرق

الاستخدام الفعّال للحصة

تتضمن الاستجابة إلى طلب محاذاة إلى الطرق قائمة من أرقام تعريف الأماكن التي يتم تعيينها للنقاط التي قدمتها، مع إمكانية إضافة نقاط في حالة تعيين interpolate=true.

من أجل الاستخدام الفعّال للحصة المسموح بها لطلب حدود السرعة، يجب أن تبحث فقط عن أرقام تعريف الأماكن الفريدة في طلبك. يستخدم هذا المثال برنامج جافا لخدمات خرائط Google لطلب حدود السرعة من قائمة معرّفات الأماكن.

/**
 * Retrieves speed limits for the previously-snapped points. This method is efficient in terms
 * of quota usage as it will only query for unique places.
 *
 * Note: Speed limit data is only available for requests using an API key enabled for a
 * Google Maps APIs Premium Plan license.
 */
private Map<String, SpeedLimit> getSpeedLimits(GeoApiContext context, List<SnappedPoint> points)
        throws Exception {
    Map<String, SpeedLimit> placeSpeeds = new HashMap<>();

    // Pro tip: Save on quota by filtering to unique place IDs.
    for (SnappedPoint point : points) {
        placeSpeeds.put(point.placeId, null);
    }

    String[] uniquePlaceIds =
            placeSpeeds.keySet().toArray(new String[placeSpeeds.keySet().size()]);

    // Loop through the places, one page (API request) at a time.
    for (int i = 0; i < uniquePlaceIds.length; i += PAGE_SIZE_LIMIT) {
        String[] page = Arrays.copyOfRange(uniquePlaceIds, i,
                Math.min(i + PAGE_SIZE_LIMIT, uniquePlaceIds.length));

        // Execute!
        SpeedLimit[] placeLimits = RoadsApi.speedLimits(context, page).await();
        for (SpeedLimit sl : placeLimits) {
            placeSpeeds.put(sl.placeId, sl);
        }
    }

    return placeSpeeds;
}

في ما يلي البيانات الواردة أعلاه مع تحديد حدود السرعة في كل رقم تعريف مكان فريد.

علامات حدود السرعة على خريطة

التفاعل مع واجهات برمجة التطبيقات الأخرى

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

/**
 * Geocodes a snapped point using the place ID.
 */
private GeocodingResult geocodeSnappedPoint(GeoApiContext context, SnappedPoint point) throws Exception {
    GeocodingResult[] results = GeocodingApi.newRequest(context)
            .place(point.placeId)
            .await();

    if (results.length > 0) {
        return results[0];
    }
    return null;
}

هنا تمت إضافة تعليق توضيحي إلى علامة حد السرعة باستخدام العنوان من واجهة برمجة التطبيقات لترميز المواقع الجغرافية.

يتم عرض عنوان تم ترميزه جغرافيًا على محدّد موقع

نموذج التعليمات البرمجية

الاعتبارات

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

تنزيل

نزِّل الرمز من GitHub.