24 votos

PostGIS la Geometría de la Consulta devuelve "Error: la Operación de mezclado SRID geometrías" sólo para ciertos valores

He PostGIS tabla con dos columnas de geometría, ambos definidos con SRID 4326. Puedo insertar en la tabla sin problema, utilizando la siguiente INSERT instrucción (donde lng y lat son los valores que se pasan en la programación):

INSERT INTO pad_meta (
    uuid, created, updated, name, origin, radius, area, expiry, creator
) VALUES (
    $1, now(), now(), $2, ST_GeomFromText('POINT(lng, lat)', 4326), $3, 
    ST_Buffer(ST_GeomFromText('POINT(lng, lat)', 4326), $4), $5, $6
)

Pero cuando voy a consulta para una intersección con ST_Intersects, dependiendo del valor del punto llego ERROR: Operation on mixed SRID geometries.

Por ejemplo, esta consulta funciona:

SELECT * FROM pad_meta where ST_Intersects(
    'POINT(-122.334172173172 46.602634395263560)'::geometry, area::geometry 
) ORDER BY created DESC;

Y este error:

SELECT * FROM pad_meta where ST_Intersects(
    'POINT(-122.334172173172 47.602634395263560)'::geometry, area::geometry 
) ORDER BY created DESC;

Nota, son consultas idénticas, excepto el valor de la longitud. He experimentado con diferentes valores, pero no se identifica un claro punto de transición entre las consultas que funcionan y las que no.

Creo que estoy fundamentalmente de la incomprensión algo. Por el momento, he resuelto/corregidos/trabajó en el problema de volver a formatear la consulta para utilizar ST_GeomFromText y se especifica explícitamente el SRID:

SELECT * FROM pad_meta where ST_Intersects(
    ST_GeomFromText('POINT(-122.334172173172 47.602634395263560)', 4326), area
) ORDER BY created DESC;

Pero, sinceramente, no entiendo muy bien cuál es la diferencia, o si realmente "la" solución.

Mi pregunta es: ¿por Qué estoy recibiendo un error sólo para valores específicos, y cuál es la forma correcta para dar formato a esta consulta?

Aquí está mi definición de tabla de referencia:

CREATE TABLE IF NOT EXISTS pad_meta (
  uuid CHAR(32),
  created TIMESTAMP,
  updated TIMESTAMP,
  name VARCHAR(128),
  origin GEOMETRY(Point, 4326),
  radius INTEGER,
  area GEOMETRY(Polygon, 4326),
  expiry TIMESTAMP,
  creator CHAR(32),
  PRIMARY KEY (uuid)
);

También he comprobado que hay sólo un tipo de SRID en el geometry_columns:

SELECT f_table_name, f_geometry_column, srid FROM geometry_columns;
f_table_name | f_geometry_column | srid
--------------+-------------------+------
 pad_meta     | origin            | 4326
 pad_meta     | area              | 4326

Ayuda/asesoramiento apreciado. Gracias! (Nota: también he visto esta pregunta, pero desde ya estoy definiendo explícitamente mi geometría Srid al insertar en la tabla, parece que eso no es lo que está sucediendo).

34voto

hernan43 Puntos 566

Cuando se especifica una geometría sin un SRID, es en realidad 0 (o -1 para la versión < 2):

SELECT ST_SRID('POINT(-122.334172173172 46.602634395263560)'::geometry);
 st_srid
---------
       0

Así que cuando se utiliza esta geometría con otro de SRID=4326, es la mezcla de 0 y 4326. Esto suele ser un error útil, si las referencias espaciales son verdaderamente diferentes. En su caso, el Srid son el mismo, pero no codificar el SRID a la consulta de punto. Así que, para solucionar su consulta especifique siempre el mismo SRID para su consulta punto, y no van a ser mixto.

Como una nota del lado, el geography tipo tiene un defecto SRID de 4326 (WGS 84), como se muestra aquí:

SELECT ST_SRID('POINT(-122.334172173172 46.602634395263560)'::geography::geometry);
 st_srid
---------
    4326

Así, si usted usa geography tipos en lugar de geometry tipos, el SRID no necesita ser especificado (a menos que quieras una diferente SRID una alternativa elipsoide de Marte o lo que sea).


En cuanto a por qué una consulta tiene un error, y el otro no, ST_Intersects realiza un && cuadro delimitador de búsqueda, que es rápido, y no se preocupan por Srid. No mezclado SRID los mensajes de error se produce si los recuadros de delimitación no se cruzan. Pero si se cruzan, el segundo filtro es _ST_Intersects, que es más preciso y comprobaciones de los dos Srid para asegurarse de que coinciden, y genera un error si se mezclan. Por ejemplo:

WITH pad_meta AS (
    SELECT 'SRID=4326;POLYGON((-124 50, -124 47, -121 50, -124 50))'::geometry AS area)

SELECT * FROM pad_meta where ST_Intersects(
    'POINT(-122.334172173172 46.602634395263560)'::geometry, area::geometry 
);

no tiene ningún intersección de las cajas de contorno, y omite _ST_Intersects. Pero POINT(-122.334172173172 47.602634395263560) aumentará el error porque los recuadros de delimitación se sobreponen (aunque las geometrías en realidad no se cruzan).

Sin embargo, con la misma geometría y de filtro diferentes:

WITH pad_meta AS (
    SELECT 'SRID=4326;POLYGON((-124 50, -124 47, -121 50, -124 50))'::geometry AS area)

SELECT * FROM pad_meta where _ST_Intersects(
    'POINT(-122.334172173172 46.602634395263560)'::geometry, area::geometry 
);

lanza una mezcla de SRID error, porque en las cajas de contorno no son considerados.

0voto

Scro Puntos 1729

Un par de observaciones que pueden ayudar: Uno, Point(Double, Double) es un nativo de PostgreSQL la función para la que la conversión a un tipo de datos PostGIS. ST_MakePoint(double x, double y) creará adecuada de la geometría. También, en su pregunta se parecen referirse al segundo argumento como la longitud. El orden correcto es x, y, que corresponde a Longitude, Latitude. Obtención de las invertida puede devolver resultados inesperados, sin lanzar ninguna excepción.

Nada de esto realmente explica el por qué de su primer ejemplo a veces funciona y a otros no, pero espero que esto le ayudará a crear una buena consultas.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X