Reputation: 150
for study we have to develop an Android game which is location based. Currently we use OSMDroid to show the map. There are resources (like wood, stone, ...) which the player has to collect. These resources are currently stored in our backend with hardcoded long/lat and will be added with setMarker onto the current map. To provide this game globally, we want to set the resources dynamically based on the "real" world. So we need different layers from OSM (like forest, sea, ..) to set our resources automatically without asking our backend. After some hours searching with google I found out that the Overpass API seems to help me implementing this functionality. But I can't find any tutorial for using Overpass API in Android. I tried some things but I don't get it... So I need your help, please give me an example or explanation how to implement this :/
This is my current code, but I don't think that this is correct..
URL url = new URL("http://overpass-api.de/api/interpreter");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
inputStream.close();
Following exception will be thrown at InputStream inputStream = urlConnection.getInputStream();
:
W/System.err(3958): java.io.FileNotFoundException: http://overpass-api.de/api/interpreter W/System.err(3958): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) W/System.err(3958): at de.htw.berlin.games.based.location.gui.MapActivity$test.doInBackground(MapActivity.java:536) W/System.err(3958): at de.htw.berlin.games.based.location.gui.MapActivity$test.doInBackground(MapActivity.java:1) W/System.err(3958): at android.os.AsyncTask$2.call(AsyncTask.java:287) W/System.err(3958): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) W/System.err(3958): at java.util.concurrent.FutureTask.run(FutureTask.java:137) W/System.err(3958): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) W/System.err(3958): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) W/System.err(3958): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) W/System.err(3958): at java.lang.Thread.run(Thread.java:856)
Thanks for all helpful replies :)
Upvotes: 3
Views: 5581
Reputation: 95
For anyone in future who needs to find a solution with overpass api, here is what I did very often: Overpass API can be addressed with a GET-Request. A GET-Request comes with a HTTP-protocoll and can be used in (I think) every programming language. You have to make a GET-request to the overpass-interpreter with all the queries in the url. In Android it would look like this:
String urlOverpass = "https://overpass-api.de/api/interpreter?data=[out:json][timeout:100];(node[shop=supermarket](52.402957,13.337429,52.420730,13.379530);way[shop=supermarket](52.402957,13.337429,52.420730,13.379530););out%20body;%3E;out%20skel%20qt;";
/* here you speak to the interpreter and you can insert whatever query you need. As an example look at overpass-turbo.eu*/
StringRequest request = new StringRequest(urlOverpass, new Response.Listener<String>() {
@Override
public void onResponse(String string) {
/* Here you can do whatever you like with the data which comes from the interpreter. The "string" is the response.*/
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
/* Here you can explain what happens when an error is coming from the interpreter*/
}
});
RequestQueue rQueue = Volley.newRequestQueue(MainActivity.this);
rQueue.add(request);
Dont forget to implement the library: implementation 'com.android.volley:volley:1.1.1'
But there are multiple possibilities to fetch data from an api with a GET-request.
Upvotes: 0
Reputation: 333
Check out https://github.com/zsoltk/overpasser. It's a Java library to ease working with the Overpass API.
Upvotes: 4
Reputation: 14103
This exception you're getting is thrown because an HTTP GET call to http://overpass-api.de/api/interpreter
returns a 400 Bad Request
response.
What you want to do is a POST request to http://overpass-api.de/api/interpreter
. An example of form-data
to pass to this API is :
data='<?xml version="1.0" encoding="UTF-8"?><osm-script><!--
This is an example Overpass query.
Try it out by pressing the Run button above!
You can find more examples with the Load tool.
-->
<query type="node">
<has-kv k="amenity" v="drinking_water"/>
<bbox-query s="41.88659196260802" w="12.488558292388916" n="41.89248629819397" e="12.51119613647461"/><!--this is auto-completed with the
current map view coordinates.-->
</query>
<print/></osm-script>'
To find out how the API is working you should check, using your browser, what HTTP query is made to the API when clicking on Run
in the example I pointed out.
EDIT
You can find plenty of examples like this one that shows how to post data using HTTP in Android. You'll have to add data
as a key and the XML query string as a value in the used value pair container, such as :
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("data", _The_XML_Query_String_));
Stick to the linked example for the rest and you hould be fine.
Upvotes: 4