欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > java >内容正文

java

Java实现Google的S2算法工具类

发布时间:2024/3/13 java 56 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Java实现Google的S2算法工具类 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

WGS84坐标系 GCJ02坐标系 BD09坐标系的各种转换

WGS84坐标系 GCJ02坐标系 BD09坐标系的各种转换 Google S2 经纬度 转 CellId 经纬度 转 cellToken CellId 转 经纬度 判断当前cellId的level * 获取任意形状内所有S2块 * 可以用于区域内目标检索,根据cellid建立索引,查询区域内cellid in (list)的区域 S2计算点距离 计算地球上某个点是否在矩形区域内 计算点s2是否在圆中心为s1半径为capHeight的圆形区域内 判断点是否在任意形状内 计算两个区域是否有交集 求不同等级S2块包含的S2子块

S2 Demo

Java实现Google的S2算法工具类GoogleS2GoogleS2GoogleS2-Java文档类资源-CSDN下载

level (等级)min area(最小面积)max area(最大面积)average area(平均面积)units(单位)Random cell 1 (UK)() min edge length(随机单元1 (UK)最小边长度)Random cell 1 (UK) max edge length(随机单元格1 (UK)最大边长度)Random cell 2 (US) min edge length(随机单元2 (US)最小边长度)Random cell 2 (US) max edge length(随机单元格2(美国)最大边长度)Number of cells(单元格数)
085011012.1985011012.1985011012.19km27842 km7842 km7842 km7842 km6
121252753.0521252753.0521252753.05km23921 km5004 km3921 km5004 km24
24919708.236026521.165313188.26km21825 km2489 km1825 km2489 km96
31055377.481646455.51328297.07km2840 km1167 km1130 km1310 km384
4231564.06413918.15332074.27km2432 km609 km579 km636 km1536
553798.67104297.9183018.57km2210 km298 km287 km315 km6K
612948.8126113.320754.64km2108 km151 km143 km156 km24K
73175.446529.095188.66km254 km76 km72 km78 km98K
8786.21632.451297.17km227 km38 km36 km39 km393K
9195.59408.12324.29km214 km19 km18 km20 km1573K
1048.78102.0381.07km27 km9 km9 km10 km6M
1112.1825.5120.27km23 km5 km4 km5 km25M
123.046.385.07km21699 m2 km2 km2 km100M
130.761.591.27km2850 m1185 m1123 m1225 m402M
140.190.40.32km2425 m593 m562 m613 m1610M
1547520.399638.9379172.67m2212 m296 m281 m306 m6B
1611880.0824909.7319793.17m2106 m148 m140 m153 m25B
172970.026227.434948.29m253 m74 m70 m77 m103B
18742.51556.861237.07m227 m37 m35 m38 m412B
19185.63389.21309.27m213 m19 m18 m19 m1649B
2046.4197.377.32m27 m9 m9 m10 m7T
2111.624.3319.33m23 m5 m4 m5 m26T
222.96.084.83m2166 cm2 m2 m2 m105T
230.731.521.21m283 cm116 cm110 cm120 cm422T
240.180.380.3m241 cm58 cm55 cm60 cm1689T
25453.19950.23755.05cm221 cm29 cm27 cm30 cm7.00E+15
26113.3237.56188.76cm210 cm14 cm14 cm15 cm2.70E+16
2728.3259.3947.19cm25 cm7 cm7 cm7 cm1.08E+17
287.0814.8511.8cm22 cm4 cm3 cm4 cm4.32E+17
291.773.712.95cm212 mm18 mm17 mm18 mm1.73E+18
300.440.930.74cm26 mm9 mm8 mm9 mm7.00E+18
package com.zz.meridian.utils.googleS2;/*** @author tiger* GPS位置信息接下来说下坐标系。目前主要有三种地理坐标系,如下:* 1、WGS84坐标系:即地球坐标系(World Geodetic System),国际上通用的坐标系。* 设备包含的GPS芯片或者北斗芯片获取的经纬度一般都是为WGS84地理坐标系,目前谷歌地图采用的是WGS84坐标系(中国范围除外)。* 2、GCJ02坐标系:即火星坐标系,国测局坐标系。是由中国国家测绘局制定。由WGS84坐标系经加密后的坐标系。谷歌中国和搜搜中国采用的GCJ02地理坐标系。* 3、BD09坐标系:百度坐标系,GCJ02坐标系经加密后的坐标系。* 4、其他(搜狗坐标系,图吧坐标系等)。大概率也是再GCJ02坐标系基础上加密生成的*/ public class PointS2Transform {public static double x_PI = 3.14159265358979324 * 3000.0 / 180.0;public static double PI = 3.1415926535897932384626;public static double a = 6378245.0;public static double ee = 0.00669342162296594323;/*** 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换* 即 百度 转 谷歌、高德** @param bd_lon* @param bd_lat* @returns {*[]}*/public static PointS2 bd09togcj02(double bd_lon, double bd_lat) {double x = bd_lon - 0.0065;double y = bd_lat - 0.006;double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);double gg_lng = z * Math.cos(theta);double gg_lat = z * Math.sin(theta);PointS2 point = new PointS2(gg_lat, gg_lng);return point;}/*** 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换* 即谷歌、高德 转 百度** @param lng* @param lat* @returns {*[]}*/public static PointS2 gcj02tobd09(double lng, double lat) {double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);double bd_lng = z * Math.cos(theta) + 0.0065;double bd_lat = z * Math.sin(theta) + 0.006;PointS2 point = new PointS2(bd_lat, bd_lng);return point;};/*** WGS84转GCj02** @param lng* @param lat* @returns {*[]}*/public static PointS2 wgs84togcj02(double lng, double lat) {double dlat = transformlat(lng - 105.0, lat - 35.0);double dlng = transformlng(lng - 105.0, lat - 35.0);double radlat = lat / 180.0 * PI;double magic = Math.sin(radlat);magic = 1 - ee * magic * magic;double sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);double mglat = lat + dlat;double mglng = lng + dlng;PointS2 point = new PointS2(mglat, mglng);return point;}/*** 84 to ⽕星坐标系 (GCJ-02) 是否离开了中国版** @param lat* @param lon*/public static PointS2 gps84_To_Gcj02(double lat, double lon) {if (outOfChina(lat, lon)) {return null;}double dLat = transformLat(lon - 105.0, lat - 35.0);double dLon = transformLon(lon - 105.0, lat - 35.0);double radLat = lat / 180.0 * PI;double magic = Math.sin(radLat);magic = 1 - ee * magic * magic;double sqrtMagic = Math.sqrt(magic);dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);double mgLat = lat + dLat;double mgLon = lon + dLon;return new PointS2(mgLat, mgLon);}/*** ⽕星坐标系 GCJ02 转换为 WGS84** @param lng* @param lat* @returns {*[]}*/public static PointS2 gcj02towgs84(double lng, double lat) {double dlat = transformlat(lng - 105.0, lat - 35.0);double dlng = transformlng(lng - 105.0, lat - 35.0);double radlat = lat / 180.0 * PI;double magic = Math.sin(radlat);magic = 1 - ee * magic * magic;double sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);double mglat = lat + dlat;double mglng = lng + dlng;PointS2 point = new PointS2(mglat, mglng);return point;}/*** ⽕星坐标系 GCJ02 转换为 WGS84 是否离开了中国版* @param lon * @param lat * @return*/public static PointS2 gcj_To_Gps84(double lat, double lon) {PointS2 gps = transform(lat, lon);double lontitude = lon * 2 - gps.getLng();double latitude = lat * 2 - gps.getLat();return new PointS2(latitude, lontitude);}/*** 将 GCJ-02 坐标转换成 BD-09 坐标* @param gg_lat* @param gg_lon*/public static PointS2 gcj02_To_Bd09(double gg_lat, double gg_lon) {double x = gg_lon, y = gg_lat;double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * PI);double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * PI);double bd_lon = z * Math.cos(theta) + 0.0065;double bd_lat = z * Math.sin(theta) + 0.006;return new PointS2(bd_lat, bd_lon);}/*** 将 BD-09 坐标转换成GCJ-02 坐标* bd_lat * @param bd_lon * @return*/public static PointS2 bd09_To_Gcj02(double bd_lat, double bd_lon) {double x = bd_lon - 0.0065;double y = bd_lat - 0.006;double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * PI);double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * PI);double gg_lon = z * Math.cos(theta);double gg_lat = z * Math.sin(theta);return new PointS2(gg_lat, gg_lon);}/*** (BD-09)-->84** @param bd_lat* @param bd_lon* @return*/public static PointS2 bd09_To_Gps84(double bd_lat, double bd_lon) {PointS2 gcj02 = bd09_To_Gcj02(bd_lat, bd_lon);PointS2 map84 = gcj_To_Gps84(gcj02.getLat(),gcj02.getLng());return map84;}/*** is or not outOfChina* 是否离开了中国* @param lat* @param lon* @return*/public static boolean outOfChina(double lat, double lon) {if (lon < 72.004 || lon > 137.8347)return true;if (lat < 0.8293 || lat > 55.8271)return true;return false;}private static double transformlat(double lng, double lat) {double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;return ret;}private static double transformlng(double lng, double lat) {double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;return ret;}public static PointS2 transform(double lat, double lon) {if (outOfChina(lat, lon)) {return new PointS2(lat, lon);}double dLat = transformLat(lon - 105.0, lat - 35.0);double dLon = transformLon(lon - 105.0, lat - 35.0);double radLat = lat / 180.0 * PI;double magic = Math.sin(radLat);magic = 1 - ee * magic * magic;double sqrtMagic = Math.sqrt(magic);dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);double mgLat = lat + dLat;double mgLon = lon + dLon;return new PointS2(mgLat, mgLon);}public static double transformLat(double x, double y) {double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y+ 0.2 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;return ret;}public static double transformLon(double x, double y) {double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1* Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0* PI)) * 2.0 / 3.0;return ret;} }

