diff --git a/README.md b/README.md index c91ea3e..61843fc 100644 --- a/README.md +++ b/README.md @@ -46,21 +46,26 @@ A full documentation on how to set this up is available at ### Build and Install -To compile BRouter (including the BRouter Android app), use +To compile BRouter (including the BRouter Android app), add a file 'local.properties' to main folder with your Android path (Windows sample) ``` -mvn clean install -Dandroid.sdk.path= +sdk.dir=D\:\\Android\\android-sdk +``` + + +and use + +``` +gradlew clean build ``` If you only want to compile BRouter and the server part (skipping the Android app), use ``` -mvn clean install -pl '!brouter-routing-app' +gradlew clean build -x :brouter-routing-app:build ``` -You can use `-Dmaven.javadoc.skip=true` to skip the JavaDoc processing and -`-DskipTests` to skip running the unitary tests. ### Get the required segments (data) files diff --git a/brouter-codec/build.gradle b/brouter-codec/build.gradle index f055667..22faffe 100644 --- a/brouter-codec/build.gradle +++ b/brouter-codec/build.gradle @@ -4,4 +4,5 @@ plugins { dependencies { implementation project(':brouter-util') + testImplementation 'junit:junit:4.13.1' } diff --git a/brouter-core/build.gradle b/brouter-core/build.gradle index 597056a..c96982f 100644 --- a/brouter-core/build.gradle +++ b/brouter-core/build.gradle @@ -8,5 +8,6 @@ dependencies { implementation project(':brouter-util') implementation project(':brouter-expressions') implementation project(':brouter-codec') + testImplementation 'junit:junit:4.13.1' } diff --git a/brouter-core/src/main/java/btools/router/OsmTrack.java b/brouter-core/src/main/java/btools/router/OsmTrack.java index 3349cad..ca18f99 100644 --- a/brouter-core/src/main/java/btools/router/OsmTrack.java +++ b/brouter-core/src/main/java/btools/router/OsmTrack.java @@ -711,6 +711,15 @@ public final class OsmTrack public List iternity; + public void writeJson( String filename ) throws Exception + { + BufferedWriter bw = new BufferedWriter( new FileWriter( filename ) ); + + bw.write( formatAsGeoJson() ); + bw.close(); + } + + public String formatAsGeoJson() { int turnInstructionMode = voiceHints != null ? voiceHints.turnInstructionMode : 0; diff --git a/brouter-expressions/build.gradle b/brouter-expressions/build.gradle index 839a17d..ff146d6 100644 --- a/brouter-expressions/build.gradle +++ b/brouter-expressions/build.gradle @@ -5,4 +5,5 @@ plugins { dependencies { implementation project(':brouter-util') implementation project(':brouter-codec') + testImplementation 'junit:junit:4.13.1' } diff --git a/brouter-expressions/src/test/java/btools/expressions/EncodeDecodeTest.java b/brouter-expressions/src/test/java/btools/expressions/EncodeDecodeTest.java index f25beb1..4e51400 100644 --- a/brouter-expressions/src/test/java/btools/expressions/EncodeDecodeTest.java +++ b/brouter-expressions/src/test/java/btools/expressions/EncodeDecodeTest.java @@ -14,7 +14,7 @@ public class EncodeDecodeTest { URL testpurl = this.getClass().getResource( "/dummy.txt" ); File workingDir = new File(testpurl.getFile()).getParentFile(); - File profileDir = new File( workingDir, "/../../../misc/profiles2" ); + File profileDir = new File( workingDir, "/../../../../misc/profiles2" ); File lookupFile = new File( profileDir, "lookups.dat" ); // read lookup.dat + trekking.brf diff --git a/brouter-map-creator/build.gradle b/brouter-map-creator/build.gradle index 1bbc73f..530e277 100644 --- a/brouter-map-creator/build.gradle +++ b/brouter-map-creator/build.gradle @@ -2,15 +2,25 @@ plugins { id 'application' } +version = '1.6.1' + application { // Gradles 'application' plugin requires one main class; since we have multiple ones, just specify // one of them, since the applications won't be run from gradle anyways. - mainClassName = 'btools.mapcreator.PosUnifier' + mainClass.set('btools.mapcreator.PosUnifier') + + jar { + manifest { + attributes "Main-Class": getMainClass() + } + } + } dependencies { - implementation project(':brouter-util') implementation project(':brouter-codec') + implementation project(':brouter-util') implementation project(':brouter-expressions') - implementation('junit:junit:4.13') + + testImplementation('junit:junit:4.13.1') } diff --git a/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java b/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java index 2ea044f..a9e555e 100644 --- a/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java +++ b/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java @@ -17,7 +17,7 @@ public class MapcreatorTest Assert.assertTrue( "test-osm-map dreieich.osm not found", mapurl != null ); File mapFile = new File(mapurl.getFile()); File workingDir = mapFile.getParentFile(); - File profileDir = new File( workingDir, "/../../../misc/profiles2" ); + File profileDir = new File( workingDir, "/../../../../misc/profiles2" ); File tmpdir = new File( workingDir, "tmp" ); tmpdir.mkdir(); diff --git a/brouter-mapaccess/build.gradle b/brouter-mapaccess/build.gradle index eb89b10..c920239 100644 --- a/brouter-mapaccess/build.gradle +++ b/brouter-mapaccess/build.gradle @@ -3,7 +3,6 @@ plugins { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':brouter-util') implementation project(':brouter-codec') implementation project(':brouter-expressions') diff --git a/brouter-routing-app/build.gradle b/brouter-routing-app/build.gradle index 9af45ba..a54bf48 100644 --- a/brouter-routing-app/build.gradle +++ b/brouter-routing-app/build.gradle @@ -3,32 +3,78 @@ plugins { } android { - compileSdkVersion 29 + compileSdkVersion 30 defaultConfig { applicationId "btools.routingapp" - minSdkVersion 10 - targetSdkVersion 29 + minSdkVersion 19 + targetSdkVersion 30 versionCode 41 versionName "1.6.1" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + setProperty("archivesBaseName","BRouterApp." + defaultConfig.versionName) + + //testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + if(project.hasProperty("RELEASE_STORE_FILE")) { + signingConfigs { + // this uses a file ~/.gradle/gradle.properties + // with content: + // RELEASE_STORE_FILE={path to your keystore} + // RELEASE_STORE_PASSWORD=***** + // RELEASE_KEY_ALIAS=***** + // RELEASE_KEY_PASSWORD=***** + // + release { + // enable signingConfig in buildTypes to get a signed apk file + storeFile file(RELEASE_STORE_FILE) + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD + + // Optional, specify signing versions used + v1SigningEnabled true + v2SigningEnabled true + + } + } + } + buildTypes { release { minifyEnabled false + debuggable false + if(project.hasProperty("RELEASE_STORE_FILE")) { + signingConfig signingConfigs.release + } proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } + debug { + minifyEnabled false + debuggable true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + lintOptions { + disable 'InvalidPackage' + checkReleaseBuilds false //added this line to the build.gradle under the /android/app/build.gradle + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - + + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation project(':brouter-mapaccess') implementation project(':brouter-core') implementation project(':brouter-expressions') implementation project(':brouter-util') + } diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java index 1dc7eb4..65e743f 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java @@ -1,195 +1,230 @@ -package btools.routingapp; - - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.util.ArrayList; -import java.util.List; - -import android.os.Bundle; -import btools.router.OsmNodeNamed; -import btools.router.OsmPathElement; -import btools.router.OsmTrack; -import btools.router.RoutingContext; -import btools.router.RoutingEngine; - -public class BRouterWorker -{ - public String baseDir; - public String segmentDir; - public String profileName; - public String profilePath; - public String rawTrackPath; - public List waypoints; - public List nogoList; - - public String getTrackFromParams(Bundle params) - { - String pathToFileResult = params.getString("pathToFileResult"); - - if (pathToFileResult != null) - { - File f = new File (pathToFileResult); - File dir = f.getParentFile(); - if (!dir.exists() || !dir.canWrite()){ - return "file folder does not exists or can not be written!"; - } - } - - long maxRunningTime = 60000; - String sMaxRunningTime = params.getString( "maxRunningTime" ); - if ( sMaxRunningTime != null ) - { - maxRunningTime = Integer.parseInt( sMaxRunningTime ) * 1000; - } - - RoutingContext rc = new RoutingContext(); - rc.rawTrackPath = rawTrackPath; - rc.localFunction = profilePath; - - String tiFormat = params.getString( "turnInstructionFormat" ); - if ( tiFormat != null ) - { - if ( "osmand".equalsIgnoreCase( tiFormat ) ) - { - rc.turnInstructionMode = 3; - } - else if ( "locus".equalsIgnoreCase( tiFormat ) ) - { - rc.turnInstructionMode = 2; - } - } - - if ( params.containsKey( "direction" ) ) - { - rc.startDirection = Integer.valueOf( params.getInt( "direction" ) ); - } - - readNogos( params ); // add interface provided nogos - RoutingContext.prepareNogoPoints( nogoList ); - rc.nogopoints = nogoList; - - waypoints = readPositions(params); - - try - { - writeTimeoutData( rc ); - } - catch( Exception e ) {} - - RoutingEngine cr = new RoutingEngine( null, null, segmentDir, waypoints, rc ); - cr.quite = true; - cr.doRun( maxRunningTime ); - - // store new reference track if any - // (can exist for timed-out search) - if ( cr.getFoundRawTrack() != null ) - { - try - { - cr.getFoundRawTrack().writeBinary( rawTrackPath ); - } - catch( Exception e ) {} - } - - if ( cr.getErrorMessage() != null ) - { - return cr.getErrorMessage(); - } - - String format = params.getString("trackFormat"); - boolean writeKml = format != null && "kml".equals( format ); - - OsmTrack track = cr.getFoundTrack(); - if ( track != null ) - { - if ( pathToFileResult == null ) - { - if ( writeKml ) return track.formatAsKml(); - return track.formatAsGpx(); - } - try - { - if ( writeKml ) track.writeKml(pathToFileResult); - else track.writeGpx(pathToFileResult); - } - catch( Exception e ) - { - return "error writing file: " + e; - } - } - return null; - } - - private List readPositions( Bundle params ) - { - List wplist = new ArrayList(); - - double[] lats = params.getDoubleArray("lats"); - double[] lons = params.getDoubleArray("lons"); - - if (lats == null || lats.length < 2 || lons == null || lons.length < 2) - { - throw new IllegalArgumentException( "we need two lat/lon points at least!" ); - } - - for( int i=0; i wps ) throws Exception - { - bw.write( wps.size() + "\n" ); - for( OsmNodeNamed wp : wps ) - { - bw.write( wp.toString() ); - bw.write( "\n" ); - } - } -} +package btools.routingapp; + + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; + +import android.os.Bundle; +import btools.router.OsmNodeNamed; +import btools.router.OsmPathElement; +import btools.router.OsmTrack; +import btools.router.RoutingContext; +import btools.router.RoutingEngine; + +public class BRouterWorker +{ + private static final int OUTPUT_FORMAT_GPX = 0; + private static final int OUTPUT_FORMAT_KML = 1; + private static final int OUTPUT_FORMAT_JSON = 2; + + public String baseDir; + public String segmentDir; + public String profileName; + public String profilePath; + public String rawTrackPath; + public List waypoints; + public List nogoList; + + public String getTrackFromParams(Bundle params) + { + String pathToFileResult = params.getString("pathToFileResult"); + + if (pathToFileResult != null) + { + File f = new File (pathToFileResult); + File dir = f.getParentFile(); + if (!dir.exists() || !dir.canWrite()){ + return "file folder does not exists or can not be written!"; + } + } + + long maxRunningTime = 60000; + String sMaxRunningTime = params.getString( "maxRunningTime" ); + if ( sMaxRunningTime != null ) + { + maxRunningTime = Integer.parseInt( sMaxRunningTime ) * 1000; + } + + RoutingContext rc = new RoutingContext(); + rc.rawTrackPath = rawTrackPath; + rc.localFunction = profilePath; + + String tiFormat = params.getString( "turnInstructionFormat" ); + if ( tiFormat != null ) + { + if ( "osmand".equalsIgnoreCase( tiFormat ) ) + { + rc.turnInstructionMode = 3; + } + else if ( "locus".equalsIgnoreCase( tiFormat ) ) + { + rc.turnInstructionMode = 2; + } + } + + if ( params.containsKey( "direction" ) ) + { + rc.startDirection = Integer.valueOf( params.getInt( "direction" ) ); + } + if (params.containsKey( "extraParams" )) { // add user params + String extraParams = params.getString("extraParams"); + if (rc.keyValues == null) rc.keyValues = new HashMap(); + StringTokenizer tk = new StringTokenizer( extraParams, "?&" ); + while( tk.hasMoreTokens() ) { + String t = tk.nextToken(); + StringTokenizer tk2 = new StringTokenizer( t, "=" ); + if ( tk2.hasMoreTokens() ) { + String key = tk2.nextToken(); + if ( tk2.hasMoreTokens() ) { + String value = tk2.nextToken(); + rc.keyValues.put( key, value ); + } + } + } + } + + readNogos( params ); // add interface provided nogos + RoutingContext.prepareNogoPoints( nogoList ); + rc.nogopoints = nogoList; + + waypoints = readPositions(params); + + try + { + writeTimeoutData( rc ); + } + catch( Exception e ) {} + + RoutingEngine cr = new RoutingEngine( null, null, segmentDir, waypoints, rc ); + cr.quite = true; + cr.doRun( maxRunningTime ); + + // store new reference track if any + // (can exist for timed-out search) + if ( cr.getFoundRawTrack() != null ) + { + try + { + cr.getFoundRawTrack().writeBinary( rawTrackPath ); + } + catch( Exception e ) {} + } + + if ( cr.getErrorMessage() != null ) + { + return cr.getErrorMessage(); + } + + String format = params.getString("trackFormat"); + int writeFromat = OUTPUT_FORMAT_GPX; + if (format != null) { + if ("kml".equals(format)) writeFromat = OUTPUT_FORMAT_KML; + if ("json".equals(format)) writeFromat = OUTPUT_FORMAT_JSON; + } + + OsmTrack track = cr.getFoundTrack(); + if ( track != null ) + { + if ( pathToFileResult == null ) + { + switch ( writeFromat ) { + case OUTPUT_FORMAT_GPX: return track.formatAsGpx(); + case OUTPUT_FORMAT_KML: return track.formatAsKml(); + case OUTPUT_FORMAT_JSON: return track.formatAsGeoJson(); + default: return track.formatAsGpx(); + } + + } + try + { + switch ( writeFromat ) { + case OUTPUT_FORMAT_GPX: track.writeGpx(pathToFileResult); break; + case OUTPUT_FORMAT_KML: track.writeKml(pathToFileResult); break; + case OUTPUT_FORMAT_JSON: track.writeJson(pathToFileResult); break; + default: track.writeGpx(pathToFileResult); break; + } + } + catch( Exception e ) + { + return "error writing file: " + e; + } + } + return null; + } + + private List readPositions( Bundle params ) + { + List wplist = new ArrayList(); + + double[] lats = params.getDoubleArray("lats"); + double[] lons = params.getDoubleArray("lons"); + + if (lats == null || lats.length < 2 || lons == null || lons.length < 2) + { + throw new IllegalArgumentException( "we need two lat/lon points at least!" ); + } + + for( int i=0; i wps ) throws Exception + { + bw.write( wps.size() + "\n" ); + for( OsmNodeNamed wp : wps ) + { + bw.write( wp.toString() ); + bw.write( "\n" ); + } + } +} diff --git a/brouter-server/build.gradle b/brouter-server/build.gradle index 6c4d867..868dfc4 100644 --- a/brouter-server/build.gradle +++ b/brouter-server/build.gradle @@ -2,19 +2,23 @@ plugins { id 'application' } +version = '1.6.1' + application { - mainClassName = 'btools.server.BRouter' + mainClass.set('btools.server.BRouter') jar { manifest { - attributes "Main-Class": "$mainClassName" + attributes "Main-Class": getMainClass() } } } dependencies { - implementation('junit:junit:4.13') + testImplementation 'junit:junit:4.13.1' + implementation project(':brouter-util') implementation project(':brouter-core') implementation project(':brouter-mapaccess') + } diff --git a/brouter-server/src/test/java/btools/server/IntegrityCheckTest.java b/brouter-server/src/test/java/btools/server/IntegrityCheckTest.java index 5637a9f..19e9237 100644 --- a/brouter-server/src/test/java/btools/server/IntegrityCheckTest.java +++ b/brouter-server/src/test/java/btools/server/IntegrityCheckTest.java @@ -20,7 +20,7 @@ public class IntegrityCheckTest File resultfile = new File( resulturl.getFile() ); workingDir = resultfile.getParentFile(); - File segmentDir = new File( workingDir, "/../../../brouter-map-creator/target/test-classes/tmp/segments" ); + File segmentDir = new File( workingDir, "/../../../../brouter-map-creator/build/resources/test/tmp/segments" ); File[] files = segmentDir.listFiles(); for ( File f : files ) diff --git a/brouter-server/src/test/java/btools/server/RouterTest.java b/brouter-server/src/test/java/btools/server/RouterTest.java index 3b4612e..e272770 100644 --- a/brouter-server/src/test/java/btools/server/RouterTest.java +++ b/brouter-server/src/test/java/btools/server/RouterTest.java @@ -61,13 +61,13 @@ public class RouterTest wplist.add( n ); RoutingContext rctx = new RoutingContext(); - rctx.localFunction = wd + "/../../../misc/profiles2/trekking.brf"; + rctx.localFunction = wd + "/../../../../misc/profiles2/trekking.brf"; // c.setAlternativeIdx( 1 ); RoutingEngine re = new RoutingEngine( wd + "/" + trackname, wd + "/" + trackname, - wd + "/../../../brouter-map-creator/target/test-classes/tmp/segments", wplist, rctx ); + wd + "/../../../../brouter-map-creator/build/resources/test/tmp/segments", wplist, rctx ); re.doRun( 0 ); return re.getErrorMessage(); diff --git a/brouter-util/build.gradle b/brouter-util/build.gradle index 4b22331..3dc5565 100644 --- a/brouter-util/build.gradle +++ b/brouter-util/build.gradle @@ -3,5 +3,5 @@ plugins { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + testImplementation('junit:junit:4.13.1') } diff --git a/build.gradle b/build.gradle index a88f623..5315d26 100644 --- a/build.gradle +++ b/build.gradle @@ -3,12 +3,11 @@ buildscript { repositories { + mavenCentral() google() - jcenter() - } dependencies { - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:4.1.3' // NOTE: Do not place your application dependencies here; they belong @@ -18,9 +17,8 @@ buildscript { allprojects { repositories { + mavenCentral() google() - jcenter() - } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 782faa3..1d288b1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip