针对“php+mongodb判断坐标是否在指定多边形区域内”的实现,我们需要按照以下步骤进行:
1.准备工作
首先,需要安装MongoDB和PHP的扩展库MongoDB driver。在此不再赘述。
其次,需要安装一个支持geoJSON数据的MongoDB插件,geoJSON数据是一种用于表示地球上任意一个二维平面片的JSON格式数据,可以更加准确地表示地理位置信息。在此我们使用MongoDB 3.2版本及以上的官方插件mongo-compass-1.14.0-win32-x64.msi。
2.插入多边形区域数据
接下来,将多边形区域的数据插入MongoDB数据库中。MongoDB支持GeoJSON格式的数据。示例代码如下:
var data = {
name: "polygon1", // 多边形区域名称,可选
geometry: {
type: "Polygon", // 几何类型(多边形)
coordinates: [
[
[113.321457, 23.195468],
[113.325632, 23.194388],
[113.327300, 23.196693],
[113.323367, 23.199188],
[113.319407, 23.197011],
[113.321457, 23.195468]
]
]
}
};
db.polygons.insert(data);
GeoJSON数据的几何类型有Point、LineString、Polygon、MultiPoint、MultiLineString、MultiPolygon、GeometryCollection七种。
以上代码中,我们插入了一个名为“polygon1”的多边形区域,它的坐标点是一个二维数组,由经纬度坐标组成。注意:坐标点的顺序必须是按照顺时针或逆时针的方向排列,末尾坐标点必须与第一个坐标点相同(闭合区域)。
3.查询坐标是否在指定多边形区域内
接下来,在PHP脚本中实现函数判断坐标是否在指定多边形区域内。示例代码如下:
/**
* 功能:判断坐标是否在指定多边形区域内
* 参数:$lon 经度;$lat 纬度;$polygon 多边形区域名称
* 返回:该点是否在指定多边形区域内
*/
function isInsidePolygon($lon, $lat, $polygon) {
// 连接MongoDB数据库
$m = new MongoDB\Driver\Manager("mongodb://localhost:27017");
// 创建查询命令
$command = new MongoDB\Driver\Command([
'geoNear' => 'polygons', // 要查询的集合
'near' => ['type' => 'Point', 'coordinates' => [$lon, $lat]], // 测试点
'spherical' => true, // 球面距离
'maxDistance' => 5000, // 最大距离,单位:米
'query' => ['name' => $polygon], // 要查询的区域名称
]);
// 执行查询命令
$cursor = $m->executeCommand('test', $command);
// 解析查询结果
foreach ($cursor as $document) {
$result = $document->results;
foreach ($result as $item) {
if ($item->dis !== NULL) { // 查询成功
return true;
}
}
}
return false; // 查询失败
}
以上代码中,我们使用MongoDB的geoNear命令进行查询。该命令能够查询给定点与指定集合中所有点的距离,并返回距离最近的点的信息。查询过程主要包括以下几个步骤:
- 创建查询命令,参数包括:要查询的集合名称、测试点、距离单位、最大距离范围、要查询的区域名称等;
- 执行查询命令,返回查询结果;
- 解析查询结果,判断测试点与多边形区域是否相交。
具体实现过程可以参考以上示例代码。
示例说明
下面分别给出两个示例说明:
示例1:判断某个点是否在指定多边形区域内
假如我们有一个多边形区域,名为“polygon1”,坐标点为:[[113.321457, 23.195468],[113.325632, 23.194388],[113.327300, 23.196693],[113.323367, 23.199188],[113.319407, 23.197011],[113.321457, 23.195468]]。现在需要判断一个点(113.322678, 23.197958)是否在该多边形区域内,我们只需要调用以上提到的isInsidePolygon函数即可。示例代码如下:
$lon = 113.322678;
$lat = 23.197958;
$polygon = "polygon1";
$result = isInsidePolygon($lon, $lat, $polygon);
if ($result) {
echo "该点在指定多边形区域内。";
} else {
echo "该点不在指定多边形区域内。";
}
示例2:批量查询坐标是否在指定多边形区域内
假如现在有一个包含多个坐标点的数组,现在需要判断每一个坐标点是否在某个多边形区域内,我们可以使用循环进行批量查询。示例代码如下:
$points = [
['lon' => 113.322678, 'lat' => 23.197958],
['lon' => 113.324847, 'lat' => 23.197962],
['lon' => 113.327011, 'lat' => 23.197969],
];
$polygon = "polygon1";
foreach ($points as $p) {
$result = isInsidePolygon($p['lon'], $p['lat'], $polygon);
if ($result) {
echo "坐标[".$p['lon'].",".$p['lat']."]在指定多边形区域内。";
} else {
echo "坐标[".$p['lon'].",".$p['lat']."]不在指定多边形区域内。";
}
}
在以上两个示例中,如果输出的结果为“该点在指定多边形区域内。”或“坐标[x,y]在指定多边形区域内。”,则表示该点或坐标在指定的多边形区域内;如果输出的结果为“该点不在指定多边形区域内。”或“坐标[x,y]不在指定多边形区域内。”,则表示该点或坐标不在指定的多边形区域内。