Compare commits

...

57 commits
master ... r1.9

Author SHA1 Message Date
Victor Shcherb
7c9b81da26 Fix gpx selection issue
Conflicts:
	OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java
2015-01-19 01:06:35 +01:00
Victor Shcherb
44e40cdefc Fix small issues 2015-01-15 03:17:26 +01:00
Victor Shcherb
741099b6ed Merge branch 'r1.9' of ssh://github.com/osmandapp/Osmand into r1.9 2015-01-15 02:47:20 +01:00
Victor Shcherb
5a19801695 Update routes
Conflicts:
	OsmAnd-java/src/net/osmand/binary/BinaryInspector.java
	OsmAnd-java/src/net/osmand/router/RouteResultPreparation.java
	OsmAnd-java/src/net/osmand/router/TurnType.java
2015-01-15 02:45:56 +01:00
Victor Shcherb
3856a67a01 Never cache activities they could be not active
Conflicts:
	OsmAnd/src/net/osmand/plus/OsmAndAppCustomization.java
	OsmAnd/src/net/osmand/plus/download/DownloadActivity.java
2015-01-13 17:27:34 +02:00
Alexey Pelykh
630bea44a2 Fix 2015-01-13 17:20:15 +02:00
Victor Shcherb
c3d5baf996 Proper GPX intent handling, replace undocumented 'category' with existing 'type' for favourites.gpx 2015-01-13 17:20:09 +02:00
Alexey Pelykh
8a1a1d86c5 Fix indent 2015-01-13 16:41:47 +02:00
Alexey Pelykh
3d7ca7e09c New GEO URI parser 2015-01-13 16:41:46 +02:00
Denis
deba789918 Fixed bug when app doesnt recognized as geo app 2015-01-13 16:41:45 +02:00
Victor Shcherb
c5ecb5e63f Fix turn:lanes 2015-01-13 10:28:00 +01:00
Victor Shcherb
a5b864a298 Fix routing 2014-11-28 01:00:03 +01:00
Victor Shcherb
107b5259f9 Fix routing with needles 2014-11-28 00:59:02 +01:00
Alexey Pelykh
8d75159aec Merge pull request #971 from jmakovicka/r1.9
Tolerate missing jnigraphics lib on Lollipop
2014-11-25 17:26:20 +02:00
jmakovicka
eb4967e6f0 ignore jnigraphics load errors
Nexus 4 w/ Android 5.0 Lollipop produces the following error message:

java.lang.UnsatisfiedLinkError: Shared library "/system/lib/libjnigraphics.so" already opened by ClassLoader 0x0
2014-11-25 13:28:27 +01:00
Jindřich Makovička
2e1a1954d7 Tolerate missing jnigraphics lib on Lollipop 2014-11-25 06:08:00 +01:00
Alexey Pelykh
6bd4cd64e8 Fix 2014-11-24 01:30:01 +01:00
Victor Shcherb
bcc8ab6c7a Fix issue with turn type 2014-11-23 19:45:46 +01:00
Victor Shcherb
c6d6897a88 Fix issue not remember state of group (small issue on server left) 2014-11-23 17:06:32 +01:00
Victor Shcherb
9963f41ccc Fix osmo bugs: use https, encryption, cancel
Conflicts:
	OsmAnd/res/values/strings.xml
2014-11-23 16:23:01 +01:00
vshcherb
46173129f0 Merge pull request #966 from Bars107/r1.9
Fixed bug with local index not showing after switching tabs
2014-11-20 17:04:38 +01:00
Denis
8928064b66 Fixed bug with local index not showing after switching tabs 2014-11-20 13:55:24 +02:00
vshcherb
f3fcc04f67 Merge pull request #964 from Bars107/r1.9
R1.9
2014-11-19 17:26:11 +01:00
Denis
b53339aef0 Fixed issue when selection for show current gpx doesnt save 2014-11-19 18:23:48 +02:00
Denis
7d0916bce6 Fixed bug with same item can be added to avoid roads twice 2014-11-19 18:23:38 +02:00
Denis
99e8409e37 Added region name in Updates tab in DownloadActivity 2014-11-19 18:23:28 +02:00
vshcherb
3b3d8017a7 Merge pull request #958 from Bars107/r1.9
Huge fixes for downloads.
2014-11-17 16:47:10 +01:00
Denis
6a29e8ab2f Fixed issue with wrong type maps downloading(roads only) 2014-11-17 17:41:59 +02:00
Denis
4d565a3ba8 Updated sort for local index 2014-11-17 17:12:52 +02:00
Denis
3f32c71c8d Refactored code of comparator 2014-11-17 16:53:50 +02:00
Denis
9fd0c20131 Updated sorting in localIndexFragment 2014-11-17 16:45:56 +02:00
Denis
89c72449d2 Fixed: removing last item in category does not remove category 2014-11-17 16:07:41 +02:00
Denis
d06e883dd1 Fixed bug when after deleting something in localindex - adapter was recreated and all open categories was closed 2014-11-17 14:32:23 +02:00
Denis
5073e82918 Fixed issue when downloaded map doesn't show in localIndex 2014-11-17 14:32:14 +02:00
vshcherb
274796d5c3 Merge pull request #950 from Zahnstocher/onresumer1.9-patch
fix route recalculation and screen update issue on MapActivity resume
2014-11-17 10:22:54 +01:00
Denis
63cdb2737e Updated solution for map modes does not fit in drawer 2014-11-12 10:44:25 +02:00
Zahnstocher
8fad1a477f fix route recalculation and screen update issue on MapActivity resume 2014-11-11 00:48:56 +01:00
Denis
e0fc9843f2 Fixed issue with wrong context for dialog 2014-11-10 14:29:48 +02:00
Denis
79cc69df46 Fixed NPE in localIndexFragment in onPostExecute 2014-11-10 11:31:14 +02:00
Denis
696b817863 Hotfix to NPE in UpdatesIndexFragment 2014-11-10 11:19:13 +02:00
Denis
ef302a0059 Fixed NPE in LocalIndexesFragment in onPostExecute 2014-11-10 11:16:54 +02:00
Denis
260d4eede2 Fixed NPE in UpdatesIntexFragment 2014-11-10 11:13:59 +02:00
Denis
1041b2de05 Fixed wrong string in Korean language 2014-11-10 10:04:13 +02:00
Denis
be705edf1c Fixed crush on lt language when opening downloads 2014-11-10 10:02:04 +02:00
Denis
89764a9b77 Fixed app mode button not fit in drawer 2014-11-10 10:01:55 +02:00
Denis
6a7fb4670b Fixed issue with drawer menu opened with slide change status 2014-11-10 10:01:46 +02:00
Victor Shcherb
984717dd11 Fix android 2.2 2014-11-08 01:40:45 +01:00
Victor Shcherb
0275990811 Fix ui helper 2014-11-07 20:00:28 +01:00
Denis
9c168dd7f3 Fixed bug when main manu does not update when using slide 2014-11-07 17:02:22 +02:00
Denis
525703b4be Fixed null pointer in favorites db helerp 2014-11-07 16:38:03 +02:00
Denis
a1b10b5aec Fixed null pointer in downloadindexadapter 2014-11-07 15:49:56 +02:00
Denis
d50ae48e54 FIxed null pointer in DownloadIndexThread 2014-11-07 15:41:10 +02:00
Denis
4bf1167707 Fixed null pointer in DownloadActivity with extras 2014-11-07 15:35:52 +02:00
Victor Shcherb
3b3e27cdc9 Fix NPE 2014-11-06 23:39:39 +01:00
Victor Shcherb
d21179a66d Fix NPE 2014-11-05 22:01:54 +01:00
vshcherb
ee2efd1291 Merge pull request #945 from Bars107/r1.9
Fixed null pointer in download indexadapter
2014-11-05 15:59:32 +01:00
Denis
4ef721063c Fixed null pointer in download indexadapter 2014-11-05 15:00:29 +02:00
51 changed files with 1891 additions and 550 deletions

View file

