dsTny
dsTny

Reputation: 150

Overpass API Android Example?

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

Answers (3)

KerryKilian
KerryKilian

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

zsolt.kocsi
zsolt.kocsi

Reputation: 333

Check out https://github.com/zsoltk/overpasser. It's a Java library to ease working with the Overpass API.

  1. You don't have to write the QL string yourself
  2. It comes with a Retrofit adapter (so you can skip the networking part)
  3. It has an Android sample showing how to put them all together over a Google Maps to get you started in no time

Upvotes: 4

Halim Qarroum
Halim Qarroum

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

Related Questions