आर में पोस्टगिस डेटा के साथ काम करना?


27

मैं लगभग हर समय आर के साथ काम करता हूं, और अब मैं इसका उपयोग स्थानिक डेटा खनन करने के लिए कर रहा हूं।

मेरे पास (स्पष्ट रूप से) जीआईएस डेटा के साथ एक पोस्टजीआईएस डेटाबेस है।

अगर मैं सांख्यिकीय स्थानिक विश्लेषण करना चाहता हूं और प्लॉट मैप बेहतर तरीका है:

  • आकृति के रूप में तालिकाओं को निर्यात करें या;
  • डेटाबेस के लिए सीधे काम?

जवाबों:


34

यदि आपके पास आरजीडीएल पैकेज में पोस्टजीआईएस चालक क्षमता है तो यह कनेक्शन स्ट्रिंग बनाने और उसका उपयोग करने का सिर्फ एक सवाल है। यहां मैं gisडिफ़ॉल्ट क्रेडेंशियल्स का उपयोग करके अपने स्थानीय डेटाबेस से जुड़ रहा हूं , इसलिए मेरा DSN सरल है। आपको एक होस्ट, उपयोगकर्ता नाम या पासवर्ड जोड़ने की आवश्यकता हो सकती है। जानकारी के लिए गदल डॉक्स देखें।

> require(rgdal)
> dsn="PG:dbname='gis'"

उस डेटाबेस में क्या टेबल हैं?

> ogrListLayers(dsn)
 [1] "ccsm_polygons"         "nongp"                 "WrldTZA"              
 [4] "nongpritalin"          "ritalinmerge"          "metforminmergev"      

एक पाओ:

> polys = readOGR(dsn="PG:dbname='gis'","ccsm_polygons")
OGR data source with driver: PostgreSQL 
Source: "PG:dbname='gis'", layer: "ccsm_polygons"
with 32768 features and 4 fields
Feature type: wkbMultiPolygon with 2 dimensions

मुझे क्या मिला है?

> summary(polys)
Object of class SpatialPolygonsDataFrame
Coordinates:
        min      max
x -179.2969 180.7031
y  -90.0000  90.0000
Is projected: NA 
proj4string : [NA]
Data attributes:
      area         perimeter       ccsm_polys      ccsm_pol_1   
 Min.   :1.000   Min.   :5.000   Min.   :    2   Min.   :    1  
 1st Qu.:1.000   1st Qu.:5.000   1st Qu.: 8194   1st Qu.: 8193  
 Median :1.000   Median :5.000   Median :16386   Median :16384  
 Mean   :1.016   Mean   :5.016   Mean   :16386   Mean   :16384  
 3rd Qu.:1.000   3rd Qu.:5.000   3rd Qu.:24577   3rd Qu.:24576  
 Max.   :2.000   Max.   :6.000   Max.   :32769   Max.   :32768  

अन्यथा आप R की डेटाबेस कार्यक्षमता का उपयोग कर सकते हैं और तालिकाओं को सीधे क्वेरी कर सकते हैं।

> require(RPostgreSQL)
Loading required package: RPostgreSQL
Loading required package: DBI
> m <- dbDriver("PostgreSQL")
> con <- dbConnect(m, dbname="gis")
> q="SELECT ST_AsText(the_geom) AS geom from ccsm_polygons LIMIT 10;"
> rs = dbSendQuery(con,q)
> df = fetch(rs,n=-1)

वह फीचर ज्यामिति लौटाता है df$geom, जिसमें आपको कुछ भी करने के लिए spक्लास ऑब्जेक्ट (SpatialPolygons, SpatialPoints, SpatialLines) में बदलने की आवश्यकता होगी । Rgeos में readWKT फ़ंक्शन उस के साथ मदद कर सकता है।

सामान से सावधान रहने वाली चीजें आमतौर पर डेटाबेस कॉलम की तरह होती हैं जिन्हें R प्रकार में मैप नहीं किया जा सकता है। आप रूपांतरण, फ़िल्टरिंग या सीमित करने के लिए क्वेरी में SQL शामिल कर सकते हैं। यह आपको हालांकि आरंभ करना चाहिए।


महान जवाब, लेकिन मैं क्षमता (पोस्टगिस चालक) को कैसे सक्षम करूं rgadl? मैं उबंटू 13.04 में हूं ...
नैनो

