验证Google地图中的某个点是Land还是Water

Obm*_*nen 100 javascript google-maps google-maps-api-3

..然后谷歌地图"划分水域的水"

嗯,不是在圣经的意义上,但..

我想知道我有什么选择来验证[Lat,Lon]的点是土地还是水.

谷歌地图显然有这些数据(水体是蓝色的) - 但是我可以使用API​​中的某些东西吗?如果没有 - 他们是不是因为他们没有想到它而服务它?还是因为它太复杂了?

我没有找到任何关于这个问题的信息 - 除了一些类似的问题(比如寻找地形类型或海拔 - 但这不是我需要的).

那有分离的层吗?一个选项?命令?或者我应该手动去做?

我能想到如何处理这个问题的唯一方法(我是否需要手动执行)是检查每个服务的磁贴的确切点 - 然后检查该Google地图色调的RGB值.这只是在理论上 - 因为在实践中 - 我不知道如何实现这一点,第一个障碍是我不知道如何将瓷砖上的像素位置转换为[LatLon]点,例如

现成的解决方案会更容易.

请注意,我不需要世界上所有的水(例如 - 我不关心溪流,小池塘,大多数河流或邻居的游泳池.我需要一个人可以在没有浮动车辆的情况下冒险的地方)

编辑我

阅读评论后:提升方法不可靠,海平面下面有太多地方(你可以在这里查看 "最深"10的列表http://geology.com/below-sea-level/)海平面(湖泊)上面有太多内陆水体.反向地理定位方法不可靠,因为它会多次返回地理政治实体,如城市或州 - 或ZERO.在问这个问题之前我已经研究了那些伪解决方案 - 但他们都没有回答过这个问题 - 这些方法充其量只是"猜测".

Eng*_*eer 54

这些是两种不同的方式,您可以尝试:

  • 您可以使用Google地图反向地理编码.在结果集中,您可以通过检查确定它是否为水types.在水域的情况下类型是natural_feature.有关详情,请访问此链接http://code.google.com/apis/maps/documentation/geocoding/#Types.

    此外,您还需要检查要素的名称(如果它们包含)Sea, Lake, Ocean以及与水相关的其他一些单词以获得更高的准确性.例如沙漠也是natural_features.

    Prons - 所有检测过程都将在客户端的机器上完成.无需创建自己的服务器端服务.

    缺点 - 非常不准确,你在水域获得"无"的可能性非常高.

  • 您可以使用Google静态地图按像素检测水域/土地.但为此您需要创建http服务.

    这些是您的服务必须执行的步骤:

    1. 接收latitude,longitudecurrent zoom从客户端.
    2. http://maps.googleapis.com/maps/api/staticmap?center={纬度,经度}&zoom={当前缩放`}&size = 1x1&maptype = roadmap&sensor = false请求发送到Google静态地图服务.
    3. 检测1x1静态图像的像素颜色.
    4. 回复有关检测的信息.

    您无法在客户端检测像素的颜色.是的,您可以在客户端的计算机上加载静态图像并在canvas元素上绘制图像.但是你不能使用getImageDatacanvas的上下文来获取像素的颜色.这受跨域策略的限制.

    Prons - 高度准确的检测

    缺点 - 使用自己的服务器资源进行检测

  • 对于世界上大部分的水,反向地理编码将返回"零结果",请查看地理编码工具:http://gmaps-samples-v3.googlecode.com/svn/trunk/geocoder/v3-geocoder- tool.html并单击海洋中的某个位置. (3认同)
  • 以提议的方式使用静态地图可能会违反[条款](http://code.google.com/apis/maps/terms.html)(10.1.1(h)). (3认同)
  • 谢谢 - 我已经检查过了 - 我不知道这些类型正在转变海湖海洋和喜欢,就像你在编辑中指出的那样 - natural_feature也将是一座山,一座岛屿和一片沙漠......你能不能指向文档?另外 - 如何为没有地址的地方进行反向地理编码?那个属于地缘政治实体的湖泊怎么样呢?像一个城市或市政当局限制的湖泊(例如genevre)或仅仅是一个城市港口内的点.在我的试验中,我有这样的事情. (2认同)

TMS*_*TMS 19

目前任何Google服务似乎都无法做到这一点.

但还有其他服务,如Koordinates Vector JSON查询服务!您只需查询URL中的数据,即可获得JSON/XML响应.

请求示例:http://api.koordinates.com/api/vectorQuery.json?key = YOUR_GEODATA_KEY&layer = 1298&x = -159.9609375&y = 13.239945499286312&max_results = 3&radius = 10000&geometry = true&with_field_names = true

您必须注册并提供您的密钥和选定的图层编号.您可以搜索所有可用图层存储库.大多数图层只是区域性的,但您也可以找到全球图,例如世界海岸线:

在此输入图像描述

选择图层后,单击"服务"选项卡,即可获得示例请求URL.我相信你只需要注册,就是这样!

而现在最好的:

你可以上传你的图层!

它不能立即使用,嘿必须以某种方式处理它,但它应该工作!层存储库实际上看起来像人们根据需要上传它们.


reb*_*00x 8

这就是我使用它并且工作不是太糟糕...如果你有更多的cpu浪费,你可以通过添加像素来改进测试.

function isItWatter($lat,$lng) {

    $GMAPStaticUrl = "https://maps.googleapis.com/maps/api/staticmap?center=".$lat.",".$lng."&size=40x40&maptype=roadmap&sensor=false&zoom=12&key=YOURAPIKEY";  
    //echo $GMAPStaticUrl;
    $chuid = curl_init();
    curl_setopt($chuid, CURLOPT_URL, $GMAPStaticUrl);   
    curl_setopt($chuid, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($chuid, CURLOPT_SSL_VERIFYPEER, FALSE);
    $data = trim(curl_exec($chuid));
    curl_close($chuid);
    $image = imagecreatefromstring($data);

    // this is for debug to print the image
    ob_start();
    imagepng($image);
    $contents =  ob_get_contents();
    ob_end_clean();
    echo "<img src='data:image/png;base64,".base64_encode($contents)."' />";

    // here is the test : I only test 3 pixels ( enough to avoid rivers ... )
    $hexaColor = imagecolorat($image,0,0);
    $color_tran = imagecolorsforindex($image, $hexaColor);

    $hexaColor2 = imagecolorat($image,0,1);
    $color_tran2 = imagecolorsforindex($image, $hexaColor2);

    $hexaColor3 = imagecolorat($image,0,2);
    $color_tran3 = imagecolorsforindex($image, $hexaColor3);

    $red = $color_tran['red'] + $color_tran2['red'] + $color_tran3['red'];
    $green = $color_tran['green'] + $color_tran2['green'] + $color_tran3['green'];
    $blue = $color_tran['blue'] + $color_tran2['blue'] + $color_tran3['blue'];

    imagedestroy($image);
    var_dump($red,$green,$blue);
    //int(492) int(570) int(660) 
    if($red == 492 && $green == 570 && $blue == 660)
        return 1;
    else
        return 0;
}
Run Code Online (Sandbox Code Playgroud)


Sau*_*rav 7

查看这篇文章.它可以准确地检测水中是否有东西,而无需服务器.这是一个依赖谷歌地图中自定义样式功能的黑客.

http://tech.bellycard.com/blog/where-d-the-water-go-google-maps-water-pixel-detection-with-canvas/


Syl*_*inB 7

我觉得在本地进行这个查询更有意思,所以我可以更自觉:假设我想一次生成25000个随机陆地坐标,我宁愿避免调用可能代价高昂的外部API.下面是我在python中的镜头,使用TomSchober提到的python示例.基本上它会查找包含所有陆地坐标的预制350MB文件的坐标,如果坐标存在于那里,则会打印它们.

import ogr
from IPython import embed
import sys

drv = ogr.GetDriverByName('ESRI Shapefile') #We will load a shape file
ds_in = drv.Open("land_polygons.shp")    #Get the contents of the shape file
lyr_in = ds_in.GetLayer(0)    #Get the shape file's first layer

#Put the title of the field you are interested in here
idx_reg = lyr_in.GetLayerDefn().GetFieldIndex("P_Loc_Nm")

#If the latitude/longitude we're going to use is not in the projection
#of the shapefile, then we will get erroneous results.
#The following assumes that the latitude longitude is in WGS84
#This is identified by the number "4236", as in "EPSG:4326"
#We will create a transformation between this and the shapefile's
#project, whatever it may be
geo_ref = lyr_in.GetSpatialRef()
point_ref=ogr.osr.SpatialReference()
point_ref.ImportFromEPSG(4326)
ctran=ogr.osr.CoordinateTransformation(point_ref,geo_ref)

def check(lon, lat):
    #Transform incoming longitude/latitude to the shapefile's projection
    [lon,lat,z]=ctran.TransformPoint(lon,lat)

    #Create a point
    pt = ogr.Geometry(ogr.wkbPoint)
    pt.SetPoint_2D(0, lon, lat)

    #Set up a spatial filter such that the only features we see when we
    #loop through "lyr_in" are those which overlap the point defined above
    lyr_in.SetSpatialFilter(pt)

    #Loop through the overlapped features and display the field of interest
    for feat_in in lyr_in:
        # success!
        print lon, lat

check(-95,47)
Run Code Online (Sandbox Code Playgroud)

我尝试了十几个坐标,效果非常好.可以在这里下载"land_polygons.shp"文件,这是OpenStreetMaps的补充.(我自己使用了第一个WGS84下载链接,也许第二个工作也是如此)


stu*_*yam 7

有一个免费的Web API,可以解决这个问题,称为onwater.io.它不是内置于Google地图中的内容,但考虑到纬度和经度,它将通过get请求准确地返回true或false.

关于水的例子:https: //api.onwater.io/api/v1/results/23.92323,-66.3

{
  lat: 23.92323,
  lon: -66.3,
  water: true
}
Run Code Online (Sandbox Code Playgroud)

土地上的例子:https: //api.onwater.io/api/v1/results/42.35,-71.1

{
  lat: 42.35,
  lon: -71.1,
  water: false
}
Run Code Online (Sandbox Code Playgroud)

完全披露我在Dockwa.com工作,这是一家名为onwater的公司.我们建立onwater以自己解决这个问题并帮助社区.它是免费使用(支付高容量),我们想分享:)

  • 不幸的是,OnWater.io 主页表示该 API 将于 2022 年 12 月 2 日关闭。[IsItWater.com](https://isitwater.com) 由同一开发人员创建,并提供相同的功能。 (2认同)

And*_*ach 5

除了反向地理编码-如莫勒博士指出,它可能会返回ZERO_RESULTS -你可以使用海拔服务.如果通过反向地理编码获得零结果,请获取该位置的高程.由于海床低于海平面,海洋通常为负数.在http://www.daftlogic.com/sandbox-google-maps-find-altitude.htm上有一个完整的高程服务示例.

请记住,由于谷歌不提供这些信息,任何其他方法只是一种猜测,猜测本质上是不准确的.但是,使用type反向地理编码返回,或者如果type不可用,则将涵盖大多数可能性.