使用 GeoJSON 資料函數

GeoJson 規格定義 JSON 物件的結構和內容,該物件應代表地球上的地理形狀 (稱為幾何)。根據 GeoJson 規格,若要讓 JSON 物件成為幾何物件,它必須有兩個稱為 typecoordinates 的欄位,其中類型欄位的值會指定幾何種類,而座標的值必須是其元素定義幾何圖形的陣列。

所有種類的幾何都是根據一組位置來指定。但是,對於線字串和多邊形,實際幾何圖形是由連接其位置的線條組成。GeoJson 規格將兩點之間的線條定義為直線,以連接 (平坦) 笛卡兒座標系統中的點,其水平軸與垂直軸分別為經度與緯度。

有多種內建函數可將 JSON 物件解譯為幾何,並允許搜尋包含符合特定條件之幾何的資料列。

若要隨範例一起追蹤,請使用「進階 DDL 輸入模式」從 OCI 主控台建立表格。DDL 敘述句如下所示。
CREATE TABLE IF NOT EXISTS PointsOfInterest (
    id INTEGER, poi JSON, 
PRIMARY KEY(id));

請參閱建立單一表格:進階 DDL 輸入模式,瞭解使用 DDL 敘述句建立表格的步驟。

若要將資料載入從 OCI 主控台建立的表格,請按一下表格名稱。便會顯示表格的詳細資訊。按一下上傳資料。按一下選取要上傳的檔案,然後提供要上傳的 JSON 檔案。您可以從此處下載 GeoJSON 資料的 DDL 和 JSON 檔案。

geo_inside

決定連結 GeoJSON 幾何內的幾何。
boolean geo_inside(any*, any*)
  • 第一個參數 any* 可以是任何幾何物件。
  • 第二個參數 any* 必須是多邊形。

函數會決定第一個參數所指向的幾何圖形是否完全包含在由第二個參數指向的多邊形內 。

如果兩個參數中的任一參數未傳回單一有效幾何物件,且在編譯時可偵測到該物件,則函數會發出錯誤。

執行時期行為如下:
  • 如果任一參數傳回 0 或大於 1 個項目,則傳回 false。
  • 如果任一參數傳回 NULL,則傳回 NULL。
  • 如果任何參數 (在執行時期) 傳回不是有效幾何物件的項目,則傳回 false。
  • 如果第二個參數傳回不是多邊形的幾何物件,則傳回 false。
  • 如果兩個參數均傳回單一幾何物件,而第二個幾何為多邊形。
    • 如果第一個幾何完全包含在第二個多邊形內 (即其所有點都屬於多邊形的內部),則傳回 true。
    • 否則會傳回 false。

附註:

多邊形的內部是多邊形區域中的所有點,定義多邊形邊界的線性環上的點除外。
範例:尋找北加州的自然公園。
SELECT t.poi.name AS park_name, 
t.poi.address.street AS park_location
FROM PointsOfInterest t
WHERE t.poi.kind = "nature park"
AND geo_inside(t.poi.location,
              { "type" : "polygon",
                "coordinates": [[
                  [-120.1135253906249, 36.99816565700228],
                  [-119.0972900390625, 37.391981943533544],
                  [-119.2840576171875, 37.97451499202459],
                  [-120.2069091796874, 38.035112420612975],
                  [-122.3822021484375, 37.74031329210266],
                  [-122.2283935546875, 37.15156050223665],
                  [-121.5362548828124, 36.85325222344018],
                  [-120.1135253906249, 36.99816565700228]
                ]]
             });
說明:
  • 您可以查詢 PointsOfInterest 表格來篩選自然公園的資料列。
  • 您可以指定多邊形作為 geo_inside 函數的第二個參數。
  • 您所指定的多邊形座標會與美國加州北部地區的座標相對應。
  • 當自然公園的位置完全包含在指定的位置點內時,geo_inside 函數只會傳回列。
結果:
{"park_name":"portola redwoods state park",
"park_location":"15000 Skyline Blvd"}

geo_intersect

決定與 GeoJSON 幾何相交的幾何圖形。
boolean geo_intersect(any*, any*)

第一個和第二個參數 any* 可以是任何幾何物件。

此函數可確定指定為參數的兩個幾何圖形是否具有共通點。如果兩個參數中的任一參數未傳回單一有效幾何物件,且在編譯時可偵測到該物件,則函數會發出錯誤。

執行時期行為如下:
  • 如果任一參數傳回 0 或大於 1 個項目,則傳回 false。
  • 如果任一參數傳回 NULL,則傳回 NULL。
  • 如果任何參數 (在執行時期) 傳回不是有效幾何物件的項目,則傳回 false。

