当前位置:   article > 正文

python中Google S2算法的简单使用案例_s2sphere

s2sphere
  • 前提: 安装了s2sphere库

程序示例:

# -*- coding: utf-8 -*-
# @Time    : 2023/3/1 下午2:48
# @Author  : Micheal
# @FileName: GoogleS2Util.py
# @Content : 关于Google S2算法的一些基本函数封装
import math
import webbrowser

import s2sphere
import folium


class GoogleS2Util(object):

    # (lat, lng, level=30) -> cell ID
    @classmethod
    def latlng2CellID(cls, lat, lng, level=30):
        ll = s2sphere.LatLng.from_degrees(lat, lng)
        cellId = s2sphere.CellId.from_lat_lng(ll).parent(level).id()  # 指定级数
        return cellId

    # cell ID -> (lat, lng)
    @classmethod
    def cellID2Latlng(cls, cellId):
        ll = s2sphere.CellId(cellId).to_lat_lng()
        point = [ll.lat().degrees, ll.lng().degrees]
        return point

    # cell ID -> (lat, lng)  (推荐使用上面的简便写法)
    @classmethod
    def cellID2Latlng2(cls, cellId):
        cell = s2sphere.Cell(s2sphere.CellId(cellId))
        ll = s2sphere.LatLng.from_point(cell.get_center())
        point = [ll.lat().degrees, ll.lng().degrees]
        return point

    # 判断Cell之间的包含关系:      (cellIdA, cellIdB) -> isContain
    @classmethod
    def cellIsContain(cls, cellIdA, cellIdB):
        return s2sphere.CellId(cellIdA).contains(s2sphere.CellId(cellIdB))

    # 获取 cell 的四个方位:       cell ID -> List<GeoPoint>
    @classmethod
    def cellId2Vertexs(cls, cellId):
        cell = s2sphere.Cell(s2sphere.CellId(cellId))
        points = []
        for i in range(4):
            ll = s2sphere.LatLng.from_point(cell.get_vertex(i))
            points.append([ll.lat().degrees, ll.lng().degrees])
        return points

    # 计算两个Point之间的距离(单位:米): (lat1, lng1, lat2, lng2) -> diatance
    @classmethod
    def getDistance(cls, lat1, lng1, lat2, lng2):
        latLng1 = s2sphere.LatLng.from_degrees(lat1, lng1)
        latLng2 = s2sphere.LatLng.from_degrees(lat2, lng2)
        angle = latLng1.get_distance(latLng2)
        # 弧长 = α(圆心角弧度数)× r(半径)=  n(圆心角)× π(圆周率)× r(半径)/180
        distance = angle.radians * 6371.01 * 1000
        # distance = (angle.degrees * math.pi / 180) * 6371.01 * 1000
        return distance

    # 利用地球经纬度来计算两个坐标点之间的距离
    @classmethod
    def rad(self, ang):
        return math.pi * ang / 180.0
    @classmethod
    def getDistance2(cls, lat1, lng1, lat2, lng2):
        lat1 = cls.rad(lat1)
        lng1 = cls.rad(lng1)
        lat2 = cls.rad(lat2)
        lng2 = cls.rad(lng2)
        dlng = lng2 - lng1
        dlat = lat2 - lat1
        a = (math.sin(dlat / 2)) ** 2
        b = math.cos(lat1) * math.cos(lat2)
        c = (math.sin(dlng / 2)) ** 2
        distance = 6371.01 * 2 * math.asin(math.sqrt(a + b * c)) * 1000.0
        return distance

    # 获取cellid的Level:         cell ID -> level
    @classmethod
    def getLevel(cls, cellId):
        cellID = s2sphere.CellId(cellId)
        return cellID.level()


    # 获取某一 cellID 的所有邻接Cell: (cellID, level) --> List<Long>
    @classmethod
    def getNeighborCells(cls, cellId, level=None):
        if level is None:
            level = cls.getLevel(cellId)
        cellID = s2sphere.CellId(cellId)
        cellANeighbor = [item.id() for item in cellID.get_all_neighbors(level)]
        return cellANeighbor

    # 判断两个(同Level的) cellId 是否相邻
    @classmethod
    def isNeighbor(cls, cellIdA, cellIdB):
        return cellIdA in cls.getNeighborCells(cellIdB)


    # 获取矩形区域内所有的 cell
    # 更多形状区域内的Cell,参考: https://blog.csdn.net/qq_43777978/article/details/116800460
    @classmethod
    def getCoverCells(cls, lat1, lng1, lat2, lng2, minLevel=0, maxLevel=30, maxCells=100):
        # 左下角坐标
        startS2 = s2sphere.LatLng.from_degrees(min(lat1, lat2), min(lng1, lng2))
        # 右上角坐标
        endS2 = s2sphere.LatLng.from_degrees(max(lat1, lat2), max(lng1, lng2))
        rect = s2sphere.LatLngRect(startS2, endS2)  # 矩形区域

        # 获取region区域内的cell
        s2RegionCoverer = s2sphere.RegionCoverer()
        s2RegionCoverer.min_level = minLevel
        s2RegionCoverer.max_level = maxLevel
        s2RegionCoverer.max_cells = maxCells

        covering = s2RegionCoverer.get_covering(rect)
        return [item.id() for item in covering]


