全部產品
Search
文件中心

PolarDB:GanosBase低代碼實現免切片遙感影像瀏覽(二):動態柵格瓦片

更新時間:Dec 10, 2024

GanosBase的動態柵格瓦片能力能夠快速實現庫內柵格資料或柵格分析結果的可視化,且無需依賴GeoServer等空間服務中介軟體。該技術棧簡潔高效,使用靈活便捷。

關於GanosBase柵格引擎

GanosBase Raster是PolarDB PostgreSQL版的一個時空引擎擴充,使上述資料庫能夠有效快速儲存管理柵格類型資料,同時支援多源柵格資料(如遙感、攝影測量和專題地圖)之間的融合與分析,並提供了GeoServer外掛程式將庫內柵格對象發布為OGC標準的服務(如WMS或WMTS等)。GanosBase Raster可用於包括氣象、環境監測、地質勘探、自然資源管理、國防、應急響應、電信、傳媒、交通、城市規劃以及國土安全等領域。

關於柵格引擎的詳細介紹,請參考柵格模型

由於柵格資料的規模較大,其可視化通常採用預製柵格瓦片並發布服務的方式。然而,切片所帶來的資料現勢性問題被越來越多的使用者所詬病,同時,切出來的瓦片資料也帶來額外的儲存成本。長期以來,GanosBase始終致力於構建卓越的時空資料查詢與分析效能,以推動更多時空業務的“線上化”,其中也包括“切片”等離線作業方式。之前我們介紹了通過GanosBase Raster的金字塔方法,在不進行預切片的情況下快速可視化庫內的柵格資料,詳情請參考低代碼實現免切片遙感影像瀏覽(一):金字塔。本次我們提供一種更加直觀的方式,類似於在向量資料中使用asMVT方法,通過動態產生柵格瓦片以快速查看柵格資料。與前一種方案相比,本文方案採用標準瓦片形式進行動態處理和輸出,無需依賴GeoServer等空間服務中介軟體,具有更為簡潔高效的技術棧,從而使得使用過程更加靈活。

動態柵格瓦片能力介紹

業務背景

傳統遙感影像服務發布過程中,需要事先對柵格對象按照切片規則進行分層切片,然後使用GeoServer等伺服器進行瓦片服務發布。該流程存在如下缺點:

  • 對超大範圍的遙感影像切片,處理耗時通常較長,服務發布流程較為複雜,導致無法實現快速發布服務。

  • 切片儲存需要消耗額外的儲存空間,造成資料大量冗餘。

  • 資料更新後,需要重新進行切片,無法實現即時更新。

能力介紹

針對上述問題,GanosBase在6.3版本及後續版本提供ST_AsTile函數。通過該函數,可以對指定範圍內的Raster對象進行即時動態瓦片產生。在柵格資料入庫後,只需指定空間範圍及相應的瓦片產生參數,資料庫將自動執行柵格對象的裁剪、重投影、重採樣和渲染等操作,並按照256x256或512x512的尺寸輸出為標準瓦片。通過測試,單個瓦片的處理時間控制在百毫秒以內,完全能夠滿足對柵格資料服務發布即時性的要求,同時有效避免資料冗餘和更新相關的問題。動態柵格瓦片將GanosBase的快顯能力與柵格資料類型進行深度融合,使得動態可視化柵格資料的使用與動態向量瓦片(ST_AsMVT)同樣便捷高效,從而在很大程度上提升GanosBase柵格資料類型視算一體的能力。

技術優勢

相比傳統的柵格切片,使用ST_AsTile的主要優勢包括:

  • 支援即時動態建置規則的瓦片,避免傳統切瓦片操作存在的資料冗餘問題,節省儲存成本。

  • 自動實現柵格裁剪、重投影、重採樣操作,更加方便簡潔。

  • 單個瓦片產生效率達到百毫秒內,滿足即時性要求。

  • 資料更新後,無需重新切片,可即時展示更新內容。

說明

目前ST_AsTile功能僅支援對單個Raster對象的操作,如果涉及到多個Raster對象(如多景影像需要同時查看)則需要對Raster對象進行鑲嵌操作。

最佳實務

