postgresql Psql仅选择具有有效几何结构的行

sc4hvdpw  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(122)

我想计算表dataset_object中所有几何的长度。

select 
     st_length(st_setsrid(st_geomfromtext(split_part((dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text, ';'::text, 2)), split_part(split_part((dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text, ';'::text, 1), '='::text, 2)::integer))::text AS lengte,
     st_isvalid(st_setsrid(st_geomfromtext(split_part((dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text, ';'::text, 2)), split_part(split_part((dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text, ';'::text, 1), '='::text, 2)::integer)),
    (dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text as shape
FROM dataset_object
WHERE dataset_object.object_type::text = 'Waterkering'::text 
and st_isvalid(st_setsrid(st_geomfromtext(split_part((dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text, ';'::text, 2)), split_part(split_part((dataset_object.data -> 'Waterkering'::text) ->> 'shape'::text, ';'::text, 1), '='::text, 2)::integer)) is True

结果如下表所示:

Lengte      st_isvalid  shape
11.66819931 true        SRID=28992;LINESTRING Z(242724.282699998 570218.723099999 …
142.3694493 true        SRID=28992;LINESTRING Z(235640.405999999 580624.9628 …
12.14911526 true        SRID=28992;LINESTRING Z(242698.064100001 570181.706900001 …

现在,如果我读取许多行,则会返回以下错误:
SQL错误[XX 000]:错误:解析错误-无效几何图形提示:“”〈--几何中位置1处的解析错误
为了解决这个问题,我希望只选择st_invalid为真的行:
数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据集对象数据“数据集对象.data -〉”水印处理“::文本)-〉〉”形状“::文本,”;'::文本,1),'='::文本,2)::整数))不为空
但这也无济于事。
有人能解释一下错误的含义、来源以及我应该如何处理吗?
我认为在运行st_geomfromtext命令时会发生这种情况。

brgchamk

brgchamk1#

跳过有问题的几何图形有一个肮脏的技巧:

create function ST_TryGeomFromText(arg text) 
returns geometry language plpgsql as $$
begin
    return st_geomfromtext(arg);
exception
    when others then return null;
end $$;

你可以用这种方式 Package 任何PostGIS ST_ 函数,或者只是任何解析你输入的函数。但是问题仍然存在,你的一些dataset_object在它们的shape字段中没有你期望的几何文本。

with 
 dataset_object(object_type,data) as ( 
 values 
    ('Waterkering','{"Waterkering":{"shape":"SRID=12;LINESTRING(0 0,1 1,3 4)"}}'::jsonb),
    --('Waterkering','{"Waterkering":{"shape":"SRID=12;LINESTRING()"}}'::jsonb),
    ('Waterkering','{"Waterkering":{"shape":"SRID=12;"}}'::jsonb),
    ('Waterkering','{"Waterkering":{"shape":"SRID=12"}}'::jsonb),
    ('Waterkering','{"Waterkering":{"shape":""}}'::jsonb),
    ('Waterkering','{"Waterkering":{}}'::jsonb) )
,parsed_dataset_objects as (
    select 
        object_type,
        data,
        (dataset_object.data -> 'Waterkering')             as waterkering,
        (dataset_object.data -> 'Waterkering') ->> 'shape' as waterkering_shape, 
        split_part((dataset_object.data -> 'Waterkering') ->> 'shape',';', 2) 
                                            as waterkering_shape_field_1,
        split_part(split_part((dataset_object.data->'Waterkering')->>'shape',';',1),'=',2)
                                            as waterkering_shape_field_1_equals,
        split_part((dataset_object.data -> 'Waterkering') ->> 'shape',';', 2)                         
                                            as waterkering_shape_field_2
    from dataset_object)
select concat('ST_GeomFromText(''',waterkering_shape_field_2,''')') as "call" 
from parsed_dataset_objects;

上面的查询结果向您展示了提取方法如何无法为ST_GeomFromText()提供参数,从而导致您得到的解析错误:

call
--------------------------------------------
 ST_GeomFromText('LINESTRING(0 0,1 1,3 4)')
 ST_GeomFromText('')--throws an error
 ST_GeomFromText('')--throws an error
 ST_GeomFromText('')--throws an error
 ST_GeomFromText('')--throws an error
(5 rows)

您可以使您的where条件更详细,也保存了一些空间和复制粘贴感谢CTE的:

with 
 parsed_dataset_objects as (
    select 
        object_type,
        data,
        (dataset_object.data -> 'Waterkering') as waterkering,
        (dataset_object.data -> 'Waterkering') ->> 'shape' as waterkering_shape, 
        split_part(
            (dataset_object.data -> 'Waterkering') ->> 'shape',
            ';', 2) as waterkering_shape_field_1,
        split_part(
            split_part(
                (dataset_object.data -> 'Waterkering') ->> 'shape',
                ';', 1), 
            '=', 2
        ) as waterkering_shape_field_1_equals,
        split_part(
            (dataset_object.data -> 'Waterkering') ->> 'shape',
            ';', 2) as waterkering_shape_field_2
    from dataset_object)
,geoms as (
    select st_setsrid(
                st_geomfromtext(waterkering_shape_field_2),
                waterkering_shape_field_1_equals::integer) as geom
    from parsed_dataset_objects
    where object_type::text = 'Waterkering'::text
    and coalesce(waterkering_shape_field_2,'')<>''
    and coalesce(waterkering_shape_field_1_equals,'')<>'')
select 
    st_length(geom)::text AS lengte,
    st_isvalid(geom),
    st_astext(geom) as shape
FROM geoms;

但是我的建议是跟踪导致问题的记录并在源头上修复它们。有太多的方式可以让你的传入text/json无效,在where中处理它是一个临时的修复。

相关问题