आर में बॉक्स को बांधने के लिए स्थानिक वस्तु को क्लिप करें


14

R में एक स्थानिक वस्तु को देखते हुए, मैं अपने सभी तत्वों को एक बाउंडिंग बॉक्स के भीतर झूठ बोलने के लिए कैसे क्लिप करूं?

ऐसी दो चीजें हैं जो मैं करना चाहता हूं (आदर्श रूप से मैं जानता हूं कि दोनों को कैसे करना है, लेकिन या तो मेरी वर्तमान समस्या का एक स्वीकार्य समाधान है - महाद्वीपीय अमेरिका के लिए एक बहुभुज आकार को सीमित करना)।

  1. प्रत्येक तत्व को बाउंडिंग बॉक्स के भीतर पूरी तरह से नहीं छोड़ें। ऐसा लगता bbox()<-है कि तार्किक तरीका होगा, लेकिन ऐसी कोई विधि मौजूद नहीं है।

  2. एक सच्चा क्लिप ऑपरेशन करें, जैसे कि गैर-असीम तत्व (जैसे बहुभुज, रेखाएं) सीमा पर काट दिए जाते हैंsp::bboxएक असाइनमेंट विधि का अभाव है, इसलिए एक ही तरीका है जिसके साथ मैं एक स्पैटियलपॉलीगॉन्स ऑब्जेक्ट के साथ उपयोग overया gContains/ gCrossesके संयोजन में होगा, जिसमें नए बाउंडिंग बॉक्स के निर्देशांक के साथ एक बॉक्स होगा। फिर जब एक बहुभुज ऑब्जेक्ट को क्लिप करते हैं, तो आपको यह पता लगाना होगा कि कौन सी क्रॉस बनाम समाहित हैं, और उन पॉलीगोन के निर्देशांक को बदल दें ताकि वे बॉक्स से अधिक न हों। या कुछ पसंद है gIntersection। लेकिन निश्चित रूप से एक सरल तरीका है?

जबकि मुझे पता है कि बाउंडिंग बॉक्स के साथ कई समस्याएं हैं , और बहुभुज के लिए एक स्थानिक ओवरले जो ब्याज के क्षेत्र को परिभाषित करता है, आमतौर पर बेहतर होता है, कई स्थितियों में, बाउंडिंग बॉक्स ठीक काम करते हैं और सरल होते हैं।


बस स्पष्ट होने के लिए, यदि आपकी स्थानिक वस्तु को विस्तारित किया गया है (बहुभुज या रेखाएँ) तो आप इसे इस तरह से काटना चाहते हैं कि यह केवल उसी का हिस्सा देता है जो आपकी दी गई सीमा के अंदर है? मुझे नहीं लगता कि कोई सरल तरीका है।
१३:१३ पर १५:३३

@Spacedman ने स्पष्ट किया कि मैं दोनों में दिलचस्पी रखता हूं लेकिन सरल संस्करण वर्तमान प्रश्न के लिए पर्याप्त होगा।
अरी बी। फ्रीडमैन

क्या आपने पहले से ही (2) rgeos का उपयोग करके समाधान लागू किया है? ऐसा लगता है कि आपने कम से कम कोशिश की है। क्या आप हमें वह समाधान और एक उदाहरण दे सकते हैं ताकि कम से कम हमारे पास 'सादगी' के खिलाफ तुलना करने के लिए कुछ हो? क्योंकि, ईमानदार होना, यह बहुत आसान लगता है।
Spacedman

@ सब कुछ सरल है; बस समय लगता है .... :-) मैंने इसे आजमाया gIntersectionऔर Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_intersection") : TopologyException: no outgoing dirEdge found at 3 2.5 नो डेब्यू के साथ आज आया; एक मैला संस्करण लिखा और भविष्य में ठीक कर देगा।
अरी बी। फ्रीडमैन

जवाबों:


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"आर / पैकेज संस्करण समस्या हो सकती है?
gregmacfarlane 21

library(raster)मेरे ट्यूटोरियल में लाइन नोट करें : robinlovelace.net/r/2014/07/29/clipping-with-r.html हमें बताएँ कि आप कैसे प्राप्त करते हैं! चीयर्स।
रोबिनवेलवेल्स

यह मेरे लिए एक चेतावनी संदेश उत्पन्न करता है: 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तर्क जोड़ता है, ताकि परिणामस्वरूप अनुमानित बॉक्स घुमावदार हो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.