我想通过地理编码获取建筑物的坐标。目前我使用GeoCoder类为android从所选地址获取坐标,但这些并不对应于建筑物的边缘。 OSM包含每个建筑物的这些信息,但我不知道如何使用GeoCoder类获取这些信息。是否有可能使用OSM与Android的地理编码器类来获取此信息?
答案 0 :(得分:4)
这可能有点复杂。首先,OSM没有建筑物的每个地址。有时建筑物包含多个地址,或者地址可能属于多个建筑物。
但作为第一步,您可以使用Nominatim进行地理编码,以获取特定地址的坐标。然后将这些坐标传递给Overpass API并搜索附近的建筑物。
示例:
我们正在寻找地址 Franzweg 4,Dresden 的建筑物。 Nominatim查询看起来像这样(假设我们想要JSON输出):
http://nominatim.openstreetmap.org/search.php?q=Franzweg+4%2C+Dresden&addressdetails=1&format=json
它返回完全匹配,因为该地址存在于OSM的数据库中。您可以通过查看地址详细信息看到* house_number *和 road 匹配。我们甚至会得到一个相应的way with ID 94892819,其中包含building标记,并在querying the API for the way ID时包含建筑物轮廓的坐标(请参阅API documentation)。
但如前所述,并非每个地址都属于建筑物。例如,当searching for Huttenstraße14,德累斯顿时,我们也会得到一个确切的结果,但返回的方式with ID 240398228属于区域。该区域包含一个建筑物,因此属于该地址。 Nominatim还返回一个边界框,在本例中为 51.0508041381836,51.0514030456543,13.7778491973877,13.7796478271484 。我们可以用它来检索该区域内的对象。如果您没有OSM数据库的本地副本,可以使用Overpass API并使用以下查询:
<osm-script output="json">
<query type="way">
<has-kv k="building"/>
<bbox-query e="13.7796478271484" n="51.0514030456543" s="51.0508041381836" w="13.7778491973877"/>
</query>
<print mode="body"/>
<recurse type="down"/>
<print mode="skeleton"/>
</osm-script>
此查询returns所有方式在给定的边界框中包含 buildings 标记。您可以使用overpass turbo来查看结果。如您所见,边界框包含多个建筑物,但只有一个建筑物位于该区域内。所以你必须通过每个建筑物的坐标来看看哪一个适合。请记住,一个地址可以属于多个建筑物,因此可以有多个匹配。
然后还有第三种情况,其中地址是单node。例如,Striesener Straße 38b的结果会返回node with ID 1615986605。这里节点实际上是构建方式的成员,因此很容易确定相应的构建。但情况并非总是如此,您可能需要运行另一个Overpass API查询来确定附近的建筑物,并再次查看最适合的建筑物。