From 02f2b5211ee9586fc25241410d201aa2811db811 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 18 Sep 2012 00:07:37 +0200 Subject: [PATCH 1/3] Speedup intermediate point route recalculation --- .../net/osmand/binary/RouteDataObject.java | 14 +++-- .../net/osmand/router/BinaryRoutePlanner.java | 56 +++++++++++++++++-- .../src/net/osmand/router/RoutingContext.java | 19 +++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/binary/RouteDataObject.java b/DataExtractionOSM/src/net/osmand/binary/RouteDataObject.java index 6ed2f03654..cad8e5be8d 100644 --- a/DataExtractionOSM/src/net/osmand/binary/RouteDataObject.java +++ b/DataExtractionOSM/src/net/osmand/binary/RouteDataObject.java @@ -206,9 +206,16 @@ public class RouteDataObject { } return -1; } + + public double directionRoute(int startPoint, boolean plus) { + // Victor : the problem to put more than 5 meters that BinaryRoutePlanner will treat + // 2 consequent Turn Right as UT and here 2 points will have same turn angle + // So it should be fix in both places + return directionRoute(startPoint, plus, 5); + } // Gives route direction of EAST degrees from NORTH ]-PI, PI] - public double directionRoute(int startPoint, boolean plus) { + public double directionRoute(int startPoint, boolean plus, float dist) { int x = getPoint31XTile(startPoint); int y = getPoint31YTile(startPoint); int nx = startPoint; @@ -231,10 +238,7 @@ public class RouteDataObject { py = getPoint31YTile(nx); // translate into meters total += Math.abs(px - x) * 0.011d + Math.abs(py - y) * 0.01863d; - // Victor : the problem to put more than 5 meters that BinaryRoutePlanner will treat - // 2 consequent Turn Right as UT and here 2 points will have same turn angle - // So it should be fix in both places - } while (total < 5); + } while (total < dist); return -Math.atan2( x - px, y - py ); } diff --git a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java index c0ba1dea95..786ec3bb45 100644 --- a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java +++ b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java @@ -167,23 +167,62 @@ public class BinaryRoutePlanner { public List searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end, List intermediate, boolean leftSideNavigation) throws IOException { if(intermediate != null && intermediate.size() > 0) { - // TODO previously calculated route ArrayList ps = new ArrayList(intermediate); + ArrayList firstPartRecalculatedRoute = null; + ArrayList restPartRecalculatedRoute = null; + if (ctx.previouslyCalculatedRoute != null) { + List prev = ctx.previouslyCalculatedRoute; + long id = intermediate.get(0).getRoad().id; + int ss = intermediate.get(0).getSegmentStart(); + for (int i = 0; i < prev.size(); i++) { + RouteSegmentResult rsr = prev.get(i); + if (id == rsr.getObject().getId() && ss == rsr.getEndPointIndex()) { + firstPartRecalculatedRoute = new ArrayList(prev.subList(0, i + 1)); + restPartRecalculatedRoute = new ArrayList(prev.subList(i + 1, prev.size())); + break; + } + } + } ps.add(end); ps.add(0, start); List results = new ArrayList(); for (int i = 0; i < ps.size() - 1; i++) { RoutingContext local = new RoutingContext(ctx.config); + local.copyLoadedDataAndClearCaches(ctx); + if(i == 0) { + local.previouslyCalculatedRoute = firstPartRecalculatedRoute; + } local.visitor = ctx.visitor; List res = searchRouteInternal(local, ps.get(i), ps.get(i + 1), leftSideNavigation); results.addAll(res); ctx.distinctLoadedTiles += local.distinctLoadedTiles; ctx.distinctUnloadedTiles.addAll(local.distinctUnloadedTiles); ctx.loadedTiles += local.loadedTiles; + ctx.visitedSegments += local.visitedSegments; ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles; ctx.timeToCalculate += local.timeToCalculate; ctx.timeToLoad += local.timeToLoad; ctx.relaxedSegments += local.relaxedSegments; + + List toUnload = new ArrayList(); + for(RoutingTile t : local.tiles.valueCollection()){ + if(!ctx.tiles.contains(t.getId())) { + toUnload.add(t); + } + } + for(RoutingTile tl : toUnload) { + local.unloadTile(tl, false); + } + if(restPartRecalculatedRoute != null) { + results.addAll(restPartRecalculatedRoute); + break; + } + } + Object[] vls = ctx.tiles.values(); + for (Object tl : vls) { + if (((RoutingTile) tl).isLoaded()) { + ctx.unloadTile((RoutingTile) tl, false); + } } printResults(ctx, start, end, results); return results; @@ -196,6 +235,10 @@ public class BinaryRoutePlanner { if(result != null) { printResults(ctx, start, end, result); } + Object[] vls = ctx.tiles.values(); + for(Object tl : vls) { + ctx.unloadTile((RoutingTile) tl, false); + } return result; } @@ -352,10 +395,6 @@ public class BinaryRoutePlanner { // 4. Route is found : collect all segments and prepare result List resultPrepared = prepareResult(ctx, start, end, leftSideNavigation); - Object[] vls = ctx.tiles.values(); - for(Object tl : vls) { - ctx.unloadTile((RoutingTile) tl, false); - } return resultPrepared; } @@ -1050,8 +1089,15 @@ public class BinaryRoutePlanner { } TurnType t = null; if (prev != null) { + boolean noAttachedRoads = rr.getAttachedRoutes(rr.getStartPointIndex()).size() == 0; // add description about turn double mpi = MapUtils.degreesDiff(prev.getBearingEnd(), rr.getBearingBegin()); + if(noAttachedRoads){ + // TODO VICTOR : look at the comment inside direction route +// double begin = rr.getObject().directionRoute(rr.getStartPointIndex(), rr.getStartPointIndex() < +// rr.getEndPointIndex(), 25); +// mpi = MapUtils.degreesDiff(prev.getBearingEnd(), begin); + } if (mpi >= TURN_DEGREE_MIN) { if (mpi < 60) { t = TurnType.valueOf(TurnType.TSLL, leftSide); diff --git a/DataExtractionOSM/src/net/osmand/router/RoutingContext.java b/DataExtractionOSM/src/net/osmand/router/RoutingContext.java index 9c988d98f4..f28fb82d57 100644 --- a/DataExtractionOSM/src/net/osmand/router/RoutingContext.java +++ b/DataExtractionOSM/src/net/osmand/router/RoutingContext.java @@ -372,6 +372,24 @@ public class RoutingContext { } } + public void copyLoadedDataAndClearCaches(RoutingContext ctx) { + for(RoutingTile tl : ctx.tiles.valueCollection()) { + if(tl.isLoaded()) { + this.tiles.put(tl.getId(), tl); + for(RouteSegment rs : tl.routes.valueCollection()) { + RouteSegment s = rs; + while(s != null) { + s.parentRoute = null; + s.parentSegmentEnd = 0; + s.distanceFromStart = 0; + s.distanceToEnd = 0; + s = s.next; + } + } + } + } + } + public static class RoutingTile { private int tileX; private int tileY; @@ -489,4 +507,5 @@ public class RoutingContext { } } + } \ No newline at end of file From d83fa5c3c4dec96da0c35ec6260adf03cc65317f Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 18 Sep 2012 00:52:59 +0200 Subject: [PATCH 2/3] Fix translator configuration --- .../net.osmand.translator/.classpath | 23 ++- .../net.osmand.translator/.gitignore | 1 + build-scripts/net.osmand.translator/.project | 53 ++++--- .../META-INF/MANIFEST.MF | 15 -- .../net.osmand.translator/build.properties | 6 - .../net.osmand.translator/icons/sample.gif | Bin 983 -> 0 bytes .../net.osmand.translator/plugin.xml | 62 -------- build-scripts/net.osmand.translator/pom.xml | 147 ++++++++++++++++++ .../src/net/osmand/translator/Activator.java | 61 -------- .../net/osmand/translator/TranslatorMain.java | 5 + .../handlers/TranslationHandler.java | 96 ++++++------ 11 files changed, 240 insertions(+), 229 deletions(-) delete mode 100644 build-scripts/net.osmand.translator/META-INF/MANIFEST.MF delete mode 100644 build-scripts/net.osmand.translator/build.properties delete mode 100644 build-scripts/net.osmand.translator/icons/sample.gif delete mode 100644 build-scripts/net.osmand.translator/plugin.xml create mode 100644 build-scripts/net.osmand.translator/pom.xml delete mode 100644 build-scripts/net.osmand.translator/src/net/osmand/translator/Activator.java create mode 100644 build-scripts/net.osmand.translator/src/net/osmand/translator/TranslatorMain.java diff --git a/build-scripts/net.osmand.translator/.classpath b/build-scripts/net.osmand.translator/.classpath index 098194ca4b..43c31e7159 100644 --- a/build-scripts/net.osmand.translator/.classpath +++ b/build-scripts/net.osmand.translator/.classpath @@ -1,7 +1,18 @@ - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-scripts/net.osmand.translator/.gitignore b/build-scripts/net.osmand.translator/.gitignore index ba077a4031..d567ba01e1 100644 --- a/build-scripts/net.osmand.translator/.gitignore +++ b/build-scripts/net.osmand.translator/.gitignore @@ -1 +1,2 @@ bin +target diff --git a/build-scripts/net.osmand.translator/.project b/build-scripts/net.osmand.translator/.project index 4bb391ea39..d5af7f4544 100644 --- a/build-scripts/net.osmand.translator/.project +++ b/build-scripts/net.osmand.translator/.project @@ -1,28 +1,27 @@ - - net.osmand.translator - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + translator + + + + + org.eclipse.jdt.core.javabuilder + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.pde.ManifestBuilder.launch + + + + + org.eclipse.pde.SchemaBuilder + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + \ No newline at end of file diff --git a/build-scripts/net.osmand.translator/META-INF/MANIFEST.MF b/build-scripts/net.osmand.translator/META-INF/MANIFEST.MF deleted file mode 100644 index c1e69ef42f..0000000000 --- a/build-scripts/net.osmand.translator/META-INF/MANIFEST.MF +++ /dev/null @@ -1,15 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Translator -Bundle-SymbolicName: net.osmand.translator;singleton:=true -Bundle-Version: 1.0.0.qualifier -Bundle-Activator: net.osmand.translator.Activator -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.jdt;bundle-version="3.7.2", - org.eclipse.jdt.core;bundle-version="3.7.3", - org.eclipse.jdt.ui;bundle-version="3.7.2", - org.eclipse.jface.text;bundle-version="3.7.2", - org.eclipse.core.resources;bundle-version="3.7.101" -Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 diff --git a/build-scripts/net.osmand.translator/build.properties b/build-scripts/net.osmand.translator/build.properties deleted file mode 100644 index 0d3d3a745d..0000000000 --- a/build-scripts/net.osmand.translator/build.properties +++ /dev/null @@ -1,6 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = plugin.xml,\ - META-INF/,\ - .,\ - icons/ diff --git a/build-scripts/net.osmand.translator/icons/sample.gif b/build-scripts/net.osmand.translator/icons/sample.gif deleted file mode 100644 index 34fb3c9d8cb7d489681b7f7aee4bdcd7eaf53610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 983 zcmZ?wbhEHb6krfw_|CxKYUg-n!?izO{@9*?jxd%4aX0yzy`dymabz zw#(eg=y~&N&n)dZv2xzduG}5lraiApo3(c4*{Ylg5#|$JO_EEZ<^|a2`Z*=9ns7DV zy=TR&gYw*7f%auV?ip3tvjRPmcdoho{K?x$_vR?C#t5&<;~V}S*>OMCr>h}%%bLZ9 zmo3`hYEwTICo-TTCZwgTsC&VjZRgJ1eE#fBa^%9R zmmfWS@;bnyJ27HWY}kxYzv(Hl>yu;FCPlAEh+34Muq-8Rb6C)<8qA3{r2e5 z`$vyngh#H=FWlqqvnapfc5%(!sQ4v?r7J61-&eJNEN^;KTK}T7{#i-gJh%G*9vcYdwv_*~xdw!Gz4Va?T!sXyyF@8?w<>X`X=#j%uHV4GRvj@+tE@ zQ%F!a)GKcn^~8abN>4la1UNXVL;{ZWi)lEwyeatDu%Lr6;aASiLrXXW zQm# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build-scripts/net.osmand.translator/pom.xml b/build-scripts/net.osmand.translator/pom.xml new file mode 100644 index 0000000000..a828c1f29a --- /dev/null +++ b/build-scripts/net.osmand.translator/pom.xml @@ -0,0 +1,147 @@ + + 4.0.0 + net.osmand.translator + translator + jar + 1 + translator + + + target + target/classes + ${artifactId}-${version} + target/test-classes + src + test/src + + + src/resources + + + + + test/resources + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.5 + + + + maven-plugin-plugin + 2.4.3 + + + maven-eclipse-plugin + 2.5 + + net.osmand.translator + + + + + + + + + com.google.guava + guava + 13.0 + compile + + + com.google.code.findbugs + jsr305 + 2.0.1 + compile + + + org.eclipse.core + org.eclipse.core.contenttype + 3.4.100.v20100505-1235 + + + org.eclipse.equinox + org.eclipse.equinox.registry + + + compile + + + org.eclipse.core + org.eclipse.core.jobs + 3.5.0.v20100515 + compile + + + org.eclipse.core + org.eclipse.core.resources + 3.6.0.v20100526-0737 + + + org.eclipse.core + org.eclipse.core.expressions + + + org.eclipse.core + org.eclipse.core.filesystem + + + compile + + + org.eclipse.core + org.eclipse.core.runtime + 3.6.0.v20100505 + + + org.eclipse.equinox + org.eclipse.equinox.app + + + compile + + + org.eclipse.equinox + org.eclipse.equinox.common + 3.6.0.v20100503 + compile + + + org.eclipse.equinox + org.eclipse.equinox.preferences + 3.3.0.v20100503 + compile + + + org.eclipse.tycho + org.eclipse.jdt.core + 3.8.1.v20120531-0637 + compile + + + org.eclipse.osgi + org.eclipse.osgi + 3.6.0.v20100517 + compile + + + org.jibx.config.3rdparty.org.eclipse + org.eclipse.text + 3.5.100.v20110505-0800 + compile + + + junit + junit + 4.10 + test + + + \ No newline at end of file diff --git a/build-scripts/net.osmand.translator/src/net/osmand/translator/Activator.java b/build-scripts/net.osmand.translator/src/net/osmand/translator/Activator.java deleted file mode 100644 index 635281cae9..0000000000 --- a/build-scripts/net.osmand.translator/src/net/osmand/translator/Activator.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.osmand.translator; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - */ -public class Activator extends AbstractUIPlugin { - - // The plug-in ID - public static final String PLUGIN_ID = "net.osmand.translator"; //$NON-NLS-1$ - - // The shared instance - private static Activator plugin; - - /** - * The constructor - */ - public Activator() { - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - } - - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static Activator getDefault() { - return plugin; - } - - /** - * Returns an image descriptor for the image file at the given - * plug-in relative path - * - * @param path the path - * @return the image descriptor - */ - public static ImageDescriptor getImageDescriptor(String path) { - return imageDescriptorFromPlugin(PLUGIN_ID, path); - } -} diff --git a/build-scripts/net.osmand.translator/src/net/osmand/translator/TranslatorMain.java b/build-scripts/net.osmand.translator/src/net/osmand/translator/TranslatorMain.java new file mode 100644 index 0000000000..090fa2bd58 --- /dev/null +++ b/build-scripts/net.osmand.translator/src/net/osmand/translator/TranslatorMain.java @@ -0,0 +1,5 @@ +package net.osmand.translator; + +public class TranslatorMain { + +} diff --git a/build-scripts/net.osmand.translator/src/net/osmand/translator/handlers/TranslationHandler.java b/build-scripts/net.osmand.translator/src/net/osmand/translator/handlers/TranslationHandler.java index 2a011dd684..28bd70ab0d 100644 --- a/build-scripts/net.osmand.translator/src/net/osmand/translator/handlers/TranslationHandler.java +++ b/build-scripts/net.osmand.translator/src/net/osmand/translator/handlers/TranslationHandler.java @@ -3,9 +3,6 @@ package net.osmand.translator.handlers; import net.osmand.translator.utils.FieldsHandler; import net.osmand.translator.utils.MethodHandler; -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; @@ -13,7 +10,6 @@ import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; @@ -28,22 +24,22 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jface.text.Document; //import org.eclipse.jface.text.Document; -public class TranslationHandler extends AbstractHandler { - public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IWorkspaceRoot root = workspace.getRoot(); - IPath path = root.getProject("DataExtactionOSM").getFile("src/net/osmand/osm/MapUtils.java").getFullPath(); -// parse "MapUtils.java" -// IPath path = Path.fromOSString("/DataExtractionOSM/src/net/osmand/osm/MapUtils.java"); - IFile iFile = root.getFileForLocation(path); - ICompilationUnit unit = (ICompilationUnit)JavaCore.create(iFile); - CompilationUnit parse = parse(unit); - FieldsHandler.printFieldsInfo(parse); - System.out.println(); - MethodHandler.printMethodsInfo(parse); - return null; - } - +public class TranslationHandler { + + public static void execute() { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + IPath path = root.getProject("DataExtactionOSM").getFile("src/net/osmand/osm/MapUtils.java").getFullPath(); + // parse "MapUtils.java" + // IPath path = Path.fromOSString("/DataExtractionOSM/src/net/osmand/osm/MapUtils.java"); + IFile iFile = root.getFileForLocation(path); + ICompilationUnit unit = (ICompilationUnit) JavaCore.create(iFile); + CompilationUnit parse = parse(unit); + FieldsHandler.printFieldsInfo(parse); + System.out.println(); + MethodHandler.printMethodsInfo(parse); + } + private static CompilationUnit parse(ICompilationUnit unit) { ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setKind(ASTParser.K_COMPILATION_UNIT); @@ -52,21 +48,20 @@ public class TranslationHandler extends AbstractHandler { return (CompilationUnit) parser.createAST(null); // parse } -///////////////////////////////////////////////////////////////////////////// - + // /////////////////////////////////////////////////////////////////////////// + private void getProjects(IWorkspaceRoot root) { IProject[] projects = root.getProjects(); - for (IProject project : projects) { - try { - printProjectInfo(project); - } catch (CoreException e) { - e.printStackTrace(); - } - } + for (IProject project : projects) { + try { + printProjectInfo(project); + } catch (CoreException e) { + e.printStackTrace(); + } + } } - - private void printProjectInfo(IProject project) throws CoreException, - JavaModelException { + + private void printProjectInfo(IProject project) throws CoreException, JavaModelException { System.out.println("Working in project " + project.getName()); // Check if we have a Java project if (project.isNatureEnabled("org.eclipse.jdt.core.javanature")) { @@ -75,34 +70,31 @@ public class TranslationHandler extends AbstractHandler { } } - private void printPackageInfos(IJavaProject javaProject) - throws JavaModelException { - IPackageFragment[] packages = javaProject.getPackageFragments(); - for (IPackageFragment mypackage : packages) { - // Package fragments include all packages in the - // classpath - // We will only look at the package from the source - // folder - // K_BINARY would include also included JARS, e.g. - // rt.jar - if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) { - System.out.println("Package " + mypackage.getElementName()); - printICompilationUnitInfo(mypackage); + private void printPackageInfos(IJavaProject javaProject) throws JavaModelException { + IPackageFragment[] packages = javaProject.getPackageFragments(); + for (IPackageFragment mypackage : packages) { + // Package fragments include all packages in the + // classpath + // We will only look at the package from the source + // folder + // K_BINARY would include also included JARS, e.g. + // rt.jar + if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) { + System.out.println("Package " + mypackage.getElementName()); + printICompilationUnitInfo(mypackage); - } + } - } - } + } + } - private void printICompilationUnitInfo(IPackageFragment mypackage) - throws JavaModelException { + private void printICompilationUnitInfo(IPackageFragment mypackage) throws JavaModelException { for (ICompilationUnit unit : mypackage.getCompilationUnits()) { printCompilationUnitDetails(unit); } } - private void printCompilationUnitDetails(ICompilationUnit unit) - throws JavaModelException { + private void printCompilationUnitDetails(ICompilationUnit unit) throws JavaModelException { System.out.println("Source file " + unit.getElementName()); Document doc = new Document(unit.getSource()); System.out.println("Has number of lines: " + doc.getNumberOfLines()); From 0f3459fec7eab319c32aeb720d047da7ac7908bc Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 18 Sep 2012 01:00:15 +0200 Subject: [PATCH 3/3] Update translator project --- .../net.osmand.translator/.classpath | 18 - .../net.osmand.translator/.gitignore | 4 +- build-scripts/net.osmand.translator/.project | 27 - .../.settings/org.eclipse.jdt.core.prefs | 7 - build-scripts/net.osmand.translator/pom.xml | 6 +- .../test/resources/MapUtils.java | 475 ++++++++++++++++++ .../model => test/resources}/map_utils.cpp | 0 .../translator/test/TranslatorTest.java | 14 + 8 files changed, 495 insertions(+), 56 deletions(-) delete mode 100644 build-scripts/net.osmand.translator/.classpath delete mode 100644 build-scripts/net.osmand.translator/.project delete mode 100644 build-scripts/net.osmand.translator/.settings/org.eclipse.jdt.core.prefs create mode 100644 build-scripts/net.osmand.translator/test/resources/MapUtils.java rename build-scripts/net.osmand.translator/{src/net/osmand/translator/cpp/model => test/resources}/map_utils.cpp (100%) create mode 100644 build-scripts/net.osmand.translator/test/src/net/osmand/translator/test/TranslatorTest.java diff --git a/build-scripts/net.osmand.translator/.classpath b/build-scripts/net.osmand.translator/.classpath deleted file mode 100644 index 43c31e7159..0000000000 --- a/build-scripts/net.osmand.translator/.classpath +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build-scripts/net.osmand.translator/.gitignore b/build-scripts/net.osmand.translator/.gitignore index d567ba01e1..1d7d5711fc 100644 --- a/build-scripts/net.osmand.translator/.gitignore +++ b/build-scripts/net.osmand.translator/.gitignore @@ -1,2 +1,4 @@ -bin +.project +.classpath +.externalToolBuilders target diff --git a/build-scripts/net.osmand.translator/.project b/build-scripts/net.osmand.translator/.project deleted file mode 100644 index d5af7f4544..0000000000 --- a/build-scripts/net.osmand.translator/.project +++ /dev/null @@ -1,27 +0,0 @@ - - translator - - - - - org.eclipse.jdt.core.javabuilder - - - org.eclipse.ui.externaltools.ExternalToolBuilder - full,incremental, - - - LaunchConfigHandle - <project>/.externalToolBuilders/org.eclipse.pde.ManifestBuilder.launch - - - - - org.eclipse.pde.SchemaBuilder - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - \ No newline at end of file diff --git a/build-scripts/net.osmand.translator/.settings/org.eclipse.jdt.core.prefs b/build-scripts/net.osmand.translator/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index f42de363af..0000000000 --- a/build-scripts/net.osmand.translator/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,7 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/build-scripts/net.osmand.translator/pom.xml b/build-scripts/net.osmand.translator/pom.xml index a828c1f29a..6a31bdab32 100644 --- a/build-scripts/net.osmand.translator/pom.xml +++ b/build-scripts/net.osmand.translator/pom.xml @@ -1,10 +1,10 @@ 4.0.0 net.osmand.translator - translator + OsmAndTranslator jar 1 - translator + OsmAndTranslator target @@ -41,7 +41,7 @@ maven-eclipse-plugin 2.5 - net.osmand.translator + OsmAndTranslator diff --git a/build-scripts/net.osmand.translator/test/resources/MapUtils.java b/build-scripts/net.osmand.translator/test/resources/MapUtils.java new file mode 100644 index 0000000000..48b5bd2630 --- /dev/null +++ b/build-scripts/net.osmand.translator/test/resources/MapUtils.java @@ -0,0 +1,475 @@ +package net.osmand.osm; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import net.osmand.data.MapObject; + + +/** + * This utility class includes : + * 1. distance algorithms + * 2. finding center for array of nodes + * 3. tile evaluation algorithms + * + * + */ +public class MapUtils { + + private static final String BASE_SHORT_OSM_URL = "http://osm.org/go/"; + + /** + * This array is a lookup table that translates 6-bit positive integer + * index values into their "Base64 Alphabet" equivalents as specified + * in Table 1 of RFC 2045. + */ + private static final char intToBase64[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '@' + }; + + public static double getDistance(Node e1, Node e2){ + return getDistance(e1.getLatitude(), e1.getLongitude(), e2.getLatitude(), e2.getLongitude()); + } + + public static double getDistance(LatLon l, double latitude, double longitude){ + return getDistance(l.getLatitude(), l.getLongitude(), latitude, longitude); + } + + public static double getDistance(Node e1, double latitude, double longitude){ + return getDistance(e1.getLatitude(), e1.getLongitude(), latitude, longitude); + } + + public static double getDistance(Node e1, LatLon point){ + return getDistance(e1.getLatitude(), e1.getLongitude(), point.getLatitude(), point.getLongitude()); + } + + private static double scalarMultiplication(double xA, double yA, double xB, double yB, double xC, double yC) { + // Scalar multiplication between (AB, AC) + double multiple = (xB - xA) * (xC - xA) + (yB- yA) * (yC -yA); + return multiple; + } + + public static double getOrthogonalDistance(double lat, double lon, double fromLat, double fromLon, double toLat, double toLon) { + return getDistance(getProjection(lat, lon, fromLat, fromLon, toLat, toLon), lat, lon); + } + + public static LatLon getProjection(double lat, double lon, double fromLat, double fromLon, double toLat, double toLon) { + // not very accurate computation on sphere but for distances < 1000m it is ok + double mDist = (fromLat - toLat) * (fromLat - toLat) + (fromLon - toLon) * (fromLon - toLon); + double projection = scalarMultiplication(fromLat, fromLon, toLat, toLon, lat, lon); + double prlat; + double prlon; + if (projection < 0) { + prlat = fromLat; + prlon = fromLon; + } else if (projection >= mDist) { + prlat = toLat; + prlon = toLon; + } else { + prlat = fromLat + (toLat - fromLat) * (projection / mDist); + prlon = fromLon + (toLon - fromLon) * (projection / mDist); + } + return new LatLon(prlat, prlon); + } + + + /** + * Gets distance in meters + */ + public static double getDistance(double lat1, double lon1, double lat2, double lon2){ + double R = 6371; // km + double dLat = Math.toRadians(lat2-lat1); + double dLon = Math.toRadians(lon2-lon1); + double a = Math.sin(dLat/2) * Math.sin(dLat/2) + + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * + Math.sin(dLon/2) * Math.sin(dLon/2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + return R * c * 1000; + } + + + /** + * Gets distance in meters + */ + public static double getDistance(LatLon l1, LatLon l2){ + return getDistance(l1.getLatitude(), l1.getLongitude(), l2.getLatitude(), l2.getLongitude()); + } + + public static LatLon getCenter(Entity e){ + if(e instanceof Node){ + return ((Node) e).getLatLon(); + } else if(e instanceof Way){ + return getWeightCenterForNodes(((Way) e).getNodes()); + } else if(e instanceof Relation){ + List list = new ArrayList(); + for(Entity fe : ((Relation) e).getMembers(null)){ + LatLon c = null; + // skip relations to avoid circular dependencies + if(!(fe instanceof Relation)){ + c = getCenter(fe); + } + if(c != null){ + list.add(c); + } + } + return getWeightCenter(list); + } + return null; + } + + public static LatLon getWeightCenter(Collection nodes){ + if(nodes.isEmpty()){ + return null; + } + double longitude = 0; + double latitude = 0; + for(LatLon n : nodes){ + longitude += n.getLongitude(); + latitude += n.getLatitude(); + } + return new LatLon(latitude/nodes.size(), longitude/nodes.size()); + } + + public static LatLon getWeightCenterForNodes(Collection nodes){ + if (nodes.isEmpty()) { + return null; + } + double longitude = 0; + double latitude = 0; + int count = 0; + for (Node n : nodes) { + if (n != null) { + count++; + longitude += n.getLongitude(); + latitude += n.getLatitude(); + } + } + if (count == 0) { + return null; + } + return new LatLon(latitude/count, longitude/count); + } + + + public static LatLon getMathWeightCenterForNodes(Collection nodes){ + if (nodes.isEmpty()) { + return null; + } + double longitude = 0; + double latitude = 0; + double sumDist = 0; + Node prev = null; + for (Node n : nodes) { + if (n != null) { + if(prev == null){ + prev = n; + } else { + double dist = MapUtils.getDistance(prev, n); + sumDist += dist; + longitude += (prev.getLongitude() + n.getLongitude()) * dist / 2; + latitude += (n.getLatitude() + n.getLatitude()) * dist / 2; + prev = n; + } + } + } + if (sumDist == 0) { + if(prev == null){ + return null; + } + return prev.getLatLon(); + } + return new LatLon(latitude/sumDist, longitude/sumDist); + } + + public static double checkLongitude(double longitude) { + while (longitude < -180 || longitude > 180) { + if (longitude < 0) { + longitude += 360; + } else { + longitude -= 360; + } + } + return longitude; + } + + public static double checkLatitude(double latitude) { + while (latitude < -90 || latitude > 90) { + if (latitude < 0) { + latitude += 180; + } else { + latitude -= 180; + } + } + if(latitude < -85.0511) { + return -85.0511; + } else if(latitude > 85.0511){ + return 85.0511; + } + return latitude; + } + + public static int get31TileNumberX(double longitude){ + longitude = checkLongitude(longitude); + long l = 1l << 31; + return (int)((longitude + 180d)/360d * l); + } + public static int get31TileNumberY( double latitude){ + latitude = checkLatitude(latitude); + double eval = Math.log( Math.tan(Math.toRadians(latitude)) + 1/Math.cos(Math.toRadians(latitude)) ); + long l = 1l << 31; + if(eval > Math.PI){ + eval = Math.PI; + } + return (int) ((1 - eval / Math.PI) / 2 * l); + } + + public static double get31LongitudeX(int tileX){ + return MapUtils.getLongitudeFromTile(21, tileX /1024f); + } + + public static double get31LatitudeY(int tileY){ + return MapUtils.getLatitudeFromTile(21, tileY /1024f); + } + + + + /** + * + * Theses methods operate with degrees (evaluating tiles & vice versa) + * degree longitude measurements (-180, 180) [27.56 Minsk] + // degree latitude measurements (90, -90) [53.9] + */ + + public static double getTileNumberX(float zoom, double longitude){ + if(longitude == 180d) { + return getPowZoom(zoom) - 1; + } + longitude = checkLongitude(longitude); + return (longitude + 180d)/360d * getPowZoom(zoom); + } + + public static double getTileNumberY(float zoom, double latitude){ + latitude = checkLatitude(latitude); + double eval = Math.log( Math.tan(Math.toRadians(latitude)) + 1/Math.cos(Math.toRadians(latitude)) ); + if (Double.isInfinite(eval) || Double.isNaN(eval)) { + latitude = latitude < 0 ? - 89.9 : 89.9; + eval = Math.log( Math.tan(Math.toRadians(latitude)) + 1/Math.cos(Math.toRadians(latitude)) ); + } + double result = (1 - eval / Math.PI) / 2 * getPowZoom(zoom); + return result; + } + + public static double getTileEllipsoidNumberY(float zoom, double latitude){ + final double E2 = (double) latitude * Math.PI / 180; + final long sradiusa = 6378137; + final long sradiusb = 6356752; + final double J2 = (double) Math.sqrt(sradiusa * sradiusa - sradiusb * sradiusb) / sradiusa; + final double M2 = (double) Math.log((1 + Math.sin(E2)) + / (1 - Math.sin(E2)))/ 2- J2 * Math.log((1 + J2 * Math.sin(E2))/ (1 - J2 * Math.sin(E2))) / 2; + final double B2 = getPowZoom(zoom); + return B2 / 2 - M2 * B2 / 2 / Math.PI; + } + + public static double getLatitudeFromEllipsoidTileY(float zoom, float tileNumberY){ + final double MerkElipsK = 0.0000001; + final long sradiusa = 6378137; + final long sradiusb = 6356752; + final double FExct = (double) Math.sqrt(sradiusa * sradiusa + - sradiusb * sradiusb) + / sradiusa; + final double TilesAtZoom = getPowZoom(zoom); + double result = (tileNumberY - TilesAtZoom / 2) + / -(TilesAtZoom / (2 * Math.PI)); + result = (2 * Math.atan(Math.exp(result)) - Math.PI / 2) * 180 + / Math.PI; + double Zu = result / (180 / Math.PI); + double yy = (tileNumberY - TilesAtZoom / 2); + + double Zum1 = Zu; + Zu = Math.asin(1 - ((1 + Math.sin(Zum1)) * Math.pow(1 - FExct * Math.sin(Zum1), FExct)) + / (Math.exp((2 * yy) / -(TilesAtZoom / (2 * Math.PI))) * Math.pow(1 + FExct * Math.sin(Zum1), FExct))); + while (Math.abs(Zum1 - Zu) >= MerkElipsK) { + Zum1 = Zu; + Zu = Math.asin(1 - ((1 + Math.sin(Zum1)) * Math.pow(1 - FExct * Math.sin(Zum1), FExct)) + / (Math.exp((2 * yy) / -(TilesAtZoom / (2 * Math.PI))) * Math.pow(1 + FExct * Math.sin(Zum1), FExct))); + } + + return Zu * 180 / Math.PI; + } + + + public static double getLongitudeFromTile(float zoom, double x) { + return x / getPowZoom(zoom) * 360.0 - 180.0; + } + + public static double getPowZoom(float zoom){ + if(zoom >= 0 && zoom - Math.floor(zoom) < 0.05f){ + return 1 << ((int)zoom); + } else { + return Math.pow(2, zoom); + } + } + + + + public static float calcDiffPixelX(float rotateSin, float rotateCos, float dTileX, float dTileY, float tileSize){ + return (rotateCos * dTileX - rotateSin * dTileY) * tileSize ; + } + + public static float calcDiffPixelY(float rotateSin, float rotateCos, float dTileX, float dTileY, float tileSize){ + return (rotateSin * dTileX + rotateCos * dTileY) * tileSize ; + } + + public static double getLatitudeFromTile(float zoom, double y){ + int sign = y < 0 ? -1 : 1; + double result = Math.atan(sign*Math.sinh(Math.PI * (1 - 2 * y / getPowZoom(zoom)))) * 180d / Math.PI; + return result; + } + + + public static int getPixelShiftX(int zoom, double long1, double long2, int tileSize){ + return (int) ((getTileNumberX(zoom, long1) - getTileNumberX(zoom, long2)) * tileSize); + } + + + public static int getPixelShiftY(int zoom, double lat1, double lat2, int tileSize){ + return (int) ((getTileNumberY(zoom, lat1) - getTileNumberY(zoom, lat2)) * tileSize); + } + + public static void addIdsToList(Collection source, List ids){ + for(Entity e : source){ + ids.add(e.getId()); + } + } + + public static void sortListOfMapObject(List list, final double lat, final double lon){ + Collections.sort(list, new Comparator() { + @Override + public int compare(MapObject o1, MapObject o2) { + return Double.compare(MapUtils.getDistance(o1.getLocation(), lat, lon), MapUtils.getDistance(o2.getLocation(), + lat, lon)); + } + }); + } + + public static void sortListOfEntities(List list, final double lat, final double lon){ + Collections.sort(list, new Comparator() { + @Override + public int compare(Entity o1, Entity o2) { + return Double.compare(MapUtils.getDistance(o1.getLatLon(), lat, lon), MapUtils.getDistance(o2.getLatLon(), + lat, lon)); + } + }); + } + + // Examples +// System.out.println(buildShortOsmUrl(51.51829d, 0.07347d, 16)); // http://osm.org/go/0EEQsyfu +// System.out.println(buildShortOsmUrl(52.30103d, 4.862927d, 18)); // http://osm.org/go/0E4_JiVhs +// System.out.println(buildShortOsmUrl(40.59d, -115.213d, 9)); // http://osm.org/go/TelHTB-- + public static String buildShortOsmUrl(double latitude, double longitude, int zoom){ + long lat = (long) (((latitude + 90d)/180d)*(1l << 32)); + long lon = (long) (((longitude + 180d)/360d)*(1l << 32)); + long code = interleaveBits(lon, lat); + StringBuilder str = new StringBuilder(10); + str.append(BASE_SHORT_OSM_URL); + // add eight to the zoom level, which approximates an accuracy of one pixel in a tile. + for(int i=0; i< Math.ceil((zoom+8)/3d); i++){ + str.append(intToBase64[(int) ((code >> (58 - 6 * i)) & 0x3f)]); + } + // append characters onto the end of the string to represent + // partial zoom levels (characters themselves have a granularity of 3 zoom levels). + for(int j=0; j< (zoom + 8) % 3 ; j++){ + str.append('-'); + } + str.append("?m"); + return str.toString(); + } + + /** + * interleaves the bits of two 32-bit numbers. the result is known as a Morton code. + */ + private static long interleaveBits(long x, long y){ + long c = 0; + for(byte b = 31; b>=0; b--){ + c = (c << 1) | ((x >> b) & 1); + c = (c << 1) | ((y >> b) & 1); + } + return c; + } + + /** + * Calculate rotation diff D, that R (rotate) + D = T (targetRotate) + * D is between -180, 180 + * @param rotate + * @param targetRotate + * @return + */ + public static float unifyRotationDiff(float rotate, float targetRotate) { + float d = targetRotate - rotate; + while(d >= 180){ + d -= 360; + } + while(d < -180){ + d += 360; + } + return d; + } + + /** + * Calculate rotation diff D, that R (rotate) + D = T (targetRotate) + * D is between -180, 180 + * @param rotate + * @param targetRotate + * @return + */ + public static float unifyRotationTo360(float rotate) { + while(rotate < 0){ + rotate += 360; + } + while(rotate > 360){ + rotate -= 360; + } + return rotate; + } + + /** + * @param diff align difference between 2 angles ]-PI, PI] + * @return + */ + public static double alignAngleDifference(double diff) { + while(diff > Math.PI) { + diff -= 2 * Math.PI; + } + while(diff <=-Math.PI) { + diff += 2 * Math.PI; + } + return diff; + + } + + /** + * @param diff align difference between 2 angles ]-180, 180] + * @return + */ + public static double degreesDiff(double a1, double a2) { + double diff = a1 - a2; + while(diff > 180) { + diff -= 360; + } + while(diff <=-180) { + diff += 360; + } + return diff; + + } + +} + + diff --git a/build-scripts/net.osmand.translator/src/net/osmand/translator/cpp/model/map_utils.cpp b/build-scripts/net.osmand.translator/test/resources/map_utils.cpp similarity index 100% rename from build-scripts/net.osmand.translator/src/net/osmand/translator/cpp/model/map_utils.cpp rename to build-scripts/net.osmand.translator/test/resources/map_utils.cpp diff --git a/build-scripts/net.osmand.translator/test/src/net/osmand/translator/test/TranslatorTest.java b/build-scripts/net.osmand.translator/test/src/net/osmand/translator/test/TranslatorTest.java new file mode 100644 index 0000000000..ff8977ae27 --- /dev/null +++ b/build-scripts/net.osmand.translator/test/src/net/osmand/translator/test/TranslatorTest.java @@ -0,0 +1,14 @@ +package net.osmand.translator.test; + +import org.junit.Test; + +public class TranslatorTest { + + + @Test + public void simpleTest(){ + + System.out.println("SUCCESS !!!!! "); + } + +}