Créer un «cadre de délimitation oblique» avec un rapport largeur / hauteur maximum?

13

Je voudrais créer un rectangle environnant avec un rapport largeur / hauteur maxiumum ("boîte de délimitation oblique") à partir d'un ensemble de caractéristiques d'entrée comme indiqué dans l'image ci-dessous:

entrez la description de l'image ici

Exemples : Les fonctions PostGIS ST_Envelopeet ST_Box2Dainsi que FME transformateurs BoundingBoxReplaceret BoundingBoxAccumulatorgénérer des boîtes englobantes axe parallèle.

Toutes les suggestions utilisant des approches avec PostGIS, QGIS ou FME sont les bienvenues!

Jochen Schwarze
la source
Pas un double exact , car le gars ne demande pas de solution applicable dans FME ou PostGIS. Néanmoins, le script python mentionné dans la réponse à la question mentionnée ci-dessus est très utile pour être placé dans le transformateur FME PythonCaller. Si j'ai un espace de travail en cours d'exécution, je publierai une solution avec un script légèrement modifié.
Jochen Schwarze
Non seulement ce n'est pas un doublon, mais la question référencée n'a pas été acceptée, et il y a des questions sans réponse quant à l'algorithme qu'il utilise, et s'il est exact ou non.
John Powell,
Voir ma réponse ci-dessous. Vous devriez pouvoir le faire dans FME. Quelle version utilisez-vous?
Fezter

Réponses:

9

C'est probablement exagéré sur le front du traitement et il y aura probablement une meilleure solution mathématique, mais comme un exemple de façon dont cela pourrait être fait plutôt simplement comme une requête

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;

Cela fait pivoter la géométrie, crée les limites, inverse la rotation pour chaque dixième de degré entre 0 et 90. Le résultat est alors la boîte englobante avec la plus petite surface. Bien sûr, ce n'est pas une manière entièrement précise de le faire et peut nécessiter un ajustement de la valeur d'incrément dans la série en fonction de vos besoins.

MickyT
la source
En fait, je pense que c'est une excellente solution. Les solutions exactes sont extrêmement coûteuses. Vous pouvez facilement l'étendre dans plpgsql pour enregistrer les meilleures boîtes englobantes x, et si deux étaient très proches, vous pouvez zoomer et effectuer des rotations plus petites pour vous rapprocher d'une solution exacte. Il y aurait toujours des cas marginaux, mais une bonne approche.
John Powell
Et comme avantage supplémentaire, il préserve l'angle de rotation :-)
Jochen Schwarze
6

QGIS a un algorithme de "boîte de délimitation orientée minimale" qui fait exactement cela.

ndawson
la source
Il est appelé "boîte de délimitation minimale orientée". Vous pouvez l'appeler à partir de la boîte à outils de traitement> Géoalgorithmes QGIS> Outils généraux vectoriels.
Stefan
Je suppose que cela dépasse QGIS 2.14, car je ne l'ai pas trouvé dans 2.14.15LTR que nous utilisons encore ici?
Jochen Schwarze
@JochenSchwarze, il existe dans QGIS 2.14.19. Vous devez rechercher dans la boîte à outils Traitement. Directement, vous pouvez le trouver sousProcessing toolbox -> QGIS geoalgorithms -> Vector General tools -> Oriented minimum bounding box
ahmadhanb
4

Le transformateur de remplacement du boîtier englobant , que vous avez mentionné, devrait être en mesure de le faire. Selon la documentation,

Remplace la géométrie de l'entité par sa boîte englobante bidimensionnelle ou sa boîte englobante orientée minimale bidimensionnelle.

Le paramètre vous permet de choisir un cadre de délimitation à axe aligné ou rectiligne.

Apparemment, il y a une amélioration suggérée pour inclure l'angle du côté le plus long du cadre de délimitation orienté. Il s'agit du numéro de sécurité PR # 53924.

Fezter
la source