基于geohash6编码实现相邻4、9、16网格合并

    前面的两篇文章介绍了geohash的基本原理及c#代码相关实现,其中geohash 5位编码单个网格覆盖面积大约在24平方千米,6位编码单网格覆盖面大约在0.73平方千米, 相邻编码长度之间单网格覆盖面积跨度太大,在实际应用中希望计算出3平方千米、5平方千米、10平方千米的覆盖率,可行的方案在Geohash6对应的网格上进行4、9、16网格的合并。

   基本思路 :

  • 将城市坐标看成一个基于经纬度线的坐标系,取出所在城市的经纬度范围(为了减少网格的个数,在满足业务的需求的前提下,确定的范围值越小越好)
  • 从最小的经纬度开始计算网格,geohash基本原理 一文中,通过在网上收集的资料,geohash码相邻网格的经纬度分别是为:0.0055 和 0.0027, 通过验证,相邻网格正确的偏移量分别为:
    DIFF_LAT = 0.0054931640625;
    DIFF_LON = 0.010986328125;
  • 在计算的过程中,将最小经纬度画出的表格定位在坐标系中的第一行、第一列,根据上面提供的偏差量依次进行循环,计算出范围内所有网格及其所在的行、列,以青岛为例,计算出来的示例数据如下:
  • 数据清洗完成后,接下来需要做的就是进行网格的合并(本质是给合并的网格一个相同的编码),如下图:
  • 红框内以4格合并为例,每个合并后的网格占2行2列,框内的11表示第一行第一列,12表示第一行第二列,21表示第二行第一行,当4格合并后新生成的风格占第一行第一列,由此不难发现,取geohash6网格所有行、列数除2向下取整即可得到合并后网格所在的新行和新列,对数据进行组合,确定唯一码
  • 同理,对于9格、16格、25格的合并岂是一样,它们分别可以使用3行3列、4行4列、5行5列的明细风格进行合并,然后取出合并后网格的最大和最小经纬度即可计算出坐标范围,如下:
    /*group4*/
        update  ETL_GeoCityGrid set geogroup4 = cityID + '-' + 'G4-' +  cast(CEILING(cast(grow as decimal)/2) as varchar) + '-' + cast(CEILING(cast(gcol as decimal)/2) as varchar);
    
        /*group9*/
        update  ETL_GeoCityGrid set geogroup9 = cityID + '-' + 'G9-' +  cast(CEILING(cast(grow as decimal)/3) as varchar) + '-' + cast(CEILING(cast(gcol as decimal)/3) as varchar);
    
        /*group16*/
        update  ETL_GeoCityGrid set geogroup16 = cityID + '-' + 'G16-' +  cast(CEILING(cast(grow as decimal)/4) as varchar) + '-' + cast(CEILING(cast(gcol as decimal)/4) as varchar);
  • 合并后网格的唯一码确定后,计算每个合并后网格的坐标范围就相对容易,如下:

     select geogroup4,min(minlat) as minlat,min(minlng) as minlng,max(maxlat) as maxlat,max(maxlng) as maxlng
            from ETL_GeoCityGrid 
           where cityid = '3702'
          group by geogroup4
  • 效果图:
原文地址:https://www.cnblogs.com/tgzhu/p/6950363.html