Dies ist eine schwierige Frage, da für Linienmerkmale nur wenige, wenn überhaupt, räumliche Prozessstatistiken entwickelt wurden. Ohne sich ernsthaft mit Gleichungen und Code zu befassen, sind Punktprozessstatistiken nicht ohne weiteres auf lineare Features anwendbar und daher statistisch ungültig. Dies liegt daran, dass die Null, gegen die ein bestimmtes Muster getestet wird, auf Punktereignissen und nicht auf linearen Abhängigkeiten im Zufallsfeld basiert. Ich muss sagen, dass ich nicht einmal weiß, was die Null wäre, was Intensität und Anordnung / Ausrichtung noch schwieriger machen würde.
Ich spucke hier nur herum, aber ich frage mich, ob eine mehrskalige Bewertung der Liniendichte in Verbindung mit dem euklidischen Abstand (oder dem Hausdorff-Abstand, wenn die Linien komplex sind) kein kontinuierliches Maß für die Häufung bedeuten würde. Diese Daten könnten dann unter Verwendung von Varianz zur Berücksichtigung von Längenunterschieden zu den Linienvektoren zusammengefasst werden (Thomas 2011) und unter Verwendung einer Statistik wie K-means einem Clusterwert zugewiesen werden. Ich weiß, dass Sie nicht nach zugewiesenen Clustern sind, aber der Clusterwert kann Clusterungsgrade aufteilen. Dies würde natürlich eine optimale Anpassung von k erfordern, so dass keine willkürlichen Cluster zugewiesen werden. Ich denke, dass dies ein interessanter Ansatz für die Bewertung der Kantenstruktur in graphentheoretischen Modellen wäre.
Hier ist ein Beispiel in R, sorry, aber es ist schneller und reproduzierbarer als ein QGIS-Beispiel und liegt mehr in meiner Komfortzone :)
Fügen Sie Bibliotheken hinzu und verwenden Sie das Kupfer-PSP-Objekt von spatstat als Linienbeispiel
library(spatstat)
library(raster)
library(spatialEco)
data(copper)
l <- copper$Lines
l <- rotate.psp(l, pi/2)
Berechnen Sie die standardisierte Liniendichte 1. und 2. Ordnung und zwingen Sie sie dann zu Objekten der Rasterklasse
d1st <- density(l)
d1st <- d1st / max(d1st)
d1st <- raster(d1st)
d2nd <- density(l, sigma = 2)
d2nd <- d2nd / max(d2nd)
d2nd <- raster(d2nd)
Standardisieren Sie die Dichte 1. und 2. Ordnung zu einer skalierten Dichte
d <- d1st + d2nd
d <- d / cellStats(d, stat='max')
Berechnen Sie die standardisierte invertierte euklidische Distanz und errechnen Sie sie für die Rasterklasse
euclidean <- distmap(l)
euclidean <- euclidean / max(euclidean)
euclidean <- raster.invert(raster(euclidean))
Erzwingen Sie die Verwendung von spatstat psp in einem sp SpatialLinesDataFrame-Objekt, das in raster :: extract verwendet werden soll
as.SpatialLines.psp <- local({
ends2line <- function(x) Line(matrix(x, ncol=2, byrow=TRUE))
munch <- function(z) { Lines(ends2line(as.numeric(z[1:4])), ID=z[5]) }
convert <- function(x) {
ends <- as.data.frame(x)[,1:4]
ends[,5] <- row.names(ends)
y <- apply(ends, 1, munch)
SpatialLines(y)
}
convert
})
l <- as.SpatialLines.psp(l)
l <- SpatialLinesDataFrame(l, data.frame(ID=1:length(l)) )
Plot-Ergebnisse
par(mfrow=c(2,2))
plot(d1st, main="1st order line density")
plot(l, add=TRUE)
plot(d2nd, main="2nd order line density")
plot(l, add=TRUE)
plot(d, main="integrated line density")
plot(l, add=TRUE)
plot(euclidean, main="euclidean distance")
plot(l, add=TRUE)
Extrahieren Sie Rasterwerte und berechnen Sie zusammenfassende Statistiken für jede Zeile
l.dist <- extract(euclidean, l)
l.den <- extract(d, l)
l.stats <- data.frame(min.dist = unlist(lapply(l.dist, min)),
med.dist = unlist(lapply(l.dist, median)),
max.dist = unlist(lapply(l.dist, max)),
var.dist = unlist(lapply(l.dist, var)),
min.den = unlist(lapply(l.den, min)),
med.den = unlist(lapply(l.den, median)),
max.den = unlist(lapply(l.den, max)),
var.den = unlist(lapply(l.den, var)))
Verwenden Sie Cluster-Silhouette-Werte, um das optimale k (Anzahl der Cluster) mit der Funktion optimal.k zu ermitteln, und weisen Sie dann den Zeilen Cluster-Werte zu. Anschließend können wir jedem Cluster und Plot über dem Dichteraster Farben zuweisen.
clust <- optimal.k(scale(l.stats), nk = 10, plot = TRUE)
l@data <- data.frame(l@data, cluster = clust$clustering)
kcol <- ifelse(clust$clustering == 1, "red", "blue")
plot(d)
plot(l, col=kcol, add=TRUE)
An diesem Punkt könnte man eine Randomisierung der Linien durchführen, um zu testen, ob die resultierende Intensität und Entfernung vom Zufall signifikant sind. Sie können die Funktion "rshift.psp" verwenden, um Ihre Zeilen nach dem Zufallsprinzip neu auszurichten. Sie können auch einfach die Start- und Stoppunkte zufällig sortieren und jede Linie neu erstellen.
Man fragt sich auch, "was wäre, wenn" Sie gerade eine Punktmusteranalyse mit einer univariaten oder Kreuzanalyse-Statistik für die Start- und Stoppunkte durchgeführt haben, die nicht mit den Linien übereinstimmen. In einer univariaten Analyse würden Sie die Ergebnisse der Start- und Stoppunkte vergleichen, um festzustellen, ob die Clusterbildung zwischen den beiden Punktmustern konsistent ist. Dies könnte über einen F-Hut, einen G-Hut oder einen Ripley's-K-Hut erfolgen (für nicht markierte Punktprozesse). Ein anderer Ansatz wäre eine Kreuzanalyse (z. B. Kreuz-K), bei der die Zweipunktprozesse gleichzeitig getestet werden, indem sie als [Start, Stopp] markiert werden. Dies würde die Entfernungsbeziehungen im Clustering-Prozess zwischen Start- und Stoppunkt angeben. Jedoch, Die räumliche Abhängigkeit (Nonstaionarity) von einem zugrunde liegenden Intensitätsprozess kann bei diesen Modelltypen ein Problem darstellen, das sie inhomogen macht und ein anderes Modell erfordert. Ironischerweise wird ein inhomogener Prozess mit einer Intensitätsfunktion modelliert, die uns den vollen Kreis zurück zur Dichte bringt und die Idee unterstützt, eine maßstabsintegrierte Dichte als Maß für die Clusterbildung zu verwenden.
Hier ist ein kurzes Beispiel dafür, ob die Ripleys K (Besags L) -Statistik für die Autokorrelation eines nicht markierten Punktprozesses die Start- und Stopppositionen einer Linien-Feature-Class verwendet. Das letzte Modell ist ein Cross-K, bei dem sowohl Start- als auch Stopp-Positionen als nominal markierter Prozess verwendet werden.
library(spatstat)
data(copper)
l <- copper$Lines
l <- rotate.psp(l, pi/2)
Lr <- function (...) {
K <- Kest(...)
nama <- colnames(K)
K <- K[, !(nama %in% c("rip", "ls"))]
L <- eval.fv(sqrt(K/pi)-bw)
L <- rebadge.fv(L, substitute(L(r), NULL), "L")
return(L)
}
### Ripley's K ( Besag L(r) ) for start locations
start <- endpoints.psp(l, which="first")
marks(start) <- factor("start")
W <- start$window
area <- area.owin(W)
lambda <- start$n / area
ripley <- min(diff(W$xrange), diff(W$yrange))/4
rlarge <- sqrt(1000/(pi * lambda))
rmax <- min(rlarge, ripley)
( Lenv <- plot( envelope(start, fun="Lr", r=seq(0, rmax, by=1), nsim=199, nrank=5) ) )
### Ripley's K ( Besag L(r) ) for end locations
stop <- endpoints.psp(l, which="second")
marks(stop) <- factor("stop")
W <- stop$window
area <- area.owin(W)
lambda <- stop$n / area
ripley <- min(diff(W$xrange), diff(W$yrange))/4
rlarge <- sqrt(1000/(pi * lambda))
rmax <- min(rlarge, ripley)
( Lenv <- plot( envelope(start, fun="Lr", r=seq(0, rmax, by=1), nsim=199, nrank=5) ) )
### Ripley's Cross-K ( Besag L(r) ) for start/stop
sdata.ppp <- superimpose(start, stop)
( Lenv <- plot(envelope(sdata.ppp, fun="Kcross", r=bw, i="start", j="stop", nsim=199,nrank=5,
transform=expression(sqrt(./pi)-bw), global=TRUE) ) )
Verweise
Thomas JCR (2011) Ein neuer Clustering-Algorithmus basierend auf K-Mitteln unter Verwendung eines Liniensegments als Prototyp. In: San Martin C., Kim SW. (Hrsg.) Fortschritte bei der Mustererkennung, Bildanalyse, Computer Vision und Anwendungen. CIARP 2011. Lecture Notes in Computer Science, Bd. 7042. Springer, Berlin, Heidelberg