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, bigint tg_id);
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.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を知りたいとします。データが完全に整列しているなら、次のようにできます。
トポジオメトリーカラムを追加します。
SELECT topology.AddTopoGeometryColumn( 'topo_boston', 'boston', 'blockgroups', 'topo', 'POLYGON');
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%が期待したブロックグループ境界に落ちる場合には数えるようにしています。
WITH candidate_faces AS (
SELECT
b.gid,
b.geom AS block_geom,
f.face_id,
topology.ST_GetFaceGeometry('topo_boston', f.face_id) AS face_geom
FROM boston.blockgroups AS b
INNER JOIN topo_boston.face AS f
ON b.geom && f.mbr
),
block_faces AS (
SELECT
gid,
topology.TopoElementArray_Agg(ARRAY[face_id, 3]) AS bfaces
FROM candidate_faces
WHERE ST_Covers(block_geom, face_geom)
OR (
ST_Intersects(block_geom, face_geom)
AND ST_Area(ST_Intersection(block_geom, face_geom))
> ST_Area(face_geom) * 0.5
)
GROUP BY gid
)
UPDATE boston.blockgroups AS bg
SET topo = topology.CreateTopoGeom(
'topo_boston',
3,
1,
block_faces.bfaces
)
FROM block_faces
WHERE block_faces.gid = bg.gid;
エッジやフェイスに沿ったトポジオメトリーをトポジオメトリーでないジオメトリーに戻すには、トポジオメトリーをジオメトリーにキャストします。結果ジオメトリーはTIGERのストリートの中心線に沿います。
UPDATE boston.blockgroups SET new_geom = topo::geometry;