s2
Google S2常用操作
- Google S2
- 包引用
- 经纬度 转 CellId
- CellId 转 经纬度
- S2计算距离
- 经纬度构建任意形状
- 经纬度构建S2矩形
- 经纬度构建S2多边形
- 经纬度构建圆形
- 任意形状内所有S2块
- 判断点是否在任意形状内
- S2块包含的S2子块
- 判断当前cellId的level
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;
}
相关阅读
功能: 滚动到第二屏才出现“返回顶部”按钮; 点击“返回顶部”按钮会返回顶部,而且速度越来越慢; 在返回顶部的途中如果用鼠标滚一
元件动画:引导层—–创建传统补间—在图层前 创建传统运动引导层—-在引导层 用线条画出运动路线—–v(选择工具) 将元件运动始
1.Array.prototype.includes()方法,查找一个值在不在数组中,在就返回true,否则返回false['a','b'].inclueds('a')//true2.求幂运算符
Friends play an important part in our lives, and although we may take the friendship for granted, we often don’t clearl
/** 设置指定键对值的系统属性* setProperty (String prop, String value);* * 参数:* prop - 系统属性的名称。* value - 系统属