I am trying to get my head around PostGIS and QGIS. I'm trying to find the area (in white) bounded by three multipolygons (in purple) - refer to picture. Each multipolygon only touches the other two multipolygons; there are no intersections.

More info: The purple areas are defined as multipolygons in the PostGIS table. I'm interested in just the coordinates for the white area. The coordinate reference system is WGS84.

Basically, the purple areas are maritime boundaries/EEZs which have been defined in the postgis table. The white area refers to international waters/high seas pockets between those maritime boundaries. I'm trying to identify the coordinates of the white areas so that I can create records for them in the same postgis table that has the EEZs. I'm building a web-app for monitoring vessel movements near real-time between EEZs and high seas pockets.

  • Welcome to gis.SE. Can you expand your question a bit, to include more background: Are the purple areas really multipolygons? Or do you mean just polygon? Do you want the coordinates of the white area or just its area? What is the end-goal of this? Can you tell us the coordinate reference system? What format do you have the data in? You can just click edit below your question to include this information. – BradHards Dec 23 '13 at 4:35
  • Thanks BradHards, I've added more information regarding my question. Cheers. – Kenneth Dec 23 '13 at 5:05
  • Would it work for you to just define a (multi)polygon for the full WGS-84 extent, then subtract all the EEZs? – BradHards Dec 23 '13 at 6:31
  • BradHards I thought of doing that but my knowledge of postgis/qgis is rather limited at the moment and couldn't figure out how to do it. Any pointers? – Kenneth Dec 23 '13 at 11:30

Do it in SQL (might get funny results when there is no bounded area...)

WITH fullarea AS (
  SELECT ST_Union(poly) AS geom FROM mytable
SELECT ST_Difference(ST_BuildArea(ST_ExteriorRing(geom), geom)
FROM fullarea;

Basically, if you subtract the thing-with-hole from the bounds-of-thing, you get just the hole. Alternatively, if you know you're only going to have one hole, you could just use the ST_InteriorRing() function to extract the bounds of the hole from the results of ST_Union().


first use : Vector > geometry tools > polygons to lines

Then : Vector > geometry tools > lines to polygons

This will create an additionnal polygon at the center

  • Thanks radouxju but I got the same three polygons I started off with – Kenneth Dec 23 '13 at 11:26
  • I bet that this is because your polygons are not "really" touching. Could you make a quick test after buffering your purple polygons to make sure that they intersect ? – radouxju Dec 23 '13 at 11:36
  • Ok let me figure out how to do that. Although using your suggestion, I tried dissolving the geoms and then applied the poly to line followed by the line to poly and that created the polygon in the center. Not sure if that's a good way to do it or not. Still feeling my way around this. – Kenneth Dec 23 '13 at 11:42

What you're describing sounds like geofencing. To do this, you probably want to decide if you want the white areas to be one polygon, a collection of polygons (a Multipolygon type), or separate polygons. If you're tracking ships in maritime waters, you probably want to know exactly what areas they're transiting through, but if not, I'd recommend @BradHards suggestion to just draw a large polygon for the whole extent and then subtract the area of the polygons to get the white area you're interested in.

To draw a large polygon in QGIS, follow these directions from the QGIS manual. You can also use this method to manually draw your polygons if that's easier for you. Use the union and difference tools in QGIS to get the polygon or polygons you want.

To create a large polygon directly in PostGIS, you'll want to use ST_GeomFromText and pass in your type, coordinates, and SRID. You'll then want to use ST_Difference to subtract the area of the other polygons. Here's an interesting reference from BostonGIS.

To get one multipolygon of the white area, I'd use ST_Union to get the union of the three areas and then use ST_Difference and hope PostGIS automatically casts the object to a multipolygon. I'm not near a computer to test this, but it would look like:

INSERT INTO table (id, geom) 
    VALUES (4, 
           ST_GeomFromText(POLYGON(<point1>,<point2>, <point3>,<point4>), 4326), 
           ST_Union(poly1, poly2, poly3)

The "id" value is just a dummy assuming your polygons have a serial from 1-3. The four points (, ...,) will define the larger polygon. You can nest the ST_Union call if it doesn't like three geometries:

ST_Union(poly1, ST_Union(poly2, poly3))

If you want to create separate polygons for each white area, you can split the multipolygon with ST_Dump or instead of starting with one large polygon, use smaller polygons that cover the particular white area and do the ST_Union and ST_Difference trick above for each area to get distinct polygons for each white area.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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