iOS port could be updated to GraphHopper version 1.0

Just fyi: there is some work going on in the currently outdated repo of the GraphHopper iOS port:

Is there any progress on this? Still cannot compile any of the ios projects on GitHub.

Did you try the pull request? If yes, can you be more specific what you did step-by-step and what problems you got (error message etc)

I followed the instructions at
git clone --recursive
cd graphhopper-ios
make class.list
make translate

running “make translate” produced the following error:

make: *** No rule to make target dependencies/hppc/com/carrotsearch/hppc/', needed by src/.translate_mark’. Stop.

I’m trying to compile graphhopper 1.0 for iOS (0.8.2 has some issues that will be hopefully fixed by this).
I used oflebbe’s graphhopper-ios as starting point but got the same error message concerning com/carrotsearch/hppc/

And there are a few things that confuse me:

  1. It seems like participates only in web target. Maybe it’s safe to remove it?
  2. GitHub - carrotsearch/hppc: High Performance Primitive Collections for Java doesn’t seem to have such class at all (I have checked releases down to 0.7.3), although here it was fetched from release 0.8.1
    Same goes for AbstractCharCollection, AbstractDoubleCollection e.t.c.
    Only was and remains part of com.carrotsearch/hppc since 0.7.0 at least.

I’m complete novice in java world so maybe I miss something there.
If @karussell could kindly provide some input on this matter this will help a lot.

I’ve managed to run iOS example app using ios_compatibility branch. I will create necessary instructions and PR’s after I do some more tests.
There are still two issues that need to be addressed:

  1. After translation from java to Obj-C one line seems to be broken.
    /graphhopper-ios/src/com/graphhopper/util/TranslationMap.m line 96 states:
    [trMap doImportWithJavaIoInputStream:[TranslationMap_class_() getResourceAsStream:JreStrcat("$$", locale, @".txt")]];
    and this produces error on localisations loading because [TranslationMap_class_() getResourceAsStream:JreStrcat("$$", locale, @".txt")] returns nil.
    The problem is that to get proper stream file name should start with “/”. So when I change line 96 to: [trMap doImportWithJavaIoInputStream:[TranslationMap_class_() getResourceAsStream:JreStrcat("$$$", @"/", locale, @".txt")]]; it works as expected.
    But this is not ideal as translated classes are not part of the repo and could be re-generated any time. I suppose this is either an error in original java code or some glitch from j2objc. I would be happy to hear any input about this. In worst case I will add this fix to instruction.

  2. Branch ios_compatibility doesn’t correlate to final 1.0 state. It seems to be branched around Because of this when I used pure 1.0 graphhopper to generate routing files they were not fully compatible. So will try to merge graphopper 1.0 to ios_compatibility branch but with my limited knowledge of java this could easily fail. It would be awesome if @karussell would be so kind to do this.

Any news here? I can’t compile the branches. I need a GraphHopper build which is working for Xcode 12, maybe Xcode 13.

Hi I looked at ios port several weeks ago as well.
I discovered “org.codehaus.janino” to be a dependency of graphhopper core now. Dynamically generating code on runtime is very difficult on ios (since it is AFAIK against the app store guidelines). I have no idea how to work around this issue.

Ah, yes. This is an interesting challenge. Janino creates Java code and we only need this feature if dynamic changes per request are required but on mobile we probably only need server side support?

And for server side custom weightings we could create Java code via Janino while the CH preparation (or import) or Objective-C conversion (there is a debug feature which emits the code - see CustomModelParser.JANINO_DEBUG and SCRIPT_FILE_DIR).

So could it make sense to replace this dependency with some static code like we replaced MMAPDataAccess?

AFAIK we have the option for mmap() data access even for the server case, so the functionality and dependency is always compiled in.
If there is a way to have Janino a build time dependency only, it might be a way out of the situation.

My naive guess is nobody will do CH preparation on mobile. Is there maybe already a way to seperate the preparation (graph generating) phase dependencies from the searching (consuming the graph) code and dependencies ? This would tremendously help for mobile (both android and ios) I presume.

You can consider this work in progress, but with no definitive timeline. I want to organize GraphHopper roughly into three segments, namely ‘import’, ‘storage’ and ‘routing’ (and maybe a forth one for the web layer / server part). Naturally this would also make it easier to limit certain dependencies to, e.g., ‘import’ only.

However, I’m not sure if this will directly help in getting rid or replacing Janino for iOS. Also why do you think CH preparation is an issue for you?

Just to explain this a bit more detailed: We use Janino to dynamically create Java code (Implementations of the Weighting interface) from custom models written in YAML syntax. We do this for ‘server-side’ custom models that are written in, e.g., config.yml, and that are used during the data import / preprocessing phase. But we also use it for custom models created at runtime to allow flexible routing where users can query the server’s /route endpoint with their custom models.

If Janino is no option for iOS we would have to make it possible to exclude the entire custom models feature.

1 Like

What I meant was that if you replace the class CustomModelParser with some special Java code that e.g. loads some custom Weighting classes statically (created by janino while the import) and remove the ExpressionVisitor class then you do not need the janino dependency at all.

Do you mean something like this:

  1. (server-side) import OSM, parse custom models and create Weighting classes using Janino, run CH preparation

  2. move graph+CH files to mobile device

  3. (mobile) Run iOS GraphHopper without Janino dependency using graph+CH files created on server side?

You would still need the Weighting created by Janino to actually use CH on mobile (because the CH files do not include weights for base graph edges), so even if you did not use Janino, you would still need to somehow add the created Weighting to the bundle. This is probably not possible for the same reasons it is not possible to use Janino in the first place? The only way around this I can imagine right now is to store all CH weights for the entire graph. Otherwise the CH files won’t be usable without the Weighting.

The idea would be to create a special binary (i.e. the GraphHopper classes plus the special Weighting classes compiled to Objective-C) that belongs to only this graph with the CH preparations.

1 Like

Ok sure this would work, but then all the weightings must be known when the binary is created. It would not be possible to create a mobile app and later provide CH files for different weightings that are not included already.

Yes, then weightings must be known and a change there always requires an binary update.

1 Like

Thanks @karussell , exactly my thoughts.

Or if manual intervention in this process is acceptable you could introduce java parameters to e.g. change the multiply_by value. Then no binary update is required if only some previously known parameters change in this “dynamic” custom weighting :wink:

(but you would need to ensure that they are always in sync via reading e.g. the storable properties)

IIRC The Java to ObjC process is able to override Methods by different implementations. However this is really complex here. Would be much easier if one would not need to deal with this package at all .
And I have to admit that Focus did change from iOS to Android , so I am not very likely to pick that up in near future again.