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