Git Product home page Git Product logo

openland's Introduction

OpenLand

R-CMD-check codecov License: GPL v3 CRAN status

OpenLand is an open-source R package for the analysis of land use and cover (LUC) time series. It includes support for consistency check and loading spatiotemporal raster data and synthesized spatial plotting. Several LUC change (LUCC) metrics in regular or irregular time intervals can be extracted and visualized through one- and multistep sankey and chord diagrams. A complete intensity analysis according to (Aldwaik and Pontius 2012) is implemented, including tools for the generation of standardized multilevel output graphics.

Installation

Install the released version of OpenLand from CRAN:

install.packages("OpenLand")

Or install the development version from GitHub with:

# install.packages("devtools")
devtools::install_github("reginalexavier/OpenLand")

Illustrative Example

This is a basic example which shows how OpenLand works, for a more detailed illustration, please see our vignettes.

The OpenLand functionality is illustrated for a LUC dataset of São Lourenço river basin, a major Pantanal wetland contribution area as provided by the 4th edition of the Monitoring of Changes in Land cover and Land Use in the Upper Paraguay River Basin - Brazilian portion - Review Period: 2012 to 2014 (Embrapa Pantanal, Instituto SOS Pantanal, and WWF-Brasil 2015). The time series is composed by five LUC maps (2002, 2008, 2010, 2012 and 2014). The study area of approximately 22,400 km2 is located in the Cerrado Savannah biom in the southeast of the Brazilian state of Mato Grosso. For processing in the OpenLand package, the original multi-year shape file was transformed into rasters and then saved as a 5-layer RasterStack (SaoLourencoBasin), available from a public repository (10.5281/zenodo.3685229) as an .RDA file which can be loaded into R.

# Loading the package
library(OpenLand)
What is Intensity Analysis?

Intensity Analysis (IA) is a quantitative method to analyze LUC maps at several time steps, using cross-tabulation matrices, where each matrix summarizes the LUC change at each time interval. IA evaluates in three levels the deviation between observed change intensity and hypothesized uniform change intensity. Hereby, each level details information given by the previous analysis level. First, the interval level indicates how size and rate of change varies across time intervals. Second, the category level examines for each time interval how the size and intensity of gross losses and gross gains in each category vary across categories for each time interval. Third, the transition level determines for each category how the size and intensity of a category’s transitions vary across the other categories that are available for that transition. At each level, the method tests for stationarity of patterns across time intervals (Aldwaik and Pontius 2012).

Outcomes of intensity analysis

The data is extracted from the rasters with the contingencyTable() function which returns a multiple grid information in tables for the next processing steps. Within the OpenLand package, the intensityAnalysis() function computes the three levels of analysis. It requires the object returned by the contingenceTable() function and that the user predefines two LUC categories n and m. Generally, n is a target category which experienced relevant gains and m a category with important losses.

my_test <- intensityAnalysis(dataset = SL_2002_2014, # here the outcome from the `contingenceTable()` function
                            category_n = "Ap", category_m = "SG")

# it returns a list with 6 objects
names(my_test)
#> [1] "lulc_table"           "interval_lvl"         "category_lvlGain"    
#> [4] "category_lvlLoss"     "transition_lvlGain_n" "transition_lvlLoss_m"

The intensityAnalysis() function returns 6 objects: lulc_table, interval_lvl, category_lvlGain, category_lvlLoss, transition_lvlGain_n, transition_lvlLoss_m. Here, we adopted an object-oriented approach that allows to set specific methods for plotting the intensity objects. Specifically, we used the S4 class, which requires the formal definition of classes and methods (Chambers 2008).

Presentation of an intensity object

In this example we will show an object from Category class. A Category object contains three slots: the first contains the colors associated with the legend items as name attributes, the second slot contains a table of the category level result (gain (Gtj) or loss (Lti) values) and the third slot contains a table storing the results of a stationarity test.

