【问题标题】:Overpass API Android Example?Overpass API Android 示例?
【发布时间】:2013-03-30 14:06:08
【问题描述】:

为了研究,我们必须开发一款基于位置的 Android 游戏。目前我们使用 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)

感谢所有有用的回复:)

【问题讨论】:

    标签: android osmdroid openstreetmap


    【解决方案1】:

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

    您要做的是对http://overpass-api.de/api/interpreter 的POST 请求。 form-dataAn example 传递给此 API 是:

    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 的工作原理,您应该使用浏览器检查在单击 example I pointed out 中的 Run 时对 API 进行的 HTTP 查询。

    编辑

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

    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
    nameValuePairs.add(new BasicNameValuePair("data", _The_XML_Query_String_));
    

    其余的请坚持linked example,您应该会没事的。

    【讨论】:

    • 您好,感谢您的回答。请问你能给我一个在Android中如何使用Overpass API的例子吗?提前致谢。
    【解决方案2】:

    查看https://github.com/zsoltk/overpasser。这是一个便于使用 Overpass API 的 Java 库。

    1. 您不必自己编写 QL 字符串
    2. 它带有一个改装适配器(因此您可以跳过网络部分)
    3. 它有一个 Android 示例,展示了如何通过 Google 地图将它们全部放在一起,让您立即开始使用

    【讨论】:

      【解决方案3】:

      对于未来需要通过 overpass api 找到解决方案的任何人,这是我经常做的事情:Overpass API 可以通过 GET-Request 来解决。 GET-Request 带有 HTTP-protocoll,可以在(我认为)每种编程语言中使用。您必须使用 url 中的所有查询向 overpass-interpreter 发出 GET 请求。在 Android 中它看起来像这样:

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

      别忘了实现这个库:implementation 'com.android.volley:volley:1.1.1' 但是有多种可能性可以通过 GET 请求从 api 获取数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多