OceanBase V4.2特性解析:MySQL模式下GIS空间表达式的场景及能力解析

news2024/11/13 9:31:33

1. 背景

1.1. OceanBase Mysql gis空间表达式的应用场景及能力

在OceanBase 4.1版本中,mysql模式下支持了gis数据类型以及部分空间对象相关的表达式,随着客户使用空间数据的需求日益增长,需要快速地补齐空间数据存储和计算分析的能力;

针对mysql的空间表达式的能力,目前补齐了部分gis表达式,包括:

  • 空间关系计算表达式:判断空间关系是否成立(ST_Crosses/ST_Overlaps)
  • 空间对象计算表达式:根据输入的空间对象计算出新的空间对象(ST_Difference/ST_Union/ST_SymDifference)
  • 空间对象测量表达式:测量空间对象长度(ST_Length)
  • 空间对象分析表达式:计算空间对象质心点(ST_Centroid)
  • 空间对象格式转换表达式:空间对象转换为json类型(ST_AsGeoJSON)

pg作为gis行业使用最广的数据库,提供了部分空间表达式的功能是mysql不具备的,且该部分表达式也被广泛应用,同时pg还支持3维空间对象存储。因此ob在兼容mysql gis的能力基础上也对空间表达式的能力进行了扩展补充,作为ob mysql模式下特有的空间表达式(这部分空间表达式以'_'做为前缀);包括以下几类:

    • 空间关系计算表达式:判断空间关系是否成立(_ST_Touches/_ST_Equals)
    • 空间对象构造表达式:构造空间对象(_ST_MakeEnvelope/)
    • 空间对象计算表达式:根据输入的空间对象计算出新的空间对象(_ST_ClipByBox2D)
    • 空间对象属性访问表达式:查询空间对象某一属性(_ST_GeometryType/_ST_IsCollection/_ST_NumInteriorRings)
    • 空间对象分析表达式:计算一个保证位于几何体内部的点(_ST_PointOnSurface)
    • 空间对象格式转换表达式:空间对象转换为mapbox vector tile格式(ST_AsMVTGeom/_ST_AsMVT)

ob mysql gis也支持了3维空间对象的存储能力。

1.2  OceanBase v4.2.2,Mysql gis空间表达式的特性支持

OceanBase 4.2.2版本下新增的兼容mysql gis空间表达式如下:

表达式名称功能介绍
boolean ST_Crosses(geometry g1, geometry g2)判断两个Geometry g1和g2在空间上是否有交叉,即几何体内部有部分点相同,但不完全相同
boolean ST_Overlaps(geometry g1, geometry g2)判断两个几何体是否空间上相交且具有相同的维度,但并不完全互相包含。
geometry ST_Difference(geometry g1, geometry g2)返回geometry g1中不和geometry g2相交的部分,等价于g1 - ST_Intersection(g1, g2)
geometry ST_Union(geometry g1, geometry g2)返回geometry g1和geometry g2的并集
geometry ST_Length(geometry g1, unit string)计算LineString类型或MultiLinestring类型的长度,该长度和线段所在空间坐标系有关,MultiLinestring类型的长度等于其包含的LineString长度之和;unit参数指定了长度显示单位
geometry ST_SymDifference(geometry geomA, geometry geomB)返回geometry A和Geometry B不重叠的部分,等价于ST_Difference(ST_Union(g1, g2), ST_Intersection(g1, g2))。
ST_AsGeoJSON(g [, max_dec_digits [, options]])将geometry转换为对应的json格式,包含两个可选参数max_dec_digits和flag。
ST_Centroid(geometry A)计算几何体的质心点,该质心点不保证在几何体上

此外,新增ob mysql特有gis空间表达式如下:

