Trying to routing via osmbonus pack here, everything works almost fine, but there is a problem which is I can not see the polyline drawn as the route on my map.
I'm sure it has een generated since (mRoadOverlay.getNumberOfPoints()) returns 41
And I'm following the OSMNavigator Sample https://code.google.com/p/osmbonuspack/source/browse/trunk/OSMNavigator/src/com/osmnavigator/MapActivity.java
void updateUIWithRoad(Road road){
mRoadNodeMarkers.getItems().clear();
TextView textView = (TextView)findViewById(R.id.tv_main_routeInfo);
textView.setText("");
List<Overlay> mapOverlays = map.getOverlays();
if (mRoadOverlay != null){
Log.d("Polylinenopoin",String.valueOf(mRoadOverlay.getNumberOfPoints()));
mapOverlays.remove(mRoadOverlay);
mRoadOverlay = null;
Log.d("POLYLINE","1");
}
if (road == null){
return;}
if (road.mStatus == Road.STATUS_TECHNICAL_ISSUE)
Toast.makeText(map.getContext(), "Technical issue when getting the route", Toast.LENGTH_SHORT).show();
else if (road.mStatus > Road.STATUS_TECHNICAL_ISSUE) //functional issues
Toast.makeText(map.getContext(), "No possible route here", Toast.LENGTH_SHORT).show();
mRoadOverlay = RoadManager.buildRoadOverlay(road, Main.this);
String routeDesc = road.getLengthDurationText(-1);
mRoadOverlay.setTitle("route" + " - " + routeDesc);
String det = String.valueOf(mRoadOverlay.getColor()) + "- " + String.valueOf(mRoadOverlay.getWidth());
Log.d("Polydet",det);
map.getOverlays().add(mRoadOverlay);
//we insert the road overlay at the "bottom", just above the MapEventsOverlay,
//to avoid covering the other overlays.
putRoadNodes(road);
map.invalidate();
//Set route info in the text view:
textView.setText(routeDesc);
}
Also I need to say that I can see road Nodes on the map, so it's safe to say that road is correct
For future reference:
I found the reason,
the reason was that to enlarge the font size of the maps I used this custom XYTileSource:
map.setTileSource(new XYTileSource("Google Terrian",
ResourceProxy.string.bing, 10, 17, 512, ".jpg", new String[] {
"http://otile1.mqcdn.com/tiles/1.0.0/map/",
"http://otile2.mqcdn.com/tiles/1.0.0/map/",
"http://otile3.mqcdn.com/tiles/1.0.0/map/",
"http://otile4.mqcdn.com/tiles/1.0.0/map/"}));
in which I had changed the aTileSizePixel to 512, while my tiles were in fact 256x256 ... this helped me to show tiles bigger and hence bigger font size, the latitude and longitude were alright as I could set points by myself on the map in exact location, also the route Nodes were alright, the route Polyline itself however was not, I guess it had been loaded in a different location which was not in the view I had checked.
Related
I have multiple locations that I need to display on my map.
I want the info/label for each marker to display on the maps along with the pin icon whether the marker/pin is clicked or not by the user.
I have the following code to display the markers.
for (DepartmentLocation loc : departmentLocations) {
if (loc != null && loc.getLatitude() != null && loc.getLongitude() != null) {
LatLng latLng = new LatLng(loc.getLatitude(), loc.getLongitude());
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
MarkerOptions markerOptions = new MarkerOptions().position(latLng).title(loc.getName());
markerOptions.visible(true);
Marker marker = googleMap.addMarker(markerOptions);
marker.showInfoWindow();
marker.setVisible(true);
markers.add(marker);
}
}
But still, I see only the red pins and no labels beside the pin.
Here is how my maps look like. I can see only one info label, not the others.
I have tried using the IconGenerator from the map utils.
implementation 'com.google.maps.android:android-maps-utils:0.5'
for (DepartmentLocation loc : departmentLocations) {
if (loc != null && loc.getLatitude() != null && loc.getLongitude() != null) {
LatLng latLng = new LatLng(loc.getLatitude(), loc.getLongitude());
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
MarkerOptions markerOptions = new MarkerOptions()
.icon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon(loc.getName())))
.position(latLng)
.title(loc.getName());
markerOptions.visible(true);
Marker marker = googleMap.addMarker(markerOptions);
marker.showInfoWindow();
marker.setVisible(true);
markers.add(marker);
}
}
When I use iconfactory, I am unable to show both the pin and the info label.
Only one InfoWindow is displayed at a time on GoogleMap. You can't display multiple InfoWindow at a time.
You have to use IconGenerator for that. You can set a view to IconGenerator and make a Bitmap form that view. You can make a view that contains both Marker and your InfoWindow View. Use that view to crate your Desired Marker.
You can check this answer
From the documentation, there is a text saying that the info window is shown one at a time, so there is no way to do that:
"An info window allows you to display information to the user when they
tap on a marker. Only one info window is displayed at a time. If a
user clicks on a marker, the current info window will be closed and
the new info window will be displayed. Note that if the user clicks on
a marker that is currently showing an info window, that info window
closes and re-opens."
You can read more here: https://developers.google.com/maps/documentation/android-sdk/infowindows
In my Android application i need to get the traveled road with car and i check it with google android directions API and GPS.
But the problem is that some times the GPS location is not precise and i can get an error of 10Km for some lecture and that means that in a total travel of 150km my "distance traveled" can be 250km and it's wrong!
Yesterday i test it in highway and the problem is that when the marker is located out from highway, the calculation of distance traveled from my current position and the last marker located by road is very wrong (in this case out of the highway).
There is some best way for getting traveled distance with car using the phone?
Maybe some better code for getting more precise GPS position?
Here is my code:
private void getUserLocation() {
Log.d(TAG, "getUserLocation()");
checkLocationPermission();
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
String stringStartLat, stringStartLng;
double lat = location.getLatitude();
double lng = location.getLongitude();
//Start position of device
if (travelInfo.getStartLat() == 0 && travelInfo.getStartLng() == 0) {
travelInfo.setStartLat(lat);
travelInfo.setStartLng(lng);
//Set lastcoordinates equals to start
travelInfo.setLastLat(lat);
travelInfo.setLastLng(lng);
}
//Current position of device
travelInfo.setCurrentLat(lat);
travelInfo.setCurrentLng(lng);
stringStartLat = Double.toString(travelInfo.getStartLat());
stringStartLng = Double.toString(travelInfo.getStartLng());
//Set the TextView in the fragment with start coordinates
Log.d(TAG,"LatitudeStart: " + stringStartLat);
Log.d(TAG,"LongitudeStart: " + stringStartLng);
if (startMarker == null) {
//Add the user location to the map with a marker
LatLng userLoction = new LatLng(travelInfo.getStartLat(), travelInfo.getStartLng());
startMarker = googleMap.addMarker(new MarkerOptions()
.position(userLoction)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))
.title("Start Position")
.snippet("Show the start position of user"));
// For zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(userLoction).zoom(9).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
} else {
LatLng currentLocation = new LatLng(travelInfo.getCurrentLat(), travelInfo.getCurrentLng());
currentPositionMarker = googleMap.addMarker(new MarkerOptions()
.position(currentLocation)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW))
.title("Current Position")
.snippet("Show the current position of user during travel"));
// For zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(currentLocation).zoom(11).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
if (travelInfo.getEndLat() != 0 && travelInfo.getEndLng() != 0) {
Log.i(TAG, "Dentro if userlocation");
//Get total distance of travel
getTotalDistanceTime(travelInfo);
//Get the percurred distance from last known coordinates
getPercurredDistance(travelInfo);
}
}
}
});
}
And getpercurredDistance use google direction API with this url
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + obj.getLastLat() + "," + obj.getLastLng() + "&destination=" + obj.getCurrentLat() + "," + obj.getCurrentLng() + "&mode=driving&key=AI*******************I";
For getting distance traveled from last marker and current position marker.
But some times it put the localized position too far from real position... how avoid this?
EDIT
The method that i use is good for my work? mFusedLocationClient.getLastLocation()
There is no possibilities to get more precise GPS position from GPS sensor of android device, but you can filter "wrong" points this ways:
1) for each travel point get several values of Lat and Lng, discard the minimum and maximum and average the remaining ones;
2) log timestamps of each travel point and compare it for two neighboring points: speed (distance between that two points divided by time interval of that points) grater than max. car speed (e.g. 250 km/h) that means the second point is wrong (if first point is good of course).
3) use Google Maps Roads API to find best-fit road geometry for a given set of GPS coordinates.
Also take a look at this question.
For real-time location purposes, location updates allow you to request location updates at different intervals. See the android developer location documentation. The function you want is FusedLocationProviderClient.requestLocationUpdates.
There is no reason GPS (or any other widely used location technology) should ever give you 10km error for a single location estimate. If you are getting this, there is a large mismatch between when you the location estimate was made and when you are requesting it.
private void setCurrentLocationMarker(LatLng currLatLng) {
if (currLatLng == null) {
Toast.makeText(getActivity(), "Check Internet Connection", Toast.LENGTH_SHORT).show();
return;
}
mMap.moveCamera(CameraUpdateFactory.newLatLng(currLatLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(R.integer.camera_zoom_value));
setMarkerAtCentre(mMap.getCameraPosition().target);
}
private void setMarkerAtCentre(LatLng cameraCentre){
if(cameraCentre == null) return;
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(cameraCentre);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
markerOptions.title("Your Position");
sourceMarker = mMap.addMarker(markerOptions);
}
Above two are the functions for setting the marker to desired latitude and longitude and placing the camera focusing the location.
Everything is working fine.
But the problem which I face here is with the zoom
mMap.animateCamera(CameraUpdateFactory.zoomBy(R.integer.camera_zoom_value));
I may place any value for the zoom.
<integer name="camera_zoom_value">2</integer>
But the zoom which I get always is the maximum one i.e. the largest possible zoom, which is kinda issue here.
Can anyone help me out? Thanks in advance.
your are passing the resource integer directly without using getResources().getInteger() so the value passed is some long integer > 20 leading to maximum zoom. Fix that and it will work.
Im getting list of planes from web api with their locations and infos. Im calling this web api every few seconds and drawing the map markers (planes) to map.
When I call my method addPlanesToMap(), to add/update markers on map, map freezes for short period of time. If im movin the map at the same time the markers get added/updated there is some lag. This happens in devices like Nexus 5. There is around 200 - 300 markers in map.
Is there something how I can improve my code, do something completely differently?
HashMap<String, MarkerContainer> mMarkerHashMap = new HashMap <String, MarkerContainer>();
public void addPlanesToMap(List <? extends RealtimePlane > planes) {
View planeMarkerView = getActivity().getLayoutInflater().inflate(R.layout.map_marker_plane, null);
TextView markerShortCodeText = (TextView) planeMarkerView.findViewById(R.id.MapMarkerText);
ImageView markerArrow = (ImageView) planeMarkerView.findViewById(R.id.MapMarkerArrow);
for (RealtimePlane plane: planes) {
MarkerContainer markerContainer = mMarkerHashMap.get(plane.getPlaneId());
// Do not process, if not updated
if (markerContainer != null && markerContainer.getPlane().getRecordedAtTime().equals(plane.getRecordedAtTime())) {
continue;
}
markerShortCodeText.setText(plane.getPlaneCode());
markerShortCodeText.setBackgroundResource(getMapMarkerDrawableBg(plane.getType()));
markerArrow.setRotation((float) plane.getBearing());
markerArrow.setVisibility(View.VISIBLE);
// Add new plane marker to map
if (markerContainer == null) {
Marker m = mMap.addMarker(new MarkerOptions()
.position(plane.getLocation())
.flat(true)
.anchor(0.5f, 0.5f)
.title(plane.getLineCode())
.icon(BitmapDescriptorFactory.fromBitmap(loadBitmapFromView(getActivity(), planeMarkerView))));
mMarkerHashMap.put(plane.getPlaneId(), new MarkerContainer(m, plane));
}
// Marker already set, update
else {
markerContainer.getMarker().setIcon(BitmapDescriptorFactory.fromBitmap(loadBitmapFromView(getActivity(), planeMarkerView)));
markerContainer.getMarker().setPosition(plane.getLocation());
markerContainer.setPlane(plane);
}
}
}
Is there something how I can improve my code, do something completely differently
yes, do not plot every single marker and only plot what is in the visible area. you can also do marker clustering.
Plotting 2-300 markers every few seconds is not really a good idea to begin with
I am developing an app of places/shops and have 500+ markers from DB on a Google Map.
I add 2 kinds of places and one kind of shop like this:
Cursor places = db.getAllPlaces();
this.placeMarker0 = new ItemizedMarker(this.getResources().getDrawable(
R.drawable.place0), this);
this.placeMarker1 = new ItemizedMarker(this.getResources().getDrawable(
R.drawable.place1), this);
this.shopMarker = new ItemizedMarker(this.getResources().getDrawable(
R.drawable.shop), this);
if (places.moveToFirst()) {
do {
String[] coordinates = places.getString(11).split(",");
if (coordinates.length > 0) {
GeoPoint point = new GeoPoint((int) (Double
.parseDouble(coordinates[0]) * 1E6), (int) (Double
.parseDouble(coordinates[1]) * 1E6));
OverlayItem overlayitem = new OverlayItem(point, places
.getString(1), Integer.toString(places.getInt(0)));
if (places.getInt(12) == 0) {
placeMarker0.addMarker(overlayitem);
} else if (places.getInt(12) == 1) {
placeMarker1.addMarker(overlayitem);
} else {
shopMarker.addMarker(overlayitem);
}
} else {
Log.w("GMaps", "Place not located - " + places.getString(1));
}
} while (places.moveToNext());
this.placeMarker0.populateNow();
this.mapOverlays.add(placeMarker0);
this.placeMarker1.populateNow();
this.mapOverlays.add(placeMarker1);
this.shopMarker.populateNow();
}
This works just fine, and all markers are shown (not shops by default though:-) )
The problem is, that after adding all the markers, the app often freezes and you can't click any of the markers or pinch-zoom / move the map for a while. I have ZoomControls added, and they work, but not interacting with the map directly.
Is Android Google Map API just not good at handling many markers, or should I use another approach?
If you need more details, please let me now!
Have you considered using Marker Clusters instead of creating 500+ individual markers? In addition to the performance overhead, your current setup could overwhelm the user.