3

为了学习,我们必须开发一个基于位置的安卓游戏。目前我们使用 OSMDroid 来显示地图。玩家必须收集一些资源(如木头、石头……)。这些资源当前以硬编码的 long/lat 存储在我们的后端,并将通过 setMarker 添加到当前地图上。为了在全球范围内提供这款游戏,我们希望根据“真实”世界动态设置资源。所以我们需要来自 OSM 的不同层(如森林、海洋等)来自动设置我们的资源,而无需询问我们的后端。在用谷歌搜索几个小时后,我发现 Overpass API 似乎可以帮助我实现这个功能。但我找不到在 Android 中使用 Overpass API 的任何教程。我尝试了一些东西,但我不明白...所以我需要你的帮助,

这是我当前的代码,但我认为这不正确..

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();

以下异常将被抛出InputStream inputStream = urlConnection.getInputStream();

W/System.err(3958): java.io.FileNotFoundException: http://overpass-api.de/api/interpreter W/System.err(3958):在 libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) W/System.err(3958):在 de.htw.berlin.games.based.location.gui。 MapActivity$test.doInBackground(MapActivity.java:536) W/System.err(3958): 在 de.htw.berlin.games.based.location.gui.MapActivity$test.doInBackground(MapActivity.java:1) W/ System.err(3958):在 android.os.AsyncTask$2.call(AsyncTask.java:287) W/System.err(3958):在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305 ) W/System.err(3958): 在 java.util.concurrent.FutureTask.run(FutureTask.java:137) W/System.err(3958): 在 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask. java:230) W/System.err(3958): 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) W/System.err(3958): 在 java.util.concurrent。ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) W/System.err(3958):在 java.lang.Thread.run(Thread.java:856)

感谢所有有用的回复:)

4

3 回答 3

4

http://overpass-api.de/api/interpreter由于 HTTP GET 调用返回400 Bad Request响应,因此引发了您遇到的此异常。

你想要做的是一个 POST 请求http://overpass-api.de/api/interpreter。传递给此 API的示例是:form-data

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>'

要了解 API 是如何工作的,您应该使用浏览器检查在我指出Run的示例中单击时对 API 进行的 HTTP 查询。

编辑

您可以找到很多类似的示例,这些示例展示了如何在 Android 中使用 HTTP 发布数据。您必须在使用的值对容器中添加和 XML 查询字符串作为data例如:

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.

于 2013-03-30T14:21:47.557 回答
4

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
于 2015-12-06T20:09:51.363 回答
0

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.

于 2022-01-08T12:08:36.843 回答