名前

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 (punctal), 2:[multi]line (lineal), 3:[multi]poly (areal), 4:collection。layer_idは、topology.layerテーブル内のレイヤ識別番号です。

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

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

Availability: 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;
-- 世界が誤差を完璧に許容することは、ほぼありません。
-- 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をgeometry型にキャストします。
-- 戻されたジオメトリは、トポロジの規則に関わりませんが、
-- フェイスとエッジに沿ったものになります。
-- 新しいジオメトリはTigerの道路中心線に沿っていて、とても素晴らしいです。
UPDATE boston.blockgroups SET new_geom = topo::geometry;

関連情報

AddTopoGeometryColumn, toTopoGeom ST_CreateTopoGeo, ST_GetFaceGeometry, TopoElementArray, TopoElementArray_Agg