Uzamsal nesneyi sınırlayıcı kutuya klipsleyin


14

R'deki bir Uzamsal nesne verildiğinde, tüm öğelerini sınırlayıcı bir kutu içinde uzanacak şekilde nasıl kırpırım?

Yapmak istediğim iki şey var (ideal olarak her ikisini de nasıl yapacağımı biliyordum, ama ya mevcut sorunum için kabul edilebilir bir çözüm - çokgen bir şekil dosyasını kıta ABD'siyle kısıtlıyor).

  1. Her elemanı sınırlayıcı kutuya tam olarak bırakmayın. Bu bbox()<-mantıklı bir yol gibi görünüyor , ancak böyle bir yöntem mevcut değil.

  2. Sınırsız sayıda sonsuz olmayan elemanların (örn. Çokgenler, çizgiler) kesileceği gerçek bir klip işlemi yapın . sp::bboxBen ettik tek yolu kullanmak olacaktır ile gelip bu nedenle, bir atama yöntemi yoksun overveya gContains/ gCrossesbir SpatialPolygons yeni sınırlayıcı kutunun koordinatlarla bir kutu içeren nesnesi ile birlikte. Daha sonra bir çokgen nesnesini kırparken, hangisinin çapraz ile karşılaştırıldığını bulmanız ve bu çokgenlerin koordinatlarını kutuyu aşmayacak şekilde değiştirmeniz gerekir. Ya da benzeri bir şey gIntersection. Ama elbette daha basit bir yol var mı?

Sınırlayıcı kutularla ilgili birçok sorun olduğunu ve ilgili bölgeyi tanımlayan bir çokgene uzamsal bir bindirmenin tipik olarak tercih edilebilir olduğunu bilsem de, çoğu durumda sınırlayıcı kutular iyi çalışır ve daha basittir.


Açıkça söylemek gerekirse, Uzamsal nesneniz genişletilmişse (Çokgenler veya Çizgiler), onu yalnızca sizin verilen boyutunuzdaki yığınını döndürecek şekilde kesmek mi istiyorsunuz? Daha basit bir yol olduğunu sanmıyorum.
Spacedman

@ Spacedman Her ikisiyle de ilgilendiğimi açıkladım, ancak daha basit sürüm mevcut soru için yeterli olacaktır.
Ari B. Friedman

Rgeos kullanarak (2) çözümünü zaten uyguladınız mı? En azından denemişsin gibi geliyor. Bize bu çözümü ve bir örneği verebilir misiniz, yani en azından 'basitlik' için karşılaştırılacak bir şeyimiz var mı? Çünkü dürüst olmak gerekirse, bu oldukça basit görünüyor.
Spacedman

@ Spacedman Her şey basit; sadece zaman alır .... :-) Ben denedim gIntersectionve Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") : TopologyException: no outgoing dirEdge found at 3 2.5 bugün hata ayıklamak için zaman yok geldi ; özensiz bir sürüm yazdı ve gelecekte düzelecek.
Ari B. Friedman

Yanıtlar:


11

Ben bu amaç için küçük bir işlev oluşturdum ve iyi değerlendirmeleri ile başkaları tarafından kullanılmıştır!

gClip <- function(shp, bb){
  if(class(bb) == "matrix") b_poly <- as(extent(as.vector(t(bb))), "SpatialPolygons")
  else b_poly <- as(extent(bb), "SpatialPolygons")
  gIntersection(shp, b_poly, byid = TRUE)
}

Bu probleminizi çözmeli. Daha fazla açıklama burada: http://robinlovelace.net/r/2014/07/29/clipping-with-r.html

Oluşturulan kukla çokgenin b_polyhiçbir proj4 dizesi yoktur, bu da " Uyarı: spgeom1 ve spgeom2'nin farklı proj4 dizeleri vardır " ile sonuçlanır , ancak bu zararsızdır.


Ben var sp, maptools, rgdalve rgeosyüklendi. Belki Error in .class1(object) : could not find function "extent"R / paket sürümü sorunu alıyorum ?
gregmacfarlane

