-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- -- $Id: cleanGeometry.sql 2008-04-24 10:30Z Dr. Horst Duester $--
-- cleanGeometry - remove self- and ring-selfintersections from -- input Polygon geometries -- http://www.sogis.ch
-- Copyright 2008 SO!GIS Koordination, Kanton Solothurn, Switzerland
-- Version 1.0
-- contact: horst dot duester at bd dot so dot ch--
-- This is free software; you can redistribute and/or modify it under-- the terms of the GNU General Public Licence. See the COPYING file.
-- This software is without any warrenty and you use it at your own risk-- -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CREATE OR REPLACE FUNCTION cleanGeometry(geometry)
RETURNS geometry AS
$BODY$DECLARE
inGeom ALIAS for $1;
outGeom geometry;
tmpLinestring geometry;
Begin
outGeom := NULL;
-- Clean Process for Polygon
IF (GeometryType(inGeom) = 'POLYGON' OR GeometryType(inGeom) = 'MULTIPOLYGON') THEN
-- Only process if geometry is not valid, -- otherwise put out without change
if not isValid(inGeom) THEN
-- create nodes at all self-intersecting lines by union the polygon boundaries-- with the startingpoint of the boundary.
tmpLinestring := st_union(st_multi(st_boundary(inGeom)),st_pointn(boundary(inGeom),1));
outGeom = buildarea(tmpLinestring);
IF (GeometryType(inGeom) = 'MULTIPOLYGON') THEN
RETURN st_multi(outGeom);
ELSE
RETURN outGeom;
END IF;
else
RETURN inGeom;
END IF;
------------------------------------------------------------------------------
-- Clean Process for LINESTRINGS, self-intersecting parts of linestrings -- will be divided into multiparts of the mentioned linestring ------------------------------------------------------------------------------
ELSIF (GeometryType(inGeom) = 'LINESTRING') THEN
-- create nodes at all self-intersecting lines by union the linestrings-- with the startingpoint of the linestring.
outGeom := st_union(st_multi(inGeom),st_pointn(inGeom,1));
RETURN outGeom;
ELSIF (GeometryType(inGeom) = 'MULTILINESTRING') THEN
outGeom := multi(st_union(st_multi(inGeom),st_pointn(inGeom,1)));
RETURN outGeom;
ELSIF (GeometryType(inGeom) = '' OR GeometryType(inGeom) = 'GEOMETRYCOLLECTION') THEN
RETURN NULL;
ELSE
RAISE NOTICE 'The input type % is not supported %',GeometryType(inGeom),st_summary(inGeom);
RETURN inGeom;
END IF; End;$BODY$
LANGUAGE 'plpgsql' VOLATILE;
以上這段是要在PostgreSQL裡建立一個function,然後在進行 insert 動作的時候, 讓要 insert 的 geometry 先丟到這個function進行檢查並重整後, 回傳正確的 geometry。結束
2010年10月26日
Insert geometry 前確認是否合法
之前為專案寫了一個 shapefile 匯入程式, 匯入目標是PostgreSQL資料庫, 後來在資料庫中進行 intersect 時發生空間分析的錯誤,經過追查發現有些Geometry有 self-intersection 的狀況,接著還好在 google 找到解決方案
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言