library(vicspatial)
#> In May 2025 (version 0.3.0) `VicmapR` was renamed to `vicspatial`. Unfortunately this change has been requested by the trademark holders of `VICMAP` (Department of Transport and Planning). While redirections should be in place for GitHub and CRAN websites, please check existing code for explicit mentions of `VicmapR`.
#>
#> Attaching package: 'vicspatial'
#> The following object is masked from 'package:stats':
#>
#> filter
library(sf)
#> Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is TRUE
library(leaflet)
#check sf installation
sf::sf_extSoftVersion()
#> GEOS GDAL proj.4 GDAL_with_GEOS USE_PROJ_H
#> "3.13.0" "3.8.5" "9.5.1" "true" "true"
#> PROJ
#> "9.5.1"
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.
available_layers <- listLayers()
head(available_layers, 10)
#> Name Title
#> 1 open-data-platform:ad_deeca_region ad_deeca_region
#> 2 open-data-platform:ad_lga_area_polygon ad_lga_area_polygon
#> 3 open-data-platform:ad_locality_area_polygon ad_locality_area_polygon
#> 4 open-data-platform:ad_vicgov_region ad_vicgov_region
#> 5 open-data-platform:address address
#> 6 open-data-platform:address_main address_main
#> 7 open-data-platform:address_sup address_sup
#> 8 open-data-platform:altern100_polygon altern100_polygon
#> 9 open-data-platform:anasurv anasurv
#> 10 open-data-platform:annotation_text annotation_text
#> Abstract
#> 1 Part of the Vicmap Admin dataset series. This dataset contains the Department of Energy, Environment and Climate Action (DEECA) Regional Boundaries as defined by DEECA. \nThe regions are based on the Victorian Government Regional Boundaries. The main difference is that the three metropolitan regions have been aggregated to form the Port Phillip region, there are six regions.\nAligned to Road Network - Vicmap Transport.
#> 2 Part of the Vicmap Admin dataset series. This dataset contains Local Government Boundaries (LGA's) polygons. LGA's are as defined by Dept. for Victorian Communities (DVC).\nAligned to Road Network - Vicmap Transport.
#> 3 Part of the Vicmap Admin dataset series. Locality Boundaries Boundary polygons for Victoria. Locality Boundaries are as defined by The Registrar of Geographic Names.\nAligned to Road Network - Vicmap Transport.
#> 4 Part of the Vicmap Admin dataset series. \n\nThis dataset contains the Victorian Government Regional Departmental Boundaries as defined by Local Government Victoria, Dept. of Planning & Community Development (DPCD). There are eight regions.\n\nAligned to Road Network - Vicmap Transport.
#> 5 See the product metadata record VICMAP_ADDRESS (Vicmap Address) ANZVI0803002578 \nTo access the data:- \nhttps://datashare.maps.vic.gov.au/search?q=uuid%3Db9e9146d-8378-5c37-b6cd-63e3a8d05d02\n\nVicmap Address is Victoria's authoritative geocoded database of property address points.
#> 6 <NA>
#> 7 <NA>
#> 8 Changes in the chemical or mineralogical composition of a rock
#> 9 The analog airborne survey index was originally compiled in MapInfo. It contains survey boundary polygons and associated survey metadata that include acquisition parameters. All open file airborne geophysical surveys are included where data were acquired using analog systems.
#> 10 Annotation Text is a point layer belonging to Vicmap Property and consists of point data representing the location of Annotation and Text for Vicmap Property. The points have been attributed with the appropropriate text.\n\nThis layer should be used in conjuction with the other layers and aspatial tables that make up Vicmap Property.
#> metadataID
#> 1 4b6be7f5-01a8-431f-90f8-91e45011dcd0
#> 2 bc822a9c-3766-57ac-a034-bcad3fb66d86
#> 3 6ed3b98f-b277-564a-997e-962be72c5ae8
#> 4 45394ea3-d758-59e2-8937-d8390cc90d7e
#> 5 8f3e3caa-e4bd-5e43-afc4-59b71c1f27f2
#> 6 4ff2aee8-ff0c-55db-b677-efc97b40a50d
#> 7 8323c048-5474-5313-b381-d771b807765c
#> 8 e7a18b45-ea9c-5172-acbd-70aca36cbabe
#> 9 23d0cc28-f727-5b1c-aa54-876fe1590926
#> 10 9128adcc-f8fd-5295-bcac-cc45a7247e8b
vicspatial 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).
# query the watercourse layer
vicmap_query(layer = "open-data-platform:hy_watercourse")
#> • Using collect() on this object will return 1832869
#> • features and 21 fields
#> • At most six rows of the record are printed here
#> ────────────────────────────────────────────────────────────────────────────────
#> Simple feature collection with 6 features and 20 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 141.8898 ymin: -39.01699 xmax: 146.3676 ymax: -34.36471
#> Geodetic CRS: GDA94
#> # A tibble: 6 × 21
#> id ufi pfi feature_type_code name named_feature_id origin
#> <chr> <int> <int> <chr> <chr> <chr> <chr>
#> 1 hy_watercourse.1 3.63e6 9.63e6 watercourse_stre… NA NA 1
#> 2 hy_watercourse.2 3.63e6 9.63e6 watercourse_stre… NA NA 1
#> 3 hy_watercourse.3 3.63e6 9.63e6 watercourse_stre… NA NA 1
#> 4 hy_watercourse.4 2.55e6 8.55e6 watercourse_chan… NA NA 2
#> 5 hy_watercourse.5 2.55e6 8.55e6 watercourse_chan… NA NA 2
#> 6 hy_watercourse.6 2.55e6 8.55e6 watercourse_chan… NA NA 2
#> # ℹ 14 more variables: construction <chr>, usage <chr>, hierarchy <chr>,
#> # auth_org_code <chr>, auth_org_id <chr>, auth_org_verified <chr>,
#> # feature_quality_id <int>, task_id <chr>, create_date_pfi <dttm>,
#> # superceded_pfi <chr>, feature_ufi <int>, feature_create_date_ufi <dttm>,
#> # create_date_ufi <dttm>, geometry <LINESTRING [°]>
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 = "open-data-platform:hy_watercourse") %>%
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()
#> <base url>
#> https://opendata.maps.vic.gov.au/geoserver/ows
#>
#> <body>
#> service: wfs
#> version: 2.0.0
#> request: GetFeature
#> typeNames: open-data-platform:hy_watercourse
#> outputFormat: application/json
#> count: 50
#> srsName: EPSG:4283
#> CQL_FILTER: ("hierarchy" = 'L')
#> propertyName: geom,hierarchy,pfi
#>
#> <full query url>
#> https://opendata.maps.vic.gov.au/geoserver/ows?service=wfs&version=2.0.0&request=GetFeature&typeNames=open-data-platform%3Ahy_watercourse&outputFormat=application%2Fjson&count=50&srsName=EPSG%3A4283&CQL_FILTER=%28%22hierarchy%22%20%3D%20%27L%27%29&propertyName=geom%2Chierarchy%2Cpfi
In order to return a spatial data.frame object (sf
)
collect()
must be used.
watercourse_data <- vicmap_query(layer = "open-data-platform:hy_watercourse") %>%
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'
collect()
str(watercourse_data)
#> sf [50 × 4] (S3: sf/tbl_df/tbl/data.frame)
#> $ id : chr [1:50] "hy_watercourse.1" "hy_watercourse.2" "hy_watercourse.3" "hy_watercourse.4" ...
#> $ pfi : int [1:50] 9627981 9628133 9628125 8547189 8547359 8547370 8547394 8547461 8547592 8547635 ...
#> $ hierarchy: chr [1:50] "L" "L" "L" "L" ...
#> $ geometry :sfc_LINESTRING of length 50; first list element: 'XY' num [1:21, 1:2] 146 146 146 146 146 ...
#> - attr(*, "sf_column")= chr "geometry"
#> - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA
#> ..- attr(*, "names")= chr [1:3] "id" "pfi" "hierarchy"
vicspatial translates numerous geometric filter functions available in the Victorian Government’s WFS Geoserver supports numerous geometric filters:
EQUALS
DISJOINT
INTERSECTS
TOUCHES
CROSSES
WITHIN
CONTAINS
OVERLAPS
DWITHIN
BEYOND
BBOX
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="vicspatial"), quiet = F) %>%
sf::st_transform(4283)
#> Reading layer `melbourne' from data source
#> `/Users/runner/work/_temp/Library/vicspatial/shapes/melbourne.geojson'
#> using driver `GeoJSON'
#> Simple feature collection with 1 feature and 8 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: 144.897 ymin: -37.85066 xmax: 144.9913 ymax: -37.77545
#> Geodetic CRS: WGS 84
# Return data that intersects melbourne
rail_intersects <- vicmap_query(layer = "open-data-platform:tr_rail") %>% # layer to query
filter(INTERSECTS(melbourne)) %>% # more advanced geometric filter
collect()
melbourne_bbox <- sf::st_bbox(melbourne)
rail_bbox <- vicmap_query(layer = "open-data-platform:tr_rail") %>%
filter(BBOX(melbourne_bbox)) %>%
collect()
melbourne_centroid <- sf::st_centroid(melbourne)
rail_dwithin <- vicmap_query(layer = "open-data-platform:tr_rail") %>%
filter(DWITHIN(melbourne_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"))