表达式名称功能介绍
geometry _ST_PointOnSurface(geometry g1)返回一个保证位于几何体内部的点,和ST_Centroid不同,ST_Centroid返回的中心点不一定在几何体上
geometry _ST_MakeEnvelope(float xmin, float ymin, float xmax, float ymax, integer srid=unknown);该函数通过输入左下角坐标与右上角坐标,构造一个矩形;
geometry _ST_ClipByBox2D(geometry geom, box2d box);通过Box快速剪裁几何体,不会检查输入几何体的合法性,也不保证输出的几何体是合法的。该函数第二个参数虽然是Box,但实际上可以输入任意Geometry,会隐式转换为Box
text _ST_GeometryType(geometry g1);返回Geometry的类型
boolean _ST_IsCollection(geometry g1);判断输入的Geometry是否为集合类型
integer _ST_NumInteriorRings(geometry a_polygon);返回Polygon的内环数,如果Geometry非Polygon类型,则返回NULL
boolean _ST_Touches(geometry A, geometry B)判断两个Geometry A和B边界是否至少有一个共同点,且内部不相交。注意若两个Geometry均为Point类型,直接返回false,因为Point没有边界
boolean ST_Equals(geometry A, geometry B);判断两个Geometry A和B是否在空间结构上相等,即包含相同的点集,但不考虑点集顺序是否一致
bytea _ST_AsMVT(table_name.*, text name, integer extent, text geom_name, text feature_id_name);将一组行聚合返回一个使用Google Protocol Buffers编码格式二进制的mapbox矢量瓦片,blob类型;第一个参数是必须的,后面的参数可选
geometry _ST_MakeValid(geometry input);尝试将输入的无效的多边形修复为一个有效的多边形
geometry ST_AsMVTGeom(geometry geom, // 输入空间对象 box2d bounds, // MVT空间坐标范围 integer extent=4096, // 矢量切片的范围(4096个单位) integer buffer=256, // 缓存区大小 boolean clip_geom=true);将一个输入的空间对象转换到bounds定义的map vector tile空间坐标系下,超出bounds的部分且位于buffer指定的缓冲区以内的部分根据clip_geom参数的配置来决定是否裁剪;map vector tile空间坐标系起始点位于左上角(屏幕参考系);转换后输出的满足mapbox vector tile 规范的有效geometry,常作为st_asmvt的入参。

支持3维gis数据存储,gis表达式适配3维数据分类如下:

  • 输入WKT/WKB格式数据构造空间对象的表达式,支持输入3维数据构造空间对象;
  • 将存储的空间数据转换成指定格式WKT/WKB/EWKB/EWKT输出的表达式,支持查询3维空间数据;
  • 不支持输入3D数据;
类型表达式功能适配内容
构造空间对象st_geomfromtext输入wkt格式创建几何值如果是3d geo,跳过检查经纬度范围的逻辑;封装geo_to_wkb,增加3d-wkb格式转成swkb;
st_geometryfromtext输入wkt格式创建几何值
_st_geomfromewkt输入ewkt格式创建几何值同上
_st_geogfromtext输入wkt格式创建几何值,默认geography坐标系同上
_st_geographyfromtext输入wkt格式创建几何值,默认geography坐标系
st_geomfromwkb输入wkb格式创建几何值增加校验3d wkb格式是否合法
st_geometryfromwkb输入wkb格式创建几何值
_st_geomfromewkb输入ewkb格式创建几何值3d-ewkb和iso 3d-wkb的type表示的方式不一样,需要做转换同样需要校验输入的wkb是否合法
格式转换st_astext/st_aswkt输出wkt格式读取swkb转换成geo对象,然后转换成3d-wkt格式。
st_aswkb/st_asbinary输出wkb格式swkb转wkb
_st_asewkb输出ewkb格式ewkb转wkb
_st_asewkt输出ewkt格式wkt前面需要加上"srid=xxx"
空间计算表达式st_area计算空间对象面积将3维空间数据转为2维处理
st_intersects计算两个空间对象是否相交
st_transform将一个空间对象的坐标转换到指定的空间坐标系下
_st_covers计算空间对象A是否包含空间对象B
st_buffer计算一个距离小于或等于给定距离的所有点的POLYGON/MULTIPOLYGON
st_distance计算两个空间对象间距离
_st_dwithin计算空间对象A是否在一定距离内被包含于空间对象B
st_distance_sphere返回球体上两个点和/或多点之间的最小球面距离
st_contains计算空间对象A是否包含空间对象B
st_within计算空间对象A是否包含于空间对象B
ST_Crosses判断两个Geometry g1和g2在空间上是否有交叉,即几何体内部有部分点相同,但不完全相同
ST_Overlaps判断两个几何体是否空间上相交且具有相同的维度,但并不完全互相包含。
_ST_Touches判断两个Geometry A和B边界是否至少有一个共同点,且内部不相交。注意若两个Geometry均为Point类型,直接返回false,因为Point没有边界
ST_Equals判断两个Geometry A和B是否在空间结构上相等,即包含相同的点集,但不考虑点集顺序是否一致
  • 以下表达式支持空间索引
表达式名称功能介绍
boolean ST_Crosses(geometry g1, geometry g2)判断两个Geometry g1和g2在空间上是否有交叉,即几何体内部有部分点相同,但不完全相同
boolean ST_Overlaps(geometry g1, geometry g2)判断两个几何体是否空间上相交且具有相同的维度,但并不完全互相包含。
boolean _ST_Touches(geometry A, geometry B)判断两个Geometry A和B边界是否至少有一个共同点,且内部不相交。注意若两个Geometry均为Point类型,直接返回false,因为Point没有边界
boolean ST_Equals(geometry A, geometry B);判断两个Geometry A和B是否在空间结构上相等,即包含相同的点集,但不考虑点集顺序是否一致

2. 使用操作

2.1. ST_Crosses(g1,g2)

支持空间索引,判断两个Geometry g1和g2在空间上是否有交叉,即几何体内部有部分点相同,但不完全相同。

OceanBase(root@oceanbase)>select st_crosses(st_geomfromtext('LINESTRING(1 1, 11 11)'), st_geomfromtext('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));
+------------------------------------------------------------------------------------------------------------------+
| st_crosses(st_geomfromtext('LINESTRING(1 1, 11 11)'), st_geomfromtext('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))')) |
+------------------------------------------------------------------------------------------------------------------+
|                                                                                                                1 |
+------------------------------------------------------------------------------------------------------------------+
1 row in set (0.004 sec)

2.2. ST_Overlaps(g1,g2)

支持空间索引,判断两个几何体是否空间上相交且具有相同的维度,但并不完全互相包含。

OceanBase(root@oceanbase)>SELECT ST_OVERLAPS(ST_GEOMFROMTEXT('POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 5,5 5,5 0,0 0))'));
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_OVERLAPS(ST_GEOMFROMTEXT('POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 5,5 5,5 0,0 0))')) |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                                                                               1 |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.005 sec)

2.3. ST_Difference(g1,g2)

返回geometry A中不和geometry B相交的部分,等价于A - ST_Intersection(A, B)

OceanBase(root@oceanbase)>SELECT ST_AsText(ST_Difference(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)')));
+----------------------------------------------------------------------------------------------------------------------+
| ST_AsText(ST_Difference(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)'))) |
+----------------------------------------------------------------------------------------------------------------------+
| LINESTRING(50 150,50 200)                                                                                            |
+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.004 sec)

2.4. ST_Union(g1,g2)

返回geometry A和geometry B的并集

OceanBase(root@oceanbase)>SELECT ST_AsText(ST_Union(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)')));
+-----------------------------------------------------------------------------------------------------------------+
| ST_AsText(ST_Union(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)'))) |
+-----------------------------------------------------------------------------------------------------------------+
| MULTILINESTRING((50 100,50 200),(50 50,50 100))                                                                 |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.004 sec)

2.5. ST_Length(ls[,unit])

unit参数指定了长度显示单位,默认为metre(米),常见的有foot、centimetre等。全部单位和其对应转换系数如下,当且仅当srid != 0且单位合法时生效。

+--------------------------------------+---------------------+
| UNIT_NAME                            | CONVERSION_FACTOR   |
+--------------------------------------+---------------------+
| British chain (Benoit 1895 A)        |          20.1167824 |
| British chain (Benoit 1895 B)        |  20.116782494375872 |
| British chain (Sears 1922 truncated) |           20.116756 |
| British chain (Sears 1922)           |  20.116765121552632 |
| British foot (1865)                  | 0.30480083333333335 |
| British foot (1936)                  |        0.3048007491 |
| British foot (Benoit 1895 A)         |  0.3047997333333333 |
| British foot (Benoit 1895 B)         | 0.30479973476327077 |
| British foot (Sears 1922 truncated)  | 0.30479933333333337 |
| British foot (Sears 1922)            |  0.3047994715386762 |
| British link (Benoit 1895 A)         |         0.201167824 |
| British link (Benoit 1895 B)         |  0.2011678249437587 |
| British link (Sears 1922 truncated)  |          0.20116756 |
| British link (Sears 1922)            |  0.2011676512155263 |
| British yard (Benoit 1895 A)         |           0.9143992 |
| British yard (Benoit 1895 B)         |  0.9143992042898124 |
| British yard (Sears 1922 truncated)  |            0.914398 |
| British yard (Sears 1922)            |  0.9143984146160288 |
| centimetre                           |                0.01 |
| chain                                |             20.1168 |
| Clarke's chain                       |       20.1166195164 |
| Clarke's foot                        |        0.3047972654 |
| Clarke's link                        |      0.201166195164 |
| Clarke's yard                        |        0.9143917962 |
| fathom                               |              1.8288 |
| foot                                 |              0.3048 |
| German legal metre                   |        1.0000135965 |
| Gold Coast foot                      |  0.3047997101815088 |
| Indian foot                          | 0.30479951024814694 |
| Indian foot (1937)                   |          0.30479841 |
| Indian foot (1962)                   |           0.3047996 |
| Indian foot (1975)                   |           0.3047995 |
| Indian yard                          |  0.9143985307444408 |
| Indian yard (1937)                   |          0.91439523 |
| Indian yard (1962)                   |           0.9143988 |
| Indian yard (1975)                   |           0.9143985 |
| kilometre                            |                1000 |
| link                                 |            0.201168 |
| metre                                |                   1 |
| millimetre                           |               0.001 |
| nautical mile                        |                1852 |
| Statute mile                         |            1609.344 |
| US survey chain                      |   20.11684023368047 |
| US survey foot                       | 0.30480060960121924 |
| US survey link                       |  0.2011684023368047 |
| US survey mile                       |  1609.3472186944375 |
| yard                                 |              0.9144 |
+--------------------------------------+---------------------+
OceanBase(root@oceanbase)>SET @ls = ST_GeomFromText('LineString(1 1,2 2,3 3)', 4326);
Query OK, 0 rows affected (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_Length(@ls, "foot");
+------------------------+
| ST_Length(@ls, "foot") |
+------------------------+
|     1029205.9131247795 |
+------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_Length(@ls);
+-------------------+
| ST_Length(@ls)    |
+-------------------+
| 313701.9623204328 |
+-------------------+
1 row in set (0.004 sec)

2.6. _ST_PointOnSurface

定义:geometry _st_pointonsurface(a geometry),返回geometry类型为POINT。

返回一个保证位于几何体内部的点,和ST_Centroid不同,ST_Centroid返回的中心点不一定在几何体上。例如下图绿色点为中心点,红色点为ST_PointOnSurface所返回的内部点。

1715851019

棕色:中心点,绿色:内部点

OceanBase(root@oceanbase)>SELECT ST_AsText(_ST_PointOnSurface(geom)) AS pt_on_surf,
    -> ST_AsText(ST_Centroid(geom)) AS centroid
    -> FROM (SELECT ST_GeomFromText('POLYGON ((0 0, 0 10, 10 10, 10 8, 2 8, 2 2, 10 2, 10 0, 0 0))') AS geom) AS t;
+------------+----------------------------+
| pt_on_surf | centroid                   |
+------------+----------------------------+
| POINT(1 5) | POINT(4.076923076923077 5) |
+------------+----------------------------+
1 row in set (0.001 sec)

2.7. _ST_MakeEnvelope

该函数通过输入左下角坐标与右上角坐标,构造一个矩形,常作为以Box为参数的其他函数的输入

-- 定义
geometry _ST_MakeEnvelope(float xmin, float ymin, float xmax, float ymax, integer srid=unknown);

-- 构造矩形
OceanBase(root@oceanbase)>SELECT ST_AsText( _ST_MakeEnvelope(10, 10, 11, 11, 4326) );
+-----------------------------------------------------+
| ST_AsText( _ST_MakeEnvelope(10, 10, 11, 11, 4326) ) |
+-----------------------------------------------------+
| POLYGON((10 10,11 10,11 11,10 11,10 10))            |
+-----------------------------------------------------+
1 row in set (0.004 sec)

-- 作为其他函数的输入
-- Rely on implicit cast from geometry to box2d for the second parameter
OceanBase(root@oceanbase)>SELECT ST_ASTEXT(_ST_ClipByBox2D(ST_GEOMFROMTEXT('POLYGON((-2 -2, -2 11, 11 11, 11 -2, -2 -2))'), 
    ->                       _ST_MakeEnvelope(0,0,10,10)));
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_ASTEXT(_ST_ClipByBox2D(ST_GEOMFROMTEXT('POLYGON((-2 -2, -2 11, 11 11, 11 -2, -2 -2))'), 
                      _ST_MakeEnvelope(0,0,10,10))) |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| POLYGON((0 0,0 10,10 10,10 0,0 0))                                                                                                              |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.005 sec)

2.8. _ST_ClipByBox2D

geometry _ST_ClipByBox2D(geometry geom, box2d box);

通过Box快速剪裁几何体,不会检查输入几何体的合法性,也不保证输出的几何体是合法的。

该函数第二个参数虽然是Box,但实际上可以输入任意Geometry,会转换为对应的Box。

OceanBase(root@oceanbase)>SELECT ST_ASTEXT(_ST_ClipByBox2D(ST_GEOMFROMTEXT('POLYGON((-2 -2, -2 11, 11 11, 11 -2, -2 -2))'), 
    ->                       _ST_MakeEnvelope(0,0,10,10)));
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_ASTEXT(_ST_ClipByBox2D(ST_GEOMFROMTEXT('POLYGON((-2 -2, -2 11, 11 11, 11 -2, -2 -2))'), 
                      _ST_MakeEnvelope(0,0,10,10))) |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| POLYGON((0 0,0 10,10 10,10 0,0 0))                                                                                                              |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.005 sec)

2.9. _ST_GeometryType

返回Geometry的SQL-MM类型,格式为ST_[TYPE]

OceanBase(root@oceanbase)>SELECT _ST_GeometryType(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
+--------------------------------------------------------------------------------------------------+
| _ST_GeometryType(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)')) |
+--------------------------------------------------------------------------------------------------+
| ST_LineString                                                                                    |
+--------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

2.10. _ST_IsCollection

判断输入的Geometry是否为集合类型,包括

  1. GEOMETRYCOLLECTION
  2. MULTI{POINT,POLYGON,LINESTRING,CURVE,SURFACE}
  3. COMPOUNDCURVE,OB暂不支持,报错处理
OceanBase(root@oceanbase)> SELECT _ST_IsCollection(st_geomfromtext('LINESTRING(0 0, 1 1)'));
+-----------------------------------------------------------+
| _ST_IsCollection(st_geomfromtext('LINESTRING(0 0, 1 1)')) |
+-----------------------------------------------------------+
|                                                         0 |
+-----------------------------------------------------------+
1 row in set (0.003 sec)

2.11. _ST_NumInteriorRings

返回Polygon的内环数,如果Geometry非Polygon类型,则返回NULL

-- 定义
integer _ST_NumInteriorRings(geometry a_polygon);

-- 示例
OceanBase(root@oceanbase)>select _ST_NumInteriorRings(ST_GeomFromText('POLYGON((2 2 1,2 8 5,8 8 7,8 2 4,2 2 1))'));
+-----------------------------------------------------------------------------------+
| _ST_NumInteriorRings(ST_GeomFromText('POLYGON((2 2 1,2 8 5,8 8 7,8 2 4,2 2 1))')) |
+-----------------------------------------------------------------------------------+
|                                                                                 0 |
+-----------------------------------------------------------------------------------+
1 row in set (0.003 sec)

2.12. _ST_Touches

支持空间索引,判断两个Geometry A和B边界是否至少有一个共同点,且内部不相交。注意若两个Geometry均为Point类型,直接返回false,因为Point没有边界。

OceanBase(root@oceanbase)>SELECT _ST_Touches(st_geomfromtext('LINESTRING(0 0, 1 1, 0 2)'),
    ->                    st_geomfromtext('POINT(0 2)'));
+-------------------------------------------------------------------------------------------------------------+
| _ST_Touches(st_geomfromtext('LINESTRING(0 0, 1 1, 0 2)'),
                   st_geomfromtext('POINT(0 2)')) |
+-------------------------------------------------------------------------------------------------------------+
|                                                                                                           1 |
+-------------------------------------------------------------------------------------------------------------+
1 row in set (0.003 sec)

2.13. ST_Equals

支持空间索引,判断两个Geometry A和B是否在空间结构上相等,即包含相同的点集,但不考虑点集顺序是否一致。

OceanBase(root@oceanbase)>SELECT ST_Equals(ST_GeomFromText('LINESTRING(0 0, 10 10)'),
    -> ST_GeomFromText('LINESTRING(0 0, 5 5, 10 10)'));
+-------------------------------------------------------------------------------------------------------+
| ST_Equals(ST_GeomFromText('LINESTRING(0 0, 10 10)'),
ST_GeomFromText('LINESTRING(0 0, 5 5, 10 10)')) |
+-------------------------------------------------------------------------------------------------------+
|                                                                                                     1 |
+-------------------------------------------------------------------------------------------------------+
1 row in set (0.003 sec)

2.14. _ST_AsMVT

功能:将表包含gis列的所有行数据聚合返回一个使用Google Protocol Buffers编码格式二进制的mapbox矢量瓦片;

OceanBase(root@oceanbase)>SELECT 'TG1', hex(_ST_AsMVT(q.*, 'test', 4096, 'geom')) FROM (SELECT 1 AS c1, ST_GeomFromText('POINT(25 17)')AS geom) AS q;
+-----+----------------------------------------------------------------------+
| TG1 | hex(_ST_AsMVT(q.*, 'test', 4096, 'geom'))                            |
+-----+----------------------------------------------------------------------+
| TG1 | 1A200A0474657374120B12020000180122030932221A026331220228012880207802 |
+-----+----------------------------------------------------------------------+
1 row in set (0.004 sec)

上例中_ST_AsMVT中生成的结果中编码了字段C1和它的值(1)、字段geom和它的值('POINT(25 17)')点的信息;

参数说明:

  • row:聚合的一组行,表名.*
  • name:layer的命名,默认为"default"
  • extent:瓦片的范围(默认4096个单位, 4096 * 4096),直接透传保存在layer中;
  • geom_name:通过该参数指定行中geom列,默认取第一个geom列;如果一行中有多个gis列,未被指定的gis列直接当成string进行编码;
  • feature_id_name: 通过该参数指定行中的列,将该列中的值作为feature的id;如果不指定,feature id默认为0;

输出的pb编码的二进制数据可读性不高,为提高可测试性,提高脚本来解析:mvt_debug.js

// 执行脚本,将表达式结果作为参数传入
node mvt_debug.js '1A200A0474657374120B12020000180122030932221A026331220228012880207802'
// 解析结果
layer name: [ 'test' ]
feature count: 1
feature VectorTileFeature {
  properties: { c1: 1 },
  extent: 4096,
    type: 1,
    _pbf: {
    buf: Uint8Array(34) [
      26, 32, 10,   4, 116, 101, 115, 116, 18,
      11, 18,  2,   0,   0,  24,   1,  34,  3,
      9, 50, 34,  26,   2,  99,  49,  34,  2,
      40,  1, 40, 128,  32, 120,   2
      ],
      pos: 21,
      type: 2,
      length: 34
  },
  _geometry: 17,
    _keys: [ 'c1' ],
    _values: [ 1 ]
}
id undefined
bbox [ 25, 17, 25, 17 ]
GEO [ [ { x: 25, y: 17 } ] ]

2.15. _ST_MakeValid

将输入的无效多边形修复为有效的多边形,只支持投影坐标系,不支持地理坐标系

OceanBase(root@oceanbase)>select st_astext(_st_makevalid(st_geomfromtext('POLYGON((0 0,1 1,2 2,0 2,1 1,2 0,0 0))')));
+-------------------------------------------------------------------------------------+
| st_astext(_st_makevalid(st_geomfromtext('POLYGON((0 0,1 1,2 2,0 2,1 1,2 0,0 0))'))) |
+-------------------------------------------------------------------------------------+
| MULTIPOLYGON(((1 1,2 2,0 2,1 1)),((1 1,0 0,2 0,1 1)))                               |
+-------------------------------------------------------------------------------------+
1 row in set (0.006 sec)

上例中将自相交的多边形,

1715851041

转换为2个三角形

1715851049

2.16. ST_SymDifference(g1,g2)

OceanBase(root@oceanbase)>SET @g1 = ST_GeomFromText('MULTIPOINT(5 0,15 10,15 25)');
Query OK, 0 rows affected (0.001 sec)

OceanBase(root@oceanbase)>SET @g2 = ST_GeomFromText('MULTIPOINT(1 1,15 10,15 25)');
Query OK, 0 rows affected (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsText(ST_SymDifference(@g1, @g2));
+---------------------------------------+
| ST_AsText(ST_SymDifference(@g1, @g2)) |
+---------------------------------------+
| MULTIPOINT((1 1),(5 0))               |
+---------------------------------------+
1 row in set (0.004 sec)

2.17. ST_AsGeoJSON(g[,max_dec_digits[,options]])

--flag 0(000)到7(111)表现
OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,0);
+---------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,0) |
+---------------------------------------------------------------------+
| {"type": "Point", "coordinates": [12.2, 11.1]}                      |
+---------------------------------------------------------------------+
1 row in set (0.003 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,1);
+----------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,1)              |
+----------------------------------------------------------------------------------+
| {"bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+----------------------------------------------------------------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,2);
+--------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,2)                                          |
+--------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "EPSG:4326"}}, "type": "Point", "coordinates": [12.2, 11.1]} |
+--------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,3);
+------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,3)                                                                            |
+------------------------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "EPSG:4326"}}, "bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,4);
+-------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,4)                                                           |
+-------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "type": "Point", "coordinates": [12.2, 11.1]} |
+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,5);
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,5)                                                                                             |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,6);
+-------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,6)                                                           |
+-------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "type": "Point", "coordinates": [12.2, 11.1]} |
+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

