postgresql导入点类型的空间数据,一般会提供xy坐标(或者lon和lat)字段,一般的工具并没有提供转换为空间数据的功能。此时,我们需要提供一些方法或者触发器来实现空间字段的自动更新。而xy坐标在导入的时候也会存在两种情况,一种是以度分秒的字符串形式提供,一种是小数的方式提供。所以这里我们还要提供一个针对坐标的归一化函数。下面就是相关设计的方法方法代码。
1.坐标标准化处理函数
CREATE or replace FUNCTION public.translate_coor(tude varchar) RETURNS NUMERIC AS $$
DECLARE data varchar[];
BEGINif like(tude,'%°%') then SELECT (regexp_split_to_array(tude, '[°′''"″]')) into data;return CAST(data[1] as numeric) + CAST(data[2] as numeric) / 60 + CAST(data[3] as numeric)/3600;else return cast(tude as numeric);end if;
END;
$$ LANGUAGE plpgsql;
在实际的数据中,度分秒有时候并不是,°′″
,至于分有的数据为了方便输入采用单引号'
,秒采用双引号"
,所以这里通过正则表达式进行了不同情况的处理。另外,对于小数的形式数据直接返回。
2.更新geom空间函数
CREATE or replace function public.fill_geom(tbl varchar,x_field varchar,y_field varchar,srid int=4326) RETURNS int AS $$
BEGINif(srid = 0) THENsrid = 4326;end if;EXECUTE format('update %s set geom=st_geomfromewkt(''srid='|| srid || ';point(''||translate_coor(%s)||'' '' || translate_coor(%s)|| '')'');', tbl,x_field,y_field);return 0;
END;
$$ LANGUAGE plpgsql;
注意:
- tbl:表名
- x_field:x坐标的字段名称
- y_field:y坐标的字段名称
- srid:默认为4326。
3.创建触发器函数
3.1 创建触发器对应函数
CREATE or replace FUNCTION public.fun_insert_meteorological() RETURNS "pg_catalog"."trigger" AS $$
BEGINif((new.lon ~ '^\d+°(\d+[′''](\d+(\.\d+)?[″"])?)?$' and new.lat ~ '^\d+°(\d+[′''](\d+(\.\d+)?[″"])?)?$') or ( new.lon ~ '^\d+(\.\d+)?$' and new.lat ~ '^\d+(\.\d+)?$')) then new.geom=st_geomfromewkt('srid=4326;point(' || translate_coor(new.lon) || ' ' || translate_coor(new.lat) || ')');end if;return NEW;
END;
$$ LANGUAGE plpgsql;
这里对度分秒的格式通过正则表达式进行了验证。如果不满足,这里按照不执行更新操作。大家可以根据实际进行调整。
3.2 创建触发器
CREATE TRIGGER "meteorological_insert_update_trigger" BEFORE INSERT OR UPDATE ON "public"."meteorological"
FOR EACH ROW
EXECUTE PROCEDURE "public"."fun_insert_meteorological"();