60

I have a set of polygons representing administrative districts. The districts were digitized by hand, and there are small spaces (slivers) between polygons where the polygons should be touching.

How can I have the polygons snap together, removing the spaces?

0

11 Answers 11

30

Use Eliminate (ArcInfo License required)

Eliminates polygons by merging them with neighboring polygons that have the largest area or the longest shared border. Eliminate is often used to remove small sliver polygons that are the result of overlay operations, such as Intersect or Union.

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00170000005p000000.htm

enter image description here

ArcGIS 10 Users Note there is a NEW Feature in the Options for this Tool.

It is now possible to preserve the original POLYGON or POLYLINE with the option > ex_features (Optional) An input polyline or polygon feature class or layer that defines polygon boundaries, or portions thereof, that should not be eliminated.

8
  • 3
    Does that work in zoo's case? There seem to be no slivers in the dataset, just gaps between polygons.
    – underdark
    Commented Jun 14, 2011 at 14:46
  • 3
    I've used this tool successfully to remove gaps between polygons. There is a problem with using this tool though. When it cracks the polygons during the geoprocessing, it over generalizes the newly created polygons. So, curves will not be as smooth, instead having sharp "jagged" lines. Ymmv.
    – amasephy
    Commented Jun 14, 2011 at 14:57
  • 3
    @underdark Good point. However, one could always introduce the slivers via a union of the data with a monolithic surrounding polygon (such as the bounding box of the dataset). An interesting question is how "Eliminate" chooses which polygons to merge the slivers into. This could bias the results (although I doubt the bias would be important in most applications). In this particular situation, an ideal solution would sort of split the slivers, or average the errors out.
    – whuber
    Commented Jun 14, 2011 at 15:00
  • One of the options of the tool is to merge the sliver with the neighboring polygon with either the longest border (the default option) or the largest area.
    – kenbuja
    Commented Jun 14, 2011 at 16:04
  • 4
    If you don't have an ArcInfo license, there is a script at arcscripts.esri.com/details.asp?dbid=14672 which automates this via Python. I used it successfully a few years ago. Commented Jun 15, 2011 at 2:12
21

To do this by hand in QGIS, go to Settings|Project Properties... On the General tab at the bottom is Snapping options... Check the layer that you want to snap, set the mode to to vertex and set the tolerance to some value less than the shortest distance between two points that you have. If you're not sure, set the units to pixels and the tolerance to something like 5 so that if there are some fiddly details you can zoom right in and be sure that you don't snap to the wrong vertex.

Then edit your vector layer, select the node tool, and move the errant points to their counterparts.

Doing it automatically is a bit trickier. AFAIK QGIS doesn't have a plugin to automate it, and although PostGIS is built on GEOS which does have snapping functions, they're not exposed to PostGIS. It might be possible to write a query to check each point of a polygon for neighbours within the snapping distance, but that is currently beyond my wit to expand upon.

GRASS has v.clean.snap which you can access via QGIS, but there's the extra step of creating a GRASS dataset.

2
  • You could always use the QGIS processing toolbox and apply v.clean.snap directly to your shapefile.
    – SAnderka
    Commented Apr 29, 2014 at 6:56
  • v.clean.snap is not available. i used v.clean and then selected the snap tool and it gave an empty layer. Documentation says that snap is to join lines to vertex. I want to join vertex to another vertex within threshold.
    – neogeomat
    Commented Jun 6, 2014 at 5:25
18

If you'r familiar with QGIS: In the QGIS trunk 1.9 (can be installed as qgis.dev via the OSGEO installer, see qgis homepage) is a new function in the vector menu called "Eliminate sliver polygons", which exactly does what you want. You can select the problematic polygons and merge them to adjacent polygons based on a common boundary or area propotion. Try it out!

