অন্য মানচিত্রের বহুভুজ দিয়ে ছেদকৃত মানচিত্রে একাধিক বহুভুজগুলির ক্ষেত্র গণনা করতে আর ব্যবহার করে


22

আমার কাছে অর্ডানেন্স জরিপ থেকে ডাউনলোড করা একটি শেফফাইল রয়েছে যা যুক্তরাজ্যের একটি কাউন্টির জন্য নির্বাচনী ওয়ার্ড (বিভাগ) সীমানা দেয়। এই প্রশ্নেggplot2 বর্ণিত হিসাবে আমি আকস্মিক ফাইলটি লোড করতে সাফল্যের সাথে আর ব্যবহার করেছি এবং বিভিন্ন মানচিত্রের প্লট করেছি । এটি সব ঠিকঠাক কাজ করছে।

এখন আমি নির্বিচারে আকারের একটি নতুন বহুভুজ তৈরি করতে, মানচিত্রে এটি যুক্ত করতে চাই, তারপরে আকৃতির নীচে পড়ে থাকা অঞ্চলে বসবাসকারী জনসংখ্যা গণনা করুন, যা একাধিক বিভাগকে আচ্ছাদিত বা আংশিকভাবে কভার করতে পারে। প্রতিটি নির্বাচনী বিভাগের জন্য আমার জনসংখ্যা রয়েছে এবং আমি প্রতিটি ওয়ার্ডের জনসংখ্যা সমানভাবে বন্টিত হয়েছে এমন সহজতর ধারণাটি করতে পারি। এটি নিম্নলিখিত পদক্ষেপগুলির পরামর্শ দেয়।

1) মানচিত্রে একটি নতুন আকারের ওভারলেটি যা একাধিক নির্বাচনী বিভাগকে আংশিকভাবে কভার করে। বলা যাক তর্ক করার পক্ষে 3 টি বিভাগ রয়েছে। এটি দেখতে এমন কিছু লাগবে। [সম্পাদনা করুন: আকৃতির নীচের চিত্রটিতে 3 টির পরিবর্তে 5 টি বিভাগ বিস্তৃত হয়]

এখানে চিত্র বর্ণনা লিখুন

2) ওভারলাইড বহুভুজ দিয়ে ছেদ করা এই 3 টি বিভাগের প্রত্যেকের ক্ষেত্রের শতাংশের গণনা করুন।

)) প্রতিটি বিভাগের ক্ষেত্রফলের পরিমাণটি আচ্ছাদিত আকারের সাথে আচ্ছাদিত করে এবং প্রতিটি বিভাগের জনসংখ্যার দ্বারা এটির সংখ্যা বৃদ্ধি করে জনসংখ্যার অনুমান করুন।

আমি মনে করি আমি সম্ভবত কাজ করে দেখতে পারেন বহুভুজ তৈরি এবং মানচিত্রের ওপর ওভারলে দরকারী উত্তর ব্যবহার বিদ্যমান তথ্য ফ্রেম থেকে এটি যোগ IE কিভাবে এই এবং অন্যান্য প্রশ্ন। যে বিটটি আমাকে উদ্বেগিত করে তা হ'ল ওভারলাইড আকার দ্বারা আবৃত প্রতিটি বিভাগের শতাংশের কাজ করা। latএবং longকলাম তথ্য ফ্রেমে ঐ অদ্ভুত অর্ডন্যান্স সার্ভে OpenData পরিসংখ্যান (Eastings এবং Northings বা কিছু) হয়।

সুতরাং আমার প্রথম প্রশ্নটি: আমি এই ডেটা ব্যবহার করে একটি নির্বাচনী বিভাগের সীমানা সংজ্ঞায়িত বহুভুজগুলির অঞ্চল (বা এলাকার একটি উপসেট) সন্ধান করতে কীভাবে যাব? কারণ এই ডেটা ফ্রেমের একটি অর্থবহ সাবসেটও বড় এই প্রশ্নটিতে পোস্ট করার চেয়ে আমি dput500k ফাইল তৈরি করতে ব্যবহার করেছি ( যা এখানে অনুলিপি এবং আটকানো যায় বা ডাউনলোড করা যায় )। উপরের চিত্রটির ভিত্তি তৈরি করা মানচিত্রটি নিম্নলিখিতটি দিয়ে তৈরি করা হয়েছিল:

