Trigger geométrico

Bueno, antes de leer este post lean este: Un poco de SQL postgis en donde explico bien todo el contexto. Ahora supongamos que tenemos propiedades, el atributo que más nos interesa (a nosotros) de la propiedad es la dirección, supongamos ahora que queremos, a partir de la dirección, generar un punto geométrico que se actualice automáticamente con un trigger. Pues bien, vamos a ver como sería eso.

A la tabla calles ya la conocen del punto anterior, así que les muestro la tabla propiedades:

CREATE TABLE propiedades
(
idpropiedades serial NOT NULL,
tipopropiedad bigint,
ambientes bigint,
conatributos bigint,
sinatributos bigint,
operacion smallint,
datoscatastrales character varying(50),
expensasfecha timestamp without time zone,
expensasmonto real,
porcentualfiscal real DEFAULT (0)::real,
editable boolean NOT NULL DEFAULT true,
CONSTRAINT propiedades_primarykey PRIMARY KEY (idpropiedades)
)

Como verán la dirección puede ser calle y altura, o bien calle1 y calle2, o sea intersección de calles. O sea, puede ser que la dirección venga como calle y altura o como calle1 y calle2 (no ambas obviamente). Pues bien creemos algunas funciones primero:

Una función por si viene como calle1 calle2:

CREATE OR REPLACE FUNCTION callesinter(integer, integer)
  RETURNS geometry AS
'select distinct Intersection(calle1.the_geom,calle2.the_geom) from segmentos_calle calle1, segmentos_calle calle2 where ST_Touches(calle1.the_geom, calle2.the_geom) and calle1.idcalles = $2 and calle2.idcalles = $1;'
  LANGUAGE 'sql' IMMUTABLE STRICT
  COST 100;

Otra función por si viene como calle y altura:

CREATE OR REPLACE FUNCTION dire2point(integer, integer)
  RETURNS geometry AS
'select distinct line_interpolate_point((linemerge(the_geom)),(($2-alturadesdeizq)/(alturahastaizq-alturadesdeizq)::numeric(4,1))) from segmentos_calle se join calles ca on ca.idcalles = se.idcalles where ca.idcalles = $1 and ((alturadesdeizq <= $2 and alturahastaizq >= $2) or (alturadesdeder <= $2 and alturahastader >= $2));'
  LANGUAGE 'sql' IMMUTABLE STRICT
  COST 100;

y ahora solo queda un simple trigger 😉

CREATE OR REPLACE FUNCTION actualiza_direcalle()
  RETURNS trigger AS
$BODY$
begin
if NEW.altura is null then
NEW.the_geom := callesinter(NEW.idcalles2,NEW.idcalles2);
else
NEW.the_geom := dire2point(NEW.idcalles1,NEW.altura);
end if;
return NEW;
end;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;

Ahora viene el test…
Testing
———-Intersección de avenida de mayo y 9 de julio———–
geoprop=# insert into direccionesdecalle (idcalles1,altura,exacta) values (10,5154,’y’);
INSERT 0 1
geoprop=# select astext(the_geom) from direccionesdecalle;
astext
——————————————–
POINT(-58.3804575068843 -34.6094559836051)
(1 row)

geoprop=# insert into direccionesdecalle (idcalles1,altura,exacta) values (10,5154,’y’);
INSERT 0 1

geoprop=# select astext(the_geom) from direccionesdecalle where iddireccionesdecalle = 723;
astext
——————————————–
POINT(-58.4179611717442 -34.6601105997032)
(1 row)

Espero les sirva, Pablo gracias por contratar nuestros servicios de gis hosting.