【发布时间】:2014-01-20 18:57:32
【问题描述】:
从标题中解释问题。我想获取信息,例如用户是否在城市、森林中,他离河流/湖泊/海洋有多远(甚至一般来说他离水有多远)。它不必非常精确。
如果标准 SDK 无法实现,是否有任何其他库可以帮助我获取有关当前位置的此类信息?
【问题讨论】:
从标题中解释问题。我想获取信息,例如用户是否在城市、森林中,他离河流/湖泊/海洋有多远(甚至一般来说他离水有多远)。它不必非常精确。
如果标准 SDK 无法实现,是否有任何其他库可以帮助我获取有关当前位置的此类信息?
【问题讨论】:
1) 检查水
您可以使用诸如创建ReverseGeocodeQuery 并检查返回的第一个条目中是否填写国家/地区字段以及与最近结果的距离等技术来伪造这一点,但是这在人口稀少的地区也会失败。另一种方法是使用places API 并检查underwater 类别中最近的地点。
更好的技术是基于来自Map Tile API 的地图图块的像素分析来构建您自己的二进制黑白小地图。 Map Tile API 基于归一化墨卡托投影,这意味着整个地球在缩放 0 时是一个正方形,在缩放 1 时是 2x2,在缩放 2 时是 4x4,等等。因此,如果您检查图块左上角的颜色(和它的蓝色)您可以确定在下一个缩放级别下它下方的 4 个像素也将是蓝色的。这可以用来定义一个“水”瓦:
您的最终地图将如下所示:
小地图中的白色像素 = 放大 10 倍时地图图块右上角的蓝色像素。每个图块宽 13 公里。使用更大的地图和更高的缩放级别以获得更高的准确性。将其存储在设备上。
现在您需要做的就是检查输入纬度/经度处表示地图图块的像素是黑色还是白色。显然,这里的每个像素都可以编码为一个单独的位,您可以使用位掩码,这样就不需要占用太多内存。
您需要分析的图块如下:
2) 检查市区
再次,您可以使用诸如制作ReverseGeocodeQuery 并检查返回的第一个条目中是否填写城市字段以及与最近的距离等技术来伪造这一点
观点。问题是你认为什么是城市地区?也许这里的正确技术是查看道路密度 - 以芝加哥的这张瓷砖为例:
很明显,瓷砖上半部的平均颜色将比下半部“更灰”。您可以分析更大区域的平均像素来制作位掩码。
最终结果将如下所示:
小地图中的白色像素 = 市区。此图像的投影是错误的,但您会明白的。
3) 检查森林。
这可能是对普通底图图块的“绿色像素”检查: http://1.base.maps.cit.api.here.com/maptile/2.1/xbasetile/newest/normal.day//zoom/column/row/128/png8?app_id=AppID&app_code=AppCode
您需要小心,这片森林在不同的缩放级别上似乎并没有一致地呈现。
您可以使用以下计算从您的longitude 和latitiude 中找到xTile 和yTile 值。显然zoom会根据你小地图的大小来固定
latRad = lat * Math.PI / 180;
n = Math.pow(2, z);
xTile = n * ((lon + 180) / 360);
yTile = n * (1-(Math.log(Math.tan(latRad) + 1/Math.cos(latRad)) /
Math.PI)) / 2;
【讨论】: