13

I would like to create a surrounding rectangle with maxiumum width/height ratio ("oblique bounding box") from a set of input features as shown in the image below:

enter image description here

E.g. the PostGIS functions ST_Envelope and ST_Box2D as well as FME Transformers BoundingBoxReplacer and BoundingBoxAccumulator generate axis parallel bounding boxes.

Any suggestions using approaches with PostGIS, QGIS or FME greatly welcome!

  • Not an exact duplicate, because the guy is not asking for a solution applicable in FME or PostGIS. Nevertheless, the python script referred to in the answer to the question referred to above is quite useful to be put in the FME PythonCaller transformer. If I have a workspace running, I'll post a solution with a slightly modified script. – Jochen Schwarze Nov 2 '17 at 11:57
  • Not only is it not a duplicate, but the referenced question has not been accepted, and there are unanswered questions as to which algorithm it uses, and whether it is exact or not. – John Powell Nov 2 '17 at 13:00
  • See my answer below. You should be able to do this in FME. What version are you using? – Fezter Nov 3 '17 at 5:40
9

This is probably overkill on the processing front and there is likely to be a better mathematical solution, but as an example of a way that it could be done rather simply as a query

SELECT 
   id, rotated_by, oblique_bound
  FROM 
     (
     SELECT 
        m.id,
        r rotated_by, 
        ST_Rotate(ST_Envelope(ST_Rotate(m.geom, r)),-r) oblique_bound,
        row_number OVER (PARTITION BY id) 
                   ORDER BY ST_Area(ST_Rotate(ST_Envelope(ST_Rotate(m.geom, r)),-r))) N
       FROM 
          generate_series(0, 90, 0.1) N(r), my_table m
    ) s
WHERE N = 1;

This rotates the geometry, creates the bounds, reverses the rotation for each tenth of a degree between 0 and 90. The result is then the bounding box with the least area. Of course this is not an entirely accurate way of doing it and may need tweaking of the increment value in the series depending on your requirements.

  • Actually, I think this is a great solution. The exact solutions are extremely expensive. You could easily extend it in plpgsql to record the best x bounding boxes, and if two were very close, you could zoom in and do some smaller rotations to get closer to an exact solution. There would alwasy be edge cases, but a nice approach. – John Powell Nov 3 '17 at 8:36
  • And as an additional benefit it preserves the rotation angle :-) – Jochen Schwarze Nov 3 '17 at 10:47
6

QGIS has a "minimum oriented bounding box" algorithm which does exactly this.

  • It is called "Oriented minimum bounding box". You can call it from the Processing Toolbox > QGIS geoalgorithms > Vector general tools. – Stefan Nov 3 '17 at 8:50
  • I presume this is beyond QGIS 2.14, because I could not find it in 2.14.15LTR wich we're still using here? – Jochen Schwarze Nov 3 '17 at 10:43
  • @JochenSchwarze it exists in QGIS 2.14.19. You need to search in Processing toolbox. Directly, you can find it under Processing toolbox -> QGIS geoalgorithms -> Vector General tools -> Oriented minimum bounding box – ahmadhanb Nov 3 '17 at 12:25
4

The bounding box replacer transformer, which you mentioned should be able to do this. According to the documentation it,

Replaces the geometry of the feature with either its two-dimensional bounding box or its two-dimensional minimum oriented bounding box.

The parameter allows you to choose either axis-algined or rectilinear bounding box.

Apparently, there is a suggested enhancement to include the angle of the longer side of the oriented bounding box. This is Safe Number PR#53924.

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.