diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java index eda20443e8..fa5f648217 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java @@ -3,14 +3,12 @@ package net.osmand.plus.views.layers.geometry; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.Path; -import android.graphics.PathMeasure; -import android.util.Log; import android.util.Pair; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; import net.osmand.Location; +import net.osmand.data.LatLon; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.osm.edit.Node; @@ -67,7 +65,7 @@ public class MultiProfileGeometryWay extends GeometryWay allSegments = new ArrayList<>(); allSegments.addAll(beforeSegments); allSegments.addAll(afterSegments); - setStyles(tileBox, allSegments, ways, styles); + setStyles(allSegments, ways, styles); styleMap = new TreeMap<>(); int i = 0; @@ -97,16 +95,13 @@ public class MultiProfileGeometryWay extends GeometryWay segments, List ways, List> styles) { - Path path = new Path(); - PathMeasure pathMeasure = new PathMeasure(); - + private void setStyles(List segments, List ways, List> styles) { for (TrkSegment segment : segments) { List points = segment.points; for (int i = 0; i < points.size() - 1; i++) { - setStylesInternal(tileBox, points, i, ways, styles, path, pathMeasure); + setStylesInternal(points, i, ways, styles); } - styles.add(new GeometryMultiProfileWayStyle(getContext(), 0, 0, true)); + styles.add(new GeometryMultiProfileWayStyle(getContext(), new ArrayList(), 0, 0, true)); Way way = new Way(-1); WptPt last = points.get(points.size() - 1); way.addNode(new Node(last.lat, last.lon, -1)); @@ -114,48 +109,42 @@ public class MultiProfileGeometryWay extends GeometryWay points, int idx, List ways, - List> styles, Path path, PathMeasure pathMeasure) { - MultiProfileGeometryWayContext context = getContext(); - WptPt leftPt = points.get(idx); - Pair userLine = new Pair<>(leftPt, points.get(idx + 1)); - RoadSegmentData routeBetweenPoints = segmentData.get(userLine); + private void setStylesInternal(List points, int idx, List ways, List> styles) { + WptPt startPt = points.get(idx); + WptPt endPt = points.get(idx + 1); + List routePoints = getRoutePoints(startPt, endPt); boolean isSecondToLast = idx + 2 == points.size(); Way way = new Way(-1); - String currProfileKey = getProfileKey(leftPt); + String currProfileKey = getProfileKey(startPt); Pair profileData = getProfileData(currProfileKey); GeometryMultiProfileWayStyle style = new GeometryMultiProfileWayStyle( - getContext(), profileData.first, profileData.second); + getContext(), routePoints, profileData.first, profileData.second); styles.add(style); ways.add(way); - path.reset(); - if (routeBetweenPoints == null || Algorithms.isEmpty(routeBetweenPoints.getPoints())) { - way.addNode(new Node(userLine.first.lat, userLine.first.lon, -1)); - if (isSecondToLast) { - way.addNode(new Node(userLine.second.lat, userLine.second.lon, -1)); - } - movePathToWpt(path, tileBox, userLine.first); - pathLineToWpt(path, tileBox, userLine.second); - } else { - movePathToWpt(path, tileBox, routeBetweenPoints.getPoints().get(0)); - for (WptPt pt : routeBetweenPoints.getPoints()) { - if (pt.lat != userLine.second.lat && pt.lon != userLine.second.lon || isSecondToLast) { - way.addNode(new Node(pt.lat, pt.lon, -1)); - } - pathLineToWpt(path, tileBox, pt); + for (LatLon routePt : routePoints) { + if (isSecondToLast || routePt.getLatitude() != endPt.getLatitude() + && routePt.getLongitude() != endPt.getLongitude()) { + way.addNode(new Node(routePt.getLatitude(), routePt.getLongitude(), -1)); } } + } - float[] xy = new float[2]; - pathMeasure.setPath(path, false); - float routeLength = pathMeasure.getLength(); - if ((routeLength - context.circleSize) / 2 >= context.minIconMargin) { - pathMeasure.getPosTan(pathMeasure.getLength() * 0.5f, xy, null); - style.setIconLat(tileBox.getLatFromPixel(xy[0], xy[1])); - style.setIconLon(tileBox.getLonFromPixel(xy[0], xy[1])); + private List getRoutePoints(WptPt start, WptPt end) { + Pair userLine = new Pair<>(start, end); + RoadSegmentData roadSegmentData = segmentData.get(userLine); + List routePoints = new ArrayList<>(); + + if (roadSegmentData == null || Algorithms.isEmpty(roadSegmentData.getPoints())) { + routePoints.add(new LatLon(start.lat, start.lon)); + routePoints.add(new LatLon(end.lat, end.lon)); + } else { + for (WptPt routePt : roadSegmentData.getPoints()) { + routePoints.add(new LatLon(routePt.lat, routePt.lon)); + } } + return routePoints; } @Override @@ -186,14 +175,6 @@ public class MultiProfileGeometryWay extends GeometryWay routePoints; - public GeometryMultiProfileWayStyle(MultiProfileGeometryWayContext context, + public GeometryMultiProfileWayStyle(MultiProfileGeometryWayContext context, List routePoints, @ColorInt int profileColor, @DrawableRes int profileIconRes, boolean isGap) { super(context); + this.routePoints = routePoints; this.lineColor = profileColor; this.borderColor = ColorUtils.blendARGB(profileColor, Color.BLACK, 0.2f); this.profileIconRes = profileIconRes; @@ -244,9 +225,9 @@ public class MultiProfileGeometryWay extends GeometryWay routePoints, @ColorInt int profileColor, @DrawableRes int profileIconRes) { - this(context, profileColor, profileIconRes, false); + this(context, routePoints, profileColor, profileIconRes, false); } @ColorInt @@ -264,20 +245,12 @@ public class MultiProfileGeometryWay extends GeometryWay getRoutePoints() { + return routePoints; } - public void setIconLon(double lon) { - iconLon = lon; - } - - public double getIconLat() { - return iconLat; - } - - public double getIconLon() { - return iconLon; + public boolean isGap() { + return isGap; } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java index 52fed039ac..b0c7e7c369 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java @@ -2,10 +2,14 @@ package net.osmand.plus.views.layers.geometry; import android.graphics.Canvas; import android.graphics.Path; +import android.graphics.PathMeasure; +import android.graphics.PointF; +import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay.GeometryMultiProfileWayStyle; +import net.osmand.util.Algorithms; import java.util.List; @@ -30,20 +34,51 @@ public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer tx, List ty, List angles, List distances, double distPixToFinish, List> styles) { + Path path = new Path(); + PathMeasure pathMeasure = new PathMeasure(); MultiProfileGeometryWayContext context = getContext(); GeometryMultiProfileWayStyle style = null; for (int i = 0; i < styles.size(); i++) { - if (styles.get(i) != null && !styles.get(i).equals(style)) { + GeometryWayStyle s = styles.get(i); + if (s != null && !s.equals(style) || !((GeometryMultiProfileWayStyle) s).isGap()) { style = (GeometryMultiProfileWayStyle) styles.get(i); - double lat = style.getIconLat(); - double lon = style.getIconLon(); - if (!Double.isNaN(lat) && !Double.isNaN(lon)) { - float x = tb.getPixXFromLatLon(lat, lon) - context.circleSize / 2; - float y = tb.getPixYFromLatLon(lat, lon) - context.circleSize / 2; + PointF center = getIconCenter(tb, style.getRoutePoints(), path, pathMeasure); + if (center != null && tb.containsPoint(center.x, center.y, context.circleSize)) { + float x = center.x - context.circleSize / 2; + float y = center.y - context.circleSize / 2; canvas.drawBitmap(style.getPointBitmap(), x, y, null); } } } } + + private PointF getIconCenter(RotatedTileBox tileBox, List routePoints, Path path, PathMeasure pathMeasure) { + if (Algorithms.isEmpty(routePoints)) { + return null; + } + + path.reset(); + PointF first = getPoint(tileBox, routePoints.get(0)); + path.moveTo(first.x, first.y); + for (int i = 1; i < routePoints.size(); i++) { + PointF pt = getPoint(tileBox, routePoints.get(i)); + path.lineTo(pt.x, pt.y); + } + + pathMeasure.setPath(path, false); + float routeLength = pathMeasure.getLength(); + if ((routeLength - getContext().circleSize) / 2 < getContext().minIconMargin) { + return null; + } + + float[] xy = new float[2]; + pathMeasure.getPosTan(routeLength * 0.5f, xy, null); + return new PointF(xy[0], xy[1]); + } + + private PointF getPoint(RotatedTileBox tileBox, LatLon latLon) { + return new PointF(tileBox.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude()), + tileBox.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude())); + } } \ No newline at end of file