Android: how to click on polyline API v2 - android

I would like to click on different polylines. I do not see any documented clickable events for polylines in android.
I found a solution with map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
I just get the polyline LatLng and search for real click coordinates on the map.
The new changes is in the code.
Thanks in advance.
code:
//Polyline
private class GetRouteTask extends AsyncTask<String, Void, String> {
String response = "";
private ProgressDialog progressDialog;
public void onPreExecute()
{
progressDialog = new ProgressDialog(RazhodCenaGoogleMaps2.this);
progressDialog.setMessage("Calculating directions");
progressDialog.show();
}
#Override
protected String doInBackground(String... urls) {
//Get All Route values
v2GetRouteDirection = new GMapV2DirectionGoogle();
document = v2GetRouteDirection.getDocument(latLngFrom, latLngTo, GMapV2DirectionGoogle.MODE_DRIVING);
response = "Success";
return response;
}
#Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
final PolylineOptions rectLine1 = new PolylineOptions().width(3).color(Color.RED).geodesic(true);
final PolylineOptions rectLine2 = new PolylineOptions().width(3).color(Color.GRAY).geodesic(true);
final PolylineOptions rectLine3 = new PolylineOptions().width(3).color(Color.GRAY).geodesic(true);
ArrayList<Integer> Count = v2GetRouteDirection.CountPoly(document);
for(j = 0; j < Routes.size(); j++ ) {
if (j == 0) {
ArrayList<LatLng> directionPoint1 = v2GetRouteDirection.getDirection1(document);
for (int i = 0; i < directionPoint1.size(); i++) {
LatLng point1 = directionPoint1.get(i);
rectLine1.add(point1);
}
// Adding route on the map
map.addPolyline(rectLine1);
}
if (j == 1) {
ArrayList<LatLng> directionPoint2 = v2GetRouteDirection.getDirection2(document);
for (int i = 0; i < directionPoint2.size(); i++) {
LatLng point2 = directionPoint2.get(i);
rectLine2.add(point2);
}
// Adding route on the map
map.addPolyline(rectLine2);
}
if (j == 2) {
ArrayList<LatLng> directionPoint3 = v2GetRouteDirection.getDirection3(document);
for (int i = 0; i < directionPoint3.size(); i++) {
LatLng point3 = directionPoint3.get(i);
rectLine3.add(point3);
}
// Adding route on the map
map.addPolyline(rectLine3);
}
//new code
final PolylineOptions rectLine11 = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
final PolylineOptions rectLine21 = new PolylineOptions().width(5).color(Color.GREEN).geodesic(true);
final PolylineOptions rectLine31 = new PolylineOptions().width(5).color(Color.BLACK).geodesic(true);
//searching for roads
ArrayList<Integer> Count1 = v2GetRouteDirection.CountPoly(document);
int j1;
int k = -1;
int p = 0;
int c = 0;
for(j1 = 0; j1 < Count1.size(); j1++ ) {
if (j1 == 0) {
k = 0;
}
if(j1 == 1){
p = 1;
}
if (j1 == 2) {
c = 2;
}
}
final int finalK = k;
final int finalC = c;
final int finalP = p;
//new code
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
// TODO Auto-generated method stub
latTouch1 = point.latitude;
lonTouch1 = point.longitude;
//Remove decimal from coordinates
DecimalFormat nf = new DecimalFormat("0.0");
String formattedLat = nf.format(latTouch1);
String formattedLon = nf.format(lonTouch1);
double latTouch = Double.parseDouble(formattedLat);
double lonTouch = Double.parseDouble(formattedLon);
LatLng touch = new LatLng(latTouch, lonTouch);
if (finalK == 0) {
ArrayList<LatLng> directionPoint11 = v2GetRouteDirection.getDirection1(document);
for (int i1 = 0; i1 < directionPoint11.size(); i1++) {
LatLng point11 = directionPoint11.get(i1);
Double latlng1 = point11.latitude;
Double latlng2 = point11.longitude;
String formattedLatLng1 = nf.format(latlng1);
String formattedLatLng2 = nf.format(latlng2);
double pointDouble1 = Double.parseDouble(formattedLatLng1);
double pointDouble2 = Double.parseDouble(formattedLatLng2);
LatLng point111 = new LatLng(pointDouble1, pointDouble2);
//check if poly is equal to the real coordinates
if (point111.equals(touch)) {
ArrayList<LatLng> directionPoint1 = v2GetRouteDirection.getDirection1(document);
for (int i = 0; i < directionPoint1.size(); i++) {
LatLng point1 = directionPoint1.get(i);
rectLine11.add(point1);
}
// Adding route on the map
map.addPolyline(rectLine11);
Toast.makeText(getApplicationContext(), "Polyline 1 founded", Toast.LENGTH_SHORT).show();
break;
}
}
}
if (finalP == 1) {
ArrayList<LatLng> directionPoint21 = v2GetRouteDirection.getDirection2(document);
for (int i1 = 0; i1 < directionPoint21.size(); i1++) {
LatLng point11 = directionPoint21.get(i1);
Double latlng1 = point11.latitude;
Double latlng2 = point11.longitude;
String formattedLatLng1 = nf.format(latlng1);
String formattedLatLng2 = nf.format(latlng2);
double pointDouble1 = Double.parseDouble(formattedLatLng1);
double pointDouble2 = Double.parseDouble(formattedLatLng2);
LatLng point111 = new LatLng(pointDouble1, pointDouble2);
if (point111.equals(touch)) {
ArrayList<LatLng> directionPoint2 = v2GetRouteDirection.getDirection2(document);
for (int i = 0; i < directionPoint2.size(); i++) {
LatLng point2 = directionPoint2.get(i);
rectLine21.add(point2);
}
// Adding route on the map
map.addPolyline(rectLine21);
Toast.makeText(getApplicationContext(), "Polyline 2 founded", Toast.LENGTH_SHORT).show();
break;
}
}
}
if (finalC == 2) {
ArrayList<LatLng> directionPoint31 = v2GetRouteDirection.getDirection3(document);
for (int i1 = 0; i1 < directionPoint31.size(); i1++) {
LatLng point11 = directionPoint31.get(i1);
Double latlng1 = point11.latitude;
Double latlng2 = point11.longitude;
String formattedLatLng1 = nf.format(latlng1);
String formattedLatLng2 = nf.format(latlng2);
double pointDouble1 = Double.parseDouble(formattedLatLng1);
double pointDouble2 = Double.parseDouble(formattedLatLng2);
LatLng point111 = new LatLng(pointDouble1, pointDouble2);
if (point111.equals(touch)) {
ArrayList<LatLng> directionPoint3 = v2GetRouteDirection.getDirection3(document);
for (int i = 0; i < directionPoint3.size(); i++) {
LatLng point3 = directionPoint3.get(i);
rectLine31.add(point3);
}
// Adding route on the map
map.addPolyline(rectLine31);
Toast.makeText(getApplicationContext(), "Polyline 3 founded", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
});
}
}

Related

android Animating markers every x sec

I am moving markers every 1 Seconds on map and this works (I am getting CarList every 1 sec from API call)
//Inside CarList there is carname which serves as id
void updateCarsLocation(final List<GeoPosition> CarList) {
//Remove old markers
if (carMarkers != null){
for (Marker marker : carMarkers) {
marker.remove();
}
}
carMarkers.clear();
if (CarList != null) {
for (GeoPosition car : CarList) {
//Rotate Car
Bitmap myImg = BitmapFactory.decodeResource(getResources(), R.drawable.car);
Matrix matrix = new Matrix();
matrix.postRotate(car.bearing);
Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0, myImg.getWidth(), myImg.getHeight(),
matrix, true);
//From Bitmap
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(car.lat, car.lng);
markerOptions.position(latLng);
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(rotated));
Marker cMarker = mMap.addMarker(markerOptions);
carMarkers.add(cMarker);
}
}
}
But i would like this movements to be animated (smooth) i have searched SO for some help and found couple links
Animate markers 1
Animate markers 2
But i just can't figure out how to do this, I taught about putting Markers + Cars in Hashmap<Marker, GeoPosition> and check new GeoPosition with Old by carname (id) then use animate, but i haven't still managed to get that working.
I have implemented this from a long time i will post my solution but make sure you read and understand what i am doing
private Emitter.Listener onNewDriversOnMap = new Emitter.Listener() {
#Override
public void call(final Object... args) {
final JSONObject receivedDrivers = (JSONObject) args[0];
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (!BusyParsingDrivers) {
BusyParsingDrivers = true;
new Parse_NearbyDrivers_Task(receivedDrivers).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Log.e("receivedDrivers", receivedDrivers.toString());
}
}
});
}
};
private ArrayList<Marker> existingMapMarkers = new ArrayList<>();
private boolean noNearby = false;
private boolean BusyParsingDrivers = false;
private List<Driver> driverList = new ArrayList<>();
private GoogleMap map;
/**
* Parse the new drivers list
**/
public class Parse_NearbyDrivers_Task extends AsyncTask<Void, Void, Integer>
{
JSONObject receivedDrivers;
List<Driver> newDrivers = new ArrayList<>();
List<Driver> oldDriversMoved = new ArrayList<>();
List<Driver> removedDrivers = new ArrayList<>();
public Parse_NearbyDrivers_Task(JSONObject receivedDrivers)
{
this.receivedDrivers = receivedDrivers;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... params)
{
try
{
//Get the status object from the received JSONObject
JSONObject status = receivedDrivers.getJSONObject("Status");
//Get the status code
int status_code = Integer.parseInt(status.getString("Status"));
//Here we define a switch to handle the values of the status code and return an integer after some work to filter the drivers
switch (status_code) {
case 0: //The list is not empty
{
JSONArray nearbyDrivers = receivedDrivers.getJSONArray("NearbyDrivers");
if (driverList.isEmpty()) //If the driversList is empty
{
//Iterate over all the new drivers and add them to the driverList and return 0
for (int i = 0; i < nearbyDrivers.length(); ++i) {
Driver tempDriver = new Driver();
tempDriver.id = Integer.parseInt(nearbyDrivers.getJSONObject(i).getString("pkDriverId"));
tempDriver.longitude = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Longitude"));
tempDriver.latitude = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Latitude"));
tempDriver.altitude = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Altitude"));
tempDriver.angle = Float.parseFloat(nearbyDrivers.getJSONObject(i).getString("Angle"));
tempDriver.speed = Float.parseFloat(nearbyDrivers.getJSONObject(i).getString("Speed"));
tempDriver.accuracy = Float.parseFloat(nearbyDrivers.getJSONObject(i).getString("Accuracy"));
tempDriver.distanceCovered = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("DistanceCovered"));
tempDriver.carType = Integer.parseInt(nearbyDrivers.getJSONObject(i).getString("CarTypeCode"));
driverList.add(tempDriver);
}
return 0;
} else //If the driversList is not empty
{
//Iterate over the received list and if the list contain a new driver then add it to the newDrivers
// but if it contain an already added driver but with different coordinates then add this driver to
// the oldDriversMoved to later move this driver to the new coordinates
for (int i = 0; i < nearbyDrivers.length(); i++) {
Driver tempDriver = new Driver();
tempDriver.id = Integer.parseInt(nearbyDrivers.getJSONObject(i).getString("pkDriverId"));
tempDriver.longitude = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Longitude"));
tempDriver.latitude = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Latitude"));
tempDriver.altitude = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Altitude"));
tempDriver.angle = Float.parseFloat(nearbyDrivers.getJSONObject(i).getString("Angle"));
tempDriver.speed = Float.parseFloat(nearbyDrivers.getJSONObject(i).getString("Speed"));
tempDriver.accuracy = Float.parseFloat(nearbyDrivers.getJSONObject(i).getString("Accuracy"));
tempDriver.distanceCovered = Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("DistanceCovered"));
tempDriver.carType = Integer.parseInt(nearbyDrivers.getJSONObject(i).getString("CarTypeCode"));
if (!isDriverAlreadyExists(driverList, nearbyDrivers.getJSONObject(i).getInt("pkDriverId"))) {
newDrivers.add(tempDriver);
} else {
for (int j = 0; j < driverList.size(); ++j) {
if (nearbyDrivers.getJSONObject(i).getInt("pkDriverId") == driverList.get(j).id) {
if (Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Longitude")) != driverList.get(j).longitude || Double.parseDouble(nearbyDrivers.getJSONObject(i).getString("Latitude")) != driverList.get(j).latitude) {
oldDriversMoved.add(tempDriver);
}
}
}
}
}
//If a driver is no more existing then add it to the removedDrivers List
for (int j = 0; j < driverList.size(); j++) {
if (!isDriverAlreadyExists(nearbyDrivers, driverList.get(j).id)) {
removedDrivers.add(driverList.get(j));
}
}
//return 1 to be handled in the onPostExecute
return 1;
}
}
case 1: //The list is empty
case 500: //The list is empty
return 2;
default: //Some error
return -1;
}
} catch (JSONException e) {
return -2;
}
}
#Override
protected void onPostExecute(Integer status)
{
super.onPostExecute(status);
try {
//According to what is received from the doInBackground make some actions that will affect the markers of the drivers
switch (status) {
case 0:
noNearby = false;
Plant_NearbyDrivers();
//helper_methods.Debug("Arrays sizes","DriverList:"+driverList.size()+" Existing map markers: "+existingMapMarkers.size());
break;
case 1:
noNearby = false;
Add_Remove_Move_Drivers(removedDrivers, oldDriversMoved, newDrivers);
break;
case 2:
Remove_AllDriverFromMap();
break;
}
} catch (Exception e) {
e.printStackTrace();
}
BusyParsingDrivers = false;
}
}
/**
* This method is called after receiving the drivers list and filtering this list according to new,removed,moved drivers to handle these actions
**/
private void Add_Remove_Move_Drivers(List<Driver> removedDrivers, List<Driver> oldDriversMoved, List<Driver> newDrivers)
{
//Get the icon that will be used to add the new drivers
BitmapDescriptor icon = getCarIcon();
ArrayList<ObjectAnimator> objectAnimatorsArray = new ArrayList<>();
ObjectAnimator[] objectAnimators;
TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() {
#Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
return new LatLngInterpolator.Spherical().interpolate(fraction, startValue, endValue);
}
};
//Iterate the removedDrivers list to see the matching drivers in the driversList and remove it
for (int i = 0; i < removedDrivers.size(); ++i) {
for (int j = 0; j < driverList.size(); ++j) {
//When Ids match then remove from the existingMapMarkers list and driversList
if (removedDrivers.get(i).id == driverList.get(j).id) {
driverList.remove(j);
existingMapMarkers.get(j).remove();
existingMapMarkers.remove(j);
}
}
}
//Iterate the oldDriversMoved List to get the matching in the driversList and update it and move it according to the new coordinates
for (int i = 0; i < oldDriversMoved.size(); ++i) {
for (int j = 0; j < driverList.size(); ++j) {
//When we get the match update the driver in driversList and move it to the new LatLang
if (oldDriversMoved.get(i).id == driverList.get(j).id) {
LatLng newDriverLatLng = new LatLng(oldDriversMoved.get(i).latitude, oldDriversMoved.get(i).longitude);
float desiredRotation = oldDriversMoved.get(i).angle;
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(existingMapMarkers.get(j), "rotation", existingMapMarkers.get(j).getRotation(), desiredRotation);
rotationAnimator.setDuration(1500);
objectAnimatorsArray.add(rotationAnimator);
Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position");
ObjectAnimator directionAnimator = ObjectAnimator.ofObject(existingMapMarkers.get(j), property, typeEvaluator, newDriverLatLng);
directionAnimator.setDuration(3000);
objectAnimatorsArray.add(directionAnimator);
objectAnimators = objectAnimatorsArray.toArray(new ObjectAnimator[objectAnimatorsArray.size()]);
AnimatorSet animDrivers = new AnimatorSet();
animDrivers.playTogether(objectAnimators);
animDrivers.start();
int position = driverList.indexOf(driverList.get(j));
driverList.remove(position);
driverList.add(position, oldDriversMoved.get(i));
}
}
}
//Iterate the newDrivers List to add them as markers and to the driversList
for (int i = 0; i < newDrivers.size(); ++i) {
LatLng newDriverLatLng = new LatLng(newDrivers.get(i).latitude, newDrivers.get(i).longitude);
driverList.add(newDrivers.get(i));
existingMapMarkers.add(map.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).position(newDriverLatLng).icon(icon)));
}
}
/**
* Remove all the drivers from the map
**/
public void Remove_AllDriverFromMap()
{
//Iterate all the drivers markers and remove them
for (int i = 0; i < existingMapMarkers.size(); ++i) {
existingMapMarkers.get(i).remove();
}
//Clear the arrays and set noNearby to true
noNearby = true;
driverList.clear();
existingMapMarkers.clear();
}
/**
* This method is called when there is no drivers visible on the map and we receive a list of drivers so we plant them right away
**/
private void Plant_NearbyDrivers()
{
try {
BitmapDescriptor icon = getCarIcon();
for (int i = 0; i < driverList.size(); i++) {
LatLng newDriverLatLng = new LatLng(driverList.get(i).latitude, driverList.get(i).longitude);
existingMapMarkers.add(map.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).position(newDriverLatLng).icon(icon)));
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Called to compare if the new drivers received is contained in the old driver list
**/
public boolean isDriverAlreadyExists(List<Driver> array, int driverId)
{
for (int c = 0; c < array.size(); c++) {
Driver current = array.get(c);
if (current.id == driverId)
return true;
}
return false;
}
/**
* Called to compare if the old drivers list is contained in the new drivers list
**/
public boolean isDriverAlreadyExists(JSONArray nearbyDrivers, int driverId)
{
for (int c = 0; c < nearbyDrivers.length(); c++) {
try {
JSONObject current = nearbyDrivers.getJSONObject(c);
if (current.getInt("pkDriverId") == driverId)
return true;
} catch (JSONException e) {
e.printStackTrace();
}
}
return false;
}
/**
* Get the icon of the car to be displayed according to the selected filter
**/
public BitmapDescriptor getCarIcon()
{
BitmapDescriptor icon = null;
//make the icon as you want
return icon;
}
add this to your build
compile 'com.nineoldandroids:library:2.4.0'

Find the closest point on polygon to user location

I have an app that find the shortest distance between my user to a polygon.
I want to convert the polygon to Geofence to check the distance between the user to the area to give mor accurate information to the user.
how can I do that?
this is the MapsActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, MinimumDistanceTask.GetMinimumDistanceListener {
private GoogleMap mMap;
private LocationManager manager;
private double lat, lng;
private KmlLayer layer;
private LatLng latLngTest;
private boolean contains = false;
private ArrayList<LatLng> outerBoundary;
#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);
manager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
#Override
protected void onResume() {
super.onResume();
String provider = LocationManager.GPS_PROVIDER;
//take the user location every second
try {
manager.requestLocationUpdates(provider, 1000, 0, this);
}catch (SecurityException e){
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
public void onLocationChanged(Location location) {
//clear map before create new location
mMap.clear();
try {
//load the kml file
layer = new KmlLayer(mMap, R.raw.polygon_layer, this);
layer.addLayerToMap();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
lat = location.getLatitude();
lng = location.getLongitude();
latLngTest = new LatLng(lat,lng);
// Add a marker in user location
LatLng userLocation = new LatLng(latLngTest.latitude, latLngTest.longitude);
mMap.addMarker(new MarkerOptions().position(userLocation).title("you are here"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
//check if the user in the polygon
boolean inside = ifUserInside();
if(inside){
Toast.makeText(MapsActivity.this, "you are in the polygon", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MapsActivity.this, "you are outside the polygon", Toast.LENGTH_SHORT).show();
//create the string address for the url
String address = "";
for (int i = 0; i < outerBoundary.size(); i++) {
address += (outerBoundary.get(i).toString() + "|");
address = address.replace("lat/lng:", "");
address = address.replace(" ", "");
address = address.replace("(", "");
address = address.replace(")", "");
}
MinimumDistanceTask task = new MinimumDistanceTask(this);
task.execute("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+latLngTest.latitude+ "," + latLngTest.longitude
+ "&destinations=" + address + "&mode=walking");
}
}
#Override
public void getMinimumDistance(int closeLocation) {
//check if you get results properly
if(closeLocation != -1) {
GetDirection direction = new GetDirection();
direction.execute("https://maps.googleapis.com/maps/api/directions/json?origin=" + latLngTest.latitude + "," + latLngTest.longitude
+ "&destination=" + outerBoundary.get(closeLocation).latitude + "+" + outerBoundary.get(closeLocation).longitude);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
public boolean ifUserInside(){
if (layer.getContainers() != null) {
for (KmlContainer container : layer.getContainers()) {
if (container.getPlacemarks() != null) {
for (KmlPlacemark placemark : container.getPlacemarks()) {
contains = false;
if (placemark.getGeometry() instanceof KmlPolygon) {
KmlPolygon polygon = (KmlPolygon) placemark.getGeometry();
// Get the outer boundary and check if the test location lies inside
outerBoundary = polygon.getOuterBoundaryCoordinates();
contains = PolyUtil.containsLocation(latLngTest, outerBoundary, true);
if (contains) {
// Get the inner boundaries and check if the test location lies inside
ArrayList<ArrayList<LatLng>> innerBoundaries = polygon.getInnerBoundaryCoordinates();
if (innerBoundaries != null) {
for (ArrayList<LatLng> innerBoundary : innerBoundaries) {
// If the test location lies in a hole, the polygon doesn't contain the location
if (PolyUtil.containsLocation(latLngTest, innerBoundary, true)) {
contains = false;
}
}
}
}
}
}
}
}
}
return contains;
}
public class GetDirection extends AsyncTask<String , Void, String> {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
#Override
protected String doInBackground(String... params) {
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return "Error from server";
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
#Override
protected void onPostExecute(String s) {
//get the polyline string
String polygonPoints = "";
try {
JSONObject object = new JSONObject(s);
JSONArray array = object.getJSONArray("routes");
for (int i = 0; i < array.length(); i++) {
JSONObject arrObj1 = array.getJSONObject(i);
JSONObject points = arrObj1.getJSONObject("overview_polyline");
polygonPoints = points.getString("points");
}
//convert the string to polyline;
ArrayList<LatLng> a = new ArrayList<>(decodePolyPoints(polygonPoints));
//add polyline to the map
mMap.addPolyline(new PolylineOptions().addAll(a).width(10).color(Color.BLUE));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
//the method that convert the string to polyline
public static ArrayList<LatLng> decodePolyPoints(String encodedPath){
int len = encodedPath.length();
final ArrayList<LatLng> path = new ArrayList<LatLng>();
int index = 0;
int lat = 0;
int lng = 0;
while (index < len) {
int result = 1;
int shift = 0;
int b;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
result = 1;
shift = 0;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
path.add(new LatLng(lat * 1e-5, lng * 1e-5));
}
return path;
}
}
This is my AsyncTask to get the minimum distance point
public class MinimumDistanceTask extends AsyncTask<String, Void, Integer>{
private int closeLocation;
// private String points;
private GetMinimumDistanceListener listener;
public MinimumDistanceTask(GetMinimumDistanceListener listener){
// this.points = points;
this.listener = listener;
}
#Override
protected Integer doInBackground(String... params) {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
int minimumDis = -1;
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return -1;
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
///get the json data
JSONObject jsonObject1 = new JSONObject(builder.toString());
JSONArray points = jsonObject1.getJSONArray("rows");
JSONObject jsonObject2 = points.getJSONObject(0);
JSONArray elements = jsonObject2.getJSONArray("elements");
for (int i = 0; i < elements.length(); i++) {
JSONObject jsonObject3 = elements.getJSONObject(i);
JSONObject distance = jsonObject3.getJSONObject("distance");
if( distance.getInt("value") < minimumDis || minimumDis == -1) {
minimumDis = distance.getInt("value");
closeLocation = i;
}
}
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return closeLocation;
}
#Override
protected void onPostExecute(Integer closeLocation) {
listener.getMinimumDistance(closeLocation);
}
public interface GetMinimumDistanceListener{
void getMinimumDistance(int closeLocation);
}
}
thanks a lot :)
You can use a function like the following to calculate the nearest point from polygon defined by a List<LatLng> and a given LatLng.
It uses the PolyUtil.distanceToLine from the Google Maps Android API Utility Library to compute the distance between the test LatLng and every segment of the list, and a method based on the distanceToLine method from https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java to compute the projection of a point on a segment.
private LatLng findNearestPoint(LatLng test, List<LatLng> target) {
double distance = -1;
LatLng minimumDistancePoint = test;
if (test == null || target == null) {
return minimumDistancePoint;
}
for (int i = 0; i < target.size(); i++) {
LatLng point = target.get(i);
int segmentPoint = i + 1;
if (segmentPoint >= target.size()) {
segmentPoint = 0;
}
double currentDistance = PolyUtil.distanceToLine(test, point, target.get(segmentPoint));
if (distance == -1 || currentDistance < distance) {
distance = currentDistance;
minimumDistancePoint = findNearestPoint(test, point, target.get(segmentPoint));
}
}
return minimumDistancePoint;
}
/**
* Based on `distanceToLine` method from
* https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java
*/
private LatLng findNearestPoint(final LatLng p, final LatLng start, final LatLng end) {
if (start.equals(end)) {
return start;
}
final double s0lat = Math.toRadians(p.latitude);
final double s0lng = Math.toRadians(p.longitude);
final double s1lat = Math.toRadians(start.latitude);
final double s1lng = Math.toRadians(start.longitude);
final double s2lat = Math.toRadians(end.latitude);
final double s2lng = Math.toRadians(end.longitude);
double s2s1lat = s2lat - s1lat;
double s2s1lng = s2lng - s1lng;
final double u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng)
/ (s2s1lat * s2s1lat + s2s1lng * s2s1lng);
if (u <= 0) {
return start;
}
if (u >= 1) {
return end;
}
return new LatLng(start.latitude + (u * (end.latitude - start.latitude)),
start.longitude + (u * (end.longitude - start.longitude)));
}
You can test it with the following code:
List<LatLng> points = new ArrayList<>();
points.add(new LatLng(2, 2));
points.add(new LatLng(4, 2));
points.add(new LatLng(4, 4));
points.add(new LatLng(2, 4));
points.add(new LatLng(2, 2));
LatLng testPoint = new LatLng(3, 0);
LatLng nearestPoint = findNearestPoint(testPoint, points);
Log.e("NEAREST POINT: ", "" + nearestPoint); // lat/lng: (3.0,2.0)
Log.e("DISTANCE: ", "" + SphericalUtil.computeDistanceBetween(testPoint, nearestPoint)); // 222085.35856591124

Get lat/lng of points along the route after every 100m in android

Using Map Api V2 I have drawn a route on the map. Now i wish to save this route in my database.
So I need to get the lat/lng of points on the route say after each 100 meters which i will save as a polygon. How can i do it in Google Map V2 in android.
i am stuck on it from last 10 days but not getting a solution.
any help will be appriciable :)
public class NavigationActivity extends FragmentActivity {
public static final String TAG_SLAT = "sourcelat";
public static final String TAG_SLONG = "sourcelong";
public static final String TAG_DLAT = "destinationlat";
public static final String TAG_DLONG = "destinationg";
private static LatLng Source = null;
private static LatLng Destination = null;
private GoogleMap map;
private SupportMapFragment fragment;
private LatLngBounds latlngBounds;
private Button bNavigation;
private Polyline newPolyline;
private Marker smarker;
private Marker dmarker;
Geocoder geocoder;
private boolean isTraveling = false;
private int width, height;
private String sourcelat;
private String sourcelong;
private String destinationg;
private String destinationlat;
double slat;
double slong;
double dlat;
double dlong;
double d;
double tempDistance;
String distance;
ConnectionDetector cd;
Boolean isConnectingToInternet = false;
String ts;
LatLng latLng;
GPSTracker gps;
List<Address> addresses;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.activity_navigation);
cd = new ConnectionDetector(getApplicationContext());
isConnectingToInternet = cd.isConnectingToInternet();
if (isConnectingToInternet) {
Intent in = getIntent();
sourcelat = in.getStringExtra(TAG_SLAT);
destinationlat = in.getStringExtra(TAG_DLAT);
destinationg = in.getStringExtra(TAG_DLONG);
sourcelong = in.getStringExtra(TAG_SLONG);
slat = Double.parseDouble(sourcelat);
slong = Double.parseDouble(sourcelong);
dlat = Double.parseDouble(destinationlat);
dlong = Double.parseDouble(destinationg);
Source = new LatLng(slat, slong);
Destination = new LatLng(dlat, dlong);
getSreenDimanstions();
fragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
map = fragment.getMap();
map.setMyLocationEnabled(true);
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
map.setTrafficEnabled(true);
ImageButton cureent_location = (ImageButton) findViewById(R.id.clocation);
cureent_location.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onLocationChanged();
}
});
if (!isTraveling) {
isTraveling = true;
findDirections(Source.latitude, Source.longitude, Destination.latitude, Destination.longitude, GMapV2Direction.MODE_DRIVING);
} else {
isTraveling = false;
}
}else {
AlertUtils.showAlertDialog(NavigationActivity.this, "No Internet Detected", "Please check your internet connection.", false);
}
}
public double calculateDistance(double fromLatitude,double fromLongitude,double toLatitude,double toLongitude)
{
float results[] = new float[1];
try {
Location.distanceBetween(fromLatitude, fromLongitude, toLatitude, toLongitude, results);
} catch (Exception e) {
if (e != null)
e.printStackTrace();
}
if (Source.equals(Destination)){
distance="0";
}
else {
int dist = (int) results[0];
if (dist <= 0)
return 0D;
DecimalFormat decimalFormat = new DecimalFormat("#.##");
results[0] /= 1000D;
distance = decimalFormat.format(results[0]);
double d = Double.parseDouble(distance);
double speed = 40;
double time = d / speed;
ts = manual(time);
Log.v("fdf", String.valueOf(ts));
}
return d;
}
private static String manual(double eta) {
int hour = (int) eta;
eta = (eta - hour) * 60;
int minutes = (int) eta;
eta = (eta - minutes) * 60;
int seconds = (int) eta;
eta = (eta - seconds) * 1000;
int ms = (int) eta;
//Log.d("ffgfh", String.valueOf(eta));
return String.format("%dHr %dMin ", hour, minutes);
}
#Override
protected void onResume() {
super.onResume();
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
}
public void handleGetDirectionsResult(ArrayList<LatLng> directionPoints) {
PolylineOptions rectLine = new PolylineOptions().width(5).color(Color.RED);
//MarkerOptions marker = new MarkerOptions().position(Source).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
MarkerOptions marker1 = new MarkerOptions().position(Destination).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
for(int i = 0 ; i < directionPoints.size() ; i++)
{
rectLine.add(directionPoints.get(i));
}
if (newPolyline != null)
{
newPolyline.remove();
}
newPolyline = map.addPolyline(rectLine);
//smarker = map.addMarker(marker);
dmarker = map.addMarker(marker1);
if (isTraveling) {
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
Dialog dialog_help = new Dialog(this);
dialog_help .requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog_help.setContentView(R.layout.title_multi_selectitems_dialog);
calculateDistance(slat, slong, dlat, dlong);
TextView dis = (TextView) dialog_help.findViewById(R.id.distance);
dis.setText("Distance " + distance + "Km ");
TextView tim = (TextView) dialog_help.findViewById(R.id.time);
tim.setText("Time " + ts);
dialog_help.setCancelable(true);
dialog_help.setTitle("Distance & Time" );
dialog_help.setCanceledOnTouchOutside(true);
dialog_help.show();
dialog_help.getWindow().setGravity(Gravity.CENTER);
dialog_help.getWindow().setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
dialog_help.getWindow().setLayout(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT);
}
else {
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
}
}
private void getSreenDimanstions()
{
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
}
private LatLngBounds createLatLngBoundsObject(LatLng firstLocation, LatLng secondLocation)
{
if (firstLocation != null && secondLocation != null)
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(firstLocation).include(secondLocation);
return builder.build();
}
return null;
}
public void findDirections(double fromPositionDoubleLat, double fromPositionDoubleLong, double toPositionDoubleLat, double toPositionDoubleLong, String mode)
{
Map<String, String> map = new HashMap<String, String>();
map.put(GetDirectionsAsyncTask.USER_CURRENT_LAT, String.valueOf(fromPositionDoubleLat));
map.put(GetDirectionsAsyncTask.USER_CURRENT_LONG, String.valueOf(fromPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DESTINATION_LAT, String.valueOf(toPositionDoubleLat));
map.put(GetDirectionsAsyncTask.DESTINATION_LONG, String.valueOf(toPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DIRECTIONS_MODE, mode);
GetDirectionsAsyncTask asyncTask = new GetDirectionsAsyncTask(this);
try {
asyncTask.execute(map);
}catch (Exception e){
Toast.makeText(getBaseContext(), "Something went Wrong", Toast.LENGTH_SHORT).show();
}
}
public void onLocationChanged( ){
TextView cl = (TextView) findViewById(R.id.latlongLocation);
cd = new ConnectionDetector(getApplicationContext());
isConnectingToInternet = cd.isConnectingToInternet();
if (isConnectingToInternet) {
gps = new GPSTracker(NavigationActivity.this);
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
latLng = new LatLng(latitude, longitude);
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String address = addresses.get(0).getAddressLine(0);
String prmises = addresses.get(0).getAddressLine(1);
String city = addresses.get(0).getAddressLine(2);
String country = addresses.get(0).getAddressLine(3);
cl.setText(address + " " + prmises + " " + city + " " + country);
}else {
AlertUtils.showAlertDialog(NavigationActivity.this, "No Internet Detected", "Please check your internet connection.", false);
}
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
}
You can try it with this map application: http://maps.cloudmade.com/.
At first you create your route with waypoints. Click on the button "Get directions" (upper left corner) and create your route (clicking on the map). After that you can export (there is a button on the upper right corner) your route (include waypoints) to a gpx-or a json-file. You can load both files to a GIS.

Adding polylines in asynctask android

i'm having performance issues adding polylines and thought that maybe it'll be possible to add them in a separate class extending AsyncTask. However as i learned that UI elements can't be added in such way (and polylines are UI elements).
Why i'm having performance issues while drawing polylines? Well, my polylines are drawn not from pos A to pos B but from my current location to destination (which is hardcoded for the sake of application atm). So the polylines are drawn when onLocationChange listener is executed and thus my application requires lots of proccessing power.
Any ideas how to use AsyncTask on this occasion?
This is the main class:
mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location arg0) {
// Get positions!
currentPOS = new LatLng(arg0.getLatitude(), arg0.getLongitude());
LatLng dst = new LatLng(58.378249, 26.714673);
CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(currentPOS, 13);
mMap.animateCamera(yourLocation);
mMap.addMarker(new MarkerOptions().position(dst).title("SCHOOL!"));
/*
// Remove comments to add marker to Liivi 2!
mMap.addMaker(new MarkerOptions().position(currentPOS).title("My POS"));
*/
if (currentPOS != null) {
//This is supposed to show directions
DirectionAPI directionAPI = new DirectionAPI(currentPOS, dst);
GoogleResponse googleResponse = null;
try {
googleResponse = (GoogleResponse) directionAPI.execute().get();
} catch (InterruptedException e) {
Log.e("CATCH","INTERRUPDED");
e.printStackTrace();
} catch (ExecutionException e) {
Log.e("CATCH","EXECUTIONEXCEPTION");
e.printStackTrace();
}
if (googleResponse.isOk()){
DrivingDirection drivingDirection = new DrivingDirection(googleResponse.getJsonObject());
polyline = drivingDirection.getTotalPolyline();
new drawPath(mMap,polyline).execute();
}
}
}
});
This is the Async for path drawing (which will result in an error due to UI conflict):
import android.graphics.Color;
import android.os.AsyncTask;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import java.util.ArrayList;
/**
* Created by Kevin on 7.10.2015.
*/
public class drawPath extends AsyncTask{
private static ArrayList<LatLng> polyline;
private static GoogleMap mMap;
public drawPath(GoogleMap map, ArrayList<LatLng> polyline){
this.mMap = map;
this.polyline = polyline;
}
#Override
protected Object doInBackground(Object[] params) {
for (int i = 0; i < polyline.size() - 1; i++) {
LatLng src = polyline.get(i);
LatLng dest = polyline.get(i + 1);
// mMap is the Map Object
Polyline line = mMap.addPolyline(
new PolylineOptions().add(
new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude,dest.longitude)
).width(2).color(Color.BLUE).geodesic(true)
);
}
return null;
}
}
I solved this issue in a way that i did not add every polyline map separately but whole polyline. For example, before i had my location about 4km away from destination and it had 280 polylines between. On every onLocationChange these polylines were drawn one-by-one to map. Now they're all added at once - AsyncTask will create polylines in the background and in the post-execute they will be added.
#Override
protected Object doInBackground(Object[] params) {
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int z = 0; z < polyline.size(); z++) {
LatLng point = polyline.get(z);
options.add(point);
}
return options;
}
protected void onPostExecute(Object result) {
Polyline line = mMap.addPolyline((PolylineOptions) result);
}
you can use this code
ublic class DrawrootTask extends AsyncTask<String, String, String> {
private Context context;
public static boolean flagCompleted = false;
private GoogleMap googleMap;
private double source_lat = 0.0;
private double source_long = 0.0;
private double dest_lat = 0.0;
private double dest_long = 0.0;
Userdata userdata;
String tag = "DrawRootTask";
private ProgressDialog progressDialog;
public static double dist, time;
private Polyline line;
String distanceText = "";
String durationText = "";
public DrawrootTask(Context context, LatLng source, LatLng destination,
GoogleMap googleMap) {
source_lat = source.latitude;
source_long = source.longitude;
dest_lat = destination.latitude;
dest_long = destination.longitude;
this.googleMap = googleMap;
this.context = context;
userdata = Userdata.getinstance(context);
}
protected void onPreExecute() {
// // TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(context);
progressDialog.setMessage(context.getResources().getString(
R.string.please_wait));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
String json = "";
// constructor
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
HashMap<String, String> keyValue = new HashMap<String, String>();
urlString.append("?origin=");// from
urlString.append(Double.toString(source_lat));
urlString.append(",");
urlString.append(Double.toString(source_long));
urlString.append("&destination=");// to
urlString.append(Double.toString(dest_lat));
urlString.append(",");
urlString.append(Double.toString(dest_long));
urlString.append("&sensor=false&mode=driving&alternatives=true");
// defaultHttpClient
String url = urlString.toString();
FetchUrl fetchurl = new FetchUrl();
json = fetchurl.fetchUrl(url, keyValue);
Log.e("Buffer Error", json);
return json;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
try {
progressDialog.dismiss();
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List<LatLng> list = decodePoly(encodedString);
for (int z = 0; z < list.size() - 1; z++) {
LatLng src = list.get(z);
LatLng dest = list.get(z + 1);
line = googleMap.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude))
// .width(8).color(Color.BLUE).geodesic(true));
.width(8)
.color(context.getResources().getColor(
R.color.actionbar_color)).geodesic(true));
Log.i("draw root", "" + "" + line.toString());
}
JSONArray legs = routes.getJSONArray("legs");
JSONObject steps = legs.getJSONObject(0);
JSONObject duration = steps.getJSONObject("duration");
JSONObject distance = steps.getJSONObject("distance");
distanceText = distance.getString("text");
durationText = duration.getString("text");
Log.i("draw root", "" + distance.toString());
dist = Double.parseDouble(distance.getString("text").replaceAll(
"[^\\.0123456789]", ""));
time = Double.parseDouble(duration.getString("text").replaceAll(
"[^\\.0123456789]", ""));
userdata.setDistance(distanceText);
userdata.setTime(durationText);
Log.d(tag, "distace is " + dist + " time is " + time);
flagCompleted = true;
} catch (JSONException e) {
Log.d("draw root", "" + e);
}
}
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;
}
}

