I am a bit stuck with an idea of offline maps in android application.
I want to use Open Street Maps. But how can I redesign their styles and then use in my project? By the way, the resource, I am looking for, has to be free..
Are there any good tutorials about this? I am new to this, so would be thankful for any helpful information.
Here are the basics:
Raster tiles are awful. To my mind, this approach of mobile mapping is very old-fashioned and has no advantages (unless your plan is to make a very bad-looking application).
The other thing is vector tiles. All the data is saved in much more efficient way and can be displayed very beautifully.
And the solutions (nominees) are:
Mapsforge - thanks to #dkiselev
OSMAnd app - thanks to #dkiselev
Mapbox GL (the android version has no releases now, but they are working really hard on it). If you really like mapbox, you can think about
Mapbox Android SDK, which uses raster tiles, but I believe, that
switching to Mapbox GL will not be that hard, when the GL lib will be released.
AirBNB AirMapView - open source and has release version
Urban Labs Sputnik Demo - also interesting solution, but I didn't use it.
Mapzen Open - open source android app, that uses all the best from everywhere. - winner!
And by the way, mapbox gl actully allows rendering your own mapping data (from your own provider). There is a closed issue on github about that, opened by me couple of days ago, and very good answer by one of the project developers.
If you don't care about using your own data source and want to rapidly implement custom (not google/apple) maps into your project - there are dozens of solutions for you as well. You could think of Mapbox, Scobbler, GetYourMap or, again, just google it to find more. There is actually a great article on OSM website about most popular libraries and apps for android ever developed.
Finally, I wish you good luck with your mapping project. And never forget:
if you can't find something doesn't mean it really doesn't exist
- probably you've just been searching not enough.
Offline raster tiles cache
If you need to show your map offline with custom style, you may use any kind of OSM renders. http://wiki.openstreetmap.org/wiki/Rendering
For the case of several cities, I would recommend you http://wiki.openstreetmap.org/wiki/AlaCarte or http://wiki.openstreetmap.org/wiki/TileMill
Create your own style, and export map tiles to sqlite db archive.
After that, you will need to create your own TileProvider for OSMDroid library. This answer could help you How to use MOBAC created OSMDroid SQLite tile source file offline?
Offline vector tiles.
Getyourmap
If you need more than just rendering with custom style, you may use:
https://getyourmap.com/ it's OSM vector renderer. But there would be some problems with accessing raw data to create routing and searching.
OSMAnd
And maybe the hardest but the best way, is to use OSMAnd. It's open-source, there are lots of capabilities, but it's an application, not a component or library.
So if you want to create a stand alone app. you will need to cut off features which you don't need.
Mapsforge
https://github.com/saintbyte/mapsforge It's opensource so it would be possible to add routing and searching. Style, as I know may be customized, but I haven't try it.
Related
I wish to make an android app that leverages OSM services and runs an algorithm of my choice to find the route, say A* or some heuristic on Dijkstra.
The Routing wiki page of OSM has some good pointers but it does not give any insight about how to go about implementing your own algorithm in the app.
This response is overview which might help you to orient better in the landscape and find a way to approach the problem. Your question is too broad to give an exact simple answer but I do understand why are you asking such question.
You can use Osmdroid library to display the route you have on Android.
Keep in mind that the core feature of Osmdroid is to display the map tiles. Map tiles are just bitmaps so you need either an online source of tiles or an offline one. How to do that is covered in the documentation and partly in other questions on SO. It's a too big topic to explain it here in detail. Just to make it clear: .osm file with raw OpenstreetMap data cannot be directly rendered by Osmdroid. Map tiles are usually rendered from that data in quite complex way and not on the fly.
Another very important feature in Osmdroid library is the ability to display so called Overlays. E.g. Markers, polygons etc. You may use those to draw your route on the map and other features you may wish to display. This is again covered in the documentation and too big to go in details here.
There is a support for routing for Osmdroid (AFAIK in Osmbonuspack) but that's about using some 3rd party service to get your routing data and displaying that. According to your comment you want to implement your own algorithm and therefore this would be no use to you.
So the last part is how to integrate your algorithm into that. That's not a simple question with a simple answer. You'll need to do almost everything on your own, starting with getting the data you need to run the algorithm from the OpenstreetMap database (.osm file). I don't think there's an API which would provide you reasonable way to access the data in a form suitable for route computation. The approach I would choose is to develop some kind of preprocessing which would take either .osm file or a database with the data an produce my own structure representing the graph for navigation. I would than include this graph in my application and run my algorithm on that data. The output of my algorithm would be the route: a list of coordinates which I would use to draw the polyline.
If the area you need to cover is small enough, you may start with including the .osm file in your project and running the algorithm in the same was as you do now. Maybe it's going to be good enough for your situation.
One interesting project to look at to find inspiration is Graphopper - they have build exactly what I said above and they use it to provide a library for Android/iOs and a web API. But the core is the same - pre-process OSM data into graph data and run the algorithm on that. Since you wish to implement the algorithm on your own this library will not help you (unless you fork the project and modify it) but it might be a valuable learning resource.
I spent several hours looking for simple solution and still haven't found one.
MapBox style editor uses this simple feature. That you can hover and click over map, and it shows small popup stating all terrain classes you enabled in your map.
Question, how to do it in Android version of MapBox given I have installed my style. Now I want click on any place in the map and get the same popup stating, for example, that this is building, woods, background here. Or other place would satte, that this is major road.
This IS doable as MapBox studio itself shows. i can't believe it uses some API not available for anyone, as this is one API no map provider gives, while still able correctly draw terrain. What so complex to add this API?
And NO I am not interested in address. I am interested exactly on terrain, for simple task - distinguiosh water from non-water, road from non-road, building, from non-building, don't care where it is by address, so reverse geolocation does not work. Or simpler - I need SIMPLER geolocation, than address.
Your questions kind of confusing but I'll try and help. If I'm reading correctly, you are trying to create an Android app that uses an API similar to Mapbox Studio that allows the user to select/distinguish the difference between objects on the map such as buildings, water, forest, etc.
If this is the case, then first you must understand that Mapbox Studio is using OpenStreetMap data to distinguish between objects. These objects are stored in a database with tags. It's tough to explain so i'll just leave a brief reading wiki page that might help.
To my knowledge, there isn't any API's specific to Android that will give you the kind of information you're looking for. However, if I was in your dilemma I'd take a look at the Overpass API as it's a complex query tool that allows you to send coordinates to it and it will return all the tags (such as building or water) at that location within a JSON object. From there you can parse and use the data in your app. It is very powerful so I suggest reading up on how to use it and test using a website called Overpass Turbo, that's if you decide to use it.
Nevertheless, I hope this helps and I understood your question correctly.
I want to use Mapbox GL in my Android application. This service is going to be released soon and I have a tricky question about using the renderer.
I like the renderer itself, but I really want to use my own maps data in the application (not the data, offered by Mapbox and which is paid). For instance, I want to parse OpenStreetMaps data on my own, customise it somehow and then put inside of a renderer to show it in my application.
And now the question: is it possible to use my own maps data while using Mapbox GL? Or it can be only used with Mapbox data?
Thank you in advance for any help. Maybe you know any other well-done solutions for this problem? The thing is, that I want to have vector tiles, not the raster ones. And this project is planned to be developed for iOS later..
You can use MapBox open-source SDK with your own tiles. The Mapbox Native renderer for Android, iOS or Node.JS can be used directly with tiles hosted outside of MapBox.com platform.
See the sample mobile app "OSM2VectorTiles" loading the vector tiles from a custom server or locally from a embedded MBTiles.
Android: https://play.google.com/store/apps/details?id=com.klokantech.osm2vectortiles
iOS: https://itunes.apple.com/us/app/osm2vectortiles/id1089255502
The trick is to point the style attribute in the API to your own JSON style file - which requests the vector tiles from your own server. An example:
See https://gist.github.com/klokan/3eee87899644f5d82b3946bf0cd1e176
See project http://www.openmaptiles.org/, where you can download ready to use vector tiles made from OpenStreetMap - or check the documentation of this project on how to generate your own customised vector tiles.
Hosting of the vector tiles itself is described at https://openmaptiles.org/docs/ or https://gis.stackexchange.com/questions/125037/self-hosting-mapbox-vector-tiles
You may need to host somewhere the assets (font glyphs + sprites) and the JSON style itself - or embed these directly into your mobile app.
If you want to rasterize the vector tiles with the same JSON style on a server - for a web-application compatible with old web clients (Leaflet, ...) or for static maps or print output with the same look&feel as you mobile app maps, you can check https://github.com/klokantech/tileserver-gl
You can use your own tiles. I tried 2 things. Generating my own Mapzen vector tiles (they use same format as Mapbox) And you can also use them for free. Here is their layer descriptions. This is quite work intensive. You need to have postgresql and load whole OSM PBF export into the database, then you run python server which requests data from this database and renders vector tiles. I think it is meant to render all the tiles in queue since it took couple of seconds per page to render visible tiles. Most of the time was spend in python after DB server was queried.
It's advantage is that you get nice tiles back. It has basically everything you need, but is much harder to customize. For example if you want to add specific style to cycle ways. You need to go deep into the code and change couple of query templates and a lot of other things.
Then I tried Tilemaker. This is just C++ program which reads OSM PBF dumps and lua config script (where you specify what tags to send into tile) and spits out mapbox tiles. It's advantage is that it is much easier to set up and customize and that all tiles are rendered at once. But it is harder to create nice tiles. (AKA load all the different highway tags are roads just of different kind. It is up to you to specify that but this already works in previously mentioned Mapzen and also Mapbox).
For example kind in Mapzen roads layer In mapzen this is already taken care of but in tilemaker it is up to you to write all the conditionals that get road type from different OSM tags into a layer. And it gets more complicated in landuse tags since kind is a:
combination of the landuse, leisure, natural, highway, aeroway, and amenity OSM tags, or urban area and park or protected land for Natural Earth areas.
Of course you can have completely different tags but it is nice to have one which tells you what landuse you are looking at.
You ned to know that Mapbox, mapzen your custom mapbox tiles all use same format, but each will have different tags. So the style you create for one probably won't work for the other.
For creating styles you can use Mapbox Studio (but is probably useless since it is in public beta currently and I'm not sure if you can specify own tiles there).
I used Mapbox codeflow, which is basically nodejs server with gulp script that reloads site with a map when style file changes. It also supports writing styles in toml, JSON5 and yml in addition to JSON. It also shows errors kinda nicely. (only line numbers are missing) Currently it support version 7 of styles but 8 is currently out. For getting line numbers of errors I used Mapbox GL style spec which can also update style to the new version.
You can also try Glug which is a different style language which compiles to Mapbox GL style. It is a little more compact.
For using tiles you can also create mbtiles with mb-util and use them.
If you have a running Tileserver GL, it is as easy as changing the following line from an example app from mapbox:
mapboxMap.setStyle(Style.MAPBOX_STREETS) {
// Map is set up and the style has loaded. Now you can add data or make other map adjustments.
}
to
mapboxMap.setStyle(Style.Builder().fromUri("https://maps.somedomain.com/styles/awesome_style/style.json")) {}
I have been messing around for a while with osmdroid and osm bonus pack(amazing libs!), and have been pondering on the idea of offline routing and turn by turn navigation, now, I haven't tried anything yet, but something sounds very promising in throwing graphhopper in on the mix:
The official Wiki guide is as following:
Download a raw map file(.osm, .osm.pbf, etc.).
Run ./graphhopper.sh import map_file
Now, this is designed to work with MapsForge, and I haven't had the chance to check out the resulting .ghz file, containing the routing data for the map, BUT my question is this, could it be possible to use this routing data to build a PathOverlay object coming in OSM Bonus Pack to actually draw routes of some kind?
I wonder if someone already tried something of this sort and has something to say about it, any help appreciated.
Using Mapsforge in osmdroid: holy grail, never-ending story...
You can have a look at this (long) thread: https://groups.google.com/forum/#!topic/osmdroid/gSieR9BF_z0
There is also this working experiment: http://www.salidasoftware.com/how-to-render-mapsforge-tiles-in-osmdroid/
Now, if you really NEED offline routing, your options are:
You leave osmdroid/OSMBonusPack and move to Graphhopper/Mapsforge, as suggested by Karussell => you will find docs on Graphhopper web site.
Or you can have a look at OsmAnd. This is an app, not a lib. It has its own vector-based maps format (and toolset) and provides offline display and offline routing.
Or you can try to reach the holy grail, and merge Mapsforge, osmdroid, Graphhopper, and OSMBonusPack...
The holy grail is possible, you can use osmdroid with vector maps and yes, GraphHopper works on Android, but be ready for OOM on low-end devices - GraphHopper requires a lot of memory.
My sample project should be a good point to start.
I would like to develop or use an existing platform that will allow me to view custom vector data and use it as a map on mobile phones such as Android/IPhone (Maybe even WP7).
I'm hoping that there's already a good infrastructure for what I need so I would not need to develop a whole infrastructure by myself.
In Conclusion -
Is there any existing platform that may answer my needs?
If not, how would you guys suggest I should begin? How should I save my vector data? How could I read it? Should I view it with a graphics engine like OpenGL? Is there any chance this solution could be cross-platform?
I know that it's possible since it was already done with apps like Waze. And it works the same on iOS and Android.
Thanks!
After much research I found a solution that fits most of my needs.
At the moment I decided to go on Android only so I'm using AndEngine (In the future I guess it would be pure OpenGL).
AndEngine can read .svg files and turn them into PNGs at runtime, and also has a built in support for ZoomCamera which allows me to pan and zoom the map very easily.
I'm converting the SVG to PNG because apparently mobile devices do not have a very good anti-aliasing support, and rendering curved paths can also be a problem.