جستجو در مسیر با مکان‌های API

این سند نحوه یافتن یک هتل، یک رستوران یا یک پمپ بنزین را در طول یک مسیر برنامه ریزی شده شرح می دهد. یاد خواهید گرفت که چگونه از Routes API برای دریافت چند خط مسیر استفاده کنید و با درخواست Places API Search Along Route (SAR) از آن استفاده کنید. همچنین یاد خواهید گرفت که چگونه با تنظیم مبدا جستجو در طول مسیر، به عنوان مثال 2 ساعت پس از سفر، بهترین نتایج را به دست آورید.

Routes API

به منظور جستجوی مکان‌ها در طول مسیر، از Routes API استفاده می‌کنیم. داده مسیر از پاسخ Routes API یک سری مختصات LatLong از مبدا تا مقصد است. داده های مسیر شامل پاها و مراحلی است که شبکه جاده را دنبال می کند.

مسیرها نیز به‌عنوان یک چند خط کدگذاری شده بازگردانده می‌شوند که به عنوان پارامتر ورودی به درخواست SAR ارسال می‌کنید. رمزگذاری Polyline یک الگوریتم فشرده سازی با اتلاف است که به شما امکان می دهد مجموعه ای از مختصات را به عنوان یک رشته واحد ذخیره کنید. دریافت پلی لاین از Routes API اجباری نیست. می‌توانید داده‌ها را خودتان ایجاد کنید، اما برای اهداف این مثال، Routes API راهی سریع و مطمئن برای دریافت داده‌های مورد نیاز است.

در این آموزش از مسیر لندن (-37.8167,144.9619) به منچستر (-37.8155, 144.9663) استفاده می کنیم.

Route from London to Manchester

مسیر در مثال: لندن به منچستر

مرحله 1: یک مسیر از Routes API دریافت کنید

برای دریافت مسیر از Routes API، باید اطلاعات زیر را ارائه دهید:

  • محل مبدا و مقصد
  • نحوه حمل و نقل (رانندگی، پیاده روی و ...)
  • هر نقطه بین راهی (اختیاری)
  • هر گونه ترجیحی (اجتناب از عوارض، اجتناب از بزرگراه ها و غیره)
  • اولویت مسیریابی آگاه از ترافیک دقیق‌ترین تخمین‌ها را به شما می‌دهد، اما از نظر محاسباتی عملیات سنگین‌تری دارد و بنابراین به تأخیر پاسخ می‌افزاید.
{"origin":{
    "location": {
        "latLng":{
            "latitude":  -37.8167,
            "longitude": 144.9619
        }
    }
},
"destination":{
    "location": {
        "latLng":{
            "latitude":-37.8155,
            "longitude": 144.9663
        }
    }
},
"routingPreference":"TRAFFIC_AWARE",
"travelMode":"DRIVE"
}

هنگام برقراری تماس، مطمئن شوید که فیلد "encodedPolyline" را در ماسک فیلد هدر قرار دهید.

headers = {
    "Content-Type": "application/json",
    "X-Goog-FieldMask": "routes.distanceMeters,routes.duration,routes.legs,routes.polyline.encodedPolyline"
}

مستندات کامل با نمونه هایی از نحوه بدست آوردن مسیر و بدست آوردن چند خط مسیر .