my_test$category_lvlGain
#> An object of class "Category"
#> Slot "lookupcolor":
#>        Ap        FF        SA        SG        aa        SF      Agua        Iu 
#> "#FFE4B5" "#228B22" "#00FF00" "#CAFF70" "#EE6363" "#00CD00" "#436EEE" "#FFAEB9" 
#>        Ac         R        Im 
#> "#FFA54F" "#68228B" "#636363" 
#> 
#> Slot "categoryData":
#> # A tibble: 23 × 6
#> # Groups:   Period, To [23]
#>    Period    To    Interval  GG_km2   Gtj    St
#>    <fct>     <fct>    <int>   <dbl> <dbl> <dbl>
#>  1 2012-2014 aa           2  14.9   0.510  1.66
#>  2 2012-2014 Ap           2 612.    3.92   1.66
#>  3 2012-2014 Ac           2 110.    1.14   1.66
#>  4 2012-2014 Im           2   0.195 0.337  1.66
#>  5 2012-2014 Iu           2   6.79  2.67   1.66
#>  6 2010-2012 aa           2  47.0   1.18   2.12
#>  7 2010-2012 Ap           2 707.    4.84   2.12
#>  8 2010-2012 Ac           2 189.    2.00   2.12
#>  9 2010-2012 Iu           2   1.90  0.792  2.12
#> 10 2010-2012 R            2   2.76  0.951  2.12
#> # ℹ 13 more rows
#> 
#> Slot "categoryStationarity":
#> # A tibble: 12 × 5
#>    To     Gain     N Stationarity Test 
#>    <fct> <int> <int> <chr>        <chr>
#>  1 aa        2     4 Active Gain  N    
#>  2 Ap        2     4 Active Gain  N    
#>  3 Ac        1     4 Active Gain  N    
#>  4 Iu        2     4 Active Gain  N    
#>  5 Agua      1     4 Active Gain  N    
#>  6 R         2     4 Active Gain  N    
#>  7 aa        2     4 Dormant Gain N    
#>  8 Ap        2     4 Dormant Gain N    
#>  9 Ac        3     4 Dormant Gain N    
#> 10 Im        3     4 Dormant Gain N    
#> 11 Iu        2     4 Dormant Gain N    
#> 12 R         1     4 Dormant Gain N

Plotting an intensity object

Visualizations of the IA results are obtained from the plot(intensity-object) function. For more details on the function arguments, please see the documentation of the plot() method.

plot(my_test$category_lvlGain,
     labels = c(leftlabel = bquote("Gain Area (" ~km^2~ ")"),
                rightlabel = "Intensity Gain (%)"),
     marginplot = c(.3, .3), labs = c("Categories", "Uniform intensity"), 
     leg_curv = c(x = 1, y = .5),
     fontsize_ui = 8)
Gain area outcome - Category level

Gain area outcome - Category level

Miscellaneous visualization tools

OpenLand provides a bench of visualization tools of LUCC metrics. One-step transitions can be balanced by net and gross changes of all categories through a combined bar chart. Transitions between LUC categories can be detailed by a circular chord chart, based on the Circlize package (Gu et al. 2014). An implementation of Sankey diagram based on the networkD3 package (Allaire et al. 2017) allow the representation of one- and multistep LUCC between categories. Areal development of all LUC categories throughout the observation period can be visualized by a grouped bar chart.

Net and Gross gain and loss
netgrossplot(dataset = SL_2002_2014$lulc_Multistep,
             legendtable = SL_2002_2014$tb_legend,
             xlab = "LUC Category",
             ylab = bquote("Area (" ~ km^2 ~ ")"),
             changesLabel = c(GC = "Gross changes", NG = "Net Gain", NL = "Net Loss"),
             color = c(GC = "gray70", NG = "#006400", NL = "#EE2C2C")
             )
Net Gross Changes 2002 - 2014

Net Gross Changes 2002 - 2014

Chord Diagram (2002 - 2014)
chordDiagramLand(dataset = SL_2002_2014$lulc_Onestep,
                 legendtable = SL_2002_2014$tb_legend)
Chord Diagram 2002 - 2014 (area in km^2^)

Chord Diagram 2002 - 2014 (area in km2)

Sankey Multi Step (2002, 2008, 2010, 2012, 2014)
# sankeyLand(dataset = SL_2002_2014$lulc_Multistep,
#            legendtable = SL_2002_2014$tb_legend)

