Google S2 常用操作

Google S2

包引用

	<dependency>
        <groupId>io.sgr</groupId>
        <artifactId>s2-geometry-library-java</artifactId>
        <version>1.0.0</version>
    </dependency>

经纬度 转 CellId

val s2LatLng : S2LatLng = S2LatLng.fromDegrees(lat, lng)
val celId = S2CellId.fromLatLng(s2LatLng)

CellId 转 经纬度

val s2LatLng = new S2CellId(celId).toLatLng
val lat = s2LatLng.latDegrees()
val lng = s2LatLng.lngDegrees()

S2计算距离

val startS2: S2LatLng = S2LatLng.fromDegrees(55.8241, 137.8347)
val endS2: S2LatLng = S2LatLng.fromDegrees(55.8271, 137.8347)
val dis = startS2.getEarthDistance(endS2)

经纬度构建任意形状

经纬度构建S2矩形

val startS2: S2LatLng = S2LatLng.fromDegrees(0.8293, 72.004) //左下角
val endS2: S2LatLng = S2LatLng.fromDegrees(55.8271, 137.8347) //右上角
val rect: S2LatLngRect = new S2LatLngRect(startS2, endS2)

经纬度构建S2多边形

val vertices = new util.ArrayList[S2Point]
//注意,一般需要多边形内侧,此处需要按照逆时针顺序添加。
vertices.add(S2LatLng.fromDegrees(lat, lng).toPoint)
val s2Loop = new S2Loop(vertices)
val polygon = new S2Polygon(s2Loop) 

经纬度构建圆形

 double radius = 600.5; //半径
 val capHeight = (2 * S2.M_PI) * (radius / 40075017)
 S2LatLng s2LatLng= S2LatLng.fromDegrees(lat, lng);
 S2Cap cap = S2Cap.fromAxisHeight(s2LatLng.toPoint(),capHeight × capHeight / 2);

任意形状内所有S2块

val rect //构建的形状
val coverer: S2RegionCoverer = new S2RegionCoverer
coverer.setMaxLevel(7)
coverer.setMinLevel(7)
val list: util.ArrayList[S2CellId] = coverer.getCovering(rect).cellIds()

判断点是否在任意形状内

 val rect //构建的形状
 S2LatLng s2LatLng = S2LatLng.fromDegrees(lat, lng);
 boolean contains = rect.contains(s2LatLng.toPoint());

S2块包含的S2子块

求level=7的S2块下的level=8的4个子块的S2CellId,如下:

val s2CellId = S2CellId.fromLatLng(S2LatLng.fromDegrees(55.130666,88.700062)).parent(7)
val interval = (s2CellId.childEnd().id() - s2CellId.childBegin().id()) / 4
val childrenId = (0 until 4).flatMap(i => {
  val id = s2CellId.childBegin().id() + interval * i
  val cellId = new S2CellId(id).toLatLng
  List(cellId.lngDegrees(), cellId.latDegrees()).mkString(",")
}).mkString(";")

求level=7的S2块下的level=9的16个子块的S2CellId,如下:

val s2CellId = S2CellId.fromLatLng(S2LatLng.fromDegrees(55.130666,88.700062)).parent(7)
val chilren = childrenCellId(s2CellId, 7, 9)

/**
* 求当前cellId下的所有 子cellId
* @param s2CellId 当前cellId
* @param curLevel 当前cellId的level 需与cellId保持一致
* @param desLevel 目标cellId的level 需大于当前cellId
* @return
*/
def childrenCellId(s2CellId: S2CellId, curLevel:Int, desLevel:Int): List[S2CellId] = {
if (curLevel < desLevel) {
  val interval = (s2CellId.childEnd().id() - s2CellId.childBegin().id()) / 4
  (0 until 4).flatMap(i => {
    val id = s2CellId.childBegin().id() + interval * i
    val cellId = new S2CellId(id)
    childrenCellId(cellId, curLevel + 1, desLevel)
  }).toList
} else List(s2CellId)
}

判断当前cellId的level

private static int getLevel(long input) {
    int n = 0;
    while (input % 2 == 0) {
        input = input / 2;
        n++;
    }
    return 30 - n / 2;
}
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

deng0515001

求鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值