هنگامی که این اطلاعات را در درخواست ارائه کردید، Routes API یک شی مسیر را برمی گرداند. شی route حاوی اطلاعات زیر خواهد بود:

  • کل مسافت مسیر
  • کل طول مسیر
  • پاها و پله های مسیر
  • چند خط کدگذاری شده مسیر، پاها و مراحل.
{
  "routes": [
    {
      "legs": [
        {
          "distanceMeters": 321799,
          "duration": "15401s",
          "staticDuration": "14518s",
          "polyline": {
            "encodedPolyline": "y_kyH`_XOr@q@xKGnBBZ|AlGPj@Y^k@^MEqAfAQLK?eI … <rest of content removed for readability>"
          },
          "startLocation": {
            "latLng": {
              "latitude": 51.507334500000006,
              "longitude": -0.1280107
            }
          },
          "endLocation": {
            "latLng": {
              "latitude": 53.4808513,
              "longitude": -2.2425864
            }
          },
          "steps": [
            {
              "distanceMeters": 320,
              "staticDuration": "82s",
              "polyline": {
                "encodedPolyline": "y_kyH`_XOr@q@xKGnBBZ|AlG"
              },
              "startLocation": {
                "latLng": {
                  "latitude": 51.507334500000006,
                  "longitude": -0.1280107
                }
              },
              "endLocation": {
                "latLng": {
                  "latitude": 51.507207,
                  "longitude": -0.1323681
                }
              },
              "navigationInstruction": {
                "maneuver": "DEPART",
                "instructions": "Head northwest on Trafalgar Sq/A4 toward Spring Gardens\nContinue to follow A4\nLeaving toll zone\nEntering toll zone\nLeaving toll zone in 210m at Haymarket"
              },
              "localizedValues": {
                "distance": {
                  "text": "0.3 km"
                },
                "staticDuration": {
                  "text": "1 min"
                }
              },
# rest of the response removed for readability

مرحله 2: جستجو در طول درخواست مسیر

Places API Text Search دارای یک درخواست جستجو در مسیر است که به شما امکان می دهد مکان ها را در طول مسیر جستجو کنید. برای انجام درخواست جستجو در طول مسیر، باید حداقل اطلاعات زیر را ارائه دهید:

  • فیلد ماسک که فیلدهای آن در پاسخ بازگردانده می شود
  • یک کلید API معتبر برای API فعال در کنسول Google Cloud
  • جستجوی رشته متنی نشان می دهد که به دنبال چه مکان هایی هستید، به عنوان مثال "رستوران گیاهی تند"
  • چند خط کدگذاری شده مسیر، از فراخوان قبلی Routes API بازیابی شده است
  • نشانی وب برای نقطه پایانی API جستجوی متن مکان‌ها
import requests

url = 'https://places.googleapis.com/v1/places:searchText'
api_key = 'YOUR_API_KEY'  # Replace with your actual API key
route_polyline = 'YOUR_ROUTE_POLYLINE'  # Replace with your encoded route polyline

headers = {
    'Content-Type': 'application/json',
    'X-Goog-Api-Key': api_key,
    'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel'
}

data = {
    "textQuery":
 "Spicy Vegetarian Food",
    "searchAlongRouteParameters": {
        "polyline": {
            "encodedPolyline": route_polyline
        }
    }
}

response = requests.post(url, headers=headers, json=data)

داده های درخواست نمونه

درخواست جستجو در طول مسیر، فهرستی از مکان‌هایی را که در طول مسیر قرار دارند، برمی‌گرداند. در اینجا بخش کوتاهی از داده های مثال آورده شده است. طول پاسخ را می توان با تنظیم حداکثر تعداد پارامترهای نتایج و افزودن فیلدهای بیشتر محدود کرد البته میزان داده های دریافتی را افزایش می دهد. برای جزئیات بیشتر درباره پاسخ Places API به مستندات مراجعه کنید.

{
  "places": [
    {
      "formattedAddress": "33 Haymarket, London SW1Y 4HA, UK",
      "displayName": {
        "text": "xxx",
        "languageCode": "en"
      }
    },
    {
      "formattedAddress": "224 Piccadilly, London W1J 9HP, UK",
      "priceLevel": "PRICE_LEVEL_MODERATE",
      "displayName": {
        "text": "yyy",
        "languageCode": "en"
      }
    },
    {
      "formattedAddress": "63 Neal St, London WC2H 9PJ, UK",
      "displayName": {
        "text": "zzz",
        "languageCode": "en"
      }
    },

داده های پاسخ نمونه

خلاصه مسیریابی و زمان های انحرافی

یافتن فقط مکان‌ها عالی است، اما اضافه کردن اطلاعات مربوط به مدت زمان رفتن به این مکان‌ها مفید خواهد بود. SAR در Places API Text Search همچنین می‌تواند یک فیلد خلاصه مسیریابی را برگرداند که هم مدت و هم مسافت سفر را در بر می‌گیرد. فیلد داده خلاصه مسیریابی فرزند ریشه پاسخ است، بنابراین نباید پیشوند " مکان " را در ماسک فیلد وارد کنید.

'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel,routingSummaries'

برای به دست آوردن خلاصه ها، باید پارامتر مکان مبدا را نیز برای جستجو ارائه دهید که برای محاسبات استفاده می شود.

"routingParameters": {
      "origin": {
        "latitude":  -37.8167,
        "longitude": 144.9619
      }
    }

هنگامی که پاسخ را دریافت می کنید، یک بخش جدید با خلاصه مسیریابی دارد که شامل پاهایی است که مدت و فاصله آنها بر حسب متر است.

"routingSummaries": [
    {
      "legs": [
        {
          "duration": "662s",
          "distanceMeters": 3093
        }
      ]
    },

در ادامه نگاهی داریم به اینکه چگونه می‌توانید تعیین کنید که در طول مسیر جستجو را از کجا شروع کنید.

مرحله 3: 2 ساعت در طول مسیر موقعیت مکانی را دریافت کنید

یک مورد استفاده معمولی را در نظر بگیرید که در آن راننده می خواهد رستوران ها را نه در ابتدای مسیر، بلکه در پایین تر از جاده پیدا کند. در مثال ما، مسافت از لندن تا منچستر حدود 4 ساعت است. راننده می خواهد یک رستوران 2 ساعته در طول مسیر پیدا کند. این درخواست برای ما مدت زمان 120 دقیقه * 60 ثانیه = 7200 ثانیه را دریافت می کند.

در پاسخ Routes API ما مدت زمان هر پا از مسیر و هر مرحله از یک پا را داریم. مطمئن شوید که فیلد " پاها " را در ماسک فیلد در درخواست خود لحاظ کنید. پاها و پله ها را حلقه بزنید تا مدت زمان انباشته شده به حداکثر 2 ساعت یا 7200 ثانیه برسد. سپس ما پا و مرحله را پیدا کرده ایم که باید به عنوان مبدا درخواست SAR تنظیم شود

برای سرعت بخشیدن به کار خود، ممکن است بخواهید کتابخانه چند خطی را برای پایتون امتحان کنید. می‌توانید از آن برای دریافت مختصات از فیلد داده « polyline.endodedPolyline» استفاده کنید.

دستورات زیر را در ترمینال محیط خود اجرا کنید.

> pip install polyline
import requests
import polyline

# We've covered getting a Routes API response earlier,
data = response.json()

  # Extract the first route and its encoded polyline
  route = data["routes"][0]
  polyline_points = polyline.decode(route["polyline"]["encodedPolyline"])

  # Calculate total duration of the route in seconds
  total_duration_seconds = route["duration"]

  # Calculate the desired time offset in seconds, 2h = 120 minutes * 60
  desired_time_offset_seconds = time_offset_minutes * 60

  # Iterate through the legs and steps to find the point at the desired time offset
  elapsed_time_seconds = 0
  for leg in route["legs"]:
      for step in leg["steps"]:
          step_duration_seconds = step["staticDuration"]

          # Check if the desired time offset falls within this step, remove last "s" from string and convert to int
          second_value = int(step_duration_seconds[:-1])
          if elapsed_time_seconds + second_value >= desired_time_offset_seconds:
              # Interpolate to find the exact point within the step
              fraction_of_step = (desired_time_offset_seconds - elapsed_time_seconds) / second_value
              step_polyline_points = polyline.decode(step["polyline"]["encodedPolyline"])
              index = int(len(step_polyline_points) * fraction_of_step)
              return step_polyline_points[index]

          elapsed_time_seconds += second_value

  # If the point is not found (e.g., time offset exceeds route duration)
  return None

اکنون که موقعیت مکانی را در مسیر پیدا کرده ایم که 2 ساعت مانده به سفر است، می توانیم از آن در درخواست استفاده کنیم. به سادگی عرض و طول جغرافیایی را در پارامتر "origin" اضافه کنید، که به نوبه خود بخشی از پارامتر "routingParameters" است. فیلد داده "routingSummaries" که قبلا به آن پرداختیم توصیه می شود. همچنین می‌توانید پارامترهای اضافی مانند حالت سفر و دستورالعمل‌ها را اضافه کنید تا در صورت تمایل از پرداخت عوارض جلوگیری کنید.


"routingParameters": {
    "origin": {
      "latitude": xx.xxxx,
      "longitude": yy.yyyy
    },
    "travelMode":"DRIVE",
    "routeModifiers": {
      "avoidTolls": true
    }
  }

Route with search results

نتایج نمونه (نماد ماشین برای نشان دادن منبع جستجو اضافه شده است).

همانطور که در تصویر می بینید، API مکان هایی را که به انتهای مسیر تعصب دارند، باز می گرداند، نتایجی که از اواسط سفر شروع می شوند. جستجو همچنان توسط همان داده‌های پلتفرم نقشه‌های گوگل که ارتباط و فاصله مکان را در میان عوامل دیگر در نظر می‌گیرد، تقویت می‌شود.

نتیجه گیری

در این آموزش یاد گرفتیم که چگونه دو API پلتفرم Google Maps، مسیرها و مکان‌ها را با هم ترکیب کنیم تا بعد از 2 ساعت سفر، مکان‌هایی برای غذا خوردن پیدا کنیم. مراحلی که باید انجام شود عبارتند از دریافت یک چند خط کدگذاری شده حاوی مختصات طول و عرض جغرافیایی برای هر مرحله از مسیر و تنظیم مبدا درخواست جستجو در طول مسیر برای دریافت بهترین نتایج.

این ویژگی یک ابزار قدرتمند جدید را به جستجوی متن موجود و جستجوی نزدیک موجود در Places API اضافه می کند. پیگیری منطقی اضافه کردن خدمات موقعیت مکانی خواهد بود به طوری که ممکن است از موقعیت مکانی راننده به عنوان نقطه شروع برای یافتن منبع جستجوی بهینه استفاده کنید. علاوه بر این، این ویژگی با دستیار صوتی داخل خودرو کاملاً کار می‌کند تا گزینه‌های غذاخوری دلخواه خود را با آن صدا کنید.

اقدامات بعدی

پیشنهاد برای مطالعه بیشتر:

مشارکت کنندگان

گوگل این سند را حفظ می کند. مشارکت کننده زیر در اصل آن را نوشته است.

نویسنده اصلی: Mikko Toivanen | مهندس راه حل های پلتفرم نقشه های گوگل