library(raster)Öğreticimdeki satırı not edin : robinlovelace.net/r/2014/07/29/clipping-with-r.html bize nasıl ulaştığınızı bildirin! Şerefe.
RobinLovelace

Bu benim için bir uyarı mesajı oluşturur: spgeom1 ve spgeom2'nin farklı proj4 dizeleri vardır. Proj4string (b_poly) <- proj4string (shp) eklemek bunu çözmeli mi?
Matifou

7

İşte özensiz bir sınır sürümü (yarın mini son tarih için zamanında ihtiyacımı karşılamak için yeterli :-)):

#' Convert a bounding box to a SpatialPolygons object
#' Bounding box is first created (in lat/lon) then projected if specified
#' @param bbox Bounding box: a 2x2 numerical matrix of lat/lon coordinates
#' @param proj4stringFrom Projection string for the current bbox coordinates (defaults to lat/lon, WGS84)
#' @param proj4stringTo Projection string, or NULL to not project
#' @seealso \code{\link{clipToExtent}} which uses the output of this to clip to a bounding box
#' @return A SpatialPolygons object of the bounding box
#' @example 
#' bb <- matrix(c(3,2,5,4),nrow=2)
#' rownames(bb) <- c("lon","lat")
#' colnames(bb) <- c('min','max')
as.SpatialPolygons.bbox <- function( bbox, proj4stringFrom=CRS("+proj=longlat +datum=WGS84"), proj4stringTo=NULL ) {
  # Create unprojected bbox as spatial object
  bboxMat <- rbind( c(bbox['lon','min'],bbox['lat','min']), c(bbox['lon','min'],bbox['lat','max']), c(bbox['lon','max'],bbox['lat','max']), c(bbox['lon','max'],bbox['lat','min']), c(bbox['lon','min'],bbox['lat','min']) ) # clockwise, 5 points to close it
  bboxSP <- SpatialPolygons( list(Polygons(list(Polygon(bboxMat)),"bbox")), proj4string=proj4stringFrom  )
  if(!is.null(proj4stringTo)) {
    bboxSP <- spTransform( bboxSP, proj4stringTo )
  }
  bboxSP
}


#' Restrict to extent of a polygon
#' Currently does the sloppy thing and returns any object that has any area inside the extent polygon
#' @param sp Spatial object
#' @param extent a SpatialPolygons object - any part of sp not within a polygon will be discarded
#' @seealso \code{\link{as.SpatialPolygons.bbox}} to create a SP from a bbox
#' @return A spatial object of the same type
#' @example
#' set.seed(1)
#' P4S.latlon <- CRS("+proj=longlat +datum=WGS84")
#' ply <- SpatialPolygons(list(Polygons(list(Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))), "s1"),Polygons(list(Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))), "s2")), proj4string=P4S.latlon)
#' pnt <- SpatialPoints( matrix(rnorm(100),ncol=2)+2, proj4string=P4S.latlon )
#' # Make bounding box as Spatial Polygon
#' bb <- matrix(c(3,2,5,4),nrow=2)
#' rownames(bb) <- c("lon","lat")
#' colnames(bb) <- c('min','max')
#' bbSP <- as.SpatialPolygons.bbox(bb, proj4stringTo=P4S.latlon )
#' # Clip to extent
#' plyClip <- clipToExtent( ply, bbSP )
#' pntClip <- clipToExtent( pnt, bbSP )
#' # Plot
#' plot( ply )
#' plot( pnt, add=TRUE )
#' plot( bbSP, add=TRUE, border="blue" )
#' plot( plyClip, add=TRUE, border="red")
#' plot( pntClip, add=TRUE, col="red", pch="o")
clipToExtent <- function( sp, extent ) {
    require(rgeos)
    keep <- gContains( extent, sp,byid=TRUE ) | gOverlaps( extent, sp,byid=TRUE )
    stopifnot( ncol(keep)==1 )
    sp[drop(keep),]
}

bbox kırpma

Projeye sınırlayıcı kutuyu gerekiyorsa, sürüm burada bir ekler interpolateçıkan öngörülen kutu kavisli olup böylece, argüman.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.