1. 程式人生 > >基於geohash6編碼實現相鄰4、9、16網格合並

基於geohash6編碼實現相鄰4、9、16網格合並

ceiling 分別是 代碼 char class ogr city 接下來 偏移

前面的兩篇文章介紹了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

基於geohash6編碼實現相鄰4、9、16網格合並