У меня есть таблица с точками. Я хотел бы создать многоугольник на основе этих точек, а затем вернуть только те точки, которые находятся по периметру (исключая точки, находящиеся внутри многоугольника). Есть ли простой способ сделать это на уровне базы данных с помощью SDO GEOMETRY? Я нахожу sth как GrahamScan, но я не могу найти что-либо подобное для Spatialмногоугольник на основе точек периметра - оракул пространственный
ответ
Я не могу придумать ни одного easy Ответьте на встроенные пакеты, поставляемые Oracle. Возможно, вам придется подумать о написании довольно ужасного кода, чтобы сделать это, если вы хотите решить проблему в Oracle.
сырное решение может быть разбить это на несколько шагов:
- Грубой силы всех возможных линий между каждым набором из двух точек (выберите декартовы произведение точек, построить их в линию):
- Найдите все линии, где нет пересечения с любой другой линией (внешний периметр) и получите значения точек.
- Соедините значения точек с исходной таблицей, чтобы получить любые данные (при необходимости).
Это, скорее всего, не будет работать или хорошо масштабироваться, но оно должно работать, если ваш набор данных не очень большой.
Вот быстрые иллюстрации (непроверенный SQL) ...
Входы:
SELECT sdo_geometry(2001, NULL, sdo_point_type(tbl.x, tbl.y, NULL), NULL, NULL)
FROM my_table tbl
декартово произведение координат преобразуется в строки:
WITH point_cartesian AS (
SELECT
tbl.x x1
, tbl.y y1
, tbl2.x x2
, tbl2.y y2
FROM my_table tbl
CROSS JOIN my_table tbl2
WHERE tbl.x != tbl2.x
OR tbl.y != tbl2.y
)
SELECT sdo_geometry(
2002
, NULL
, NULL
, sdo_elem_info_array(1, 2, 1)
, sdo_ordinate_array(x1, y1, x2, y2)
)
FROM point_cartesian
Определить нужные строки:
WITH point_cartesian AS (
SELECT
tbl.x x1
, tbl.y y1
, tbl2.x x2
, tbl2.y y2
FROM my_table tbl
CROSS JOIN my_table tbl2
WHERE tbl.x != tbl2.x
OR tbl.y != tbl2.y
)
, lines AS (
SELECT sdo_geometry(
2002
, NULL
, NULL
, sdo_elem_info_array(1, 2, 1)
, sdo_ordinate_array(x1, y1, x2, y2)
) geom
, ROWNUM line_id
FROM point_cartesian
)
SELECT *
FROM lines l1
WHERE NOT EXISTS (
SELECT 1
FROM lines l2
WHERE l2.line_id != l1.line_id
AND sdo_geom.sdo_intersect (l1.geom, l2.geom, 0.05) IS NOT NULL
)
Обратите внимание: SQL не тестировался, но, надеюсь, вы поняли идею.
Brillant ответ –
Если данные действительно так описаны в первом ответе, то самым простым и быстрым методом является получение выпуклого корпуса вокруг вашего набора точек. Предполагая, что ваш вклад таблицы my_table, который содержит две колонки, X и Y, которые представляют долготы и широты (отсюда SRID из 4326):
select sdo_aggr_convexhull (
sdoaggrtype (
sdo_geometry(2001, 4326, sdo_point_type(x, y, NULL), NULL, NULL),
0.5
)
)
from my_table;
В результате получается многоугольник строится с помощью точки периметра.
Как вы определяете периметр неупорядоченного множества точек в первую очередь? Вы ищете выпуклый корпус (google, если вы не знаете, что это такое) из набора точек? – Spacedman