У меня много точек данных. На самом деле слишком много очков. Ни одна из точек не перекрывается, но некоторые из них находятся довольно близко друг к другу. Я хотел бы иметь меньше очков, но без перемещения каких-либо локаций.
Я хотел бы получить как можно больше точек, но только точки, которые находятся на расстоянии не менее ~ 5,7 км от любой другой точки. (если есть небольшое перекрытие, ничего страшного — допустима погрешность в 0,5 км)
Я попытался выполнить это с помощью написать алгоритм на R, но получил довольно много неожиданных результатов. У меня есть некоторые данные о 300 000 точках, покрывающих землю. У меня есть некоторые другие данные, которые составляют несколько миллионов. Когда я выполняю алгоритм, я могу сегментировать данные по странам, что может сократить эти числа до диапазона от 20 000 до 100 000. Если бы расположение точек не имело значения, я бы, вероятно, просто сделал интерполированный растр и назвал его хорошим, но для этой проблемы мне нужно сохранить конкретное местоположение нетронутым.
Еще одна вещь, которую я пробовал, — это создать обычную сетку с шагом 0,028 градуса и запустить NNJoin, чтобы найти ближайшую точку данных. Это работало немного лучше, чем мой код R, но результаты немного забавны, как вы, наверное, можете себе представить.
Еще одна идея, которая у меня была, заключалась в том, чтобы буферизовать точки, подсчитывая, сколько точек пересекается с буферизованным слоем. я все еще работаю над этим
Существует ли уже установленный метод получения этого результата? Мне удобно работать с PostGIS, QGIS, Python, R, если есть пакет или библиотека, которые могут это сделать.
Вкратце, как уменьшить плотные группы точек, но сохранить покрытие с уменьшенным набором точек?
интересно... как я могу использовать эту библиотеку без координаты Z?
Вот подход.
Пример данных
x <- runif (10000, -180, 180)
y <- runif (10000, -90, 90)
pts <- cbind(x, y)
Решение
library(raster)
# you will want a lower resolution than this
r <- raster(nrow=18, ncol=36, vals=1)
# get cell numbers
cells <- cellFromXY(r, pts)
# pick one point per cell
sel <- aggregate(pts, list(cells), function(i)i[1]) # or sample
Давайте посмотрим
plot(r)
points(pts, cex=.1)
points(sel[,2:3], pch=20, col = "red")
Обратите внимание, что здесь используется долгота/широта, поэтому расстояния в разных широтах неодинаковы. Не уверен, что это имеет значение; но если так, вы могли бы трансформироваться.
Позже:
Существует несколько способов создания смещенных вариаций путем изменения экстента или при создании RasterLayer. См. ?raster и ?extent для получения дополнительной информации. Вы также можете использовать shift
#add a row and a column
r1 <- raster(nrow=19, ncol=37, xmx=190, ymn=-100)
r2 <- shift(r1, -.5*xres(r1), -.5*yres(r1))
plot(as(r1, "SpatialPolygons"))
lines(as(r2, "SpatialPolygons"), col = "red")
ах да это очень быстро. есть ли способ сместить или сдвинуть край растра? Я думаю, что я буду запускать это несколько раз с различными смещениями или разрешениями, чтобы добиться идеального результата.
некоторые точки группируются у краев ячеек. если есть способ сдвинуть границы ячеек на одну половину разрешения вправо и на одну половину разрешения вниз, то это, вероятно, будет идеально
Пакет
lidR
имеет некоторую функцию для уменьшения плотности точек, напримерhomogenize()
, он будет поддерживать покрытие и подразумевать расстояние между точками, но вы не можете точно установить расстояние.