سلام دوستان امیدوارم حالتون خوب باشد در این سری از آموزش برنامه نویسی اندروید به آموزش رسم مسیر و محاسبه فاصله بین دو مکان در Google Maps در برنامه نویسی اندروید می پردازیم همانطور که گفتیم بین دو مسیر فاصله را به دست آورده سپس در Google Map آن را رسم میکنیم ( این آموزش بخشی از برنامه هایی مانند اسنپ و تپسی است) در ادامه می توانید پیش نمایشی از آن را مشاهده کنید.

ابتدا توصیه می کنم آموزش اولیه مربوط به Google map را که در ادامه لینک آن را قرار میدهیم مطالعه کنید ! (گفته های قبلی تکرار نمی شوند)
آموزش کار با نقشه (Google map) در برنامه نویسی اندروید

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
سپس در همان فایل بررسی کنید کد زیر نیز وجود داشته باشد.
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
تغییری کدهای بالا ایجاد نکید وارد مسیر res/value شده در آنجا باید یک فایل به نام google_maps_api.xml وجود دارد اگر وجود نداشت یک فایل به همین نام ایجاد کرده و کدهای زیر را در آن قرار دهید.
<resources> <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">Your APi Key</string> </resources>
باید به جای Your APi Key در بالا Api Key به دست آورده را قرار دهید (باید به آموزش قبلی مراجعه کنید)
سپس در پوشه layout یک فایل به نام activity_maps.xml ایجاد شده است (اگر وجود نداشت بسازید و کدهای زیر را در آن قرار دهید. )
agment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
در کد بالا تغییری ایجاد نکنید.
یک فایل جاوا به نام JSONParserTask.java (برای پارس json) ایجاد کرده و کدهای زیر را در آن قرار دهید.
package ir.programchi;
import com.google.android.gms.maps.model.LatLng;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class JSONParserTask {
public List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<>() ;
JSONArray jRoutes;
JSONArray jLegs;
JSONArray jSteps;
try {
jRoutes = jObject.getJSONArray("routes");
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List path = new ArrayList<>();
for(int j=0;j<jLegs.length();j++){
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
for(int k=0;k<jSteps.length();k++){
String polyline = "";
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
for(int l=0;l<list.size();l++){
HashMap<String, String> hm = new HashMap<>();
hm.put("lat", Double.toString((list.get(l)).latitude) );
hm.put("lng", Double.toString((list.get(l)).longitude) );
path.add(hm);
}
}
routes.add(path);
}
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception e){
}
return routes;
}
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
}
کار کد بالا پارس یا تجزیه یک url است که در ادامه به آن اشاره می کنیم (این یک json پارسر سفارشی است نمی توانید برای پارس چیزهای دیگر از آن استفاده کنید البته با تغییر می شود از آن استفاده کرد).
باید یک اکتیویتی به نام MapsActivity.java داشته باشید اگر نبود آن را با همین نام بسازید و کدهای زیر را در آن قرار دهید.
package ir.programchi;
import android.graphics.Color;
import android.os.AsyncTask;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private LatLng delhi= new LatLng(28.6139,77.2090);
private LatLng chandigarh = new LatLng(30.7333,76.7794);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
private class FetchUrl extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
String data = "";
try {
data = downloadUrl(url[0]);
Log.d("Background Task data", data.toString());
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
parserTask.execute(result);
}
}
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
Log.d("downloadUrl", data.toString());
br.close();
} catch (Exception e) {
Log.d("Exception", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.addMarker(new MarkerOptions().position(chandigarh).title("Chandigarh"));
mMap.addMarker(new MarkerOptions().position(delhi).title("Delhi"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(delhi));
String str_origin = "origin=" + delhi.latitude + "," + delhi.longitude;
String str_dest = "destination=" + chandigarh.latitude + "," + chandigarh.longitude;
String sensor = "sensor=false";
String parameters = str_origin + "&" + str_dest + "&" + sensor;
String output = "json";
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
Log.d("onMapClick", url.toString());
FetchUrl FetchUrl = new FetchUrl();
FetchUrl.execute(url);
mMap.moveCamera(CameraUpdateFactory.newLatLng(delhi));
mMap.animateCamera(CameraUpdateFactory.zoomTo(7));
Location delhi_location = new Location("Delhi");
delhi_location.setLatitude(delhi.latitude);
delhi_location.setLongitude(delhi.longitude);
Location chandigarh_location = new Location("Chandigarh");
chandigarh_location.setLatitude(chandigarh.latitude);
chandigarh_location.setLongitude(chandigarh.longitude);
double distance = (delhi_location.distanceTo(chandigarh_location))* 0.000621371 ;
AlertDialog alertDialog = new AlertDialog.Builder(MapsActivity.this).create();
alertDialog.setTitle("Info");
alertDialog.setMessage("Distance between these two location is : "+distance +" miles");
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
Log.d("ParserTask",jsonData[0].toString());
JSONParserTask parser = new JSONParserTask();
Log.d("ParserTask", parser.toString());
routes = parser.parse(jObject);
Log.d("ParserTask","Executing routes");
Log.d("ParserTask",routes.toString());
} catch (Exception e) {
Log.d("ParserTask",e.toString());
e.printStackTrace();
}
return routes;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points;
PolylineOptions lineOptions = null;
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<>();
lineOptions = new PolylineOptions();
List<HashMap<String, String>> path = result.get(i);
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.RED);
Log.d("onPostExecute","onPostExecute lineoptions decoded");
}
if(lineOptions != null) {
mMap.addPolyline(lineOptions);
}
else {
Log.d("onPostExecute","without Polylines drawn");
}
}
}
}
لازم است ما latitude و longitude یا همان طول و عرض جغرافیایی هر دو مسیر را به دست بیاریم در بالا ما مسیر delhi به chandigarh را به دست آوردیم (در آموزش های بعدی آموزش به دست آوردن latitude و longitude توسط انتخاب کاربر را برای شما قرار می دهیم ) و در برنامه قرار دادیم سپس به api گوگل latitude و longitude را ارسال می کنیم و برگشت آن که یک json است را پارس می کنیم برای این کار از کلاس Async Task استفاده کردیم و در صورتی که json برگردد یک alert نمایش داده می شود.
این آموزش هم به پایان رسید.
موفق و پیروز باشید.
آموزش برنامه نویسی اندروید |
با سلام
ببخشید اگه بخواهیم مثلا یکی از این نقاط همون موقعیت فعلی خودمون باشه باید چه کار کنیم. بنده موقعیت فعلی رو می تونم نمایش بدم ولی اینکه یکی از نقاط رو موقعیت فعلی قرار بدم و نسبت به یه نقطه دیگه فاصبه رو بسنجم مشکل داره و فورس کلوز میده. لطفا راهنمایی بفرمایید. ممنون
با سلام
سپاسگزارم بابت آموزش عالیتان
من گام به گام مراحل بالا را انجام دادم و برنامه را ساختم. برنامه اجرا می شود و نقاط را هم نشان می دهد اما مسیر بین 2 نقطه را رسم نمی کند. لطفا راهنمایی نمایید
سپاسگزارم
سلام
ممنونم به خاطر آموزشتون
من نیز گام به گام مراحل بالا را انجام دادم و برنامه را ساختم. برنامه اجرا می شود و نقاط را هم نشان می دهد اما مسیر بین ۲ نقطه را رسم نمی کند.لطف میکنید بگید چه کاری باید انجام دهم؟
ممنونم