[postgis-users] Building Heirarchical Topology
Regina Obe
lr at pcorp.us
Wed Feb 8 11:44:54 PST 2023
Your topo should be a collection of topo elements, not the collection of
primitives that make up the topo.
Try:
WITH elms AS (
SELECT left(geoid20,14) AS blkid,
ARRAY[(topo).id,(topo).layer_id] AS elm
FROM block20_topo
WHERE geoid20 LIKE '53001950100101%'
)
INSERT INTO blockgroup20_topo (bgid20, topo) SELECT blkid AS bgid20,
CreateTopoGeom(
'census',
3, -- polygon
2, -- blockgroup20_topo layer_id
TopoElementArray_Agg(elm)
) AS topo
FROM elms
GROUP BY 1
> -----Original Message-----
> From: postgis-users [mailto:postgis-users-bounces at lists.osgeo.org] On
Behalf
> Of Paul Ramsey
> Sent: Wednesday, February 8, 2023 2:24 PM
> To: PostGIS Users Discussion <postgis-users at lists.osgeo.org>
> Subject: [postgis-users] Building Heirarchical Topology
>
> Hello users, a question! But first all the setup.
>
> Starting from a base set of data, census blocks, which come with a nice
> heirarchical key, so it's easy to create contiguous collections just by
struncating
> the key and grouping.
>
> Here's an example key (the column is called geoid20): 530019501001
>
> OK, so let's start just building a topology and associated topogeoms for
the
> blocks. Original simple features geometry table is 'block20', new topogeom
> table is 'block20_topo'.
>
> SELECT CreateTopology('census', 6599);
> CREATE TABLE block20_topo (geoid20 text); SELECT
> AddTopoGeometryColumn(
> 'census',
> 'public',
> 'block20_topo',
> 'topo',
> 'POLYGON'
> );
>
> All good! Now we load the simple features data into the topology and get
> topogeoms at the same time (magic).
>
> -- Load 463 blocks in one tract, ~15seconds INSERT INTO block20_topo
> (geoid20, topo) SELECT
> geoid20, toTopoGeom(geom, 'census', 1)
> FROM block20
> WHERE geoid20 LIKE '53001950100%';
>
> Still, good, keeping things small, just one tract of 463 blocks.
>
> OK, now hierarchy. Blocks can be formed up into groups. PostGIS topology
> supports heirarchy by letting one build up "parent" topogeoms where each
> parent item is made up of "child" topogeoms. In this case the block groups
will
> be made up of blocks.
>
> CREATE TABLE blockgroup20_topo (bgid20 text); SELECT
> AddTopoGeometryColumn(
> 'census',
> 'public',
> 'blockgroup20_topo',
> 'topo',
> 'POLYGON',
> 1 -- layer_id of the blocks
> );
>
> So far so good: make table, add topogeom for the parent groups, and
specify in
> the function the layer_id of the children.
>
> Now, how to build and insert a parent topogeom into the blockgroup20_topo
> table?
>
> WITH elms AS (
> SELECT left(geoid20,14) AS blkid,
> GetTopoGeomElements(topo) AS elm
> FROM block20_topo
> WHERE geoid20 LIKE '53001950100101%'
> )
> INSERT INTO blockgroup20_topo (bgid20, topo) SELECT blkid AS bgid20,
> CreateTopoGeom(
> 'census',
> 3, -- polygon
> 2, -- blockgroup20_topo layer_id
> TopoElementArray_Agg(elm)
> ) AS topo
> FROM elms
> GROUP BY 1
>
> This would seem the most likely way, getting all the elements from the
> relevant children using GetTopoGeomElements(), group them into one array
> with TopoElementArray_Agg() and finally create the topogeom with
> CreateTopoGeom(). But it fails with an error.
>
> ERROR: TopoGeom element layer do not match TopoGeom child layer
>
> Just changing the layer_id in the CreateTopoGeom() to 1 doesn't fix it,
because
> though it successfully creates a topogeom, the restrictions in the topo
column
> blockgroup20_topo correctly stop it from inserting a topogeom that
references
> layer_id 1 into a column that is built for layer_id 2.
>
> Thoughst?
>
> P
>
> _______________________________________________
> postgis-users mailing list
> postgis-users at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/postgis-users
More information about the postgis-users
mailing list