使用 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 语句创建表的步骤,请参见 Creating Singleton Table:Advanced DDL Input Mode

要将数据加载到从 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。
  • 如果任何参数返回 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 表以筛选 restaurant 的行。
  • 您可以使用 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 米的距离内(其中 N 是第三个参数返回的数字),则返回 true;否则返回 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 表以筛选 city hall 的行。
  • 您可以使用 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 表以过滤 gas station 的行。
  • 您可以使用 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* 可以是任何几何对象。

该函数确定给定输入是否为有效的几何对象。
  • 如果参数返回零个或多个项,则返回 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}