多边形中的geoPHP点
Posted
技术标签:
【中文标题】多边形中的geoPHP点【英文标题】:geoPHP point in polygon 【发布时间】:2014-03-26 00:36:20 【问题描述】:我需要一些帮助,谷歌让我很难过
我得到了多边形http://geojson.io/#id=gist:anonymous/069b8a955897723ca256&map=4/58.75/48.03 它涵盖了很多。 我得到了geophp库https://github.com/phayes/geoPHP 哪些得到的方法包含、覆盖、覆盖...
一切正常,除了像 74.224074、96.428248 这样的点对于该多边形的 contains、coveredBy、covers 等方法始终为 false。但一定是真的。
请告诉我为什么。我头疼。
或
请告诉我,如何检查纬度 lng 是否在多边形内。我在 perl 和 php 中测试了大约 3 个库,制作了我自己的代码等......但我只从 google containsLocation 中得到了正确的结果。但我必须在服务器端使用它,而不是在浏览器中。如果有机会在 nodejs 中使用 containsLocation 那就太好了。
谢谢
A little code for geoPHP:
$a='JSON FROM LINK';
$b=geoPHP::load("POINT(74.224074 96.428248)","wkt");
$a=geoPHP::load($a, 'json');
$result=$a->contains($b);
var_dump($result);
它会是假的
编辑: 我想我明白了。 GeoJson 以错误的方式、经度、纬度制作坐标。但它必须是纬度,经度。 会试一下,如果可行的话就写在这里
回答:
使用这个 www.birdtheme.org/useful/v3tool.html 在地图上制作多边形。它以正确的方式(纬度,经度)
geoPHP 的工作代码:
include_once('geoPHP.inc');
$addr=file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($_GET['address']).'&sensor=false');
foreach($addr->results as $addr1)
if(array_key_exists("geometry",$addr1))
$lat=$addr1->geometry->location->lat;
$lng=$addr1->geometry->location->lng;
break;
$point1 = geoPHP::load("POINT($lat $lng)","wkt");
$ya200=geoPHP::load("POLYGON((41.51 12.3, 38.27 28.83, 32.55 41.84, 27.6 55.55, 29.54 71.37, 33.43 83.32, 36.6 94.92, 36.6 99.49, 35.17 111.45, 32.55 124.8, 35.17 130.78, 39.64 142.73, 43.58 152.58, 45.83 166.29, 56.17 163.83, 63.07 159.26, 68.66 154.69, 72.18 148.71, 75.93 140.63, 78.49 129.02, 80.3 114.26, 80.98 100.2, 81.2 87.54, 80.87 73.83, 79.62 59.41, 76.27 40.43, 71.07 28.13, 67.2 23.2, 63.55 20.04, 59.01 17.23, 54.16 15.12, 48.46 13.36,41.51 12.3))","wkt");
var_dump($ya200->contains($point1));
【问题讨论】:
【参考方案1】:我是 geoPHP 库 (https://geophp.net) 的维护者。你的纬度和经度混淆了。 WKT 指定首先出现x
,然后是y
,然后是(可选)z
。这是有道理的,因为我们通常按 XYZ 顺序做事。
在数学中,横轴为 X,纵轴为 Y,这是数学上的惯例。如果我们想象一个地球仪覆盖在一张指定 X 轴和 Y 轴的方格纸上,我们可以看到经度是水平轴,对应X,纬度是垂直轴,对应Y。因此将其读作“经度,纬度”非常有意义。
遗憾的是,这种合理的方法与水手和其他制图师在历史上描述地球坐标的方式大相径庭。从历史上看,它经常被描述为“纬度,经度”。
这种历史与数学约定的冲突就是为什么您会在不同的系统中看到不同的约定。在 Google Maps API 中它是“纬度,经度”,而在 OpenLayers 中它是“经度,纬度”。
在这种特殊情况下,您使用的是 WKT,它以“经度、纬度”的顺序指定。
【讨论】:
我创建了另一个问题***.com/questions/41459331/…。我在这里尝试了解决方案,但它不起作用。【参考方案2】:WKT 格式需要POINT(lon, lat)
,lon
是第一个。你把顺序搞混了。更正:
geoPHP::load("POINT($lon $lat)","wkt");
【讨论】:
【参考方案3】:我已经回答了几乎相同的问题,但不知道如何重新发布,所以我在这里重复一遍(对不起)
如果您使用这个 PHP 库 (https://github.com/xopbatgh/sb-polygon-pointer),它可能会满足您的所有需求
(但首先您需要将 GEOjson 坐标转换为 lat/lng)
计划做:
将多边形的坐标插入数组
询问图书馆是这个多边形内的任何带 lat/lng 的点
$polygonBox = [
[55.761515, 37.600375],
[55.759428, 37.651156],
[55.737112, 37.649566],
[55.737649, 37.597301],
];
$sbPolygonEngine = new sbPolygonEngine($polygonBox);
$isCrosses = $sbPolygonEngine->isCrossesWith(55.746768, 37.625605);
// $isCrosses is boolean
【讨论】:
【参考方案4】:经过数小时的努力,我无法让 contains
方法与 geoPHP 一起使用。事实证明,正如 this SO response 指出的那样,geos 库需要手动安装(没有作曲家),在筛选了 archive.org 上的文档后,我无法开始工作。
作为替代方案,我发现mjaschen/phpgeo 可以简单地用于进行多边形包含点的计算。只需将您的纬度加载到对象中,然后将 contains 方法调用为 outlined in the documentation:
$polygon = new Polygon();
$polygon->addPoint(new Coordinate(12.3, 41.51));
$polygon->addPoint(new Coordinate(28.83, 38.27));
$polygon->addPoint(new Coordinate(41.84, 32.55));
$point = new Coordinate(74.224074, 96.428248)
var_dump($polygon->contains($point))
【讨论】:
【参考方案5】:geoPHP 中的所有高级方法都需要安装 GEOS。如果您无法安装它但仍想对点和多边形使用相交测试,那么我已经分叉了 geoPHP 并为此添加了 Polygon->pointInPolygon 和 MultiPolygon->pointInPolygon 方法。看一看: https://github.com/sookoll/geoPHP
$point = \geoPHP::load('POINT (x y)','wkt');
$polygon = \geoPHP::load('POLYGON ((x y...))','wkt');
$point_is_in_polygon = $polygon->pointInPolygon($point);
【讨论】:
以上是关于多边形中的geoPHP点的主要内容,如果未能解决你的问题,请参考以下文章