5

Given two polygon tables L1 (blue) and L2 (red) that share a common boundary but different amount of vertexes, how can one make the shared boundary identical (they should share the same vertexes) ?

EDIT:

By identical I mean that 'If we say the Blue Layer is the reference layer, then the edge of the Red that is common with the blue should afterwards have 3 vertexes instead of two that is now'

enter image description here

1
  • What rule are you using to make them identical? The wider or the narrower of the two end points. Is there some kind of tolerance? What do you want as output, the Linestring of the common boundary? Commented Apr 23, 2015 at 11:00

1 Answer 1

3

What you have in PostGIS for that is ST_Snap http://postgis.net/docs/ST_Snap.html

This is a four-vertex polygon

POLYGON (( 420 420, 420 520, 700 520, 700 420, 420 420 ))

This is an adjacent five-vertex polygon that has one vertex in the middle of the common boundary at location (582 420)

POLYGON (( 420 420, 582 420, 700 420, 700 320, 420 320, 420 420 ))

With the following SQL you can make the four-vertex polygon to snap to the five-vertex polygon:

select ST_AsText(ST_Snap(ST_GeomFromText('POLYGON (( 420 420, 420 520, 700 520, 700 420, 420 420 ))'),ST_GeomFromText('POLYGON (( 420 420, 582 420, 700 420, 700 320, 420 320, 420 420 ))'),1))

The result which now contains a new vertex at (582 420)

POLYGON((420 420,420 520,700 520,700 420,582 420,420 420))

Looks perfect, doesn't it? Unfortunately it is not so simple with real world data. For the first you must first snap A to B and then B to A for getting the same vertices to both polygons. And if the polygon boundaries make a curve then there will be small overlaps and gaps between the polygons which are created from different vertices and the result of using ST_Snap function may not be satisfying.

For cleaning bigger datasets I would use OpenJUMP which has quite a clever tool just for this purpose. It is processing the whole layer and it takes care of adding vertices to both parties at one run. With very complicated polygons the result may still not be perfect but from my experience the result is better than by using ST_Snap.

enter image description here

enter image description here

EDIT

An advanced example about snapping A to B and then B to snapped-A

Source geometries

POLYGON (( 280 580, 660 580, 660 460, 460 480, 280 460, 280 580 ))
POLYGON (( 280 460, 520 480, 660 460, 660 380, 280 380, 280 460 ))

enter image description here

SQL to use

SELECT ST_AsText(ST_Snap(ST_GeomFromText('POLYGON (( 280 580, 660 580, 660 460, 460 480, 280 460, 280 580 ))'),ST_GeomFromText('POLYGON (( 280 460, 520 480, 660 460, 660 380, 280 380, 280 460 ))'),20));

SELECT ST_AsText(ST_Snap(ST_GeomFromText('POLYGON (( 280 460, 520 480, 660 460, 660 380, 280 380, 280 460 ))'),
ST_Snap(ST_GeomFromText('POLYGON (( 280 580, 660 580, 660 460, 460 480, 280 460, 280 580 ))'),ST_GeomFromText('POLYGON (( 280 460, 520 480, 660 460, 660 380, 280 380, 280 460 ))'),20),20));

The result:

enter image description here

2
  • something like : ST_Snap(a,ST_Snap(b,a,tol),tol) ?
    – nickves
    Commented Apr 23, 2015 at 13:07
  • Looks good to me. I can make a test case later if you are not faster than me. Remember to make some slivers between the source polygons so you can test if the topology is OK after the snap-snap.
    – user30184
    Commented Apr 23, 2015 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.