以前在处理gis数据的时候,都是直接导入本地shp素材、本地geojson素材,本地topojson素材,自从接触postgis数据之后,深感使用规范的存储系统来统一管理gis数据的好处,特别是数据量大了之后,优势便更加明显,你可以选择将很多需要做空间计算的步骤转移到Postgis数据库内进行计算,要知道Postgis提供的空间计算能力与R和 Python 这种应用导向的 工具 相比,优势要大得多。
在批量导入素材之前,我们可以先看下R语言目前提供的各种导入接口在I/O性能上相比有何异同。
#install.packages("geojsonio")
#devtools::install_github("ropensci/geojsonio")
library("geojsonio")
library("rgdal")
library("sf")
library("maptools")
使用maptools包中的readShapePoly函数进行导入(已快被遗弃了,推荐使用sf和rgdal包)
system.time(china_map <- readShapePoly("D:/R/rstudy/CHN_adm/bou2_4p.shp"))
用户 系统 流逝
0.23 0.00 0.23
Warning message:
use rgdal::readOGR or sf::st_read
china_map@data
ggplot2::fortify(china_map)
geojsonio包导入:
system.time(geojson1 <- geojson_read(
"D:/R/rstudy/CHN_adm/bou2_4p.shp",
method = "local",
parse = TRUE,
what = "sp",
encoding="utf-8",
use_iconv=TRUE
))
用户 系统 流逝
0.69 0.03 0.71
使用rgdal包:
system.time(map_data <- readOGR(
"D:/R/rstudy/CHN_adm/bou2_4p.shp",
encoding="utf-8",
use_iconv=TRUE
))
OGR data source with driver: ESRI Shapefile
Source: "D:\R\rstudy\CHN_adm\bou2_4p.shp",
layer: "bou2_4p"with 925 features
It has 7 fields
Integer64 fields read as strings: BOU2_4M_ BOU2_4M_ID
用户 系统 流逝
0.66 0.09 0.75
使用sf包导入:
system.time(nepal_shp <- read_sf(
"D:/R/rstudy/CHN_adm/bou2_4p.shp",
options = "ENCODING=gbk"
))
用户 系统 流逝
0.05 0.00 0.05
可以看到在同一个shp文件单项导入的情况下,纯粹从时间上来看:
sf > maptools > rgdal > geojsonio
这里值得一提的是,geojsonio包是封装的rgdal服务,性能上自然略逊rgdal一筹,以上四个包中,除sf包是基于simple features标准的模型之外,其他基本都是基于sp模型的。sf模型的性能由此可见一斑。
当然,以上sf包、rgdal包和sf包都是兼容性很好地包,可以支持非常广泛的数据源,以下分别是在json标准下的两种素材上进行测试。
geojson
system.time(geojson <- geojson_read(
"D:/R/mapdata/State/china.geojson",
method = "local",
parse = TRUE,
encoding="utf-8",
use_iconv=TRUE,
what = "sp"
))
用户 系统 流逝
0.80 0.02 0.81
system.time(map_data <- readOGR(
"D:/R/mapdata/State/china.geojson",
encoding="utf-8",
use_iconv=TRUE,
stringsAsFactors = FALSE
))
OGR data source with driver: GeoJSON
Source: "D:\R\mapdata\State\china.geojson", layer: "china"with 34 features
It has 2 fields
用户 系统 流逝
0.77 0.00 0.76
system.time(nepal_shp <- read_sf(
"D:/R/mapdata/State/china.geojson"
))
用户 系统 流逝
0.03 0.00 0.03
topojson
system.time(map_data <- readOGR(
"D:/R/mapdata/china.topojson",
use_iconv=TRUE,
encoding = "utf-8",
stringsAsFactors = FALSE
))
OGR data source with driver: GeoJSON
Source: "D:\R\mapdata\china.topojson", layer: "china"with 34 features
It has 2 fields
用户 系统 流逝
0.52 0.01 0.59
system.time(geojson <- topojson_read(
"D:/R/mapdata/china.topojson",
encoding="utf-8",
use_iconv=TRUE
))
OGR data source with driver: GeoJSON
Source: "D:\R\mapdata\china.topojson", layer: "china"with 34 features
It has 2 fields
用户 系统 流逝
0.59 0.00 0.59
system.time(nepal_shp <- read_sf(
"D:/R/mapdata/china.topojson"
))
用户 系统 流逝
0.02 0.00 0.01
是不是看完这个性能大比拼之后大吃一惊,为sf包的超强IO能力所折服,sf包是一个非常强大的包,实现了基于simple features的所有特性,如果你了解一点儿Postgis的话,你会发现作者把大部分空间运算的函数名称设计的和Postgis中的函数一模一样,这就意味着你无论是只了解过sf包函数,或者只了解过Postgis函数,都可以低成本的迁移到两一个平台,因为同名函数往往功能一致。
如果你要想将sf包导入的数据模型转换为普通的数据框模式,仅仅只需使用其提供的as(sf,’Spatial’)函数一次转化即可,当然sf有自己的ggplot2通道函数geom_sf(),这意味着你不必多此一举。(当然对于sf不甚熟悉,习惯于使用geom_polygon来实现地理信息可视化的小伙伴儿,可以采取这种办法,但是仍然要推荐大家学习sf包,因为它代表着未来)。
R语言-gis数据批量入库:
#定义读写函数:
task <- function(filename,conn){
#此处为写入本地gis数据(可以是任意格式,可以使用任意一种导入工具)
map_data <- readOGR(filename,use_iconv=TRUE,encoding = "utf-8",stringsAsFactors = FALSE)
file_name <- sub('.json','',basename(filename))
#此处是写入数据库的函数,可以使用sf包、rgdal包以及RPostgreSQL包提供的写出函数。
writeOGR(obj = map_data ,dsn = conn,driver = "PostgreSQL",layer=file_name,encoding="gbk",overwrite_layer = TRUE)
}
#此处使用l_ply函数创建批量执行任务
Project_io <- function(path){
setwd(path)
input_list = list.files(path)
conn <- "PG:dbname='mytest' host='localhost' port='5432' user='postgres' password='708965'"
l_ply(input_list,task,conn)
}
#启动任务
Project_io("D:/R/mapdata/Province")
Python-gis数据批量入库:
import geopandas as gpd
import pandas as pd
from sqlalchemy import create_engine
from geoalchemy2 import Geometry,WKTElement
import numpy as np
import os
import re
import json
#数据写入函数:
def write_gis(path):
map_data = gpd.GeoDataFrame.from_file(path)
map_data['geometry'] = map_data['geometry'].apply(lambda x: WKTElement(x.wkt,4326))
map_data.drop(['center','parent'], axis = 1, inplace=True)
map_data.to_sql(
name = re.split('\\.',path)[0],
con = engine,
if_exists= 'replace',
dtype = {'geometry':Geometry(geometry_type ='POLYGON',srid = 4326)}
)
return None
#创建批量任务
def to_do(file_path,username,password,dbname):
os.chdir(file_path)
link = "postgresql://{0}:{1}@localhost:5432/{2}".format(username,password,dbname)
engine = create_engine(link,encoding = 'utf-8')
file_list = os.listdir()
map(lambda x: write_gis(x),file_list)
return None
#执行任务计划
if __name__ == '__main__':
file_path = 'D:/R/mapdata/Province'
username = 'postgres'
password = *****
dbname = 'mytest'
to_do(file_path,username,password,dbname)
print('DODE')
本文由杜雨 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Phoenix 数据导入与导出
- Redis批量导入数据的方法
- 导入Blob数据到Hive
- MySQL也能并发导入数据
- JanusGraph批量导入数据代码总结
- 数据搬运组件:基于 Sqoop 管理数据导入和导出
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Data Structures and Algorithms with JavaScript
Michael McMillan / O'Reilly Media / 2014-2-22 / USD 28.51
If you’re using JavaScript on the server-side, you need to implement classic data structures that conventional object-oriented programs (such as C# and Java) provide. This practical book shows you how......一起来看看 《Data Structures and Algorithms with JavaScript》 这本书的介绍吧!