As I needed to implement "snap GPS location to road" function for an Android application I've modified Android example of https://github.com/graphhopper to suit my needs. It actually did what was expected, but now I'm quite confused about data format i should provide to users device.
Is it possible to provide pbf.osm files? What should I do to provide the user as small data chunks as possible?
Or is this a completely wrong approach to achieve "snap to road" to a native Android app (not web based)?
I'm not that familar with Graphhopper in detail, but please take into account that it's just an routing engine and thus tuned for that purpose.
What you are looking for is a very simple method of 'reverse geocoding' that just returns the clothest point on a road for a given geopos. This doesn't work on a (simplified) routing graph as routers does, but on a optimized structure that is just tuned for geospatial queries. Maybe there are existing offline maps frameworks that already implement 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've been trying to develop speed limit application & have tried many different approaches to get done .
I have used Overpass APIs & it did good but it did not have speed limit information for few of locations around Europe & also installed Velociraptor which uses OSM map & HERE Maps APIs still they failed to get data . Here is screenshot of Velociraptor app :
Yesterday I came across osmbonuspack & it looks promising as it allows us to choose from 3 best routing services available but Author of osmbonuspack told me that unfortunately, the 3 routing services are not returning speed limit information. Refer : Is it possible to get speed limit data using OSMBonusPack?
I have installed Waze application & it has speed limit data for locations around Europe which are not available from above options. So , anyone has a idea how they are getting information OR anyone knows which datasource they are using ?
Any suggestions would be appreciated.
I'm afraid Waze does not use another data source or at the very least not one unique data source that you could use. As a crowd-sourced application it relies on the information entered by map editors via the Waze Map Editor. Some editors might have used some open data sources available for their regions (if permitted by their local organisation), but it's far more likely they've used their local knowledge, Google Street View (Waze has a special license for that) or user reports sent in via the app.
As the map used by Waze is not open data, I'd highly advice against attempting to retrieve the speed data from their map. They have not exposed this information in an open API, which should be a strong indication that reuse of this data is not permitted.
OSM tagging is rich and flexible, but can be quite difficult to interpret.
Typically, max speed information is certainly there (the various routing services are based on it). The point is: how it's defined?
Have a close look here: http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Maxspeed
And you will discover that getting maxspeed tag is not enough...
Then, refining your Overpass queries, maybe you will be able to get it everywhere!
Other hint: look at OSRM source code (or ask them), to see how they get this information.
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 am developing an offline maps & navigation app for Android as my final year project. The application has to provide transit route planning similar to the way Google Transit does. Currently I am working on a small city as a prototype and efficiency is not an issue right now.
However I'm unaware of any off-the-shelf Java frameworks that would help me implement such a feature, nor am I aware of any algorithms to help me code my own.
Can anyone instruct me on where to start, either by pointing me to code examples of this, or at least routing theory pages to assist me in coding my own?
Theory & Algorithms:
If you haven't already read about it, the shortest path problem is mainly the challenge that most journey planning algorithms are dealing with. On the wiki page, read the "Algorithms" section for a list of possible solutions (Dijkstra's is probably the most popular). There are some algorithm variations specifically for public transport, such as RAPTOR.
Model & Journey Planner:
Depending on the scope of your work, it could be over the top to design a model and to implement the whole journey planner on your own.
I would suggest that you provide your data (stops, connections, times, ...) in the GTFS format (really easy, based on CSV files) and then use a journey planner such as OpenTripPlanner. It takes several planning factors into account and can import the GTFS data that you provide. There is also an Android implementation of OpenTripPlanner, but I'm not sure how advanced it is.
Alternative:
Other than GTFS/OpenTripPlanner, there is a widely used standard in Europe to model transport information, called Transmodel, and supporting planning engines like "JourneyWeb". Many local transport providers (including the one in my city) build their services on top of Transmodel. But I think that would be way harder to implement (plus I'm not sure about licenses and free/open implementations), so I'd stick to the above-mentioned solution.
I need a Map API for Android that can provide me with indexed nodes and indices that make up the road network. The main idea is to determine if two GPS devices are on the same road. Thank you in advance
A Map API by itself will not have that information. Anyway, you can get it from OpenStreetMap freely. You can download it from here.
I don't understand from your question if you intend on displaying the results on a map. If so, and you want a nice and free map API, I would suggest Leaflet. It's not as mature as the likes of OpenLayers but, as you've tagged this post with "android", Leaflet just kicks ass in the mobile department.
OpenStreetMap is definitely a good source of data for this kind of project. Unlike google maps, it gives developers access to the underlying vector data of a map (fully open). This allows interesting new use cases which simply are not possible with google maps, and something involving geometric calculations like this would definitely fit into that category. You either need OpenStreetMap or some other source of "vector" map data, and beyond OpenStreetMap this can be expensive.
Unfortunately that's not the full answer to your question. You still have a lot of work to do to use the data in the way you intend. You need to calculate the proximity of two points (GPS readings from two devices?) to nearby roads, and figure out which road the point lies closest to. It's the kind of powerful geo calculation you might do using a GIS package such as QGIS or a functions of a geo-aware database system PostGIS.
But that's not the answer to your question, because you need to do these calculations on device. I'm not aware of an off-the-shelf library to do this on android. I think you would have to roll your own.
But another challenge is to get the vector data onto the device in a suitable format in the first place, and this is the first thing to solve. You'd want the vector data either as a large download for a whole country, or perhaps a smaller area, perhaps with an on-the-fly download feature within this app. Whole countries are not infeasible when working with maps in vector form (ever tried the awesome MayDroyd app?), but require some compact formatting. Happily some of these problems are starting to be solved in open source off-the-shelf libraries. You could try to build on top of MapsForge for example.
So then you're back to the challenge of writing on-device code to poke around in this data and do the calculations you want to do. I suppose it could be rather good if projects like MapsForge included generic PostGIS style geo-functions to make this easier. Something to ask the mapsforge developers about perhaps.