使用 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 文件

地理内侧

确定边界 GeoJSON 几何内的几何图形。

boolean geo_inside(any*, any*)

该函数确定由第一个参数指向的几何体是否完全包含在由第二个参数指向的多边形内。

如果这两个参数中的任何一个没有返回一个有效的几何对象,并且如果可以在编译时检测到它,则函数会引发错误。

运行时行为如下:

注:多边形的内部是多边形区域中的所有点,但定义多边形边界的线性环上的点除外。

示例:查看北加利福尼亚州的自然公园。

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]
                ]]
             });

说明:

结果:

{"park_name":"portola redwoods state park",
"park_location":"15000 Skyline Blvd"}

地理交集

确定与 GeoJSON 几何相交的几何图形。

boolean geo_intersect(any*, any*)

第一个和第二个参数 any* 可以是任何几何对象。

该函数确定指定为参数的两个几何体是否具有任何共同点。如果这两个参数中的任何一个没有返回一个有效的几何对象,并且如果可以在编译时检测到它,则函数会引发错误。

运行时行为如下:

如果两个参数都返回单个几何对象,则如果 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]
          ]
        ]
    }
);

说明:

结果:

{"County_needs_regulation":"Tarrant","Contact_phone":"469 745 5687"}
{"County_needs_regulation":"Kinga","Contact_phone":"469 384 7612"}

地理距离

确定两个地理空间对象之间的距离。

double geo_distance(any*, any*)

第一个和第二个参数 any* 可以是任何几何对象。

该函数返回两个输入几何体之间的大地测量距离。返回的距离是第一点属于第一几何体且第二点属于第二几何体的任何对点的距离中的最小值。在两个这样的点之间,它们的距离是连接点的大地测量线的长度。

测地线概览

2 点之间的大地测量线是最短的线,可以在地球椭圆表面的 2 点之间绘制。对于一个简化但更具说明性的定义,暂时假设地球表面是一个球体。然后,地球上的两个点之间的大地测量线是大圆上两个点之间的小弧,对应于这些点,即由球体的交叉点形成的圆,以及由地球中心和两个点定义的平面。

下图显示了洛杉矶和伦敦之间的大地测量线和直线之间的差异。

后面是 geodetic-vs-straight-line.jpg 的说明

插图 geodetic-vs-straight-line.jpg 的说明

如果这两个参数中的任何一个没有返回一个有效的几何对象,并且如果可以在编译时检测到它,则函数会引发错误。

运行时行为如下:

否则,该函数将返回 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" ;

说明:

结果:

{"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 米。

距离内

确定靠近某个点的地理空间对象。

boolean geo_within_distance(any*, any*,double)

第一个和第二个参数 any* 可以是任何几何对象。

该函数确定第一个几何体是否在距离第二个几何体 N 米的距离内。

如果这两个参数中的任何一个没有返回一个有效的几何对象,并且如果可以在编译时检测到它,则函数会引发错误。

运行时行为如下:

最后,如果两个参数都返回单个几何对象,则如果第一个几何对象在距离第二个几何对象 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
);

说明:

结果:

{"city_hall_address":"70 North 1st street","distance_in_meters":1736.0144040331768}

市政厅距离当前位置有 1736 米(1.73 公里)。

地理附近

确定靠近某个点的地理空间对象。

boolean geo_near(any*, any*, double)

第一个和第二个参数 any* 可以是任何几何对象。

该函数确定第一个几何体是否在距离第二个几何体 N 米的距离内。

如果这两个参数中的任何一个没有返回一个有效的几何对象,并且如果可以在编译时检测到它,则函数会引发错误。

运行时行为如下:

最后,如果前两个参数都返回单个几何对象,则如果第一个几何对象在距离第二个几何对象的 N 米的距离内(其中 N 是第三个参数返回的数字),则返回 true;否则返回 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
);

说明:

结果:

{"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
);

说明:

结果:

{"gas_station_address":"33 North Avenue","distance_in_meters":886.7004173859665}

到下一英里内最近的加油站的实际距离是 886 米。

几何图形

验证地理空间对象。

boolean geo_is_geometry(any*)

参数 any* 可以是任何几何对象。

该函数确定给定输入是否为有效的几何对象。

示例:确定指向市政厅的位置是否为有效的几何对象。

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}

相关主题