Creare una grande quantità di punti casuali nel raster binario?


9

Voglio creare un set di dati vettoriali di punti di 10000 punti (o superiore) all'interno di un raster binario, in cui i punti dovrebbero essere vincolati ad aree in cui il valore raster è 1.

Ho provato i seguenti passaggi.

  1. Poligono raster
  2. QGIS: Vector -> Strumenti di ricerca -> Punti casuali

Funziona bene fino a 2000 punti, ma qualsiasi cosa sopra causa solo l'arresto anomalo di QGIS.

Esiste un modo per creare un set di dati vettoriali con un gran numero di funzioni punto vincolate da un raster binario (o dalla sua versione poligonale)?

Sono a mia disposizione i seguenti strumenti, classificati dal più favorevole al meno favorevole: QGIS, Python, R, ArcGIS

Questo è quello che sto cercando, solo con 10 volte le caratteristiche del punto.

1k punti casuali


Quanto è grande il tuo raster, in genere?
Spacedman

Quello nell'esempio sopra è 19200 x 9600. Il raster tipico è di circa 10000 x 10000 pixel.
Kersten,

Bene, più RAM ha la tua macchina, meglio è. Non oso testare su un raster 10.000x10.000 sul mio piccolo PC qui, anche se potresti sempre dividere il raster, campionare in parti e unirmi ...
Spacedman

perché poligonizzare il raster? ti dispiace che questa risposta ti sia utile? gis.stackexchange.com/questions/22601/…
Luigi Pirelli,

Perché allora posso usare la funzione "Punti casuali nel poligono", mentre QGIS non ha una funzione "Punti casuali all'interno di valori specifici di un raster".
Kersten,

Risposte:


7

Ecco un modo in R:

Crea un test raster, 20x30 celle, crea 1/10 delle celle impostate su 1, traccia:

> require(raster)
> m = raster(nrow=20, ncol=30)
> m[] = as.numeric(runif(20*30)>.9)
> plot(m)

Per un raster esistente in un file, ad esempio un geoTIFF, puoi semplicemente fare:

> m = raster("mydata.tif")

Ora prendi una matrice delle coordinate xy delle 1 celle, traccia questi punti e vediamo che abbiamo centri cellulari:

> ones = xyFromCell(m,1:prod(dim(m)))[getValues(m)==1,]
> head(ones)
       x    y
[1,] -42 85.5
[2,] 102 85.5
[3,] 162 85.5
[4,]  42 76.5
[5,] -54 67.5
[6,]  30 67.5
> points(ones[,1],ones[,2])

Passaggio 1. Generare 1000 coppie (xo, yo) centrate su 0 in una casella delle dimensioni di una singola cella. Nota l'uso di resper ottenere le dimensioni della cella:

> pts = data.frame(xo=runif(1000,-.5,.5)*res(m)[1], yo=runif(1000,-.5,.5)*res(m)[2])

Passaggio 2. Calcola in quale cella si trova ciascuno dei punti precedenti campionando casualmente 1000 valori da 1 al numero di 1 celle:

> pts$cell = sample(nrow(ones), 1000, replace=TRUE)

Infine calcola le coordinate aggiungendo il centro della cella all'offset. Trama per controllare:

> pts$x = ones[pts$cell,1]+pts$xo
> pts$y = ones[pts$cell,2]+pts$yo
> plot(m)
> points(pts$x, pts$y)

Ecco 10.000 punti (sostituisci i 1000 sopra con 10000), tracciati con pch=".":

punti in uno

Praticamente istantaneo per 10.000 punti su un raster 200x300 con metà dei punti come quelli. Aumenterò nel tempo in modo lineare con quanti nel raster, penso.

Per salvare come file di forma, converti in un SpatialPointsoggetto, dagli il giusto riferimento al sistema di coordinate (lo stesso del tuo raster) e salva:

> coordinates(pts)=~x+y
> proj4string(pts)=CRS("+init=epsg:4326") # WGS84 lat-long here
> shapefile(pts,"/tmp/pts.shp")

Ciò creerà un file di forma che include il numero di cella e gli offset come attributi.


Questo sembra molto promettente. La mia R è diventata un po 'arrugginita: come sarei in grado di esportare i punti in un formato vettoriale (Shapefile, geojson, gml, ... qualunque cosa realmente) - Devo salvare le posizioni dei punti campione per un uso successivo.
Kersten,

Le modifiche mostrano come leggere un raster e convertire i pts in shapefile ...
Spacedman

3

Ogni volta che lavoro con set di dati di grandi dimensioni, mi piace eseguire strumenti / comandi all'esterno di QGIS, ad esempio da uno script autonomo o da OSGeo4W Shell . Non tanto perché QGIS si arresta in modo anomalo (anche se dice "Non risponde", probabilmente sta ancora elaborando i dati che è possibile controllare dal Task Manager ), ma perché sono disponibili più risorse CPU come la RAM per elaborare i dati. QGIS stesso consuma una buona parte della memoria per l'esecuzione.

Ad ogni modo, per eseguire uno strumento al di fuori di QGIS ( è necessario aver installato QGIS tramite il programma di installazione OSGeo4W ), seguire i primi 2 passaggi descritti da @gcarrillo in questo post: Problema con import qgis.core durante la scrittura di uno script PyQGIS autonomo (Suggerisco di scaricare e utilizzare il suo file .bat).

Una volta impostati i PERCORSI, digitare pythonnella riga di comando. Per comodità, copia il seguente codice in un editor di testo come Blocco note, modifica i parametri come il nome del tuo file di forma, ecc., Quindi incolla tutto nella riga di comando facendo clic con il pulsante destro del mouse> Incolla :

import os, sys
from qgis.core import *
from qgis.gui import *
from PyQt4.QtGui import *

from os.path import expanduser
home = expanduser("~")

QgsApplication( [], False, home + "/AppData/Local/Temp" )

QgsApplication.setPrefixPath("C://OSGeo4W64//apps//qgis", True)
QgsApplication.initQgis()
app = QApplication([])

sys.path.append(home + '/.qgis2/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *

shape = home + "/Desktop/Polygon.shp"
result = home + "/Desktop/Point.shp"
general.runalg("qgis:randompointsinlayerbounds", shape, 10000, 0, result)

Usando lo script, ho eseguito lo strumento Punti casuali nei limiti del livello per un file di forma abbastanza grande e ci sono voluti meno di 20 secondi per generare 10k punti. La sua esecuzione all'interno di QGIS ha richiesto quasi 2 minuti, quindi almeno per me, c'è una differenza significativa.


1
Ottima alternativa, +1. Ho appena provato questo per la mia applicazione e mentre è un po 'più lento dell'approccio R, crea i risultati desiderati.
Kersten,

@Kersten - Fantastico, felice che funzioni :)
Joseph,

1

È inoltre possibile utilizzare GRASS GIS direttamente per questo lavoro - Campionamento casuale stratificato: Campionamento casuale dalla mappa vettoriale con vincoli spaziali :

https://grass.osgeo.org/grass72/manuals/v.random.html#stratified-random-sampling:-random-sampling-from-vector-map-with-spatial-constraints

Inoltre, nel comando sono implementati campionamenti casuali dalla mappa vettoriale per attributo e alcuni altri metodi.

Nota: la versione v.random esposta in QGIS attraverso l'elaborazione non riflette la piena funzionalità ma solo una vista semplificata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.