আর-তে বহুভুজের চক্রান্ত কীভাবে দ্রুত করা যায়?


24

আমি উত্তর আমেরিকার দেশের সীমানাগুলি একটি রাস্টার চিত্রের উপর দিয়ে কিছু পরিবর্তনশীল এবং তারপরে আর এর সাহায্যে প্লটটির শীর্ষে ওভারলে সংশ্লেষ চিত্রিত করতে চাই base আমি বেস গ্রাফিক্স এবং ল্যাটিস ব্যবহার করে এটি সফল করতে পেরেছি, তবে মনে হচ্ছে প্লট করার প্রক্রিয়াটি অনেক ধীর! আমি এখনও ggplot2 এ এটি করিনি, তবে আমি সন্দেহ করি যে এটি গতির দিক থেকে আরও ভাল হবে।

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

এখানে কিছু কোড রয়েছে:

# Load packages
library(raster)
#library(ncdf) # If you cannot install ncdf4
library(ncdf4)

# Read in the file, get the 13th layer
# fn <- 'path_to_file'
r <- raster(fn, band=13)

# Set the projection and extent
p4 <- "+proj=lcc +lat_1=50.0 +lat_2=50.0 +units=km +x_0=32.46341 +y_0=32.46341 +lon_0=-107 +lat_0=1.0"
projection(r) <- CRS(p4)
extent(r) <- c(-5648.71, 5680.72, 1481.40, 10430.62)

# Get the country borders
# This will download the RData files to your working directory
can<-getData('GADM', country="CAN", level=1)
usa<-getData('GADM', country="USA", level=1)
mex<-getData('GADM', country="MEX", level=1)

# Project to model grid
can_p <- spTransform(can, CRS(p4))
usa_p <- spTransform(usa, CRS(p4))
mex_p <- spTransform(mex, CRS(p4))

### USING BASE GRAPHICS
par(mar=c(0,0,0,0))
# Plot the raster
bins <- 100
plot(r, axes=FALSE, box=FALSE, legend=FALSE,
     col=rev( rainbow(bins,start=0,end=1) ),
     breaks=seq(4500,6000,length.out=bins))
plot(r, legend.only=TRUE, col=rev( rainbow(bins,start=0,end=1)),
     legend.width=0.5, legend.shrink=0.75, 
     breaks=seq(4500,6000,length.out=bins),
     axis.args=list(at=seq(4500,6000,length.out=11),
                labels=seq(4500,6000,length.out=11),
                cex.axis=0.5),
     legend.args=list(text='Height (m)', side=4, font=2, 
                      line=2, cex=0.8))
# Plot the borders
# These are so slow!!
plot(can_p, add=TRUE, border='white', lwd=2)
plot(usa_p, add=TRUE, border='white', lwd=2)
plot(mex_p, add=TRUE, border='white', lwd=2)
# Add the contours
contour(r, add=TRUE, nlevel=5)

### USING LATTICE
library(rasterVis)

# Some settings for our themes
myTheme <- RdBuTheme()
myTheme$axis.line$col<-"transparent"
myTheme$add.line$alpha <- 1
myTheme2 <- myTheme
myTheme2$regions$col <- 'transparent'
myTheme2$add.text$cex <- 0.7
myTheme2$add.line$lwd <- 1
myTheme2$add.line$alpha <- 0.8

# Get JUST the contour lines
contours <- contourplot(r, margin=FALSE, scales=list(draw=FALSE),
                        par.settings=myTheme2, pretty=TRUE, key=NULL, cuts=5,
                        labels=TRUE)

# Plot the colour
levels <- levelplot(r, contour=FALSE, margin=FALSE, scales=list(draw=FALSE),
                    par.settings = myTheme, cuts=100)

# Plot!
levels +  
  layer(sp.polygons(can_p, col='green', lwd=2)) +
  layer(sp.polygons(usa_p, col='green', lwd=2)) +
  layer(sp.polygons(mex_p, col='green', lwd=2)) +
  contours

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

ধন্যবাদ!


ঠিক এর মতো একটি ধারণা, আপনি কি আপনার বহুভুত জ্যামিতি ক্ষেত্রে সূচী তৈরি করতে পারেন?
রাডার নীচে

