Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2014-03-02 18:51:04 +01:00
commit 81ed287193
7 changed files with 226 additions and 73 deletions

View file

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.List;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree;
@ -42,6 +43,11 @@ public class PrecalculatedRouteDirection {
init(ls);
}
private PrecalculatedRouteDirection(LatLon[] ls, float maxSpeed) {
this.maxSpeed = maxSpeed;
init(ls);
}
private PrecalculatedRouteDirection(PrecalculatedRouteDirection parent, int s1, int s2) {
this.minSpeed = parent.minSpeed;
this.maxSpeed = parent.maxSpeed;
@ -81,6 +87,10 @@ public class PrecalculatedRouteDirection {
return null;
}
public static PrecalculatedRouteDirection build(LatLon[] ls, float maxSpeed){
return new PrecalculatedRouteDirection(ls, maxSpeed);
}
private void init(List<RouteSegmentResult> ls) {
TIntArrayList px = new TIntArrayList();
@ -104,6 +114,19 @@ public class PrecalculatedRouteDirection {
}
init(px, py, speedSegments);
}
private void init(LatLon[] ls) {
TIntArrayList px = new TIntArrayList();
TIntArrayList py = new TIntArrayList();
List<Float> speedSegments = new ArrayList<Float>();
for (LatLon s : ls) {
float routeSpd = maxSpeed; // (s.getDistance() / s.getRoutingTime())
px.add(MapUtils.get31TileNumberX(s.getLongitude()));
py.add(MapUtils.get31TileNumberY(s.getLatitude()));
speedSegments.add(routeSpd);
}
init(px, py, speedSegments);
}
private void init(TIntArrayList px, TIntArrayList py, List<Float> speedSegments) {
float totaltm = 0;

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
<string name="calculate_osmand_route_gpx">Calculate OsmAnd offline route</string>
<string name="app_mode_truck">Truck</string>
<string name="guidance_preferences_descr">Navigation preferences</string>
<string name="routing_preferences_descr">Routing preferences</string>

View file

@ -8,8 +8,8 @@ import net.osmand.CallbackWithObject;
import net.osmand.Location;
import net.osmand.access.AccessibleToast;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@ -72,8 +72,11 @@ public class OsmAndLocationSimulation {
new CallbackWithObject<GPXUtilities.GPXFile>() {
@Override
public boolean processResult(GPXUtilities.GPXFile result) {
GPXRouteParams prms = new RouteProvider.GPXRouteParams(result, false, ch
.isChecked(), app.getSettings());
GPXRouteParamsBuilder builder = GPXRouteParams.GPXRouteParamsBuilder.newBuilder(result, app.getSettings());
if(ch.isChecked()){
builder.announceWaypoints();
}
GPXRouteParams prms = builder.build();
startAnimationThread(app.getRoutingHelper(), ma, prms.getPoints(), true,
speedup.getProgress() + 1);
return true;

View file

@ -739,6 +739,7 @@ public class OsmandSettings {
public final OsmandPreference<Boolean> SPEAK_SPEED_LIMIT = new BooleanPreference("speak_speed_limit", true).makeProfile().cache();
public final OsmandPreference<Boolean> SPEAK_GPX_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache();
public final OsmandPreference<Boolean> CALC_GPX_ROUTE = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache();

View file

@ -19,6 +19,7 @@ import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams.GPXRouteParamsBuilder;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@ -66,10 +67,11 @@ public class NavigateAction {
public boolean navigateUsingGPX(final ApplicationMode appMode, final LatLon endForRouting,
final GPXFile result) {
Builder builder = new AlertDialog.Builder(mapActivity);
final boolean[] props = new boolean[]{false, false, false, settings.SPEAK_GPX_WPT.get()};
final boolean[] props = new boolean[]{false, false, false, settings.SPEAK_GPX_WPT.get(), settings.CALC_GPX_ROUTE.get()};
builder.setMultiChoiceItems(new String[] { getString(R.string.gpx_option_reverse_route),
getString(R.string.gpx_option_destination_point), getString(R.string.gpx_option_from_start_point),
getString(R.string.announce_gpx_waypoints) }, props,
getString(R.string.announce_gpx_waypoints),
getString(R.string.calculate_osmand_route_gpx)}, props,
new OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
@ -83,9 +85,20 @@ public class NavigateAction {
boolean passWholeWay = props[2];
boolean useDestination = props[1];
boolean announceGpxWpt = props[3];
boolean calculateOsmAndRoute = props[4];
settings.SPEAK_GPX_WPT.set(announceGpxWpt);
GPXRouteParams gpxRoute = new GPXRouteParams(result, reverse, announceGpxWpt, settings);
settings.CALC_GPX_ROUTE.set(calculateOsmAndRoute);
GPXRouteParamsBuilder bld = GPXRouteParamsBuilder.newBuilder(result, settings);
if(reverse) {
bld.reverse();
}
if(announceGpxWpt) {
bld.announceWaypoints();
}
if(calculateOsmAndRoute) {
bld.calculateOsmAndRoute();
}
GPXRouteParams gpxRoute = bld.build();
Location loc = getLastKnownLocation();
if(passWholeWay && loc != null){
gpxRoute.setStartPoint(loc);

View file

@ -16,6 +16,7 @@ import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams.GPXRouteParamsBuilder;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
@ -123,14 +124,26 @@ public class FailSafeFuntions {
@Override
protected void onPostExecute(GPXFile result) {
final GPXRouteParams gpxRoute = result == null ? null : new GPXRouteParams(result, false,
settings.SPEAK_GPX_WPT.get(), settings);
final GPXRouteParams gpxRoute;
if (result != null) {
GPXRouteParamsBuilder builder = GPXRouteParamsBuilder.newBuilder(result, settings);
if (settings.SPEAK_GPX_WPT.get()) {
builder.announceWaypoints();
}
if(settings.CALC_GPX_ROUTE.get()) {
builder.calculateOsmAndRoute();
}
gpxRoute = builder.build();
} else {
gpxRoute = null;
}
LatLon endPoint = pointToNavigate != null ? pointToNavigate : gpxRoute.getLastPoint();
net.osmand.Location startPoint = gpxRoute == null ? null : gpxRoute.getStartPointForRoute();
if (endPoint == null) {
notRestoreRoutingMode(ma, app);
} else {
ma.followRoute(settings.getApplicationMode(), endPoint, targetPoints.getIntermediatePoints(), startPoint, gpxRoute);
ma.followRoute(settings.getApplicationMode(), endPoint,
targetPoints.getIntermediatePoints(), startPoint, gpxRoute);
}
}
};

View file

@ -3,6 +3,7 @@ package net.osmand.plus.routing;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
@ -48,6 +49,7 @@ import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.GeneralRouter.RoutingParameter;
import net.osmand.router.GeneralRouter.RoutingParameterType;
import net.osmand.router.PrecalculatedRouteDirection;
import net.osmand.router.RoutePlannerFrontEnd;
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
import net.osmand.router.RouteSegmentResult;
@ -115,9 +117,9 @@ public class RouteProvider {
List<Location> points = new ArrayList<Location>();
List<RouteDirectionInfo> directions;
DataTileManager<WptPt> wpt;
boolean calculateOsmAndRoute = false;
public GPXRouteParams(GPXFile file, boolean reverse, boolean announceWaypoints, OsmandSettings settings){
prepareEverything(file, reverse, announceWaypoints, settings.DRIVING_REGION.get().leftHandDriving);
private GPXRouteParams(){
}
public void setStartPoint(Location startPoint) {
@ -144,6 +146,45 @@ public class RouteProvider {
return null;
}
public static class GPXRouteParamsBuilder {
private GPXRouteParams obj = new GPXRouteParams();
private GPXFile file;
private boolean leftHandDriving;
private boolean reverse;
private boolean announceWaypoints;
private GPXRouteParamsBuilder(GPXFile f, OsmandSettings settings) {
this.file = f;
leftHandDriving = settings.DRIVING_REGION.get().leftHandDriving;
// obj = new GPXRouteParams(file, reverse, announceWaypoints, settings)
// TODO Auto-generated constructor stub
}
public GPXRouteParamsBuilder reverse() {
this.reverse = true;
return this;
}
public GPXRouteParamsBuilder announceWaypoints() {
this.announceWaypoints = true;
return this;
}
public GPXRouteParamsBuilder calculateOsmAndRoute() {
obj.calculateOsmAndRoute = true;
return this;
}
public static GPXRouteParamsBuilder newBuilder(GPXFile f, OsmandSettings settings) {
return new GPXRouteParamsBuilder(f, settings);
}
public GPXRouteParams build(){
obj.prepareEverything(file, reverse, announceWaypoints, leftHandDriving);
return obj;
}
}
private void prepareEverything(GPXFile file, boolean reverse, boolean announceWaypoints, boolean leftSide){
if(file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)){
directions = parseCloudmadeRoute(points, file, OSMAND_ROUTER.equals(file.author), leftSide, 10);
@ -210,7 +251,10 @@ public class RouteProvider {
}
try {
RouteCalculationResult res;
if(params.gpxRoute != null && !params.gpxRoute.points.isEmpty()){
boolean calcGPXRoute = params.gpxRoute != null && !params.gpxRoute.points.isEmpty();
if (params.type == RouteService.OSMAND || (calcGPXRoute && params.gpxRoute.calculateOsmAndRoute)) {
res = findVectorMapsRoute(params, calcGPXRoute);
} else if(calcGPXRoute){
res = calculateGpxRoute(params);
} else if (params.type == RouteService.YOURS) {
res = findYOURSRoute(params);
@ -218,8 +262,6 @@ public class RouteProvider {
res = findORSRoute(params);
} else if (params.type == RouteService.OSRM) {
res = findOSRMRoute(params);
} else if (params.type == RouteService.OSMAND) {
res = findVectorMapsRoute(params);
} else if (params.type == RouteService.BROUTER) {
res = findBROUTERRoute(params);
} else {
@ -246,45 +288,20 @@ public class RouteProvider {
private RouteCalculationResult calculateGpxRoute(RouteCalculationParams pars) {
RouteCalculationResult res;
// get the closest point to start and to end
float minDist = Integer.MAX_VALUE;
int startI = 0;
GPXRouteParams params = pars.gpxRoute;
List<Location> gpxRoute = params.points;
int endI = gpxRoute.size();
if (pars.start != null) {
for (int i = 0; i < gpxRoute.size(); i++) {
float d = gpxRoute.get(i).distanceTo(pars.start);
if (d < minDist) {
startI = i;
minDist = d;
}
}
} else {
pars.start = gpxRoute.get(0);
}
Location l = new Location("temp"); //$NON-NLS-1$
l.setLatitude(pars.end.getLatitude());
l.setLongitude(pars.end.getLongitude());
minDist = Integer.MAX_VALUE;
// get in reverse order taking into account ways with cycle
for (int i = gpxRoute.size() - 1; i >= startI; i--) {
float d = gpxRoute.get(i).distanceTo(l);
if (d < minDist) {
endI = i + 1;
// slightly modify to allow last point to be added
minDist = d - 40;
}
}
ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(startI, endI));
int[] startI = new int[]{0};
int[] endI = new int[]{gpxRoute.size()};
ArrayList<Location> sublist = findGpxLocations(pars, startI, endI);
pars.intermediates = null;
if(params.directions == null){
res = new RouteCalculationResult(sublist, null, pars, params.wpt);
} else {
List<RouteDirectionInfo> subdirections = new ArrayList<RouteDirectionInfo>();
for (RouteDirectionInfo info : params.directions) {
if(info.routePointOffset >= startI && info.routePointOffset < endI){
if(info.routePointOffset >= startI[0] && info.routePointOffset < endI[0]){
RouteDirectionInfo ch = new RouteDirectionInfo(info.getAverageSpeed(), info.getTurnType());
ch.routePointOffset = info.routePointOffset - startI;
ch.routePointOffset = info.routePointOffset - startI[0];
ch.setDescriptionRoute(info.getDescriptionRoute());
// recalculate
@ -297,6 +314,49 @@ public class RouteProvider {
}
return res;
}
private ArrayList<Location> findGpxLocations(RouteCalculationParams pars, int[] startI, int[] endI) {
GPXRouteParams params = pars.gpxRoute;
List<Location> gpxRoute = params.points;
float minDist = Integer.MAX_VALUE;
int start = 0;
int end = gpxRoute.size();
if (pars.start != null) {
for (int i = 0; i < gpxRoute.size(); i++) {
float d = gpxRoute.get(i).distanceTo(pars.start);
if (d < minDist) {
start = i;
minDist = d;
}
}
} else {
pars.start = gpxRoute.get(0);
}
Location l = new Location("temp"); //$NON-NLS-1$
l.setLatitude(pars.end.getLatitude());
l.setLongitude(pars.end.getLongitude());
minDist = Integer.MAX_VALUE;
// get in reverse order taking into account ways with cycle
for (int i = gpxRoute.size() - 1; i >= start; i--) {
float d = gpxRoute.get(i).distanceTo(l);
if (d < minDist) {
end = i + 1;
// slightly modify to allow last point to be added
minDist = d - 40;
}
}
ArrayList<Location> sublist = new ArrayList<Location>(gpxRoute.subList(start, end));
if(startI != null) {
startI[0] = start;
}
if(endI != null) {
endI[0] = end;
}
return sublist;
}
protected String getString(ClientContext ctx, int resId){
if(ctx == null){
@ -370,10 +430,65 @@ public class RouteProvider {
return new RouteCalculationResult(res, null, params, null);
}
protected RouteCalculationResult findVectorMapsRoute(final RouteCalculationParams params) throws IOException {
protected RouteCalculationResult findVectorMapsRoute(final RouteCalculationParams params, boolean calcGPXRoute) throws IOException {
BinaryMapIndexReader[] files = params.ctx.getTodoAPI().getRoutingMapFiles();
RoutePlannerFrontEnd router = new RoutePlannerFrontEnd(false);
OsmandSettings settings = params.ctx.getSettings();
GeneralRouter generalRouter = SettingsNavigationActivity.getRouter(params.mode);
if(generalRouter == null) {
return applicationModeNotSupported(params);
}
RoutingConfiguration cf = initOsmAndRoutingConfig(params, settings, generalRouter);
if(cf == null){
return applicationModeNotSupported(params);
}
PrecalculatedRouteDirection precalculated = null;
if(calcGPXRoute) {
ArrayList<Location> sublist = findGpxLocations(params, null, null);
LatLon[] latLon = new LatLon[sublist.size()];
for(int k = 0; k < latLon.length; k ++) {
latLon[k] = new LatLon(sublist.get(k).getLatitude(), sublist.get(k).getLongitude());
}
precalculated = PrecalculatedRouteDirection.build(latLon, generalRouter.getMaxDefaultSpeed());
cf.planRoadDirection = 1;
}
// BUILD context
RoutingContext ctx = router.buildRoutingContext(cf, params.ctx.getInternalAPI().getNativeLibrary(), files,
RouteCalculationMode.NORMAL);
RoutingContext complexCtx = null;
boolean complex = params.mode.isDerivedRoutingFrom(ApplicationMode.CAR) && !settings.DISABLE_COMPLEX_ROUTING.get()
&& precalculated == null;
if(complex) {
complexCtx = router.buildRoutingContext(cf, params.ctx.getInternalAPI().getNativeLibrary(), files,
RouteCalculationMode.COMPLEX);
complexCtx.calculationProgress = params.calculationProgress;
complexCtx.leftSideNavigation = params.leftSide;
}
if(precalculated != null) {
ctx.precalculatedRouteDirection = precalculated.adopt(ctx);
}
ctx.leftSideNavigation = params.leftSide;
ctx.calculationProgress = params.calculationProgress;
if(params.previousToRecalculate != null) {
// not used any more
// ctx.previouslyCalculatedRoute = params.previousToRecalculate.getOriginalRoute();
}
LatLon st = new LatLon(params.start.getLatitude(), params.start.getLongitude());
LatLon en = new LatLon(params.end.getLatitude(), params.end.getLongitude());
List<LatLon> inters = new ArrayList<LatLon>();
if (params.intermediates != null) {
inters = new ArrayList<LatLon>(params.intermediates);
}
return calcOfflineRouteImpl(params, router, ctx, complexCtx, st, en, inters);
}
private RoutingConfiguration initOsmAndRoutingConfig(final RouteCalculationParams params, OsmandSettings settings,
GeneralRouter generalRouter) throws IOException, FileNotFoundException {
File routingXml = params.ctx.getAppPath(IndexConstants.ROUTING_XML_FILE);
RoutingConfiguration.Builder config ;
if (routingXml.exists() && routingXml.canRead()) {
@ -393,12 +508,9 @@ public class RouteProvider {
} else if(params.mode.isDerivedRoutingFrom(ApplicationMode.CAR)){
p = GeneralRouterProfile.CAR;
} else {
return applicationModeNotSupported(params);
}
GeneralRouter generalRouter = SettingsNavigationActivity.getRouter(params.mode);
if(generalRouter == null) {
return applicationModeNotSupported(params);
return null;
}
Map<String, String> paramsR = new LinkedHashMap<String, String>();
for(Map.Entry<String, RoutingParameter> e : generalRouter.getParameters().entrySet()){
String key = e.getKey();
@ -427,28 +539,15 @@ public class RouteProvider {
RoutingConfiguration cf = config.build(p.name().toLowerCase(), params.start.hasBearing() ?
params.start.getBearing() / 180d * Math.PI : null,
memoryLimit, paramsR);
boolean complex = params.mode.isDerivedRoutingFrom(ApplicationMode.CAR) && !settings.DISABLE_COMPLEX_ROUTING.get();
RoutingContext ctx = router.buildRoutingContext(cf, params.ctx.getInternalAPI().getNativeLibrary(), files,
RouteCalculationMode.NORMAL);
RoutingContext complexCtx = null;
if(complex) {
complexCtx = router.buildRoutingContext(cf, params.ctx.getInternalAPI().getNativeLibrary(), files,
RouteCalculationMode.COMPLEX);
complexCtx.calculationProgress = params.calculationProgress;
complexCtx.leftSideNavigation = params.leftSide;
}
ctx.leftSideNavigation = params.leftSide;
ctx.calculationProgress = params.calculationProgress;
if(params.previousToRecalculate != null) {
// not used any more
// ctx.previouslyCalculatedRoute = params.previousToRecalculate.getOriginalRoute();
}
LatLon st = new LatLon(params.start.getLatitude(), params.start.getLongitude());
LatLon en = new LatLon(params.end.getLatitude(), params.end.getLongitude());
List<LatLon> inters = new ArrayList<LatLon>();
if (params.intermediates != null) {
inters = new ArrayList<LatLon>(params.intermediates);
}
return cf;
}
private RouteCalculationResult calcOfflineRouteImpl(final RouteCalculationParams params,
RoutePlannerFrontEnd router, RoutingContext ctx, RoutingContext complexCtx, LatLon st, LatLon en,
List<LatLon> inters) throws IOException {
try {
List<RouteSegmentResult> result ;
if(complexCtx != null) {