Skip to content

Commit

Permalink
Fix map freezes by long tracks with gradient coloring
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-osm committed Sep 26, 2024
1 parent 5940597 commit 41a6e88
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 28 deletions.
10 changes: 10 additions & 0 deletions OsmAnd/src/net/osmand/core/android/MapRendererContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public class MapRendererContext {
private volatile MapRendererView mapRendererView;

private float cachedReferenceTileSize;
private boolean heightmapsActive;

public MapRendererContext(OsmandApplication app, float density) {
this.app = app;
Expand Down Expand Up @@ -145,10 +146,15 @@ public void setMapRendererView(@Nullable MapRendererView mapRendererView) {
public MapRendererView getMapRendererView() {
return mapRendererView;
}

public boolean isVectorLayerEnabled() {
return !app.getSettings().MAP_ONLINE_DATA.get();
}

public boolean isHeightmapsActive() {
return heightmapsActive;
}

public void setNightMode(boolean nightMode) {
if (nightMode != this.nightMode) {
this.nightMode = nightMode;
Expand Down Expand Up @@ -403,11 +409,15 @@ public void recreateHeightmapProvider() {
SRTMPlugin srtmPlugin = PluginsHelper.getActivePlugin(SRTMPlugin.class);
if (srtmPlugin == null || !srtmPlugin.is3DMapsEnabled()) {
mapRendererView.resetElevationDataProvider();
heightmapsActive = false;
return;
}
GeoTiffCollection geoTiffCollection = getGeoTiffCollection();
int elevationTileSize = mapRendererView.getElevationDataTileSize();
mapRendererView.setElevationDataProvider(new SqliteHeightmapTileProvider(geoTiffCollection, elevationTileSize));
heightmapsActive = true;
} else {
heightmapsActive = false;
}
}
public void resetHeightmapProvider() {
Expand Down
22 changes: 15 additions & 7 deletions OsmAnd/src/net/osmand/plus/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class Version {
private final String appName;
private final String appVersion;

private static Boolean openGlEsVersionSupported;
private static Boolean openGlExists;

public static boolean isHuawei() {
return getBuildFlavor().contains("huawei");
}
Expand Down Expand Up @@ -192,17 +195,22 @@ public static boolean isOpenGlAvailable(@NonNull OsmandApplication app) {
if (!NativeCore.isAvailable() || isQnxOperatingSystem() || !isOpenGlEsVersionSupported(app)) {
return false;
}
File nativeLibraryDir = new File(app.getApplicationInfo().nativeLibraryDir);
if (checkOpenGlExists(nativeLibraryDir)) return true;
// check opengl doesn't work correctly on some devices when native libs are not unpacked
if (openGlExists == null) {
File nativeLibraryDir = new File(app.getApplicationInfo().nativeLibraryDir);
openGlExists = checkOpenGlExists(nativeLibraryDir);
// check opengl doesn't work correctly on some devices when native libs are not unpacked
}
return true;
}

public static boolean isOpenGlEsVersionSupported(@NonNull OsmandApplication app) {
ActivityManager activityManager = (ActivityManager) app.getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo deviceConfigurationInfo = activityManager.getDeviceConfigurationInfo();
int majorVersion = (deviceConfigurationInfo.reqGlEsVersion & 0xffff0000) >> 16;
return majorVersion >= 3;
if (openGlEsVersionSupported == null) {
ActivityManager activityManager = (ActivityManager) app.getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo deviceConfigurationInfo = activityManager.getDeviceConfigurationInfo();
int majorVersion = (deviceConfigurationInfo.reqGlEsVersion & 0xffff0000) >> 16;
openGlEsVersionSupported = majorVersion >= 3;
}
return openGlEsVersionSupported;
}

public static boolean isQnxOperatingSystem() {
Expand Down
1 change: 1 addition & 0 deletions OsmAnd/src/net/osmand/plus/shared/SharedUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ object SharedUtil {
@JvmStatic
fun jGpxFile(gpxFile: GpxFile): GPXFile {
val jGpxFile = GPXFile(gpxFile.author)
jGpxFile.path = gpxFile.path
jGpxFile.metadata = jMetadata(gpxFile.metadata)
val jTracks = jGpxFile.tracks
for (track in gpxFile.tracks) {
Expand Down
11 changes: 2 additions & 9 deletions OsmAnd/src/net/osmand/plus/track/Gpx3DVisualizationType.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import androidx.annotation.StringRes;

import net.osmand.plus.R;
import net.osmand.plus.plugins.PluginsHelper;
import net.osmand.plus.plugins.externalsensors.SensorAttributesUtils;
import net.osmand.plus.plugins.srtm.SRTMPlugin;
import net.osmand.shared.gpx.primitives.WptPt;
import net.osmand.util.CollectionUtils;

Expand Down Expand Up @@ -63,7 +61,7 @@ public boolean is3dType() {
private static final Float SPEED_TO_HEIGHT_SCALE = 10.0f;
private static final Float TEMPERATURE_TO_HEIGHT_OFFSET = 100.0f;

public static double getPointElevation(@NonNull WptPt point, @NonNull Track3DStyle style) {
public static double getPointElevation(@NonNull WptPt point, @NonNull Track3DStyle style, boolean heightmapsActive) {
double pointElevation = getValidElevation(point.getEle());
Gpx3DVisualizationType type = style.getVisualizationType();

Expand All @@ -75,7 +73,7 @@ public static double getPointElevation(@NonNull WptPt point, @NonNull Track3DSty
case HEART_RATE, BICYCLE_CADENCE, BICYCLE_POWER, TEMPERATURE, SPEED_SENSOR ->
getSensorElevation(point, type);
};
boolean addGpxHeight = is3DMapsEnabled() && !CollectionUtils.equalsToAny(type, ALTITUDE, NONE);
boolean addGpxHeight = heightmapsActive && !CollectionUtils.equalsToAny(type, ALTITUDE, NONE);
return addGpxHeight ? elevation + pointElevation : elevation;
}

Expand Down Expand Up @@ -107,9 +105,4 @@ public static float getSensorElevation(@NonNull WptPt point, @NonNull Gpx3DVisua
private static double getValidElevation(double elevation) {
return Double.isNaN(elevation) ? 0 : elevation;
}

private static boolean is3DMapsEnabled() {
SRTMPlugin plugin = PluginsHelper.getActivePlugin(SRTMPlugin.class);
return plugin != null && plugin.is3DMapsEnabled();
}
}
17 changes: 14 additions & 3 deletions OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import androidx.core.content.ContextCompat;

import net.osmand.PlatformUtil;
import net.osmand.core.android.MapRendererContext;
import net.osmand.plus.shared.SharedUtil;
import net.osmand.core.android.MapRendererView;
import net.osmand.core.jni.*;
Expand Down Expand Up @@ -57,6 +58,7 @@
import net.osmand.plus.track.fragments.TrackAppearanceFragment;
import net.osmand.plus.track.fragments.TrackMenuFragment;
import net.osmand.plus.track.helpers.GpxAppearanceHelper;
import net.osmand.plus.views.corenative.NativeCoreContext;
import net.osmand.shared.gpx.GpxDbHelper;
import net.osmand.plus.track.helpers.GpxDisplayGroup;
import net.osmand.plus.track.helpers.GpxDisplayItem;
Expand Down Expand Up @@ -520,6 +522,14 @@ private int calculateHash(Object... o) {
return Arrays.hashCode(o);
}

private boolean isHeightmapsActive() {
MapRendererContext mapRendererContext = NativeCoreContext.getMapRendererContext();
if (mapRendererContext != null) {
return mapRendererContext.isHeightmapsActive();
}
return false;
}

private void drawSelectedFilesSplits(@NonNull Canvas canvas, @NonNull RotatedTileBox tileBox,
@NonNull List<SelectedGpxFile> selectedGPXFiles) {
if (tileBox.getZoom() >= START_ZOOM) {
Expand All @@ -546,6 +556,7 @@ private void drawSelectedFilesSplitsOpenGl(@NonNull MapRendererView mapRenderer,
@NonNull List<SelectedGpxFile> selectedGPXFiles, boolean forceUpdate) {
if (tileBox.getZoom() >= START_ZOOM) {
boolean changed = forceUpdate;
boolean heightmapsActive = isHeightmapsActive();
int startFinishPointsCount = 0;
int splitLabelsCount = 0;
for (SelectedGpxFile selectedGpxFile : selectedGPXFiles) {
Expand Down Expand Up @@ -618,8 +629,8 @@ private void drawSelectedFilesSplitsOpenGl(@NonNull MapRendererView mapRenderer,
WptPt start = segment.getPoints().get(0);
WptPt finish = segment.getPoints().get(segment.getPoints().size() - 1);
if (visualizationType != Gpx3DVisualizationType.NONE && trackLinePosition == Gpx3DLinePositionType.TOP) {
startFinishHeights.add((float) Gpx3DVisualizationType.getPointElevation(start, track3DStyle));
startFinishHeights.add((float) Gpx3DVisualizationType.getPointElevation(finish, track3DStyle));
startFinishHeights.add((float) Gpx3DVisualizationType.getPointElevation(start, track3DStyle, heightmapsActive));
startFinishHeights.add((float) Gpx3DVisualizationType.getPointElevation(finish, track3DStyle, heightmapsActive));
}
startFinishPoints.add(new PointI(Utilities.get31TileNumberX(start.getLon()), Utilities.get31TileNumberY(start.getLat())));
startFinishPoints.add(new PointI(Utilities.get31TileNumberX(finish.getLon()), Utilities.get31TileNumberY(finish.getLat())));
Expand All @@ -643,7 +654,7 @@ private void drawSelectedFilesSplitsOpenGl(@NonNull MapRendererView mapRenderer,
if (visualizationType == Gpx3DVisualizationType.NONE || trackLinePosition != Gpx3DLinePositionType.TOP) {
splitLabel = new SplitLabel(point31, name, NativeUtilities.createColorARGB(color, 179));
} else {
float labelHeight = (float) Gpx3DVisualizationType.getPointElevation(point, track3DStyle);
float labelHeight = (float) Gpx3DVisualizationType.getPointElevation(point, track3DStyle, heightmapsActive);
splitLabel = new SplitLabel(point31, name, NativeUtilities.createColorARGB(color, 179), labelHeight);
}
splitLabels.add(splitLabel);
Expand Down
10 changes: 10 additions & 0 deletions OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.core.android.MapRendererContext;
import net.osmand.core.android.MapRendererView;
import net.osmand.core.jni.VectorLineArrowsProvider;
import net.osmand.core.jni.VectorLinesCollection;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.views.corenative.NativeCoreContext;
import net.osmand.shared.gpx.GpxUtilities;
import net.osmand.plus.track.Gpx3DVisualizationType;
import net.osmand.plus.views.layers.geometry.GeometryWayDrawer.DrawPathData;
Expand Down Expand Up @@ -102,6 +104,14 @@ public MapRendererView getMapRenderer() {
return context.getMapRenderer();
}

protected boolean isHeightmapsActive() {
MapRendererContext mapRendererContext = NativeCoreContext.getMapRendererContext();
if (mapRendererContext != null) {
return mapRendererContext.isHeightmapsActive();
}
return false;
}

protected void updateWay(@NonNull GeometryWayProvider locationProvider, @NonNull RotatedTileBox tb) {
updateWay(locationProvider, null, tb);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import net.osmand.plus.track.Gpx3DVisualizationType;
import net.osmand.plus.track.Track3DStyle;
import net.osmand.shared.routing.ColoringType;
import net.osmand.shared.routing.RouteColorize.ColorizationType;
import net.osmand.shared.routing.RouteColorize.RouteColorizationPoint;
import net.osmand.router.RouteSegmentResult;
import net.osmand.shared.gpx.primitives.WptPt;
Expand Down Expand Up @@ -97,7 +96,7 @@ public void updateSegment(RotatedTileBox tb, List<WptPt> points,

Track3DStyle track3DStyle = getTrack3DStyle();
if (hasMapRenderer() && track3DStyle != null && track3DStyle.getVisualizationType().is3dType()) {
updateGpx3dWay(tb, points, routeSegments);
updateGpx3dWay(tb, points, routeSegments, isHeightmapsActive());
} else if (coloringType.isTrackSolid()) {
if (hasMapRenderer()) {
Map<Integer, GeometryWayStyle<?>> styleMap = new TreeMap<>();
Expand All @@ -109,7 +108,7 @@ public void updateSegment(RotatedTileBox tb, List<WptPt> points,
}
} else if (coloringType.isGradient()) {
if (hasMapRenderer()) {
updateGpxGradientWay(tb, points);
updateGpxGradientWay(tb, points, isHeightmapsActive());
} else {
updateWay(new GeometryWayWptPtProvider(points), tb);
}
Expand All @@ -123,28 +122,29 @@ public void updateSegment(RotatedTileBox tb, List<WptPt> points,
}
}

protected void updateGpxGradientWay(@NonNull RotatedTileBox tb, @NonNull List<WptPt> points) {
protected void updateGpxGradientWay(@NonNull RotatedTileBox tb, @NonNull List<WptPt> points, boolean heightmapsActive) {
List<RouteColorizationPoint> colorizationPoints = new ArrayList<>();
List<Float> pointHeights = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
WptPt wptPt = points.get(i);
pointHeights.add((float) getPointElevation(wptPt));
pointHeights.add((float) getPointElevation(wptPt, heightmapsActive));
RouteColorizationPoint point = new RouteColorizationPoint(i, wptPt.getLat(), wptPt.getLon(), 0);
point.setPrimaryColor(getPointGradientColor(coloringType, wptPt));
colorizationPoints.add(point);
}
updateWay(new GradientGeometryWayProvider(null, colorizationPoints, pointHeights), createGradientStyles(colorizationPoints), tb);
}

protected void updateGpx3dWay(@NonNull RotatedTileBox tileBox, @NonNull List<WptPt> points, @Nullable List<RouteSegmentResult> segments) {
protected void updateGpx3dWay(@NonNull RotatedTileBox tileBox, @NonNull List<WptPt> points,
@Nullable List<RouteSegmentResult> segments, boolean heightmapsActive) {
ColoringType outlineColoringType = getOutlineColoringType();
List<RouteColorizationPoint> colorization = new ArrayList<>(points.size());
List<Integer> routeColors = coloringType.isRouteInfoAttribute()
? getRouteInfoAttributesColors(RouteProvider.locationsFromSharedWpts(points), segments) : null;

for (int i = 0; i < points.size(); i++) {
WptPt wptPt = points.get(i);
double value = getPointElevation(wptPt);
double value = getPointElevation(wptPt, heightmapsActive);
RouteColorizationPoint point = new RouteColorizationPoint(i, wptPt.getLat(), wptPt.getLon(), value);
point.setPrimaryColor(getPointColor(coloringType, wptPt, routeColors, i));
if (outlineColoringType != null) {
Expand All @@ -155,9 +155,9 @@ protected void updateGpx3dWay(@NonNull RotatedTileBox tileBox, @NonNull List<Wpt
updateWay(new Geometry3DWayProvider(colorization), createGradient3DStyles(colorization), tileBox);
}

private double getPointElevation(@NonNull WptPt point) {
private double getPointElevation(@NonNull WptPt point, boolean heightmapsActive) {
Track3DStyle style = getTrack3DStyle();
return style != null ? Gpx3DVisualizationType.getPointElevation(point, style) : 0;
return style != null ? Gpx3DVisualizationType.getPointElevation(point, style, heightmapsActive) : 0;
}

@ColorInt
Expand Down

0 comments on commit 41a6e88

Please sign in to comment.