क्या आपके पास है? OgrDrivers () फ़ंक्शन को आपको कहीं बताना चाहिए। यदि नहीं, तो यह एक पूरी तरह से दूसरा सवाल है (शायद पहले के लिए सबसे अच्छा googled और फिर R-sig-geo पर पूछा गया)
Spacedman

उबंटू में, ड्राइवर डिफ़ॉल्ट रूप से स्थापित होता है। MacOS X में वह बात नहीं है। धन्यवाद!
नैनो ज्यूँ

उपरोक्त आपके कोड में, क्या readOGRपद्धति में पूर्ण तालिका के बजाय एक sql का उपयोग करना संभव है ?
नैनो ज्यूँ

वर्तमान में मुझे नहीं लगता। इस बारे में 2.5 साल पहले r-sig-geo पर कुछ बकबक हुआ था, लेकिन ऐसा कुछ भी नहीं हुआ। ऐसा लगता है whereकि एक खंड जोड़ना और उस OGR को पास करना आसान है, setAttributeFilterलेकिन सभी को C और C ++ कोड में करना होगा ...
Spacedman

8

यदि आपके पास Postgis में डेटा है, तो उसे आकृति के लिए निर्यात न करें। मेरे दृष्टिकोण से, यह एक तरह का कदम है।

आप एसक्यूएल स्टेटमेंट्स का उपयोग करके अपने पोस्टगिस डेटाबेस को क्वेरी कर सकते हैं, उन्हें डेटाफ्रेम के रूप में आयात कर सकते हैं और, चूंकि आप आर से परिचित हैं, इसलिए वहां से आपकी जरूरत के सभी जियोस्टैटिस्टिक्स करें। मेरा मानना ​​है कि आप अपने भू-स्थानिक परिणाम को वापस पोस्टगिस में भी निर्यात कर सकते हैं।

पोस्टगिस फंक्शंस के साथ एसक्यूएल का उपयोग करके आप सभी तरह के स्थानिक विश्लेषण भी कर सकते हैं, जैसे कि ओवरले संचालन, दूरी, और इसी तरह।

मैप प्लॉटिंग के लिए मैं क्यूजीआईएस , एक ओपनसोर्स जीआईएस सॉफ्टवेयर का उपयोग करूंगा , जो सीधे पोस्टगिस पढ़ सकता है (जहां तक ​​मुझे पता है कि यह परियोजना का प्रारंभिक लक्ष्य था), और आगामी संस्करण 2.0 में बहुत सी दिखने वाले नक्शे का उत्पादन करने के लिए बहुत सारी विशेषताएं हैं ।


ठीक है, महान सलाह, लेकिन जब से मैं आर (प्लॉट सहित) में सब कुछ स्वचालित करना चाहता हूं, क्यूजी पर जा रहा हूं, प्रवाह को तोड़ता है, तो यह नहीं है?
नानौने जुले

उस स्थिति में, यदि आप इसके साथ सहज हैं, तो बस अपने मानचित्रों को प्लॉट करने के लिए R का उपयोग करें। फिर भी, पोस्टगिस (अद्यतन) डेटा के आधार पर तैयार किए गए qgis प्रोजेक्ट लेआउट होने के नाते, वे भी अपडेट करेंगे। मुझे लगता है कि अंत में यह एक व्यक्तिगत विकल्प होगा कि क्या आर या क्यूजीआईएस का उपयोग किया जाए।
अलेक्जेंड्रे नेटो

आपकी त्वरित प्रतिक्रिया के लिए धन्यवाद, लेकिन मैं पोस्टगिस की एक तालिका से आर का उपयोग करके एक भूखंड कैसे बना सकता हूं?
नानौने जुले

मैं आर के साथ बहुत अनुभवी नहीं हूं और मुझे नहीं पता कि आप इसका उपयोग करके वेक्टर डेटा को कैसे प्लॉट करेंगे (जैसे मैंने कहा कि मैं इसके लिए क्यूजीआईएस का उपयोग करता हूं), आप आर में कैसे आकार-प्रकार की साजिश करते हैं? RI से PostgresSQL से कनेक्ट करने के लिए पहले RPostgreSQL का उपयोग किया है । मुझे लगता है कि रग्गल ]। सौभाग्य!
अलेक्जेंड्रे नेटो

5

