Rのバウンディングボックスに空間オブジェクトをクリップする


13

Rの空間オブジェクトが与えられた場合、すべての要素をクリップして境界ボックス内に配置するにはどうすればよいですか?

私がやりたいことが2つあります(理想的には両方を行う方法を知っていますが、どちらも私の現在の問題に対する許容可能な解決策です-ポリゴンシェープファイルを米国本土に制限します)。

  1. 境界ボックス内に完全にはない各要素をドロップします。 これbbox()<-は論理的な方法のようですが、そのような方法は存在しません。

  2. 無限小要素(ポリゴン、ラインなど)が境界で切り取られるように、真のクリップ操作を実行しますsp::bbox割り当て方法を欠いているので、私が作ってみた唯一の方法は、使用するのだろうovergContains/ gCrossesSpatialPolygonsと連携して、新たなバウンディングボックスの座標を持つボックスを含むオブジェクト。次に、ポリゴンオブジェクトをクリップするとき、含まれているものとクロスされているものを把握し、それらのポリゴンの座標を変更して、ボックスを超えないようにする必要があります。または何かのようなgIntersection。しかし、確かに簡単な方法がありますか?

バウンディングボックスには多くの問題があり、通常、関心領域を定義するポリゴンへの空間オーバーレイが望ましいことを知っていますが、多くの場合、バウンディングボックスはうまく機能し、よりシンプルです。


明確にするために、Spatialオブジェクトが拡張されている場合(ポリゴンまたはライン)、指定された範囲内にあるチャンクのみを返すようにカットする必要がありますか?もっと簡単な方法はないと思います。
Spacedman

@Spacedmanは両方に興味があることを明確にしたが、現在の質問にはもっと単純なバージョンで十分だろう。
アリB.フリードマン

(2)rgeosを使用してソリューションを既に実装していますか?少なくとも試してみたようです。その解決策と例を挙げてください。少なくとも「単純さ」について比較するものがありますか?なぜなら、正直に言うと、それは非常に単純に思えるからです。
Spacedman

@Spacedmanすべてがシンプルです。ただ時間がかかります。...:-)私はそれを試してみましたがgIntersectionError in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") : TopologyException: no outgoing dirEdge found at 3 2.5 今日デバッグする時間はありません。ずさんなバージョンを作成し、将来修正します。
アリB.フリードマン

回答:


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文字列があります」が発生しますが、これは無害です。


私が持っているspmaptoolsrgdal、およびrgeosロードされました。私が取得Error in .class1(object) : could not find function "extent"、おそらくR /パッケージのバージョンの問題を?
グレッグマクファーレン14

library(raster)私のチュートリアルの次の行に注意してください:robinlovelace.net/r/2014/07/29/clipping-with-r.htmlご連絡方法をお知らせください!乾杯。
RobinLovelace 14

これにより、警告メッセージが生成されます。spgeom1とspgeom2には異なるproj4文字列があります。proj4string(b_poly)<-proj4string(shp)を追加すると解決しますか?
マティフォー

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.