OceanBase(root@oceanbase)>SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,7);
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,7)                                                                                             |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

2.18. ST_Centroid

OceanBase(root@oceanbase)>SELECT ST_AsText(_ST_PointOnSurface(geom)) AS pt_on_surf,
    -> ST_AsText(ST_Centroid(geom)) AS centroid
    -> FROM (SELECT ST_GeomFromText('POLYGON ((0 0, 0 10, 10 10, 10 8, 2 8, 2 2, 10 2, 10 0, 0 0))') AS geom) AS t;
+------------+----------------------------+
| pt_on_surf | centroid                   |
+------------+----------------------------+
| POINT(1 5) | POINT(4.076923076923077 5) |
+------------+----------------------------+
1 row in set (0.001 sec)

2.19. _ST_AsMVTGeom

OceanBase(root@oceanbase)>SELECT ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, false));
+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, false)) |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| POLYGON((0 4096,10 4091,10 4096,0 4101,0 4096))                                                                                                                  |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.002 sec)

OceanBase(root@oceanbase)>SELECT ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, true));
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, true)) |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| POLYGON((0 4096,10 4091,10 4096,0 4096))                                                                                                                        |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

2.20. 3维空间对象

3维空间对象ddl/dml与2维基本一致,只是3维空间对象无法写入到由子类型定义的字段上