नए शुरू किए गए एसएफ-पैकेज (एसपी का सक्सेसर) कार्यों st_read()और st_read_db()कार्यों को प्रदान करता है । इस ट्यूटोरियल के बाद और मेरे अनुभव से यह पहले से बताए गए तरीकों से तेज है। के रूप में sf शायद एक दिन सपा की जगह लेगा यह भी एक अच्छा फोन है अब देखो;)

require(sf)
dsn = "PG:dbname='dbname' host='host' port='port' user='user' password='pw'"
st_read(dsn, "schema.table")

आप RPostgreSQL का उपयोग करके DB भी एक्सेस कर सकते हैं:

require(sf)
require(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname = dbname, user = user, host = host, port = port, password = pw)

st_read_db(con, table = c("schema", "table"))
# or:
st_read_db(con, query = "SELECT * FROM schema.table")

dbDisconnect(con)
dbUnloadDriver(drv)

st_write()आप के साथ डेटा अपलोड कर सकते हैं।


1
यह सबसे सरल उपाय है, एक विगनेट क्रै। R-project.org/web/packages/sf/vignettes/sf2.html है जो sf का उपयोग करते हुए समझाता है
Cedric

2

आप अपने समाधान के लिए प्रत्येक चरण के आधार पर एक ही समय में सभी उपकरणों का उपयोग कर सकते हैं।

  • यदि आप भूस्थैतिक विश्लेषण करना चाहते हैं, तो आर। आर के पैकेज अधिक मजबूत हैं और आपको अधिक विश्लेषणात्मक परिणाम की अनुमति देता है। आप SQL querries के आधार पर डेटा आयात कर सकते हैं।
  • यदि आप अपने डेटा को तार्किक आधार पर एकत्रित करना चाहते हैं तो आप PostGIS का उपयोग कर सकते हैं। आप जटिल प्रश्नों का उत्तर दे सकते हैं जैसे कि मेरी निर्धारित सीमा के भीतर कौन से बिंदु हैं? लेकिन भव्य पैमाने पर।
  • मैपिंग के लिए, आप R या QGIS का उपयोग कर सकते हैं। क्यूजीआईएस अधिक सीधे आगे है, आर के साथ आप वांछित परिणाम प्राप्त करने के लिए संघर्ष कर सकते हैं।

यदि आप हमें अपनी समस्या से अधिक जानकारी देते हैं तो हम आपको और अधिक विशिष्ट उत्तर प्रदान कर सकते हैं


क्या आप अंतिम बिंदु का एक उदाहरण प्रदान कर सकते हैं, मेरा मतलब है, अगर मैं पोस्टपेडिस में तालिका से आर के साथ एक नक्शा साजिश करना चाहता हूं तो मैं कैसे कर सकता हूं?
नानाउने जुले

@nanounanue सुनिश्चित करें: लाइब्रेरी ("rgdal") mydata = readOGR (dsn = "PG: dbname = <mydb>", layer = "schema.table") प्लॉट (mydata, axes = TRUE) शीर्षक ("माय प्लॉट")।
nickves

: भी इस पेज पर एक नज़र डालें wiki.intamap.org/index.php/PostGIS
nickves

2

मैं rgdal और RPostgreSQL के संयोजन पर भी जाऊंगा। तो, @Guillaume के समान कोड, एक ट्राइकैच को छोड़कर जो अधिक लाइनों को हैंडल करता है, एक छद्म यादृच्छिक तालिका नाम और बेहतर प्रदर्शन के लिए एक अनलॉगेड टेबल का उपयोग। (खुद पर ध्यान दें: हम TEMP तालिका का उपयोग नहीं कर सकते, क्योंकि यह readOGR से दिखाई नहीं देती है)

