Skip to content

Commit

Permalink
projection support, remove bboxtools for rcanvec dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
paleolimbot committed Oct 17, 2015
1 parent 6c0e2ff commit fc2a852
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 236 deletions.
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: rcanvec
Type: Package
Title: Access and Plot CanVec and CanVec+ Data for Rapid Basemap Creation in Canada
Version: 0.1.3.9000
Date: 2015-10-05
Version: 0.1.3
Date: 2015-10-17
Author: Dewey Dunnington <dewey@fishandwhistle.net>
Maintainer: Dewey Dunnington <dewey@fishandwhistle.net>
Description: Provides an interface to the National Topographic System (NTS), which is
Expand All @@ -18,4 +18,4 @@ Imports: rjson, sp, digest, rgdal
URL: https://github.com/paleolimbot/rcanvec
BugReports: http://github.com/paleolimbot/rcanvec
LazyData: true
Suggests: testthat
Suggests: prettymapr, testthat
3 changes: 0 additions & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export(canvec.loadfromdir)
export(canvec.plot)
export(canvec.qplot)
export(canvec.url)
export(makebbox)
export(nts)
export(nts.SCALE250K)
export(nts.SCALE50K)
Expand All @@ -20,5 +19,3 @@ export(nts.bbox)
export(nts.bybbox)
export(nts.idat)
export(ntsstring)
export(searchbbox)
export(zoom)
90 changes: 0 additions & 90 deletions R/bboxtools.R

This file was deleted.

103 changes: 80 additions & 23 deletions R/canvec.R
Original file line number Diff line number Diff line change
Expand Up @@ -229,24 +229,34 @@ canvec.loadfromdir <- function(directory, layerid) {

#' Export CanVec Data
#'
#' Export \code{layerids} for one or more NTS reference(s) \code{ntsid} to path \code{tofolder},
#' automatically renaming layers based on their layerid. Generates warnings if files
#' cannot be found.
#' Export \code{layers} for one or more NTS reference(s) \code{ntsid} to path \code{tofolder},
#' automatically renaming layers based on their layerid. Pass \code{crs} to re-project data,
#' or pass \code{driver} to convert file format.
#'
#' @param ntsid One or more NTS References as generated by \code{nts()}
#' @param tofolder A directory to which files should be copied.
#' @param layerids One or more layer ids as listed in \code{canvec_layers$id}. Defaults to
#' @param layers One or more layer ids as listed in \code{canvec_layers$id}. Defaults to
#' all layers.
#' @param crs A CRS (as generated by \code{sp::CRS()}) in which to project the data.
#' @param driver A \code{rgdal} driver with which to save data. \code{ESRI Shapefile},
#' \code{KML}, \code{CSV}, and \code{GML} have been tested; others returned by
#' \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()}
#'
#' @examples
#' \donttest{
#' canvec.export(nts("21h01"), "~/canvecdata", layerids=c("road", "river"))
#' download(nts("21h01"))
#' canvec.export(nts("21h01"), "exporteddata", layers=c("road", "river"))
#' canvec.export(nts("21h01"), "exporteddataUTM", layers=c("road", "river"),
#' crs=sp::CRS("+init=epsg:26920"))
#' canvec.export(nts("21h01"), "exporteddata", layers=c("road", "river"),
#' driver="KML")
#' canvec.export(nts("21h01"), "exporteddataALL")
#' }
#'
#' @export
canvec.export <- function(ntsid, tofolder, layerids=NULL, cachedir=NULL) {
canvec.export <- function(ntsid, tofolder, layers=NULL, crs=NULL, cachedir=NULL, driver=NULL) {

dir.create(tofolder)

Expand All @@ -256,34 +266,74 @@ canvec.export <- function(ntsid, tofolder, layerids=NULL, cachedir=NULL) {
if(is.null(cachedir)) {
cachedir <- canvec.cachedir()
}
if(is.null(layerids)) {
if(is.null(layers)) {
canvec_layers <- NULL #hack because data(canvec_layers) will load to variable
utils::data(canvec_layers, envir=environment())
layerids <- canvec_layers$id
layers <- canvec_layers$id
}

layerinfo <- list()
filesto <- rep(NA, length(layerids)*length(ntsid))
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(layerids)) {
ind <- (i-1)*length(layerids)+j
layerinfo[[ind]] <- c(directory, canvec.findlayer(directory, layerids[j]))
filesto[ind] <- file.path(tofolder,
paste(layerids[j], paste(ntsid[[i]], collapse=""), sep="_"))
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)) {
for(ext in extensions) {
filefrom <- file.path(layerinfo[[i]][1], paste0(layerinfo[[i]][2], ext))
if(file.exists(filefrom)) {
fileto <- paste0(filesto[i],ext)
cat("Copying", filefrom, "to", fileto, "\n")
file.copy(filefrom, fileto, overwrite=TRUE)
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)
} else {
cat("*File", filename, "not found. not copied\n")
}
}
} 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 {
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)
}

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)
} else {
rgdal::writeOGR(sp::spTransform(spobj, crs),
dsn=dsn, layer=layer, driver=driver)
}
} else {
cat("*File", filefrom, "not found. not copied\n")
cat("File", filefrom, "not found, skipping.")
}
}

