Suite

ST_MakeLine équivalent pour CIRCULARSTRING dans PostGIS

ST_MakeLine équivalent pour CIRCULARSTRING dans PostGIS


J'aimerais créer un CIRCULARSTRING dans PostGIS 2.0.0 à partir de points calculés dans le cadre de la requête (plutôt que de constantes). Pour un LINESTRING, je peux le faire en utilisant ST_MakeLine(). Existe-t-il un équivalent pour CIRCULARSTRING ou une autre façon de le faire ?

J'ai 3 points qui sont calculés d'une manière ou d'une autre (dans l'exemple, utilisons simplement ST_GeomFromText):

SELECT ST_GeomFromText('POINT(10 10)'), ST_GeomFromText('POINT(15 10)'), ST_GeomFromText('POINT(10 20)')

Ce que je veux obtenir, c'estCHAÎNE CIRCULAIRE (10 10, 15 10, 10 20).

Si je lance :

ST_LineToCurve(ST_MakeLine(ARRAY[ST_GeomFromText('POINT(10 10)'), ST_GeomFromText('POINT(15 10)'), ST_GeomFromText('POINT(10 20)')]))

ça me donneLINESTRING (10 10,15 10,10 20), pas unCHAÎNE CIRCULAIRE.

Même question pour CURVEPOLYGON - que puis-je utiliser à la place de ST_MakePolygon (qui renvoie "Shell is not a line" si je passe dans un CIRCULARSTRING) ?


EM,

Ce que vous demandez est une bonne idée, et je pense qu'il est assez trivial à mettre en œuvre. Je suggérerais de publier une amélioration de ticket sur le suivi des bogues PostGIS. Peut-être l'appeler ST_MakeCurveLine ou quelque chose comme ça.

http://trac.osgeo.org/postgis/newticket

Cela ne passera probablement pas en 2.0 puisque nous approchons du gel des fonctionnalités, mais on ne sait jamais, donc probablement, seules les choses pour lesquelles les gens sont prêts à payer auront une chance d'être ajoutées. De toute façon, si vous le mettez, cela le fera très probablement pour 2.1.

Comme solution rapide, vous pouvez utiliser ST_MakeLine en combinaison avec ST_AsText et ST_CurveToLine.

Donc quelque chose comme ST_CurveToLine((replace(ST_AsText(ST_MakeLine(yourpointset)), 'LINESTRING', 'CIRCULARLINESTRING'))::geometry)


C'est la fonction que j'ai fini par écrire, basée sur LR1234567la réponse de :

CRÉER OU REMPLACER LA FONCTION make_circularstring(points geometry(Point)[]) RETOURNE geometry(CircularString) AS $BODY$ DECLARE start_index integer ; end_index entier ; srid entier ; BEGIN start_index = array_lower(points, 1); end_index = array_upper(points, 1); -- Les points de début et de fin doivent avoir le même SRID. Les transformer n'est pas sûr, car cette fonction doit -- retourner un CIRCULARSTRING avec les points de début et de fin correspondant exactement à l'entrée. srid = ST_SRID(points[start_index]); SI (ST_SRID(points[end_index]) != srid) ALORS RAISE EXCEPTION 'Le SRID du point de départ (%) diffère du SRID du point d'arrivée (%) - ils doivent correspondre.', ST_AsEWKT(points[start_index]), ST_AsEWKT(points[ index_fin]); FIN SI; --… mais tous les points intermédiaires peuvent être transformés. FOR i IN (start_index + 1)… (end_index - 1) LOOP points[i] = ST_Transform(points[i], srid); FIN DE BOUCLE ; RETURN ST_GeomFromEWKT(remplacer(ST_AsEWKT(ST_MakeLine(points)), 'LINESTRING', 'CIRCULARSTRING')); END $BODY$ LANGUAGE plpgsql STABLE;

Essayer ST_LigneVersCourbe

ST_LineToCurve - Convertit un LINESTRING/POLYGON en un CIRCULARSTRING, CURVED POLYGON

Je sais que ce n'est pas l'équivalent de ST_MakeLine, mais vous pouvez utiliser ST_MakeLine puis le convertir en votre POLYGONE COURBE ou CIRCULARSTRING en utilisant ST_LineToCurve.

Vous devriez être capable de faire quelque chose comme :

sélectionnez ST_LineToCurve(ST_MakeLine(… ))

EDIT #1 : D'accord, je ne comprends pas parfaitement pourquoi parfois ST_LineToCurve renvoie une chaîne de ligne, mais ce sont des comportements que j'ai remarqués et c'est peut-être pourquoi ils disent que ce n'est pas "entièrement pris en charge".

Une chaîne circulaire valide doit avoir un nombre impair de points supérieur à 1.

De plus, il semble que s'il ne suive pas un chemin droit, il renverra un LINESTRING.

Par exemple:

Cette ligne droite :

sélectionnez ST_AsEWKT(ST_LineToCurve(ST_MakeLine(ARRAY[ST_GeomFromText('Point(10 15)'), ST_GeomFromText('POINT(20 30)'), ST_GeomFromText('POINT(30 45)'), ST_GeomFromText('POINT(40 60) ')]))))

Retour:

"CORDONNE CIRCULAIRE (10 15,30 45,40 60)"

Cette ligne non droite :

sélectionnez ST_AsEWKT(ST_LineToCurve(ST_MakeLine(ARRAY[ST_GeomFromText('Point(11 15)'), ST_GeomFromText('POINT(20 30)'), ST_GeomFromText('POINT(30 45)'), ST_GeomFromText('POINT(40 60) ')]))))

Retour:

"LINESTRING(11 15,20 30,30 45,40 60)"

Si c'était moi qui avais ce problème, je rejoindrais les listes de diffusion postgis-users et/ou postgis-devel, je leur expliquerais ce comportement et je verrais ce qu'ils disent. Est-ce par conception? Est-ce à cause d'un bogue ou d'un problème non entièrement pris en charge ?