سلام دوستان امیدوارم حالتون خوب باشد در این سری از آموزش برنامه نویسی اندروید به آموزش رسم مسیر و محاسبه فاصله بین دو مکان در Google Maps در برنامه نویسی اندروید می پردازیم همانطور که گفتیم بین دو مسیر فاصله را به دست آورده سپس در Google Map آن را رسم میکنیم ( این آموزش بخشی از برنامه هایی مانند اسنپ و تپسی است) در ادامه می توانید پیش نمایشی از آن را مشاهده کنید.
ابتدا توصیه می کنم آموزش اولیه مربوط به Google map را که در ادامه لینک آن را قرار میدهیم مطالعه کنید ! (گفته های قبلی تکرار نمی شوند)
آموزش کار با نقشه (Google map) در برنامه نویسی اندروید
ابتدا در هنگام ساخت پروژه جدید همانند عکس زیر Google Map Activity را انتخاب کنید.
این کار باعث می شود برخی از فایل ها به طور اتوماتیک ایجاد شوند.
بعد از اینکار باید Api Key را به دست بیارید در آموزش قبلی نحوه به دست آوردن آن گفته شده است در اینجا دیگر آن را تکرار نمی کنیم.
وارد AndroidManifest.xml شده و بررسی کنید دسترسی زیر اضافه شده باشد اگر نبود آن را اضافه کنید.
AndroidManifest.xml
1 | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> |
1 2 3 | <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" /> |
1 2 3 | <resources> <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">Your APi Key</string> </resources> |
سپس در پوشه layout یک فایل به نام activity_maps.xml ایجاد شده است (اگر وجود نداشت بسازید و کدهای زیر را در آن قرار دهید. )
activity_maps.xml
1 2 3 4 5 6 7 8 | 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) ایجاد کرده و کدهای زیر را در آن قرار دهید.
JSONParserTask.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 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; } } |
باید یک اکتیویتی به نام MapsActivity.java داشته باشید اگر نبود آن را با همین نام بسازید و کدهای زیر را در آن قرار دهید.
MapsActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | 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"); } } } } |
این آموزش هم به پایان رسید.
موفق و پیروز باشید.
با سلام
ببخشید اگه بخواهیم مثلا یکی از این نقاط همون موقعیت فعلی خودمون باشه باید چه کار کنیم. بنده موقعیت فعلی رو می تونم نمایش بدم ولی اینکه یکی از نقاط رو موقعیت فعلی قرار بدم و نسبت به یه نقطه دیگه فاصبه رو بسنجم مشکل داره و فورس کلوز میده. لطفا راهنمایی بفرمایید. ممنون
با سلام
سپاسگزارم بابت آموزش عالیتان
من گام به گام مراحل بالا را انجام دادم و برنامه را ساختم. برنامه اجرا می شود و نقاط را هم نشان می دهد اما مسیر بین 2 نقطه را رسم نمی کند. لطفا راهنمایی نمایید
سپاسگزارم
سلام
ممنونم به خاطر آموزشتون
من نیز گام به گام مراحل بالا را انجام دادم و برنامه را ساختم. برنامه اجرا می شود و نقاط را هم نشان می دهد اما مسیر بین ۲ نقطه را رسم نمی کند.لطف میکنید بگید چه کاری باید انجام دهم؟
ممنونم