आर में बहुभुज के बीच {न्यूनतम} दूरी की गणना


9

मैंने प्रजातियों के वितरण के सतह क्षेत्र की गणना की है (आकार-प्रकार से बहुभुजों को विलय करना), लेकिन चूंकि यह क्षेत्र काफी विकृत बहुभुजों में शामिल हो सकता है, इसलिए मैं फैलाव के कुछ माप की गणना करना चाहूंगा। मैंने अब तक जो भी किया है, वह प्रत्येक बहुभुज के केन्द्रक को पुनः प्राप्त करने के लिए है, उन दोनों के बीच की दूरी की गणना की और भिन्नता के गुणांक की गणना करने के लिए इनका उपयोग किया, जैसा कि नीचे दिए गए उदाहरण में है;

require(sp)
require(ggplot2)
require(mapdata)
require(gridExtra)
require(scales)
require(rgeos)
require(spatstat)

# Create the coordinates for 3 squares
ls.coords <- list()
ls.coords <- list()
ls.coords[[1]] <- c(15.7, 42.3, # a list of coordinates
                    16.7, 42.3,
                    16.7, 41.6,
                    15.7, 41.6,
                    15.7, 42.3)

ls.coords[[2]] <- ls.coords[[1]]+0.5 # use simple offset

ls.coords[[3]] <- c(13.8, 45.4, # a list of coordinates
                    15.6, 45.4,
                    15.6, 43.7,
                    13.8, 43.7,
                    13.8, 45.4)

# Prepare lists to receive the sp objects and data frames
ls.polys <- list()
ls.sp.polys <- list()

for (ii in seq_along(ls.coords)) {
   crs.args <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
   my.rows <- length(ls.coords[[ii]])/2
   # create matrix of pairs
   my.coords <- matrix(ls.coords[[ii]],nrow = my.rows,ncol = 2,byrow = TRUE)
   # now build sp objects from scratch...
   poly = Polygon(my.coords)
   # layer by layer...
   polys = Polygons(list(poly),1)
   spolys = SpatialPolygons(list(polys))
   # projection is important
   proj4string(spolys) <- crs.args
   # Now save sp objects for later use
   ls.sp.polys[[ii]] <- spolys
   # Then create data frames for ggplot()
   poly.df <- fortify(spolys)
   poly.df$id <- ii
   ls.polys[[ii]] <- poly.df
}

# Convert the list of polygons to a list of owins
w <- lapply(ls.sp.polys, as.owin)
# Calculate the centroids and get the output to a matrix
centroid <- lapply(w, centroid.owin)
centroid <- lapply(centroid, rbind)
centroid <- lapply(centroid, function(x) rbind(unlist(x)))
centroid <- do.call('rbind', centroid)

# Create a new df and use fortify for ggplot
centroid_df <- fortify(as.data.frame(centroid))
# Add a group column
centroid_df$V3 <- rownames(centroid_df)

ggplot(data = italy, aes(x = long, y = lat, group = group)) +
  geom_polygon(fill = "grey50") +
  # Constrain the scale to 'zoom in'
  coord_cartesian(xlim = c(13, 19), ylim = c(41, 46)) +
  geom_polygon(data = ls.polys[[1]], aes(x = long, y = lat, group = group), fill = alpha("red", 0.3)) +
  geom_polygon(data = ls.polys[[2]], aes(x = long, y = lat, group = group), fill = alpha("green", 0.3)) +
  geom_polygon(data = ls.polys[[3]], aes(x = long, y = lat, group = group), fill = alpha("lightblue", 0.8)) + 
  coord_equal() +
  # Plot the centroids
  geom_point(data=centroid_points, aes(x = V1, y = V2, group = V3))

# Calculate the centroid distances using spDists {sp}
centroid_dists <- spDists(x=centroid, y=centroid, longlat=TRUE)

centroid_dists

       [,1]      [,2]     [,3]
[1,]   0.00000  69.16756 313.2383
[2,]  69.16756   0.00000 283.7120
[3,] 313.23834 283.71202   0.0000

# Calculate the coefficient of variation as a measure of polygon dispersion 
cv <- sd(centroid_dist)/mean(centroid_dist)
[1] 0.9835782

तीन बहुभुज और उनके केन्द्रक के प्लॉट

यहां छवि विवरण दर्ज करें

मुझे यकीन नहीं है कि अगर यह दृष्टिकोण बहुत सारे मामलों में बहुत उपयोगी है, तो कुछ पॉलीगन्स (उपरोक्त उदाहरण में नीला एक) बाकी की तुलना में काफी बड़े हैं, इस प्रकार दूरी को और भी अधिक बढ़ाते हैं। उदाहरण के लिए, ऑस्ट्रेलिया के केन्द्रक में पापुआ के समान पश्चिमी बोर्डर की दूरी लगभग है।

वैकल्पिक तरीकों पर मुझे कुछ इनपुट मिलने चाहिए। उदाहरण के लिए या मैं किस फ़ंक्शन के साथ बहुभुज के बीच की दूरी की गणना कर सकता हूं?

मैंने सभी बिंदुओं के बीच की दूरी की गणना {spatstat}करने के लिए चलने में सक्षम होने के लिए पॉइंटपैटर्न (पीपीपी) से ऊपर स्पैटियलपॉलिऑन डेटाफ़्रेम को बदलने के लिए परीक्षण किया है nndist() {spatstat}। लेकिन जब से मैं काफी बड़े क्षेत्रों (कई बहुभुज और बड़े वाले) के साथ काम कर रहा हूं, मैट्रिक्स बहुत बड़ा हो गया है और मुझे यकीन नहीं है कि बहुभुज के बीच कम से कम दूरी तक कैसे जारी रखा जाए ।

मैंने फ़ंक्शन को भी देखा है gDistance {rgeos}, लेकिन मुझे लगता है कि यह केवल अनुमानित डेटा पर काम करता है जो मेरे लिए एक समस्या हो सकती है क्योंकि मेरे क्षेत्र कई को पार कर सकते हैं EPSG areas। कार्य के लिए भी यही समस्या उत्पन्न होगी crossdist {spatstat}


1
क्या आप postgres/postgisइसके अलावा उपयोग करने पर विचार करेंगे R? मैंने एक वर्कफ़्लो का उपयोग किया है जहाँ मैं अपने अधिकांश काम करता हूँ R, लेकिन उस डेटा को डेटाबेस में संग्रहीत करता हूँ जिसका मैं उपयोग करता हूँ sqldf। यह आपको सभी postgisकार्यों का उपयोग करने में सक्षम बनाता है (
पॉलीगोन के

@djq: टिप्पणी करने के लिए धन्यवाद। हाँ, मैं निश्चित रूप से इसे जाने देना होगा :) मैं में एक डेटाबेस का निर्माण शुरू किया था postgresलेकिन जब मैं (मुड़कर नहीं देखा) कैसे डेटाबेस और के बीच कार्यप्रवाह / geostats कनेक्ट करने के लिए नहीं पता था बंद कर दिया R...
Jo।

जवाबों:


9

आप इस विश्लेषण को "स्पदीप" पैकेज में कर सकते हैं। संबंधित पड़ोसी कार्यों में, यदि आप "longlat = TRUE" का उपयोग करते हैं, तो फ़ंक्शन महान सर्कल दूरी की गणना करता है और दूरी इकाई के रूप में किलोमीटर लौटाता है। नीचे दिए गए उदाहरण में आप परिणामी दूरी सूची ऑब्जेक्ट ("dist.list") को एक मैट्रिक्स या डेटा.फ्रेम में ले जा सकते हैं, हालाँकि, यह लंगोटी का उपयोग करके सारांश आँकड़ों की गणना करने में काफी कुशल है।

require(sp)
require(spdep)

# Create SpatialPolygonsDataFrame for 3 squares
poly1 <- Polygons(list(Polygon(matrix(c(15.7,42.3,16.7,42.3,16.7,41.6,15.7,41.6,15.7,42.3), 
                   nrow=5, ncol=2, byrow=TRUE))),"1")     
poly2 <- Polygons(list(Polygon(matrix(c(15.7,42.3,16.7,42.3,16.7,41.6,15.7,41.6,15.7,42.3)+0.5, 
                   nrow=5, ncol=2, byrow=TRUE))),"2")     
poly3 <- Polygons(list(Polygon(matrix(c(13.8, 45.4, 15.6, 45.4,15.6, 43.7,13.8, 43.7,13.8, 45.4), 
                   nrow=5, ncol=2, byrow=TRUE))),"3")                      
spolys = SpatialPolygons(list(poly1,poly2,poly3),1:3)
 spolys <- SpatialPolygonsDataFrame(spolys, data.frame(ID=sapply(slot(spolys, "polygons"), 
                                    function(x) slot(x, "ID"))) )   
   proj4string(spolys) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"

# Centroid coordinates (not used but provided for example) 
coords <- coordinates(spolys)

# Create K Nearest Neighbor list
skNN.nb <- knn2nb(knearneigh(coordinates(spolys), longlat=TRUE), 
                  row.names=spolys@data$ID)

# Calculate maximum distance for all linkages 
maxDist <- max(unlist(nbdists(skNN.nb, coordinates(spolys), longlat=TRUE)))

# Create spdep distance object
sDist <- dnearneigh(coordinates(spolys), 0, maxDist^2, row.names=spolys@data$ID)
  summary(sDist, coordinates(spolys), longlat=TRUE)

# Plot neighbor linkages                  
plot(spolys, border="grey") 
  plot(sDist, coordinates(spolys), add=TRUE)  

# Create neighbor distance list 
( dist.list <- nbdists(sDist, coordinates(spolys), longlat=TRUE) )

# Minimum distance 
( dist.min <- lapply(dist.list, FUN=min) )

# Distance coefficient of variation    
( dist.cv <- lapply(dist.list, FUN=function(x) { sd(x) / mean(x) } ) )

टिप्पणी और spdebपैकेज में अंतर्दृष्टि के लिए धन्यवाद । स्पष्टीकरण के लिए, यह दृष्टिकोण मेरे उदाहरण के रूप में एक ही आउटपुट देता है, है ना?
जे.ओ.

अगर आपने मेरी उपरोक्त टिप्पणी
jO

हालांकि प्रतिक्रिया सेंट्रोइड्स के बीच की दूरी की गणना के लिए उपयोगी कोड प्रदान करती है, लेकिन यह ओपी के केंद्रीय बिंदु के साथ सौदा नहीं करता है जो कि बहुभुज सीमाओं के दो निकटतम बिंदुओं के बीच की दूरी का पता लगाने का तरीका है।
csfowler

एसई के लिए एक विशाल पुलिस आउट और खराब फॉर्म, लेकिन मैं अभी पूरा काम नहीं कर सकता। इस सवाल के जवाब के लिए मेरी खुद की खोज से प्रतीत होता है कि पुस्तकालय rgeos से gDistance फ़ंक्शन ओपी का उद्देश्य क्या करेगा: किनारों के बीच सबसे कम दूरी का पता लगाएं। यदि, मेरी जल्दबाजी में एक तंग समय सीमा को पूरा करने के लिए मैंने ओपी या जेफरी इवांस को मेरी ईमानदारी से माफी मांगी है।
csfowler
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.