I am in the world totally new to me, so… be kind.
I am trying to write a function in Oracle that would take SDO_GEOMETRY (a line) and return the mid-point of that line in ddmmss format (longitude and latitude). I have it working (I hope it is right) but I would not mind some ‘critic’ of my code. There is always a better way to do stuff. And if anyone finds any miss-calculations in my math, please let me know.
One problem I have is the validation of the passed SDO_GEOMETRY: if it is NOT a line, I would like to have different outcome of that Function, something like ‘not sdo line’
I can pass a valid SDO_GEOMETRY for a line and the Function does return ‘954835 404621’ - two longitudes and latitudes of a point.
Have fun.
---- Andy
I am trying to write a function in Oracle that would take SDO_GEOMETRY (a line) and return the mid-point of that line in ddmmss format (longitude and latitude). I have it working (I hope it is right) but I would not mind some ‘critic’ of my code. There is always a better way to do stuff. And if anyone finds any miss-calculations in my math, please let me know.
One problem I have is the validation of the passed SDO_GEOMETRY: if it is NOT a line, I would like to have different outcome of that Function, something like ‘not sdo line’
Code:
CREATE OR REPLACE FUNCTION S2010000.MID_POINT_OF_LINE
( pass_sdo_geometry IN SDO_GEOMETRY )
RETURN varchar2
IS
outcome varchar2(255); [green] -- I know it should be shorter[/green]
startGeom SDO_GEOMETRY;
lrsGeom SDO_GEOMETRY;
measure NUMBER;
midpoint SDO_GEOMETRY;
x NUMBER;
y NUMBER;
x_d CHAR(2 BYTE);
x_m_no NUMBER;
x_m CHAR(2 BYTE);
x_s CHAR(2 BYTE);
y_d CHAR(2 BYTE);
y_m_no NUMBER;
y_m CHAR(2 BYTE);
y_s CHAR(2 BYTE);
BEGIN
startGeom := pass_sdo_geometry;
IF startGeom.SDO_GTYPE = 2002 THEN [green]-- I don't think this part works[/green]
[green]-- convert standard geometry to LRS geometry[/green]
lrsGeom := SDO_LRS.CONVERT_TO_LRS_GEOM(startGeom);
[green]-- get the measure of the halfway point of the geometry[/green]
measure := SDO_LRS.PERCENTAGE_TO_MEASURE(lrsGeom, 50);
[green]-- convert the measure to a point[/green]
midpoint := SDO_LRS.LOCATE_PT(lrsGeom, measure);
[green]-- convert LRS Lambert point to lat/long point[/green]
midpoint := SDO_CS.TRANSFORM(midpoint, 8192);
[green]-- extract x/y coordinates from the point[/green]
SELECT t.x, t.y
INTO x, y
FROM dual, TABLE (sdo_util.getvertices (midpoint)) t;
[green]--outcome := 'x: ' || x || ', y: ' || y;[/green]
x_d := ABS(TRUNC(x));
y_d := ABS(TRUNC(y));
[green]--outcome := 'x_d: ' || x_d || ', y_d: ' || y_d;[/green]
x_m_no := SUBSTR(X, 4) * 60;
x_m := TRUNC(x_m_no);
IF TO_NUMBER(x_m) < 10 then
x_m := '0' || x_m;
END IF;
y_m_no := SUBSTR(y, 3) * 60;
y_m := TRUNC(y_m_no);
IF TO_NUMBER(y_m) < 10 then
y_m := '0' || y_m;
END IF;
[green]--outcome := 'x_m: ' || x_m || ', y_m: ' || y_m;[/green]
x_s := TRUNC((x_m_no - TO_NUMBER(x_m)) * 60);
IF TO_NUMBER(x_s) < 10 THEN
x_s := '0' || x_s;
END IF;
y_s := TRUNC((y_m_no - TO_NUMBER(y_m)) * 60);
IF TO_NUMBER(y_s) < 10 THEN
y_s := '0' || y_s;
END IF;
[green]---outcome := 'x_s: ' || x_s || ', y_s: ' || y_s;[/green]
outcome := x_d || x_m || x_s || ' ' || y_d || y_m || y_s;
ELSE
outcome := 'not sdo line';
END IF;
RETURN outcome;
END MID_POINT_OF_LINE;
/
I can pass a valid SDO_GEOMETRY for a line and the Function does return ‘954835 404621’ - two longitudes and latitudes of a point.
Have fun.
---- Andy