require(ggplot2)
ggplot(smalldf, aes(x = long, y = lat, group = group)) +
    geom_polygon(colour = "grey50", size = 1, aes(fill = smalldf$bin))

আমার দ্বিতীয় প্রশ্নটি: আমি কি সঠিক সরঞ্জামগুলি ব্যবহার করছি? বর্তমানে আমি ব্যবহার করছি readShapePolyথেকে maptoolsপ্যাকেজ shapefile পড়তে। আমি তারপরে ব্যবহারের fortifyজন্য উপযুক্ত, প্রায় 130k লাইনের একটি ডেটা ফ্রেম তৈরি করতে ব্যবহার করি ggplot। যদি এই জাতীয় প্রক্রিয়াগুলির জন্য দরকারী সরঞ্জামগুলির সাথে একটি থাকে তবে আমার অন্য প্যাকেজটি ব্যবহার করা উচিত?

উত্তর:


16

স্পেসডম্যানের উত্তর এবং উপরের ইঙ্গিতগুলি কার্যকর ছিল, তবে তারা নিজেরাই পুরো উত্তরটি গঠন করে না। আমার পক্ষ থেকে কিছু গোয়েন্দা কাজ করার পরে আমি একটি উত্তরের নিকটবর্তী হয়েছি যদিও আমি এখনও gIntersectionযেভাবে চাইছি তা পেতে সক্ষম হইনি (উপরে মূল প্রশ্নটি দেখুন)। তবুও আমি আছে SpatialPolygonsDataFrame মধ্যে আমার নতুন বহুভুজ পেতে পরিচালিত।

আপডেট 2012-11-11: আমি মনে করি একটি কার্যক্ষম সমাধান পেয়েছি (নীচে দেখুন)। কী একটি বহুভুজ মোড়ানো ছিল SpatialPolygonsযখন ব্যবহার কল gIntersectionথেকে rgeosপ্যাকেজ। আউটপুটটি দেখতে এটির মতো দেখাচ্ছে:

[1] "Haverfordwest: Portfield ED (poly 2) area = 1202564.3, intersect = 143019.3, intersect % = 11.9%"
[1] "Haverfordwest: Prendergast ED (poly 3) area = 1766933.7, intersect = 100870.4, intersect % = 5.7%"
[1] "Haverfordwest: Castle ED (poly 4) area = 683977.7, intersect = 338606.7, intersect % = 49.5%"
[1] "Haverfordwest: Garth ED (poly 5) area = 1861675.1, intersect = 417503.7, intersect % = 22.4%"

বহুভুজ সন্নিবেশ করা আমার চিন্তাভাবনার চেয়ে শক্ত ছিল কারণ আশ্চর্যজনকভাবে, বিদ্যমান অর্ডানেন্স জরিপ-প্রাপ্ত আকৃতির ফাইলে কোনও নতুন আকৃতি সন্নিবেশ করার কোনও সহজ-অনুসরণ-অনুসরণ উদাহরণ বলে মনে হয় না। আমি এখানে আমার পদক্ষেপগুলি পুনরায় উত্পাদন করেছি এই আশায় যে এটি অন্য কারও পক্ষে কার্যকর হবে। ফলাফলটি এর মতো একটি মানচিত্র।

মানচিত্র নতুন বহুভুজ ওভারলাইড দেখাচ্ছে

