From b1152c4271d78c3b606c481f3e75bb366e6bd7ca Mon Sep 17 00:00:00 2001 From: crimean Date: Sun, 25 Nov 2018 18:41:49 +0300 Subject: [PATCH] Draw transport route with colors --- .../osmand/plus/routing/RoutingHelper.java | 2 +- .../net/osmand/plus/views/OsmandMapLayer.java | 40 +++++- .../src/net/osmand/plus/views/RouteLayer.java | 136 ++++++++++++------ 3 files changed, 134 insertions(+), 44 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index b8e0261d37..9a5f4abe91 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -936,6 +936,7 @@ public class RoutingHelper { } public void recalculateRouteDueToSettingsChange() { + clearCurrentRoute(finalLocation, intermediatePoints); if (isPublicTransportMode()) { Location start = lastFixedLocation; LatLon finish = finalLocation; @@ -946,7 +947,6 @@ public class RoutingHelper { transportRoutingHelper.recalculateRouteDueToSettingsChange(); } } else { - clearCurrentRoute(finalLocation, intermediatePoints); recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false); } } diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java index 767e0cd10e..e024b0dfd4 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java @@ -13,6 +13,7 @@ import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.os.AsyncTask; import android.support.annotation.NonNull; +import android.util.Pair; import android.view.MotionEvent; import net.osmand.binary.BinaryMapIndexReader; @@ -137,14 +138,25 @@ public abstract class OsmandMapLayer { return x >= lx && x <= rx && y >= ty && y <= by; } - public int calculatePath(RotatedTileBox tb, TIntArrayList xs, TIntArrayList ys, Path path) { + List> paths = new ArrayList<>(); + int res = calculatePath(tb, xs, ys, null, paths); + if (paths.size() > 0) { + path.addPath(paths.get(0).first); + } + return res; + } + + public int calculatePath(RotatedTileBox tb, TIntArrayList xs, TIntArrayList ys, List colors, List> paths) { boolean segmentStarted = false; int prevX = xs.get(0); int prevY = ys.get(0); int height = tb.getPixHeight(); int width = tb.getPixWidth(); int cnt = 0; + boolean hasColors = colors != null && colors.size() == xs.size(); + int color = hasColors ? colors.get(0) : 0; + Path path = new Path(); boolean prevIn = isIn(prevX, prevY, 0, 0, width, height); for (int i = 1; i < xs.size(); i++) { int currX = xs.get(i); @@ -186,6 +198,21 @@ public abstract class OsmandMapLayer { prevIn = currIn; prevX = currX; prevY = currY; + + if (hasColors) { + int newColor = colors.get(i); + if (color != newColor) { + paths.add(new Pair<>(path, color)); + path = new Path(); + if (segmentStarted) { + path.moveTo(currX, currY); + } + color = newColor; + } + } + } + if (!path.isEmpty()) { + paths.add(new Pair<>(path, color)); } return cnt; } @@ -383,6 +410,8 @@ public abstract class OsmandMapLayer { protected static class RenderingLineAttributes { protected int cachedHash; public Paint paint; + public Paint customColorPaint; + public int customColor = 0; public int defaultWidth = 0; public int defaultColor = 0; public boolean isPaint2; @@ -402,6 +431,7 @@ public abstract class OsmandMapLayer { public RenderingLineAttributes(String renderingAttribute) { this.renderingAttribute = renderingAttribute; paint = initPaint(); + customColorPaint = new Paint(paint); paint2 = initPaint(); paint3 = initPaint(); paint_1 = initPaint(); @@ -462,6 +492,7 @@ public abstract class OsmandMapLayer { if (paint.getStrokeWidth() == 0 && defaultWidth != 0) { paint.setStrokeWidth(defaultWidth); } + customColorPaint = new Paint(paint); } return true; } @@ -486,7 +517,12 @@ public abstract class OsmandMapLayer { if (isShadowPaint) { canvas.drawPath(path, shadowPaint); } - canvas.drawPath(path, paint); + if (customColor != 0) { + customColorPaint.setColor(customColor); + canvas.drawPath(path, customColorPaint); + } else { + canvas.drawPath(path, paint); + } if (isPaint2) { canvas.drawPath(path, paint2); } diff --git a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java index 3b0ef78466..3ce17b7be9 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java @@ -12,11 +12,13 @@ import android.graphics.PointF; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.support.annotation.ColorInt; +import android.util.Pair; import net.osmand.Location; import net.osmand.data.LatLon; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; +import net.osmand.data.TransportRoute; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OSMSettings; import net.osmand.osm.edit.Way; @@ -28,12 +30,14 @@ import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.TransportRoutingHelper; -import net.osmand.router.TransportRoutePlanner; +import net.osmand.plus.transport.TransportStopRoute; +import net.osmand.plus.transport.TransportStopType; import net.osmand.router.TransportRoutePlanner.TransportRouteResult; import net.osmand.router.TransportRoutePlanner.TransportRouteResultSegment; import net.osmand.util.MapUtils; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -53,8 +57,6 @@ public class RouteLayer extends OsmandMapLayer { // keep array lists created private List actionPoints = new ArrayList(); - private Path path; - // cache private Bitmap coloredArrowUp; private Bitmap actionArrow; @@ -69,6 +71,7 @@ public class RouteLayer extends OsmandMapLayer { private TrackChartPoints trackChartPoints; private RenderingLineAttributes attrs; + private boolean nightMode; public RouteLayer(RoutingHelper helper) { @@ -82,8 +85,7 @@ public class RouteLayer extends OsmandMapLayer { private void initUI() { actionArrow = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_action_arrow, null); - path = new Path(); - + paintIcon = new Paint(); paintIcon.setFilterBitmap(true); paintIcon.setAntiAlias(true); @@ -189,6 +191,7 @@ public class RouteLayer extends OsmandMapLayer { paintIconAction.setColorFilter(new PorterDuffColorFilter(attrs.paint3.getColor(), Mode.MULTIPLY)); paintIcon.setColorFilter(new PorterDuffColorFilter(attrs.paint2.getColor(), Mode.MULTIPLY)); } + nightMode = settings != null && settings.isNightMode(); } private void drawXAxisPoints(Canvas canvas, RotatedTileBox tileBox) { @@ -427,14 +430,27 @@ public class RouteLayer extends OsmandMapLayer { TransportRouteResult transportRoute; double mapDensity; TreeMap zooms = new TreeMap<>(); - List locations = Collections.emptyList(); - + List locations = Collections.emptyList(); + TreeMap colorsMap = new TreeMap<>(); + // cache arrays TIntArrayList tx = new TIntArrayList(); TIntArrayList ty = new TIntArrayList(); List angles = new ArrayList<>(); List distances = new ArrayList<>(); - + List colors = new ArrayList<>(); + + private int getColor(int index) { + List list = new ArrayList<>(colorsMap.keySet()); + for (int i = list.size() -1; i >= 0; i--) { + int c = list.get(i); + if (c <= index) { + return colorsMap.get(c); + } + } + return attrs.paint.getColor(); + } + public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) { if(tb.getMapDensity() != mapDensity || this.route != route) { this.route = route; @@ -443,6 +459,7 @@ public class RouteLayer extends OsmandMapLayer { } else { locations = route.getImmutableAllLocations(); } + colorsMap.clear(); this.mapDensity = tb.getMapDensity(); zooms.clear(); } @@ -453,25 +470,35 @@ public class RouteLayer extends OsmandMapLayer { this.transportRoute = route; if (route == null) { locations = Collections.emptyList(); + colorsMap.clear(); } else { LatLon start = transportHelper.getStartLocation(); LatLon end = transportHelper.getEndLocation(); List list = new ArrayList<>(); - calculateTransportResult(start, end, route, list); + List cols = new ArrayList<>(); + calculateTransportResult(start, end, route, list, cols); List locs = new ArrayList<>(); - for (Way w : list) { - //Location loc = new Location("transport"); - //loc.setLatitude(w.getLatitude()); - //loc.setLongitude(w.getLongitude()); - //locs.add(loc); - for (Node n : w.getNodes()) { - Location ln = new Location("transport"); - ln.setLatitude(n.getLatitude()); - ln.setLongitude(n.getLongitude()); - locs.add(ln); + TreeMap colsMap = new TreeMap<>(); + int i = 0; + int k = 0; + if (list.size() > 0) { + for (Way w : list) { + colsMap.put(k, cols.get(i++)); + //Location loc = new Location(""); + //loc.setLatitude(w.getLatitude()); + //loc.setLongitude(w.getLongitude()); + //locs.add(loc); + for (Node n : w.getNodes()) { + Location ln = new Location(""); + ln.setLatitude(n.getLatitude()); + ln.setLongitude(n.getLongitude()); + locs.add(ln); + k++; + } } } locations = locs; + colorsMap = colsMap; } this.mapDensity = tb.getMapDensity(); zooms.clear(); @@ -494,14 +521,13 @@ public class RouteLayer extends OsmandMapLayer { TByteArrayList simplification = geometryZoom.getSimplifyPoints(); List odistances = geometryZoom.getDistances(); - - clearArrays(); + int color = attrs.paint.getColor(); boolean previousVisible = false; if (lastProjection != null) { if (leftLongitude <= lastProjection.getLongitude() && lastProjection.getLongitude() <= rightLongitude && bottomLatitude <= lastProjection.getLatitude() && lastProjection.getLatitude() <= topLatitude) { - addLocation(tb, lastProjection, tx, ty, angles, distances, 0); + addLocation(tb, lastProjection, color, tx, ty, angles, distances, 0, colors); previousVisible = true; } } @@ -509,7 +535,8 @@ public class RouteLayer extends OsmandMapLayer { int previous = -1; for (int i = currentRoute; i < routeNodes.size(); i++) { Location ls = routeNodes.get(i); - if(simplification.getQuick(i) == 0) { + color = getColor(i); + if (simplification.getQuick(i) == 0 && !colorsMap.containsKey(i)) { continue; } if (leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude && bottomLatitude <= ls.getLatitude() @@ -523,23 +550,23 @@ public class RouteLayer extends OsmandMapLayer { } else if (lastProjection != null) { lt = lastProjection; } - addLocation(tb, lt, tx, ty, angles, distances, 0); // first point + addLocation(tb, lt, color, tx, ty, angles, distances, 0, colors); // first point } - addLocation(tb, ls, tx, ty, angles, distances, dist); + addLocation(tb, ls, color, tx, ty, angles, distances, dist, colors); previousVisible = true; } else if (previousVisible) { - addLocation(tb, ls, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i)); + addLocation(tb, ls, color, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i), colors); double distToFinish = 0; for(int ki = i + 1; ki < odistances.size(); ki++) { distToFinish += odistances.get(ki); } - drawRouteSegment(tb, canvas, tx, ty, angles, distances, distToFinish); + drawRouteSegment(tb, canvas, tx, ty, angles, distances, distToFinish, colors); previousVisible = false; clearArrays(); } previous = i; } - drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0); + drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0, colors); } private void clearArrays() { @@ -547,10 +574,11 @@ public class RouteLayer extends OsmandMapLayer { ty.clear(); distances.clear(); angles.clear(); + colors.clear(); } - private void addLocation(RotatedTileBox tb, Location ls, TIntArrayList tx, TIntArrayList ty, - List angles, List distances, double dist) { + private void addLocation(RotatedTileBox tb, Location ls, int color, TIntArrayList tx, TIntArrayList ty, + List angles, List distances, double dist, List colors) { float x = tb.getPixXFromLatLon(ls.getLatitude(), ls.getLongitude()); float y = tb.getPixYFromLatLon(ls.getLatitude(), ls.getLongitude()); float px = x; @@ -573,21 +601,26 @@ public class RouteLayer extends OsmandMapLayer { ty.add((int) y); angles.add(angle); distances.add(distSegment); + colors.add(color); } } RouteSimplificationGeometry routeGeometry = new RouteSimplificationGeometry(); private void drawRouteSegment(RotatedTileBox tb, Canvas canvas, TIntArrayList tx, TIntArrayList ty, - List angles, List distances, double distToFinish) { - if(tx.size() < 2) { + List angles, List distances, double distToFinish, List colors) { + if (tx.size() < 2) { return; } try { - path.reset(); + List> paths = new ArrayList<>(); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - calculatePath(tb, tx, ty, path); - attrs.drawPath(canvas, path); + calculatePath(tb, tx, ty, colors, paths); + for (Pair pc : paths) { + attrs.customColor = pc.second; + attrs.drawPath(canvas, pc.first); + } + attrs.customColor = 0; if (tb.getZoomAnimation() == 0) { drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, coloredArrowUp, distToFinish); } @@ -768,21 +801,22 @@ public class RouteLayer extends OsmandMapLayer { return false; } - - private void calculateTransportResult(LatLon start, LatLon end, TransportRouteResult r, List res) { + private void calculateTransportResult(LatLon start, LatLon end, TransportRouteResult r, List res, List colors) { if (r != null) { LatLon p = start; for (TransportRouteResultSegment s : r.getSegments()) { LatLon floc = s.getStart().getLocation(); - addWalk(res, p, floc); - res.addAll(s.getGeometry()); + addRouteWalk(p, floc, res, colors); + List geometry = s.getGeometry(); + res.addAll(geometry); + addColors(s.route, geometry.size(), colors); p = s.getEnd().getLocation(); } - addWalk(res, p, end); + addRouteWalk(p, end, res, colors); } } - private void addWalk(List res, LatLon s, LatLon e) { + private void addRouteWalk(LatLon s, LatLon e, List res, List colors) { double dist = MapUtils.getDistance(s, e); if (dist > 50) { Way way = new Way(-1); @@ -790,6 +824,26 @@ public class RouteLayer extends OsmandMapLayer { way.addNode(new Node(s.getLatitude(), s.getLongitude(), -1)); way.addNode(new Node(e.getLatitude(), e.getLongitude(), -1)); res.add(way); + addColors(null, 1, colors); } } + + private void addColors(TransportRoute route, int count, List colors) { + int color; + if (route == null) { + color = attrs.paint.getColor(); + } else { + TransportStopRoute r = new TransportStopRoute(); + r.type = TransportStopType.findType(route.getType()); + r.route = route; + color = r.getColor(helper.getApplication(), nightMode); + } + addColors(color, count, colors); + } + + private void addColors(int color, int count, List colors) { + Integer[] integers = new Integer[count]; + Arrays.fill(integers, color); + colors.addAll(Arrays.asList(integers)); + } }