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スキーマの関連テーブルに登録します。
tg_typeは次の整数値とします: 1:[multi]point (点), 2:[multi]line (線), 3:[multi]poly (面), 4:collection。layer_idは、topology.layerテーブル内のレイヤ識別番号です。
点レイヤはノードの集合から形成され、線レイヤはエッジの集合から形成され、面レイヤはフェイスの集合から形成され、コレクションはノード、エッジ、フェイスの混合から形成されます。
要素の配列を省略した場合、空のTopoGeometryオブジェクトが生成されます。
Availability: 1.?
ri_topoスキーマ内 (ST_CreateTopoGeoの例でロードしてあります)で、ラインタイプ (整数値で2)の、layer_idが2のレイヤ (ri_roads)の最初のエッジからTopoGeometryを生成します。
INSERT INTO ri.ri_roads(road_name, topo) VALUES('Unknown', topology.CreateTopoGeom('ri_topo',2,2,'{{1,2}}'::topology.topoelementarray);フェイスのコレクションから形成されるジオメトリがあるとします。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;
-- 世界が誤差を完璧に許容することは、ほぼありません。
-- 50%がblockgroupの境界の内側に落ちるフェイスを数えます。
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から、フェイスやエッジに沿うような正規化が
-- なされていないジオメトリに戻すには、topoをジオメトリにキャストします。
-- 新しいジオメトリは、Tigerの道路中心線に沿っていて、とても素晴らしいです。
UPDATE boston.blockgroups SET new_geom = topo::geometry;