回答:
rgdalパッケージにPostGISドライバー機能がある場合は、接続文字列を作成して使用するだけの質問です。ここではgis
、デフォルトの資格情報を使用してローカルデータベースに接続しているため、DSNはかなり単純です。ホスト、ユーザー名、またはパスワードの追加が必要になる場合があります。詳細については、gdalのドキュメントを参照してください。
> 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を含めて、変換、フィルタリング、または制限を行うことができます。しかし、これで開始できます。
readOGR
メソッドでフルテーブルの代わりにSQLを使用することは可能ですか?
where
節を追加してOGRに渡すことは簡単に見えますsetAttributeFilter
が、すべてCおよびC ++コードで実行する必要があります...
Postgisにデータがある場合は、シェープファイルにエクスポートしないでください。私の観点からすると、それは一種の後退です。
SQLステートメントを使用してRからpostgisデータベースをクエリし、それらをデータフレームとしてインポートし、Rに精通しているため、そこから必要なすべての地球統計学を実行できます。地球統計の結果をpostgisにエクスポートして戻すこともできます。
Postgis関数でSQLを使用すると、オーバーレイ操作、距離など、あらゆる種類の空間分析も実行できます。
マッププロットには、PostGISを直接読み取ることができるオープンソースGISソフトウェアであるQGISを使用します(それがプロジェクトの最初の目標である限り)、今後のバージョン2.0には、見栄えの良いマップを作成するための多くの機能が含まれます。
新たに導入されたSF-パッケージ(SPの後継)を提供st_read()
し、st_read_db()
機能します。このチュートリアルの後、私の経験では、すでに述べた方法よりも高速です。sfはいつの日かspに取って代わるだろうので、今すぐ見てみるのもいいでしょう;)
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()
、あなたのデータをアップロードすることができます。
ソリューションの各ステップに基づいて、すべてのツールを同時に使用できます。
問題の詳細をお知らせいただければ、より具体的な回答を提供できます。
また、rgdalとRPostgreSQLを組み合わせて使用します。したがって、@ Guillaumeと同じコードですが、より多くの行を処理するtryCatch、擬似ランダムテーブル名、およびパフォーマンス向上のためのログなしテーブルの使用を除きます。(自分自身への注意: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フィールド)の場合:
postgisパーツ:
user system elapsed
0.001 0.000 0.008
readOGRパート:
user system elapsed
0.313 0.021 1.436
rgdalとRPostreSQLを組み合わせることもできます。このサンプル関数は、RPostgreSQLで一時テーブルを作成し、空間オブジェクトの出力のためにreadOGRに送信します。これは本当に非効率的でandいですが、非常にうまく機能します。クエリはSELECTクエリである必要があり、ユーザーはデータベースへの書き込みアクセス権を持っている必要があることに注意してください。
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")
'ST_AsText(geom)as geomwkt'でクエリを返し、結果をデータにフェッチする場合、次を使用できます。
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秒。
Geotuple- https://github.com/rhansson/geotuple は、R-ServerとPostGISを接続するWebアプリです(RPostgreSQL を使用)
rgadl
ますか?私はUbuntu 13.04にいます...