dbGetSp <- function(dbInfo,query) {
 if(!require('rgdal')|!require(RPostgreSQL))stop('missing rgdal or RPostgreSQL')
  d <- dbInfo
  tmpTbl <- sprintf('tmp_table_%s',round(runif(1)*1e5))
  dsn <- sprintf("PG:dbname='%s' host='%s' port='%s' user='%s' password='%s'",
    d$dbname,d$host,d$port,d$user,d$password
    )
  drv <- dbDriver("PostgreSQL")
  con <- dbConnect(drv, dbname=d$dbname, host=d$host, port=d$port,user=d$user, password=d$password)
  tryCatch({
    sql <- sprintf("CREATE UNLOGGED TABLE %s AS %s",tmpTbl,query)
    res <- dbSendQuery(con,sql)
    nr <- dbGetInfo(res)$rowsAffected
    if(nr<1){
      warning('There is no feature returned.');
      return()
    }
    sql <- sprintf("SELECT f_geometry_column from geometry_columns WHERE f_table_name='%s'",tmpTbl)
    geo <- dbGetQuery(con,sql)
    if(length(geo)>1){
      tname <- sprintf("%s(%s)",tmpTbl,geo$f_geometry_column[1])
    }else{
      tname <- tmpTbl;
    }
    out <- readOGR(dsn,tname)
    return(out)
  },finally={
    sql <- sprintf("DROP TABLE %s",tmpTbl)
    dbSendQuery(con,sql)
    dbClearResult(dbListResults(con)[[1]])
    dbDisconnect(con)
  })
}

उपयोग:

d=list(host='localhost', dbname='spatial_db', port='5432', user='myusername', password='mypassword')
spatialObj<-dbGetSp(dbInfo=d,"SELECT * FROM spatial_table")

लेकिन, यह अभी भी धीमी गति से है:

बहुभुज के एक छोटे से सेट के लिए (6 सुविधाएँ, 22 क्षेत्र):

पोस्टगिस हिस्सा:

user  system elapsed
0.001   0.000   0.008

readOGR हिस्सा:

user  system elapsed
0.313   0.021   1.436

2

अब एक RPostGIS पैकेज है जो SQL प्रश्नों के साथ R में PostGIS geoms आयात कर सकता है।


1

आप rgdal और RPostreSQL को भी जोड़ सकते हैं। यह उदाहरण फ़ंक्शन RPostgreSQL के साथ एक अस्थायी तालिका बनाता है और इसे spOGial ऑब्जेक्ट के आउटपुट के लिए readOGR को भेजता है। यह वास्तव में अक्षम और बदसूरत है, लेकिन यह काफी अच्छी तरह से काम करता है। ध्यान दें कि क्वेरी को एक सेलेक्ट क्वेरी होना है और उपयोगकर्ता को डेटाबेस तक लिखने की आवश्यकता है।

RPostGIS <- function(coninfo,query) {
  dsn=paste("PG:dbname='",coninfo$dbname,"' host='",coninfo$host,"' port='",coninfo$port,"' user='",coninfo$user,"' password='",coninfo$password,"'", sep='')
  drv <- dbDriver("PostgreSQL")
  con <- dbConnect(drv, user=coninfo$user, password=coninfo$password, dbname=coninfo$dbname)
  res <- dbSendQuery(con,paste('CREATE TABLE tmp1209341251dva1 AS ',query,sep=''))
  geo <- dbGetQuery(con,"SELECT f_geometry_column from geometry_columns WHERE f_table_name='tmp1209341251dva1'")
  if(length(geo)>1){
    tname=paste("tmp1209341251dva1(",geo$f_geometry_column[1],")")
  }else{
    tname="tmp1209341251dva1";
  }
  out <- tryCatch(readOGR(dsn,tname), finally=dbSendQuery(con,'DROP TABLE tmp1209341251dva1'))
  dbDisconnect(con)
  return(out)
}

आप इसे कुछ इस तरह से कह सकते हैं:

> require('rgdal')
> require('RPostgreSQL')
> coninfo=list(host='localhost',dbname='spatial_db',port='5432',user='myusername',password='mypassword')
> spatial_obj<-RPostGIS(coninfo,"SELECT * FROM spatial_table")

0

यदि आप 'ST_AsText (geom) के साथ ज्योमवॉक' के रूप में एक क्वेरी लौटाते हैं और परिणाम को डेटा में लाते हैं, तो आप इसका उपयोग कर सकते हैं:

library(rgeos);library(sp)
wkt_to_sp <- function(data) {
  #data is data.frame from postgis with geomwkt as only geom
  SpP <- SpatialPolygons(lapply(1:length(data$geomwkt), 
           function(x) Polygons(list(Polygon(readWKT(data$geomwkt[x]))),x)))
  data <- data[,!(names(data) == "geomwkt")]
  return(SpatialPolygonsDataFrame(SpP, data))
}

अभी भी दर्द धीमी गति से .... एक परीक्षण पर 100 जियोम के लिए 1 सेकंड।


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