如果兩個參數各傳回單一幾何物件,則如果 2 個幾何具有共通點,函數會傳回 true;否則為 false。

範例:德州正在考慮對地下供水的管制存取。水層是承受水滲透的岩石、岩石破裂或未合併材料的地下層。政府希望對接近水層的地點實施新規定。

水層座標已映射 。您想知道德州的所有國家與該水層交會,以便您可以通知各受影響縣政府參與新規定的會談。
SELECT t.poi.county AS County_needs_regulation,
t.poi.contact AS Contact_phone
FROM PointsOfInterest t WHERE
geo_intersect(
    t.poi.location,
    { 

     "type" : "polygon",
      "coordinates": [
          [
            [-97.668457031249, 29.34387539941801],
            [-95.207519531258, 29.19053283229458],
            [-92.900390625653, 30.37287518811801],
            [-94.636230468752, 32.21280106801518],
            [-97.778320312522, 32.45415593941475],
            [-99.799804687541, 31.18460913574325],
            [-97.668457031249, 29.34387539941801]
          ]
        ]
    }
);
說明:
  • 上述查詢會擷取與水層位置相交的位置。也就是說,如果位置座標具有與水層位置共通的任何點。
  • 您可以使用 geo_intersect 來查看位置的座標是否有任何與指定之層座標共用的點。
結果:
{"County_needs_regulation":"Tarrant","Contact_phone":"469 745 5687"}
{"County_needs_regulation":"Kinga","Contact_phone":"469 384 7612"}

geo_distance

決定兩個空間物件之間的距離。
double geo_distance(any*, any*)

第一個和第二個參數 any* 可以是任何幾何物件。

此函數會傳回兩個輸入幾何之間的大地距離。傳回的距離是第一個點屬於第一個幾何圖形和第二個點到第二個幾何圖形之任何一對點的距離中的最小值。這兩個點之間,它們的距離是連接點的大地線長度。

大地線概要

介於 2 個點間的大地線是可以繪製在地球橢球表面上 2 個點之間的最短線。對於簡化但更具說明性的定義,假設地球表面為球體的一刻。然後,地球上兩個點之間的大地線是與點相對應之大圓上兩個點之間的小弧,也就是由球體交點形成的圓,以及由地球中心與兩點定義的平面。

下圖顯示洛杉磯與倫敦之間大地線與直線之間的差異。


如果兩個參數中的任一參數未傳回單一有效幾何物件,且在編譯時可偵測到該物件,則函數會發出錯誤。

執行時期行為如下:
  • 如果任一參數傳回零或超過 1 個項目,則傳回 -1。
  • 如果任一參數傳回 NULL,則傳回 NULL。
  • 如果任一參數不是幾何物件,則傳回 -1。
否則,此函數會傳回 2 個輸入幾何之間的大地距離 (公尺)。

附註:

結果會依距離遞增排序 (先顯示最短距離)。
範例:指定地點最近的餐廳多遠?
SELECT 
t.poi.name AS restaurant_name,
t.poi.address.street AS street_name,
geo_distance(
    t.poi.location,
    { 
       "type" : "point",
       "coordinates": [-121.94034576416016,37.2812239247177]
    }
) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "restaurant" ;
說明:
  • 您可以查詢 PointsOfInterest 表格來篩選餐廳的資料列。
  • 您可以使用 geo_distance 函數提供正確的位置點並判斷距離。
結果:
{"restaurant_name":"Coach Sports Bar & Grill","street_name":"80 Edward St","distance_in_meters":799.2645323337218}
{"restaurant_name":"Ricos Taco","street_name":"80 East Boulevard St","distance_in_meters":976.5361117138553}
{"restaurant_name":"Effie's Restaurant and Bar","street_name":"80 Woodeard St","distance_in_meters":2891.0508307646282}    

目前位置與最近餐廳之間的距離為 799 公尺。

geo_within_distance

決定與點相鄰的地理空間物件。
boolean geo_within_distance(any*, any*,double)

第一個和第二個參數 any* 可以是任何幾何物件。

該函數確定第一個幾何圖形在 N 公尺與第二個幾何圖形的距離內。

如果兩個參數中的任一參數未傳回單一有效幾何物件,且在編譯時可偵測到該物件,則函數會發出錯誤。

執行時期行為如下:
  • 如果任一參數傳回 0 或大於 1 個項目,則傳回 false。
  • 如果前兩個參數中的任一個傳回 NULL,則傳回 NULL。
  • 如果前兩個參數中的任一個傳回不是有效幾何物件的項目,則傳回 false。

最後,如果兩個參數各傳回單一幾何物件,則如果第一個幾何在 N 公尺與第二個幾何的距離內,則傳回 true,其中 N 是第三個參數傳回的數字;否則為 false。2 個幾何之間的距離定義為第一點屬於第一個幾何圖形和第二點至第二個幾何圖形的任何一對點之間的距離的最小值。如果 N 為負數,則會設定為 0。

