请问高德地图有没有可以判断某个经纬度坐标是否在指定的地理围栏内部的 API?

304 天前
 nnegier

找 API 找的太苦了~

我的地理围栏就是一个经纬坐标点的方圆 500 米。然后需要判断给定的坐标是否在这个围栏内。

这是高德地图开发相关文档(我没找到 o(╥﹏╥)o ):

https://lbs.amap.com/api/android-location-sdk/guide/additional-func/local-geofence#s5

https://lbs.amap.com/demo/sdk/location-geofence#android

2474 次点击
所在节点    程序员
23 条回复
Endward
304 天前
你直接计算两个坐标点的距离是否大于 500 米不就好了
shxlxa
304 天前
有的,做过这个功能,我明天找一下
zu1y
304 天前
直接算就好了呀,网上有详细的公式和代码的
Melting
304 天前
https://lbs.amap.com/api/webservice/guide/api/geofence_service#t10
查询设备与附近的围栏交互状态。例如是否在围栏中,是否进出围栏;若未在围栏中,返回最近围栏的信息等。

有个 web 接口
nnegier
304 天前
@Endward
@zu1y
我还是想要更官方一点的针对地理围栏的方法,因为有些地理围栏是多边形的。纯计算距离这个可以 CoordinateConverter.calculateLineDistance
liplushe
304 天前
有很多算法都可以实现判断点是否在多边形内,射线交点法、顶点相交法、面积法等等,这些算法有很多公开代码,也不复杂。
liplushe
304 天前
需要注意的是,点的坐标分地理坐标系和投影坐标系,单位分别是度和米,计算的时候需要使用正确的坐标系统,这就涉及到了一点 GIS 知识了。
Arita
304 天前
Turf.js 可以了解一下
xuanbg
304 天前
redis 就有这个功能
awinds
304 天前
自己用点在边形内算
xaplux
304 天前
sayonara7
304 天前
anguiao
304 天前
AMap.GeometryUtil.isPointInRing ?不知道是不是你想要的。
这个页面还有更多几何计算的方法,https://lbs.amap.com/api/javascript-api/reference/math
然后如果已经有一个覆盖物了,也可以用 getBounds 或 getPath 之类的方法获取边界,然后再判断。
aken29
304 天前
围栏功能内的 api 没有找到,地图功能的倒是有计算点是否在多边形内(换个思路),
js 的 https://lbs.amap.com/demo/javascript-api/example/relationship-judgment/point-surface-relation
android 的 https://lbs.amap.com/api/android-sdk/guide/computing-equipment/calcute-distance-tool 里面有说到“Android 地图 SDK 提供了很多计算方法,包括:计算两点距离、矩形面积、坐标转换、判断点是否圆或者多边形内等等,下面做简单介绍:”中 “判断点是否圆或者多边形内”,安卓应该也有相关 api ,但是我也没有找到🤣
opengps
304 天前
我记得是有的
sobev
304 天前
我记得 elasticsearch 是不是有这玩意
TianQian
304 天前
高德的矢量图形类基本都包含一个叫做 contains 的方法,用来判断点是否在图形内,不管是否为多边形
https://lbs.amap.com/api/javascript-api-v2/documentation#polygon
EspoirBao
304 天前
function isCoordinateInsideFence(latitude1, longitude1, latitude2, longitude2) {
const earthRadius = 6371000; // 地球半径,单位为米

// 将经纬度转换为弧度
const lat1Rad = toRadians(latitude1);
const lon1Rad = toRadians(longitude1);
const lat2Rad = toRadians(latitude2);
const lon2Rad = toRadians(longitude2);

// 计算两个坐标点之间的距离
const distance = getDistance(lat1Rad, lon1Rad, lat2Rad, lon2Rad, earthRadius);

// 判断距离是否小于等于 500 米
return distance <= 500;
}

function toRadians(degrees) {
return degrees * Math.PI / 180;
}

function getDistance(lat1, lon1, lat2, lon2, radius) {
const dLat = lat2 - lat1;
const dLon = lon2 - lon1;

const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);

const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

const distance = radius * c;
return distance;
}

// 测试
const fenceLatitude = 40.123456; // 围栏中心点的纬度
const fenceLongitude = -74.123456; // 围栏中心点的经度
const testLatitude = 40.123; // 测试点的纬度
const testLongitude = -74.123; // 测试点的经度

const isInside = isCoordinateInsideFence(
fenceLatitude,
fenceLongitude,
testLatitude,
testLongitude
);

console.log(isInside ? '坐标在围栏内' : '坐标不在围栏内');
aken29
304 天前
@aken29
根据 17 楼的提示,找到安卓的文档了,https://a.amap.com/lbs/static/unzip/Android_Map_Doc/index.html ,还是 contains 方法
xiangyuecn
304 天前
射线法,不管什么奇形怪状都能计算是不是在内部

服务器里面的话:
- 可以用 RTree 对每条边进行索引,然后还是用射线法😂 性能:1 秒判断 10 万+ 个坐标点
- Java:高性能的省市区坐标数据、边界数据查询工具,Java 开源程序、带 http 查询接口,内存占用低( 1 秒可查 1 万个以上坐标对应的城市信息): https://github.com/xiangyuecn/AreaCity-Query-Geometry

客户端:依旧是射线法,自己手撸一下,百来行代码,性能一般😂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/955315

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX