공간 객체를 R의 경계 상자에 클립


14

R에 Spatial 객체가 주어지면 모든 요소를 ​​클리핑하여 경계 상자 안에 놓을 수 있습니까?

내가하고 싶은 두 가지가 있습니다 (이상적으로 두 가지를 수행하는 방법을 알고 있지만 현재 미국 문제로 다각형 모양 파일을 제한하는 현재 문제에 대한 적절한 해결책입니다).

  1. 경계 상자 안에 각 요소를 완전히 넣지 마십시오. 이것은 bbox()<-논리적 인 방법 처럼 보이지만 그러한 방법은 존재하지 않습니다.

  2. 무한대가 아닌 요소 (예 : 다각형, 선)가 경계에서 잘 리도록 실제 클립 작업을 수행하십시오 . sp::bbox나는했습니다 유일한 방법은 사용하는 것 가지고 올 수 있도록, 할당 방법이 부족 over하거나 gContains/ gCrossesSpatialPolygons 새로운 경계 상자의 좌표 상자를 포함하는 객체와 함께. 그런 다음 다각형 객체를 클리핑 할 때 포함 된 십자가와 교차하는 것을 파악하고 상자를 초과하지 않도록 다각형의 좌표를 변경해야합니다. 또는 같은 것 gIntersection. 그러나 더 간단한 방법이 있습니까?

경계 상자 에는 많은 문제가 있으며 관심 영역을 정의하는 다각형에 대한 공간 오버레이가 일반적으로 바람직하지만 많은 경우 경계 상자가 잘 작동하고 더 간단하다는 것을 알고 있습니다.


공간 객체가 확장 된 경우 (다각형 또는 선) 주어진 범위 안에있는 덩어리 만 반환하도록 자르기를 원하십니까? 더 간단한 방법이 없다고 생각합니다.
Spacedman

@Spacedman 나는 둘 다에 관심이 있지만 더 간단한 버전은 현재 질문에 충분하다고 설명했다.
Ari B. Friedman

rgeos를 사용하여 (2)에 대한 솔루션을 이미 구현 했습니까? 최소한 시도한 것처럼 들립니다. 적어도 우리는 '간단 성'과 비교할만한 무언가를 가지고 그 해결책과 예를 줄 수 있습니까? 솔직히 말하면, 그것은 매우 단순 해 보입니다.
Spacedman

@Spacedman 모든 것이 간단합니다. 그냥 시간이 걸립니다 .... :-) 나는 그것을 시도하고 오늘 디버깅 할 시간 gIntersectionError in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") : TopologyException: no outgoing dirEdge found at 3 2.5없었 습니다 . 조잡한 버전을 작성했으며 앞으로 수정 될 것입니다.
Ari B. Friedman

답변:


11

나는이 목적을 위해 작은 기능을 만들었으며 좋은 리뷰를 가진 다른 사람들이 사용했습니다!

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

문제가 해결 될 것입니다. 자세한 설명은 여기에 있습니다 : http://robinlovelace.net/r/2014/07/29/clipping-with-r.html

b_poly생성 된 더미 다각형 에는 proj4 문자열이 없으므로 " 경고 : spgeom1과 spgeom2의 proj4 문자열이 다릅니다 "가 발생하지만 이는 무해합니다.


나는 한 sp, maptools, rgdal, 및 rgeos로드. 내가 얻을 Error in .class1(object) : could not find function "extent"아마도 R / 패키지 버전 문제?
gregmacfarlane

library(raster)내 튜토리얼 의 줄 을 참고하십시오 : robinlovelace.net/r/2014/07/29/clipping-with-r.html 우리가 어떻게하는지 알게하십시오! 건배.
RobinLovelace

spgeom1과 spgeom2에는 다른 proj4 문자열이 있습니다. proj4string (b_poly) <-proj4string (shp)를 추가하면 문제가 해결됩니까?
Matifou

7

다음은 조잡한 경계 버전입니다 (내일 마감일 :-)에 필요한 시간을 충족시키기에 충분합니다).

#' 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 클리핑

투영 할 경계 상자가 필요한 경우 여기 에 버전 에 interpolate인수가 추가 되어 결과 투영 된 상자가 구부러집니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.