| 1 | [[TOC]] |
| 2 | |
| 3 | = Another example showing how to simplify (generalize) a multipolygon layer using PostGIS Topology = |
| 4 | |
| 5 | This article is a kind of "follower" for this one: UsersWikiSimplifyPreserveTopology, showing another method to build generalized polygons keeping their spatial relationship. |
| 6 | |
| 7 | It uses the PostGIS Topology module ([http://postgis.org/documentation/manual-2.0/Topology.html]) and aims at producing |
| 8 | |
| 9 | A big thank to Brent Wood for its Topology Example and to Sandro Santilli for the topology module |
| 10 | |
| 11 | == What we want == |
| 12 | |
| 13 | || Simplifying this layer: || into this: || avoiding that: |
| 14 | || [[Image(wiki:UsersWikiSimplifyPreserveTopology:SPT_dept_ori.gif)]] || [[Image(SPT_dept_sim.png)]] || [[Image(SPT_no_topo.png)]] || |
| 15 | |
| 16 | == The data == |
| 17 | |
| 18 | French administrative subdivisions, called "départements", will be used. Data can be downloaded here: [http://professionnels.ign.fr/DISPLAY/000/528/175/5281750/GEOFLADept_FR_Corse_AV_L93.zip] |
| 19 | |
| 20 | Data projection is Lambert-93, EPSG:2154 |
| 21 | |
| 22 | == Loading the data == |
| 23 | |
| 24 | {{{ |
| 25 | #!sh |
| 26 | shp2pgsql -IiD -g geom -s 2154 DEPARTEMENT.SHP departement | psql |
| 27 | }}} |
| 28 | |
| 29 | == Principle of simplification == |
| 30 | |
| 31 | * The [http://postgis.org/documentation/manual-2.0/Topology.html | Postgis Topology] module is used to build a topology from input data |
| 32 | * A new topology is then created, using a simplified (generalized) version of the first one. |
| 33 | * Node connections seem to be preserved doing so, |
| 34 | * Then, simplified polygons are matched against initial ones using spatial operations |
| 35 | |
| 36 | == Steps == |
| 37 | |
| 38 | 1. Creates the target table that will contain simplified geometry. Initial departement polygons are dumped to handle simple objects. |
| 39 | |
| 40 | {{{ |
| 41 | #!sql |
| 42 | create table new_dept as ( |
| 43 | select gid, code_dept, (st_dump(geom)).* |
| 44 | from departement |
| 45 | ); |
| 46 | create index new_dept_geom_gist on new_dept using gist(geom); |
| 47 | |
| 48 | -- adds the new geom column that will contain simplified geoms |
| 49 | alter table new_dept add column simple_geom geometry(POLYGON, 2154); |
| 50 | }}} |
| 51 | |
| 52 | 2. Creates a topology from the departements |
| 53 | |
| 54 | {{{ |
| 55 | #!sql |
| 56 | -- create new empty topology structure |
| 57 | select CreateTopology('topo1',2154,0); |
| 58 | |
| 59 | -- add all departements polygons to topology in one operation as a collection |
| 60 | select ST_CreateTopoGeo('topo1',ST_Collect(geom)) |
| 61 | from departement; |
| 62 | }}} |
| 63 | |
| 64 | 3. Create a new topology based on the simplification of existing one. (''should not be the right way to do it, but calling ST_ChangeEdgeGeom'') |
| 65 | |
| 66 | {{{ |
| 67 | #!sql |
| 68 | select CreateTopology('topo2',2154,0); |
| 69 | |
| 70 | select ST_CreateTopoGeo('topo2', geom) |
| 71 | from ( |
| 72 | select ST_Collect(st_simplifyPreserveTopology(geom, 10000)) as geom |
| 73 | from topo1.edge_data |
| 74 | ) as foo; |
| 75 | }}} |
| 76 | |
| 77 | 4. Retrieves polygons by comparing surfaces (pip is not enough for odd-shaped polygons) |
| 78 | |
| 79 | {{{ |
| 80 | #!sql |
| 81 | with simple_face as ( |
| 82 | select st_getFaceGeometry('topo2', face_id) as geom |
| 83 | from topo2.face |
| 84 | where face_id > 0 |
| 85 | ) update new_dept d set simple_geom = sf.geom |
| 86 | from simple_face sf |
| 87 | where st_intersects(d.geom, sf.geom) |
| 88 | and st_area(st_intersection(sf.geom, d.geom))/st_area(sf.geom) > 0.5; |
| 89 | }}} |
| 90 | |
| 91 | == Results == |
| 92 | |
| 93 | This method produces a clean result: |
| 94 | |
| 95 | |
| 96 | |
| 97 | == Notes == |
| 98 | |
| 99 | Find a way to associate faces to initial polygon using topology, not using spatial operations. |