I'm using these settings to create a direction from a location to another:
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.width(15);
polylineOptions.color(colorPrimary);
mMap.addPolyline(polylineOptions.addAll(points));
And on the map, it looks like this:
https://ibb.co/D13xc0T
How to draw a continuous line from one point to another without those interruptions?
This is the code that gets the points:
if (direction != null) {
List<Route> routes = direction.routes;
Route route = routes.get(0);
List<Leg> legs = route.legs;
Leg leg = legs.get(0);
List<Step> steps = leg.steps;
for (Step step : steps) {
String point = step.polyline.points;
List<LatLng> points = PolyUtil.decode(point);
}
}
You add many PolylineOptions to map. They are not connected to each over and so you get this interruptions. Try to add all decoded paths to one common array.
Your edited code:
ArrayList<LatLng> points = new ArrayList<LatLng>();
for (Step step : steps) {
String point = step.polyline.points;
points.addAll(PolyUtil.decode(point));
}
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.width(15);
polylineOptions.color(colorPrimary);
mMap.addPolyline(polylineOptions.addAll(points));
Try with this, it works fine for me. You can add multiple point also.
mMap.addPolyline(new PolylineOptions().add(PointA).add(PointB).width(8f).color(Color.RED));
I ran into the same problem with broken polylines. After not finding a solution here, I stumbled across a closed issue here. If you just add all points of all steps as given by the result of an call to Googles API you won't get a continuous line, because the endpoints will be added twice. Once as end of a step and a second time as beginning of the next step. That is why there is no single continuous line and why you have to remove duplicates. In Kotlin this is pretty easy by calling allPoints = allPoints.distinct() as ArrayList<LatLng>. Calling this will keep the order of the points, but remove any duplicates in the list.
Related
I am trying to build an application with google direction API on Android.
I want apply direction mode as driving but when there is no route available, I want to apply dot polylines like Google Map App.
Bellow is sample code for apply polylines pattern for route from atabouraya's answer but it is opposite of what I want to apply.
public static final int PATTERN_GAP_LENGTH_PX = 20;
public static final PatternItem DOT = new Dot();
public static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX);
public static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX);
public static final List<PatternItem> PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH);
private void drawDashedLeg(GoogleMap googleMap, Route route) {
PolylineOptions polyOptions = new PolylineOptions();
polyOptions.color(ContextCompat.getColor(getContext(), R.color.coolgrey));
polyOptions.addAll(route.getPoints());
polyOptions.pattern(PATTERN_POLYGON_ALPHA);
Polyline polyline = googleMap.addPolyline(polyOptions);
polylines.add(polyline);
}
And here is another reference for how to draw curved dashed line on Google Map as they focus only how to draw curved line from one location to another.
My purpose is how to draw route from one location to another as driving route and apply walking mode when there is no route available.
Anyone who have any idea on this please help to share it. Thank you.
For my temporary solution, I just separate polyline to 3 parts:
From origin (driver's current location) to first route (available driving route)
From first available driving route until the last of driving route
From last available driving route to destination (store's location)
Here is my sample code after decode polylinePoint
if (routeList.size > 0) {
val polylineOptionsWalkingStart = getPolylineOptionsConfig(routeI)
val polylineOptionsWalingEnd = getPolylineOptionsConfig(routeI)
val polylineOptionsDriving = getPolylineOptionsConfig(routeI)
// Add walking route from origin to first driving route
polylineOptionsWalkingStart.add(origin, routeList[0]!!)
.pattern(MapUtil.PATTERN_POLYGON_ALPHA)
// Add walking route from last driving route to destination
polylineOptionsWalingEnd.add(
routeList[routeList.size - 1]!!,
destination
).pattern(MapUtil.PATTERN_POLYGON_ALPHA)
// Add driving route from origin to destination
polylineOptionsDriving.addAll(routeList)
// Adding route for driving and walking mode on the map
polylineWalkingStart = mMap.addPolyline(polylineOptionsWalkingStart)
polylineWalkingEnd = mMap.addPolyline(polylineOptionsWalingEnd)
polylineDriving = mMap.addPolyline(polylineOptionsDriving)
}
and here is my PolylineOptions configuration
private fun getPolylineOptionsConfig(mainRoute: Int): PolylineOptions {
val polylineOptions = PolylineOptions().width(18f).geodesic(true)
return when (mainRoute) {
0 -> {
polylineOptions.color(Color.parseColor("#B1C001"))
}
1 -> {
polylineOptions.color(Color.parseColor("#0099D8"))
}
2 -> {
polylineOptions.color(Color.parseColor("#1777EB"))
}
else -> {
polylineOptions.color(Color.parseColor("#515C6F"))
}
}
}
And here is polyline pattern
private val DOT: PatternItem = Dot()
val PATTERN_POLYGON_ALPHA = listOf(DOT)
If you have another better solution please share your answer here.
Anyway, I hope my answer can help you in this situation.
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 would like to search places between two given distances, using GeoPoints. Using the currently api, I think I could make something like this pseudo algorithm:
query.whereWithinKilometers("directions", GlobalData.ownerGeoPoint, MAXIMUM distance);
MINUS
query.whereWithinKilometers("directions", GlobalData.ownerGeoPoint, MINIMUM distance);
How can I translate to real code?
Finally I found a way to do it with a parse query.
// Do not want locations further than maxDistance
ParseQuery query = ParseQuery.getQuery("MyData");
query.whereWithinKilometers("location", userGeoPoint, maxDistance);
// Do not want locations closer than minDistance
ParseQuery<ParseObject> innerQuery = ParseQuery.getQuery("MyData");
innerQuery.whereWithinKilometers("location", userGeoPoint, minDistance);
query.whereDoesNotMatchKeyInQuery("objectId", "objectId", innerQuery);
Likely you'll have to pull in everything within the maximum distance from Parse to your app, then inside your app filter out anything that is closer than the minimum.
Thankfully Parse includes some distance measuring as part of PFGeoPoint. Check out the three methods here.
distanceInRadiansTo:
distanceInMilesTo:
distanceInKilometersTo:
So your pseudocode is:
(After you get back everything within the outer radius)
Make a new array (var) called finalList
For i = 0; i < objects.count; i++ {
var gp: PFGeoPoint = objects[i]
if gp.distanceInMilesTo:originalGeoPoint >= minimumRadiusInMiles {
finalList.push(gp)
}
}
I'm using MapQuest (since Google Map API will be down in september) and I'd like to add a point at an exact coordinates position.
I've created a movieClip named geoPoint and traced a circle in it.
Now, I've managed to display the coordinates in a text field like that :
if (Geolocation.isSupported){
var my_geo:Geolocation = new Geolocation();
my_geo.addEventListener(GeolocationEvent.UPDATE, onGeoUpdate);
my_geo.setRequestedUpdateInterval(50);
var my_txt:TextField = new TextField();
my_txt.wordWrap=true;
addChild(my_txt);
}
function onGeoUpdate(e:GeolocationEvent):void{
my_txt.text = "My Latitude is "+e.latitude+" and my Longitude is "+e.longitude;
}
Now is it possible to add my movieClip at the e.latitude and e.longitude point ?
I've tried :
var geo:MovieClip;
geo = new geoPoint;
addChild(geo(new LatLng(e.latitude, e.longitude)));
but it doesn't work.
Someone knows how can I do it ?
Thanks !
It should be
geo = new geoPoint();
You should also probably figure how to translate latitude and longitude to x and y coordinates, because I'm doubtful the next line will work. You're calling a MovieClip constructor that takes a LatLng argument.
For what you need to achive, you may have to use a class provided by the MapQuest Api, like PolygonOverlay or CircleOverlay. There is an example here under "Shape Collections" http://developer.mapquest.com/content/as3/v7/7.0.6_MQ/samples/samplesexplorer/index.html#
I'm currently having a map, and each 10 meters I use LocationListener to refresh my location and get the new Latitude and Longitude. Now I wish that the route the user is taking will be displayed with a red line. So everytime the OnLocationChange() from LocationListener class is called, I want to update the map with a line between the last location and the new location.
So far I've added the following:
private void initializeDraw() {
lineOptions = new PolylineOptions().width(5).color(Color.RED);
lineRoute = workoutMap.addPolyline(lineOptions);
}
during the OnLocationChanged I call this:
drawTrail();
now what should I insert into this function so that each time it adds the newly attained location as a point and draws a line from the last to the new point.
Thanks
First translate Location into LatLng:
LatLng newPoint = new LatLng(location.getLatitude(), location.getLongitude());
Then add a point to existing list of points:
List<LatLng> points = lineRoute.getPoints();
points.add(newPoint);
lineRoute.setPoints(points);