How to Draw Line between Source and Destination in Google map?
我在地图中获得了正确的源和目标纬度和经度,但我能够在源和目标之间绘制线,但这条线是地图中源和目标标记之间的海峡线显示。目标纬度和目标经度已成功从服务器获取。
但我想在源和目标之间画线,如下所示。
这是示例。
Google Map 也是显示 Source 和 Destination 的 CurrectPosition。
怎么可能?
请指导我。
请帮我。
谢谢。
我的代码是,
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 | public class Map extends FragmentActivity { GoogleMap googleMap; SupportMapFragment fm; double myLat = 23.0137759; double destLat = 0.0; double myLng = 72.5158836; double destLng = 0.0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.navigate_to_me_map); if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .permitAll().build(); StrictMode.setThreadPolicy(policy); } Intent intent = getIntent(); destLat = intent.getDoubleExtra("latitude", 0.0); destLng = intent.getDoubleExtra("longitude", 0.0); int status = GooglePlayServicesUtil .isGooglePlayServicesAvailable(getBaseContext()); // Showing status if (status != ConnectionResult.SUCCESS) { // Google Play Services int requestCode = 10; Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode); dialog.show(); } else { SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.fullmap); googleMap = supportMapFragment.getMap(); googleMap.setMyLocationEnabled(true); } googleMap .setOnMyLocationChangeListener(new OnMyLocationChangeListener() { public void onMyLocationChange(Location location) { // TODO Auto-generated method stub myLat = location.getLatitude(); myLng = location.getLongitude(); } }); drawRoutePath(strAddressOne); } } private void drawRoutePath(String searchText) { try { // find current address latlong and true than draw route // between to points or current loction and search // address googleMap.clear(); if (myLat != 0 && myLng != 0) { LatLng origin = new LatLng(myLat, myLng); drawMarker(origin); LatLng dest = new LatLng(destLat, destLng); drawMarker(dest); Polyline line = googleMap.addPolyline(new PolylineOptions() .add(origin, dest).width(5).color(Color.RED)); } else { Toast.makeText(getApplicationContext(), "Current Location does not found", Toast.LENGTH_SHORT).show(); } } } catch (Exception e) { // TODO: handle exception Log.e("Second","drawRoutePath errro" + e.toString()); } } private void drawMarker(LatLng point) { // Creating an instance of MarkerOptions MarkerOptions markerOptions = new MarkerOptions(); // Setting latitude and longitude for the marker markerOptions.position(point); // Adding marker on the Google Map googleMap.addMarker(new MarkerOptions().position(point).visible(true)) .showInfoWindow(); googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng( point.latitude, point.longitude), 6f)); } } |
这是在源和目的地之间绘制路线的源代码:
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 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | public class MapActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private SupportMapFragment mapFragment; private GoogleMap map; private GoogleApiClient mGoogleApiClient; ArrayList markerPoints; private LocationRequest mLocationRequest; private long UPDATE_INTERVAL = 15000; /* 15 secs */ private long FASTEST_INTERVAL = 5000; /* 5 secs */ private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; // Marker marker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!isGooglePlayServicesAvailable()) { finish(); } setContentView(R.layout.activity_map); getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getSupportActionBar().setDisplayShowCustomEnabled(true); getSupportActionBar().setCustomView(R.layout.custom_actionbar_maps); markerPoints = new ArrayList(); mapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)); if (mapFragment != null) { mapFragment.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap map) { loadMap(map); } }); } else { Toast.makeText(this,"Error - Map Fragment was null!!", Toast.LENGTH_SHORT).show(); } } protected void loadMap(GoogleMap googleMap) { map = googleMap; if (map != null) { // Map is ready Toast.makeText(this,"Map Fragment was loaded properly!", Toast.LENGTH_SHORT).show(); map.setMyLocationEnabled(true); map.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng point) { // Already two locations if(markerPoints.size()>1){ markerPoints.clear(); map.clear(); } // Adding new item to the ArrayList markerPoints.add(point); // Creating MarkerOptions MarkerOptions options = new MarkerOptions(); // Setting the position of the marker options.position(point); /** * For the start location, the color of marker is GREEN and * for the end location, the color of marker is RED. */ if(markerPoints.size()==1){ options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); }else if(markerPoints.size()==2){ options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); } // Add new marker to the Google Map Android API V2 map.addMarker(options); // Checks, whether start and end locations are captured if(markerPoints.size() >= 2){ LatLng origin = (LatLng) markerPoints.get(0); LatLng dest = (LatLng) markerPoints.get(1); // Getting URL to the Google Directions API String url = getDirectionsUrl(origin, dest); DownloadTask downloadTask = new DownloadTask(); // Start downloading json data from Google Directions API downloadTask.execute(url); } } }); // Now that map has loaded, let's get our location! mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this).build(); connectClient(); } else { Toast.makeText(this,"Error - Map was null!!", Toast.LENGTH_SHORT).show(); } } protected void connectClient() { // Connect the client. if (isGooglePlayServicesAvailable() && mGoogleApiClient != null) { mGoogleApiClient.connect(); } } /* * Called when the Activity becomes visible. */ @Override protected void onStart() { super.onStart(); connectClient(); } /* * Called when the Activity is no longer visible. */ @Override protected void onStop() { // Disconnecting the client invalidates it. if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } super.onStop(); } /* * Handle results returned to the FragmentActivity by Google Play services */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // Decide what to do based on the original request code switch (requestCode) { case CONNECTION_FAILURE_RESOLUTION_REQUEST: /* * If the result code is Activity.RESULT_OK, try to connect again */ switch (resultCode) { case Activity.RESULT_OK: mGoogleApiClient.connect(); break; } } } // Fetches data from url passed private boolean isGooglePlayServicesAvailable() { // Check that Google Play services is available int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { // In debug mode, log the status Log.d("Location Updates","Google Play services is available."); return true; } else { // Get the error dialog from Google Play services Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, CONNECTION_FAILURE_RESOLUTION_REQUEST); // If Google Play services can provide an error dialog if (errorDialog != null) { // Create a new DialogFragment for the error dialog ErrorDialogFragment errorFragment = new ErrorDialogFragment(); errorFragment.setDialog(errorDialog); errorFragment.show(getSupportFragmentManager(),"Location Updates"); } return false; } } /* * Called by Location Services when the request to connect the client * finishes successfully. At this point, you can request the current * location or start periodic updates */ @Override public void onConnected(Bundle dataBundle) { // Display the connection status Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if (location != null) { Toast.makeText(this,"GPS location was found!", Toast.LENGTH_SHORT).show(); LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16); map.animateCamera(cameraUpdate); //marker = map.addMarker(new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.vehicle_marker)).flat(true).anchor(0.5f,0.5f)); startLocationUpdates(); } else { Toast.makeText(this,"Current location was null, enable GPS on emulator!", Toast.LENGTH_SHORT).show(); } } protected void startLocationUpdates() { mLocationRequest = new LocationRequest(); mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); mLocationRequest.setInterval(UPDATE_INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } public void onLocationChanged(Location location) { // Report to the UI that the location was updated LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); /* if(marker == null){ *//* marker.remove();*//* marker = map.addMarker(new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.vehicle_marker))); } marker.setPosition(latLng); */ CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16); map.animateCamera(cameraUpdate); String msg ="Updated Location:" + Double.toString(location.getLatitude()) +"," + Double.toString(location.getLongitude()); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } /* * Called by Location Services if the connection to the location client * drops because of an error. */ @Override public void onConnectionSuspended(int i) { if (i == CAUSE_SERVICE_DISCONNECTED) { Toast.makeText(this,"Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show(); } else if (i == CAUSE_NETWORK_LOST) { Toast.makeText(this,"Network lost. Please re-connect.", Toast.LENGTH_SHORT).show(); } } /* * Called by Location Services if the attempt to Location Services fails. */ @Override public void onConnectionFailed(ConnectionResult connectionResult) { /* * Google Play services can resolve some errors it detects. If the error * has a resolution, try sending an Intent to start a Google Play * services activity that can resolve error. */ if (connectionResult.hasResolution()) { try { // Start an Activity that tries to resolve the error connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST); /* * Thrown if Google Play services canceled the original * PendingIntent */ } catch (IntentSender.SendIntentException e) { // Log the error e.printStackTrace(); } } else { Toast.makeText(getApplicationContext(), "Sorry. Location services not available to you", Toast.LENGTH_LONG).show(); } } // Define a DialogFragment that displays the error dialog public static class ErrorDialogFragment extends DialogFragment { // Global field to contain the error dialog private Dialog mDialog; // Default constructor. Sets the dialog field to null public ErrorDialogFragment() { super(); mDialog = null; } // Set the dialog to display public void setDialog(Dialog dialog) { mDialog = dialog; } // Return a Dialog to the DialogFragment. @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return mDialog; } } // Fetches data from url passed private class DownloadTask extends AsyncTask<String, Void, String>{ // Downloading data in non-ui thread @Override protected String doInBackground(String... url) { // For storing data from web service String data =""; try{ // Fetching the data from web service data = downloadUrl(url[0]); }catch(Exception e){ Log.d("Background Task",e.toString()); } return data; } // Executes in UI thread, after the execution of // doInBackground() @Override protected void onPostExecute(String result) { super.onPostExecute(result); ParserTask parserTask = new ParserTask(); // Invokes the thread for parsing the JSON data parserTask.execute(result); } } /** A class to parse the Google Places in JSON format */ private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{ // Parsing the data in non-ui thread @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 parser = new DirectionsJSONParser(); // Starts parsing data routes = parser.parse(jObject); }catch(Exception e){ e.printStackTrace(); } return routes; } // Executes in UI thread, after the parsing process @Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { ArrayList points = null; PolylineOptions lineOptions = null; MarkerOptions markerOptions = new MarkerOptions(); // Traversing through all the routes for(int i=0;i<result.size();i++){ points = new ArrayList(); lineOptions = new PolylineOptions(); // Fetching i-th route List<HashMap<String, String>> path = result.get(i); // Fetching all the points in i-th route 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); } // Adding all the points in the route to LineOptions lineOptions.addAll(points); lineOptions.width(12); lineOptions.color(Color.RED); lineOptions.geodesic(true); } // Drawing polyline in the Google Map for the i-th route map.addPolyline(lineOptions); } } private String getDirectionsUrl(LatLng origin,LatLng dest){ // Origin of route String str_origin ="origin="+origin.latitude+","+origin.longitude; // Destination of route String str_dest ="destination="+dest.latitude+","+dest.longitude; // Sensor enabled String sensor ="sensor=false"; // Building the parameters to the web service String parameters = str_origin+"&"+str_dest+"&"+sensor; // Output format String output ="json"; // Building the url to the web service String url ="https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters; return url; } /** A method to download json data from url */ private String downloadUrl(String strUrl) throws IOException { String data =""; InputStream iStream = null; HttpURLConnection urlConnection = null; try{ URL url = new URL(strUrl); // Creating an http connection to communicate with url urlConnection = (HttpURLConnection) url.openConnection(); // Connecting to url urlConnection.connect(); // Reading data from url 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(); br.close(); }catch(Exception e){ Log.d("Exception while downloading url", e.toString()); }finally{ iStream.close(); urlConnection.disconnect(); } return data; } } |
DirectionsJSONParser.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 | 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 DirectionsJSONParser { /** Receives a JSONObject and returns a list of lists containing latitude and longitude */ public List<List<HashMap<String,String>>> parse(JSONObject jObject){ List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ; JSONArray jRoutes = null; JSONArray jLegs = null; JSONArray jSteps = null; try { jRoutes = jObject.getJSONArray("routes"); /** Traversing all routes */ for(int i=0;i<jRoutes.length();i++){ jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs"); List path = new ArrayList<HashMap<String, String>>(); /** Traversing all legs */ for(int j=0;j<jLegs.length();j++){ jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps"); /** Traversing all steps */ for(int k=0;k<jSteps.length();k++){ String polyline =""; polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points"); List list = decodePoly(polyline); /** Traversing all points */ 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; } /** * Method to decode polyline points * Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java * */ private List decodePoly(String encoded) { List 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; } } |
您可以使用以下库:
Google-Directions-Android