How to Query Vicmap Data

2021-06-10

library(VicmapR)
#> 
#> Attaching package: 'VicmapR'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(leaflet)

#check sf installation
sf::sf_extSoftVersion()
#>           GEOS           GDAL         proj.4 GDAL_with_GEOS     USE_PROJ_H 
#>        "3.9.0"        "3.2.1"        "7.2.1"         "true"         "true"

How to query data

Searching for data

In order to begin a query of the WFS server a spatial layer must be selected. To know which layers are available use the listLayers() function, which will return ~ 690 layers to choose from.

Vicmap promise

VicmapR introduces a new class called vicmap_promise, which is an extension to the httr::url class. Essentially this object is how the vicmap query is stored before data is collected. That is to say vicmap_promise is essentially a promise of what data will be retrieved.

In order to generate a new promise the vicmap_query function can be used to select the layer. The promise prints a sample of the data (max = 6 rows) as well as the dimensions (nrow and ncol).

Adding arguments to the query

The vicmap_promise object can be easily added to through piping in of additional functions (e.g. head(), filter() and select()).

The resulting query can be displayed using the show_query() function, which will list the WFS parameters.

vicmap_query(layer = "datavic:VMHYDRO_WATERCOURSE_DRAIN") %>%
  head(50) %>% #return only 50 rows
  filter(HIERARCHY == "L") %>% # filter the column 'HIERACHY' to values of 'L'
  select(HIERARCHY, PFI) %>% # select columns 'HIERARCHY' and 'PFI'
  show_query()
#> Note: method with signature 'DBIConnection#character' chosen for function 'dbQuoteIdentifier',
#>  target signature 'wfsConnection#ident'.
#>  "wfsConnection#ANY" would also be valid
#> Note: method with signature 'DBIConnection#character' chosen for function 'dbQuoteIdentifier',
#>  target signature 'wfsConnection#character'.
#>  "wfsConnection#ANY" would also be valid
#> Note: method with signature 'DBIConnection#character' chosen for function 'dbQuoteString',
#>  target signature 'wfsConnection#character'.
#>  "wfsConnection#ANY" would also be valid
#> <base url>
#> http://services.land.vic.gov.au/catalogue/publicproxy/guest/dv_geoserver/wfs
#> 
#> <body>
#> service: wfs 
#> version: 2.0.0 
#> request: GetFeature 
#> typeNames: datavic:VMHYDRO_WATERCOURSE_DRAIN 
#> outputFormat: application/json 
#> count: 50 
#> srsName: EPSG:4283 
#> CQL_FILTER: ("HIERARCHY" = 'L') 
#> propertyName: SHAPE,HIERARCHY,PFI 
#> 
#> <full query url>
#> http://services.land.vic.gov.au/catalogue/publicproxy/guest/dv_geoserver/wfs?service=wfs&version=2.0.0&request=GetFeature&typeNames=datavic%3AVMHYDRO_WATERCOURSE_DRAIN&outputFormat=application%2Fjson&count=50&srsName=EPSG%3A4283&CQL_FILTER=%28%22HIERARCHY%22%20%3D%20%27L%27%29&propertyName=SHAPE%2CHIERARCHY%2CPFI

In order to return a spatial data.frame object (sf) collect() must be used.

Geometric filters

VicmapR translates numerous geometric filter functions available in the Victorian Government’s WFS Geoserver supports numerous geometric filters:

These filters can be used within the filter() function by providing them an object of class sf/sfc/sfg/bbox. Below is a leaflet map with the melbourne rail network being read in with the use of three different types of filter functions: INTERSECTS(), BBOX() and DWITHIN().

#### Return objects that intersect melbourne ####
# Read in an example shape to restrict our query to using geometric filtering
melbourne <- sf::st_read(system.file("shapes/melbourne.geojson", package="VicmapR"), quiet = F) %>% 
  sf::st_transform(4283)
#> Reading layer `melbourne' from data source `C:\Users\local_callyj\Temp\RtmpCMUTsd\Rinst5a0528b201d\VicmapR\shapes\melbourne.geojson' using driver `GeoJSON'
#> Simple feature collection with 1 feature and 8 fields
#> geometry type:  MULTIPOLYGON
#> dimension:      XY
#> bbox:           xmin: 144.897 ymin: -37.85066 xmax: 144.9913 ymax: -37.77545
#> geographic CRS: WGS 84

# Return data that intersects melbourne
rail_intersects <- vicmap_query(layer = "datavic:VMTRANS_TR_RAIL") %>% # layer to query
  filter(INTERSECTS(melbourne)) %>% # more advanced geometric filter
  collect()

rail_bbox <- vicmap_query(layer = "datavic:VMTRANS_TR_RAIL") %>%
  filter(BBOX(sf::st_bbox(melbourne))) %>%
  collect()

rail_dwithin <- vicmap_query(layer = "datavic:VMTRANS_TR_RAIL") %>%
  filter(DWITHIN(melbourne %>% sf::st_centroid(), distance = 10000, units = "meters")) %>%
  collect()

leaflet(width = "100%") %>%
  addProviderTiles("CartoDB.Positron") %>%
  addPolygons(data = melbourne, color = "grey", group = "Melbourne polygon") %>%
  addPolygons(data = sf::st_bbox(melbourne) %>% st_as_sfc(), color = "black", group = "Melbourne bbox") %>%
  addPolylines(data = rail_intersects, color = "Red", group = "INTERSECTS") %>% 
  addPolylines(data = rail_bbox, color = "Blue", group = "BBOX") %>%
  addPolylines(data = rail_dwithin, color = "Green", group = "DWITHIN") %>%
  addLayersControl(baseGroups = c("Melbourne polygon", "Melbourne bbox"), 
                   overlayGroups = c("INTERSECTS", "BBOX", "DWITHIN")) %>%
  hideGroup(c("BBOX", "DWITHIN"))