Две ближайшие точки на границе геометрии Postgis
У меня есть таблица geofences
, в которой хранится geometry
многоугольника.
У меня также есть точка A
, которая находится внутри геометрии. Я должен найти две ближайшие точки из точки A
, которые лежат на поверхности геометрии многоугольника.
Функция в PostGIS:
CREATE OR REPLACE FUNCTION accuracyCheck(Polygon geometry
,decimal lat
,decimal lon)
RETURNS VARCHAR AS
$BODY$
DECLARE height DECIMAL;
DECLARE accuracy VARCHAR(250);
BEGIN
CREATE TEMPORARY TABLE closePointStorage AS
SELECT ST_AsText(ST_ClosestPoint(geometry
,ST_GeomFromText('POINT(lat lon)',0)
)
) AS closestPoint
FROM (
SELECT ST_GeomFromText(geometry) as geometry
FROM gfe_geofences
WHERE is_active=true
) As tempName;
CREATE TEMPORARY TABLE areaStorage ON COMMIT DROP AS
SELECT ST_Area(ST_GeomFromText('Polygon((23.0808622876029 96.1304006624291
,28.0808622876029 99.1304006624291
,100 200
,23.0808622876029 96.1304006624291
))'
,0)
) AS area;
CREATE TEMPORARY TABLE distanceStorage ON COMMIT DROP AS
SELECT ST_Distance(
ST_GeomFromText('POINT(23.0808622876029 96.1304006624291)',-1)
,ST_GeomFromText('POINT(28.0808622876029 99.1304006624291)',-1)
) AS distance;
height = (SELECT area FROM areaStorage)
/(0.5*(SELECT distance FROM distanceStorage));
IF height < (SELECT radius_meters
FROM gfe_geofences Where is_active=true) THEN
accuracy = "FullConfirm";
RETURN accuracy;
ELSE
accuracy = "PartiallyConfirm";
RETURN accuracy;
END IF;
END;
$BODY$ LANGUAGE plpgsql;
Я просто хочу найти две точки на границе геометрии многоугольника. Так же, как я нашел один из запроса:
CREATE TEMPORARY TABLE closePointStorage AS
SELECT ST_AsText(ST_ClosestPoint(geometry
,ST_GeomFromText('POINT(lat lon)',0)
)
) AS closestPoint
FROM (
SELECT ST_GeomFromText(geometry) as geometry
FROM gfe_geofences
WHERE is_active=true
)
AS tempName;
Другое, тогда я должен найти еще один с расстоянием, большим, чем точка, найденная выше, но меньшая, чем остальные точки.
Ответы
Ответ 1
Я предполагаю, что вы хотите найти край многоугольника, который проходит ближе всего к рассматриваемой точке
![distance from line problem]()
Чтобы получить расстояние "d" точки "C" от линии [A, B]
Сначала переведите все точки, так что A находится в 0,0
B -= A //vector subtraction
C -= A
Затем нормируйте B так, чтобы он имел длину 1.0
len = sqrt( B . B) //dotproduct of two vectors is the length squared
B /= len //scalar divide by length
Найдите длину от A, которая находится под прямым углом к C
dotp = B . C //dot product again
closestPointOnLine = B * dotp //scalar multiply
Теперь получите расстояние
diff = (C - ClosestPointOnLine)
d = sqrt(diff . diff)
Не знаю, как это сделать в SQL. Вам нужно будет сделать выше для каждого края на вашем полигоне, а затем найти наименьшее значение "d"
Кстати, знак перекрестного произведения B и C теперь скажет вам, находится ли точка внутри полигона или нет
Ответ 2
Используйте ST_DumpPoints(), чтобы сбросить точки многоугольника, затем выберите из этого порядка значение ST_Distance для A limit 2.?
Так что это что-то вроде
SELECT * from ST_DumpPoints(poly) order by ST_Distance(A,geom) asc limit 2;
(предполагается, что это внутренний выбор, где poly - многоугольник, A - это точка для сравнения, а geom - столбец geom одной из точек сопоставления поли)
Ответ 3
Как правило, на граничном полигоне нет второй ближайшей точки, если вы включаете строки. Точно так же, как нет реального числа, второго ближе всего к нулю.
Или вы только хотите рассмотреть точки в углах, как предлагает Маркус.
Или у вас есть только одна ближайшая точка.
Ответ 4
1) Вид идеи с левым полем, но чтобы найти вторую ближайшую точку к месту назначения, почему бы не найти ближайшую точку к точке, которую вы уже нашли?
2) Или, еще больше германии по вашему конкретному вопросу,
- найти набор точек в пределах некоторого разумного диапазона точки,
- найдите пересечение этого множества с множеством точек, лежащих на границе многоугольника (что, как я предполагаю, может быть другой функцией PostGIS, не использовали postG через некоторое время, поэтому я не уверен)
3) Дальше в левое поле выгрузите часть вашего набора данных в Mongo и используйте функцию $near... http://docs.mongodb.org/manual/reference/operator/near/ p >