使用dynamodb的golang S2几何库

使用dynamodb的golang S2几何库,go,geolocation,geometry,amazon-dynamodb,geometry-surface,Go,Geolocation,Geometry,Amazon Dynamodb,Geometry Surface,我希望将库的一部分移植到golang,以便查询距离给定点最近的点(存储在DyanmoDB中) 按查询是理想的,但如果按查询是一种更简单的算法,我也会很冷静 这是我用radius查询的代码,但我似乎无法得到覆盖单元格的非空列表 我的算法有什么问题 //查询由中心点及其半径构成的圆形区域。 //@见https://github.com/rh389/dynamodb-geo.js/blob/6c388b9070014a096885e00fff6c3fc933d9853f/src/GeoDataMana

我希望将库的一部分移植到golang,以便查询距离给定点最近的点(存储在DyanmoDB中)

按查询是理想的,但如果按查询是一种更简单的算法,我也会很冷静

这是我用radius查询的代码,但我似乎无法得到覆盖单元格的非空列表

我的算法有什么问题

//查询由中心点及其半径构成的圆形区域。
//@见https://github.com/rh389/dynamodb-geo.js/blob/6c388b9070014a096885e00fff6c3fc933d9853f/src/GeoDataManager.ts#L229
func queryRadius(横向浮动64,液化天然气浮动64,半径计浮动64)(错误){
地球半径计:=6367000.0
//步骤1:从中心和半径获取边界区域(矩形)
//@见https://github.com/rh389/dynamodb-geo.js/blob/6c388b9070014a096885e00fff6c3fc933d9853f/src/s2/S2Util.ts#L23
中心距:=s2.横向角度(横向,横向)
latReferenceUnit:=1.0
如果lat>0.0{
latReferenceUnit=-1.0
}
latReferenceLatLng:=s2.LatLngFromDegrees(lat+latReferenceUnit,lng)
lngReferenceUnit:=1.0
如果液化天然气>0.0{
lngReferenceUnit=-1.0
}
Lngreferencelng:=s2.纬度F度(纬度,lng+lngReferenceUnit)
latForRadius:=半径米/中心线。距离(LATFREFERENCELATLING)。弧度()*地球半径米
lngForRadius:=半径米/中心距(Lngreferencelatelng).弧度()*地球半径米
minLatLng:=s2.LatLngFromDegrees(lat lat latForRadius,lng lngForRadius)
maxLatLng:=s2.LatLngFromDegrees(lat+latForRadius,lng+lngForRadius)
boundingRect:=s2.RectFromLatLng(minLatLng)
boundingRect=boundingRect.AddPoint(maxLatLng)
//第二步:计算我们要覆盖的区域的单元ID。
//默认值https://github.com/vekexasia/nodes2-ts/blob/1952d8c1f6cb4a862731ace2d5f74d472ec22e55/src/S2RegionCoverer.ts#L101
rc:=&s2.regionOverer{MaxLevel:30,MaxCells:8,LevelMod:1}
r:=s2.Region(boundingRect.CapBound())
覆盖单元:=钢筋混凝土覆盖层(r)
对于u,c:=范围覆盖单元{
log.WithFields(log.Fields{
“覆盖单元”:c,
}).Info(“=>”)
}
归零
}

注意:这是对我的特定原始问题的回答,但是我无法找到我试图解决的问题的完整解决方案(使用S2查询存储在DyanmoDB中到给定点的最近点)。如果/当我得到完整的解决方案时,我将更新此答案。我现在被封锁了。谢谢你的帮助

这是一个完整的go程序,它从一个点(以度为单位)和一个半径(以米为单位)计算覆盖单元

FWIW从一个点和一个半径确定边界正方形的算法不是很精确。因此,需要提供边界盒算法

主程序包
进口(
“fmt”
“数学”
“strconv”
“github.com/golang/geo/s2”
)
常数接地半径m=6371000//perhttps://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html
常数hashLength=8/<1公里/小时https://github.com/rh389/dynamodb-geo.js/blob/master/test/integration/hashKeyLength.ts
func main(){
低前缀:=uint64(0)
highPrefix:=uint64(0)
ctrLat:=52.225730//英国剑桥
ctrLng:=0.149593
边界Q:=中心和半径的平方(中心距,中心距,500)
格式打印F(“\n边界sq%+v\n”,边界Q)
coveringCells:=getCoveringCells(boundingSq)
fmt.Printf(“覆盖单元格(%d):\n”,len(覆盖单元格))
对于idx,单元格:=范围覆盖单元格{
//cell是此cell中心的UUID
fullHash,hashPrefix:=genCellIntPrefix(单元格)
如果0==idx{
lowPrefix=哈希前缀
highPrefix=哈希前缀
}如果hashPrefixhighPrefix,则为else{
highPrefix=哈希前缀
}
fmt.Printf(“\tID:%19v uint64:%-19d前缀:%-10d范围:%-19d-%-19d\n”,单元格,fullHash,hashPrefix,uint64(cell.RangeMin()),uint64(cell.RangeMax())
}
fmt.Printf(“\tPrefix范围从循环:%-10d-%-10d\n”,低前缀,高前缀)
//TODO:假设覆盖单元格已排序。假设正确吗?
_,lowPrefix=genCellIntPrefix(覆盖单元格[0].RangeMin())
_,highPrefix=genCellIntPrefix(coveringCells[len(coveringCells)-1].RangeMax())
fmt.Printf(“\tPrefix范围直接:%-10d-%-10d\n”,低前缀,高前缀)
}
//从中心点和半径获取边界框正方形
//Boundnig box对于传入的半径计不是非常精确
//@见https://gis.stackexchange.com/questions/80809/calculating-bounding-box-coordinates-based-on-center-and-radius
func squareFromCenterAndRadius(centerLatDegrees浮动64,centerLngDegrees浮动64,radiusMeters浮动32)s2.Rect{
车床角度:=s2.车床角度(中心车床角度,中心车床角度)
deltaLng:=float64(360*半径米/地球半径米)//搜索半径,纬度差
deltaLat:=deltaLng*math.Cos(latLng.Lng.Radians())//搜索半径,Lng中的差值
lowerLeftLatDeg:=中心LatDegrees-deltaLat
lowerLeftLngDeg:=中心LNGDegrees-deltaLng
lowerLeft:=s2.LatLngFromDegrees(lowerLeftLatDeg,lowerLeftLngDeg)//AKA s2.Rect.Lo
upperRightLatDeg:=中心LatDegrees+三角
右上角LNGDEG:=中心LNGDEGRES+deltaLng
右上:=s2.LatLngFromDegrees(upperRightLatDeg,upperRightLngDeg)//AKA s2.Rect.Hi
边界正方形:=s2.RectFromLatLng(lowerLeft).AddPoint(右上)
返回边界正方形
}
func getCoveringCells(boundingRect s2.Rect)s2.CellUnion{
//默认值https://github.com/vekexasia/nodes2-ts/blob/1952d8c1f6cb4a862731ace2d5f74d472ec22e55/src/S2RegionCoverer.ts#L101
rc:=&s2.regionOverer{
最小标高:12,//3km^2/米http://s2geometry.io/resources/s2cell_statist