الحصول على مصفوفة مسار

مطوّرو المنطقة الاقتصادية الأوروبية (EEA)

مصفوفة المسارات هي مصفوفة ثنائية الأبعاد لمعلومات المسار، حيث تتطابق الصفوف مع نقاط الانطلاق والأعمدة مع الوجهات. بالنظر إلى قائمة بنقاط الانطلاق والوجهات، تحسب فئة Route Matrix المسافة والمدة لمسار يبدأ من كل نقطة انطلاق وينتهي عند كل وجهة. استخدِم فئة Route Matrix لحساب الـ مسافة والمدة لمسار لعدة نقاط انطلاق ووجهات.

الاطّلاع على رمز المصدر الكامل للمثال

يوضّح هذا المثال كيفية استخدام فئة Route Matrix لحساب المسافات والمدد للسفر بين نقاط انطلاق ووجهات متعددة.

TypeScript

// Initialize and add the map.
let map: google.maps.Map;
const markers: google.maps.marker.AdvancedMarkerElement[] = [];
const center = { lat: 51.55, lng: -1.8 };

async function init(): Promise<void> {
    //  Request the needed libraries.
    const [
        { Map },
        { Place },
        { AdvancedMarkerElement, PinElement },
        { RouteMatrix },
        { LatLngBounds, UnitSystem },
    ] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes'),
        google.maps.importLibrary('core'),
    ]);

    const bounds = new LatLngBounds();

    map = new Map(document.getElementById('map')!, {
        zoom: 8,
        center,
        mapId: 'DEMO_MAP_ID',
    });

    // Build the request using Place instances.
    const origin1 = new Place({
        id: 'ChIJ83WZp86p2EcRbMrkYqGncBQ', // Greenwich, London, UK
    });
    const origin2 = new Place({
        id: 'ChIJCSkVvleJc0gR8HHaTGpajKc', // Southampton, UK
    });
    const destinationA = new Place({
        id: 'ChIJYdizgWaDcUgRH9eaSy6y5I4', // Bristol, UK
    });
    const destinationB = new Place({
        id: 'ChIJ9VPsNNQCbkgRDmeGZdsGNBQ', // Cardiff, UK
    });

    await Promise.all([
        origin1.fetchFields({ fields: ['location', 'displayName'] }),
        origin2.fetchFields({ fields: ['location', 'displayName'] }),
        destinationA.fetchFields({ fields: ['location', 'displayName'] }),
        destinationB.fetchFields({ fields: ['location', 'displayName'] }),
    ]);

    const destinations = [destinationA, destinationB];
    const origins = [origin1, origin2];
    const request: google.maps.routes.ComputeRouteMatrixRequest = {
        origins,
        destinations,
        travelMode: 'DRIVING',
        units: UnitSystem.METRIC,
        fields: ['distanceMeters', 'durationMillis', 'condition'],
    };

    // Show the request.
    document.getElementById('request')!.innerText = JSON.stringify(
        request,
        null,
        2
    );

    // Get the RouteMatrix response.
    const response = await RouteMatrix.computeRouteMatrix(request);

    // Show the response.
    document.getElementById('response')!.innerText = JSON.stringify(
        response,
        null,
        2
    );

    // Add markers for the origins.
    for (const origin of origins) {
        if (origin.location) {
            const pin = new PinElement({
                glyphText: 'O',
                glyphColor: 'white',
                background: '#137333',
                borderColor: 'white',
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                title: `Origin: ${origin.displayName}`,
            });
            marker.append(pin);
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }

    // Add markers for the destinations.
    for (const destination of destinations) {
        if (destination.location) {
            const pin = new PinElement({
                glyphText: 'D',
                glyphColor: 'white',
                background: '#C5221F',
                borderColor: 'white',
            });

            const marker = new AdvancedMarkerElement({
                map,
                position: destination.location,
                content: pin,
                title: `Destination: ${destination.displayName ?? 'Unknown'}`,
            });

            markers.push(marker);
            bounds.extend(destination.location);
        }
    }

    // Fit the map to the bounds of all markers.
    map.fitBounds(bounds);
}

void init();

JavaScript

// Initialize and add the map.
let map;
const markers = [];
const center = { lat: 51.55, lng: -1.8 };

async function init() {
    //  Request the needed libraries.
    const [
        { Map },
        { Place },
        { AdvancedMarkerElement, PinElement },
        { RouteMatrix },
        { LatLngBounds, UnitSystem },
    ] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes'),
        google.maps.importLibrary('core'),
    ]);

    const bounds = new LatLngBounds();

    map = new Map(document.getElementById('map'), {
        zoom: 8,
        center,
        mapId: 'DEMO_MAP_ID',
    });

    // Build the request using Place instances.
    const origin1 = new Place({
        id: 'ChIJ83WZp86p2EcRbMrkYqGncBQ', // Greenwich, London, UK
    });
    const origin2 = new Place({
        id: 'ChIJCSkVvleJc0gR8HHaTGpajKc', // Southampton, UK
    });
    const destinationA = new Place({
        id: 'ChIJYdizgWaDcUgRH9eaSy6y5I4', // Bristol, UK
    });
    const destinationB = new Place({
        id: 'ChIJ9VPsNNQCbkgRDmeGZdsGNBQ', // Cardiff, UK
    });

    await Promise.all([
        origin1.fetchFields({ fields: ['location', 'displayName'] }),
        origin2.fetchFields({ fields: ['location', 'displayName'] }),
        destinationA.fetchFields({ fields: ['location', 'displayName'] }),
        destinationB.fetchFields({ fields: ['location', 'displayName'] }),
    ]);

    const destinations = [destinationA, destinationB];
    const origins = [origin1, origin2];
    const request = {
        origins,
        destinations,
        travelMode: 'DRIVING',
        units: UnitSystem.METRIC,
        fields: ['distanceMeters', 'durationMillis', 'condition'],
    };

    // Show the request.
    document.getElementById('request').innerText = JSON.stringify(
        request,
        null,
        2
    );

    // Get the RouteMatrix response.
    const response = await RouteMatrix.computeRouteMatrix(request);

    // Show the response.
    document.getElementById('response').innerText = JSON.stringify(
        response,
        null,
        2
    );

    // Add markers for the origins.
    for (const origin of origins) {
        if (origin.location) {
            const pin = new PinElement({
                glyphText: 'O',
                glyphColor: 'white',
                background: '#137333',
                borderColor: 'white',
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                title: `Origin: ${origin.displayName}`,
            });
            marker.append(pin);
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }

    // Add markers for the destinations.
    for (const destination of destinations) {
        if (destination.location) {
            const pin = new PinElement({
                glyphText: 'D',
                glyphColor: 'white',
                background: '#C5221F',
                borderColor: 'white',
            });

            const marker = new AdvancedMarkerElement({
                map,
                position: destination.location,
                content: pin,
                title: `Destination: ${destination.displayName ?? 'Unknown'}`,
            });

            markers.push(marker);
            bounds.extend(destination.location);
        }
    }

    // Fit the map to the bounds of all markers.
    map.fitBounds(bounds);
}

void init();

CSS

/*
 * Always set the map height explicitly to define the size of the div element
 * that contains the map.
 */
/* Optional: Makes the sample page fill the window. */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#container {
    height: 100%;
    display: flex;
}

#sidebar {
    flex-basis: 15rem;
    flex-grow: 1;
    padding: 1rem;
    max-width: 30rem;
    height: 100%;
    box-sizing: border-box;
    overflow: auto;
}

#map {
    flex-basis: 0;
    flex-grow: 4;
    height: 100%;
}

#sidebar {
    flex-direction: column;
}

HTML

<html>
    <head>
        <title>Route matrix</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <div id="container">
            <div id="map"></div>
            <div id="sidebar">
                <h3 style="flex-grow: 0">Request</h3>
                <pre style="flex-grow: 1" id="request"></pre>
                <h3 style="flex-grow: 0">Response</h3>
                <pre style="flex-grow: 1" id="response"></pre>
            </div>
        </div>
    </body>
</html>

الحدود القصوى المسموح بها للطلب

تفرض طريقة computeRouteMatrix الحدود القصوى التالية للطلبات للحدود القصوى لنقاط المرور باستخدام عناوين أو مثيلات Place، وللسلع. السلع هي المسارات بين كل نقطة انطلاق ووجهة في مصفوفة المسارات، لذا فإنّ عدد السلع هو عدد نقاط الانطلاق مضروبًا في عدد الوجهات. على سبيل المثال، إذا كان لديك 10 نقاط انطلاق و10 وجهات، سيكون لديك 100 سلعة:

  • لا يمكن أن يتجاوز عدد السلع 625 للمسارات التي ليست مسارات TRANSIT.
  • إذا حدّدت مسارًا TRANSIT ، لا يمكن أن يتجاوز عدد السلع لا يمكن أن يتجاوز 100.
  • إذا حدّدت TRAFFIC_AWARE_OPTIMAL، لا يمكن أن يتجاوز عدد السلع 100.
  • إذا حدّدت نقاط انطلاق أو وجهات باستخدام عناوين أو مثيلات Place، يمكنك تحديد ما يصل إلى 50 إجماليًا بهذه الطريقة.

لمزيد من التفاصيل، يُرجى الاطّلاع على الحصول على مسار نقل عام.

مثال على طلب مصفوفة مسارات

يوضّح المثال التالي ComputeRouteMatrixRequest. ويُجري هذا المثال ما يلي:

  • يوضّح كيفية تحديد مصفوفة من نقطتَي انطلاق ونقطتَي مرور للوجهة. تحسب الطريقة مسارًا من كل نقطة انطلاق إلى كل وجهة، لذا تحتوي الاستجابة على أربعة مسارات.
    في المصفوفة، يكون العنصر الأول في الفهرس 0، والثاني في الفهرس 1، وهكذا.
  • تحديد الحقول المطلوب عرضها. في هذا المثال، تم ضبط الطلب لعرض durationMillis, distanceMeters, وcondition لكل مسار.

