Así que, si entiendo bien tu pregunta, hay muchas soluciones y ésta es una de ellas.
No queda claro en tu dibujo si quieres tener en cuenta las rotaciones en los objetos poligonales, si todas las formas son similares al patrón, etc.
Para el primer ejemplo (imagen 1), RUN CTE
WITH
tbla AS (SELECT (ST_Dump(geom)).geom geom FROM <table_name>),
tblb AS (SELECT ST_LongestLine(a.geom, b.geom) geom FROM tbla a JOIN
tbla b ON ST_Intersects(a.geom, b.geom))
(SELECT geom, ST_Length(geography(geom)) lenght FROM tblb)
Para el segundo ejemplo (imagen 2), he creado intuitivamente otra función de cálculo espacial y he calculado en m, la anchura media de un objeto poligonal complejo:
CREATE OR REPLACE FUNCTION ST_AvgLengthLineIRRegularPolygon(
geom GEOMETRY,
n integer)
RETURNS double precision AS
$BODY$
WITH
tbl_rigth AS (WITH
tbla AS (SELECT (ST_Dump(geom)).geom geom),
tblb AS (SELECT ST_LongestLine(a.geom, b.geom) geom FROM tbla a JOIN tbla b ON ST_Intersects(a.geom, b.geom)),
tblc AS (SELECT geom, ST_Length(geography(geom)) lenght FROM tblb),
tbld AS (SELECT ST_Buffer(geom, lenght/1855/60) geom FROM tblc),
tble AS (SELECT ST_Boundary(ST_OrientedEnvelope(geom)) geom FROM tbld),
tblf AS (SELECT line1, line2 FROM (SELECT ST_MakeLine(ST_PointN(geom,1), ST_PointN(geom,2)) line1,
ST_MakeLine(ST_PointN(geom,4), ST_PointN(geom,3)) line2 FROM tble) foo),
tblg AS (SELECT generate_series (0, n) as steps),
tblh AS (SELECT steps AS stp1, ST_LineInterpolatePoint(line1, steps/(SELECT count(steps)::float-1 FROM tblg)) geom1 FROM tblf, tblg GROUP BY tblg.steps, geom1),
tbli AS (SELECT steps AS stp2, ST_LineInterpolatePoint(line2, steps/(SELECT count(steps)::float-1 FROM tblg)) geom2 FROM tblf, tblg GROUP BY tblg.steps, geom2),
tblj AS (SELECT ST_MakeLine(geom1, geom2) geom FROM tblh JOIN tbli ON true AND stp1=stp2),
tblk AS (SELECT (ST_Dump(ST_Intersection(a.geom, b.geom))).geom geom, count(*) cnt FROM tblj a JOIN tbla b ON true GROUP BY a.geom, b.geom)
(SELECT ST_Length(geography(ST_Union(geom)))/SUM(cnt) avg_length FROM tblk)),
tbl_lefth AS (WITH
tbla AS (SELECT (ST_Dump(geom)).geom geom),
tblb AS (SELECT ST_LongestLine(a.geom, b.geom) geom FROM tbla a JOIN tbla b ON ST_Intersects(a.geom, b.geom)),
tblc AS (SELECT geom, ST_Length(geography(geom)) lenght FROM tblb),
tbld AS (SELECT ST_Buffer(geom, lenght/1855/60) geom FROM tblc),
tble AS (SELECT ST_Boundary(ST_OrientedEnvelope(geom)) geom FROM tbld),
tblf AS (SELECT line1, line2 FROM (SELECT ST_MakeLine(ST_PointN(geom,2), ST_PointN(geom,3)) line1,
ST_MakeLine(ST_PointN(geom,1), ST_PointN(geom,4)) line2 FROM tble) foo),
tblg AS (SELECT generate_series (0, n) as steps),
tblh AS (SELECT steps AS stp1, ST_LineInterpolatePoint(line1, steps/(SELECT count(steps)::float-1 FROM tblg)) geom1 FROM tblf, tblg GROUP BY tblg.steps, geom1),
tbli AS (SELECT steps AS stp2, ST_LineInterpolatePoint(line2, steps/(SELECT count(steps)::float-1 FROM tblg)) geom2 FROM tblf, tblg GROUP BY tblg.steps, geom2),
tblj AS (SELECT ST_MakeLine(geom1, geom2) geom FROM tblh JOIN tbli ON true AND stp1=stp2),
tblk AS (SELECT (ST_Dump(ST_Intersection(a.geom, b.geom))).geom geom, count(*) cnt FROM tblj a JOIN tbla b ON true GROUP BY a.geom, b.geom)
(SELECT ST_Length(geography(ST_Union(geom)))/SUM(cnt) avg_length FROM tblk))
SELECT avg_length FROM tbl_rigth UNION SELECT avg_length FROM tbl_lefth
$BODY$
LANGUAGE SQL
RUN
SELECT ST_AvgLengthLineIRRegularPolygon(geom, 300) avglengt FROM <table_name>
Esta respuesta es la continuación de esa respuesta: https://gis.stackexchange.com/a/418891/120129
Soluciones espaciales originales...
Traducido con www.DeepL.com/Translator (versión gratuita)
1 votos
Es una pregunta interesante, y definitivamente es posible. Como mínimo, basta con trazar una línea de cada vértice a cada uno de los otros, con un tiempo de ejecución polinómico, pero una solución. Para soluciones más elegantes, echa un vistazo a gis.stackexchange.com/questions/32552/
1 votos
Su ilustración de "longitud máxima" parece clara, pero su ejemplo de "anchura media" no es perpendicular a dicha longitud. ¿No debería serlo? Luego mencionas la "altura". Todo es un poco confuso.
1 votos
Creo que es necesario detallar más este concepto de anchura media, en particular con ejemplos de las geometrías reales que estás utilizando
0 votos
¿Por qué no? rectángulo de mejor ajuste y su diagonal ? (en lugar de la longitud máxima) ... Imagina un rectángulo con la misma área y un anchura paralela a la ST_OrientedEnvelope o algo similar. Así, el "rectángulo medio y mejor ajustado", con anchura W y la longitud L , suministrará una diagonal D ,
D=SQRT(W^2+D^2)
.... Si es válido, puede utilizar mi respuesta a continuación para todos los valores, W , L y D .