# 创建gis字段
OceanBase(root@oceanbase)>create table geo_3d(g geometry);
Query OK, 0 rows affected (0.302 sec)

# 写入3维的点
OceanBase(root@oceanbase)>insert into geo_3d values(ST_GeomFromText('POINT Z (0 0 0)'));
Query OK, 1 row affected (0.025 sec)

#查询3维数据
OceanBase(root@oceanbase)>select st_aswkt(g) from geo_3d;
+-----------------+
| st_aswkt(g)     |
+-----------------+
| POINT Z (0 0 0) |
+-----------------+
1 row in set (0.007 sec)

# 对3维空间对象做空间计算时,会先转换为2维;
# 如下例所示point(0 0 0)和point(0 0 1)在3维空间下是不相交的,转换到2维就是相交的
OceanBase(root@oceanbase)>select st_intersects(g, st_geomfromtext('POINT Z (0 0 1)')) from geo_3d;
+------------------------------------------------------+
| st_intersects(g, st_geomfromtext('POINT Z (0 0 1)')) |
+------------------------------------------------------+
|                                                    1 |
+------------------------------------------------------+
1 row in set (0.005 sec)

# 部分表达式不支持3维数据
OceanBase(root@oceanbase)>select st_x(g,1) from geo_3d;
ERROR 3037 (22023): Invalid GIS data provided to function st_x.

