#oracle #oracle11g #geospatial
Вопрос:
Я пытаюсь найти все точки, которые покрыты полигоном на сервере oracle11g. Inside и contains возвращают логические значения, но covers и covered всегда являются ложными. Я неправильно это понимаю? Разве обложки не должны быть истинными, если «содержит» истинно, когда точка находится в середине прямоугольника многоугольника?
Создать таблицу
CREATE TABLE geo
(
name varchar(255),
geo MDSYS.SDO_GEOMETRY NOT NULL
);
Настройка метаданных
insert into user_sdo_geom_metadata(table_name, column_name, diminfo, srid)
VALUES (
'GEO',
'GEO',
SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('LONGITUDE',-180, 180, 0.25),
MDSYS.SDO_DIM_ELEMENT('LATITUDE',-90, 90, 0.25)),
4326);
Создание пространственного индекса
CREATE INDEX blabla ON geo (geo) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
Сделайте прямоугольник между 0/0 и 2/2
INSERT INTO geo (name, geo)
VALUES ('SimplePolygon',
sdo_geometry(2003, 4326, null,
sdo_elem_info_array(1, 1003, 1),
sdo_ordinate_array(0, 0,
2, 0,
2, 2,
0, 2,
0, 0)));
Поставьте точку на 1/1
INSERT INTO geo(name, geo)
VALUES ('SimplePoint',
sdo_geometry(2001, 4326, null,
sdo_elem_info_array(1, 1, 1),
sdo_ordinate_array(1, 1)));
Сопоставьте все данные со всеми данными и посмотрите, какая маска возвращает значение true/false.
select
g1.name,
g2.name,
sdo_relate(g1.geo, g2.geo, 'mask=COVEREDBY') as COVEREDBY,
sdo_relate(g1.geo, g2.geo, 'mask=COVERS') as COVERS,
sdo_relate(g1.geo, g2.geo, 'mask=COVERS INSIDE') as COVERSINSIDE,
sdo_relate(g1.geo, g2.geo, 'mask=INSIDE') as INSIDE,
sdo_relate(g1.geo, g2.geo, 'mask=CONTAINS') as CONTAINS,
sdo_relate(g1.geo, g2.geo, 'mask=ANYINTERACT') as ANYINTERACT,
-- turn around geometry
sdo_relate(g2.geo, g1.geo, 'mask=COVEREDBY') as COVEREDBY2,
sdo_relate(g2.geo, g1.geo, 'mask=COVERS') as COVERS2,
sdo_relate(g2.geo, g1.geo, 'mask=INSIDE') as INSIDE2,
sdo_relate(g2.geo, g1.geo, 'mask=CONTAINS') as CONTAINS2,
sdo_relate(g2.geo, g1.geo, 'mask=ANYINTERACT') as ANYINTERACT2
from geo g1, geo g2
Ответ №1:
Из документации по пространственным отношениям и фильтрации:
COVERS
: Граница и внутренняя часть одного объекта полностью содержатся во внутренней части или границе другого объекта, их внутренние части пересекаются, а граница или внутренняя часть одного объекта и граница другого объекта пересекаются.COVEREDBY
: ПротивоположностьCOVERS
.A COVEREDBY B
подразумеваетB COVERS A
.
Причина, по которой связь является ложной, заключается в конечном условии, что «и граница или внутренняя часть одного объекта и граница другого объекта пересекаются». Поскольку ваша точка и прямоугольник не имеют границ, которые пересекаются, то они COVER
ни COVEREDBY
то, ни другое.
Комментарии:
1. Я ставлю точку на границе многоугольника, но covers не возвращает TRUE. Если я сделаю это с другим полигоном, который частично находится на линии большего многоугольника, то COVERS вернет значение TRUE для двух полигонов. Может ли быть так, что точки несовместимы с ОБЛОЖКАМИ.