مسیریابی – B4A

Android SDK Resources

هدف از این بخش از پروژه، مسیریابی بین دو نقطه از نقشه، به وسیله سرویس مسیریابی نشان است. با استفاده از این سرویس، بهترین مسیر جهت رفتن از نقطه مبدا به نقطه مقصد محاسبه می شود.

برای آشنایی با وب سرویس مسیریابی نشان، میتوانید از لینک زیر استفاده کنید:

معرفی وب سرویس مسیریابی نشان

به منظور استفاده از سرویس های نشان، شما باید یک Api-Key در پنل توسعه دهندگان نشان ایجاد کرده و از آن در ارسال سرویس استفاده کنید.

سپس در فایل Main پروژه در قسمت Region Project Attributes خط زیر را اضافه کنید:

#AdditionalJar: common-release.aar
#AdditionalJar: gson-2.8.5.jar

اکتیویتی مسیریابی دارای تنها یک شیء نقشه است. 

جهت تعریف شیء نقشه در کد روی View ی مربوط به نقشه که نام آن در این مثال NeshanMapSdk1 است راست کلیک کرده و از منوی باز شونده Generate، گزینه Dim NeshanMapSdk1 as NeshanMapSdk را انتخاب میکنیم. پس از این عمل، شیء نقشه در فایل کد مربوط به اکتیویتی مسیریابی (RoutingActivity) در قسمت Globals اضافه میشود.

            Sub Globals
	'These global variables will be redeclared each time the activity is created.
	'These variables can only be accessed from this module.

	Private NeshanMapSdk1 As NeshanMapSdk
End Sub
        

نحوه عملکرد این اکتیویتی به این صورت است که ابتدا نقطه مبدا توسط Long click روی نقشه توسط کاربر دریافت شده و در یک متغیر به نام sourceLocation که از نوع Location است ذخیره میشود.

سپس با Long click مجدد کاربر روی نقشه، نقطه مقصد دریافت شده و در متغیری به نام destinationLocation ذخیره میشود. 