TypeScript

const destinations = [destinationA, destinationB];
const origins = [origin1, origin2];
const request: google.maps.routes.ComputeRouteMatrixRequest = {
    origins,
    destinations,
    travelMode: 'DRIVING',
    units: UnitSystem.METRIC,
    fields: ['distanceMeters', 'durationMillis', 'condition'],
};

JavaScript

const destinations = [destinationA, destinationB];
const origins = [origin1, origin2];
const request = {
    origins,
    destinations,
    travelMode: 'DRIVING',
    units: UnitSystem.METRIC,
    fields: ['distanceMeters', 'durationMillis', 'condition'],
};

تحتوي الاستجابة على أربعة مسارات محتملة لمجموعة نقاط مرور الانطلاق والوجهة، كما هو موضّح في المثال التالي:

"matrix": {
  "rows": [
    {
      "items": [
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 202587,
          "durationMillis": 10040000
        },
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 252734,
          "durationMillis": 12240000
        }
      ]
    },
    {
      "items": [
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 166135,
          "durationMillis": 6596000
        },
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 216282,
          "durationMillis": 8797000
        }
      ]
    }
  ]
}
    

حدِّد كل مسار في النتيجة باستخدام فهرس نقطة الانطلاق والوجهة للعثور على المقابل RouteMatrixItem في المصفوفة الثنائية الأبعاد. على سبيل المثال، سيكون RouteMatrixItem الذي يصف المسار المحسوب من نقطة الانطلاق في الفهرس 1 و الوجهة 0 في الطلب في العنصر الثاني من مصفوفة RouteMatrix.rows والعنصر الأول من مصفوفة RouteMatrixRow.items.

يوضّح مقتطف الرمز التالي كيفية تحديد RouteMatrixItem للعثور على المسار لنقطة انطلاق ووجهة معيّنتَين:

// Find the route for origin 'x' and destination 'y'.
const {matrix} = await RouteMatrix.computeRouteMatrix(request);
const myRouteMatrixItem = matrix.rows[x].items[y];
    

اختيار الحقول المطلوب عرضها

عند طلب مصفوفة مسارات، يجب استخدام قناع حقول لتحديد المعلومات التي يجب أن تعرضها الاستجابة.

يضمن استخدام قناع الحقول أيضًا عدم طلب بيانات غير ضرورية، ما يساعد بدوره في تقليل وقت استجابة الطلب وتجنُّب عرض معلومات لا يحتاجها نظامك.

حدِّد قائمة الحقول التي تحتاج إليها من خلال ضبط السمة ComputeRoutesMatrixRequest.fields، كما هو موضّح في مقتطف الرمز التالي:

fields: ['durationMillis', 'distanceMeters', 'condition'],
    

تحديد أقنعة الحقول التي يجب استخدامها

إليك كيفية تحديد الحقول التي تريد استخدامها وإنشاء أقنعة الحقول لها:

  1. اطلب جميع الحقول باستخدام قناع حقول ['*'].
  2. اطّلِع على التسلسل الهرمي للحقول في فئة RouteMatrixItem للحقول التي تريدها.
  3. أنشئ أقنعة الحقول باستخدام التسلسل الهرمي للحقول الموضّح في الخطوة السابقة، باستخدام هذا التنسيق:

    topLevelField[.secondLevelField][.thirdLevelField][...]

على سبيل المثال، بالنسبة إلى RouteMatrixItem هذا:

  "travelAdvisory": {
    "fuelConsumptionMicroliters": 0,
    "tollInfo": {
      "estimatedPrices": [
        {
          "currencyCode": "USD",
          "units": 4,
          "nanos": 400000000
        }
      ]
    }
  },
    

إذا أردت عرض حقل tollInfo فقط لـ RouteMatrixItem ، يكون قناع الحقول على النحو التالي:

fields: ['travelAdvisory.tollInfo']

إذا أردت بدلاً من ذلك طلب استهلاك الوقود المقدَّر، يكون قناع الحقول على النحو التالي:

fields: ['travelAdvisory.fuelConsumptionMicroliters']

إذا أردت طلب كليهما، يكون قناع الحقول على النحو التالي:

fields: ['travelAdvisory.fuelConsumptionMicroliters', 'travelAdvisory.tollInfo']

إذا أردت طلب المجموعة الكاملة من الإشعارات المتعلقة بالسفر، يكون قناع الحقول على النحو التالي:

fields: ['travelAdvisory']

طلب مصفوفة مسارات النقل العام

احصل على مصفوفة مسارات نقل عام تستخدم خيارات النقل العام المتاحة في الـ منطقة. قد تشمل خيارات النقل العام الحافلات والمترو والقطارات، من بين خيارات أخرى. لطلب مصفوفة مسارات نقل عام:

  • اضبط travelMode على TRANSIT
  • اطلب حقل travelAdvisory.

مزيد من المعلومات عن مسارات النقل العام.