您好我正在尝试实现一个谷歌地图应用程序,显示两个位置标记之间的方向路线。 我的第一个标记/位置是我设备的当前位置,第二个是从db到api。
输出图片附于此问题。
谷歌地图输出
这是我的代码。
HttpConnection.java类 - >
public class HttpConnection {
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();
br.close();
} catch (Exception e) {
// Log.d("Exception while reading url", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
}
DirectionsJSONParser.java类 - >
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;
}
}
MainActivity.java类 - &gt;
public class MainActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
ArrayList<LatLng> MarkerPoints = new ArrayList<>();
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker1,mCurrLocationMarker2;
LocationRequest mLocationRequest;
private static final int PERMISSIONS_REQUEST_READ_PHONE_STATE = 1;
String stringIMEI = "",stringLatitudeOrigin = "",stringLongitudeOrigin = "",
stringLatitudeDest = "",stringLongitudeDest = "";
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// MultiDex.install(this);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(map);
mapFragment.getMapAsync(this);
if (checkLocationPermission()){
buildGoogleApiClient();
}
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{android.Manifest.permission.READ_PHONE_STATE},
PERMISSIONS_REQUEST_READ_PHONE_STATE);
}else {
TelephonyManager mngr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
stringIMEI = mngr.getDeviceId().toString();
}
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (checkLocationPermission()) {
mMap.setMyLocationEnabled(true);
}
}
private String getUrl(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;
/* String waypoints = "waypoints=optimize:true|" + ANDHERI.latitude + "," + ANDHERI.longitude + "|"
+ JAGRUTI_NAGAR.latitude + "," + JAGRUTI_NAGAR.longitude + "|";
Sensor enabled
String sensor = "sensor=false";
String mode = "mode=driving"; */
String key = "key=mygoogleapikey";
// Building the parameters to the web service
String parameters = str_origin + "&" + str_dest + "&" + key;//+ waypoints + "&"
// Output format
String output = "json";
// Building the url to the web service
String url = "http://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
return url;
}
/**
* A method to download json data from url
*/
// Fetches data from url passed
private class FetchUrl extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
String data = "";
try {
HttpConnection http = new HttpConnection();
data = http.downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
new 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]);
Log.d("ParserTask",jsonData[0].toString());
DirectionsJSONParser parser = new DirectionsJSONParser();
Log.d("ParserTask", parser.toString());
// Starts parsing data
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;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points;
PolylineOptions lineOptions = null;
// 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 < MarkerPoints.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(10);
lineOptions.color(Color.RED);
Log.d("onPostExecute","onPostExecute lineoptions decoded");
}
// Drawing polyline in the Google Map for the i-th route
if(lineOptions != null) {
mMap.addPolyline(lineOptions);
}
else {
Log.d("onPostExecute","without Polylines drawn");
}
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) { }
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker1 != null) {
mCurrLocationMarker1.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
stringLatitudeOrigin = String.valueOf(location.getLatitude());
stringLongitudeOrigin = String.valueOf(location.getLongitude());
mCurrLocationMarker1 = mMap.addMarker(new MarkerOptions().position(latLng).title("Your device"));
GetLocationVolleyRequest();
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,13.0f));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) { }
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
}else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
case PERMISSIONS_REQUEST_READ_PHONE_STATE : {
if (requestCode == PERMISSIONS_REQUEST_READ_PHONE_STATE
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
TelephonyManager mngr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
stringIMEI = mngr.getDeviceId().toString();
}else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
} // other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
}
public void GetLocationVolleyRequest(){
StringRequest stringRequest = new StringRequest(Request.Method.POST, Constants.LOCATIONAPI_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject json = new JSONObject(response);
if (json.getString("success").equals("1")) {
stringLatitudeDest = json.getString("latitude");
stringLongitudeDest = json.getString("longitude");
Toast.makeText(MainActivity.this,"Other Device -> Lat : "+stringLatitudeDest + " Lng : " +
stringLongitudeDest,Toast.LENGTH_LONG).show();
mCurrLocationMarker2 = mMap.addMarker(new MarkerOptions().position(new LatLng(Double.parseDouble(stringLatitudeDest),
Double.parseDouble(stringLongitudeDest))).title("Other device"));
MarkerPoints.add(new LatLng(Double.parseDouble(stringLatitudeOrigin),
Double.parseDouble(stringLongitudeOrigin)));
MarkerPoints.add(new LatLng(Double.parseDouble(stringLatitudeDest),
Double.parseDouble(stringLongitudeDest)));
// Instantiating the class PolylineOptions to plot polyline in the map
PolylineOptions polylineOptions = new PolylineOptions();
// Setting the color of the polyline
polylineOptions.color(Color.RED);
// Setting the width of the polyline
polylineOptions.width(10);
// Setting points of polyline
polylineOptions.addAll(MarkerPoints);
// Adding the polyline to the map
mMap.addPolyline(polylineOptions);
// Checks, whether start and end locations are captured
if (MarkerPoints.size() >= 2) {
LatLng origin = MarkerPoints.get(0);
LatLng dest = MarkerPoints.get(1);
// Getting URL to the Google Directions API
String url = getUrl(origin, dest);
Log.d("onMapClick", url.toString());
FetchUrl fetchUrl = new FetchUrl();
// Start downloading json data from Google Directions API
fetchUrl.execute(url);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(origin,14.0f));
}
}else {
Toast.makeText(MainActivity.this,"Could not Co-ordinates due to"+json.getString("error_msg"),
Toast.LENGTH_LONG).show();
}
}catch (JSONException je){
je.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_LONG).show();
}
}){
@Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("imei",stringIMEI);
params.put("latitude",stringLatitudeOrigin);
params.put("longitude",stringLongitudeOrigin);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
请帮忙。
答案 0 :(得分:0)
试试这个:
1获取路线网址需要调用Google Maps API
private String getMapsApiDirectionsUrl(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;
}
2。在后台进行URL调用
private class ReadTask extends AsyncTask<String, Void , String> {
@Override
protected String doInBackground(String... url) {
// TODO Auto-generated method stub
String data = "";
try {
MapHttpConnection http = new MapHttpConnection();
data = http.readUr(url[0]);
} catch (Exception e) {
// TODO: handle exception
Log.d("Background Task", e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
new ParserTask().execute(result);
}
}
public class MapHttpConnection {
public String readUr(String mapsApiDirectionsUrl) throws IOException{
String data = "";
InputStream istream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(mapsApiDirectionsUrl);
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();
br.close();
}
catch (Exception e) {
Log.d("Exception while reading url", e.toString());
} finally {
istream.close();
urlConnection.disconnect();
}
return data;
}
}
3。创建Parser类以将数据从JSON解析为指针列表
public class PathJSONParser {
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");
for (int i=0 ; i < jRoutes.length() ; i ++) {
jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
List<HashMap<String, String>> 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 ++) {
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 (Exception e) {
e.printStackTrace();
}
return routes;
}
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;
}}
使用另一个线程进行解析以扩展性能
private class ParserTask extends AsyncTask<String,Integer,
List<List<HashMap<String , String >>>> {
@Override
protected List<List<HashMap<String, String>>> doInBackground(
String... jsonData) {
// TODO Auto-generated method stub
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
PathJSONParser parser = new PathJSONParser();
routes = parser.parse(jObject);
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
ArrayList<LatLng> points = null;
PolylineOptions polyLineOptions = null;
// traversing through routes
for (int i = 0; i < routes.size(); i++) {
points = new ArrayList<LatLng>();
polyLineOptions = new PolylineOptions();
List<HashMap<String, String>> path = routes.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.addAll(points);
polyLineOptions.width(4);
polyLineOptions.color(Color.BLUE);
}
googleMap.addPolyline(polyLineOptions);
}}
5当你想获得两点的路径时
String url = getMapsApiDirectionsUrl(latlngOne, latlngTwo);
ReadTask downloadTask = new ReadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
计算点之间的距离
float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongB.longitude,
latLongB.latitude, latLongB.longitude,
results);
注意:结果将以米为单位
答案 1 :(得分:0)
我的Android代码没有通过http://
从google api网址获得任何回复,因此将其更改为https://
并且有效。