Skip to content

Commit

Permalink
auto combine layers when exporting multiple NTS sheets of data
Browse files Browse the repository at this point in the history
  • Loading branch information
paleolimbot committed Apr 4, 2016
1 parent 65d47a9 commit b44105d
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 64 deletions.
8 changes: 4 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ Package: rcanvec
Type: Package
Title: Access and Plot CanVec and CanVec+ Data for Rapid Basemap Creation in
Canada
Version: 0.1.6
Date: 2016-03-24
Version: 0.2.0
Date: 2016-04-04
Author: Dewey Dunnington <[email protected]>
Maintainer: Dewey Dunnington <[email protected]>
Description: Provides an interface to the National Topographic System (NTS),
Expand All @@ -15,9 +15,9 @@ Description: Provides an interface to the National Topographic System (NTS),
readable shapefiles for use in another GIS.
License: GPL-2
Depends:
R (>= 2.10)
R (>= 2.10),
sp
Imports:
sp,
rgdal
URL: https://github.com/paleolimbot/rcanvec
BugReports: https://github.com/paleolimbot/rcanvec/issues
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ export(nts.bbox)
export(nts.bybbox)
export(nts.idat)
export(ntsstring)
importFrom(sp,rbind.SpatialLinesDataFrame)
importFrom(sp,rbind.SpatialPointsDataFrame)
importFrom(sp,rbind.SpatialPolygonsDataFrame)
179 changes: 122 additions & 57 deletions R/canvec.R
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ canvec.loadfromdir <- function(directory, layerid) {
#' \code{rgdal::ogrDrivers()} may also work.
#' @param cachedir Pass a specific cache directory in which files have been extracted.
#' Default value is that returned by \code{canvec.cachedir()}
#' @param combine \code{TRUE} if output should be one file per layer, \code{FALSE} otherwise
#' @param overwrite \code{TRUE} if files should overwrite files already in output directory.
#' @param ... Arguments passed on to \code{sp::writeOGR()}
#' @examples
#' \donttest{
Expand All @@ -258,8 +260,13 @@ canvec.loadfromdir <- function(directory, layerid) {
#' }
#'
#' @export
canvec.export <- function(ntsid, tofolder, layers=NULL, crs=NULL, cachedir=NULL, driver=NULL, ...) {

#' @importFrom sp rbind.SpatialPointsDataFrame
#' @importFrom sp rbind.SpatialPolygonsDataFrame
#' @importFrom sp rbind.SpatialLinesDataFrame
canvec.export <- function(ntsid, tofolder, layers=NULL, crs=NULL, cachedir=NULL, driver=NULL,
combine=TRUE, overwrite=TRUE, ...) {
# CMD trick
rbind.SpatialLinesDataFrame; rbind.SpatialPointsDataFrame; rbind.SpatialPolygonsDataFrame
dir.create(tofolder)

if(class(ntsid) != "list") {
Expand All @@ -272,73 +279,117 @@ canvec.export <- function(ntsid, tofolder, layers=NULL, crs=NULL, cachedir=NULL,
layers <- canvec_layers$id
}

layerinfo <- list()
filesto <- rep(NA, length(layers)*length(ntsid))
filemeta <- list()
for(i in 1:length(ntsid)) {
directory = file.path(cachedir, canvec.filename(ntsid[[i]]))
for(j in 1:length(layers)) {
ind <- (i-1)*length(layers)+j
layerinfo[[ind]] <- c(directory, canvec.findlayer(directory, layers[j]))
filemeta[[ind]] <- c(ntsstring(ntsid[[i]]), layers[j])
filesto[ind] <- paste(layers[j], paste(ntsid[[i]], collapse=""), sep="_")
}
}

extensions <- c(".cpg", ".dbf", ".prj", ".shp", ".shx")
for(i in 1:length(layerinfo)) {
filefrom <- file.path(layerinfo[[i]][1], layerinfo[[i]][2])
if(is.null(crs) && is.null(driver)) {
#copy files
for(ext in extensions) {
filename <- paste0(filefrom, ext)
if(file.exists(filename)) {
fileto <- paste0(file.path(tofolder, filesto[i]),ext)
cat("Copying", filename, "to", fileto, "\n")
file.copy(filename, fileto, overwrite=TRUE)
if(combine && length(ntsid) > 1) {

for(layer in layers) {
spdf <- do.call(.spatial_rbind, lapply(ntsid, function(n, ...) {
tryCatch(return(canvec.load(n, ...)), error=function(err) {
return(NULL)
})
}, layer))

if(is.null(spdf)) {
next
}

if(is.null(driver)) {
driver <- "ESRI Shapefile"
}

if(driver == "ESRI Shapefile") {
dsn <- tofolder
} else {
if(driver == "KML") {
ext <- ".kml"
} else if(driver == "CSV") {
ext <- ".csv"
} else if(driver == "GML") {
ext <- ".gml"
} else {
cat("*File", filename, "not found. not copied\n")
ext <- driver
}

dsn <- paste0(file.path(tofolder, layer), ext)
}
} else {
#load file, convert crs, then save
if(file.exists(paste0(filefrom, ".shp"))) {
if(is.null(driver)) {
driver <- "ESRI Shapefile"
message("Writing dsn: ", dsn, "; layer: ", layer)
if(is.null(crs)) {
rgdal::writeOGR(spdf, dsn=dsn, layer=layer, driver=driver, overwrite=overwrite, ...)
} else {
rgdal::writeOGR(sp::spTransform(spdf, crs),
dsn=dsn, layer=layer, driver=driver, overwrite=overwrite, ...)
}
}

} else {
layerinfo <- list()
filesto <- rep(NA, length(layers)*length(ntsid))
filemeta <- list()
for(i in 1:length(ntsid)) {
directory = file.path(cachedir, canvec.filename(ntsid[[i]]))
for(j in 1:length(layers)) {
ind <- (i-1)*length(layers)+j
layerinfo[[ind]] <- c(directory, canvec.findlayer(directory, layers[j]))
filemeta[[ind]] <- c(ntsstring(ntsid[[i]]), layers[j])
filesto[ind] <- paste(layers[j], paste(ntsid[[i]], collapse=""), sep="_")
}
}

extensions <- c(".cpg", ".dbf", ".prj", ".shp", ".shx")
for(i in 1:length(layerinfo)) {
filefrom <- file.path(layerinfo[[i]][1], layerinfo[[i]][2])
if(is.null(crs) && is.null(driver)) {
#copy files
for(ext in extensions) {
filename <- paste0(filefrom, ext)
if(file.exists(filename)) {
fileto <- paste0(file.path(tofolder, filesto[i]),ext)
message("Copying ", filename, " to ", fileto, "\n")
file.copy(filename, fileto, overwrite=TRUE)
} else {
message("*File ", filename, " not found. not copied\n")
}
}
if(driver == "ESRI Shapefile") {
dsn <- tofolder
} else {
if(driver == "KML") {
ext <- ".kml"
} else if(driver == "CSV") {
ext <- ".csv"
} else if(driver == "GML") {
ext <- ".gml"
} else {
#load file, convert crs, then save
if(file.exists(paste0(filefrom, ".shp"))) {
if(is.null(driver)) {
driver <- "ESRI Shapefile"
}

if(driver == "ESRI Shapefile") {
dsn <- tofolder
} else {
ext <- driver
if(driver == "KML") {
ext <- ".kml"
} else if(driver == "CSV") {
ext <- ".csv"
} else if(driver == "GML") {
ext <- ".gml"
} else {
ext <- driver
}

dsn <- paste0(file.path(tofolder, filesto[i]), ext)
}

dsn <- paste0(file.path(tofolder, filesto[i]), ext)
}

layer <- filesto[i]

spobj <- rgdal::readOGR(dsn=layerinfo[[i]][1], layer=layerinfo[[i]][2])
if(is.null(crs)) {
rgdal::writeOGR(spobj, dsn=dsn, layer=layer, driver=driver, ...)
layer <- filesto[i]

spobj <- rgdal::readOGR(dsn=layerinfo[[i]][1], layer=layerinfo[[i]][2])
message("Writing dsn: ", dsn, "; layer: ", layer)
if(is.null(crs)) {
rgdal::writeOGR(spobj, dsn=dsn, layer=layer, driver=driver, overwrite=overwrite, ...)
} else {
rgdal::writeOGR(sp::spTransform(spobj, crs),
dsn=dsn, layer=layer, driver=driver, overwrite=overwrite, ...)
}
} else {
rgdal::writeOGR(sp::spTransform(spobj, crs),
dsn=dsn, layer=layer, driver=driver, ...)
message("File ", filefrom, " not found, skipping.")
}
} else {
cat("File", filefrom, "not found, skipping.")
}

}

}

}

#' Remove CanVec Data Files
Expand Down Expand Up @@ -495,4 +546,18 @@ canvec.defaultoptions <- function(layerid) {
}
}

.spatial_rbind <- function(...) {
arglist <- list(...)
lastid <- -1

for(i in 1:length(arglist)) {
rows <- length(arglist[[i]])
if(rows > 0) {
row.names(arglist[[i]]) <- as.character((lastid+1):(lastid+rows))
}
lastid <- lastid + rows
}

do.call(rbind, arglist[!sapply(arglist,is.null)])
}

7 changes: 5 additions & 2 deletions data-raw/canvec_layers.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ canvec_layers <- structure(list(name = c("Navigational aid", "Residential area",
"municipality", "aboriginal_lands", "nts50k_boundary_polygon",
"lookout", "ski_centre", "cemetery", "fort", "marina", "sports_track",
"golf_course", "camp", "drive-in_theatre", "botanical_garden",
"shrine", "historical_site/point_of_interest", "amusement_park",
"park/sports_field", "footbridge", "ruins", "trail", "stadium",
"shrine", "point_of_interest", "amusement_park",
"park", "footbridge", "ruins", "trail", "stadium",
"campground", "picnic_site", "golf_drining_range", "exhibition_ground",
"zoo", "tundra_pond", "palsa_bog", "saturated_soil", "wetland",
"string_bog", "named_feature", "railway", "railway_structure",
Expand Down Expand Up @@ -100,3 +100,6 @@ canvec_layers <- structure(list(name = c("Navigational aid", "Residential area",
row.names = c(NA, -96L))

canvec_layers$geometry_ext <- gsub("point", "_0", gsub("line", "_1", gsub("polygon", "_2", canvec_layers$geometry)))

# no duplicate IDs!
canvec_layers <- canvec_layers[!duplicated(canvec_layers$id),]
Binary file modified data/canvec_layers.rda
Binary file not shown.
6 changes: 5 additions & 1 deletion man/canvec.export.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b44105d

Please sign in to comment.