Expand Down Expand Up @@ -380,14 +430,15 @@ canvec.cleanup <- function(ntsid=NULL, cachedir=NULL, all=FALSE,
#' generated by \code{canvec.load()}
#' @param options A \code{list} object with the graphical options to be applied
#' to the layers specified
#' @param crs A CRS (as generated by \code{sp::CRS()}) in which to project the data.
#' @param add TRUE if layer or layers should be added to the current plot, FALSE
#' if all layers should be plotted on a fresh plot (not reccomended) or NULL for
#' default behaviour, which will create a new plot for the first layer and add
#' each subsequent layer
#'
#' @export
#'
canvec.plot <- function(loaded, options=NULL, add=NULL) {
canvec.plot <- function(loaded, options=NULL, crs=NULL, add=NULL) {
if(class(loaded)!="list") {
loaded <- list(loaded)
}
Expand All @@ -396,11 +447,17 @@ canvec.plot <- function(loaded, options=NULL, add=NULL) {
}
added=FALSE
for(layer in loaded) {
options$x <- layer
if(is.null(crs)) {
options$x <- layer
} else {
options$x <- sp::spTransform(layer, crs)
}

if(is.null(add) && !added) {
options$add <- TRUE
}
options$add <- add

do.call(sp::plot, options)
added=TRUE
}
Expand Down
51 changes: 40 additions & 11 deletions R/canvec.qplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,23 @@
#' @param atscale One of \code{nts.SCALE50K} (CanVec data) or \code{nts.SCALE250K} (CanVec+ data)
#' @param stoponlargerequest Stop if a large (greater than 4 tiles) area is requested. Defaults to
#' \code{TRUE}.
#' @param ... A list of graphical parameters passed to the inital call to \code{plot()}.
#' @param epsg The epsg code in which to plot the data, or \code{NULL} for automatic. Use
#' \code{epsg=3857} to layer on Open Street Map tiles, or \code{epsg=269XX} (where \code{XX}
#' is the UTM Zone) for a UTM projection. Defaults to no projection, although \code{sp::plot}
#' adjusts the aspect such that the default does not appear distorted.
#' @param ... A list of graphical parameters passed to the inital call to \code{plot()}. Use
#' \code{add=TRUE} to layer on an existing plot.
#' @return A list object that contains the Spatial* data that was plotted
#'
#' @examples
#' \donttest{
#' #simplest use using searchbbox()
#' canvec.qplot(bbox=searchbbox("Wolfville NS"))
#' canvec.qplot(bbox=searchbbox("Wolfville NS"), layers=c("waterbody", "forest"))
#'
#' #be careful with large areas and lots of layers
#' canvec.qplot(bbox=searchbbox("Toronto, ON")) #will take ~10 minutes to plot
#' #simplest use using searchbbox() from {prettymapr}
#' library(prettymapr)
#' wolfville <- searchbbox("Wolfville NS", source="google")
#' canvec.qplot(bbox=wolfville)
#' canvec.qplot(bbox=wolfville, layers=c("waterbody", "forest"))
#'
#' #can also plot by NTS sheet and use bbox= or xlim, ylim to zoom.
#' canvec.qplot(nts("21h1"), layers=c("waterbody", "forest", "contour", "river", "road"))
#' canvec.qplot(bbox=makebbox(45.1, -64.35, 45.05, -64.4),
#' layers=c("waterbody", "contour", "river", "building", "road"))
Expand All @@ -54,7 +59,14 @@
canvec.qplot <- function(ntsid=NULL, bbox=NULL,
layers=c("waterbody", "forest", "contour", "river", "road"),
options=NULL, data=NULL, cachedir=NULL, plotdata=TRUE, atscale=nts.SCALE50K,
stoponlargerequest=TRUE, ...) {
stoponlargerequest=TRUE, epsg=NULL, ...) {

if(!is.null(epsg)) {
crs <- sp::CRS(paste0("+init=epsg:", epsg))
} else {
crs <- NULL
}

if(!is.null(bbox)) {
if(is.null(ntsid)) {
ntsid <- nts(bbox=bbox, atscale = atscale)
Expand All @@ -63,6 +75,13 @@ canvec.qplot <- function(ntsid=NULL, bbox=NULL,
" mapsheets. This may download a large amount of data and/or take a",
" very long time to load. Rerun with stoponlargerequest=FALSE to continue.")
}
if(!is.null(crs)) {
#transform bbox
coords <- sp::coordinates(
sp::spTransform(
sp::SpatialPoints(sp::coordinates(t(bbox)), sp::CRS("+init=epsg:4326")), crs))
bbox <- t(coords)
}
xlim <- bbox[1,]
ylim <- bbox[2,]
} else if(is.null(ntsid)) {
Expand Down Expand Up @@ -113,8 +132,17 @@ canvec.qplot <- function(ntsid=NULL, bbox=NULL,
} else {
bbox1 = nts.bbox(ntsid)
}
coords <- sp::coordinates(t(bbox1))
spoints = sp::SpatialPoints(coords, proj4string = sp::CRS("+proj=longlat +ellps=GRS80 +no_defs"))

if(!is.null(crs)) {
coords <- sp::coordinates(t(bbox1))
spoints <- sp::SpatialPoints(coords, proj4string = sp::CRS("+proj=longlat +ellps=GRS80 +no_defs"))
spoints <- sp::spTransform(spoints, crs)
coords <- sp::coordinates(spoints)
bbox1 <- t(coords)
} else {
coords <- sp::coordinates(t(bbox1))
spoints <- sp::SpatialPoints(coords, proj4string = sp::CRS("+proj=longlat +ellps=GRS80 +no_defs"))
}

plotargs <- list(...)
if(is.null(bbox)) {
Expand All @@ -123,14 +151,15 @@ canvec.qplot <- function(ntsid=NULL, bbox=NULL,
if(is.null(plotargs$ylim))
ylim <- bbox1[2,]
}

sp::plot(spoints, pch=".", xlim=xlim, ylim=ylim, ...)

#plot data
for(layerid in layers) {
layeropts <- options[[layerid]]
if(is.null(layeropts))
layeropts <- canvec.defaultoptions(layerid)
canvec.plot(data[[layerid]], layeropts, add=TRUE)
canvec.plot(data[[layerid]], layeropts, crs=crs, add=TRUE)
}

}
Expand Down
Loading

0 comments on commit fc2a852

Please sign in to comment.