MaxCompute 原生支援 GEOGRAPHY 地理空間資料類型,用於表示地球表面的點、線、多邊形等幾何對象,支援空間資料的儲存、構造和運算,用於高效儲存與操作地理空間資料。MaxCompute 的 GEOGRAPHY 類型底層採用 S2 Geometry 庫實現。
支援幾何類型
MaxCompute 支援構建以下幾何類型:
幾何類型 | 描述 |
Point(點) | 地球表面的一個位置,由經度和緯度座標描述,經度在前,緯度在後。樣本如下: |
LineString(線) | 一維曲線,由一系列點及其串連的測地線組成。樣本如下: |
Polygon(多邊形) | 二維面,用一條或者多條閉合的曲線來描述,其中第1條閉合的曲線用來描述它的外邊界,其他閉合曲線(如果存在)則描述多邊形中的洞,Polygon 中的洞用於描述多邊形內部的排除地區。樣本如下: |
MultiPoint | 多個點的集合。 |
MultiLineString | 多條線段的集合。 |
MultiPolygon | 多個多邊形的集合。 |
GeometryCollection | 多種幾何類型對象的集合。 |
座標以(經度, 緯度)形式給出,單位為度,遵循 WGS84 地理座標系。經度應在 [-180, 180] 範圍內,緯度應在 [-90, 90] 範圍內。
MaxCompute 的 GEOGRAPHY 類型底層採用 S2 Geometry庫實現。與傳統 GIS(地理資訊系統)庫最大的不同是,S2 不使用任何平面地圖投影(如墨卡托投影),而是直接將地球視為一個完美的球體。地球上的經緯度座標首先會被轉換成球體上的三維笛卡爾座標 (x, y, z),因此在兩極也不會產生平面投影導致的計算誤差增大問題。
S2 地理庫使用 DOUBLE 類型描述地理對象的座標,將輸入的資料轉換為 S2 地理庫對象時可能會有極微小的精度損失,導致輸入和輸出之間存在非常微小的差異。
使用限制
用戶端版本限制:查詢 GEOGRAPHY 類型資料時,若使用本地用戶端 odpscmd,需使用 0.56.0 及以上版本,且不支援設定
use_instance_tunnel=true。資料類型限制:1.0 資料類型不支援GEOGRAPHY 類型資料,使用時需要在 project 層級或 session 層級設定
odps.sql.type.system.odps2=true;開啟 2.0 資料類型版本。GEOGRAPHY 類型不支援比較操作,因此不能用於 SELECT DISTINCT、GROUP BY、ORDER BY 或作為 JOIN 的等值串連條件。
GEOGRAPHY 類型暫不支援地理類型對象的 Z(高程)或 M(測量值)維度。
GEOGRAPHY 類型不支援構造大於半個地球球體的地理對象。樣本如下:若希望通過如下 SQL 陳述式構造一個從西經 179 度到東經 179 度之間幾乎覆蓋整個地球的地理對象,而實際上得到的是一個小於半球的地理對象,其經度範圍是從東經 179 度向東,越過 180 度經線,然後到達西經 179 度。
SELECT ST_GEOGFROMTEXT( 'POLYGON ((-179 -89, 179 -89, 179 89, -179 89, -179 -89))' ); -- 返回結果: +------+ | _c0 | +------+ | POLYGON ((-179 89, 179 89, 179 -89, -179 -89, -179 89)) | +------+
建立與使用 GEOGRAPHY 資料
建表時可直接使用 GEOGRAPHY 類型作為欄位類型:
SET odps.sql.type.system.odps2=true;
CREATE TABLE spatial_points (
id BIGINT,
name STRING,
location GEOGRAPHY,
region GEOGRAPHY
);支援使用內建函數(如 ST_GEOGPOINT、ST_GEOGFROMTEXT、ST_GEOGFROMWKB、ST_MAKELINE 和 ST_MAKEPOLYGON 函數)來構造地理類型對象,詳情請參見地理函數概述。
-- 插入資料:使用地理函數構造 GEOGRAPHY 對象
INSERT INTO spatial_points VALUES
(1, '北京中心', ST_GEOGPOINT(116.4074, 39.9042),
ST_GEOGFROMTEXT('POLYGON((116.3 39.8, 116.5 39.8, 116.5 40.0, 116.3 40.0, 116.3 39.8))')),
(2, '上海外灘', ST_GEOGPOINT(121.4894, 31.2403),
ST_MAKEPOLYGON(ST_MAKELINE(ARRAY(
ST_GEOGPOINT(121.4, 31.2),
ST_GEOGPOINT(121.5, 31.2),
ST_GEOGPOINT(121.5, 31.3),
ST_GEOGPOINT(121.4, 31.3),
ST_GEOGPOINT(121.4, 31.2)
))));
-- 查詢插入的資料
SELECT * FROM spatial_points;
-- 返回結果:
+------------+---------+--------------------------+--------+
| id | name | location | region |
+------------+---------+--------------------------+--------+
| 1 | 北京中心 | POINT (116.4074 39.9042) | POLYGON ((116.3 39.8, 116.5 39.8, 116.5 40, 116.3 40, 116.3 39.8)) |
| 2 | 上海外灘 | POINT (121.4894 31.2403) | POLYGON ((121.4 31.2, 121.5 31.2, 121.5 31.3, 121.4 31.3, 121.4 31.2)) |
+------------+---------+--------------------------+--------+地理函數
MaxCompute 提供一系列以 ST_ 開頭的地理函數,用於構造、轉換和分析 GEOGRAPHY 類型的地理資料。通過這些函數,可以從經緯度座標或 WKT/WKB 文本建立點、線、多邊形等地理對象,提取座標、邊界框等屬性資訊,判斷地理對象之間的包含、相交、覆蓋等空間關係,以及計算地理對象之間的距離。
更多詳情請參見地理函數概述。
目前支援的地理函數如下:
分類 | 函數 | 說明 |
構造與解析 | 通過指定的經度和緯度構造一個 Point 類型的地理對象 | |
通過指定的端點構造 LineString 類型的地理對象 | ||
通過指定外部邊界(shell)和 0 個或多個洞(hole)構造 Polygon 類型的地理對象 | ||
將 WKT 格式的字串轉換為 GEOGRAPHY 類型的地理對象 | ||
將 WKB 格式的 BINARY 資料轉換為 GEOGRAPHY 類型的地理對象 | ||
格式化 | 將 GEOGRAPHY 值轉換為 BINARY 類型的 WKB 格式 | |
將 GEOGRAPHY 值轉換為 STRING 類型的 WKT 格式 | ||
屬性訪問 | 擷取 GEOGRAPHY 值的 BoundingBox 資訊 | |
從 POINT 類型的地理對象中擷取經度值 | ||
從 POINT 類型的地理對象中擷取緯度值 | ||
空間運算 | 判斷 value1 對應的地理對象是否包含 value2 對應的地理對象 | |
判斷 value1 對應的地理對象是否覆蓋 value2 對應的地理對象(value2 的所有點均在 value1 的邊界或內部) | ||
判斷兩個地理對象是否相交(存在至少一個公用點) | ||
判斷 value1 對應的地理對象是否被包含在 value2 對應的地理對象中 | ||
判斷兩個地理對象之間的最短距離是否小於或等於指定的距離值 | ||
計算兩個地理對象之間的最短距離,單位為米 |
空間串連(Spatial Join)
空間串連(Spatial Join)是在兩個包含 GEOGRAPHY 類型資料的表之間,基於空間謂詞函數(如 ST_CONTAINS、ST_INTERSECTS 等)判斷地理對象之間的空間關係,並以此作為串連條件的非等值串連操作。
通常用法:表中儲存 GEOGRAPHY 列,地理函數判斷空間關係,JOIN 將兩者串聯為串連條件。
典型情境包括:判斷興趣點(POI)是否落在指定地區內、分析軌跡與地理柵欄的交叉關係等。
MaxCompute 基於廣播小表實現空間串連,使用時須通過 MAPJOIN HINT 指定需廣播的小表。
更多詳情請參見Spatial JOIN(空間串連)。