যদি / যখন আমি ছেদ করার সমস্যাটি সমাধান করি তবে আমি এই উত্তরটি সম্পাদনা করব এবং চূড়ান্ত পদক্ষেপগুলি যুক্ত করব, যদি না কেউ অবশ্যই আমাকে এতে মারধর করে এবং পুরো উত্তর সরবরাহ না করে। ইতিমধ্যে, আমার সমাধান সম্পর্কে এখনও অবধি মন্তব্য / পরামর্শ সব স্বাগত।

কোড অনুসরণ।

require(sp) # the classes and methods that make up spatial ops in R
require(maptools) # tools for reading and manipulating spatial objects
require(mapdata) # includes good vector maps of world political boundaries.
require(rgeos)
require(rgdal)
require(gpclib)
require(ggplot2)
require(scales)
gpclibPermit()

## Download the Ordnance Survey Boundary-Line data (large!) from this URL:
## https://www.ordnancesurvey.co.uk/opendatadownload/products.html
## then extract all the files to a local folder.
## Read the electoral division (ward) boundaries from the shapefile
shp1 <- readOGR("C:/test", layer = "unitary_electoral_division_region")
## First subset down to the electoral divisions for the county of Pembrokeshire...
shp2 <- shp1[shp1$FILE_NAME == "SIR BENFRO - PEMBROKESHIRE" | shp1$FILE_NAME == "SIR_BENFRO_-_PEMBROKESHIRE", ]
## ... then the electoral divisions for the town of Haverfordwest (this could be done in one step)
shp3 <- shp2[grep("haverford", shp2$NAME, ignore.case = TRUE),]

## Create a matrix holding the long/lat coordinates of the desired new shape;
## one coordinate pair per line makes it easier to visualise the coordinates
my.coord.pairs <- c(
                    194500,215500,
                    194500,216500,
                    195500,216500,
                    195500,215500,
                    194500,215500)

my.rows <- length(my.coord.pairs)/2
my.coords <- matrix(my.coord.pairs, nrow = my.rows, ncol = 2, byrow = TRUE)

## The Ordnance Survey-derived SpatialPolygonsDataFrame is rather complex, so
## rather than creating a new one from scratch, copy one row and use this as a
## template for the new polygon. This wouldn't be ideal for complex/multiple new
## polygons but for just one simple polygon it seems to work
newpoly <- shp3[1,]

## Replace the coords of the template polygon with our own coordinates
newpoly@polygons[[1]]@Polygons[[1]]@coords <- my.coords

## Change the name as well
newpoly@data$NAME <- "zzMyPoly" # polygons seem to be plotted in alphabetical
                                 # order so make sure it is plotted last

## The IDs must not be identical otherwise the spRbind call will not work
## so use the spCHFIDs to assign new IDs; it looks like anything sensible will do
newpoly2 <- spChFIDs(newpoly, paste("newid", 1:nrow(newpoly), sep = ""))

## Now we should be able to insert the new polygon into the existing SpatialPolygonsDataFrame
shp4 <- spRbind(shp3, newpoly2)

## We want a visual check of the map with the new polygon but
## ggplot requires a data frame, so use the fortify() function
mydf <- fortify(shp4, region = "NAME")

## Make a distinction between the underlying shapes and the new polygon
## so that we can manually set the colours
mydf$filltype <- ifelse(mydf$id == 'zzMyPoly', "colour1", "colour2")

## Now plot
ggplot(mydf, aes(x = long, y = lat, group = group)) +
    geom_polygon(colour = "black", size = 1, aes(fill = mydf$filltype)) +
    scale_fill_manual("Test", values = c(alpha("Red", 0.4), "white"), labels = c("a", "b"))

## Visual check, successful, so back to the original problem of finding intersections
overlaid.poly <- 6 # This is the index of the polygon we added
num.of.polys <- length(shp4@polygons)
all.polys <- 1:num.of.polys
all.polys <- all.polys[-overlaid.poly] # Remove the overlaid polygon - no point in comparing to self
all.polys <- all.polys[-1] ## In this case the visual check we did shows that the
                           ## first polygon doesn't intersect overlaid poly, so remove