@ -8,16 +8,21 @@ import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import net.osmand.PlatformUtil;
import net.osmand.util.Algorithms;
import net.osmand.util.LIFOBlockingDeque;
import org.apache.commons.logging.Log;
@ -106,14 +111,34 @@ public class MapTileDownloader {
public MapTileDownloader(int numberOfThreads){
threadPoolExecutor = new ThreadPoolExecutor(numberOfThreads, numberOfThreads, TILE_DOWNLOAD_SECONDS_TO_WORK,
TimeUnit.SECONDS, new LIFOBlockingDeque<Runnable>());
TimeUnit.SECONDS, createQueue());
// 1.6 method but very useful to kill non-running threads
// threadPoolExecutor.allowCoreThreadTimeOut(true);
pendingToDownload = Collections.synchronizedSet(new HashSet<File>());
currentlyDownloaded = Collections.synchronizedSet(new HashSet<File>());
}
protected BlockingQueue<Runnable> createQueue() {
boolean loaded = false;
try {
Class<?> cl = Class.forName("java.util.concurrent.LinkedBlockingDeque");
loaded = cl != null;
} catch (Throwable e) {
e.printStackTrace();
}
if(!loaded) {
// for Android 2.2
return new LinkedBlockingQueue<Runnable>();
}
return createDeque();
}
protected static BlockingQueue<Runnable> createDeque() {
return new net.osmand.util.LIFOBlockingDeque<Runnable>();
}
public void addDownloaderCallback(IMapDownloaderCallback callback){
callbacks.add(callback);

View file

@ -206,14 +206,41 @@ public class BinaryRoutePlanner {
}
}
}
public RouteSegment initRouteSegment(final RoutingContext ctx, RouteSegment segment, boolean positiveDirection) {
if(segment.getSegmentStart() == 0 && !positiveDirection && segment.getRoad().getPointsLength() > 0) {
segment = loadSameSegment(ctx, segment, 1);
} else if(segment.getSegmentStart() == segment.getRoad().getPointsLength() -1 && positiveDirection && segment.getSegmentStart() > 0) {
segment = loadSameSegment(ctx, segment, segment.getSegmentStart() -1);
}
if(segment == null) {
return null;
}
return segment.initRouteSegment(positiveDirection);
}
protected RouteSegment loadSameSegment(final RoutingContext ctx, RouteSegment segment, int ind) {
int x31 = segment.getRoad().getPoint31XTile(ind);
int y31 = segment.getRoad().getPoint31YTile(ind);
RouteSegment s = ctx.loadRouteSegment(x31, y31, 0);
while(s != null) {
if(s.getRoad().getId() == segment.getRoad().getId()) {
segment = s;
break;
}
s = s.getNext();
}
return segment;
}
private void initQueuesWithStartEnd(final RoutingContext ctx, RouteSegment start, RouteSegment end,
PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments) {
RouteSegment startPos = start.initRouteSegment(true);
RouteSegment startNeg = start.initRouteSegment(false);
RouteSegment endPos = end.initRouteSegment(true);
RouteSegment endNeg = end.initRouteSegment(false);
RouteSegment startPos = initRouteSegment(ctx, start, true);
RouteSegment startNeg = initRouteSegment(ctx, start, false);
RouteSegment endPos = initRouteSegment(ctx, end, true);
RouteSegment endNeg = initRouteSegment(ctx, end, false);
// for start : f(start) = g(start) + h(start) = 0 + h(start) = h(start)
if(ctx.config.initialDirection != null) {
// mark here as positive for further check

View file

@ -1,16 +1,16 @@
package net.osmand.router;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.set.hash.TIntHashSet;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
@ -21,6 +21,8 @@ import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
public class RouteResultPreparation {
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = false;
@ -38,13 +40,35 @@ public class RouteResultPreparation {
List<RouteSegmentResult> prepareResult(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
validateAllPointsConnected(result);
splitRoadsAndAttachRoadSegments(ctx, result);
// calculate time
calculateTimeSpeed(ctx, result);
addTurnInfo(ctx.leftSideNavigation, result);
for (int i = 0; i < result.size(); i ++) {
TurnType turnType = getTurnInfo(result, i, ctx.leftSideNavigation);
result.get(i).setTurnType(turnType);
}
determineTurnsToMerge(ctx.leftSideNavigation, result);
justifyUTurns(ctx.leftSideNavigation, result);
addTurnInfoDescriptions(result);
return result;
}
private void justifyUTurns(boolean leftSide, List<RouteSegmentResult> result) {
int next;
for (int i = 0; i < result.size() - 1; i = next) {
next = i + 1;
TurnType t = result.get(i).getTurnType();
// justify turn
if (t != null) {
TurnType jt = justifyUTurn(leftSide, result, i, t);
if (jt != null) {
result.get(i).setTurnType(jt);
next = i + 2;
}
}
}
}
private void calculateTimeSpeed(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
for (int i = 0; i < result.size(); i++) {
RouteSegmentResult rr = result.get(i);
@ -328,58 +352,41 @@ public class RouteResultPreparation {
}
private void addTurnInfo(boolean leftside, List<RouteSegmentResult> result) {
protected void addTurnInfoDescriptions(List<RouteSegmentResult> result) {
int prevSegment = -1;
float dist = 0;
int next = 1;
for (int i = 0; i <= result.size(); i = next) {
TurnType t = null;
next = i + 1;
if (i < result.size()) {
t = getTurnInfo(result, i, leftside);
// justify turn
if(t != null && i < result.size() - 1) {
boolean tl = TurnType.TL == t.getValue();
boolean tr = TurnType.TR == t.getValue();
if(tl || tr) {
TurnType tnext = getTurnInfo(result, i + 1, leftside);
if (tnext != null && result.get(i).getDistance() < 35) { //
boolean ut = true;
if (i > 0) {
double uTurn = MapUtils.degreesDiff(result.get(i - 1).getBearingEnd(), result
.get(i + 1).getBearingBegin());
if (Math.abs(uTurn) < 120) {
ut = false;
}
}
String highway = result.get(i).getObject().getHighway();
if(highway == null || highway.endsWith("track") || highway.endsWith("services") || highway.endsWith("service")
|| highway.endsWith("path")) {
ut = false;
}
if (ut) {
if (tl && TurnType.TL == tnext.getValue()) {
next = i + 2;
t = TurnType.valueOf(TurnType.TU, false);
} else if (tr && TurnType.TR == tnext.getValue()) {
next = i + 2;
t = TurnType.valueOf(TurnType.TU, true);
}
}
}
}
}
result.get(i).setTurnType(t);
}
if (t != null || i == result.size()) {
for (int i = 0; i <= result.size(); i++) {
if (i == result.size() || result.get(i).getTurnType() != null) {
if (prevSegment >= 0) {
String turn = result.get(prevSegment).getTurnType().toString();
if (result.get(prevSegment).getTurnType().getLanes() != null) {
turn += Arrays.toString(result.get(prevSegment).getTurnType().getLanes());
final int[] lns = result.get(prevSegment).getTurnType().getLanes();
if (lns != null) {
String s = "[ ";
for (int h = 0; h < lns.length; h++) {
if (h > 0) {
s += ", ";
}
if (lns[h] % 2 == 1) {
s += "+";
}
int pt = TurnType.getPrimaryTurn(lns[h]);
if (pt == 0) {
pt = 1;
}
s += TurnType.valueOf(pt, false).toXmlString();
int st = TurnType.getSecondaryTurn(lns[h]);
if (st != 0) {
s += ";" + TurnType.valueOf(st, false).toXmlString();
}
}
s += "]";
turn += s;
}
result.get(prevSegment).setDescription(turn + MessageFormat.format(" and go {0,number,#.##} meters", dist));
if(result.get(prevSegment).getTurnType().isSkipToSpeak()) {
result.get(prevSegment).setDescription("-*"+result.get(prevSegment).getDescription());
result.get(prevSegment).setDescription(
turn + MessageFormat.format(" and go {0,number,#.##} meters", dist));
if (result.get(prevSegment).getTurnType().isSkipToSpeak()) {
result.get(prevSegment).setDescription("-*" + result.get(prevSegment).getDescription());
}
}
prevSegment = i;
@ -390,6 +397,154 @@ public class RouteResultPreparation {
}
}
}
protected TurnType justifyUTurn(boolean leftside, List<RouteSegmentResult> result, int i, TurnType t) {
boolean tl = TurnType.TL == t.getValue();
boolean tr = TurnType.TR == t.getValue();
if(tl || tr) {
TurnType tnext = result.get(i + 1).getTurnType();
if (tnext != null && result.get(i).getDistance() < 35) { //
boolean ut = true;
if (i > 0) {
double uTurn = MapUtils.degreesDiff(result.get(i - 1).getBearingEnd(), result
.get(i + 1).getBearingBegin());
if (Math.abs(uTurn) < 120) {
ut = false;
}
}
String highway = result.get(i).getObject().getHighway();
if(highway == null || highway.endsWith("track") || highway.endsWith("services") || highway.endsWith("service")
|| highway.endsWith("path")) {
ut = false;
}
if (ut) {
tnext.setSkipToSpeak(true);
if (tl && TurnType.TL == tnext.getValue()) {
return TurnType.valueOf(TurnType.TU, false);
} else if (tr && TurnType.TR == tnext.getValue()) {
return TurnType.valueOf(TurnType.TU, true);
}
}
}
}
return null;
}
private void determineTurnsToMerge(boolean leftside, List<RouteSegmentResult> result) {
RouteSegmentResult nextSegment = null;
double dist = 0;
for (int i = result.size() - 1; i >= 0; i--) {
RouteSegmentResult currentSegment = result.get(i);
TurnType currentTurn = currentSegment.getTurnType();
dist += currentSegment.getDistance();
if (currentTurn == null || currentTurn.getLanes() == null) {
// skip
} else {
if (nextSegment != null) {
String hw = currentSegment.getObject().getHighway();
double mergeDistance = 200;
if (hw != null && (hw.startsWith("trunk") || hw.startsWith("motorway"))) {
mergeDistance = 400;
}
if (dist < mergeDistance) {
mergeTurnLanes(leftside, currentSegment, nextSegment);
}
}
nextSegment = currentSegment;
dist = 0;
}
}
}
private class MergeTurnLaneTurn {
TurnType turn;
int[] originalLanes;
int[] disabledLanes;
int activeStartIndex = -1;
int activeEndIndex = -1;
int activeLen = 0;
public MergeTurnLaneTurn(RouteSegmentResult segment) {
this.turn = segment.getTurnType();
if(turn != null) {
originalLanes = turn.getLanes();
}
if(originalLanes != null) {
disabledLanes = new int[originalLanes.length];
for (int i = 0; i < originalLanes.length; i++) {
int ln = originalLanes[i];
disabledLanes[i] = ln & ~1;
if ((ln & 1) > 0) {
if (activeStartIndex == -1) {
activeStartIndex = i;
}
activeEndIndex = i;
activeLen++;
}
}
}
}
public boolean isActiveTurnMostLeft() {
return activeStartIndex == 0;
}
public boolean isActiveTurnMostRight() {
return activeEndIndex == originalLanes.length - 1;
}
}
private void mergeTurnLanes(boolean leftSide, RouteSegmentResult currentSegment, RouteSegmentResult nextSegment) {
MergeTurnLaneTurn active = new MergeTurnLaneTurn(currentSegment);
MergeTurnLaneTurn target = new MergeTurnLaneTurn(nextSegment);
if (active.activeLen < 2) {
return;
}
if (target.activeStartIndex == -1) {
return;
}
boolean changed = false;
if (target.isActiveTurnMostLeft()) {
// let only the most left lanes be enabled
if (target.activeLen <= active.activeLen) {
active.activeEndIndex -= (active.activeLen - target.activeLen);
changed = true;
}
} else if (target.isActiveTurnMostRight()) {
// next turn is right
// let only the most right lanes be enabled
if (target.activeLen < active.activeLen) {
active.activeStartIndex += (active.activeLen - target.activeLen);
changed = true;
}
} else {
// next turn is get through (take out the left and the right turn)
if (target.activeLen < active.activeLen) {
float ratio = (active.activeLen - target.activeLen) / 2f;
active.activeEndIndex = (int) Math.ceil(active.activeEndIndex - ratio);
active.activeStartIndex = (int) Math.floor(active.activeStartIndex + ratio);
changed = true;
}
}
if (!changed) {
return;
}
// set the allowed lane bit
for (int i = 0; i < active.disabledLanes.length; i++) {
if (i >= active.activeStartIndex && i <= active.activeEndIndex) {
active.disabledLanes[i] |= 1;
}
}
TurnType currentTurn = currentSegment.getTurnType();
currentTurn.setLanes(active.disabledLanes);
int turn = inferTurnFromLanes(active.disabledLanes);
if (turn != 0 && turn != currentTurn.getValue()) {
TurnType newTurnType = TurnType.valueOf(turn, leftSide);
newTurnType.setLanes(active.disabledLanes);
newTurnType.setSkipToSpeak(currentTurn.isSkipToSpeak());
currentSegment.setTurnType(newTurnType);
}
}
private static final int MAX_SPEAK_PRIORITY = 5;
private int highwaySpeakPriority(String highway) {
@ -440,7 +595,8 @@ public class RouteResultPreparation {
} else {
t = TurnType.valueOf(TurnType.TU, leftSide);
}
assignLanesInfo(prev, t, leftSide);
int[] lanes = getTurnLanesInfo(prev, t.getValue());
t.setLanes(lanes);
} else if (mpi < -TURN_DEGREE_MIN) {
if (mpi > -60) {
t = TurnType.valueOf(TurnType.TSLR, leftSide);
@ -449,11 +605,12 @@ public class RouteResultPreparation {
} else if (mpi > -135 || !leftSide) {
t = TurnType.valueOf(TurnType.TSHR, leftSide);
} else {
t = TurnType.valueOf(TurnType.TU, leftSide);
t = TurnType.valueOf(TurnType.TRU, leftSide);
}
assignLanesInfo(prev, t, leftSide);
int[] lanes = getTurnLanesInfo(prev, t.getValue());
t.setLanes(lanes);
} else {
t = attachKeepLeftInfoAndLanes(leftSide, prev, rr, t);
t = attachKeepLeftInfoAndLanes(leftSide, prev, rr);
}
if (t != null) {
t.setTurnAngle((float) -mpi);
@ -462,62 +619,47 @@ public class RouteResultPreparation {
return t;
}
private void assignLanesInfo(RouteSegmentResult prevSegm, TurnType t, boolean leftSide) {
int lanes = prevSegm.getObject().getLanes();
if (prevSegm.getObject().getOneway() == 0) {
lanes = countLanes(prevSegm, lanes);
}
if (lanes <= 0) {
return;
}
private int[] getTurnLanesInfo(RouteSegmentResult prevSegm, int mainTurnType) {
String turnLanes = getTurnLanesString(prevSegm);
if (turnLanes == null) {
return;
return null;
}
String[] splitLaneOptions = turnLanes.split("\\|", -1);
if (splitLaneOptions.length != lanes) {
// Error in data or missing data
return;
}
int[] lanesArray = new int[lanes];
t.setLanes(lanesArray);
assignTurns(splitLaneOptions, t);
// In some cases (at least in the US), the rightmost lane might not have a right turn indicated as per turn:lanes, but is allowed and being used here. This section adds in that indicator. The same applies for where leftSide is true.
if (leftSide) {
if (t.getValue() == TurnType.TL
&& TurnType.getPrimaryTurn(lanesArray[0]) != TurnType.TL
&& TurnType.getPrimaryTurn(lanesArray[0]) != TurnType.TSLL
&& TurnType.getPrimaryTurn(lanesArray[0]) != TurnType.TSHL) {
if (TurnType.getPrimaryTurn(lanesArray[0]) != 0) {
// This was just to make sure that there's no bad data.
t.setSecondaryTurn(0, TurnType.getPrimaryTurn(lanesArray[0]));
t.setPrimaryTurn(0, TurnType.TL);
}
}
} else {
int lastIndex = lanesArray.length - 1;
if (t.getValue() == TurnType.TR
&& TurnType.getPrimaryTurn(lanesArray[lastIndex]) != TurnType.TR
&& TurnType.getPrimaryTurn(lanesArray[lastIndex]) != TurnType.TSLR
&& TurnType.getPrimaryTurn(lanesArray[lastIndex]) != TurnType.TSHR) {
if (TurnType.getPrimaryTurn(lanesArray[lastIndex]) != 0) {
// This was just to make sure that there's no bad data.
t.setSecondaryTurn(lastIndex, TurnType.getPrimaryTurn(lanesArray[lastIndex]));
t.setPrimaryTurn(lastIndex, TurnType.TR);
}
}
}
int[] lanesArray = calculateRawTurnLanes(turnLanes, mainTurnType);
// Manually set the allowed lanes.
boolean isSet = setAllowedLanes(mainTurnType, lanesArray);
if(!isSet && lanesArray.length > 0) {
// In some cases (at least in the US), the rightmost lane might not have a right turn indicated as per turn:lanes,
// but is allowed and being used here. This section adds in that indicator. The same applies for where leftSide is true.
boolean leftTurn = TurnType.isLeftTurn(mainTurnType);
int ind = leftTurn? 0 : lanesArray.length - 1;
final int tt = TurnType.getPrimaryTurn(lanesArray[ind]);
if (leftTurn) {
if (!TurnType.isLeftTurn(tt)) {
// This was just to make sure that there's no bad data.
TurnType.setPrimaryTurnAndReset(lanesArray, ind, TurnType.TL);
TurnType.setSecondaryTurn(lanesArray, ind, tt);
}
} else {
if (!TurnType.isRightTurn(tt)) {
// This was just to make sure that there's no bad data.
TurnType.setPrimaryTurnAndReset(lanesArray, ind, TurnType.TR);
TurnType.setSecondaryTurn(lanesArray, ind, tt);
}
}
setAllowedLanes(tt, lanesArray);
}
return lanesArray;
}
protected boolean setAllowedLanes(int mainTurnType, int[] lanesArray) {
boolean turnSet = false;
for (int i = 0; i < lanesArray.length; i++) {
if (TurnType.getPrimaryTurn(lanesArray[i]) == t.getValue()) {
if (TurnType.getPrimaryTurn(lanesArray[i]) == mainTurnType) {
lanesArray[i] |= 1;
turnSet = true;
}
}
return turnSet;
}
private TurnType processRoundaboutTurn(List<RouteSegmentResult> result, int i, boolean leftSide, RouteSegmentResult prev,
@ -550,104 +692,206 @@ public class RouteResultPreparation {
t.setTurnAngle((float) MapUtils.degreesDiff(last.getBearingBegin(), prev.getBearingEnd())) ;
return t;
}
private TurnType attachKeepLeftInfoAndLanes(boolean leftSide, RouteSegmentResult prevSegm, RouteSegmentResult currentSegm, TurnType t) {
// keep left/right
int[] lanes = null;
boolean kl = false;
boolean kr = false;
List<RouteSegmentResult> attachedRoutes = currentSegm.getAttachedRoutes(currentSegm.getStartPointIndex());
int ls = prevSegm.getObject().getLanes();
if(ls >= 0 && prevSegm.getObject().getOneway() == 0) {
ls = (ls + 1) / 2;
}
int left = 0;
int right = 0;
private class RoadSplitStructure {
boolean keepLeft = false;
boolean keepRight = false;
boolean speak = false;
int leftLanes = 0;
int rightLanes = 0;
int roadsOnLeft = 0;
int addRoadsOnLeft = 0;
int roadsOnRight = 0;
int addRoadsOnRight = 0;
}
private TurnType attachKeepLeftInfoAndLanes(boolean leftSide, RouteSegmentResult prevSegm, RouteSegmentResult currentSegm) {
List<RouteSegmentResult> attachedRoutes = currentSegm.getAttachedRoutes(currentSegm.getStartPointIndex());
if(attachedRoutes == null || attachedRoutes.size() == 0) {
return null;
}
// keep left/right
RoadSplitStructure rs = calculateRoadSplitStructure(prevSegm, currentSegm, attachedRoutes);
if(rs.roadsOnLeft + rs.roadsOnRight == 0) {
return null;
}
// turn lanes exist
String turnLanes = getTurnLanesString(prevSegm);
if (turnLanes != null) {
return createKeepLeftRightTurnBasedOnTurnTypes(rs, prevSegm, currentSegm, turnLanes, leftSide);
}
// turn lanes don't exist
if (rs.keepLeft || rs.keepRight) {
return createSimpleKeepLeftRightTurn(leftSide, prevSegm, currentSegm, rs);
}
return null;
}
protected TurnType createKeepLeftRightTurnBasedOnTurnTypes(RoadSplitStructure rs, RouteSegmentResult prevSegm,
RouteSegmentResult currentSegm, String turnLanes,boolean leftSide) {
// Maybe going straight at a 90-degree intersection
TurnType t = TurnType.valueOf(TurnType.C, leftSide);
int[] rawLanes = calculateRawTurnLanes(turnLanes, TurnType.C);
if (rs.keepLeft || rs.keepRight) {
String[] splitLaneOptions = turnLanes.split("\\|", -1);
int activeBeginIndex = findActiveIndex(rawLanes, splitLaneOptions, rs.leftLanes, true,
rs.roadsOnLeft, rs.addRoadsOnLeft);
int activeEndIndex = findActiveIndex(rawLanes, splitLaneOptions, rs.rightLanes, false,
rs.roadsOnRight, rs.addRoadsOnRight);
if (activeBeginIndex == -1 || activeEndIndex == -1 || activeBeginIndex > activeEndIndex) {
// something went wrong
return createSimpleKeepLeftRightTurn(leftSide, prevSegm, currentSegm, rs);
}
for (int k = 0; k < rawLanes.length; k++) {
if (k >= activeBeginIndex && k <= activeEndIndex) {
rawLanes[k] |= 1;
}
}
int tp = inferTurnFromLanes(rawLanes);
if (tp != t.getValue() && tp != 0) {
t = TurnType.valueOf(tp, leftSide);
}
} else {
for (int k = 0; k < rawLanes.length; k++) {
int turn = rawLanes[k];
boolean active = false;
if (TurnType.getPrimaryTurn(turn) == TurnType.C) {
active = true;
} else if (TurnType.isRightTurn(turn) && rs.roadsOnRight == 0) {
// some turns go through many segments (to turn right or left)
// so on one first segment the lane could be available and may be only 1 possible
// all undesired lanes will be disabled through the 2nd pass
active = true;
} else if (TurnType.isLeftTurn(turn) && rs.roadsOnLeft == 0) {
active = true;
}
if (active) {
rawLanes[k] |= 1;
}
}
}
t.setSkipToSpeak(!rs.speak);
t.setLanes(rawLanes);
return t;
}
protected int findActiveIndex(int[] rawLanes, String[] splitLaneOptions, int lanes, boolean left,
int roads, int addRoads) {
int activeStartIndex = -1;
boolean lookupSlightTurn = addRoads > 0;
for (int i = 0; i < rawLanes.length; i++) {
int ind = left ? i : (rawLanes.length - i - 1);
if (!lookupSlightTurn ||
TurnType.isSlightTurn(TurnType.getPrimaryTurn(rawLanes[ind]))
|| TurnType.isSlightTurn(TurnType.getSecondaryTurn(rawLanes[ind]))) {
int cnt = countOccurrences(splitLaneOptions[ind], ';') + 1;
if(cnt > 1) {
// sometimes slight right turn goes to the road with 2 lanes
// the better situation to group all the lanes and
// when ';' we know for sure the lane combines 2 group
roads -= 2;
}
lanes -= cnt;
// we already found slight turn others are turn in different direction
lookupSlightTurn = false;
}
if (lanes < 0 || roads < 0) {
activeStartIndex = ind;
break;
}
}
return activeStartIndex;
}
protected RoadSplitStructure calculateRoadSplitStructure(RouteSegmentResult prevSegm, RouteSegmentResult currentSegm,
List<RouteSegmentResult> attachedRoutes) {
RoadSplitStructure rs = new RoadSplitStructure();
int speakPriority = Math.max(highwaySpeakPriority(prevSegm.getObject().getHighway()), highwaySpeakPriority(currentSegm.getObject().getHighway()));
if (attachedRoutes != null) {
for (RouteSegmentResult attached : attachedRoutes) {
double ex = MapUtils.degreesDiff(attached.getBearingBegin(), currentSegm.getBearingBegin());
double mpi = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), attached.getBearingBegin()));
int rsSpeakPriority = highwaySpeakPriority(attached.getObject().getHighway());
if (rsSpeakPriority != MAX_SPEAK_PRIORITY || speakPriority == MAX_SPEAK_PRIORITY) {
if ((ex < TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex >= 0) {
kl = true;
int lns = attached.getObject().getLanes();
if(attached.getObject().getOneway() == 0) {
lns = countLanes(attached, lns);
}
if (lns <= 0) {
right += 1;
} else {
right += lns;
}
speak = speak || rsSpeakPriority <= speakPriority;
} else if ((ex > -TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex <= 0) {
kr = true;
int lns = attached.getObject().getLanes();
if(attached.getObject().getOneway() == 0) {
lns = countLanes(attached, lns);
}
if (lns <= 0) {
left += 1;
} else {
left += lns;
}
speak = speak || rsSpeakPriority <= speakPriority;
for (RouteSegmentResult attached : attachedRoutes) {
double ex = MapUtils.degreesDiff(attached.getBearingBegin(), currentSegm.getBearingBegin());
double mpi = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), attached.getBearingBegin()));
int rsSpeakPriority = highwaySpeakPriority(attached.getObject().getHighway());
if (rsSpeakPriority != MAX_SPEAK_PRIORITY || speakPriority == MAX_SPEAK_PRIORITY) {
int lanes = countLanesMinOne(attached);
boolean smallStraightVariation = mpi < TURN_DEGREE_MIN;
boolean smallTargetVariation = Math.abs(ex) < TURN_DEGREE_MIN;
boolean attachedOnTheRight = ex >= 0;
if (attachedOnTheRight) {
rs.roadsOnRight++;
} else {
rs.roadsOnLeft++;
}
if (smallTargetVariation || smallStraightVariation) {
if (attachedOnTheRight) {
rs.keepLeft = true;
rs.rightLanes += lanes;
} else {
rs.keepRight = true;
rs.leftLanes += lanes;
}
rs.speak = rs.speak || rsSpeakPriority <= speakPriority;
} else {
if (attachedOnTheRight) {
rs.addRoadsOnRight++;
} else {
rs.addRoadsOnLeft++;
}
}
}
}
if(kr && left == 0) {
left = 1;
} else if(kl && right == 0) {
right = 1;
}
int current = currentSegm.getObject().getLanes();
// attachedRoutes covers all allowed outbound routes at that point except currentSegm.
if (currentSegm.getObject().getOneway() == 0) {
current = countLanes(currentSegm, current);
}
if (current <= 0) {
current = 1;
}
// if(ls >= 0 /*&& current + left + right >= ls*/){
lanes = new int[current + left + right];
ls = current + left + right;
for(int it=0; it< ls; it++) {
if(it < left || it >= left + current) {
lanes[it] = 0;
} else {
lanes[it] = 1;
}
}
// sometimes links are
if ((current <= left + right) && (left > 1 || right > 1)) {
speak = true;
}
// }
return rs;
}
protected TurnType createSimpleKeepLeftRightTurn(boolean leftSide, RouteSegmentResult prevSegm,
RouteSegmentResult currentSegm, RoadSplitStructure rs) {
int current = countLanesMinOne(currentSegm);
int ls = current + rs.leftLanes + rs.rightLanes;
int[] lanes = new int[ls];
for (int it = 0; it < ls; it++) {
if (it < rs.leftLanes || it >= rs.leftLanes + current) {
lanes[it] = 0;
} else {
lanes[it] = 1;
}
}
// sometimes links are
if ((current <= rs.leftLanes + rs.rightLanes) && (rs.leftLanes > 1 || rs.rightLanes > 1)) {
rs.speak = true;
}
double devation = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), currentSegm.getBearingBegin()));
boolean makeSlightTurn = devation > 5 && (!isMotorway(prevSegm) || !isMotorway(currentSegm));
if (kl) {
TurnType t = null;
if (rs.keepLeft && rs.keepRight) {
t = TurnType.valueOf(TurnType.C, leftSide);
} else if (rs.keepLeft) {
t = TurnType.valueOf(makeSlightTurn ? TurnType.TSLL : TurnType.KL, leftSide);
t.setSkipToSpeak(!speak);
}
if (kr) {
} else if (rs.keepRight) {
t = TurnType.valueOf(makeSlightTurn ? TurnType.TSLR : TurnType.KR, leftSide);
t.setSkipToSpeak(!speak);
}
if (t != null && lanes != null) {
t.setLanes(lanes);
t = attachTurnLanesData(leftSide, prevSegm, t);
} else {
return t;
}
t.setSkipToSpeak(!rs.speak);
t.setLanes(lanes);
return t;
}
protected int countLanes(RouteSegmentResult attached, int lns) {
protected int countLanesMinOne(RouteSegmentResult attached) {
final boolean oneway = attached.getObject().getOneway() != 0;
int lns = attached.getObject().getLanes();
if(lns == 0) {
String tls = getTurnLanesString(attached);
if(tls != null) {
lns = countOccurrences(tls, '|');
}
}
if (oneway) {
return Math.max(1, lns);
}
try {
if (attached.isForwardDirection() && attached.getObject().getValue("lanes:forward") != null) {
return Integer.parseInt(attached.getObject().getValue("lanes:forward"));
@ -657,7 +901,7 @@ public class RouteResultPreparation {
} catch (NumberFormatException e) {
e.printStackTrace();
}
return (lns + 1) / 2;
return Math.max(1, (lns + 1) / 2);
}
protected String getTurnLanesString(RouteSegmentResult segment) {
@ -672,65 +916,7 @@ public class RouteResultPreparation {
}
}
private TurnType attachTurnLanesData(boolean leftSide, RouteSegmentResult prevSegm, TurnType t) {
int lanes = prevSegm.getObject().getLanes();
String turnLanes = getTurnLanesString(prevSegm);
if (turnLanes == null) {
return t;
}
String[] splitLaneOptions = turnLanes.split("\\|", -1);
if (splitLaneOptions.length != lanes) {
// Error in data or missing data
return t;
}
if (t.getLanes().length != lanes) {
// The turn:lanes don't easily match up to the target road.
List<Integer> sourceLanes = new ArrayList<Integer>();
int outgoingLanesIndex = 0;
int sourceLanesIndex = 0;
while (outgoingLanesIndex < t.getLanes().length && sourceLanesIndex < lanes) {
if (splitLaneOptions[sourceLanesIndex].contains(";")) {
// Two or more allowed turns for this lane
int options = countOccurrences(splitLaneOptions[sourceLanesIndex], ';');
if (options == 1) {
if (outgoingLanesIndex + 1 >= t.getLanes().length) {
// Likely an error in data
return t;
}
int usability = t.getLanes()[outgoingLanesIndex] | t.getLanes()[outgoingLanesIndex + 1];
sourceLanes.add(usability);
outgoingLanesIndex += 2;
sourceLanesIndex++;
} else {
// Not supported
return t;
}
} else {
// Only one allowed turn; behave normally
sourceLanes.add(t.getLanes()[outgoingLanesIndex]);
outgoingLanesIndex++;
sourceLanesIndex++;
}
}
int[] newLanes = new int[sourceLanes.size()];
for (int i = 0; i < sourceLanes.size(); i++) {
newLanes[i] = sourceLanes.get(i);
}
t.setLanes(newLanes);
}
assignTurns(splitLaneOptions, t);
t = inferTurnFromLanes(t, leftSide);
return t;
}
private int countOccurrences(String haystack, char needle) {
int count = 0;
@ -742,7 +928,58 @@ public class RouteResultPreparation {
return count;
}
private void assignTurns(String[] splitLaneOptions, TurnType t) {
public static int[] parseTurnLanes(RouteDataObject ro, double dirToNorthEastPi) {
String turnLanes = null;
if (ro.getOneway() == 0) {
// we should get direction to detect forward or backward
double cmp = ro.directionRoute(0, true);
if(Math.abs(MapUtils.alignAngleDifference(dirToNorthEastPi -cmp)) < Math.PI / 2) {
turnLanes = ro.getValue("turn:lanes:forward");
} else {
turnLanes = ro.getValue("turn:lanes:backward");
}
} else {
turnLanes = ro.getValue("turn:lanes");
}
if(turnLanes == null) {
return null;
}
return calculateRawTurnLanes(turnLanes, 0);
}
public static int[] parseLanes(RouteDataObject ro, double dirToNorthEastPi) {
int lns = 0;
try {
if (ro.getOneway() == 0) {
// we should get direction to detect forward or backward
double cmp = ro.directionRoute(0, true);
if(Math.abs(MapUtils.alignAngleDifference(dirToNorthEastPi -cmp)) < Math.PI / 2) {
if(ro.getValue("lanes:forward") != null) {
lns = Integer.parseInt(ro.getValue("lanes:forward"));
}
} else {
if(ro.getValue("lanes:backward") != null) {
lns = Integer.parseInt(ro.getValue("lanes:backward"));
}
}
if (lns == 0 && ro.getValue("lanes") != null) {
lns = Integer.parseInt(ro.getValue("lanes")) / 2;
}
} else {
lns = Integer.parseInt(ro.getValue("lanes"));
}
if(lns > 0 ) {
return new int[lns];
}
} catch (NumberFormatException e) {
}
return null;
}
private static int[] calculateRawTurnLanes(String turnLanes, int calcTurnType) {
String[] splitLaneOptions = turnLanes.split("\\|", -1);
int[] lanes = new int[splitLaneOptions.length];
for (int i = 0; i < splitLaneOptions.length; i++) {
String[] laneOptions = splitLaneOptions[i].split(";");
@ -769,80 +1006,79 @@ public class RouteResultPreparation {
continue;
}
if (TurnType.getPrimaryTurn(t.getLanes()[i]) == 0) {
t.setPrimaryTurn(i, turn);
final int primary = TurnType.getPrimaryTurn(lanes[i]);
if (primary == 0) {
TurnType.setPrimaryTurnAndReset(lanes, i, turn);
} else {
if (turn == t.getValue()) {
t.setSecondaryTurn(i, TurnType.getPrimaryTurn(t.getLanes()[i]));
t.setPrimaryTurn(i, turn);
if (turn == calcTurnType ||
(TurnType.isRightTurn(calcTurnType) && TurnType.isRightTurn(turn)) ||
(TurnType.isLeftTurn(calcTurnType) && TurnType.isLeftTurn(turn))
) {
TurnType.setPrimaryTurnAndReset(lanes, i, turn);
TurnType.setSecondaryTurn(lanes, i, primary);
} else {
t.setSecondaryTurn(i, turn);
TurnType.setSecondaryTurn(lanes, i, turn);
}
break; // Move on to the next lane
}
}
}
return lanes;
}
private TurnType inferTurnFromLanes(TurnType t, boolean leftSide) {
List<Integer> possibleTurns = new ArrayList<Integer>();
for (int i = 0; i < t.getLanes().length; i++) {
if ((t.getLanes()[i] & 1) == 0) {
private int inferTurnFromLanes(int[] oLanes) {
TIntHashSet possibleTurns = new TIntHashSet();
for (int i = 0; i < oLanes.length; i++) {
if ((oLanes[i] & 1) == 0) {
continue;
}
if (possibleTurns.isEmpty()) {
// Nothing is in the list to compare to, so add the first elements
possibleTurns.add(TurnType.getPrimaryTurn(t.getLanes()[i]));
if (TurnType.getSecondaryTurn(t.getLanes()[i]) != 0) {
possibleTurns.add(TurnType.getSecondaryTurn(t.getLanes()[i]));
possibleTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
possibleTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
}
} else {
List<Integer> laneTurns = new ArrayList<Integer>();
laneTurns.add(TurnType.getPrimaryTurn(t.getLanes()[i]));
if (TurnType.getSecondaryTurn(t.getLanes()[i]) != 0) {
laneTurns.add(TurnType.getSecondaryTurn(t.getLanes()[i]));
TIntArrayList laneTurns = new TIntArrayList();
laneTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
laneTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
}
possibleTurns.retainAll(laneTurns);
if (possibleTurns.isEmpty()) {
// No common turns, so can't determine anything.
return t;
return 0;
}
}
}
// Remove all turns from lanes not selected...because those aren't it
for (int i = 0; i < t.getLanes().length; i++) {
if ((t.getLanes()[i] & 1) == 0 && !possibleTurns.isEmpty()) {
List<Integer> notLaneTurns = new ArrayList<Integer>();
notLaneTurns.add(TurnType.getPrimaryTurn(t.getLanes()[i]));
if (TurnType.getSecondaryTurn(t.getLanes()[i]) != 0) {
notLaneTurns.add(TurnType.getSecondaryTurn(t.getLanes()[i]));
for (int i = 0; i < oLanes.length; i++) {
if ((oLanes[i] & 1) == 0 && !possibleTurns.isEmpty()) {
possibleTurns.remove((Integer) TurnType.getPrimaryTurn(oLanes[i]));
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
possibleTurns.remove((Integer) TurnType.getSecondaryTurn(oLanes[i]));
}
possibleTurns.removeAll(notLaneTurns);
}
}
// Checking to see that there is only one unique turn
if (new HashSet<Integer>(possibleTurns).size() == 1) {
TurnType derivedTurnType = TurnType.valueOf(possibleTurns.get(0), leftSide);
derivedTurnType.setLanes(t.getLanes());
derivedTurnType.setSkipToSpeak(t.isSkipToSpeak());
t = derivedTurnType;
// Because only the primary turn is displayed, if the turn to be taken is currently set as the secondary turn, then that needs to be switched around.
for (int i = 0; i < t.getLanes().length; i++) {
if (TurnType.getSecondaryTurn(t.getLanes()[i]) == t.getValue()) {
int temp = TurnType.getSecondaryTurn(t.getLanes()[i]);
t.setSecondaryTurn(i, TurnType.getPrimaryTurn(t.getLanes()[i]));
t.setPrimaryTurn(i, temp);
if (possibleTurns.size() == 1) {
int infer = possibleTurns.iterator().next();
for(int i = 0; i < oLanes.length; i++) {
if(TurnType.getSecondaryTurn(oLanes[i]) == infer) {
int pt = TurnType.getPrimaryTurn(oLanes[i]);
int en = oLanes[i] & 1;
TurnType.setPrimaryTurnAndReset(oLanes, i, infer);
oLanes[i] |= en;
TurnType.setSecondaryTurn(oLanes, i, pt);
}
}
return infer;
}
return t;
return 0;
}
private boolean isMotorway(RouteSegmentResult s){

View file

@ -114,8 +114,10 @@ public class RoutingConfiguration {
}
public void addImpassableRoad(RouteDataObject r) {
impassableRoadIds.add(r.id);
impassableRoads.add(r);
if (!impassableRoadIds.contains(r.id)){
impassableRoadIds.add(r.id);
impassableRoads.add(r);
}
}

View file

@ -162,17 +162,19 @@ public class TurnType {
this.lanes = lanes;
}
// Note that there is no "weight" or ordering between the primary and secondary turns.
public void setPrimaryTurn(int lane, int turnType) {
lanes[lane] |= (turnType << 1);
// Note that the primary turn will be the one displayed on the map.
public static void setPrimaryTurnAndReset(int[] lanes, int lane, int turnType) {
lanes[lane] = (turnType << 1);
}
public static int getPrimaryTurn(int laneValue) {
// Get the primary turn modifier for the lane
return (laneValue >> 1) & ((1 << 4) - 1);
}
public void setSecondaryTurn(int lane, int turnType) {
public static void setSecondaryTurn(int[] lanes, int lane, int turnType) {
lanes[lane] |= (turnType << 5);
}
@ -237,4 +239,16 @@ public class TurnType {
}
return super.toString();
}
}
public static boolean isLeftTurn(int type) {
return type == TL || type == TSHL || type == TSLL || type == TRU;
}
public static boolean isRightTurn(int type) {
return type == TR || type == TSHR || type == TSLR || type == TU;
}
public static boolean isSlightTurn(int type) {
return type == TSLR || type == TSLL || type == KL || type == KR || type == C;
}
}

View file

@ -1,6 +1,8 @@
package net.osmand.util;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -82,15 +84,15 @@ public class GeoPointParserUtil {
// google calendar
// geo:0,0?q=760 West Genesee Street Syracuse NY 13204
String qstr = "q=760 West Genesee Street Syracuse NY 13204";
url = "geo:0,0?" + qstr;
String qstr = "760 West Genesee Street Syracuse NY 13204";
url = "geo:0,0?q=" + qstr;
System.out.println("url: " + url);
actual = GeoPointParserUtil.parse("geo", url);
assertGeoPoint(actual, new GeoParsedPoint(qstr.replaceAll("\\s+", "+")));
assertGeoPoint(actual, new GeoParsedPoint(qstr));
// geo:0,0?z=11&q=1600+Amphitheatre+Parkway,+CA
qstr = "q=1600+Amphitheatre+Parkway,+CA";
url = "geo:0,0?z=11&" + qstr;
qstr = "1600 Amphitheatre Parkway, CA";
url = "geo:0,0?z=11&q=" + URLEncoder.encode(qstr);
System.out.println("url: " + url);
actual = GeoPointParserUtil.parse("geo", url);
assertGeoPoint(actual, new GeoParsedPoint(qstr));
@ -330,7 +332,7 @@ public class GeoPointParserUtil {
/**
* Parses geo and map intents:
*
*
* @param scheme
* The intent scheme
* @param data
@ -450,48 +452,79 @@ public class GeoPointParserUtil {
return null;
}
if ("geo".equals(scheme) || "osmand.geo".equals(scheme)) {
final String schemeSpecific = data.getSchemeSpecificPart();
String schemeSpecific = data.getSchemeSpecificPart();
if (schemeSpecific == null) {
return null;
}
if (schemeSpecific.startsWith("0,0?")) {
// geo:0,0?q=34.99,-106.61(Treasure Island)
// geo:0,0?z=11&q=34.99,-106.61(Treasure Island)
String query = schemeSpecific.substring("0,0?".length());
final String pattern = "(?:z=(\\d{1,2}))?&?q=([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)[\\+]?(?:\\((.+?)\\))?";
final Matcher matcher = Pattern.compile(pattern).matcher(query);
if (matcher.matches()) {
final String z = matcher.group(1);
final String name = matcher.group(4);
final int zoom = z != null ? Integer.parseInt(z) : GeoParsedPoint.NO_ZOOM;
final double lat = Double.parseDouble(matcher.group(2));
final double lon = Double.parseDouble(matcher.group(3));
return new GeoParsedPoint(lat, lon, zoom, name);
} else {
// geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA
if (query.contains("z="))
query = query.substring(query.indexOf("&") + 1);
return new GeoParsedPoint(query);
}
} else {
// geo:47.6,-122.3
// geo:47.6,-122.3?z=11 (Treasure Island)
final String pattern = "([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)(?:(?:\\?z=(\\d{1,2}))?|(?:\\?q=.*?)?)[\\+]?(?:\\((.*?)\\))?";
final Matcher matcher = Pattern.compile(pattern).matcher(schemeSpecific);
if (matcher.matches()) {
final double lat = Double.valueOf(matcher.group(1));
final double lon = Double.valueOf(matcher.group(2));
final String name = matcher.group(4);
int zoom = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : GeoParsedPoint.NO_ZOOM;
if (zoom != GeoParsedPoint.NO_ZOOM) {
return new GeoParsedPoint(lat, lon, zoom, name);
} else {
return new GeoParsedPoint(lat, lon, name);
}
} else {
return null;
String name = null;
final Pattern namePattern = Pattern.compile("[\\+\\s]*\\((.*)\\)[\\+\\s]*$");
final Matcher nameMatcher = namePattern.matcher(schemeSpecific);
if (nameMatcher.find()) {
name = URLDecoder.decode(nameMatcher.group(1));
if (name != null) {
schemeSpecific = schemeSpecific.substring(0, nameMatcher.start());
}
}
String positionPart;
String queryPart = "";
int queryStartIndex = schemeSpecific.indexOf('?');
if (queryStartIndex == -1) {
positionPart = schemeSpecific;
} else {
positionPart = schemeSpecific.substring(0, queryStartIndex);
if (queryStartIndex < schemeSpecific.length())
queryPart = schemeSpecific.substring(queryStartIndex + 1);
}
final Pattern positionPattern = Pattern.compile(
"([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)");
final Matcher positionMatcher = positionPattern.matcher(positionPart);
if (!positionMatcher.find()) {
return null;
}
double lat = Double.valueOf(positionMatcher.group(1));
double lon = Double.valueOf(positionMatcher.group(2));
int zoom = GeoParsedPoint.NO_ZOOM;
String searchRequest = null;
for (String param : queryPart.split("&")) {
String paramName;
String paramValue = null;
int nameValueDelimititerIndex = param.indexOf('=');
if (nameValueDelimititerIndex == -1) {
paramName = param;
} else {
paramName = param.substring(0, nameValueDelimititerIndex);
if (nameValueDelimititerIndex < param.length())
paramValue = param.substring(nameValueDelimititerIndex + 1);
}
if ("z".equals(paramName) && paramValue != null) {
zoom = Integer.parseInt(paramValue);
} else if ("q".equals(paramName) && paramValue != null) {
searchRequest = URLDecoder.decode(paramValue);
}
}
if (searchRequest != null) {
final Matcher positionInSearchRequestMatcher =
positionPattern.matcher(searchRequest);
if (lat == 0.0 && lon == 0.0 && positionInSearchRequestMatcher.find()) {
lat = Double.valueOf(positionInSearchRequestMatcher.group(1));
lon = Double.valueOf(positionInSearchRequestMatcher.group(2));
}
}
if (lat == 0.0 && lon == 0.0 && searchRequest != null) {
return new GeoParsedPoint(searchRequest);
}
if (zoom != GeoParsedPoint.NO_ZOOM) {
return new GeoParsedPoint(lat, lon, zoom, name);
}
return new GeoParsedPoint(lat, lon, name);
}
return null;
}

View file

@ -165,11 +165,16 @@
<activity android:name="net.osmand.plus.activities.search.GeoIntentActivity" android:label="@string/app_name">
<intent-filter>
<data android:scheme="geo" />
<data android:scheme="osmand.geo" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<data android:scheme="geo" />
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
<intent-filter>
<data android:scheme="http" android:host="maps.google.com" />
<data android:scheme="https" android:host="maps.google.com" />

Binary file not shown.

View file

@ -38,14 +38,14 @@
</target>
<target name="fix_apostrophe_issues">
<replace token="version='1.0'" value="version=&quot;1.0&quot;">
<replace token="version='1.0'" value="version=&quot;1.0&quot;" encoding="UTF-8">
<fileset dir="res" includes="**/strings.xml" />
</replace>
<replace token="encoding='utf-8'" value="encoding=&quot;utf-8&quot;">
<replace token="encoding='utf-8'" value="encoding=&quot;utf-8&quot;" encoding="UTF-8">
<fileset dir="res" includes="**/strings.xml" />
</replace>
<replaceregexp match="([^\\])'" replace="\1\\\\'" flags="-g" byline="off">
<replaceregexp match="([^\\])'" replace="\1\\\\'" flags="-g" byline="off" encoding="UTF-8">
<fileset dir="res" includes="**/strings.xml" />
</replaceregexp>
</target>

View file

@ -84,6 +84,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dip"
android:autoLink="web"
android:gravity="center"
android:textSize="18sp" />

View file

@ -84,6 +84,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dip"
android:autoLink="web"
android:gravity="center"
android:textSize="18sp" />

View file

@ -2037,7 +2037,7 @@
<string name="traffic_warning_calming">교통량 감소</string>
<string name="traffic_warning_speed_camera">속도 경고 카메라</string>
<string name="traffic_warning">트래픽 경고</string>
<string name="local_index_description">기존 항목을 클릭하여 더 많은 정보를 보세요. 비활성화 하려면 꾹 눌러주시거나 삭제하세요. 현재 데이터는 (%1$ s 무료):</string>
<string name="local_index_description">기존 항목을 클릭하여 더 많은 정보를 보세요. 비활성화 하려면 꾹 눌러주시거나 삭제하세요. 현재 데이터는 (%1$s 무료):</string>
<string name="text_size_descr">지도에 텍스트 크기를 설정 합니다.</string>
<string name="text_size">텍스트 크기</string>
<string name="fav_point_dublicate">즐겨찾기 포인트 이름 중복</string>

View file

@ -1839,7 +1839,7 @@ OsmAnd yra aktyviai tobulinama ir mūsų projektas bei jo tolesnis progresas pri
<string name="text_size">Teksto dydis</string>
<string name="fav_point_dublicate">Pasikartojantis įsimintinos vietos pavadinimas</string>
<string name="fav_point_dublicate_message">Mes pakeitėme įsimintinos vietos pavadinimą į %1$s kad išvengtume pasikartojimų.</string>
<string name="local_index_description">Spustelėkite bet kurį elementą, norėdami gauti daugiau informacijos, paspauskite ir laikykite, norėdami išjungti arba ištrinti. Dabartiniai duomenys įrenginyje (%1$ s laisva):</string>
<string name="local_index_description">Spustelėkite bet kurį elementą, norėdami gauti daugiau informacijos, paspauskite ir laikykite, norėdami išjungti arba ištrinti. Dabartiniai duomenys įrenginyje (%1$s laisva):</string>
<string name="print_route">Išspausdinti maršrutą</string>
<string name="fav_point_emoticons_message">Mes pakeitėme jūsų įsimintos vietos pavadinimą į %1$s, nes teksto su veidukais išsaugoti faile neįmanoma.</string>
<string name="test_native_render">Testuoti aparatinį atvaizdavimą</string>

View file

@ -1,5 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<resources><string name="srtm_plugin_description">Плагин позволяет загружать контурные линии и затемнение высот для использования оффлайн (\"Настройки\" → \"Управление файлами карт\" → \"Загрузить\").</string>
<resources>
<string name="osmo_use_https_descr">Использовать безопасное соединение с сервером</string>
<string name="osmo_use_https">Использовать https</string>
<string name="srtm_plugin_description">Плагин позволяет загружать контурные линии и затемнение высот для использования оффлайн (\"Настройки\" → \"Управление файлами карт\" → \"Загрузить\").</string>
<string name="srtm_paid_version_msg">Рассмотрите, пожалуйста, покупку плагина \"Линии высот\" в Google Play, чтобы поддержать последующую разработку.</string>
<string name="srtm_paid_version_title">Линии высот</string>
<string name="av_def_action_video">Запись видео</string>

View file

@ -9,6 +9,13 @@
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="osmo_use_https_descr">Use secure connection with server</string>
<string name="osmo_use_https">Use https</string>
<string name="advanced_settings">Advanced</string>
<string name="rendering_attr_publicTransportMode_name">Bus, trolleybus, shuttle routes</string>
<string name="rendering_attr_tramTrainRoutes_name">Tram and train routes</string>
<string name="rendering_attr_subwayMode_name">Subway routes</string>
<string name="lock_screen_request_explanation">%1$s needs this permission to turn off the screen for the power saving feature.</string>
<string name="wake_on_voice">Turn on the screen</string>
<string name="wake_on_voice_descr">Turn on the phone screen when approaching a turn</string>
<string name="select_impassable_road">Select on map</string>

View file

@ -54,11 +54,11 @@ public class GLActivity extends Activity {
private ResolvedMapStyle _mapStyle;
private ObfsCollection _obfsCollection;
private MapPresentationEnvironment _mapPresentationEnvironment;
private Primitiviser _primitiviser;
private BinaryMapDataProvider _binaryMapDataProvider;
private BinaryMapPrimitivesProvider _binaryMapPrimitivesProvider;
private BinaryMapStaticSymbolsProvider _binaryMapStaticSymbolsProvider;
private BinaryMapRasterLayerProvider _binaryMapRasterLayerProvider;
private MapPrimitiviser _mapPrimitiviser;
private ObfMapObjectsProvider _obfMapObjectsProvider;
private MapPrimitivesProvider _mapPrimitivesProvider;
private MapObjectsSymbolsProvider _mapObjectsSymbolsProvider;
private MapRasterLayerProvider _mapRasterLayerProvider;
private OnlineRasterMapLayerProvider _onlineMapRasterLayerProvider;
private IMapRenderer _mapRenderer;
private GpuWorkerThreadPrologue _gpuWorkerThreadPrologue;
@ -194,19 +194,19 @@ public class GLActivity extends Activity {
_displayDensityFactor,
"en"); //TODO: here should be current locale
//mapPresentationEnvironment->setSettings(configuration.styleSettings);
_primitiviser = new Primitiviser(
_mapPrimitiviser = new MapPrimitiviser(
_mapPresentationEnvironment);
_binaryMapDataProvider = new BinaryMapDataProvider(
_obfMapObjectsProvider = new ObfMapObjectsProvider(
_obfsCollection);
_binaryMapPrimitivesProvider = new BinaryMapPrimitivesProvider(
_binaryMapDataProvider,
_primitiviser,
_mapPrimitivesProvider = new MapPrimitivesProvider(
_obfMapObjectsProvider,
_mapPrimitiviser,
_rasterTileSize);
_binaryMapStaticSymbolsProvider = new BinaryMapStaticSymbolsProvider(
_binaryMapPrimitivesProvider,
_mapObjectsSymbolsProvider = new MapObjectsSymbolsProvider(
_mapPrimitivesProvider,
_rasterTileSize);
_binaryMapRasterLayerProvider = new BinaryMapRasterLayerProvider_Software(
_binaryMapPrimitivesProvider);
_mapRasterLayerProvider = new MapRasterLayerProvider_Software(
_mapPrimitivesProvider);
_onlineMapRasterLayerProvider = OnlineTileSources.getBuiltIn().createProviderFor("Mapnik (OsmAnd)");
@ -222,14 +222,14 @@ public class GLActivity extends Activity {
atlasRendererConfiguration.setReferenceTileSizeOnScreenInPixels(_referenceTileSize);
_mapRenderer.setConfiguration(AtlasMapRendererConfiguration.Casts.downcastTo_MapRendererConfiguration(atlasRendererConfiguration));
_mapRenderer.addSymbolsProvider(_binaryMapStaticSymbolsProvider);
_mapRenderer.addSymbolsProvider(_mapObjectsSymbolsProvider);
updateView();
/*
IMapRasterLayerProvider mapnik = OnlineTileSources.getBuiltIn().createProviderFor("Mapnik (OsmAnd)");
if (mapnik == null)
Log.e(TAG, "Failed to create mapnik");
*/
_mapRenderer.setMapLayerProvider(0, _binaryMapRasterLayerProvider);
_mapRenderer.setMapLayerProvider(0, _mapRasterLayerProvider);
_glSurfaceView = (GLSurfaceView) findViewById(R.id.glSurfaceView);
//TODO:_glSurfaceView.setPreserveEGLContextOnPause(true);
@ -289,29 +289,29 @@ public class GLActivity extends Activity {
_mapPresentationEnvironment = null;
}
if (_primitiviser != null) {
_primitiviser.delete();
_primitiviser = null;
if (_mapPrimitiviser != null) {
_mapPrimitiviser.delete();
_mapPrimitiviser = null;
}
if (_binaryMapDataProvider != null) {
_binaryMapDataProvider.delete();
_binaryMapDataProvider = null;
if (_obfMapObjectsProvider != null) {
_obfMapObjectsProvider.delete();
_obfMapObjectsProvider = null;
}
if (_binaryMapPrimitivesProvider != null) {
_binaryMapPrimitivesProvider.delete();
_binaryMapPrimitivesProvider = null;
if (_mapPrimitivesProvider != null) {
_mapPrimitivesProvider.delete();
_mapPrimitivesProvider = null;
}
if (_binaryMapStaticSymbolsProvider != null) {
_binaryMapStaticSymbolsProvider.delete();
_binaryMapStaticSymbolsProvider = null;
if (_mapObjectsSymbolsProvider != null) {
_mapObjectsSymbolsProvider.delete();
_mapObjectsSymbolsProvider = null;
}
if (_binaryMapRasterLayerProvider != null) {
_binaryMapRasterLayerProvider.delete();
_binaryMapRasterLayerProvider = null;
if (_mapRasterLayerProvider != null) {
_mapRasterLayerProvider.delete();
_mapRasterLayerProvider = null;
}
if (_mapRenderer != null) {

View file

@ -0,0 +1,727 @@
<?xml version="1.0" ?>
<poi_types>
<poi_category name="shop">
<poi_filter name="shop_food">
<poi_type name="bakery" tag="shop" value="bakery"></poi_type>
<poi_type name="alcohol" tag="shop" value="alcohol"></poi_type>
<poi_type name="convenience" tag="shop" value="convenience"></poi_type>
<poi_type name="mall" tag="shop" value="mall"></poi_type>
<poi_type name="beverages" tag="shop" value="beverages"></poi_type>
<poi_type name="butcher" tag="shop" value="butcher"></poi_type>
<poi_type name="deli" tag="shop" value="deli"></poi_type>
<poi_type name="shop_farm" tag="shop" value="farm"></poi_type>
<poi_type name="greengrocer" tag="shop" value="greengrocer"></poi_type>
<poi_type name="seafood" tag="shop" value="seafood"></poi_type>
<poi_type name="confectionery" tag="shop" value="confectionery"></poi_type>
<poi_type name="ice_cream" tag="shop" value="ice_cream"></poi_type>
<poi_type name="supermarket" tag="shop" value="supermarket"></poi_type>
<poi_type name="shop_tea" tag="shop" value="tea"></poi_type>
<poi_type name="dairy" tag="shop" value="dairy"></poi_type>
<poi_type name="vending_machine" tag="amenity" value="vending_machine"></poi_type>
</poi_filter>
<poi_type name="bookshop" tag="shop" value="books"></poi_type>
<poi_type name="bicycle_shop" tag="shop" value="bicycle"></poi_type>
<poi_type name="mall" tag="shop" value="mall"></poi_type>
<poi_type name="anime_shop" tag="shop" value="anime"></poi_type>
<poi_type name="antiques_shop" tag="shop" value="antiques"></poi_type>
<poi_type name="art_shop" tag="shop" value="art"></poi_type>
<poi_type name="baby_goods" tag="shop" value="baby_goods"></poi_type>
<poi_type name="bag_shop" tag="shop" value="bag"></poi_type>
<poi_type name="bathroom_furnishing_shop" tag="shop" value="bathroom_furnishing"></poi_type>
<poi_type name="bed_shop" tag="shop" value="bed"></poi_type>
<poi_type name="boutique" tag="shop" value="boutique"></poi_type>
<poi_type name="carpet_shop" tag="shop" value="carpet"></poi_type>
<poi_type name="charity" tag="shop" value="charity"></poi_type>
<poi_type name="chemist_shop" tag="shop" value="chemist"></poi_type>
<poi_type name="clothes_shop" tag="shop" value="clothes"></poi_type>
<poi_type name="children_clothes_shop" tag="shop" value="clothes" tag2="clothes" value2="children"></poi_type>
<poi_type name="shoes" tag="shop" value="shoes"></poi_type>
<poi_type name="computer_shop" tag="shop" value="computer"></poi_type>
<poi_type name="copyshop" tag="shop" value="copyshop"></poi_type>
<poi_type name="curtain_shop" tag="shop" value="curtain"></poi_type>
<poi_type name="fabric_shop" tag="shop" value="fabric"></poi_type>
<poi_type name="bedding_shop" tag="shop" value="bedding"></poi_type>
<poi_type name="dive_shop" tag="shop" value="dive"></poi_type>
<poi_type name="doityourself_shop" tag="shop" value="doityourself"></poi_type>
<poi_type name="erotic_shop" tag="shop" value="erotic"></poi_type>
<poi_type name="fishing_shop" tag="shop" value="fishing"></poi_type>
<poi_type name="florist" tag="shop" value="florist"></poi_type>
<poi_type name="frame_shop" tag="shop" value="frame"></poi_type>
<poi_type name="furniture_shop" tag="shop" value="furniture"></poi_type>
<poi_type name="garden_centre" tag="shop" value="garden_centre"></poi_type>
<poi_type name="gas_shop" tag="shop" value="gas"></poi_type>
<poi_type name="general_shop" tag="shop" value="general"></poi_type>
<poi_type name="gift_shop" tag="shop" value="gift"></poi_type>
<poi_type name="glaziery_shop" tag="shop" value="glaziery"></poi_type>
<poi_type name="hardware_shop" tag="shop" value="hardware"></poi_type>
<poi_type name="hearing_aids_shop" tag="shop" value="hearing_aids"></poi_type>
<poi_type name="herbalist" tag="shop" value="herbalist"></poi_type>
<poi_type name="hifi_shop" tag="shop" value="hifi"></poi_type>
<poi_type name="houseware_shop" tag="shop" value="houseware"></poi_type>
<poi_type name="hunting_shop" tag="shop" value="hunting"></poi_type>
<poi_type name="interior_decoration_shop" tag="shop" value="interior_decoration"></poi_type>
<poi_type name="jewelry_shop" tag="shop" value="jewelry"></poi_type>
<poi_type name="kiosk" tag="shop" value="kiosk"></poi_type>
<poi_type name="kitchen_shop" tag="shop" value="kitchen"></poi_type>
<poi_type name="mobile_phone_shop" tag="shop" value="mobile_phone"></poi_type>
<poi_type name="motorcycle_shop" tag="shop" value="motorcycle"></poi_type>
<poi_type name="musical_instrument_shop" tag="shop" value="musical_instrument"></poi_type>
<poi_type name="newsagent_shop" tag="shop" value="newsagent"></poi_type>
<poi_type name="optician_shop" tag="shop" value="optician"></poi_type>
<poi_type name="organic_shop" tag="shop" value="organic"></poi_type>
<poi_type name="outdoor_shop" tag="shop" value="outdoor"></poi_type>
<poi_type name="paint_shop" tag="shop" value="paint"></poi_type>
<poi_type name="pet_shop" tag="shop" value="pet"></poi_type>
<poi_type name="radiotechnics_shop" tag="shop" value="radiotechnics"></poi_type>
<poi_type name="second_hand" tag="shop" value="second_hand"></poi_type>
<poi_type name="ship_chandler" tag="shop" value="ship_chandler"></poi_type>
<poi_type name="sports_shop" tag="shop" value="sports"></poi_type>
<poi_type name="stationery_shop" tag="shop" value="stationery"></poi_type>
<poi_type name="tableware_shop" tag="shop" value="tableware"></poi_type>
<poi_type name="ticket_shop" tag="shop" value="ticket"></poi_type>
<poi_type name="tobacco_shop" tag="shop" value="tobacco"></poi_type>
<poi_type name="toys_shop" tag="shop" value="toys"></poi_type>
<poi_type name="trade_shop" tag="shop" value="trade"></poi_type>
<poi_type name="vacuum_cleaner_shop" tag="shop" value="vacuum_cleaner"></poi_type>
<poi_type name="variety_store" tag="shop" value="variety_store"></poi_type>
<poi_type name="video_shop" tag="shop" value="video"></poi_type>
<poi_type name="window_blind_shop" tag="shop" value="window_blind"></poi_type>
<poi_type name="supermarket" tag="shop" value="supermarket"></poi_type>
<poi_type name="department_store" tag="shop" value="department_store"></poi_type>
<poi_type name="electronics_shop" tag="shop" value="electronics"></poi_type>
<poi_type name="car_shop" tag="shop" value="car"></poi_type>
<poi_type name="car_parts_shop" tag="shop" value="car_parts"></poi_type>
<poi_type name="atv_shop" tag="shop" value="atv"></poi_type>
<poi_type name="pawnbroker" tag="shop" value="pawnbroker"></poi_type>
<poi_type name="cosmetics_shop" tag="shop" value="cosmetics"></poi_type>
<poi_type name="marketplace" tag="amenity" value="marketplace"></poi_type>
<poi_type name="sewing_shop" tag="shop" value="sewing"></poi_type>
</poi_category>
<poi_category name="emergency">
<poi_type name="police" tag="amenity" value="police"></poi_type>
<poi_type name="fire_station" tag="amenity" value="fire_station"></poi_type>
<poi_type name="emergency_phone" tag="emergency" value="phone"></poi_type>
<poi_type name="fire_hydrant" tag="emergency" value="fire_hydrant"></poi_type>
<poi_type name="fire_extinguisher" tag="emergency" value="fire_extinguisher"></poi_type>
<poi_type name="fire_flapper" tag="emergency" value="fire_flapper"></poi_type>
<poi_type name="fire_hose" tag="emergency" value="fire_hose"></poi_type>
<poi_type name="fire_water_pond" tag="emergency" value="fire_water_pond"></poi_type>
<poi_type name="grit_bin" tag="amenity" value="grit_bin"></poi_type>
<poi_type name="ambulance_station" tag="emergency" value="ambulance_station"></poi_type>
<poi_type name="ses_station" tag="emergency" value="ses_station"></poi_type>
<poi_type name="emergency_access_point" tag="highway" value="emergency_access_point"></poi_type>
</poi_category>
<poi_category name="transportation">
<poi_filter name="road_obstacles">
<poi_type name="ford" tag="highway" value="ford"></poi_type>
<poi_type name="mountain_pass" tag="mountain_pass" value="yes"></poi_type>
<poi_type name="gate" tag="barrier" value="gate"></poi_type>
<poi_type name="city_wall" tag="barrier" value="city_wall"></poi_type>
<poi_type name="lift_gate" tag="barrier" value="lift_gate"></poi_type>
<poi_type name="toll_booth" tag="barrier" value="toll_booth"></poi_type>
<poi_type name="border_control" tag="barrier" value="border_control"></poi_type>
<poi_type name="traffic_calming_bump" tag="traffic_calming" value="bump"></poi_type>
<poi_type name="traffic_calming_hump" tag="traffic_calming" value="hump"></poi_type>
<poi_type name="traffic_calming_cushion" tag="traffic_calming" value="cushion"></poi_type>
<poi_type name="traffic_calming_chicane" tag="traffic_calming" value="chicane"></poi_type>
<poi_type name="traffic_calming_rumble_strip" tag="traffic_calming" value="rumble_strip"></poi_type>
<poi_type name="traffic_calming_table" tag="traffic_calming" value="table"></poi_type>
<poi_type name="traffic_calming_choker" tag="traffic_calming" value="choker"></poi_type>
<poi_type name="traffic_signals" tag="highway" value="traffic_signals"></poi_type>
</poi_filter>
<poi_filter name="personal_transport">
<poi_type name="car_repair" tag="shop" value="car_repair"></poi_type>
<poi_type name="service_tyres" tag="shop" value="car_repair" tag2="service" value2="tyres"></poi_type>
<poi_type name="vehicle_inspection" tag="amenity" value="vehicle_inspection"></poi_type>
<poi_type name="car_wash" tag="amenity" value="car_wash"></poi_type>
<poi_type name="fuel" tag="amenity" value="fuel"></poi_type>
<poi_type name="charging_station" tag="amenity" value="charging_station"></poi_type>
<poi_type name="vehicle_ramp" tag="amenity" value="vehicle_ramp"></poi_type>
<poi_type name="compressed_air" tag="amenity" value="compressed_air"></poi_type>
<poi_type name="parking" tag="amenity" value="parking"></poi_type>
<poi_type name="motorcycle_parking" tag="amenity" value="motorcycle_parking"></poi_type>
<poi_type name="parking_entrance" tag="amenity" value="parking_entrance"></poi_type>
<poi_type name="garages" tag="landuse" value="garages"></poi_type>
</poi_filter>
<poi_filter name="public_transport">
<poi_type name="public_transport_platform" tag="public_transport" value="platform"></poi_type>
<poi_type name="public_transport_platform_bus" tag="public_transport" value="platform" tag2="route" value2="bus"></poi_type>
<poi_type name="public_transport_platform_trolleybus" tag="public_transport" value="platform" tag2="route" value2="trolleybus"></poi_type>
<poi_type name="bus_stop" tag="highway" value="bus_stop"></poi_type>
<poi_type name="public_transport_platform_tram" tag="public_transport" value="platform" tag2="route" value2="tram"></poi_type>
<poi_type name="tram_stop" tag="railway" value="tram_stop"></poi_type>
<poi_type name="public_transport_station" tag="public_transport" value="station"></poi_type>
<poi_type name="bus_station" tag="amenity" value="bus_station"></poi_type>
<poi_type name="railway_station" tag="railway" value="station"></poi_type>
<poi_type name="railway_platform" tag="railway" value="platform"></poi_type>
<poi_type name="railway_halt" tag="railway" value="halt"></poi_type>
<poi_type name="subway_entrance" tag="railway" value="subway_entrance"></poi_type>
<poi_type name="subway_station" tag="railway" value="station" tag2="station" value2="subway"></poi_type>
<poi_type name="taxi" tag="amenity" value="taxi"></poi_type>
<poi_type name="funicular" tag="railway" value="funicular"></poi_type>
</poi_filter>
<poi_filter name="air_transport">
<poi_type name="airport" tag="aeroway" value="aerodrome"></poi_type>
<poi_type name="helipad" tag="aeroway" value="helipad"></poi_type>
<poi_type name="runway" tag="aeroway" value="runway"></poi_type>
<poi_type name="aeroway_terminal" tag="aeroway" value="terminal"></poi_type>
<poi_type name="aeroway_gate" tag="aeroway" value="gate"></poi_type>
</poi_filter>
<poi_filter name="water_transport">
<poi_type name="slipway" tag="leisure" value="slipway"></poi_type>
<poi_type name="ferry_terminal" tag="amenity" value="ferry_terminal"></poi_type>
<poi_type name="lighthouse" tag="man_made" value="lighthouse"></poi_type>
</poi_filter>
<poi_filter name="bicycle_transport">
<poi_type name="bicycle_rental" tag="amenity" value="bicycle_rental"></poi_type>
<poi_type name="bicycle_parking" tag="amenity" value="bicycle_parking"></poi_type>
</poi_filter>
<poi_filter name="aerialway_transport">
<poi_type name="aerialway_station" tag="aerialway" value="station"></poi_type>
<poi_type name="aerialway_cable_car" tag="aerialway" value="cable_car"></poi_type>
<poi_type name="aerialway_gondola" tag="aerialway" value="gondola"></poi_type>
<poi_type name="aerialway_chair_lift" tag="aerialway" value="chair_lift"></poi_type>
<poi_type name="aerialway_t_bar" tag="aerialway" value="t-bar"></poi_type>
<poi_type name="aerialway_j_bar" tag="aerialway" value="j-bar"></poi_type>
<poi_type name="aerialway_platter" tag="aerialway" value="platter"></poi_type>
<poi_type name="aerialway_mixed_lift" tag="aerialway" value="mixed_lift"></poi_type>
<poi_type name="aerialway_drag_lift" tag="aerialway" value="drag_lift"></poi_type>
<poi_type name="aerialway_rope_tow" tag="aerialway" value="rope_tow"></poi_type>
<poi_type name="aerialway_goods" tag="aerialway" value="goods"></poi_type>
<poi_type name="aerialway_magic_carpet" tag="aerialway" value="magic_carpet"></poi_type>
</poi_filter>
<poi_filter name="transport_constructions">
<poi_type name="tunnel" tag="man_made" value="tunnel"></poi_type>
<poi_type name="bridge" tag="man_made" value="bridge"></poi_type>
</poi_filter>
<poi_type name="speed_camera" tag="highway" value="speed_camera"></poi_type>
<poi_type name="turning_circle" tag="highway" value="turning_circle"></poi_type>
<poi_type name="motorway_junction" tag="highway" value="motorway_junction"></poi_type>
</poi_category>
<poi_category name="man_made">
<poi_filter name="transport_constructions">
<poi_type name="tunnel" tag="man_made" value="tunnel"></poi_type>
<poi_type name="bridge" tag="man_made" value="bridge"></poi_type>
</poi_filter>
<poi_filter name="water_supply">
<poi_type name="water_well" tag="man_made" value="water_well"></poi_type>
<poi_type name="standpipe" tag="man_made" value="standpipe"></poi_type>
<poi_type name="water_works" tag="man_made" value="water_works"></poi_type>
<poi_type name="boatyard" tag="waterway" value="boatyard"></poi_type>
<poi_type name="wastewater_plant" tag="man_made" value="wastewater_plant"></poi_type>
<poi_type name="water_tower" tag="man_made" value="water_tower"></poi_type>
<poi_type name="lock_gate" tag="waterway" value="lock_gate"></poi_type>
<poi_type name="waterway_turning_point" tag="waterway" value="turning_point"></poi_type>
<poi_type name="weir" tag="waterway" value="weir"></poi_type>
<poi_type name="dam" tag="man_made" value="dam"></poi_type>
<poi_type name="mill_pond" tag="waterway" value="mill_pond"></poi_type>
<poi_type name="water_mill" tag="man_made" value="water_mill"></poi_type>
<poi_type name="salt_pond" tag="landuse" value="salt_pond"></poi_type>
</poi_filter>
<poi_filter name="power">
<poi_type name="power_substation" tag="power" value="substation"></poi_type>
<poi_type name="power_transformer" tag="power" value="transformer"></poi_type>
<poi_type name="power_plant" tag="plant:output:electricity" value="*" tag2="power" value2="plant"></poi_type>
<poi_type name="power_generator" tag="power" value="generator" tag2="generator:output:electricity" value2="*"></poi_type>
</poi_filter>
<poi_filter name="communications">
<poi_type name="post_office" tag="amenity" value="post_office"></poi_type>
<poi_type name="post_box" tag="amenity" value="post_box"></poi_type>
<poi_type name="telephone" tag="amenity" value="telephone"></poi_type>
<poi_type name="emergency_phone" tag="emergency" value="phone"></poi_type>
<poi_type name="communication_tower" tag="man_made" value="communications_tower"></poi_type>
<poi_type name="telephone_exchange" tag="man_made" value="telephone_exchange"></poi_type>
</poi_filter>
<poi_filter name="trash_disposal">
<poi_type name="recycling" tag="amenity" value="recycling"></poi_type>
<poi_type name="landfill" tag="landuse" value="landfill"></poi_type>
<poi_type name="waste_disposal" tag="amenity" value="waste_disposal"></poi_type>
<poi_type name="waste_basket" tag="amenity" value="waste_basket"></poi_type>
</poi_filter>
<poi_type name="pier" tag="man_made" value="pier"></poi_type>
<poi_type name="surveillance" tag="man_made" value="surveillance"></poi_type>
<poi_type name="observatory" tag="man_made" value="observatory"></poi_type>
<poi_type name="astronomical_observatory" tag="man_made" value="observatory" tag2="observatory:type" value2="astronomical"></poi_type>
<poi_type name="tower" tag="man_made" value="tower"></poi_type>
<poi_type name="mast" tag="man_made" value="mast"></poi_type>
<poi_type name="radar" tag="man_made" value="monitoring_station" tag2="monitoring_station" value2="radar"></poi_type>
<poi_type name="construction" tag="landuse" value="construction"></poi_type>
<poi_type name="works" tag="man_made" value="works"></poi_type>
<poi_type name="mineshaft" tag="man_made" value="mineshaft"></poi_type>
<poi_type name="adit" tag="man_made" value="adit"></poi_type>
<poi_type name="petroleum_well" tag="man_made" value="petroleum_well"></poi_type>
<poi_type name="survey_point" tag="man_made" value="survey_point"></poi_type>
<poi_type name="windmill" tag="man_made" value="windmill"></poi_type>
<poi_type name="quarry" tag="landuse" value="quarry"></poi_type>
<poi_type name="vineyard" tag="landuse" value="vineyard"></poi_type>
<poi_type name="orchard" tag="landuse" value="orchard"></poi_type>
<poi_type name="cricket_nets" tag="sport" value="cricket_nets"></poi_type>
</poi_category>
<poi_category name="education">
<poi_type name="driving_school" tag="amenity" value="driving_school"></poi_type>
<poi_type name="school" tag="amenity" value="school"></poi_type>
<poi_type name="kindergarten" tag="amenity" value="kindergarten"></poi_type>
<poi_type name="library" tag="amenity" value="library"></poi_type>
<poi_type name="college" tag="amenity" value="college"></poi_type>
<poi_type name="university" tag="amenity" value="university"></poi_type>
</poi_category>
<poi_category name="administrative">
<poi_type name="social_facility" tag="amenity" value="social_facility"></poi_type>
<poi_type name="police" tag="amenity" value="police"></poi_type>
<poi_type name="courthouse" tag="amenity" value="courthouse"></poi_type>
<poi_type name="prison" tag="amenity" value="prison"></poi_type>
<poi_type name="register_office" tag="amenity" value="register_office"></poi_type>
<poi_type name="embassy" tag="amenity" value="embassy"></poi_type>
<poi_type name="government" tag="office" value="government"></poi_type>
<poi_type name="bailiff" tag="office" value="government" tag2="government" value2="bailiff"></poi_type>
<poi_type name="prosecutor" tag="office" value="government" tag2="government" value2="prosecutor"></poi_type>
<poi_type name="pension_fund" tag="office" value="government" tag2="government" value2="pension_fund"></poi_type>
<poi_type name="migration" tag="office" value="government" tag2="government" value2="migration"></poi_type>
<poi_type name="tax_inspection" tag="office" value="government" tag2="government" value2="taxes"></poi_type>
<poi_type name="administrative_office" tag="office" value="administrative"></poi_type>
<poi_type name="town_hall" tag="amenity" value="townhall"></poi_type>
<poi_type name="customs" tag="amenity" value="customs"></poi_type>
<poi_type name="city" tag="place" value="city"></poi_type>
<poi_type name="town" tag="place" value="town"></poi_type>
<poi_type name="village" tag="place" value="village"></poi_type>
<poi_type name="hamlet" tag="place" value="hamlet"></poi_type>
<poi_type name="isolated_dwelling" tag="place" value="isolated_dwelling"></poi_type>
<poi_type name="suburb" tag="place" value="suburb"></poi_type>
<poi_type name="neighbourhood" tag="place" value="neighbourhood"></poi_type>
<poi_type name="locality" tag="place" value="locality"></poi_type>
<poi_type name="place_allotments" tag="place" value="allotments"></poi_type>
<poi_type name="place_farm" tag="place" value="farm"></poi_type>
</poi_category>
<poi_category name="healthcare">
<poi_type name="pharmacy" tag="amenity" value="pharmacy"></poi_type>
<poi_type name="hospital" tag="amenity" value="hospital"></poi_type>
<poi_type name="doctors" tag="amenity" value="doctors"></poi_type>
<poi_type name="clinic" tag="amenity" value="clinic"></poi_type>
<poi_type name="first_aid" tag="amenity" value="first_aid"></poi_type>
<poi_type name="dentist" tag="amenity" value="dentist"></poi_type>
<poi_type name="nursing_home" tag="amenity" value="nursing_home"></poi_type>
<poi_type name="baby_hatch" tag="amenity" value="baby_hatch"></poi_type>
<poi_type name="veterinary" tag="amenity" value="veterinary"></poi_type>
<poi_type name="ambulance_station" tag="emergency" value="ambulance_station"></poi_type>
<poi_type name="sanatorium" tag="amenity" value="sanatorium"></poi_type>
<poi_type name="healthcare_alternative" tag="healthcare" value="alternative"></poi_type>
<poi_type name="audiologist" tag="healthcare" value="audiologist"></poi_type>
<poi_type name="blood_bank" tag="healthcare" value="blood_bank"></poi_type>
<poi_type name="healthcare_centre" tag="healthcare" value="centre"></poi_type>
<poi_type name="midwife" tag="healthcare" value="midwife"></poi_type>
<poi_type name="occupational_therapist" tag="healthcare" value="occupational_therapist"></poi_type>
<poi_type name="optometrist" tag="healthcare" value="optometrist"></poi_type>
<poi_type name="physiotherapist" tag="healthcare" value="physiotherapist"></poi_type>
<poi_type name="podiatrist" tag="healthcare" value="podiatrist"></poi_type>
<poi_type name="psychotherapist" tag="healthcare" value="psychotherapist"></poi_type>
<poi_type name="healthcare_rehabilitation" tag="healthcare" value="rehabilitation"></poi_type>
<poi_type name="speech_therapist" tag="healthcare" value="speech_therapist"></poi_type>
<poi_type name="healthcare_yes" tag="healthcare" value="yes"></poi_type>
</poi_category>
<poi_category name="office">
<poi_type name="company" tag="office" value="company"></poi_type>
<poi_type name="insurance" tag="office" value="insurance"></poi_type>
<poi_type name="estate_agent" tag="office" value="estate_agent"></poi_type>
<poi_type name="lawyer" tag="office" value="lawyer"></poi_type>
<poi_type name="telecommunication_office" tag="office" value="telecommunication"></poi_type>
<poi_type name="travel_agent" tag="office" value="travel_agent"></poi_type>
<poi_type name="ngo" tag="office" value="ngo"></poi_type>
<poi_type name="town_hall" tag="amenity" value="townhall"></poi_type>
<poi_type name="accountant" tag="office" value="accountant"></poi_type>
<poi_type name="employment_agency" tag="office" value="employment_agency"></poi_type>
<poi_type name="research_office" tag="office" value="research"></poi_type>
<poi_type name="it_office" tag="office" value="it"></poi_type>
<poi_type name="newspaper_office" tag="office" value="newspaper"></poi_type>
<poi_type name="architect_office" tag="office" value="architect"></poi_type>
<poi_type name="advertising_agency" tag="office" value="advertising_agency"></poi_type>
<poi_type name="educational_institution" tag="office" value="educational_institution"></poi_type>
<poi_type name="studio" tag="amenity" value="studio"></poi_type>
<poi_type name="bookmaker" tag="shop" value="bookmaker"></poi_type>
</poi_category>
<poi_category name="sport">
<poi_type name="stadium" tag="leisure" value="stadium"></poi_type>
<poi_type name="sports_centre" tag="leisure" value="sports_centre"></poi_type>
<poi_type name="golf_course" tag="leisure" value="golf_course"></poi_type>
<poi_type name="ice_rink" tag="leisure" value="ice_rink"></poi_type>
<poi_type name="pitch" tag="leisure" value="pitch"></poi_type>
<poi_type name="leisure_track" tag="leisure" value="track"></poi_type>
<poi_type name="running_track" tag="sport" value="running" tag2="leisure" value2="track"></poi_type>
<poi_type name="bicycle_track" tag="sport" value="cycling" tag2="leisure" value2="track"></poi_type>
<poi_type name="horse_track" tag="sport" value="horse_racing" tag2="leisure" value2="track"></poi_type>
<poi_type name="raceway" tag="highway" value="raceway"></poi_type>
<poi_type name="club_sport" tag="club" value="sport"></poi_type>
<poi_type name="9pin" tag="sport" value="9pin"></poi_type>
<poi_type name="10pin" tag="sport" value="10pin"></poi_type>
<poi_type name="archery" tag="sport" value="archery"></poi_type>
<poi_type name="athletics" tag="sport" value="athletics"></poi_type>
<poi_type name="american_football" tag="sport" value="american_football"></poi_type>
<poi_type name="australian_football" tag="sport" value="australian_football"></poi_type>
<poi_type name="base" tag="sport" value="base"></poi_type>
<poi_type name="baseball" tag="sport" value="baseball"></poi_type>
<poi_type name="basketball" tag="sport" value="basketball"></poi_type>
<poi_type name="beachvolleyball" tag="sport" value="beachvolleyball"></poi_type>
<poi_type name="bmx_sport" tag="sport" value="bmx"></poi_type>
<poi_type name="boules" tag="sport" value="boules"></poi_type>
<poi_type name="bowls" tag="sport" value="bowls"></poi_type>
<poi_type name="canadian_football" tag="sport" value="canadian_football"></poi_type>
<poi_type name="canoe" tag="sport" value="canoe"></poi_type>
<poi_type name="chess" tag="sport" value="chess"></poi_type>
<poi_type name="climbing" tag="sport" value="climbing"></poi_type>
<poi_type name="cricket" tag="sport" value="cricket"></poi_type>
<poi_type name="croquet" tag="sport" value="croquet"></poi_type>
<poi_type name="cycling" tag="sport" value="cycling"></poi_type>
<poi_type name="diving" tag="sport" value="diving"></poi_type>
<poi_type name="scuba_diving" tag="sport" value="scuba_diving"></poi_type>
<poi_type name="dog_racing" tag="sport" value="dog_racing"></poi_type>
<poi_type name="equestrian" tag="sport" value="equestrian"></poi_type>
<poi_type name="football" tag="sport" value="football"></poi_type>
<poi_type name="golf" tag="sport" value="golf"></poi_type>
<poi_type name="gymnastics" tag="sport" value="gymnastics"></poi_type>
<poi_type name="handball" tag="sport" value="handball"></poi_type>
<poi_type name="hockey" tag="sport" value="hockey"></poi_type>
<poi_type name="horse_racing" tag="sport" value="horse_racing"></poi_type>
<poi_type name="ice_skating" tag="sport" value="ice_skating"></poi_type>
<poi_type name="ice_stock" tag="sport" value="ice_stock"></poi_type>
<poi_type name="korfbal" tag="sport" value="korfball"></poi_type>
<poi_type name="motor_sport" tag="sport" value="motor"></poi_type>
<poi_type name="multi_sport" tag="sport" value="multi"></poi_type>
<poi_type name="orienteering" tag="sport" value="orienteering"></poi_type>
<poi_type name="paddle_tennis" tag="sport" value="paddle_tennis"></poi_type>
<poi_type name="paragliding" tag="sport" value="paragliding"></poi_type>
<poi_type name="pelota" tag="sport" value="pelota"></poi_type>
<poi_type name="racquet" tag="sport" value="racquet"></poi_type>
<poi_type name="roller_skating" tag="sport" value="roller_skating"></poi_type>
<poi_type name="rowing" tag="sport" value="rowing"></poi_type>
<poi_type name="rugby" tag="sport" value="rugby"></poi_type>
<poi_type name="sailing" tag="sport" value="sailing"></poi_type>
<poi_type name="shooting" tag="sport" value="shooting"></poi_type>
<poi_type name="skating" tag="sport" value="skating"></poi_type>
<poi_type name="skateboard" tag="sport" value="skateboard"></poi_type>
<poi_type name="skiing" tag="sport" value="skiing"></poi_type>
<poi_type name="soccer" tag="sport" value="soccer"></poi_type>
<poi_type name="surfing" tag="sport" value="surfing"></poi_type>
<poi_type name="swimming" tag="sport" value="swimming"></poi_type>
<poi_type name="table_tennis" tag="sport" value="table_tennis"></poi_type>
<poi_type name="tennis" tag="sport" value="tennis"></poi_type>
<poi_type name="toboggan" tag="sport" value="toboggan"></poi_type>
<poi_type name="volleyball" tag="sport" value="volleyball"></poi_type>
</poi_category>
<poi_category name="tourism">
<poi_filter name="sights">
<poi_type name="museum" tag="tourism" value="museum"></poi_type>
<poi_type name="memorial" tag="historic" value="memorial"></poi_type>
<poi_type name="artwork" tag="tourism" value="artwork"></poi_type>
<poi_type name="archaeological_site" tag="historic" value="archaeological_site"></poi_type>
<poi_type name="palaeontological_site" tag="geological" value="palaeontological_site"></poi_type>
<poi_type name="battlefield" tag="historic" value="battlefield"></poi_type>
<poi_type name="boundary_stone" tag="historic" value="boundary_stone"></poi_type>
<poi_type name="cannon" tag="historic" value="cannon"></poi_type>
<poi_type name="castle" tag="historic" value="castle"></poi_type>
<poi_type name="city_gate" tag="historic" value="city_gate"></poi_type>
<poi_type name="fort" tag="historic" value="fort"></poi_type>
<poi_type name="fountain" tag="amenity" value="fountain"></poi_type>
<poi_type name="ruins_historic" tag="historic" value="ruins"></poi_type>
<poi_type name="rune_stone" tag="historic" value="rune_stone"></poi_type>
<poi_type name="wreck" tag="historic" value="wreck"></poi_type>
<poi_type name="ship_historic" tag="historic" value="ship"></poi_type>
<poi_type name="mine_historic" tag="historic" value="mine"></poi_type>
<poi_type name="monument" tag="historic" value="monument"></poi_type>
<poi_type name="viewpoint" tag="tourism" value="viewpoint"></poi_type>
<poi_type name="zoo" tag="tourism" value="zoo"></poi_type>
<poi_type name="aquarium" tag="tourism" value="aquarium"></poi_type>
<poi_type name="theme_park" tag="tourism" value="theme_park"></poi_type>
<poi_type name="lighthouse" tag="man_made" value="lighthouse"></poi_type>
</poi_filter>
<poi_filter name="attraction">
<poi_type name="attraction" tag="tourism" value="attraction"></poi_type>
<poi_type name="amusement_ride" tag="tourism" value="amusement_ride"></poi_type>
<poi_type name="attraction_animal" tag="tourism" value="animal"></poi_type>
<poi_type name="ferris_wheel" tag="tourism" value="big_wheel"></poi_type>
<poi_type name="carousel" tag="tourism" value="carousel"></poi_type>
<poi_type name="maze" tag="tourism" value="maze"></poi_type>
<poi_type name="roller_coaster" tag="tourism" value="roller_coaster"></poi_type>
<poi_type name="slide" tag="tourism" value="slide"></poi_type>
<poi_type name="summer_toboggan" tag="tourism" value="summer_toboggan"></poi_type>
<poi_type name="swing_carousel" tag="tourism" value="swing_carousel"></poi_type>
<poi_type name="attraction_train" tag="tourism" value="train"></poi_type>
<poi_type name="water_slide" tag="tourism" value="water_slide"></poi_type>
</poi_filter>
<poi_filter name="lodging">
<poi_type name="hotel" tag="tourism" value="hotel"></poi_type>
<poi_type name="guest_house" tag="tourism" value="guest_house"></poi_type>
<poi_type name="hostel" tag="tourism" value="hostel"></poi_type>
<poi_type name="motel" tag="tourism" value="motel"></poi_type>
<poi_type name="alpine_hut" tag="tourism" value="alpine_hut"></poi_type>
<poi_type name="chalet" tag="tourism" value="chalet"></poi_type>
</poi_filter>
<poi_type name="place_of_worship" tag="amenity" value="place_of_worship"></poi_type>
<poi_type name="place_of_worship_christian" tag="religion" value="christian" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_jewish" tag="religion" value="jewish" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_muslim" tag="religion" value="muslim" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_sikh" tag="religion" value="sikh" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_buddhist" tag="religion" value="buddhist" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_hindu" tag="religion" value="hindu" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_shinto" tag="religion" value="shinto" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="place_of_worship_taoist" tag="religion" value="taoist" tag2="amenity" value2="place_of_worship"></poi_type>
<poi_type name="monastery" tag="amenity" value="monastery"></poi_type>
<poi_type name="historic_monastery" tag="historic" value="monastery"></poi_type>
<poi_type name="wayside_cross" tag="historic" value="wayside_cross"></poi_type>
<poi_type name="wayside_shrine" tag="historic" value="wayside_shrine"></poi_type>
<poi_type name="tourism_information" tag="tourism" value="information"></poi_type>
<poi_type name="clock" tag="amenity" value="clock"></poi_type>
<poi_type name="travel_agent" tag="office" value="travel_agent"></poi_type>
<poi_type name="viewpoint" tag="tourism" value="viewpoint"></poi_type>
<poi_type name="camp_site" tag="tourism" value="camp_site"></poi_type>
<poi_type name="caravan_site" tag="tourism" value="caravan_site"></poi_type>
<poi_type name="picnic_site" tag="tourism" value="picnic_site"></poi_type>
<poi_type name="spring" tag="natural" value="spring"></poi_type>
<poi_type name="hot_spring" tag="natural" value="hot_spring"></poi_type>
<poi_type name="cemetery" tag="landuse" value="cemetery"></poi_type>
<poi_type name="grave_yard" tag="amenity" value="grave_yard"></poi_type>
<poi_type name="shelter" tag="amenity" value="shelter"></poi_type>
<poi_type name="club_tourism" tag="club" value="tourism"></poi_type>
<poi_type name="funicular" tag="railway" value="funicular"></poi_type>
<poi_type name="resort" tag="leisure" value="resort"></poi_type>
</poi_category>
<poi_category name="leisure">
<poi_filter name="clubs">
<poi_type name="club_art" tag="club" value="art"></poi_type>
<poi_type name="club_astronomy" tag="club" value="astronomy"></poi_type>
<poi_type name="club_computer" tag="club" value="computer"></poi_type>
<poi_type name="club_board_games" tag="club" value="board_games"></poi_type>
<poi_type name="club_motorcycle" tag="club" value="motorcycle"></poi_type>
<poi_type name="club_sport" tag="club" value="sport"></poi_type>
<poi_type name="club_game" tag="club" value="game"></poi_type>
<poi_type name="club_automobile" tag="club" value="automobile"></poi_type>
<poi_type name="club_chess" tag="club" value="chess"></poi_type>
<poi_type name="club_cinema" tag="club" value="cinema"></poi_type>
<poi_type name="club_fan" tag="club" value="fan"></poi_type>
<poi_type name="club_fishing" tag="club" value="fishing"></poi_type>
<poi_type name="club_veterans" tag="club" value="veterans"></poi_type>
<poi_type name="club_linux" tag="club" value="linux"></poi_type>
<poi_type name="club_theatre" tag="club" value="theatre"></poi_type>
<poi_type name="club_history" tag="club" value="history"></poi_type>
<poi_type name="club_music" tag="club" value="music"></poi_type>
<poi_type name="club_ethnic" tag="club" value="ethnic"></poi_type>
<poi_type name="club_nature" tag="club" value="nature"></poi_type>
<poi_type name="club_photography" tag="club" value="photography"></poi_type>
<poi_type name="club_hunting" tag="club" value="hunting"></poi_type>
<poi_type name="club_shooting" tag="club" value="shooting"></poi_type>
<poi_type name="club_tourism" tag="club" value="tourism"></poi_type>
<poi_type name="club_charity" tag="club" value="charity"></poi_type>
</poi_filter>
<poi_type name="library" tag="amenity" value="library"></poi_type>
<poi_type name="arts_centre" tag="amenity" value="arts_centre"></poi_type>
<poi_type name="cinema" tag="amenity" value="cinema"></poi_type>
<poi_type name="casino" tag="amenity" value="casino"></poi_type>
<poi_type name="community_centre" tag="amenity" value="community_centre"></poi_type>
<poi_type name="social_centre" tag="amenity" value="social_centre"></poi_type>
<poi_type name="theatre" tag="amenity" value="theatre"></poi_type>
<poi_type name="circus" tag="theatre:genre" value="circus" tag2="amenity" value2="theatre"></poi_type>
<poi_type name="museum" tag="tourism" value="museum"></poi_type>
<poi_type name="dance_floor" tag="leisure" value="dance"></poi_type>
<poi_type name="zoo" tag="tourism" value="zoo"></poi_type>
<poi_type name="nightclub" tag="amenity" value="nightclub"></poi_type>
<poi_type name="stripclub" tag="amenity" value="stripclub"></poi_type>
<poi_type name="beach_resort" tag="leisure" value="beach_resort"></poi_type>
<poi_type name="dog_park" tag="leisure" value="dog_park"></poi_type>
<poi_type name="fishing_place" tag="leisure" value="fishing"></poi_type>
<poi_type name="hunting_stand" tag="amenity" value="hunting_stand"></poi_type>
<poi_type name="harbour" tag="harbour" value="yes"></poi_type>
<poi_type name="marina" tag="leisure" value="marina"></poi_type>
<poi_type name="slipway" tag="leisure" value="slipway"></poi_type>
<poi_type name="miniature_golf" tag="leisure" value="miniature_golf"></poi_type>
<poi_type name="playground" tag="leisure" value="playground"></poi_type>
<poi_type name="swimming_pool" tag="leisure" value="swimming_pool"></poi_type>
<poi_type name="water_park" tag="leisure" value="water_park"></poi_type>
<poi_type name="park" tag="leisure" value="park"></poi_type>
<poi_type name="sauna" tag="amenity" value="sauna"></poi_type>
<poi_type name="theme_park" tag="tourism" value="theme_park"></poi_type>
</poi_category>
<poi_category name="food">
<poi_type name="cafe" tag="amenity" value="cafe"></poi_type>
<poi_type name="biergarten" tag="amenity" value="biergarten"></poi_type>
<poi_type name="restaurant" tag="amenity" value="restaurant"></poi_type>
<poi_type name="fast_food" tag="amenity" value="fast_food"></poi_type>
<poi_type name="bar" tag="amenity" value="bar"></poi_type>
<poi_type name="pub" tag="amenity" value="pub"></poi_type>
<poi_type name="food_court" tag="amenity" value="food_court"></poi_type>
<poi_type name="drinking_water" tag="amenity" value="drinking_water"></poi_type>
<poi_type name="barbecue" tag="amenity" value="bbq"></poi_type>
</poi_category>
<poi_category name="service">
<poi_filter name="craft">
<poi_type name="agricultural_engines_craft" tag="craft" value="agricultural_engines"></poi_type>
<poi_type name="basket_maker" tag="craft" value="basket_maker"></poi_type>
<poi_type name="beekeeper" tag="craft" value="beekeeper"></poi_type>
<poi_type name="blacksmith" tag="craft" value="blacksmith"></poi_type>
<poi_type name="brewery" tag="craft" value="brewery"></poi_type>
<poi_type name="boatbuilder" tag="craft" value="boatbuilder"></poi_type>
<poi_type name="bookbinder" tag="craft" value="bookbinder"></poi_type>
<poi_type name="carpenter" tag="craft" value="carpenter"></poi_type>
<poi_type name="carpet_layer" tag="craft" value="carpet_layer"></poi_type>
<poi_type name="caterer" tag="craft" value="caterer"></poi_type>
<poi_type name="clockmaker" tag="craft" value="clockmaker"></poi_type>
<poi_type name="dressmaker" tag="craft" value="dressmaker"></poi_type>
<poi_type name="electrician" tag="craft" value="electrician"></poi_type>
<poi_type name="gardener" tag="craft" value="gardener"></poi_type>
<poi_type name="glaziery_craft" tag="craft" value="glaziery"></poi_type>
<poi_type name="handicraft" tag="craft" value="handicraft"></poi_type>
<poi_type name="hvac_craft" tag="craft" value="hvac"></poi_type>
<poi_type name="insulation_craft" tag="craft" value="insulation"></poi_type>
<poi_type name="jeweller" tag="craft" value="jeweller"></poi_type>
<poi_type name="locksmith" tag="craft" value="locksmith"></poi_type>
<poi_type name="key_cutter" tag="craft" value="key_cutter"></poi_type>
<poi_type name="metal_construction_craft" tag="craft" value="metal_construction"></poi_type>
<poi_type name="optician" tag="craft" value="optician"></poi_type>
<poi_type name="painter" tag="craft" value="painter"></poi_type>
<poi_type name="parquet_layer" tag="craft" value="parquet_layer"></poi_type>
<poi_type name="photographer" tag="craft" value="photographer"></poi_type>
<poi_type name="photographic_laboratory" tag="craft" value="photographic_laboratory"></poi_type>
<poi_type name="plasterer" tag="craft" value="plasterer"></poi_type>
<poi_type name="plumber" tag="craft" value="plumber"></poi_type>
<poi_type name="pottery_craft" tag="craft" value="pottery"></poi_type>
<poi_type name="rigger" tag="craft" value="rigger"></poi_type>
<poi_type name="roofer" tag="craft" value="roofer"></poi_type>
<poi_type name="saddler" tag="craft" value="saddler"></poi_type>
<poi_type name="sailmaker" tag="craft" value="sailmaker"></poi_type>
<poi_type name="sawmill" tag="craft" value="sawmill"></poi_type>
<poi_type name="scaffolder" tag="craft" value="scaffolder"></poi_type>
<poi_type name="sculptor" tag="craft" value="sculptor"></poi_type>
<poi_type name="shoemaker" tag="craft" value="shoemaker"></poi_type>
<poi_type name="stand_builder" tag="craft" value="stand_builder"></poi_type>
<poi_type name="stonemason" tag="craft" value="stonemason"></poi_type>
<poi_type name="sun_protection_craft" tag="craft" value="sun_protection"></poi_type>
<poi_type name="sweep" tag="craft" value="sweep"></poi_type>
<poi_type name="tailor" tag="craft" value="tailor"></poi_type>
<poi_type name="tiler" tag="craft" value="tiler"></poi_type>
<poi_type name="tinsmith" tag="craft" value="tinsmith"></poi_type>
<poi_type name="upholsterer" tag="craft" value="upholsterer"></poi_type>
<poi_type name="watchmaker" tag="craft" value="watchmaker"></poi_type>
<poi_type name="window_construction" tag="craft" value="window_construction"></poi_type>
</poi_filter>
<poi_type name="funeral_directors" tag="shop" value="funeral_directors"></poi_type>
<poi_type name="currencyexchange" tag="amenity" value="bureau_de_change"></poi_type>
<poi_type name="driving_school" tag="amenity" value="driving_school"></poi_type>
<poi_type name="computer_craft" tag="craft" value="computer"></poi_type>
<poi_type name="post_office" tag="amenity" value="post_office"></poi_type>
<poi_type name="post_box" tag="amenity" value="post_box"></poi_type>
<poi_type name="beauty_salon" tag="shop" value="beauty"></poi_type>
<poi_type name="beauty_salon_nails" tag="shop" value="beauty" tag2="beauty" value2="nails"></poi_type>
<poi_type name="hairdresser" tag="shop" value="hairdresser"></poi_type>
<poi_type name="massage" tag="shop" value="massage"></poi_type>
<poi_type name="tattoo" tag="shop" value="tattoo"></poi_type>
<poi_type name="dry_cleaning" tag="shop" value="dry_cleaning"></poi_type>
<poi_type name="laundry" tag="shop" value="laundry"></poi_type>
<poi_type name="car_rental" tag="amenity" value="car_rental"></poi_type>
<poi_type name="car_sharing" tag="amenity" value="car_sharing"></poi_type>
<poi_type name="bicycle_rental" tag="amenity" value="bicycle_rental"></poi_type>
<poi_type name="boat_sharing" tag="amenity" value="boat_sharing"></poi_type>
<poi_type name="dock" tag="waterway" value="dock"></poi_type>
<poi_type name="charging_station" tag="amenity" value="charging_station"></poi_type>
<poi_type name="toilets" tag="amenity" value="toilets"></poi_type>
<poi_type name="telephone" tag="amenity" value="telephone"></poi_type>
<poi_type name="sauna" tag="amenity" value="sauna"></poi_type>
<poi_type name="brothel" tag="amenity" value="brothel"></poi_type>
<poi_type name="recycling" tag="amenity" value="recycling"></poi_type>
<poi_type name="mortuary" tag="amenity" value="mortuary"></poi_type>
<poi_type name="crematorium" tag="amenity" value="crematorium"></poi_type>
<poi_type name="internet_cafe" tag="amenity" value="internet_cafe"></poi_type>
</poi_category>
<poi_category name="finance">
<poi_type name="bank" tag="amenity" value="bank"></poi_type>
<poi_type name="atm" tag="amenity" value="atm"></poi_type>
<poi_type name="money_lender" tag="shop" value="money_lender"></poi_type>
<poi_type name="pawnbroker" tag="shop" value="pawnbroker"></poi_type>
<poi_type name="currencyexchange" tag="amenity" value="bureau_de_change"></poi_type>
<poi_type name="accountant" tag="office" value="accountant"></poi_type>
<poi_type name="bitcoin_yes" tag="bitcoin" value="yes"></poi_type>
</poi_category>
<poi_category name="natural">
<poi_type name="cave_entrance" tag="natural" value="cave_entrance"></poi_type>
<poi_type name="peak" tag="natural" value="peak"></poi_type>
<poi_type name="saddle" tag="natural" value="saddle"></poi_type>
<poi_type name="volcano" tag="natural" value="volcano"></poi_type>
<poi_type name="glacier" tag="natural" value="glacier"></poi_type>
<poi_type name="crater" tag="natural" value="crater"></poi_type>
<poi_type name="ridge" tag="natural" value="ridge"></poi_type>
<poi_type name="sinkhole" tag="natural" value="sinkhole"></poi_type>
<poi_type name="waterfall" tag="natural" value="waterfall"></poi_type>
<poi_type name="rapids" tag="waterway" value="rapids"></poi_type>
<poi_type name="spring" tag="natural" value="spring"></poi_type>
<poi_type name="hot_spring" tag="natural" value="hot_spring"></poi_type>
<poi_type name="geyser" tag="natural" value="geyser"></poi_type>
<poi_type name="river" tag="waterway" value="river"></poi_type>
<poi_type name="stream" tag="waterway" value="stream"></poi_type>
<poi_type name="stone" tag="natural" value="stone"></poi_type>
<poi_type name="cape" tag="natural" value="cape"></poi_type>
<poi_type name="beach" tag="natural" value="beach"></poi_type>
<poi_type name="bay" tag="natural" value="bay"></poi_type>
<poi_type name="fjord" tag="natural" value="fjord"></poi_type>
<poi_type name="reef" tag="natural" value="reef"></poi_type>
<poi_type name="wetland" tag="natural" value="wetland"></poi_type>
<poi_type name="nature_reserve" tag="leisure" value="nature_reserve"></poi_type>
<poi_type name="strait" tag="natural" value="strait"></poi_type>
<poi_type name="island" tag="place" value="island"></poi_type>
<poi_type name="islet" tag="place" value="islet"></poi_type>
</poi_category>
<poi_category name="seamark">
<poi_type name="seamark_anchorage" tag="seamark" value="anchorage"></poi_type>
<poi_type name="seamark_anchor_berth" tag="seamark" value="anchor_berth"></poi_type>
<poi_type name="seamark_beacon" tag="man_made" value="beacon"></poi_type>
<poi_type name="seamark_beacon_cardinal" tag="seamark" value="beacon_cardinal"></poi_type>
<poi_type name="seamark_beacon_lateral" tag="seamark" value="beacon_lateral"></poi_type>
<poi_type name="seamark_beacon_safe_water" tag="seamark" value="beacon_safe_water"></poi_type>
<poi_type name="seamark_beacon_special_purpose" tag="seamark" value="beacon_special_purpose"></poi_type>
<poi_type name="seamark_berth" tag="seamark" value="berth"></poi_type>
<poi_type name="seamark_building" tag="seamark" value="building"></poi_type>
<poi_type name="seamark_bridge" tag="seamark" value="bridge"></poi_type>
<poi_type name="seamark_buoy_cardinal" tag="seamark" value="buoy_cardinal"></poi_type>
<poi_type name="seamark_buoy_installation" tag="seamark" value="buoy_installation"></poi_type>
<poi_type name="seamark_buoy_isolated_danger" tag="seamark" value="buoy_isolated_danger"></poi_type>
<poi_type name="seamark_buoy_lateral" tag="seamark" value="buoy_lateral"></poi_type>
<poi_type name="seamark_buoy_safe_water" tag="seamark" value="buoy_safe_water"></poi_type>
<poi_type name="seamark_buoy_special_purpose" tag="seamark" value="buoy_special_purpose"></poi_type>
<poi_type name="seamark_daymark" tag="seamark" value="daymark"></poi_type>
<poi_type name="seamark_distance_mark" tag="seamark" value="distance_mark"></poi_type>
<poi_type name="seamark_dry_dock" tag="seamark" value="dry_dock"></poi_type>
<poi_type name="seamark_dyke" tag="seamark" value="dyke"></poi_type>
<poi_type name="seamark_floating_dock" tag="seamark" value="floating_dock"></poi_type>
<poi_type name="seamark_fog_signal" tag="seamark" value="fog_signal"></poi_type>
<poi_type name="seamark_harbour_basin" tag="seamark" value="harbour_basin"></poi_type>
<poi_type name="seamark_harbour" tag="seamark" value="harbour"></poi_type>
<poi_type name="seamark_landmark" tag="seamark" value="landmark"></poi_type>
<poi_type name="seamark_light" tag="seamark" value="light"></poi_type>
<poi_type name="seamark_light_major" tag="seamark" value="light_major"></poi_type>
<poi_type name="seamark_light_minor" tag="seamark" value="light_minor"></poi_type>
<poi_type name="seamark_light_float" tag="seamark" value="light_float"></poi_type>
<poi_type name="seamark_light_vessel" tag="seamark" value="light_vessel"></poi_type>
<poi_type name="seamark_mooring" tag="seamark" value="mooring"></poi_type>
<poi_type name="seamark_notice" tag="seamark" value="notice"></poi_type>
<poi_type name="seamark_pile" tag="seamark" value="pile"></poi_type>
<poi_type name="seamark_radar_transponder" tag="seamark" value="radar_transponder"></poi_type>
<poi_type name="seamark_radio_station" tag="seamark" value="radio_station"></poi_type>
<poi_type name="seamark_signal_station_traffic" tag="seamark" value="signal_station_traffic"></poi_type>
<poi_type name="seamark_signal_station_warning" tag="seamark" value="signal_station_warning"></poi_type>
<poi_type name="seamark_small_craft_facility" tag="seamark" value="small_craft_facility"></poi_type>
<poi_type name="seamark_topmark" tag="seamark" value="topmark"></poi_type>
<poi_type name="seamark_rock" tag="seamark" value="rock"></poi_type>
<poi_type name="seamark_wreck" tag="seamark" value="wreck"></poi_type>
</poi_category>
<poi_category name="military">
<poi_type name="military" tag="landuse" value="military"></poi_type>
<poi_type name="military_airfield" tag="military" value="airfield"></poi_type>
<poi_type name="military_bunker" tag="building" value="bunker"></poi_type>
<poi_type name="military_barracks" tag="military" value="barracks"></poi_type>
<poi_type name="military_danger_area" tag="military" value="danger_area"></poi_type>
<poi_type name="military_range" tag="military" value="range"></poi_type>
<poi_type name="military_naval_base" tag="military" value="naval_base"></poi_type>
<poi_type name="military_nuclear_explosion_site" tag="military" value="nuclear_explosion_site"></poi_type>
</poi_category>
<poi_category name="entertainment">
</poi_category>
<poi_category name="osmwiki">
</poi_category>
<poi_category name="user_defined_other">
</poi_category>
</poi_types>

View file

@ -16,6 +16,7 @@ import java.util.regex.Pattern;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
@ -151,9 +152,6 @@ public class FavouritesDbHelper {
}
FavoriteGroup group = getOrCreateGroup(p, 0);
//making sure that dublicated names will not occur in favorites
checkDublicates(p);
if (!p.getName().equals("")) {
p.setVisible(group.visible);
p.setColor(group.color);
@ -167,44 +165,45 @@ public class FavouritesDbHelper {
return true;
}
private void checkDublicates(FavouritePoint p){
boolean fl = true;
public static AlertDialog.Builder checkDublicates(FavouritePoint p, FavouritesDbHelper fdb, Context uiContext) {
boolean emoticons = false;
String index = "";
int number = 0;
String name = checkEmoticons(p.getName());
String category = checkEmoticons(p.getCategory());
p.setCategory(category);
if (name.length() != p.getName().length()){
if (name.length() != p.getName().length()) {
emoticons = true;
}
while (fl){
boolean fl = true;
while (fl) {
fl = false;
for (FavouritePoint fp : cachedFavoritePoints){
if (fp.getName().equals(name)){
for (FavouritePoint fp : fdb.getFavouritePoints()) {
if (fp.getName().equals(name)) {
number++;
index = " (" + number + ")";
name = p.getName() + index;
fl=true;
fl = true;
break;
}
}
}
if (index.length() > 0 || emoticons){
AlertDialog.Builder builder = new AlertDialog.Builder(context.getMapActivity());
if ((index.length() > 0 || emoticons) ) {
AlertDialog.Builder builder = new AlertDialog.Builder(uiContext);
builder.setTitle(R.string.fav_point_dublicate);
if (emoticons){
builder.setMessage(context.getString(R.string.fav_point_emoticons_message, name));
if (emoticons) {
builder.setMessage(uiContext.getString(R.string.fav_point_emoticons_message, name));
} else {
builder.setMessage(context.getString(R.string.fav_point_dublicate_message, name));
builder.setMessage(uiContext.getString(R.string.fav_point_dublicate_message, name));
}
builder.setPositiveButton(R.string.default_buttons_ok, null);
p.setName(name);
builder.show();
return builder;
}
return null;
}
public String checkEmoticons(String name){
public static String checkEmoticons(String name){
char[] chars = name.toCharArray();
int index;
char ch1;
@ -316,7 +315,7 @@ public class FavouritesDbHelper {
return false;
}
private File getExternalFile() {
public File getExternalFile() {
return new File(context.getAppPath(null), FILE_TO_SAVE);
}

View file

@ -87,6 +87,7 @@ public class GPXUtilities {
public double lat;
public double lon;
public String name = null;
// previous undocumented feature 'category' ,now 'type'
public String category = null;
public String desc = null;
// by default
@ -754,7 +755,7 @@ public class GPXUtilities {
}
writeNotNullText(serializer, "name", p.name);
writeNotNullText(serializer, "desc", p.desc);
writeNotNullText(serializer, "category", p.category);
writeNotNullText(serializer, "type", p.category);
if (!Double.isNaN(p.hdop)) {
writeNotNullText(serializer, "hdop", p.hdop + "");
}
@ -917,6 +918,10 @@ public class GPXUtilities {
((WptPt) parse).desc = readText(parser, "desc");
} else if (tag.equals("category")) {
((WptPt) parse).category = readText(parser, "category");
} else if (tag.equals("type")) {
if(((WptPt) parse).category == null) {
((WptPt) parse).category = readText(parser, "type");
}
} else if (parser.getName().equals("ele")) {
String text = readText(parser, "ele");
if (text != null) {

View file

@ -324,7 +324,7 @@ public class GpxSelectionHelper {
selectedGPXFiles.add(savingTrackHelper.getCurrentTrack());
}
}
} catch (JSONException e) {
} catch (Exception e) {
app.getSettings().SELECTED_GPX.set("");
e.printStackTrace();
}
@ -337,10 +337,10 @@ public class GpxSelectionHelper {
if(s.gpxFile != null && !s.notShowNavigationDialog) {
JSONObject obj = new JSONObject();
try {
if(!Algorithms.isEmpty(s.gpxFile.path)) {
obj.put(FILE, s.gpxFile.path);
} else {
if(s.isShowCurrentTrack()) {
obj.put(CURRENT_TRACK, true);
} else if(!Algorithms.isEmpty(s.gpxFile.path)) {
obj.put(FILE, s.gpxFile.path);
}
} catch (JSONException e) {
e.printStackTrace();
@ -410,10 +410,14 @@ public class GpxSelectionHelper {
if(gpxFile.tracks.size() > 0) {
this.color = gpxFile.tracks.get(0).getColor(0);
}
processPoints();
}
public void processPoints() {
this.processedPointsToDisplay = gpxFile.proccessPoints();
if(this.processedPointsToDisplay.isEmpty()) {
this.processedPointsToDisplay = gpxFile.processRoutePoints();
routePoints = true;
routePoints = !this.processedPointsToDisplay.isEmpty();
}
}
@ -437,6 +441,11 @@ public class GpxSelectionHelper {
return gpxFile;
}
public GPXFile getModifiableGpxFile() {
// call process points after
return gpxFile;
}
public boolean isShowCurrentTrack() {
return showCurrentTrack;
}

View file

@ -152,5 +152,14 @@ public class OsmAndAppCustomization {
public boolean showNavigationControls() { return true;}
public boolean onlyTourDownload() { return false;}
public boolean onlyTourDownload() {
return false;
}
public <T> void resumeActivity(Class<T> class1, T d) {
}
public <T> void pauseActivity(Class<T> class1) {
}
}

View file

@ -117,9 +117,6 @@ public class OsmandApplication extends Application {
SQLiteAPI sqliteAPI;
BRouterServiceConnection bRouterServiceConnection;
MapActivity mapActivity;
DownloadActivity downloadActivity;
@Override
public void onCreate() {
@ -595,6 +592,8 @@ public class OsmandApplication extends Application {
} catch (RuntimeException e) {
warnings.add(e.getMessage());
}
} else {
savingTrackHelper.loadGpxFromDatabase();
}
}
if(getSettings().SAVE_GLOBAL_TRACK_TO_GPX.get()){
@ -911,19 +910,5 @@ public class OsmandApplication extends Application {
}
}
public MapActivity getMapActivity() {
return mapActivity;
}
public void setMapActivity(MapActivity mapActivity) {
this.mapActivity = mapActivity;
}
public void setDownloadActivity(DownloadActivity downloadActivity) {
this.downloadActivity = downloadActivity;
}
public DownloadActivity getDownloadActivity() {
return downloadActivity;
}
}

View file

@ -57,6 +57,8 @@ public class OsmandSettings {
void addListener(StateChangedListener<T> listener);
void removeListener(StateChangedListener<T> listener);
boolean isSet();
}
private abstract class PreferenceWithListener<T> implements OsmandPreference<T> {
@ -168,6 +170,11 @@ public class OsmandSettings {
set(ApplicationMode.DEFAULT);
};
@Override
public boolean isSet() {
return true;
};
@Override
public boolean set(ApplicationMode val) {
ApplicationMode oldMode = currentMode;
@ -875,6 +882,9 @@ public class OsmandSettings {
public final OsmandPreference<Boolean> OSMO_AUTO_CONNECT = new BooleanPreference("osmo_automatically_connect", false).makeGlobal();
public final CommonPreference<Boolean> OSMO_USE_HTTPS = new BooleanPreference("osmo_use_https",
Build.VERSION.SDK_INT < 14/*Build.VERSION_CODES.ICE_CREAM_SANDWICH*/? false : true).makeGlobal();
public final OsmandPreference<Long> OSMO_LAST_PING = new LongPreference("osmo_last_ping", 0).makeGlobal().cache();
public final OsmandPreference<Boolean> OSMO_AUTO_SEND_LOCATIONS = new BooleanPreference("osmo_automatically_send_locations", false).makeGlobal();

View file

@ -124,7 +124,15 @@ public class TargetPointsHelper {
return intermediatePoints;
}
public List<LatLon> getIntermediatePointsLatLon() {
List<LatLon> intermediatePointsLatLon = new ArrayList<LatLon>();
for (TargetPoint t : intermediatePoints) {
intermediatePointsLatLon.add(t.point);
}
return intermediatePointsLatLon;
}
public List<TargetPoint> getIntermediatePointsWithTarget() {
List<TargetPoint> res = new ArrayList<TargetPoint>();

View file

@ -38,6 +38,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v4.app.FragmentActivity;
import android.text.Spannable;
@ -524,9 +525,11 @@ public class FavouritesTreeFragment extends OsmandExpandableListFragment {
hideProgressBar();
final Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, GPXUtilities.asString(gpxFile, getMyApplication()));
sendIntent.putExtra(Intent.EXTRA_TEXT, "Favourites.gpx:\n\n\n"+GPXUtilities.asString(gpxFile, getMyApplication()));
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_fav_subject));
sendIntent.setType("application/gpx+xml");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(helper.getExternalFile()));
// sendIntent.setType("application/gpx+xml");
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
};

View file

@ -292,9 +292,7 @@ public class MapActivity extends AccessibleActivity implements
@Override
protected void onResume() {
super.onResume();
if ((wakeLock != null) || (keyguardLock != null)) {
return;
}
cancelNotification();
//fixing bug with action bar appearing on android 2.3.3
if (getSupportActionBar() != null){
@ -334,8 +332,8 @@ public class MapActivity extends AccessibleActivity implements
TargetPointsHelper targets = app.getTargetPointsHelper();
RoutingHelper routingHelper = app.getRoutingHelper();
if (routingHelper.isFollowingMode() && (
!Algorithms.objectEquals(targets.getPointToNavigate(), routingHelper.getFinalLocation() )||
!Algorithms.objectEquals(targets.getIntermediatePoints(), routingHelper.getIntermediatePoints())
!Algorithms.objectEquals(targets.getPointToNavigate().point, routingHelper.getFinalLocation() )||
!Algorithms.objectEquals(targets.getIntermediatePointsLatLon(), routingHelper.getIntermediatePoints())
)) {
targets.updateRouteAndReferesh(true);
}
@ -348,7 +346,6 @@ public class MapActivity extends AccessibleActivity implements
}
settings.MAP_ACTIVITY_ENABLED.set(true);
app.setMapActivity(this);
checkExternalStorage();
showAndHideMapPosition();
@ -422,6 +419,7 @@ public class MapActivity extends AccessibleActivity implements
if(glSurfaceView != null) {
glSurfaceView.onResume();
}
getMyApplication().getAppCustomization().resumeActivity(MapActivity.class, this);
}
@ -625,7 +623,7 @@ public class MapActivity extends AccessibleActivity implements
settings.setLastKnownMapZoom(mapView.getZoom());
settings.MAP_ACTIVITY_ENABLED.set(false);
app.setMapActivity(null);
getMyApplication().getAppCustomization().pauseActivity(MapActivity.class);
app.getResourceManager().interruptRendering();
app.getResourceManager().setBusyIndicator(null);
OsmandPlugin.onMapActivityPause(this);

View file

@ -94,6 +94,7 @@ public class MapActivityActions implements DialogProvider {
private enum DrawerType{
WAYPOINTS,
CONFIGURE_SCREEN,
CONFIGURE_MAP,
MAIN_MENU
}
@ -580,6 +581,9 @@ public class MapActivityActions implements DialogProvider {
if (mDrawerList != null && refreshDrawer){
if (currentDrawer == DrawerType.WAYPOINTS){
showWaypointsInDrawer(false);
} else if (currentDrawer == DrawerType.MAIN_MENU){
final ContextMenuAdapter cm = createOptionsMenu();
prepareOptionsMenu(cm);
} else {
mDrawerList.invalidateViews();
}
@ -813,6 +817,7 @@ public class MapActivityActions implements DialogProvider {
.listen(new OnContextMenuClick() {
@Override
public boolean onContextMenuClick(ArrayAdapter<?> adapter, int itemId, int pos, boolean isChecked) {
currentDrawer = DrawerType.CONFIGURE_MAP;
prepareConfigureMap();
return false;
}
@ -822,7 +827,7 @@ public class MapActivityActions implements DialogProvider {
.listen(new OnContextMenuClick() {
@Override
public boolean onContextMenuClick(ArrayAdapter<?> adapter, int itemId, int pos, boolean isChecked) {
currentDrawer = DrawerType.CONFIGURE_MAP;
currentDrawer = DrawerType.CONFIGURE_SCREEN;
ContextMenuAdapter cm = mapActivity.getMapLayers().getMapInfoLayer().getViewConfigureMenuAdapter();
prepareOptionsMenu(cm);
return false;

View file

@ -298,6 +298,8 @@ public class MapActivityLayers {
if (!settings.SAVE_TRACK_TO_GPX.get() && !
settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) {
AccessibleToast.makeText(activity, R.string.gpx_monitoring_disabled_warn, Toast.LENGTH_SHORT).show();
} else {
g.path = getString(R.string.show_current_gpx_title);
}
break;
}

View file

@ -373,20 +373,23 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
assert track.segments.size() == points.size();
if (points.size() == 0 || newSegment) {
points.add(new ArrayList<WptPt>());
}
if(track.segments.size() == 0 || newSegment) {
track.segments.add(new TrkSegment());
}
if (pt != null) {
int ind = points.size() - 1;
List<WptPt> last = points.get(ind);
last.add(pt);
track.segments.get(ind).points.add(pt);
TrkSegment lt = track.segments.get(track.segments.size() - 1);
lt.points.add(pt);
}
}
public void insertPointData(double lat, double lon, long time, String description) {
final WptPt pt = new WptPt(lat, lon, time, Double.NaN, 0, Double.NaN);
pt.name = description;
currentTrack.getGpxFile().points.add(pt);
currentTrack.getModifiableGpxFile().points.add(pt);
execWithClose(updatePointsScript, new Object[] { lat, lon, time, description });
}
@ -402,7 +405,16 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
}
}
}
public void loadGpxFromDatabase(){
Map<String, GPXFile> files = collectRecordedData();
for (Map.Entry<String, GPXFile> entry : files.entrySet()){
currentTrack.getModifiableGpxFile().points.addAll(entry.getValue().points);
currentTrack.getModifiableGpxFile().tracks.addAll(entry.getValue().tracks);
}
currentTrack.processPoints();
}
public boolean getIsRecording() {
return isRecording;
}

View file

@ -28,7 +28,7 @@ public class AppModeDialog {
if (showDefault || settings.getApplicationMode() != ApplicationMode.DEFAULT) {
selected.add(settings.getApplicationMode());
}
return prepareAppModeView(a, values, selected, parent, singleSelection, onClickListener);
return prepareAppModeView(a, values, selected, parent, singleSelection, false, onClickListener);
}
//special method for drawer menu
@ -41,7 +41,7 @@ public class AppModeDialog {
if (values.size() > 4) {
return createDrawerView(a, visible, values, selected, allModes, onClickListener);
} else {
return prepareAppModeView(a, values, selected, null, true, onClickListener);
return prepareAppModeView(a, values, selected, null, true, true, onClickListener);
}
}
@ -102,7 +102,7 @@ public class AppModeDialog {
newButtons[buttons.length] = tb;
tb.setTextOn("");
tb.setTextOff("");
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, a.getResources().getDisplayMetrics());
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, a.getResources().getDisplayMetrics());
int metrics = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 64, a.getResources().getDisplayMetrics());
tb.setButtonDrawable(R.drawable.ic_other_modes);
LayoutParams lp = new LayoutParams(metrics, metrics);
@ -168,9 +168,9 @@ public class AppModeDialog {
}
public static View prepareAppModeView(Activity a, final List<ApplicationMode> values , final Set<ApplicationMode> selected,
ViewGroup parent, final boolean singleSelection, final View.OnClickListener onClickListener) {
ViewGroup parent, final boolean singleSelection,boolean drawer, final View.OnClickListener onClickListener) {
LinearLayout ll = (LinearLayout) a.getLayoutInflater().inflate(R.layout.mode_toggles, parent);
final ToggleButton[] buttons = createToggles(values, ll, a, false);
final ToggleButton[] buttons = createToggles(values, ll, a, drawer);
for (int i = 0; i < buttons.length; i++) {
setButtonListener(values, selected, onClickListener, buttons, i, singleSelection);
}
@ -238,7 +238,7 @@ public class AppModeDialog {
static private ToggleButton createToggle(Context ctx, LinearLayout layout, ApplicationMode mode, boolean drawer){
int margin = 0;
if (drawer) {
margin = 5;
margin = 2;
} else {
margin = 10;
}

View file

@ -126,7 +126,7 @@ public class SettingsDevelopmentActivity extends SettingsBaseActivity {
modes.remove(ApplicationMode.DEFAULT);
final Set<ApplicationMode> selected = new LinkedHashSet<ApplicationMode>(ApplicationMode.values(settings));
selected.remove(ApplicationMode.DEFAULT);
View v = AppModeDialog.prepareAppModeView(this, modes, selected, null, false,
View v = AppModeDialog.prepareAppModeView(this, modes, selected, null, false, false,
new View.OnClickListener() {
@Override

View file

@ -12,17 +12,17 @@ import net.osmand.AndroidUtils;
import net.osmand.access.AccessibleToast;
import net.osmand.data.FavouritePoint;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.FavoriteImageDrawable;
import net.osmand.util.MapUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Build;
@ -202,13 +202,27 @@ public class FavoriteDialogs {
builder.setPositiveButton(R.string.default_buttons_add, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
FavouritePoint point = (FavouritePoint) args.getSerializable(KEY_FAVORITE);
final FavouritePoint point = (FavouritePoint) args.getSerializable(KEY_FAVORITE);
OsmandApplication app = (OsmandApplication) activity.getApplication();
String categoryStr = cat.getText().toString().trim();
final FavouritesDbHelper helper = app.getFavorites();
app.getSettings().LAST_FAV_CATEGORY_ENTERED.set(categoryStr);
point.setName(editText.getText().toString().trim());
point.setCategory(categoryStr);
Builder bld = FavouritesDbHelper.checkDublicates(point, helper, activity);
if(bld != null) {
bld.setPositiveButton(R.string.default_buttons_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
addFavorite(activity, point, helper);
}
});
} else {
addFavorite(activity, point, helper);
}
}
protected void addFavorite(final Activity activity, FavouritePoint point, final FavouritesDbHelper helper) {
boolean added = helper.addFavourite(point);
if (added) {
AccessibleToast.makeText(activity, MessageFormat.format(

View file

@ -18,6 +18,7 @@ import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Window;
import net.osmand.IndexConstants;
import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.*;
import net.osmand.plus.activities.FavouritesActivity;
import net.osmand.plus.activities.LocalIndexInfo;
@ -71,6 +72,16 @@ public class DownloadActivity extends SherlockFragmentActivity {
setProgressBarIndeterminateVisibility(false);
setContentView(R.layout.tab_content);
if(downloadListIndexThread == null) {
downloadListIndexThread = new DownloadIndexesThread(this);
}
if (downloadListIndexThread.getCachedIndexFiles() != null && downloadListIndexThread.isDownloadedFromInternet()) {
downloadListIndexThread.runCategorization(type);
} else {
downloadListIndexThread.runReloadIndexFiles();
}
downloadListIndexThread.setUiActivity(this);
settings = ((OsmandApplication) getApplication()).getSettings();
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
@ -90,16 +101,6 @@ public class DownloadActivity extends SherlockFragmentActivity {
tabHost.setCurrentTab(0);
if(downloadListIndexThread == null) {
downloadListIndexThread = new DownloadIndexesThread(this);
}
if (downloadListIndexThread.getCachedIndexFiles() != null && downloadListIndexThread.isDownloadedFromInternet()) {
downloadListIndexThread.runCategorization(type);
} else {
downloadListIndexThread.runReloadIndexFiles();
}
downloadListIndexThread.setUiActivity(this);
settings = ((OsmandApplication)getApplication()).getSettings();
indeterminateProgressBar = (ProgressBar) findViewById(R.id.IndeterminateProgressBar);
@ -146,7 +147,7 @@ public class DownloadActivity extends SherlockFragmentActivity {
}
}
String tab = intent.getExtras().get(TAB_TO_OPEN).toString();
String tab = intent.getExtras().getString(TAB_TO_OPEN);
if (tab != null) {
if (tab.equals(DOWNLOAD_TAB)){
tabHost.setCurrentTab(1);
@ -216,8 +217,7 @@ public class DownloadActivity extends SherlockFragmentActivity {
@Override
protected void onResume() {
super.onResume();
getMyApplication().setDownloadActivity(this);
BasicProgressAsyncTask<?, ?, ?> t = downloadListIndexThread.getCurrentRunningTask();
getMyApplication().getAppCustomization().resumeActivity(DownloadActivity.class, this);
}
@ -288,7 +288,7 @@ public class DownloadActivity extends SherlockFragmentActivity {
@Override
public void onPause() {
super.onPause();
(getMyApplication()).setDownloadActivity(null);
getMyApplication().getAppCustomization().pauseActivity(DownloadActivity.class);
}
protected void downloadFilesCheckFreeVersion() {
@ -447,7 +447,11 @@ public class DownloadActivity extends SherlockFragmentActivity {
public void downloadedIndexes(){
for(WeakReference<Fragment> ref : fragList) {
Fragment f = ref.get();
if(f instanceof DownloadIndexFragment) {
if(f instanceof LocalIndexesFragment){
if(!f.isDetached()){
((LocalIndexesFragment) f).reloadData();
}
} else if(f instanceof DownloadIndexFragment) {
if(!f.isDetached()) {
DownloadIndexAdapter adapter = ((DownloadIndexAdapter)((DownloadIndexFragment) f).getExpandableListAdapter());
if (adapter != null) {
@ -592,4 +596,20 @@ public class DownloadActivity extends SherlockFragmentActivity {
}
}
public static String getFullName(IndexItem e, OsmandApplication app, OsmandRegions osmandRegions) {
String eName;
List<IndexItem> forCat = new ArrayList<IndexItem>();
forCat.add(e);
List<IndexItemCategory> category = IndexItemCategory.categorizeIndexItems(app, forCat);
if (category.size() != 0){
eName = e.getVisibleDescription(app) + "\n"
+ category.get(0).name + " "
+ e.getVisibleName(app, osmandRegions);
} else {
eName = e.getVisibleDescription(app) + "\n"
+ e.getVisibleName(app, osmandRegions);
}
return eName;
}
}

View file

@ -64,6 +64,9 @@ public class DownloadIndexAdapter extends OsmandBaseExpandableListAdapter implem
}
public void collapseTrees(final CharSequence constraint) {
if (downloadFragment == null || downloadFragment.getDownloadActivity() == null) {
return;
}
downloadFragment.getDownloadActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
@ -170,9 +173,9 @@ public class DownloadIndexAdapter extends OsmandBaseExpandableListAdapter implem
if (items != null && !items.isEmpty()) {
list.addAll(IndexItemCategory.categorizeIndexItems(app, items));
} else if(DownloadIndexAdapter.this.indexFiles.isEmpty()){
list.add(new IndexItemCategory(downloadFragment.getResources().getString(R.string.no_index_file_to_download), 1));
list.add(new IndexItemCategory(app.getString(R.string.no_index_file_to_download), 1));
} else {
list.add(new IndexItemCategory(downloadFragment.getResources().getString(R.string.select_index_file_to_download), 1));
list.add(new IndexItemCategory(app.getString(R.string.select_index_file_to_download), 1));
}
}
notifyDataSetChanged();

View file

@ -531,7 +531,7 @@ public class DownloadIndexesThread {
itemsToUpdate.clear();
for (IndexItem item : filtered) {
String sfName = item.getTargetFileName();
java.text.DateFormat format = uiActivity.getMyApplication().getResourceManager().getDateFormat();
java.text.DateFormat format = app.getResourceManager().getDateFormat();
String date = item.getDate(format);
String indexactivateddate = indexActivatedFileNames.get(sfName);
String indexfilesdate = indexFileNames.get(sfName);

View file

@ -114,8 +114,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
public void onResume() {
super.onResume();
if (asyncLoader == null || asyncLoader.getResult() == null) {
asyncLoader = new LoadLocalIndexTask();
asyncLoader.execute(getActivity());
reloadData();
}
getExpandableListView().setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@ -131,8 +130,13 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
}
});
}
public void reloadData() {
asyncLoader = new LoadLocalIndexTask();
asyncLoader.execute(getActivity());
}
private void showContextMenu(final LocalIndexInfo info) {
Builder builder = new AlertDialog.Builder(getActivity());
final ContextMenuAdapter adapter = new ContextMenuAdapter(getActivity());
@ -241,6 +245,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
@Override
protected void onPreExecute() {
getDownloadActivity().setSupportProgressBarIndeterminateVisibility(true);
listAdapter.clear();
}
@Override
@ -268,9 +273,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
protected void onPostExecute(List<LocalIndexInfo> result) {
this.result = result;
listAdapter.sortData();
getDownloadActivity().setSupportProgressBarIndeterminateVisibility(false);
getDownloadActivity().setLocalIndexInfos(result);
if (getDownloadActivity() != null){
getDownloadActivity().setSupportProgressBarIndeterminateVisibility(false);
getDownloadActivity().setLocalIndexInfos(result);
}
}
public List<LocalIndexInfo> getResult() {
@ -382,9 +388,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
protected void onPostExecute(String result) {
getDownloadActivity().setProgressBarIndeterminateVisibility(false);
AccessibleToast.makeText(getDownloadActivity(), result, Toast.LENGTH_LONG).show();
listAdapter.clear();
reloadIndexes();
if (operation == RESTORE_OPERATION){
listAdapter.clear();
reloadIndexes();
}
}
}
@ -469,7 +476,8 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
for(LocalIndexInfo info : getDownloadActivity().getLocalIndexInfos()){
listAdapter.addLocalIndexInfo(info);
}
listAdapter.notifyDataSetChanged();
listAdapter.sortData();
getExpandableListView().setAdapter(listAdapter);
}
ActionBar actionBar = getDownloadActivity().getSupportActionBar();
//hide action bar from downloadindexfragment
@ -701,6 +709,9 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
@Override
protected void onPostExecute(List<String> warnings) {
if ( getDownloadActivity() == null) {
return;
}
getDownloadActivity().setProgressBarIndeterminateVisibility(false);
if (!warnings.isEmpty()) {
final StringBuilder b = new StringBuilder();
@ -769,10 +780,9 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
final Collator cl = Collator.getInstance();
for(List<LocalIndexInfo> i : data.values()) {
Collections.sort(i, new Comparator<LocalIndexInfo>() {
@Override
public int compare(LocalIndexInfo lhs, LocalIndexInfo rhs) {
return cl.compare(lhs.getName(), rhs.getName());
return cl.compare(getNameToDisplay(lhs), getNameToDisplay(rhs));
}
});
}
@ -796,6 +806,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
LocalIndexInfo c = findCategory(i, i.isBackupedData());
if(c != null){
data.get(c).remove(i);
if (data.get(c).size() == 0){
data.remove(c);
category.remove(c);
}
}
}
listAdapter.notifyDataSetChanged();
@ -888,14 +902,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
v = inflater.inflate(net.osmand.plus.R.layout.local_index_list_item, parent, false);
}
TextView viewName = ((TextView) v.findViewById(R.id.local_index_name));
String mapDescr = getMapDescription(child.getFileName());
String mapName = FileNameTranslationHelper.getFileName(ctx, ((OsmandApplication) getDownloadActivity().getApplication()).getResourceManager().getOsmandRegions(), child.getFileName());
if (mapDescr.length() > 0){
viewName.setText(mapDescr + " - " + mapName);
} else {
viewName.setText(mapName);
}
viewName.setText(getNameToDisplay(child));
if (child.isNotSupported()) {
viewName.setTextColor(warningColor);
viewName.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
@ -953,6 +960,18 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
return v;
}
private String getNameToDisplay(LocalIndexInfo child) {
String mapDescr = getMapDescription(child.getFileName());
String mapName = FileNameTranslationHelper.getFileName(ctx,
((OsmandApplication) getDownloadActivity().getApplication()).getResourceManager().getOsmandRegions(),
child.getFileName());
if (mapDescr.length() > 0){
return mapDescr + " - " + mapName;
} else {
return mapName;
}
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View v = convertView;

View file

@ -41,7 +41,11 @@ public class UpdatesIndexFragment extends SherlockListFragment {
format = getMyApplication().getResourceManager().getDateFormat();
updateColor = getResources().getColor(R.color.color_update);
osmandRegions = getMyApplication().getResourceManager().getOsmandRegions();
listAdapter = new UpdateIndexAdapter(getDownloadActivity(), R.layout.download_index_list_item, DownloadActivity.downloadListIndexThread.getItemsToUpdate());
List<IndexItem> indexItems = new ArrayList<IndexItem>();
if (DownloadActivity.downloadListIndexThread != null) {
indexItems = DownloadActivity.downloadListIndexThread.getItemsToUpdate();
}
listAdapter = new UpdateIndexAdapter(getDownloadActivity(), R.layout.download_index_list_item, indexItems);
listAdapter.sort(new Comparator<IndexItem>() {
@Override
public int compare(IndexItem indexItem, IndexItem indexItem2) {
@ -80,7 +84,7 @@ public class UpdatesIndexFragment extends SherlockListFragment {
return;
}
List<DownloadEntry> download = e.createDownloadEntry(getMyApplication(), getDownloadActivity().getDownloadType(), new ArrayList<DownloadEntry>());
List<DownloadEntry> download = e.createDownloadEntry(getMyApplication(), e.getType(), new ArrayList<DownloadEntry>());
if (download.size() > 0) {
getDownloadActivity().getEntriesToDownload().put(e, download);
getDownloadActivity().updateDownloadButton(true);
@ -198,7 +202,8 @@ public class UpdatesIndexFragment extends SherlockListFragment {
TextView name = (TextView) v.findViewById(R.id.download_item);
TextView description = (TextView) v.findViewById(R.id.download_descr);
IndexItem e = items.get(position);
String eName = e.getVisibleDescription(getMyApplication()) + "\n" + e.getVisibleName(getMyApplication(), osmandRegions);
String eName = DownloadActivity.getFullName(e, getMyApplication(), osmandRegions);
name.setText(eName.trim()); //$NON-NLS-1$
String d = e.getDate(format) + "\n" + e.getSizeDescription(getMyApplication());
description.setText(d);

View file

@ -65,7 +65,8 @@ public class GpxImportHelper {
if (fileName != null && fileName.endsWith(KML_SUFFIX)) {
handleKmlImport(intentUri, fileName, saveFile);
} else if (fileName != null && fileName.endsWith("favourites.gpx")) {
} else if (fileName != null && (fileName.contains("favourite")||
fileName.contains("favorite"))) {
handleFavouritesImport(intentUri, fileName, saveFile);
} else {
handleGpxImport(intentUri, fileName, saveFile);

View file

@ -141,7 +141,9 @@ public class GpxUiHelper {
if(showCurrentGpx){
allGpxList.add(0, activity.getString(R.string.show_current_gpx_title));
}
final ContextMenuAdapter adapter = createGpxContextMenuAdapter(activity,allGpxList, selectedGpxList, multipleChoice);
final ContextMenuAdapter adapter = createGpxContextMenuAdapter(activity, allGpxList, selectedGpxList, multipleChoice,
showCurrentGpx);
return createDialog(activity, showCurrentGpx, multipleChoice, callbackWithObject, allGpxList, adapter);
}
return null;
@ -160,13 +162,16 @@ public class GpxUiHelper {
list.add(0, activity.getString(R.string.show_current_gpx_title));
}
final ContextMenuAdapter adapter = createGpxContextMenuAdapter(activity, list, null, multipleChoice);
final ContextMenuAdapter adapter = createGpxContextMenuAdapter(activity, list, null, multipleChoice,
showCurrentGpx);
return createDialog(activity, showCurrentGpx, multipleChoice, callbackWithObject, list, adapter);
}
return null;
}
private static ContextMenuAdapter createGpxContextMenuAdapter(Activity activity, List<String> allGpxList, List<String> selectedGpxList, boolean multipleChoice) {
private static ContextMenuAdapter createGpxContextMenuAdapter(Activity activity, List<String> allGpxList,
List<String> selectedGpxList, boolean multipleChoice,
boolean showCurrentTrack) {
final ContextMenuAdapter adapter = new ContextMenuAdapter(activity);
//element position in adapter
int i = 0;
@ -182,17 +187,28 @@ public class GpxUiHelper {
//if there's some selected files - need to mark them as selected
if (selectedGpxList != null) {
for (String file : selectedGpxList) {
if (file.endsWith(fileName)) {
adapter.setSelection(i, 1);
break;
}
}
updateSelection(selectedGpxList, showCurrentTrack, adapter, i, fileName);
}
i++;
}
return adapter;
}
protected static void updateSelection(List<String> selectedGpxList, boolean showCurrentTrack,
final ContextMenuAdapter adapter, int i, String fileName) {
if(i == 0 && showCurrentTrack) {
if(selectedGpxList.contains("")) {
adapter.setSelection(i, 1);
}
} else {
for (String file : selectedGpxList) {
if (file.endsWith(fileName)) {
adapter.setSelection(i, 1);
break;
}
}
}
}
private static void setDescripionInDialog(final ArrayAdapter<?> adapter, final ContextMenuAdapter cmAdapter, Activity activity,
final File dir, String filename, final int position) {

View file

@ -371,7 +371,7 @@ public class WaypointDialogHelper implements OsmAndLocationListener {
@Override
public void onClick(View v) {
IntermediatePointsDialog.openIntermediatePointsDialog(app.getMapActivity(), app, true);
IntermediatePointsDialog.openIntermediatePointsDialog(a, app, true);
if (dlg != null) {
dlg.dismiss();
} else if(a instanceof MapActivity){

View file

@ -26,6 +26,7 @@ import android.text.TextUtils;
public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
private static final String GROUP_NAME = "name";
private static final String ACTIVE = "active";
private static final String GROUP_ID = "group_id";
private static final String EXPIRE_TIME = "expireTime";
private static final String DESCRIPTION = "description";
@ -250,14 +251,14 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
JSONArray arr = new JSONArray(data);
int arrLength = arr.length();
if (arrLength > 0) {
Map<String, OsMoGroup> resivedGroups = new HashMap<String, OsMoGroupsStorage.OsMoGroup>();
Map<String, OsMoGroup> receivedGroups = new HashMap<String, OsMoGroupsStorage.OsMoGroup>();
for (int i = 0; i < arrLength; i++) {
JSONObject o = arr.getJSONObject(i);
OsMoGroup parsedGroup = parseGroup(o);
resivedGroups.put(parsedGroup.getGroupId(), parsedGroup);
receivedGroups.put(parsedGroup.getGroupId(), parsedGroup);
}
storage.mergeGroups(resivedGroups);
storage.mergeGroups(receivedGroups);
storage.save();
}
processed = true;
@ -287,6 +288,9 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
if (!mid.equals(trackerId)) {
if (toDelete.contains(trackerId)) {
toDelete.remove(trackerId);
OsMoDevice dv = mainGroup.users.get(trackerId);
dv.serverColor = device.userColor;
dv.serverName = device.userName;
} else {
mainGroup.users.put(trackerId, device);
}
@ -357,7 +361,8 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
private OsMoGroup parseGroup(JSONObject obj) throws JSONException {
OsMoGroup groupe = new OsMoGroup();
groupe.enabled = true;
groupe.enabled = !(obj.has(ACTIVE) && ("0".equals(obj.getString(ACTIVE)) ||
"false".equals(obj.getString(ACTIVE))));
groupe.name = obj.optString(GROUP_NAME);
groupe.groupId = obj.getString(GROUP_ID);
groupe.description = obj.optString(DESCRIPTION);
@ -478,7 +483,9 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
}
points.add(pt);
}
plugin.getSaveGpxTask(gr.groupId + "_points", modify).execute(points.toArray(new WptPt[points.size()]));
if(points.size() > 0) {
plugin.getSaveGpxTask(gr.name + " points", modify, false).execute(points.toArray(new WptPt[points.size()]));
}
}
if(deleteUsers) {
for(OsMoDevice s : toDelete.values()) {

View file

@ -241,8 +241,11 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
mtd.setVisibility(visible? View.VISIBLE:View.GONE);
if(visible) {
mtd.setText(si.motd);
mtd.setLinksClickable(true);
mtd.setMovementMethod(LinkMovementMethod.getInstance());
}
CompoundButton login = (CompoundButton) header.findViewById(R.id.osmo_login_logoff);
login.setChecked(osMoPlugin.getService().isLoggedIn());
login.setOnCheckedChangeListener(new LoginOnCheckedChangeListener());

View file

@ -1,10 +1,8 @@
package net.osmand.plus.osmo;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

View file

@ -67,12 +67,12 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
public OsMoPlugin(final OsmandApplication app) {
this.app = app;
service = new OsMoService(app, this);
tracker = new OsMoTracker(service, app.getSettings().OSMO_SAVE_TRACK_INTERVAL,
app.getSettings().OSMO_AUTO_SEND_LOCATIONS);
new OsMoControlDevice(app, this, service, tracker);
groups = new OsMoGroups(this, service, tracker, app);
this.app = app;
ApplicationMode.regWidget("osmo_control", (ApplicationMode[])null);
}
@ -85,6 +85,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
return true;
}
public OsMoGroupsActivity getGroupsActivity() {
return groupsActivity;
}
@ -229,8 +230,17 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
if (si != null) {
String uname = si.username;
if (uname != null && uname.length() > 0) {
if (uname.length() > 7 && uname.indexOf(' ') != -1) {
uname = uname.substring(0, uname.indexOf(' '));
if (uname.length() > 7) {
for(int k = 4; k < uname.length(); k++) {
if(!Character.isLetterOrDigit(uname.charAt(k)) &&
uname.charAt(k) != '.' && uname.charAt(k) != '-') {
uname = uname.substring(0, k);
break;
}
}
if(uname.length() > 12) {
uname = uname.substring(0, 12);
}
}
if (uname.length() > 4) {
txt = "";
@ -350,11 +360,11 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
return service;
}
public AsyncTask<WptPt, String, String> getSaveGpxTask(final String name, final long timestamp) {
public AsyncTask<WptPt, String, String> getSaveGpxTask(final String name, final long timestamp, final boolean generateToast) {
return new AsyncTask<WptPt, String, String>() {
protected void onProgressUpdate(String... values) {
if (values != null) {
if (values != null && generateToast) {
String t = "";
for (String s : values) {
t += s + "\n";
@ -381,7 +391,9 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
if (errors == null) {
errors = "";
}
publishProgress(app.getString(R.string.osmo_gpx_points_downloaded, name));
if(generateToast) {
publishProgress(app.getString(R.string.osmo_gpx_points_downloaded, name));
}
}
SelectedGpxFile byPath = app.getSelectedGpxHelper().getSelectedFileByPath(ps.getAbsolutePath());
if (byPath == null || changed) {
@ -396,7 +408,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
@Override
protected void onPostExecute(String result) {
if (result.length() > 0) {
if (result.length() > 0 && generateToast) {
app.showToastMessage(app.getString(R.string.osmo_io_error) + result);
}
}
@ -525,4 +537,8 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
}
}
public boolean useHttps() {
return app.getSettings().OSMO_USE_HTTPS.get();
}
}

View file

@ -8,7 +8,6 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import net.osmand.Location;
import net.osmand.access.AccessibleToast;
import net.osmand.core.jni.ColorARGB;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmAndFormatter;
@ -294,6 +293,7 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
private static String followTrackerId;
private static LatLon followMapLocation;
private static String followDestinationId;
private static LatLon followTargetLocation;
public static void setFollowTrackerId(OsMoDevice d) {
if(d != null) {
@ -322,17 +322,29 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
Location l = device.getLastLocation();
if(sameDestId && l != null) {
TargetPointsHelper targets = map.getMyApplication().getTargetPointsHelper();
RoutingHelper rh = map.getMyApplication().getRoutingHelper();
double dist = 1;
if(rh.isRouteBeingCalculated()) {
dist = 100;
} else if(rh.isRouteCalculated()) {
dist = 30;
}
LatLon lt = new LatLon(l.getLatitude(), l.getLongitude());
final TargetPoint pn = targets.getPointToNavigate();
if(pn == null || MapUtils.getDistance(pn.point, lt) > dist) {
targets.navigateToPoint(lt, true, -1);
LatLon lt = new LatLon(l.getLatitude(), l.getLongitude());
boolean cancelDestinationId = false;
if(followTargetLocation != null ) {
if(pn == null || pn.point == null || !pn.point.equals(lt) ) {
cancelDestinationId = true;
}
}
if(cancelDestinationId) {
followTargetLocation = null;
followDestinationId = null;
} else {
RoutingHelper rh = map.getMyApplication().getRoutingHelper();
double dist = 1;
if (rh.isRouteBeingCalculated()) {
dist = 100;
} else if (rh.isRouteCalculated()) {
dist = 30;
}
if (pn == null || MapUtils.getDistance(pn.point, lt) > dist) {
followTargetLocation = lt;
targets.navigateToPoint(lt, true, -1);
}
}
}

View file

@ -4,11 +4,20 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.crypto.Cipher;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
@ -45,6 +54,12 @@ import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
public class OsMoService implements OsMoReactor {
private static final String HTTP_API_PREPARE = "http://api.osmo.mobi/prepare";
private static final String HTTPS_API_PREPARE = "https://api.osmo.mobi/prepare";
private static final String HTTP_AUTH = "http://api.osmo.mobi/auth";
private static final String HTTPS_AUTH = "https://api.osmo.mobi/auth";
private static final boolean USE_RSA_ENCRYPTION = false;
public static final String REGENERATE_CMD = "TRACKER_REGENERATE_ID";
public static final String SIGN_IN_URL = "http://osmo.mobi/signin?key=";
private OsMoThread thread;
@ -61,6 +76,7 @@ public class OsMoService implements OsMoReactor {
private boolean enabled = false;
private BroadcastReceiver broadcastReceiver;
private Notification notification;
public final static String OSMO_REGISTER_AGAIN = "OSMO_REGISTER_AGAIN"; //$NON-NLS-1$
private final static int SIMPLE_NOTFICATION_ID = 5;
@ -170,7 +186,7 @@ public class OsMoService implements OsMoReactor {
public String registerOsmoDeviceKey() throws IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth");
HttpPost httppost = new HttpPost(plugin.useHttps()? HTTPS_AUTH : HTTP_AUTH);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
@ -209,6 +225,7 @@ public class OsMoService implements OsMoReactor {
public String token;
public String uid;
public String username;
// after auth
public String protocol = "";
public String groupTrackerId;
@ -217,6 +234,8 @@ public class OsMoService implements OsMoReactor {
public long motdTimestamp;
public String motd = "";
public Cipher clientEncCypher;
public Cipher clientDecCypher;
}
public SessionInfo getCurrentSessionInfo() {
@ -258,12 +277,33 @@ public class OsMoService implements OsMoReactor {
deviceKey = registerOsmoDeviceKey();
}
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://api.osmo.mobi/prepare");
KeyPair getMsgPair = null;
if (plugin.useHttps() && USE_RSA_ENCRYPTION) {
try {
KeyPairGenerator rsaGen = KeyPairGenerator.getInstance("RSA");
getMsgPair = rsaGen.generateKeyPair();
} catch (Exception e1) {
if (thread != null) {
thread.exc("Private key can't be generated", e1);
} else {
e1.printStackTrace();
}
}
}
HttpPost httppost = new HttpPost(plugin.useHttps()? HTTPS_API_PREPARE : HTTP_API_PREPARE);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("app", Version.getFullVersion(app)));
nameValuePairs.add(new BasicNameValuePair("key", deviceKey));
if(getMsgPair != null && getMsgPair.getPublic() instanceof RSAPublicKey) {
nameValuePairs.add(new BasicNameValuePair("encAlgorithm", "RSA"));
BigInteger modulus = ((RSAPublicKey) getMsgPair.getPublic()).getModulus();
BigInteger pe = ((RSAPublicKey) getMsgPair.getPublic()).getPublicExponent();
nameValuePairs.add(new BasicNameValuePair("encClientPublicKey1", modulus.toString()));
nameValuePairs.add(new BasicNameValuePair("encClientPublicKey2", pe.toString()));
}
if(app.getSettings().OSMO_USER_PWD.get() != null) {
nameValuePairs.add(new BasicNameValuePair("auth", app.getSettings().OSMO_USER_PWD.get()));
}
@ -304,6 +344,23 @@ public class OsMoService implements OsMoReactor {
si.hostName = a.substring(0, i);
si.port = a.substring(i + 1);
si.token = obj.getString("token");
try {
if(getMsgPair != null && obj.has("encServerPublicKey1")) {
si.clientEncCypher = Cipher.getInstance("RSA");
PublicKey pk = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger(obj.getString("encServerPublicKey1")),
new BigInteger(obj.getString("encServerPublicKey2"))));
si.clientEncCypher.init(Cipher.ENCRYPT_MODE, pk);
si.clientDecCypher = Cipher.getInstance("RSA");
si.clientDecCypher.init(Cipher.DECRYPT_MODE, getMsgPair.getPrivate());
}
} catch (Exception e) {
if (thread != null) {
thread.exc("Error exchanging private keys", e);
} else {
e.printStackTrace();
}
}
return si;
} catch (ClientProtocolException e) {
throw new IOException(e);

View file

@ -17,7 +17,11 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import net.osmand.PlatformUtil;
import net.osmand.osm.io.Base64;
import net.osmand.plus.osmo.OsMoService.SessionInfo;
import org.apache.commons.logging.Log;
@ -261,6 +265,15 @@ public class OsMoThread {
while ((i = readCommand.indexOf('\n')) != -1) {
String cmd = readCommand.substring(0, i);
readCommand = readCommand.substring(i + 1);
if(sessionInfo != null && sessionInfo.clientDecCypher != null) {
try {
final byte[] inMsg = android.util.Base64.decode(cmd.getBytes(), android.util.Base64.DEFAULT);
final byte[] byts = sessionInfo.clientDecCypher.doFinal(inMsg);
cmd = new String(byts);
} catch (Exception e) {
exc("Error decrypting", e);
}
}
queueOfMessages.add(cmd.replace("\\n", "\n"));
}
}
@ -449,15 +462,23 @@ public class OsMoThread {
private String prepareCommand(String l) {
StringBuilder res = new StringBuilder(l.length());
for(int i = 0; i < l.length(); i++) {
for (int i = 0; i < l.length(); i++) {
char c = l.charAt(i);
if(c == '\n' || c == '=' || c == '\\') {
res.append('\\');
if (c == '\n' || c == '=' || c == '\\') {
res.append('\\');
}
res.append(c);
}
return res.toString().trim() + "=\n";
String finalCmd = res.toString().trim();
if(sessionInfo != null && sessionInfo.clientEncCypher != null) {
try {
finalCmd = Base64.encode(sessionInfo.clientEncCypher.doFinal(finalCmd.getBytes()));
} catch (Exception e) {
exc("Error encrypting", e);
}
}
return finalCmd + "=\n";
}
public long getLastCommandTime() {

View file

@ -68,6 +68,11 @@ public class SettingsOsMoActivity extends SettingsBaseActivity {
showGroupNotifiations.setSummary(R.string.osmo_show_group_notifications_descr);
grp.addPreference(showGroupNotifiations);
CheckBoxPreference useHttps = createCheckBoxPreference(settings.OSMO_USE_HTTPS);
useHttps.setTitle(R.string.osmo_use_https);
useHttps.setSummary(R.string.osmo_use_https_descr);
grp.addPreference(useHttps);
if (OsmandPlugin.isDevelopment()) {
debugPref = new Preference(this);
debugPref.setTitle(R.string.osmo_settings_debug);

View file

@ -49,7 +49,12 @@ public class NativeOsmandLibrary extends NativeLibrary {
System.loadLibrary("cpufeatures_proxy");
if (android.os.Build.VERSION.SDK_INT >= 8) {
log.debug("Loading jnigraphics, since Android >= 2.2 ..."); //$NON-NLS-1$
System.loadLibrary("jnigraphics");
try {
System.loadLibrary("jnigraphics");
} catch( UnsatisfiedLinkError e ) {
// handle "Shared library already opened" error
log.debug("Failed to load jnigraphics: " + e); //$NON-NLS-1$
}
}
final String libCpuSuffix = cpuHasNeonSupport() ? "_neon" : "";
log.debug("Loading native libraries..."); //$NON-NLS-1$

View file

@ -5,6 +5,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -84,6 +85,7 @@ public class SherpafyCustomization extends OsmAndAppCustomization {
public static final String TOUR_SERVER = "download.osmand.net";
private static final String SAVE_GPX_FOLDER = "save_gpx_folder";
private Object originalGlobal;
private Map<Class<Object>, Object> activities = new HashMap<Class<Object>, Object>();
@Override
public void setup(OsmandApplication app) {
@ -230,7 +232,7 @@ public class SherpafyCustomization extends OsmAndAppCustomization {
}
this.tourPresent = tourPresent;
if(!suggestToDownloadMap.isEmpty()) {
final DownloadActivity da = app.getDownloadActivity();
final DownloadActivity da = (DownloadActivity) activities.get(DownloadActivity.class);
if (da != null) {
app.runInUIThread(new Runnable() {
@ -687,7 +689,7 @@ public class SherpafyCustomization extends OsmAndAppCustomization {
}
public boolean onDestinationReached() {
final MapActivity map = app.getMapActivity();
final MapActivity map = (MapActivity) activities.get(MapActivity.class);
if(map != null && getSelectedStage() != null) {
app.runInUIThread(new Runnable() {
@ -700,6 +702,17 @@ public class SherpafyCustomization extends OsmAndAppCustomization {
return true;
}
@Override
public <T> void pauseActivity(Class<T> class1) {
super.pauseActivity(class1);
}
@Override
@SuppressWarnings("unchecked")
public <T> void resumeActivity(Class<T> class1, T d) {
activities.put((Class<Object>) class1, d);
}
public void runStage(Activity a, TourInformation tour, StageInformation stage, boolean startOver) {
WptPt point = null;
GPXFile gpx = null;

View file

@ -12,10 +12,10 @@ import javax.microedition.khronos.egl.EGLSurface;
import net.osmand.core.android.CoreResourcesFromAndroidAssetsCustom;
import net.osmand.core.jni.AtlasMapRendererConfiguration;
import net.osmand.core.jni.BinaryMapDataProvider;
import net.osmand.core.jni.BinaryMapPrimitivesProvider;
import net.osmand.core.jni.BinaryMapRasterLayerProvider_Software;
import net.osmand.core.jni.BinaryMapStaticSymbolsProvider;
import net.osmand.core.jni.ObfMapObjectsProvider;
import net.osmand.core.jni.MapPrimitivesProvider;
import net.osmand.core.jni.MapRasterLayerProvider_Software;
import net.osmand.core.jni.MapObjectsSymbolsProvider;
import net.osmand.core.jni.IMapRenderer;
import net.osmand.core.jni.Logger;
import net.osmand.core.jni.MapPresentationEnvironment;
@ -26,7 +26,7 @@ import net.osmand.core.jni.ObfsCollection;
import net.osmand.core.jni.OnlineRasterMapLayerProvider;
import net.osmand.core.jni.OnlineTileSources;
import net.osmand.core.jni.OsmAndCore;
import net.osmand.core.jni.Primitiviser;
import net.osmand.core.jni.MapPrimitiviser;
import net.osmand.core.jni.QIODeviceLogSink;
import net.osmand.core.jni.ResolvedMapStyle;
import net.osmand.plus.OsmandApplication;
@ -158,15 +158,15 @@ public class NativeQtLibrary {
MapPresentationEnvironment presentation = notGc(new MapPresentationEnvironment(mapStyle, displayDensityFactor, "en"));
//TODO: here should be current locale
//mapPresentationEnvironment->setSettings(configuration.styleSettings);
BinaryMapPrimitivesProvider binaryMapPrimitivesProvider = notGc(new BinaryMapPrimitivesProvider(
notGc(new BinaryMapDataProvider(obfsCollection)),
notGc(new Primitiviser(presentation)), rasterTileSize));
BinaryMapRasterLayerProvider_Software binaryMapRasterLayerProvider = notGc(new BinaryMapRasterLayerProvider_Software(
binaryMapPrimitivesProvider));
mapRenderer.setMapLayerProvider(0, binaryMapRasterLayerProvider);
BinaryMapStaticSymbolsProvider binaryMapStaticSymbolsProvider = notGc(new BinaryMapStaticSymbolsProvider(
binaryMapPrimitivesProvider, rasterTileSize));
mapRenderer.addSymbolsProvider(binaryMapStaticSymbolsProvider);
MapPrimitivesProvider mapPrimitivesProvider = notGc(new MapPrimitivesProvider(
notGc(new ObfMapObjectsProvider(obfsCollection)),
notGc(new MapPrimitiviser(presentation)), rasterTileSize));
MapRasterLayerProvider_Software mapRasterLayerProvider = notGc(new MapRasterLayerProvider_Software(
mapPrimitivesProvider));
mapRenderer.setMapLayerProvider(0, mapRasterLayerProvider);
MapObjectsSymbolsProvider mapObjectsSymbolsProvider = notGc(new MapObjectsSymbolsProvider(
mapPrimitivesProvider, rasterTileSize));
mapRenderer.addSymbolsProvider(mapObjectsSymbolsProvider);
} else {
OnlineRasterMapLayerProvider onlineMapRasterLayerProvider = notGc(OnlineTileSources.getBuiltIn()
.createProviderFor("Mapnik (OsmAnd)"));