if __name__ == "__main__":
    # # 验证 “获取矩形区域内所有的 cell”
    # tiles = 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'  # 蓝黑版
    # myMap = folium.Map([31.374500, 121.487500], zoom_start=12, tiles=tiles, attr='蓝黑版')
    # lat1, lng1, lat2, lng2 = -31.408080852440047, -121.26010348059191, -30.995548292413257, -121.727418244035
    #
    # # 绘制矩形框
    # folium.Polygon(
    #     locations=[[lat1, lng1], [lat1, lng2], [lat2, lng2], [lat2, lng1]],
    #     color="yellow",  # 线条边框颜色
    #     weight=2,  # 线条的宽度
    #     opacity=0.8,  # 线条透明度
    # ).add_to(myMap)
    #
    # # 获取cellIDs
    # cells = GoogleS2Util.getCoverCells(lat1, lng1, lat2, lng2, 1, 30, 100)
    # for cell in cells:
    #     # 绘制矩形框
    #     folium.Polygon(
    #         locations=GoogleS2Util.cellId2Vertexs(cell),
    #         color="yellow",  # 线条边框颜色
    #         weight=2,  # 线条的宽度
    #         opacity=0.1,  # 线条透明度
    #         fill=True,  # 是否填充内部
    #         fill_color="red",  # 内部颜色
    #         fill_opacity=0.5  # 内部颜色透明度
    #     ).add_to(myMap)
    #
    #
    # file_name = "test_debug_analysis.html"
    # myMap.save(file_name)  # 保存
    # webbrowser.get(using='google-chrome').open(file_name, new=2)  # 加载

    # # 是否包含关系
    # loc = GoogleS2Util.cellID2Latlng(3869282349875200000)
    # result = GoogleS2Util.cellIsContain(3869280597528543232, GoogleS2Util.latlng2CellID(loc[0], loc[1], 14))
    # print(result)
    #
    # # 获取 cell 的 4个方位
    # result = GoogleS2Util.cellId2Vertexs(3869280597528543232)
    # print(result)
    #
    # 获取距离
    locA = GoogleS2Util.cellID2Latlng(3869275444641529856)
    locB = GoogleS2Util.cellID2Latlng(3869275455378948096)
    locC = GoogleS2Util.cellID2Latlng(3869281267543441408)
    locA2 = GoogleS2Util.cellID2Latlng2(3869275444641529856)
    locB2 = GoogleS2Util.cellID2Latlng2(3869275455378948096)
    locC2 = GoogleS2Util.cellID2Latlng2(3869281267543441408)
    print(locA, locB, locC)
    print(locA2, locB2, locC2)
    # result = GoogleS2Util.getDistance(locA[0], locA[1], locB[0], locB[1])
    # result2 = GoogleS2Util.getDistance2(locA[0], locA[1], locB[0], locB[1])
    # print(result)
    # print(result2)
    #
    # # 获取级数
    # result = GoogleS2Util.getLevel(3869280597528543232)
    # print(result)
    #
    # # 获取邻居 cell
    # result = GoogleS2Util.getNeighborCells(3869280597528543232, 14)
    # print(result)
    #
    # # 判断是否相邻
    # flag = GoogleS2Util.isNeighbor(3869280597528543232, 3869282315515461632)
    # print(flag)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/138631?site
推荐阅读
相关标签
  

闽ICP备14008679号