Reputation: 13
QN: Am getting error from ST_Within function for the geometry supplied in PostGIS. Not sure on what is the rite way to implement first argument of ST_Within.
Note: variables longitude and latitude are of character type supplied to function. However, I am not able to construct the value passed to ST_Within.
extract of code from custom function:
pointText := 'POINT(longitude || || latitude )';
result := (select p_code
from public.parking_lot
b where ST_Within (ST_GeomFromText(pointText)::geometry::geography,wkb_geography) limit 1);
EDIT: 14TH Nov 2019 With @jim-jones suggestion, I have re-created my function as follows:
CREATE OR REPLACE FUNCTION public.returnParkingLot(
longitude character,
latitude character)
RETURNS character AS
$BODY$
declare result text;
declare pointText text;
BEGIN
IF longitude = '0' THEN
return '';
ELSE
pointText := 'POINT(' || longitude || ' ' || latitude || ')';
result := (select p_code from public.parking_lot b where ST_Within (ST_GeomFromText(pointText),b.wkb_geography::GEOMETRY) limit 1);
return result;
END IF;
END;$BODY$
LANGUAGE plpgsql VOLATILE STRICT
COST 100;
ALTER FUNCTION public.returnParkingLot(character, character)
OWNER TO mother;
Access: I use the above function using select statement as follows:
select public.returnParkingLot('103.84472222','1.28333333');
Notes: Wish to know whether this implementation is right.
Edit: 21st Nov
As requested by @jim-jones, changes to datatype of inputs from user below.
CREATE OR REPLACE FUNCTION public.returnParkingLot(
longitude double precision,
latitude double precision)
RETURNS character AS
$BODY$
declare result text;
declare pointText text;
BEGIN
IF longitude = '0' THEN
return '';
ELSE
pointText := 'POINT(' || longitude || ' ' || latitude || ')';
result := (select p_code from public.parking_lot b where ST_Within (ST_GeomFromText(pointText),b.wkb_geography::GEOMETRY) limit 1);
return result;
END IF;
END;$BODY$
LANGUAGE plpgsql VOLATILE STRICT
COST 100;
ALTER FUNCTION public.returnParkingLot(double precision, double precision)
OWNER TO mother;
Select statement:
select public.returnParkingLot(103.84472222, 1.28333333);
Upvotes: 2
Views: 861
Reputation: 19613
Considering that a) pointText
contains valid numeric parameters and b) wkb_geography
is indeed of type geography, we can assume that the problem is the parameters data type. According to the documentation ST_Within
expects geometry
. You might wanna try this out:
SELECT p_code
FROM public.parking_lot b
WHERE ST_Within(ST_GeomFromText('POINT(2 2)'),b.wkb_geography::GEOMETRY);
Your function should look like this:
CREATE OR REPLACE FUNCTION public.returnParkingLot(
longitude NUMERIC,
latitude NUMERIC) RETURNS character AS
$BODY$
DECLARE result text;
DECLARE pointText text;
BEGIN
IF longitude = '0' THEN
RETURN '';
ELSE
pointText := 'POINT(' || longitude || ' ' || latitude || ')';
result := (SELECT p_code FROM public.parking_lot b
WHERE ST_Within(ST_GeomFromText(pointText),b.wkb_geography::GEOMETRY) LIMIT 1);
RETURN result;
END IF;
END;
$BODY$ LANGUAGE plpgsql VOLATILE STRICT COST 100;
Test:
CREATE TABLE parking_lot (p_code INT, wkb_geography GEOMETRY);
INSERT INTO parking_lot VALUES (1,'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))');
SELECT public.returnParkingLot(30, 11);
returnparkinglot
------------------
1
(1 Zeile)
Side note: Do you really need this much precision to locate a parking lot? With eight decimal places you're almost in the microscopy realm.
Upvotes: 1