@ Burton449 দুঃখিত, আমি আর এ ম্যাপিং সম্পর্কিত জিনিস, বহুভুজ, অনুমান, ইত্যাদি ... আমি তোমার প্রশ্ন বুঝতে না সহ নতুন am
ialm

2
আপনি প্লট উইন্ডো ব্যতীত অন্য কোনও ডিভাইসে প্লট করার চেষ্টা করতে পারেন। প্লট ফাংশনগুলি পিডিএফ বা জেপিগে আবদ্ধ করুন (যুক্ত যুক্তিগুলির সাথে) এবং এই ফর্ম্যাটগুলির একটি আউটপুট। আমি খুঁজে পেয়েছি যে এটি যথেষ্ট দ্রুত।
জেফ্রি ইভান্স 21

@ জেফ্রিএভান্স ওয়া, হ্যাঁ আমি এটা বিবেচনা করিনি। প্লট উইন্ডোতে তিনটি আকারের ফাইল প্লট করতে প্রায় 60 সেকেন্ড সময় লেগেছে, তবে কোনও ফাইলের প্লট করতে 14 মিনিট সময় লেগেছে। হাতের কাজটির জন্য এখনও খুব ধীর, তবে নীচের উত্তরের কয়েকটি পদ্ধতির সাথে একত্রিত হলে এটি কার্যকর প্রমাণিত হতে পারে। ধন্যবাদ!
আইলমে

উত্তর:


30

আমি আকৃতি ফাইল থেকে দেশের সীমানা ষড়যন্ত্র গতি বৃদ্ধি 3 টি উপায় খুঁজে পেল আর আমি থেকে কিছু অনুপ্রেরণার এবং কোড পাওয়া এখানে এবং এখানে

(1) বহুভুজগুলির দ্রাঘিমাংশ এবং দ্রাঘিমাংশ পেতে আমরা শেপ ফাইলগুলি থেকে স্থানাঙ্কগুলি বের করতে পারি। তারপরে আমরা তাদের দ্রাঘিমাংশ এবং দ্বিতীয় অক্ষাংশযুক্ত দ্বিতীয় কলাম সহ একটি কলাম ডেটা ফ্রেমে রাখতে পারি। বিভিন্ন আকারগুলি এনএ দ্বারা পৃথক করা হয়।

(২) আমরা আমাদের শেপ ফাইল থেকে কিছু বহুভুজ সরাতে পারি। আকৃতির ফাইলটি খুব, খুব বিস্তারিত, তবে কিছু আকার ছোট ছোট দ্বীপ যা গুরুত্বহীন (আমার প্লটগুলির জন্য, যাইহোক)। বৃহত্তর বহুভুজগুলি রাখতে আমরা ন্যূনতম বহুভুজ অঞ্চল প্রান্তিক স্থাপন করতে পারি।

(3) আমরা ডগলাস-পিউকার অ্যালগোরিদম ব্যবহার করে আমাদের আকারগুলির জ্যামিতিটি সহজ করতে পারি । আমাদের বহুভুজ আকারের প্রান্তগুলি সরল করা যায়, কারণ এগুলি মূল ফাইলটিতে খুব জটিল। ভাগ্যক্রমে, একটি প্যাকেজ রয়েছে rgeos, এটি প্রয়োগ করে।

সেট আপ করুন:

# Load packages
library(rgdal)
library(raster)
library(sp)
library(rgeos)

# Load the shape files
can<-getData('GADM', country="CAN", level=0)
usa<-getData('GADM', country="USA", level=0)
mex<-getData('GADM', country="MEX", level=0)

পদ্ধতি 1: আকৃতি ফাইলগুলি থেকে একটি ডেটা ফ্রেম এবং প্লট লাইনে স্থানাঙ্কগুলি বের করুন

