When you specify a geometry without an SRID, it is actually 0
(or -1
for version < 2):
SELECT ST_SRID('POINT(-122.334172173172 46.602634395263560)'::geometry);
st_srid
---------
0
So when you use this geometry with another one with SRID=4326, it is mixing 0
and 4326
. This is usually a useful error, if the spatial references are truly different. With your case, the SRIDs are the same, but you didn't encode the SRID to the query point. So, to fix your query always specify the same SRID for your query point, and they will no longer be mixed.
As a side note, the geography
type has a default SRID of 4326 (WGS 84), as shown here:
SELECT ST_SRID('POINT(-122.334172173172 46.602634395263560)'::geography::geometry);
st_srid
---------
4326
So, if you use geography
types instead of geometry
types, the SRID does not need to be specified (unless you want a different SRID for an alternative ellipsoid for Mars or whatever).
As to why one query has an error, and the other does not, ST_Intersects
first does a &&
bounding box search, which is fast, and doesn't care about SRIDs. No mixed SRID error messages will be raised if the bounding boxes don't intersect. But if they do intersect, the second filter is _ST_Intersects
, which is more precise and checks the two SRIDs to make sure they match, and raises an error if they are mixed. For example:
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
);
does not have any intersecting bounding boxes, and bypasses _ST_Intersects
. But POINT(-122.334172173172 47.602634395263560)
will raise the error because the bounding boxes do overlap (even though the geometries don't actually intersect).
However, with the same geometries and different filter:
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
);
throws a mixed SRID error, because bounding boxes are not considered.
There are a few issues to consider. First, have you considered using a VIEW? I.e.
CREATE OR REPLACE VIEW places_with_coods AS
SELECT gid, ST_Y(geo::geometry) AS lat, ST_X(geo::geometry) AS lon
FROM places;
However, if you want to use triggers, these changes will make things work. The important pieces being that NEW
is the row, which can be modified and returned. Also, use ST_Y
and not new.st_y
. Lastly, the trigger must be a BEFORE
trigger, since it modifies the record before it is stored.
CREATE OR REPLACE FUNCTION update_tg2()
RETURNS trigger AS
$$
BEGIN
NEW.lat := ST_Y(NEW.geo::geometry);
NEW.lon := ST_X(NEW.geo::geometry);
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
DROP TRIGGER IF EXISTS triger_coords2 on places;
CREATE TRIGGER triger_coords2 BEFORE INSERT OR UPDATE ON places
FOR EACH ROW EXECUTE PROCEDURE update_tg2();
Best Answer
ST_SetSRID
will set the coordinate reference system of your geometry. This will allow PostGIS commands to understand how your grid will relate to other geometries.Using
ST_SetSRID
is not essential, as long as all other geometries you may query against are known to be on the same grid. However, if you query against another table that has a SRID set, even if it is known to be of the same grid, PostGIS will fail with a 'mixed geometries' error, which is only resolved when both tables have the same SRID value.