2
  • 3
    To update this answer, in QGIS 2.18.1 'Eliminate Sliver Polygons' is available in the stable package and is found under Vector -> Geoprocessing Tools. Commented Dec 27, 2016 at 17:39
  • 1
    This applies to existing stray sliver polygons in between the main ones, not in the case of spaces between polygons.
    – stragu
    Commented Apr 21, 2017 at 4:31
15

If you are a QGIS user than you get all the power of GRASS, as it is a fully topological GIS. Inside QGIS activate the GRASS plugin, create a location/mapset where to import your data.

Open the mapset and import you dirty layer with v.in.ogr: play with the two advanced parameters "snapping threshold for boundaries" and "minimum size of area to be imported".

You can also use the options that the v.clean module provide.

11

ArcGIS has topology rules that will help you identify and correct gaps in your data such as what you are referring to. In order to create Topology Rules you will need either an ArcEditor or ArcInfo license and store your Feature Class in a Feature Dataset in a personal or file geodatabase.

You would most likely want to implement the "Must Not Have Gaps" rule. Once you have created the rulebase with all of the rules that you think are necessary, you would want to validate the topology which will identify all of the errors in your data.

Then, using the Error Inspector and the Fix Topology Errors Tool, you can either individually or bulk select the errors you want to fix and how you want to fix them (ie- create new polygons to fill the voids or merge with larger polygons nearby).

6

There is an "Eliminate sliver polygons" function in QGIS 2.12 (Lyon) Toolbox. I am sure it is also in some earlier version.

3

Well, I've been using a PostGIS function (I use on my QGIS directly) that executes a recursive snap to solve this problem. The results are quite good, it just demand a good joice of tolerance values to get best results. If you are willing to try, check it (in my case the geometries are all multi, hence the st_multi in my execute):

CREATE OR REPLACE FUNCTION dsgsnap(tabela text, snap float) RETURNS void AS 
        $BODY$
            DECLARE
            id int;
            BEGIN
                FOR id in execute('select id from '||tabela)
                LOOP
                    EXECUTE     
                'update '||tabela||' as classe set geom = st_multi(res.geom) 
                from 
                    (
                        select st_snap(a.geom, st_collect(b.geom), '||snap||') as geom, a.id as id 
                        from '||tabela||' a, '||tabela||' b 
                        where a.id != b.id and a.id = '||id||' 
                        group by a.id, a.geom
                    ) as res 
                where res.id = classe.id';
                END LOOP;
                RETURN;                        
            END
        $BODY$
        LANGUAGE plpgsql;
0

I faced the same problem, which by exploring the tools I settled quite easily although I dont know the logic. ![In tools go to Data Management tool box, go to Feature Class and run the Integrate script by double click][1]

in the Script window select the feature class having problem and in the XY tolerance add the vale by measuring distance with the help of measure tool at multiple points and get an average vale put that value in the tolerance environment and apply the problem get solved I do not now how but solved with about 90% accuracy. ![enter image description here][2]

I tried all other methods described in above answers but was a hard and cumbersome to get the automated corrections for gaps between the adjacent polygons.

1
  • 1
    If you paste a link to the images you are referring to I can add them in.
    – djq
    Commented Nov 21, 2012 at 21:32
0

Not a perfect solution, but one of these two things works for me in most cases:

  1. In QGIS, save the layer in GEOJSON format. But before saving, in the "save layer as" dialogue box, set the coordinate precision to 3 (15 is the default). This will have the effect of uniting vertices that are very close to eachother.

  2. Go to Mapshaper, upload the file, and hit "simplify." In the upper-left corner it will tell you how many line intersections it finds, and will give you the option to fix them. I find this fix works about half the time.

-1

I haven't used it, but ET Geowizards, which brings many ArcEditor and ArcInfo only processing tools to the ArcView level license (a.k.a. ArcGIS Standard) has an Eliminate Wizard that "Eliminates unwanted polygons (slivers) by merging them into the neighboring polygons or deleting them". The wizard toolkit will set you back $250 usd (pricelist).

-1

QGIS Processing Toolbox has "Snap geometries to layer"

0

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