আরে বহুভুজগুলির মধ্যে {সর্বনিম্ন} দূরত্ব গণনা করা হচ্ছে


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ফাংশন ব্যবহার করতে সক্ষম করে (বহুভুজগুলির মধ্যে দূরত্বটি সোজা)
ডিজেকি

@ ডিজেকি: মন্তব্য করার জন্য ধন্যবাদ। হ্যাঁ, আমি স্পষ্টভাবে এটি একটি যেতে দিতে হবে :) আমি একটি ডাটাবেস নির্মাণের শুরু আউট postgresকিন্তু যখন আমি (দেখুন না) কিভাবে ডাটাবেসের মধ্যে কর্মপ্রবাহ / geostats সংযোগ করতে জানেন না বন্ধ R...
JO।

উত্তর:


9

আপনি "স্পিডেপ" প্যাকেজে এই বিশ্লেষণটি করতে পারেন। সম্পর্কিত প্রতিবেশী কার্যক্রমে, আপনি "লংল্যাট = সত্য" ব্যবহার করলে ফাংশনটি দুর্দান্ত বৃত্তের দূরত্ব গণনা করে এবং দূরত্বের একক হিসাবে কিলোমিটার ফেরত দেয়। নীচের উদাহরণে আপনি কোনও ম্যাট্রিক্স বা ডেটা ফ্রেম হিসাবে ফলাফলের দূরত্বের তালিকা ("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প্যাকেজ অন্তর্দৃষ্টি জন্য ধন্যবাদ । শুধু স্পষ্টতার জন্য, এই পদ্ধতির আমার উদাহরণের মতো একই আউটপুট দেয়, তাই না?
জো।


যদিও প্রতিক্রিয়াটি সেন্ট্রয়েডের মধ্যে দূরত্ব গণনা করার জন্য দরকারী কোড সরবরাহ করে এটি ওপির কেন্দ্রীয় পয়েন্টের সাথে মোকাবিলা করে না এটি কীভাবে বহুভুজ সীমানার দুটি নিকটতম পয়েন্টের মধ্যে দূরত্বটি খুঁজে বের করতে হয়।
csfowler

SE এর জন্য একটি বিশাল পুলিশ এবং খারাপ ফর্ম, তবে আমি এখনই পুরো কাজটি করতে পারছি না। এই প্রশ্নের উত্তরের জন্য আমার নিজের অনুসন্ধানটি ইঙ্গিত দেয় যে গ্রন্থাগার rgeos থেকে প্রাপ্ত gDistance ফাংশনটি ওপি যা করতে চেয়েছিল তা করবে: প্রান্তগুলির মধ্যে স্বল্পতম দূরত্বটি সন্ধান করবে। যদি, আমার কোনও দৃ tight় সময়সীমাটি পূরণের তাড়াহুড়োয় আমি ওপি বা জেফরি ইভান্সকে আমার আন্তরিক ক্ষমার ভুল ব্যাখ্যা করে ফেলেছি।
csfowler
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.