## Display example intersection for a visual check - note use of SpatialPolygons()
plot(gIntersection(SpatialPolygons(shp4@polygons[3]), SpatialPolygons(shp4@polygons[6])))

## Calculate and print out intersecting area as % total area for each polygon
areas.list <- sapply(all.polys, function(x) {
    my.area <- shp4@polygons[[x]]@Polygons[[1]]@area # the OS data contains area
    intersected.area <- gArea(gIntersection(SpatialPolygons(shp4@polygons[x]), SpatialPolygons(shp4@polygons[overlaid.poly])))
    print(paste(shp4@data$NAME[x], " (poly ", x, ") area = ", round(my.area, 1), ", intersect = ", round(intersected.area, 1), ", intersect % = ", sprintf("%1.1f%%", 100*intersected.area/my.area), sep = ""))
    return(intersected.area) # return the intersected area for future use
      })

এই প্রশ্নটি (এবং উত্তর) আমার পক্ষে কার্যকর হয়েছে। library(scales)স্বচ্ছতার কাজ করতে এখন যোগ করতে হবে।
আইরিন

1
ধন্যবাদ। আমি বিশ্বাস করি সেখানে একটি require(scales)কল আছে যা চালাকি করবে।
স্লোলিয়ারার

15

রিডশেপপলি ব্যবহার করবেন না - এটি প্রজেকশন স্পেসিফিকেশন উপেক্ষা করে। এসপি প্যাকেজ থেকে রিডওজিআর ব্যবহার করুন।

আপনার বহুভুজ ওভারলে যেমন ভৌগলিক ক্রিয়াকলাপের জন্য, rgeos প্যাকেজটি দেখুন।

আক্ষরিকভাবে আপনার শেষ কাজটি করা উচিতটি দুর্গমুক্তি এবং জিজিপ্লট দিয়ে। আপনার ডেটা এসপি-শ্রেণীর অবজেক্টগুলিতে রাখুন, বেস গ্রাফিক্সের সাহায্যে তাদের প্লট করুন এবং প্রকল্পের শেষ অবধি জিপিপ্লট চিনিকে ছেড়ে দিন এবং আপনার কিছু চমত্কার প্লট প্রয়োজন।


টিপস জন্য ধন্যবাদ; আমি আবারও রিডওজিআর এ দেখব। জি জিপ্লট হিসাবে, এটি আর যা শিখেছে তা স্বাভাবিকভাবেই আসে - কখনই বেস গ্রাফিক্স নিয়ে বিরক্ত করেনি।
স্লোলিয়ার্নার

1
এসপি-শ্রেণীর বস্তুগুলিতে আপনার মন্তব্যটি পুনরায় করুন, আমি যদি ফাংশনগুলির মধ্যে সুবিধা নিতে চাই তবে এটি গুরুত্বপূর্ণ মনে হয় rgeos। আমি লিঙ্কযুক্ত উত্তরে আপনার উদাহরণটি ব্যবহার করে বহুভুজগুলির ভাণ্ডার তৈরিতে পরিচালিত হয়েছি, তবে বিদ্যমান স্থানিক ডেটা ফ্রেমে নতুন বহুভুজটি কীভাবে যুক্ত করা যায় তা আমি কাজ করতে পারি না। আমি @dataসিনট্যাক্সটি নিয়ে কিছুটা গোলযোগ করেছি কিন্তু কোথাও পেলাম না। আপনার কি কোনও পরামর্শ আছে?
স্লোলিয়ার্নার

4
তাদের দুটি cbind(part1,part2)অনন্য বহুভুজ আইডি থাকলে আপনি দুটি স্থানিক বহুভুজ ডেটা ফ্রেমে যোগদান করতে পারেন - অন্যথায় আপনি একটি সতর্কতা পেয়েছেন এবং spChFIDsঅনন্য বহুভুজ বৈশিষ্ট্য আইডি নির্ধারণ করতে ব্যবহার করতে হবে।
স্পেসডম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.