為了得到良好的體驗,PolarDB叢集建議使用以下配置:

  • 資料庫引擎:PostgreSQL 14

  • 核心版本:14.13.25.0

  • CPU:>4 核

  • 記憶體:>16GB

  • 磁碟:>50GB

  • GanosBase版本:>=6.3

  1. 安裝ganos_raster外掛程式。

    CREATE EXTENSION ganos_raster CASCADE;
  2. 資料準備與入庫。準備4景landsat8影像,共RGB+NIR四個波段,上傳到OSS。

    image

    • 建立柵格資料表。

      CREATE TABLE landsat8
      (
        id integer,
        rast raster
      );
    • 使用ST_ImportFrom函數進行資料入庫。

      INSERT INTO landsat8 VALUES (1, ST_ImportFrom('chunk_table','OSS://<access_id>:<secrect_key>@<Endpoint>/<bucket>/path_to/file1.TIF'));
      INSERT INTO landsat8 VALUES (2, ST_ImportFrom('chunk_table','OSS://<access_id>:<secrect_key>@<Endpoint>/<bucket>/path_to/file2.TIF'));
      INSERT INTO landsat8 VALUES (3, ST_ImportFrom('chunk_table','OSS://<access_id>:<secrect_key>@<Endpoint>/<bucket>/path_to/file3.TIF'));
      INSERT INTO landsat8 VALUES (4, ST_ImportFrom('chunk_table','OSS://<access_id>:<secrect_key>@<Endpoint>/<bucket>/path_to/file1.TIF'));
      說明

      PolarDB叢集需要和OSS在同一個Region中,並通過使用內部地址方式進行訪問。以上SQL語句的OSS檔案地址需要替換為實際資訊(不帶角括弧)。資料入庫成功後可以查看4景raster影像。

      SELECT ST_Name(rast), ST_Width(rast),ST_Height(rast),ST_SRID(rast),ST_NumBands(rast) FROM landsat8;
  3. 資料鑲嵌/勻色。使用Raster提供的ST_MosaicFrom函數將多景遙感影像鑲嵌為一個Raster對象,id為101。這裡通過設定"color_balance"屬性為true以支援勻色功能(按需)。然後,通過ST_BuildPyramid函數對鑲嵌後Raster對象建立金字塔資訊以提高顯示效率。具體SQL語句如下。

    --鑲嵌/勻色
    INSERT INTO landsat8 values(101, ST_MosaicFrom(Array(
      SELECT rast FROM landsat8 WHERE id < 5),
      'rbt_mosaic','',
      '{"srid":4326, "cell_size":[0.0002,0.0002], "nodata": true, "nodatavalue":0, "color_balance":true}'));
    
    --建立金字塔
    UPDATE landsat8 SET rast=st_buildpyramid(rast) WHERE id=101;

    勻色後的Raster對象匯出為GTiff格式後顯示如下:

    image

  4. 產生瓦片。使用ST_AsTile函數可以對指定範圍內的Raster對象進行裁剪,重投影,並按照256x256尺寸輸出為標準瓦片。在具體使用過程中,空間範圍可以按照Google地圖的切片方式,通過zoom的層級和行列號來換算出具體的空間範圍,然後通過下面SQL就可以擷取PNG格式的256x256的瓦片,從而可直接從地圖上展示。

    1. RGB DOM影像

      對於三波段的DOM影像,不需要額外像素值展開處理,可以直接匯出為PNG格式的Tile進行顯示。每個瓦片的空間範圍可以通過ST_TileEnvelope獲得。具體SQL如下。

      SELECT ST_AsTile(
        rast,
        ST_TileEnvelope(tile_zoom, tile_column, tile_row),
        '{"strength":"none", "format":"PNG", "alpha":true}'
      )
      FROM landsat8 WHERE id=101;

      ST_TileEnvelope參數介紹:

      • format:匯出瓦片格式,目前支援PNG、JPEG和Tiff三種格式。預設為PNG,為經過展開後可以直接顯示的RGB瓦片。如果希望對原始像素資訊進行處理,可以選擇GTiff,可以拿到最原始的像素值。

      • bands:指定RGB對應的波段,如果不指定,預設選擇前三個波段。

      • strength:顯示增強方式,取值範圍包括:

        • none:不進行增強。

        • stats(預設):使用統計值進行展開。

        • ratio:按照百分比展開。

    2. 多波段

      對於像Landsat這種多波段遙感影像,一般需要選擇3個波段,並對像素值進行展開,變成0-255範圍內的RGB波段,才能正常顯示。具體SQL語句需要修改strength和bands參數,如下:

      SELECT ST_AsTile(
        rast,
        ST_TileEnvelope(tile_zoom, tile_column, tile_row),,
        '{"strength":"ratio", "format":"PNG", "bands":"0,1,2", "alpha":true}'
      )
      FROM landsat8 WHERE id=101;

      這裡選擇0,1,2三個波段作為RGB波段,並採用ratio方式按照百分比展開。

  5. 前端設計。可以使用任何開發語言進行服務介面的開發,此處以Python環境為例。

    1. 首先安裝需要的包。

      pip install asyncpg
      pip install quart
    2. 建立app.py檔案。

      from quart import Quart, send_file, render_template
      import asyncpg
      import io
      import re
      
      ## 資料庫連接參數
      CONNECTION = {"host": "資料庫連接地址", "port": "連接埠",
                    "user": "使用者名稱", "password": "密碼", "database": "資料庫名稱"}
      
      ## 目標表名
      TABLE_NAME = "landsat8"
      
      ## 目標欄位
      RASTER_COLUMN = "rast"
      
      ## 目標ID
      RASTER_ID = "101"
      
      app = Quart(__name__, template_folder='./')
      
      
      @app.before_serving
      async def create_db_pool():
          app.db_pool = await asyncpg.create_pool(**CONNECTION)
      
      
      @app.after_serving
      async def close_db_pool():
          await app.db_pool.close()
      
      
      @app.route("/")
      async def home():
          sql = f'''
          SELECT ST_Extent(
            ST_Transform(
              ST_Envelope({RASTER_COLUMN}), 4326))
          FROM {TABLE_NAME} 
          WHERE ID = {RASTER_ID};
          '''
          async with app.db_pool.acquire() as connection:
              box = await connection.fetchval(sql)
              box = re.findall('BOX\((.*?) (.*?),(.*?) (.*?)\)', box)[0]
              min_x, min_y, max_x, max_y = list(map(float, box))
              bounds = [[min_x, min_y], [max_x, max_y]]
              center = [(min_x + max_x) / 2, (min_y + max_y) / 2]
              return await render_template('./index.jinja2', center=str(center), bounds=str(bounds))
      
      
      @app.route("/raster/<int:z>/<int:x>/<int:y>")
      async def raster(z, x, y):
          # 指定波段及展開方式
          config = '{"strength":"ratio","bands":"0,1,2","alpha":true}'
          sql = f'''
          SELECT (
            ST_AsTile({RASTER_COLUMN},
              ST_Transform(
                ST_Tileenvelope($1,$2,$3),
              ST_Srid({RASTER_COLUMN})), \'{config}\')
            ).data tile
          FROM {TABLE_NAME}
          WHERE ID = {RASTER_ID};'''
          async with app.db_pool.acquire() as connection:
              tile = await connection.fetchval(sql, z, x, y)
              return await send_file(io.BytesIO(tile), mimetype='image/png')
      
      if __name__ == "__main__":
          # 指定連接埠為5500,可自行修改為合適的連接埠
          app.run(port=5500)
    3. 啟動服務。

      python app.py
  6. 在瀏覽器中查看圖層效果.

    image

總結

GanosBase的柵格資料快顯能力,可以快速可視化儲存在PolarDB資料庫中的各類柵格資料。相較於傳統發布預製柵格瓦片服務的方式,全新的動態柵格瓦片可以更好地保持資料現勢性,同時,與GanosBase強大的柵格分析能力結合,保證分析結果即時可見。GanosBase作為全球首個專業級空間資料庫,已經將狹義的空間資料拓展至“空天地、室內外、地上下、動靜態”等全空間範疇,從資料庫系統最底層為物理世界數字化提供時空處理架構,未來GanosBase還將提供更多高效的庫內空間分析與可視化能力,推動各行業的空間資訊應用真正走向“視算一體”。

試用體驗

您可以訪問PolarDB免費試用頁面,選擇試用“雲原生資料庫PolarDB PostgreSQL版”,體驗GanosBase快顯能力。