display duration and distance between two locations google maps api v2

I'm currently working on a google maps application i could display the route between two given (by the user) points, and now i'm trying to display some information ,for the user , as : duration between the two points and distance as well as showing alternative roads .
After searching i found out that i can add things to my URL such as mode, alternatives=true...
public class MapsActivity extends FragmentActivity {
private GoogleMap gm;
String Depart;
String Arrive;
TextView tvdirections;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapifNeeded();
ImageButton serch_button = (ImageButton) findViewById(R.id.btnSearch);
tvdirections=(TextView)findViewById(R.id.tvdirections);
serch_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog_button = new Dialog(MapsActivity.this);
dialog_button.setTitle("Voir itineraires");
dialog_button.setContentView(R.layout.dialog);
dialog_button.show();
final EditText edittxt1 = (EditText) dialog_button.findViewById(R.id.depart);
final EditText edittxt2 = (EditText) dialog_button.findViewById(R.id.arrive);
Button GoButton = (Button) dialog_button.findViewById(R.id.btnDialog);
GoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Depart = edittxt1.getText().toString();
Arrive = edittxt2.getText().toString();
if ((Depart.equals("") || Arrive.equals("")) || (Depart.equals(null) || Arrive.equals(null))) {
Toast.makeText(getApplicationContext(), "Veuillez entrer les points de depart et d'arrive", Toast.LENGTH_SHORT).show();
} else {
new ItineraryActivity(getApplicationContext(), gm, Depart, Arrive,tvdirections).execute();
dialog_button.cancel();
gm.clear();
}
}
});
}
});
}
#Override
protected void onResume() {
super.onResume();
setUpMapifNeeded();
}
public void OnChangeToHybrid(View view) {
gm.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
public void OnChangeToNormal(View view) {
gm.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
private void setUpMapifNeeded() {
if (gm == null) {
gm = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mymap)).getMap();
}
if (gm != null) {
setUpMap();
}
}
private void setUpMap() {
//gm.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("hi bouchra :)"));
//gm.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(0, 0), 18));
gm.setMyLocationEnabled(true);
gm.getUiSettings().setZoomControlsEnabled(true);
gm.getUiSettings().setCompassEnabled(true);
}
}
here is the other class
public class ItineraryActivity extends AsyncTask<Void,Integer,Boolean> {
private static final String TOAST_ERR_MAJ = "Impossible de trouver un itineraire";
private Context context;
private GoogleMap gm;
private String Depart;
private String Arrive;
private TextView tvdirections;
private final ArrayList<LatLng> lstLatLng = new ArrayList<LatLng>();
private NodeList nl1;
private NodeList nl2;
private Node node1=null;
private Node node2=null;
public ItineraryActivity(final Context context, final GoogleMap gMap, final String Depart, final String Arrive, final TextView tvdirections) {
this.context = context;
this.gm = gMap;
this.Depart = Depart;
this.Arrive = Arrive;
this.tvdirections = tvdirections;
//nl1 = null;
}
#Override
protected void onPreExecute() {
}
#Override
public Boolean doInBackground(Void... params) {
try {
//Construction de l'url a appeler
final StringBuilder url = new StringBuilder("http://maps.googleapis.com/maps/api/directions/xml?sensor=false");
url.append("&origin=");
url.append(Depart.replace(' ', '+'));
url.append("&destination=");
url.append(Arrive.replace(' ', '+'));
url.append("&alternatives=true&units=metric");
final InputStream stream = new URL(url.toString()).openStream();
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setIgnoringComments(true);
final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
final Document document = documentBuilder.parse(stream);
document.getDocumentElement().normalize();
final String status = document.getElementsByTagName("status").item(0).getTextContent();
if (!"OK".equals(status)) {
return false;
}
//On recupere les steps
final Element elementLeg = (Element) document.getElementsByTagName("leg").item(0);
final NodeList nodeListStep = elementLeg.getElementsByTagName("step");
final int length = nodeListStep.getLength();
//final NodeList distancelist= elementLeg.getElementsByTagName("distance");
for (int i = 0; i < length; i++) {
final Node nodeStep = nodeListStep.item(i);
if (nodeStep.getNodeType() == Node.ELEMENT_NODE) {
final Element elementStep = (Element) nodeStep;
//On decode les points du XML
decodePolylines(elementStep.getElementsByTagName("points").item(0).getTextContent());
}
}
nl1= document.getElementsByTagName("distance");
node1=nl1.item(0);
nl2=node1.getChildNodes();
node2=nl2.item(getNodeIndex(nl2, "text"));
return true;
} catch (final Exception e) {
return false;
}
}
private int getNodeIndex(NodeList nl, String nodename) {
for(int i = 0 ; i < nl.getLength() ; i++) {
if(nl.item(i).getNodeName().equals(nodename))
return i;
}
return -1;
}
private void decodePolylines(final String encodedPoints) {
int index = 0;
int lat = 0, lng = 0;
while (index < encodedPoints.length()) {
int b, shift = 0, result = 0;
do {
b = encodedPoints.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 = encodedPoints.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
lstLatLng.add(new LatLng((double) lat / 1E5, (double) lng / 1E5));
}
}
//List<HashMap<String, String>> path = result.get(i);
protected void onPostExecute( final Boolean result) {
/*String distance = "";
String duration = "";*/
if (!result) {
Toast.makeText(context, TOAST_ERR_MAJ, Toast.LENGTH_SHORT).show();
} else {
final PolylineOptions polylines = new PolylineOptions();
polylines.color(Color.BLUE);
polylines.width(3);
//On construit le polyline
for (final LatLng latLng : lstLatLng) {
polylines.add(latLng);
}
final MarkerOptions markerA = new MarkerOptions();
markerA.position(lstLatLng.get(0));
markerA.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
final MarkerOptions markerB = new MarkerOptions();
markerB.position(lstLatLng.get(lstLatLng.size() - 1));
markerB.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
gm.moveCamera(CameraUpdateFactory.newLatLngZoom(lstLatLng.get(0), 10));
gm.addMarker(markerA);
gm.addPolyline(polylines);
gm.addMarker(markerB);
tvdirections.setText(""+node2);
}
}
Using JSON:
This example is thought to get data for only one route, but in order to work with more options the only thing you should know is that you'll have a "legs" JSONArray for each route.
final String str = "http://maps.googleapis.com/maps/api/directions/json?"
+ "origin=" + Start.latitude + "," + Start.longitude
+ "&destination=" + End.latitude + "," + End.longitude
+"&language=" +getResources().getConfiguration().locale.getDefault().getLanguage()
+ "&sensor=false&units=metric&mode=" + "walking"
+ "&alternatives=true";
URL url = new URL(str);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
StringBuilder jsonResults = new StringBuilder();
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray parentArray = jsonObj.getJSONArray("routes");
final JSONArray legArray = parentArray.getJSONObject(0).getJSONArray("legs");
//Distance
JSONObject distanceObj = legArray.getJSONObject(0).getJSONObject("distance");
distance = distanceObj.getInt("value"); //Value of distance
distance = distanceObj.getString("text"); //String that contains the distance value formated
//With duration is the same changing getJSONObject("distance") with getJSONObject("duration")

Categories

Resources