جهت پیاده سازی Event مربوط به LongClick روی نقشه کافیست به Visual Designer مربوط به اکتیویتی مسیریابی (RoutingActivity) رفته و روی شیء نقشه ای که اضافه کرده اید، راست کلیک کنید و از منوی بازشونده Generate گزینه mapLongClick(latLngObject As Objectرا انتخاب کنید. پس از انتخاب این گزینه، Event مربوط به لمس طولانی نقشه یا LongClick به اکتیویتی مسیریابی افزوده میشود. پس از این کار زمانی که روی نقشه لمس طولانی شود، این Event صدا زده میشود و پارامتر آن که از نوع Object است دارای مختصات جغرافیایی نقطه لمس شده میباشد.

پس از بدست آوردن هر 2 نقطه مبدا و مقصد، سرویس مسیریابی نشان را به صورت زیر صدا بزنید:

            NeshanMapSdk1.neshanDirection(API-KEY(String), Type(String), sourceLat(Double), sourceLng(Double), destinationLat(Double), destinationLng(Double), wayPoints(String), avoidTrafficZone(Boolean), avoidOddEvenZone(Boolean), alternative(Boolean), bearing(Int))
        

پارامترهای مربوط به سرویس neshanDirection:

API-KEY: کلید دسترسی ساخته شده در پنل توسعه دهندگان نشان

type: مشخص میکند که مسیریابی مخصوص به خودرو یا موتورسیکلت استفاده شود. مقدار آن میتواند car برای مسیریابی خودرو و motorcycle برای مسیریابی موتور باشد.

sourceLat: عرض جغرافیایی مربوط به مبدا

sourceLng: طول جغرافیایی مربوط به مبدا

destinationLat: عرض جغرافیایی مربوط به مقصد

destinationLng: طول جغرافیایی مربوط به مقصد

wayPoints: این پارامتر برای مشخص کردن نقاط میانی مسیر استفاده می‌شود. فرمت ارسال هر نقطه میانی به صورت latitude,longitude می‌باشد. در صورتی که بیش از یک نقطه میانی دارید با به صورت زیر آن‌ها را با علامت پایپ (|) از هم جدا کنید: latitude,longitude|latitude,longitude

این پارامتر اختیاری است و در صورتی که نمیخواهید آن را مقداردهی کنید کافیست یک رشته خالی (“”) به جای آن ارسال نمایید

avoidTrafficZone: مقادیر این پارامتر True یا False می‌تواند باشد. در صورتی که این پارامتر True باشد مسیر از داخل طرح ترافیک عبور نخواهد کرد. همچنین در صورتی که مقصد داخل طرح ترافیک باشد هیچ مسیری پیدا نمی‌شود.

avoidOddEvenZone: مقادیر این پارامتر True یا False می‌تواند باشد. در صورتی که این پارامتر True باشد مسیر از داخل طرح زوج و فرد عبور نخواهد کرد. همچین در صورتی که مقصد داخل طرح ترافیک باشد هیچ مسیری پیدا نمی‌شود.

alternative: مقادیر این پارامتر True یا False می‌تواند باشد. در صورتی که این پارامتر True باشد و مسیرهای جایگزین برای نقاط مشخص شده وجود داشته باشد این مسیرها در پاسخ ارائه خواهند شد.

bearing: این فیلد که مقدار آن میتواند بین ۰ تا ۳۶۰ باشد(زاویه ساعت گرد نسبت به شمال)، جهت را هنگام شروع مسیر یابی مشخص می نماید. این مقدار منجر به مسیر یابی بهینه تر بر اساس جهت شروع مسیر یابی در خیابان میشود. 

در صورتی که نمیخواهید جهت را هنگام شروع مسیریابی تعیین کنید، مقدار 1- را برای این پارامتر ارسال نمایید.

خروجی سرویس

پس از صدا زدن سرویس مسیریابی، در صورتی که خطایی در سرویس رخ ندهد خروجی سرویس در تابعی به نام directionReceived برگردانده خواهد شد و در صورتی که خطایی در ارسال یا دریافت سرویس رخ دهد، خروجی سرویس در تابعی به نام directionResultReceivingError برگردانده خواهد شد.

جهت دریافت نتیجه سرویس و خطا، باید این 2 تابع را به کد خود اضافه نمایید.

خروجی:

            Sub directionReceived(neshanDirectionResultObject As Object)

End Sub
        

خطا:

            Sub directionResultReceivingError(errorObject As Object)

End Sub
        

استخراج نقاط مسیر:

پس از دریافت خروجی در تابع directionReveived خروجی در پارامتر این تابع که neshanDirectionResultObject نام دارد بازگردانده میشود.

ماهیت متغیر neshanDirectionResultObject از نوع Object است. برای استخراج مقادیر از این متغیر باید آن را تبدیل به یک JavaObject کنید. برای تبدیل این متغیر به JavaObject کافیست آن را به یک متغیر از نوع JavaObject به صورت زیر اختصاص دهید:

            Dim neshanDirectionResultJo As JavaObject = neshanDirectionResultObject
        

نمونه ای از خروجی JSON سرویس مسیریابی به صورت زیر است که متغیر neshanDirectionResultJo نیز حاوی این محتویات است:

            {
  "routes": [
    {
      "legs": [
        {
          "summary": "آزادی - ولیعصر",
          "distance": {
            "value": 8998,
            "text": "۹ کیلومتر"
          },
          "duration": {
            "value": 2012,
            "text": "۳۴ دقیقه"
          },
          "steps": [
            {
              "name": "عضدی جنوبی",
              "instruction": "در جهت شرق در عضدی جنوبی قرار بگیرید",
              "distance": {
                "value": 46,
                "text": "۴۶ متر"
              },
              "duration": {
                "value": 11,
                "text": "کمتر از ۱ دقیقه"
              },
              "polyline": "qxu|EkpcjJb@{@Tc@b...",
              "maneuver": "depart",
              "start_location": [
                51.344035,
                35.695452
              ]
            }
          ]
        }
      ],
      "overview_polyline": {
        "points": "qwzxEgckxHBeAWEDq ..."
      }
    }
  ]
}
        

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

در مثال بالا خروجی شامل تنها یک مسیر است. متغیر neshanDirectionResultJo شامل اجزای JSON بالاست که توسط متد GetField و GetFieldJO میتوان به آنها دسترسی داشت.

با توجه به مثال بالا، برای دریافت مقادیر مربوط به جزء routes که در متغیر neshanDirectionResultJo قرار دارد به صورت زیر عمل میکنیم:

            neshanDirectionResultJo.GetFieldJO("dRoutes")
        

خروجی متد بالا لیستی از مسیرهای یافت شده توسط سرویس مسیریابی است.

حال از نمونه JSON ذکر شده در بالا، مسیر را استخراج کرده و آن را روی نقشه به صورت زیر ترسیم کنید:

            Sub directionReceived(neshanDirectionResultObject As Object)
	Private neshanDirectionResultJo As JavaObject = neshanDirectionResultObject
	Private directionResultLegs As List = neshanDirectionResultJo.GetFieldJO("dRoutes").RunMethodJO("get",Array(0)).GetFieldJO("dRouteLegs")
	
	Private polylinesPoints As List
	polylinesPoints.Initialize
	For Each directionResultLeg As JavaObject In directionResultLegs
		Private directionStepList As List = directionResultLeg.GetField("dLegSteps")
		For Each directionStep As JavaObject In directionStepList
			polylinesPoints.AddAll(NeshanMapSdk1.decodePolyline(directionStep.GetField("dStepPolyline")))
		Next
	Next
	NeshanMapSdk1.drawLine(polylinesPoints,NeshanMapSdk1.generateLineStyle("#00ff00",10))
	Dim loc As Location = polylinesPoints.Get(0)
	NeshanMapSdk1.moveCamera(loc.Latitude,loc.Longitude,0.5)
End Sub
        

در خط سوم از تکه کد بالا، مقادیر لیست routes توسط متد GetFieldJO از متغیر neshanDirectionResultJo در قالب یک متغیر JavaObject استخراج میشود. سپس روی JavaObject بدست آمده متد RunMethodJO برای صدا زدن متد جاوایی get  که برای استخراج یک مورد مشخص از لیست استفاده میشود، صدا زده میشود. مقدار Array(0) به منظور ارسال پارامتر به متد جاوایی get استفاده شده است و در این مثال مقدار 0 را به متد جاوایی get ارسال میکند به این معنی که اولین مسیر از مسیرهای دریافتی را  در قالب یک JavaObject استخراج میکند. سپس روی JavaObject بدست آمده متد GetFieldJO را صدا زده و مقادیر legs را از آن استخراج کرده و نتیجه را داخل متغیر directionResultLegs میریزد.

با توجه به توضیحات سرویس مسیریابی، فیلد polyline که یکی از اجزای steps است، شامل polyline مسیر به صورت encode شده است. برای استفاده از آن برای ترسیم خطوط مسیر روی نقشه باید آن را توسط متد decodePolyline که روی شیء نقشه صدا زده میشود، decode کرد. پس از decode کردن polyline خروجی شامل نقاط مربوط به خطوط است که در مثال بالا در لیستی به نام polylinesPoints ریخته میشود. و در پایان لیست polylinePoints به متد drawLine داده شده و خطوط مسیر بدست آمده از سرویس روی نقشه ترسیم میشود.

نحوه نام گذاری فیلدهای مربوط به هر سرویس به این صورت است که ابتدا حروف ابتدایی نام سرویس مورد نظر به صورت camel case آورده شده سپس نام فیلد پس از آن قرار میگیرد.

در تکه کد بالا همانطور که نام سرویس direction است، ابتدای فیلدها حروف قرار گرفته است.

نام فیلدها:

نام فیلد در سرویس

            routes
	legs
		summary
		distance
			value
			text
		duration
			value
			text
		steps
			name
			instruction
			distance
				value
				text
			duration
				value
				text
			polyline
			maneuver
			start_location
	overview_polyline
		points
        

نام فیلد در اس دی کی

            dRoutes
	dRouteLegs
		dLegSummary
		dLegDistance
			value
			text
		dLegDuration
			value
			text
		dLegSteps
			dStepName
			dStepInstruction
			dStepDistance
				value
				text
			dStepDuration
				value
				text
			dStepPolyline
			dStepManeuver
			dStartLocation
	dRouteOverviewPolyline
		dOverviewPolylinePoints