From d2a982398bcd148702b66e296c64a2e4c98a4838 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Fri, 29 Jul 2016 14:29:22 +0200 Subject: [PATCH 1/2] Update route layer --- .../src/net/osmand/plus/views/GPXLayer.java | 3 - .../net/osmand/plus/views/OsmandMapLayer.java | 138 +++++++++++++++++- .../src/net/osmand/plus/views/RouteLayer.java | 118 ++++----------- 3 files changed, 159 insertions(+), 100 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index 8e6c59308d..efc3e0a255 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -369,17 +369,14 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex for (SelectedGpxFile g : selectedGPXFiles) { List segments = g.getPointsToDisplay(); for (TrkSegment ts : segments) { - if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD) && !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how? - if (g.isShowCurrentTrack()) { ts.renders.add(new Renderable.CurrentTrack(ts.points)); } else { ts.renders.add(new Renderable.StandardTrack(ts.points, 17.2)); } } - updatePaints(ts.getColor(cachedColor), g.isRoutePoints(), g.isShowCurrentTrack(), settings, tileBox); ts.drawRenderers(view.getZoom(), paint, canvas, tileBox); } diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java index a3084832c3..8ea5a0b455 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapLayer.java @@ -1,21 +1,33 @@ package net.osmand.plus.views; import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; +import android.graphics.PorterDuffColorFilter; +import android.graphics.Paint.Cap; +import android.graphics.Paint.Join; +import android.graphics.Paint.Style; +import android.graphics.PorterDuff.Mode; import android.os.AsyncTask; import android.support.annotation.NonNull; import android.view.MotionEvent; - import net.osmand.data.LatLon; import net.osmand.data.QuadRect; import net.osmand.data.QuadTree; import net.osmand.data.RotatedTileBox; import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.render.OsmandRenderer; +import net.osmand.plus.render.OsmandRenderer.RenderingContext; +import net.osmand.render.RenderingRuleSearchRequest; +import net.osmand.render.RenderingRulesStorage; import net.osmand.util.MapAlgorithms; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -115,25 +127,28 @@ public abstract class OsmandMapLayer { int py = ys.get(0); int h = tb.getPixHeight(); int w = tb.getPixWidth(); + int left = -w / 4; + int right = w + w / 4; + int top = - h/4; + int bottom = h + h/4; int cnt = 0; - boolean pin = isIn(px, py, 0, 0, w, h); - Path path = null; + + boolean pin = isIn(px, py, left, top, right, bottom); for (int i = 1; i < xs.size(); i++) { int x = xs.get(i); int y = ys.get(i); - boolean in = isIn(x, y, 0, 0, w, h); + boolean in = isIn(x, y, left, top, right, bottom); boolean draw = false; if (pin && in) { draw = true; } else { long intersection = MapAlgorithms.calculateIntersection(x, y, - px, py, 0, w, h, 0); + px, py, left, right, bottom, top); if (intersection != -1) { draw = true; } } if (draw) { - path = new Path(); results.add(px); results.add(py); results.add(x); @@ -323,4 +338,115 @@ public abstract class OsmandMapLayer { } + protected static class RenderingLineAttributes { + protected int cachedHash; + public Paint paint; + public int defaultWidth = 0; + public int defaultColor = 0; + public boolean isPaint2; + public Paint paint2; + public int defaultWidth2 = 0; + public boolean isPaint3; + public Paint paint3; + public int defaultWidth3 = 0; + public Paint shadowPaint; + public boolean isShadowPaint; + public int defaultShadowWidthExtent = 2; + public Paint paint_1; + public boolean isPaint_1; + public int defaultWidth_1 = 0; + private String renderingAttribute; + + public RenderingLineAttributes(String renderingAttribute) { + this.renderingAttribute = renderingAttribute; + paint = initPaint(); + paint2 = initPaint(); + paint3 = initPaint(); + paint_1 = initPaint(); + shadowPaint = initPaint(); + } + + + private Paint initPaint() { + Paint paint = new Paint(); + paint.setStyle(Style.STROKE); + paint.setAntiAlias(true); + paint.setStrokeCap(Cap.ROUND); + paint.setStrokeJoin(Join.ROUND); + return paint; + } + + + public boolean updatePaints(OsmandMapTileView view, DrawSettings settigns, RotatedTileBox tileBox) { + OsmandApplication app = view.getApplication(); + OsmandRenderer renderer = app.getResourceManager().getRenderer().getRenderer(); + RenderingRulesStorage rrs = app.getRendererRegistry().getCurrentSelectedRenderer(); + final boolean isNight = settigns != null && settigns.isNightMode(); + int hsh = calculateHash(rrs, isNight, tileBox.getMapDensity()); + if (hsh != cachedHash) { + cachedHash = hsh; + if (rrs != null) { + RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs); + req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, isNight); + if (req.searchRenderingAttribute(renderingAttribute)) { + RenderingContext rc = new OsmandRenderer.RenderingContext(app); + rc.setDensityValue((float) tileBox.getMapDensity()); + // cachedColor = req.getIntPropertyValue(rrs.PROPS.R_COLOR); + renderer.updatePaint(req, paint, 0, false, rc); + if(paint.getColor() == 0 && defaultColor != 0) { + paint.setColor(defaultColor); + } + if (paint.getStrokeWidth() == 0 && defaultWidth != 0) { + paint.setStrokeWidth(defaultWidth); + } + isPaint2 = renderer.updatePaint(req, paint2, 1, false, rc); + if (paint2.getStrokeWidth() == 0 && defaultWidth2 != 0) { + paint2.setStrokeWidth(defaultWidth2); + } + isPaint3 = renderer.updatePaint(req, paint3, 2, false, rc); + if (paint3.getStrokeWidth() == 0 && defaultWidth3 != 0) { + paint3.setStrokeWidth(defaultWidth3); + } + isPaint_1 = renderer.updatePaint(req, paint_1, -1, false, rc); + if (paint_1.getStrokeWidth() == 0 && defaultWidth_1 != 0) { + paint_1.setStrokeWidth(defaultWidth_1); + } + isShadowPaint = req.isSpecified(rrs.PROPS.R_SHADOW_RADIUS); + if (isShadowPaint) { + ColorFilter cf = new PorterDuffColorFilter( + req.getIntPropertyValue(rrs.PROPS.R_SHADOW_COLOR), Mode.SRC_IN); + shadowPaint.setColorFilter(cf); + shadowPaint.setStrokeWidth(paint.getStrokeWidth() + defaultShadowWidthExtent + * rc.getComplexValue(req, rrs.PROPS.R_SHADOW_RADIUS)); + } + } else { + System.err.println("Rendering attribute route is not found !"); + paint.setStrokeWidth(defaultWidth); + } + } + return true; + } + return false; + } + + private int calculateHash(Object... o) { + return Arrays.hashCode(o); + } + + public void drawPath(Canvas canvas, Path path) { + if (isPaint_1) { + canvas.drawPath(path, paint_1); + } + if (isShadowPaint) { + canvas.drawPath(path, shadowPaint); + } + canvas.drawPath(path, paint); + if (isPaint2) { + canvas.drawPath(path, paint2); + } + if (isPaint3) { + canvas.drawPath(path, paint3); + } + } + } } diff --git a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java index 35e8ec5682..039ed62454 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java @@ -10,6 +10,7 @@ import java.util.List; import net.osmand.Location; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.render.OsmandRenderer; import net.osmand.plus.render.OsmandRenderer.RenderingContext; @@ -39,15 +40,6 @@ public class RouteLayer extends OsmandMapLayer { private final RoutingHelper helper; private List points = new ArrayList(); private List actionPoints = new ArrayList(); - private Paint paint; - private Paint actionPaint; - private Paint paint2; - private boolean isPaint2; - private Paint shadowPaint; - private boolean isShadowPaint; - private Paint paint_1; - private boolean isPaint_1; - private int cachedHash; private Path path; @@ -58,7 +50,7 @@ public class RouteLayer extends OsmandMapLayer { private Paint paintIcon; private Paint paintIconAction; - private OsmandRenderer osmandRenderer; + private RenderingLineAttributes attrs; public RouteLayer(RoutingHelper helper){ @@ -67,20 +59,7 @@ public class RouteLayer extends OsmandMapLayer { private void initUI() { - paint = new Paint(); - paint.setStyle(Style.STROKE); - paint.setAntiAlias(true); - paint.setStrokeCap(Cap.ROUND); - paint.setStrokeJoin(Join.ROUND); actionArrow = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_action_arrow, null); - - actionPaint = new Paint(); - actionPaint.setStyle(Style.STROKE); - actionPaint.setAntiAlias(true); - actionPaint.setStrokeCap(Cap.BUTT); - actionPaint.setStrokeJoin(Join.ROUND); - actionPaint.setStrokeWidth(7 * view.getScaleCoefficient()); - actionPaint.setColor(Color.WHITE); path = new Path(); paintIcon = new Paint(); @@ -89,72 +68,39 @@ public class RouteLayer extends OsmandMapLayer { paintIcon.setColor(Color.BLACK); paintIcon.setStrokeWidth(3); - paintIconAction = new Paint(); paintIconAction.setFilterBitmap(true); paintIconAction.setAntiAlias(true); + attrs = new RenderingLineAttributes("route"); + attrs.defaultWidth = (int) (12 * view.getDensity()); + attrs.defaultWidth3 = (int) (7 * view.getDensity()); + attrs.defaultColor = view.getResources().getColor(R.color.nav_track); + attrs.paint3.setStrokeCap(Cap.BUTT); + attrs.paint3.setColor(Color.WHITE); } @Override public void initLayer(OsmandMapTileView view) { this.view = view; - osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer(); initUI(); } public void updateLayerStyle() { - cachedHash = -1; + attrs.cachedHash = -1; } - private void updatePaints(DrawSettings nightMode, RotatedTileBox tileBox){ - RenderingRulesStorage rrs = view.getApplication().getRendererRegistry().getCurrentSelectedRenderer(); - final boolean isNight = nightMode != null && nightMode.isNightMode(); - int hsh = calculateHash(rrs, isNight, tileBox.getMapDensity()); - if (hsh != cachedHash) { - cachedHash = hsh; - // cachedColor = view.getResources().getColor(R.color.nav_track); - if (rrs != null) { - RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs); - req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, isNight); - if (req.searchRenderingAttribute("route")) { - RenderingContext rc = new OsmandRenderer.RenderingContext(view.getContext()); - rc.setDensityValue((float) tileBox.getMapDensity()); -// cachedColor = req.getIntPropertyValue(rrs.PROPS.R_COLOR); - osmandRenderer.updatePaint(req, paint, 0, false, rc); - if(paint.getStrokeWidth() == 0) { - paint.setStrokeWidth(12 * view.getDensity()); - } - osmandRenderer.updatePaint(req, actionPaint, 2, false, rc); - paintIconAction.setColorFilter(new PorterDuffColorFilter(actionPaint.getColor(), Mode.MULTIPLY)); - - isPaint2 = osmandRenderer.updatePaint(req, paint2, 1, false, rc); - isPaint_1 = osmandRenderer.updatePaint(req, paint_1, -1, false, rc); - isShadowPaint = req.isSpecified(rrs.PROPS.R_SHADOW_RADIUS); - if(isShadowPaint) { - ColorFilter cf = new PorterDuffColorFilter(req.getIntPropertyValue(rrs.PROPS.R_SHADOW_COLOR), Mode.SRC_IN); - shadowPaint.setColorFilter(cf); - shadowPaint.setStrokeWidth(paint.getStrokeWidth() + 2 * rc.getComplexValue(req, rrs.PROPS.R_SHADOW_RADIUS)); - } - } else { - System.err.println("Rendering attribute route is not found !"); - paint.setStrokeWidth(12 * view.getDensity()); - } - actionPaint.setStrokeWidth(7 * view.getScaleCoefficient()); - } - } - } - - - private int calculateHash(Object... o) { - return Arrays.hashCode(o); - } @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { path.reset(); if (helper.getFinalLocation() != null && helper.getRoute().isCalculated()) { - updatePaints(settings, tileBox); + boolean updatePaints = attrs.updatePaints(view, settings, tileBox); + attrs.isPaint3 = false; + if(updatePaints) { + paintIconAction.setColorFilter(new PorterDuffColorFilter(attrs.paint3.getColor(), Mode.MULTIPLY)); + } + if(coloredArrowUp == null) { Bitmap originalArrowUp = BitmapFactory.decodeResource(view.getResources(), R.drawable.h_arrow, null); coloredArrowUp = originalArrowUp; @@ -200,7 +146,7 @@ public class RouteLayer extends OsmandMapLayer { Location o = actionPoints.get(i); if (o == null) { first = true; - canvas.drawPath(pth, actionPaint); + canvas.drawPath(pth, attrs.paint3); double angleRad = Math.atan2(y - py, x - px); double angle = (angleRad * 180 / Math.PI) + 90f; double distSegment = Math.sqrt((y - py) * (y - py) + (x - px) * (x - px)); @@ -250,17 +196,7 @@ public class RouteLayer extends OsmandMapLayer { ty.add(y); } calculatePath(tb, tx, ty, path); - - if (isPaint_1) { - canvas.drawPath(path, paint_1); - } - if (isShadowPaint) { - canvas.drawPath(path, shadowPaint); - } - canvas.drawPath(path, paint); - if (isPaint2) { - canvas.drawPath(path, paint2); - } + attrs.drawPath(canvas, path); if (tb.getZoomAnimation() == 0) { TIntArrayList lst = new TIntArrayList(50); calculateSplitPaths(tb, tx, ty, lst); @@ -274,29 +210,29 @@ public class RouteLayer extends OsmandMapLayer { private void drawArrowsOverPath(Canvas canvas, TIntArrayList lst, Bitmap arrow) { - float pxStep = arrow.getHeight() * 4f; + double pxStep = arrow.getHeight() * 4f; Matrix matrix = new Matrix(); - float dist = 0; + double dist = 0; for (int i = 0; i < lst.size(); i += 4) { int px = lst.get(i); int py = lst.get(i + 1); int x = lst.get(i + 2); int y = lst.get(i + 3); - float angleRad = (float) Math.atan2(y - py, x - px); - float angle = (float) (angleRad * 180 / Math.PI) + 90f; - float distSegment = (float) Math.sqrt((y - py) * (y - py) + (x - px) * (x - px)); + double angleRad = Math.atan2(y - py, x - px); + double angle = (angleRad * 180 / Math.PI) + 90f; + double distSegment = Math.sqrt((y - py) * (y - py) + (x - px) * (x - px)); if(distSegment == 0) { continue; } int len = (int) (distSegment / pxStep); if (len > 0) { - float pdx = ((x - px) / len); - float pdy = ((y - py) / len); + double pdx = ((x - px) / len); + double pdy = ((y - py) / len); for (int k = 1; k <= len; k++) { matrix.reset(); matrix.postTranslate(0, -arrow.getHeight() / 2); - matrix.postRotate(angle, arrow.getWidth() / 2, 0); - matrix.postTranslate(px + k * pdx- arrow.getWidth() / 2 , py + pdy * k); + matrix.postRotate((float) angle, arrow.getWidth() / 2, 0); + matrix.postTranslate((float)(px + k * pdx- arrow.getWidth() / 2) , (float)(py + pdy * k)); canvas.drawBitmap(arrow, matrix, paintIcon); dist = 0; } @@ -304,7 +240,7 @@ public class RouteLayer extends OsmandMapLayer { if(dist > pxStep) { matrix.reset(); matrix.postTranslate(0, -arrow.getHeight() / 2); - matrix.postRotate(angle, arrow.getWidth() / 2, 0); + matrix.postRotate((float) angle, arrow.getWidth() / 2, 0); matrix.postTranslate(px + (x - px) / 2 - arrow.getWidth() / 2, py + (y - py) / 2); canvas.drawBitmap(arrow, matrix, paintIcon); dist = 0; From 0855c6c36d1d10760efecc2dcc04c3840362ca87 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Fri, 29 Jul 2016 15:14:11 +0200 Subject: [PATCH 2/2] Update route layer --- .../controllers/TransportStopController.java | 51 +++++++------------ .../resources/TransportIndexRepository.java | 2 +- .../TransportIndexRepositoryBinary.java | 30 ++--------- 3 files changed, 24 insertions(+), 59 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java index 731cde125c..f79287d248 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java @@ -2,6 +2,7 @@ package net.osmand.plus.mapcontextmenu.controllers; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.data.TransportRoute; import net.osmand.data.TransportStop; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -62,7 +63,7 @@ public class TransportStopController extends MenuController { } private TransportStop transportStop; - private List> routes = new ArrayList<>(); + private List routes = new ArrayList<>(); private TransportStopType topType; public TransportStopController(OsmandApplication app, MapActivity mapActivity, @@ -111,13 +112,11 @@ public class TransportStopController extends MenuController { @Override public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) { - for (List l : routes) { - for (TransportStopRoute r : l) { - if (r.type == null) { - addPlainMenuItem(R.drawable.ic_action_polygom_dark, r.desc, false, false); - } else { - addPlainMenuItem(r.type.getResourceId(), r.desc, false, false); - } + for (TransportStopRoute r : routes) { + if (r.type == null) { + addPlainMenuItem(R.drawable.ic_action_polygom_dark, r.desc, false, false); + } else { + addPlainMenuItem(r.type.getResourceId(), r.desc, false, false); } } super.addPlainMenuItems(typeStr, pointDescription, latLon); @@ -133,33 +132,18 @@ public class TransportStopController extends MenuController { for (TransportIndexRepository t : reps) { if (t.acceptTransportStop(transportStop)) { - List l; - if (useEnglishNames) { - l = t.getRouteDescriptionsForStop(transportStop, "{1} {0} - {3}"); - } else { - l = t.getRouteDescriptionsForStop(transportStop, "{1} {0} - {2}"); - } - if (l != null) { - List routeList = new ArrayList<>(); - for (String s : l) { - int firstSpaceIndex = s.indexOf(' '); - if (firstSpaceIndex != -1) { - String typeName = s.substring(0, firstSpaceIndex); - TransportStopType type = TransportStopType.findType(typeName); - TransportStopRoute r = new TransportStopRoute(); - r.type = type; - if (type == null) { - r.desc = s; - } else { - r.desc = s.substring(firstSpaceIndex + 1); - } - routeList.add(r); - if (topType == null && type != null && type.isTopType()) { - topType = type; - } + List rts = t.getRouteForStop(transportStop); + if (rts != null) { + for (TransportRoute rs : rts) { + TransportStopType type = TransportStopType.findType(rs.getType()); + TransportStopRoute r = new TransportStopRoute(); + if (topType == null && type != null && type.isTopType()) { + topType = type; } + r.desc = rs.getRef() + " " + (useEnglishNames ? rs.getName() : rs.getEnName(true)); + r.route = rs; + this.routes.add(r); } - routes.add(routeList); } } } @@ -168,5 +152,6 @@ public class TransportStopController extends MenuController { private class TransportStopRoute { public TransportStopType type; public String desc; + public TransportRoute route; } } diff --git a/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepository.java b/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepository.java index e228f24eca..9e6df98679 100644 --- a/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepository.java +++ b/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepository.java @@ -18,7 +18,7 @@ public interface TransportIndexRepository { public void searchTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, List stops, ResultMatcher matcher); - public List getRouteDescriptionsForStop(TransportStop stop, String format); + public List getRouteForStop(TransportStop stop); public List searchTransportRouteStops(double latitude, double longitude, LatLon locationToGo, int zoom); diff --git a/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepositoryBinary.java index fb521a0812..aadb5201e7 100644 --- a/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/resources/TransportIndexRepositoryBinary.java @@ -55,38 +55,18 @@ public class TransportIndexRepositoryBinary implements TransportIndexRepository } } - - /** - * - * @param stop - * @param format {0} - ref, {1} - type, {2} - name, {3} - name_en - * @return null if something goes wrong - */ @Override - public List getRouteDescriptionsForStop(TransportStop stop, String format) { - assert acceptTransportStop(stop); - long now = System.currentTimeMillis(); - - MessageFormat f = new MessageFormat(format); - List res = new ArrayList(); + public List getRouteForStop(TransportStop stop){ try { - List routes = file.getTransportRouteDescriptions(stop); - if(routes != null){ - for(TransportRoute route : routes){ - res.add(f.format(new String[] { route.getRef() + "", route.getType() + "", route.getName() + "", route.getEnName(true) + "" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } + List res = file.getTransportRouteDescriptions(stop); + if(res != null){ + return res; } } catch (IOException e) { log.error("Disk error ", e); //$NON-NLS-1$ } - - if (log.isDebugEnabled()) { - log.debug(String.format("Search for stop %s done in %s ms found %s.", //$NON-NLS-1$ - stop.getId() + "", System.currentTimeMillis() - now, res.size())); //$NON-NLS-1$ - } - return res; + return Collections.emptyList(); } - @Override