我必须在两个地址之间画一条路线,这两个地址写在两个地方的自动完成片段中。我搜索了它,但大多数代码是onclick事件。我必须根据片段中写入的地址绘制折线。你能给我一个关于如何为此编写代码的一般概念吗?
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
Context context;
Polyline polyline;
Marker markers;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
addMarker(place);
// Log.i(TAG, "Place: " + place.getName());
String placeName = place.getName().toString();
}
@Override
public void onError(Status status) {
// TODO: Handle the error.
//Log.i(TAG, "An error occurred: " + status);
}
});
final PlaceAutocompleteFragment autocompleteFragments = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragments);
autocompleteFragments.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
addMarker(place);
// Log.i(TAG, "Place: " + place.getName());
String placeName = place.getName().toString();
}
@Override
public void onError(Status status) {
// TODO: Handle the error.
//Log.i(TAG, "An error occurred: " + status);
}
});
}
/**
* 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(final GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
//LatLng warora = new LatLng(20.2407, 79.0136);
//LatLng amravati=new LatLng(20.9374,77.7796);
/*LatLng nagpur=new LatLng(21.1458,79.0882);
PolylineOptions polylineOptions=new PolylineOptions().add(warora).add(nagpur).width(5).color(Color.BLUE)
.geodesic(true);
googleMap.addPolyline(polylineOptions);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(warora,8));
mMap.addMarker(new MarkerOptions().position(warora).title("Marker in India"));
//mMap.addMarker(new MarkerOptions().position(amravati).title("Marker in Pune"));
mMap.addMarker(new MarkerOptions().position(nagpur).title("Marker in Nagpur"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(warora));
*/
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
}
public void addMarker(Place p) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(p.getLatLng()).title(p.getName() + "");
mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(p.getLatLng()));
mMap.animateCamera(CameraUpdateFactory.zoomTo(9));
}
}
在我的代码中,我添加了标记,但搜索框都调用了一个方法(addMarker)。我想这就是我无法获得它们之间折线的原因。我尝试使用相同的代码制作不同的方法,然后添加折线,但它不起作用。
答案 0 :(得分:2)
我为您提供了绘制路径的代码加上获取行车距离和行程时间。
创建一个新的java文件,即“ 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;
JSONObject jDistance = null;
JSONObject jDuration = 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<HashMap<String, String>> path = new
ArrayList<HashMap<String, String>>();
/** Traversing all legs */
for(int j=0;j<jLegs.length();j++){
/** Getting distance from the json data */
jDistance = ((JSONObject)
jLegs.get(j)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String,
String>();
hmDistance.put("distance", jDistance.getString("text"));
/** Getting duration from the json data */
jDuration = ((JSONObject)
jLegs.get(j)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String,
String>();
hmDuration.put("duration", jDuration.getString("text"));
/** Adding distance object to the path */
path.add(hmDistance);
/** Adding duration object to the path */
path.add(hmDuration);
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<LatLng> 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 : jeffreysambells.com/2010/05/27/decoding-polylines-from-
google-maps-direction-api-with-java
* */
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;
}
}
现在位于地图存在的MainActivity中:
public class MainActivity extends FragmentActivity {
GoogleMap map;
ArrayList<LatLng> markerPoints;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing
markerPoints = new ArrayList<LatLng>();
// Getting reference to SupportMapFragment of the activity_main
SupportMapFragment fm =
(SupportMapFragment)getSupportFragmentManager().
findFragmentById(R.id.map);
// Getting Map for the SupportMapFragment
map = fm.getMap();
// Enable MyLocation Button in the Map
map.setMyLocationEnabled(true);
// Setting onclick event listener for the map
map.setOnMapClickListener(new 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 = markerPoints.get(0);
LatLng dest = 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);
}
}
});
}
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;
}
// 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<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
if(result.size()<1){
Toast.makeText(getBaseContext(), "No Points",
Toast.LENGTH_SHORT).show();
return;
}
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
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);
if(j==0){ // Get distance from the list
distance = (String)point.get("distance");
continue;
}else if(j==1){ // Get duration from the list
duration = (String)point.get("duration");
continue;
}
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(2);
lineOptions.color(Color.RED);
}
// Drawing polyline in the Google Map for the i-th route
map.addPolyline(lineOptions);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is
present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
那就是它!
如果您需要更多解释,请参阅link。
答案 1 :(得分:0)
答案 2 :(得分:0)
使用google directions API获取2个地址之间的航点。有Util lib by Google可帮助您在地图上显示响应中的“overview_polyline”。