Merge pull request #11363 from osmandapp/ui_multi_profile_plan_route
UI multi profile fixes
This commit is contained in:
commit
9d20e4ae11
4 changed files with 73 additions and 49 deletions
|
@ -2,6 +2,7 @@ package net.osmand.plus.measurementtool;
|
||||||
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.TrkSegment;
|
import net.osmand.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
@ -1115,16 +1116,26 @@ public class MeasurementEditingContext implements IRouteSettingsListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInMultiProfileMode() {
|
public boolean isInMultiProfileMode() {
|
||||||
if (lastCalculationMode == CalculationMode.NEXT_SEGMENT) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Set<String> profiles = new HashSet<>();
|
Set<String> profiles = new HashSet<>();
|
||||||
for (RoadSegmentData segmentData : roadSegmentData.values()) {
|
List<TrkSegment> allSegments = new ArrayList<>();
|
||||||
String profile = segmentData.getAppMode().getStringKey();
|
allSegments.addAll(beforeSegments);
|
||||||
if (!DEFAULT_APP_MODE.getStringKey().equals(profile)) {
|
allSegments.addAll(afterSegments);
|
||||||
profiles.add(profile);
|
for (TrkSegment segment : allSegments) {
|
||||||
|
List<WptPt> points = segment.points;
|
||||||
|
if (Algorithms.isEmpty(points)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < points.size() / 2 + 1; i++) {
|
||||||
|
WptPt left = points.get(i);
|
||||||
|
int rightIdx = points.size() - 1 - i;
|
||||||
|
WptPt right = points.get(rightIdx);
|
||||||
|
if (!left.isGap() && i + 1 < points.size()) {
|
||||||
|
profiles.add(left.getProfileType());
|
||||||
|
}
|
||||||
|
if (!right.isGap() && rightIdx + 1 < points.size()) {
|
||||||
|
profiles.add(right.getProfileType());
|
||||||
|
}
|
||||||
if (profiles.size() >= 2) {
|
if (profiles.size() >= 2) {
|
||||||
lastCalculationMode = NEXT_SEGMENT;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,10 @@ import android.graphics.Canvas;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.util.MapAlgorithms;
|
import net.osmand.util.MapAlgorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay.GeometryMultiProfileWayStyle;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -20,6 +15,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import gnu.trove.list.array.TByteArrayList;
|
import gnu.trove.list.array.TByteArrayList;
|
||||||
|
|
||||||
public abstract class GeometryWay<T extends GeometryWayContext, D extends GeometryWayDrawer<T>> {
|
public abstract class GeometryWay<T extends GeometryWayContext, D extends GeometryWayDrawer<T>> {
|
||||||
|
@ -176,7 +173,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
|
||||||
}
|
}
|
||||||
double lat = locationProvider.getLatitude(i);
|
double lat = locationProvider.getLatitude(i);
|
||||||
double lon = locationProvider.getLongitude(i);
|
double lon = locationProvider.getLongitude(i);
|
||||||
if (shouldAddLocation(tb, leftLongitude, rightLongitude, bottomLatitude, topLatitude,
|
if (shouldAddLocation(simplification, leftLongitude, rightLongitude, bottomLatitude, topLatitude,
|
||||||
locationProvider, i)) {
|
locationProvider, i)) {
|
||||||
double dist = previous == -1 ? 0 : odistances.get(i);
|
double dist = previous == -1 ? 0 : odistances.get(i);
|
||||||
if (!previousVisible) {
|
if (!previousVisible) {
|
||||||
|
@ -210,7 +207,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
|
||||||
drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0, styles);
|
drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0, styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldAddLocation(RotatedTileBox tileBox, double leftLon, double rightLon, double bottomLat,
|
protected boolean shouldAddLocation(TByteArrayList simplification, double leftLon, double rightLon, double bottomLat,
|
||||||
double topLat, GeometryWayProvider provider, int currLocationIdx) {
|
double topLat, GeometryWayProvider provider, int currLocationIdx) {
|
||||||
double lat = provider.getLatitude(currLocationIdx);
|
double lat = provider.getLatitude(currLocationIdx);
|
||||||
double lon = provider.getLongitude(currLocationIdx);
|
double lon = provider.getLongitude(currLocationIdx);
|
||||||
|
|
|
@ -29,6 +29,7 @@ import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.graphics.ColorUtils;
|
import androidx.core.graphics.ColorUtils;
|
||||||
|
import gnu.trove.list.array.TByteArrayList;
|
||||||
|
|
||||||
public class MultiProfileGeometryWay extends GeometryWay<MultiProfileGeometryWayContext, MultiProfileGeometryWayDrawer> {
|
public class MultiProfileGeometryWay extends GeometryWay<MultiProfileGeometryWayContext, MultiProfileGeometryWayDrawer> {
|
||||||
|
|
||||||
|
@ -140,27 +141,40 @@ public class MultiProfileGeometryWay extends GeometryWay<MultiProfileGeometryWay
|
||||||
routePoints.add(new LatLon(start.lat, start.lon));
|
routePoints.add(new LatLon(start.lat, start.lon));
|
||||||
routePoints.add(new LatLon(end.lat, end.lon));
|
routePoints.add(new LatLon(end.lat, end.lon));
|
||||||
} else {
|
} else {
|
||||||
|
List<WptPt> points = roadSegmentData.getPoints();
|
||||||
|
if (points.get(0).getLatitude() != start.getLatitude() && points.get(0).getLongitude() != start.getLongitude()) {
|
||||||
|
routePoints.add(new LatLon(start.lat, start.lon));
|
||||||
|
}
|
||||||
for (WptPt routePt : roadSegmentData.getPoints()) {
|
for (WptPt routePt : roadSegmentData.getPoints()) {
|
||||||
routePoints.add(new LatLon(routePt.lat, routePt.lon));
|
routePoints.add(new LatLon(routePt.lat, routePt.lon));
|
||||||
}
|
}
|
||||||
|
int lastIdx = routePoints.size() - 1;
|
||||||
|
if (routePoints.get(lastIdx).getLatitude() != end.getLatitude()
|
||||||
|
&& routePoints.get(lastIdx).getLongitude() != end.getLongitude()) {
|
||||||
|
routePoints.add(new LatLon(end.lat, end.lon));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return routePoints;
|
return routePoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldAddLocation(RotatedTileBox tileBox, double leftLon, double rightLon,
|
protected boolean shouldAddLocation(TByteArrayList simplification, double leftLon, double rightLon,
|
||||||
double bottomLat, double topLat, GeometryWayProvider provider,
|
double bottomLat, double topLat, GeometryWayProvider provider,
|
||||||
int currLocationIdx) {
|
int currLocationIdx) {
|
||||||
float currX = tileBox.getPixXFromLatLon(provider.getLatitude(currLocationIdx), provider.getLongitude(currLocationIdx));
|
double currLat = provider.getLatitude(currLocationIdx);
|
||||||
float currY = tileBox.getPixYFromLatLon(provider.getLatitude(currLocationIdx), provider.getLongitude(currLocationIdx));
|
double currLon = provider.getLongitude(currLocationIdx);
|
||||||
if (tileBox.containsPoint(currX, currY, getContext().circleSize)) {
|
|
||||||
return true;
|
int nextIdx = currLocationIdx;
|
||||||
} else if (currLocationIdx + 1 >= provider.getSize()) {
|
for (int i = nextIdx + 1; i < simplification.size(); i++) {
|
||||||
return false;
|
if (simplification.getQuick(i) == 1) {
|
||||||
|
nextIdx = i;
|
||||||
}
|
}
|
||||||
float nextX = tileBox.getPixXFromLatLon(provider.getLatitude(currLocationIdx + 1), provider.getLongitude(currLocationIdx + 1));
|
}
|
||||||
float nextY = tileBox.getPixXFromLatLon(provider.getLatitude(currLocationIdx + 1), provider.getLongitude(currLocationIdx + 1));
|
|
||||||
return tileBox.containsPoint(nextX, nextY, getContext().circleSize);
|
double nextLat = provider.getLatitude(nextIdx);
|
||||||
|
double nextLon = provider.getLongitude(nextIdx);
|
||||||
|
return Math.min(currLon, nextLon) < rightLon && Math.max(currLon, nextLon) > leftLon
|
||||||
|
&& Math.min(currLat, nextLat) < topLat && Math.max(currLat, nextLat) > bottomLat;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean segmentDataChanged(Map<Pair<WptPt, WptPt>, RoadSegmentData> other) {
|
private boolean segmentDataChanged(Map<Pair<WptPt, WptPt>, RoadSegmentData> other) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext {
|
||||||
|
|
||||||
private RenderingLineAttributes multiProfileAttrs;
|
private RenderingLineAttributes multiProfileAttrs;
|
||||||
|
|
||||||
private Bitmap pointIcon;
|
private final Bitmap pointIcon;
|
||||||
private final Map<String, Bitmap> profileIconsBitmapCache;
|
private final Map<String, Bitmap> profileIconsBitmapCache;
|
||||||
|
|
||||||
public MultiProfileGeometryWayContext(Context ctx, UiUtilities iconsCache, float density) {
|
public MultiProfileGeometryWayContext(Context ctx, UiUtilities iconsCache, float density) {
|
||||||
|
@ -41,6 +41,7 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext {
|
||||||
minIconMargin = density * 30;
|
minIconMargin = density * 30;
|
||||||
circleSize = density * 70;
|
circleSize = density * 70;
|
||||||
pointIconSize = density * 22f;
|
pointIconSize = density * 22f;
|
||||||
|
pointIcon = createPointIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePaints(boolean nightMode, @NonNull RenderingLineAttributes multiProfileAttrs) {
|
public void updatePaints(boolean nightMode, @NonNull RenderingLineAttributes multiProfileAttrs) {
|
||||||
|
@ -48,29 +49,6 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext {
|
||||||
super.updatePaints(nightMode, multiProfileAttrs);
|
super.updatePaints(nightMode, multiProfileAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void recreateBitmaps() {
|
|
||||||
float density = getDensity();
|
|
||||||
float outerRadius = density * 11f;
|
|
||||||
float centerRadius = density * 10.5f;
|
|
||||||
float innerRadius = density * 6.5f;
|
|
||||||
float centerXY = pointIconSize / 2;
|
|
||||||
|
|
||||||
pointIcon = Bitmap.createBitmap((int) pointIconSize, (int) pointIconSize, Bitmap.Config.ARGB_8888);
|
|
||||||
Canvas canvas = new Canvas(pointIcon);
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
|
|
||||||
paint.setColor(Color.BLACK);
|
|
||||||
canvas.drawCircle(centerXY, centerXY, outerRadius, paint);
|
|
||||||
|
|
||||||
paint.setColor(Color.WHITE);
|
|
||||||
canvas.drawCircle(centerXY, centerXY, centerRadius, paint);
|
|
||||||
|
|
||||||
paint.setColor(Algorithms.parseColor(pointColorHex));
|
|
||||||
canvas.drawCircle(centerXY, centerXY, innerRadius, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Bitmap getProfileIconBitmap(@DrawableRes int iconRes, @ColorInt int color) {
|
public Bitmap getProfileIconBitmap(@DrawableRes int iconRes, @ColorInt int color) {
|
||||||
String key = iconRes + "_" + color;
|
String key = iconRes + "_" + color;
|
||||||
|
@ -94,6 +72,30 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext {
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Bitmap createPointIcon() {
|
||||||
|
float density = getDensity();
|
||||||
|
float outerRadius = density * 11f;
|
||||||
|
float centerRadius = density * 10.5f;
|
||||||
|
float innerRadius = density * 6.5f;
|
||||||
|
float centerXY = pointIconSize / 2;
|
||||||
|
|
||||||
|
Bitmap bitmap = Bitmap.createBitmap((int) pointIconSize, (int) pointIconSize, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
|
||||||
|
paint.setColor(Color.BLACK);
|
||||||
|
canvas.drawCircle(centerXY, centerXY, outerRadius, paint);
|
||||||
|
|
||||||
|
paint.setColor(Color.WHITE);
|
||||||
|
canvas.drawCircle(centerXY, centerXY, centerRadius, paint);
|
||||||
|
|
||||||
|
paint.setColor(Algorithms.parseColor(pointColorHex));
|
||||||
|
canvas.drawCircle(centerXY, centerXY, innerRadius, paint);
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Bitmap getPointIcon() {
|
public Bitmap getPointIcon() {
|
||||||
return pointIcon;
|
return pointIcon;
|
||||||
|
|
Loading…
Reference in a new issue