# 用子类型(point/linestring等)定义gis字段,不支持插入3维数据
OceanBase(root@oceanbase)>create table t(geo point);
Query OK, 0 rows affected (0.511 sec)
# 可以写入2维数据
OceanBase(root@oceanbase)>insert into t values(ST_GeomFromText('POINT(0 0)'));
Query OK, 1 row affected (0.004 sec)
# 无法写入3维数据
OceanBase(root@oceanbase)>insert into t values(ST_GeomFromText('POINT Z (0 0 0)'));
ERROR 1416 (22003): Cannot get geometry object from data you send to the GEOMETRY field.

3. 总结和展望

如上所述,本次特性为满足用户的需求,补充了部分ob mysql特有的gis空间表达式;同时补齐了部分兼容mysql gis的空间表达式。目前ob mysql gis提供的空间计算和分析的能力与mysql gis仍然有一定差距,将在后续的版本迭代中快速补齐相关功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单分享下Python进程

1. 单进程与多进程 理论讲解: 进程是操作系统中资源分配的基本单位,每个进程都有独立的内存空间。 多进程允许同时运行多个进程,提高CPU利用率和程序响应速度。 示例代码: import os print("当前进程ID:", os.getp…

【适配器模式】设计模式: 穿越接口的时空隧道(架起接口间的桥梁)

文章目录 Java 设计模式之适配器模式:理论与实践1. 引言1.1 结构型模式介绍1.2 为什么需要适配器模式? 2. 适配器模式概述2.1 定义2.2 关键概念2.3 适配器模式的类型 3. 适配器模式的参与者4. 适配器模式的工作原理4.1 类适配器模式的工作流程4.2 对象适…

CSS基础 - CSS3

目录 A. 简介 B. 基础用法 C. 总结 A. 简介 CSS3 是 CSS(层叠样式表)技术的升级版本。 一、新特性概述 选择器增强 CSS3 引入了更多强大的选择器,使得开发者能够更精确地选择和样式化网页元素。例如,属性选择器可以根据元素…

Golang | Leetcode Golang题解之第329题矩阵中的最长递增路径

题目: 题解: var (dirs [][]int{[]int{-1, 0}, []int{1, 0}, []int{0, -1}, []int{0, 1}}rows, columns int )func longestIncreasingPath(matrix [][]int) int {if len(matrix) 0 || len(matrix[0]) 0 {return 0}rows, columns len(matrix), len(m…

仓颉编程入门 -- 循环语句详解

仓颉编程入门 – 循环语句 一 . while 表达式 while 表达式的基本形式为: while (条件) {循环体 }注意事项 : 其中“条件”是布尔类型表达式,“循环体”是一个代码块。while 表达式将按如下规则执行: 计算“条件”表达式,如果…

计算机毕业设计选题推荐-电缆行业生产管理系统-Java/Python项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

LabVIEW软件开发的未来是什么?

LabVIEW软件开发的未来展望可以从以下几个方面进行分析: 1. 与硬件集成的进一步增强 LabVIEW一贯以其与硬件的紧密集成而著称,未来这一优势将进一步得到强化。随着物联网(IoT)设备、工业4.0和智能制造的发展,LabVIEW将…

Mipi SoundWire Spec 详解4.2~4.3

目录 4.2 低层特性 4.2.1 物理接口 4.2.1.1 信号拓扑 4.2.1.2 多数据通道 4.2.1.3 高性能PHY 4.2.2 数据编码 4.2.3 物理信号值和逻辑信号值的术语 4.2.4 对开发和测试低级功能的支持 4.3 控制特性 4.3.1 比特流与帧结构 4.3.1.1 控制字与带宽权衡 4.3.2 同步 4.3.…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 8月8日,星期四

每天一分钟,知晓天下事! 2024年8月8日 星期四 农历七月初五 1、 财政部预拨4.65亿元资金支持辽宁、吉林等7省(市)开展应急抢险救灾工作。 2、 2024年“三区”人才支持计划发布:全国将选派15952名教师赴“三区”。 3…

什么是三维坐标系?

在研究向量和高级微积分主题时,了解 3D 坐标系非常重要。过去,我们一直在处理平面和矩形坐标。这一次,我们将研究三维坐标系的组成部分和约定。 3D 坐标系使我们能够表示包含三个相互垂直轴的空间中的一个量。通过 3D 坐标系统,我…

计算机网络——网络层(多协议标签交换MPLS、软件定义网络SDN)

多协议标签交换MPLS 多协议标签交换MPLS(multiProtocal Label Switching):“多协议”表示在MPLS的上层可以采用多种协议。 MPLS利用面向连接技术,使每个分组携带一个叫作标签的小整数(这叫作打上标签)。当分…

Linux下终极下载管理器:uGet and aria2

你是否曾在火狐浏览器中点击过下载链接,然后连接中断,不得不从头开始重新下载文件? 这就是 uGet 下载管理器的用武之地。 1)uGet 是一款开源的轻量级下载管理器,适用于 Linux、BSD、Android 和 Windows。有了 uGet&a…

Github 2024-08-08 开源项目日报Top10

根据Github Trendings的统计,今日(2024-08-08统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目5JavaScript项目3Python项目2C#项目1C++项目1Go项目1免费编程学习平台:freeCodeCamp.org 创建周期:3302 天开发语言:TypeScri…

Linux-入门-02

上节我们讲了如何安装虚拟机,本节课讲一些linux的常用命令,首先我们需要做一些配置,我们的centos的镜像是最小版安装,里面什么也没有,所以我们的linux是不能进行联网的,接下来我们就来一步一步联网 1、配置网络 首先我们需要先使用命令查看ip地址,linux中一切皆文件,只能使用命…

opencascade TopoDS_TShape源码学习

opencascade TopoDS_TShape 前言 TShape 是描述二维或三维空间中一组点的拓扑结构。 拓扑形状是由其他形状组成的结构。这是一个延迟类,用于支持拓扑对象。 TShape 由其可选的域(几何)和组件(带有位置和方向的其他 TShape&#…

德国EKKIF高定五金——不断探索全球新材料、新技术和新生活方式

Ekkif Concept品牌理念 “New life” We have always advocated the new concept and lifestyle of "New life". Our design team adheres to the concept of innovation and originality, constantly exploring new materials, technologies, and lifestyles a…

详细分析Linux中的ss命令基本知识(附Demo)

目录 1. 基本知识2. 基本命令2.1 查套接字2.2 查端口 1. 基本知识 ss 用于在 Linux 系统中显示网络套接字统计信息的命令 是 netstat 命令的现代替代品,提供了更快、更详细的输出是 iproute2 套件的一部分,支持许多高级网络功能 基本的功能如下&#…

html+css 实现hover选择按钮

前言:哈喽,大家好,今天给大家分享htmlcss 绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目…

WEB应用(十四)---文件上传

什么是文件上传漏洞 文件上传是Web应用的常见功能,允许用户上传图片、视频及其他文件类型文件。如果用户上传的是木马文件,则服务器就会收到攻击。 对于这个漏洞的练习有一个专门的靶场,即upload-labs,这个的安装可以在windows中使…

使用TLA+形式化验证Go并发程序

Writing is natures way of letting you know how sloppy your thinking is - Guindon 在2024年6月份举办的GopherCon Europe Berlin 2024[1]上,一个叫Raghav Roy的印度程序员(听口音判断的)分享了Using Formal Reasoning to Build Concurrent Go Systems[2]&#x…