範例:接下來 5 公里是否有市政廳?多遠?
SELECT t.poi.address.street AS city_hall_address,
geo_distance(
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-120.653828125,38.85682013474361]
    }

) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "city hall" AND
geo_within_distance( 
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-120.653828125,38.85682013474361]
    },
    5000
);
說明:
  • 您可以查詢 PointsOfInterest 表格來篩選市政廳的資料列。
  • 您可以使用 geo_within_distance 函數來篩選指定位置 5 公里 (5000m) 內的市政廳。
  • 您也可以使用 geo_distance 函數擷取您所在位置與市政廳之間的實際距離。
結果:
{"city_hall_address":"70 North 1st street","distance_in_meters":1736.0144040331768}

市政廳距離目前位置 1736 米 (1.73 公里)。

geo_near

決定與點相鄰的地理空間物件。
boolean geo_near(any*, any*, double)

第一個和第二個參數 any* 可以是任何幾何物件。

該函數確定第一個幾何圖形在 N 公尺與第二個幾何圖形的距離內。

如果兩個參數中的任一參數未傳回單一有效幾何物件,且在編譯時可偵測到該物件,則函數會發出錯誤。

執行時期行為如下:
  • 如果任一參數傳回 0 或大於 1 個項目,則傳回 false。
  • 如果前兩個參數中的任一個傳回 NULL,則傳回 NULL。
  • 如果前兩個參數中的任一個傳回不是有效幾何物件的項目,則傳回 false。
最後,如果前兩個參數中兩個參數均傳回單一幾何物件,則如果第一個幾何從第二個幾何處算起 N 公尺的距離內,則傳回 true,其中 N 是第三個參數傳回的數字;否則為 false。

附註:

geo_near 會依兩個幾何之間的距離,在內部轉換成 geo_within_distance 加上 (隱含) 順序。不過,如果查詢已有 (明確) 排序依據,則不會執行依距離排序。geo_near 函數只能出現在 WHERE 子句中,其中必須是最上層述詞 (亦即,非巢狀在 OR 或 NOT 運算子之下)。
範例 1:指定地點的 3 公里內是否有醫院?
SELECT 
t.poi.name AS hospital_name,
t.poi.address.street AS hospital_address
FROM PointsOfInterest t
WHERE t.poi.kind = "hospital" 
AND
geo_near( 
    t.poi.location,
    {"type" : "point",
     "coordinates" : [-122.03493933105469,37.32949164059004]  
    },
    3000
);
說明:
  • 您可以查詢 PointsOfInterest 表格來篩選醫院的資料列。
  • 您可以使用 geo_near 函數來篩選指定地點之 3000m 內的醫院。
結果:
{"hospital_name":"St. Marthas hospital","hospital_address":"18000 West Blvd"}
{"hospital_name":"Memorial hospital","hospital_address":"10500 South St"}
範例 2:從指定地點起,下一個英里內的燃氣站是多遠?
SELECT 
t.poi.address.street AS gas_station_address,
geo_distance(
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-121.90768646240233,37.292081740702365] 
    }
) AS distance_in_meters
FROM PointsOfInterest t
WHERE t.poi.kind = "gas station" AND
geo_near( 
    t.poi.location,
    { 
        "type" : "point",
        "coordinates" : [-121.90768646240233,37.292081740702365]
    },
    1600
);
說明:
  • 您可以查詢 PointsOfInterest 表格來篩選氣體站的資料列。
  • 您可以使用 geo_near 函數在指定位置的一英里 (1600m) 內篩選燃氣站。
  • 您還可以使用 geo_distance 函數擷取您所在位置與燃氣站之間的實際距離。
結果:
{"gas_station_address":"33 North Avenue","distance_in_meters":886.7004173859665}

下一英里內與最近燃氣站的實際距離為 886m。

geo_is_geometry

驗證地理空間物件。
boolean geo_is_geometry(any*)

參數 any* 可以是任何幾何物件。

函數會決定指定的輸入是否為有效的幾何物件。
  • 如果參數傳回零或大於 1 個項目,則傳回 false。
  • 如果參數傳回 NULL,則傳回 NULL。
  • 如果輸入是單一有效幾何物件,則傳回 true。否則,False。
範例:決定指向市政廳的位置是否為有效的幾何物件。
SELECT geo_is_geometry(t.poi.location) AS city_hall
FROM PointsOfInterest t
WHERE t.poi.kind = "city hall" 

說明:您可以使用函數 geo_is_geometry 來判斷指定的位置是否為有效的幾何物件。

結果:
{ "city_hall" : true}