Günümüzde konum bilgisi kullanarak hayatımızı birçok alanda kolaylaştırması sağlayan yazılımlar bulunmaktadır. Mobil uygulamalarda GPS, araba kullanırken ya da yaya olarak yürürken, ulaşmak istediğimiz noktaya gidebilmek için yol tarifi yapması, bulunduğunuz konum çevresinde en yakın eczaneye ulaşmak gibi birçok konuda hayatımızı kolaylaştırmaktadır.
Bu makalemde, bir Android uygulamasında Google Directions API ‘yi kullanarak haritada belirlenen iki nokta arasında nasıl bir rota çizileceğini ve bu rotaya ne kadar sürede varılacağını göstereceğim.
Örnek projemizi kodlamaya başlamadan önce bazı işlemler yapmamız gerekmektedir.Bu işlemleri sırayla yapmaya başlayalım.
1- Google Play Services Yükleme
Google haritayla ilgili bir geliştirme yapacağımızdan dolayı, Google Play Services yüklememiz gerekmektedir. Bunun için Tools->Sdk manager’ı açıp Sdk Tools bölümünden Google Play Services işaretleyip, yükleme işlemini gerçekleştirin.
2- Google Maps API Key Oluşturma
3-Gerekli Kütüphanelerin Eklenmesi
Android Studio Ide ile oluşturduğum projemin app dizinin altındaki build.gradle dosyasını açıyoruz. Dependencies kod bloklarının arasına aşağıdaki kodları yerleştirerek Google Play services kütüphanesini yüklüyoruz.
1 |
implementation 'com.google.android.gms:play-services-maps:17.0.0' |
4-AndroidManifest Dosyasına İlgili Ayarları Ekleme
Kullanıcının konumu belirlemek için izin tanımlamamız gerekir. Aşağıdaki izin kodunu da AndroidManifest.xml dosyasında application tag’nin üst kısmına yerleştirin.
1 |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> |
AndroidManifest dosyasına, daha önce üretmiş olduğumuz Google API Key’i ekleme işlemini yapacağız. Application tag arasına aşağıda görmüş olduğunuz meta-data tag kodunun içindeki value özelliğine Google API Key’i ekleyeniz.
1 2 |
<meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyBconZdqpSflHNcs6t-btfk0Rlo1Lex7wo" /> |
5-Xml Kodları
Haritayı gösterebilmek için SupportMapFragment sınıfını fragment ile kullanıyoruz.
1 2 3 4 5 6 7 8 |
<?xml version="1.0" encoding="utf-8"?> <fragment 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" /> |
4-Java Kodları
İlgili rotayı çizebilmek için ilk önce Google Map Directions web servisine API Key, başlangıç ve varış noktalarının konum bilgilerini bir url ile göndermeniz gerekir. İlgili url ile web servise bağlandığınızda, rotayı ne kadar sürede bitirebileceğiniz, rotanın kaç km olduğu, yol tarifleri hakkında detaylı bilgiler json verisi halinde gelecektir. Bu kısmı ve rotanın harita çizilmesi MainActivity sınıfında yapılmıştır. Detaylı anlatım kodlarda bulunmaktadır.
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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
import androidx.fragment.app.FragmentActivity; import android.content.SharedPreferences; import android.graphics.Color; import android.os.*; import android.preference.PreferenceManager; import android.widget.Toast; import com.google.android.gms.maps.*; import com.google.android.gms.maps.model.*; import org.json.JSONObject; import java.io.*; import java.net.*; import java.util.*; public class MainActivity extends FragmentActivity implements OnMapReadyCallback { private GoogleMap mMap; private LatLng mOrigin; private LatLng mDestination; private Polyline mPolyline; ArrayList<LatLng> mMarkerPoints; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // SupportMapFragment ile haritayı yükleyeceğimiz arayüz elemanını tanımlıyoruz SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); mMarkerPoints = new ArrayList<>(); } //Harita üzerinde yolun başlangıç ve bitiş noktasını imleçler ile işaretleyerek seçme @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng point) { // Her lokasyon yolunu çizme işleminden sonra yeni yol çizimi için harita refresh yapılıyor if(mMarkerPoints.size()>1){ mMarkerPoints.clear(); mMap.clear(); } mMarkerPoints.add(point); //İmleçleri oluşturan sınıfı tanımladık MarkerOptions options = new MarkerOptions(); //İmleci, haritada belirtilen noktalara eklenmesi için ilgili yerin değerini atadık options.position(point); //DirectionsJSONParser sınıfında, yol süresi değerini SharedPreferences ile taşıyıp // imleçde gösterdik SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); options.title("Duration: " +preferences.getString("duration", null)); /** * İmleçlerin görsellerini belirleme, Başlangıç imlecini yeşil * lokasyonu bitişini belirten imleç ise kırmızı olarak belirledim */ if(mMarkerPoints.size()==1){ options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); }else if(mMarkerPoints.size()==2){ options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); } // Haritada marker(imleç) ekleniyor mMap.addMarker(options); // Google Directions web servis urlsini hazırlayan ve web servisi kullanan metodu çağırdık if(mMarkerPoints.size() >= 2){ mOrigin = mMarkerPoints.get(0); mDestination = mMarkerPoints.get(1); drawRoute(); } } }); } // Google Directions API den konum datalarını kullanabilmek için web servis ile //bağlantı kuracağımız url hazırlayan metodu çağırdık ve web servisi çalıştırdık private void drawRoute(){ String url = getDirectionsUrl(mOrigin, mDestination); DownloadTask downloadTask = new DownloadTask(); downloadTask.execute(url); } //Haritada belirttiğiniz başlangeç ve bitiş imleçlerinin koordinatlarını API Key ile kullanarak //çizilecek düzergah ile ilgili bilgileri elde etmek adına url olusturan metod private String getDirectionsUrl(LatLng origin,LatLng dest){ String str_origin = "origin="+origin.latitude+","+origin.longitude; String str_dest = "destination="+dest.latitude+","+dest.longitude; // API Key parametre olarak hazırlama String key = "key=" +"AIzaSyBconZdqpSflHNcs6t-btfk0Rlo1Lex7wo"; String parameters = str_origin+"&"+str_dest+"&"+key; String output = "json"; // Oluşturduğumuz parametreleri kullanarak url yi oluşturuyoruz String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters; return url; } private String downloadUrl(String strUrl) throws IOException { String data = ""; InputStream iStream = null; HttpURLConnection urlConnection = null; try{ // Hazırladığımız url yi kullanarak web servise Http bağlantısı ile sağlıyoruz URL url = new URL(strUrl); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.connect(); // webservisden gelen json datayı okuyup, data değişkenine atadık iStream = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); StringBuffer sb = new StringBuffer(); String line = ""; while( ( line = br.readLine()) != null){ sb.append(line); } //json veriyi data değişkenine atadıkve metodda return yaptık data = sb.toString(); br.close(); }catch(Exception e){ //Log.d("Exception on download", e.toString()); }finally{ iStream.close(); urlConnection.disconnect(); } return data; } /** Bu sınıf da, Google Directions URL kullanarak, rotanın kaç km. olduğu, ne kadar sürede gidilebildiği * gibi bilgileri barındıran json datayı çektik */ private class DownloadTask extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... url) { String data = ""; try{ data = downloadUrl(url[0]); }catch(Exception e){ //Log.d("Background Task",e.toString()); } return data; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); //Google Directions bilgisini, JSON formatını parse ederek almayı sağlayan sınıf ParserTask parserTask = new ParserTask(); parserTask.execute(result); } } /** Bu sınıf Google Directions bilgisini, JSON formatını parse ederek almayı sağlar */ 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]); //DirectionsJSONParser sınıfında tüm json çözümlenir. DirectionsJSONParser parser = new DirectionsJSONParser(); routes = parser.parse(jObject,MainActivity.this); }catch(Exception e){ e.printStackTrace(); } return routes; } // Json çözümlendikten sonra, harita üzerinde rotayı(path) çizmeyi sağlayan metod @Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { ArrayList<LatLng> points = null; PolylineOptions lineOptions = null; for(int i=0;i<result.size();i++){ points = new ArrayList<LatLng>(); 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); } //PolylineOptions ile rota üzerinde noktalar ekleyerek, çizginin rengini ve genişliğini belirleme lineOptions.addAll(points); lineOptions.width(8); lineOptions.color(Color.RED); } if(lineOptions != null) { if(mPolyline != null){ mPolyline.remove(); } mPolyline = mMap.addPolyline(lineOptions); }else Toast.makeText(getApplicationContext(),"Rota bulanamadı", Toast.LENGTH_LONG).show(); } } } |
DirectionsJSONParser sınıfında ise web servisden gelen Json veriyi çözümleyip, içindeki bilgileri ArrayList yapısına ekleyerek MainActivity sınıfında kullanılması sağlanmıştır. Ek olarak DirectionsJSONParser sınıfında Json veriden gelen polyline değerini (rota yolunun şifrelenmiş çizgileri) çözümleyen bir metod yazılmıştır. Bu metod sayesinde rota yolunun çizilebilmesi için gerekli enlem, boylam değerleri elde edilir. Detaylı anlatım kodlarda bulunmaktadır.
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 |
import android.content.*; import android.preference.PreferenceManager; import com.google.android.gms.maps.model.LatLng; import org.json.*; import java.util.*; public class DirectionsJSONParser { /** Google Directions URL kullanarak web servisden elde edilen JSONObject çözümlenerek, rotayı ne kadar sürede bitirebileceğiniz, rotanın kaç km olduğu, yol tarifleri hakkında detaylı bilgiler elde edilir */ public List<List<HashMap<String,String>>> parse(JSONObject jObject, Context context){ List<List<HashMap<String, String>>> routes = new ArrayList<>() ; JSONArray jRoutes = null; JSONArray jLegs = null; JSONArray jSteps = null; try { jRoutes = jObject.getJSONArray("routes"); for(int i=0;i<jRoutes.length();i++){ jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs"); JSONObject c = jLegs.getJSONObject(i); JSONObject vo = c.getJSONObject("duration"); //Rotaya varış süresini, SharedPreferences nesnesine atadım. Haritada gösterimi, MainActivity sınıfında. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putString("duration", vo.getString("text")); editor.commit(); List path = new ArrayList<HashMap<String, String>>(); for(int j=0;j<jLegs.length();j++){ jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps"); for(int k=0;k<jSteps.length();k++){ //Polyline çözümleyerek, rota noktalarının enlem, boylam bilgisi alma 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<String, String>(); hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) ); hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) ); path.add(hm); } } routes.add(path); } } } catch (JSONException e) { e.printStackTrace(); }catch (Exception e){ } return routes; } /** * Polyline (rota yolunun şifrelenmiş çizgileri) çözümleyerek, rota noktalarının enlem, boylam bilgisini döner */ private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); 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; } } |
Örneklediğim projemin kodlarını indirmek isterseniz; yapmanız gereken tek şey aşağıya koyduğum KODLARI İNDİR resmine tıklamak.
Henüz yorum yapılmamış, sesinizi aşağıya ekleyin!