Other functions

OpenLand enables furthermore the spatial screening of LUCC frequencies for one or a series of raster layers with summary_map() and summary_dir(). The acc_changes() function returns for a LUC time series the number of times a pixel has changed during the analysed period, returning a grid layer and a table with the percentages of transition numbers in the study area. Here we use the tmap package for plotting the outcomes of the acc_changes() function.

Accumulated changes in pixels in the interval 2002 - 2014 at four time points (2002, 2008, 2010, 2012, 2014)

Accumulated changes in pixels in the interval 2002 - 2014 at four time points (2002, 2008, 2010, 2012, 2014)

References

Aldwaik, Safaa Zakaria, and Robert Gilmore Pontius. 2012. “Intensity analysis to unify measurements of size and stationarity of land changes by interval, category, and transition.” Landsc. Urban Plan. 106 (1): 103–14. https://doi.org/10.1016/j.landurbplan.2012.02.010.

Allaire, J J, Christopher Gandrud, Kenton Russell, and C J Yetman. 2017. “networkD3: D3 JavaScript Network Graphs from R.” https://cran.r-project.org/package=networkD3.

Chambers, John. 2008. Software for Data Analysis. Statistics and Computing. New York, NY: Springer New York. https://doi.org/10.1007/978-0-387-75936-4.

Embrapa Pantanal, Instituto SOS Pantanal, and WWF-Brasil. 2015. “Mapeamento da Bacia do Alto Paraguai.” https://www.embrapa.br/pantanal/bacia-do-alto-paraguai.

Gu, Zuguang, Lei Gu, Roland Eils, Matthias Schlesner, and Benedikt Brors. 2014. “circlize implements and enhances circular visualization in R.” Bioinformatics 30 (19): 2811–2.


CITATION:

Reginal Exavier and Peter Zeilhofer. OpenLand: Software for Quantitative Analysis and Visualization of Land Use and Cover Change. The R Journal, v. 12, n. 2, p. 359–371, 2021. https://doi.org/10.32614/RJ-2021-021.

openland's People

Contributors

olivroy avatar peterzeilhofer avatar reginalexavier avatar teunbrand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

openland's Issues

attempt to make a table with >= 2^31 elements

I keep getting the following error when using the contingencyTable function on my raster.

I'm using a MODIS MCD12q1 land-cover yearly dataset.

landcover
class      : RasterStack 
dimensions : 7149, 10258, 73334442, 10  (nrow, ncol, ncell, nlayers)
resolution : 463.3127, 463.3127  (x, y)
extent     : -9793968, -5041306, 2716866, 6029088  (xmin, xmax, ymin, ymax)
crs        : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +R=6371007.181 +units=m +no_defs 
names      : landcover_2010, landcover_2011, landcover_2012, landcover_2013, landcover_2014, landcover_2015, landcover_2016, landcover_2017, landcover_2018, landcover_2019 
min values :              0,              0,              0,              0,              0,              0,              0,              0,              0,              0 
max values :            255,            255,            255,            255,            255,            255,            255,            255,            255,            255 
land.cover<- contingencyTable(input_raster = landcover, pixelresolution = 5)