package com.zz.meridian.utils.googleS2;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;@Data @NoArgsConstructor @AllArgsConstructor public class PointS2 {double lat;double lng; }

package com.zz.meridian.utils.googleS2;import com.google.common.collect.Lists; import com.google.common.geometry.*;import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;/*** @author tiger* 必须使用-S2使用的是WGS84坐标* 如果你获得的是WGS84坐标-百度或者高德的地理坐标,请将其转换为GPS-WGS84坐标* 由于google s2默认使用gps坐标系,在国内无法使用,需要转换为国内的gcj坐标或者bd09坐标* 主要包含3类方法:* getS2RegionByXXX* 获取给定经纬度坐标对应的S2Region,该region可用于获取cellId,或用于判断包含关系* getCellIdList* 获取给定region的cellId,并通过childrenCellId方法控制其严格遵守minLevel* contains* 对于指定S2Region,判断经纬度或CellToken是否在其范围内*/ /* 包<dependency><groupId>io.sgr</groupId><artifactId>s2-geometry-library-java</artifactId><version>1.0.0</version></dependency>*/ public class GoogleS2 {/*** 经纬度 转 S2CellId** @param lat 维度* @param lng 经度* @param currentLevel level选择级别*/public static S2CellId latLonToS2LatLng(double lat, double lng, int currentLevel) {S2LatLng s2LatLng = S2LatLng.fromDegrees(lat, lng);S2CellId cellId = S2CellId.fromLatLng(s2LatLng).parent(currentLevel);return cellId;}/*** 经纬度 转 CellId** @param lat 维度* @param lng 经度* @param currentLevel level选择级别*/public static Long latLonToCellId(double lat, double lng, int currentLevel) {S2LatLng s2LatLng = S2LatLng.fromDegrees(lat, lng);S2CellId cellId = S2CellId.fromLatLng(s2LatLng).parent(currentLevel);return cellId.id();}/*** 经纬度 转 cellToken** @param lat 维度* @param lng 经度* @param currentLevel level选择级别*/public static String latLonToCellToken(double lat, double lng, int currentLevel) {try {S2LatLng s2LatLng = S2LatLng.fromDegrees(lat, lng);S2CellId cellId = S2CellId.fromLatLng(s2LatLng).parent(currentLevel);return cellId.toToken();} catch (Exception e) {e.printStackTrace();return null;}}/*** CellId 转 经纬度** @param cellId 是 S2CellId.id();* @return*/public static PointS2 cellIdToLatLon(Long cellId) {S2LatLng s2LatLng = new S2CellId(cellId).toLatLng();double lat = s2LatLng.latDegrees();double lng = s2LatLng.lngDegrees();return new PointS2(lat, lng);}/*** cellToken 转 经纬度** @param cellToken* @return*/public static PointS2 cellTokenToLatLon(String cellToken) {S2LatLng latLng = new S2LatLng(S2CellId.fromToken(cellToken).toPoint());return new PointS2(latLng.latDegrees(), latLng.lngDegrees());}/*** 判断region是否包含指定经纬度坐标** @param region* @param lat* @param lon* @return*/public static boolean contains(S2Region region, double lat, double lon) {S2LatLng s2LatLng = S2LatLng.fromDegrees(lat, lon);try {boolean contains = region.contains(new S2Cell(s2LatLng));return contains;} catch (NullPointerException e) {e.printStackTrace();return false;}}/*** 判断当前cellId的level** @param cellId* @return*/public static int getLevel(long cellId) {int n = 0;while (cellId % 2 == 0) {cellId = cellId / 2;n++;}return 30 - n / 2;}/*** 获取任意形状内所有S2块* 可以用于区域内目标检索,根据cellid建立索引,查询区域内cellid in (list)的区域** @param vertices 形成多边形的点集合* @return*/private static List<Long> vertices(List<PointS2> vertices) {//因为x一般表示经度 y轴表示纬度所以这儿需要参数需要对应一下List<S2Point> collect = vertices.stream().map(e -> S2LatLng.fromDegrees(e.getLng(), e.getLat()).toPoint()).collect(Collectors.toList());S2Loop s2Loop = new S2Loop(collect);S2Polygon cap = new S2Polygon(s2Loop); //创建多边形//S2Region cap 任意区域S2RegionCoverer coverer = new S2RegionCoverer();//最小格子和最大格子,总格子数量coverer.setMinLevel(7);//设置最小级别coverer.setMaxLevel(15);//设置最大级别coverer.setMaxCells(500);//设置最大CellList<S2CellId> list = coverer.getCovering(cap).cellIds(); // for (S2CellId s : list) { // System.out.println(s.id()); // }return list.stream().map(S2CellId::id).collect(Collectors.toList());}/*** S2计算距离** @param s1 点1的经度 纬度* @param s2 点2的经度 纬度* @return*/public static double distance(PointS2 s1, PointS2 s2) {S2LatLng startS2 = S2LatLng.fromDegrees(s1.getLat(), s1.getLng());S2LatLng endS2 = S2LatLng.fromDegrees(s2.getLat(), s2.getLng());double distance = startS2.getEarthDistance(endS2);return distance;}/*** 计算地球上某个点是否在矩形区域内* 矩形的左下角点和矩形的右上角点通过纬度来判断,高低不然算不出来* @param s1 生成矩形的经纬度s1* @param s2 生成矩形的经纬度s2* @param s3 判断s3点是否在上面s1和s2的矩形中* @return*/public static boolean pointRectangleArea(PointS2 s1, PointS2 s2, int desLevel, PointS2 s3) {S2LatLngRect rect = null;if (s1.getLat() > s2.getLat()) {//两个点可以经纬度-构建S2矩形rect = new S2LatLngRect(S2LatLng.fromDegrees(s2.getLat(), s2.getLng()),S2LatLng.fromDegrees(s1.getLat(), s1.getLng()));} else {//两个点可以经纬度-构建S2矩形rect = new S2LatLngRect(S2LatLng.fromDegrees(s1.getLat(), s1.getLng()),S2LatLng.fromDegrees(s2.getLat(), s2.getLng()));}//设置矩形的大小S2RegionCoverer coverer = new S2RegionCoverer();//设置cellcoverer.setMinLevel(7);coverer.setMaxLevel(15);coverer.setMaxCells(500);S2CellUnion covering = coverer.getCovering(rect);S2LatLng s2LatLng = S2LatLng.fromDegrees(s3.getLat(), s3.getLng());return covering.contains(s2LatLng.toPoint());}/*** 计算点s2是否在圆中心为s1半径为capHeight的圆形区域内** @param s1* @param capHeight* @param s2* @return*/public static boolean pointGardenArea(PointS2 s1, double capHeight, PointS2 s2) {S2LatLng s2LatLng = S2LatLng.fromDegrees(s1.getLat(), s1.getLng());S2Cap cap = S2Cap.fromAxisHeight(s2LatLng.toPoint(), capHeight);S2LatLng s2LatLng2 = S2LatLng.fromDegrees(s2.getLat(), s2.getLng());boolean contains = cap.contains(s2LatLng2.toPoint());return contains;}/*** 判断点是否在任意形状内** @param vertices 形成多边形的点集合* @param s 判断的点* @return*/public static boolean pointPolygonArea(List<PointS2> vertices, PointS2 s) {//因为x一般表示经度 y轴表示纬度所以这儿需要参数需要对应一下List<S2Point> collect = vertices.stream().map(e -> S2LatLng.fromDegrees(e.getLng(), e.getLat()).toPoint()).collect(Collectors.toList());S2Loop s2Loop = new S2Loop(collect);S2Polygon polygon = new S2Polygon(s2Loop); //创建多边形S2Point s2Point = S2LatLng.fromDegrees(s.getLat(), s.getLng()).toPoint();boolean contains = polygon.contains(s2Point);return contains;}/*** 计算两个区域是否有交集** @param vertices 形成多边形的点集合1* @param vertices2 形成多边形的点集合2* @return*/public static boolean pointUniteArea(List<PointS2> vertices, List<PointS2> vertices2) {//因为x一般表示经度 y轴表示纬度所以这儿需要参数需要对应一下List<S2Point> collect = vertices.stream().map(e -> S2LatLng.fromDegrees(e.getLng(), e.getLat()).toPoint()).collect(Collectors.toList());//因为x一般表示经度 y轴表示纬度所以这儿需要参数需要对应一下List<S2Point> collect2 = vertices2.stream().map(e -> S2LatLng.fromDegrees(e.getLng(), e.getLat()).toPoint()).collect(Collectors.toList());S2Loop s2Loop = new S2Loop(collect);S2Polygon polygon = new S2Polygon(s2Loop);S2Loop s2Loop2 = new S2Loop(collect2);S2Polygon polygon2 = new S2Polygon(s2Loop2);S2RegionCoverer coverer = new S2RegionCoverer();//设置cellcoverer.setMinLevel(7);//设置最小级别coverer.setMaxLevel(15);//设置最大级别coverer.setMaxCells(500);//设置最大CellS2CellUnion covering = coverer.getCovering(polygon2);for (S2CellId s2CellId : covering.cellIds()) {boolean b = polygon.mayIntersect(new S2Cell(s2CellId));if (b) {System.out.println("两个区域之间含有交集.....");}return b;}return false;}/*** 不同等级S2块包含的S2子块** @param s 自己的点* @param level 自己的等级* @param desLevel 被计算的格子等级,注意:等级越大算的就越多* @return*/public static List<S2CellId> childrenCellId(PointS2 s, Integer level, Integer desLevel) {S2LatLng s2LatLng = S2LatLng.fromDegrees(s.getLat(), s.getLng());S2CellId cellId = S2CellId.fromLatLng(s2LatLng).parent(level);return childrenCellId(cellId, cellId.level(), desLevel);}//递归调用,每个格子一分为四private static List<S2CellId> childrenCellId(S2CellId s2CellId, Integer curLevel, Integer desLevel) {if (curLevel < desLevel) {//计算当前格子每个格子的差值long interval = (s2CellId.childEnd().id() - s2CellId.childBegin().id()) / 4;List<S2CellId> s2CellIds = Lists.newArrayList();for (int i = 0; i < 4; i++) {long id = s2CellId.childBegin().id() + interval * i;s2CellIds.addAll(childrenCellId(new S2CellId(id), curLevel + 1, desLevel));}return s2CellIds;} else {return Lists.newArrayList(s2CellId);}}/*** 任意形状内所有指定等级的S2块** @param vertices 多边形的点* @param desevel 需要计算的内部的s2块的等级* @return*/public static List<S2CellId> childrenCellId(List<PointS2> vertices, int desevel) {List<S2Point> collect = vertices.stream().map(e -> S2LatLng.fromDegrees(e.getLng(), e.getLat()).toPoint()).collect(Collectors.toList());S2Loop s2Loop = new S2Loop(collect);S2Polygon polygon = new S2Polygon(s2Loop);S2RegionCoverer coverer = new S2RegionCoverer();//设置cellcoverer.setMinLevel(6);//设置最小级别 108km~151kmcoverer.setMaxLevel(11);//设置最大级别 3km~5kmcoverer.setMaxCells(500);//设置最大CellS2CellUnion covering = coverer.getCovering(polygon);List<S2CellId> s2CellIds = covering.cellIds();int i=0;List<S2CellId> list=new ArrayList<>();for (S2CellId s2CellId : s2CellIds) {List<S2CellId> s2CellIds1 = childrenCellId(s2CellId, s2CellId.level(), desevel);list.addAll(s2CellIds1);}return list;}public static void main(String[] args) {double lat = 30.2;double lng = 116.3;int currentLevel = 13;S2LatLng s2LatLng = S2LatLng.fromDegrees(lat, lng);S2CellId cellId = S2CellId.fromLatLng(s2LatLng).parent(currentLevel);System.err.println(cellId);String s = cellId.toToken();System.err.println(s);/* System.err.println("------------------------------");System.err.println(latLonToCellToken(lat,lng,1));System.err.println(latLonToCellToken(lat,lng,2));System.err.println(latLonToCellToken(lat,lng,3));System.err.println(latLonToCellToken(lat,lng,4));System.err.println(latLonToCellToken(lat,lng,5));System.err.println(latLonToCellToken(lat,lng,6));System.err.println(latLonToCellToken(lat,lng,7));System.err.println(latLonToCellToken(lat,lng,8));System.err.println(latLonToCellToken(lat,lng,9));System.err.println(latLonToCellToken(lat,lng,10));System.err.println(latLonToCellToken(lat,lng,11));System.err.println(latLonToCellToken(lat,lng,12));System.err.println(latLonToCellToken(lat,lng,13));System.err.println(latLonToCellToken(lat,lng,14));System.err.println(latLonToCellToken(lat,lng,15));System.err.println(latLonToCellToken(lat,lng,16));System.err.println(latLonToCellToken(lat,lng,17));System.err.println(latLonToCellToken(lat,lng,18));System.err.println(latLonToCellToken(lat,lng,19));System.err.println(latLonToCellToken(lat,lng,20));System.err.println(latLonToCellToken(lat,lng,21));System.err.println(latLonToCellToken(lat,lng,30));System.err.println("------------------------------");*/PointS2 pointS2 = cellIdToLatLon(cellId.id());System.err.println(pointS2);double distance = distance(new PointS2(55.8241, 137.8347), new PointS2(55.8271, 137.8347));System.err.println("距离为:" + distance + " m");boolean b = pointRectangleArea(new PointS2(41.808006669390046, 111.495546258779), new PointS2(47.55467105799515, 117.6168335999181),30, new PointS2(45.47161041105891, 114.84087253252726));System.err.println("矩形-----------------" + b);boolean b2 = pointGardenArea(new PointS2(112.030500, 27.970271), 600.5, new PointS2(22.629164, 114.025514));System.err.println(b2);ArrayList<PointS2> pointS2s = new ArrayList<>();pointS2s.add(new PointS2(41.200195, 97.760681));pointS2s.add(new PointS2(41.827161, 103.119335));pointS2s.add(new PointS2(36.507585, 103.688463));pointS2s.add(new PointS2(35.895869, 98.743842));pointS2s.add(new PointS2(41.253179, 97.700277));boolean b1 = pointPolygonArea(pointS2s, new PointS2(39.470948, 100.302180));System.err.println("多边形-----------" + b1);System.err.println("多边形2-----------" + Ryamethod.ray2(39.470948f, 100.302180f, pointS2s));// boolean b3 = pointUniteArea(pointS2s, pointS2s);ArrayList<PointS2> pointS2s1 = Lists.newArrayList(new PointS2(1, 2), new PointS2(3, 4));boolean b3 = pointUniteArea(pointS2s, pointS2s1);System.err.println(b3);// List<S2CellId> s2CellIds1 = childrenCellId(new PointS2(39.470948, 100.302180), 10, 12); // for (S2CellId s2CellId : s2CellIds1) { // System.err.println("点下的s2的token------"+s2CellId.toToken()); // }List<S2CellId> s2CellIds = childrenCellId(pointS2s, 10); // for (S2CellId s2CellId : s2CellIds) { // System.err.println("token------"+s2CellId.toToken()); // }}}

总结

以上是生活随笔为你收集整理的Java实现Google的S2算法工具类的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。