Skip to content

Commit

Permalink
Merge branch 'osmandapp:master' into hardy_Afa
Browse files Browse the repository at this point in the history
  • Loading branch information
sonora authored Dec 6, 2024
2 parents 38f6cd1 + bfe4f4e commit 86c6ba4
Show file tree
Hide file tree
Showing 121 changed files with 9,578 additions and 767 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,15 @@ public String getDestinationRef(String lang, boolean transliterate, boolean dire
int k = kt[i];
if (region.routeEncodingRules.size() > k) {
if (refTag.equals(region.routeEncodingRules.get(k).getTag())) {
return names.get(k);
return Algorithms.splitAndClearRepeats(names.get(k), ";");
}
if (refTagDefault.equals(region.routeEncodingRules.get(k).getTag())) {
refDefault = names.get(k);
}
}
}
if (refDefault != null) {
return refDefault;
return Algorithms.splitAndClearRepeats(refDefault, ";");
}
//return names.get(region.refTypeRule);
}
Expand Down
4 changes: 4 additions & 0 deletions OsmAnd-java/src/main/java/net/osmand/router/ExitInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ public String getExitStreetName() {
public void setExitStreetName(String exitStreetName) {
this.exitStreetName = exitStreetName;
}

public boolean isEmpty() {
return ref == null && exitStreetName == null;
}
}
56 changes: 23 additions & 33 deletions OsmAnd-java/src/main/java/net/osmand/router/GeneralRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ public class GeneralRouter implements VehicleRouter {

// cached values
private boolean restrictionsAware = true;
private float sharpTurn;
private float roundaboutTurn;
private float slightTurn;
private float sharpTurn, shortWaySharpTurn;
private float slightTurn, shortWaySlightTurn;
private float roundaboutTurn, shortWayRoundaboutTurn;
// speed in m/s
private float minSpeed = 0.28f;
// speed in m/s
Expand All @@ -97,8 +97,7 @@ public class GeneralRouter implements VehicleRouter {
public String[] hhNativeFilter = new String[0]; // getFilteredTags() as flat Array (JNI)
public String[] hhNativeParameterValues = new String[0]; // parameterValues as flat Array (JNI)
private final GeneralRouter root;



public enum RouteDataObjectAttribute {
ROAD_SPEED("speed"),
ROAD_PRIORITIES("priority"),
Expand Down Expand Up @@ -293,6 +292,12 @@ public void addAttribute(String k, String v) {
minSpeed = parseSilentFloat(v, minSpeed * 3.6f) / 3.6f;
} else if (k.equals("maxDefaultSpeed") || k.equals("maxSpeed")) {
maxSpeed = parseSilentFloat(v, maxSpeed * 3.6f) / 3.6f;
} else if (k.equals("shortWaySharpTurn")) {
shortWaySharpTurn = parseSilentFloat(v, shortWaySharpTurn);
} else if (k.equals("shortWaySlightTurn")) {
shortWaySlightTurn = parseSilentFloat(v, shortWaySlightTurn);
} else if (k.equals("shortWayRoundaboutTurn")) {
shortWayRoundaboutTurn = parseSilentFloat(v, shortWayRoundaboutTurn);
}
}

Expand Down Expand Up @@ -682,16 +687,16 @@ public float getMaxSpeed() {
return maxSpeed;
}

public double getLeftTurn() {
return sharpTurn;
private float getSharpTurnPenalty() {
return shortestRoute ? shortWaySharpTurn : sharpTurn;
}

public double getRightTurn() {
return slightTurn;
private float getSlightTurnPenalty() {
return shortestRoute ? shortWaySlightTurn : slightTurn;
}

public double getRoundaboutTurn() {
return roundaboutTurn;
private float getRoundaboutTurnPenalty() {
return shortestRoute ? shortWayRoundaboutTurn : roundaboutTurn;
}

@Override
Expand All @@ -703,42 +708,27 @@ public double calculateTurnTime(RouteSegment segment, RouteSegment prev) {
totalPenalty += Math.abs(ts - prevTs) / 2;
}

// int[] pt = prev.getRoad().getPointTypes(prevSegmentEnd);
// if(pt != null) {
// RouteRegion reg = prev.getRoad().region;
// for (int i = 0; i < pt.length; i++) {
// RouteTypeRule r = reg.quickGetEncodingRule(pt[i]);
// if ("highway".equals(r.getTag()) && "traffic_signals".equals(r.getValue())) {
// // traffic signals don't add turn info
// return 0;
// }
// }
// }
if (shortestRoute) {
return totalPenalty;
}
if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) {
double rt = getRoundaboutTurn();
if(rt > 0) {
if (segment.getRoad().roundabout() && !prev.getRoad().roundabout()) {
double rt = getRoundaboutTurnPenalty();
if (rt > 0) {
totalPenalty += rt;
}
} else if (getLeftTurn() > 0 || getRightTurn() > 0) {
} else if (getSharpTurnPenalty() > 0 || getSlightTurnPenalty() > 0) {
double a1 = segment.getRoad().directionRoute(segment.getSegmentStart(), segment.isPositive());
double a2 = prev.getRoad().directionRoute(prev.getSegmentEnd(), !prev.isPositive());
double diff = Math.abs(MapUtils.alignAngleDifference(a1 - a2 - Math.PI));
if (diff > Math.PI / 1.5) {
totalPenalty += getLeftTurn(); // >120 degree (U-turn)
totalPenalty += getSharpTurnPenalty(); // >120 degree (U-turn)
} else if (diff > Math.PI / 3) {
totalPenalty += getRightTurn(); // >60 degree (standard)
totalPenalty += getSlightTurnPenalty(); // >60 degree (standard)
} else if (diff > Math.PI / 6) {
totalPenalty += getRightTurn() / 2; // >30 degree (light)
totalPenalty += getSlightTurnPenalty() / 2; // >30 degree (light)
// totalPenalty += getRightTurn() * diff * 3 / Math.PI; // to think
}
}

return totalPenalty;
}


@Override
public boolean containsAttribute(String attribute) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ public void addTurnInfoDescriptions(List<RouteSegmentResult> result) {
if (!Algorithms.isEmpty(nm) || !Algorithms.isEmpty(ref)) {
streetName = String.format("onto %s %s " , nm, ref);
}
String to = result.get(prevSegment + 1).getDestinationName("", false, result, prevSegment + 1);
String to = result.get(prevSegment + 1).getDestinationName("", false, result, prevSegment + 1, true);
if(!Algorithms.isEmpty(to)) {
streetName = "to " + to;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ public String toString() {
return object.toString() + ": " + startPointIndex + "-" + endPointIndex;
}

public String getDestinationName(String lang, boolean transliterate, List<RouteSegmentResult> list, int routeInd) {
public String getDestinationName(String lang, boolean transliterate, List<RouteSegmentResult> list, int routeInd, boolean withRef) {
String dnRef = getObject().getDestinationRef(lang, transliterate, isForwardDirection());
String destinationName = getObject().getDestinationName(lang, transliterate, isForwardDirection());
if (Algorithms.isEmpty(destinationName)) {
Expand All @@ -678,10 +678,12 @@ public String getDestinationName(String lang, boolean transliterate, List<RouteS
}
}
}
if (!Algorithms.isEmpty(dnRef) && !Algorithms.isEmpty(destinationName)) {
destinationName = dnRef + ", " + destinationName;
} else if (!Algorithms.isEmpty(dnRef) && Algorithms.isEmpty(destinationName)) {
destinationName = dnRef;
if (withRef) {
if (!Algorithms.isEmpty(dnRef) && !Algorithms.isEmpty(destinationName)) {
destinationName = dnRef + ", " + destinationName;
} else if (!Algorithms.isEmpty(dnRef) && Algorithms.isEmpty(destinationName)) {
destinationName = dnRef;
}
}
return destinationName;
}
Expand Down
16 changes: 16 additions & 0 deletions OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java
Original file line number Diff line number Diff line change
Expand Up @@ -1349,4 +1349,20 @@ public static String[] deserializeStringArray(String serialized, String delimite
return resultList.toArray(new String[resultList.size()]);
}

public static String splitAndClearRepeats(String ref, String symbol) {
String[] arr = ref.split(symbol);
String res = "";
String prev = "";
for (String s : arr) {
if (Algorithms.isEmpty(s) || prev.equals(s))
continue;
if (!res.isEmpty()) {
res += symbol;
}
res += s;
prev = s;
}
return res;
}

}
44 changes: 26 additions & 18 deletions OsmAnd-java/src/test/java/net/osmand/router/RouteTestingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public void testRouting() throws Exception {
List<RouteSegmentResult> routeSegments = fe.searchRoute(ctx, te.getStartPoint(), te.getEndPoint(),
te.getTransitPoint()).detailed;
Set<Long> reachedSegments = new TreeSet<Long>();
Set<String> reachedSegmentPoints = new TreeSet<>();
Assert.assertNotNull(routeSegments);
int prevSegment = -1;
for (int i = 0; i <= routeSegments.size(); i++) {
Expand All @@ -159,7 +160,13 @@ public void testRouting() throws Exception {
prevSegment = i;
}
if (i < routeSegments.size()) {
reachedSegments.add(routeSegments.get(i).getObject().getId() >> (RouteResultPreparation.SHIFT_ID));
RouteSegmentResult seg = routeSegments.get(i);
long id = seg.getObject().getId() >> RouteResultPreparation.SHIFT_ID;
for (int point = Math.min(seg.getStartPointIndex(), seg.getEndPointIndex());
point <= Math.max(seg.getStartPointIndex(), seg.getEndPointIndex()); point++) {
reachedSegmentPoints.add(id + ":" + point);
}
reachedSegments.add(id);
}
}
Map<String, String> expectedResults = te.getExpectedResults();
Expand All @@ -170,32 +177,33 @@ public void testRouting() throws Exception {
checkRoutingTime(ctx, params);
for (Entry<String, String> es : expectedResults.entrySet()) {
long id = RouterUtilTest.getRoadId(es.getKey());
int point = RouterUtilTest.getRoadStartPoint(es.getKey());
String pointInSegment = id + ":" + point;
switch (es.getValue()) {
case "false":
Assert.assertFalse("Expected segment " + id + " was wrongly reached in route segments "
+ reachedSegments, reachedSegments.contains(id));
if (point == -1) {
Assert.assertFalse("Expected segment " + id + " was wrongly reached in route segments "
+ reachedSegments, reachedSegments.contains(id));
} else {
Assert.assertTrue("Unexpected pointInSegment " + pointInSegment + " is found in "
+ reachedSegmentPoints, !reachedSegmentPoints.contains(pointInSegment));
}
break;
case "true":
Assert.assertTrue("Expected segment " + id + " weren't reached in route segments "
+ reachedSegments, reachedSegments.contains(id));
if (point == -1) {
Assert.assertTrue("Expected segment " + id + " weren't reached in route segments "
+ reachedSegments, reachedSegments.contains(id));
} else {
Assert.assertTrue("Expected pointInSegment " + pointInSegment + " is not found in "
+ reachedSegmentPoints, reachedSegmentPoints.contains(pointInSegment));
}
break;
case "visitedSegments":
Assert.assertTrue("Expected segments visit " + id + " less then actually visited segments "
+ ctx.getVisitedSegments(), ctx.getVisitedSegments() < id);
break;
default: // case ID:N to check exact point within the ID's segment
boolean isFound = false;
int point = Integer.parseInt(es.getValue());
for (RouteSegmentResult seg : routeSegments) {
if (seg.getObject().getId() / 64 == id) {
if (point >= Math.min(seg.getStartPointIndex(), seg.getEndPointIndex()) &&
point <= Math.max(seg.getStartPointIndex(), seg.getEndPointIndex())) {
isFound = true;
break;
}
}
}
Assert.assertTrue("Expected point " + point + " is not found in segment " + id, isFound);
default:
Assert.assertTrue("Invalid key " + es.getKey() + " value " + es.getValue(), false);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class TrackFolderLoaderTask(

if (file.isDirectory()) {
val subfolder = TrackFolder(file, folder)
subfolder.dirItem = GpxDbHelper.getGpxDirItem(file)
launch {
log.info("Loading track subfolder = $subfolder")
scanFolder(subfolder, progress, trackItems)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.osmand.shared.gpx.data

import net.osmand.shared.gpx.GpxDirItem
import net.osmand.shared.gpx.GpxHelper
import net.osmand.shared.gpx.TrackItem
import net.osmand.shared.gpx.filters.TrackFolderAnalysis
Expand All @@ -17,6 +18,7 @@ class TrackFolder(dirFile: KFile, parentFolder: TrackFolder?) :
private var flattenedSubFolders: List<TrackFolder>? = null
private var folderAnalysis: TrackFolderAnalysis? = null
private var lastModified: Long = -1
var dirItem: GpxDirItem? = null

init {
this.dirFile = dirFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import net.osmand.shared.util.Localization
import net.osmand.shared.util.PlatformUtil


private const val FUEL_CONSUMPTION_DEFAULT_AVERAGE_TIME = 5 * 60

object OBDDataComputer {

private const val LITER_KM_CONSUMPTION_LIMIT = 100
Expand Down Expand Up @@ -120,7 +122,8 @@ object OBDDataComputer {
val locationNeeded: Boolean,
val requiredCommand: OBDCommand,
val nameId: String,
val formatter: OBDComputerWidgetFormatter
val formatter: OBDComputerWidgetFormatter,
val defaultAverageTime: Int = 0
) {
SPEED(
false,
Expand Down Expand Up @@ -170,15 +173,18 @@ object OBDDataComputer {
FUEL_CONSUMPTION_RATE_PERCENT_HOUR(
false,
OBD_FUEL_LEVEL_COMMAND,
"obd_fuel_consumption_rate_percent_hour", OBDComputerWidgetFormatter("%.1f")),
"obd_fuel_consumption_rate_percent_hour", OBDComputerWidgetFormatter("%.1f"),
FUEL_CONSUMPTION_DEFAULT_AVERAGE_TIME),
FUEL_CONSUMPTION_RATE_LITER_KM(
true,
OBD_FUEL_LEVEL_COMMAND,
"obd_fuel_consumption_rate_l_km", OBDComputerWidgetFormatter("%.1f")),
"obd_fuel_consumption_rate_l_km", OBDComputerWidgetFormatter("%.1f"),
FUEL_CONSUMPTION_DEFAULT_AVERAGE_TIME),
FUEL_CONSUMPTION_RATE_LITER_HOUR(
false,
OBD_FUEL_LEVEL_COMMAND,
"obd_fuel_consumption_rate_liter_hour", OBDComputerWidgetFormatter("%.1f")),
"obd_fuel_consumption_rate_liter_hour", OBDComputerWidgetFormatter("%.1f"),
FUEL_CONSUMPTION_DEFAULT_AVERAGE_TIME),
FUEL_CONSUMPTION_RATE_SENSOR(
false,
OBD_FUEL_CONSUMPTION_RATE_COMMAND,
Expand Down Expand Up @@ -307,7 +313,7 @@ object OBDDataComputer {
FUEL_CONSUMPTION_RATE_LITER_HOUR -> {
if (locValues.size >= 2) {
val result = getFuelTank() * calculateFuelConsumption(locValues) / 100
if(result > LITER_HOUR_CONSUMPTION_LIMIT) {
if (result > LITER_HOUR_CONSUMPTION_LIMIT) {
Float.NaN
} else {
result
Expand All @@ -331,7 +337,7 @@ object OBDDataComputer {
if (distance > 0) {
log.debug("l/100km. distance $distance; difLiter $difLiter; result ${100 * difLiter / (distance / 1000)}")
val result = 100 * difLiter / (distance / 1000)
return if(result > LITER_KM_CONSUMPTION_LIMIT) {
return if (result > LITER_KM_CONSUMPTION_LIMIT) {
Float.NaN
} else {
result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package net.osmand.shared.util

import co.touchlab.stately.collections.ConcurrentMutableMap
import net.osmand.shared.data.KLatLon
import kotlin.math.*
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.osmand.shared.data.KQuadRect
import net.osmand.shared.extensions.toDegrees
import net.osmand.shared.extensions.toRadians
import kotlin.math.*

/**
* This utility class includes :
Expand Down Expand Up @@ -860,4 +857,7 @@ object KMapUtils {
}
return KGeoParsedPoint(lat, lon, z)
}

fun interpolateLatLon(lat1: Double, lon1: Double, lat2: Double, lon2: Double, fraction: Double) =
KLatLon(lat1 + (lat2 - lat1) * fraction, lon1 + (lon2 - lon1) * fraction)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ class SinkStringWriter(sink: Sink) : StringWriter() {
bufferedSink.writeUtf8CodePoint(c)
}

@Throws(IOException::class)
override fun write(str: String?) {
if (str != null) {
bufferedSink.writeUtf8(str)
}
}

@Throws(IOException::class)
override fun write(cbuf: CharArray, off: Int, len: Int) {
bufferedSink.writeUtf8(String(cbuf, off, len))
Expand Down
1 change: 1 addition & 0 deletions OsmAnd-telegram/res/values-hr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,5 @@
<string name="enter_code">Upiši kȏd</string>
<string name="shared_string_error">Greška</string>
<string name="send_live_location_error">Greška prilikom slanja trenutne lokacije: %1$s</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s – %2$s</string>
</resources>
Loading

0 comments on commit 86c6ba4

Please sign in to comment.