I have two geometry in two feature class ,one named "HY90299 " and the other named "hyboxsdo " ,the two geometry do not intersect .
but when i run a spatial query in oralce ,
"select sdo_relate(t.shape,g.shape ,'mask=ANYINTERACT') from HY90299 t,hyboxsdo g " ,
it return "true", the result is not correct .am I doing something wrong?
my oracle version is 11g
you can get the two geometry by
1.i put the two geometry into two shape file . you can get them from here
https://pan.baidu.com/s/1YQnwe8nstzgHOAwHgx9JGQ
2.or create the two geometry by wkt
①MULTIPOLYGON (((-16.657423019000021 82.843477248999989, 16.710901260000014 66.242341995000004, 74.611375808999981 57.038061142000004, 111.18630027799998 67.126588820999984, -16.657423019000021 82.843477248999989)))
②MULTIPOLYGON (((60.839999999999975 26.569999999999993, 143.45000000000005 26.569999999999993, 143.45000000000005 55.75, 60.839999999999975 55.75, 60.839999999999975 26.569999999999993)))
Append
1.select * from user_sdo_geom_metadata where table_name='HY90299'
=============================
return "HY90299 SHAPE {{null,-180,180,0.001},{null,-90,90,0.001}} 4326"
2.select sdo_geom.validate_geometry_with_context(c.shape,0.000000005) from hy90299 c
select sdo_geom.validate_geometry_with_context(c.shape,0.001) from hy90299 c
=============================
all return "true"
3.select shape from hy90299
=============================
return "{2003,4326,null,{1,1003,1},{111.186300278,67.126588821,-16.657423019,82.843477249,16.71090126,66.242341995,74.611375809,57.038061142,111.186300278,67.126588821}}"
4.select sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450,55.750)),0.000000005) as spat_rel from HY90299 t
=============================
return "DISJOINT"
5.select sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(60.840,26.570, 143.450,26.570, 143.450,55.750,60.840,55.750,60.840, 26.570)),0.000000005) as spat_rel from HY90299 t
=============================
return "OVERLAPBDYINTERSECT"
From the manual (https://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#SPATL1039), spatial operators "must always be used in a WHERE clause", not in the SELECT part of the query.
To use them (in the WHERE clause, as mentioned), they must be spatially indexed.
If you want to see the spatial relation, you can use one of the spatial functions - e.g:
select t.*,g.*, sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) as spat_rel
from HY90299 t, hyboxsdo g
If you want you can add the function to the WHERE caluse as well, to filter the results - e.g. add in the above snippet:
where sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) not in ('TOUCH','DISJOINT')
For a handful of geometries, you'll be fine. As the number of geometries grows, you must either use spatial indexes and add operator(s) in the WHERE clause, or device another way to filter the rows (e.g. by an attribute, id, etc) - spatial functions do not scale well.
You also have the responsibility to choose the TOLERANCE value that is appropriate for your data and query (I chose 0.000000005 as your shapes seem to have 8 significant decimals).
Last, BUT NOT LEAST, you'd want to make certain that your geometries are valid (again, at the appropriate tolerance).
HTH
APPEND:
1)
with HY90299 as (
select sdo_util.from_wktgeometry(
'MULTIPOLYGON (((-16.657423019000021 82.843477248999989, 16.710901260000014 66.242341995000004, 74.611375808999981 57.038061142000004, 111.18630027799998 67.126588820999984, -16.657423019000021 82.843477248999989)))'
) shape from dual ),
HYBOXSDO as (
select sdo_util.from_wktgeometry(
'MULTIPOLYGON (((60.839999999999975 26.569999999999993, 143.45000000000005 26.569999999999993, 143.45000000000005 55.75, 60.839999999999975 55.75, 60.839999999999975 26.569999999999993)))'
) shape from dual )
select sdo_geom.relate(t.shape,'determine',g.shape,0.000000005)
from HY90299 t,hyboxsdo g ;
The result is DISJOINT - also:
with HY90299 as (
select sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(-16.657423019000021, 82.843477248999989, 16.710901260000014, 66.242341995000004, 74.611375808999981, 57.038061142000004, 111.18630027799998, 67.126588820999984, -16.657423019000021, 82.843477248999989))
shape from dual )
select sdo_geom.relate(t.shape,'determine',
sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450,55.750))
,0.000000005) as spat_rel from HY90299 t
The result is, again, DISJOINT.
Your 'overlapbdyintersect' shouldn't be there - check the contents of your tables (since the difference in your two queries is the 'window' geometry, double check the hyboxsdo table).
2) You are wrong. Tolerance is essential. If you use sdo_geom.relate(t.shape,'determine',g.shape,2) -that is a tolerance of 2 meters- in the above queries, you will get TOUCH instead of DISJOINT (and by this, you can also tell that your geometries are roughly 2m apart). However, with these two geometries, you would never get OVERLAP.
3) A geometry's validity is directly related to the tolerance you use. Your geometries are valid (in 8 decimals) - I'm just saying that it will save you LOTS of headaches if you don't take it for granted. Never assume - check!
4) It doesn't matter how you put the geometries in the table. The only think you might want to consider (especially in production environments) is the number of decimals stored in the database - if your data make good sense at a precision of, say, 3 decimals, you'd be better off rounding or truncating your coordinates to that. Simpler coordinates lead to smaller footprint (database storage) and faster performance.
Related
I want to count the occurrences of values in a column. In my case the value I want to count is TRUE().
Lets say my table is called Table and has two columns:
boolean value
TRUE() A
FALSE() B
TRUE() A
TRUE() B
All solutions I found so far are like this:
count_true = COUNTROWS(FILTER(Table, Table[boolean] = TRUE()))
The problem is that I still want the visual (card), that displays the measure, to consider the filters (coming from the slicers) to reduce the table. So if I have a slicer that is set to value = A, the card with the count_true measure should show 2 and not 3.
As far as I understand the FILTER function always overwrites the visuals filter context.
To further explain my intent: At an earlier point the TRUE/FALSE column had the values 1/0 and I could achieve my goal by just using the SUM function that does not specify a filter context and just acts within the visuals filter context.
I think the DAX you gave should work as long as it's a measure, not a calculated column. (Calculated columns cannot read filter context from the report.)
When evaluating the measure,
count_true = COUNTROWS ( FILTER ( Table, Table[boolean] = TRUE() ) )
the first argument inside FILTER is not necessarily the full table but that table already filtered by the local filter context (including report/page/visual filters along with slicer selections and local context from e.g. rows/column a matrix visual).
So if you select Value = "A" via slicer, then the table in FILTER is already filtered to only include "A" values.
I do not know for sure if this will fix your problem but it is more efficient dax in my opinion:
count_true = CALCULATE(COUNTROWS(Table), Table[boolean])
If you still have the issue after changing your measure to use this format, you may have an underlying issue with the model. There is also the function KEEPFILTERS that may apply here but I think using KEEPFILTERS is overcomplicating your case.
I have two facts tables, First and Second, and two dimension tables, dimTime and dimColour.
Fact table First looks like this:
and facet table Second looks like this:
Both dim-tables have 1:* relationships to both fact tables and the filtering is one-directional (from dim to fact), like this:
dimColour[Color] 1 -> * First[Colour]
dimColour[Color] 1 -> * Second[Colour]
dimTime[Time] 1 -> * First[Time]
dimTime[Time] 1 -> * Second[Time_]
Adding the following measure, I would expect the FILTER-functuion not to have any affect on the calculation, since Second does not filter First, right?
Test_Alone =
CALCULATE (
SUM ( First[Amount] );
First[Alone] = "Y";
FILTER(
'Second';
'Second'[Colour]="Red"
)
)
So this should evaluate to 7, since only two rows in First have [Alone] = "Y" with values 1 and 6 and that there is no direct relationship between First and Second. However, this evaluates to 6. If I remove the FILTER-function argument in the calculate, it evaluates to 7.
There are thre additional measures in the pbix-file attached which show the same type of behaviour.
How is filtering one fact table which has no direct relationship to a second fact table affecting the calculation done on the second table?
Ziped Power BI-file: PowerBIFileDownload
Evaluating the table reference 'Second' produces a table that includes the columns in both the Second table, as well as those in all the (transitive) parents of the Second table.
In this case, this is a table with all of the columns in dimColour, dimTime, Second.
You can't see this if you just run:
evaluate 'Second'
as when 'evaluate' returns the results to the user, these "Parent Table" (or "Related") columns are not included.
Even so, these columns are certainly present.
When a table is converted to a row context, these related columns become available via RELATED.
See the following queries:
evaluate FILTER('Second', ISBLANK(RELATED(dimColour[Color])))
evaluate 'Second' order by RELATED(dimTime[Hour])
Similarly, when arguments to CALCULATE are used to update the filter context, these hidden "Related" columns are not ignored; hence, they can end up filtering First, in your example. You can see this, by using a function that strips the related columns, such as INTERSECT:
Test_ActuallyAlone = CALCULATE (
SUM ( First[Amount] ),
First[Alone] = "Y",
//This filter now does nothing, as none of the columns in Second
//have an impact on 'SUM ( First[Amount] )'; and the related columns
//are removed by the INTERSECT.
FILTER(
INTERSECT('Second', 'Second')
'Second'[Colour]="Red"
)
)
(See these resources that describe the "Expanded Table"
(this is an alternative but equivalent explanation of this behaviour)
https://www.sqlbi.com/articles/expanded-tables-in-dax/
https://www.sqlbi.com/articles/context-transition-and-expanded-tables/
)
I have three big tables with same structure (BATHY_SHC_1, BATHY_SHC_2 and BATHY_SHC_3), each with a SDO_GEOMETRY column “POINT_PP”, the spatial index of each is VALID.
I have made a view on these tables that includes this geometry column (V_BATHY_SHC).
I can make spatial request on the view to find all point within a rectangle like this with correct results:
SELECT PT_ID, POINT_PP from V_BATHY_SHC
WHERE SDO_RELATE(POINT_PP, MDSYS.SDO_GEOMETRY(2003, 32618, null, MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),MDSYS.SDO_ORDINATE_ARRAY(635267,5037808, 635277,5037818)), 'mask=anyinteract') = 'TRUE';
I have upload a polygon MASK in a table MNE_MASK, added a line in metadata and created a spatial index (as usual). It has a valid spatial index. The geometry is in the same SRID (32618).
Then I want to get all points from the view that are within the polygon from the MNE_MASK table. If I made the query on one of the table, I get correct results:
SELECT A.PT_ID, A.POINT_PP
FROM BATHY_SHC_1 A, MNE_MASK B
WHERE B.MNE_ID = 1
AND SDO_RELATE(A.POINT_PP, B.MASK, 'mask=ANYINTERACT ') = 'TRUE';
But if I made it on the view like this:
SELECT A.PT_ID, A.POINT_PP
FROM V_BATHY_SHC A, MNE_MASK B
WHERE B.MNE_ID = 1
AND SDO_RELATE(A.POINT_PP, B.MASK, 'mask=ANYINTERACT ') = 'TRUE';
I got this error:
ORA-13226: interface not supported without a spatial index
ORA-06512: at "MDSYS.MD", line 1723
ORA-06512: at "MDSYS.MDERR", line 8
ORA-06512: at "MDSYS.SDO_3GL", line 94
In the past, I’ve always made queries on spatial index of views of multiple tables without problem.
I can make spatial query on both without issue but I can’t make a SDO_RELATE between them…
Why is this one any different?
Thanks a lot for your insight and help!
Edit:
I've found a quick workaround but it doesn't explain why.
If I swap the two first params in the SDO_RELATE function, the request works.
SELECT A.PT_ID, A.POINT_PP
FROM V_BATHY_SHC A, MNE_MASK B
WHERE B.MNE_ID = 1
AND SDO_RELATE(B.MASK, A.POINT_PP, 'mask=ANYINTERACT ') = 'TRUE';
In SDO_RELATE, the first parameter is a geometry column in a table, whereas the second is a single geometry. This said, I wonder why your original query works. There you have the view column as the first parameter, just like in the failing query.
I have a simple DataSet with 2 different coordinates by record.
(dem_latitude & dem_longitude are one coordinate, html_latitude & html_longitude are the other coordinate)
My main purpose is to see how big are the distances between each couple of coordinates.
As an clarification I don't want to see the distance as a number but represented in the map with the 2 coordinates (that form a couple) easily recognisable.
Solutions I can image but I don't know how to develop:
I can see for each coordinate which is its partner, maybe through a line.
Events like clicking in one coordinate makes the partner coordinate to be highlighted.
Any suggestion of how to implement any of this solutions or any other suggestion to achieve my "main purpose"?
If the solution is using the WYSIWYG CartoDB editor better :)
CartoDB UI and CartoDB WYSIWYG are very good and intuitive but when working with a single geometry per row. I'm not an expert, but I think in this case you'll need to use your developer super-powers and:
1 - alter the table schema and add a new column distance
2 - run a simple query to update that column value based on the points information:
UPDATE <table_name> SET distance = (SELECT ST_Distance(
ST_GeographyFromText(
'SRID=4326;POINT(' || dem_longitude || ' ' || dem_latitude || ')'
),
ST_GeographyFromText(
'SRID=4326;POINT(' || html_longitude || ' ' || html_latitude || ')'
)
)
);
Remember you can run queries using the API, so it's easy to integrate this query in any callback that adds data to the table to keep it updated.
Inspired by the #blat's answer, and after dealing with a lot of weird errors with SRIDs codes and the_geom_webmercator vs the_geom, I got this solution:
select
st_transform(
st_makeline(
st_setsrid(st_makepoint(html_longitude,html_latitude), 4326),
st_setsrid(st_makepoint(dem_longitude,dem_latitude), 4326)
),
3857
) as the_geom_webmercator
from the_data_set
If you also want to show the initial and the end point you have to create extra layers for each coordinate couple and then do something like:
select
cartodb_id,
st_transform(
st_setsrid(st_makepoint(dem_longitude,dem_latitude), 4326),
3857
) as the_geom_webmercator
from the_data_set
The result looks like this:
I'm becoming crazy with a calculated measure into OLAP Analytic Workspace Manager, that is defined like next OLAP Expression syntax:
NVL(CUBE.MEASURE1[DIM1= 'A'], 0) + NVL(CUBE.MEASURE2[DIM2= 'B'], 0)
Where:
CUBE.MEASURE1 and CUBE.MEASURE2 are not calculated measures, they are stored measures.
DIM1 and DIM2 are edges of the CUBE, A and B values both exist in their dimensions.
In most of all my queries, the calculated measure retrieves correct results, when both members of the sum retrieves data. But I other cases the calculated measure retrieves null !!!
In these cases, the calculated measure retrieves null when CUBE.MEASURE2[DIM2= 'B'] retrieves NO results. But I expect that if any of both QDR expresions retrieves no results, NVL function will replace it by 0.
I was reading about it, situations when QDR expressions retrieves no results, by default it throws and error and not null o NA value. I found that exist 2 ORACLE DML options that can manage this type of situations:
LIMITSTRICT = NO
(http://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_options043.htm#OLADM384)
OKNULLSTATUS = YES
(http://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_options077.htm#OLADM418)
I tried to create a DML Function in the AW to set both options, first to NO and second to YES, calling this function with OLAP_DML_EXPRESSION('MyFUNCTION', NUMBER) statement, but it doesn`t work
Please, I need a workaround of that, how I can catch these situations? Must I create a DML program to solve it? Where can I set this options (LIMITSTRICT,OKNULLSTATUS) by default and not set them in each measure calculation?