প্রধান অসুবিধাটি হ'ল আমরা এখানে কিছু তথ্য হারিয়ে ফেলি যখন প্রজেকশনের মতো অবজেক্টটিকে স্পেশালপলিজোনডাটা ফ্রেম অবজেক্ট হিসাবে রাখে। যাইহোক, আমরা এটিকে আবার কোনও এসপি অবজেক্টে পরিণত করতে পারি এবং প্রজেকশন তথ্যটি আবার যুক্ত করতে পারি এবং এটি মূল ডেটা প্লট করার চেয়ে আরও দ্রুত।

নোট করুন যে এই কোডটি মূল ফাইলটিতে খুব ধীরে চলে runs কারণ অনেকগুলি আকার রয়েছে এবং ফলাফল ডেটা ফ্রেমটি 2 মিলিয়ন ডলার সারি দীর্ঘ।

কোড:

# Convert the polygons into data frames so we can make lines
poly2df <- function(poly) {
  # Convert the polygons into data frames so we can make lines
  # Number of regions
  n_regions <- length(poly@polygons)

  # Get the coords into a data frame
  poly_df <- c()
  for(i in 1:n_regions) {
    # Number of polygons for first region
    n_poly <- length(poly@polygons[[i]]@Polygons)
    print(paste("There are",n_poly,"polygons"))
    # Create progress bar
    pb <- txtProgressBar(min = 0, max = n_poly, style = 3)
    for(j in 1:n_poly) {
      poly_df <- rbind(poly_df, NA, 
                       poly@polygons[[i]]@Polygons[[j]]@coords)
      # Update progress bar
      setTxtProgressBar(pb, j)
    }
    close(pb)
    print(paste("Finished region",i,"of",n_regions))
  }
  poly_df <- data.frame(poly_df)
  names(poly_df) <- c('lon','lat')
  return(poly_df)
}

পদ্ধতি 2: ছোট বহুভুজ সরান

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

কানাডার জন্য বহুভুজ আকারের কোয়ান্টাইলস:

          0%          25%          50%          75%         100% 
4.335000e-10 8.780845e-06 2.666822e-05 1.800103e-04 2.104909e+02 

কোড:

# Get the main polygons, will determine by area.
getSmallPolys <- function(poly, minarea=0.01) {
  # Get the areas
  areas <- lapply(poly@polygons, 
                  function(x) sapply(x@Polygons, function(y) y@area))

  # Quick summary of the areas
  print(quantile(unlist(areas)))

  # Which are the big polygons?
  bigpolys <- lapply(areas, function(x) which(x > minarea))
  length(unlist(bigpolys))

  # Get only the big polygons and extract them
  for(i in 1:length(bigpolys)){
    if(length(bigpolys[[i]]) >= 1 && bigpolys[[i]] >= 1){
      poly@polygons[[i]]@Polygons <- poly@polygons[[i]]@Polygons[bigpolys[[i]]]
      poly@polygons[[i]]@plotOrder <- 1:length(poly@polygons[[i]]@Polygons)
    }
  }
  return(poly)
}

পদ্ধতি 3: বহুভুজ আকারের জ্যামিতি সরল করুন

আমরা প্যাকেজ gSimplifyথেকে ক্রিয়াকলাপটি ব্যবহার করে আমাদের বহুভুজ আকারের শীর্ষে অবস্থানকে হ্রাস করতে পারিrgeos

কোড:

can <- getData('GADM', country="CAN", level=0)
can <- gSimplify(can, tol=0.01, topologyPreserve=TRUE)

কিছু মানদণ্ড:

আমি system.timeআমার প্লট করার সময়গুলিকে বেঞ্চমার্ক করতে ব্যবহার করেছি দ্রষ্টব্য যে কনট্যুর লাইন এবং অন্যান্য অতিরিক্ত জিনিস ব্যতীত দেশগুলি ষড়যন্ত্রের জন্য এটি কেবল সময়। এসপি বস্তুর জন্য, আমি কেবল plotফাংশনটি ব্যবহার করেছি । ডেটা ফ্রেম অবজেক্টের জন্য, আমি plotফাংশনটি সহ type='l'এবং ফাংশনটি ব্যবহার করেছি lines

মূল কানাডা, মার্কিন যুক্তরাষ্ট্র, মেক্সিকো বহুভুজ প্লট করা:

73.009 সেকেন্ড

পদ্ধতি 1 ব্যবহার:

