My Problem is I have 4 Location's Latitude and Longitude into my local database, I am fetching those data and use for draw route path in android but problem is first to second location route is not display on mapview other second to third and third to fourth route path is display on mapview. Sorry for bad English communication.
i am getting code from following link for draw route path.
MapRoute Example
and call drawing class using following function:-
public void drawpath(){
mDb.open();
Cursor cr = mDb.getAllTitles();
cr.moveToFirst();
if (cr.getCount() > 0) {
for (int i = 0; i <= cr.getCount()/2; i++) {
fromlat = Double.parseDouble(cr.getString(1));
fromlng = Double.parseDouble(cr.getString(2));
cr.moveToNext();
tolat = Double.parseDouble(cr.getString(1));
tolng = Double.parseDouble(cr.getString(2));
String url = RoadProvider
.getUrl(fromlat, fromlng, tolat, tolng);
InputStream is = getConnection(url);
mRoad = RoadProvider.getRoute(is);
MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
}
}
cr.close();
mDb.close();
}
Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("http://maps.google.com/maps?saddr=20.344,34.34&daddr=20.5666,45.345"));
startActivity(intent);
It is happening because you are using cr.getCount()/2.
When you will have even number of count then it will work not work fine
For example if you have 4 number of rows then you cr.getCount()/2 = 2
so your loop will continue from 0 to 2 means 3 times.
Actually it should be continue 2 times as your coding.
Now lat take a odd numbers say 5 so cr.getCount()/2 = 2 because i is the integer value so your loop will work total 3 times.
So you have different mechanism.
Like try to add all the lat and long in the arraylist and then after loop complete.
Make a loop of the size of that arrayList and create a path.May be for that you required two additional variable to store the previous lat and long.
Related
I am developing a bus tracking application where I am getting the location using service from server. Now, with that I want to show the bus movement and draw a proper polyline. I achieved a part of this but facing two main issues:
Every time bus marker is showing, it is not getting removed. So, the older footprint of the bus is still present. Although I reached destination, I am seeing many bus icons.
I am able to draw the polyline by joining the latitude and longitude but it is showing sometimes a straight line.
I have attached two screenshots for that.
The code which I used is here:
private void setmMap() {
progressDialog.show();
if (broadcastReceiver == null)
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Testing", "inside the setmap");
// show progress dialog
try {
double latitude = intent.getDoubleExtra("lat", 22.560214);
double longitude = intent.getDoubleExtra("longi", 22.560214);
Log.d("SetMap", intent.getExtras().getString("time"));
LatLng startLocation = new LatLng(latitude, longitude);
m.setPosition(startLocation);
points.add(startLocation);
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int i = 0; i < points.size(); i++) {
LatLng point = points.get(i);
options.add(point);
}
line = mMap.addPolyline(options); //add Polyline
mMap.moveCamera(CameraUpdateFactory.newLatLng(startLocation));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(startLocation, 15));
progressDialog.cancel();
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(context, Locale.getDefault());
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String strLoc = "Latitude:: "+latitude+" ::Longitude:: "+longitude+" ::Address:: "+address+" "+city+" "+
state;
Toast.makeText(getApplicationContext(),strLoc, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
progressDialog.cancel();
}
}
};
registerReceiver(broadcastReceiver, new IntentFilter("carLocationService"));
}
Thanks,
Arindam.
1) you din't show part of code where marker m added, possible that code runs several times;
2) seems bus location sensor's polling period is quite large and does not allow tracking bus turns (bus can make several turns between it's known locations). So you need to interpolate path between known bus locations for example with Google Directions API.
I have a huge list in an XML tag like so:
<coor> -123.3858,41.34119,0
-123.3856,41.34109,0
-123.3852,41.34121,0
-123.3848,41.34139,0</coor>
and need it like this:
new LatLng(-123.3858,41.34119),
new LatLng(-123.3856,41.34109),
new LatLng(-123.3852,41.34121),
new LatLng(-123.3848,41.34139),
to work with google maps v2 android.
I've done a string replace on the coordinates and am getting the correct results like so:
String ll = "),new LatLng(";
coor = coor.replaceAll(",0", ll);
replacing the ,0 for the new LatLng(... I am not figuring out how to change the large string of latlng text into latlng locations to put into my polygon:
PolygonOptions perimeteres = new PolygonOptions().add(coor);
Is there way to do this? Or do I need to separate each out and make them individual latlng?
EDIT::::
String[] splitData = coor.split(",0");
for (String eachSplit : splitData) {
if (!eachSplit.endsWith(",0")) {
//Log.e("EACH",eachSplit);
Log.v("e","new LatLon("+eachSplit+");");
}
}
This is getting me a little closer...
You are going completely in the wrong direction, this
String ll = "),new LatLng(";
coor = coor.replaceAll(",0", ll);
is not the same as
new LatLng(-123.3858,41.34119)
the first gives you a string which does nothing for you, the second is an object which is what you need.
Edit
you need to remove the 0 from the coordinates then you do a string split on the , so you have an array of latitudes and longitudes.
then create a List<LatLng> which is what you need to create a polygon of points
and loop through your points
for(int j=0;j<locationAry.length;j++){
if(j%2 == 0){
lon = Float.parseFloat(locationAry[j+1]);
lat = Float.parseFloat(locationAry[j]);
}
}
I have a array of about 7000 locations, each one was recorded using the location manager on android, when loading these locations I filter out any that are further then 1km from the previous or have an accuracy higher then 50 using this:
if (c.moveToFirst())
do {
lat = c.getString(0);
lng = c.getString(1);
ac = c.getString(2);
alt = c.getString(3);
if (l1 != null) {
l2 = new Location("MAP");
l2.setLatitude(Double.parseDouble(lat));
l2.setLongitude(Double.parseDouble(lng));
l2.setAltitude(Double.parseDouble(alt));
l2.setAccuracy(Float.parseFloat(ac));
if (l1.distanceTo(l2) < 1000
&& l2.getAccuracy() < 51) {
opts.add(new LatLng(Double.parseDouble(lat),
Double.parseDouble(lng)));
list.add(l2);
l1 = l2;
}
} else {
l1 = new Location("MAP");
l1.setLatitude(Double.parseDouble(lat));
l1.setLongitude(Double.parseDouble(lng));
l1.setAccuracy(Float.parseFloat(ac));
l1.setAltitude(Double.parseDouble(alt));
if (l1.getAccuracy() > 50)
l1 = null;
}
} while (c.moveToNext());
So that removes the possibilities for these random lines assuming its working as it should.
When it is working correctly it should come up like this:
However, when I zoom in a little more or move around sometimes I get these random lines:
Im adding the lines like this:
Location[] locations = Arrays.copyOfRange(mLocations, a, b);
if (mStartLine != null)
mStartLine.remove();
if (mMiddleLine != null)
mMiddleLine.remove();
if (mEndLine != null)
mEndLine.remove();
if (mMarker != null) {
mMarker.remove();
mMarker = null;
}
PolylineOptions so = new PolylineOptions();
PolylineOptions mo = new PolylineOptions();
PolylineOptions eo = new PolylineOptions();
so.color(Color.GREEN);
eo.color(Color.GREEN);
mo.color(Color.BLACK);
if (locations.length < 2) {
if (locations.length == 0)
return;
// Add just a dot instead.
MarkerOptions m = new MarkerOptions();
m.position(new LatLng(locations[0].getLatitude(), locations[0]
.getLongitude()));
mMarker = mMap.addMarker(m);
return;
}
so.add(new LatLng(locations[0].getLatitude(), locations[0].getLongitude()));
so.add(new LatLng(locations[1].getLatitude(), locations[1].getLongitude()));
mStartLine = mMap.addPolyline(so);
for(int i = 1; i < (locations.length - 1); i++){
mo.add(new LatLng(locations[i].getLatitude(), locations[i].getLongitude()));
}
mMiddleLine = mMap.addPolyline(mo);
eo.add(new LatLng(locations[locations.length - 2].getLatitude(), locations[locations.length - 2].getLongitude()));
eo.add(new LatLng(locations[locations.length - 1].getLatitude(), locations[locations.length - 1].getLongitude()));
mEndLine = mMap.addPolyline(eo);
The bar at the bottom is a selector to only show that span of locations (Because when you have something like 7000 locations showing then it gets pretty crazy and you get StackOverflowError's)
There appears to be a bug open for it: https://code.google.com/p/gmaps-api-issues/issues/detail?id=5313
EDIT
It appears if you filter vertices that are closer than 1 meter to each other the the bug is resolved. I will write some code to fix this later tonight and put it here.
UPDATE
This bug was handled in Google issue tracker
https://issuetracker.google.com/issues/35821816
It was fixed in Google Play Services - 9.2.56
https://developers.google.com/maps/documentation/android-api/releases#june_27_2016
Here is an approach that fixed this issue for us. Not necessarily the ideal solution, but it works. At certain zoom levels you may see a polyline extend beyond where it should be (like the pictures show above). If you keep changing your zoom level the extension would disappear and then reappear. This happened to us everytime when two coordinates were exactly the same. e.g.
Lets say you have 3 coordinates A,B,C. Bus starts from A and goes to B, the bus then turns around and comes to C. If A and C are the exact same coordinates you would see this polyline extension problem.
After a few approaches we settled on offseting the latitude of point C by .00001. That has fixed all our issues.
I'm getting latitude and longitude as strings from a Google Places URL. Now I'd like to place a pin on a map using the obtained coordinates. Something is goofy because I'm trying to parse the strings into integers for the GeoPoint, and the results show as 0,0 so the pin is placed off the coast of Africa. Here's my code:
int lati5Int, longi5Int;
String latiString = in.getStringExtra(TAG_GEOMETRY_LOCATION_LAT);
String longiString = in.getStringExtra(TAG_GEOMETRY_LOCATION_LNG);
TextView getLatiStringtv.setText(latiString);
TextView getLongiStringtv.setText(longiString);
try {
lati5Int = Integer.parseInt(getLatiStringtv.getText().toString());
longi5Int = Integer.parseInt(getLongiStringtv.getText().toString());
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
// shows that the ints are zeros
doubleLatiTV.setText(Integer.toString(lati5Int));
doubleLongiTV.setText(Integer.toString(longi5Int));
//--- GeoPoint---
newPoint = new GeoPoint(lati5Int,longi5Int);
mapController.animateTo(newPoint);
mapController.setZoom(17);
//--- Place pin ----
marker = getResources().getDrawable(R.drawable.malls);
OverlayItem overlaypoint = new OverlayItem(newPoint, "Boing", "Whattsup");
CustomPinpoint customPin = new CustomPinpoint(marker, SMIMap.this);
customPin.insertPinpoint(overlaypoint);
overlayList.add(customPin);
I think the error is in the parsing of the integers:
lati5Int = Integer.parseInt(getLatiStringtv.getText().toString());
longi5Int = Integer.parseInt(getLongiStringtv.getText().toString());
I think the parsing sees the decimal point in the coordinates and freaks out. So how can I parse the coordinate strings into integers so that the GeoPoint will see them as correctly formatted coordinates like: 30.487263, -97.970799
GeoPoint doesn't want to see them as 30.487263, -97.970799. It wants them as the integers 30487263, -97970799. So like A.A said, parse as double first, multiply by E6, then cast to int.
So maybe something like:
lati5Int = Double.parseDouble(getLatiStringtv.getText().toString());
latiE6 = (int) (lati5Int*1000000);
Is it possible to make the addition of a geopoint in a map more "automatic"? I mean, if we have many points to add in the map (more than 100), we don't have to add them one by one like that:
GeoPoint point2 = new GeoPoint(microdegrees(36.86774),microdegrees(10.305302));
GeoPoint point3 = new GeoPoint(microdegrees(36.87154),microdegrees(10.341815));
GeoPoint point4 = new GeoPoint(microdegrees(36.876093),microdegrees(10.325716));
pinOverlay.addPoint(point2);
pinOverlay.addPoint(point3);
pinOverlay.addPoint(point4);
Is there a method to stock them all in a table and then the compiler adds them one by one?
You'll want to store them in either a SQLite database or some other form of data storage, and then you can pull them in and place them on the map with an ItemizedOverlay, see Google Map View (a tutorial).
Create your array from a database cursor
Cursor cursor = mDbHelper.getItems();
cursor.moveToFirst();
List<CatchItem> catchList = new ArrayList<CatchItem>();
if (cursor != null && cursor.getCount() > 0) {
for (int i = 0; i < cursor.getCount(); i++) {
CatchItem item = new CatchItem();
item.Latitude = cursor.getDouble(cursor.getColumnIndex("latitude"));
item.Longitude = cursor.getDouble(cursor.getColumnIndex("longitude"));
catchList.add(item);
cursor.moveToNext();
}
}
ItemizedOverlay
List<Overlay> overlays = mMaps.getOverlays();
overlays.clear();
CatchesItemizedOverlay catchOverlays = new CatchesItemizedOverlay(getResources().getDrawable(R.drawable.map_markeroverlay_blue72), this);
for (int i = 0; i < catchList.size(); i++) {
double lat = catchList.get(i).Latitude;
double lng = catchList.get(i).Longitude;
GeoPoint geopoint = new GeoPoint((int)(lat*1E6), (int)(lng*1E6));
catchOverlays.addOverlay(new CatchOverlayItem(this, geopoint, catchList.get(i)));
}
overlays.add(catchOverlays);
CatchesItemizedOverlay is my own extended ItemizedOverlay (I needed custom functionality). The catchList object is just a custom object that has latitude and longitude.
Hopefully this works for you.
You could store them in a SQLite databse, and pull them as needed