Merge branch 'master' into imp_exp_osm_note
# Conflicts: # OsmAnd/res/values/strings.xml
This commit is contained in:
commit
6112b20a6d
81 changed files with 1607 additions and 957 deletions
|
@ -52,6 +52,7 @@ public class GPXUtilities {
|
|||
private static final String DEFAULT_ICON_NAME = "special_star";
|
||||
private static final String BACKGROUND_TYPE_EXTENSION = "background";
|
||||
private static final String PROFILE_TYPE_EXTENSION = "profile";
|
||||
private static final String GAP_PROFILE_TYPE = "gap";
|
||||
private static final String TRKPT_INDEX_EXTENSION = "trkpt_idx";
|
||||
|
||||
private final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
|
||||
|
@ -324,6 +325,20 @@ public class GPXUtilities {
|
|||
getExtensionsToWrite().put(PROFILE_TYPE_EXTENSION, profileType);
|
||||
}
|
||||
|
||||
public boolean hasProfile() {
|
||||
String profileType = getProfileType();
|
||||
return profileType != null && !GAP_PROFILE_TYPE.equals(profileType);
|
||||
}
|
||||
|
||||
public boolean isGap() {
|
||||
String profileType = getProfileType();
|
||||
return GAP_PROFILE_TYPE.equals(profileType);
|
||||
}
|
||||
|
||||
public void setGap() {
|
||||
setProfileType(GAP_PROFILE_TYPE);
|
||||
}
|
||||
|
||||
public void removeProfileType() {
|
||||
getExtensionsToWrite().remove(PROFILE_TYPE_EXTENSION);
|
||||
}
|
||||
|
@ -374,11 +389,16 @@ public class GPXUtilities {
|
|||
|
||||
public static class TrkSegment extends GPXExtensions {
|
||||
public boolean generalSegment = false;
|
||||
|
||||
public List<WptPt> points = new ArrayList<>();
|
||||
|
||||
public Object renderer;
|
||||
|
||||
public List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
public List<RouteType> routeTypes = new ArrayList<>();
|
||||
|
||||
public boolean hasRoute() {
|
||||
return !routeSegments.isEmpty() && !routeTypes.isEmpty();
|
||||
}
|
||||
|
||||
public List<GPXTrackAnalysis> splitByDistance(double meters, boolean joinSegments) {
|
||||
return split(getDistanceMetric(), getTimeSplit(), meters, joinSegments);
|
||||
|
@ -393,7 +413,6 @@ public class GPXUtilities {
|
|||
splitSegment(metric, secondaryMetric, metricLimit, splitSegments, this, joinSegments);
|
||||
return convert(splitSegments);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Track extends GPXExtensions {
|
||||
|
@ -1078,9 +1097,6 @@ public class GPXUtilities {
|
|||
private List<WptPt> points = new ArrayList<>();
|
||||
public List<Route> routes = new ArrayList<>();
|
||||
|
||||
public List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
public List<RouteType> routeTypes = new ArrayList<>();
|
||||
|
||||
public Exception error = null;
|
||||
public String path = "";
|
||||
public boolean showCurrentTrack;
|
||||
|
@ -1108,7 +1124,7 @@ public class GPXUtilities {
|
|||
}
|
||||
|
||||
public boolean hasRoute() {
|
||||
return !routeSegments.isEmpty() && !routeTypes.isEmpty();
|
||||
return getNonEmptyTrkSegments(true).size() > 0;
|
||||
}
|
||||
|
||||
public List<WptPt> getPoints() {
|
||||
|
@ -1218,7 +1234,7 @@ public class GPXUtilities {
|
|||
GPXTrackAnalysis g = new GPXTrackAnalysis();
|
||||
g.wptPoints = points.size();
|
||||
g.wptCategoryNames = getWaypointCategories(true);
|
||||
List<SplitSegment> splitSegments = new ArrayList<GPXUtilities.SplitSegment>();
|
||||
List<SplitSegment> splitSegments = new ArrayList<>();
|
||||
for (int i = 0; i < tracks.size(); i++) {
|
||||
Track subtrack = tracks.get(i);
|
||||
for (TrkSegment segment : subtrack.segments) {
|
||||
|
@ -1243,6 +1259,15 @@ public class GPXUtilities {
|
|||
return points;
|
||||
}
|
||||
|
||||
public List<WptPt> getRoutePoints(int routeIndex) {
|
||||
List<WptPt> points = new ArrayList<>();
|
||||
if (routes.size() > routeIndex) {
|
||||
Route rt = routes.get(routeIndex);
|
||||
points.addAll(rt.points);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public boolean hasRtePt() {
|
||||
for (Route r : routes) {
|
||||
if (r.points.size() > 0) {
|
||||
|
@ -1318,15 +1343,16 @@ public class GPXUtilities {
|
|||
return pt;
|
||||
}
|
||||
|
||||
public TrkSegment getNonEmptyTrkSegment() {
|
||||
for (GPXUtilities.Track t : tracks) {
|
||||
public List<TrkSegment> getNonEmptyTrkSegments(boolean routesOnly) {
|
||||
List<TrkSegment> segments = new ArrayList<>();
|
||||
for (Track t : tracks) {
|
||||
for (TrkSegment s : t.segments) {
|
||||
if (s.points.size() > 0) {
|
||||
return s;
|
||||
if (!s.generalSegment && s.points.size() > 0 && (!routesOnly || s.hasRoute())) {
|
||||
segments.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return segments;
|
||||
}
|
||||
|
||||
public void addTrkSegment(List<WptPt> points) {
|
||||
|
@ -1365,8 +1391,8 @@ public class GPXUtilities {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void addRoutePoints(List<WptPt> points) {
|
||||
if (routes.size() == 0) {
|
||||
public void addRoutePoints(List<WptPt> points, boolean addRoute) {
|
||||
if (routes.size() == 0 || addRoute) {
|
||||
Route route = new Route();
|
||||
routes.add(route);
|
||||
}
|
||||
|
@ -1608,7 +1634,7 @@ public class GPXUtilities {
|
|||
bottom = Math.min(bottom, p.getLatitude());
|
||||
}
|
||||
}
|
||||
for (GPXUtilities.Route route : routes) {
|
||||
for (Route route : routes) {
|
||||
for (WptPt p : route.points) {
|
||||
if (left == 0 && right == 0) {
|
||||
left = p.getLongitude();
|
||||
|
@ -1720,7 +1746,7 @@ public class GPXUtilities {
|
|||
|
||||
public static String asString(GPXFile file) {
|
||||
final Writer writer = new StringWriter();
|
||||
GPXUtilities.writeGpx(writer, file);
|
||||
writeGpx(writer, file);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
|
@ -1807,6 +1833,8 @@ public class GPXUtilities {
|
|||
writeWpt(format, serializer, p);
|
||||
serializer.endTag(null, "trkpt"); //$NON-NLS-1$
|
||||
}
|
||||
assignRouteExtensionWriter(segment);
|
||||
writeExtensions(serializer, segment);
|
||||
serializer.endTag(null, "trkseg"); //$NON-NLS-1$
|
||||
}
|
||||
writeExtensions(serializer, track);
|
||||
|
@ -1834,7 +1862,6 @@ public class GPXUtilities {
|
|||
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
assignRouteExtensionWriter(file);
|
||||
writeExtensions(serializer, file);
|
||||
|
||||
serializer.endTag(null, "gpx"); //$NON-NLS-1$
|
||||
|
@ -1847,19 +1874,19 @@ public class GPXUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static void assignRouteExtensionWriter(final GPXFile gpxFile) {
|
||||
if (gpxFile.hasRoute() && gpxFile.getExtensionsWriter() == null) {
|
||||
gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||
private static void assignRouteExtensionWriter(final TrkSegment segment) {
|
||||
if (segment.hasRoute() && segment.getExtensionsWriter() == null) {
|
||||
segment.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||
@Override
|
||||
public void writeExtensions(XmlSerializer serializer) {
|
||||
StringBundle bundle = new StringBundle();
|
||||
List<StringBundle> segmentsBundle = new ArrayList<>();
|
||||
for (RouteSegment segment : gpxFile.routeSegments) {
|
||||
for (RouteSegment segment : segment.routeSegments) {
|
||||
segmentsBundle.add(segment.toStringBundle());
|
||||
}
|
||||
bundle.putBundleList("route", "segment", segmentsBundle);
|
||||
List<StringBundle> typesBundle = new ArrayList<>();
|
||||
for (RouteType routeType : gpxFile.routeTypes) {
|
||||
for (RouteType routeType : segment.routeTypes) {
|
||||
typesBundle.add(routeType.toStringBundle());
|
||||
}
|
||||
bundle.putBundleList("types", "type", typesBundle);
|
||||
|
@ -1901,12 +1928,15 @@ public class GPXUtilities {
|
|||
}
|
||||
|
||||
private static void writeExtensions(XmlSerializer serializer, GPXExtensions p) throws IOException {
|
||||
Map<String, String> extensionsToRead = p.getExtensionsToRead();
|
||||
writeExtensions(serializer, p.getExtensionsToRead(), p);
|
||||
}
|
||||
|
||||
private static void writeExtensions(XmlSerializer serializer, Map<String, String> extensions, GPXExtensions p) throws IOException {
|
||||
GPXExtensionsWriter extensionsWriter = p.getExtensionsWriter();
|
||||
if (!extensionsToRead.isEmpty() || extensionsWriter != null) {
|
||||
if (!extensions.isEmpty() || extensionsWriter != null) {
|
||||
serializer.startTag(null, "extensions");
|
||||
if (!extensionsToRead.isEmpty()) {
|
||||
for (Entry<String, String> s : extensionsToRead.entrySet()) {
|
||||
if (!extensions.isEmpty()) {
|
||||
for (Entry<String, String> s : extensions.entrySet()) {
|
||||
writeNotNullText(serializer, s.getKey(), s.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -1943,8 +1973,21 @@ public class GPXUtilities {
|
|||
if (!Float.isNaN(p.heading)) {
|
||||
p.getExtensionsToWrite().put("heading", String.valueOf(Math.round(p.heading)));
|
||||
}
|
||||
Map<String, String> extensions = p.getExtensionsToRead();
|
||||
if (!"rtept".equals(serializer.getName())) {
|
||||
// Leave "profile" and "trkpt" tags for rtept only
|
||||
extensions.remove(PROFILE_TYPE_EXTENSION);
|
||||
extensions.remove(TRKPT_INDEX_EXTENSION);
|
||||
writeExtensions(serializer, extensions, p);
|
||||
} else {
|
||||
// Remove "gap" profile
|
||||
String profile = extensions.get(PROFILE_TYPE_EXTENSION);
|
||||
if (GAP_PROFILE_TYPE.equals(profile)) {
|
||||
extensions.remove(PROFILE_TYPE_EXTENSION);
|
||||
}
|
||||
writeExtensions(serializer, p);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeAuthor(XmlSerializer serializer, Author author) throws IOException {
|
||||
writeNotNullText(serializer, "name", author.name);
|
||||
|
@ -2099,10 +2142,11 @@ public class GPXUtilities {
|
|||
TrkSegment routeTrackSegment = new TrkSegment();
|
||||
routeTrack.segments.add(routeTrackSegment);
|
||||
Stack<GPXExtensions> parserState = new Stack<>();
|
||||
TrkSegment firstSegment = null;
|
||||
boolean extensionReadMode = false;
|
||||
boolean routePointExtension = false;
|
||||
List<RouteSegment> routeSegments = gpxFile.routeSegments;
|
||||
List<RouteType> routeTypes = gpxFile.routeTypes;
|
||||
List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
List<RouteType> routeTypes = new ArrayList<>();
|
||||
boolean routeExtension = false;
|
||||
boolean typesExtension = false;
|
||||
parserState.push(gpxFile);
|
||||
|
@ -2403,6 +2447,16 @@ public class GPXUtilities {
|
|||
assert pop instanceof Route;
|
||||
} else if (tag.equals("trkseg")) {
|
||||
Object pop = parserState.pop();
|
||||
if (pop instanceof TrkSegment) {
|
||||
TrkSegment segment = (TrkSegment) pop;
|
||||
segment.routeSegments = routeSegments;
|
||||
segment.routeTypes = routeTypes;
|
||||
routeSegments = new ArrayList<>();
|
||||
routeTypes = new ArrayList<>();
|
||||
if (firstSegment == null) {
|
||||
firstSegment = segment;
|
||||
}
|
||||
}
|
||||
assert pop instanceof TrkSegment;
|
||||
} else if (tag.equals("rpt")) {
|
||||
Object pop = parserState.pop();
|
||||
|
@ -2413,6 +2467,10 @@ public class GPXUtilities {
|
|||
if (!routeTrackSegment.points.isEmpty()) {
|
||||
gpxFile.tracks.add(routeTrack);
|
||||
}
|
||||
if (!routeSegments.isEmpty() && !routeTypes.isEmpty() && firstSegment != null) {
|
||||
firstSegment.routeSegments = routeSegments;
|
||||
firstSegment.routeTypes = routeTypes;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
gpxFile.error = e;
|
||||
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||
|
|
|
@ -20,10 +20,10 @@ public class RouteExporter {
|
|||
|
||||
public static final String OSMAND_ROUTER_V2 = "OsmAndRouterV2";
|
||||
|
||||
private String name;
|
||||
private List<RouteSegmentResult> route;
|
||||
private List<Location> locations;
|
||||
private List<WptPt> points;
|
||||
private final String name;
|
||||
private final List<RouteSegmentResult> route;
|
||||
private final List<Location> locations;
|
||||
private final List<WptPt> points;
|
||||
|
||||
public RouteExporter(String name, List<RouteSegmentResult> route, List<Location> locations, List<WptPt> points) {
|
||||
this.name = name;
|
||||
|
@ -33,6 +33,34 @@ public class RouteExporter {
|
|||
}
|
||||
|
||||
public GPXFile exportRoute() {
|
||||
GPXFile gpx = new GPXFile(OSMAND_ROUTER_V2);
|
||||
Track track = new Track();
|
||||
track.name = name;
|
||||
gpx.tracks.add(track);
|
||||
track.segments.add(generateRouteSegment());
|
||||
if (points != null) {
|
||||
for (WptPt pt : points) {
|
||||
gpx.addPoint(pt);
|
||||
}
|
||||
}
|
||||
return gpx;
|
||||
}
|
||||
|
||||
public static GPXFile exportRoute(String name, List<TrkSegment> trkSegments, List<WptPt> points) {
|
||||
GPXFile gpx = new GPXFile(OSMAND_ROUTER_V2);
|
||||
Track track = new Track();
|
||||
track.name = name;
|
||||
gpx.tracks.add(track);
|
||||
track.segments.addAll(trkSegments);
|
||||
if (points != null) {
|
||||
for (WptPt pt : points) {
|
||||
gpx.addPoint(pt);
|
||||
}
|
||||
}
|
||||
return gpx;
|
||||
}
|
||||
|
||||
public TrkSegment generateRouteSegment() {
|
||||
RouteDataResources resources = new RouteDataResources(locations);
|
||||
List<StringBundle> routeItems = new ArrayList<>();
|
||||
if (!Algorithms.isEmpty(route)) {
|
||||
|
@ -57,15 +85,9 @@ public class RouteExporter {
|
|||
typeList.add(typeBundle);
|
||||
}
|
||||
|
||||
GPXFile gpx = new GPXFile(OSMAND_ROUTER_V2);
|
||||
Track track = new Track();
|
||||
track.name = name;
|
||||
gpx.tracks.add(track);
|
||||
TrkSegment trkSegment = new TrkSegment();
|
||||
track.segments.add(trkSegment);
|
||||
|
||||
if (locations == null || locations.isEmpty()) {
|
||||
return gpx;
|
||||
return trkSegment;
|
||||
}
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
Location loc = locations.get(i);
|
||||
|
@ -83,23 +105,17 @@ public class RouteExporter {
|
|||
}
|
||||
trkSegment.points.add(pt);
|
||||
}
|
||||
if (points != null) {
|
||||
for (WptPt pt : points) {
|
||||
gpx.addPoint(pt);
|
||||
}
|
||||
}
|
||||
|
||||
List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
for (StringBundle item : routeItems) {
|
||||
routeSegments.add(RouteSegment.fromStringBundle(item));
|
||||
}
|
||||
gpx.routeSegments = routeSegments;
|
||||
trkSegment.routeSegments = routeSegments;
|
||||
List<RouteType> routeTypes = new ArrayList<>();
|
||||
for (StringBundle item : typeList) {
|
||||
routeTypes.add(RouteType.fromStringBundle(item));
|
||||
}
|
||||
gpx.routeTypes = routeTypes;
|
||||
|
||||
return gpx;
|
||||
trkSegment.routeTypes = routeTypes;
|
||||
return trkSegment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import net.osmand.GPXUtilities;
|
|||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.RouteSegment;
|
||||
import net.osmand.GPXUtilities.RouteType;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -28,10 +29,9 @@ public class RouteImporter {
|
|||
|
||||
private File file;
|
||||
private GPXFile gpxFile;
|
||||
private TrkSegment segment;
|
||||
|
||||
private List<RouteSegmentResult> route = new ArrayList<>();
|
||||
private RouteRegion region = new RouteRegion();
|
||||
private RouteDataResources resources = new RouteDataResources();
|
||||
private final List<RouteSegmentResult> route = new ArrayList<>();
|
||||
|
||||
public RouteImporter(File file) {
|
||||
this.file = file;
|
||||
|
@ -41,8 +41,12 @@ public class RouteImporter {
|
|||
this.gpxFile = gpxFile;
|
||||
}
|
||||
|
||||
public RouteImporter(TrkSegment segment) {
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
public List<RouteSegmentResult> importRoute() {
|
||||
if (gpxFile != null) {
|
||||
if (gpxFile != null || segment != null) {
|
||||
parseRoute();
|
||||
} else if (file != null) {
|
||||
FileInputStream fis = null;
|
||||
|
@ -69,19 +73,34 @@ public class RouteImporter {
|
|||
}
|
||||
|
||||
private void parseRoute() {
|
||||
collectLocations();
|
||||
collectSegments();
|
||||
collectTypes();
|
||||
for (RouteSegmentResult segment : route) {
|
||||
segment.fillNames(resources);
|
||||
if (segment != null) {
|
||||
parseRoute(segment);
|
||||
} else if (gpxFile != null) {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(true);
|
||||
for (TrkSegment s : segments) {
|
||||
parseRoute(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectLocations() {
|
||||
private void parseRoute(TrkSegment segment) {
|
||||
RouteRegion region = new RouteRegion();
|
||||
RouteDataResources resources = new RouteDataResources();
|
||||
|
||||
collectLocations(resources, segment);
|
||||
List<RouteSegmentResult> route = collectRouteSegments(region, resources, segment);
|
||||
collectRouteTypes(region, segment);
|
||||
for (RouteSegmentResult routeSegment : route) {
|
||||
routeSegment.fillNames(resources);
|
||||
}
|
||||
this.route.addAll(route);
|
||||
}
|
||||
|
||||
private void collectLocations(RouteDataResources resources, TrkSegment segment) {
|
||||
List<Location> locations = resources.getLocations();
|
||||
double lastElevation = HEIGHT_UNDEFINED;
|
||||
if (gpxFile.tracks.size() > 0 && gpxFile.tracks.get(0).segments.size() > 0 && gpxFile.tracks.get(0).segments.get(0).points.size() > 0) {
|
||||
for (WptPt point : gpxFile.tracks.get(0).segments.get(0).points) {
|
||||
if (segment.hasRoute()) {
|
||||
for (WptPt point : segment.points) {
|
||||
Location loc = new Location("", point.getLatitude(), point.getLongitude());
|
||||
if (!Double.isNaN(point.ele)) {
|
||||
loc.setAltitude(point.ele);
|
||||
|
@ -94,18 +113,20 @@ public class RouteImporter {
|
|||
}
|
||||
}
|
||||
|
||||
private void collectSegments() {
|
||||
for (RouteSegment segment : gpxFile.routeSegments) {
|
||||
private List<RouteSegmentResult> collectRouteSegments(RouteRegion region, RouteDataResources resources, TrkSegment segment) {
|
||||
List<RouteSegmentResult> route = new ArrayList<>();
|
||||
for (RouteSegment routeSegment : segment.routeSegments) {
|
||||
RouteDataObject object = new RouteDataObject(region);
|
||||
RouteSegmentResult segmentResult = new RouteSegmentResult(object);
|
||||
segmentResult.readFromBundle(new RouteDataBundle(resources, segment.toStringBundle()));
|
||||
segmentResult.readFromBundle(new RouteDataBundle(resources, routeSegment.toStringBundle()));
|
||||
route.add(segmentResult);
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
private void collectTypes() {
|
||||
private void collectRouteTypes(RouteRegion region, TrkSegment segment) {
|
||||
int i = 0;
|
||||
for (RouteType routeType : gpxFile.routeTypes) {
|
||||
for (RouteType routeType : segment.routeTypes) {
|
||||
StringBundle bundle = routeType.toStringBundle();
|
||||
String t = bundle.getString("t", null);
|
||||
String v = bundle.getString("v", null);
|
||||
|
|
|
@ -243,9 +243,6 @@ public class RoutePlannerFrontEnd {
|
|||
start = gpxPoints.get(0);
|
||||
}
|
||||
while (start != null && !gctx.ctx.calculationProgress.isCancelled) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
return null;
|
||||
}
|
||||
double routeDist = gctx.MAXIMUM_STEP_APPROXIMATION;
|
||||
GpxPoint next = findNextGpxPointWithin(gctx, gpxPoints, start, routeDist);
|
||||
boolean routeFound = false;
|
||||
|
|
|
@ -255,7 +255,8 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
Map<RouteTypeRule, Integer> rules = bundle.getResources().getRules();
|
||||
bundle.putInt("length", (Math.abs(endPointIndex - startPointIndex) + 1) * (endPointIndex >= startPointIndex ? 1 : -1));
|
||||
boolean reversed = endPointIndex < startPointIndex;
|
||||
bundle.putInt("length", Math.abs(endPointIndex - startPointIndex) + 1);
|
||||
bundle.putFloat("segmentTime", segmentTime, 2);
|
||||
bundle.putFloat("speed", speed, 2);
|
||||
if (turnType != null) {
|
||||
|
@ -278,17 +279,22 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
int end = Math.max(startPointIndex, endPointIndex) + 1;
|
||||
if (object.pointTypes != null && start < object.pointTypes.length) {
|
||||
int[][] types = Arrays.copyOfRange(object.pointTypes, start, Math.min(end, object.pointTypes.length));
|
||||
if (reversed) {
|
||||
Algorithms.reverseArray(types);
|
||||
}
|
||||
bundle.putArray("pointTypes", convertTypes(types, rules));
|
||||
}
|
||||
if (object.nameIds != null) {
|
||||
bundle.putArray("names", convertNameIds(object.nameIds, rules));
|
||||
}
|
||||
if (object.pointNameTypes != null && start < object.pointNameTypes.length) {
|
||||
if (object.pointNameTypes != null && start < object.pointNameTypes.length && object.pointNames != null) {
|
||||
int[][] types = Arrays.copyOfRange(object.pointNameTypes, start, Math.min(end, object.pointNameTypes.length));
|
||||
if (object.pointNames != null) {
|
||||
String[][] names = Arrays.copyOfRange(object.pointNames, start, Math.min(end, object.pointNames.length));
|
||||
bundle.putArray("pointNames", convertPointNames(types, names, rules));
|
||||
if (reversed) {
|
||||
Algorithms.reverseArray(types);
|
||||
Algorithms.reverseArray(names);
|
||||
}
|
||||
bundle.putArray("pointNames", convertPointNames(types, names, rules));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -886,6 +886,14 @@ public class Algorithms {
|
|||
return map;
|
||||
}
|
||||
|
||||
public static <T> void reverseArray(T[] array) {
|
||||
for (int i = 0; i < array.length / 2; i++) {
|
||||
T temp = array[i];
|
||||
array[i] = array[array.length - i - 1];
|
||||
array[array.length - i - 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean containsInArrayL(long[] array, long value) {
|
||||
return Arrays.binarySearch(array, value) >= 0;
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
<string name="monitoring_is_enabled">Oppsyn er påskrudd</string>
|
||||
<string name="monitoring_is_disabled">Oppsyn er ikke aktivert</string>
|
||||
<string name="time_on_the_move">Tid i bevegelse</string>
|
||||
<string name="average_altitude">Gjennomsnittlig høyde</string>
|
||||
<string name="average_altitude">Gjennomsnittshøyde</string>
|
||||
<string name="average_speed">Gjennomsnittsfart</string>
|
||||
<string name="open_in_osmand">Vis i OsmAnd</string>
|
||||
<string name="end_date">Sluttdato</string>
|
||||
|
|
32
OsmAnd/res/drawable/shadow.xml
Normal file
32
OsmAnd/res/drawable/shadow.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape
|
||||
android:dither="true"
|
||||
android:shape="rectangle">
|
||||
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#1A000000"
|
||||
android:centerColor="#00FFFFFF"
|
||||
android:endColor="#00FFFFFF" />
|
||||
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<shape
|
||||
android:dither="true"
|
||||
android:shape="rectangle">
|
||||
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#0D000000"
|
||||
android:centerColor="#00FFFFFF"
|
||||
android:endColor="#00FFFFFF" />
|
||||
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
|
@ -38,9 +38,9 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light"
|
||||
android:background="@drawable/shadow"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include layout="@layout/bottom_buttons" />
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light"
|
||||
android:background="@drawable/shadow"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light" />
|
||||
android:layout_height="8dp"
|
||||
android:background="@drawable/shadow" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -128,9 +128,9 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light" />
|
||||
android:background="@drawable/shadow" />
|
||||
|
||||
<include
|
||||
layout="@layout/bottom_buttons"
|
||||
|
|
|
@ -98,9 +98,9 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light" />
|
||||
android:background="@drawable/shadow" />
|
||||
|
||||
<include
|
||||
layout="@layout/bottom_buttons"
|
||||
|
|
|
@ -591,9 +591,9 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light" />
|
||||
android:background="@drawable/shadow" />
|
||||
|
||||
<include
|
||||
layout="@layout/route_info_menu_control_buttons"
|
||||
|
|
|
@ -129,9 +129,9 @@
|
|||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/buttons_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="10dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="@drawable/bg_contextmenu_shadow_top_light" />
|
||||
android:background="@drawable/shadow" />
|
||||
|
||||
<include
|
||||
layout="@layout/bottom_buttons"
|
||||
|
|
|
@ -904,7 +904,7 @@
|
|||
<string name="rendering_attr_OSMMapperAssistant_name">مساعد تخطيط OSM</string>
|
||||
<string name="agps_info">معلومات A-GPS</string>
|
||||
<string name="shared_string_manage">إدارة</string>
|
||||
<string name="shared_string_edit">تعديل/حذف</string>
|
||||
<string name="shared_string_edit">تعديل</string>
|
||||
<string name="shared_string_places">أماكن</string>
|
||||
<string name="shared_string_search">بحث</string>
|
||||
<string name="shared_string_show_description">عرض الوصف.</string>
|
||||
|
@ -1076,8 +1076,8 @@
|
|||
<string name="rendering_category_others">سمات أخرى للخريطة</string>
|
||||
<string name="map_widget_appearance_rem">العناصر الأخرى</string>
|
||||
<string name="map_widget_top">شريط المعلومات</string>
|
||||
<string name="map_widget_right">العدادات على اليمين</string>
|
||||
<string name="map_widget_left">العدادات على اليسار</string>
|
||||
<string name="map_widget_right">العدادات على اليسار</string>
|
||||
<string name="map_widget_left">العدادات على اليمين</string>
|
||||
<string name="search_radius_proximity">ضمن</string>
|
||||
<string name="anonymous_user">مستخدم مجهول</string>
|
||||
<string name="logged_as">سجل الدخول ب %1$s</string>
|
||||
|
@ -1153,7 +1153,7 @@
|
|||
<string name="action_delete">حذف إجراء</string>
|
||||
<string name="osm_edits">التعديلات</string>
|
||||
<string name="parking_place_limited">وقت وقوف السيارات يقتصر على</string>
|
||||
<string name="shared_string_collapse">تدلي</string>
|
||||
<string name="shared_string_collapse">أقل</string>
|
||||
<string name="drawer">قائمة منبسطة</string>
|
||||
<string name="osm_settings">تعديل OSM</string>
|
||||
<string name="free">فارغ %1$s</string>
|
||||
|
@ -1483,7 +1483,7 @@
|
|||
<string name="access_smart_autoannounce">التنبيه الآلي الذكي</string>
|
||||
<string name="access_smart_autoannounce_descr">الإشعار فقط عند تغير الوجهة نحو نقطة الهدف.</string>
|
||||
<string name="access_autoannounce_period">مهلة التنبيه الآلي</string>
|
||||
<string name="access_autoannounce_period_descr">أقل مهلة بين الاخطارات.</string>
|
||||
<string name="access_autoannounce_period_descr">أقل مهلة بين الإشعارات.</string>
|
||||
<string name="access_map_linked_to_location">الخريطة مرتبطة بالموقع</string>
|
||||
<string name="rendering_value_bold_name">عريض</string>
|
||||
<string name="anonymous_user_hint">المستخدم المجهول لا يمكنه :
|
||||
|
@ -1658,7 +1658,7 @@
|
|||
<string name="no_location_permission">منح الوصول إلى بيانات الموقع.</string>
|
||||
<string name="rendering_attr_horseRoutes_name">مسارات الخيول</string>
|
||||
<string name="shared_string_hide">إخفاء</string>
|
||||
<string name="av_video_quality_low">أقل جودة</string>
|
||||
<string name="av_video_quality_low">جودة أقل</string>
|
||||
<string name="av_video_quality_high">أعلى جودة</string>
|
||||
<string name="copied_to_clipboard">تم النسخ في الحافظة</string>
|
||||
<string name="context_menu_item_open_note">فتح ملاحظة OSM</string>
|
||||
|
@ -1838,7 +1838,7 @@
|
|||
<string name="osb_comment_dialog_error">لا يمكن إضافة تعليق.</string>
|
||||
<string name="shared_string_commit">تقديم</string>
|
||||
<string name="context_menu_item_delete_waypoint">حذف إحداثية GPX ؟</string>
|
||||
<string name="context_menu_item_edit_waypoint">تعديل/حذف</string>
|
||||
<string name="context_menu_item_edit_waypoint">تعديل</string>
|
||||
<string name="lang_nds">ألمانية منخفضة</string>
|
||||
<string name="lang_fy">اللغة الفريزية</string>
|
||||
<string name="rendering_attr_hideProposed_name">الأشياء المقترحة</string>
|
||||
|
@ -1996,7 +1996,7 @@
|
|||
<string name="rendering_attr_hideOverground_name">أشياء فوق سطح الأرض</string>
|
||||
<string name="shared_string_change">تغيير</string>
|
||||
<string name="get_started">ابدأ</string>
|
||||
<string name="routing_attr_short_way_name">طريق أقل استهلاكا للوقود</string>
|
||||
<string name="routing_attr_short_way_name">طريق أقل استهلاكاً للوقود</string>
|
||||
<string name="routing_attr_short_way_description">استخدم طريق أقل استهلاكا للوقود (عادة أقصر).</string>
|
||||
<string name="replace_favorite_confirmation">هل تريد استبدال المفضلة %1$s؟</string>
|
||||
<string name="clear_tile_data">حذف جميع الطبقات</string>
|
||||
|
@ -2249,7 +2249,7 @@
|
|||
<string name="quick_action_auto_zoom_on">قم بتشغيل التكبير التلقائي</string>
|
||||
<string name="quick_action_auto_zoom_off">إيقاف التكبير التلقائي</string>
|
||||
<string name="quick_action_add_first_intermediate">إضافة وجهة وسطى</string>
|
||||
<string name="analyze_on_map">تحليل على الخريطة</string>
|
||||
<string name="analyze_on_map">تحليل</string>
|
||||
<string name="shared_string_visible">المعروضة على الخريطة</string>
|
||||
<string name="restore_purchases">استرجاع الشراء</string>
|
||||
<string name="do_not_send_anonymous_app_usage">لا ترسل إحصاءات مجهولة عن استخدام التطبيق</string>
|
||||
|
@ -2302,7 +2302,7 @@
|
|||
<string name="download_depth_countours">محيطات الأعماق البحرية</string>
|
||||
<string name="do_not_send_anonymous_app_usage_desc">أوسماند يقوم بجمع معلومات حول أجزاء من التطبيقات التي تفتحها. الموقع الخاص بك لا يرسل ابدأ، ولا أي شيء تقوم بإدخاله في التطبيق أو أي تفاصيل لمناطق رأيتها ، بحثت عنها أو نزلتها.</string>
|
||||
<string name="do_not_show_startup_messages_desc">عرض خصومات التطبيق ورسائل الأحداث المحلية الخاصة.</string>
|
||||
<string name="routing_attr_relief_smoothness_factor_plains_name">أقل تضاريس</string>
|
||||
<string name="routing_attr_relief_smoothness_factor_plains_name">تضاريس أقل</string>
|
||||
<string name="routing_attr_relief_smoothness_factor_more_plains_name">مسطح</string>
|
||||
<string name="routing_attr_driving_style_balance_name">متوازن</string>
|
||||
<string name="relief_smoothness_factor_descr">التضاريس المفضلة : مسطحة أو تلال.</string>
|
||||
|
@ -2730,7 +2730,7 @@
|
|||
<string name="coord_input_add_point">إضافة نقطة</string>
|
||||
<string name="coord_input_save_as_track">حفظ كمسار</string>
|
||||
<string name="coord_input_save_as_track_descr">أنت بحاجة %1$s نقاط. اكتب اسم ملف واضغط \"حفظ\".</string>
|
||||
<string name="error_notification_desc">يرجى إرسال لقطة شاشة من هذا الإخطار إلى support@osmand.net</string>
|
||||
<string name="error_notification_desc">يرجى إرسال لقطة شاشة من هذا الإشعار إلى support@osmand.net</string>
|
||||
<string name="quick_action_edit_actions">تعديل الإجراء</string>
|
||||
<string name="get_osmand_live">احصل على أوسماند لايف لإلغاء قفل جميع الميزات: تحديثات الخرائط اليومية مع تنزيلات غير محدودة، وجميع الإضافات المدفوعة والمجانية ، ويكيبيديا، ويكي الرحلات وأكثر.</string>
|
||||
<string name="osm_live_subscriptions">الاشتراكات</string>
|
||||
|
@ -3101,7 +3101,7 @@
|
|||
<string name="rendering_attr_tracktype_grade5_name">لينة</string>
|
||||
<string name="routeInfo_tracktype_name">متانة السطح</string>
|
||||
<string name="shared_string_file_is_saved">%s تم الحفظ</string>
|
||||
<string name="shared_string_open_track">مسار مفتوح</string>
|
||||
<string name="shared_string_open_track">فتح المسار</string>
|
||||
<string name="shared_string_track_is_saved">المسار %s تم حفظ</string>
|
||||
<string name="gpx_join_gaps">ربط الأجزاء</string>
|
||||
<string name="app_mode_camper">العربه</string>
|
||||
|
@ -3223,7 +3223,7 @@
|
|||
<string name="app_mode_offroad">الطرق الوعره</string>
|
||||
<string name="edit_profile_setup_title">إعداد الوضع</string>
|
||||
<string name="edit_profile_setup_subtitle">يحتفظ الوضع بإعداداتك</string>
|
||||
<string name="edit_profile_setup_map_subtitle">حدد خيارات الخريطة للملف الشخصي</string>
|
||||
<string name="edit_profile_setup_map_subtitle">حدد خيارات الخريطة للوضع</string>
|
||||
<string name="edit_profile_screen_options_subtitle">حدد خيارات الشاشة للوضع</string>
|
||||
<string name="edit_profile_nav_settings_subtitle">حدد إعدادات الملاحة للوضع</string>
|
||||
<string name="routing_attr_max_num_changes_description">حدد الحد الأعلى للتغييرات</string>
|
||||
|
@ -3387,7 +3387,7 @@
|
|||
<string name="selected_profile">الوضع المحدد</string>
|
||||
<string name="reset_confirmation_descr">بالضغط على %1$s، ستفقد كل تغييراتك.</string>
|
||||
<string name="reset_all_profile_settings_descr">سيتم إعادة ضبط جميع إعدادات الوضع إلى الحالة الافتراضية بعد التثبيت.</string>
|
||||
<string name="reset_all_profile_settings">استعادة الضبط الافتراضي؟</string>
|
||||
<string name="reset_all_profile_settings">استعادة الضبط الافتراضي لكل الأوضاع؟</string>
|
||||
<string name="ltr_or_rtl_combine_via_space">%2$s %1$s</string>
|
||||
<string name="ltr_or_rtl_combine_via_colon">%2$s :%1$s</string>
|
||||
<string name="file_does_not_contain_routing_rules">\'%1$s\' لا يحتوي الملف على قواعد توجيه ،يرجى اختيار ملف آخر.</string>
|
||||
|
@ -3489,7 +3489,7 @@
|
|||
<string name="copy_coordinates">نسخ الإحداثيات</string>
|
||||
<string name="routing_profile_direct_to">مباشر إلى نقطة</string>
|
||||
<string name="sort_by_category">الفرز حسب الفئة</string>
|
||||
<string name="please_provide_profile_name_message">يرجى اعطاء اسم للملف الشخصي</string>
|
||||
<string name="please_provide_profile_name_message">يرجى إدخال اسم للوضع</string>
|
||||
<string name="open_settings">افتح الإعدادات</string>
|
||||
<string name="plugin_disabled">الملحق مُعطل</string>
|
||||
<string name="shared_string_menu">القائمة</string>
|
||||
|
@ -3732,7 +3732,7 @@
|
|||
\nشهر واحد هو 43 829 دقيقة.</string>
|
||||
<string name="tiles_storage_descr">اختر كيفية تخزين الطبقات المنزلة.</string>
|
||||
<string name="default_screen_timeout">مهلة الشاشة الافتراضية</string>
|
||||
<string name="export_import_quick_actions_with_profiles_promo">يمكنك تصدير أو استيراد إجراءات سريعة باستخدام ملفات بروفايل التطبيق .</string>
|
||||
<string name="export_import_quick_actions_with_profiles_promo">يمكنك تصدير أو استيراد إجراءات سريعة باستخدام أوضاع التطبيق .</string>
|
||||
<string name="shared_string_delete_all_q">حذف الكل؟</string>
|
||||
<string name="delete_all_actions_message_q">هل أنت متأكد من رغبتك في حذف الاختصارات السريعة %d نهائيًا؟</string>
|
||||
<string name="screen_timeout">مهلة الشاشة</string>
|
||||
|
@ -3771,7 +3771,7 @@
|
|||
\n
|
||||
\nحدد %1$s وستتلقى تنبيهات وتحذيرات حول كاميرات السرعة.
|
||||
\n
|
||||
\nحدد %2$s. جميع البيانات المتعلقة كاميرات السرعة: التنبيهات، والإخطارات، سيتم حذف نقاط الاهتمام حتى يتم إعادة تثبيت أوسماند تماما.</string>
|
||||
\nحدد %2$s. جميع البيانات المتعلقة كاميرات السرعة: التنبيهات، والإشعارات، سيتم حذف نقاط الاهتمام حتى يتم إعادة تثبيت أوسماند تماما.</string>
|
||||
<string name="routing_attr_length_description">تحديد الارتفاع الأعلى المسموح به على الطرق.</string>
|
||||
<string name="routing_attr_length_name">حد الطول</string>
|
||||
<string name="speed_cameras_removed_descr">هذا الجهاز لا يملك كاميرات السرعة.</string>
|
||||
|
@ -3909,7 +3909,7 @@
|
|||
<string name="complex_routing_descr">التوجيه على مرحلتين لملاحة السيارة.</string>
|
||||
<string name="use_native_pt">تطوير النقل العام المحلي</string>
|
||||
<string name="use_native_pt_desc">قم بالتبديل إلى Java (الآمن) حساب توجيه النقل العام</string>
|
||||
<string name="perform_oauth_authorization_description">قم بإجراء تسجيل دخول إلى OAuth لاستخدام ميزات osmedit</string>
|
||||
<string name="perform_oauth_authorization_description">قم بتسجيل الدخول إلى OAuth لاستخدام ميزات osmedit</string>
|
||||
<string name="perform_oauth_authorization">تسجيل الدخول عبر OAuth</string>
|
||||
<string name="clear_osm_token">مسح رمز OpenStreetMap OAuth</string>
|
||||
<string name="osm_edit_logout_success">تسجيل الخروج بنجاح</string>
|
||||
|
@ -3920,4 +3920,6 @@
|
|||
\nسيتوفر الرسم البياني بعد إعادة الحساب.</string>
|
||||
<string name="snowmobile_render_descr">للقيادة على الجليد مع طرق ومسارات مخصصة.</string>
|
||||
<string name="shared_string_graph">رسم بياني</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%2$s — %1$s</string>
|
||||
<string name="app_mode_gap">فجوة</string>
|
||||
</resources>
|
|
@ -1553,7 +1553,7 @@ Per retornar a l\'estil habitual dels mapes d\'OsmAnd, només cal desactivar aqu
|
|||
<string name="routing_attr_height_name">Límit d\'alçada</string>
|
||||
<string name="routing_attr_height_description">Indiqueu l\'alçada del vehicle que les rutes han d\'admetre.</string>
|
||||
<string name="use_fast_recalculation">Recàlcul intel·ligent de la ruta</string>
|
||||
<string name="use_fast_recalculation_desc">En viatges llargs, només actualitzis la part inicial de la ruta.</string>
|
||||
<string name="use_fast_recalculation_desc">Actualitza només la part inicial de la ruta. Pot ser usat per a viatges llargs.</string>
|
||||
<string name="shared_string_logoff">Surt</string>
|
||||
<string name="rendering_value_disabled_name">Desactivat</string>
|
||||
<string name="rendering_value_walkingRoutesScopeOSMC_name">Acoloreix segons el tipus de xarxa</string>
|
||||
|
@ -3589,10 +3589,10 @@ Abasta l\'àrea: %1$s x %2$s</string>
|
|||
<string name="slope_description">Les pistes es mostren sobre el terreny i amb colors.</string>
|
||||
<string name="download_slope_maps">Pistes</string>
|
||||
<string name="custom_osmand_plugin">Connector d\'OsmAnd adaptat</string>
|
||||
<string name="replace_point_descr">Substitueix un altre punt per aquest</string>
|
||||
<string name="replace_point_descr">Substitueix un altre punt per aquest.</string>
|
||||
<string name="changes_applied_to_profile">S\'han fet els canvis al perfil \'%1$s\'.</string>
|
||||
<string name="settings_item_read_error">No s\'ha pogut llegir des de \'%1$s\'.</string>
|
||||
<string name="settings_item_write_error">No s\'ha pogut escriure %1$s.</string>
|
||||
<string name="settings_item_write_error">No s\'ha pogut escriure a \'%1$s\'.</string>
|
||||
<string name="settings_item_import_error">No s\'ha pogut importar des de \'%1$s\'.</string>
|
||||
<string name="select_track_file">Seleccioneu fitxer de la traça</string>
|
||||
<string name="shared_string_languages">Idiomes</string>
|
||||
|
@ -3619,7 +3619,7 @@ Abasta l\'àrea: %1$s x %2$s</string>
|
|||
<string name="lang_an">Aragonès</string>
|
||||
<string name="lang_lmo">Llombard</string>
|
||||
<string name="custom_color">Color personalitzat</string>
|
||||
<string name="select_wikipedia_article_langs">Seleccioneu els idiomes de la Viquipèdia en que es veuran els articles al mapa. Mentre llegiu un article podeu modificar la llengua entre les disponibles.</string>
|
||||
<string name="select_wikipedia_article_langs">Seleccioneu els idiomes per als articles de Viquipèdia al mapa. Canvieu la llengua entre les disponibles mentre llegiu un article.</string>
|
||||
<string name="some_articles_may_not_available_in_lang">Alguns articles de la Viquipèdia podrien no estar disponibles en el vostre idioma.</string>
|
||||
<string name="lang_zhyue">Cantonès</string>
|
||||
<string name="lang_zhminnan">Min nan</string>
|
||||
|
@ -3672,11 +3672,11 @@ Abasta l\'àrea: %1$s x %2$s</string>
|
|||
<string name="routing_attr_length_name">Llargada màxima</string>
|
||||
<string name="shared_string_bearing">Trajectòria</string>
|
||||
<string name="item_deleted">S\'ha esborrat %1$s</string>
|
||||
<string name="speed_cameras_restart_descr">Cal reiniciar per esborrar totalment les dades de les càmeres de radar.</string>
|
||||
<string name="speed_cameras_restart_descr">Reinicia l\'aplicació per esborrar totes les dades de les càmeres de radar.</string>
|
||||
<string name="shared_string_uninstall_and_restart">Desinstal·la i Reinicia</string>
|
||||
<string name="speed_cameras_removed_descr">Aquest dispositiu no inclou les càmeres de radar.</string>
|
||||
<string name="app_mode_inline_skates">Patins en línia</string>
|
||||
<string name="use_volume_buttons_as_zoom_descr">Activeu per controlar el nivell d\'ampliació del mapa amb els botons del volum del dispositiu.</string>
|
||||
<string name="use_volume_buttons_as_zoom_descr">Controla el nivell d\'ampliació del mapa fent servir els botons del volum del dispositiu.</string>
|
||||
<string name="use_volume_buttons_as_zoom">Botons de volum pel zoom</string>
|
||||
<string name="delete_all_actions_message_q">Esteu segur que voleu suprimir definitivament %d dreceres\?</string>
|
||||
<string name="export_import_quick_actions_with_profiles_promo">Podeu exportar o importar les dreceres amb els perfils de les aplicacions.</string>
|
||||
|
@ -3686,7 +3686,7 @@ Abasta l\'àrea: %1$s x %2$s</string>
|
|||
<string name="screen_timeout_descr">Si està activat \"%1$s\" el temps d\'activitat quedarà afectat.</string>
|
||||
<string name="shared_string_tones">tones</string>
|
||||
<string name="shared_string_meters">metres</string>
|
||||
<string name="quick_action_remove_next_destination">Suprimeix la propera fita</string>
|
||||
<string name="quick_action_remove_next_destination">Suprimeix la fita més propera</string>
|
||||
<string name="please_provide_point_name_error">Proporcioneu un nom per al punt</string>
|
||||
<string name="quick_action_remove_next_destination_descr">La propera fita de la ruta s\'esborrarà. Si es tractés de la Destinació final, la navegació s\'aturaria.</string>
|
||||
<string name="search_download_wikipedia_maps">Baixa mapes de la Viquipèdia</string>
|
||||
|
@ -3850,4 +3850,13 @@ Abasta l\'àrea: %1$s x %2$s</string>
|
|||
\n • S\'han corregit problemes en la importació/exportació de la configuració dels perfils
|
||||
\n
|
||||
\n</string>
|
||||
<string name="quick_action_transport_show">Mostra el transport públic</string>
|
||||
<string name="shared_string_add_profile">Afegeix un perfil</string>
|
||||
<string name="change_application_profile">Canvia el perfil de l\'aplicació</string>
|
||||
<string name="index_item_world_basemap_detailed">Mapa general del món (detallat)</string>
|
||||
<string name="unsupported_type_error">Tipus no suportat</string>
|
||||
<string name="shared_string_always">Sempre</string>
|
||||
<string name="screen_control">Control de pantalla</string>
|
||||
<string name="development">Desenvolupament</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3588,20 +3588,20 @@
|
|||
<string name="poi_substation_compensation">Kompenzační</string>
|
||||
<string name="poi_substation_compression">Kompresní</string>
|
||||
<string name="poi_substation_measurement">Měřicí</string>
|
||||
<string name="poi_rtsa_scale_nc">н/к</string>
|
||||
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
|
||||
<string name="poi_rtsa_scale_nc">n/c</string>
|
||||
<string name="poi_rtsa_scale_nc_asterisk">n/c*</string>
|
||||
<string name="poi_rtsa_scale_1a">1А</string>
|
||||
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
|
||||
<string name="poi_rtsa_scale_1b">1Б</string>
|
||||
<string name="poi_rtsa_scale_1b_asterisk">1Б*</string>
|
||||
<string name="poi_rtsa_scale_2a">2А</string>
|
||||
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
|
||||
<string name="poi_rtsa_scale_2b">2Б</string>
|
||||
<string name="poi_rtsa_scale_2b_asterisk">2Б*</string>
|
||||
<string name="poi_rtsa_scale_3a">3А</string>
|
||||
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
|
||||
<string name="poi_rtsa_scale_3b">3Б</string>
|
||||
<string name="poi_rtsa_scale_3b_asterisk">3Б*</string>
|
||||
<string name="poi_rtsa_scale_1b">1B</string>
|
||||
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
|
||||
<string name="poi_rtsa_scale_2a">2A</string>
|
||||
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
|
||||
<string name="poi_rtsa_scale_2b">2B</string>
|
||||
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
|
||||
<string name="poi_rtsa_scale_3a">3A</string>
|
||||
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
|
||||
<string name="poi_rtsa_scale_3b">3B</string>
|
||||
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
|
||||
<string name="poi_snowmobile_filter">Přístup sněžným skútrům</string>
|
||||
<string name="poi_access_bus">Přístup autobusům</string>
|
||||
<string name="poi_access_caravan">Přístup karavanům</string>
|
||||
|
@ -3827,7 +3827,7 @@
|
|||
<string name="poi_osmand_fire_hydrant_pressure_pressurized">Pod tlakem</string>
|
||||
<string name="poi_fire_hydrant_style_water_source_groundwater">Podzemní voda</string>
|
||||
<string name="poi_fire_hydrant_type_pipe">Roura</string>
|
||||
<string name="poi_internet_access_fee_customers">Internetový přístup: zdarma pro zákazníky</string>
|
||||
<string name="poi_internet_access_fee_customers">Internetový přístup: zákazníci</string>
|
||||
<string name="poi_monastery_type_clerks_regular">Typ klášteru: řeholnický</string>
|
||||
<string name="poi_monastery_type_hermitage">Typ klášteru: poustevnický</string>
|
||||
<string name="poi_monastery_type_canonry">Typ klášteru: kanovnický</string>
|
||||
|
@ -3845,4 +3845,8 @@
|
|||
<string name="poi_traffic_signals_vibration">Vibrace</string>
|
||||
<string name="poi_fire_hydrant_pressure_filter">Tlak</string>
|
||||
<string name="poi_fuel_lng">Zkapalněný zemní plyn</string>
|
||||
<string name="poi_parking_layby">Podél silnice</string>
|
||||
<string name="poi_parking_sheds">Přístřešky</string>
|
||||
<string name="poi_parking_rooftop">Střešní</string>
|
||||
<string name="poi_gpx_point">Bod GPX</string>
|
||||
</resources>
|
|
@ -3578,4 +3578,15 @@ Zobrazená oblast: %1$s x %2$s</string>
|
|||
<string name="sort_name_ascending">Název: A – Z</string>
|
||||
<string name="start_finish_icons">Ikony startu/cíle</string>
|
||||
<string name="contour_lines_thanks">Děkujeme za zakoupení modulu \'Vrstevnice\'</string>
|
||||
<string name="perform_oauth_authorization_description">Přihlásit se pomocí OAuth pro použití funkcí editace OSM</string>
|
||||
<string name="perform_oauth_authorization">Přihlásit pomocí OAuth</string>
|
||||
<string name="clear_osm_token">Vymazat OpenStreetMap OAuth token</string>
|
||||
<string name="osm_edit_logout_success">Odhlášení úspěšné</string>
|
||||
<string name="file_already_imported">Soubor je již importovaný v OsmAnd</string>
|
||||
<string name="use_two_phase_routing">Použít dvoufázový algoritmus A* pro výpočet trasy</string>
|
||||
<string name="shared_string_graph">Graf</string>
|
||||
<string name="message_need_calculate_route_before_show_graph">Údaje %1$s jsou dostupné pouze na cestách, pro jejich získání musíte vypočítat trasu pomocí “Trasa medzi body”.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Počkejte na přepočet trasy.
|
||||
\nGraf bude dostupný po přepočtu.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3788,4 +3788,6 @@
|
|||
<string name="all_next_segments_will_be_recalc">Alle efterfølgende segmenter genberegnes ved hjælp af den valgte profil.</string>
|
||||
<string name="all_previous_segments_will_be_recalc">Alle tidligere segmenter genberegnes ved hjælp af den valgte profil.</string>
|
||||
<string name="start_finish_icons">Start-/slutikoner</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="app_mode_gap">Hul</string>
|
||||
</resources>
|
|
@ -3848,4 +3848,8 @@
|
|||
<string name="poi_recycling_small_electrical_appliances">Kleine Elektrogeräte</string>
|
||||
<string name="poi_nuts">Nussladen</string>
|
||||
<string name="poi_fuel_lng">Flüssigerdgas</string>
|
||||
<string name="poi_parking_layby">Parken in Parallelstraße</string>
|
||||
<string name="poi_parking_sheds">Überdachter Parkplatz</string>
|
||||
<string name="poi_parking_rooftop">Dachparkplätze</string>
|
||||
<string name="poi_gpx_point">GPX-Wegpunkt</string>
|
||||
</resources>
|
|
@ -3652,9 +3652,9 @@
|
|||
<string name="ltr_or_rtl_combine_via_slash_with_space">%1$s / %2$s</string>
|
||||
<string name="osm_live_payment_subscription_management">Die Bezahlung wird Ihrem Google Play-Konto bei der Bestätigung des Kaufs belastet.
|
||||
\n
|
||||
\n Das Abonnement verlängert sich automatisch, sofern es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird für den Verlängerungszeitraum (Monat / drei Monate / Jahr) nur am Verlängerungsdatum belastet.
|
||||
\nDas Abonnement verlängert sich automatisch, sofern es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird für den Verlängerungszeitraum (Monat / drei Monate / Jahr) nur am Verlängerungsdatum belastet.
|
||||
\n
|
||||
\n Sie können Ihre Abonnements verwalten und kündigen, indem Sie zu Ihren Google Play-Einstellungen gehen.</string>
|
||||
\nSie können Ihre Abonnements verwalten und kündigen, indem Sie zu Ihren Google Play-Einstellungen gehen.</string>
|
||||
<string name="search_poi_types">Suche nach POI-Typen</string>
|
||||
<string name="search_poi_types_descr">Kombinieren Sie POI-Typen aus verschiedenen Kategorien. Tippen Sie auf den Schalter, um alle auszuwählen, tippen Sie auf die linke Seite zur Kategorieauswahl.</string>
|
||||
<string name="shared_string_divider">Trenner</string>
|
||||
|
@ -3913,9 +3913,9 @@
|
|||
<string name="osm_live_payment_desc_hw">Das Abonnement wird pro ausgewähltem Zeitraum berechnet. Sie können das Abonnement jederzeit über die AppGallery kündigen.</string>
|
||||
<string name="osm_live_payment_subscription_management_hw">Die Bezahlung wird Ihrem AppGallery-Konto bei der Bestätigung des Kaufs belastet.
|
||||
\n
|
||||
\n Das Abonnement verlängert sich automatisch, sofern es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird für den Verlängerungszeitraum (Monat / drei Monate / Jahr) nur am Verlängerungsdatum belastet.
|
||||
\nDas Abonnement verlängert sich automatisch, sofern es nicht vor dem Verlängerungsdatum gekündigt wird. Ihr Konto wird für den Verlängerungszeitraum (Monat / drei Monate / Jahr) nur am Verlängerungsdatum belastet.
|
||||
\n
|
||||
\n Sie können Ihre Abonnements verwalten und kündigen, indem Sie zu Ihren AppGallery-Einstellungen gehen.</string>
|
||||
\nSie können Ihre Abonnements verwalten und kündigen, indem Sie zu Ihren AppGallery-Einstellungen gehen.</string>
|
||||
<string name="routing_attr_avoid_footways_description">Vermeidet Fußwege</string>
|
||||
<string name="routing_attr_avoid_footways_name">Keine Fußwege</string>
|
||||
<string name="development">Entwicklung</string>
|
||||
|
@ -3929,4 +3929,8 @@
|
|||
<string name="file_already_imported">Datei wurde bereits in OsmAnd importiert</string>
|
||||
<string name="perform_oauth_authorization">Anmelden über OAuth</string>
|
||||
<string name="clear_osm_token">OpenStreetMap OAuth-Token löschen</string>
|
||||
<string name="what_is_new">Was ist neu</string>
|
||||
<string name="snowmobile_render_descr">Für das Schneemobilfahren mit speziellen Straßen und Tracks.</string>
|
||||
<string name="perform_oauth_authorization_description">Durchführen eines OAuth-Logins zur Nutzung der osmedit-Funktionen</string>
|
||||
<string name="use_two_phase_routing">2-Phasen-A*-Routing-Algorithmus verwenden</string>
|
||||
</resources>
|
|
@ -3838,4 +3838,8 @@
|
|||
<string name="poi_departures_board">Tabulo de forveturoj</string>
|
||||
<string name="poi_drinking_water_refill">Plenigi per trinkebla akvo</string>
|
||||
<string name="poi_fuel_lng">tergaso likva (LNG)</string>
|
||||
<string name="poi_parking_layby">laŭlonge de strato</string>
|
||||
<string name="poi_parking_sheds">privataj garaĝ-budoj</string>
|
||||
<string name="poi_parking_rooftop">tegmento</string>
|
||||
<string name="poi_gpx_point">GPX-punkto</string>
|
||||
</resources>
|
|
@ -3931,9 +3931,10 @@
|
|||
<string name="osm_edit_logout_success">Sesión finalizada</string>
|
||||
<string name="snowmobile_render_descr">Para caminos y senderos exclusivos de motos de nieve.</string>
|
||||
<string name="file_already_imported">El archivo ya fue importado en OsmAnd</string>
|
||||
<string name="use_two_phase_routing">Usar el algoritmo de enrutamiento A* de 2 fases</string>
|
||||
<string name="use_two_phase_routing">Usar el algoritmo de navegación A* bifásica</string>
|
||||
<string name="shared_string_graph">Gráfico</string>
|
||||
<string name="message_need_calculate_route_before_show_graph">%1$s datos disponibles sólo en los caminos, necesitas calcular una ruta usando «Ruta entre puntos» para obtenerla.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Espera el recálculo de la ruta.
|
||||
\nEl gráfico estará disponible después del recálculo.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3774,7 +3774,7 @@
|
|||
<string name="poi_tactile_paving_incorrect">Ebaõige</string>
|
||||
<string name="poi_tactile_paving_contrasted">Kontrastne</string>
|
||||
<string name="poi_traffic_signals_sound_locate">Ainult kui jalakäijatele lubatud</string>
|
||||
<string name="poi_internet_access_fee_customers">Tasuline internetipunkt</string>
|
||||
<string name="poi_internet_access_fee_customers">Tasuline internetipunkt klientidele</string>
|
||||
<string name="poi_video_no">Ei</string>
|
||||
<string name="poi_video_yes">Jah</string>
|
||||
<string name="poi_booth">Kioski tüüp</string>
|
||||
|
@ -3827,4 +3827,8 @@
|
|||
<string name="poi_beehive">Mesitaru</string>
|
||||
<string name="poi_nuts">Pähklipood</string>
|
||||
<string name="poi_fuel_lng">Veeldatud maagaas</string>
|
||||
<string name="poi_gpx_point">GPX sõlm</string>
|
||||
<string name="poi_parking_layby">Parkla kiirtee ääres</string>
|
||||
<string name="poi_parking_sheds">Parkimine varjualustes</string>
|
||||
<string name="poi_parking_rooftop">Parkla katusel</string>
|
||||
</resources>
|
|
@ -3782,4 +3782,8 @@
|
|||
<string name="what_is_new">Meie uudised</string>
|
||||
<string name="use_two_phase_routing">Kasuta kahefaasilist A-klassi teekonna koostamise algoritmi</string>
|
||||
<string name="file_already_imported">See fail on juba OsmAnd\'i imporditud</string>
|
||||
<string name="use_live_routing">OsmAnd andmed reaalajas</string>
|
||||
<string name="use_live_public_transport">OsmAnd andmed reaalajas</string>
|
||||
<string name="snowmobile_render_descr">Mootorsaanide sõitmine eraldi määratud teedel ja radadel.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -1050,7 +1050,7 @@
|
|||
<string name="poi_nudism_no">Interdit</string>
|
||||
<string name="poi_nudism_obligatory">Obligatoire</string>
|
||||
<string name="poi_population">Population</string>
|
||||
<string name="poi_parking_underground">Parking : sous-terrain</string>
|
||||
<string name="poi_parking_underground">Parking : souterrain</string>
|
||||
<string name="poi_trees_olive">Olivier</string>
|
||||
<string name="poi_trees_apple">Pommier</string>
|
||||
<string name="poi_trees_oil">Palmier</string>
|
||||
|
|
|
@ -3845,7 +3845,7 @@
|
|||
<string name="simplified_track">Trace simplifiée</string>
|
||||
<string name="shared_string_file_name">Nom de fichier</string>
|
||||
<string name="system_default_theme">Par défaut</string>
|
||||
<string name="open_saved_track">Ouvrir une trace enregistrée</string>
|
||||
<string name="open_saved_track">Ouvrir la trace enregistrée</string>
|
||||
<string name="shared_string_is_saved">a été enregistré</string>
|
||||
<string name="one_point_error">Veuillez ajouter au moins deux points.</string>
|
||||
<string name="import_track_descr">Sélectionnez le fichier de trace à suivre ou importez-le depuis votre appareil.</string>
|
||||
|
@ -3912,4 +3912,6 @@
|
|||
\nLe graphique sera disponible à l\'issue du calcul.</string>
|
||||
<string name="snowmobile_render_descr">Pour la conduite en motoneige avec des routes et des pistes dédiées.</string>
|
||||
<string name="shared_string_graph">Graphique</string>
|
||||
<string name="app_mode_gap">Écart</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s - %2$s</string>
|
||||
</resources>
|
|
@ -3950,4 +3950,9 @@ Lon %2$s</string>
|
|||
<string name="perform_oauth_authorization">Entrar polo OAuth</string>
|
||||
<string name="clear_osm_token">Limpar token do OpenStreetMap OAuth</string>
|
||||
<string name="osm_edit_logout_success">Sesión rematada</string>
|
||||
<string name="snowmobile_render_descr">Para estradas e pistas exclusivas de motos de neve.</string>
|
||||
<string name="file_already_imported">O ficheiro xa foi importado no OsmAnd</string>
|
||||
<string name="use_two_phase_routing">Usar algoritmo de enrutamento A* de 2 fases</string>
|
||||
<string name="shared_string_graph">Gráfica</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -454,7 +454,7 @@
|
|||
<string name="poi_attraction_train">Vonat (látványosság)</string>
|
||||
<string name="poi_attraction_water_slide">Vízi csúszda</string>
|
||||
<string name="poi_hunting_lodge">Vadászház</string>
|
||||
<string name="poi_internet_access_wlan">Internetcsatlakozás: WLAN</string>
|
||||
<string name="poi_internet_access_wlan">Internetcsatlakozás: WLAN (wifi)</string>
|
||||
<string name="poi_internet_access_terminal">Internetcsatlakozás: munkaállomás</string>
|
||||
<string name="poi_internet_access_wired">Internetcsatlakozás: kábel</string>
|
||||
<string name="poi_internet_access_public">Internetcsatlakozás: nyilvános</string>
|
||||
|
@ -836,7 +836,7 @@
|
|||
<string name="poi_denomination_georgian_orthodox">Grúz ortodox</string>
|
||||
<string name="poi_denomination_romanian_orthodox">Román ortodox</string>
|
||||
<string name="poi_denomination_coptic_orthodox">Kopt ortodox</string>
|
||||
<string name="poi_internet_access_yes">Internetcsatlakozás</string>
|
||||
<string name="poi_internet_access_yes">Internetcsatlakozás van</string>
|
||||
<string name="poi_internet_access_no">Internetcsatlakozás nincs</string>
|
||||
<string name="poi_dance_floor">Tánctér</string>
|
||||
<string name="poi_nightclub">Night club; Diszkó</string>
|
||||
|
@ -1547,7 +1547,7 @@
|
|||
<string name="poi_internet_access_type_wlan">Wi-Fi</string>
|
||||
<string name="poi_internet_access_type_terminal">Munkaállomás</string>
|
||||
<string name="poi_internet_access_type_wired">Vezetékes</string>
|
||||
<string name="poi_internet_access_type_public">Nyilvános</string>
|
||||
<string name="poi_internet_access_type_public">Internetcsatlakozás: nyilvános</string>
|
||||
<string name="poi_internet_access_type_service">Segítenek</string>
|
||||
<string name="poi_internet_access_type_no">Internetcsatlakozás nincs</string>
|
||||
<string name="poi_internet_access_type_yes">Internetcsatlakozás van</string>
|
||||
|
@ -3836,4 +3836,8 @@
|
|||
<string name="poi_nuts">Mag- és aszaltgyümölcsbolt</string>
|
||||
<string name="poi_beehive">Méhkaptár</string>
|
||||
<string name="poi_fuel_lng">LNG (cseppfolyósított földgáz)</string>
|
||||
<string name="poi_parking_layby">Út mellett parkolósáv (UK)</string>
|
||||
<string name="poi_parking_sheds">Fedett parkolóhely</string>
|
||||
<string name="poi_parking_rooftop">Tető</string>
|
||||
<string name="poi_internet_access_fee_customers">Internetcsatlakozás: ügyfeleknek</string>
|
||||
</resources>
|
|
@ -3509,7 +3509,7 @@
|
|||
<string name="clear_recorded_data">Rögzített adatok törlése</string>
|
||||
<string name="terrain_empty_state_text">Engedélyezésével domborzatárnyékolás vagy lejtőtérkép jeleníthető meg. Ezekről a térképfajtákról többet olvashat a honlapunkon.</string>
|
||||
<string name="app_mode_ski_touring">Túrasízés</string>
|
||||
<string name="app_mode_ski_snowmobile">Motoros hószán</string>
|
||||
<string name="app_mode_ski_snowmobile">Motoros szán</string>
|
||||
<string name="custom_osmand_plugin">Egyéni OsmAnd bővítmény</string>
|
||||
<string name="settings_item_read_error">Sikertelen olvasás innen: \'%1$s\'.</string>
|
||||
<string name="settings_item_write_error">Sikertelen írás ide: \'%1$s\'.</string>
|
||||
|
@ -3920,4 +3920,10 @@
|
|||
<string name="osm_edit_logout_success">Sikeresen kijelentkezett</string>
|
||||
<string name="use_two_phase_routing">Kétszakaszos A* útvonaltervezési algoritmus használata</string>
|
||||
<string name="file_already_imported">A fájl már importálva van az OsmAndba</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s - %2$s</string>
|
||||
<string name="snowmobile_render_descr">Motorosszánutakhoz kifejezetten motoros szán számára kijelölt utakon.</string>
|
||||
<string name="shared_string_graph">Grafikon</string>
|
||||
<string name="message_need_calculate_route_before_show_graph">%1$s adatok csak az utakról állnak rendelkezésre. Használja az „Útvonal tervezése pontok között” funkciót.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Várja meg az útvonal újraszámítását.
|
||||
\nAz ábra az újraszámítás után lesz látható.</string>
|
||||
</resources>
|
|
@ -3905,4 +3905,32 @@
|
|||
<string name="sort_name_ascending">Nome: A – Z</string>
|
||||
<string name="start_finish_icons">Icona Partenza/Arrivo</string>
|
||||
<string name="contour_lines_thanks">Grazie per l\'acquisto del \'Plugin delle curve di livello\'</string>
|
||||
<string name="what_is_new">Novità</string>
|
||||
<string name="snowmobile_render_descr">Per slitte a motore con strade e sentieri dedicati.</string>
|
||||
<string name="osm_live_payment_desc_hw">Sottoscrizione addebitata per il periodo selezionato. Cancellala nell\'AppGallery in ogni momento.</string>
|
||||
<string name="osm_live_payment_subscription_management_hw">Il pagamento sarà addebitato nella tuo account AppGallery alla conferma dell\'acquisto.
|
||||
\n
|
||||
\nLe sottoscrizioni si rinnovano automaticamente finché non vengono cancellate prima della date del rinnovo. Il tuo account sarà addebitato per i rinnovi periodici solo (mensile/trimestrale/annuale) solo alla data di rinnovo.
|
||||
\n
|
||||
\nPuoi gestire le tue sottoscrizioni nelle impostazioni della tua AppGallery.</string>
|
||||
<string name="routing_attr_avoid_footways_description">Evita i marciapiedi</string>
|
||||
<string name="routing_attr_avoid_footways_name">Evita i marciapiedi</string>
|
||||
<string name="development">Sviluppo</string>
|
||||
<string name="use_live_public_transport">Dati OsmAnd Live</string>
|
||||
<string name="use_live_routing">Dati OsmAnd Live</string>
|
||||
<string name="complex_routing_descr">Calcolo del percorso in due fasi per la navigazione in auto.</string>
|
||||
<string name="use_native_pt">Sviluppo Trasporto Pubblico nativo</string>
|
||||
<string name="use_native_pt_desc">Cambia a Java (safe) calcolo del percorso su Trasporto Pubblico</string>
|
||||
<string name="perform_oauth_authorization_description">Effettua una connessione OAuth per usare le funzionalità osmedit</string>
|
||||
<string name="perform_oauth_authorization">Connettiti via OAuth</string>
|
||||
<string name="clear_osm_token">Cancella il token OAuth OpenStreetMap</string>
|
||||
<string name="osm_edit_logout_success">Disconnessione effettuata</string>
|
||||
<string name="file_already_imported">Il file è già importato in OsmAnd</string>
|
||||
<string name="use_two_phase_routing">Utilizza l\'algoritmo di calcolo a 2-fasi A*</string>
|
||||
<string name="shared_string_graph">Grafico</string>
|
||||
<string name="message_need_calculate_route_before_show_graph">%1$s dati disponibili solo per le strade, necessiti di calcolare un percorso utilizzando \"Percorso fra punti\" per ottenerlo.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Attendi per il ricalcolo del percorso.
|
||||
\nIl grafico sarà disponibile dopo il ricalcolo.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="app_mode_gap">Buco</string>
|
||||
</resources>
|
|
@ -3938,4 +3938,5 @@
|
|||
<string name="shared_string_graph">תרשים</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">נא להמתין לחישוב המסלול מחדש.
|
||||
\nהתרשים יהיה זמין לאחר החישוב מחדש.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -17,10 +17,10 @@
|
|||
<string name="new_destination_point_dialog">Du har allerede angitt et reisemål:</string>
|
||||
<string name="shared_string_target_points">Reisemål</string>
|
||||
<string name="intermediate_point_too_far">Mellomliggende reisemål %1$s er for langt fra den nærmeste veien.</string>
|
||||
<string name="arrived_at_intermediate_point">Ankommet mellomliggende reisemål</string>
|
||||
<string name="arrived_at_intermediate_point">Mellomliggende reisemål er nådd</string>
|
||||
<string name="context_menu_item_intermediate_point">Legg til som mellomliggende reisemål</string>
|
||||
<string name="map_widget_intermediate_distance">Mellomliggende reisemål</string>
|
||||
<string name="ending_point_too_far">Sluttpunkt for langt fra nærmeste vei.</string>
|
||||
<string name="ending_point_too_far">Endepunkt for langt fra nærmeste vei.</string>
|
||||
<string name="add_tag">Legg til merke</string>
|
||||
<string name="btn_advanced_mode">Avansert modus…</string>
|
||||
<string name="poi_filter_parking">Parkering</string>
|
||||
|
@ -259,7 +259,7 @@
|
|||
<string name="local_indexes_cat_poi">Interessepunkt-data</string>
|
||||
<string name="ttsvoice">TTS-tale</string>
|
||||
<string name="search_offline_clear_search">Nytt søk</string>
|
||||
<string name="map_text_size_descr">Navnetekststørrelse på kartet:</string>
|
||||
<string name="map_text_size_descr">Tekststørrelse for navn på kartet:</string>
|
||||
<string name="map_text_size">Skriftstørrelse for kart</string>
|
||||
<string name="internet_connection_required_for_online_route">Nettbasert navigering fungerer ikke frakoblet.</string>
|
||||
<string name="tts_language_not_supported_title">Språk ikke støttet</string>
|
||||
|
@ -406,7 +406,7 @@
|
|||
<string name="route_general_information">Total distanse %1$s, reisetid %2$d t %3$d min.</string>
|
||||
<string name="router_service_descr">Nettbasert eller frakoblet navigeringstjeneste.</string>
|
||||
<string name="router_service">Navigeringstjeneste</string>
|
||||
<string name="sd_dir_not_accessible">Datalagringsmappen på minnekortet er ikke tilgjengelig!</string>
|
||||
<string name="sd_dir_not_accessible">Lagringsmappen på minnekortet er ikke tilgjengelig!</string>
|
||||
<string name="download_question">Laste ned {0} - {1} \?</string>
|
||||
<string name="download_question_exist">Nettfrakoblede data for {0} finnes allerede ({1}). Oppdater ({2})\?</string>
|
||||
<string name="address">Adresse</string>
|
||||
|
@ -456,7 +456,7 @@
|
|||
<string name="search_button">Søk</string>
|
||||
<string name="search_activity">Søk</string>
|
||||
<string name="searchpoi_activity">Velg interessepunkt</string>
|
||||
<string name="search_POI_level_btn">Finn mer</string>
|
||||
<string name="search_POI_level_btn">Finn flere</string>
|
||||
<string name="incremental_search_city">Søk etter by trinnvis</string>
|
||||
<string name="incremental_search_street">Søk etter gate trinnvis</string>
|
||||
<string name="incremental_search_building">Søk etter bygning trinnvis</string>
|
||||
|
@ -472,8 +472,8 @@
|
|||
<string name="navigate_point_top_text">Angi bredde- og lengdegrad i det valgte formatet (G - grader, M - minutter, S - sekunder)</string>
|
||||
<string name="navigate_point_latitude">Breddegrad</string>
|
||||
<string name="navigate_point_longitude">Lengdegrad</string>
|
||||
<string name="navigate_point_format_D">DDD.DDDDD</string>
|
||||
<string name="navigate_point_format_DM">DDD MM,MMM</string>
|
||||
<string name="navigate_point_format_D">GGG.GGGGG</string>
|
||||
<string name="navigate_point_format_DM">GGG MM,MMM</string>
|
||||
<string name="navigate_point_format_DMS">GGG MM SS,S</string>
|
||||
<string name="search_address_top_text">Adresse</string>
|
||||
<string name="search_address_region">Region</string>
|
||||
|
@ -522,7 +522,7 @@
|
|||
<string name="choose_osmand_theme_descr">Tilpass programutseende.</string>
|
||||
<string name="driving_region_us">USA</string>
|
||||
<string name="driving_region_canada">Canada</string>
|
||||
<string name="driving_region_europe_asia">Europa, Asia, Latin-Amerika & lignende</string>
|
||||
<string name="driving_region_europe_asia">Europa, Asia, Latin-Amerika og lignende</string>
|
||||
<string name="driving_region_uk">Storbritannia, India og lignende</string>
|
||||
<string name="driving_region_descr">Velg bilkjøringssted: USA, Europa, Storbritannia, Asia og andre.</string>
|
||||
<string name="driving_region_japan">Japan</string>
|
||||
|
@ -603,7 +603,7 @@
|
|||
<string name="lang_lv">Latvisk</string>
|
||||
<string name="lang_lt">Litauisk</string>
|
||||
<string name="lang_mr">Marathi</string>
|
||||
<string name="lang_no">Norsk Bokmål</string>
|
||||
<string name="lang_no">Norsk bokmål</string>
|
||||
<string name="lang_pl">Polsk</string>
|
||||
<string name="lang_pt">Portugisisk</string>
|
||||
<string name="lang_ro">Rumensk</string>
|
||||
|
@ -637,7 +637,7 @@
|
|||
<string name="rendering_attr_showCycleRoutes_name">Vis sykkelruter</string>
|
||||
<string name="show_zoom_buttons_navigation_descr">Vis zoom-knapper under navigering.</string>
|
||||
<string name="show_zoom_buttons_navigation">Vis zoom-knapper</string>
|
||||
<string name="map_widget_plain_time">Nåtid</string>
|
||||
<string name="map_widget_plain_time">Gjeldende tid</string>
|
||||
<string name="osmo_edit_color">Visningsfarge</string>
|
||||
<string name="always_center_position_on_map">Sentrer posisjon på kart</string>
|
||||
<string name="guidance_preferences_descr">Navigeringsinnstillinger</string>
|
||||
|
@ -675,7 +675,7 @@
|
|||
<string name="rendering_category_others">Andre kartattributter</string>
|
||||
<string name="rendering_attr_publicTransportMode_name">Buss-, trolleybuss-, skyttelbussruter</string>
|
||||
<string name="rendering_attr_tramTrainRoutes_name">Trikk- og togruter</string>
|
||||
<string name="rendering_attr_subwayMode_name">Undergrunnsruter</string>
|
||||
<string name="rendering_attr_subwayMode_name">T-bane-ruter</string>
|
||||
<string name="rendering_attr_trainLightrailRoutes_name">Togruter</string>
|
||||
<string name="rendering_attr_tramRoutes_name">Trikkeruter</string>
|
||||
<string name="rendering_attr_trolleybusRoutes_name">Trolleybussruter</string>
|
||||
|
@ -721,7 +721,7 @@
|
|||
<string name="lang_al">Albansk</string>
|
||||
<string name="lang_ar">Arabisk</string>
|
||||
<string name="lang_fa">Persisk</string>
|
||||
<string name="lang_sc">Sardinsk</string>
|
||||
<string name="lang_sc">Sardisk</string>
|
||||
<string name="route_descr_select_destination">Velg reisemål</string>
|
||||
<string name="routing_attr_prefer_motorway_name">Foretrekk motorveier</string>
|
||||
<string name="routing_attr_prefer_motorway_description">Foretrekk motorveier</string>
|
||||
|
@ -1103,7 +1103,7 @@
|
|||
<string name="mark_to_delete">Merk for å slette</string>
|
||||
<string name="agps_info">A-GPS-info</string>
|
||||
<string name="shared_string_message">Melding</string>
|
||||
<string name="agps_data_last_downloaded">A-GPS-data sist nedlastet: %1$s</string>
|
||||
<string name="agps_data_last_downloaded">A-GPS-data nedlastet: %1$s</string>
|
||||
<string name="welcome_text">OsmAnd tilbyr global nettfrakoblet kartlesing og navigering.</string>
|
||||
<string name="current_route">Gjeldende rute</string>
|
||||
<string name="shared_string_go">Start</string>
|
||||
|
@ -1257,7 +1257,7 @@
|
|||
<string name="favorite_category_name">Kategorinavn</string>
|
||||
<string name="favorite_category_add_new_title">Legg til ny kategori</string>
|
||||
<string name="regions">Regioner</string>
|
||||
<string name="region_maps">Regionkart</string>
|
||||
<string name="region_maps">Regionale kart</string>
|
||||
<string name="world_maps">Verdenskart</string>
|
||||
<string name="hillshade_layer_disabled">Relieffskyggelag deaktivert</string>
|
||||
<string name="share_menu_location">Del posisjon</string>
|
||||
|
@ -1271,7 +1271,7 @@
|
|||
<string name="update_all">Oppdater alle (%1$s MB)</string>
|
||||
<string name="free_downloads_used">Gratis nedlastinger brukt</string>
|
||||
<string name="application_dir_description">Velg hvor du vil lagre kart og andre datafiler.</string>
|
||||
<string name="enter_country_name">Oppgi navn på land</string>
|
||||
<string name="enter_country_name">Angi navn på land</string>
|
||||
<string name="world_map_download_descr">Basiskart verden (som dekker hele verden ved lavt zoomnivå) mangler eller er utdatert. Vurder å laste det ned for en global oversikt.</string>
|
||||
<string name="shared_string_qr_code">QR-kode</string>
|
||||
<string name="basemap_was_selected_to_download">Basiskart velges for nedlasting slik at programmet fungerer.</string>
|
||||
|
@ -1455,7 +1455,7 @@
|
|||
<string name="poi_action_delete">slett</string>
|
||||
<string name="poi_error_io_error_template">I/O-feil under utførelse av handlingen {0}.</string>
|
||||
<string name="user_hates_app_get_feedback">Fortell oss hvorfor.</string>
|
||||
<string name="failed_to_upload">Klarte ikke å laste opp</string>
|
||||
<string name="failed_to_upload">Kunne ikke laste opp</string>
|
||||
<string name="buy">Kjøp</string>
|
||||
<string name="faq_item">Ofte stilte spørsmål</string>
|
||||
<string name="number_of_edits">Antall redigeringer</string>
|
||||
|
@ -1482,7 +1482,7 @@
|
|||
<string name="use_osm_live_routing">OsmAnd Live-navigering</string>
|
||||
<string name="access_no_destination">Reisemål er ikke angitt</string>
|
||||
<string name="access_shared_string_navigate_up">Naviger opp</string>
|
||||
<string name="open_street_map_login_and_pass">OpenStreetMap-brukernavn og passord</string>
|
||||
<string name="open_street_map_login_and_pass">OSM-brukernavn og passord</string>
|
||||
<string name="osm_live_subscription">OsmAnd Live-abonnement</string>
|
||||
<string name="osm_live_hide_user_name">Ikke vis mitt navn i rapporter</string>
|
||||
<string name="osm_live_ask_for_purchase">Kjøp først et OsmAnd Live-abonnement</string>
|
||||
|
@ -1564,7 +1564,7 @@
|
|||
<string name="current_track">Aktuelle spor</string>
|
||||
<string name="show_current_gpx_title">Vis aktuelle spor</string>
|
||||
<string name="rendering_attr_currentTrackWidth_description">GPX-bredde</string>
|
||||
<string name="storage_place_description">OsmAnds datalagring (for kart, GPX-filer, osv.): %1$s.</string>
|
||||
<string name="storage_place_description">OsmAnds datalagring (for kart, sporfiler, etc.): %1$s.</string>
|
||||
<string name="first_usage_greeting">Få anvisninger og oppdag nye steder uten å ha internettforbindelse</string>
|
||||
<string name="update_all_maps_now">Oppdater alle kart nå\?</string>
|
||||
<string name="osm_live_payment_desc">Abonnementsavgift belastes månedsvis. Avbryt det på Google Play når som helst.</string>
|
||||
|
@ -1694,7 +1694,7 @@
|
|||
<string name="upload_osm_note_description">Last opp ditt OSM-notat anonymt eller ved å bruke din profil hos OpenStreetMap.org.</string>
|
||||
<string name="gpx_no_tracks_title">Du har ingen GPX-filer enda</string>
|
||||
<string name="gpx_no_tracks_title_folder">Du kan også legge til GPX-filer i mappen</string>
|
||||
<string name="gpx_add_track">Legg til mer…</string>
|
||||
<string name="gpx_add_track">Legg til flere…</string>
|
||||
<string name="trip_rec_notification_settings">Skru på hurtigopptak</string>
|
||||
<string name="trip_rec_notification_settings_desc">Vis et systemvarsel som kan starte turopptak.</string>
|
||||
<string name="save_track_min_speed">Minimumshastighet for logging</string>
|
||||
|
@ -1801,7 +1801,7 @@
|
|||
<string name="osmo_connect_menu">Koble til</string>
|
||||
<string name="routing_attr_avoid_stairs_name">Ingen trapper</string>
|
||||
<string name="routing_attr_avoid_stairs_description">Unngår trapper</string>
|
||||
<string name="speech_rate_descr">Angi talehastigheten for TTS.</string>
|
||||
<string name="speech_rate_descr">Angi talehastigheten for tekst-til-tale.</string>
|
||||
<string name="speech_rate">Talehastighet</string>
|
||||
<string name="complex_route_calculation_failed">Rask ruteberegning mislyktes (%s), faller tilbake på treg beregning.</string>
|
||||
<string name="disable_complex_routing_descr">Slå av to-fase ruteplanlegging for bilnavigering.</string>
|
||||
|
@ -1856,7 +1856,7 @@
|
|||
<string name="lang_new">Nepal bhasa</string>
|
||||
<string name="lang_ceb">Cebuano</string>
|
||||
<string name="lang_ast">Asturiansk</string>
|
||||
<string name="lang_hsb">Øvervendisk</string>
|
||||
<string name="lang_hsb">Oversorbisk</string>
|
||||
<string name="lang_kab">Kabylsk</string>
|
||||
<string name="lang_zh_hk">Kinesisk (Hongkong)</string>
|
||||
<string name="use_displayed_track_for_navigation">Bruk vist spor for navigering\?</string>
|
||||
|
@ -1932,7 +1932,7 @@
|
|||
<string name="quick_action_map_overlay_action">Legg til overlegg</string>
|
||||
<string name="quick_action_map_overlay_switch">Kartoverlegg er endret til \"%s\".</string>
|
||||
<string name="points_delete_multiple_succesful">Punkt(er) slettet.</string>
|
||||
<string name="points_delete_multiple">ER du sikker på at du vil slette %1$d punkt(er)\?</string>
|
||||
<string name="points_delete_multiple">Er du sikker på at du vil slette %1$d punkt(er)\?</string>
|
||||
<string name="average_speed">Gjennomsnittsfart</string>
|
||||
<string name="select_gpx_folder">Velg mappe for GPX-fil</string>
|
||||
<string name="osmand_extended_description_part1">OsmAnd (OSM Automated Navigation Directions) er et kart- og navigeringsprogram med tilgang til gratis, verdensomspennende og høykvalitets data fra OpenStreetMap (OSM).
|
||||
|
@ -2003,7 +2003,7 @@
|
|||
<string name="altitude_descent">Fall</string>
|
||||
<string name="altitude_ascent">Stigning</string>
|
||||
<string name="altitude_range">Høydeintervall</string>
|
||||
<string name="average_altitude">Gjennomsnittlig høyde</string>
|
||||
<string name="average_altitude">Gjennomsnittshøyde</string>
|
||||
<string name="route_head">Følg</string>
|
||||
<string name="shared_string_action_name">Handlingsnavn</string>
|
||||
<string name="display_zoom_level">Visningszoomnivå: %1$s</string>
|
||||
|
@ -2025,7 +2025,7 @@
|
|||
<string name="routing_attr_height_obstacles_description">Ta hensyn til terrenghøyde (data fra SRTM, ASTER og EU-DEM).</string>
|
||||
<string name="quick_action_bug_message">Melding</string>
|
||||
<string name="shared_string_permissions">Tillatelser</string>
|
||||
<string name="import_gpx_failed_descr">Kunne ikke importere filen. Kontroller at OsmAnd kan lese den.</string>
|
||||
<string name="import_gpx_failed_descr">Kunne ikke importere filen. Kontroller at OsmAnd har tillatelse til å lese den.</string>
|
||||
<string name="distance_moving">Korrigert avstand</string>
|
||||
<string name="shared_string_reload">Last på nytt</string>
|
||||
<string name="wrong_user_name">Feil brukernavn</string>
|
||||
|
@ -2053,7 +2053,7 @@
|
|||
<string name="quick_action_resume_pause_navigation">Navigering: sett på pause/gjenoppta</string>
|
||||
<string name="quick_action_resume_pause_navigation_descr">Knapp for å ta en pause i eller gjenoppta navigeringen.</string>
|
||||
<string name="right_side_navigation">Høyrekjøring</string>
|
||||
<string name="quick_action_start_stop_navigation_descr">Trykk på denne knappen for å starte eller avslutte navigeringen.</string>
|
||||
<string name="quick_action_start_stop_navigation_descr">Knapp for å starte eller avslutte navigering.</string>
|
||||
<string name="store_tracks_in_monthly_directories">Lagre spor som er tatt opp i månedlige mapper</string>
|
||||
<string name="store_tracks_in_monthly_directories_descrp">Lagre spor som er tatt opp, i undermapper per opptaksmåned (f.eks. 2018-01).</string>
|
||||
<string name="mapillary_menu_descr_tile_cache">Last kartfliser på nytt for å se oppdaterte data.</string>
|
||||
|
@ -2085,7 +2085,7 @@
|
|||
<string name="mapillary_image">Mapillary-bilde</string>
|
||||
<string name="open_mapillary">Åpne Mapillary</string>
|
||||
<string name="shared_string_install">Installer</string>
|
||||
<string name="improve_coverage_mapillary">Forbedre billeddekningen med Mapillary</string>
|
||||
<string name="improve_coverage_mapillary">Forbedre bildedekningen med Mapillary</string>
|
||||
<string name="online_photos">Nettbaserte bilder</string>
|
||||
<string name="shared_string_add_photos">Legg til bilder</string>
|
||||
<string name="no_photos_descr">Ingen bilder her.</string>
|
||||
|
@ -2097,7 +2097,7 @@
|
|||
<string name="nautical_maps">Sjøkart</string>
|
||||
<string name="restore_purchases">Gjenopprett kjøp</string>
|
||||
<string name="do_not_send_anonymous_app_usage">Ikke send anonym bruksstatistikk</string>
|
||||
<string name="parking_options">Parkeringsalternativer</string>
|
||||
<string name="parking_options">Parkeringsmuligheter</string>
|
||||
<string name="full_version_thanks">Takk for at du kjøpte betalingsversjonen av OsmAnd.</string>
|
||||
<string name="routing_attr_driving_style_speed_name">Kortere ruter</string>
|
||||
<string name="routing_attr_driving_style_balance_name">Balansert</string>
|
||||
|
@ -2137,7 +2137,7 @@
|
|||
<string name="shared_string_list">Liste</string>
|
||||
<string name="passed">Sist brukt: %1$s</string>
|
||||
<string name="mapillary_menu_filter_description">Filtrer bilder etter innsender, dato eller type. Kun aktivt på nærgående forstørrelsesnivå.</string>
|
||||
<string name="improve_coverage_install_mapillary_desc">Installer Mapillary for å legge til et eller flere bilder til denne kartposisjonen.</string>
|
||||
<string name="improve_coverage_install_mapillary_desc">Installer Mapillary for å legge til bilder i denne kartposisjonen.</string>
|
||||
<string name="plugin_mapillary_descr">Foto på gatenivå for alle. Oppdag plasser, samarbeid, fang inn verden.</string>
|
||||
<string name="quick_action_showhide_osmbugs_title">Vis/skjul OSM-notater</string>
|
||||
<string name="quick_action_osmbugs_show">Vis OSM-notater</string>
|
||||
|
@ -2147,7 +2147,7 @@
|
|||
<string name="index_item_depth_contours_osmand_ext">Havdybdekonturer</string>
|
||||
<string name="download_depth_countours">Havdybdekonturer</string>
|
||||
<string name="route_points_category_name">Svinger å passere langs ruten</string>
|
||||
<string name="rendering_attr_depthContours_description">Vis havdybdekonturer og punkter.</string>
|
||||
<string name="rendering_attr_depthContours_description">Vis dybdekonturer og punkter.</string>
|
||||
<string name="rendering_attr_depthContours_name">Havdybdekonturer</string>
|
||||
<string name="auto_split_recording_title">Del opp opptak automatisk etter avbrudd</string>
|
||||
<string name="auto_split_recording_descr">Start nytt segment etter et avbrudd på 6 min., nytt spor etter avbrudd på 2 timer, eller ny fil etter et lengre avbrudd hvis datoen er endret.</string>
|
||||
|
@ -2156,7 +2156,7 @@
|
|||
\n- Synkronisere grupper og enheter med tjeneren;
|
||||
\n- Behandle grupper og enheter i et personlig dashbord på nettstedet.</string>
|
||||
<string name="simulate_initial_startup">Simuler første programstart</string>
|
||||
<string name="audionotes_plugin_description">Programtillegget for Audio/video-notater tilbyr funksjoner for å ta lyd/video/bilde-notater på en tur, enten ved bruk av en knapp på kartet, eller direkte i kontekstmenyen for enhver posisjon på kartet.</string>
|
||||
<string name="audionotes_plugin_description">Lag audio/foto/video-notater på en tur, enten ved bruk av en knapp på kartet eller posisjon-kontekstmeny.</string>
|
||||
<string name="average">Gjennomsnitt</string>
|
||||
<string name="of">%1$d av %2$d</string>
|
||||
<string name="ascent_descent">Stigning/fall</string>
|
||||
|
@ -2177,7 +2177,7 @@
|
|||
<string name="order_by">Sorter etter:</string>
|
||||
<string name="map_orientation_change_in_accordance_with_speed">Kartorienteringsterskel</string>
|
||||
<string name="map_orientation_change_in_accordance_with_speed_descr">Velg hastighet for skifte av kartorientering fra \'Bevegelsesretning\' til \'Kompassretning\' nedenfor.</string>
|
||||
<string name="srtm_purchase_header">Kjøp og installer \"Koter\"-programtillegget for å vise loddrett skyggelegging.</string>
|
||||
<string name="srtm_purchase_header">Kjøp og installer \"Koter\"-tillegget for å vise graderte vertikale områder.</string>
|
||||
<string name="native_app_allocated_memory">Totalt innebygget minne</string>
|
||||
<string name="starting_point_too_far">Startpunkt for langt fra nærmeste vei.</string>
|
||||
<string name="shared_location">Delt posisjon</string>
|
||||
|
@ -2213,7 +2213,7 @@
|
|||
<string name="rendering_exception">Kunne ikke tegne valgt område.</string>
|
||||
<string name="renderer_load_sucess">Kartgenerator lastet</string>
|
||||
<string name="error_reading_gpx">Kunne ikke lese GPX-data.</string>
|
||||
<string name="any_poi">Hvilke som helst</string>
|
||||
<string name="any_poi">Alle</string>
|
||||
<string name="thanks_yandex_traffic">Takk til Yandex for trafikkinfo.</string>
|
||||
<string name="layer_yandex_traffic">Yandex-trafikk</string>
|
||||
<string name="background_service_provider">Stedsbestemmelsestjeneste</string>
|
||||
|
@ -2238,7 +2238,7 @@
|
|||
<string name="use_fast_recalculation">Smart omberegning av rute</string>
|
||||
<string name="rate_this_app">Vurder dette programmet</string>
|
||||
<string name="rate_this_app_long">Gi OsmAnd en poengsum på Google Play</string>
|
||||
<string name="user_hates_app_get_feedback_long">Fortell oss hva du ønsker å endre i dette programmet.</string>
|
||||
<string name="user_hates_app_get_feedback_long">Gi oss beskjed om forslag.</string>
|
||||
<string name="shared_string_card_was_hidden">Kortet ble skjult</string>
|
||||
<string name="count_of_lines">Antall linjer</string>
|
||||
<string name="poi_context_menu_modify_osm_change">Modifiser OSM-endring</string>
|
||||
|
@ -2370,7 +2370,7 @@
|
|||
<string name="poi_namefinder_query_empty">Skriv for å finne interessepunkt</string>
|
||||
<string name="background_service_wait_int_descr">Setter høyeste tillatte ventetid for hver bakgrunns-posisjonsbestemmelse.</string>
|
||||
<string name="background_service_wait_int">Maksimal ventetid for posisjonsbestemmelse</string>
|
||||
<string name="background_service_int_descr">Vekkingsintervall brukt av bakgrunnstjeneste:</string>
|
||||
<string name="background_service_int_descr">Vekkingsintervall brukt av bakgrunnstjenesten:</string>
|
||||
<string name="background_service_provider_descr">Stedsbestemmelsesmetode brukt av bakgrunnstjeneste:</string>
|
||||
<string name="transport_search_after">Etterfølgende rute</string>
|
||||
<string name="transport_search_before">Tidligere rute</string>
|
||||
|
@ -2437,8 +2437,8 @@
|
|||
<string name="audionotes_location_not_defined">Sted å assosiere med notatet er ikke definert ennå. \"Bruk posisjon…\" for å tilordne et notat til det angitte stedet.</string>
|
||||
<string name="add_waypoint_dialog_title">Legg til rutepunkt i innspilt GPX-spor</string>
|
||||
<string name="voice_is_not_available_msg">Taleveiledning er ikke tilgjengelig, gå til \'Innstillinger\' → \'Navigeringsinnstillinger\' , velg profilen → \'Taleveiledning\' og velg eller last ned en talemeldingspakke.</string>
|
||||
<string name="use_fast_recalculation_desc">For lange turer, beregn på nytt bare den første delen av ruten.</string>
|
||||
<string name="nautical_renderer">Nautisk</string>
|
||||
<string name="use_fast_recalculation_desc">Beregner på nytt bare den første delen av ruten. Kan brukes for lange turer.</string>
|
||||
<string name="nautical_renderer">Maritimt</string>
|
||||
<string name="day_off_label">stengt (fridag)</string>
|
||||
<string name="copy_location_name">Kopier sted/interessepunkt-navn</string>
|
||||
<string name="toast_empty_name_error">Sted uten navn</string>
|
||||
|
@ -3679,7 +3679,7 @@
|
|||
<string name="quick_action_remove_next_destination_descr">Nåværende målpunkt på ruten vil slettes. Hvis det er målet, vil navigasjonen stoppe.</string>
|
||||
<string name="app_mode_wheelchair">Rullestol</string>
|
||||
<string name="app_mode_go_cart">Gokart</string>
|
||||
<string name="plan_a_route">Planlegg en rute</string>
|
||||
<string name="plan_a_route">Ruteplanlegging</string>
|
||||
<string name="additional_actions_descr">Du får tilgang til disse handlingene ved å trykke på knappen “%1$s”.</string>
|
||||
<string name="use_volume_buttons_as_zoom_descr">Styr zoomnivået på kartet med enhetens volumknapper.</string>
|
||||
<string name="add_hidden_group_info">Det tillagte punktet vil ikke være synlig på kartet, siden den valgte gruppen er skjult, du kan finne det i \"%s\".</string>
|
||||
|
@ -3823,7 +3823,7 @@
|
|||
<string name="simplified_track_description">Kun rutelinjen vil lagres, rutepunktene vil slettes.</string>
|
||||
<string name="context_menu_item_add_waypoint">Legg til spor-rutepunkt</string>
|
||||
<string name="quick_action_add_gpx">Legg til spor-rutepunkt</string>
|
||||
<string name="complex_routing_descr">To-delt ruting for bilkjøring.</string>
|
||||
<string name="complex_routing_descr">To-fase-ruting for bilnavigering.</string>
|
||||
<string name="osm_live_payment_desc_hw">Abonnement påløper per valgte periode. Avbryt det når som helst fra programgalleriet.</string>
|
||||
<string name="attach_to_the_roads">Følg veier</string>
|
||||
<string name="monitoring_min_distance">Minimumsforskyvning</string>
|
||||
|
@ -3868,4 +3868,8 @@
|
|||
<string name="osm_edit_logout_success">Utlogget</string>
|
||||
<string name="use_two_phase_routing">Bruk 2-stegs A*-rutingsalgoritme</string>
|
||||
<string name="file_already_imported">Filen er allerede importert i OsmAnd</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Vent på omberegning av ruten.
|
||||
\nGraf vil være tilgjengelig etter omberegning.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="shared_string_graph">Graf</string>
|
||||
</resources>
|
|
@ -30,7 +30,7 @@
|
|||
<string name="back_to_location">Terug naar locatie</string>
|
||||
<string name="accessibility_mode">Toegankelijkheidsmodus</string>
|
||||
<string name="accessibility_mode_descr">Zet toegankelijkheidsmodus aan.</string>
|
||||
<string name="accessibility_default">Gelijk aan systeeminstelling</string>
|
||||
<string name="accessibility_default">Gelijk aan de Android systeeminstelling</string>
|
||||
<string name="backToMenu">Terug naar menu</string>
|
||||
<string name="zoomOut">Zoom uit</string>
|
||||
<string name="zoomIn">Zoom in</string>
|
||||
|
@ -251,8 +251,8 @@
|
|||
<string name="error_doing_search">Fout bij offline zoeken.</string>
|
||||
<string name="search_osm_offline">Zoek adres in de offline kaarten</string>
|
||||
<string name="system_locale">Systeem</string>
|
||||
<string name="preferred_locale_descr">App menu-taal (OsmAnd dient opnieuw gestart).</string>
|
||||
<string name="preferred_locale">Taal</string>
|
||||
<string name="preferred_locale_descr">App toon talen (OsmAnd dient opnieuw gestart).</string>
|
||||
<string name="preferred_locale">Toon talen</string>
|
||||
<string name="unit_of_length_descr">Wijzig de eenheid van afstand voor metingen.</string>
|
||||
<string name="unit_of_length">Afstand eenheden</string>
|
||||
<string name="si_mi_feet">Mijlen/voeten</string>
|
||||
|
@ -824,7 +824,7 @@
|
|||
<string name="intermediate_point">Tussenpunt %1$s</string>
|
||||
<string name="gps_not_available">Schakel GPS in via de instellingen</string>
|
||||
<string name="map_widget_show_destination_arrow">Richting van de bestemming tonen</string>
|
||||
<string name="enable_plugin_monitoring_services">Activeer de GPX-Track opnemen- Plugin om de afgelegde weg vast te leggen (GPX-track, online tracking)</string>
|
||||
<string name="enable_plugin_monitoring_services">Activeer de \"GPX-Track opnemen\" Plug-in om de afgelegde weg vast te leggen (GPX-track, online tracking)</string>
|
||||
<string name="non_optimal_route_calculation">Bereken mogelijk niet-optimale route voor lange afstanden</string>
|
||||
<string name="rendering_attr_roadColors_description">Kies kleurschema voor wegen:</string>
|
||||
<string name="rendering_attr_roadColors_name">Kleurschema voor wegen</string>
|
||||
|
@ -921,7 +921,7 @@
|
|||
<string name="osmand_play_title_30_chars">OsmAnd Kaarten & Navigatie</string>
|
||||
<string name="osmand_plus_play_title_30_chars">OsmAnd+ Kaarten & Navigatie</string>
|
||||
<string name="hno">Huisnummer</string>
|
||||
<string name="monitoring_settings">GPX-track</string>
|
||||
<string name="monitoring_settings">Track opnemen</string>
|
||||
<string name="monitoring_settings_descr">Stel in hoe uw trips op te nemen.</string>
|
||||
<string name="street_name">Straatnaam</string>
|
||||
<string name="choose_osmand_theme_descr">Aanpassen van app uitzicht aan uw wensen.</string>
|
||||
|
@ -952,8 +952,8 @@
|
|||
<string name="plugin_distance_point">Punt</string>
|
||||
<string name="gpx_file_name">GPX-bestandsnaam</string>
|
||||
<string name="gpx_saved_sucessfully">GPX-bestand succesvol opgeslagen als {0}</string>
|
||||
<string name="osmand_distance_planning_plugin_description">Deze plug-in voorziet een kaart-widget waarmee u een route kan ontwerpen door op de kaart te tikken, of gebruik te maken (of wijzigen) van bestaande GPX-bestanden. Plan zo een reis en bereken de afstand tussen punten. Het resultaat kan worden bewaard als GPX-bestand, om later te gebruiken als navigatieroute.</string>
|
||||
<string name="osmand_distance_planning_plugin_name">Afstand meten en Route plannen</string>
|
||||
<string name="osmand_distance_planning_plugin_description">Maak paden door op de kaart te tikken of door bestaande GPX-bestanden te gebruiken of te wijzigen om een reis te plannen en de afstand tussen punten te meten. Het resultaat kan worden opgeslagen als een GPX-bestand om later als richtlijn te gebruiken.</string>
|
||||
<string name="osmand_distance_planning_plugin_name">Afstandscalculator en planningstool</string>
|
||||
<string name="use_distance_measurement_help">* Tik om een punt te markeren.
|
||||
\n* Druk lang op de kaart om het vorige punt te verwijderen.
|
||||
\n* Druk lang en houd vast op een punt om de beschrijving te zien en toe te voegen.
|
||||
|
@ -1247,7 +1247,7 @@
|
|||
<string name="speak_poi">Dichtbij POI</string>
|
||||
<string name="shared_string_all">Alles</string>
|
||||
<string name="index_tours">Reizen</string>
|
||||
<string name="record_plugin_name">GPX-track opnemen</string>
|
||||
<string name="record_plugin_name">Track opnemen</string>
|
||||
<string name="int_hour">u.</string>
|
||||
<string name="duration">Duur</string>
|
||||
<string name="distance">Afstand</string>
|
||||
|
@ -1462,7 +1462,7 @@
|
|||
<string name="shared_string_audio">Geluid</string>
|
||||
<string name="shared_string_video">Video</string>
|
||||
<string name="shared_string_photo">Foto</string>
|
||||
<string name="delay_to_start_navigation_descr">Kies de wachttijd in om op het route-planning scherm te blijven.</string>
|
||||
<string name="delay_to_start_navigation_descr">Geef de wachttijd op om op het route-planning scherm te blijven.</string>
|
||||
<string name="delay_to_start_navigation">Start begeleiding na…</string>
|
||||
<string name="shared_string_go">Start</string>
|
||||
<string name="action_create">Actietoets aanmaken</string>
|
||||
|
@ -1639,7 +1639,7 @@
|
|||
<string name="min_mile">min/m</string>
|
||||
<string name="min_km">min/km</string>
|
||||
<string name="m_s">m/s</string>
|
||||
<string name="shared_string_trip_recording">GPX-Track opnemen</string>
|
||||
<string name="shared_string_trip_recording">Track opnemen</string>
|
||||
<string name="shared_string_navigation">Navigatie</string>
|
||||
<string name="favourites_edit_dialog_title">Informatie over favoriet</string>
|
||||
<string name="simulate_your_location_stop_descr">Positiesimulatie beëindigen.</string>
|
||||
|
@ -2058,7 +2058,7 @@
|
|||
<string name="gpx_add_track">Meer toevoegen…</string>
|
||||
<string name="shared_string_appearance">Weergave</string>
|
||||
<string name="trip_rec_notification_settings">Snelle opname activeren</string>
|
||||
<string name="trip_rec_notification_settings_desc">Toon systeemmelding waarmee ritopname toegestaan wordt.</string>
|
||||
<string name="trip_rec_notification_settings_desc">Toon systeemmelding waarmee track opname toegestaan wordt.</string>
|
||||
<string name="shared_string_notifications">Meldingen</string>
|
||||
<string name="route_calculation">Route berekening</string>
|
||||
<string name="rendering_value_fine_name">Fijn</string>
|
||||
|
@ -2359,10 +2359,10 @@
|
|||
<string name="shared_string_install">Installeer</string>
|
||||
<string name="improve_coverage_mapillary">Verbeter de fotocollectie van Mapillary</string>
|
||||
<string name="improve_coverage_install_mapillary_desc">Installeer Mapillary om foto\'s aan deze kaartlocatie toe te voegen.</string>
|
||||
<string name="mapillary_action_descr">Deel uw straatniveau uitzicht via Mapillary.</string>
|
||||
<string name="mapillary_action_descr">Deel uw weergave op straatniveau via Mapillary.</string>
|
||||
<string name="mapillary_widget_descr">Snel bijdragen aan Mapillary.</string>
|
||||
<string name="mapillary_descr">Foto\'s van buiten voor iedereen. Ondek plaatsen, werk samen, en leg de wereld vast.</string>
|
||||
<string name="plugin_mapillary_descr">Foto\'s van buiten voor iedereen. Ondek plaatsen, werk samen, en leg de wereld vast.</string>
|
||||
<string name="mapillary_descr">Online foto\'s op straatniveau voor iedereen. Ontdek plaatsen, werk samen, leg de wereld vast.</string>
|
||||
<string name="plugin_mapillary_descr">Foto\'s op straatniveau voor iedereen. Ontdek plaatsen, werk samen, leg de wereld vast.</string>
|
||||
<string name="shared_string_permissions">Rechten</string>
|
||||
<string name="import_gpx_failed_descr">Kan bestand niet importeren. Controleer of OsmAnd rechten heeft om het bestand te lezen.</string>
|
||||
<string name="distance_moving">Gecorrigeerde afstand</string>
|
||||
|
@ -3297,7 +3297,7 @@
|
|||
<string name="added_profiles_descr">Door plug-in toegevoegde profielen</string>
|
||||
<string name="shared_string_turn_off">Uitschakelen</string>
|
||||
<string name="new_plugin_added">Nieuwe plug-in toegevoegd</string>
|
||||
<string name="join_segments">verbind segmenten</string>
|
||||
<string name="join_segments">Segmenten samenvoegen</string>
|
||||
<string name="release_3_4">• App profiles: Create a custom profile for your own needs, with a custom icon and color
|
||||
\n
|
||||
\n • Nu aan te passen standaard en min / max snelheden voor elk profiel
|
||||
|
@ -3356,7 +3356,7 @@
|
|||
<string name="multimedia_notes_prefs_descr">Afbeeldingsgrootte, geluids- en videokwaliteit</string>
|
||||
<string name="osm_editing_prefs_descr">Login, wachtwoord, offline bewerken</string>
|
||||
<string name="accessibility_prefs_descr">Kies icoon, kleur en naam</string>
|
||||
<string name="live_monitoring_descr">Laat u toe uw positie te delen dankzij reisopname.</string>
|
||||
<string name="live_monitoring_descr">Laat u toe uw positie te delen dankzij track opname.</string>
|
||||
<string name="live_monitoring">Online volgen</string>
|
||||
<string name="save_track_logging_accuracy">Opnamenauwkeurigheid</string>
|
||||
<string name="tracks_view_descr">De opgenomen tracks zijn opgeslagen in %1$s, of in de OsmAnd-map.</string>
|
||||
|
@ -3530,7 +3530,7 @@
|
|||
<string name="shared_string_terrain">Terrein</string>
|
||||
<string name="slope_description">Helling gebruikt kleuren om de steilheid van het terrein te visualiseren.</string>
|
||||
<string name="terrain_slider_description">Stel de minimale en maximale zoomniveaus in waarbij de laag wordt weergegeven.</string>
|
||||
<string name="slope_download_description">Om Hellingen te tonen zijn extra kaarten nodig.</string>
|
||||
<string name="slope_download_description">Om hellingen te tonen zijn extra kaarten nodig.</string>
|
||||
<string name="slope_read_more">Meer over Hellingen in %1$s.</string>
|
||||
<string name="shared_string_transparency">Transparantie</string>
|
||||
<string name="shared_string_zoom_levels">Zoomniveaus</string>
|
||||
|
@ -3666,7 +3666,7 @@
|
|||
<string name="shared_string_legal">Legaal</string>
|
||||
<string name="speed_camera_pois">Snelheidscamera’s als POI’s</string>
|
||||
<string name="hillshade_description">De reliëfschaduwkaart maakt gebruik van donkere schaduwen om hellingen, bergtoppen en valleien te visualiseren.</string>
|
||||
<string name="hillshade_download_description">Om Reliëfschaduw te tonen zijn extra kaarten nodig.</string>
|
||||
<string name="hillshade_download_description">Om reliëfschaduw te tonen zijn extra kaarten nodig.</string>
|
||||
<string name="shared_string_hillshade">Reliëfschaduw</string>
|
||||
<string name="terrain_empty_state_text">Selecteer deze optie om een reliëfschaduw- of hellingskaart te tonen. Op onze site staat meer informatie over deze kaarttypes.</string>
|
||||
<string name="map_source_zoom_levels_descr">Heeft invloed op de weergave bij gebruik als kaart of als extra kaartlaag/achtergrondlaag.
|
||||
|
@ -3696,4 +3696,79 @@
|
|||
<string name="app_mode_wheelchair_forward">Rolstoel vooraanzicht</string>
|
||||
<string name="osm_edit_closed_note">Opgeloste OSM-opmerking</string>
|
||||
<string name="app_mode_go_cart">Kart</string>
|
||||
<string name="map_widget_monitoring">Track opnemen</string>
|
||||
<string name="save_global_track_interval_descr">Specificeer het registratie-interval voor de algemene trackregistratie (ingeschakeld via de track-widget op de kaart).</string>
|
||||
<string name="gpx_monitoring_stop">Pauzeer track opname</string>
|
||||
<string name="gpx_monitoring_start">Hervat track opnemen</string>
|
||||
<string name="street_level_imagery">Beelden op srraatniveau</string>
|
||||
<string name="select_track_width">Selecteer dikte</string>
|
||||
<string name="track_show_start_finish_icons">Toon start en aankomst pictogrammen</string>
|
||||
<string name="gpx_direction_arrows">Richtingaanwijzers</string>
|
||||
<string name="add_hidden_group_info">Het toegevoegde punt zal niet zichtbaar zijn op de kaart, aangezien de geselecteerde groep verborgen is, je kan het vinden in \"%s\".</string>
|
||||
<string name="system_default_theme">Standaard</string>
|
||||
<string name="route_between_points">Route tussen punten</string>
|
||||
<string name="route_between_points_warning_desc">"Vervolgens, zet uw track vast op de dichtstbijzijnde toegestane weg met een van uw navigatieprofielen om deze optie te gebruiken."</string>
|
||||
<string name="message_need_calculate_route_before_show_graph">%1$s gegevens alleen beschikbaar op de wegen, u moet een route berekenen met behulp van \"Route tussen punten\" om deze te krijgen.</string>
|
||||
<string name="route_between_points_desc">Selecteer hoe de punten verbonden worden, via een rechte lijn, of een route berekenen tussen de punten zoals hieronder aangegeven.</string>
|
||||
<string name="route_between_points_next_segment_button_desc">Alleen het volgende segment wordt opnieuw berekend met het geselecteerde profiel.</string>
|
||||
<string name="next_segment">Volgende segment</string>
|
||||
<string name="all_next_segments">Alle volgende segmenten</string>
|
||||
<string name="all_next_segments_will_be_recalc">Alle volgende segmenten worden opnieuw berekend met het geselecteerde profiel.</string>
|
||||
<string name="whole_track">De ganse track</string>
|
||||
<string name="route_between_points_whole_track_button_desc">De ganse track wordt herberekend volgens het geselecteerde profiel.</string>
|
||||
<string name="pass_whole_track_descr">Punt van de track om te navigeren</string>
|
||||
<string name="shared_string_save_as_gpx">Bewaar als nieuw trackbestand</string>
|
||||
<string name="save_as_new_track">Bewaar als nieuwe track</string>
|
||||
<string name="release_3_7">Nieuwe offline pistekaarten
|
||||
\n
|
||||
\n • Volledige aanpassing van favorieten en GPX-waypoints - aangepaste kleuren, pictogrammen, vormen
|
||||
\n
|
||||
\n • Pas de volgorde van items aan in \"Contextmenu\", \"Configureer kaart\" en \"........\"
|
||||
\n
|
||||
\n •Wikipedia als een afzonderlijke laag in Kaart configureren, selecteer alleen de benodigde talen
|
||||
\n
|
||||
\n • Creëer uw eigen POI-filter / kaarten met totale flexibiliteit
|
||||
\n
|
||||
\n • Opties toegevoegd om instellingen voor aangepaste profielen te herstellen
|
||||
\n
|
||||
\n • Volledige GPX-routes van navigatieondersteunende rijstroken en volledige afslaginstructies
|
||||
\n
|
||||
\n •Verbeterde UI-formaten op tablets
|
||||
\n
|
||||
\n •Herstel bugs met RTL
|
||||
\n
|
||||
\n</string>
|
||||
<string name="add_to_a_track">Voeg toe aan een track</string>
|
||||
<string name="add_segment_to_the_track">Voeg toe aan een trackbestand</string>
|
||||
<string name="simplified_track">Vereenvoudigde track</string>
|
||||
<string name="simplified_track_description">Alleen de routelijn wordt opgeslagen, de waypoints worden verwijderd.</string>
|
||||
<string name="shared_string_done">Bewaar</string>
|
||||
<string name="reverse_route">Route omkeren</string>
|
||||
<string name="route_between_points_add_track_desc">"Selecteer een track waaraan je een nieuw segment wil toevoegen."</string>
|
||||
<string name="plan_route_select_track_file_for_open">Selecteer een trackbestand om te openen.</string>
|
||||
<string name="plan_route_exit_dialog_descr">Weet u zeker dat u alle wijzigingen in de geplande route wilt annuleren door deze te sluiten\?</string>
|
||||
<string name="plan_route_trim_before">Opsmukken voor</string>
|
||||
<string name="plan_route_trim_after">Opsmukken na</string>
|
||||
<string name="plan_route_change_route_type_before">Wijzig het routetype voor</string>
|
||||
<string name="plan_route_change_route_type_after">Wijzig het routetype na</string>
|
||||
<string name="release_3_8">• Bijgewerkt Plan een route functie: maakt het mogelijk om verschillende navigatietypes per segment te gebruiken en tracks op te nemen
|
||||
\n
|
||||
\n • Nieuw menu voor tracks: selecteer kleur, dikte, weergeven van richtingspijlen, start / finish-pictogrammen.
|
||||
\n
|
||||
\n • Verbeterde zichtbaarheid van fietsknooppunten.
|
||||
\n
|
||||
\n • Tracks kun je nu aantikken en hebben een contextmenu met basisinformatie.
|
||||
\n
|
||||
\n • Verbeterde zoekalgoritmen.
|
||||
\n
|
||||
\n • Verbeterde volg track-opties bij navigatie
|
||||
\n
|
||||
\n • Problemen opgelost met het importeren / exporteren van profielinstellingen
|
||||
\n
|
||||
\n</string>
|
||||
<string name="plan_route_import_track">Importeer track</string>
|
||||
<string name="plan_route_last_edited">Laatst bewerkt</string>
|
||||
<string name="plan_route_create_new_route">Maak een nieuwe route</string>
|
||||
<string name="plan_route_open_existing_track">Open een bestaande track</string>
|
||||
<string name="plan_a_route">Plan een route</string>
|
||||
</resources>
|
|
@ -3265,7 +3265,7 @@
|
|||
<string name="language_and_output">Język i wyjście</string>
|
||||
<string name="plugins_settings">Ustawienia wtyczki</string>
|
||||
<string name="shared_string_by_default">Domyślnie</string>
|
||||
<string name="download_detailed_map">Pobierz szczegółową mapę %S, aby zobaczyć ten obszar.</string>
|
||||
<string name="download_detailed_map">Pobierz szczegółową mapę %s, aby zobaczyć ten obszar.</string>
|
||||
<string name="change_data_storage_full_description">Przenieść pliki danych OsmAnd do nowego położenia\?
|
||||
\n%1$s > %2$s</string>
|
||||
<string name="enter_path_to_folder">Proszę wprowadzić ścieżkę do katalogu</string>
|
||||
|
@ -3769,11 +3769,11 @@
|
|||
<string name="uninstall_speed_cameras">Odinstaluj fotoradary</string>
|
||||
<string name="shared_string_legal">Prawny</string>
|
||||
<string name="speed_camera_pois">Punkty fotoradarów</string>
|
||||
<string name="speed_cameras_legal_descr">W niektórych krajachi regionach uzywanie aplikacji ostrzegających o fotoradarach jest zabronione przez prawo.
|
||||
<string name="speed_cameras_legal_descr">W niektórych krajach i regionach używanie aplikacji ostrzegających o fotoradarach jest zabronione przez prawo.
|
||||
\n
|
||||
\nMusisz dokonać wyboru w zależności od prawa danego kraju.
|
||||
\n
|
||||
\nWybierz %1$S i będziesz otrzymywać powiadomienia i ostrzeżenia o fotoradarach.
|
||||
\nWybierz %1$s i będziesz otrzymywać powiadomienia i ostrzeżenia o fotoradarach.
|
||||
\n
|
||||
\nWybierz %2$s. Wszystkie dane o fotoradarach: ostrzeżenia, powiadomienia, miejsca użyteczne zostaną usunięte, aż OsmAnd zostanie zainstalowany ponownie.</string>
|
||||
<string name="keep_active">Nie wyłączaj</string>
|
||||
|
@ -3814,7 +3814,7 @@
|
|||
<string name="gpx_split_interval_none_descr">Wybierz żądaną opcję podziału: według czasu lub odległości.</string>
|
||||
<string name="track_coloring_solid">Stałe</string>
|
||||
<string name="gpx_parse_error">OsmAnd GPX nie jest dobrze uformowany, prosimy o kontakt z zespołem wsparcia technicznego w celu dalszego zbadania sprawy.</string>
|
||||
<string name="turn_screen_on_wake_time_descr">Wybierz limit czasu ekranu po przebudzeniu. (\"%1$s\" nie powoduje przekroczenia limitu czasu).</string>
|
||||
<string name="turn_screen_on_wake_time_descr">Wybierz limit czasu ekranu po przebudzeniu. (\"%1$s\" nie powoduje przekroczenia limitu czasu.)</string>
|
||||
<string name="track_show_start_finish_icons">Pokaż ikony początku i końca</string>
|
||||
<string name="gpx_split_interval_descr">Wybierz przedział czasowy, w którym będą wyświetlane znaki z odległością lub czasem na torze.</string>
|
||||
<string name="shared_string_custom">Dostosowany</string>
|
||||
|
@ -3891,7 +3891,7 @@
|
|||
<string name="open_saved_track">Otwórz zapisaną ścieżkę</string>
|
||||
<string name="shared_string_is_saved">jest zapisywany</string>
|
||||
<string name="one_point_error">Należy dodać co najmniej dwa punkty.</string>
|
||||
<string name="disable_recording_once_app_killed_descrp">Wstrzyma rejestrowanie ścieżki, gdy aplikacja zostanie zabita (za pośrednictwem ostatnich aplikacji). (Wskazanie tła OsmAnd znika z paska powiadomień Androida).</string>
|
||||
<string name="disable_recording_once_app_killed_descrp">Wstrzyma rejestrowanie ścieżki, gdy aplikacja zostanie zabita (za pośrednictwem ostatnich aplikacji). (Wskazanie tła OsmAnd znika z paska powiadomień Androida.)</string>
|
||||
<string name="shared_string_redo">Ponów</string>
|
||||
<string name="release_3_8">• Zaktualizowana funkcja planu trasy: umożliwia korzystanie z różnych typów nawigacji na segment i dołączanie ścieżek
|
||||
\n
|
||||
|
@ -3933,4 +3933,6 @@
|
|||
<string name="perform_oauth_authorization">Zaloguj się przez OAuth</string>
|
||||
<string name="clear_osm_token">Wyczyść token OpenStreetMap OAuth</string>
|
||||
<string name="osm_edit_logout_success">Wylogowanie powiodło się</string>
|
||||
<string name="file_already_imported">Plik jest już zaimportowany do OsmAnd</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3800,7 +3800,7 @@
|
|||
<string name="poi_booth">Tipo de cabine</string>
|
||||
<string name="poi_video_yes">Sim</string>
|
||||
<string name="poi_video_no">Não</string>
|
||||
<string name="poi_internet_access_fee_customers">Sinal para encontrar o poste</string>
|
||||
<string name="poi_internet_access_fee_customers">Acesso à Internet: clientes</string>
|
||||
<string name="poi_traffic_signals_sound_locate">Somente quando andar é permitido</string>
|
||||
<string name="poi_tactile_paving_contrasted">Contrastado</string>
|
||||
<string name="poi_tactile_paving_primitive">Primitivo</string>
|
||||
|
@ -3845,4 +3845,6 @@
|
|||
<string name="poi_beehive">Colmeia</string>
|
||||
<string name="poi_nuts">Loja de nozes</string>
|
||||
<string name="poi_fuel_lng">GNL</string>
|
||||
<string name="poi_parking_sheds">Galpões</string>
|
||||
<string name="poi_gpx_point">Ponto GPX</string>
|
||||
</resources>
|
|
@ -3928,4 +3928,5 @@
|
|||
<string name="message_need_calculate_route_before_show_graph">Dados de %1$s disponíveis apenas nas estradas, você precisa calcular uma rota usando “Rota entre pontos” para obtê-la.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Aguarde o recálculo da rota.
|
||||
\nO gráfico estará disponível após o recálculo.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3935,4 +3935,6 @@
|
|||
<string name="message_need_calculate_route_before_show_graph">%1$s dados disponíveis apenas nas estradas, precisa calcular uma rota a usar \"Rota entre pontos\" para obtê-la.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Espere pelo recalculo da rota.
|
||||
\nO gráfico estará disponível após o recalculo.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="app_mode_gap">Lacuna</string>
|
||||
</resources>
|
|
@ -1974,7 +1974,7 @@
|
|||
<string name="downloads">Загрузки</string>
|
||||
<string name="show_free_version_banner">Показывать баннер бесплатной версии</string>
|
||||
<string name="show_free_version_banner_description">Показывать баннер бесплатной версии даже в платной версии.</string>
|
||||
<string name="confirm_download_roadmaps">В карте дорог не необходимости, так как у вас уже есть стандартная (полная) карта. Загрузить в любом случае?</string>
|
||||
<string name="confirm_download_roadmaps">В карте дорог нет необходимости, так как у вас уже есть стандартная (полная) карта. Загрузить в любом случае?</string>
|
||||
<string name="value_downloaded_of_max">%1$.1f из %2$.1f МБ</string>
|
||||
<string name="file_size_in_mb">%.1f МБ</string>
|
||||
<string name="update_all">Обновить все (%1$s МБ)</string>
|
||||
|
|
|
@ -3796,7 +3796,7 @@
|
|||
<string name="poi_booth">Casta de cabina</string>
|
||||
<string name="poi_video_yes">Eja</string>
|
||||
<string name="poi_video_no">Nono</string>
|
||||
<string name="poi_internet_access_fee_customers">Sinnale pro agatare su palu</string>
|
||||
<string name="poi_internet_access_fee_customers">Atzessu a ìnternet: clientes</string>
|
||||
<string name="poi_traffic_signals_sound_locate">Petzi cando si podet camminare</string>
|
||||
<string name="poi_tactile_paving_contrasted">Cuntrastadu</string>
|
||||
<string name="poi_tactile_paving_primitive">Primitivu</string>
|
||||
|
@ -3841,4 +3841,8 @@
|
|||
<string name="poi_departures_board">Tabellone de sas tzucadas</string>
|
||||
<string name="poi_drinking_water_refill">Ricàrriga de abba potàbile</string>
|
||||
<string name="poi_fuel_lng">GNL (LNG)</string>
|
||||
<string name="poi_parking_layby">Ispiatzu (layby)</string>
|
||||
<string name="poi_parking_sheds">Cabannas</string>
|
||||
<string name="poi_parking_rooftop">Cobertura</string>
|
||||
<string name="poi_gpx_point">Puntu GPX</string>
|
||||
</resources>
|
|
@ -3931,4 +3931,5 @@
|
|||
<string name="shared_string_graph">Gràficu</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Iseta su càrculu nou de s\'àndala.
|
||||
\nSu gràficu at a èssere a disponimentu a pustis de su càrculu.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3933,4 +3933,6 @@
|
|||
<string name="message_need_calculate_route_before_show_graph">Údaje %1$s sú dostupné len na cestách, pre ich získanie musíte vypočítať trasu pomocou “Trasa medzi bodmi”.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Počkajte na prepočet trasy.
|
||||
\nGraf bude dostupný po prepočte.</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="app_mode_gap">Medzera</string>
|
||||
</resources>
|
|
@ -3788,7 +3788,7 @@
|
|||
<string name="poi_booth">Вид стенда</string>
|
||||
<string name="poi_video_yes">Так</string>
|
||||
<string name="poi_video_no">Ні</string>
|
||||
<string name="poi_internet_access_fee_customers">Сигнал, щоб знайти полюс</string>
|
||||
<string name="poi_internet_access_fee_customers">Доступ до Інтернету: клієнти</string>
|
||||
<string name="poi_traffic_signals_sound_locate">Допускається лише при ходінні</string>
|
||||
<string name="poi_tactile_paving_contrasted">Контрастний</string>
|
||||
<string name="poi_tactile_paving_primitive">Примітивний</string>
|
||||
|
@ -3833,4 +3833,8 @@
|
|||
<string name="poi_beehive">Вулик</string>
|
||||
<string name="poi_nuts">Насіннєвий магазин</string>
|
||||
<string name="poi_fuel_lng">СПГ</string>
|
||||
<string name="poi_parking_layby">Придорожня стоянка</string>
|
||||
<string name="poi_parking_sheds">Навіси</string>
|
||||
<string name="poi_parking_rooftop">Дах</string>
|
||||
<string name="poi_gpx_point">Точка GPX</string>
|
||||
</resources>
|
|
@ -3929,4 +3929,6 @@
|
|||
<string name="message_need_calculate_route_before_show_graph">%1$s дані доступні лише для доріг, вам потрібно обчислити маршрут за допомогою «Маршрут між точками», щоб отримати його.</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Дочекайтеся переобчислення маршруту.
|
||||
\nГрафік буде доступний після переобчислення.</string>
|
||||
<string name="app_mode_gap">Розрив</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
</resources>
|
|
@ -3799,7 +3799,7 @@
|
|||
<string name="poi_booth">亭類型</string>
|
||||
<string name="poi_video_yes">是</string>
|
||||
<string name="poi_video_no">否</string>
|
||||
<string name="poi_internet_access_fee_customers">找到極點的訊號</string>
|
||||
<string name="poi_internet_access_fee_customers">網際網路存取:顧客</string>
|
||||
<string name="poi_traffic_signals_sound_locate">僅在步行時允許</string>
|
||||
<string name="poi_tactile_paving_contrasted">對比</string>
|
||||
<string name="poi_tactile_paving_primitive">粗糙</string>
|
||||
|
@ -3844,4 +3844,8 @@
|
|||
<string name="poi_beehive">蜂箱</string>
|
||||
<string name="poi_nuts">堅果店</string>
|
||||
<string name="poi_fuel_lng">LNG</string>
|
||||
<string name="poi_parking_layby">停車區</string>
|
||||
<string name="poi_parking_sheds">車棚</string>
|
||||
<string name="poi_parking_rooftop">屋頂</string>
|
||||
<string name="poi_gpx_point">GPX 點</string>
|
||||
</resources>
|
|
@ -3928,4 +3928,6 @@
|
|||
<string name="message_need_calculate_route_before_show_graph">%1$s 資料僅供道路使用,您需要使用「兩點間的路線」來計算路線。</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">等待路線重新計算。
|
||||
\n重新計算後即可使用圖表。</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="app_mode_gap">分隔</string>
|
||||
</resources>
|
|
@ -11,6 +11,16 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="icon_group_travel">Travel</string>
|
||||
<string name="icon_group_emergency">Emergency</string>
|
||||
<string name="icon_group_sport">Sport</string>
|
||||
<string name="icon_group_symbols">Symbols</string>
|
||||
<string name="icon_group_service">Service</string>
|
||||
<string name="icon_group_transport">Transport</string>
|
||||
<string name="icon_group_special">Special</string>
|
||||
<string name="icon_group_amenity">Amenity</string>
|
||||
<string name="app_mode_gap">Gap</string>
|
||||
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
|
||||
<string name="shared_string_local_maps">Local maps</string>
|
||||
<string name="message_graph_will_be_available_after_recalculation">Wait for the route recalculation.\nGraph will be available after recalculation.</string>
|
||||
<string name="message_need_calculate_route_before_show_graph">%1$s data available only on the roads, you need to calculate a route using “Route between points” to get it.</string>
|
||||
|
@ -104,7 +114,7 @@
|
|||
<string name="route_between_points_warning_desc">Next, snap your track to the nearest allowed road with one of your navigation profiles to use this option.</string>
|
||||
<string name="next_segment">Next segment</string>
|
||||
<string name="whole_track">Whole track</string>
|
||||
<string name="route_between_points_desc">Select how to connect points, by a straight line, or calculate a route between them as specified below.</string>
|
||||
<string name="route_between_points_desc">Choose how to connect the points, by a straight line, or calculate a route between them as specified below.</string>
|
||||
<string name="route_between_points_next_segment_button_desc">Only the next segment will be recalculated using the selected profile.</string>
|
||||
<string name="route_between_points_whole_track_button_desc">The whole track will be recalculated using the selected profile.</string>
|
||||
<string name="reverse_route">Reverse route</string>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
android:layout="@layout/preference_button"
|
||||
android:persistent="false"
|
||||
android:title="@string/reorder_profiles"
|
||||
app:fragment="net.osmand.plus.profiles.fragments.EditProfilesFragment"
|
||||
app:fragment="net.osmand.plus.profiles.EditProfilesFragment"
|
||||
tools:icon="@drawable/ic_action_edit_dark" />
|
||||
|
||||
<Preference
|
||||
|
|
|
@ -428,7 +428,7 @@ public class FavouritesDbHelper {
|
|||
while (fl) {
|
||||
fl = false;
|
||||
for (FavouritePoint fp : fdb.getFavouritePoints()) {
|
||||
if (fp.getName().equals(name) && p.getLatitude() != fp.getLatitude() && p.getLongitude() != fp.getLongitude()) {
|
||||
if (fp.getName().equals(name) && p.getLatitude() != fp.getLatitude() && p.getLongitude() != fp.getLongitude() && fp.getCategory().equals(p.getCategory())) {
|
||||
number++;
|
||||
index = " (" + number + ")";
|
||||
name = p.getName() + index;
|
||||
|
|
|
@ -114,6 +114,19 @@ public abstract class SettingsBaseActivity extends ActionBarPreferenceActivity
|
|||
return p;
|
||||
}
|
||||
|
||||
public static String getIconStringPropertyName(Context ctx, String propertyName, String defValue) {
|
||||
try {
|
||||
Field f = R.string.class.getField("icon_group_" + propertyName);
|
||||
if (f != null) {
|
||||
Integer in = (Integer) f.get(null);
|
||||
return ctx.getString(in);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static String getRoutingStringPropertyName(Context ctx, String propertyName, String defValue) {
|
||||
try {
|
||||
Field f = R.string.class.getField("routing_attr_" + propertyName + "_name");
|
||||
|
|
|
@ -21,7 +21,6 @@ import com.google.android.material.bottomnavigation.BottomNavigationView;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.LatLon;
|
||||
|
@ -32,9 +31,7 @@ import net.osmand.plus.GpxSelectionHelper;
|
|||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.LockableViewPager;
|
||||
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
|
||||
import net.osmand.plus.measurementtool.GpxData;
|
||||
|
@ -44,6 +41,8 @@ import net.osmand.plus.myplaces.TrackBitmapDrawer;
|
|||
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
||||
import net.osmand.plus.myplaces.TrackPointFragment;
|
||||
import net.osmand.plus.myplaces.TrackSegmentFragment;
|
||||
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -136,14 +135,9 @@ public class TrackActivity extends TabActivity {
|
|||
}
|
||||
}
|
||||
|
||||
public void addNewGpxData(GpxData.ActionType actionType) {
|
||||
addNewGpxData(actionType, null);
|
||||
}
|
||||
|
||||
public void addNewGpxData(GpxData.ActionType actionType, TrkSegment segment) {
|
||||
public void addNewGpxData() {
|
||||
GPXFile gpxFile = getGpx();
|
||||
QuadRect rect = getRect();
|
||||
GpxData gpxData = new GpxData(gpxFile, rect, actionType, segment);
|
||||
GpxData gpxData = new GpxData(gpxFile);
|
||||
WptPt pointToShow = gpxFile != null ? gpxFile.findPointToShow() : null;
|
||||
if (pointToShow != null) {
|
||||
LatLon location = new LatLon(pointToShow.getLatitude(), pointToShow.getLongitude());
|
||||
|
@ -154,7 +148,6 @@ public class TrackActivity extends TabActivity {
|
|||
false,
|
||||
gpxData
|
||||
);
|
||||
|
||||
MapActivity.launchMapActivityMoveToTop(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
|
|||
|
||||
private LayerDrawable createBackgroundDrawable(@NonNull Context ctx, @DrawableRes int shadowDrawableResId) {
|
||||
Drawable shadowDrawable = ContextCompat.getDrawable(ctx, shadowDrawableResId);
|
||||
Drawable[] layers = new Drawable[] {shadowDrawable, getColoredBg(ctx)};
|
||||
Drawable[] layers = new Drawable[]{shadowDrawable, getColoredBg(ctx)};
|
||||
return new LayerDrawable(layers);
|
||||
}
|
||||
|
||||
|
@ -434,6 +434,21 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
|
|||
return !app.getSettings().isLightContent();
|
||||
}
|
||||
|
||||
private void showShadowButton() {
|
||||
buttonsShadow.setVisibility(View.VISIBLE);
|
||||
buttonsShadow.animate()
|
||||
.alpha(0.8f)
|
||||
.setDuration(200)
|
||||
.setListener(null);
|
||||
}
|
||||
|
||||
private void hideShadowButton() {
|
||||
buttonsShadow.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(200);
|
||||
|
||||
}
|
||||
|
||||
private void setupScrollShadow(View view) {
|
||||
final View scrollView;
|
||||
if (useScrollableItemsContainer()) {
|
||||
|
@ -446,7 +461,11 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
|
|||
@Override
|
||||
public void onScrollChanged() {
|
||||
boolean scrollToBottomAvailable = scrollView.canScrollVertically(1);
|
||||
AndroidUiHelper.updateVisibility(buttonsShadow, scrollToBottomAvailable);
|
||||
if (scrollToBottomAvailable) {
|
||||
showShadowButton();
|
||||
} else {
|
||||
hideShadowButton();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -670,7 +670,10 @@ public class ImportHelper {
|
|||
}
|
||||
fp.setAddress(p.getExtensionsToRead().get("address"));
|
||||
fp.setColor(p.getColor(0));
|
||||
fp.setIconIdFromName(app, p.getIconName());
|
||||
String iconName = p.getIconName();
|
||||
if (iconName != null) {
|
||||
fp.setIconIdFromName(app, iconName);
|
||||
}
|
||||
fp.setBackgroundType(BackgroundType.getByTypeName(p.getBackgroundType(), DEFAULT_BACKGROUND_TYPE));
|
||||
favourites.add(fp);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import net.osmand.plus.OsmandApplication;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.SettingsBaseActivity;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.ColorDialogs;
|
||||
|
@ -567,23 +568,6 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
|
|||
: R.color.inactive_buttons_and_links_bg_light)));
|
||||
}
|
||||
|
||||
private void createIconSelector() {
|
||||
iconCategories = new LinkedHashMap<>();
|
||||
try {
|
||||
JSONObject obj = new JSONObject(loadJSONFromAsset());
|
||||
JSONObject categories = obj.getJSONObject("categories");
|
||||
for (int i = 0; i < categories.length(); i++) {
|
||||
JSONArray names = categories.names();
|
||||
JSONObject icons = categories.getJSONObject(names.get(i).toString());
|
||||
iconCategories.put(names.get(i).toString(), icons.getJSONArray("icons"));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
selectedIconCategory = getInitCategory();
|
||||
createIconForCategory();
|
||||
}
|
||||
|
||||
private String getInitCategory() {
|
||||
for (int j = 0; j < iconCategories.values().size(); j++) {
|
||||
JSONArray iconJsonArray = (JSONArray) iconCategories.values().toArray()[j];
|
||||
|
@ -604,6 +588,25 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
|
|||
return app.getResources().getResourceEntryName(iconId).replaceFirst("mx_", "");
|
||||
}
|
||||
|
||||
private void createIconSelector() {
|
||||
iconCategories = new LinkedHashMap<>();
|
||||
try {
|
||||
JSONObject obj = new JSONObject(loadJSONFromAsset());
|
||||
JSONObject categories = obj.getJSONObject("categories");
|
||||
for (int i = 0; i < categories.length(); i++) {
|
||||
JSONArray names = categories.names();
|
||||
JSONObject icons = categories.getJSONObject(names.get(i).toString());
|
||||
String name = names.get(i).toString();
|
||||
String translatedName = SettingsBaseActivity.getIconStringPropertyName(app, name, name);
|
||||
iconCategories.put(translatedName, icons.getJSONArray("icons"));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
selectedIconCategory = getInitCategory();
|
||||
createIconForCategory();
|
||||
}
|
||||
|
||||
private void createIconForCategory() {
|
||||
FlowLayout selectIcon = view.findViewById(R.id.select_icon);
|
||||
selectIcon.removeAllViews();
|
||||
|
|
|
@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentActivity;
|
|||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.LocationsHolder;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
|
@ -27,11 +28,18 @@ import net.osmand.plus.activities.MapActivity;
|
|||
import net.osmand.plus.base.ContextMenuScrollFragment;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.routing.GpxApproximator;
|
||||
import net.osmand.plus.routing.GpxApproximator.GpxApproximationProgressCallback;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.plus.measurementtool.ProfileCard.ProfileCardListener;
|
||||
import static net.osmand.plus.measurementtool.SliderCard.SliderCardListener;
|
||||
|
||||
|
@ -49,8 +57,11 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
private ApplicationMode snapToRoadAppMode = ApplicationMode.CAR;
|
||||
private int distanceThreshold = 50;
|
||||
private boolean applyApproximation;
|
||||
private GpxApproximationProgressCallback approximationProgress;
|
||||
|
||||
private List<LocationsHolder> locationsHolders;
|
||||
private final Map<LocationsHolder, GpxRouteApproximation> resultMap = new HashMap<>();
|
||||
|
||||
private LocationsHolder locationsHolder;
|
||||
@Nullable
|
||||
private GpxApproximator gpxApproximator;
|
||||
private ProgressBar progressBar;
|
||||
|
@ -119,44 +130,26 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
distanceThreshold = savedInstanceState.getInt(DISTANCE_THRESHOLD_KEY);
|
||||
snapToRoadAppMode = ApplicationMode.valueOfStringKey(
|
||||
savedInstanceState.getString(SNAP_TO_ROAD_APP_MODE_STRING_KEY), ApplicationMode.CAR);
|
||||
try {
|
||||
gpxApproximator = new GpxApproximator(requireMyApplication(), snapToRoadAppMode, distanceThreshold, locationsHolder);
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
gpxApproximator = new GpxApproximator(requireMyApplication(), locationsHolder);
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (gpxApproximator != null) {
|
||||
gpxApproximator.setApproximationProgress(new GpxApproximator.GpxApproximationProgressCallback() {
|
||||
approximationProgress = new GpxApproximationProgressCallback() {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (isResumed()) {
|
||||
startProgress();
|
||||
public void start(GpxApproximator approximator) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(GpxApproximator approximator, int progress) {
|
||||
if (isResumed() && approximator == GpxApproximationFragment.this.gpxApproximator) {
|
||||
float partSize = 100f / locationsHolders.size();
|
||||
float p = resultMap.size() * partSize + (progress / 100f) * partSize;
|
||||
GpxApproximationFragment.this.updateProgress((int) p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(int progress) {
|
||||
if (isResumed()) {
|
||||
GpxApproximationFragment.this.updateProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
if (isResumed()) {
|
||||
finishProgress();
|
||||
}
|
||||
}
|
||||
});
|
||||
public void finish(GpxApproximator approximator) {
|
||||
}
|
||||
};
|
||||
|
||||
applyButton = mainView.findViewById(R.id.right_bottom_button);
|
||||
cancelButton = mainView.findViewById(R.id.dismiss_button);
|
||||
|
@ -180,7 +173,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
}
|
||||
runLayoutListener();
|
||||
|
||||
calculateGpxApproximation();
|
||||
calculateGpxApproximation(true);
|
||||
|
||||
return mainView;
|
||||
}
|
||||
|
@ -219,6 +212,20 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
}
|
||||
}
|
||||
|
||||
private GpxApproximator getNewGpxApproximator(@NonNull LocationsHolder locationsHolder) {
|
||||
GpxApproximator gpxApproximator = null;
|
||||
try {
|
||||
OsmandApplication app = getMyApplication();
|
||||
if (app != null) {
|
||||
gpxApproximator = new GpxApproximator(app, snapToRoadAppMode, distanceThreshold, locationsHolder);
|
||||
gpxApproximator.setApproximationProgress(approximationProgress);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
return gpxApproximator;
|
||||
}
|
||||
|
||||
private void updateCardsLayout() {
|
||||
View mainView = getMainView();
|
||||
if (mainView != null) {
|
||||
|
@ -299,13 +306,17 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
}
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fm, @Nullable Fragment targetFragment,
|
||||
@NonNull LocationsHolder locationsHolder, @Nullable ApplicationMode appMode) {
|
||||
@NonNull List<List<WptPt>> pointsList, @Nullable ApplicationMode appMode) {
|
||||
try {
|
||||
if (!fm.isStateSaved()) {
|
||||
GpxApproximationFragment fragment = new GpxApproximationFragment();
|
||||
fragment.setRetainInstance(true);
|
||||
fragment.setTargetFragment(targetFragment, REQUEST_CODE);
|
||||
fragment.setLocationsHolder(locationsHolder);
|
||||
List<LocationsHolder> locationsHolders = new ArrayList<>();
|
||||
for (List<WptPt> points : pointsList) {
|
||||
locationsHolders.add(new LocationsHolder(points));
|
||||
}
|
||||
fragment.setLocationsHolders(locationsHolders);
|
||||
fragment.setSnapToRoadAppMode(appMode);
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, fragment, TAG)
|
||||
|
@ -328,30 +339,48 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
}
|
||||
}
|
||||
|
||||
public void calculateGpxApproximation() {
|
||||
public boolean calculateGpxApproximation(boolean newCalculation) {
|
||||
if (newCalculation) {
|
||||
if (gpxApproximator != null) {
|
||||
gpxApproximator.cancelApproximation();
|
||||
gpxApproximator = null;
|
||||
}
|
||||
resultMap.clear();
|
||||
startProgress();
|
||||
}
|
||||
GpxApproximator gpxApproximator = null;
|
||||
for (LocationsHolder locationsHolder : locationsHolders) {
|
||||
if (!resultMap.containsKey(locationsHolder)) {
|
||||
gpxApproximator = getNewGpxApproximator(locationsHolder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gpxApproximator != null) {
|
||||
try {
|
||||
this.gpxApproximator = gpxApproximator;
|
||||
gpxApproximator.setMode(snapToRoadAppMode);
|
||||
gpxApproximator.setPointApproximation(distanceThreshold);
|
||||
approximateGpx();
|
||||
approximateGpx(gpxApproximator);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderChange(int sliderValue) {
|
||||
if (distanceThreshold != sliderValue) {
|
||||
distanceThreshold = sliderValue;
|
||||
calculateGpxApproximation();
|
||||
calculateGpxApproximation(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProfileSelect(ApplicationMode applicationMode) {
|
||||
if (setSnapToRoadAppMode(applicationMode)) {
|
||||
calculateGpxApproximation();
|
||||
calculateGpxApproximation(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,12 +392,12 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
return false;
|
||||
}
|
||||
|
||||
public LocationsHolder getLocationsHolder() {
|
||||
return locationsHolder;
|
||||
public List<LocationsHolder> getLocationsHolders() {
|
||||
return locationsHolders;
|
||||
}
|
||||
|
||||
public void setLocationsHolder(LocationsHolder locationsHolder) {
|
||||
this.locationsHolder = locationsHolder;
|
||||
public void setLocationsHolders(List<LocationsHolder> locationsHolders) {
|
||||
this.locationsHolders = locationsHolders;
|
||||
}
|
||||
|
||||
public void startProgress() {
|
||||
|
@ -393,9 +422,8 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
}
|
||||
}
|
||||
|
||||
private void approximateGpx() {
|
||||
if (gpxApproximator != null) {
|
||||
setApplyButtonEnabled(false);
|
||||
private void approximateGpx(@NonNull final GpxApproximator gpxApproximator) {
|
||||
onApproximationStarted();
|
||||
gpxApproximator.calculateGpxApproximation(new ResultMatcher<GpxRouteApproximation>() {
|
||||
@Override
|
||||
public boolean publish(final GpxRouteApproximation gpxApproximation) {
|
||||
|
@ -404,16 +432,18 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof GpxApproximationFragmentListener) {
|
||||
((GpxApproximationFragmentListener) fragment).onGpxApproximationDone(gpxApproximation, gpxApproximator.getMode());
|
||||
if (!gpxApproximator.isCancelled()) {
|
||||
if (gpxApproximation != null) {
|
||||
resultMap.put(gpxApproximator.getLocationsHolder(), gpxApproximation);
|
||||
}
|
||||
if (!calculateGpxApproximation(false)) {
|
||||
onApproximationFinished();
|
||||
}
|
||||
}
|
||||
setApplyButtonEnabled(gpxApproximation != null);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -422,6 +452,28 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onApproximationStarted() {
|
||||
setApplyButtonEnabled(false);
|
||||
}
|
||||
|
||||
private void onApproximationFinished() {
|
||||
finishProgress();
|
||||
Fragment fragment = getTargetFragment();
|
||||
List<GpxRouteApproximation> approximations = new ArrayList<>();
|
||||
List<List<WptPt>> points = new ArrayList<>();
|
||||
for (LocationsHolder locationsHolder : locationsHolders) {
|
||||
GpxRouteApproximation approximation = resultMap.get(locationsHolder);
|
||||
if (approximation != null) {
|
||||
approximations.add(approximation);
|
||||
points.add(locationsHolder.getWptPtList());
|
||||
}
|
||||
}
|
||||
if (fragment instanceof GpxApproximationFragmentListener) {
|
||||
((GpxApproximationFragmentListener) fragment).onGpxApproximationDone(
|
||||
approximations, points, snapToRoadAppMode);
|
||||
}
|
||||
setApplyButtonEnabled(!approximations.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -431,7 +483,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
|
|||
|
||||
public interface GpxApproximationFragmentListener {
|
||||
|
||||
void onGpxApproximationDone(GpxRouteApproximation gpxApproximation, ApplicationMode mode);
|
||||
void onGpxApproximationDone(List<GpxRouteApproximation> gpxApproximations, List<List<WptPt>> pointsList, ApplicationMode mode);
|
||||
|
||||
void onApplyGpxApproximation();
|
||||
|
||||
|
|
|
@ -1,35 +1,20 @@
|
|||
package net.osmand.plus.measurementtool;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.data.QuadRect;
|
||||
|
||||
public class GpxData {
|
||||
|
||||
public enum ActionType {
|
||||
ADD_SEGMENT,
|
||||
ADD_ROUTE_POINTS,
|
||||
EDIT_SEGMENT,
|
||||
OVERWRITE_SEGMENT
|
||||
}
|
||||
private final GPXFile gpxFile;
|
||||
private final QuadRect rect;
|
||||
|
||||
private GPXFile gpxFile;
|
||||
private TrkSegment trkSegment;
|
||||
private QuadRect rect;
|
||||
private ActionType actionType;
|
||||
|
||||
public GpxData(GPXFile gpxFile, QuadRect rect, ActionType actionType, TrkSegment trkSegment) {
|
||||
public GpxData(GPXFile gpxFile) {
|
||||
this.gpxFile = gpxFile;
|
||||
this.rect = rect;
|
||||
this.actionType = actionType;
|
||||
this.trkSegment = trkSegment;
|
||||
if (gpxFile != null) {
|
||||
this.rect = gpxFile.getRect();
|
||||
} else {
|
||||
this.rect = new QuadRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public GpxData(GPXFile gpxFile, GpxData gpxData) {
|
||||
this.gpxFile = gpxFile;
|
||||
this.rect = gpxData.rect;
|
||||
this.actionType = gpxData.actionType;
|
||||
this.trkSegment = gpxData.trkSegment;
|
||||
}
|
||||
|
||||
public GPXFile getGpxFile() {
|
||||
|
@ -39,12 +24,4 @@ public class GpxData {
|
|||
public QuadRect getRect() {
|
||||
return rect;
|
||||
}
|
||||
|
||||
public ActionType getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
public TrkSegment getTrkSegment() {
|
||||
return trkSegment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -341,7 +341,7 @@ public class GraphsCard extends BaseCard implements OnUpdateAdditionalInfoListen
|
|||
if (editingCtx.getGpxData() != null) {
|
||||
gpx = editingCtx.getGpxData().getGpxFile();
|
||||
} else {
|
||||
gpx = editingCtx.exportRouteAsGpx(GRAPH_DATA_GPX_FILE_NAME);
|
||||
gpx = editingCtx.exportGpx(GRAPH_DATA_GPX_FILE_NAME);
|
||||
}
|
||||
return gpx != null ? gpx.getAnalysis(0) : null;
|
||||
}
|
||||
|
|
|
@ -53,9 +53,11 @@ public class MeasurementEditingContext {
|
|||
private final MeasurementCommandManager commandManager = new MeasurementCommandManager();
|
||||
|
||||
private final TrkSegment before = new TrkSegment();
|
||||
private TrkSegment beforeCacheForSnap;
|
||||
private List<TrkSegment> beforeSegments = new ArrayList<>();
|
||||
private List<TrkSegment> beforeSegmentsForSnap;
|
||||
private final TrkSegment after = new TrkSegment();
|
||||
private TrkSegment afterCacheForSnap;
|
||||
private List<TrkSegment> afterSegments = new ArrayList<>();
|
||||
private List<TrkSegment> afterSegmentsForSnap;
|
||||
|
||||
private GpxData gpxData;
|
||||
|
||||
|
@ -63,6 +65,7 @@ public class MeasurementEditingContext {
|
|||
private WptPt originalPointToMove;
|
||||
|
||||
private boolean inAddPointMode;
|
||||
private boolean inAddPointBeforeMode;
|
||||
private boolean inApproximationMode;
|
||||
private int calculatedPairs;
|
||||
private int pointsToCalculateSize;
|
||||
|
@ -72,18 +75,23 @@ public class MeasurementEditingContext {
|
|||
private RouteCalculationProgress calculationProgress;
|
||||
private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public enum CalculationMode {
|
||||
NEXT_SEGMENT,
|
||||
WHOLE_TRACK
|
||||
}
|
||||
|
||||
public enum AdditionMode {
|
||||
UNDEFINED,
|
||||
ADD_AFTER,
|
||||
ADD_BEFORE,
|
||||
}
|
||||
|
||||
public static class RoadSegmentData {
|
||||
private ApplicationMode appMode;
|
||||
private WptPt start;
|
||||
private WptPt end;
|
||||
private List<WptPt> points;
|
||||
private List<RouteSegmentResult> segments;
|
||||
private final ApplicationMode appMode;
|
||||
private final WptPt start;
|
||||
private final WptPt end;
|
||||
private final List<WptPt> points;
|
||||
private final List<RouteSegmentResult> segments;
|
||||
private double distance;
|
||||
|
||||
public RoadSegmentData(@NonNull ApplicationMode appMode, @NonNull WptPt start, @NonNull WptPt end,
|
||||
|
@ -156,8 +164,12 @@ public class MeasurementEditingContext {
|
|||
return inAddPointMode;
|
||||
}
|
||||
|
||||
public void updateCacheForSnap() {
|
||||
updateCacheForSnap(true);
|
||||
public boolean isInAddPointBeforeMode() {
|
||||
return inAddPointBeforeMode;
|
||||
}
|
||||
|
||||
public void updateSegmentsForSnap() {
|
||||
updateSegmentsForSnap(true);
|
||||
}
|
||||
|
||||
public int getSelectedPointPosition() {
|
||||
|
@ -176,8 +188,9 @@ public class MeasurementEditingContext {
|
|||
this.originalPointToMove = originalPointToMove;
|
||||
}
|
||||
|
||||
void setInAddPointMode(boolean inAddPointMode) {
|
||||
void setInAddPointMode(boolean inAddPointMode, boolean inAddPointAfterMode) {
|
||||
this.inAddPointMode = inAddPointMode;
|
||||
this.inAddPointBeforeMode = inAddPointAfterMode;
|
||||
}
|
||||
|
||||
public boolean isInApproximationMode() {
|
||||
|
@ -188,10 +201,10 @@ public class MeasurementEditingContext {
|
|||
this.inApproximationMode = inApproximationMode;
|
||||
}
|
||||
|
||||
public List<WptPt> getOriginalTrackPointList() {
|
||||
public List<List<WptPt>> getOriginalSegmentPointsList() {
|
||||
MeasurementModeCommand command = commandManager.getLastCommand();
|
||||
if (command.getType() == APPROXIMATE_POINTS) {
|
||||
return ((ApplyGpxApproximationCommand) command).getPoints();
|
||||
return ((ApplyGpxApproximationCommand) command).getOriginalSegmentPointsList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -213,10 +226,6 @@ public class MeasurementEditingContext {
|
|||
return gpxData != null && gpxData.getGpxFile() != null && gpxData.getGpxFile().hasRtePt();
|
||||
}
|
||||
|
||||
public boolean hasSavedRoute() {
|
||||
return gpxData != null && gpxData.getGpxFile() != null && gpxData.getGpxFile().hasRoute();
|
||||
}
|
||||
|
||||
public CalculationMode getLastCalculationMode() {
|
||||
return lastCalculationMode;
|
||||
}
|
||||
|
@ -252,7 +261,7 @@ public class MeasurementEditingContext {
|
|||
if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE || !pair.first.lastPoint || !pair.second.firstPoint) {
|
||||
double localDist = MapUtils.getDistance(pair.first.getLatitude(), pair.first.getLongitude(),
|
||||
pair.second.getLatitude(), pair.second.getLongitude());
|
||||
if(!Double.isNaN(pair.first.ele) && !Double.isNaN(pair.second.ele) &&
|
||||
if (!Double.isNaN(pair.first.ele) && !Double.isNaN(pair.second.ele) &&
|
||||
pair.first.ele != 0 && pair.second.ele != 0) {
|
||||
double h = Math.abs(pair.first.ele - pair.second.ele);
|
||||
localDist = Math.sqrt(localDist * localDist + h * h);
|
||||
|
@ -279,28 +288,104 @@ public class MeasurementEditingContext {
|
|||
return !roadSegmentData.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isApproximationNeeded() {
|
||||
boolean hasDefaultPoints = false;
|
||||
boolean newData = isNewData();
|
||||
if (!newData) {
|
||||
List<WptPt> points = getPoints();
|
||||
WptPt prevPoint = null;
|
||||
for (WptPt point : points) {
|
||||
if (!point.hasProfile() && (prevPoint == null || !prevPoint.hasProfile())) {
|
||||
hasDefaultPoints = true;
|
||||
break;
|
||||
}
|
||||
prevPoint = point;
|
||||
}
|
||||
}
|
||||
return !newData && hasDefaultPoints && getPoints().size() > 2;
|
||||
}
|
||||
|
||||
public boolean isSelectionNeedApproximation() {
|
||||
boolean hasDefaultPoints = false;
|
||||
boolean newData = isNewData();
|
||||
if (!newData && selectedPointPosition != -1) {
|
||||
WptPt selectedPoint = getPoints().get(selectedPointPosition);
|
||||
List<TrkSegment> segments = getBeforeSegments();
|
||||
List<WptPt> points = null;
|
||||
for (TrkSegment segment : segments) {
|
||||
if (segment.points.contains(selectedPoint)) {
|
||||
points = segment.points;
|
||||
}
|
||||
}
|
||||
WptPt prevPoint = null;
|
||||
if (points != null) {
|
||||
for (WptPt point : points) {
|
||||
if (!point.hasProfile() && (prevPoint == null || !prevPoint.hasProfile())) {
|
||||
hasDefaultPoints = true;
|
||||
break;
|
||||
}
|
||||
prevPoint = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !newData && hasDefaultPoints && getPoints().size() > 2;
|
||||
}
|
||||
|
||||
public void clearSnappedToRoadPoints() {
|
||||
roadSegmentData.clear();
|
||||
}
|
||||
|
||||
TrkSegment getBeforeTrkSegmentLine() {
|
||||
if (beforeCacheForSnap != null) {
|
||||
return beforeCacheForSnap;
|
||||
List<TrkSegment> getBeforeTrkSegmentLine() {
|
||||
if (beforeSegmentsForSnap != null) {
|
||||
return beforeSegmentsForSnap;
|
||||
}
|
||||
return before;
|
||||
return beforeSegments;
|
||||
}
|
||||
|
||||
TrkSegment getAfterTrkSegmentLine() {
|
||||
if (afterCacheForSnap != null) {
|
||||
return afterCacheForSnap;
|
||||
List<TrkSegment> getAfterTrkSegmentLine() {
|
||||
if (afterSegmentsForSnap != null) {
|
||||
return afterSegmentsForSnap;
|
||||
}
|
||||
return after;
|
||||
return afterSegments;
|
||||
}
|
||||
|
||||
public List<TrkSegment> getBeforeSegments() {
|
||||
return beforeSegments;
|
||||
}
|
||||
|
||||
public List<TrkSegment> getAfterSegments() {
|
||||
return afterSegments;
|
||||
}
|
||||
|
||||
public List<WptPt> getPoints() {
|
||||
return getBeforePoints();
|
||||
}
|
||||
|
||||
public List<List<WptPt>> getPointsSegments(boolean plain, boolean route) {
|
||||
List<List<WptPt>> res = new ArrayList<>();
|
||||
List<WptPt> allPoints = getPoints();
|
||||
List<WptPt> segment = new ArrayList<>();
|
||||
String prevProfileType = null;
|
||||
for (WptPt point : allPoints) {
|
||||
String profileType = point.getProfileType();
|
||||
boolean isGap = point.isGap();
|
||||
boolean plainPoint = Algorithms.isEmpty(profileType) || (isGap && Algorithms.isEmpty(prevProfileType));
|
||||
boolean routePoint = !plainPoint;
|
||||
if (plain && plainPoint || route && routePoint) {
|
||||
segment.add(point);
|
||||
if (isGap) {
|
||||
res.add(segment);
|
||||
segment = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
prevProfileType = profileType;
|
||||
}
|
||||
if (!segment.isEmpty()) {
|
||||
res.add(segment);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
List<WptPt> getBeforePoints() {
|
||||
return before.points;
|
||||
}
|
||||
|
@ -335,31 +420,118 @@ public class MeasurementEditingContext {
|
|||
after.points.clear();
|
||||
before.points.addAll(points.subList(0, position));
|
||||
after.points.addAll(points.subList(position, points.size()));
|
||||
updateCacheForSnap(true);
|
||||
updateSegmentsForSnap(true);
|
||||
}
|
||||
|
||||
private void preAddPoint(int position, AdditionMode additionMode, WptPt point) {
|
||||
switch (additionMode) {
|
||||
case UNDEFINED: {
|
||||
if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
point.setProfileType(appMode.getStringKey());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ADD_AFTER: {
|
||||
List<WptPt> points = getBeforePoints();
|
||||
if (position > 0 && position <= points.size()) {
|
||||
WptPt prevPt = points.get(position - 1);
|
||||
if (prevPt.isGap()) {
|
||||
point.setGap();
|
||||
if (position > 1) {
|
||||
WptPt pt = points.get(position - 2);
|
||||
if (pt.hasProfile()) {
|
||||
prevPt.setProfileType(pt.getProfileType());
|
||||
} else {
|
||||
prevPt.removeProfileType();
|
||||
}
|
||||
}
|
||||
} else if (prevPt.hasProfile()) {
|
||||
point.setProfileType(prevPt.getProfileType());
|
||||
}
|
||||
} else if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
point.setProfileType(appMode.getStringKey());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ADD_BEFORE: {
|
||||
List<WptPt> points = getAfterPoints();
|
||||
if (position >= -1 && position + 1 < points.size()) {
|
||||
WptPt nextPt = points.get(position + 1);
|
||||
if (nextPt.hasProfile()) {
|
||||
point.setProfileType(nextPt.getProfileType());
|
||||
}
|
||||
} else if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
point.setProfileType(appMode.getStringKey());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addPoint(WptPt pt) {
|
||||
addPoint(pt, AdditionMode.UNDEFINED);
|
||||
}
|
||||
|
||||
public void addPoint(WptPt pt, AdditionMode additionMode) {
|
||||
if (additionMode == AdditionMode.ADD_AFTER || additionMode == AdditionMode.ADD_BEFORE) {
|
||||
preAddPoint(additionMode == AdditionMode.ADD_BEFORE ? -1 : getBeforePoints().size(), additionMode, pt);
|
||||
}
|
||||
before.points.add(pt);
|
||||
updateCacheForSnap(false);
|
||||
updateSegmentsForSnap(false);
|
||||
}
|
||||
|
||||
public void addPoint(int position, WptPt pt) {
|
||||
addPoint(position, pt, AdditionMode.UNDEFINED);
|
||||
}
|
||||
|
||||
public void addPoint(int position, WptPt pt, AdditionMode additionMode) {
|
||||
if (additionMode == AdditionMode.ADD_AFTER || additionMode == AdditionMode.ADD_BEFORE) {
|
||||
preAddPoint(position, additionMode, pt);
|
||||
}
|
||||
before.points.add(position, pt);
|
||||
updateCacheForSnap(false);
|
||||
updateSegmentsForSnap(false);
|
||||
}
|
||||
|
||||
public void addPoints(List<WptPt> points) {
|
||||
before.points.addAll(points);
|
||||
updateCacheForSnap(false);
|
||||
updateSegmentsForSnap(false);
|
||||
}
|
||||
|
||||
public void replacePoints(List<WptPt> originalPoints, List<WptPt> points) {
|
||||
if (originalPoints.size() > 1) {
|
||||
int firstPointIndex = before.points.indexOf(originalPoints.get(0));
|
||||
int lastPointIndex = before.points.indexOf(originalPoints.get(originalPoints.size() - 1));
|
||||
List<WptPt> newPoints = new ArrayList<>();
|
||||
if (firstPointIndex != -1 && lastPointIndex != -1) {
|
||||
newPoints.addAll(before.points.subList(0, firstPointIndex));
|
||||
newPoints.addAll(points);
|
||||
if (before.points.size() > lastPointIndex + 1) {
|
||||
newPoints.addAll(before.points.subList(lastPointIndex + 1, before.points.size()));
|
||||
}
|
||||
} else {
|
||||
newPoints.addAll(points);
|
||||
}
|
||||
before.points = newPoints;
|
||||
} else {
|
||||
before.points = points;
|
||||
}
|
||||
updateSegmentsForSnap(false);
|
||||
}
|
||||
|
||||
public WptPt removePoint(int position, boolean updateSnapToRoad) {
|
||||
if (position < 0 || position >= before.points.size()) {
|
||||
return new WptPt();
|
||||
}
|
||||
WptPt pt = before.points.remove(position);
|
||||
WptPt pt = before.points.get(position);
|
||||
if (position > 0 && pt.isGap()) {
|
||||
WptPt prevPt = before.points.get(position - 1);
|
||||
if (!prevPt.isGap()) {
|
||||
prevPt.setGap();
|
||||
}
|
||||
}
|
||||
before.points.remove(position);
|
||||
if (updateSnapToRoad) {
|
||||
updateCacheForSnap(false);
|
||||
updateSegmentsForSnap(false);
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
@ -382,24 +554,40 @@ public class MeasurementEditingContext {
|
|||
|
||||
public void clearBeforeSegments() {
|
||||
before.points.clear();
|
||||
if (beforeCacheForSnap != null) {
|
||||
beforeCacheForSnap.points.clear();
|
||||
if (beforeSegmentsForSnap != null) {
|
||||
beforeSegmentsForSnap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAfterSegments() {
|
||||
after.points.clear();
|
||||
if (afterCacheForSnap != null) {
|
||||
afterCacheForSnap.points.clear();
|
||||
if (afterSegmentsForSnap != null) {
|
||||
afterSegmentsForSnap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFirstPointSelected() {
|
||||
return selectedPointPosition == 0;
|
||||
return isBorderPointSelected(true);
|
||||
}
|
||||
|
||||
public boolean isLastPointSelected() {
|
||||
return selectedPointPosition == getPoints().size() - 1;
|
||||
return isBorderPointSelected(false);
|
||||
}
|
||||
|
||||
private boolean isBorderPointSelected(boolean first) {
|
||||
WptPt selectedPoint = getPoints().get(selectedPointPosition);
|
||||
List<TrkSegment> segments = getBeforeSegments();
|
||||
int count = 0;
|
||||
for (TrkSegment segment : segments) {
|
||||
int i = segment.points.indexOf(selectedPoint);
|
||||
if (i != -1) {
|
||||
int segmentPosition = selectedPointPosition - count;
|
||||
return first ? segmentPosition == 0 : segmentPosition == segment.points.size() - 1;
|
||||
} else {
|
||||
count += segment.points.size();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ApplicationMode getSelectedPointAppMode() {
|
||||
|
@ -438,8 +626,10 @@ public class MeasurementEditingContext {
|
|||
List<Pair<WptPt, WptPt>> res = new ArrayList<>();
|
||||
for (List<WptPt> points : Arrays.asList(before.points, after.points)) {
|
||||
for (int i = 0; i < points.size() - 1; i++) {
|
||||
Pair<WptPt, WptPt> pair = new Pair<>(points.get(i), points.get(i + 1));
|
||||
if (roadSegmentData.get(pair) == null) {
|
||||
WptPt startPoint = points.get(i);
|
||||
WptPt endPoint = points.get(i + 1);
|
||||
Pair<WptPt, WptPt> pair = new Pair<>(startPoint, endPoint);
|
||||
if (roadSegmentData.get(pair) == null && startPoint.hasProfile()) {
|
||||
res.add(pair);
|
||||
}
|
||||
}
|
||||
|
@ -457,46 +647,82 @@ public class MeasurementEditingContext {
|
|||
return keys;
|
||||
}
|
||||
|
||||
private void recreateCacheForSnap(TrkSegment cache, TrkSegment original, boolean calculateIfNeeded) {
|
||||
boolean hasDefaultModeOnly = true;
|
||||
if (original.points.size() > 1) {
|
||||
for (int i = 0; i < original.points.size(); i++) {
|
||||
String profileType = original.points.get(i).getProfileType();
|
||||
if (profileType != null && !profileType.equals(DEFAULT_APP_MODE.getStringKey())) {
|
||||
hasDefaultModeOnly = false;
|
||||
break;
|
||||
private void recreateSegments(List<TrkSegment> segments, List<TrkSegment> segmentsForSnap, List<WptPt> points, boolean calculateIfNeeded) {
|
||||
List<Integer> roadSegmentIndexes = new ArrayList<>();
|
||||
TrkSegment s = new TrkSegment();
|
||||
segments.add(s);
|
||||
boolean defaultMode = true;
|
||||
if (points.size() > 1) {
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
WptPt point = points.get(i);
|
||||
s.points.add(point);
|
||||
String profileType = point.getProfileType();
|
||||
if (profileType != null) {
|
||||
boolean isDefault = profileType.equals(DEFAULT_APP_MODE.getStringKey());
|
||||
boolean isGap = point.isGap();
|
||||
if (defaultMode && !isDefault && !isGap) {
|
||||
roadSegmentIndexes.add(segments.size() - 1);
|
||||
defaultMode = false;
|
||||
}
|
||||
if (isGap) {
|
||||
if (!s.points.isEmpty()) {
|
||||
s = new TrkSegment();
|
||||
segments.add(s);
|
||||
defaultMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (original.points.size() > 1) {
|
||||
for (int i = 0; i < original.points.size() - 1; i++) {
|
||||
Pair<WptPt, WptPt> pair = new Pair<>(original.points.get(i), original.points.get(i + 1));
|
||||
}
|
||||
} else {
|
||||
s.points.addAll(points);
|
||||
}
|
||||
if (s.points.isEmpty()) {
|
||||
segments.remove(s);
|
||||
}
|
||||
if (!segments.isEmpty()) {
|
||||
for (TrkSegment segment : segments) {
|
||||
TrkSegment segmentForSnap = new TrkSegment();
|
||||
for (int i = 0; i < segment.points.size() - 1; i++) {
|
||||
Pair<WptPt, WptPt> pair = new Pair<>(segment.points.get(i), segment.points.get(i + 1));
|
||||
RoadSegmentData data = this.roadSegmentData.get(pair);
|
||||
List<WptPt> pts = data != null ? data.getPoints() : null;
|
||||
if (pts != null) {
|
||||
cache.points.addAll(pts);
|
||||
segmentForSnap.points.addAll(pts);
|
||||
} else {
|
||||
if (calculateIfNeeded && !hasDefaultModeOnly) {
|
||||
if (calculateIfNeeded && roadSegmentIndexes.contains(segmentsForSnap.size())) {
|
||||
scheduleRouteCalculateIfNotEmpty();
|
||||
}
|
||||
cache.points.addAll(Arrays.asList(pair.first, pair.second));
|
||||
segmentForSnap.points.addAll(Arrays.asList(pair.first, pair.second));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cache.points.addAll(original.points);
|
||||
if (segmentForSnap.points.isEmpty()) {
|
||||
segmentForSnap.points.addAll(segment.points);
|
||||
}
|
||||
segmentsForSnap.add(segmentForSnap);
|
||||
}
|
||||
} else if (!points.isEmpty()) {
|
||||
TrkSegment segmentForSnap = new TrkSegment();
|
||||
segmentForSnap.points.addAll(points);
|
||||
segmentsForSnap.add(segmentForSnap);
|
||||
}
|
||||
}
|
||||
|
||||
void addPoints() {
|
||||
GpxData gpxData = getGpxData();
|
||||
if (gpxData == null || gpxData.getTrkSegment() == null || Algorithms.isEmpty(gpxData.getTrkSegment().points)) {
|
||||
if (gpxData == null || gpxData.getGpxFile() == null) {
|
||||
return;
|
||||
}
|
||||
List<WptPt> points = gpxData.getTrkSegment().points;
|
||||
if (isTrackSnappedToRoad()) {
|
||||
RouteImporter routeImporter = new RouteImporter(gpxData.getGpxFile());
|
||||
List<RouteSegmentResult> segments = routeImporter.importRoute();
|
||||
List<WptPt> routePoints = gpxData.getGpxFile().getRoutePoints();
|
||||
List<TrkSegment> segments = gpxData.getGpxFile().getNonEmptyTrkSegments(false);
|
||||
if (Algorithms.isEmpty(segments)) {
|
||||
return;
|
||||
}
|
||||
for (int si = 0; si < segments.size(); si++) {
|
||||
TrkSegment segment = segments.get(si);
|
||||
List<WptPt> points = segment.points;
|
||||
if (segment.hasRoute()) {
|
||||
RouteImporter routeImporter = new RouteImporter(segment);
|
||||
List<RouteSegmentResult> routeSegments = routeImporter.importRoute();
|
||||
List<WptPt> routePoints = gpxData.getGpxFile().getRoutePoints(si);
|
||||
int prevPointIndex = 0;
|
||||
if (routePoints.isEmpty() && points.size() > 1) {
|
||||
routePoints.add(points.get(0));
|
||||
|
@ -521,11 +747,11 @@ public class MeasurementEditingContext {
|
|||
if (points.size() > prevPointIndex + 1) {
|
||||
pairPoints.add(points.get(prevPointIndex + 1));
|
||||
}
|
||||
Iterator<RouteSegmentResult> it = segments.iterator();
|
||||
Iterator<RouteSegmentResult> it = routeSegments.iterator();
|
||||
int k = endIndex - startIndex - 1;
|
||||
List<RouteSegmentResult> pairSegments = new ArrayList<>();
|
||||
if (k == 0 && !segments.isEmpty()) {
|
||||
pairSegments.add(segments.remove(0));
|
||||
if (k == 0 && !routeSegments.isEmpty()) {
|
||||
pairSegments.add(routeSegments.remove(0));
|
||||
} else {
|
||||
while (it.hasNext() && k > 0) {
|
||||
RouteSegmentResult s = it.next();
|
||||
|
@ -538,17 +764,23 @@ public class MeasurementEditingContext {
|
|||
roadSegmentData.put(pair, new RoadSegmentData(appMode, pair.first, pair.second, pairPoints, pairSegments));
|
||||
}
|
||||
}
|
||||
if (!routePoints.isEmpty() && si < segments.size() - 1) {
|
||||
routePoints.get(routePoints.size() - 1).setGap();
|
||||
}
|
||||
addPoints(routePoints);
|
||||
} else {
|
||||
addPoints(points);
|
||||
if (!points.isEmpty() && si < segments.size() - 1) {
|
||||
points.get(points.size() - 1).setGap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPoints(GpxRouteApproximation gpxApproximation, ApplicationMode mode) {
|
||||
public List<WptPt> setPoints(GpxRouteApproximation gpxApproximation, List<WptPt> originalPoints, ApplicationMode mode) {
|
||||
if (gpxApproximation == null || Algorithms.isEmpty(gpxApproximation.finalPoints) || Algorithms.isEmpty(gpxApproximation.result)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
roadSegmentData.clear();
|
||||
List<WptPt> routePoints = new ArrayList<>();
|
||||
List<GpxPoint> gpxPoints = gpxApproximation.finalPoints;
|
||||
for (int i = 0; i < gpxPoints.size(); i++) {
|
||||
|
@ -590,7 +822,13 @@ public class MeasurementEditingContext {
|
|||
break;
|
||||
}
|
||||
}
|
||||
addPoints(routePoints);
|
||||
WptPt lastOriginalPoint = originalPoints.get(originalPoints.size() - 1);
|
||||
WptPt lastRoutePoint = routePoints.get(routePoints.size() - 1);
|
||||
if (lastOriginalPoint.isGap()) {
|
||||
lastRoutePoint.setGap();
|
||||
}
|
||||
replacePoints(originalPoints, routePoints);
|
||||
return routePoints;
|
||||
}
|
||||
|
||||
private boolean isLastGpxPoint(List<GpxPoint> gpxPoints, int index) {
|
||||
|
@ -648,24 +886,21 @@ public class MeasurementEditingContext {
|
|||
return index;
|
||||
}
|
||||
|
||||
boolean isTrackSnappedToRoad() {
|
||||
GpxData gpxData = getGpxData();
|
||||
return gpxData != null && gpxData.getTrkSegment() != null
|
||||
&& !gpxData.getTrkSegment().points.isEmpty()
|
||||
&& gpxData.getGpxFile().hasRoute();
|
||||
}
|
||||
|
||||
private void updateCacheForSnap(boolean both) {
|
||||
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before, true);
|
||||
private void updateSegmentsForSnap(boolean both) {
|
||||
recreateSegments(beforeSegments = new ArrayList<>(),
|
||||
beforeSegmentsForSnap = new ArrayList<>(), before.points, true);
|
||||
if (both) {
|
||||
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after, true);
|
||||
recreateSegments(afterSegments = new ArrayList<>(),
|
||||
afterSegmentsForSnap = new ArrayList<>(), after.points, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCacheForSnap(boolean both, boolean calculateIfNeeded) {
|
||||
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before, calculateIfNeeded);
|
||||
private void updateSegmentsForSnap(boolean both, boolean calculateIfNeeded) {
|
||||
recreateSegments(beforeSegments = new ArrayList<>(),
|
||||
beforeSegmentsForSnap = new ArrayList<>(), before.points, calculateIfNeeded);
|
||||
if (both) {
|
||||
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after, calculateIfNeeded);
|
||||
recreateSegments(afterSegments = new ArrayList<>(),
|
||||
afterSegmentsForSnap = new ArrayList<>(), after.points, calculateIfNeeded);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,7 +953,7 @@ public class MeasurementEditingContext {
|
|||
int pairs = pointsToCalculateSize;
|
||||
if (pairs != 0) {
|
||||
float pairProgress = 100f / pairs;
|
||||
progress = (int)(calculatedPairs * pairProgress + (float) progress / pairs);
|
||||
progress = (int) (calculatedPairs * pairProgress + (float) progress / pairs);
|
||||
}
|
||||
progressListener.updateProgress(progress);
|
||||
}
|
||||
|
@ -762,7 +997,7 @@ public class MeasurementEditingContext {
|
|||
application.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateCacheForSnap(true, false);
|
||||
updateSegmentsForSnap(true, false);
|
||||
progressListener.refresh();
|
||||
RouteCalculationParams params = getParams(false);
|
||||
if (params != null) {
|
||||
|
@ -777,34 +1012,41 @@ public class MeasurementEditingContext {
|
|||
return params;
|
||||
}
|
||||
|
||||
public List<WptPt> getRoutePoints() {
|
||||
List<WptPt> res = new ArrayList<>();
|
||||
List<WptPt> points = new ArrayList<>(before.points);
|
||||
points.addAll(after.points);
|
||||
int size = points.size();
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
Pair<WptPt, WptPt> pair = new Pair<>(points.get(i), points.get(i + 1));
|
||||
RoadSegmentData data = this.roadSegmentData.get(pair);
|
||||
if (data != null) {
|
||||
res.addAll(data.points);
|
||||
public List<List<WptPt>> getRoutePoints() {
|
||||
List<List<WptPt>> res = new ArrayList<>();
|
||||
List<WptPt> plainPoints = new ArrayList<>(before.points);
|
||||
plainPoints.addAll(after.points);
|
||||
List<WptPt> points = new ArrayList<>();
|
||||
for (WptPt point : plainPoints) {
|
||||
if (point.getTrkPtIndex() != -1) {
|
||||
points.add(point);
|
||||
if (point.isGap()) {
|
||||
res.add(points);
|
||||
points = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!points.isEmpty()) {
|
||||
res.add(points);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GPXFile exportRouteAsGpx(@NonNull String gpxName) {
|
||||
if (application == null || before.points.isEmpty() || !hasRoute()) {
|
||||
public GPXFile exportGpx(@NonNull String gpxName) {
|
||||
if (application == null || before.points.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return RouteExporter.exportRoute(gpxName, getRouteSegments(), null);
|
||||
}
|
||||
|
||||
private TrkSegment getRouteSegment(int startPointIndex, int endPointIndex) {
|
||||
List<RouteSegmentResult> route = new ArrayList<>();
|
||||
List<Location> locations = new ArrayList<>();
|
||||
before.points.get(0).setTrkPtIndex(0);
|
||||
int size = before.points.size();
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
for (int i = startPointIndex; i < endPointIndex; i++) {
|
||||
Pair<WptPt, WptPt> pair = new Pair<>(before.points.get(i), before.points.get(i + 1));
|
||||
RoadSegmentData data = this.roadSegmentData.get(pair);
|
||||
if (data != null) {
|
||||
if (data != null && data.points != null && data.segments != null) {
|
||||
for (WptPt pt : data.points) {
|
||||
Location l = new Location("");
|
||||
l.setLatitude(pt.getLatitude());
|
||||
|
@ -814,11 +1056,42 @@ public class MeasurementEditingContext {
|
|||
}
|
||||
locations.add(l);
|
||||
}
|
||||
pair.second.setTrkPtIndex(i < size - 1 ? locations.size() : locations.size() - 1);
|
||||
pair.second.setTrkPtIndex(i + 1 < before.points.size() - 1 ? locations.size() : locations.size() - 1);
|
||||
route.addAll(data.segments);
|
||||
}
|
||||
}
|
||||
return new RouteExporter(gpxName, route, locations, null).exportRoute();
|
||||
if (!locations.isEmpty() && !route.isEmpty()) {
|
||||
before.points.get(startPointIndex).setTrkPtIndex(0);
|
||||
return new RouteExporter("", route, locations, null).generateRouteSegment();
|
||||
} else if (endPointIndex - startPointIndex >= 0) {
|
||||
TrkSegment segment = new TrkSegment();
|
||||
segment.points = before.points.subList(startPointIndex, endPointIndex + 1);
|
||||
return segment;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<TrkSegment> getRouteSegments() {
|
||||
List<TrkSegment> res = new ArrayList<>();
|
||||
List<Integer> lastPointIndexes = new ArrayList<>();
|
||||
for (int i = 0; i < before.points.size(); i++) {
|
||||
WptPt pt = before.points.get(i);
|
||||
if (pt.isGap()) {
|
||||
lastPointIndexes.add(i);
|
||||
}
|
||||
}
|
||||
if (lastPointIndexes.isEmpty() || lastPointIndexes.get(lastPointIndexes.size() - 1) < before.points.size() - 1) {
|
||||
lastPointIndexes.add(before.points.size() - 1);
|
||||
}
|
||||
int firstPointIndex = 0;
|
||||
for (Integer lastPointIndex : lastPointIndexes) {
|
||||
TrkSegment segment = getRouteSegment(firstPointIndex, lastPointIndex);
|
||||
if (segment != null) {
|
||||
res.add(segment);
|
||||
}
|
||||
firstPointIndex = lastPointIndex + 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
interface SnapToRoadProgressListener {
|
||||
|
|
|
@ -34,9 +34,7 @@ import net.osmand.AndroidUtils;
|
|||
import net.osmand.FileUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.LocationsHolder;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
|
@ -53,7 +51,6 @@ import net.osmand.plus.base.BaseOsmAndFragment;
|
|||
import net.osmand.plus.base.ContextMenuFragment.MenuState;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.measurementtool.GpxApproximationFragment.GpxApproximationFragmentListener;
|
||||
import net.osmand.plus.measurementtool.GpxData.ActionType;
|
||||
import net.osmand.plus.measurementtool.OptionsBottomSheetDialogFragment.OptionsFragmentListener;
|
||||
import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsDialogMode;
|
||||
import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsDialogType;
|
||||
|
@ -139,7 +136,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
private static final int UNDO_MODE = 0x8;
|
||||
private int modes = 0x0;
|
||||
|
||||
private boolean approximationApplied = false;
|
||||
private boolean portrait;
|
||||
private boolean nightMode;
|
||||
private int cachedMapPosition;
|
||||
|
@ -149,7 +145,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
private LatLon initialPoint;
|
||||
|
||||
enum SaveType {
|
||||
ROUTE_POINT,
|
||||
ROUTE,
|
||||
LINE
|
||||
}
|
||||
|
||||
|
@ -355,7 +351,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
mainView.findViewById(R.id.options_button).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
boolean trackSnappedToRoad = editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData() || approximationApplied;
|
||||
boolean trackSnappedToRoad = !editingCtx.isApproximationNeeded();
|
||||
OptionsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
MeasurementToolFragment.this,
|
||||
trackSnappedToRoad,
|
||||
|
@ -503,7 +499,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
if (savedInstanceState == null) {
|
||||
if (fileName != null) {
|
||||
addNewGpxData(getGpxFile(fileName));
|
||||
} else if (!editingCtx.isNewData() && !editingCtx.hasRoutePoints() && !editingCtx.hasRoute() && editingCtx.getPointsCount() > 1) {
|
||||
} else if (editingCtx.isApproximationNeeded()) {
|
||||
enterApproximationMode(mapActivity);
|
||||
}
|
||||
} else {
|
||||
|
@ -570,7 +566,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
if (mapActivity != null) {
|
||||
editingCtx.getCommandManager().setMeasurementLayer(mapActivity.getMapLayers().getMeasurementToolLayer());
|
||||
enterMeasurementMode();
|
||||
updateSnapToRoadControls();
|
||||
if (gpxData != null && addPoints) {
|
||||
if (!isUndoMode()) {
|
||||
List<WptPt> points = gpxData.getGpxFile().getRoutePoints();
|
||||
|
@ -581,13 +576,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
}
|
||||
}
|
||||
}
|
||||
ActionType actionType = gpxData.getActionType();
|
||||
if (actionType == ActionType.ADD_ROUTE_POINTS) {
|
||||
displayRoutePoints();
|
||||
} else if (actionType == ActionType.EDIT_SEGMENT) {
|
||||
displaySegmentPoints();
|
||||
}
|
||||
collectPoints();
|
||||
}
|
||||
updateSnapToRoadControls();
|
||||
setMode(UNDO_MODE, false);
|
||||
}
|
||||
}
|
||||
|
@ -675,16 +666,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
|
||||
private void updateMainIcon() {
|
||||
GpxData gpxData = editingCtx.getGpxData();
|
||||
if (gpxData != null) {
|
||||
ActionType actionType = gpxData.getActionType();
|
||||
if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) {
|
||||
mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_polygom_dark));
|
||||
} else {
|
||||
mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_markers_dark));
|
||||
}
|
||||
} else {
|
||||
mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_ruler));
|
||||
}
|
||||
mainIcon.setImageDrawable(getActiveIcon(gpxData != null ? R.drawable.ic_action_polygom_dark : R.drawable.ic_action_ruler));
|
||||
}
|
||||
|
||||
private void startSnapToRoad(boolean rememberPreviousTitle) {
|
||||
|
@ -696,15 +678,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
toolBarController.setTitle(getString(R.string.route_between_points));
|
||||
mapActivity.refreshMap();
|
||||
|
||||
if (editingCtx.isNewData() || editingCtx.hasRoutePoints() || editingCtx.hasRoute() || editingCtx.getPointsCount() <= 2) {
|
||||
if (editingCtx.isApproximationNeeded()) {
|
||||
enterApproximationMode(mapActivity);
|
||||
} else {
|
||||
RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
this, RouteBetweenPointsDialogType.WHOLE_ROUTE_CALCULATION,
|
||||
editingCtx.getLastCalculationMode() == CalculationMode.NEXT_SEGMENT
|
||||
? RouteBetweenPointsDialogMode.SINGLE
|
||||
: RouteBetweenPointsDialogMode.ALL,
|
||||
editingCtx.getAppMode());
|
||||
} else {
|
||||
enterApproximationMode(mapActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -713,12 +695,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
if (editingCtx.getPointsCount() > 0) {
|
||||
GpxData gpxData = editingCtx.getGpxData();
|
||||
if (editingCtx.isNewData() || (isInEditMode() && gpxData.getActionType() == ActionType.EDIT_SEGMENT)) {
|
||||
if (editingCtx.isNewData() || isInEditMode()) {
|
||||
if (showDialog) {
|
||||
openSaveAsNewTrackMenu(mapActivity);
|
||||
} else {
|
||||
saveNewGpx(null, getSuggestedFileName(), true, false, finalSaveAction);
|
||||
saveNewGpx("", getSuggestedFileName(), true, false, finalSaveAction);
|
||||
}
|
||||
} else {
|
||||
addToGpx(mapActivity, finalSaveAction);
|
||||
|
@ -732,6 +713,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
switch (requestCode) {
|
||||
case SnapTrackWarningFragment.REQUEST_CODE:
|
||||
switch (resultCode) {
|
||||
|
@ -742,14 +724,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
updateToolbar();
|
||||
break;
|
||||
case SnapTrackWarningFragment.CONTINUE_RESULT_CODE:
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
ApplicationMode mode = editingCtx.getAppMode();
|
||||
if (mode == ApplicationMode.DEFAULT || "public_transport".equals(mode.getRoutingProfile())) {
|
||||
mode = null;
|
||||
}
|
||||
GpxApproximationFragment.showInstance(mapActivity.getSupportFragmentManager(),
|
||||
this, new LocationsHolder(editingCtx.getPoints()), mode);
|
||||
List<List<WptPt>> pointsSegments = editingCtx.getPointsSegments(true, false);
|
||||
if (!pointsSegments.isEmpty()) {
|
||||
GpxApproximationFragment.showInstance(
|
||||
mapActivity.getSupportFragmentManager(), this, pointsSegments, mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -757,10 +741,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
case ExitBottomSheetDialogFragment.REQUEST_CODE:
|
||||
switch (resultCode) {
|
||||
case ExitBottomSheetDialogFragment.EXIT_RESULT_CODE:
|
||||
if (mapActivity != null) {
|
||||
dismiss(getMapActivity());
|
||||
}
|
||||
break;
|
||||
case ExitBottomSheetDialogFragment.SAVE_RESULT_CODE:
|
||||
if (mapActivity != null) {
|
||||
openSaveAsNewTrackMenu(getMapActivity());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -792,7 +780,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
} else {
|
||||
String trackName = getSuggestedFileName();
|
||||
if (editingCtx.hasRoute()) {
|
||||
GPXFile gpx = editingCtx.exportRouteAsGpx(trackName);
|
||||
GPXFile gpx = editingCtx.exportGpx(trackName);
|
||||
if (gpx != null) {
|
||||
dismiss(mapActivity);
|
||||
runNavigation(gpx, appMode);
|
||||
|
@ -800,15 +788,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
Toast.makeText(mapActivity, getString(R.string.error_occurred_saving_gpx), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else {
|
||||
if (editingCtx.isNewData() || editingCtx.hasRoutePoints()) {
|
||||
if (editingCtx.isApproximationNeeded()) {
|
||||
setMode(DIRECTION_MODE, true);
|
||||
enterApproximationMode(mapActivity);
|
||||
} else {
|
||||
GPXFile gpx = new GPXFile(Version.getFullVersion(requireMyApplication()));
|
||||
gpx.addRoutePoints(points);
|
||||
gpx.addRoutePoints(points, true);
|
||||
dismiss(mapActivity);
|
||||
targetPointsHelper.clearAllPoints(false);
|
||||
mapActions.enterRoutePlanningModeGivenGpx(gpx, appMode, null, null, true, true, MenuState.HEADER_ONLY);
|
||||
} else {
|
||||
setMode(DIRECTION_MODE, true);
|
||||
enterApproximationMode(mapActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -860,7 +848,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addToTheTrackOnClick() {
|
||||
public void addToTrackOnClick() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
if (editingCtx.getPointsCount() > 0) {
|
||||
|
@ -927,7 +915,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
if (measurementLayer != null) {
|
||||
measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition());
|
||||
editingCtx.setInAddPointMode(true);
|
||||
editingCtx.setInAddPointMode(true, false);
|
||||
editingCtx.splitSegments(editingCtx.getSelectedPointPosition() + 1);
|
||||
}
|
||||
((TextView) mainView.findViewById(R.id.add_point_before_after_text)).setText(mainView.getResources().getString(R.string.add_point_after));
|
||||
|
@ -940,7 +928,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
if (measurementLayer != null) {
|
||||
measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition());
|
||||
editingCtx.setInAddPointMode(true);
|
||||
editingCtx.setInAddPointMode(true, true);
|
||||
editingCtx.splitSegments(editingCtx.getSelectedPointPosition());
|
||||
}
|
||||
((TextView) mainView.findViewById(R.id.add_point_before_after_text)).setText(mainView.getResources().getString(R.string.add_point_before));
|
||||
|
@ -1081,8 +1069,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
SelectedGpxFile selectedGpxFile = mapActivity.getMyApplication().getSelectedGpxHelper()
|
||||
.getSelectedFileByPath(gpxFile.path);
|
||||
boolean showOnMap = selectedGpxFile != null;
|
||||
saveExistingGpx(gpxFile, showOnMap, ActionType.ADD_SEGMENT,
|
||||
editingCtx.hasRoute() ? SaveType.ROUTE_POINT : SaveType.LINE, FinalSaveAction.SHOW_TOAST);
|
||||
saveExistingGpx(gpxFile, showOnMap, false, true, FinalSaveAction.SHOW_TOAST);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1107,10 +1094,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
private GpxData setupGpxData(@Nullable GPXFile gpxFile) {
|
||||
GpxData gpxData = null;
|
||||
if (gpxFile != null) {
|
||||
QuadRect rect = gpxFile.getRect();
|
||||
TrkSegment segment = gpxFile.getNonEmptyTrkSegment();
|
||||
ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
|
||||
gpxData = new GpxData(gpxFile, rect, actionType, segment);
|
||||
gpxData = new GpxData(gpxFile);
|
||||
}
|
||||
editingCtx.setGpxData(gpxData);
|
||||
return gpxData;
|
||||
|
@ -1128,22 +1112,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack) {
|
||||
saveNewGpx(folderName, fileName, showOnMap, simplifiedTrack, FinalSaveAction.SHOW_IS_SAVED_FRAGMENT);
|
||||
}
|
||||
|
||||
private void saveNewGpx(String folderName, String fileName, boolean showOnMap, boolean simplifiedTrack,
|
||||
FinalSaveAction finalSaveAction) {
|
||||
OsmandApplication app = getMyApplication();
|
||||
if (app != null) {
|
||||
File dir = getMyApplication().getAppPath(GPX_INDEX_DIR);
|
||||
if (folderName != null && !dir.getName().equals(folderName)) {
|
||||
dir = new File(dir, folderName);
|
||||
}
|
||||
fileName += GPX_FILE_EXT;
|
||||
SaveType saveType = simplifiedTrack ? SaveType.LINE : SaveType.ROUTE_POINT;
|
||||
saveNewGpx(dir, fileName, showOnMap, saveType, finalSaveAction);
|
||||
}
|
||||
public void onSaveAsNewTrack(String folderName, String fileName, boolean showOnMap, boolean simplified) {
|
||||
saveNewGpx(folderName, fileName, showOnMap, simplified, FinalSaveAction.SHOW_IS_SAVED_FRAGMENT);
|
||||
}
|
||||
|
||||
MeasurementAdapterListener createMeasurementAdapterListener(final ItemTouchHelper touchHelper) {
|
||||
|
@ -1219,7 +1189,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
final ApplicationMode appMode = editingCtx.getAppMode();
|
||||
if (mapActivity != null) {
|
||||
Drawable icon;
|
||||
if (editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData() || approximationApplied) {
|
||||
if (!editingCtx.isApproximationNeeded() || editingCtx.isNewData()) {
|
||||
if (appMode == MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
icon = getActiveIcon(R.drawable.ic_action_split_interval);
|
||||
} else {
|
||||
|
@ -1241,23 +1211,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
}
|
||||
}
|
||||
|
||||
private void displayRoutePoints() {
|
||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
GpxData gpxData = editingCtx.getGpxData();
|
||||
GPXFile gpx = gpxData != null ? gpxData.getGpxFile() : null;
|
||||
if (gpx != null) {
|
||||
List<WptPt> points = gpx.getRoutePoints();
|
||||
if (measurementLayer != null) {
|
||||
if (!isUndoMode()) {
|
||||
editingCtx.addPoints(points);
|
||||
}
|
||||
updateAdditionalInfoView();
|
||||
updateDistancePointsText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void displaySegmentPoints() {
|
||||
private void collectPoints() {
|
||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
if (measurementLayer != null) {
|
||||
if (!isUndoMode()) {
|
||||
|
@ -1354,7 +1308,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
switchAddPointBeforeAfterMode(false);
|
||||
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
|
||||
editingCtx.setSelectedPointPosition(-1);
|
||||
editingCtx.setInAddPointMode(false);
|
||||
editingCtx.setInAddPointMode(false, false);
|
||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
if (measurementLayer != null) {
|
||||
measurementLayer.refreshMap();
|
||||
|
@ -1366,7 +1320,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
switchAddPointBeforeAfterMode(false);
|
||||
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
|
||||
editingCtx.setSelectedPointPosition(-1);
|
||||
editingCtx.setInAddPointMode(false);
|
||||
editingCtx.setInAddPointMode(false, false);
|
||||
MeasurementToolLayer measurementToolLayer = getMeasurementLayer();
|
||||
if (measurementToolLayer != null) {
|
||||
measurementToolLayer.refreshMap();
|
||||
|
@ -1520,8 +1474,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
SelectedGpxFile selectedGpxFile =
|
||||
mapActivity.getMyApplication().getSelectedGpxHelper().getSelectedFileByPath(gpx.path);
|
||||
boolean showOnMap = selectedGpxFile != null;
|
||||
saveExistingGpx(gpx, showOnMap, gpxData.getActionType(),
|
||||
editingCtx.hasRoute() ? SaveType.ROUTE_POINT : SaveType.LINE, finalSaveAction);
|
||||
saveExistingGpx(gpx, showOnMap, false, false, finalSaveAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1555,30 +1508,45 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
return displayedName;
|
||||
}
|
||||
|
||||
private void saveNewGpx(@NonNull File dir, @NonNull String fileName, boolean showOnMap, SaveType saveType, FinalSaveAction finalSaveAction) {
|
||||
saveGpx(new File(dir, fileName), null, null, saveType, finalSaveAction, showOnMap);
|
||||
private void saveNewGpx(String folderName, String fileName, boolean showOnMap,
|
||||
boolean simplified, FinalSaveAction finalSaveAction) {
|
||||
OsmandApplication app = getMyApplication();
|
||||
if (app != null) {
|
||||
File dir = getMyApplication().getAppPath(GPX_INDEX_DIR);
|
||||
if (!Algorithms.isEmpty(folderName) && !dir.getName().equals(folderName)) {
|
||||
dir = new File(dir, folderName);
|
||||
}
|
||||
fileName += GPX_FILE_EXT;
|
||||
saveNewGpx(dir, fileName, showOnMap, simplified, finalSaveAction);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveExistingGpx(@NonNull GPXFile gpx, boolean showOnMap, ActionType actionType,
|
||||
SaveType saveType, FinalSaveAction finalSaveAction) {
|
||||
saveGpx(new File(gpx.path), gpx, actionType, saveType, finalSaveAction, showOnMap);
|
||||
private void saveNewGpx(@NonNull File dir, @NonNull String fileName, boolean showOnMap,
|
||||
boolean simplified, FinalSaveAction finalSaveAction) {
|
||||
saveGpx(new File(dir, fileName), null, simplified, false, finalSaveAction, showOnMap);
|
||||
}
|
||||
|
||||
private void saveGpx(@NonNull final File outFile, @Nullable GPXFile gpxFile, final ActionType actionType,
|
||||
SaveType saveType, final FinalSaveAction finalSaveAction, final boolean showOnMap) {
|
||||
private void saveExistingGpx(@NonNull GPXFile gpx, boolean showOnMap,
|
||||
boolean simplified, boolean addToTrack, FinalSaveAction finalSaveAction) {
|
||||
saveGpx(new File(gpx.path), gpx, simplified, addToTrack, finalSaveAction, showOnMap);
|
||||
}
|
||||
|
||||
private void saveGpx(@NonNull final File outFile, @Nullable GPXFile gpxFile, boolean simplified,
|
||||
boolean addToTrack, final FinalSaveAction finalSaveAction, final boolean showOnMap) {
|
||||
SaveGpxRouteListener saveGpxRouteListener = new SaveGpxRouteListener() {
|
||||
@Override
|
||||
public void gpxSavingFinished(Exception warning, GPXFile savedGpxFile, File backupFile) {
|
||||
onGpxSaved(warning, savedGpxFile, outFile, backupFile, actionType, finalSaveAction, showOnMap);
|
||||
onGpxSaved(warning, savedGpxFile, outFile, backupFile, finalSaveAction, showOnMap);
|
||||
}
|
||||
};
|
||||
|
||||
SaveGpxRouteAsyncTask saveTask = new SaveGpxRouteAsyncTask(this, outFile, gpxFile, actionType, saveType, showOnMap, saveGpxRouteListener);
|
||||
SaveGpxRouteAsyncTask saveTask = new SaveGpxRouteAsyncTask(this, outFile, gpxFile, simplified,
|
||||
addToTrack, showOnMap, saveGpxRouteListener);
|
||||
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void onGpxSaved(Exception warning, GPXFile savedGpxFile, final File outFile, final File backupFile,
|
||||
final ActionType actionType, FinalSaveAction finalSaveAction, final boolean showOnMap) {
|
||||
FinalSaveAction finalSaveAction, final boolean showOnMap) {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity == null) {
|
||||
return;
|
||||
|
@ -1586,9 +1554,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
mapActivity.refreshMap();
|
||||
if (warning == null) {
|
||||
if (editingCtx.isNewData() && savedGpxFile != null) {
|
||||
QuadRect rect = savedGpxFile.getRect();
|
||||
TrkSegment segment = savedGpxFile.getNonEmptyTrkSegment();
|
||||
GpxData gpxData = new GpxData(savedGpxFile, rect, ActionType.EDIT_SEGMENT, segment);
|
||||
GpxData gpxData = new GpxData(savedGpxFile);
|
||||
editingCtx.setGpxData(gpxData);
|
||||
updateToolbar();
|
||||
}
|
||||
|
@ -1614,7 +1580,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
GPXFile gpx = GPXUtilities.loadGPXFile(outFile);
|
||||
setupGpxData(gpx);
|
||||
if (showOnMap) {
|
||||
showGpxOnMap(app, gpx, actionType, false);
|
||||
showGpxOnMap(app, gpx, false);
|
||||
}
|
||||
} else {
|
||||
setupGpxData(null);
|
||||
|
@ -1660,14 +1626,12 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
}
|
||||
}
|
||||
|
||||
protected static void showGpxOnMap(OsmandApplication app, GPXFile gpx, ActionType actionType, boolean isNewGpx) {
|
||||
protected static void showGpxOnMap(OsmandApplication app, GPXFile gpx, boolean isNewGpx) {
|
||||
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
|
||||
if (sf != null && !isNewGpx) {
|
||||
if (actionType == ActionType.ADD_SEGMENT || actionType == ActionType.EDIT_SEGMENT) {
|
||||
sf.processPoints(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUndoRedoButton(boolean enable, View view) {
|
||||
view.setEnabled(enable);
|
||||
|
@ -1704,25 +1668,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
if (mapActivity == null) {
|
||||
return;
|
||||
}
|
||||
final GpxData gpxData = editingCtx.getGpxData();
|
||||
String fileName = getSuggestedFileName();
|
||||
String actionStr = getString(R.string.plan_route);
|
||||
boolean editMode = isInEditMode();
|
||||
if (editMode) {
|
||||
ActionType actionType = gpxData.getActionType();
|
||||
switch (actionType) {
|
||||
case ADD_ROUTE_POINTS:
|
||||
actionStr = getString(R.string.add_route_points);
|
||||
break;
|
||||
case ADD_SEGMENT:
|
||||
actionStr = getString(R.string.add_line);
|
||||
break;
|
||||
case EDIT_SEGMENT:
|
||||
case OVERWRITE_SEGMENT:
|
||||
actionStr = getString(R.string.edit_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
String actionStr = getString(editMode ? R.string.edit_line : R.string.plan_route);
|
||||
if (!editMode && editingCtx.getPointsCount() > 1) {
|
||||
toolBarController.setTitle(fileName.replace('_', ' '));
|
||||
toolBarController.setDescription(actionStr);
|
||||
|
@ -1969,12 +1917,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onGpxApproximationDone(GpxRouteApproximation gpxApproximation, ApplicationMode mode) {
|
||||
public void onGpxApproximationDone(List<GpxRouteApproximation> gpxApproximations, List<List<WptPt>> pointsList, ApplicationMode mode) {
|
||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||
if (measurementLayer != null) {
|
||||
boolean approximationMode = editingCtx.isInApproximationMode();
|
||||
editingCtx.setInApproximationMode(true);
|
||||
ApplyGpxApproximationCommand command = new ApplyGpxApproximationCommand(measurementLayer, gpxApproximation, mode);
|
||||
if (!editingCtx.getCommandManager().update(command)) {
|
||||
ApplyGpxApproximationCommand command = new ApplyGpxApproximationCommand(measurementLayer, gpxApproximations, pointsList, mode);
|
||||
if (!approximationMode || !editingCtx.getCommandManager().update(command)) {
|
||||
editingCtx.getCommandManager().execute(command);
|
||||
}
|
||||
if (additionalInfoExpanded) {
|
||||
|
@ -1986,7 +1935,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
|
||||
@Override
|
||||
public void onApplyGpxApproximation() {
|
||||
approximationApplied = true;
|
||||
exitApproximationMode();
|
||||
doAddOrMovePointCommonStuff();
|
||||
updateSnapToRoadControls();
|
||||
|
@ -2001,7 +1949,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
|||
if (mapActivity != null) {
|
||||
if (editingCtx.hasRoute()) {
|
||||
String trackName = getSuggestedFileName();
|
||||
GPXFile gpx = editingCtx.exportRouteAsGpx(trackName);
|
||||
GPXFile gpx = editingCtx.exportGpx(trackName);
|
||||
if (gpx != null) {
|
||||
ApplicationMode appMode = editingCtx.getAppMode();
|
||||
dismiss(mapActivity);
|
||||
|
|
|
@ -17,7 +17,7 @@ import net.osmand.data.PointDescription;
|
|||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext.AdditionMode;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.Renderable;
|
||||
|
@ -183,22 +183,27 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
|||
lineAttrs.updatePaints(view.getApplication(), settings, tb);
|
||||
|
||||
if (editingCtx.isInApproximationMode()) {
|
||||
List<WptPt> originalTrackPointList = editingCtx.getOriginalTrackPointList();
|
||||
if (originalTrackPointList != null) {
|
||||
List<List<WptPt>> originalPointsList = editingCtx.getOriginalSegmentPointsList();
|
||||
if (originalPointsList != null) {
|
||||
lineAttrs.customColorPaint.setColor(ContextCompat.getColor(view.getContext(),
|
||||
R.color.activity_background_transparent_color_dark));
|
||||
new Renderable.StandardTrack(new ArrayList<>(originalTrackPointList), 17.2).
|
||||
for (List<WptPt> points : originalPointsList) {
|
||||
new Renderable.StandardTrack(new ArrayList<>(points), 17.2).
|
||||
drawSegment(view.getZoom(), lineAttrs.customColorPaint, canvas, tb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
|
||||
new Renderable.StandardTrack(new ArrayList<>(before.points), 17.2).
|
||||
List<TrkSegment> before = editingCtx.getBeforeTrkSegmentLine();
|
||||
for (TrkSegment segment : before) {
|
||||
new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2).
|
||||
drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb);
|
||||
|
||||
TrkSegment after = editingCtx.getAfterTrkSegmentLine();
|
||||
new Renderable.StandardTrack(new ArrayList<>(after.points), 17.2).
|
||||
}
|
||||
List<TrkSegment> after = editingCtx.getAfterTrkSegmentLine();
|
||||
for (TrkSegment segment : after) {
|
||||
new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2).
|
||||
drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb);
|
||||
}
|
||||
|
||||
drawPoints(canvas, tb);
|
||||
}
|
||||
|
@ -308,38 +313,54 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
|||
}
|
||||
|
||||
private void drawBeforeAfterPath(Canvas canvas, RotatedTileBox tb) {
|
||||
TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
|
||||
TrkSegment after = editingCtx.getAfterTrkSegmentLine();
|
||||
if (before.points.size() > 0 || after.points.size() > 0) {
|
||||
List<TrkSegment> before = editingCtx.getBeforeSegments();
|
||||
List<TrkSegment> after = editingCtx.getAfterSegments();
|
||||
if (before.size() > 0 || after.size() > 0) {
|
||||
path.reset();
|
||||
tx.clear();
|
||||
ty.clear();
|
||||
|
||||
if (before.points.size() > 0) {
|
||||
WptPt pt = before.points.get(before.points.size() - 1);
|
||||
boolean hasPointsBefore = false;
|
||||
boolean hasGapBefore = false;
|
||||
if (before.size() > 0) {
|
||||
TrkSegment segment = before.get(before.size() - 1);
|
||||
if (segment.points.size() > 0) {
|
||||
hasPointsBefore = true;
|
||||
WptPt pt = segment.points.get(segment.points.size() - 1);
|
||||
hasGapBefore = pt.isGap();
|
||||
if (!pt.isGap() || !editingCtx.isInAddPointBeforeMode()) {
|
||||
float locX = tb.getPixXFromLatLon(pt.lat, pt.lon);
|
||||
float locY = tb.getPixYFromLatLon(pt.lat, pt.lon);
|
||||
tx.add(locX);
|
||||
ty.add(locY);
|
||||
}
|
||||
tx.add((float) tb.getCenterPixelX());
|
||||
ty.add((float) tb.getCenterPixelY());
|
||||
}
|
||||
if (after.points.size() > 0) {
|
||||
if (before.points.size() == 0) {
|
||||
}
|
||||
if (after.size() > 0) {
|
||||
TrkSegment segment = after.get(0);
|
||||
if (segment.points.size() > 0) {
|
||||
if (!hasPointsBefore) {
|
||||
tx.add((float) tb.getCenterPixelX());
|
||||
ty.add((float) tb.getCenterPixelY());
|
||||
}
|
||||
WptPt pt = after.points.get(0);
|
||||
if (!hasGapBefore || editingCtx.isInAddPointBeforeMode()) {
|
||||
WptPt pt = segment.points.get(0);
|
||||
float locX = tb.getPixXFromLatLon(pt.lat, pt.lon);
|
||||
float locY = tb.getPixYFromLatLon(pt.lat, pt.lon);
|
||||
tx.add(locX);
|
||||
ty.add(locY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!tx.isEmpty() && !ty.isEmpty()) {
|
||||
GeometryWay.calculatePath(tb, tx, ty, path);
|
||||
canvas.drawPath(path, lineAttrs.paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, boolean nightMode) {
|
||||
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
|
@ -359,7 +380,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
|||
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
|
||||
}
|
||||
|
||||
public WptPt addCenterPoint() {
|
||||
public WptPt addCenterPoint(boolean addPointBefore) {
|
||||
RotatedTileBox tb = view.getCurrentRotatedTileBox();
|
||||
LatLon l = tb.getCenterLatLon();
|
||||
WptPt pt = new WptPt();
|
||||
|
@ -367,18 +388,13 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
|||
pt.lon = l.getLongitude();
|
||||
boolean allowed = editingCtx.getPointsCount() == 0 || !editingCtx.getPoints().get(editingCtx.getPointsCount() - 1).equals(pt);
|
||||
if (allowed) {
|
||||
|
||||
ApplicationMode applicationMode = editingCtx.getAppMode();
|
||||
if (applicationMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
pt.setProfileType(applicationMode.getStringKey());
|
||||
}
|
||||
editingCtx.addPoint(pt);
|
||||
editingCtx.addPoint(pt, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER);
|
||||
return pt;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public WptPt addPoint() {
|
||||
public WptPt addPoint(boolean addPointBefore) {
|
||||
if (pressedPointLatLon != null) {
|
||||
WptPt pt = new WptPt();
|
||||
double lat = pressedPointLatLon.getLatitude();
|
||||
|
@ -388,11 +404,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
|||
pressedPointLatLon = null;
|
||||
boolean allowed = editingCtx.getPointsCount() == 0 || !editingCtx.getPoints().get(editingCtx.getPointsCount() - 1).equals(pt);
|
||||
if (allowed) {
|
||||
ApplicationMode applicationMode = editingCtx.getAppMode();
|
||||
if (applicationMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
pt.setProfileType(applicationMode.getStringKey());
|
||||
}
|
||||
editingCtx.addPoint(pt);
|
||||
editingCtx.addPoint(pt, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER);
|
||||
moveMapToLatLon(lat, lon);
|
||||
return pt;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
|
|||
public void onClick(View v) {
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof OptionsFragmentListener) {
|
||||
((OptionsFragmentListener) fragment).addToTheTrackOnClick();
|
||||
((OptionsFragmentListener) fragment).addToTrackOnClick();
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
|
|||
|
||||
void saveAsNewTrackOnClick();
|
||||
|
||||
void addToTheTrackOnClick();
|
||||
void addToTrackOnClick();
|
||||
|
||||
void directionsOnClick();
|
||||
|
||||
|
|
|
@ -35,9 +35,7 @@ public class PointsCard extends BaseCard implements OnUpdateAdditionalInfoListen
|
|||
@Override
|
||||
protected void updateContent() {
|
||||
MeasurementEditingContext editingCtx = fragment.getEditingCtx();
|
||||
final GpxData gpxData = editingCtx.getGpxData();
|
||||
adapter = new MeasurementToolAdapter(mapActivity, editingCtx.getPoints(),
|
||||
gpxData != null ? gpxData.getActionType() : null);
|
||||
adapter = new MeasurementToolAdapter(mapActivity, editingCtx.getPoints());
|
||||
RecyclerView pointsRv = view.findViewById(R.id.measure_points_recycler_view);
|
||||
ItemTouchHelper touchHelper = new ItemTouchHelper(new ReorderItemTouchHelperCallback(adapter));
|
||||
touchHelper.attachToRecyclerView(pointsRv);
|
||||
|
|
|
@ -4,10 +4,13 @@ import android.app.ProgressDialog;
|
|||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.FileUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Route;
|
||||
import net.osmand.GPXUtilities.Track;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
|
@ -15,42 +18,38 @@ import net.osmand.plus.OsmandApplication;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.measurementtool.GpxData.ActionType;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolFragment.SaveType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
||||
|
||||
class SaveGpxRouteAsyncTask extends AsyncTask<Void, Void, Exception> {
|
||||
|
||||
private WeakReference<MeasurementToolFragment> fragmentRef;
|
||||
private final WeakReference<MeasurementToolFragment> fragmentRef;
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
private SaveType saveType;
|
||||
private ActionType actionType;
|
||||
|
||||
private File outFile;
|
||||
private final File outFile;
|
||||
private File backupFile;
|
||||
private GPXFile gpxFile;
|
||||
private final GPXFile gpxFile;
|
||||
private GPXFile savedGpxFile;
|
||||
private boolean showOnMap;
|
||||
|
||||
private SaveGpxRouteListener saveGpxRouteListener;
|
||||
private final boolean simplified;
|
||||
private final boolean addToTrack;
|
||||
private final boolean showOnMap;
|
||||
|
||||
private final SaveGpxRouteListener saveGpxRouteListener;
|
||||
|
||||
public SaveGpxRouteAsyncTask(MeasurementToolFragment fragment, File outFile, GPXFile gpxFile,
|
||||
ActionType actionType, SaveType saveType, boolean showOnMap, SaveGpxRouteListener saveGpxRouteListener) {
|
||||
boolean simplified, boolean addToTrack, boolean showOnMap,
|
||||
SaveGpxRouteListener saveGpxRouteListener) {
|
||||
fragmentRef = new WeakReference<>(fragment);
|
||||
this.outFile = outFile;
|
||||
this.showOnMap = showOnMap;
|
||||
this.gpxFile = gpxFile;
|
||||
this.actionType = actionType;
|
||||
this.saveType = saveType;
|
||||
this.simplified = simplified;
|
||||
this.addToTrack = addToTrack;
|
||||
this.saveGpxRouteListener = saveGpxRouteListener;
|
||||
}
|
||||
|
||||
|
@ -77,119 +76,73 @@ class SaveGpxRouteAsyncTask extends AsyncTask<Void, Void, Exception> {
|
|||
OsmandApplication app = mapActivity.getMyApplication();
|
||||
MeasurementToolLayer measurementLayer = mapActivity.getMapLayers().getMeasurementToolLayer();
|
||||
MeasurementEditingContext editingCtx = fragment.getEditingCtx();
|
||||
|
||||
List<WptPt> points = editingCtx.getPoints();
|
||||
TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
|
||||
TrkSegment after = editingCtx.getAfterTrkSegmentLine();
|
||||
Exception res = null;
|
||||
if (gpxFile == null) {
|
||||
String fileName = outFile.getName();
|
||||
String trackName = fileName.substring(0, fileName.length() - GPX_FILE_EXT.length());
|
||||
GPXFile gpx = new GPXFile(Version.getFullVersion(app));
|
||||
if (measurementLayer != null) {
|
||||
if (saveType == MeasurementToolFragment.SaveType.LINE) {
|
||||
TrkSegment segment = new TrkSegment();
|
||||
if (editingCtx.hasRoute()) {
|
||||
segment.points.addAll(editingCtx.getRoutePoints());
|
||||
} else {
|
||||
segment.points.addAll(before.points);
|
||||
segment.points.addAll(after.points);
|
||||
}
|
||||
Track track = new Track();
|
||||
track.name = trackName;
|
||||
track.segments.add(segment);
|
||||
gpx.tracks.add(track);
|
||||
} else if (saveType == MeasurementToolFragment.SaveType.ROUTE_POINT) {
|
||||
if (editingCtx.hasRoute()) {
|
||||
GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName);
|
||||
if (newGpx != null) {
|
||||
gpx = newGpx;
|
||||
}
|
||||
}
|
||||
gpx.addRoutePoints(points);
|
||||
}
|
||||
}
|
||||
Exception res = GPXUtilities.writeGpxFile(outFile, gpx);
|
||||
GPXFile gpx = generateGpxFile(measurementLayer, editingCtx, trackName, new GPXFile(Version.getFullVersion(app)));
|
||||
res = GPXUtilities.writeGpxFile(outFile, gpx);
|
||||
gpx.path = outFile.getAbsolutePath();
|
||||
savedGpxFile = gpx;
|
||||
if (showOnMap) {
|
||||
MeasurementToolFragment.showGpxOnMap(app, gpx, actionType, true);
|
||||
MeasurementToolFragment.showGpxOnMap(app, gpx, true);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
GPXFile gpx = gpxFile;
|
||||
backupFile = FileUtils.backupFile(app, outFile);
|
||||
String trackName = Algorithms.getFileNameWithoutExtension(outFile);
|
||||
if (measurementLayer != null) {
|
||||
if (fragment.isPlanRouteMode()) {
|
||||
if (saveType == MeasurementToolFragment.SaveType.LINE) {
|
||||
TrkSegment segment = new TrkSegment();
|
||||
if (editingCtx.hasRoute()) {
|
||||
segment.points.addAll(editingCtx.getRoutePoints());
|
||||
} else {
|
||||
segment.points.addAll(before.points);
|
||||
segment.points.addAll(after.points);
|
||||
}
|
||||
Track track = new Track();
|
||||
track.name = trackName;
|
||||
track.segments.add(segment);
|
||||
gpx.tracks.add(track);
|
||||
} else if (saveType == MeasurementToolFragment.SaveType.ROUTE_POINT) {
|
||||
if (editingCtx.hasRoute()) {
|
||||
GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName);
|
||||
if (newGpx != null) {
|
||||
gpx = newGpx;
|
||||
}
|
||||
}
|
||||
gpx.addRoutePoints(points);
|
||||
}
|
||||
} else if (actionType != null) {
|
||||
GpxData gpxData = editingCtx.getGpxData();
|
||||
switch (actionType) {
|
||||
case ADD_SEGMENT: {
|
||||
List<WptPt> snappedPoints = new ArrayList<>();
|
||||
snappedPoints.addAll(before.points);
|
||||
snappedPoints.addAll(after.points);
|
||||
gpx.addTrkSegment(snappedPoints);
|
||||
break;
|
||||
}
|
||||
case ADD_ROUTE_POINTS: {
|
||||
gpx.replaceRoutePoints(points);
|
||||
break;
|
||||
}
|
||||
case EDIT_SEGMENT: {
|
||||
if (gpxData != null) {
|
||||
TrkSegment segment = new TrkSegment();
|
||||
segment.points.addAll(points);
|
||||
gpx.replaceSegment(gpxData.getTrkSegment(), segment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OVERWRITE_SEGMENT: {
|
||||
if (gpxData != null) {
|
||||
List<WptPt> snappedPoints = new ArrayList<>();
|
||||
snappedPoints.addAll(before.points);
|
||||
snappedPoints.addAll(after.points);
|
||||
TrkSegment segment = new TrkSegment();
|
||||
segment.points.addAll(snappedPoints);
|
||||
gpx.replaceSegment(gpxData.getTrkSegment(), segment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gpx.addRoutePoints(points);
|
||||
}
|
||||
}
|
||||
Exception res = null;
|
||||
GPXFile gpx = generateGpxFile(measurementLayer, editingCtx, trackName, gpxFile);
|
||||
if (!gpx.showCurrentTrack) {
|
||||
res = GPXUtilities.writeGpxFile(outFile, gpx);
|
||||
}
|
||||
savedGpxFile = gpx;
|
||||
if (showOnMap) {
|
||||
MeasurementToolFragment.showGpxOnMap(app, gpx, actionType, false);
|
||||
MeasurementToolFragment.showGpxOnMap(app, gpx, false);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private GPXFile generateGpxFile(MeasurementToolLayer measurementLayer, MeasurementEditingContext editingCtx,
|
||||
String trackName, @NonNull GPXFile gpx) {
|
||||
if (measurementLayer != null) {
|
||||
List<TrkSegment> before = editingCtx.getBeforeTrkSegmentLine();
|
||||
List<TrkSegment> after = editingCtx.getAfterTrkSegmentLine();
|
||||
if (simplified) {
|
||||
Track track = new Track();
|
||||
track.name = trackName;
|
||||
gpx.tracks.add(track);
|
||||
for (TrkSegment s : before) {
|
||||
TrkSegment segment = new TrkSegment();
|
||||
segment.points.addAll(s.points);
|
||||
track.segments.add(segment);
|
||||
}
|
||||
for (TrkSegment s : after) {
|
||||
TrkSegment segment = new TrkSegment();
|
||||
segment.points.addAll(s.points);
|
||||
track.segments.add(segment);
|
||||
}
|
||||
} else {
|
||||
GPXFile newGpx = editingCtx.exportGpx(trackName);
|
||||
if (newGpx != null) {
|
||||
List<Track> gpxTracks = gpx.tracks;
|
||||
List<WptPt> gpxPoints = gpx.getPoints();
|
||||
List<Route> gpxRoutes = gpx.routes;
|
||||
gpx = newGpx;
|
||||
List<List<WptPt>> routePoints = editingCtx.getRoutePoints();
|
||||
for (List<WptPt> points : routePoints) {
|
||||
gpx.addRoutePoints(points, true);
|
||||
}
|
||||
if (!Algorithms.isEmpty(gpxPoints)) {
|
||||
gpx.addPoints(gpxPoints);
|
||||
}
|
||||
if (addToTrack) {
|
||||
gpx.tracks.addAll(gpxTracks);
|
||||
gpx.routes.addAll(gpxRoutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return gpx;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.osmand.plus.measurementtool;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -25,7 +26,6 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
|
|||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleDividerItem;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.measurementtool.GpxData.ActionType;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
|
@ -39,6 +39,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
|||
private static final Log LOG = PlatformUtil.getLog(SelectedPointBottomSheetDialogFragment.class);
|
||||
private MeasurementEditingContext editingCtx;
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
|
@ -172,7 +173,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
|||
dismiss();
|
||||
}
|
||||
})
|
||||
.setDisabled(editingCtx.isFirstPointSelected())
|
||||
.setDisabled(editingCtx.isFirstPointSelected() || editingCtx.isSelectionNeedApproximation())
|
||||
.create();
|
||||
items.add(changeRouteTypeBefore);
|
||||
|
||||
|
@ -191,7 +192,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
|||
dismiss();
|
||||
}
|
||||
})
|
||||
.setDisabled(editingCtx.isLastPointSelected())
|
||||
.setDisabled(editingCtx.isLastPointSelected() || editingCtx.isSelectionNeedApproximation())
|
||||
.create();
|
||||
items.add(changeRouteTypeAfter);
|
||||
|
||||
|
@ -264,11 +265,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
|||
if (!TextUtils.isEmpty(pointName)) {
|
||||
return pointName;
|
||||
}
|
||||
GpxData gpxData = editingCtx.getGpxData();
|
||||
if (gpxData != null && gpxData.getActionType() == ActionType.ADD_ROUTE_POINTS) {
|
||||
return getString(R.string.route_point) + " - " + (pos + 1);
|
||||
}
|
||||
return getString(R.string.plugin_distance_point) + " - " + (pos + 1);
|
||||
return getString(R.string.ltr_or_rtl_combine_via_dash, getString(R.string.plugin_distance_point), String.valueOf(pos + 1));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -305,8 +302,6 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
|||
}
|
||||
description.append(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication()));
|
||||
}
|
||||
GpxData gpxData = editingCtx.getGpxData();
|
||||
if (gpxData != null && gpxData.getActionType() == ActionType.EDIT_SEGMENT) {
|
||||
double elevation = pt.ele;
|
||||
if (!Double.isNaN(elevation)) {
|
||||
description.append(" ").append((getString(R.string.altitude)).substring(0, 1)).append(": ");
|
||||
|
@ -317,7 +312,6 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
|||
description.append(" ").append((getString(R.string.map_widget_speed)).substring(0, 1)).append(": ");
|
||||
description.append(OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication()));
|
||||
}
|
||||
}
|
||||
return description.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import net.osmand.plus.OsmAndFormatter;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.measurementtool.GpxData.ActionType;
|
||||
import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -32,13 +31,11 @@ public class MeasurementToolAdapter extends RecyclerView.Adapter<MeasurementTool
|
|||
private final List<WptPt> points;
|
||||
private MeasurementAdapterListener listener;
|
||||
private boolean nightMode;
|
||||
private final ActionType actionType;
|
||||
private final static String BULLET = " • ";
|
||||
|
||||
public MeasurementToolAdapter(MapActivity mapActivity, List<WptPt> points, ActionType actionType) {
|
||||
public MeasurementToolAdapter(MapActivity mapActivity, List<WptPt> points) {
|
||||
this.mapActivity = mapActivity;
|
||||
this.points = points;
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
public void setAdapterListener(MeasurementAdapterListener listener) {
|
||||
|
@ -79,11 +76,7 @@ public class MeasurementToolAdapter extends RecyclerView.Adapter<MeasurementTool
|
|||
if (!TextUtils.isEmpty(pointTitle)) {
|
||||
holder.title.setText(pointTitle);
|
||||
} else {
|
||||
if (actionType == ActionType.ADD_ROUTE_POINTS) {
|
||||
holder.title.setText(mapActivity.getString(R.string.route_point) + " - " + (pos + 1));
|
||||
} else {
|
||||
holder.title.setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1));
|
||||
}
|
||||
holder.title.setText(mapActivity.getString(R.string.ltr_or_rtl_combine_via_dash, mapActivity.getString(R.string.plugin_distance_point), String.valueOf(pos + 1)));
|
||||
}
|
||||
String pointDesc = pt.desc;
|
||||
if (!TextUtils.isEmpty(pointDesc)) {
|
||||
|
@ -114,11 +107,11 @@ public class MeasurementToolAdapter extends RecyclerView.Adapter<MeasurementTool
|
|||
holder.descr.setText(text);
|
||||
}
|
||||
}
|
||||
if (actionType == ActionType.EDIT_SEGMENT) {
|
||||
double elevation = pt.ele;
|
||||
if (!Double.isNaN(elevation)) {
|
||||
String eleStr = (mapActivity.getString(R.string.altitude)).substring(0, 1);
|
||||
holder.elevation.setText(eleStr + ": " + OsmAndFormatter.getFormattedAlt(elevation, mapActivity.getMyApplication()));
|
||||
holder.elevation.setText(mapActivity.getString(R.string.ltr_or_rtl_combine_via_colon,
|
||||
eleStr, OsmAndFormatter.getFormattedAlt(elevation, mapActivity.getMyApplication())));
|
||||
} else {
|
||||
holder.elevation.setText("");
|
||||
}
|
||||
|
@ -129,7 +122,6 @@ public class MeasurementToolAdapter extends RecyclerView.Adapter<MeasurementTool
|
|||
} else {
|
||||
holder.speed.setText("");
|
||||
}
|
||||
}
|
||||
holder.deleteBtn.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_remove_dark,
|
||||
nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light));
|
||||
holder.deleteBtn.setOnClickListener(new View.OnClickListener() {
|
||||
|
|
|
@ -3,48 +3,57 @@ package net.osmand.plus.measurementtool.command;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext.AdditionMode;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolLayer;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddPointCommand extends MeasurementModeCommand {
|
||||
|
||||
private int position;
|
||||
private WptPt point;
|
||||
private String prevPointProfile;
|
||||
private boolean center;
|
||||
private boolean addPointBefore;
|
||||
|
||||
public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) {
|
||||
super(measurementLayer);
|
||||
init(measurementLayer, null, center);
|
||||
init(null, center);
|
||||
}
|
||||
|
||||
public AddPointCommand(MeasurementToolLayer measurementLayer, LatLon latLon) {
|
||||
super(measurementLayer);
|
||||
init(measurementLayer, latLon, false);
|
||||
init(latLon, false);
|
||||
}
|
||||
|
||||
private void init(MeasurementToolLayer measurementLayer, LatLon latLon, boolean center) {
|
||||
private void init(LatLon latLon, boolean center) {
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
if (latLon != null) {
|
||||
point = new WptPt();
|
||||
point.lat = latLon.getLatitude();
|
||||
point.lon = latLon.getLongitude();
|
||||
ApplicationMode appMode = measurementLayer.getEditingCtx().getAppMode();
|
||||
if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||
point.setProfileType(appMode.getStringKey());
|
||||
}
|
||||
}
|
||||
this.center = center;
|
||||
position = measurementLayer.getEditingCtx().getPointsCount();
|
||||
position = ctx.getPointsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
addPointBefore = ctx.isInAddPointBeforeMode();
|
||||
List<WptPt> points = ctx.getPoints();
|
||||
if (points.size() > 0) {
|
||||
WptPt prevPt = points.get(points.size() - 1);
|
||||
prevPointProfile = prevPt.getProfileType();
|
||||
}
|
||||
if (point != null) {
|
||||
getEditingCtx().addPoint(point);
|
||||
ctx.addPoint(point, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER);
|
||||
measurementLayer.moveMapToPoint(position);
|
||||
} else if (center) {
|
||||
point = measurementLayer.addCenterPoint();
|
||||
point = measurementLayer.addCenterPoint(addPointBefore);
|
||||
} else {
|
||||
point = measurementLayer.addPoint();
|
||||
point = measurementLayer.addPoint(addPointBefore);
|
||||
}
|
||||
refreshMap();
|
||||
return point != null;
|
||||
|
@ -52,13 +61,22 @@ public class AddPointCommand extends MeasurementModeCommand {
|
|||
|
||||
@Override
|
||||
public void undo() {
|
||||
getEditingCtx().removePoint(position, true);
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
if (position > 0) {
|
||||
WptPt prevPt = ctx.getPoints().get(position - 1);
|
||||
if (prevPointProfile != null) {
|
||||
prevPt.setProfileType(prevPointProfile);
|
||||
} else {
|
||||
prevPt.removeProfileType();
|
||||
}
|
||||
}
|
||||
ctx.removePoint(position, true);
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redo() {
|
||||
getEditingCtx().addPoint(position, point);
|
||||
getEditingCtx().addPoint(position, point, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER);
|
||||
refreshMap();
|
||||
measurementLayer.moveMapToPoint(position);
|
||||
}
|
||||
|
|
|
@ -1,24 +1,36 @@
|
|||
package net.osmand.plus.measurementtool.command;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolLayer;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
|
||||
|
||||
private ApplicationMode mode;
|
||||
private GpxRouteApproximation approximation;
|
||||
private List<WptPt> points;
|
||||
private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData;
|
||||
private List<GpxRouteApproximation> approximations;
|
||||
private List<List<WptPt>> segmentPointsList;
|
||||
private final List<List<WptPt>> originalSegmentPointsList;
|
||||
|
||||
public ApplyGpxApproximationCommand(MeasurementToolLayer measurementLayer, GpxRouteApproximation approximation, ApplicationMode mode) {
|
||||
public ApplyGpxApproximationCommand(MeasurementToolLayer measurementLayer,
|
||||
List<GpxRouteApproximation> approximations,
|
||||
List<List<WptPt>> segmentPointsList, ApplicationMode mode) {
|
||||
super(measurementLayer);
|
||||
this.approximation = approximation;
|
||||
this.approximations = approximations;
|
||||
this.segmentPointsList = segmentPointsList;
|
||||
this.originalSegmentPointsList = new ArrayList<>(segmentPointsList);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
|
@ -26,6 +38,10 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
|
|||
return points;
|
||||
}
|
||||
|
||||
public List<List<WptPt>> getOriginalSegmentPointsList() {
|
||||
return originalSegmentPointsList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeasurementCommandType getType() {
|
||||
return MeasurementCommandType.APPROXIMATE_POINTS;
|
||||
|
@ -33,8 +49,9 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
|
|||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
List<WptPt> pts = getEditingCtx().getPoints();
|
||||
points = new ArrayList<>(pts);
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
points = new ArrayList<>(ctx.getPoints());
|
||||
roadSegmentData = ctx.getRoadSegmentData();
|
||||
applyApproximation();
|
||||
refreshMap();
|
||||
return true;
|
||||
|
@ -44,7 +61,7 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
|
|||
public boolean update(@NonNull Command command) {
|
||||
if (command instanceof ApplyGpxApproximationCommand) {
|
||||
ApplyGpxApproximationCommand approxCommand = (ApplyGpxApproximationCommand) command;
|
||||
approximation = approxCommand.approximation;
|
||||
approximations = approxCommand.approximations;
|
||||
mode = approxCommand.mode;
|
||||
applyApproximation();
|
||||
refreshMap();
|
||||
|
@ -55,10 +72,12 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
|
|||
|
||||
@Override
|
||||
public void undo() {
|
||||
getEditingCtx().resetAppMode();
|
||||
getEditingCtx().clearSegments();
|
||||
getEditingCtx().addPoints(points);
|
||||
getEditingCtx().updateCacheForSnap();
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
ctx.resetAppMode();
|
||||
ctx.clearSegments();
|
||||
ctx.setRoadSegmentData(roadSegmentData);
|
||||
ctx.addPoints(points);
|
||||
segmentPointsList = new ArrayList<>(originalSegmentPointsList);
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
|
@ -69,8 +88,15 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
|
|||
}
|
||||
|
||||
public void applyApproximation() {
|
||||
getEditingCtx().setAppMode(mode);
|
||||
getEditingCtx().clearSegments();
|
||||
getEditingCtx().setPoints(approximation, mode);
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
ctx.setAppMode(mode);
|
||||
for (int i = 0; i < approximations.size(); i++) {
|
||||
GpxRouteApproximation approximation = approximations.get(i);
|
||||
List<WptPt> segmentPoints = segmentPointsList.get(i);
|
||||
List<WptPt> newSegmentPoints = ctx.setPoints(approximation, segmentPoints, mode);
|
||||
if (newSegmentPoints != null) {
|
||||
segmentPointsList.set(i, newSegmentPoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
|
|||
editingCtx.addPoints(oldPoints);
|
||||
editingCtx.setAppMode(oldMode);
|
||||
editingCtx.setRoadSegmentData(oldRoadSegmentData);
|
||||
editingCtx.updateCacheForSnap();
|
||||
editingCtx.updateSegmentsForSnap();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,14 +146,16 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
|
|||
if (newRoadSegmentData != null) {
|
||||
editingCtx.setRoadSegmentData(newRoadSegmentData);
|
||||
}
|
||||
editingCtx.updateCacheForSnap();
|
||||
editingCtx.updateSegmentsForSnap();
|
||||
}
|
||||
|
||||
private void updateProfileType(WptPt pt) {
|
||||
if (!pt.isGap()) {
|
||||
if (newMode != null && newMode != DEFAULT_APP_MODE) {
|
||||
pt.setProfileType(newMode.getStringKey());
|
||||
} else {
|
||||
pt.removeProfileType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
package net.osmand.plus.measurementtool.command;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolLayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClearPointsCommand extends MeasurementModeCommand {
|
||||
|
||||
private List<WptPt> points;
|
||||
private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData;
|
||||
private ClearCommandMode clearMode;
|
||||
private int pointPosition;
|
||||
|
||||
|
@ -31,27 +37,30 @@ public class ClearPointsCommand extends MeasurementModeCommand {
|
|||
}
|
||||
|
||||
private void executeCommand() {
|
||||
List<WptPt> pts = getEditingCtx().getPoints();
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
List<WptPt> pts = ctx.getPoints();
|
||||
points = new ArrayList<>(pts);
|
||||
roadSegmentData = ctx.getRoadSegmentData();
|
||||
switch (clearMode) {
|
||||
case ALL:
|
||||
pts.clear();
|
||||
getEditingCtx().clearSegments();
|
||||
ctx.clearSegments();
|
||||
break;
|
||||
case BEFORE:
|
||||
getEditingCtx().trimBefore(pointPosition);
|
||||
ctx.trimBefore(pointPosition);
|
||||
break;
|
||||
case AFTER:
|
||||
getEditingCtx().trimAfter(pointPosition);
|
||||
ctx.trimAfter(pointPosition);
|
||||
}
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undo() {
|
||||
getEditingCtx().clearSegments();
|
||||
getEditingCtx().addPoints(points);
|
||||
getEditingCtx().updateCacheForSnap();
|
||||
MeasurementEditingContext ctx = getEditingCtx();
|
||||
ctx.clearSegments();
|
||||
ctx.setRoadSegmentData(roadSegmentData);
|
||||
ctx.addPoints(points);
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,6 @@ public class MeasurementCommandManager {
|
|||
}
|
||||
|
||||
public MeasurementModeCommand getLastCommand() {
|
||||
return undoCommands.getLast();
|
||||
return undoCommands.getFirst();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ public class RemovePointCommand extends MeasurementModeCommand {
|
|||
|
||||
private final int position;
|
||||
private WptPt point;
|
||||
private String prevPointProfile;
|
||||
|
||||
public RemovePointCommand(MeasurementToolLayer measurementLayer, int position) {
|
||||
super(measurementLayer);
|
||||
|
@ -15,6 +16,9 @@ public class RemovePointCommand extends MeasurementModeCommand {
|
|||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
if (position > 0) {
|
||||
prevPointProfile = getEditingCtx().getPoints().get(position - 1).getProfileType();
|
||||
}
|
||||
point = getEditingCtx().removePoint(position, true);
|
||||
refreshMap();
|
||||
return true;
|
||||
|
@ -22,6 +26,14 @@ public class RemovePointCommand extends MeasurementModeCommand {
|
|||
|
||||
@Override
|
||||
public void undo() {
|
||||
if (position > 0) {
|
||||
WptPt prevPt = getEditingCtx().getPoints().get(position - 1);
|
||||
if (prevPointProfile != null) {
|
||||
prevPt.setProfileType(prevPointProfile);
|
||||
} else {
|
||||
prevPt.removeProfileType();
|
||||
}
|
||||
}
|
||||
getEditingCtx().addPoint(position, point);
|
||||
refreshMap();
|
||||
measurementLayer.moveMapToPoint(position);
|
||||
|
|
|
@ -18,7 +18,7 @@ public class ReorderPointCommand extends MeasurementModeCommand {
|
|||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
getEditingCtx().updateCacheForSnap();
|
||||
getEditingCtx().updateSegmentsForSnap();
|
||||
refreshMap();
|
||||
return true;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class ReorderPointCommand extends MeasurementModeCommand {
|
|||
private void reorder(int addTo, int removeFrom) {
|
||||
List<WptPt> points = getEditingCtx().getPoints();
|
||||
points.add(addTo, points.remove(removeFrom));
|
||||
getEditingCtx().updateCacheForSnap();
|
||||
getEditingCtx().updateSegmentsForSnap();
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class ReversePointsCommand extends MeasurementModeCommand {
|
|||
WptPt lastPoint = newPoints.get(newPoints.size() - 1);
|
||||
editingCtx.setAppMode(ApplicationMode.valueOfStringKey(lastPoint.getProfileType(), DEFAULT_APP_MODE));
|
||||
}
|
||||
editingCtx.updateCacheForSnap();
|
||||
editingCtx.updateSegmentsForSnap();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -57,7 +57,7 @@ public class ReversePointsCommand extends MeasurementModeCommand {
|
|||
editingCtx.addPoints(oldPoints);
|
||||
editingCtx.setAppMode(oldMode);
|
||||
editingCtx.setRoadSegmentData(oldRoadSegmentData);
|
||||
editingCtx.updateCacheForSnap();
|
||||
editingCtx.updateSegmentsForSnap();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -50,14 +50,13 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
|
|||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.TrackActivity;
|
||||
import net.osmand.plus.dialogs.GpxAppearanceAdapter;
|
||||
import net.osmand.plus.measurementtool.GpxData;
|
||||
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.track.GpxSplitType;
|
||||
import net.osmand.plus.track.SplitTrackAsyncTask;
|
||||
import net.osmand.plus.track.SplitTrackAsyncTask.SplitTrackListener;
|
||||
|
@ -918,17 +917,10 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
|||
}
|
||||
}
|
||||
|
||||
public void addNewGpxData(GpxData.ActionType actionType) {
|
||||
public void addNewGpxData() {
|
||||
TrackActivity activity = getTrackActivity();
|
||||
if (activity != null) {
|
||||
activity.addNewGpxData(actionType);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNewGpxData(GpxData.ActionType actionType, GPXUtilities.TrkSegment segment) {
|
||||
TrackActivity activity = getTrackActivity();
|
||||
if (activity != null) {
|
||||
activity.addNewGpxData(actionType, segment);
|
||||
activity.addNewGpxData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -951,10 +943,8 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
|||
PointDescription pointWptDescription =
|
||||
new PointDescription(PointDescription.POINT_TYPE_WPT, app.getString(R.string.add_waypoint));
|
||||
addPoint(pointWptDescription);
|
||||
} else if (i == R.id.route_text_layout || i == R.id.route_fab) {
|
||||
addNewGpxData(GpxData.ActionType.ADD_ROUTE_POINTS);
|
||||
} else if (i == R.id.line_text_layout || i == R.id.line_fab) {
|
||||
addNewGpxData(GpxData.ActionType.ADD_SEGMENT);
|
||||
} else if (i == R.id.route_text_layout || i == R.id.route_fab || i == R.id.line_fab) {
|
||||
addNewGpxData();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -65,11 +65,10 @@ import net.osmand.plus.helpers.GpxUiHelper;
|
|||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
||||
import net.osmand.plus.measurementtool.GpxData;
|
||||
import net.osmand.plus.track.SaveGpxAsyncTask;
|
||||
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
||||
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.track.SaveGpxAsyncTask;
|
||||
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider;
|
||||
import net.osmand.plus.views.controls.WrapContentHeightViewPager;
|
||||
|
@ -1026,7 +1025,7 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
|
|||
private void editSegment() {
|
||||
TrkSegment segment = getTrkSegment();
|
||||
if (segment != null && fragmentAdapter != null) {
|
||||
fragmentAdapter.addNewGpxData(GpxData.ActionType.EDIT_SEGMENT, segment);
|
||||
fragmentAdapter.addNewGpxData();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package net.osmand.plus.routepreparationmenu;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
@ -16,6 +19,7 @@ import android.view.ViewGroup.MarginLayoutParams;
|
|||
import android.view.ViewTreeObserver.OnScrollChangedListener;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -24,7 +28,6 @@ import androidx.fragment.app.FragmentManager;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -44,7 +47,6 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
|
|||
import net.osmand.plus.importfiles.ImportHelper;
|
||||
import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener;
|
||||
import net.osmand.plus.measurementtool.GpxData;
|
||||
import net.osmand.plus.measurementtool.GpxData.ActionType;
|
||||
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.LocalRoutingParameter;
|
||||
|
@ -86,6 +88,8 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
|
||||
private GPXFile gpxFile;
|
||||
|
||||
private View buttonsShadow;
|
||||
|
||||
private boolean editingTrack;
|
||||
private boolean selectingTrack;
|
||||
private int menuTitleHeight;
|
||||
|
@ -148,6 +152,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
if (view != null) {
|
||||
ImageButton closeButton = view.findViewById(R.id.close_button);
|
||||
buttonsShadow = view.findViewById(R.id.buttons_shadow);
|
||||
closeButton.setImageDrawable(getContentIcon(AndroidUtils.getNavigationIconResId(app)));
|
||||
closeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -174,6 +179,22 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
return view;
|
||||
}
|
||||
|
||||
private void showShadowButton() {
|
||||
buttonsShadow.setVisibility(View.VISIBLE);
|
||||
buttonsShadow.animate()
|
||||
.alpha(0.8f)
|
||||
.setDuration(200)
|
||||
.setListener(null);
|
||||
}
|
||||
|
||||
private void hideShadowButton() {
|
||||
buttonsShadow.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void setupCards() {
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
|
@ -554,10 +575,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null && gpxFile != null) {
|
||||
editingTrack = true;
|
||||
QuadRect rect = gpxFile.getRect();
|
||||
TrkSegment segment = gpxFile.getNonEmptyTrkSegment();
|
||||
ActionType actionType = segment == null ? ActionType.ADD_ROUTE_POINTS : ActionType.EDIT_SEGMENT;
|
||||
GpxData gpxData = new GpxData(gpxFile, rect, actionType, segment);
|
||||
GpxData gpxData = new GpxData(gpxFile);
|
||||
MeasurementEditingContext editingContext = new MeasurementEditingContext();
|
||||
editingContext.setGpxData(gpxData);
|
||||
editingContext.setAppMode(app.getRoutingHelper().getAppMode());
|
||||
|
@ -598,20 +616,16 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
|
|||
}
|
||||
|
||||
private void setupScrollShadow() {
|
||||
int shadowIconId = isNightMode() ? R.drawable.bg_contextmenu_shadow : R.drawable.bg_contextmenu_shadow;
|
||||
final Drawable shadowIcon = app.getUIUtilities().getIcon(shadowIconId);
|
||||
|
||||
final View scrollView = getBottomScrollView();
|
||||
final FrameLayout bottomContainer = getBottomContainer();
|
||||
scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
|
||||
|
||||
@Override
|
||||
public void onScrollChanged() {
|
||||
int scrollY = scrollView.getScrollY();
|
||||
if (scrollY <= 0 && bottomContainer.getForeground() != null) {
|
||||
bottomContainer.setForeground(null);
|
||||
} else if (scrollY > 0 && bottomContainer.getForeground() == null) {
|
||||
bottomContainer.setForeground(shadowIcon);
|
||||
boolean scrollToBottomAvailable = scrollView.canScrollVertically(1);
|
||||
if (scrollToBottomAvailable) {
|
||||
showShadowButton();
|
||||
} else {
|
||||
hideShadowButton();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,28 +1,23 @@
|
|||
package net.osmand.plus.routing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.LocationsHolder;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.measurementtool.GpxApproximationFragment;
|
||||
import net.osmand.plus.routing.RouteProvider.RoutingEnvironment;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.router.RouteCalculationProgress;
|
||||
import net.osmand.router.RoutePlannerFrontEnd;
|
||||
import net.osmand.router.RoutePlannerFrontEnd.GpxPoint;
|
||||
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -31,29 +26,31 @@ public class GpxApproximator {
|
|||
|
||||
protected static final Log log = PlatformUtil.getLog(GpxApproximator.class);
|
||||
|
||||
private OsmandApplication ctx;
|
||||
private RoutingHelper routingHelper;
|
||||
private final OsmandApplication ctx;
|
||||
private final RoutingHelper routingHelper;
|
||||
|
||||
private RoutingEnvironment env;
|
||||
private GpxRouteApproximation gctx;
|
||||
private ApplicationMode mode;
|
||||
private LocationsHolder locationsHolder;
|
||||
private final LocationsHolder locationsHolder;
|
||||
private List<GpxPoint> points;
|
||||
private LatLon start;
|
||||
private LatLon end;
|
||||
private double pointApproximation = 50;
|
||||
private Runnable approximationTask;
|
||||
|
||||
private static final ThreadPoolExecutor SINGLE_THREAD_EXECUTOR
|
||||
= new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());;
|
||||
|
||||
private ThreadPoolExecutor singleThreadedExecutor;
|
||||
private GpxApproximationProgressCallback approximationProgress;
|
||||
private Future<?> currentApproximationTask;
|
||||
|
||||
public interface GpxApproximationProgressCallback {
|
||||
|
||||
void start();
|
||||
void start(GpxApproximator approximator);
|
||||
|
||||
void updateProgress(int progress);
|
||||
void updateProgress(GpxApproximator approximator, int progress);
|
||||
|
||||
void finish();
|
||||
void finish(GpxApproximator approximator);
|
||||
}
|
||||
|
||||
public GpxApproximator(@NonNull OsmandApplication ctx, @NonNull LocationsHolder locationsHolder) throws IOException {
|
||||
|
@ -61,12 +58,7 @@ public class GpxApproximator {
|
|||
this.locationsHolder = locationsHolder;
|
||||
this.routingHelper = ctx.getRoutingHelper();
|
||||
this.mode = ApplicationMode.CAR;
|
||||
if (locationsHolder.getSize() > 1) {
|
||||
start = locationsHolder.getLatLon(0);
|
||||
end = locationsHolder.getLatLon(locationsHolder.getSize() - 1);
|
||||
prepareEnvironment(ctx, mode);
|
||||
}
|
||||
init();
|
||||
initEnvironment(mode, locationsHolder);
|
||||
}
|
||||
|
||||
public GpxApproximator(@NonNull OsmandApplication ctx, @NonNull ApplicationMode mode, double pointApproximation, @NonNull LocationsHolder locationsHolder) throws IOException {
|
||||
|
@ -75,16 +67,15 @@ public class GpxApproximator {
|
|||
this.pointApproximation = pointApproximation;
|
||||
this.routingHelper = ctx.getRoutingHelper();
|
||||
this.mode = mode;
|
||||
initEnvironment(mode, locationsHolder);
|
||||
}
|
||||
|
||||
private void initEnvironment(@NonNull ApplicationMode mode, @NonNull LocationsHolder locationsHolder) throws IOException {
|
||||
if (locationsHolder.getSize() > 1) {
|
||||
start = locationsHolder.getLatLon(0);
|
||||
end = locationsHolder.getLatLon(locationsHolder.getSize() - 1);
|
||||
prepareEnvironment(ctx, mode);
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
|
||||
}
|
||||
|
||||
private void prepareEnvironment(@NonNull OsmandApplication ctx, @NonNull ApplicationMode mode) throws IOException {
|
||||
|
@ -140,6 +131,10 @@ public class GpxApproximator {
|
|||
this.approximationProgress = approximationProgress;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return gctx != null && gctx.ctx.calculationProgress.isCancelled;
|
||||
}
|
||||
|
||||
public void cancelApproximation() {
|
||||
if (gctx != null) {
|
||||
gctx.ctx.calculationProgress.isCancelled = true;
|
||||
|
@ -154,10 +149,7 @@ public class GpxApproximator {
|
|||
this.gctx = gctx;
|
||||
startProgress();
|
||||
updateProgress(gctx);
|
||||
if (currentApproximationTask != null) {
|
||||
currentApproximationTask.cancel(true);
|
||||
}
|
||||
currentApproximationTask = singleThreadedExecutor.submit(new Runnable() {
|
||||
approximationTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
@ -166,21 +158,23 @@ public class GpxApproximator {
|
|||
resultMatcher.publish(null);
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
approximationTask = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
SINGLE_THREAD_EXECUTOR.submit(approximationTask);
|
||||
}
|
||||
|
||||
private void startProgress() {
|
||||
final GpxApproximationProgressCallback approximationProgress = this.approximationProgress;
|
||||
if (approximationProgress != null) {
|
||||
approximationProgress.start();
|
||||
approximationProgress.start(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void finishProgress() {
|
||||
final GpxApproximationProgressCallback approximationProgress = this.approximationProgress;
|
||||
if (approximationProgress != null) {
|
||||
approximationProgress.finish();
|
||||
approximationProgress.finish(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,15 +186,13 @@ public class GpxApproximator {
|
|||
@Override
|
||||
public void run() {
|
||||
RouteCalculationProgress calculationProgress = gctx.ctx.calculationProgress;
|
||||
if (!gctx.result.isEmpty() && GpxApproximator.this.gctx == gctx) {
|
||||
if (approximationTask == null && GpxApproximator.this.gctx == gctx) {
|
||||
finishProgress();
|
||||
}
|
||||
if (gctx.result.isEmpty() && calculationProgress != null && !calculationProgress.isCancelled) {
|
||||
if (approximationTask != null && calculationProgress != null && !calculationProgress.isCancelled) {
|
||||
float pr = calculationProgress.getLinearProgress();
|
||||
approximationProgress.updateProgress((int) pr);
|
||||
if (GpxApproximator.this.gctx != gctx) {
|
||||
// different calculation started
|
||||
} else {
|
||||
approximationProgress.updateProgress(GpxApproximator.this, (int) pr);
|
||||
if (GpxApproximator.this.gctx == gctx) {
|
||||
updateProgress(gctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ public class ApplicationMode {
|
|||
public static final ApplicationMode DEFAULT = createBase(R.string.app_mode_default, "default")
|
||||
.icon(R.drawable.ic_world_globe_dark).reg();
|
||||
|
||||
public static final ApplicationMode GAP = new ApplicationMode(R.string.app_mode_gap, "gap");
|
||||
|
||||
public static final ApplicationMode CAR = createBase(R.string.app_mode_car, "car")
|
||||
.icon(R.drawable.ic_action_car_dark)
|
||||
|
|
|
@ -899,7 +899,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
|
|||
}
|
||||
|
||||
public static boolean showInstance(FragmentActivity activity, SettingsScreenType screenType, @Nullable ApplicationMode appMode) {
|
||||
return showInstance(activity, screenType, null, new Bundle());
|
||||
return showInstance(activity, screenType, appMode, new Bundle());
|
||||
}
|
||||
|
||||
public static boolean showInstance(FragmentActivity activity, SettingsScreenType screenType,
|
||||
|
|
|
@ -475,24 +475,33 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
|||
AndroidUiHelper.updateVisibility(saveButton, true);
|
||||
AndroidUiHelper.updateVisibility(view.findViewById(R.id.buttons_divider), true);
|
||||
}
|
||||
private void showShadowButton() {
|
||||
buttonsShadow.setVisibility(View.VISIBLE);
|
||||
buttonsShadow.animate()
|
||||
.alpha(0.8f)
|
||||
.setDuration(200)
|
||||
.setListener(null);
|
||||
}
|
||||
|
||||
private void hideShadowButton() {
|
||||
buttonsShadow.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(200);
|
||||
|
||||
}
|
||||
|
||||
private void setupScrollShadow() {
|
||||
int shadowIconId = isNightMode() ? R.drawable.bg_contextmenu_shadow : R.drawable.bg_contextmenu_shadow;
|
||||
final Drawable shadowIcon = app.getUIUtilities().getIcon(shadowIconId);
|
||||
|
||||
final View scrollView = getBottomScrollView();
|
||||
final FrameLayout bottomContainer = getBottomContainer();
|
||||
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
|
||||
|
||||
@Override
|
||||
public void onScrollChanged() {
|
||||
int scrollY = scrollView.getScrollY();
|
||||
if (scrollY <= 0 && bottomContainer.getForeground() != null) {
|
||||
bottomContainer.setForeground(null);
|
||||
} else if (scrollY > 0 && bottomContainer.getForeground() == null) {
|
||||
bottomContainer.setForeground(shadowIcon);
|
||||
boolean scrollToBottomAvailable = scrollView.canScrollVertically(1);
|
||||
if (scrollToBottomAvailable) {
|
||||
showShadowButton();
|
||||
} else {
|
||||
hideShadowButton();
|
||||
}
|
||||
updateButtonsShadow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue