การสร้างคะแนนสุ่มจำนวนมากในไบนารีแรสเตอร์?


9

ฉันต้องการสร้างชุดข้อมูลเวกเตอร์แบบจุด 10,000 จุด (หรือใหญ่กว่า) ภายในไบนารีแรสเตอร์ซึ่งจุดควรถูก จำกัด พื้นที่ที่ค่าแรสเตอร์เป็น 1

ฉันลองทำตามขั้นตอนต่อไปนี้

  1. รูปหลายเหลี่ยมแรสเตอร์
  2. QGIS: Vector -> เครื่องมือวิจัย -> คะแนนสุ่ม

วิธีนี้ใช้งานได้ดีมากถึง 2,000 คะแนน แต่สิ่งที่เหนือกว่าเพียงแค่ทำให้ QGIS ผิดพลาด

มีวิธีในการสร้างชุดข้อมูลเวกเตอร์ที่มีคุณสมบัติจุดจำนวนมากที่ จำกัด โดยไบนารีแรสเตอร์ (หรือรุ่นที่มีรูปหลายเหลี่ยมของมัน) หรือไม่?

เครื่องมือต่อไปนี้อยู่ในการกำจัดของฉันจัดอันดับจากที่นิยมมากไปน้อย: QGIS, Python, R, ArcGIS

นี่คือสิ่งที่ฉันจะทำเพียง 10 เท่าที่มีคุณสมบัติจุด

1k คะแนนสุ่ม


โดยทั่วไปแล้วแรสเตอร์ของคุณใหญ่แค่ไหน?
Spacedman

หนึ่งในตัวอย่างข้างต้นคือ 19200 x 9600 แรสเตอร์ทั่วไปมีประมาณ 10,000 x 10,000 พิกเซล
Kersten

โอเคยิ่ง RAM ของเครื่องคุณดีขึ้นเท่าไร ฉันไม่กล้าทดสอบแรสเตอร์ 10,000x10,000 บนพีซีตัวเล็ก ๆ ของฉันที่นี่ถึงแม้ว่าคุณจะสามารถแบ่งแรสเตอร์ตัวอย่างในส่วนต่างๆและเข้าร่วม ...
Spacedman

ทำไมรูปหลายเหลี่ยมแรสเตอร์? คุณคิดว่าคำตอบนี้มีประโยชน์สำหรับคุณหรือไม่ gis.stackexchange.com/questions/22601/…
Luigi Pirelli

เพราะฉันสามารถใช้ฟังก์ชัน "คะแนนสุ่มในรูปหลายเหลี่ยม" ในขณะที่ QGIS ไม่มีฟังก์ชัน "คะแนนสุ่มภายในค่าเฉพาะของ Raster"
Kersten

คำตอบ:


7

นี่คือวิธีใน R:

ทำการทดสอบแรสเตอร์เซลล์ 20x30 สร้าง 1/10 ของเซลล์ที่ตั้งค่าเป็น 1 พล็อต:

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

สำหรับแรสเตอร์ที่มีอยู่ในไฟล์เช่น geoTIFF คุณสามารถทำได้:

> m = raster("mydata.tif")

ทีนี้รับเมทริกซ์ของพิกัด xy ของ 1 เซลล์พล็อตจุดเหล่านั้นและเราเห็นว่าเรามีศูนย์เซลล์:

> 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])

ขั้นตอนที่ 1 สร้างคู่ 1,000 (xo, yo) ที่อยู่ตรงกลางบน 0 ในกล่องขนาดของเซลล์เดียว หมายเหตุการใช้resเพื่อให้ได้ขนาดเซลล์:

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

ขั้นตอนที่ 2 กำหนดว่าเซลล์ใดที่จุดใดจุดหนึ่งข้างต้นนั้นสุ่มโดยสุ่มค่า 1,000 ค่าจาก 1 ถึงจำนวน 1 เซลล์:

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

ในที่สุดก็คำนวณพิกัดด้วยการเพิ่มศูนย์เซลล์เพื่อชดเชย ลงจุดตรวจสอบ:

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

นี่คือ 10,000 คะแนน (แทนที่ 1,000 ข้างต้นด้วย 10,000), พล็อตด้วยpch=".":

คะแนนในคน

สวยมากทันทีสำหรับ10,000คะแนนในแรสเตอร์200x300โดยมีครึ่งหนึ่งของคะแนน จะเพิ่มขึ้นในเวลาเชิงเส้นกับจำนวนคนในแรสเตอร์ฉันคิดว่า

หากต้องการบันทึกเป็นรูปร่างไฟล์ให้แปลงเป็นSpatialPointsวัตถุให้การอ้างอิงระบบพิกัดที่ถูกต้อง (เช่นเดียวกับแรสเตอร์ของคุณ) และบันทึก:

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

ที่จะสร้าง shapefile ที่มีหมายเลขเซลล์และออฟเซ็ตเป็นแอตทริบิวต์


สิ่งนี้ดูมีแนวโน้มมาก My R ได้รับสนิมเล็กน้อย: ฉันจะส่งออกคะแนนไปเป็นรูปแบบเวกเตอร์ได้อย่างไร (Shapefile, geojson, gml, ... อะไรก็ตาม) - ฉันต้องบันทึกตำแหน่งของจุดตัวอย่างเพื่อใช้ในภายหลัง
Kersten

การแก้ไขแสดงวิธีการอ่านแรสเตอร์และแปลง pts เป็น shapefile ...
Spacedman

3

เมื่อใดก็ตามที่ผมทำงานกับชุดข้อมูลขนาดใหญ่ผมชอบที่จะเรียกใช้เครื่องมือ / คำสั่งนอกของ QGIS เช่นจากสคริปต์แบบสแตนด์อโลนหรือจากOSGeo4W เชลล์ ไม่มากเพราะ QGIS ล่ม (แม้ว่าจะมีข้อความว่า "ไม่ตอบสนอง" แต่ก็อาจยังคงประมวลผลข้อมูลที่คุณสามารถตรวจสอบได้จากตัวจัดการงาน ) แต่เนื่องจากทรัพยากร CPU เช่น RAM มีให้ใช้ในการประมวลผลข้อมูลมากขึ้น QGIS ใช้หน่วยความจำที่พอเหมาะในการรัน

อย่างไรก็ตามหากต้องการเรียกใช้เครื่องมือภายนอก QGIS ( คุณต้องติดตั้ง QGIS ผ่านทางตัวติดตั้ง OSGeo4W ) ให้ทำตาม2 ขั้นตอนแรกตามที่อธิบายโดย @ gcarrillo ในบทความนี้: ปัญหาการนำเข้า qgis.core เมื่อเขียนสคริปต์ PyQGIS แบบสแตนด์อะโลน (ฉันแนะนำให้ดาวน์โหลดและใช้ไฟล์. bat ของเขา)

เมื่อตั้งค่า PATHS แล้วให้พิมพ์pythonลงในบรรทัดคำสั่ง เพื่อความสะดวกให้คัดลอกรหัสต่อไปนี้ลงในตัวแก้ไขข้อความเช่น Notepad แก้ไขพารามิเตอร์เช่นชื่อพา ธ ของรูปร่างไฟล์ของคุณเป็นต้นจากนั้นวางสิ่งทั้งหมดลงในบรรทัดคำสั่งโดยคลิกขวา> วาง :

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)

เมื่อใช้สคริปต์ฉันใช้เครื่องมือสุ่มคะแนนในเลเยอร์ขอบเขตสำหรับไฟล์รูปร่างที่ค่อนข้างใหญ่และใช้เวลาไม่เกิน 20 วินาทีในการสร้างคะแนน 10k ทำงานภายใน QGIS ใช้เวลาเกือบ 2 นาทีอย่างน้อยที่สุดสำหรับฉันมันมีความแตกต่างที่สำคัญ


1
ทางเลือกที่ยอดเยี่ยม +1 เพิ่งทดสอบสิ่งนี้กับแอปพลิเคชันของฉันและในขณะที่ช้ากว่าวิธี R เล็กน้อยมันสร้างผลลัพธ์ที่ต้องการ
Kersten

@Kersten - ยอดเยี่ยมดีใจที่มันได้ผล :)
โจเซฟ

1

นอกจากนี้คุณยังสามารถใช้ GRASS GIS โดยตรงสำหรับงานนี้ - การสุ่มแบบแบ่งชั้น: การสุ่มแบบสุ่มจากแผนที่เวกเตอร์ที่มีข้อ จำกัด เชิงพื้นที่ :

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

นอกจากนี้การสุ่มตัวอย่างจากแผนที่เวกเตอร์โดยคุณลักษณะและวิธีการอื่น ๆ จะถูกนำมาใช้ในคำสั่ง

หมายเหตุ: เวอร์ชัน v.random ที่แสดงใน QGIS ผ่านการประมวลผลไม่ได้สะท้อนการทำงานเต็มรูปแบบ แต่เป็นเพียงมุมมองที่เรียบง่าย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.