Error in (function (..., exclude = if (useNA == "no") c(NA, NaN), useNA = c("no", :
attempt to make a table with >= 2^31 elements

I thought it was a problem with pixelresolution, so I had it changed to 463.3127 and selected ontly the first two years:

land.cover<- contingencyTable(input_raster = landcover[[1:2]], pixelresolution = 463.3127)

Warning messages:
1: Expected 2 pieces. Missing pieces filled with NA in 176 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
2: Expected 2 pieces. Missing pieces filled with NA in 176 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
3: Expected 2 pieces. Missing pieces filled with NA in 176 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
4: Expected 2 pieces. Missing pieces filled with NA in 176 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...]

Then I got:

land.cover
$lulc_Multistep
# A tibble: 532 x 8
   Period  From    To         km2  QtPixel Interval yearFrom yearTo
   <chr>  <int> <int>       <dbl>    <int>    <int>    <int>  <int>
 1 NA-NA      0     0 3790609.    17658776       NA       NA     NA
 2 NA-NA      0     1      29.6        138       NA       NA     NA
 3 NA-NA      0     4       0.215        1       NA       NA     NA
 4 NA-NA      0     5       7.94        37       NA       NA     NA
 5 NA-NA      0     8      98.3        458       NA       NA     NA
 6 NA-NA      0     9      15.7         73       NA       NA     NA
 7 NA-NA      0    10      31.8        148       NA       NA     NA
 8 NA-NA      0    11     310.        1445       NA       NA     NA
 9 NA-NA      0    15      77.9        363       NA       NA     NA
10 NA-NA      1     0       9.02        42       NA       NA     NA
# ... with 522 more rows

$lulc_Onestep
# A tibble: 190 x 8
   Period  From    To         km2  QtPixel Interval yearFrom yearTo
   <chr>  <int> <int>       <dbl>    <int>    <int>    <int>  <int>
 1 NA-NA      0     0 3789984.    17655864       NA       NA     NA
 2 NA-NA      0     1      55.4        258       NA       NA     NA
 3 NA-NA      0     4       0.644        3       NA       NA     NA
 4 NA-NA      0     5      11.4         53       NA       NA     NA
 5 NA-NA      0     7       1.29         6       NA       NA     NA
 6 NA-NA      0     8     158.         737       NA       NA     NA
 7 NA-NA      0     9      29.4        137       NA       NA     NA
 8 NA-NA      0    10     151.         705       NA       NA     NA
 9 NA-NA      0    11     548.        2552       NA       NA     NA
10 NA-NA      0    12       7.73        36       NA       NA     NA
# ... with 180 more rows

$tb_legend
# A tibble: 16 x 3
   categoryValue categoryName color  
           <int> <fct>        <chr>  
 1             0 PQL          #7F2A2B
 2             1 JCP          #5F1415
 3             2 RZW          #6F8DD2
 4             3 DLW          #BD5758
 5             4 HNU          #DD9191
 6             5 GSX          #C5CFF0
 7             6 SEK          #EFF1F8
 8             7 HZI          #F9DCDC
 9             8 MWH          #F9EFEF
10             9 YFN          #8EA4DE
11            10 SYW          #ABBBE8
12            11 QXN          #295EAE
13            12 QOB          #EAACAC
14            13 AOF          #002F70
15            14 BDX          #DCE2F6
16            15 NFA          #A13F3F

$totalArea
# A tibble: 1 x 2
   area_km2   QtPixel
      <dbl>     <int>
1 38406511. 178918995

$totalInterval
[1] NA

Everything filled with NA's

Feature request: netgrossplot

Greetings

Thanks for a great package.

It would be great if you could add the option to facet by a variable in the netgrossplot. For example if you wanted to compare land cover change across areas with different land use types. I've played with retrofitting this with cowplot, but can't get rid of the extra legends and axis labels. Please let me know if you know of any other ggplot add-on packages that would allow it?

I haven't looked at your code to see how to implement this as I don't have time rght now, but if I get te chance I'll send a pull request.

Thanks!
Jasper

CRAN breakages

Your CRAN breakages (revdep tested as your package uses raster are still present with dplyr from github:

* checking tests ...
  Running ‘testthat.R’
 ERROR
Running the tests in ‘tests/testthat.R’ failed.
Last 13 lines of output:
   14. base::tryCatch(...)
   15. base:::tryCatchList(expr, classes, parentenv, handlers)
   16. base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
   17. value[[3L]](cond)
  
  ══ testthat results  ═══════════════════════════════════════════════════════════
  [ OK: 108 | SKIPPED: 0 | WARNINGS: 49 | FAILED: 5 ]
  1. Failure: Behavior of the contingencyTable (@test_contingencyTable.R#41) 
  2. Failure: Behavior of acc_changes (@test_generalfunctions.R#13) 
  3. Failure: Behavior of acc_changes (@test_generalfunctions.R#14) 
  4. Failure: Behavior of acc_changes (@test_generalfunctions.R#15) 
  5. Error: Behavior of summary_map (@test_generalfunctions.R#53) 
  
  Error: testthat unit tests failed
  Execution halted

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.