No PostGIS, tenho um monte de objetos LINESTRING Z (que representam pólos) e quero descobrir quais estão dentro de uma área (representada por um POLYGON). Para os fins deste exercício, podemos assumir com segurança que um poste é praticamente vertical, para que não cruze o limite da área.
O problema é que, às vezes, o poste é exatamente vertical.
Esta consulta, a que eu gostaria de fazer, não tem êxito:
SELECT ST_Intersects(ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));
Explorando algumas variantes, é possível:
SELECT ST_Intersects(ST_GeomFromText('POINT (544483.525 6849134.28)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));
Isso não tem êxito:
SELECT ST_Intersects(ST_GeomFromText('LINESTRING (544483.525 6849134.28,544483.525 6849134.28)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));
Se você fizer uma consulta 3DIntersects, ela terá êxito:
SELECT ST_3DIntersects(ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));
no entanto, gera um aviso de que:
One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value"
Então isso funciona, mais ou menos, mas enche meus logs de ruído e eu prefiro não desativar os avisos.
Minha leitura do padrão de acesso ao recurso OpenGIS Simple (consulte a parte 1, seção 4.14) é que, embora o LINESTRING seja degenerado, ele ainda deve ser interpretado como topologicamente fechado, para que eles se cruzem.
Isso está correto?
EDITAR
Após algumas experiências, posso responder parte da minha própria pergunta. A razão pela qual as consultas acima retornam false é isso porque acredita-se que o LINESTRING Z não seja válido:
SELECT ST_IsValidReason(ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356));
st_isvalidreason
----------------------------------------------------------------------
Too few points in geometry component[544483.525 6849134.28 104.1098]
(1 row)
É uma maneira educada de dizer que o OGC não suporta 3D e, como tal, o GDAL / PostGIS apenas o suporta.
Posso aceitar isso, embora ainda não tenha encontrado nada na especificação OGC que indique que o LINESTRING correspondente não é válido.
Então, acho que minha pergunta é: existe uma maneira oficialmente abençoada de encontrar a pegada de um pedaço de geometria 3D que sempre retorna geometria 2D válida?