2.449 সেকেন্ড

পদ্ধতি 2 ব্যবহার:

17.660 সেকেন্ড

পদ্ধতি 3 ব্যবহার:

16.695 সেকেন্ড

পদ্ধতি 2 + 1 ব্যবহার:

1.729 সেকেন্ড

পদ্ধতি 2 + 3 ব্যবহার করে:

0.445 সেকেন্ড

পদ্ধতি 2 + 3 + 1 ব্যবহার করে:

0.172 সেকেন্ড

অন্যান্য মন্তব্য:

দেখে মনে হয় যে পদ্ধতিগুলি 2 + 3 এর সংমিশ্রণটি বহুভুজের প্লট করার ক্ষেত্রে যথেষ্ট গতি বাড়িয়ে তোলে। 2 + 3 + 1 পদ্ধতি ব্যবহার করা spঅবজেক্টগুলির দুর্দান্ত বৈশিষ্ট্যগুলি হারাতে সমস্যা যুক্ত করে এবং আমার প্রধান সমস্যাটি অনুমানগুলি প্রয়োগ করা। আমি ডেটা ফ্রেম অবজেক্টটি প্রজেক্ট করতে একসাথে কিছু হ্যাক করেছি, তবে এটি বরং ধীর গতিতে চলেছে। আমি মনে করি পদ্ধতি 2 + 3 ব্যবহার করা আমার জন্য পর্যাপ্ত গতি বাড়িয়ে দেয় যতক্ষণ না আমি পদ্ধতি 2 + 3 + 1 ব্যবহারের মাধ্যমে কীঙ্কসটি পেতে পারি।


3
লেখার জন্য +1, যা কোনও সন্দেহ নেই যে ভবিষ্যতের পাঠকরা দরকারী পাবেন।
স্লোলিয়ারার

3

প্রত্যেকেরই এসপির পরিবর্তে এসএফ (স্থানিক বৈশিষ্ট্য) প্যাকেজে স্থানান্তরিত হওয়া উচিত। এটি উল্লেখযোগ্যভাবে দ্রুত (এই ক্ষেত্রে 1/60 তম) এবং ব্যবহার করা সহজ। এখানে একটি shp এ পড়া এবং ggplot2 এর মাধ্যমে প্লট করার উদাহরণ।

দ্রষ্টব্য: গিথুব-এ সাম্প্রতিক বিল্ডটি থেকে আপনাকে ggplot2 পুনরায় ইনস্টল করতে হবে (নীচে দেখুন)

library(rgdal)
library(sp)
library(sf)
library(plyr)
devtools::install_github("tidyverse/ggplot2")
library(ggplot2)

# Load the shape files
can<-getData('GADM', country="CAN", level=0)
td <- file.path(tempdir(), "rgdal_examples"); dir.create(td)
st_write(st_as_sf(can),file.path(td,'can.shp'))


ptm <- proc.time()
  can = readOGR(dsn=td, layer="can")
  can@data$id = rownames(can@data)
  can.points = fortify(can, region="id")
  can.df = join(can.points, can@data, by="id")
  ggplot(can.df) +  geom_polygon(aes(long,lat,group=group,fill='NAME_ENGLISH'))
proc.time() - ptm

user  system elapsed 
683.344   0.980 684.51 

ptm <- proc.time()
  can2 = st_read(file.path(td,'can.shp'))  
  ggplot(can2)+geom_sf( aes(fill = 'NAME_ENGLISH' )) 
proc.time() - ptm

user  system elapsed 
11.340   0.096  11.433 

0

GADM ডেটা উপকূলরেখার একটি খুব উচ্চ স্থানিক রেজোলিউশন আছে। আপনার যদি প্রয়োজন না হয় আপনি আরও সাধারণীকরণ করা ডেটা সেট ব্যবহার করতে পারেন। আইলমের পন্থাগুলি খুব আকর্ষণীয়, তবে একটি সহজ বিকল্প হ'ল 'ম্যাপটুলস' এর সাথে আসে 'আরআরএল_সিম্পল' ডেটা ব্যবহার করা is

library(maptools)
data(wrld_simpl)
plot(wrld_simpl)

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