The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
This vignette focuses on loading, intersecting and comparing multiple (3 to 5) LCZ maps on the same area or set of areas. The first part of the vignette describes the recommended pipeline, which should cover most of the cases.
Some specific functions are described later on for more specific cases.
Note : Only vector workflows (as opposed to raster) can be processed
when comparing more than 2 workflows.
lczexplore::importLCZraster function allows to import
raster images with an LCZ band and sf::write_sf re-exports
them, for instance to FlatGeobuf (.fgb)
Climate change is a growing concern for city planners. Stewardt and Oke have proposed a classification into Local Climate Zones (LCZ) that describes rural and urban areas, with 10 built types and 7 land cover types. Several workflows allow to produce LCZ maps, and none can be considered as an absolute reference. Therefore, there is a need for comparison of maps produced by different workflows on the same area.
This vignette shows how to compare 3 workflows (i.e. their resulting maps) at a time. The process can be extended to more maps, but graphical outputs may become hard to read for more than 4 or 5 workflows.
This package does not produce LCZ maps, but imports, shows and compare maps from standard GIS format, with a prefered input format in flatGeoBuffer (.fgb).
Each LCZ map partitions the territory into spatial units, for instance regular grid when based on raster image, or topographic spatial units. Each spatial unit is assigned a LCZ type. When comparing different maps, one needs to intersect all spatial units to obtain units common to all maps. On each intersected unit, it is then possible to look if two workflows agree or disagree.
The most generic case study is when several maps are available for several locations. A simple folder tree allows an easy analysis.
When several LCZ maps are available for several places and stored into local files, the following data structure allows an easier analysis.
–main_data_directory
|–location1
|--wf1_lcz.fgb
|--wf2_lcz.fgb
|--wfp_lcz.fgb
|–location2
|--wf1_lcz.fgb
|--wf2_lcz.fgb
|--wfp_lcz.fgb
The main data directory must contain only the data subdirectories, as the loading functions will span the subdirectories searching for data.
In each subdirectory, the data are stored in files named
wfNamei_lcz.fgb where
Other spatial extensions may work, but .fgb files are
recommended and were the most tested.
Import. First, all the data is loaded in a list.
This list contains a sublist for each location, and each location sublist contains one sf object for each LCZ map.
Intersection. Second, the spatial units of all maps (i.e. the geometries bearing the LCZ type) are intersected. On any resulting geometry, a pair of workflow either totally agree or totally disagree. Intersection is done within lists, which allows to try to intersect only geometries of the same location. The result is concatenated in a single sf objects which contains a column for each lcz map, named after the workflow it comes from, a column with the location name, a column with the area and a column with the geometry for each intersected spatial unit.
Visualisation
Simple descriptive barplots give a general idea of the behavior of the different workflows.
Pairwise comparison allow a visual correspondence between 2 workflows.
Circular Chord Diagram allow a simultaneous visualization of correspondences between all workflows.
Numerical Comparison
Pairwise agreement between workflow and consensus value for each LCZ type quantify this comparison.
In case of several workflows and several locations, the function
importMultipleLocsLCZvect allow to load all the data in a
list.
In the data structure from above section, the function would be
applied to the main_directory folder.
The small data files for this vignette are in the
inst/extdata/multipleWfs folder, which contains the
locations Arville and Redon, for which three LCZ maps are available,
produced by the following workflows : - GeoClimate based on
OpenStreetMap input data - GeoClimate based on french Geographical
Information Institute database called BDTOPO - WUDAPT, based on
satellite images and machine learning.
require(lczexplore)
twoLocsDir<-paste0(
system.file("extdata", package = "lczexplore"),"/multipleWfs")
twoLocsSfList<-importMultipleLocsLCZvect(dirPath = twoLocsDir, workflowNames = c("osm","bdt","wudapt"),
location = c("Arville", "Redon"))
#> The data will be imported from the following folders :/tmp/RtmppWIPZu/Rinst132c522a1db42/lczexplore/extdata/multipleWfs/ArvilleThe data will be imported from the following folders :/tmp/RtmppWIPZu/Rinst132c522a1db42/lczexplore/extdata/multipleWfs/Redon
#> The locations are :ArvilleThe locations are :Redon
#> The names of the LCZ types columns were mis-specified, attempt to load with default 'lcz_primary' name
#> Column lcz_primary not found,but LCZ_PRIMARY was, trying with it
#> Column lcz_primary not found,but LCZ_PRIMARY was, trying with it
#> Column lcz_primary not found,but LCZ_PRIMARY was, trying with it
#> Column lcz_primary not found,but LCZ_PRIMARY was, trying with itThe function importMultipleLocsLCZvect loads all the
input .fgb files in a list.
When comparing maps for only one location use the similar function
importMultipleLCZvect.
The spatial units
In the case of only two workflows, the function
compareLCZ loads the two sf objects,
intersects their geometries, produce the array of correspondance between
the LCZ types of the two workflows.
With more than two workflows, one needs more control over the intersection steps. First, in case of multiple locations, the intersection of the several workflows must occur within each location. Second, intersecting the spatial units of multiple workflows can lead to artificially small geometries.
The createIntersect function allows to specify a minimal
area threshold. Resulting geometries whose area are lesser than this
threshold will be discarded.
twoLocsSfIntersected <- createIntersect(sfList = twoLocsSfList, columns = rep("lcz_primary", 4),
refCrs=NULL, workflowNames=c("osm", "bdt", "wudapt"), minZeroArea=0.000)
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometriesNote : the function createIntersect is able to see if
the list fed to the sfList argument has one or two levels, i.e. if there
are one or multiple locations.
The twoLocsSfList list contains one sf object per
workflow per location. This sf object can be fed to the function
showLCZ() for a map and a summary of the area classified in
each LCZ type.
One can also compare two maps from the same location using the
function compareLCZ()
Note : for only 2 maps, the user feeds compareLCZ the sf files, the function does the intersection.
redonOSM <- twoLocsSfList$Redon$osm
redonBDT <- twoLocsSfList$Redon$bdt
compareLCZ(sf1 = redonOSM, sf2 = redonBDT, column1 = "lcz_primary", column2 = "lcz_primary", wf1 = "osm", wf2 = "bdt_V_2")
#> The column lcz_primary of the dataset sf1 is the reference against which the lcz_primary column of the dataset sf2 will be compared.
#> For Technical reason in this package, worfklow names can't contain spaces or underscores, they were replaced by dots
#> Both sf datasets need to live in the same crs projection (srid / epsg),
#> they will be coerced to the specified reference (sf1)
#> Warning: Unknown or uninitialised column: `location`.
#> Warning: Unknown or uninitialised column: `wf`.
#> Warning: Unknown or uninitialised column: `location`.
#> Warning: Unknown or uninitialised column: `wf`.
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometriesThe function barplotLCZfromIntersected allows the
visualisation of what area is classified into each LCZ type of each
workflow.
areaPerLCZtype<-barplotLCZfromIntersect(sfIn = twoLocsSfIntersected, workflowNames = c("osm", "bdt", "wudapt"))
#> The names of the columns of the lcz types for each workflow are missing, an attempt will be made with workflowNames insteadThe function compareMultipleLCZ outputs a list
containing two objects. The first one is an sf object, named sfInt. It
contains the LCZ type for each workflow, the pairwise agreements, and
the number of workflows who agree for each geometry (ie, intersected
spatial units).
twoLocsCompared <- compareMultipleLCZ(
sfInt = twoLocsSfIntersected,
columns = c("osm","bdt","wudapt"),
trimPerc = 0)
#> This function computes how any LCZ type from any workflow
#> breaks into the LCZ types of all other workflows: it can take a while
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Only standard LCZ levels detected, standard colors and labels used
#> Note: 3 points are out of plotting region in sector 'bdt_002', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_002', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_003', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_003', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_005', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_006', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_006', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_006', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_008', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_008', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_008', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_009', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_009', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_009', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_101', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_101', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_101', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_102', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_102', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_102', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_104', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_104', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_104', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_105', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_105', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_106', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_107', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_107', track
#> '2'.
## Pairwise agreements From this sfInt object, the function
workflowAgreeAreas compute pairwise agreement between
workflows, defined as the sum (or percentage) of the area on which two
workflows agree. It is also directly given as an output of
compareMultipleLCZ()
twoLocsCompared$agreements
#> whichWfs areaAgree areaDisagree percAgree
#> 1 osm_wudapt 11556485.4 1330970.1 89.67236
#> 2 osm_bdt 831817.6 755647.3 52.39911
#> 3 bdt_wudapt 500523.3 1086941.6 31.52972To explore this agreement further, we compute all the repartition
from an LCZ type from a workflow to the LCZ types of another workflow,
using the function createWeightedFlux
twoLocsFlow<-createWeightedFlux(twoLocsSfIntersected, wfNamesIn = c("osm","bdt","wudapt"))
#> This function computes how any LCZ type from any workflow
#> breaks into the LCZ types of all other workflows: it can take a while
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, 106, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, 106, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, 106, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 5, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 5, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 5, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, 106, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, 106, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, 106, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 5, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 5, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 5, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, Unclassified
#> Warning: Unknown levels in `f`: 1, 4, 7, 10, 103, UnclassifiedTo avoid exploring all the pairwise possible matrices, we can explore
these correspondences through a circular chord diagram, using the
function drawChordDiagram.
drawChordDiagram(weightedFluxIn = twoLocsFlow)
#> Only standard LCZ levels detected, standard colors and labels used
#> Note: 3 points are out of plotting region in sector 'bdt_002', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_002', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_003', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_003', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_005', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_006', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_006', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_006', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_008', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_008', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_008', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_009', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_009', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_009', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_101', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_101', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_101', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_102', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_102', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_102', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_104', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_104', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'wud_104', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_105', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_105', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_106', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'bdt_107', track
#> '2'.
#> Note: 3 points are out of plotting region in sector 'osm_107', track
#> '2'.#> [[1]]
#> NULL
#>
#> [[2]]
#> NULL
#>
#> [[3]]
#> NULL
#>
#> [[4]]
#> NULL
#>
#> [[5]]
#> NULL
#>
#> [[6]]
#> NULL
#>
#> [[7]]
#> NULL
#>
#> [[8]]
#> NULL
#>
#> [[9]]
#> NULL
#>
#> [[10]]
#> NULL
#>
#> [[11]]
#> NULL
#>
#> [[12]]
#> NULL
This treatment is also directly done in compareMultipleLCZ, but as
circlize doesn’t create an object (like ggplot2 does) it can not be
exported as an object, so you have to recall
drawChordDiagram.
When, for a location, some workflows have missing geometries,
i.e. don’t map some area and leave them as holes, one can put a zone.fgb
file in the directory, and the function
importConcatMultipleLocsLCZvect will allow to use it and
create the missing geometries and assign them a given type. Feed the
name of the workflow whose geometries are missing to the
missingGeomWf argument, and the function will intersect it
with the zone.fgb geometries. Sometimes, the missing
geometries can be of one type, as a decision from the designers of the
LCZ workflow. In this case, one can choose another workflow as a
reference (through refWf) and the corresponding LCZ typ
(through refLCZ). The remaining geometries which wouldn’t
intersect with the Chosen LCZ type of the chosen reference workflow will
receive the value fed to residualLCZvalue.
twoLocsDir<-paste0(
system.file("extdata", package = "lczexplore"),"/multipleWfs")
# allWfsAllLocs<-importConcatMultipleLocsLCZvect(twoLocsDir, locations = NA, workflowNames = c("osm", "bdt", "wudapt"),
# missingGeomsWf= "osm", refWf = NULL, refLCZ = NA,
# residualLCZvalue = NA, column = "lcz_primary")These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.