## ----09-gis-1, message=FALSE------------------------------------------------------------------------
library(sf)
library(terra)
## ----09-gis-1-2, message=FALSE, eval=FALSE----------------------------------------------------------
## # remotes::install_github("r-spatial/qgisprocess")
## library(qgisprocess)
## library(Rsagacmd)
## library(rgrass)
## library(rstac)
## library(gdalcubes)
## A command line interface is a means of interacting with computer programs in which the user issues commands via successive lines of text (command lines).
## `bash` in Linux and `PowerShell` in Windows are its common examples.
## CLIs can be augmented with IDEs such as RStudio for R, which provides code auto-completion and other features to improve the user experience.
## ----gis-comp, echo=FALSE, message=FALSE------------------------------------------------------------
library(dplyr)
d = tibble("GIS" = c("QGIS", "SAGA", "GRASS"),
"First release" = c("2002", "2004", "1982"),
"No. functions" = c(">1000", ">600", ">500"),
"Support" = c("hybrid", "hybrid", "hybrid"))
knitr::kable(x = d,
caption = paste("Comparison between three open-source GIS.",
"Hybrid refers to the support of vector and",
"raster operations."),
caption.short = "Comparison between three open-source GIS.",
booktabs = TRUE) #|>
# kableExtra::add_footnote(label = "Comparing downloads of different providers is rather difficult (see http://spatialgalaxy.net/2011/12/19/qgis-users-around-the-world), and here also useless since every Windows QGIS download automatically also downloads SAGA and GRASS.", notation = "alphabet")
## ---- eval=FALSE------------------------------------------------------------------------------------
## library(qgisprocess)
## #> Using 'qgis_process' at 'qgis_process'.
## #> QGIS version: 3.20.3-Odense
## #> ...
## ----providers, eval=FALSE--------------------------------------------------------------------------
## qgis_providers()
## #> # A tibble: 6 × 2
## #> provider provider_title
## #> <chr> <chr>
## #> 1 3d QGIS (3D)
## #> 2 gdal GDAL
## #> 3 grass7 GRASS
## #> 4 native QGIS (native c++)
## #> 5 qgis QGIS
## #> 6 saga SAGA
## ----09-gis-4---------------------------------------------------------------------------------------
data("incongruent", "aggregating_zones", package = "spData")
incongr_wgs = st_transform(incongruent, "EPSG:4326")
aggzone_wgs = st_transform(aggregating_zones, "EPSG:4326")
## ----uniondata, echo=FALSE, fig.cap="Illustration of two areal units: incongruent (black lines) and aggregating zones (red borders). "----
library(tmap)
tm_shape(incongr_wgs) +
tm_polygons(border.col = "gray5") +
tm_shape(aggzone_wgs) +
tm_borders(alpha = 0.5, col = "red") +
tm_add_legend(type = "line",
labels = c("incongr_wgs", "aggzone_wgs"),
col = c("gray5", "red"),
lwd = 3) +
tm_scale_bar(position = c("left", "bottom"),
breaks = c(0, 0.5, 1)) +
tm_layout(frame = FALSE,
legend.text.size = 1)
## ---- eval=FALSE------------------------------------------------------------------------------------
## qgis_algo = qgis_algorithms()
## ---- eval=FALSE------------------------------------------------------------------------------------
## grep("union", qgis_algo$algorithm, value = TRUE)
## #> [1] "native:union" "saga:fuzzyunionor" "saga:polygonunion"
## ----09-gis-6, eval=FALSE---------------------------------------------------------------------------
## alg = "native:union"
## qgis_show_help(alg)
## ----09-gis-7, eval=FALSE---------------------------------------------------------------------------
## union = qgis_run_algorithm(alg, INPUT = incongr_wgs, OVERLAY = aggzone_wgs)
## union
## ---- eval=FALSE------------------------------------------------------------------------------------
## union_sf = st_as_sf(union)
## ---- eval=FALSE------------------------------------------------------------------------------------
## grep("clean", qgis_algo$algorithm, value = TRUE)
## ---- eval=FALSE------------------------------------------------------------------------------------
## qgis_show_help("grass7:v.clean")
## ----09-gis-7c, eval=FALSE--------------------------------------------------------------------------
## clean = qgis_run_algorithm("grass7:v.clean", input = union_sf,
## tool = 10, threshold = 25000)
## clean_sf = st_as_sf(clean)
## ----sliver, echo=FALSE, fig.cap="Sliver polygons colored in red (left panel). Cleaned polygons (right panel)."----
knitr::include_graphics("images/10-sliver.png")
## ---- eval=FALSE------------------------------------------------------------------------------------
## library(qgisprocess)
## library(terra)
## dem = rast(system.file("raster/dem.tif", package = "spDataLarge"))
## ---- eval=FALSE------------------------------------------------------------------------------------
## dem_slope = terrain(dem, unit = "radians")
## dem_aspect = terrain(dem, v = "aspect", unit = "radians")
## ---- eval=FALSE------------------------------------------------------------------------------------
## qgis_algo = qgis_algorithms()
## grep("wetness", qgis_algo$algorithm, value = TRUE)
## ---- eval=FALSE------------------------------------------------------------------------------------
## qgis_show_help("saga:sagawetnessindex")
## ---- eval=FALSE------------------------------------------------------------------------------------
## dem_wetness = qgis_run_algorithm("saga:sagawetnessindex", DEM = dem)
## ---- eval=FALSE------------------------------------------------------------------------------------
## dem_wetness_twi = qgis_as_terra(dem_wetness$TWI)
## ---- eval=FALSE------------------------------------------------------------------------------------
## grep("geomorphon", qgis_algo$algorithm, value = TRUE)
## qgis_show_help("grass7:r.geomorphon")
## ---- eval=FALSE------------------------------------------------------------------------------------
## dem_geomorph = qgis_run_algorithm("grass7:r.geomorphon", elevation = dem,
## `-m` = TRUE, search = 120)
## ---- eval=FALSE------------------------------------------------------------------------------------
## dem_geomorph_terra = qgis_as_terra(dem_geomorph$forms)
## ----qgis-raster-map, echo=FALSE, fig.cap="Topographic wetness index (TWI, left panel) and geomorphons (right panel) derived for the Mongón study area."----
knitr::include_graphics("images/10-qgis-raster-map.png")
## ---- eval=FALSE------------------------------------------------------------------------------------
## ndvi = rast(system.file("raster/ndvi.tif", package = "spDataLarge"))
## ---- eval=FALSE------------------------------------------------------------------------------------
## library(Rsagacmd)
## ---- eval=FALSE------------------------------------------------------------------------------------
## saga = saga_gis(raster_backend = "terra", vector_backend = "sf")
## ---- eval=FALSE------------------------------------------------------------------------------------
## sg = saga$imagery_segmentation$seed_generation
## ---- eval=FALSE------------------------------------------------------------------------------------
## ndvi_seeds = sg(ndvi, band_width = 2)
## plot(ndvi_seeds$seed_grid)
## ---- eval=FALSE------------------------------------------------------------------------------------
## srg = saga$imagery_segmentation$seeded_region_growing
## ndvi_srg = srg(ndvi_seeds$seed_grid, ndvi, method = 1)
## plot(ndvi_srg$segments)
## ---- eval=FALSE------------------------------------------------------------------------------------
## ndvi_segments = as.polygons(ndvi_srg$segments) |>
## st_as_sf()
## ----sagasegments, echo=FALSE, fig.cap="Normalized difference vegetation index (NDVI, left panel) and NDVi-based segments derived using t he seeded region growing algorithm for the Mongón study area."----
knitr::include_graphics("images/10-saga-segments.png")
## ----09-gis-24--------------------------------------------------------------------------------------
data("cycle_hire", package = "spData")
points = cycle_hire[1:25, ]
## ----09-gis-25, eval=FALSE--------------------------------------------------------------------------
## library(osmdata)
## b_box = st_bbox(points)
## london_streets = opq(b_box) |>
## add_osm_feature(key = "highway") |>
## osmdata_sf()
## london_streets = london_streets[["osm_lines"]]
## london_streets = select(london_streets, osm_id)
## ----09-gis-30, eval=FALSE--------------------------------------------------------------------------
## library(rgrass)
## link2GI::linkGRASS(london_streets, ver_select = TRUE)
## ----09-gis-31, eval=FALSE--------------------------------------------------------------------------
## write_VECT(terra::vect(london_streets), vname = "london_streets")
## write_VECT(terra::vect(points[, 1]), vname = "points")
## ----09-gis-32, eval=FALSE--------------------------------------------------------------------------
## execGRASS(cmd = "v.clean", input = "london_streets", output = "streets_clean",
## tool = "break", flags = "overwrite")
## To learn about the possible arguments and flags of the GRASS GIS modules you can you the `help` flag.
## For example, try `execGRASS("g.region", flags = "help")`.
## ----09-gis-32b, eval=FALSE-------------------------------------------------------------------------
## execGRASS(cmd = "v.net", input = "streets_clean", output = "streets_points_con",
## points = "points", operation = "connect", threshold = 0.001,
## flags = c("overwrite", "c"))
## ----09-gis-33, eval=FALSE--------------------------------------------------------------------------
## execGRASS(cmd = "v.net.salesman", input = "streets_points_con",
## output = "shortest_route", center_cats = paste0("1-", nrow(points)),
## flags = "overwrite")
## ----09-gis-34, eval=FALSE--------------------------------------------------------------------------
## route = read_VECT("shortest_route") |>
## st_as_sf() |>
## st_geometry()
## mapview::mapview(route) + points
## ----grass-mapview, fig.cap="Shortest route (blue line) between 24 cycle hire stations (blue dots) on the OSM street network of London.", fig.scap="Shortest route between 24 cycle hire stations.", echo=FALSE, out.width="80%"----
knitr::include_graphics("images/10_shortest_route.png")
## ----09-gis-35, eval=FALSE, echo=FALSE--------------------------------------------------------------
## library(mapview)
## m_1 = mapview(route) + points
## mapview::mapshot(m_1,
## file = file.path(getwd(), "images/09_shortest_route.png"),
## remove_controls = c("homeButton", "layersControl",
## "zoomControl"))
## ----09-gis-27, eval=FALSE--------------------------------------------------------------------------
## library(link2GI)
## link = findGRASS()
## ---- eval=FALSE------------------------------------------------------------------------------------
## library(rgrass)
## grass_path = link$instDir[[1]]
## initGRASS(gisBase = grass_path, gisDbase = tempdir(),
## location = "london", mapset = "PERMANENT", override = TRUE)
## ----09-gis-29, eval=FALSE--------------------------------------------------------------------------
## execGRASS("g.proj", flags = c("c", "quiet"), srid = "EPSG:4326")
## b_box = st_bbox(london_streets)
## execGRASS("g.region", flags = c("quiet"),
## n = as.character(b_box["ymax"]), s = as.character(b_box["ymin"]),
## e = as.character(b_box["xmax"]), w = as.character(b_box["xmin"]),
## res = "1")
## ---- eval=FALSE------------------------------------------------------------------------------------
## link2GI::linkGDAL()
## ----09-gis-36, eval=FALSE, message=FALSE-----------------------------------------------------------
## our_filepath = system.file("shapes/world.gpkg", package = "spData")
## cmd = paste("ogrinfo -al -so", our_filepath)
## system(cmd)
## #> INFO: Open of `.../spData/shapes/world.gpkg'
## #> using driver `GPKG' successful.
## #>
## #> Layer name: world
## #> Geometry: Multi Polygon
## #> Feature Count: 177
## #> Extent: (-180.000000, -89.900000) - (179.999990, 83.645130)
## #> Layer SRS WKT:
## #> ...
## ----09-gis-37, eval=FALSE--------------------------------------------------------------------------
## library(RPostgreSQL)
## conn = dbConnect(drv = PostgreSQL(),
## dbname = "rtafdf_zljbqm", host = "db.qgiscloud.com",
## port = "5432", user = "rtafdf_zljbqm", password = "d3290ead")
## ----09-gis-38, eval=FALSE--------------------------------------------------------------------------
## dbListTables(conn)
## #> [1] "spatial_ref_sys" "topology" "layer" "restaurants"
## #> [5] "highways"
## ----09-gis-39, eval=FALSE--------------------------------------------------------------------------
## dbListFields(conn, "highways")
## #> [1] "qc_id" "wkb_geometry" "gid" "feature"
## #> [5] "name" "state"
## ----09-gis-40, eval=FALSE--------------------------------------------------------------------------
## query = paste(
## "SELECT *",
## "FROM highways",
## "WHERE name = 'US Route 1' AND state = 'MD';")
## us_route = read_sf(conn, query = query, geom = "wkb_geometry")
## ----09-gis-41, eval=FALSE--------------------------------------------------------------------------
## query = paste(
## "SELECT ST_Union(ST_Buffer(wkb_geometry, 35000))::geometry",
## "FROM highways",
## "WHERE name = 'US Route 1' AND state = 'MD';")
## buf = read_sf(conn, query = query)
## ----09-gis-42, eval=FALSE, warning=FALSE-----------------------------------------------------------
## query = paste(
## "SELECT *",
## "FROM restaurants r",
## "WHERE EXISTS (",
## "SELECT gid",
## "FROM highways",
## "WHERE",
## "ST_DWithin(r.wkb_geometry, wkb_geometry, 35000) AND",
## "name = 'US Route 1' AND",
## "state = 'MD' AND",
## "r.franchise = 'HDE');"
## )
## hardees = read_sf(conn, query = query)
## ----09-gis-43, eval=FALSE--------------------------------------------------------------------------
## RPostgreSQL::postgresqlCloseConnection(conn)
## ----09-gis-44, echo=FALSE--------------------------------------------------------------------------
load("extdata/postgis_data.Rdata")
## ----postgis, echo=FALSE, fig.cap="Visualization of the output of previous PostGIS commands showing the highway (black line), a buffer (light yellow) and four restaurants (red points) within the buffer.", fig.scap="Visualization of the output of previous PostGIS commands."----
# plot the results of the queries
library(tmap)
tm_shape(buf) +
tm_polygons(col = "#FFFDD0", border.alpha = 0.3) +
tm_shape(us_route) +
tm_lines(col = "black", lwd = 3) +
tm_shape(hardees) +
tm_symbols(col = "#F10C26") +
tm_add_legend(type = "line", col = "black", lwd = 3,
labels = "The US Route 1 highway") +
tm_add_legend(type = "fill", col = "#FFFDD0",
border.alpha = 0.3, label = "35km buffer") +
tm_add_legend(type = "symbol", col = "#F10C26",
labels = "Restaurants") +
tm_layout(frame = FALSE,
legend.outside = TRUE,
legend.outside.size = 0.3)
## ----09-stac-example, eval = FALSE------------------------------------------------------------------
## library(rstac)
## # Connect to the STAC-API endpoint for Sentinel-2 data
## # and search for images intersecting our AOI
## s = stac("https://earth-search.aws.element84.com/v0")
## items = s |>
## stac_search(collections = "sentinel-s2-l2a-cogs",
## bbox = c(7.1, 51.8, 7.2, 52.8),
## datetime = "2020-01-01/2020-12-31") |>
## post_request() |> items_fetch()
## ----09-gdalcubes-example, eval = FALSE-------------------------------------------------------------
## library(gdalcubes)
## # Filter images from STAC response by cloud cover
## # and create an image collection object
## collection = stac_image_collection(items$features,
## property_filter = function(x) {x[["eo:cloud_cover"]] < 10})
## # Define extent, resolution (250m, daily) and CRS of the target data cube
## v = cube_view(srs = "EPSG:3857", extent = collection, dx = 250, dy = 250,
## dt = "P1D") # "P1D" is an ISO 8601 duration string
## # Create and process the data cube
## cube = raster_cube(collection, v) |>
## select_bands(c("B04", "B08")) |>
## apply_pixel("(B08-B04)/(B08+B04)", "NDVI") |>
## reduce_time("max(NDVI)")
## # gdalcubes_options(parallel = 8)
## # plot(cube, zlim = c(0, 1))
## ----09-openeo-example, eval=FALSE------------------------------------------------------------------
## library(openeo)
## con = connect(host = "https://openeo.cloud")
## p = processes() # load available processes
## collections = list_collections() # load available collections
## formats = list_file_formats() # load available output formats
## # Load Sentinel-2 collection
## s2 = p$load_collection(id = "SENTINEL2_L2A",
## spatial_extent = list(west = 7.5, east = 8.5,
## north = 51.1, south = 50.1),
## temporal_extent = list("2021-01-01", "2021-01-31"),
## bands = list("B04","B08"))
## # Compute NDVI vegetation index
## compute_ndvi = p$reduce_dimension(data = s2, dimension = "bands",
## reducer = function(data, context) {
## (data[2] - data[1]) / (data[2] + data[1])
## })
## # Compute maximum over time
## reduce_max = p$reduce_dimension(data = compute_ndvi, dimension = "t",
## reducer = function(x, y) {max(x)})
## # Export as GeoTIFF
## result = p$save_result(reduce_max, formats$output$GTiff)
## # Login, see https://docs.openeo.cloud/getting-started/r/#authentication
## login(login_type = "oidc", provider = "egi",
## config = list(client_id = "...", secret = "..."))
## # Execute processes
## compute_result(graph = result, output_file = tempfile(fileext = ".tif"))
## ---- echo=FALSE, results='asis'--------------------------------------------------------------------
res = knitr::knit_child('_10-ex.Rmd', quiet = TRUE,
options = list(include = FALSE, eval = FALSE))
cat(res, sep = '\n')
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.