Skip to content

Commit

Permalink
Allow to navigate from outside the map.
Browse files Browse the repository at this point in the history
- Simple compass-direction-navigation while outside.
- Full navigation starts when entering map.
Enter correct lat lon for fromCurrentLocation.
  • Loading branch information
Starcommander committed Oct 7, 2018
1 parent e072058 commit dbfde54
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 72 deletions.
Expand Up @@ -380,8 +380,7 @@ private void initUseCurrentLocationHandler(final boolean isStartP, int viewID, f
if (MapActivity.getmCurrentLocation() != null) {
GeoPoint newPos = new GeoPoint(MapActivity.getmCurrentLocation().getLatitude(),
MapActivity.getmCurrentLocation().getLongitude());
String text = Destination.getDestination().getStartPointToString();
if (!isStartP) { text = Destination.getDestination().getEndPointToString(); }
String text = "" + newPos.getLatitude() + ", " + newPos.getLongitude();
doSelectCurrentPos(newPos, text, isStartP);
} else {
Toast.makeText(activity, "Current Location not available, Check your GPS signal!",
Expand Down Expand Up @@ -644,16 +643,17 @@ private void initTravelModeSetting() {
bikeBtn = (ImageButton) activity.findViewById(R.id.nav_settings_bike_btn);
carBtn = (ImageButton) activity.findViewById(R.id.nav_settings_car_btn);
// init travel mode
switch (Variable.getVariable().getTravelMode()) {
case "foot":
footBtn.setImageResource(R.drawable.ic_directions_walk_orange_24dp);
break;
case "bike":
bikeBtn.setImageResource(R.drawable.ic_directions_bike_orange_24dp);
break;
case "car":
carBtn.setImageResource(R.drawable.ic_directions_car_orange_24dp);
break;
if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Foot)
{
footBtn.setImageResource(R.drawable.ic_directions_walk_orange_24dp);
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Bike)
{
bikeBtn.setImageResource(R.drawable.ic_directions_bike_orange_24dp);
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Car)
{
carBtn.setImageResource(R.drawable.ic_directions_car_orange_24dp);
}

//foot
Expand All @@ -662,8 +662,8 @@ private void initTravelModeSetting() {
footBtn.setImageResource(R.drawable.ic_directions_walk_orange_24dp);
bikeBtn.setImageResource(R.drawable.ic_directions_bike_white_24dp);
carBtn.setImageResource(R.drawable.ic_directions_car_white_24dp);
if (!Variable.getVariable().getTravelMode().equalsIgnoreCase("foot")) {
Variable.getVariable().setTravelMode("foot");
if (Variable.getVariable().getTravelMode() != Variable.TravelMode.Foot) {
Variable.getVariable().setTravelMode(Variable.TravelMode.Foot);
if (activateNavigator())
{
MapHandler.getMapHandler().recalcPath();
Expand All @@ -677,8 +677,8 @@ private void initTravelModeSetting() {
footBtn.setImageResource(R.drawable.ic_directions_walk_white_24dp);
bikeBtn.setImageResource(R.drawable.ic_directions_bike_orange_24dp);
carBtn.setImageResource(R.drawable.ic_directions_car_white_24dp);
if (!Variable.getVariable().getTravelMode().equalsIgnoreCase("bike")) {
Variable.getVariable().setTravelMode("bike");
if (Variable.getVariable().getTravelMode() != Variable.TravelMode.Bike) {
Variable.getVariable().setTravelMode(Variable.TravelMode.Bike);
if (activateNavigator())
{
MapHandler.getMapHandler().recalcPath();
Expand All @@ -692,8 +692,8 @@ private void initTravelModeSetting() {
footBtn.setImageResource(R.drawable.ic_directions_walk_white_24dp);
bikeBtn.setImageResource(R.drawable.ic_directions_bike_white_24dp);
carBtn.setImageResource(R.drawable.ic_directions_car_orange_24dp);
if (!Variable.getVariable().getTravelMode().equalsIgnoreCase("car")) {
Variable.getVariable().setTravelMode("car");
if (Variable.getVariable().getTravelMode() != Variable.TravelMode.Car) {
Variable.getVariable().setTravelMode(Variable.TravelMode.Car);
if (activateNavigator())
{
MapHandler.getMapHandler().recalcPath();
Expand Down
Expand Up @@ -12,7 +12,6 @@
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.oscim.android.MapView;
import org.oscim.android.canvas.AndroidGraphics;
import org.oscim.backend.canvas.Bitmap;
Expand Down Expand Up @@ -48,6 +47,7 @@
import com.junjunguo.pocketmaps.R;
import com.junjunguo.pocketmaps.model.listeners.MapHandlerListener;
import com.junjunguo.pocketmaps.navigator.NaviEngine;
import com.junjunguo.pocketmaps.util.TargetDirComputer;
import com.junjunguo.pocketmaps.util.Variable;


Expand Down Expand Up @@ -406,17 +406,29 @@ public void calcPath(final double fromLat, final double fromLon,

@Override
protected GHResponse doInBackground(Void... v) {
StopWatch sw = new StopWatch().start();
GHRequest req = new GHRequest(fromLat, fromLon, toLat, toLon).
setAlgorithm(Algorithms.DIJKSTRA_BI);
req.getHints().put(Routing.INSTRUCTIONS, Variable.getVariable().getDirectionsON());
req.setVehicle(Variable.getVariable().getTravelMode());
req.setWeighting(Variable.getVariable().getWeighting());
GHResponse resp = hopper.route(req);
time = sw.stop().getSeconds();
return resp;
StopWatch sw = new StopWatch().start();
GHRequest req = new GHRequest(fromLat, fromLon, toLat, toLon).
setAlgorithm(Algorithms.DIJKSTRA_BI);
req.getHints().put(Routing.INSTRUCTIONS, Variable.getVariable().getDirectionsON());
req.setVehicle(Variable.getVariable().getTravelMode().toString().toLowerCase());
req.setWeighting(Variable.getVariable().getWeighting());
GHResponse resp = hopper.route(req);
if (resp.hasErrors())
{
NaviEngine.getNaviEngine().setDirectTargetDir(true);
List<Throwable> errors = resp.getErrors();
log("Multible errors, first: " + errors.get(0));
resp = TargetDirComputer.getInstance().createTargetdirResponse(fromLat, fromLon, toLat, toLon);
}
else
{
NaviEngine.getNaviEngine().setDirectTargetDir(false);
}
time = sw.stop().getSeconds();
return resp;
}


@Override
protected void onPostExecute(GHResponse ghResp) {
if (!ghResp.hasErrors()) {
Expand Down Expand Up @@ -468,6 +480,18 @@ private PathLayer updatePathLayer(PathLayer ref, PointList pointList, int color,
ref.setPoints(geoPoints);
return ref;
}

public void joinPathLayerToPos(double lat, double lon)
{
try
{
List<GeoPoint> geoPoints = new ArrayList<>();
geoPoints.add(new GeoPoint(lat,lon));
geoPoints.add(pathLayer.getPoints().get(1));
pathLayer.setPoints(geoPoints);
}
catch (Exception e) { log("Error: " + e); }
}

private PathLayer createPathLayer(int color, int strokeWidth)
{
Expand Down
Expand Up @@ -183,51 +183,67 @@ public String toString() {
* @return int resId
*/
public int getTravelModeResId(boolean dark) {
if (dark) {
switch (Variable.getVariable().getTravelMode()) {
case "foot":
return R.drawable.ic_directions_walk_orange_24dp;
case "bike":
return R.drawable.ic_directions_bike_orange_24dp;
case "car":
return R.drawable.ic_directions_car_orange_24dp;
}
} else {
switch (Variable.getVariable().getTravelMode()) {
case "foot":
return R.drawable.ic_directions_walk_white_24dp;
case "bike":
return R.drawable.ic_directions_bike_white_24dp;
case "car":
return R.drawable.ic_directions_car_white_24dp;
}
if (dark)
{
if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Foot)
{
return R.drawable.ic_directions_walk_orange_24dp;
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Bike)
{
return R.drawable.ic_directions_bike_orange_24dp;
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Car)
{
return R.drawable.ic_directions_car_orange_24dp;
}
}
else
{
if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Foot)
{
return R.drawable.ic_directions_walk_white_24dp;
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Bike)
{
return R.drawable.ic_directions_bike_white_24dp;
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Car)
{
return R.drawable.ic_directions_car_white_24dp;
}
}
throw new NullPointerException("this method can only used when Variable class is ready!");
}

public int getTravelModeArrayIndex() {
switch (Variable.getVariable().getTravelMode()) {
case "foot":
return 0;
case "bike":
return 1;
case "car":
return 2;
public int getTravelModeArrayIndex()
{
if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Foot)
{
return 0;
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Bike)
{
return 1;
}
else if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Car)
{
return 2;
}
throw new NullPointerException("this method can only used when Variable class is ready!");
}

public boolean setTravelModeArrayIndex(int index) {
String selected;
Variable.TravelMode selected;
switch (index) {
case 0:
selected = "foot";
selected = Variable.TravelMode.Foot;
break;
case 1:
selected = "bike";
selected = Variable.TravelMode.Bike;
break;
default:
selected = "car";
selected = Variable.TravelMode.Car;
}
Variable.getVariable().setTravelMode(selected);
return Variable.getVariable().saveVariables();
Expand Down
Expand Up @@ -32,6 +32,7 @@ public class NaviEngine
private static final int BEST_NAVI_ZOOM = 18;
enum UiJob { Nothing, RecalcPath, UpdateInstruction, Finished };
private UiJob uiJob = UiJob.Nothing;
private boolean directTargetDir = false;
NaviVoice naviVoice;
LightSensor lightSensor;
boolean naviVoiceSpoken = false;
Expand Down Expand Up @@ -101,10 +102,20 @@ else if ((!active) && lightSensor!=null)
}
}

/** This allows to update pathLayer, when instructions is just a line from target to curLoc.
* @param directTargetDir True to update pathLayer, join to curPos. **/
public void setDirectTargetDir(boolean directTargetDir)
{
this.directTargetDir = directTargetDir;
}

public void onUpdateInstructions(InstructionList instructions)
{
if (uiJob != UiJob.RecalcPath) { throw new IllegalStateException("Getting instructions but state is not RecalcPath!"); }
nearestP.checkDirectionOk(pos, instructions.get(0), naviVoice);
if (!directTargetDir)
{
nearestP.checkDirectionOk(pos, instructions.get(0), naviVoice);
}
this.instructions = instructions;
getNewInstruction();
uiJob = UiJob.UpdateInstruction;
Expand Down Expand Up @@ -152,6 +163,7 @@ public void updatePosition(Activity activity, Location pos)
private void calculatePositionAsync(GeoPoint curPos)
{
if (naviEngineTask == null) { createNaviEngineTask(); }
updateDirectTargetDir(curPos);
if (naviEngineTask.getStatus() == Status.RUNNING)
{
log("Error, NaviEngineTask is still running! Drop job ...");
Expand All @@ -167,6 +179,12 @@ else if (naviEngineTask.hasError())
}
}

private void updateDirectTargetDir(GeoPoint curPos)
{
if (!directTargetDir) { return; }
MapHandler.getMapHandler().joinPathLayerToPos(curPos.getLatitude(), curPos.getLongitude());
}

@UiThread
private void createNaviEngineTask()
{
Expand Down Expand Up @@ -334,11 +352,13 @@ else if (nearestP.arrPos == instructions.get(0).getPoints().size()-1 &&
}
if (!nearestP.isDistanceOk())
{
Instruction nearestNext = instructions.find(curPos.getLatitude(), curPos.getLongitude(), MAX_WAY_TOLERANCE_METER);
double maxWayTolMeters = MAX_WAY_TOLERANCE_METER;
if (directTargetDir) { maxWayTolMeters = maxWayTolMeters * 10.0; }
Instruction nearestNext = instructions.find(curPos.getLatitude(), curPos.getLongitude(), maxWayTolMeters);
if (nearestNext == null)
{
GeoPoint closestP = findClosestStreet(curPos);
nearestNext = instructions.find(closestP.getLatitude(), closestP.getLongitude(), MAX_WAY_TOLERANCE_METER);
nearestNext = instructions.find(closestP.getLatitude(), closestP.getLongitude(), maxWayTolMeters);
}
if (nearestNext == null)
{
Expand Down
Expand Up @@ -17,7 +17,7 @@ public static double dist2(double v_x, double v_y, double w_x, double w_y)
return sqr(v_x - w_x) + sqr(v_y - w_y);
}

/** Function from GeoPoint.java! **/
/** Calculates the estimated distance in degree. Function from GeoPoint.java! **/
public static double fastDistance(double lat1, double lon1, double lat2, double lon2)
{
return Math.hypot(lon1 - lon2, lat1 - lat2);
Expand Down
@@ -0,0 +1,80 @@
package com.junjunguo.pocketmaps.util;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.graphhopper.GHResponse;
import com.graphhopper.PathWrapper;
import com.graphhopper.util.Instruction;
import com.graphhopper.util.InstructionAnnotation;
import com.graphhopper.util.InstructionList;
import com.graphhopper.util.PointList;
import com.graphhopper.util.Translation;
import com.junjunguo.pocketmaps.map.Tracking;

import android.util.Log;

public class TargetDirComputer
{
private static TargetDirComputer instance = new TargetDirComputer();

public static TargetDirComputer getInstance()
{
return instance;
}

public GHResponse createTargetdirResponse(double fromLat, double fromLon, double toLat, double toLon)
{
GHResponse resp = new GHResponse();
PathWrapper pr = new PathWrapper();
PointList pl = new PointList();
pl.add(fromLat, fromLon);
pl.add(toLat, toLon);
pr.setPoints(pl);
double distance = GeoMath.fastDistance(fromLat, fromLon, toLat, toLon);
distance = distance * GeoMath.METER_PER_DEGREE;
pr.setDistance(distance);
double distKm = distance / 1000.0;
double hours = distKm / 50; // 50km == 1h
if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Bike) { hours = hours * 3.0; }
if (Variable.getVariable().getTravelMode() == Variable.TravelMode.Foot) { hours = hours * 9.0; }
long timeMs = (long)(hours * 60.0 * 60.0 * 1000.0);
pr.setTime(timeMs);
InstructionList insL = new InstructionList(createEmptyTranslator());
int sign = Instruction.CONTINUE_ON_STREET;
String name = "direction to target";
InstructionAnnotation ia = InstructionAnnotation.EMPTY;
Instruction ins = new Instruction(sign, name, ia, pl);
ins.setDistance(distance);
ins.setTime(timeMs);
insL.add(ins);
pr.setInstructions(insL);
resp.add(pr);
return resp;
}

private Translation createEmptyTranslator()
{
Translation t = new Translation()
{
@Override public String tr(String key, Object... params)
{
StringBuilder sb = new StringBuilder(key);
for (Object o : params) { sb.append(" ").append(o.toString()); }
return sb.toString();
}

@Override public Map<String, String> asMap()
{
return new HashMap<String, String>();
}

@Override public Locale getLocale() { return Locale.ENGLISH; }

@Override public String getLanguage() { return Locale.ENGLISH.getLanguage(); }
};
return t;
}
}

0 comments on commit dbfde54

Please sign in to comment.