Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculating routes Offline in Android #4704

Closed
SrMatheus2000 opened this issue Apr 23, 2024 · 8 comments
Closed

Calculating routes Offline in Android #4704

SrMatheus2000 opened this issue Apr 23, 2024 · 8 comments
Labels
troubleshooting a request to help debug an issue with the software

Comments

@SrMatheus2000
Copy link

Hello,

I would like to compile Valhalla to add it to my android application so I`m able to calculate routes from point A to B totally offline.

Looking into some issues and documentation, it seems like this is possible. For my specific use case, can someone show me which module from Valhalla should I compile, and how would I approach compiling only it.

It would also be great if someone is able to show me which function does this route calculation, then later Ill try to write the JNI integration for it.

But right now I'm kind of stuck. I was able to compile Valhalla for Linux, but i don't know how to disable the unwanted modules or what are the unwanted modules in my case.

I saw some scripts in some issues of the past, related to android compiling, but they don't seem to work anymore, specially the compiling Protobuff and Boost parts. And am a bit of a noob with C++, so I don't know how to start approaching this problem.

Sorry for the ramble, but help would be very appreciated!

@kevinkreiser
Copy link
Member

some tips:

  • you need a linux build so that you can build the tileset that has a geographic region to serve your use case (i recommend building the world and then carving pieces out of it as needed)
  • you need a tileserver so that your android application can download the routing tile data the router needs to compute a route. eg. this part could be the part that carves chunks out depending on the users request
  • to build for android just the route finding stuff you can have a look here: https://github.com/valhalla/valhalla/blob/master/docs/docs/building.md#build-configuration-all-platforms for a client side use case i would turn off most everything, eg: tools, data tools, python bindings, services, tests, coverage, shared_libs (you want static libs), gdal. you will want to turn on http if you want to fetch tiles on the fly from an http tile server and you will want to turn on thread safe tile ref count if you want to use multithreaded tile fetching
  • there is currently no jni or objc bundled with the project (though i have been wanting to add it forever) however the c++ library comes with a bit called tyr::actor_t. when adding bindings for java i would target that specific api as its the top level api that lets you talk json to the library.
  • as far as building for android, i cant give tips on that as my knowledge is out of date. id love to have time to change that soon though but sadly google will have to help you out with this part until i (or someone else) can find the time to do it

@SrMatheus2000
Copy link
Author

Awesome, that helps a lot man, thanks for the tips!
One more thing, Do i need a tileset in build time? (maybe i mixed up the meanins, but the tileset and the map are the samething, right?)
My use case would be to get the maps at runtime, and they would be pbf maps with some custom data. Can i provide this maps to valhalla after it is already compiled?

@kevinkreiser
Copy link
Member

The tileset is the final map data that the router uses to calculate a route. To build a tileset you need to download some unprocessed raw data, eg. from geofabrik.de or one of the osm planet mirrors.

My use case would be to get the maps at runtime, and they would be pbf maps with some custom data.

you can do that but that means that you need to turn them into something routable (the tileset). this is a very expensive operation. you can do it on the client side (the bit of your code that wants to find routes) but it manes that the client has to have a lot more dependencies and needs to spend a lot of resources and time to make the data routable. a better approach, like i outlined above is to have the server build the tileset from the pbf once and then you can cut pieces of it (collections of tile files) to ship to your client at runtime.

anyway what you said is possible but its a lot more painful

@SrMatheus2000
Copy link
Author

ohh i think i got it, thats would be great, i think. because right now im rendering the map itselft using the mapsForge ".map" format anyway.. so in this way, i just need to send the tileset and the .map format to the client. instead of having to render the pbf map and do all this conversion of tileset all in the client. i think this sounds good.

Thank you very much

@kevinkreiser
Copy link
Member

oh i have no clue about mapsForge 😄 the only stuff im talking about has to do with routing. if you are using this for display as well then you'll need to keep doing whatever it is you are doing there.

@nilsnolde nilsnolde added the troubleshooting a request to help debug an issue with the software label Apr 25, 2024
@SrMatheus2000
Copy link
Author

Oh yeah, dont worry about it, if i can get valhalla working in my app and I'm able to send coordinates to it and receive the geojson. ill figure out a way to display it in mapsforge 😅

@SrMatheus2000
Copy link
Author

For Reference, i got the android build to complie, this is what i used:
To compile protobufs:

export NDK=~/android-ndk/android-ndk-r26d
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
export TARGET=x86_64-linux-android
export API=30

export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip

export LDFLAGS="-llog -fPIC"
export CXXFLAGS="-fPIC"

./configure --host $TARGET --disable-shared --with-pic
make -j$(nproc)

then to compile valhalla:

cmake -B build-android \
 -DCMAKE_SYSTEM_NAME=Android \
 -DCMAKE_ANDROID_NDK=~/android-ndk/android-ndk-r26d \
 -DCMAKE_SYSTEM_VERSION=21 \
 -DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a \
 -DCMAKE_C_COMPILER=~/android-ndk/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin/clang \
 -DCMAKE_CXX_COMPILER=~/android-ndk/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ \
 -DCMAKE_BUILD_TYPE=Release \
 -DENABLE_TOOLS=Off \
 -DENABLE_DATA_TOOLS=Off \
 -DENABLE_HTTP=Off \
 -DENABLE_PYTHON_BINDINGS=Off \
 -DENABLE_SERVICES=Off \
 -DENABLE_THREAD_SAFE_TILE_REF_COUNT=On \
 -DENABLE_CCACHE=Off \
 -DENABLE_BENCHMARKS=Off \
 -DENABLE_TESTS=Off \
 -DBUILD_SHARED_LIBS=On \
 -DENABLE_STATIC_LIBRARY_MODULES=On \
 -DENABLE_SINGLE_FILES_WERROR=Off \
 -DENABLE_ADDRESS_SANITIZER=Off \
 -DPREFER_SYSTEM_DEPS=Off \
 -DENABLE_GDAL=Off \
 -DBoost_INCLUDE_DIR=~/boost_1_77_0 \
 -DProtobuf_PROTOC_EXECUTABLE=~/protobuf/src/protoc \
 -DProtobuf_INCLUDE_DIR=~/protobuf/src \
 -DProtobuf_LIBRARY_RELEASE=~/protobuf/src/.libs

Dont know yet if it will work inside android or not, but it compiled without errors 😁

@SrMatheus2000
Copy link
Author

Unfortunately this approach ended up not working. The .so file that was build seems like it was just a symbolic link, and the file it was pointing to didn't exists. So I assume it actually didn't build. After that I've tried a lot o things. but now something is broken in my Linux and i cant even build protobuffs anymore. It seems like i broke everything 😅
But anyway, thanks a lot for your kind help @kevinkreiser

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
troubleshooting a request to help debug an issue with the software
Projects
None yet
Development

No branches or pull requests

3 participants