7 votos

Precisión coordenada fuerza en QGIS cuando ahorro a PostGIS

¿Es posible configurar QGIS de una manera, que uno puede definir específicamente la deseada precisión coordenada que se guarda para cada punto de vértice al escribir en una capas PostGIS? Quiero lograr WGS84 en coordenadas se guardan como

En lugar de

Cambiar la configuración de visualización de coordenadas del proyecto no hace el truco.

12voto

MBCook Puntos 8316

Usted puede hacer esto mediante la adición de un disparo a la mesa en la que estás editando. En primer lugar, se puede definir un genérico de ajuste de disparo:

CREATE OR REPLACE FUNCTION snap_coords ()
RETURNS TRIGGER AS $$
BEGIN
    NEW.geom := ST_SnapToGrid(NEW.geom, TG_ARGV[0]::float);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Usted podría tener esta función de complemento para una precisión fija (como 1e-5), pero este ejemplo permite una precisión que se pasa como argumento cuando el gatillo está enlazado a una tabla.

A continuación, ejecute un CREATE TRIGGER norma para obligar a la función de disparador para la tabla:

CREATE TABLE test (id serial, geom geometry);

CREATE TRIGGER test_snap_coords
BEFORE INSERT OR UPDATE ON test
FOR EACH ROW EXECUTE PROCEDURE snap_coords (1e-5);

Ahora, podemos comprobar que las geometrías almacenados a test son de hecho, espetó:

INSERT INTO test(geom) VALUES ('POINT(0.0628843267570899 0.24537407891492)'::geometry)

SELECT ST_AsText(geom) FROM test;
-- POINT(0.06288 0.24537)

Una advertencia

Usted puede estar sorprendido por el resultado de la siguiente consulta:

SELECT ST_Equals(geom, 'POINT(0.06288 0.24537)') FROM test;
-- false

El ST_SnapToGrid función no siempre se obtienen las coordenadas que están en consonancia con los producidos por el analizador sintáctico de coordenadas. Para intentar aclarar a modo de ejemplo, considere el siguiente punto:

POINT (0 1.5234567)

Si analizamos este punto y la almacenan como una geometría PostGIS, obtendremos el siguiente binario geometría:

010100000000000000000000000EF4F5211460F83F

El ajuste de este momento, 1e-7 debe ser un no-op, ¿verdad? Pero ST_SnapToGrid('POINT (0 1.5234567)') devuelve un diferente valor binario:

010100000000000000000000000DF4F5211460F83F

Tenga en cuenta que la primera E en la cadena binaria se ha convertido en un F. Ambos son "correctas" en el sentido de que no puede almacenar 1.5234567 exactamente como un número de punto flotante, y ambos de la almacenan las coordenadas están muy cerca de (0, 1.5234567). En efecto, llamando ST_AsText devolverá la misma cadena de texto para ambos.

Sin embargo, si su aplicación/base de datos consume texto coordenadas a partir de otras fuentes, puede que desee que la almacenan las coordenadas de ser coherente con la representación de texto. En este caso, el gatillo se debe en realidad la fuerza de las coordenadas a través de un viaje redondo para el texto.

CREATE OR REPLACE FUNCTION snap_coords ()
RETURNS TRIGGER AS $$
BEGIN
    NEW.geom := ST_AsText(ST_SnapToGrid(NEW.geom, TG_ARGV[0]::float));
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Ahora, la ejecución de la consulta de prueba de nuevo, podemos ver que nuestro almacenados de coordenadas es consistente con la representación de texto.

SELECT id, ST_Equals(geom, 'POINT(0.06288 0.24537)') FROM test;

 id | st_equals 
----+-----------
  3 | f
  4 | t

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