i have polyline set from point A to point B to which i need to create an animation as we see in uber app (trail animation) between the points something like this
You haven't mentioned what software you want to show the animation in, but if you look at the Road Map for ArcGIS Pro: https://community.esri.com/community/gis/applications/arcgis-pro/blog/2018/02/02/arcgis-pro-roadmap you will see that animated symbols are planned to release in the Mid Term. You can create animated point symbols (not what you are looking for) as described here: Bring Your Points to Life with GIF Symbols | ArcGIS Blog and use GeoEvent Server | ArcGIS Enterprise to simulate movement along a route. Otherwise you will probably end up programming this functionality.
I use Android studio and xcode with their native sdk to develop app for
esri.
I don't want to animate the points but the path in which polyline is drawn
Asif - did you figure this out? I have the same issue - want to animate the polyline - but in javascript
Anybody figured this out ? I need to animate the polyline between two point like growing lines towards destination. (In ArcGis 4.11 Javascript)
Hi, I was able to do this on Android using Esri's SDK (version 100.6.0)
The route I have was from calling
routeTask.solveRouteAsync(routeParameters);
After I had the route (a Graphic object), I added it to the graphics on the graphics overlay
graphicsOverlay.getGraphics().add(routeGraphic)
I got all the graphics from the graphicsOverlay and looked for this route (I know this is not even close to be a good idea, but it's the only one I had).
for (int i = 0; i < graphicsOverlay.getGraphics().size(); i++) {
Graphic g = graphicsOverlay.getGraphics().get(i);
if (g.getGeometry() != null && g.getGeometry().getInternal() != null &&
g.getGeometry().getInternal().w() != null && !g.getGeometry().getInternal().w().equals("")) {
Path path = new Gson().fromJson(g.getGeometry().getInternal().w(), Path.class);
if (path.getPaths() != null && path.getPaths().length > 0) {
Log.d("Graphic " + i, ", " + g.getGeometry().getInternal().w());
List<Marker> points = path.getPoints();
Log.d("path.getPoints", " size " + points.size());
Path.pointsInPath(new ArrayList<>(points), 50, 1); // speed: 50km/h, refresh rate: 1 per second
}
}
}
The Path class was needed to parse the JSon I got from
g.getGeometry().getInternal().w()
In this class the important atritube is
private double[][][] paths
and the important method is getPoints()
public List<Marker> getPoints() {
List<Marker> list = new ArrayList<>();
list.add(new Marker(getPaths()[0][0][0], getPaths()[0][0][1], Marker.REPRESENTATION_WGS84));for (int i = 0; i < getPaths().length; i++) {
for (int j = 0; j < getPaths().length; j++) {
if (j > 0) {
list.add(new Marker(getPaths()[0], getPaths() [1], Marker.REPRESENTATION_WGS84));
}
}
}
return list;
}
This Method joins the segments of the route on the map (as the method: g.getGeometry().getInternal().w() returns a group of segments of the route that ended and started one after the other, I just ignored the first point of each route, except for the first route, to get a succession of points that forms the "real" route I wanted), you may have to change this method acording to your problem.
The Marker class is just like Point from Esri, it has longitud, latitude and its representation (wgs84 in this case)
pointsInPath is a method that shows the current position of the uber, acroding to a speed (50km/h) and a refresh rate (1 per second)
public static List<Marker> pointsInPath(List<Marker> list, double speed, double refreshRate) {
double distRecorrida = (speed / 3600) * refreshRate;
return Path.nextPoint(list, distRecorrida, distRecorrida);
}private static List<Marker> nextPoint(List<Marker> list, double distAcumulada, double distPorSalto) {
if (list == null || list.size() == 0) {
return null;
} else if (list.size() == 1) {
return list;
} else {
Marker org = list.get(0);
Marker dst = list.get(1);
double distPuntos = Marker.LotLong2Km(org, dst);
if (distPuntos < distAcumulada) {
list.remove(0);
return nextPoint(list,distAcumulada - distPuntos, distPorSalto);
} else if (distPuntos > distAcumulada) {
double ratio = distAcumulada / distPuntos;
double newLon = org.lon - (org.lon - dst.lon) * ratio;
double newLat = org.lat - (org.lat - dst.lat) * ratio;
Marker newMarker = new Marker(newLon, newLat, Marker.REPRESENTATION_WGS84);
List<Marker> result = new ArrayList<>();
result.add(newMarker);
list.remove(0);
list.add(0, newMarker);
List<Marker> res = nextPoint(list, distPorSalto, distPorSalto);
if (res != null) {
result.addAll(res);
}
return result;
} else {
List<Marker> result = new ArrayList<>();
result.add(list.get(1));
list.remove(0);
List<Marker> res = nextPoint(list, distPorSalto, distPorSalto);
if (res != null) {
result.addAll(res);
}
return result;
}
}
}