sdo_geom.relate vs sdo_relate
HelloAs a beginner to oracle space, I have a query which is a little confusing me.
I understand that sdo_relate uses the spatial index and queries data slightly differently than sdo_geom.relate therefor.
I have a database of street that is shared by postal code, for example if a street passes through 3 postal codes, I have it divided into 3 separate blocks.
Now, I want to go back to all segments of the streets and their post_code id matching.
-REQUEST 1
Select street_id, post_code p.id s.id
of AP_STREETS s, AP_POSTCODE p
where sdo_relate (s.geoloc, p.geoloc, "MASK = INSIDE + DOMMAGESCAUSDSPAR") = "TRUE";
-REQUEST 2
Select street_id, post_code p.id s.id
of AP_STREETS s, AP_POSTCODE p
where sdo_geom.relate (s.geoloc, 'INTERIOR + DOMMAGESCAUSDSPAR', p.geoloc, 0.05) = "INTERIOR + DOMMAGESCAUSDSPAR;
QUERY 1 returns nothing while 2 QUERY returns the values and the correct set of records.
The only thing is the time it takes for the shuttle sdo_geom.relate is not very effective.
I tested only with a recordset of 10 000 segments streets, but the live DB will be over 5 million.
At 10,000, it takes the request almost 30 minutes, is not ideal to say the least.
Any help/advice would be welcome.
Kind regards
David
sdo_relate should return the same results as sdo_geom.relate returns,
If the same tolerance is used. Which version of DB are you using? Please
Try 11.2.0.2 if possible.
Tags: Database
Similar Questions
-
sdo_geom.relate returns the MASK of the UNKNOWN: 000000001
I have everything,
I use on a database of Oracle 11 g Release 11.1.0.6.0 - 64 bit Production With the Real Application Clusters option.
I have to determine what relationship there is between 2 sdo_geometry.
I run this query:
Select sdo_geom.relate (shape_1, "determine", shape_2, 0.5) determine,
sdo_geom.relate (shape_1, 'anyinteract', shape_2, 0.5) anyinteract
Double;
I get:
DETERMINE THE ANYINTERACT
MASK UNKNOWN: 000000001 TRUE
That means MASK UNKNOWN: 000000001 average?
How can I determine the relationship?
Thanks in advance.
SamuelThe second and third pairs ordered at the end are the same for the two geometry.
shape_1:-66.89470555713654,10.514948048707884
shape_2:-66.87824215820313,10.508391980537853remove the redundancy pts and see if that fixes the problem.
Jack
-
Incorrect results of SDO_GEOM. Relate()
Hi all
I get incorrect results of calls to SDO_GEOM.relate / SDO_RELATE / SDO_INSIDE etc., apparently because they cannot handle the values of Longitude both positive and negative in the same query.
The request goes in the direction of
Where SCOTT.ASIA is a layer containing a geometry for each Asian countries (although I experienced the same behavior with other, more simple polygons)SELECT COUNTRY, SDO_GEOM.relate(SCOTT.ASIA.GEOLOC, 'DETERMINE', < A Transient Geometry>, '0.005') from SCOTT.ASIA;
And transitional geometry is defined:
This query gives me:MDSYS.SDO_GEOMETRY( 2003, 8307, null, MDSYS.SDO_ELEM_INFO_ARRAY(1,1003, 1), MDSYS.SDO_ORDINATE_ARRAY(-1.2, 89.9, 6.6, -16.2, 170.3, -21.1, 168.25, 89.9, -1.2, 89.9))
When all these geometries have to resolve on the INSIDE.Malaysia DISJOINT Maldives DISJOINT Mongolia DISJOINT Myanmar DISJOINT ...etc
I traced this issue to the fact that there is a selected point with a negative longitude (-1.2, 89.9), which should be perfectly fine. If I change of (1,2, 89.9):
I get:
This occurs regardless of what point is outside the hemisphere for example:Malaysia INSIDE Maldives INSIDE Mongolia INSIDE Myanmar INSIDE ...etc
Note that the second and third entries represent a limit to the East that surrounds the Western hemisphere. None of these definitions provide good results when using SDO_GEOM.relate... MDSYS.SDO_ORDINATE_ARRAY(-1.2, 89.9, 6.6, -16.2, 170.3, -21.1, 168.25, 89.9, -1.2, 89.9)... ... MDSYS.SDO_ORDINATE_ARRAY(1.2, 89.9, 6.6, -16.2, 170.3, -21.1, *191.75*, 89.9, 1.2, 89.9)... ... MDSYS.SDO_ORDINATE_ARRAY(1.2, 89.9, 6.6, -16.2, 170.3, -21.1, *-168.25*, 89.9, 1.2, 89.9)...
Is there a way to make sure that spatial queries returning correct results with geometries that envelop this way?
Thank youThis type of query "whole earth" does not work as you did. See http://download.oracle.com/docs/html/B14255_01/sdo_cs_concepts.htm#i891851
>
The following size limits apply, with geodetic data
No polygon element can have an area larger than half of the surface of the Earth.
Online, the distance between two adjacent coordinates cannot be greater or equal to half of the perimeter (a great circle) of the Earth.If you need to work with larger items, first break these elements into several smaller components and work with them. For example, you cannot create a geometry that represents the entire surface of the Earth; However, you can create several geometries, each representative of the global ocean surface. To work with a line string that is greater than or equal to half of the perimeter of the land, you can add one or more points on the line so that all adjacent coordinates are less than half of the perimeter of the land.
>Search this forum for "Earth." for example
Re: Simple Transformation work not as expected
the whole earth MBR GEODESIC -
ORA-13000: number of dimensions is out of reach when you use SDO_GEOM. RELATE
Dear everybody
I try to drive what polygons covering the same area to determine separate polygons. This is so I can then have a copy of a polygon in a new table and delete all the polygons in doubles in the current table.
I ran as follows everything first to check something:
but I got the error message:SELECT SDO_GEOM.RELATE (A.geographical_coordinates, 'DETERMINE', B.geographical_coordinates, 0.05) relationship FROM MAP_INDEX A, MAP_INDEX B where A.geographical_coordinates is not NULL and B.geographical_coordinates is not NULL;
Then, I tried the following:Error starting at line 1 in command: SELECT DISTINCT A.mi_prinx, SDO_GEOM.RELATE (A.geographical_coordinates, 'EQUAL', B.geographical_coordinates, 0.05) FROM MAP_INDEX A, MAP_INDEX B where A.geographical_coordinates is not NULL and B.geographical_coordinates is not NULL Error report: SQL Error: ORA-13000: dimension number is out of range ORA-06512: at "MDSYS.SDO_GEOM", line 70 ORA-06512: at "MDSYS.SDO_GEOM", line 2647 13000. 00000 - "dimension number is out of range" *Cause: The specified dimension is either smaller than 1 or greater than the number of dimensions encoded in the HHCODE. *Action: Make sure that the dimension number is between 1 and the maximum number of dimensions encoded in the HHCODE.
which produces the following error message:SELECT DISTINCT A.mi_prinx, SDO_GEOM.RELATE (A.geographical_coordinates, 'EQUAL', B.geographical_coordinates, 0.05) FROM MAP_INDEX A, MAP_INDEX B where A.geographical_coordinates is not NULL and B.geographical_coordinates is not NULL
Does anyone have an idea as to what I might hurt? The original polygons have been created in MapInfo Professional 8 and I work at 10.2 gError starting at line 1 in command: SELECT SDO_GEOM.RELATE (A.geographical_coordinates, 'EQUAL', B.geographical_coordinates, 0.05) relationship FROM MAP_INDEX A, MAP_INDEX B Error report: SQL Error: ORA-13050: unable to construct spatial object ORA-06512: at "MDSYS.SDO_3GL", line 4 ORA-06512: at "MDSYS.MD2", line 771 ORA-06512: at "MDSYS.SDO_GEOM", line 2622 ORA-06512: at "MDSYS.SDO_GEOM", line 2649 13050. 00000 - "unable to construct spatial object" *Cause: This is an internal error. *Action: Contact Oracle Support Services.
I think that Imust be something wrong. I looked in SDO_GEOM_VALIDATE but once again produce the same error as the first message. I already created a spatial index and inserted values in USER_SDO_GEOM_METADATA view.
I was able to get the following to work, I was testing the examples online just to see if I could produce a result on an sdo function:
When I drew my polygons in MapInfo, they are likely to be gone in part outside the dimension values inserted in USER_SDO_GEOM_METADATA limit. Who is likely to be the cause of my problems or something else?SELECT NAME_OF_FEATURE, SDO_GEOM.SDO_AREA(GEOGRAPHICAL_COORDINATES,M.DIMINFO) FROM MAP_INDEX, user_sdo_geom_metadata M WHERE M.TABLE_NAME='MAP_INDEX' AND M.COLUMN_NAME='GEOGRAPHICAL_COORDINATES' AND geographical_coordinates is not null;
If this is the cause, is far from Oracle or MapInfo installation so that anything drawn outside the area of the dimension is cut off.
Kind regards
TimHi Tim,.
Since Oracle Oracle 8.1.6 suggested the use of 4-digit SDO_GTYPE values, which encode the number of dimensions in geometry. Examples of 4-digit SDO_GTYPES 2001 for one point 2D, 3001 for a 3D point, 2002 for a 2D linestring, 3002 for 3D linestring, 2003 for a 2D polygon and 3003 for a 3D polygon... Compare these values to a single digit from 1 to a point, a linestring 2 and 3 for a polygon.
My guess is that at least some of your data is loaded using SDO_GTYPE values to a single digit, and service Oracle does not know the dimensionality of the data (is a peak identified by 2, 3 or 4 numbers?). You can check this by a:
Select distinct a.geographical_coordinates.sdo_gtype from MAP_INDEX;
If all of the values returned are single-digit values, then you know that's the problem.
You have a few options.
You can have Oracle automatically correct data migration data:
execute sdo_migrate.to_current ('MAP_INDEX', 'GEOGRAPHICAL_COORDINATES');This will not define only the SDO_GTYPE properly but will fix also to any ring rotation problems (ensures the outer rings is stored in the anti-clockwise and the inner rings is stored in a clockwise direction), it will set the control problems ring (ensure an outside ring is followed by its inner rings) and it will be appropiately set of values in the SDO_ELEM_INFO_ARRAY.
After that, you should be good to go. However, if you use a tool to update the data, and it resets the information back, the problem will continue to torment you. You should check with your provider if this is the case.
Another option is to modify the query for a different signature, which uses the SDO_GEOM_METADATA to get the dimensionality of the data. Rather than write the query that you have, you want to change it to:
SELECT SDO_GEOM. RELATE
(A.geographical_coordinates,
C.DIMINFO,
"DETERMINE."
B.geographical_coordinates,
Relationship C.DIMINFO)
OF MAP_INDEX,.
B MAP_INDEX,
C USER_SDO_GEOM_METADATA
WHERE A.geographical_coordinates is not NULL
and B.geographical_coordinates is not NULL
and C.TABLE_NAME = 'MAP_INDEX'
and C.COLUMN_NAME = 'GEOGRAPHICAL_COORDINATES';So either of those who should solve the problem, you see, but none of those who are the best way to accomplish what you want to do.
If I were you, I would follow the first set of directions (migrate your data), make sure that I have a spatial index on my table:
Select index_name
of user_sdo_index_info
where table_name = 'MAP_INDEX ';If no row is returned, create the index:
create index MAP_INDEX_SIDX on MAP_INDEX (GEOGRAPHICAL_COORDINATES)
indexType is mdsys.spatial_index;You can use SDO_JOIN to perform a self-join:
http://download.Oracle.com/docs/CD/B28359_01/AppDev.111/b28400/sdo_operat.htm#BGEDJIBF
using the SAME mask. Note the section on optimization of self-joins.If you don't have too much data, it could be a start to do what you want:
create the table dups_rowids as
Select / * + ordered * / a.rowid rowid1, b.rowid rowid2
MAP_INDEX a,.
MAP_INDEX B
where (a.geographical_coordinates, b.geographical_coordinates) SDO_EQUALS = 'TRUE'
and a.rowid <> b.rowid.create table nodup_rowid (noduprid VARCHAR2 (24));
create table dup_rowid (duprid VARCHAR2 (24));Set serveroutput on;
declare
Modou varchar2 (24);
rowidb varchar2 (24);
rowidt varchar2 (24);
is of type Ref cursor myCursor;
acursor myCursor;
cursor c1 is select rowid1, rowid2 from dups_rowids;
Start
for r c1 loop
Modou: = r.rowid1;
rowidb: = r.rowid2;
rowidt: = NULL;Open acursor for ' select duprid in the dup_rowid where duprid =: modou ' using modou;
extract the acursor in rowidt;
If rowidt is null
then
immediately execute "insert into nodup_rowid values (: modou)" using modou;
immediately execute "insert into dup_rowid values (: modou)" using modou;
run immediately "committed."
end if;
close acursor;
rowidt: = NULL;Open acursor for ' select duprid in the dup_rowid where duprid =: rowidb' using rowidb;
extract the acursor in rowidt;
If rowidt is null
then
run immediately ' insert into dup_rowid values (: rowidb) "using rowidb;
run immediately "committed."
end if;
close acursor;
end loop;
end;
/Your final table would then have the geometries of the original table, which had no match:
create the table MAP_INDEX_NODUPS
in select * from MAP_INDEX where rownum<>insert into MAP_INDEX_NODUPS
(select *)
of MAP_INDEX
where ROWID not in
(by selecting ROWID1 in DUPS_ROWIDS)) ;more alone geometries that were equal:
insert into MAP_INDEX_NODUPS
(select *)
of MAP_INDEX
where ROWID in
(by selecting ROWID1 in NODUP_ROWID);I hope this helps.
-
SDO_Relate and SDO_filter with SDO_Join
Hi all
Could someone please help me find the difference with the following query
I compare SDO_filter with SDO_join and SDO_Relate.
Query using SDO_filter and SDO_Relate
SELECT count (spa1.id)
FROM temp_tab tmp_tab,.
spa1 spatial_tab,
spatial_tab spa2
WHERE tmp_tab.id = spa1.id
AND sdo_filter (spa2.geo_link, spa1.geo_link) = 'TRUE '.
AND spa1.rowid! = spa2.rowid
AND sdo_geom.relate (spa1.geo_link, "ANYINTERACT', spa2.link,.0000005) = 'TRUE '.
With this, I get a result of 600 lines.
Query using SDO_join
SELECT count (spa1.id)
OF spatial_tab a, spatial_tab b, temp_tab d,.
TABLE (SDO_JOIN ('spatial_tab', 'geo_link', 'spatial_tab', 'geo_link',
"(masque = ANYINTERACT')) c"
WHERE (c.rowid1 = a.rowid AND c.rowid2 = b.rowid)
and (d.id = a.id);
With this, I get a result of 750 lines.
I assume that both the query must return to 600 lines.
Rgds and thanks
SaazCan you please try:
SELECT count (spa1.id)
OF spatial_tab a, spatial_tab b, temp_tab d,.
TABLE (SDO_JOIN ('spatial_tab', 'geo_link', 'spatial_tab', 'geo_link',
"(masque = ANYINTERACT')) c"
WHERE (c.rowid1 = a.rowid AND c.rowid2 = b.rowid)
and (d.id = a.id) and c.rowid1! = c.rowid2; -
dividing the dataset into regions using sdo_relate
Hi all
I have difficulties subdivision my dataset in different regions. I have the data space of the city of auckland and found the coordinates of the lower left and limited right of data. What I want to do now is to break this dataset into 9 individual regions and assign a code to each region. I tried to use subsequently issue with not much luck...
Select a.link_id in the nz_testlinks_auck where mdsys.sdo_relate (a.GEOM,
MDSYS. SDO_GEOMETRY (2003, null, null, mdsys.) SDO_ELEM_INFO_ARRAY (1,1003,3),
MDSYS. SDO_ORDINATE_ARRAY(174.7083,-37.0141,174.7910,-36.9544)), "mask = ANYINTERACT querytype = FENΩTRE") = "TRUE";
When I put the output into a table data and display the data, I notice that the rectangle has chosen a lot more data than what was actually defined in the query. I have been using the model of network data and MapBuilder Editor to check the data and contact information.
And when I try to create another rectangle for another region next to each other like that...
Select a.link_id in the nz_testlinks_auck where mdsys.sdo_relate (a.GEOM,
MDSYS. SDO_GEOMETRY (2003, null, null, mdsys.) SDO_ELEM_INFO_ARRAY (1,1003,3),
MDSYS. SDO_ORDINATE_ARRAY(174.7910,-37.0141,174.8736,-36.9544)), "mask = ANYINTERACT querytype = FENΩTRE") = "TRUE";
He again selects a rectangle more great selection of half of the data of the previous selection rectangle as well.
Please help me solve this problem.
Look forward to your responses.
AvinashAvinash,
Do you have geometries that cross your limit of rectangle, as a long line, or a large polygon? What rectangle you plan such a line or polygon to appear in?
Or would you say that the geometries that are completely disjoint from your rectangle are chosen? If you think that this is the case, try the sdo_geom.relate with the mask "determine" in order to verify the relationship between your rectangle and one of the unexpected geometries.
http://download.Oracle.com/docs/HTML/B14255_01/sdo_objgeom.htm#BGHCDIDGIf you want to be sure that nothing is selected twice by your rectangles the ANYINTERACT mask is probably not a good choice. A = INSIDE + DOMMAGESCAUSDSPAR mask mask will be better, but you still have to decide what to do with stuff that crosses.
Matt
-
Hello
working with oracle 11.2.0.1.0, the following query returns to the INSIDE of the relationship, in fact it is DISJOINT.
Select sdo_geom.relate (a.geometry, "determine", b.geometry, 0.05) test a, b test where a.idnumber =' Steve ' and b.idnumber ='abcd ';ABCD MDSYS. SDO_GEOMETRY (2003,8307, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,1003,1), MDSYS. SDO_ORDINATE_ARRAY(-63.511895146,44.883927382,-63.511917747,44.883932719,-63.511943823,44.883931141,-63.51234812,44.883862534,-63.512410738,44.88381001,-63.512641895,44.883616114,-63.512867359,44.88342672,-63.512910261,44.883383825,-63.513899075,44.882385966,-63.515021288,44.88124581,-63.515320558,44.880941675,-63.51553685,44.880721866,-63.515847735,44.880405706,-63.51680081,44.879436458,-63.517103832,44.879128292,-63.517949007,44.878268728,-63.518479978,44.87772787,-63.518536077,44.877670724,-63.519862136,44.876324062,-63.520352141,44.875826445,-63.520875977,44.87529447,-63.521012779,44.87515414,-63.521029469,44.875134851,-63.521038752,44.875117469,-63.521046038,44.875094454,-63.521048577,44.875072368,-63.521046494,44.875048106,-63.521040844,44.875027953,-63.52103162,44.875008859,- 63.521019009,44.874991525,-63.521007524,44.874978615,-63.520990199,44.874959284,-63.520968364,44.874936809,-63.520940738,44.874911432,-63.520880061,44.874862375,-63.520848717,44.874840831,-63.520786635,44.874798894,-63.520716909,44.87475688,-63.520654302,44.87472334,-63.520595816,44.874695319,-63.520515013,44.874662486,-63.520428784,44.874634104,-63.520350631,44.874613439,-63.520278473,44.874598439,-63.520198047,44.874586401,-63.520111209,44.874577969,-63.520030138,44.874573262,-63.519940956,44.874571591,-63.519864301,44.874573084,-63.519778699,44.874576795,-63.519678073,44.874584332,-63.519579202,44.874595104,-63.519494358,44.874607036,-63.519408372,44.874621695,-63.519327355,44.874637906,-63.5192365,44.874658704,-63.519146286,44.87468136,-63.519068168,44.874703018,- 63.518959636,44.874736331,-63.518903063,44.874755342,-63.518846253,44.874775112,-63.518734517,44.874888332,-63.518819058,44.874842649,-63.518911751,44.874805767,-63.518987812,44.874779833,-63.519068179,44.874756665,-63.519145115,44.874733827,-63.519236361,44.874709944,-63.519317179,44.874691623,-63.519397124,44.87467606,-63.519484395,44.874661925,-63.519579638,44.874649845,-63.519683429,44.874636,-63.519759209,44.87462827,-63.519846351,44.87462252,-63.519921021,44.874620247,-63.51997481,44.874620122,-63.520026922,44.874621208,-63.520065397,44.874622774,-63.520116942,44.874628591,-63.52017073,44.874635781,-63.520235021,44.874645889,-63.520280769,44.874654097,-63.520326648,44.874663184,-63.520375078,44.874673719,-63.520425629,44.874687552,-63.520482676,44.874707912,-63.520528305,44.874726295 ,-63.520576379,44.87474778,-63.520632999,44.874776024,-63.520716465,44.874823086,-63.520783988,44.874867665,-63.52083892,44.874909345,-63.520882895,44.874944811,-63.520901148,44.874963038,-63.520909245,44.874980936,-63.520907967,44.875005651,-63.520897312,44.875041872,-63.520863074,44.875132124,-63.520839957,44.875175126,-63.520794797,44.875224578,-63.520599847,44.875421292,-63.5183909,44.877657061,-63.518139304,44.877922764,-63.513933818,44.882196182,-63.513853277,44.882276678,-63.512799484,44.883329899,-63.512687478,44.883425868,-63.51262839,44.883472607,-63.512545714,44.883531,-63.512460967,44.883591331,-63.512370783,44.88364668,-63.512277899,44.883698706,-63.512239574,44.883718778,-63.512214286,44.883731593,-63.512183522,44.883745273,-63.512164668,44.883751508,- 63.512138925,44.883759169,-63.512107764,44.883767169,-63.512079528,44.883773247,-63.512043277,44.88377946,-63.512007231,44.883783905,-63.511967858,44.883786821,-63.511934709,44.883787722,-63.511905193,44.883787333,-63.511866053,44.883785083,-63.511843135,44.883782842,-63.511807275,44.883773062,-63.511784093,44.883763448,-63.511752174,44.883749749,-63.511716923,44.883733988,-63.511673453,44.883713618,-63.511621498,44.883687881,-63.511531986,44.883639829,-63.511326651,44.88353215,-63.511239223,44.883478511,-63.5110421,44.883340078,-63.510961335,44.883282054,-63.51092987,44.883255839,-63.510910861,44.883230934,-63.510892506,44.883190955,-63.510812347,44.883009086,-63.510802747,44.88297249,-63.510804296,44.882923898,-63.510687933,44.883041808,-63.510805401,44.883275341,- 63.51081841,44.883296868,-63.510836851,44.883312892,-63.510952665,44.883397298,-63.511170025,44.883557617,-63.511199734,44.883577286,-63.511224225,44.88359013,-63.511545644,44.883751197,-63.511895146,44.883927382))
Steve MDSYS. SDO_GEOMETRY (2003,8307, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,1003,1), MDSYS. SDO_ORDINATE_ARRAY(-63.518193562,44.878400883,-63.518170639,44.878424027,-63.51732663,44.879276283,-63.517306365,44.879305756,-63.517302882,44.879339193,-63.517307944,44.879370666,-63.517313567,44.879396826,-63.517331081,44.879425327,-63.517352059,44.879449059,-63.517529907,44.879536473,-63.517450676,44.87944834,-63.517428804,44.879421979,-63.51741049,44.879399976,-63.517401953,44.879376169,-63.517411281,44.879350954,-63.517430699,44.879327567,-63.518392524,44.878351357,-63.518193562,44.878400883))In 11.2.0.3, I have DISJOINT. So, it could be a bug on 11.2.0.1.
-
Sdo_Geom.Sdo_Intersection does not vertices overlapping
Hi all
I run the query where I try to get the number of vertices that intersect between 2 objects GEOM below.
Sdo_Util.Getnumvertices (Sdo_Geom.Sdo_Intersection(B.geom,R.geom,.00000000005))
The query above works fine when, for ex B.GEOM to say 5 different X tops and are coordinated. It gives me the good number of vertices that intersect with R.GEOM.
However, in my case, B.GEOM has 15 peaks, all having the same X and are coordinated. When I run the above query, the output returned is 1 when there are actually 15 peaks that are intertwined with R.GEOM.
I am a novice in the database space and not very sure if Sdo_Geom.Sdo_Intersection will remove duplication/overlap of the summits? I want to be able to examine all vertices that overlap as well. Can you get it someone please let me know if I'm doing the right thing here?
Please see below the image of intersection where B.Geom have 15 vertices overlapping and R.Geom is the polygon.
You poor soul, who deals these clusters on you anyway? They should buy lunch you.
So yes, go getnumelem to getnumvertices in the meter of the loop, and then you will need manually extract every x, y in a temporary point normal, simple geometry in the loop.
Here's a little revised sample PL/SQL.
declare multip sdo_geometry := sdo_geometry (2005, null, null, sdo_elem_info_array (1,1,3), sdo_ordinate_array (50,5, 55,7, 60,5)); singlep sdo_geometry; poly sdo_geometry := SDO_GEOMETRY (2003, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 1003, 1), SDO_ORDINATE_ARRAY (-100,-100,100,-100,100,100,-100,100,-100,-100)); kount pls_integer := 0; begin for i in 1 .. sdo_util.getnumvertices(multip) loop singlep := SDO_GEOMETRY ( 2001, multip.sdo_srid, SDO_POINT_TYPE ( multip.sdo_ordinates(i * 2 - 1), multip.sdo_ordinates(i * 2), NULL ), NULL, NULL); --debuggin tip - use determine mask --dbms_output.put_line(sdo_geom.relate(singlep, 'mask=DETERMINE', poly, .05)); if sdo_geom.relate(singlep, 'mask=INSIDE', poly, .05) <> 'FALSE' then kount := kount + 1; end if; end loop; dbms_output.put_line(kount); end;
-
SDO_FILTER which gives weird results
Hi people,
Not sure if this is a bug or maybe I'm just not see something simple. On 11.2.0.4. I have an area of the area of interest and a line next door representing a piece of water, the two geometries validate the tolerance of 5 centimeters.
http://www.dziemiela.com/june27.PNG
The box is more than a mile away from the stream. The flow is relatively small and its MBR is no where close to touch the area. However, according to SDO_FILTER, two geometries are TRUE. I'm puzzled. So I wrote the mess for anyone wishing to give it a shot. I'll be back
Streamy is valid? TRUE
Véronique is valid? TRUE
Basic SDO_GEOM. RELATE? DISJOINT
Distance between 1795.19857225394 M
MIL SDO_GEOM. RELATE? DISJOINT
Distance between 1794.97512096382 M
SDO_RELATE County 0
SDO_FILTER County 1
If two geometries are distance of 1.7 km and their members are distance of 1.7 km. I would like to say very clearly that these things shouldn't interact. Right? However, filter gives TRUE. Am I a something Klutz?
Thank you
Paul
DECLARE sdo_streamy SDO_GEOMETRY := SDO_GEOMETRY(2002,8265,NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(-77.6495001234516,38.9423350727726,-77.6482987901201,38.9418092727734,-77.6468049234557,38.9413522727742,-77.6461311901235,38.9413982061074,-77.6438177901271,38.942107872773,-77.6427925901286,38.9423368727726,-77.6423533234627,38.9422912727727,-77.6410643234647,38.9417884061068,-77.6406835234653,38.9416968727736,-77.6403321234658,38.9417886061068,-77.6394825901338,38.9417886727735,-77.63760792347,38.9414232061074,-77.6370221234709,38.9410114727747,-77.6357033901397,38.9392504727774,-77.6352933234736,38.9389760727778,-77.6347071901412,38.9380154727793,-77.6313675901464,38.9348822727842,-77.6301375234816,38.9342876061185,-77.6295517234825,38.9336930061194,-77.6294929901493,38.9335098727863)); sdo_boxy SDO_GEOMETRY := SDO_GEOMETRY(2003,8265,NULL,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(-77.6087382736728,38.9295533233688,-77.4229814409148,38.9295533233688,-77.4229814409148,39.0744969598833,-77.6087382736728,39.0744969598833,-77.6087382736728,38.9295533233688)); num_result NUMBER; BEGIN dbms_output.put_line('Streamy is valid? ' || SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(sdo_streamy,0.05)); dbms_output.put_line('Boxy is valid? ' || SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(sdo_boxy,0.05)); dbms_output.put_line('Basic SDO_GEOM.RELATE? ' || SDO_GEOM.RELATE(sdo_streamy,'DETERMINE',sdo_boxy,0.05)); dbms_output.put_line('Distance Between ' || SDO_GEOM.SDO_DISTANCE(sdo_streamy,sdo_boxy,0.05) || 'M'); dbms_output.put_line('MBRs SDO_GEOM.RELATE? ' || SDO_GEOM.RELATE(SDO_GEOM.SDO_MBR(sdo_streamy),'DETERMINE',SDO_GEOM.SDO_MBR(sdo_boxy),0.05)); dbms_output.put_line('Distance Between ' || SDO_GEOM.SDO_DISTANCE(SDO_GEOM.SDO_MBR(sdo_streamy),SDO_GEOM.SDO_MBR(sdo_boxy),0.05) || 'M'); EXECUTE IMMEDIATE 'CREATE TABLE streamy (shape SDO_GEOMETRY)'; EXECUTE IMMEDIATE 'INSERT INTO streamy (shape) VALUES (:p01)' USING sdo_streamy; COMMIT; INSERT INTO user_sdo_geom_metadata(table_name,column_name,diminfo,srid) VALUES ('STREAMY','SHAPE',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-180,180,.05),MDSYS.SDO_DIM_ELEMENT('Y',-90,90,.05)),8265); COMMIT; EXECUTE IMMEDIATE 'CREATE INDEX streamy_spx ON streamy(shape) INDEXTYPE IS MDSYS.SPATIAL_INDEX'; EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM streamy a WHERE SDO_RELATE(a.shape,:p01,''MASK=ANYINTERACT'')=''TRUE''' INTO num_result USING sdo_boxy; dbms_output.put_line('SDO_RELATE Count ' || TO_CHAR(num_result)); EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM streamy a WHERE SDO_FILTER(a.shape,:p01)=''TRUE''' INTO num_result USING sdo_boxy; dbms_output.put_line('SDO_FILTER Count ' || TO_CHAR(num_result)); END; /
Hi Paul,.
For geodetic geometry, R-tree index are in 3D. For example, you can see:
SQL> select sdo_index_name, SDO_ROOT_MBR from user_sdo_index_metadata; SDO_INDEX_NAME -------------------------------- SDO_ROOT_MBR(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINAT -------------------------------------------------------------------------------- STREAMY_SPX SDO_GEOMETRY(3008, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1007, 3), SDO_ORDINATE_ARR AY(.16636, -.759816, .628418, .166646, -.759754, .628538))
sdo_boxy is converted to:
SDO_GEOMETRY (3008, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 1007, 3), SDO_ORDINATE_ARR)
AY (. 166589,-. 759798,.628364,.169393,-. 757698,.630331))If the two MBR or minimum limit boxes (MBBs) intersect.
Thank you
Ying -
crossing polygon and point as parameters
Hi all
I'm new on this excuse, so please, if this is a stupid question - but I need to write a function in Oracle, mySQL and SQLserver called via java to determine whether a given point is inside the specified polygon.
The call will be as follows in all databases:
SELECT point_in_polygon ('(6|2) ','(5|1) |(8| 1) |) (8: 6). (5: 7). (5|1)') = 1;
I have remove polygon and point settings above in my service and had hoped to make the select statement in Oracle to determine whether the point is inside the polygon:
Select 1 of the DOUBLE
where
SDO_RELATE (SDO_GEOMETRY ('POINT (6-2)'),
SDO_GEOMETRY (' POLYGON ((5.0 1.0, 8.0 1.0, 8,0 6,0, 5,0 7,0, 5,0 1.0)) ").
+ "(masque = anyinteract querytype = fenêtre ') = 'TRUE';" +
or something similar - but I get the error there is no spatial index:
ERROR on line 1:
ORA-13226: interface not supported without a spatial index
ORA-06512: at the 'MDSYS. MD", line 1723
ORA-06512: at the 'MDSYS. MDERR", line 8
ORA-06512: at the 'MDSYS. SDO_3GL', line 62
As I wanted to avoid the insertion of data in a table - I had hoped to make the comparison between the point and the polygon settings.
Someone can let me know if this is possible, or do I read my settings, insert into a column of type geometry in a table, create the spatial index, and then make the comparison?
Thanks in advance for your expertise.Hello
You must use the function space sdo_geom.relate rather than the operator space sdo_relate, which requires the spatial index.
In your WKT constructor you must also pass a SRID (NULL values are used in the following example)select 1 from dual where sdo_geom.RELATE(SDO_GEOMETRY('POLYGON ((5.0 1.0, 8.0 1.0, 8.0 6.0, 5.0 7.0, 5.0 1.0))',null),'anyinteract',SDO_GEOMETRY('POINT(6 2)',null),0.001) = 'TRUE';
Jack
-
Lines and spatial relationships
What is the LIMIT of a line, which is a POINT INSIDE? Where can I find the exact definition and implementation in Oracle Spatial?
Where can I find documentation definition of relations of a line and the implementation in Oracle Spatial?
In the Oracle Spatial Developer's Guide, most of the examples use polygons.
Look at the example below (Oracle 11.2, WINDOWS Server 2008 64-bit)
If I have a line of L1 with 3 Points from A1 = (0,0), next point B1 = (1,0) and ending at C1 (2.0) then
A1 and C1 are LIMITS, B1 is an interior point.
A second line begins at the point A2 = (1,0) and ends at B2 (1,1).
Then I have two points P1 = (0,0) and P2 = (1,0).
The following relationships are valid
P1 = A1
P2 = B1 = A2
If I check the topological relationships between L1, L2 and P1, P2 I get:
Line L1 and Point P1
SQL > select sdo_geom.relate)
SDO_GEOMETRY 2 (2001, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 1, 1) SDO_ORDINATE_ARRAY (0, 0));
3 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)).
4 "DETERMINE."
5 SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 2, 1) SDO_ORDINATE_ARRAY (0, 0, 1,0,2,0));
6 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)))
7 double;
SDO_GEOM. RELATE (SDO_GEOMETRY (2001, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,1,1), SDO_ORDIN))
--------------------------------------------------------------------------------
TOUCH
This it true: A1 is a LIMIT of the L1, P1 has no 'indoor', it is only 'LIMIT', LIMIT and LIMIT = > TOUCH.
Line L1 and Point P2
SQL > select sdo_geom.relate)
SDO_GEOMETRY 2 (2001, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 1, 1) SDO_ORDINATE_ARRAY (1, 0));
3 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)).
4 "DETERMINE."
5 SDO_GEOMETRY (2002, NULL, NULL, SDO_ORDINATE_ARRAY (0,0,1,0,2,0)), SDO_ELEM_INFO_ARRAY (1, 2, 1)
,
6 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)))
7 double;
SDO_GEOM. RELATE (SDO_GEOMETRY (2001, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,1,1), SDO_ORDIN))
--------------------------------------------------------------------------------
INSIDE
Now we change the order of point and line:
SQL > select sdo_geom.relate)
SDO_GEOMETRY 2 (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 2, 1) SDO_ORDINATE_ARRAY (0, 0, 1,0,2,0));
3 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)).
4 "DETERMINE."
SDO_GEOMETRY 5 (2001, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 1, 1) SDO_ORDINATE_ARRAY (1, 0));
6 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)))
7 double;
SDO_GEOM. RELATE (SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDIN))
--------------------------------------------------------------------------------
CONTAINS
P2 is an INTERIOR POINT of L1, P2 is inside of the L1 or P2 CONTAINS of L1.
For P2 and L2, we get: P2 keys L2.
If I check the relationships between L1 and L2 I get
SQL > select sdo_geom.relate)
SDO_GEOMETRY 2 (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 2, 1) SDO_ORDINATE_ARRAY (1, 0, 1, 1));
3 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)).
4 "DETERMINE."
5 SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 2, 1) SDO_ORDINATE_ARRAY (0, 0, 1,0,2,0))
,
6 SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X',-100, 100,.0001), SDO_DIM_ELEMENT ('Y',-100, 100,.0001)))
7 double;
SDO_GEOM. RELATE (SDO_GEOMETRY (2002, NULL, NULL, SDO_ELEM_INFO_ARRAY (1,2,1), SDO_ORDIN))
--------------------------------------------------------------------------------
TOUCH
This result is not valid or the documentation is incorrect or incomplete.
The lines have one thing in common (1.0), which is a POINT INSIDE the line L1 and L2 of LIMIT.
Guide/1.8 spatial relationships of the developer space Oracle® and filtering
find us
CONTACT: Borders intersect, but the Interior does not intersect.
The SDO_GEOM. SDO_RELATE gives an incorrect result:
TOUCH is a relationship between the limits, OVERLAPBDYINTERSECT is a relationship between a POINT INSIDE and a LIMIT.
If we insert the lines into a table LINES_TEST (ID NUMBER, GEOMETRY SDO_GEOMETRY), build a spatial index and run a query such as
Select a.id, b.id of LINES_TEST a, LINES_TEST b where
sdo_touch (a.geometry, b.geometry) = 'TRUE' and a.id = 1 and b.id = 2;
We get that L1 button L2.
Karl MannKarl
In addition
A point is defined only by its interior, there is NO limit.
So:
«This it true: A1 is a LIMIT of the L1, P1 has no 'indoor', it's only "LIMIT", and LIMIT-online TOUCH.»
should be
It's true: A1 is a LIMIT of the L1, P1 has no "LIMIT", it's only ' INSIDE ', LIMIT meets INTERIOR-online TOUCH»»
a point of intersection of row limit (ends) is a KEY. If the point is the inner line intersection is contained inside
Hope that clarifies
Luke
-
Strange results, of the points within the polygon query
Hi all -
This weekend I upgraded to 11.1.0.7 and apply the latest patch for 64-bit Windows (which seems to include that of space, ORA-13243 )
To recall a previous post, I have two tables:
GEO_POINTS:
(
DEP_ID NUMBER (12) NOT NULL,
LINE NUMBER 4 NOT NULL,.
MDSYS. POINT_LOC SDO_GEOMETRY
)
and POLYGON_AREAS:
(
POLY_NAME VARCHAR2 (120 CHAR),
POLY_DESC VARCHAR2 (120 CHAR),
MDSYS POLY_POINTS. SDO_GEOMETRY
)
Can I get an application to work correctly for the points at a distance from another point, but I can't now get a list of all the points in a polygon. I tried all sorts of different permutations without success. I either recover all or none.
On a previous thread I saw where someone (reggie?), suggested to someone that they check the data with SDO_RELATE, and that is what I have:
Say most of the records returned "INSIDE" a handful only seem to say "DISJOINT".SELECT poly_name, dep_id, SDO_GEOM.RELATE (P.point_loc, 'determine', poly_points, 0.0005) relation, point_loc FROM polygon_areas A, geo_points P WHERE poly_name = 'Test polygon 2' and sdo_within_distance ( point_loc, poly_points, 'distance=.5 unit=KM') = 'TRUE'; Test polygon 2 10033733 DISJOINT MDSYS.SDO_GEOMETRY(2001,8307,MDSYS.SDO_POINT_TYPE(-122.99056,40.134829348511,null),null,null) Test polygon 2 10214613 INSIDE MDSYS.SDO_GEOMETRY(2001,8307,MDSYS.SDO_POINT_TYPE(-123.0094,40.1389892964955,null),null,null)
My polygon (3D) is defined as:
INSERT INTO polygon_areas (poly_name, poly_desc, poly_points)
VALUES)
"Polygon of test 2',
"Polygon"
sdo_geometry (3003, 8307, null, sdo_elem_info_array (1,1003,1),)
sdo_ordinate_array (-122.0964560075894,46.30771933405131,0)
-122.0972586160512,46.30776603954445,0-122.0979453045886,46.30775572181209,0
-122.0985334819956,46.30786533360153,0-122.099123700718,46.30779394701457,0
-122.0998599545021,46.30764987505434,0-122.1005382096634,46.30746110208141,0
-122.101326745694,46.30725380166289,0-122.1020786809103,46.30711506779254,0
-122.1026951262488,46.30700016188705,0-122.1035181114156,46.30708532675261,0
-122.1040365310453,46.30718342118976,0-122.1046786530477,46.30731880865087,0
-122.1052722538113,46.3074574038917,0-122.1059987733943,46.30759676662286,0
-122.1066135560114,46.30762026982092,0-122.107424410801,46.30770302649447,0
-122.1080550935476,46.30762084571995,0-122.108746234047,46.30740774945418,0
-122.10937359006,46.30729761128382,0-122.1100646417299,46.30714433883676,0
-122.1105582889429,46.3069148535724,0-122.1112424328653,46.30673924798984,0
-122.1118583117779,46.30655124816924,0-122.1123792992415,46.30625620936262,0
-122.1129469500482,46.30586492598907,0-122.1133879475662,46.30552644690658,0
-122.1138881417885,46.30519890535538,0-122.1142563739051,46.30478653178479,0
-122.1145727728044,46.30435698252731,0-122.1149405876922,46.30400540617813,0
-122.1152438944599,46.30353655099154,0-122.1153926533235,46.30310263815314,0
-122.1154930418943,46.3026438525083,0-122.1155465318717,46.30227910845313,0
-122.1155460578878,46.30184016484801,0-122.1155125313209,46.3014098821799,0
-122.1155096519663,46.30093026865168,0-122.1155608294837,46.30049629380712,0
-122.1156091083421,46.30009499519977,0-122.1157053861092,46.29972055773055,0
-122.115760057761,46.29927471296439,0-122.1157313924571,46.2988898486807,0
-122.1156359044943,46.29845780132688,0-122.1155964027547,46.29806176680103,0
-122.115497397242,46.29766481786432,0-122.1152629640372,46.29730033931028,0
-122.1149123880282,46.2969384915262,0-122.1146047092177,46.29660813484444,0
-122.1142729906227,46.29610218210313,0-122.114129480908,46.29568258694918,0
-122.1140445631658,46.29522306882703,0-122.1137792523926,46.29476638544778,0
-122.1133991541599,46.29439487649638,0-122.1129044572885,46.29410744244564,0
-122.1124115408205,46.29382101043342,0-122.1120258682855,46.29341113849787,0
-122.1115713280984,46.29308325131224,0-122.1109310112231,46.29287767817464,0
-122.1103502973562,46.29267460727225,0-122.1096675994897,46.29267107652063,0
-122.1090662864219,46.29266881956065,0-122.1085381831469,46.2928983897998,0
-122.1083085173859,46.2932820188678,0-122.1083135200142,46.29366815074521,0
-122.1083216917668,46.29405755081569,0-122.1081500113631,46.29444132056023,0
-122.1083937683288,46.29480203039793,0-122.1087590296771,46.29517019740266,0
-122.1090062022728,46.29553641921602,0-122.1091433251551,46.29598906324692,0
-122.1092197934307,46.29640318538178,0-122.1090473697216,46.29684097388007,0
-122.1088741842866,46.29723867989154,0-122.1085733732482,46.29749920125438,0
-122.108275429804,46.29791598573875,0-122.1079835519625,46.29830261263341,0
-122.1077454788967,46.29867221178163,0-122.1075069644332,46.29899213519031,0
-122.1071579725203,46.29935618253118,0-122.106754980223,46.29960929039363,0
-122.1064686406685,46.29997605830629,0-122.106412384199,46.30031570325313,0
-122.1061858294833,46.30073313120077,0-122.1057885702821,46.30104316873193,0
-122.1052779521816,46.30125865231757,0-122.1049388492519,46.30160047014105,0
-122.1046010364788,46.30193421026415,0-122.1043767457976,46.30231141703782,0
-122.1040954619466,46.30269248072795,0-122.1039221949925,46.3031055071681,0
-122.1034669714409,46.30330597227303,0-122.1028484841032,46.30331988824609,0
-122.1021910294617,46.3032493533724,0-122.101711761657,46.30294476023612,0
-122.1011645802931,46.30280256913363,0-122.1005447743755,46.30281600088056,0
-122.099927372097,46.30282247816702,0-122.0993034748202,46.3028386313971,0
-122.0986869119303,46.3030411668907,0-122.0980410374456,46.30335216401479,0
-122.0975276320658,46.30386407205707,0-122.0971770391533,46.3042659531001,0
-122.0969551928034,46.3047699651079,0-122.0967233514249,46.30525030573208,0
-122.0964414955943,46.3058054153648,0-122.0960589774954,46.30642296217163,0
-122.0958540181483,46.30709385539263,0-122.0962198823426,46.30753180536824,0
-122.09646054927,46.30766952392737,0-122.0964560075894,46.30771933405131,0
))
);
So, how can we the second returned row above say "INSIDE" when the degrees are - 123.xxxxx, and none of the polygon dimensions fall into this longitude?
A I saw something with the insert statement? I know as I don't need that level of precision (it's pretty ridiculous), but I'm prototyping how a user can create a polygon in Google Earth and then paste the information into a box in my application so I can "convert" Oracle format. Near as I can tell, there isn't an easy way to enter the coordinates 3D GE creates in a simpler 2D coordinate, so I created the column like 3D polygon (hopefully correctly).
I have something simple and obvious to those who know what you are missing.
Thank you
Bill Fergusoncould you please email me (baris kazar at oracle dot com dot) your sql script?
I would like to see what you do exactly.
Thank you -
How gaps (fill) when converting to a 2006 geometry in a geometry of 2002
Is it possible to fill (filling) the differences when converting to a geometry in a single geometry of 2002 in 2006. I have a solution for the conversion of 2006 to 2002 provided by BHall but on other investigation of my dataset some of the multi line polygons are weak I need to fill and I don't know how to go on this subject.
Here is a simple example of what I'm trying to reach
Front
SELECT (sdo_geometry (2006, 81989, NULL,))
MDSYS.sdo_elem_info_array (1,2,1,5,2,1,9,2,1,13,2,1),
MDSYS.sdo_ordinate_array (16,0.999,16.998,-0,001, 17.253,-0.001, 18.003, 0.999, 18.003, 0.999, 19.001, 0.999, 19.001, 0.999, 19,999,-0,001)))
OF the double
After
SELECT (sdo_geometry (2006, 81989, NULL,))
MDSYS.sdo_elem_info_array (1,2,1),
MDSYS.sdo_ordinate_array (16,0.999,17.253,-0.001,18.003,0.999,19.001,0.999,19.999,-0.001))) DOUBLE
Thanks in advance
Hi rock,
Well, I ran all three examples that you sent through my code and it seemed to work! I pasted the code above in a "pre" html tag and I can still see things deteriorated. Lemme try this with a different syntax. You know that this new forum software not only grew on me. It's just clumsy and exaggerated. And those weird people at the top. What were they looking at? I imagine that Larry on some loft above.
Anyway, you are right that when Bryan code is used to convert the multiple string, the gaps are filled. But that's because he wrote of this approach.
Really, there is no generic way to convert a multiple line string we are discussing. If you use SDO_UTIL. CONCATENATE_LINES, it will leave gaps.
See you soon,.
Paul
CREATE OR REPLACE PACKAGE dz_gap_fill AUTHID CURRENT_USER AS FUNCTION linear_gap_filler( p_input IN MDSYS.SDO_GEOMETRY ,p_tolerance IN NUMBER DEFAULT 0.05 ) RETURN MDSYS.SDO_GEOMETRY; END dz_gap_fill; CREATE OR REPLACE PACKAGE BODY dz_gap_fill AS FUNCTION fast_point( p_x IN NUMBER ,p_y IN NUMBER ,p_z IN NUMBER DEFAULT NULL ,p_m IN NUMBER DEFAULT NULL ,p_srid IN NUMBER DEFAULT 8265 ) RETURN MDSYS.SDO_GEOMETRY AS BEGIN -------------------------------------------------------------------------- -- Step 10 -- Check over incoming parameters -------------------------------------------------------------------------- IF p_x IS NULL OR p_y IS NULL THEN RAISE_APPLICATION_ERROR(-20001,'x and y cannot be NULL'); END IF; -------------------------------------------------------------------------- -- Step 20 -- Do the simplest solution first -------------------------------------------------------------------------- IF p_z IS NULL AND p_m IS NULL THEN RETURN SDO_GEOMETRY( 2001 ,p_srid ,SDO_POINT_TYPE( p_x ,p_y ,NULL ) ,NULL ,NULL ); END IF; -------------------------------------------------------------------------- -- Step 30 -- Do the other wilder choices -------------------------------------------------------------------------- IF p_z IS NULL AND p_m IS NOT NULL THEN RETURN SDO_GEOMETRY( 3301 ,p_srid ,SDO_POINT_TYPE( p_x ,p_y ,p_m ) ,NULL ,NULL ); ELSIF p_z IS NOT NULL AND p_m IS NULL THEN RETURN SDO_GEOMETRY( 3001 ,p_srid ,SDO_POINT_TYPE( p_x ,p_y ,p_z ) ,NULL ,NULL ); ELSIF p_z IS NOT NULL AND p_m IS NOT NULL THEN RETURN SDO_GEOMETRY( 4401 ,p_srid ,NULL ,SDO_ELEM_INFO_ARRAY(1,1,1) ,SDO_ORDINATE_ARRAY(p_x,p_y,p_z,p_m) ); ELSE RAISE_APPLICATION_ERROR(-20001,'ERR!'); END IF; END fast_point; FUNCTION get_start_point( p_input IN MDSYS.SDO_GEOMETRY ) RETURN MDSYS.SDO_GEOMETRY AS int_dims PLS_INTEGER; int_gtyp PLS_INTEGER; int_lrs PLS_INTEGER; BEGIN -------------------------------------------------------------------------- -- Step 10 -- Check over incoming parameters -------------------------------------------------------------------------- IF p_input IS NULL THEN RETURN NULL; END IF; -------------------------------------------------------------------------- -- Step 20 -- Gather information about the geometry -------------------------------------------------------------------------- int_dims := p_input.get_dims(); int_gtyp := p_input.get_gtype(); int_lrs := p_input.get_lrs_dim(); -------------------------------------------------------------------------- -- Step 30 -- Handle point and multipoint inputs -------------------------------------------------------------------------- IF int_gtyp = 1 THEN RETURN p_input; ELSIF int_gtyp = 5 THEN RETURN SDO_UTIL.EXTRACT(p_input,1); END IF; -------------------------------------------------------------------------- -- Step 40 -- Return results -------------------------------------------------------------------------- IF int_dims = 2 THEN RETURN fast_point( p_input.SDO_ORDINATES(1) ,p_input.SDO_ORDINATES(2) ,NULL ,NULL ,p_input.SDO_SRID ); ELSIF int_dims = 3 AND int_lrs = 3 THEN RETURN fast_point( p_input.SDO_ORDINATES(1) ,p_input.SDO_ORDINATES(2) ,NULL ,p_input.SDO_ORDINATES(3) ,p_input.SDO_SRID ); ELSIF int_dims = 3 AND int_lrs = 0 THEN RETURN fast_point( p_input.SDO_ORDINATES(1) ,p_input.SDO_ORDINATES(2) ,p_input.SDO_ORDINATES(3) ,NULL ,p_input.SDO_SRID ); ELSIF int_dims = 4 AND int_lrs IN (4,0) THEN RETURN fast_point( p_input.SDO_ORDINATES(1) ,p_input.SDO_ORDINATES(2) ,p_input.SDO_ORDINATES(3) ,p_input.SDO_ORDINATES(4) ,p_input.SDO_SRID ); ELSIF int_dims = 4 AND int_lrs = 3 THEN RETURN fast_point( p_input.SDO_ORDINATES(1) ,p_input.SDO_ORDINATES(2) ,p_input.SDO_ORDINATES(4) ,p_input.SDO_ORDINATES(3) ,p_input.SDO_SRID ); ELSE RAISE_APPLICATION_ERROR(-20001,'ERR!'); END IF; END get_start_point; FUNCTION get_end_point( p_input IN MDSYS.SDO_GEOMETRY ) RETURN MDSYS.SDO_GEOMETRY AS int_dims PLS_INTEGER; int_gtyp PLS_INTEGER; int_lrs PLS_INTEGER; int_len PLS_INTEGER; BEGIN -------------------------------------------------------------------------- -- Step 10 -- Check over incoming parameters -------------------------------------------------------------------------- IF p_input IS NULL THEN RETURN NULL; END IF; -------------------------------------------------------------------------- -- Step 20 -- Gather information about the geometry -------------------------------------------------------------------------- int_dims := p_input.get_dims(); int_gtyp := p_input.get_gtype(); int_lrs := p_input.get_lrs_dim(); int_len := p_input.SDO_ORDINATES.COUNT(); -------------------------------------------------------------------------- -- Step 30 -- Handle point and multipoint inputs -------------------------------------------------------------------------- IF int_gtyp = 1 THEN RETURN p_input; ELSIF int_gtyp = 5 THEN RETURN SDO_UTIL.EXTRACT( p_input ,SDO_UTIL.GETNUMELEM(p_input) ); END IF; -------------------------------------------------------------------------- -- Step 40 -- Return results -------------------------------------------------------------------------- IF int_dims = 2 THEN RETURN fast_point( p_input.SDO_ORDINATES(int_len - 1) ,p_input.SDO_ORDINATES(int_len) ,NULL ,NULL ,p_input.SDO_SRID ); ELSIF int_dims = 3 AND int_lrs = 3 THEN RETURN fast_point( p_input.SDO_ORDINATES(int_len - 2) ,p_input.SDO_ORDINATES(int_len - 1) ,NULL ,p_input.SDO_ORDINATES(int_len) ,p_input.SDO_SRID ); ELSIF int_dims = 3 AND int_lrs = 0 THEN RETURN fast_point( p_input.SDO_ORDINATES(int_len - 2) ,p_input.SDO_ORDINATES(int_len - 1) ,p_input.SDO_ORDINATES(int_len) ,NULL ,p_input.SDO_SRID ); ELSIF int_dims = 4 AND int_lrs IN (4,0) THEN RETURN fast_point( p_input.SDO_ORDINATES(int_len - 3) ,p_input.SDO_ORDINATES(int_len - 2) ,p_input.SDO_ORDINATES(int_len - 1) ,p_input.SDO_ORDINATES(int_len) ,p_input.SDO_SRID ); ELSIF int_dims = 4 AND int_lrs = 3 THEN RETURN fast_point( p_input.SDO_ORDINATES(int_len - 3) ,p_input.SDO_ORDINATES(int_len - 2) ,p_input.SDO_ORDINATES(int_len) ,p_input.SDO_ORDINATES(int_len - 1) ,p_input.SDO_SRID ); ELSE RAISE_APPLICATION_ERROR(-20001,'ERR!'); END IF; END get_end_point; FUNCTION is_spaghetti( p_input IN MDSYS.SDO_GEOMETRY ,p_tolerance IN NUMBER DEFAULT 0.05 ) RETURN VARCHAR2 AS num_tolerance NUMBER := p_tolerance; ary_strings MDSYS.SDO_GEOMETRY_ARRAY := MDSYS.SDO_GEOMETRY_ARRAY(); ary_starts MDSYS.SDO_GEOMETRY_ARRAY := MDSYS.SDO_GEOMETRY_ARRAY(); ary_ends MDSYS.SDO_GEOMETRY_ARRAY := MDSYS.SDO_GEOMETRY_ARRAY(); int_count PLS_INTEGER; ary_start_count MDSYS.SDO_NUMBER_ARRAY := MDSYS.SDO_NUMBER_ARRAY(); ary_end_count MDSYS.SDO_NUMBER_ARRAY := MDSYS.SDO_NUMBER_ARRAY(); ary_inside_count MDSYS.SDO_NUMBER_ARRAY := MDSYS.SDO_NUMBER_ARRAY(); BEGIN -------------------------------------------------------------------------- -- Step 10 -- Check over incoming parameters -------------------------------------------------------------------------- IF p_input IS NULL THEN RETURN NULL; ELSIF p_input.get_gtype = 2 THEN RETURN 'FALSE'; ELSIF p_input.get_gtype <> 6 THEN RAISE_APPLICATION_ERROR(-20001,'input gtype must be 2 or 6'); END IF; IF num_tolerance IS NULL THEN num_tolerance := 0.05; END IF; -------------------------------------------------------------------------- -- Step 20 -- Break multistring into single linestrings with nodes -------------------------------------------------------------------------- int_count := SDO_UTIL.GETNUMELEM(p_input); ary_strings.EXTEND(int_count); ary_starts.EXTEND(int_count); ary_ends.EXTEND(int_count); ary_start_count.EXTEND(int_count); ary_end_count.EXTEND(int_count); ary_inside_count.EXTEND(int_count); FOR i IN 1 .. int_count LOOP ary_strings(i) := SDO_UTIL.EXTRACT(p_input,i); ary_starts(i) := get_start_point(ary_strings(i)); ary_ends(i) := get_end_point(ary_strings(i)); END LOOP; -------------------------------------------------------------------------- -- Step 30 -- Loop through and count the nodes connections -------------------------------------------------------------------------- FOR i IN 1 .. int_count LOOP ary_start_count(i) := 0; ary_end_count(i) := 0; ary_inside_count(i) := 0; FOR j IN 1 .. int_count LOOP IF i != j THEN IF SDO_GEOM.RELATE( ary_starts(i), 'DETERMINE', ary_strings(j), num_tolerance ) IN ('TOUCH','CONTAINS','COVERS','ON') THEN ary_start_count(i) := ary_start_count(i) + 1; ELSIF SDO_GEOM.RELATE( ary_ends(i), 'DETERMINE', ary_strings(j), num_tolerance ) IN ('TOUCH','CONTAINS','COVERS','ON') THEN ary_end_count(i) := ary_end_count(i) + 1; ELSIF SDO_GEOM.RELATE( ary_strings(i), 'DETERMINE', ary_strings(j), num_tolerance ) IN ('TOUCH','CONTAINS','COVERS','OVERLAPBYINTERSECT') THEN ary_inside_count(i) := ary_inside_count(i) + 1; END IF; END IF; END LOOP; IF ary_start_count(i) > 1 OR ary_end_count(i) > 1 OR ary_inside_count(i) > 0 THEN RETURN 'TRUE'; END IF; END LOOP; RETURN 'FALSE'; END is_spaghetti; ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- FUNCTION points2segment( p_point_one IN MDSYS.SDO_POINT_TYPE ,p_point_two IN MDSYS.SDO_POINT_TYPE ,p_srid IN NUMBER ) RETURN MDSYS.SDO_GEOMETRY AS BEGIN IF ( p_point_one.Z IS NULL AND p_point_two.Z IS NOT NULL ) OR ( p_point_one.Z IS NOT NULL AND p_point_two.Z IS NULL ) THEN RAISE_APPLICATION_ERROR( -20001, 'both points must have the same number of dimensions, point_one Z is ' || NVL(TO_CHAR(p_point_one.Z),'
') || ' and point_two Z is ' || NVL(TO_CHAR(p_point_two.Z),' ') ); END IF; IF p_point_one.Z IS NULL THEN RETURN SDO_GEOMETRY( 2002 ,p_srid ,NULL ,SDO_ELEM_INFO_ARRAY(1,2,1) ,SDO_ORDINATE_ARRAY(p_point_one.X,p_point_one.Y,p_point_two.X,p_point_two.Y) ); ELSE RETURN SDO_GEOMETRY( 3002 ,p_srid ,NULL ,SDO_ELEM_INFO_ARRAY(1,2,1) ,SDO_ORDINATE_ARRAY(p_point_one.X,p_point_one.Y,p_point_one.Z,p_point_two.X,p_point_two.Y,p_point_two.Z) ); END IF; END points2segment; ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- FUNCTION points2segment( p_point_one IN MDSYS.SDO_GEOMETRY ,p_point_two IN MDSYS.SDO_GEOMETRY ) RETURN MDSYS.SDO_GEOMETRY AS int_gtype1 PLS_INTEGER; int_dims1 PLS_INTEGER; int_gtype2 PLS_INTEGER; int_dims2 PLS_INTEGER; point_one MDSYS.SDO_POINT_TYPE; point_two MDSYS.SDO_POINT_TYPE; BEGIN int_gtype1 := p_point_one.get_gtype(); int_dims1 := p_point_one.get_dims(); int_gtype2 := p_point_two.get_gtype(); int_dims2 := p_point_two.get_dims(); IF int_gtype1 = 1 AND int_gtype2 = 1 AND int_dims1 = int_dims2 AND p_point_one.SDO_SRID = p_point_two.SDO_SRID THEN NULL; -- Good ELSE RAISE_APPLICATION_ERROR( -20001 ,'both point objects must be points and have the same number of dimensions and SRIDs' ); END IF; IF int_dims1 = 4 THEN RETURN SDO_GEOMETRY( 4402 ,p_point_one.SDO_SRID ,NULL ,SDO_ELEM_INFO_ARRAY(1,2,1) ,SDO_ORDINATE_ARRAY( p_point_one.SDO_ORDINATES(1) ,p_point_one.SDO_ORDINATES(2) ,p_point_one.SDO_ORDINATES(3) ,p_point_one.SDO_ORDINATES(4) ,p_point_two.SDO_ORDINATES(1) ,p_point_two.SDO_ORDINATES(2) ,p_point_two.SDO_ORDINATES(3) ,p_point_two.SDO_ORDINATES(4) ) ); ELSE -- Use the sdo_point_type method for the rest IF p_point_one.SDO_POINT IS NOT NULL THEN point_one := p_point_one.SDO_POINT; ELSE IF int_dims1 = 3 THEN point_one := SDO_POINT_TYPE( p_point_one.SDO_ORDINATES(1) ,p_point_one.SDO_ORDINATES(2) ,p_point_one.SDO_ORDINATES(3) ); ELSE point_one := SDO_POINT_TYPE( p_point_one.SDO_ORDINATES(1) ,p_point_one.SDO_ORDINATES(2) ,NULL ); END IF; END IF; IF p_point_two.SDO_POINT IS NOT NULL THEN point_two := p_point_two.SDO_POINT; ELSE IF int_dims1 = 3 THEN point_two := SDO_POINT_TYPE( p_point_two.SDO_ORDINATES(1) ,p_point_two.SDO_ORDINATES(2) ,p_point_two.SDO_ORDINATES(3) ); ELSE point_two := SDO_POINT_TYPE( p_point_two.SDO_ORDINATES(1) ,p_point_two.SDO_ORDINATES(2) ,NULL ); END IF; END IF; RETURN points2segment( p_point_one => point_one ,p_point_two => point_two ,p_srid => p_point_one.SDO_SRID ); END IF; END points2segment; FUNCTION linear_gap_filler( p_input IN MDSYS.SDO_GEOMETRY ,p_tolerance IN NUMBER DEFAULT 0.05 ) RETURN MDSYS.SDO_GEOMETRY AS sdo_input MDSYS.SDO_GEOMETRY := p_input; num_tolerance NUMBER; int_counter PLS_INTEGER; ary_edges MDSYS.SDO_GEOMETRY_ARRAY; ary_starts MDSYS.SDO_GEOMETRY_ARRAY; ary_ends MDSYS.SDO_GEOMETRY_ARRAY; ary_nearest MDSYS.SDO_NUMBER_ARRAY; ary_distance MDSYS.SDO_NUMBER_ARRAY; num_temp NUMBER; num_nearest NUMBER; int_winner PLS_INTEGER; int_winner2 PLS_INTEGER; sdo_point1 MDSYS.SDO_GEOMETRY; sdo_point2 MDSYS.SDO_GEOMETRY; boo_done BOOLEAN; num_one NUMBER; num_two NUMBER; int_looper PLS_INTEGER := 1; BEGIN -------------------------------------------------------------------------- -- Step 10 -- Check over incoming parameters -------------------------------------------------------------------------- IF num_tolerance IS NULL THEN num_tolerance := 0.05; END IF; IF sdo_input IS NULL OR sdo_input.get_gtype() <> 6 THEN RETURN sdo_input; END IF; IF is_spaghetti(sdo_input,p_tolerance) = 'TRUE' THEN RETURN sdo_input; END IF; < > ary_edges := MDSYS.SDO_GEOMETRY_ARRAY(); ary_starts := MDSYS.SDO_GEOMETRY_ARRAY(); ary_ends := MDSYS.SDO_GEOMETRY_ARRAY(); ary_nearest := MDSYS.SDO_NUMBER_ARRAY(); ary_distance := MDSYS.SDO_NUMBER_ARRAY(); -------------------------------------------------------------------------- -- Step 20 -- Break multistring into edges and start and end nodes -------------------------------------------------------------------------- int_counter := SDO_UTIL.GETNUMELEM(sdo_input); ary_edges.EXTEND(int_counter); ary_starts.EXTEND(int_counter); ary_ends.EXTEND(int_counter); FOR i IN 1 .. int_counter LOOP ary_edges(i) := SDO_UTIL.EXTRACT(sdo_input,i); ary_starts(i) := get_start_point(ary_edges(i)); ary_ends(i) := get_end_point(ary_edges(i)); END LOOP; -------------------------------------------------------------------------- -- Step 30 -- Determine the closest endpoints -------------------------------------------------------------------------- ary_nearest.EXTEND(int_counter); ary_distance.EXTEND(int_counter); FOR i IN 1 .. int_counter LOOP num_nearest := NULL; int_winner := NULL; FOR j IN 1 .. int_counter LOOP IF j != i THEN num_temp := SDO_GEOM.SDO_DISTANCE( ary_edges(i) ,ary_edges(j) ,num_tolerance ); IF num_nearest IS NULL OR num_temp < num_nearest THEN num_nearest := num_temp; int_winner := j; END IF; END IF; END LOOP; ary_nearest(i) := int_winner; ary_distance(i) := num_nearest; END LOOP; -------------------------------------------------------------------------- -- Step 40 -- Find the smallest gap -------------------------------------------------------------------------- int_winner := NULL; num_nearest := NULL; FOR i IN 1 .. int_counter LOOP IF num_nearest IS NULL OR ary_distance(i) < num_nearest THEN int_winner := i; num_nearest := ary_distance(i); int_winner2 := ary_nearest(i); END IF; END LOOP; -------------------------------------------------------------------------- -- Step 50 -- Determine the endpoints to connect -------------------------------------------------------------------------- num_one := SDO_GEOM.SDO_DISTANCE( get_start_point(ary_edges(int_winner)), ary_edges(int_winner2), num_tolerance ); num_two := SDO_GEOM.SDO_DISTANCE( get_end_point(ary_edges(int_winner)), ary_edges(int_winner2), num_tolerance ); IF ( num_one = 0 AND SDO_GEOM.RELATE( get_start_point(ary_edges(int_winner)), 'ANYINTERACT', ary_edges(int_winner2), num_tolerance ) = 'TRUE' ) OR ( num_two = 0 AND SDO_GEOM.RELATE( get_end_point(ary_edges(int_winner)), 'ANYINTERACT', ary_edges(int_winner2), num_tolerance ) = 'TRUE' ) THEN sdo_point1 := NULL; ELSIF num_one < num_two THEN sdo_point1 := get_start_point(ary_edges(int_winner)); ELSE sdo_point1 := get_end_point(ary_edges(int_winner)); END IF; num_one := SDO_GEOM.SDO_DISTANCE( get_start_point(ary_edges(int_winner2)), ary_edges(int_winner), num_tolerance ); num_two := SDO_GEOM.SDO_DISTANCE( get_end_point(ary_edges(int_winner2)), ary_edges(int_winner), num_tolerance ); IF ( num_one = 0 AND SDO_GEOM.RELATE( get_start_point(ary_edges(int_winner2)), 'ANYINTERACT', ary_edges(int_winner), num_tolerance ) = 'TRUE' ) OR ( num_two = 0 AND SDO_GEOM.RELATE( get_end_point(ary_edges(int_winner2)), 'ANYINTERACT', ary_edges(int_winner), num_tolerance ) = 'TRUE' ) THEN sdo_point2 := NULL; ELSIF num_one < num_two THEN sdo_point2 := get_start_point(ary_edges(int_winner2)); ELSE sdo_point2 := get_end_point(ary_edges(int_winner2)); END IF; -------------------------------------------------------------------------- -- Step 50 -- Smash together -------------------------------------------------------------------------- IF sdo_point1 IS NULL OR sdo_point2 IS NULL THEN sdo_input := SDO_UTIL.CONCAT_LINES( ary_edges(int_winner), ary_edges(int_winner2) ); ELSE sdo_input := SDO_UTIL.CONCAT_LINES( SDO_UTIL.CONCAT_LINES( ary_edges(int_winner), points2segment(sdo_point1,sdo_point2) ), ary_edges(int_winner2) ); END IF; boo_done := TRUE; FOR i IN 1 .. int_counter LOOP IF i NOT IN (int_winner,int_winner2) THEN sdo_input := SDO_UTIL.APPEND(sdo_input,ary_edges(i)); boo_done := FALSE; END IF; END LOOP; -------------------------------------------------------------------------- -- Step 60 -- Check if valid if returning -------------------------------------------------------------------------- IF sdo_input.get_gtype() = 2 OR boo_done = TRUE THEN RETURN sdo_input; END IF; int_looper := int_looper + 1; GOTO TOP_OF_IT; END linear_gap_filler; END dz_gap_fill; -
nested to perform DML and wait function call commit
Hello world
I would like to make a few DML - one insert statement, to be precise - in function and have the function and then return the number keys on the newly added row. I call this function from a different context and woud then be able to use the newly added data to do something.
Specifically, what I do is the following: I have a graph composed of triplets source, destination and distance in a picture. A user should now be able to
1.) add a node "A" to the curve.
2.) add a node 'B' to the chart
(3.) to get the shortest path from A to B in the graphs.
I have an internal function
adding new nodes to the chart, links, calculates distances etc. and returns a handle to the newly added node. I call this function twice function, externalfunction INSERT_NEW_NODE(node_in in sdo_geometry, graph_in in integer) return integer is pragma autonomous_transaction; cursor node_cur is select source, source_geom from graph ; cursor edge_cur is select source, destination, distance, edge_geom from graph where sdo_geom.relate(edge_geom, 'anyinteract', node_in, .005) = 'TRUE'; begin -- check if identical with any existing node for node_rec in node_cur loop if sdo_geom.relate(node_rec.source_geom, 'EQUAL', node_in, .005) = 'EQUAL' then return node_rec.source; end if; end loop; -- get edges for edge_rec in edge_cur loop -- new_node-->edge.destination and vice versa insert into graph ( ID, GRAPH, SOURCE, DESTINATION, DISTANCE, SOURCE_GEOM, DESTINATION_GEOM, EDGE_GEOM ) values ( graph_id_seq.nextval, --id graph_in, --graph morton(node_in.sdo_point.x, node_in.sdo_point.y), -- source morton key edge_rec.source, -- destination morton key sdo_geom.sdo_distance(edge_rec.source_geom_marl2000, node_in, .005, 'unit=M'), -- distance node_in, -- source geom edge_rec.source_geom, -- dest geom split_line(edge_rec.edge_geom_marl2000, node_in).segment1 -- edge geom ); commit; --new_node-->edge.source and vice versa insert into gl_graph ( ID, GRAPH, SOURCE, DESTINATION, DISTANCE, SOURCE_GEOM, DESTINATION_GEOM, EDGE_GEOM ) values ( graph_id_seq.nextval, --id graph_in, --graph edge_rec.source, -- source morton key morton(node_in.sdo_point.x, node_in.sdo_point.y), -- destination morton key sdo_geom.sdo_distance(edge_rec.source_geom, node_in, .005, 'unit=M'), -- distance edge_rec.source_geom, -- source geom node_in, -- dest geom split_line(edge_rec.edge_geom, node_in).segment2 -- edge geom ); commit; end loop ; return(morton(node_in.sdo_point.x, node_in.sdo_point.y)); end insert_new_node;
; and I think thatI have to use autonomous transaction in the internal function, so that the external function can see any changes made by the inside one. However, it doesn't work, when I call twice the function internal (i.e. remove the comment panels in front of the last two lines of code just before the return statement in the outer function.)function get_path (line_in in sdo_geometry, graph_in in integer) return sdo_geometry is source number; destination number; source_geom mdsys.sdo_geometry; destination_geom mdsys.sdo_geometry; begin source := insert_new_node(get_firstvertex(line_in), graph_in); destination := insert_new_node(get_lastvertex(line_in), graph_in); -- source := insert_new_node(get_firstvertex(line_in), graph_in); -- destination := insert_new_node(get_lastvertex(line_in), graph_in); return(get_path_geom(source, destination)); --returns a geometry which is the shortest path between source and destination end get_path;
So here are my questions: 1) why should I call the function twice to see the complete transaction? (and 2.) How can I avoid this? Is it possible to wait for the execution of the return statement in the internal function that the insert is committed and can be seen by the external function?
See you soon!OK, here's the solution: the external function
get_path()
calls a functionget_path_geom(source, destination)
, who himself called something liketable(dijkstra(source, destination))
, (omitted by me because only carefully tested and ok, my bad!) which makes the job of finding the shortest path and returns an array in pipeline. It turns out that this feature for some reason is not the scope of the external function and therefore does not see the transaction committed themselves on the graphics table. After you change thedijkstra()
-function to return a list instead of a table, all works all of a sudden.If this question has been answered; I would still like to know why the table function does not have the same scope as the rest of the transaction.
Edit: removed misleading blame on application external and inserted a correct solution.
-
Date column updated with trigger update of the geometry
Hello
I have a column named "GEO_MOD_DATE" which is supposed to be updated every time that my geometry column is updated. My trigger code is below. Currently the trigger is fired when other than my column of geometry columns are updated. I searched the forum and many other sites. As far as I know, my trigger is written correctly. But I can't understand why it is taken when the columns except my geometry column are updated. You have any ideas? Thanks in advance! Note that the trigger fires when I update the geometry column. However, it is also SHOOTING when the other columns are updated. I have also tried adding 'OF GDO_GEOMETRY' from "BEFORE UPDATE" paragraph and which did not help.
Jeff
Triggering factor:
CREATE OR REPLACE TRIGGER OPER_ZONE_VALVE_GEO_BU_T
BEFORE THE UPDATE
ON OPER_ZONE_VALVE
REFERRING AGAIN AS NINE OLD AND OLD
FOR EACH LINE
DECLARE
v_foo NUMBER (9);
BEGIN
-Comment from below if you do not want to assign GEO_MOD_DATE
BEGIN
IF the UPDATE ("GDO_GEOMETRY") and: NEW.gdo_geometry IS NOT NULL
THEN
: NEW.geo_mod_date: = SYSDATE;
ON THE OTHER
: NEW.geo_mod_date: = NULL;
END IF;
EXCEPTION
WHILE OTHERS
THEN
raise_application_error
(- 20013,
"Cannot be autoassign field OPER ZONE VALVE".
);
END;
/*****/
NULL;
EXCEPTION
WHILE OTHERS
THEN
raise_application_error
(- 20013,
'error in executing BEFORE INSERT TRIGGER OPER_ZONE_VALVE_GEO_BU_T;'
);
END;
/
--------------------------------------------
And here is my table structure:
CREATE TABLE OPER_ZONE_VALVE
(
MSLINK NUMBER (38),
VALVE_NUMBER VARCHAR2 (8 BYTE),
ECM_NUMBER VARCHAR2 (8 BYTE),
VALVE_SIZE VARCHAR2 (4 BYTE),
CONNECTION_TYPE VARCHAR2 (100 BYTE),
HEADER_STREET VARCHAR2 (100 BYTE),
HEADER_FEET VARCHAR2 (8 BYTE),
HEADER_DIR VARCHAR2 (4 BYTE),
HEADER_PROP VARCHAR2 (4 BYTE),
SUB_STREET VARCHAR2 (100 BYTE),
SUB_FEET VARCHAR2 (8 BYTE),
SUB_DIR VARCHAR2 (4 BYTE),
SUB_PROP VARCHAR2 (4 BYTE),
PLAT_MAP_NUMBER VARCHAR2 (4 BYTE),
USER DEFAULT CREATED_BY VARCHAR2 (50 BYTES)
CREATED_DATE DATE DEFAULT SYSDATE,
MODIFIED_BY VARCHAR2 (50 BYTE),
MODIFIED_DATE DATE,
DATE OF GEO_MOD_DATE,
NOTE VARCHAR2 (40 BYTE),
MDSYS GDO_GEOMETRY. SDO_GEOMETRY
)I read that FORWARD updated TO does not work with data as CLOB types
Yes. But what does this mean for the SDO_GEOMETRY objects is that you cannot directly use a WHEN clause in the definition of the trigger and you cannot compare two geometries directly via If (: old.geom =: new.geom) then.
So, in your trigger update of your business rules conditions require the trigger to implement are not enough.
Try to check if the geometry column has actually changed.
DROP TABLE oper_zone_valve; CREATE TABLE oper_zone_valve ( mslink NUMBER (38), valve_number VARCHAR2 (8 BYTE), ecm_number VARCHAR2 (8 BYTE), valve_size VARCHAR2 (4 BYTE), connection_type VARCHAR2 (100 BYTE), header_street VARCHAR2 (100 BYTE), header_feet VARCHAR2 (8 BYTE), header_dir VARCHAR2 (4 BYTE), header_prop VARCHAR2 (4 BYTE), sub_street VARCHAR2 (100 BYTE), sub_feet VARCHAR2 (8 BYTE), sub_dir VARCHAR2 (4 BYTE), sub_prop VARCHAR2 (4 BYTE), plat_map_number VARCHAR2 (4 BYTE), created_by VARCHAR2 (50 BYTE) DEFAULT USER, created_date DATE DEFAULT SYSDATE, modified_by VARCHAR2 (50 BYTE), modified_date DATE, geo_mod_date DATE, remark VARCHAR2 (40 BYTE), gdo_geometry MDSYS.sdo_geometry ); CREATE OR REPLACE TRIGGER air_valve_geo_bu_t BEFORE UPDATE OF gdo_geometry ON oper_zone_valve REFERENCING NEW AS new OLD AS old FOR EACH ROW BEGIN IF ( NOT UPDATING('GDO_GEOMETRY') ) THEN RETURN; END IF; IF ( :old.gdo_geometry is not null and :new.gdo_geometry IS not NULL ) THEN -- Check if geometry has changed internally IF ( sdo_geom.relate(:old.gdo_geometry,'DETERMINE',:new.gdo_geometry,0.005) != 'EQUAL' ) Then :new.geo_mod_date := SYSDATE; End If; ELSIF ( ( :old.gdo_geometry is null and :new.gdo_geometry IS NOT NULL ) OR ( :old.gdo_geometry is not null and :new.gdo_geometry IS NULL ) ) THEN :new.geo_mod_date := SYSDATE; ELSE :new.geo_mod_date := NULL; END IF; END; / SHOW ERRORS
Some tests
SET NULL NULL INSERT INTO oper_zone_valve ( remark, gdo_geometry) VALUES ('remark', MDSYS.sdo_geometry(2001,NULL,SDO_POINT_TYPE(0,0,0), NULL,NULL)); COMMIT; 1 rows inserted. commited. SELECT remark, to_char(geo_mod_date,'YYYY-MM-DD HH24:MI:SS') as geo_mod_date, gdo_geometry FROM oper_zone_valve; REMARK GEO_MOD_DATE GDO_GEOMETRY ------ ------------------- ------------------------------------------------------- remark NULL SDO_GEOMETRY(2001,NULL,SDO_POINT_TYPE(0,0,0),NULL,NULL) update oper_zone_valve set gdo_geometry = sdo_geometry(2001, NULL,SDO_POINT_TYPE( 0,0,0),NULL,NULL) where remark = 'remark'; COMMIT; 1 rows updated. commited. SELECT remark, to_char(geo_mod_date,'YYYY-MM-DD HH24:MI:SS') as geo_mod_date, gdo_geometry FROM oper_zone_valve; REMARK GEO_MOD_DATE GDO_GEOMETRY ------ ------------------- ------------------------------------------------------- remark NULL SDO_GEOMETRY(2001,NULL,SDO_POINT_TYPE(0,0,0),NULL,NULL) update oper_zone_valve set gdo_geometry = sdo_geometry(2001, NULL,SDO_POINT_TYPE(10,0,0),NULL,NULL) where remark = 'remark'; COMMIT; 1 rows updated. commited. SELECT remark, to_char(geo_mod_date,'YYYY-MM-DD HH24:MI:SS') as geo_mod_date, gdo_geometry FROM oper_zone_valve; REMARK GEO_MOD_DATE GDO_GEOMETRY ------ ------------------- -------------------------------------------------------- remark 2012-10-16 09:24:53 SDO_GEOMETRY(2001,NULL,SDO_POINT_TYPE(10,0,0),NULL,NULL) execute dbms_lock.sleep(5); anonymous block completed update oper_zone_valve set gdo_geometry = NULL where remark = 'remark'; COMMIT; 1 rows updated. commited. SELECT remark, to_char(geo_mod_date,'YYYY-MM-DD HH24:MI:SS') as geo_mod_date, gdo_geometry FROM oper_zone_valve; REMARK GEO_MOD_DATE GDO_GEOMETRY ------ ------------------- -------------------------------------------------------- remark 2012-10-16 09:24:58 NULL
This seems to be the answer you are looking for or puts you on a path to achieve the correct execution of your business rules in the trigger.
Shows please!
concerning
SimonPublished by: Simon Greener on 17 October 2012 15:39, fixed a display issue does not
Maybe you are looking for
-
2000-2b22DX HP: HP 2000-2b22DX Ram Upgrade
Recently, I encountered some problems with my laptop. I have accumulated a few programs of work (I'm a designer and a musician for hobby) so the tear begins to take a toll.First of all, I want to know how can I upgrade Ram. I looked in the next page
-
I recently installed Windows 7 on a computer science professor and there a NVIDIA e-GeForce2 MX TWV MORE and it is an AGP graphics card. I'm looking for the driver for this video card. It's a HP d530. I know it's old, but I try to get the NVIDIA driv
-
WindowsUpdate_80242014"windows update do not stop telling me to restart.
of course computer 100 timesDelete and I reinstalled the update.
-
Windows XP - update [error number: 0x8024402F]
Original title: what happens now? After the update when I'm home for some time, I get this message [Error number: 0x8024402F] The website has encountered a problem and cannot display the page you are trying to view. I tried a restore, but it does not
-
Desktop Pavilion a6742p does not start after the HP screen
Less than a box of 64-bit years with 6 GB of RAM, Vista Home Premium. Does load the HP screen without feature, no possibility to go to recovery or utilities. No fan, no HD no spin. Not removable drive storage (only connected when you fill out the bac