名前

CreateTopoGeom — 新しい TopoGeometryオブジェクトを topoエレメント配列から生成します - tg_type: 1:[multi]point, 2:[multi]line, 3:[multi]poly, 4:collection

概要

topogeometry CreateTopoGeom(varchar toponame, integer tg_type, integer layer_id, topoelementarray tg_objs);

topogeometry CreateTopoGeom(varchar toponame, integer tg_type, integer layer_id);

説明

layer_idで示されたレイヤのためのTopoGeometryオブジェクトを生成し、toponameスキーマのrelationテーブルに登録します。

tg_typeは次の整数値とします: 1:[multi]point (punctal), 2:[multi]line (lineal), 3:[multi]poly (areal), 4:collection。layer_idは、topology.layerテーブル内のレイヤ識別番号です。

点レイヤはノードの集合から形成され、線レイヤはエッジの集合から形成され、面レイヤはフェイスの集合から形成され、コレクションはノード、エッジ、フェイスの混合から形成されます。

要素の配列を省略した場合、空のTopoGeometryオブジェクトが生成されます。

初出: 1.?

例: 既存エッジからの形成

ラインタイプ(整数値で2)の、layer_idが2のレイヤ(ri_roads)があるri_topoスキーマ内で最初のエッジ(ST_CreateTopoGeoでロードしてあります)からTopoGeometryを生成します。

INSERT INTO ri.ri_roads(road_name, topo) VALUES('Unknown', topology.CreateTopoGeom('ri_topo',2,2,'{{1,2}}'::topology.topoelementarray);

例: 面ジオメトリから最善と推測されるTopoGeometryへの変換

フェイスのコレクションから形成されるジオメトリがあるとします。blockgroupsテーブルがあり、それぞれの区画群のTopoGeometryを知りたいとします。データが完全に整列しているなら、次のようにできます。

-- TopoGeometryカラムの生成 --
SELECT topology.AddTopoGeometryColumn(
	'topo_boston', 
	'boston', 'blockgroups', 'topo', 'POLYGON');
	
-- addtopgeometrycolumn --
1
	
-- 全てが完全にエッジに整列していると仮定している
-- カラムの更新
UPDATE boston.blockgroups AS bg
	SET topo = topology.CreateTopoGeom('topo_boston'
        ,3,1
        , foo.bfaces)
FROM (SELECT b.gid,  topology.TopoElementArray_Agg(ARRAY[f.face_id,3]) As bfaces
	FROM boston.blockgroups As b
            INNER JOIN topo_boston.face As f ON b.geom && f.mbr
        WHERE ST_Covers(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id))
            GROUP BY b.gid) As foo
WHERE foo.gid = bg.gid; 
-- 世界はほとんど完全ではなく、ある程度の誤差は許容しなければなりません。
-- 各々のフェイスについてblockgroupの境界と思われるものの中に
-- 50%以上含まれているものを対象とします。
UPDATE boston.blockgroups AS bg
	SET topo = topology.CreateTopoGeom('topo_boston'
        ,3,1
        , foo.bfaces)
FROM (SELECT b.gid,  topology.TopoElementArray_Agg(ARRAY[f.face_id,3]) As bfaces
	FROM boston.blockgroups As b
            INNER JOIN topo_boston.face As f ON b.geom && f.mbr
        WHERE ST_Covers(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id))
        	OR
 (  ST_Intersects(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id))
            AND ST_Area(ST_Intersection(b.geom, topology.ST_GetFaceGeometry('topo_boston', f.face_id) ) ) > 
                ST_Area(topology.ST_GetFaceGeometry('topo_boston', f.face_id))*0.5
                )
            GROUP BY b.gid) As foo
WHERE foo.gid = bg.gid; 

-- そして、TopoGeometryをフェイスとエッジに整列された非正規ジオメトリに
-- 戻すには、トポロジをジオメトリにキャストします。
-- 新しいジオメトリはtigerのストリートのセンタラインに整列しているところが
-- 本当にクールなところです。
UPDATE boston.blockgroups SET new_geom = topo::geometry;

関連情報

AddTopoGeometryColumn, toTopoGeom ST_CreateTopoGeo, ST_GetFaceGeometry, topoelementarray, TopoElementArray_Agg