diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index dfa465e..97a99ec 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-07-09T14:04:19","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-07-10T10:54:21","documenter_version":"1.5.0"}} \ No newline at end of file diff --git a/dev/about/citing/index.html b/dev/about/citing/index.html index ac5caf3..c45c237 100644 --- a/dev/about/citing/index.html +++ b/dev/about/citing/index.html @@ -12,4 +12,4 @@ url={https://dx.doi.org/10.21105/joss.00692}, year={2018}, month={Apr} -} +} diff --git a/dev/about/community/index.html b/dev/about/community/index.html index 203efe6..3ede8b1 100644 --- a/dev/about/community/index.html +++ b/dev/about/community/index.html @@ -1,2 +1,2 @@ -Community · GeoStats.jl

We use the Zulip platform to chat and help the community of users. Consider creating an account and pressing ? on the keyboard there for navigation instructions.

Click on the image to join the channel:

Zulip

+Community · GeoStats.jl

We use the Zulip platform to chat and help the community of users. Consider creating an account and pressing ? on the keyboard there for navigation instructions.

Click on the image to join the channel:

Zulip

diff --git a/dev/about/license/index.html b/dev/about/license/index.html index 7d9631d..5946a79 100644 --- a/dev/about/license/index.html +++ b/dev/about/license/index.html @@ -19,4 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. diff --git a/dev/contributing/index.html b/dev/contributing/index.html index 16216ac..f2e6434 100644 --- a/dev/contributing/index.html +++ b/dev/contributing/index.html @@ -1,3 +1,3 @@ Contributing · GeoStats.jl

Contributing

First off, thank you for considering contributing to GeoStats.jl. It’s people like you that make this project so much fun. Below are a few suggestions to speed up the collaboration process:

  • Please be polite, we are here to help and learn from each other.
  • Try to explain your contribution with simple language.
  • References to textbooks and papers are always welcome.
  • Follow the coding standards in the source.

How to start contributing?

Contributing to an open-source project for the very first time can be a very daunting task. To make the process easier and more GitHub-beginner-friendly, the community has written an article about how to start contributing to open-source and overcome the mental and technical barriers that come associated with it. The article will also take you through the steps required to make your first contribution in detail.

Reporting issues

If you are experiencing issues or have discovered a bug, please report it on GitHub. To make the resolution process easier, please include the version of Julia and GeoStats.jl in your writeup. These can be found with two commands:

julia> versioninfo()
-julia> using Pkg; Pkg.status()

Feature requests

If you have suggestions of improvement or algorithms that you would like to see implemented, please open an issue on GitHub. Suggestions as well as feature requests are very welcome.

Code contribution

If you have code that you would like to contribute that is awesome! Please open an issue or reach out in our community channel before you create the pull request on GitHub so that we make sure your idea is aligned with the project goals.

After your idea is revised by project maintainers, you implement it online on Github or offline on your machine.

Online changes

If the changes to the code are minimal, we recommend pressing . on the keyboard on any file in the GitHub repository of interest. This will open the VSCode editor on the web browser where you can implement the changes, commit them and submit a pull request.

Offline changes

If the changes require additional investigation and tests, please get the development version of the project by typing the following in the package manager:

] activate @geo

This will create a fresh environment called @geo where you can edit the project modules without effects on your global user environment. Next, go ahead and ask the package manager to develop the package of interest (e.g. GeoStatsFunctions.jl):

] dev GeoStatsFunctions

You can modify the source code that was cloned in the .julia/dev folder and submit a pull request on GitHub later.

+julia> using Pkg; Pkg.status()

Feature requests

If you have suggestions of improvement or algorithms that you would like to see implemented, please open an issue on GitHub. Suggestions as well as feature requests are very welcome.

Code contribution

If you have code that you would like to contribute that is awesome! Please open an issue or reach out in our community channel before you create the pull request on GitHub so that we make sure your idea is aligned with the project goals.

After your idea is revised by project maintainers, you implement it online on Github or offline on your machine.

Online changes

If the changes to the code are minimal, we recommend pressing . on the keyboard on any file in the GitHub repository of interest. This will open the VSCode editor on the web browser where you can implement the changes, commit them and submit a pull request.

Offline changes

If the changes require additional investigation and tests, please get the development version of the project by typing the following in the package manager:

] activate @geo

This will create a fresh environment called @geo where you can edit the project modules without effects on your global user environment. Next, go ahead and ask the package manager to develop the package of interest (e.g. GeoStatsFunctions.jl):

] dev GeoStatsFunctions

You can modify the source code that was cloned in the .julia/dev folder and submit a pull request on GitHub later.

diff --git a/dev/data/2ffb1b0e.png b/dev/data/2ffb1b0e.png new file mode 100644 index 0000000..6adceb0 Binary files /dev/null and b/dev/data/2ffb1b0e.png differ diff --git a/dev/data/523f311f.png b/dev/data/523f311f.png deleted file mode 100644 index 34fb528..0000000 Binary files a/dev/data/523f311f.png and /dev/null differ diff --git a/dev/data/6998466a.png b/dev/data/6998466a.png new file mode 100644 index 0000000..79f865a Binary files /dev/null and b/dev/data/6998466a.png differ diff --git a/dev/data/6f72bc3f.png b/dev/data/6f72bc3f.png deleted file mode 100644 index 0a6349d..0000000 Binary files a/dev/data/6f72bc3f.png and /dev/null differ diff --git a/dev/data/6f77817d.png b/dev/data/6f77817d.png new file mode 100644 index 0000000..0c9b281 Binary files /dev/null and b/dev/data/6f77817d.png differ diff --git a/dev/data/8d392047.png b/dev/data/8d392047.png deleted file mode 100644 index 8195868..0000000 Binary files a/dev/data/8d392047.png and /dev/null differ diff --git a/dev/data/c4412881.png b/dev/data/c4412881.png deleted file mode 100644 index 59bdb01..0000000 Binary files a/dev/data/c4412881.png and /dev/null differ diff --git a/dev/data/cae03bed.png b/dev/data/cae03bed.png deleted file mode 100644 index 35e8a70..0000000 Binary files a/dev/data/cae03bed.png and /dev/null differ diff --git a/dev/data/dc2ebe3f.png b/dev/data/dc2ebe3f.png new file mode 100644 index 0000000..8ca2751 Binary files /dev/null and b/dev/data/dc2ebe3f.png differ diff --git a/dev/data/e0105ab4.png b/dev/data/e0105ab4.png new file mode 100644 index 0000000..439ecf4 Binary files /dev/null and b/dev/data/e0105ab4.png differ diff --git a/dev/data/index.html b/dev/data/index.html index 903a7c0..9e89bc1 100644 --- a/dev/data/index.html +++ b/dev/data/index.html @@ -1,11 +1,11 @@ Data · GeoStats.jl

Geospatial data

Overview

Given a table or array containing data, we can georeference these objects onto a geospatial domain with the georef function. The result of the georef function is a GeoTable. If you would like to learn this concept in more depth, check out the recording of our JuliaEO 2024 workshop:

-

GeoTables.georefFunction
georef(table, domain)

Georeference table on domain.

table must implement the Tables.jl interface (e.g., DataFrame, CSV.File, XLSX.Worksheet).

domain must implement the Meshes.jl interface (e.g., CartesianGrid, SimpleMesh, GeometrySet).

Examples

julia> georef((a=rand(100), b=rand(100)), CartesianGrid(10, 10))
source
georef(table, geoms)

Georeference table on vector of geometries geoms.

geoms must implement the Meshes.jl interface (e.g., Point, Quadrangle, Hexahedron).

Examples

julia> georef((a=rand(10), b=rand(10)), rand(Point2, 10))
source
georef(table, coords)

Georeference table on PointSet(coords).

Examples

julia> georef((a=rand(10), b=rand(10)), rand(2, 10))
source
georef(table, names; [crs])

Georeference table using coordinates stored in given column names.

Optionally, specify the coordinate reference system crs, which is set by default based on heuristics.

Examples

georef((a=rand(10), x=rand(10), y=rand(10)), ("x", "y"))
+

GeoTables.georefFunction
georef(table, domain)

Georeference table on domain.

table must implement the Tables.jl interface (e.g., DataFrame, CSV.File, XLSX.Worksheet).

domain must implement the Meshes.jl interface (e.g., CartesianGrid, SimpleMesh, GeometrySet).

Examples

julia> georef((a=rand(100), b=rand(100)), CartesianGrid(10, 10))
source
georef(table, geoms)

Georeference table on vector of geometries geoms.

geoms must implement the Meshes.jl interface (e.g., Point, Quadrangle, Hexahedron).

Examples

julia> georef((a=rand(10), b=rand(10)), rand(Point{2}, 10))
source
georef(table, coords)

Georeference table on PointSet(coords) using Cartesian coords.

Examples

julia> georef((a=rand(10), b=rand(10)), [(rand(), rand()) for i in 1:10])
source
georef(table, names; [crs])

Georeference table using coordinates stored in given column names.

Optionally, specify the coordinate reference system crs, which is set by default based on heuristics.

Examples

georef((a=rand(10), x=rand(10), y=rand(10)), ("x", "y"))
 georef((a=rand(10), x=rand(10), y=rand(10)), ["x", "y"])
 georef((a=rand(10), x=rand(10), y=rand(10)), ["x", "y"], crs=Cartesian)
-georef((a=rand(10), x=rand(10), y=rand(10)), ["x", "y"], crs=LatLon)
source
georef(tuple)

Georeference a named tuple on CartesianGrid(dims), with dims being the dimensions of the tuple arrays.

Examples

julia> georef((a=rand(10, 10), b=rand(10, 10))) # 2D grid
-julia> georef((a=rand(10, 10, 10), b=rand(10, 10, 10))) # 3D grid
source

The functions values and domain can be used to retrieve the table of attributes and the underlying geospatial domain:

Base.valuesFunction
values(geotable, [rank])

Return the values of geotable for a given rank as a table.

The rank is a non-negative integer that specifies the parametric dimension of the geometries of interest:

  • 0 - points
  • 1 - segments
  • 2 - triangles, quadrangles, ...
  • 3 - tetrahedrons, hexahedrons, ...

If the rank is not specified, it is assumed to be the rank of the elements of the domain.

source

The GeoIO.jl package can be used to load/save geospatial data from/to various file formats:

GeoIO.loadFunction
load(fname, layer=0, fix=true, kwargs...)

Load geospatial table from file fname and convert the geometry column to Meshes.jl geometries.

Optionally, specify the layer of geometries to read within the file and keyword arguments kwargs accepted by Shapefile.Table, GeoJSON.read GeoParquet.read and ArchGDAL.read.

The option fix can be used to fix orientation and degeneracy issues with polygons.

To see supported formats, use the formats function.

source
GeoIO.saveFunction
save(fname, geotable; kwargs...)

Save geospatial table to file fname using the appropriate format based on the file extension. Optionally, specify keyword arguments accepted by Shapefile.write and GeoJSON.write. For example, use force = true to force writing on existing .shp file.

To see supported formats, use the formats function.

source
GeoIO.formatsFunction
formats([io]; sortby=:format)

Displays in io (defaults to stdout if io is not given) a table with all formats supported by GeoIO.jl and the packages used to load and save each of them.

Optionally, sort the table by the :extension, :load or :save columns using the sortby argument.

source

The GeoArtifacts.jl package provides utility functions to automatically download geospatial data from repositories on the internet.

Examples

using GeoStats
+georef((a=rand(10), x=rand(10), y=rand(10)), ["x", "y"], crs=LatLon)
source
georef(tuple)

Georeference a named tuple on CartesianGrid(dims), with dims being the dimensions of the tuple arrays.

Examples

julia> georef((a=rand(10, 10), b=rand(10, 10))) # 2D grid
+julia> georef((a=rand(10, 10, 10), b=rand(10, 10, 10))) # 3D grid
source

The functions values and domain can be used to retrieve the table of attributes and the underlying geospatial domain:

Base.valuesFunction
values(geotable, [rank])

Return the values of geotable for a given rank as a table.

The rank is a non-negative integer that specifies the parametric dimension of the geometries of interest:

  • 0 - points
  • 1 - segments
  • 2 - triangles, quadrangles, ...
  • 3 - tetrahedrons, hexahedrons, ...

If the rank is not specified, it is assumed to be the rank of the elements of the domain.

source

The GeoIO.jl package can be used to load/save geospatial data from/to various file formats:

GeoIO.loadFunction
load(fname, layer=0, fix=true, kwargs...)

Load geospatial table from file fname and convert the geometry column to Meshes.jl geometries.

Optionally, specify the layer of geometries to read within the file and keyword arguments kwargs accepted by Shapefile.Table, GeoJSON.read GeoParquet.read and ArchGDAL.read.

The option fix can be used to fix orientation and degeneracy issues with polygons.

To see supported formats, use the formats function.

source
GeoIO.saveFunction
save(fname, geotable; kwargs...)

Save geospatial table to file fname using the appropriate format based on the file extension. Optionally, specify keyword arguments accepted by Shapefile.write and GeoJSON.write. For example, use force = true to force writing on existing .shp file.

To see supported formats, use the formats function.

source
GeoIO.formatsFunction
formats([io]; sortby=:format)

Displays in io (defaults to stdout if io is not given) a table with all formats supported by GeoIO.jl and the packages used to load and save each of them.

Optionally, sort the table by the :extension, :load or :save columns using the sortby argument.

source

The GeoArtifacts.jl package provides utility functions to automatically download geospatial data from repositories on the internet.

Examples

using GeoStats
 import CairoMakie as Mke
 
 # helper function for plotting two
@@ -17,15 +17,15 @@
   fig
 end
plot (generic function with 1 method)

Tables

Consider a table (e.g. DataFrame) with 25 samples of temperature T and pressure P:

using DataFrames
 
-table = DataFrame(T=rand(25), P=rand(25))
25×2 DataFrame
RowTP
Float64Float64
10.5990150.801149
20.3903460.804464
30.5381460.360577
40.8604810.972413
50.1869490.632382
60.5186710.412969
70.836880.563689
80.8985220.0812046
90.9612680.428503
100.9128330.698005
110.8435170.0141457
120.02424060.619516
130.2188490.0566977
140.8836170.365328
150.8024880.216712
160.9149110.353659
170.432060.621711
180.8036980.880654
190.9793090.860301
200.3227060.93121
210.1112980.780138
220.02265840.815383
230.9303890.962957
240.06064150.00944304
250.7778730.609043

We can georeference this table based on a given set of points:

georef(table, rand(Point{2}, 25)) |> plot
Example block output

or alternatively, georeference it on a 5x5 regular grid (5x5 = 25 samples):

georef(table, CartesianGrid(5, 5)) |> plot
Example block output

Another common pattern in geospatial data is when the coordinates of the samples are already part of the table as columns. In this case, we can specify the column names:

table = DataFrame(T=rand(25), P=rand(25), X=rand(25), Y=rand(25), Z=rand(25))
+table = DataFrame(T=rand(25), P=rand(25))
25×2 DataFrame
RowTP
Float64Float64
10.2848790.308627
20.8719410.815617
30.838410.947034
40.2347420.658704
50.1662430.678789
60.4508940.525152
70.848330.720055
80.2218690.45369
90.2262120.802153
100.5916820.834743
110.4556260.768586
120.2748460.923697
130.1410.290557
140.6615030.722738
150.6805780.950095
160.2181980.592707
170.5831230.525838
180.4211470.626795
190.9576170.668292
200.2947480.684258
210.3190210.383345
220.8274110.572864
230.4320560.382358
240.3734660.187014
250.6664130.978453

We can georeference this table based on a given set of points:

georef(table, rand(Point{2}, 25)) |> plot
Example block output

or alternatively, georeference it on a 5x5 regular grid (5x5 = 25 samples):

georef(table, CartesianGrid(5, 5)) |> plot
Example block output

Another common pattern in geospatial data is when the coordinates of the samples are already part of the table as columns. In this case, we can specify the column names:

table = DataFrame(T=rand(25), P=rand(25), X=rand(25), Y=rand(25), Z=rand(25))
 
-georef(table, ("X", "Y", "Z")) |> plot
Example block output

Arrays

Consider arrays (e.g. images) with data for various geospatial variables. We can georeference these arrays using a named tuple, and the framework will understand that the shape of the arrays should be preserved in a CartesianGrid:

T, P = rand(5, 5), rand(5, 5)
+georef(table, ("X", "Y", "Z")) |> plot
Example block output

Arrays

Consider arrays (e.g. images) with data for various geospatial variables. We can georeference these arrays using a named tuple, and the framework will understand that the shape of the arrays should be preserved in a CartesianGrid:

T, P = rand(5, 5), rand(5, 5)
 
-georef((T=T, P=P)) |> plot
Example block output

Alternatively, we can interpret the entries of the named tuple as columns in a table:

georef((T=vec(T), P=vec(P)), rand(Point{2}, 25)) |> plot
Example block output

Files

We can easily load geospatial data from disk without any specific knowledge of file formats:

using GeoIO
+georef((T=T, P=P)) |> plot
Example block output

Alternatively, we can interpret the entries of the named tuple as columns in a table:

georef((T=vec(T), P=vec(P)), rand(Point{2}, 25)) |> plot
Example block output

Files

We can easily load geospatial data from disk without any specific knowledge of file formats:

using GeoIO
 
 zone = GeoIO.load("data/zone.shp")
 path = GeoIO.load("data/path.shp")
 
 viz(zone.geometry)
 viz!(path.geometry, color = :gray90)
-Mke.current_figure()
Example block output
+Mke.current_figure()Example block output diff --git a/dev/declustering/index.html b/dev/declustering/index.html index d5ad402..960ffdd 100644 --- a/dev/declustering/index.html +++ b/dev/declustering/index.html @@ -4,4 +4,4 @@

The following statistics have geospatial semantics:

Statistics.meanMethod
mean(data, v)
 mean(data, v, s)

Declustered mean of geospatial data. Optionally, specify the variable v and the block side s.

source
Statistics.varMethod
var(data, v)
 var(data, v, s)

Declustered variance of geospatial data. Optionally, specify the variable v and the block side s.

source
Statistics.quantileMethod
quantile(data, v, p)
-quantile(data, v, p, s)

Declustered quantile of geospatial data at probability p. Optionally, specify the variable v and the block side s.

source

A histogram with geospatial semantics is also available where the heights of the bins are adjusted based on the coordinates of the samples:

GeoStatsBase.EmpiricalHistogramType
EmpiricalHistogram(sdata, var, [s]; kwargs...)

Spatial histogram of variable var in spatial data sdata. Optionally, specify the block side s and the keyword arguments kwargs for the fit(Histogram, ...) call.

source
+quantile(data, v, p, s)

Declustered quantile of geospatial data at probability p. Optionally, specify the variable v and the block side s.

source

A histogram with geospatial semantics is also available where the heights of the bins are adjusted based on the coordinates of the samples:

GeoStatsBase.EmpiricalHistogramType
EmpiricalHistogram(sdata, var, [s]; kwargs...)

Spatial histogram of variable var in spatial data sdata. Optionally, specify the block side s and the keyword arguments kwargs for the fit(Histogram, ...) call.

source
diff --git a/dev/domains/0868ff89.png b/dev/domains/0868ff89.png deleted file mode 100644 index c775010..0000000 Binary files a/dev/domains/0868ff89.png and /dev/null differ diff --git a/dev/domains/a8c0b28a.png b/dev/domains/a8c0b28a.png new file mode 100644 index 0000000..e3c2da4 Binary files /dev/null and b/dev/domains/a8c0b28a.png differ diff --git a/dev/domains/index.html b/dev/domains/index.html index 9cf5e33..4280098 100644 --- a/dev/domains/index.html +++ b/dev/domains/index.html @@ -1,17 +1,14 @@ -Domains · GeoStats.jl

Domains

Overview

A geospatial domain is a (discretized) region in physical space. For example, a collection of rain gauge stations can be represented as a PointSet in the map. Similarly, a collection of states in a given country can be represented as a GeometrySet of polygons.

We provide flexible domain types for advanced geospatial workflows via the Meshes.jl submodule. The domains can consist of sets (or "soups") of geometries as it is most common in GIS or be actual meshes with topological information.

Meshes.DomainType
Domain{Dim,CRS}

A domain is an indexable collection of geometries (e.g. mesh).

source
Meshes.MeshType
Mesh{Dim,CRS,TP}

A mesh embedded in a Dim-dimensional space with given coordinate reference system CRS and topology of type TP.

source

Examples

PointSet

Meshes.PointSetType
PointSet(points)

A set of points (a.k.a. point cloud) representing a Domain.

Examples

All point sets below are the same and contain two points in R³:

julia> PointSet([Point(1,2,3), Point(4,5,6)])
+Domains · GeoStats.jl

Domains

Overview

A geospatial domain is a (discretized) region in physical space. For example, a collection of rain gauge stations can be represented as a PointSet in the map. Similarly, a collection of states in a given country can be represented as a GeometrySet of polygons.

We provide flexible domain types for advanced geospatial workflows via the Meshes.jl submodule. The domains can consist of sets (or "soups") of geometries as it is most common in GIS or be actual meshes with topological information.

Meshes.DomainType
Domain{Dim,CRS}

A domain is an indexable collection of geometries (e.g. mesh).

source
Meshes.MeshType
Mesh{Dim,CRS,TP}

A mesh embedded in a Dim-dimensional space with given coordinate reference system CRS and topology of type TP.

source

Examples

PointSet

Meshes.PointSetType
PointSet(points)

A set of points (a.k.a. point cloud) representing a Domain.

Examples

All point sets below are the same and contain two points in R³:

julia> PointSet([Point(1,2,3), Point(4,5,6)])
 julia> PointSet(Point(1,2,3), Point(4,5,6))
 julia> PointSet([(1,2,3), (4,5,6)])
-julia> PointSet((1,2,3), (4,5,6))
-julia> PointSet([[1,2,3], [4,5,6]])
-julia> PointSet([1,2,3], [4,5,6])
-julia> PointSet([1 4; 2 5; 3 6])
source
pset = PointSet(rand(Point{3}, 100))
+julia> PointSet((1,2,3), (4,5,6))
source
pset = PointSet(rand(Point{3}, 100))
 
-viz(pset)
Example block output

GeometrySet

Meshes.GeometrySetType
GeometrySet(geometries)

A set of geometries representing a Domain.

Examples

Set containing two balls centered at (0.0, 0.0) and (1.0, 1.0):

julia> GeometrySet([Ball((0.0, 0.0)), Ball((1.0, 1.0))])
source
tria = Triangle((0.0, 0.0), (1.0, 1.0), (0.0, 1.0))
+viz(pset)
Example block output

GeometrySet

Meshes.GeometrySetType
GeometrySet(geometries)

A set of geometries representing a Domain.

Examples

Set containing two balls centered at (0.0, 0.0) and (1.0, 1.0):

julia> GeometrySet([Ball((0.0, 0.0)), Ball((1.0, 1.0))])
source
tria = Triangle((0.0, 0.0), (1.0, 1.0), (0.0, 1.0))
 quad = Quadrangle((1.0, 1.0), (2.0, 1.0), (2.0, 2.0), (1.0, 2.0))
 gset = GeometrySet([tria, quad])
 
 viz(gset, showsegments = true)
Example block output

CartesianGrid

Meshes.CartesianGridType
CartesianGrid(dims, origin, spacing)

A Cartesian grid with dimensions dims, lower left corner at origin and cell spacing spacing. The three arguments must have the same length.

CartesianGrid(dims, origin, spacing, offset)

A Cartesian grid with dimensions dims, with lower left corner of element offset at origin and cell spacing spacing.

CartesianGrid(start, finish, dims=dims)

Alternatively, construct a Cartesian grid from a start point (lower left) to a finish point (upper right).

CartesianGrid(start, finish, spacing)

Alternatively, construct a Cartesian grid from a start point to a finish point using a given spacing.

CartesianGrid(dims)
-CartesianGrid(dim1, dim2, ...)

Finally, a Cartesian grid can be constructed by only passing the dimensions dims as a tuple, or by passing each dimension dim1, dim2, ... separately. In this case, the origin and spacing default to (0,0,...) and (1,1,...).

Examples

Create a 3D grid with 100x100x50 hexahedrons:

julia> CartesianGrid(100, 100, 50)

Create a 2D grid with 100 x 100 quadrangles and origin at (10.0, 20.0):

julia> CartesianGrid((100, 100), (10.0, 20.0), (1.0, 1.0))

Create a 1D grid from -1 to 1 with 100 segments:

julia> CartesianGrid((-1.0,), (1.0,), dims=(100,))
source
grid = CartesianGrid(10, 10, 10)
+CartesianGrid(dim1, dim2, ...)

Finally, a Cartesian grid can be constructed by only passing the dimensions dims as a tuple, or by passing each dimension dim1, dim2, ... separately. In this case, the origin and spacing default to (0,0,...) and (1,1,...).

Examples

Create a 3D grid with 100x100x50 hexahedrons:

julia> CartesianGrid(100, 100, 50)

Create a 2D grid with 100 x 100 quadrangles and origin at (10.0, 20.0):

julia> CartesianGrid((100, 100), (10.0, 20.0), (1.0, 1.0))

Create a 1D grid from -1 to 1 with 100 segments:

julia> CartesianGrid((-1.0,), (1.0,), dims=(100,))
source
grid = CartesianGrid(10, 10, 10)
 
-viz(grid, showsegments = true)
Example block output
+viz(grid, showsegments = true)Example block output diff --git a/dev/index.html b/dev/index.html index 984bc91..d45f329 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,5 +1,5 @@ -Home · GeoStats.jl
GeoStatsModule

GeoStats.jl

GeoStats.jl is an extensible framework for geospatial data science and geostatistical modeling fully written in Julia. It is comprised of several modules for advanced geometric processing, state-of-the-art geostatistical algorithms and sophisticated visualization of geospatial data.

All further information is provided in the online documentation.

source
Star us on GitHub!

If you have found this software useful, please consider starring it on GitHub. This gives us an accurate lower bound of the (satisfied) user count.

Organizations using the framework:

+Home · GeoStats.jl

GeoStatsModule

GeoStats.jl

GeoStats.jl is an extensible framework for geospatial data science and geostatistical modeling fully written in Julia. It is comprised of several modules for advanced geometric processing, state-of-the-art geostatistical algorithms and sophisticated visualization of geospatial data.

All further information is provided in the online documentation.

source
Star us on GitHub!

If you have found this software useful, please consider starring it on GitHub. This gives us an accurate lower bound of the (satisfied) user count.

Organizations using the framework:

@@ -53,4 +53,4 @@ url={https://dx.doi.org/10.21105/joss.00692}, year={2018}, month={Apr} -}

We ❤ to see our list of publications growing.

+}

We ❤ to see our list of publications growing.

diff --git a/dev/kriging/index.html b/dev/kriging/index.html index b41f939..2eca773 100644 --- a/dev/kriging/index.html +++ b/dev/kriging/index.html @@ -53,4 +53,4 @@ \begin{bmatrix} \g \\ \f -\end{bmatrix}\]

with $\boldsymbol{\nu}$ the Lagrange multipliers associated with the universal constraints. The mean and variance at location $\x_0$ are given by:

\[\mu(\x_0) = \z^\top \l\]

\[\sigma^2(\x_0) = \begin{bmatrix}\g \\ \f\end{bmatrix}^\top \begin{bmatrix}\l \\ \boldsymbol{\nu}\end{bmatrix}\]

GeoStatsModels.UniversalKrigingType
UniversalKriging(γ, degree, dim)

Universal Kriging with variogram model γ and polynomial degree on a geospatial domain of dimension dim.

Notes

source

External Drift Kriging

In External Drift Kriging, the mean of the random field is assumed to be a combination of known smooth functions:

\[\mu(\x) = \sum_k \beta_k m_k(\x)\]

Differently than Universal Kriging, the functions $m_k$ are not necessarily polynomials of the geospatial coordinates. In practice, they represent a list of variables that is strongly correlated (and co-located) with the variable being estimated.

External drifts are known to cause numerical instability. Give preference to other Kriging variants if possible.

GeoStatsModels.ExternalDriftKrigingType
ExternalDriftKriging(γ, drifts)

External Drift Kriging with variogram model γ and external drifts functions.

Notes

  • External drift functions should be smooth
  • Kriging system with external drift is often unstable
  • Include a constant drift (e.g. x->1) for unbiased estimation
  • OrdinaryKriging is recovered for drifts = [x->1]
  • For polynomial mean, see UniversalKriging
source
+\end{bmatrix}\]

with $\boldsymbol{\nu}$ the Lagrange multipliers associated with the universal constraints. The mean and variance at location $\x_0$ are given by:

\[\mu(\x_0) = \z^\top \l\]

\[\sigma^2(\x_0) = \begin{bmatrix}\g \\ \f\end{bmatrix}^\top \begin{bmatrix}\l \\ \boldsymbol{\nu}\end{bmatrix}\]

GeoStatsModels.UniversalKrigingType
UniversalKriging(γ, degree, dim)

Universal Kriging with variogram model γ and polynomial degree on a geospatial domain of dimension dim.

Notes

source

External Drift Kriging

In External Drift Kriging, the mean of the random field is assumed to be a combination of known smooth functions:

\[\mu(\x) = \sum_k \beta_k m_k(\x)\]

Differently than Universal Kriging, the functions $m_k$ are not necessarily polynomials of the geospatial coordinates. In practice, they represent a list of variables that is strongly correlated (and co-located) with the variable being estimated.

External drifts are known to cause numerical instability. Give preference to other Kriging variants if possible.

GeoStatsModels.ExternalDriftKrigingType
ExternalDriftKriging(γ, drifts)

External Drift Kriging with variogram model γ and external drifts functions.

Notes

  • External drift functions should be smooth
  • Kriging system with external drift is often unstable
  • Include a constant drift (e.g. x->1) for unbiased estimation
  • OrdinaryKriging is recovered for drifts = [x->1]
  • For polynomial mean, see UniversalKriging
source
diff --git a/dev/links/index.html b/dev/links/index.html index 75b7cf2..1c4f4af 100644 --- a/dev/links/index.html +++ b/dev/links/index.html @@ -1,2 +1,2 @@ -Index · GeoStats.jl

Index

Below is the list of types and functions mentioned in the documentation.

Types

Functions

+Index · GeoStats.jl

Index

Below is the list of types and functions mentioned in the documentation.

Types

Functions

diff --git a/dev/objects.inv b/dev/objects.inv index 7fa83f3..f5ca775 100644 Binary files a/dev/objects.inv and b/dev/objects.inv differ diff --git a/dev/queries/index.html b/dev/queries/index.html index 31d3ff2..b2df0aa 100644 --- a/dev/queries/index.html +++ b/dev/queries/index.html @@ -6,7 +6,7 @@ @groupby(geotable, (col₁, col₂, ..., colₙ))

Group geospatial geotable by columns col₁, col₂, ..., colₙ.

@groupby(geotable, regex)

Group geospatial geotable by columns that match with regex.

Examples

@groupby(geotable, 1, 3, 5)
 @groupby(geotable, [:a, :c, :e])
 @groupby(geotable, ("a", "c", "e"))
-@groupby(geotable, r"[ace]")
source
GeoTables.@transformMacro
@transform(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)

Returns geospatial geotable with columns col₁, col₂, ..., colₙ computed with expressions expr₁, expr₂, ..., exprₙ.

See also: @groupby.

Examples

@transform(geotable, :z = :x + 2*:y)
+@groupby(geotable, r"[ace]")
source
GeoTables.@transformMacro
@transform(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)

Returns geospatial geotable with columns col₁, col₂, ..., colₙ computed with expressions expr₁, expr₂, ..., exprₙ.

See also: @groupby.

Examples

@transform(geotable, :z = :x + 2*:y)
 @transform(geotable, :w = :x^2 - :y^2)
 @transform(geotable, :sinx = sin(:x), :cosy = cos(:y))
 
@@ -16,7 +16,7 @@
 
 @transform(geotable, {"z"} = {"x"} - 2*{"y"})
 xnm, ynm, znm = :x, :y, :z
-@transform(geotable, {znm} = {xnm} - 2*{ynm})
source
GeoTables.@combineMacro
@combine(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)

Returns geospatial geotable with columns :col₁, :col₂, ..., :colₙ computed with reduction expressions expr₁, expr₂, ..., exprₙ.

If a reduction expression is not defined for the :geometry column, the geometries will be reduced using Multi.

See also: @groupby.

Examples

@combine(geotable, :x_sum = sum(:x))
+@transform(geotable, {znm} = {xnm} - 2*{ynm})
source
GeoTables.@combineMacro
@combine(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)

Returns geospatial geotable with columns :col₁, :col₂, ..., :colₙ computed with reduction expressions expr₁, expr₂, ..., exprₙ.

If a reduction expression is not defined for the :geometry column, the geometries will be reduced using Multi.

See also: @groupby.

Examples

@combine(geotable, :x_sum = sum(:x))
 @combine(geotable, :x_mean = mean(:x))
 @combine(geotable, :x_mean = mean(:x), :geometry = centroid(:geometry))
 
@@ -27,13 +27,13 @@
 
 @combine(geotable, {"z"} = sum({"x"}) + prod({"y"}))
 xnm, ynm, znm = :x, :y, :z
-@combine(geotable, {znm} = sum({xnm}) + prod({ynm}))
source

Geospatial join

GeoTables.geojoinFunction
geojoin(geotable₁, geotable₂, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, pred=intersects, on=nothing)

Joins geotable₁ with geotable₂ using a certain kind of join and predicate function pred that takes two geometries and returns a boolean ((g1, g2) -> g1 ⊆ g2).

Optionally, add a variable value match to join, in addition to geometric match, by passing a single name or list of variable names (strings or symbols) to the on keyword argument. The variable value match use the isequal function.

Whenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.

Kinds

  • :left - Returns all rows of geotable₁ filling entries with missing when there is no match in geotable₂.
  • :inner - Returns the subset of rows of geotable₁ that has a match in geotable₂.

Examples

geojoin(gtb1, gtb2)
+@combine(geotable, {znm} = sum({xnm}) + prod({ynm}))
source

Geospatial join

GeoTables.geojoinFunction
geojoin(geotable₁, geotable₂, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, pred=intersects, on=nothing)

Joins geotable₁ with geotable₂ using a certain kind of join and predicate function pred that takes two geometries and returns a boolean ((g1, g2) -> g1 ⊆ g2).

Optionally, add a variable value match to join, in addition to geometric match, by passing a single name or list of variable names (strings or symbols) to the on keyword argument. The variable value match use the isequal function.

Whenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.

Kinds

  • :left - Returns all rows of geotable₁ filling entries with missing when there is no match in geotable₂.
  • :inner - Returns the subset of rows of geotable₁ that has a match in geotable₂.

Examples

geojoin(gtb1, gtb2)
 geojoin(gtb1, gtb2, 1 => mean)
 geojoin(gtb1, gtb2, :a => mean, :b => std)
 geojoin(gtb1, gtb2, "a" => mean, pred=issubset)
 geojoin(gtb1, gtb2, on=:a)
-geojoin(gtb1, gtb2, kind=:inner, on=["a", "b"])

See also tablejoin.

source
GeoTables.tablejoinFunction
tablejoin(geotable, table, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, on)

Joins geotable with table using the values of the on variables to match rows with a certain kind of join.

on variables can be a single name or list of variable names (strings or symbols). The variable value match use the isequal function.

Whenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.

Kinds

  • :left - Returns all rows of geotable filling entries with missing when there is no match in table.
  • :inner - Returns the subset of rows of geotable that has a match in table.

Examples

tablejoin(gtb, tab, on=:a)
+geojoin(gtb1, gtb2, kind=:inner, on=["a", "b"])

See also tablejoin.

source
GeoTables.tablejoinFunction
tablejoin(geotable, table, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, on)

Joins geotable with table using the values of the on variables to match rows with a certain kind of join.

on variables can be a single name or list of variable names (strings or symbols). The variable value match use the isequal function.

Whenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.

Kinds

  • :left - Returns all rows of geotable filling entries with missing when there is no match in table.
  • :inner - Returns the subset of rows of geotable that has a match in table.

Examples

tablejoin(gtb, tab, on=:a)
 tablejoin(gtb, tab, 1 => mean, on=:a)
 tablejoin(gtb, tab, :a => mean, :b => std, on=:a)
 tablejoin(gtb, tab, "a" => mean, on=[:a, :b])
-tablejoin(gtb, tab, kind=:inner, on=["a", "b"])

See also geojoin.

source
+tablejoin(gtb, tab, kind=:inner, on=["a", "b"])

See also geojoin.

source diff --git a/dev/quickstart/380acd7d.png b/dev/quickstart/380acd7d.png deleted file mode 100644 index fa583d9..0000000 Binary files a/dev/quickstart/380acd7d.png and /dev/null differ diff --git a/dev/quickstart/90fa986d.png b/dev/quickstart/90fa986d.png new file mode 100644 index 0000000..ce5e533 Binary files /dev/null and b/dev/quickstart/90fa986d.png differ diff --git a/dev/quickstart/index.html b/dev/quickstart/index.html index e521c02..cc557a4 100644 --- a/dev/quickstart/index.html +++ b/dev/quickstart/index.html @@ -9,7 +9,7 @@ viz(zone.geometry) viz!(path.geometry, color = :gray90) -Mke.current_figure()Example block output

Various functions are defined over these geometries, for instance:

sum(area, zone.geometry)
238.01470157543523 m^2
sum(perimeter, zone.geometry)
295.25311339990634 m

Please check the Meshes.jl documentation for more details.

Note

We highly recommend using Meshes.jl geometries in geospatial workflows as they were carefully designed to accomodate advanced features of the GeoStats.jl framework. Any other geometry type will likely fail with our geostatistical algorithms and pipelines.

Creating data

Geospatial data can be derived from other Julia variables. For example, given a Julia array, which is not attached to any coordinate system, we can georeference the array using the georef function:

Z = [10sin(i/10) + 2j for i in 1:50, j in 1:50]
+Mke.current_figure()
Example block output

Various functions are defined over these geometries, for instance:

sum(area, zone.geometry)
238.0147015754351 m^2
sum(perimeter, zone.geometry)
295.25311339990634 m

Please check the Meshes.jl documentation for more details.

Note

We highly recommend using Meshes.jl geometries in geospatial workflows as they were carefully designed to accomodate advanced features of the GeoStats.jl framework. Any other geometry type will likely fail with our geostatistical algorithms and pipelines.

Creating data

Geospatial data can be derived from other Julia variables. For example, given a Julia array, which is not attached to any coordinate system, we can georeference the array using the georef function:

Z = [10sin(i/10) + 2j for i in 1:50, j in 1:50]
 
 Ω = georef((Z=Z,))
@@ -288,4 +288,4 @@

Scientific visualization

We note that the prediction of a geostatistical learning model is a geospatial data object, and we can inspect it with the same methods already described above. This also means that we can visualize the prediction directly, side by side with the true label in this synthetic example:

fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], Ω̂t.geometry, color = Ω̂t.crop)
 viz(fig[1,2], Ωt.geometry, color = Ωt.crop)
-fig
Example block output

With this example we conclude the basic workflow. To get familiar with other features of the project, please check the the reference guide.

+figExample block output

With this example we conclude the basic workflow. To get familiar with other features of the project, please check the the reference guide.

diff --git a/dev/random/fields/189114f6.png b/dev/random/fields/189114f6.png new file mode 100644 index 0000000..c1f8e76 Binary files /dev/null and b/dev/random/fields/189114f6.png differ diff --git a/dev/random/fields/1a5e5d4e.png b/dev/random/fields/1a5e5d4e.png deleted file mode 100644 index 198badd..0000000 Binary files a/dev/random/fields/1a5e5d4e.png and /dev/null differ diff --git a/dev/random/fields/25223c9f.png b/dev/random/fields/25223c9f.png deleted file mode 100644 index 79aa479..0000000 Binary files a/dev/random/fields/25223c9f.png and /dev/null differ diff --git a/dev/random/fields/25f57b9d.png b/dev/random/fields/25f57b9d.png new file mode 100644 index 0000000..ba817b1 Binary files /dev/null and b/dev/random/fields/25f57b9d.png differ diff --git a/dev/random/fields/27acf132.png b/dev/random/fields/27acf132.png deleted file mode 100644 index 4c98ac4..0000000 Binary files a/dev/random/fields/27acf132.png and /dev/null differ diff --git a/dev/random/fields/45e56c8f.png b/dev/random/fields/45e56c8f.png deleted file mode 100644 index c0450a8..0000000 Binary files a/dev/random/fields/45e56c8f.png and /dev/null differ diff --git a/dev/random/fields/4eeac554.png b/dev/random/fields/4eeac554.png deleted file mode 100644 index 131dc0a..0000000 Binary files a/dev/random/fields/4eeac554.png and /dev/null differ diff --git a/dev/random/fields/5dcd1b50.png b/dev/random/fields/5dcd1b50.png deleted file mode 100644 index 546ebf8..0000000 Binary files a/dev/random/fields/5dcd1b50.png and /dev/null differ diff --git a/dev/random/fields/62f72048.png b/dev/random/fields/62f72048.png new file mode 100644 index 0000000..91ab25d Binary files /dev/null and b/dev/random/fields/62f72048.png differ diff --git a/dev/random/fields/70a6265f.png b/dev/random/fields/70a6265f.png deleted file mode 100644 index 35a959d..0000000 Binary files a/dev/random/fields/70a6265f.png and /dev/null differ diff --git a/dev/random/fields/72aa8bfa.png b/dev/random/fields/72aa8bfa.png new file mode 100644 index 0000000..90fd3ef Binary files /dev/null and b/dev/random/fields/72aa8bfa.png differ diff --git a/dev/random/fields/7eb96309.png b/dev/random/fields/7eb96309.png deleted file mode 100644 index bd283b9..0000000 Binary files a/dev/random/fields/7eb96309.png and /dev/null differ diff --git a/dev/random/fields/83813838.png b/dev/random/fields/83813838.png new file mode 100644 index 0000000..c840682 Binary files /dev/null and b/dev/random/fields/83813838.png differ diff --git a/dev/random/fields/8833d3d0.png b/dev/random/fields/8833d3d0.png new file mode 100644 index 0000000..f2f6933 Binary files /dev/null and b/dev/random/fields/8833d3d0.png differ diff --git a/dev/random/fields/a97d9f6a.png b/dev/random/fields/a97d9f6a.png new file mode 100644 index 0000000..fce3827 Binary files /dev/null and b/dev/random/fields/a97d9f6a.png differ diff --git a/dev/random/fields/abb96626.png b/dev/random/fields/abb96626.png deleted file mode 100644 index 924a3fd..0000000 Binary files a/dev/random/fields/abb96626.png and /dev/null differ diff --git a/dev/random/fields/b759cf86.png b/dev/random/fields/b759cf86.png new file mode 100644 index 0000000..90563d8 Binary files /dev/null and b/dev/random/fields/b759cf86.png differ diff --git a/dev/random/fields/c3b067aa.png b/dev/random/fields/c3b067aa.png deleted file mode 100644 index e71027b..0000000 Binary files a/dev/random/fields/c3b067aa.png and /dev/null differ diff --git a/dev/random/fields/c55c7b33.png b/dev/random/fields/c55c7b33.png new file mode 100644 index 0000000..886162e Binary files /dev/null and b/dev/random/fields/c55c7b33.png differ diff --git a/dev/random/fields/cdfee517.png b/dev/random/fields/cdfee517.png deleted file mode 100644 index f35ec95..0000000 Binary files a/dev/random/fields/cdfee517.png and /dev/null differ diff --git a/dev/random/fields/cfcb3aa4.png b/dev/random/fields/cfcb3aa4.png new file mode 100644 index 0000000..271f734 Binary files /dev/null and b/dev/random/fields/cfcb3aa4.png differ diff --git a/dev/random/fields/d4b48f8e.png b/dev/random/fields/d4b48f8e.png new file mode 100644 index 0000000..418b957 Binary files /dev/null and b/dev/random/fields/d4b48f8e.png differ diff --git a/dev/random/fields/index.html b/dev/random/fields/index.html index 7f855d0..462fa62 100644 --- a/dev/random/fields/index.html +++ b/dev/random/fields/index.html @@ -16,18 +16,18 @@ N° reals: 100

We can visualize the first two realizations:

fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].Z)
 viz(fig[1,2], real[2].geometry, color = real[2].Z)
-fig
Example block output

the mean and variance:

m, v = mean(real), var(real)
+fig
Example block output

the mean and variance:

m, v = mean(real), var(real)
 
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], m.geometry, color = m.Z)
 viz(fig[1,2], v.geometry, color = v.Z)
-fig
Example block output

or the 25th and 75th percentiles:

q25 = quantile(real, 0.25)
+fig
Example block output

or the 25th and 75th percentiles:

q25 = quantile(real, 0.25)
 q75 = quantile(real, 0.75)
 
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], q25.geometry, color = q25.Z)
 viz(fig[1,2], q75.geometry, color = q75.Z)
-fig
Example block output

All field processes can generate realizations in parallel using multiple Julia processes. Doing so requires using the Distributed standard library, like in the following example:

using Distributed
+fig
Example block output

All field processes can generate realizations in parallel using multiple Julia processes. Doing so requires using the Distributed standard library, like in the following example:

using Distributed
 
 # request additional processes
 addprocs(3)
@@ -58,7 +58,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].Z)
 viz(fig[1,2], real[2].geometry, color = real[2].Z)
-fig
Example block output
GeoStatsProcesses.LindgrenProcessType
LindgrenProcess(range=1.0, sill=1.0; init=NearestInit())

Lindgren process with given range (correlation length) and sill (total variance) as described in Lindgren 2011. Optionally, specify the data initialization method init.

The process relies relies on a discretization of the Laplace-Beltrami operator on meshes and is adequate for highly curved domains (e.g. surfaces).

References

source

External

The following processes are available in external packages.

ImageQuilting.jl

GeoStatsProcesses.QuiltingProcessType
QuiltingProcess(trainimg, tilesize; [paramaters])

Image quilting process with training image trainimg and tile size tilesize as described in Hoffimann et al. 2017.

Parameters

  • overlap - Overlap size (default to (1/6, 1/6, ..., 1/6))
  • path - Process path (:raster (default), :dilation, or :random)
  • inactive - Vector of inactive voxels (i.e. CartesianIndex) in the grid
  • soft - A pair (data,dataTI) of geospatial data objects (default to nothing)
  • tol - Initial relaxation tolerance in (0,1] (default to 0.1)
  • init - Data initialization method (default to NearestInit())

References

source
using ImageQuilting
+fig
Example block output
GeoStatsProcesses.LindgrenProcessType
LindgrenProcess(range=1.0, sill=1.0; init=NearestInit())

Lindgren process with given range (correlation length) and sill (total variance) as described in Lindgren 2011. Optionally, specify the data initialization method init.

The process relies relies on a discretization of the Laplace-Beltrami operator on meshes and is adequate for highly curved domains (e.g. surfaces).

References

source

External

The following processes are available in external packages.

ImageQuilting.jl

GeoStatsProcesses.QuiltingProcessType
QuiltingProcess(trainimg, tilesize; [paramaters])

Image quilting process with training image trainimg and tile size tilesize as described in Hoffimann et al. 2017.

Parameters

  • overlap - Overlap size (default to (1/6, 1/6, ..., 1/6))
  • path - Process path (:raster (default), :dilation, or :random)
  • inactive - Vector of inactive voxels (i.e. CartesianIndex) in the grid
  • soft - A pair (data,dataTI) of geospatial data objects (default to nothing)
  • tol - Initial relaxation tolerance in (0,1] (default to 0.1)
  • init - Data initialization method (default to NearestInit())

References

source
using ImageQuilting
 using GeoArtifacts
 
 # domain of interest
@@ -74,7 +74,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].facies)
 viz(fig[1,2], real[2].geometry, color = real[2].facies)
-fig
Example block output
# domain of interest
+fig
Example block output
# domain of interest
 grid = CartesianGrid(200, 200)
 
 # quilting process
@@ -87,7 +87,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].Z)
 viz(fig[1,2], real[2].geometry, color = real[2].Z)
-fig
Example block output
# domain of interest
+fig
Example block output
# domain of interest
 grid = domain(img)
 
 # pre-existing observations
@@ -103,7 +103,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].facies)
 viz(fig[1,2], real[2].geometry, color = real[2].facies)
-fig
Example block output

Voxels marked with the special symbol NaN are treated as inactive. The algorithm will skip tiles that only contain inactive voxels to save computation and will generate realizations that are consistent with the mask. This is particularly useful with complex 3D models that have large inactive portions.

# domain of interest
+fig
Example block output

Voxels marked with the special symbol NaN are treated as inactive. The algorithm will skip tiles that only contain inactive voxels to save computation and will generate realizations that are consistent with the mask. This is particularly useful with complex 3D models that have large inactive portions.

# domain of interest
 grid = domain(img)
 
 # skip circle at the center
@@ -124,7 +124,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].facies)
 viz(fig[1,2], real[2].geometry, color = real[2].facies)
-fig
Example block output

It is possible to incorporate auxiliary variables to guide the selection of patterns from the training image.

using ImageFiltering
+fig
Example block output

It is possible to incorporate auxiliary variables to guide the selection of patterns from the training image.

using ImageFiltering
 
 # image assumed as ground truth (unknown)
 truth = GeoStatsImages.get("WalkerLakeTruth")
@@ -151,7 +151,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].Z)
 viz(fig[1,2], real[2].geometry, color = real[2].Z)
-fig
Example block output

TuringPatterns.jl

GeoStatsProcesses.TuringProcessType
TuringProcess(; [paramaters])

Turing process as described in Turing 1952.

Parameters

  • params - basic parameters (default to nothing)
  • blur - blur algorithm (default to nothing)
  • edge - edge condition (default to nothing)
  • iter - number of iterations (default to 100)

References

source
using TuringPatterns
+fig
Example block output

TuringPatterns.jl

GeoStatsProcesses.TuringProcessType
TuringProcess(; [paramaters])

Turing process as described in Turing 1952.

Parameters

  • params - basic parameters (default to nothing)
  • blur - blur algorithm (default to nothing)
  • edge - edge condition (default to nothing)
  • iter - number of iterations (default to 100)

References

source
using TuringPatterns
 
 # domain of interest
 grid = CartesianGrid(200, 200)
@@ -162,7 +162,7 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].z)
 viz(fig[1,2], real[2].geometry, color = real[2].z)
-fig
Example block output

StratiGraphics.jl

GeoStatsProcesses.StrataProcessType
StrataProcess(environment; [paramaters])

Strata process with given geological environment as described in Hoffimann 2018.

Parameters

  • state - Initial geological state
  • stack - Stacking scheme (:erosional or :depositional)
  • nepochs - Number of epochs (default to 10)

References

source
using StratiGraphics
+fig
Example block output

StratiGraphics.jl

GeoStatsProcesses.StrataProcessType
StrataProcess(environment; [paramaters])

Strata process with given geological environment as described in Hoffimann 2018.

Parameters

  • state - Initial geological state
  • stack - Stacking scheme (:erosional or :depositional)
  • nepochs - Number of epochs (default to 10)

References

source
using StratiGraphics
 
 # domain of interest
 grid = CartesianGrid(50, 50, 20)
@@ -179,4 +179,4 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], real[1].geometry, color = real[1].z)
 viz(fig[1,2], real[2].geometry, color = real[2].z)
-fig
Example block output +figExample block output diff --git a/dev/random/points/1271b6dc.png b/dev/random/points/1271b6dc.png new file mode 100644 index 0000000..e5b6d44 Binary files /dev/null and b/dev/random/points/1271b6dc.png differ diff --git a/dev/random/points/14eeba72.png b/dev/random/points/14eeba72.png deleted file mode 100644 index 7cd1e8a..0000000 Binary files a/dev/random/points/14eeba72.png and /dev/null differ diff --git a/dev/random/points/1f18d3cd.png b/dev/random/points/1f18d3cd.png new file mode 100644 index 0000000..4c2839a Binary files /dev/null and b/dev/random/points/1f18d3cd.png differ diff --git a/dev/random/points/2758f031.png b/dev/random/points/2758f031.png deleted file mode 100644 index f922899..0000000 Binary files a/dev/random/points/2758f031.png and /dev/null differ diff --git a/dev/random/points/6ab8653b.png b/dev/random/points/6ab8653b.png deleted file mode 100644 index 206b604..0000000 Binary files a/dev/random/points/6ab8653b.png and /dev/null differ diff --git a/dev/random/points/88db6331.png b/dev/random/points/88db6331.png deleted file mode 100644 index be3e77d..0000000 Binary files a/dev/random/points/88db6331.png and /dev/null differ diff --git a/dev/random/points/926c4285.png b/dev/random/points/926c4285.png new file mode 100644 index 0000000..418ab22 Binary files /dev/null and b/dev/random/points/926c4285.png differ diff --git a/dev/random/points/96dc19c5.png b/dev/random/points/96dc19c5.png new file mode 100644 index 0000000..f3280c1 Binary files /dev/null and b/dev/random/points/96dc19c5.png differ diff --git a/dev/random/points/9d95d4d3.png b/dev/random/points/9d95d4d3.png new file mode 100644 index 0000000..75205c6 Binary files /dev/null and b/dev/random/points/9d95d4d3.png differ diff --git a/dev/random/points/a2500bbe.png b/dev/random/points/a2500bbe.png deleted file mode 100644 index 5df0de1..0000000 Binary files a/dev/random/points/a2500bbe.png and /dev/null differ diff --git a/dev/random/points/a8ea711b.png b/dev/random/points/a8ea711b.png new file mode 100644 index 0000000..90263df Binary files /dev/null and b/dev/random/points/a8ea711b.png differ diff --git a/dev/random/points/cea92872.png b/dev/random/points/cea92872.png new file mode 100644 index 0000000..e032873 Binary files /dev/null and b/dev/random/points/cea92872.png differ diff --git a/dev/random/points/d506ae07.png b/dev/random/points/d506ae07.png deleted file mode 100644 index 01e31fb..0000000 Binary files a/dev/random/points/d506ae07.png and /dev/null differ diff --git a/dev/random/points/e3739c2e.png b/dev/random/points/e3739c2e.png deleted file mode 100644 index 2a399fe..0000000 Binary files a/dev/random/points/e3739c2e.png and /dev/null differ diff --git a/dev/random/points/e3be1361.png b/dev/random/points/e3be1361.png deleted file mode 100644 index c2a14d6..0000000 Binary files a/dev/random/points/e3be1361.png and /dev/null differ diff --git a/dev/random/points/f09b715b.png b/dev/random/points/f09b715b.png new file mode 100644 index 0000000..3dd57c0 Binary files /dev/null and b/dev/random/points/f09b715b.png differ diff --git a/dev/random/points/index.html b/dev/random/points/index.html index 1103290..f2c795c 100644 --- a/dev/random/points/index.html +++ b/dev/random/points/index.html @@ -14,7 +14,7 @@ viz!(fig[1,1], pset[1], color = :black) viz(fig[1,2], sphere) viz!(fig[1,2], pset[2], color = :black) -figExample block output
GeoStatsProcesses.ishomogeneousFunction
ishomogeneous(process::PointProcess)

Tells whether or not the spatial point process process is homogeneous.

source

Processes

GeoStatsProcesses.BinomialProcessType
BinomialProcess(n)

A Binomial point process with n points.

source
# geometry of interest
+fig
Example block output
GeoStatsProcesses.ishomogeneousFunction
ishomogeneous(process::PointProcess)

Tells whether or not the spatial point process process is homogeneous.

source

Processes

GeoStatsProcesses.BinomialProcessType
BinomialProcess(n)

A Binomial point process with n points.

source
# geometry of interest
 box = Box((0, 0), (100, 100))
 
 # Binomial process
@@ -28,7 +28,7 @@
 viz!(fig[1,1], pset[1], color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset[2], color = :black)
-fig
Example block output
GeoStatsProcesses.PoissonProcessType
PoissonProcess(λ)

A Poisson process with intensity λ. For a homogeneous process, define λ as a constant real value, while for an inhomogeneous process, define λ as a function or vector of values. If λ is a vector, it is assumed that the process is associated with a Domain with the same number of elements as λ.

source
# geometry of interest
+fig
Example block output
GeoStatsProcesses.PoissonProcessType
PoissonProcess(λ)

A Poisson process with intensity λ. For a homogeneous process, define λ as a constant real value, while for an inhomogeneous process, define λ as a function or vector of values. If λ is a vector, it is assumed that the process is associated with a Domain with the same number of elements as λ.

source
# geometry of interest
 box = Box((0, 0), (100, 100))
 
 # intensity function
@@ -49,7 +49,7 @@
 viz!(fig[1,1], pset₁, color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset₂, color = :black)
-fig
Example block output
GeoStatsProcesses.InhibitionProcessType
InhibitionProcess(δ)

An inhibition point process with minimum distance δ.

source
# geometry of interest
+fig
Example block output
GeoStatsProcesses.InhibitionProcessType
InhibitionProcess(δ)

An inhibition point process with minimum distance δ.

source
# geometry of interest
 box = Box((0, 0), (100, 100))
 
 # inhibition process
@@ -63,7 +63,7 @@
 viz!(fig[1,1], pset[1], color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset[2], color = :black)
-fig
Example block output
GeoStatsProcesses.ClusterProcessType
ClusterProcess(proc, ofun)

A cluster process with parent process proc and offsprings generated with ofun. It is a function that takes a parent point and returns a point pattern from another point process.

ClusterProcess(proc, offs, gfun)

Alternatively, specify the parent process proc, the offspring process offs and the geometry function gfun. It is a function that takes a parent point and returns a geometry or domain for the offspring process.

source
# geometry of interest
+fig
Example block output
GeoStatsProcesses.ClusterProcessType
ClusterProcess(proc, ofun)

A cluster process with parent process proc and offsprings generated with ofun. It is a function that takes a parent point and returns a point pattern from another point process.

ClusterProcess(proc, offs, gfun)

Alternatively, specify the parent process proc, the offspring process offs and the geometry function gfun. It is a function that takes a parent point and returns a geometry or domain for the offspring process.

source
# geometry of interest
 box = Box((0, 0), (5, 5))
 
 # Matérn process
@@ -88,7 +88,7 @@
 viz!(fig[1,1], pset₁, color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset₂, color = :black)
-fig
Example block output

Operations

Base.unionMethod
p₁ ∪ p₂

Return the union of point processes p₁ and p₂.

source
# geometry of interest
+fig
Example block output

Operations

Base.unionMethod
p₁ ∪ p₂

Return the union of point processes p₁ and p₂.

source
# geometry of interest
 box = Box((0, 0), (100, 100))
 
 # superposition of two Binomial processes
@@ -103,7 +103,7 @@
 viz!(fig[1,1], pset[1], color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset[2], color = :black)
-fig
Example block output
GeoStatsProcesses.thinFunction
thin(process, method)

Thin spatial point process with thinning method.

source
GeoStatsProcesses.RandomThinningType
RandomThinning(p)

Random thinning with retention probability p, which can be a constant probability value in [0,1] or a function mapping a point to a probability.

Examples

RandomThinning(0.5)
+fig
Example block output
GeoStatsProcesses.RandomThinningType
RandomThinning(p)

Random thinning with retention probability p, which can be a constant probability value in [0,1] or a function mapping a point to a probability.

Examples

RandomThinning(0.5)
 RandomThinning(p -> sum(to(p)))
source
# geometry of interest
 box = Box((0, 0), (100, 100))
 
@@ -120,7 +120,7 @@
 viz!(fig[1,1], pset₁, color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset₂, color = :black)
-fig
Example block output
# geometry of interest
+fig
Example block output
# geometry of interest
 box = Box((0, 0), (100, 100))
 
 # Binomial process
@@ -137,4 +137,4 @@
 viz!(fig[1,1], pset₁, color = :black)
 viz(fig[1,2], box)
 viz!(fig[1,2], pset₂, color = :black)
-fig
Example block output
+figExample block output diff --git a/dev/resources/ecosystem/index.html b/dev/resources/ecosystem/index.html index c9db846..c0d5722 100644 --- a/dev/resources/ecosystem/index.html +++ b/dev/resources/ecosystem/index.html @@ -1,4 +1,4 @@ Ecosystem · GeoStats.jl

Ecosystem

The Julia ecosystem for geospatial modeling is maturing very quickly as the result of multiple initiatives such as JuliaEarth, JuliaClimate, and JuliaGeo. Each of these initiatives is associated with a different set of challenges that ultimatively determine the types of packages that are being developed in the corresponding GitHub organizations. In this section, we try to clarify what is available to first-time users of the language.

-

JuliaEarth

Originally created to host the GeoStats.jl framework, this initiative is primarily concerned with geospatial data science and geostatistical modeling. Due to the various applications in the subsurface of the Earth, most of our Julia packages were developed to work efficiently with both 2D and 3D geometries.

Unlike other initiatives, JuliaEarth is 100% Julia by design. This means that we do not rely on external libraries such as GDAL or Proj4 for geospatial work.

JuliaClimate

The most recent of the three initiatives, JuliaClimate has been created to address specific challenges in climate modeling. One of these challenges is access to climate data in Julia. Packages such as INMET.jl and CDSAPI.jl serve this purpose and are quite nice to work with.

JuliaGeo

Focused on bringing well-established external libraries to Julia, JuliaGeo provides packages that are widely used by geospatial communities from other programming languages. GDAL.jl, Proj4.jl and LibGEOS.jl are good examples of such packages.

+

JuliaEarth

Originally created to host the GeoStats.jl framework, this initiative is primarily concerned with geospatial data science and geostatistical modeling. Due to the various applications in the subsurface of the Earth, most of our Julia packages were developed to work efficiently with both 2D and 3D geometries.

Unlike other initiatives, JuliaEarth is 100% Julia by design. This means that we do not rely on external libraries such as GDAL or Proj4 for geospatial work.

JuliaClimate

The most recent of the three initiatives, JuliaClimate has been created to address specific challenges in climate modeling. One of these challenges is access to climate data in Julia. Packages such as INMET.jl and CDSAPI.jl serve this purpose and are quite nice to work with.

JuliaGeo

Focused on bringing well-established external libraries to Julia, JuliaGeo provides packages that are widely used by geospatial communities from other programming languages. GDAL.jl, Proj4.jl and LibGEOS.jl are good examples of such packages.

diff --git a/dev/resources/education/index.html b/dev/resources/education/index.html index 6360069..7d030df 100644 --- a/dev/resources/education/index.html +++ b/dev/resources/education/index.html @@ -1,2 +1,2 @@ -Education · GeoStats.jl

Education

We recommend the following educational resources.

Learning resources

Textbooks

Video lectures

  • Júlio Hoffimann - Video lectures with the GeoStats.jl framework.

  • Edward Isaaks - Video lectures on variography, Kriging and related concepts.

  • Jef Caers - Video lectures on two-point and multiple-point methods.

Workshop material

  • UFMG 2023 [Portuguese] - Geociência de Dados na Mineração, UFMG 2023

  • JuliaEO 2023 [English] - Global Workshop on Earth Observation, AIRCentre 2023

  • CBMina 2021 [Portuguese] - Introução à Geoestatística, CBMina 2021

  • UFMG 2021 [Portuguese] - Introdução à Geoestatística, UFMG 2021

GaussianProcesses.jl

GaussianProcesses.jl - Gaussian process regression and Simple Kriging are essentially two names for the same concept. The derivation of Kriging estimators, however; does not require distributional assumptions. It is a beautiful coincidence that for multivariate Gaussian distributions, Simple Kriging gives the conditional expectation.

KernelFunctions.jl

KernelFunctions.jl - Spatial structure can be represented in many different forms: covariance, variogram, correlogram, etc. Variograms are more general than covariance kernels according to the intrinsic stationary property. This means that there are variogram models with no covariance counterpart. Furthermore, empirical variograms can be easily estimated from the data (in various directions) with an efficient procedure. GeoStats.jl treats variograms as first-class objects.

Interpolations.jl

Interpolations.jl - Kriging and spline interpolation have different purposes, yet these two methods are sometimes listed as competing alternatives. Kriging estimation is about minimizing variance (or estimation error), whereas spline interpolation is about deriving smooth estimators for computer visualization. Kriging is a generalization of splines in which one has the freedom to customize geospatial structure based on data. Besides the estimate itself, Kriging also provides the variance map as a function of point patterns.

ScikitLearn.jl

ScikitLearn.jl - Traditional statistical learning relies on core assumptions that do not hold in geospatial settings (fixed support, i.i.d. samples, ...). Geostatistical learning has been introduced recently as an attempt to push the frontiers of statistical learning with geospatial data.

+Education · GeoStats.jl

Education

We recommend the following educational resources.

Learning resources

Textbooks

Video lectures

  • Júlio Hoffimann - Video lectures with the GeoStats.jl framework.

  • Edward Isaaks - Video lectures on variography, Kriging and related concepts.

  • Jef Caers - Video lectures on two-point and multiple-point methods.

Workshop material

  • UFMG 2024 [Portuguese] - Geociência de Dados na Mineração, UFMG 2024

  • JuliaEO 2024 [English] - Global Workshop on Earth Observation, AIRCentre 2024

  • UFMG 2023 [Portuguese] - Geociência de Dados na Mineração, UFMG 2023

  • JuliaEO 2023 [English] - Global Workshop on Earth Observation, AIRCentre 2023

  • CBMina 2021 [Portuguese] - Introução à Geoestatística, CBMina 2021

  • UFMG 2021 [Portuguese] - Introdução à Geoestatística, UFMG 2021

GaussianProcesses.jl

GaussianProcesses.jl - Gaussian process regression and Simple Kriging are essentially two names for the same concept. The derivation of Kriging estimators, however; does not require distributional assumptions. It is a beautiful coincidence that for multivariate Gaussian distributions, Simple Kriging gives the conditional expectation.

KernelFunctions.jl

KernelFunctions.jl - Spatial structure can be represented in many different forms: covariance, variogram, correlogram, etc. Variograms are more general than covariance kernels according to the intrinsic stationary property. This means that there are variogram models with no covariance counterpart. Furthermore, empirical variograms can be easily estimated from the data (in various directions) with an efficient procedure. GeoStats.jl treats variograms as first-class objects.

Interpolations.jl

Interpolations.jl - Kriging and spline interpolation have different purposes, yet these two methods are sometimes listed as competing alternatives. Kriging estimation is about minimizing variance (or estimation error), whereas spline interpolation is about deriving smooth estimators for computer visualization. Kriging is a generalization of splines in which one has the freedom to customize geospatial structure based on data. Besides the estimate itself, Kriging also provides the variance map as a function of point patterns.

ScikitLearn.jl

ScikitLearn.jl - Traditional statistical learning relies on core assumptions that do not hold in geospatial settings (fixed support, i.i.d. samples, ...). Geostatistical learning has been introduced recently as an attempt to push the frontiers of statistical learning with geospatial data.

diff --git a/dev/resources/publications/index.html b/dev/resources/publications/index.html index 6654924..01dec86 100644 --- a/dev/resources/publications/index.html +++ b/dev/resources/publications/index.html @@ -1,2 +1,2 @@ -Publications · GeoStats.jl

Publications

Below is a list of publications made possible with this project:

+Publications · GeoStats.jl

Publications

Below is a list of publications made possible with this project:

diff --git a/dev/search_index.js b/dev/search_index.js index f664ad0..e988a41 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"about/community/","page":"Community","title":"Community","text":"We use the Zulip platform to chat and help the community of users. Consider creating an account and pressing ? on the keyboard there for navigation instructions.","category":"page"},{"location":"about/community/","page":"Community","title":"Community","text":"Click on the image to join the channel:","category":"page"},{"location":"about/community/","page":"Community","title":"Community","text":"(Image: Zulip)","category":"page"},{"location":"random/points/#Points","page":"Points","title":"Points","text":"","category":"section"},{"location":"random/points/","page":"Points","title":"Points","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"Base.rand(::GeoStatsProcesses.PointProcess, ::Any)","category":"page"},{"location":"random/points/#Base.rand-Tuple{GeoStatsProcesses.PointProcess, Any}","page":"Points","title":"Base.rand","text":"rand([rng], process::PointProcess, geometry, [nreals])\nrand([rng], process::PointProcess, domain, [nreals])\n\nGenerate one or nreals realizations of the point process inside geometry or domain. Optionally specify the random number generator rng.\n\n\n\n\n\n","category":"method"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nsphere = Sphere((0, 0, 0), 1)\n\n# homogeneous Poisson process\nproc = PoissonProcess(5.0)\n\n# sample two point patterns\npset = rand(proc, sphere, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], sphere)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], sphere)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"ishomogeneous","category":"page"},{"location":"random/points/#GeoStatsProcesses.ishomogeneous","page":"Points","title":"GeoStatsProcesses.ishomogeneous","text":"ishomogeneous(process::PointProcess)\n\nTells whether or not the spatial point process process is homogeneous.\n\n\n\n\n\n","category":"function"},{"location":"random/points/#Processes","page":"Points","title":"Processes","text":"","category":"section"},{"location":"random/points/","page":"Points","title":"Points","text":"BinomialProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.BinomialProcess","page":"Points","title":"GeoStatsProcesses.BinomialProcess","text":"BinomialProcess(n)\n\nA Binomial point process with n points.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# Binomial process\nproc = BinomialProcess(1000)\n\n# sample point patterns\npset = rand(proc, box, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"PoissonProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.PoissonProcess","page":"Points","title":"GeoStatsProcesses.PoissonProcess","text":"PoissonProcess(λ)\n\nA Poisson process with intensity λ. For a homogeneous process, define λ as a constant real value, while for an inhomogeneous process, define λ as a function or vector of values. If λ is a vector, it is assumed that the process is associated with a Domain with the same number of elements as λ.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# intensity function\nλ(p) = sum(to(p))^2 / 10000\n\n# homogeneous process\nproc₁ = PoissonProcess(0.5)\n\n# inhomogeneous process\nproc₂ = PoissonProcess(λ)\n\n# sample point patterns\npset₁ = rand(proc₁, box)\npset₂ = rand(proc₂, box)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"InhibitionProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.InhibitionProcess","page":"Points","title":"GeoStatsProcesses.InhibitionProcess","text":"InhibitionProcess(δ)\n\nAn inhibition point process with minimum distance δ.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# inhibition process\nproc = InhibitionProcess(2.0)\n\n# sample point pattern\npset = rand(proc, box, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"ClusterProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.ClusterProcess","page":"Points","title":"GeoStatsProcesses.ClusterProcess","text":"ClusterProcess(proc, ofun)\n\nA cluster process with parent process proc and offsprings generated with ofun. It is a function that takes a parent point and returns a point pattern from another point process.\n\nClusterProcess(proc, offs, gfun)\n\nAlternatively, specify the parent process proc, the offspring process offs and the geometry function gfun. It is a function that takes a parent point and returns a geometry or domain for the offspring process.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (5, 5))\n\n# Matérn process\nproc₁ = ClusterProcess(\n PoissonProcess(1),\n PoissonProcess(1000),\n p -> Ball(p, 0.2)\n)\n\n# inhomogeneous parent and offspring processes\nproc₂ = ClusterProcess(\n PoissonProcess(p -> 0.1 * sum(to(p) .^ 2)),\n p -> rand(PoissonProcess(x -> 5000 * sum((x - p).^2)), Ball(p, 0.5))\n)\n\n# sample point patterns\npset₁ = rand(proc₁, box)\npset₂ = rand(proc₂, box)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"random/points/#Operations","page":"Points","title":"Operations","text":"","category":"section"},{"location":"random/points/","page":"Points","title":"Points","text":"Base.union(::GeoStatsProcesses.PointProcess, ::GeoStatsProcesses.PointProcess)","category":"page"},{"location":"random/points/#Base.union-Tuple{GeoStatsProcesses.PointProcess, GeoStatsProcesses.PointProcess}","page":"Points","title":"Base.union","text":"p₁ ∪ p₂\n\nReturn the union of point processes p₁ and p₂.\n\n\n\n\n\n","category":"method"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# superposition of two Binomial processes\nproc₁ = BinomialProcess(500)\nproc₂ = BinomialProcess(500)\nproc = proc₁ ∪ proc₂ # 1000 points\n\npset = rand(proc, box, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"thin\nRandomThinning","category":"page"},{"location":"random/points/#GeoStatsProcesses.thin","page":"Points","title":"GeoStatsProcesses.thin","text":"thin(process, method)\n\nThin spatial point process with thinning method.\n\n\n\n\n\n","category":"function"},{"location":"random/points/#GeoStatsProcesses.RandomThinning","page":"Points","title":"GeoStatsProcesses.RandomThinning","text":"RandomThinning(p)\n\nRandom thinning with retention probability p, which can be a constant probability value in [0,1] or a function mapping a point to a probability.\n\nExamples\n\nRandomThinning(0.5)\nRandomThinning(p -> sum(to(p)))\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# reduce intensity of Poisson process by half\nproc₁ = PoissonProcess(0.5)\nproc₂ = thin(proc₁, RandomThinning(0.5))\n\n# sample point patterns\npset₁ = rand(proc₁, box)\npset₂ = rand(proc₂, box)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# Binomial process\nproc = BinomialProcess(2000)\n\n# sample point pattern\npset₁ = rand(proc, box)\n\n# thin point pattern with probability 0.5\npset₂ = thin(pset₁, RandomThinning(0.5))\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"variography/empirical/#Empirical-variograms","page":"Empirical variograms","title":"Empirical variograms","text":"","category":"section"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Variograms are widely used in geostatistics due to their intimate connection with (cross-)variance and visual interpretability. The following video explains the concept in detail:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"

\n\n

","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"The Matheron's estimator of the empirical variogram is given by","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"widehatgamma_M(h) = frac12N(h) sum_(ij) in N(h) (z_i - z_j)^2","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"where N(h) = left(ij) mid x_i - x_j = hright is the set of pairs of locations at a distance h and N(h) is the cardinality of the set. Alternatively, the robust Cressie's estimator is given by","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"widehatgamma_C(h) = frac12fracleftfrac1N(h) sum_(ij) in N(h) z_i - z_j^12right^40457 + frac0494N(h) + frac0045N(h)^2","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Both estimators are available and can be used with general distance functions in order to for example:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Model anisotropy (e.g. ellipsoid distance)\nPerform simulation on sphere (e.g. haversine distance)","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Please see Distances.jl for a complete list of distance functions.","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"The high-performance estimation procedure implemented in the framework can consider all pairs of locations regardless of direction (ominidirectional) or a specified partition of the geospatial data (e.g. directional, planar).","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Variograms estimated along all directions in a given plane of reference are called varioplanes. Both variograms and varioplanes can be plotted directly with the following options:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"varioplot","category":"page"},{"location":"variography/empirical/#GeoStatsFunctions.varioplot","page":"Empirical variograms","title":"GeoStatsFunctions.varioplot","text":"varioplot(γ; [options])\n\nPlot the variogram or varioplane γ with given options.\n\nEmpirical variogram options:\n\nvcolor - color of variogram\npsize - size of points of variogram\nssize - size of segments of variogram\ntshow - show text counts\ntsize - size of text counts\nhshow - show histogram\nhcolor - color of histogram\n\nEmpirical varioplane options:\n\nvscheme - color scheme of varioplane\nrshow - show range of theoretical model\nrmodel - theoretical model (e.g. SphericalVariogram)\nrcolor - color of range curve\n\nTheoretical variogram options:\n\nmaxlag - maximum lag for theoretical model\n\nNotes\n\nThis function will only work in the presence of a Makie.jl backend via package extensions in Julia v1.9 or later versions of the language.\n\n\n\n\n\n","category":"function"},{"location":"variography/empirical/#(Omini)directional","page":"Empirical variograms","title":"(Omini)directional","text":"","category":"section"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"EmpiricalVariogram\nDirectionalVariogram\nPlanarVariogram\nvalues(::EmpiricalVariogram)\ndistance(::EmpiricalVariogram)\nestimator(::EmpiricalVariogram)\nmerge(::EmpiricalVariogram{V,D,E}, ::EmpiricalVariogram{V,D,E}) where {V,D,E}","category":"page"},{"location":"variography/empirical/#GeoStatsFunctions.EmpiricalVariogram","page":"Empirical variograms","title":"GeoStatsFunctions.EmpiricalVariogram","text":"EmpiricalVariogram(data, var₁, var₂=var₁; [parameters])\n\nComputes the empirical (a.k.a. experimental) omnidirectional (cross-)variogram for variables var₁ and var₂ stored in geospatial data.\n\nParameters\n\nnlags - number of lags (default to 20)\nmaxlag - maximum lag in length units (default to 1/10 of maximum lag of data)\ndistance - custom distance function (default to Euclidean distance)\nestimator - variogram estimator (default to :matheron estimator)\nalgorithm - accumulation algorithm (default to :ball)\n\nAvailable estimators:\n\n:matheron - simple estimator based on squared differences\n:cressie - robust estimator based on 4th power of differences\n\nAvailable algorithms:\n\n:full - loop over all pairs of points in the data\n:ball - loop over all points inside maximum lag ball\n\nAll implemented algorithms produce the exact same result. The :ball algorithm is considerably faster when the maximum lag is much smaller than the bounding box of the domain of the data.\n\nSee also: DirectionalVariogram, PlanarVariogram, EmpiricalVarioplane.\n\nReferences\n\nChilès, JP and Delfiner, P. 2012. Geostatistics: Modeling Spatial Uncertainty\nWebster, R and Oliver, MA. 2007. Geostatistics for Environmental Scientists\nHoffimann, J and Zadrozny, B. 2019. Efficient variography with partition variograms\n\n\n\n\n\n","category":"type"},{"location":"variography/empirical/#GeoStatsFunctions.DirectionalVariogram","page":"Empirical variograms","title":"GeoStatsFunctions.DirectionalVariogram","text":"DirectionalVariogram(direction, data, var₁, var₂=var₁; dtol=1e-6u\"m\", [parameters])\n\nComputes the empirical (cross-)variogram for the variables var₁ and var₂ stored in geospatial data along a given direction with band tolerance dtol in length units.\n\nOptionally, forward parameters for the underlying EmpiricalVariogram.\n\n\n\n\n\n","category":"function"},{"location":"variography/empirical/#GeoStatsFunctions.PlanarVariogram","page":"Empirical variograms","title":"GeoStatsFunctions.PlanarVariogram","text":"PlanarVariogram(normal, data, var₁, var₂=var₁; ntol=1e-6u\"m\", [parameters])\n\nComputes the empirical (cross-)variogram for the variables var₁ and var₂ stored in geospatial data along a plane perpendicular to a normal direction with plane tolerance ntol in length units.\n\nOptionally, forward parameters for the underlying EmpiricalVariogram.\n\n\n\n\n\n","category":"function"},{"location":"variography/empirical/#Base.values-Tuple{EmpiricalVariogram}","page":"Empirical variograms","title":"Base.values","text":"values(γ)\n\nReturns the abscissa, the ordinate, and the bin counts of the empirical variogram γ.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/#GeoStatsFunctions.distance-Tuple{EmpiricalVariogram}","page":"Empirical variograms","title":"GeoStatsFunctions.distance","text":"distance(γ)\n\nReturn the distance used to compute the empirical variogram γ.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/#GeoStatsFunctions.estimator-Tuple{EmpiricalVariogram}","page":"Empirical variograms","title":"GeoStatsFunctions.estimator","text":"estimator(γ)\n\nReturn the estimator used to compute the empirical variogram γ.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/#Base.merge-Union{Tuple{E}, Tuple{D}, Tuple{V}, Tuple{EmpiricalVariogram{V, D, E}, EmpiricalVariogram{V, D, E}}} where {V, D, E}","page":"Empirical variograms","title":"Base.merge","text":"merge(γα, γβ)\n\nMerge the empirical variogram γα with the empirical variogram γβ assuming that both variograms have the same number of lags, distance and estimator.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Consider the following example image:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"using GeoArtifacts\n\n𝒟 = GeoStatsImages.get(\"Gaussian30x10\")\n\nviz(𝒟.geometry, color = 𝒟.Z)","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"We can compute ominidirectional variograms, which consider pairs of points along all directions:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γ = EmpiricalVariogram(𝒟, :Z, maxlag = 50.)\n\nMke.plot(γ)","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"directional variograms along a specific direction:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γₕ = DirectionalVariogram((1.,0.), 𝒟, :Z, maxlag = 50.)\nγᵥ = DirectionalVariogram((0.,1.), 𝒟, :Z, maxlag = 50.)\n\nMke.plot(γₕ, vcolor = :maroon, hcolor = :maroon)\nMke.plot!(γᵥ)\nMke.current_figure()","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"or planar variograms over a specific plane:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γᵥ = PlanarVariogram((1.,0.), 𝒟, :Z, maxlag = 50.)\nγₕ = PlanarVariogram((0.,1.), 𝒟, :Z, maxlag = 50.)\n\nMke.plot(γₕ, vcolor = :maroon, hcolor = :maroon)\nMke.plot!(γᵥ)\nMke.current_figure()","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"note: Note\nThe directional and planar variograms coincide in this example because planes are equal to lines in 2-dimensional space. These concepts are most useful in 3-dimensional space where we may be interested in comparing the horizontal planar range to the vertical directional range.","category":"page"},{"location":"variography/empirical/#Varioplanes","page":"Empirical variograms","title":"Varioplanes","text":"","category":"section"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"EmpiricalVarioplane","category":"page"},{"location":"variography/empirical/#GeoStatsFunctions.EmpiricalVarioplane","page":"Empirical variograms","title":"GeoStatsFunctions.EmpiricalVarioplane","text":"EmpiricalVarioplane(data, var₁, var₂=var₁;\n normal=Vec(0,0,1),\n nangs=50, ptol=0.5u\"m\", dtol=0.5u\"m\",\n [parameters])\n\nGiven a normal direction, estimate the (cross-)variogram of variables var₁ and var₂ along all directions in the corresponding plane of variation.\n\nOptionally, specify the tolerance ptol in length units for the plane partition, the tolerance dtol in length units for the direction partition, the number of angles nangs in the plane, and forward the parameters to the underlying EmpiricalVariogram.\n\n\n\n\n\n","category":"type"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"The varioplane is plotted on a polar axis for all lags and angles:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γ = EmpiricalVarioplane(𝒟, :Z, maxlag = 50.)\n\nfig = Mke.Figure()\nax = Mke.PolarAxis(fig[1,1], title = \"Varioplane\")\nMke.plot!(ax, γ)\nfig","category":"page"},{"location":"variography/theoretical/#Theoretical-variograms","page":"Theoretical variograms","title":"Theoretical variograms","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"We provide various theoretical variogram models from the literature, which can can be combined with ellipsoid distances to model geometric anisotropy and nested with scalars or matrix coefficients to express multivariate relations.","category":"page"},{"location":"variography/theoretical/#Models","page":"Theoretical variograms","title":"Models","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"In an intrinsic isotropic model, the variogram is only a function of the distance between any two points x_1x_2 in R^m:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(x_1x_2) = gamma(x_1 - x_2) = gamma(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Under the additional assumption of 2nd-order stationarity, the well-known covariance is directly related via gamma(h) = cov(0) - cov(h). This package implements a few commonly used as well as other more exotic variogram models. Most of these models share a set of default parameters (e.g. sill=1.0, range=1.0), which can be set with keyword arguments.","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Functions are provided to query properties of variogram models programmatically:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"isstationary(::Variogram)\nisisotropic(::Variogram)","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.isstationary-Tuple{Variogram}","page":"Theoretical variograms","title":"GeoStatsFunctions.isstationary","text":"isstationary(γ)\n\nCheck if variogram γ possesses the 2nd-order stationary property.\n\n\n\n\n\n","category":"method"},{"location":"variography/theoretical/#Meshes.isisotropic-Tuple{Variogram}","page":"Theoretical variograms","title":"Meshes.isisotropic","text":"isisotropic(γ)\n\nTells whether or not variogram γ is isotropic.\n\n\n\n\n\n","category":"method"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Corresponding covariance models are available for convenience. For example, the GaussianVariogram and the GaussianCovariance are two alternative representations of the same geostatistical behavior.","category":"page"},{"location":"variography/theoretical/#Gaussian","page":"Theoretical variograms","title":"Gaussian","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - expleft(-3left(frachrright)^2right)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"GaussianVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.GaussianVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.GaussianVariogram","text":"GaussianVariogram(range=r, sill=s, nugget=n)\nGaussianVariogram(ball; sill=s, nugget=n)\n\nA Gaussian variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(GaussianVariogram())","category":"page"},{"location":"variography/theoretical/#Exponential","page":"Theoretical variograms","title":"Exponential","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - expleft(-3left(frachrright)right)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"ExponentialVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.ExponentialVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.ExponentialVariogram","text":"ExponentialVariogram(range=r, sill=s, nugget=n)\nExponentialVariogram(ball; sill=s, nugget=n)\n\nAn exponential variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(ExponentialVariogram())","category":"page"},{"location":"variography/theoretical/#Matern","page":"Theoretical variograms","title":"Matern","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - frac2^1-nuGamma(nu) left(sqrt2nu 3left(frachrright)right)^nu K_nuleft(sqrt2nu 3left(frachrright)right)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"MaternVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.MaternVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.MaternVariogram","text":"MaternVariogram(range=r, sill=s, nugget=n, order=ν)\nMaternVariogram(ball; sill=s, nugget=n, order=ν)\n\nA Matérn variogram with range r, sill s and nugget n. The parameter ν is the order of the Bessel function. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(MaternVariogram())","category":"page"},{"location":"variography/theoretical/#Spherical","page":"Theoretical variograms","title":"Spherical","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(frac32left(frachrright) + frac12left(frachrright)^3right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"SphericalVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.SphericalVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.SphericalVariogram","text":"SphericalVariogram(range=r, sill=s, nugget=n)\nSphericalVariogram(ball; sill=s, nugget=n)\n\nA spherical variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(SphericalVariogram())","category":"page"},{"location":"variography/theoretical/#Cubic","page":"Theoretical variograms","title":"Cubic","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(7left(frachrright)^2 - frac354left(frachrright)^3 + frac72left(frachrright)^5 - frac34left(frachrright)^7right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"CubicVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.CubicVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.CubicVariogram","text":"CubicVariogram(range=r, sill=s, nugget=n)\nCubicVariogram(ball; sill=s, nugget=n)\n\nA cubic variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(CubicVariogram())","category":"page"},{"location":"variography/theoretical/#Pentaspherical","page":"Theoretical variograms","title":"Pentaspherical","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(frac158left(frachrright) - frac54left(frachrright)^3 + frac38left(frachrright)^5right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"PentasphericalVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.PentasphericalVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.PentasphericalVariogram","text":"PentasphericalVariogram(range=r, sill=s, nugget=n)\nPentasphericalVariogram(ball; sill=s, nugget=n)\n\nA pentaspherical variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(PentasphericalVariogram())","category":"page"},{"location":"variography/theoretical/#Power","page":"Theoretical variograms","title":"Power","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = sh^a + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"PowerVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.PowerVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.PowerVariogram","text":"PowerVariogram(scaling=s, exponent=a, nugget=n)\n\nA power variogram with scaling s, exponent a and nugget n.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(PowerVariogram())","category":"page"},{"location":"variography/theoretical/#Sine-hole","page":"Theoretical variograms","title":"Sine hole","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - fracsin(pi h r)pi h rright + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"SineHoleVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.SineHoleVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.SineHoleVariogram","text":"SineHoleVariogram(range=r, sill=s, nugget=n)\nSineHoleVariogram(ball; sill=s, nugget=n)\n\nA sine hole variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(SineHoleVariogram())","category":"page"},{"location":"variography/theoretical/#Nugget","page":"Theoretical variograms","title":"Nugget","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"NuggetEffect","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.NuggetEffect","page":"Theoretical variograms","title":"GeoStatsFunctions.NuggetEffect","text":"NuggetEffect(nugget=n)\n\nA pure nugget effect variogram with nugget n.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(NuggetEffect(1.0))","category":"page"},{"location":"variography/theoretical/#Circular","page":"Theoretical variograms","title":"Circular","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(1 - frac2pi cos^-1left(frachrright) + frac2hpi r sqrt1 - frach^2r^2 right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"CircularVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.CircularVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.CircularVariogram","text":"CircularVariogram(; range=r, sill=s, nugget=n)\nCircularVariogram(ball; sill=s, nugget=n)\n\nA circular variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(CircularVariogram())","category":"page"},{"location":"variography/theoretical/#Anisotropy","page":"Theoretical variograms","title":"Anisotropy","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Anisotropic models are easily obtained by defining an ellipsoid metric in place of the default Euclidean metric as shown in the following example. First, we create an ellipsoid that specifies the ranges and angles of rotation:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"ellipsoid = MetricBall((3.0, 2.0, 1.0), RotZXZ(0.0, 0.0, 0.0))","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"All rotations from Rotations.jl are supported as well as the following additional rotations from commercial geostatistical software:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"MinesightAngles\nDatamineAngles\nVulcanAngles\nGslibAngles","category":"page"},{"location":"variography/theoretical/#GeoStatsBase.MinesightAngles","page":"Theoretical variograms","title":"GeoStatsBase.MinesightAngles","text":"MinesightAngles(θ₁, θ₂, θ₃)\n\nMineSight z-x'-y'' intrinsic rotation convention following the right-hand rule. All angles are in degrees and the sign convention is CW, CCW, CW positive.\n\nThe first rotation θ₁ is a horizontal rotation around the Z-axis, with positive being clockwise. The second rotation θ₂ is a rotation around the new X-axis, which moves the Y-axis into the desired position, with positive direction of rotation is up. The third rotation θ₃ is a rotation around the new Y-axis, which moves the X-axis into the desired position, with positive direction of rotation is up.\n\nReferences\n\nSanchez, J. MINESIGHT® TUTORIALS\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/#GeoStatsBase.DatamineAngles","page":"Theoretical variograms","title":"GeoStatsBase.DatamineAngles","text":"DatamineAngles(θ₁, θ₂, θ₃)\n\nDatamine ZXY rotation convention following the left-hand rule. All angles are in degrees and the signal convention is CW, CW, CW positive. Y is the principal axis.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/#GeoStatsBase.VulcanAngles","page":"Theoretical variograms","title":"GeoStatsBase.VulcanAngles","text":"VulcanAngles(θ₁, θ₂, θ₃)\n\nVulcan ZYX rotation convention following the right-hand rule. All angles are in degrees and the signal convention is CW, CCW, CW positive. X is the principal axis.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/#GeoStatsBase.GslibAngles","page":"Theoretical variograms","title":"GeoStatsBase.GslibAngles","text":"GslibAngles(θ₁, θ₂, θ₃)\n\nGSLIB z-x'-y'' intrinsic rotation convention following the left-hand rule. All angles are in degrees and the sign convention is CW, CCW, CW positive. Y is the principal axis.\n\nThe first rotation θ₁ is a rotation around the Z-axis, this is also called the azimuth. The second rotation θ₂ is a rotation around the new X-axis, this is also called the dip. The third rotation θ₃ is a rotation around the new Y-axis, this is also called the tilt. \n\nReferences\n\nDeutsch, 2015. The Angle Specification for GSLIB Software\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"We pass the ellipsoid as the first argument to the variogram model instead of specifying a single range with a keyword argument:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"GaussianVariogram(ellipsoid, sill = 2.0)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"To illustrate the concept, consider the following 2D data set:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"using Random # hide\nRandom.seed!(2000) # hide\n\ngeotable = georef((Z=rand(50),), 100rand(2, 50))\n\nviz(geotable.geometry, color = geotable.Z)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"We interpolate the data with different ellipsoids by varying the angle of rotation from 0 to 2pi clockwise:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"θs = range(0.0, step = π/4, stop = 2π - π/4)\n\n# initialize figure\nfig = Mke.Figure(size = (800, 1600))\n\n# helper function to position subfigures\npos = i -> CartesianIndices((4, 2))[i].I\n\n# Kriging with different angles\nfor (i, θ) in enumerate(θs)\n # ellipsoid rotated clockwise by angle θ\n e = MetricBall((20.,5.), Angle2d(θ))\n\n # anisotropic variogram model\n γ = GaussianVariogram(e)\n\n # domain of interpolation\n grid = CartesianGrid(100, 100)\n\n # perform interpolation\n sol = geotable |> Interpolate(grid, Kriging(γ))\n\n # visualize solution at subplot i\n viz(fig[pos(i)...], sol.geometry, color = sol.Z,\n axis = (title = \"θ = $(rad2deg(θ))ᵒ\",)\n )\nend\n\nfig","category":"page"},{"location":"variography/theoretical/#Nesting","page":"Theoretical variograms","title":"Nesting","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"A nested variogram model gamma(h) = c_1cdotgamma_1(h) + c_2cdotgamma_2(h) + cdots + c_ncdotgamma_n(h) can be constructed from multiple variogram models, including matrix coefficients. The individual structures can be recovered in canonical form with the structures function:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"structures","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.structures","page":"Theoretical variograms","title":"GeoStatsFunctions.structures","text":"structures(γ)\n\nReturn the individual structures of a (possibly nested) variogram as a tuple. The structures are the total nugget cₒ, and the coefficients (or contributions) c[i] for the remaining non-trivial structures g[i] after normalization (i.e. sill=1, nugget=0).\n\nExamples\n\nγ₁ = GaussianVariogram(nugget=1, sill=2)\nγ₂ = SphericalVariogram(nugget=2, sill=3)\n\nγ = 2γ₁ + 3γ₂\n\ncₒ, c, g = structures(γ)\n\n\n\n\n\n","category":"function"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"γ₁ = GaussianVariogram(nugget=1, sill=2)\nγ₂ = ExponentialVariogram(nugget=2, sill=3)\n\n# nested model with matrix coefficients\nγ = [1.0 0.0; 0.0 1.0] * γ₁ + [2.0 0.5; 0.5 3.0] * γ₂\n\n# structures in canonical form\ncₒ, c, g = structures(γ)\n\ncₒ # matrix nugget","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"c # matrix coefficients","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"g # normalized structures","category":"page"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"First off, thank you for considering contributing to GeoStats.jl. It’s people like you that make this project so much fun. Below are a few suggestions to speed up the collaboration process:","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Please be polite, we are here to help and learn from each other.\nTry to explain your contribution with simple language.\nReferences to textbooks and papers are always welcome.\nFollow the coding standards in the source.","category":"page"},{"location":"contributing/#How-to-start-contributing?","page":"Contributing","title":"How to start contributing?","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Contributing to an open-source project for the very first time can be a very daunting task. To make the process easier and more GitHub-beginner-friendly, the community has written an article about how to start contributing to open-source and overcome the mental and technical barriers that come associated with it. The article will also take you through the steps required to make your first contribution in detail.","category":"page"},{"location":"contributing/#Reporting-issues","page":"Contributing","title":"Reporting issues","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If you are experiencing issues or have discovered a bug, please report it on GitHub. To make the resolution process easier, please include the version of Julia and GeoStats.jl in your writeup. These can be found with two commands:","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"julia> versioninfo()\njulia> using Pkg; Pkg.status()","category":"page"},{"location":"contributing/#Feature-requests","page":"Contributing","title":"Feature requests","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If you have suggestions of improvement or algorithms that you would like to see implemented, please open an issue on GitHub. Suggestions as well as feature requests are very welcome.","category":"page"},{"location":"contributing/#Code-contribution","page":"Contributing","title":"Code contribution","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If you have code that you would like to contribute that is awesome! Please open an issue or reach out in our community channel before you create the pull request on GitHub so that we make sure your idea is aligned with the project goals.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"After your idea is revised by project maintainers, you implement it online on Github or offline on your machine.","category":"page"},{"location":"contributing/#Online-changes","page":"Contributing","title":"Online changes","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If the changes to the code are minimal, we recommend pressing . on the keyboard on any file in the GitHub repository of interest. This will open the VSCode editor on the web browser where you can implement the changes, commit them and submit a pull request.","category":"page"},{"location":"contributing/#Offline-changes","page":"Contributing","title":"Offline changes","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If the changes require additional investigation and tests, please get the development version of the project by typing the following in the package manager:","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"] activate @geo","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"This will create a fresh environment called @geo where you can edit the project modules without effects on your global user environment. Next, go ahead and ask the package manager to develop the package of interest (e.g. GeoStatsFunctions.jl):","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"] dev GeoStatsFunctions","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"You can modify the source code that was cloned in the .julia/dev folder and submit a pull request on GitHub later.","category":"page"},{"location":"links/#Index","page":"Index","title":"Index","text":"","category":"section"},{"location":"links/","page":"Index","title":"Index","text":"Below is the list of types and functions mentioned in the documentation.","category":"page"},{"location":"links/#Types","page":"Index","title":"Types","text":"","category":"section"},{"location":"links/","page":"Index","title":"Index","text":"Order = [:type]","category":"page"},{"location":"links/#Functions","page":"Index","title":"Functions","text":"","category":"section"},{"location":"links/","page":"Index","title":"Index","text":"Order = [:function]","category":"page"},{"location":"data/#Geospatial-data","page":"Data","title":"Geospatial data","text":"","category":"section"},{"location":"data/#Overview","page":"Data","title":"Overview","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Given a table or array containing data, we can georeference these objects onto a geospatial domain with the georef function. The result of the georef function is a GeoTable. If you would like to learn this concept in more depth, check out the recording of our JuliaEO 2024 workshop:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"

\n\n

","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef","category":"page"},{"location":"data/#GeoTables.georef","page":"Data","title":"GeoTables.georef","text":"georef(table, domain)\n\nGeoreference table on domain.\n\ntable must implement the Tables.jl interface (e.g., DataFrame, CSV.File, XLSX.Worksheet).\n\ndomain must implement the Meshes.jl interface (e.g., CartesianGrid, SimpleMesh, GeometrySet).\n\nExamples\n\njulia> georef((a=rand(100), b=rand(100)), CartesianGrid(10, 10))\n\n\n\n\n\ngeoref(table, geoms)\n\nGeoreference table on vector of geometries geoms.\n\ngeoms must implement the Meshes.jl interface (e.g., Point, Quadrangle, Hexahedron).\n\nExamples\n\njulia> georef((a=rand(10), b=rand(10)), rand(Point2, 10))\n\n\n\n\n\ngeoref(table, coords)\n\nGeoreference table on PointSet(coords).\n\nExamples\n\njulia> georef((a=rand(10), b=rand(10)), rand(2, 10))\n\n\n\n\n\ngeoref(table, names; [crs])\n\nGeoreference table using coordinates stored in given column names.\n\nOptionally, specify the coordinate reference system crs, which is set by default based on heuristics.\n\nExamples\n\ngeoref((a=rand(10), x=rand(10), y=rand(10)), (\"x\", \"y\"))\ngeoref((a=rand(10), x=rand(10), y=rand(10)), [\"x\", \"y\"])\ngeoref((a=rand(10), x=rand(10), y=rand(10)), [\"x\", \"y\"], crs=Cartesian)\ngeoref((a=rand(10), x=rand(10), y=rand(10)), [\"x\", \"y\"], crs=LatLon)\n\n\n\n\n\ngeoref(tuple)\n\nGeoreference a named tuple on CartesianGrid(dims), with dims being the dimensions of the tuple arrays.\n\nExamples\n\njulia> georef((a=rand(10, 10), b=rand(10, 10))) # 2D grid\njulia> georef((a=rand(10, 10, 10), b=rand(10, 10, 10))) # 3D grid\n\n\n\n\n\n","category":"function"},{"location":"data/","page":"Data","title":"Data","text":"The functions values and domain can be used to retrieve the table of attributes and the underlying geospatial domain:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"values\ndomain","category":"page"},{"location":"data/#Base.values","page":"Data","title":"Base.values","text":"values(geotable, [rank])\n\nReturn the values of geotable for a given rank as a table.\n\nThe rank is a non-negative integer that specifies the parametric dimension of the geometries of interest:\n\n0 - points\n1 - segments\n2 - triangles, quadrangles, ...\n3 - tetrahedrons, hexahedrons, ...\n\nIf the rank is not specified, it is assumed to be the rank of the elements of the domain.\n\n\n\n\n\n","category":"function"},{"location":"data/#GeoTables.domain","page":"Data","title":"GeoTables.domain","text":"domain(geotable)\n\nReturn underlying domain of the geotable.\n\n\n\n\n\n","category":"function"},{"location":"data/","page":"Data","title":"Data","text":"The GeoIO.jl package can be used to load/save geospatial data from/to various file formats:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"GeoIO.load\nGeoIO.save\nGeoIO.formats","category":"page"},{"location":"data/#GeoIO.load","page":"Data","title":"GeoIO.load","text":"load(fname, layer=0, fix=true, kwargs...)\n\nLoad geospatial table from file fname and convert the geometry column to Meshes.jl geometries.\n\nOptionally, specify the layer of geometries to read within the file and keyword arguments kwargs accepted by Shapefile.Table, GeoJSON.read GeoParquet.read and ArchGDAL.read.\n\nThe option fix can be used to fix orientation and degeneracy issues with polygons.\n\nTo see supported formats, use the formats function.\n\n\n\n\n\n","category":"function"},{"location":"data/#GeoIO.save","page":"Data","title":"GeoIO.save","text":"save(fname, geotable; kwargs...)\n\nSave geospatial table to file fname using the appropriate format based on the file extension. Optionally, specify keyword arguments accepted by Shapefile.write and GeoJSON.write. For example, use force = true to force writing on existing .shp file.\n\nTo see supported formats, use the formats function.\n\n\n\n\n\n","category":"function"},{"location":"data/#GeoIO.formats","page":"Data","title":"GeoIO.formats","text":"formats([io]; sortby=:format)\n\nDisplays in io (defaults to stdout if io is not given) a table with all formats supported by GeoIO.jl and the packages used to load and save each of them. \n\nOptionally, sort the table by the :extension, :load or :save columns using the sortby argument.\n\n\n\n\n\n","category":"function"},{"location":"data/","page":"Data","title":"Data","text":"The GeoArtifacts.jl package provides utility functions to automatically download geospatial data from repositories on the internet.","category":"page"},{"location":"data/#Examples","page":"Data","title":"Examples","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"using GeoStats\nimport CairoMakie as Mke\n\n# helper function for plotting two\n# variables named T and P side by side\nfunction plot(data)\n fig = Mke.Figure(size = (800, 400))\n viz(fig[1,1], data.geometry, color = data.T)\n viz(fig[1,2], data.geometry, color = data.P)\n fig\nend","category":"page"},{"location":"data/#Tables","page":"Data","title":"Tables","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Consider a table (e.g. DataFrame) with 25 samples of temperature T and pressure P:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"using DataFrames\n\ntable = DataFrame(T=rand(25), P=rand(25))","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"We can georeference this table based on a given set of points:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef(table, rand(Point{2}, 25)) |> plot","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"or alternatively, georeference it on a 5x5 regular grid (5x5 = 25 samples):","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef(table, CartesianGrid(5, 5)) |> plot","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"Another common pattern in geospatial data is when the coordinates of the samples are already part of the table as columns. In this case, we can specify the column names:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"table = DataFrame(T=rand(25), P=rand(25), X=rand(25), Y=rand(25), Z=rand(25))\n\ngeoref(table, (\"X\", \"Y\", \"Z\")) |> plot","category":"page"},{"location":"data/#Arrays","page":"Data","title":"Arrays","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Consider arrays (e.g. images) with data for various geospatial variables. We can georeference these arrays using a named tuple, and the framework will understand that the shape of the arrays should be preserved in a CartesianGrid:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"T, P = rand(5, 5), rand(5, 5)\n\ngeoref((T=T, P=P)) |> plot","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"Alternatively, we can interpret the entries of the named tuple as columns in a table:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef((T=vec(T), P=vec(P)), rand(Point{2}, 25)) |> plot","category":"page"},{"location":"data/#Files","page":"Data","title":"Files","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"We can easily load geospatial data from disk without any specific knowledge of file formats:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"using GeoIO\n\nzone = GeoIO.load(\"data/zone.shp\")\npath = GeoIO.load(\"data/path.shp\")\n\nviz(zone.geometry)\nviz!(path.geometry, color = :gray90)\nMke.current_figure()","category":"page"},{"location":"visualization/#Visualization","page":"Visualization","title":"Visualization","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"The framework provides powerful visualization recipes for geospatial data science via the Makie.jl project. These recipes were carefully designed to maximize productivity and to protect users from GIS jargon. The main entry point is the viz function:","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"viz\nviz!","category":"page"},{"location":"visualization/#Meshes.viz","page":"Visualization","title":"Meshes.viz","text":"viz(object; [options])\n\nVisualize Meshes.jl object with various options.\n\nAvailable options\n\ncolor - color of geometries\nalpha - transparency in [0,1]\ncolormap - color scheme/map from ColorSchemes.jl\ncolorrange - minimum and maximum color values\nshowsegments - visualize segments\nsegmentcolor - color of segments\nsegmentsize - width of segments\nshowpoints - visualize points\npointcolor - color of points\npointsize - size of points\n\nThe option color can be a single scalar or a vector of scalars. For Mesh subtypes, the length of the vector of colors determines if the colors should be assigned to vertices or to elements.\n\nExamples\n\nDifferent coloring methods (vertex vs. element):\n\n# vertex coloring (i.e. linear interpolation)\nviz(mesh, color = 1:nvertices(mesh))\n\n# element coloring (i.e. discrete colors)\nviz(mesh, color = 1:nelements(mesh))\n\nDifferent strategies to show the boundary of geometries (showsegments vs. boundary):\n\n# visualize boundary with showsegments\nviz(polygon, showsegments = true)\n\n# visualize boundary with separate call\nviz(polygon)\nviz!(boundary(polygon))\n\nNotes\n\nThis function will only work in the presence of a Makie.jl backend via package extensions in Julia v1.9 or later versions of the language.\n\n\n\n\n\n","category":"function"},{"location":"visualization/#Meshes.viz!","page":"Visualization","title":"Meshes.viz!","text":"viz!(object; [options])\n\nVisualize Meshes.jl object in an existing scene with options forwarded to viz.\n\n\n\n\n\n","category":"function"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"This function takes a geospatial domain as input and provides a set of aesthetic options to style the elements (i.e. geometries) of the domain.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"note: Note\nNotice that the geometry column of our geospatial data type is a domain (i.e. data.geometry isa Domain), and that this design enables several optimizations in the visualization itself.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Users can also call Makie's plot function in the geometry column as in","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Mke.plot(data.geometry)","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"and this is equivalent to calling the viz recipe above. The plot function also works with various other objects such as EmpiricalHistogram and EmpiricalVariogram. That is convenient if you don't remember the name of the recipe.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Additionaly, we provide a basic scientific viewer to visualize all viewable variables in the data:","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"viewer","category":"page"},{"location":"visualization/#GeoTables.viewer","page":"Visualization","title":"GeoTables.viewer","text":"viewer(geotable; kwargs...)\n\nBasic scientific viewer for geospatial table geotable.\n\nAesthetic options are forwarded via kwargs to the Meshes.viz recipe.\n\n\n\n\n\n","category":"function"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Other plots are listed below that can be useful for geostatistical analysis.","category":"page"},{"location":"visualization/#Built-in","page":"Visualization","title":"Built-in","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"A hscatter plot between two variables var1 and var2 (possibly with var2 = var1) is a simple scatter plot in which the dots represent all ordered pairs of values of var1 and var2 at a given lag h.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"𝒟 = georef((Z=[10sin(i/10) + j for i in 1:100, j in 1:200],))\n\n𝒮 = sample(𝒟, UniformSampling(500))\n\nfig = Mke.Figure(size = (800, 400))\nhscatter(fig[1,1], 𝒮, :Z, :Z, lag=0)\nhscatter(fig[1,2], 𝒮, :Z, :Z, lag=20)\nhscatter(fig[2,1], 𝒮, :Z, :Z, lag=40)\nhscatter(fig[2,2], 𝒮, :Z, :Z, lag=60)\nfig","category":"page"},{"location":"visualization/#PairPlots.jl","page":"Visualization","title":"PairPlots.jl","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"The PairPlots.jl package provides the pairplot function that can be used with any table, including tables of attributes obtained with the values function.","category":"page"},{"location":"visualization/#Biplots.jl","page":"Visualization","title":"Biplots.jl","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"The Biplot.jl package provides 2D and 3D statistical biplots.","category":"page"},{"location":"resources/education/#Education","page":"Education","title":"Education","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"We recommend the following educational resources.","category":"page"},{"location":"resources/education/#Learning-resources","page":"Education","title":"Learning resources","text":"","category":"section"},{"location":"resources/education/#Textbooks","page":"Education","title":"Textbooks","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"Hoffimann, J. 2023. Geospatial Data Science with Julia - A fresh approach to data science with geospatial data and the Julia programming language.\nIsaaks, E. and Srivastava, R. 1990. An Introduction to Applied Geostatistics - An introductory book on geostatistics that covers important concepts with very simple language.\nChilès, JP and Delfiner, P. 2012. Geostatistics: Modeling Spatial Uncertainty - An incredible book for those with good mathematical background.\nWebster, R and Oliver, MA. 2007. Geostatistics for Environmental Scientists - A great book with good balance between theory and practice.\nJournel, A. and Huijbregts, Ch. 2003. Mining Geostatistics - A great book with both theoretical and practical developments.","category":"page"},{"location":"resources/education/#Video-lectures","page":"Education","title":"Video lectures","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"Júlio Hoffimann - Video lectures with the GeoStats.jl framework.\nEdward Isaaks - Video lectures on variography, Kriging and related concepts.\nJef Caers - Video lectures on two-point and multiple-point methods.","category":"page"},{"location":"resources/education/#Workshop-material","page":"Education","title":"Workshop material","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"UFMG 2023 [Portuguese] - Geociência de Dados na Mineração, UFMG 2023\nJuliaEO 2023 [English] - Global Workshop on Earth Observation, AIRCentre 2023\nCBMina 2021 [Portuguese] - Introução à Geoestatística, CBMina 2021\nUFMG 2021 [Portuguese] - Introdução à Geoestatística, UFMG 2021","category":"page"},{"location":"resources/education/#Related-concepts","page":"Education","title":"Related concepts","text":"","category":"section"},{"location":"resources/education/#GaussianProcesses.jl","page":"Education","title":"GaussianProcesses.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"GaussianProcesses.jl - Gaussian process regression and Simple Kriging are essentially two names for the same concept. The derivation of Kriging estimators, however; does not require distributional assumptions. It is a beautiful coincidence that for multivariate Gaussian distributions, Simple Kriging gives the conditional expectation.","category":"page"},{"location":"resources/education/#KernelFunctions.jl","page":"Education","title":"KernelFunctions.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"KernelFunctions.jl - Spatial structure can be represented in many different forms: covariance, variogram, correlogram, etc. Variograms are more general than covariance kernels according to the intrinsic stationary property. This means that there are variogram models with no covariance counterpart. Furthermore, empirical variograms can be easily estimated from the data (in various directions) with an efficient procedure. GeoStats.jl treats variograms as first-class objects.","category":"page"},{"location":"resources/education/#Interpolations.jl","page":"Education","title":"Interpolations.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"Interpolations.jl - Kriging and spline interpolation have different purposes, yet these two methods are sometimes listed as competing alternatives. Kriging estimation is about minimizing variance (or estimation error), whereas spline interpolation is about deriving smooth estimators for computer visualization. Kriging is a generalization of splines in which one has the freedom to customize geospatial structure based on data. Besides the estimate itself, Kriging also provides the variance map as a function of point patterns.","category":"page"},{"location":"resources/education/#ScikitLearn.jl","page":"Education","title":"ScikitLearn.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"ScikitLearn.jl - Traditional statistical learning relies on core assumptions that do not hold in geospatial settings (fixed support, i.i.d. samples, ...). Geostatistical learning has been introduced recently as an attempt to push the frontiers of statistical learning with geospatial data.","category":"page"},{"location":"about/license/","page":"License","title":"License","text":"The GeoStats.jl project is licensed under the MIT license:","category":"page"},{"location":"about/license/","page":"License","title":"License","text":"MIT License\n\nCopyright (c) 2015 Júlio Hoffimann and contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","category":"page"},{"location":"domains/#Domains","page":"Domains","title":"Domains","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"domains/#Overview","page":"Domains","title":"Overview","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"A geospatial domain is a (discretized) region in physical space. For example, a collection of rain gauge stations can be represented as a PointSet in the map. Similarly, a collection of states in a given country can be represented as a GeometrySet of polygons.","category":"page"},{"location":"domains/","page":"Domains","title":"Domains","text":"We provide flexible domain types for advanced geospatial workflows via the Meshes.jl submodule. The domains can consist of sets (or \"soups\") of geometries as it is most common in GIS or be actual meshes with topological information.","category":"page"},{"location":"domains/","page":"Domains","title":"Domains","text":"Domain\nMesh","category":"page"},{"location":"domains/#Meshes.Domain","page":"Domains","title":"Meshes.Domain","text":"Domain{Dim,CRS}\n\nA domain is an indexable collection of geometries (e.g. mesh).\n\n\n\n\n\n","category":"type"},{"location":"domains/#Meshes.Mesh","page":"Domains","title":"Meshes.Mesh","text":"Mesh{Dim,CRS,TP}\n\nA mesh embedded in a Dim-dimensional space with given coordinate reference system CRS and topology of type TP.\n\n\n\n\n\n","category":"type"},{"location":"domains/#Examples","page":"Domains","title":"Examples","text":"","category":"section"},{"location":"domains/#PointSet","page":"Domains","title":"PointSet","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"PointSet","category":"page"},{"location":"domains/#Meshes.PointSet","page":"Domains","title":"Meshes.PointSet","text":"PointSet(points)\n\nA set of points (a.k.a. point cloud) representing a Domain.\n\nExamples\n\nAll point sets below are the same and contain two points in R³:\n\njulia> PointSet([Point(1,2,3), Point(4,5,6)])\njulia> PointSet(Point(1,2,3), Point(4,5,6))\njulia> PointSet([(1,2,3), (4,5,6)])\njulia> PointSet((1,2,3), (4,5,6))\njulia> PointSet([[1,2,3], [4,5,6]])\njulia> PointSet([1,2,3], [4,5,6])\njulia> PointSet([1 4; 2 5; 3 6])\n\n\n\n\n\n","category":"type"},{"location":"domains/","page":"Domains","title":"Domains","text":"pset = PointSet(rand(Point{3}, 100))\n\nviz(pset)","category":"page"},{"location":"domains/#GeometrySet","page":"Domains","title":"GeometrySet","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"GeometrySet","category":"page"},{"location":"domains/#Meshes.GeometrySet","page":"Domains","title":"Meshes.GeometrySet","text":"GeometrySet(geometries)\n\nA set of geometries representing a Domain.\n\nExamples\n\nSet containing two balls centered at (0.0, 0.0) and (1.0, 1.0):\n\njulia> GeometrySet([Ball((0.0, 0.0)), Ball((1.0, 1.0))])\n\n\n\n\n\n","category":"type"},{"location":"domains/","page":"Domains","title":"Domains","text":"tria = Triangle((0.0, 0.0), (1.0, 1.0), (0.0, 1.0))\nquad = Quadrangle((1.0, 1.0), (2.0, 1.0), (2.0, 2.0), (1.0, 2.0))\ngset = GeometrySet([tria, quad])\n\nviz(gset, showsegments = true)","category":"page"},{"location":"domains/#CartesianGrid","page":"Domains","title":"CartesianGrid","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"CartesianGrid","category":"page"},{"location":"domains/#Meshes.CartesianGrid","page":"Domains","title":"Meshes.CartesianGrid","text":"CartesianGrid(dims, origin, spacing)\n\nA Cartesian grid with dimensions dims, lower left corner at origin and cell spacing spacing. The three arguments must have the same length.\n\nCartesianGrid(dims, origin, spacing, offset)\n\nA Cartesian grid with dimensions dims, with lower left corner of element offset at origin and cell spacing spacing.\n\nCartesianGrid(start, finish, dims=dims)\n\nAlternatively, construct a Cartesian grid from a start point (lower left) to a finish point (upper right).\n\nCartesianGrid(start, finish, spacing)\n\nAlternatively, construct a Cartesian grid from a start point to a finish point using a given spacing.\n\nCartesianGrid(dims)\nCartesianGrid(dim1, dim2, ...)\n\nFinally, a Cartesian grid can be constructed by only passing the dimensions dims as a tuple, or by passing each dimension dim1, dim2, ... separately. In this case, the origin and spacing default to (0,0,...) and (1,1,...).\n\nExamples\n\nCreate a 3D grid with 100x100x50 hexahedrons:\n\njulia> CartesianGrid(100, 100, 50)\n\nCreate a 2D grid with 100 x 100 quadrangles and origin at (10.0, 20.0):\n\njulia> CartesianGrid((100, 100), (10.0, 20.0), (1.0, 1.0))\n\nCreate a 1D grid from -1 to 1 with 100 segments:\n\njulia> CartesianGrid((-1.0,), (1.0,), dims=(100,))\n\n\n\n\n\n","category":"type"},{"location":"domains/","page":"Domains","title":"Domains","text":"grid = CartesianGrid(10, 10, 10)\n\nviz(grid, showsegments = true)","category":"page"},{"location":"kriging/#Kriging","page":"Kriging","title":"Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"note: Note\nThis section describes the Kriging models used in the Interpolate and InterpolateNeighbors transforms, which provide options for neighborhood search, change of support, etc.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"A Kriging model has the form:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"hatZ(x_0) = lambda_1 Z(x_1) + lambda_2 Z(x_2) + cdots + lambda_n Z(x_n)quad x_i in R^m lambda_i in R","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with Zcolon R^m times Omega to R a random field.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"This package implements the following Kriging variants:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"Simple Kriging\nOrdinary Kriging\nUniversal Kriging\nExternal Drift Kriging","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"All these variants follow the same interface: an object is first created with a given set of parameters, it is then combined with the data to obtain predictions at new geometries.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The fit function takes care of building the Kriging system and factorizing the LHS with an appropriate decomposition (e.g. Cholesky, LU), and the predict (or predictprob) function performs the estimation for a given variable and geometry.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"All variants work with general Hilbert spaces, meaning that one can interpolate any data type that implements scalar multiplication, vector addition and inner product.","category":"page"},{"location":"kriging/#Simple-Kriging","page":"Kriging","title":"Simple Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In Simple Kriging, the mean mu of the random field is assumed to be constant and known. The resulting linear system is:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"beginbmatrix\ncov(x_1x_1) cov(x_1x_2) cdots cov(x_1x_n) \ncov(x_2x_1) cov(x_2x_2) cdots cov(x_2x_n) \nvdots vdots ddots vdots \ncov(x_nx_1) cov(x_nx_2) cdots cov(x_nx_n)\nendbmatrix\nbeginbmatrix\nlambda_1 \nlambda_2 \nvdots \nlambda_n\nendbmatrix\n=\nbeginbmatrix\ncov(x_1x_0) \ncov(x_2x_0) \nvdots \ncov(x_nx_0)\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"or in matricial form Cl = c. We subtract the given mean from the observations boldsymboly = z - mu 1 and compute the mean and variance at location x_0:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_0) = mu + boldsymboly^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"sigma^2(x_0) = cov(0) - c^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.SimpleKriging","category":"page"},{"location":"kriging/#GeoStatsModels.SimpleKriging","page":"Kriging","title":"GeoStatsModels.SimpleKriging","text":"SimpleKriging(γ, μ)\n\nSimple Kriging with variogram model γ and constant mean μ.\n\nNotes\n\nSimple Kriging requires stationary variograms\n\n\n\n\n\n","category":"type"},{"location":"kriging/#Ordinary-Kriging","page":"Kriging","title":"Ordinary Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In Ordinary Kriging the mean of the random field is assumed to be constant and unknown. The resulting linear system is:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"beginbmatrix\nG 1 \n1^top 0\nendbmatrix\nbeginbmatrix\nl \nnu\nendbmatrix\n=\nbeginbmatrix\ng \n1\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with nu the Lagrange multiplier associated with the constraint 1^top l = 1. The mean and variance at location x_0 are given by:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_0) = z^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"sigma^2(x_0) = beginbmatrix g 1 endbmatrix^top beginbmatrix l nu endbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.OrdinaryKriging","category":"page"},{"location":"kriging/#GeoStatsModels.OrdinaryKriging","page":"Kriging","title":"GeoStatsModels.OrdinaryKriging","text":"OrdinaryKriging(γ)\n\nOrdinary Kriging with variogram model γ.\n\n\n\n\n\n","category":"type"},{"location":"kriging/#Universal-Kriging","page":"Kriging","title":"Universal Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In Universal Kriging, the mean of the random field is assumed to be a polynomial of the geospatial coordinates:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x) = sum_k=1^N_d beta_k f_k(x)","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with N_d monomials f_k of degree up to d. For example, in 2D there are 6 monomials of degree up to 2:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_1x_2) = beta_1 1 + beta_2 x_1 + beta_3 x_2 + beta_4 x_1 x_2 + beta_5 x_1^2 + beta_6 x_2^2","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The choice of the degree d determines the size of the polynomial matrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"F =\nbeginbmatrix\nf_1(x_1) f_2(x_1) cdots f_N_d(x_1) \nf_1(x_2) f_2(x_2) cdots f_N_d(x_2) \nvdots vdots ddots vdots \nf_1(x_n) f_2(x_n) cdots f_N_d(x_n)\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"and polynomial vector f = beginbmatrix f_1(x_0) f_2(x_0) cdots f_N_d(x_0) endbmatrix^top.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The variogram determines the variogram matrix:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"G =\nbeginbmatrix\ngamma(x_1x_1) gamma(x_1x_2) cdots gamma(x_1x_n) \ngamma(x_2x_1) gamma(x_2x_2) cdots gamma(x_2x_n) \nvdots vdots ddots vdots \ngamma(x_nx_1) gamma(x_nx_2) cdots gamma(x_nx_n)\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"and the variogram vector g = beginbmatrix gamma(x_1x_0) gamma(x_2x_0) cdots gamma(x_nx_0) endbmatrix^top.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The resulting linear system is:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"beginbmatrix\nG F \nF^top boldsymbol0\nendbmatrix\nbeginbmatrix\nl \nboldsymbolnu\nendbmatrix\n=\nbeginbmatrix\ng \nf\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with boldsymbolnu the Lagrange multipliers associated with the universal constraints. The mean and variance at location x_0 are given by:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_0) = z^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"sigma^2(x_0) = beginbmatrixg fendbmatrix^top beginbmatrixl boldsymbolnuendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.UniversalKriging","category":"page"},{"location":"kriging/#GeoStatsModels.UniversalKriging","page":"Kriging","title":"GeoStatsModels.UniversalKriging","text":"UniversalKriging(γ, degree, dim)\n\nUniversal Kriging with variogram model γ and polynomial degree on a geospatial domain of dimension dim.\n\nNotes\n\nOrdinaryKriging is recovered for 0th degree polynomial\nFor non-polynomial mean, see ExternalDriftKriging\n\n\n\n\n\n","category":"type"},{"location":"kriging/#External-Drift-Kriging","page":"Kriging","title":"External Drift Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In External Drift Kriging, the mean of the random field is assumed to be a combination of known smooth functions:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x) = sum_k beta_k m_k(x)","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"Differently than Universal Kriging, the functions m_k are not necessarily polynomials of the geospatial coordinates. In practice, they represent a list of variables that is strongly correlated (and co-located) with the variable being estimated.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"External drifts are known to cause numerical instability. Give preference to other Kriging variants if possible.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.ExternalDriftKriging","category":"page"},{"location":"kriging/#GeoStatsModels.ExternalDriftKriging","page":"Kriging","title":"GeoStatsModels.ExternalDriftKriging","text":"ExternalDriftKriging(γ, drifts)\n\nExternal Drift Kriging with variogram model γ and external drifts functions.\n\nNotes\n\nExternal drift functions should be smooth\nKriging system with external drift is often unstable\nInclude a constant drift (e.g. x->1) for unbiased estimation\nOrdinaryKriging is recovered for drifts = [x->1]\nFor polynomial mean, see UniversalKriging\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#Fields","page":"Fields","title":"Fields","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Base.rand(::GeoStatsProcesses.FieldProcess, ::Domain, ::Any, ::Any)","category":"page"},{"location":"random/fields/#Base.rand-Tuple{GeoStatsProcesses.FieldProcess, Domain, Any, Any}","page":"Fields","title":"Base.rand","text":"rand([rng], process::FieldProcess, domain, data, [nreals], [method]; [parameters])\n\nGenerate one or nreals realizations of the field process with method over the domain with data and optional paramaters. Optionally, specify the random number generator rng and global parameters.\n\nThe data can be a geotable, a pair, or an iterable of pairs of the form var => T, where var is a symbol or string with the variable name and T is the corresponding data type.\n\nParameters\n\npool - Pool of worker processes (default to [myid()])\nthreads - Number of threads (default to cpucores())\nverbose - Show progress and other information (default to true)\n\nExamples\n\njulia> rand(process, domain, geotable, 3)\njulia> rand(process, domain, :z => Float64)\njulia> rand(process, domain, \"z\" => Float64)\njulia> rand(process, domain, [:a => Float64, :b => Float64])\njulia> rand(process, domain, [\"a\" => Float64, \"b\" => Float64])\n\n\n\n\n\n","category":"method"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Realizations are stored in an Ensemble as illustrated in the following example:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Ensemble","category":"page"},{"location":"random/fields/#GeoStatsBase.Ensemble","page":"Fields","title":"GeoStatsBase.Ensemble","text":"Ensemble\n\nAn ensemble of geostatistical realizations from a geostatistical process.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = CartesianGrid(100, 100)\n\n# Gaussian process\nproc = GaussianProcess(GaussianVariogram(range=30.0))\n\n# unconditional simulation\nreal = rand(proc, grid, [:Z => Float64], 100)","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"We can visualize the first two realizations:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"fig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"the mean and variance:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"m, v = mean(real), var(real)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], m.geometry, color = m.Z)\nviz(fig[1,2], v.geometry, color = v.Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"or the 25th and 75th percentiles:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"q25 = quantile(real, 0.25)\nq75 = quantile(real, 0.75)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], q25.geometry, color = q25.Z)\nviz(fig[1,2], q75.geometry, color = q75.Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"All field processes can generate realizations in parallel using multiple Julia processes. Doing so requires using the Distributed standard library, like in the following example:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using Distributed\n\n# request additional processes\naddprocs(3)\n\n# load code on every single process\n@everywhere using GeoStats\n\n# ------------\n# main script\n# ------------\n\n# domain of interest\ngrid = CartesianGrid(100, 100)\n\n# Gaussian process\nproc = GaussianProcess(GaussianVariogram(range=30.0))\n\n# generate three realizations with three processes\nreal = rand(proc, grid, [:Z => Float64], 3, pool = workers())","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Please consult The ultimate guide to distributed computing in Julia.","category":"page"},{"location":"random/fields/#Builtin","page":"Fields","title":"Builtin","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"The following processes are shipped with the framework.","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"GaussianProcess\nLUMethod\nFFTMethod\nSEQMethod","category":"page"},{"location":"random/fields/#GeoStatsProcesses.GaussianProcess","page":"Fields","title":"GeoStatsProcesses.GaussianProcess","text":"GaussianProcess(variogram=GaussianVariogram(), mean=0.0)\n\nGaussian process with given theoretical variogram and global mean.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#GeoStatsProcesses.LUMethod","page":"Fields","title":"GeoStatsProcesses.LUMethod","text":"LUMethod(; [paramaters])\n\nThe LU Gaussian process method introduced by Alabert 1987. The full covariance matrix is built to include all locations of the process domain, and samples from the multivariate Gaussian are drawn via LU factorization.\n\nParameters\n\nfactorization - Factorization method (default to cholesky)\ncorrelation - Correlation coefficient between two covariates (default to 0)\ninit - Data initialization method (default to NearestInit())\n\nReferences\n\nAlabert 1987. The practice of fast conditional simulations through the LU decomposition of the covariance matrix\nOliver 2003. Gaussian cosimulation: modeling of the cross-covariance\n\nNotes\n\nThe method is only adequate for domains with relatively small number of elements (e.g. 100x100 grids) where it is feasible to factorize the full covariance.\nFor larger domains (e.g. 3D grids), other methods are preferred such as SEQMethod and FFTMethod.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#GeoStatsProcesses.FFTMethod","page":"Fields","title":"GeoStatsProcesses.FFTMethod","text":"FFTMethod(; [paramaters])\n\nThe FFT Gaussian process method introduced by Gutjahr 1997. The covariance function is perturbed in the frequency domain after a fast Fourier transform. White noise is added to the phase of the spectrum, and a realization is produced by an inverse Fourier transform.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - Distance used to find nearest neighbors (default to Euclidean())\n\nReferences\n\nGutjahr 1997. General joint conditional simulations using a fast Fourier transform method\nGómez-Hernández, J. & Srivastava, R. 2021. One Step at a Time: The Origins of Sequential Simulation and Beyond\n\nNotes\n\nThe method is limited to simulations on Cartesian grids, and care must be taken to make sure that the correlation length is small enough compared to the grid size.\nAs a general rule of thumb, avoid correlation lengths greater than 1/3 of the grid.\nThe method is extremely fast, and can be used to generate large 3D realizations.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#GeoStatsProcesses.SEQMethod","page":"Fields","title":"GeoStatsProcesses.SEQMethod","text":"SEQMethod(; [paramaters])\n\nThe sequential process method introduced by Gomez-Hernandez 1993. It traverses all locations of the geospatial domain according to a path, approximates the conditional Gaussian distribution within a neighborhood using simple Kriging, and assigns a value to the center of the neighborhood by sampling from this distribution.\n\nParameters\n\npath - Process path (default to LinearPath())\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 36)\nneighborhood - Search neighborhood (default to :range)\ndistance - Distance used to find nearest neighbors (default to Euclidean())\ninit - Data initialization method (default to NearestInit())\n\nFor each location in the process path, a maximum number of neighbors maxneighbors is used to fit the conditional Gaussian distribution. The neighbors are searched according to a neighborhood.\n\nThe neighborhood can be a MetricBall, the symbol :range or nothing. The symbol :range is converted to MetricBall(range(γ)) where γ is the variogram of the Gaussian process. If neighborhood is nothing, the nearest neighbors are used without additional constraints.\n\nReferences\n\nGomez-Hernandez & Journel 1993. Joint Sequential Simulation of MultiGaussian Fields\n\nNotes\n\nThis method is very sensitive to the various parameters. Care must be taken to make sure that enough neighbors are used in the underlying Kriging model.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = CartesianGrid(100, 100)\n\n# Gaussian process\nproc = GaussianProcess(GaussianVariogram(range=30.0))\n\n# unconditional simulation\nreal = rand(proc, grid, [:Z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"LindgrenProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.LindgrenProcess","page":"Fields","title":"GeoStatsProcesses.LindgrenProcess","text":"LindgrenProcess(range=1.0, sill=1.0; init=NearestInit())\n\nLindgren process with given range (correlation length) and sill (total variance) as described in Lindgren 2011. Optionally, specify the data initialization method init.\n\nThe process relies relies on a discretization of the Laplace-Beltrami operator on meshes and is adequate for highly curved domains (e.g. surfaces).\n\nReferences\n\nLindgren et al. 2011. An explicit link between Gaussian fields and Gaussian Markov random fields: the stochastic partial differential equation approach\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#External","page":"Fields","title":"External","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"The following processes are available in external packages.","category":"page"},{"location":"random/fields/#ImageQuilting.jl","page":"Fields","title":"ImageQuilting.jl","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"QuiltingProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.QuiltingProcess","page":"Fields","title":"GeoStatsProcesses.QuiltingProcess","text":"QuiltingProcess(trainimg, tilesize; [paramaters])\n\nImage quilting process with training image trainimg and tile size tilesize as described in Hoffimann et al. 2017.\n\nParameters\n\noverlap - Overlap size (default to (1/6, 1/6, ..., 1/6))\npath - Process path (:raster (default), :dilation, or :random)\ninactive - Vector of inactive voxels (i.e. CartesianIndex) in the grid\nsoft - A pair (data,dataTI) of geospatial data objects (default to nothing)\ntol - Initial relaxation tolerance in (0,1] (default to 0.1)\ninit - Data initialization method (default to NearestInit())\n\nReferences\n\nHoffimann et al 2017. Stochastic simulation by image quilting of process-based geological models\nHoffimann et al 2015. Geostatistical modeling of evolving landscapes by means of image quilting\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using ImageQuilting\nusing GeoArtifacts\n\n# domain of interest\ngrid = CartesianGrid(200, 200)\n\n# quilting process\nimg = GeoStatsImages.get(\"Strebelle\")\nproc = QuiltingProcess(img, (62, 62))\n\n# unconditional simulation\nreal = rand(proc, grid, [:facies => Int], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].facies)\nviz(fig[1,2], real[2].geometry, color = real[2].facies)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = CartesianGrid(200, 200)\n\n# quilting process\nimg = GeoStatsImages.get(\"StoneWall\")\nproc = QuiltingProcess(img, (13, 13))\n\n# unconditional simulation\nreal = rand(proc, grid, [:Z => Int], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = domain(img)\n\n# pre-existing observations\nimg = GeoStatsImages.get(\"Strebelle\")\ndata = img |> Sample(20, replace=false)\n\n# quilting process\nproc = QuiltingProcess(img, (30, 30))\n\n# conditional simulation\nreal = rand(proc, grid, data, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].facies)\nviz(fig[1,2], real[2].geometry, color = real[2].facies)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Voxels marked with the special symbol NaN are treated as inactive. The algorithm will skip tiles that only contain inactive voxels to save computation and will generate realizations that are consistent with the mask. This is particularly useful with complex 3D models that have large inactive portions.","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = domain(img)\n\n# skip circle at the center\nnx, ny = size(grid)\nr = 100; circle = []\nfor i in 1:nx, j in 1:ny\n if (i-nx÷2)^2 + (j-ny÷2)^2 < r^2\n push!(circle, CartesianIndex(i, j))\n end\nend\n\n# quilting process\nproc = QuiltingProcess(img, (62, 62), inactive = circle)\n\n# unconditional simulation\nreal = rand(proc, grid, [:facies => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].facies)\nviz(fig[1,2], real[2].geometry, color = real[2].facies)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"It is possible to incorporate auxiliary variables to guide the selection of patterns from the training image.","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using ImageFiltering\n\n# image assumed as ground truth (unknown)\ntruth = GeoStatsImages.get(\"WalkerLakeTruth\")\n\n# training image with similar patterns\nimg = GeoStatsImages.get(\"WalkerLake\")\n\n# forward model (blur filter)\nfunction forward(data)\n img = asarray(data, :Z)\n krn = KernelFactors.IIRGaussian([10,10])\n fwd = imfilter(img, krn)\n georef((; fwd=vec(fwd)), domain(data))\nend\n\n# apply forward model to both images\ndata = forward(truth)\ndataTI = forward(img)\n\nproc = QuiltingProcess(img, (27, 27), soft=(data, dataTI))\n\nreal = rand(proc, domain(truth), [:Z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/#TuringPatterns.jl","page":"Fields","title":"TuringPatterns.jl","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"TuringProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.TuringProcess","page":"Fields","title":"GeoStatsProcesses.TuringProcess","text":"TuringProcess(; [paramaters])\n\nTuring process as described in Turing 1952.\n\nParameters\n\nparams - basic parameters (default to nothing)\nblur - blur algorithm (default to nothing)\nedge - edge condition (default to nothing)\niter - number of iterations (default to 100)\n\nReferences\n\nTuring 1952. The chemical basis of morphogenesis\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using TuringPatterns\n\n# domain of interest\ngrid = CartesianGrid(200, 200)\n\n# unconditional simulation\nreal = rand(TuringProcess(), grid, [:z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].z)\nviz(fig[1,2], real[2].geometry, color = real[2].z)\nfig","category":"page"},{"location":"random/fields/#StratiGraphics.jl","page":"Fields","title":"StratiGraphics.jl","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"StrataProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.StrataProcess","page":"Fields","title":"GeoStatsProcesses.StrataProcess","text":"StrataProcess(environment; [paramaters])\n\nStrata process with given geological environment as described in Hoffimann 2018.\n\nParameters\n\nstate - Initial geological state\nstack - Stacking scheme (:erosional or :depositional)\nnepochs - Number of epochs (default to 10)\n\nReferences\n\nHoffimann 2018. Morphodynamic analysis and statistical synthesis of geormorphic data\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using StratiGraphics\n\n# domain of interest\ngrid = CartesianGrid(50, 50, 20)\n\n# stratigraphic environment\np = SmoothingProcess()\nT = [0.5 0.5; 0.5 0.5]\nΔ = ExponentialDuration(1.0)\nℰ = Environment([p, p], T, Δ)\n\n# strata simulation\nreal = rand(StrataProcess(ℰ), grid, [:z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].z)\nviz(fig[1,2], real[2].geometry, color = real[2].z)\nfig","category":"page"},{"location":"resources/publications/#Publications","page":"Publications","title":"Publications","text":"","category":"section"},{"location":"resources/publications/","page":"Publications","title":"Publications","text":"Below is a list of publications made possible with this project:","category":"page"},{"location":"resources/publications/","page":"Publications","title":"Publications","text":"Hoffimann, J. 2023. Geospatial Data Science with Julia\nGruchalla et al. 2023. Reevaluating Contour Visualizations for Power Systems Data\nKarsanina, M. & Gerke, K. 2022. Stochastic (re)constructions of non-stationary material structures: Using ensemble averaged correlation functions and non-uniform phase distributions\nSepúlveda et al. 2022. Evaluation of multivariate Gaussian transforms for geostatistical applications\nHoffimann et al. 2022. Modeling Geospatial Uncertainty of Geometallurgical Variables with Bayesian Models and Hilbert-Kriging\nHoffimann et al. 2021. Geostatistical Learning: Challenges and Opportunities\nAsner et al. 2021. Abiotic and Human Drivers of Reef Habitat Complexity Throughout the Main Hawaiian Islands\nAsner et al. 2020. Large-scale mapping of live corals to guide reef conservation\nHoffimann, J. & Zadrozny, B. 2019. Efficient Variography with Partition Variograms\nHoffimann et al. 2019. Morphodynamic Analysis and Statistical Synthesis of Geomorphic Data: Application to a Flume Experiment\nBarfod et al. 2017. Hydrostratigraphic Modeling using Multiple-point Statistics and Airborne Transient Electromagnetic Methods\nHoffimann et al. 2017. Stochastic Simulation by Image Quilting of Process-based Geological Models","category":"page"},{"location":"transforms/#Geospatial-transforms","page":"Transforms","title":"Geospatial transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"We provide a very powerful list of transforms that were designed to work seamlessly with geospatial data. These transforms are implemented in different packages depending on how they interact with geometries.","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"The list of supported transforms is continuously growing. The following code can be used to print an updated list in any project environment:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# packages to print type tree\nusing InteractiveUtils\nusing AbstractTrees\nusing TransformsBase\n\n# packages with transforms\nusing GeoStats\n\n# define the tree of types\nAbstractTrees.children(T::Type) = subtypes(T)\n\n# print all currently available transforms\nAbstractTrees.print_tree(TransformsBase.Transform)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Transforms at the leaves of the tree above should have a docstring with more information on the available options. For example, the documentation of the Select transform is shown below:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Select","category":"page"},{"location":"transforms/#TableTransforms.Select","page":"Transforms","title":"TableTransforms.Select","text":"Select(col₁, col₂, ..., colₙ)\nSelect([col₁, col₂, ..., colₙ])\nSelect((col₁, col₂, ..., colₙ))\n\nThe transform that selects columns col₁, col₂, ..., colₙ.\n\nSelect(col₁ => newcol₁, col₂ => newcol₂, ..., colₙ => newcolₙ)\n\nSelects the columns col₁, col₂, ..., colₙ and rename them to newcol₁, newcol₂, ..., newcolₙ.\n\nSelect(regex)\n\nSelects the columns that match with regex.\n\nExamples\n\nSelect(1, 3, 5)\nSelect([:a, :c, :e])\nSelect((\"a\", \"c\", \"e\"))\nSelect(1 => :x, 3 => :y)\nSelect(:a => :x, :b => :y)\nSelect(\"a\" => \"x\", \"b\" => \"y\")\nSelect(r\"[ace]\")\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Transforms of type FeatureTransform operate on the attribute table, whereas transforms of type GeometricTransform operate on the underlying geospatial domain:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"TableTransforms.FeatureTransform\nMeshes.GeometricTransform","category":"page"},{"location":"transforms/#TableTransforms.FeatureTransform","page":"Transforms","title":"TableTransforms.FeatureTransform","text":"FeatureTransform\n\nA transform that operates on the columns of the table containing features, i.e., simple attributes such as numbers, strings, etc.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#Meshes.GeometricTransform","page":"Transforms","title":"Meshes.GeometricTransform","text":"GeometricTransform\n\nA method to transform the geometry (e.g. coordinates) of objects. See https://en.wikipedia.org/wiki/Geometric_transformation.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Other transforms such as Detrend are defined in terms of both the geospatial domain and the attribute table. All transforms and pipelines implement the following functions:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"TransformsBase.isrevertible\nTransformsBase.isinvertible\nTransformsBase.inverse\nTransformsBase.apply\nTransformsBase.revert\nTransformsBase.reapply","category":"page"},{"location":"transforms/#TransformsBase.isrevertible","page":"Transforms","title":"TransformsBase.isrevertible","text":"isrevertible(transform)\n\nTells whether or not the transform is revertible, i.e. supports a revert function. Defaults to false for new transform types.\n\nTransforms can be revertible and yet don't be invertible. Invertibility is a mathematical concept, whereas revertibility is a computational concept.\n\nSee also isinvertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.isinvertible","page":"Transforms","title":"TransformsBase.isinvertible","text":"isinvertible(transform)\n\nTells whether or not the transform is invertible, i.e. whether it implements the inverse function. Defaults to false for new transform types.\n\nTransforms can be invertible in the mathematical sense, i.e., there exists a one-to-one mapping between input and output spaces.\n\nSee also inverse, isrevertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.inverse","page":"Transforms","title":"TransformsBase.inverse","text":"inverse(transform)\n\nReturns the inverse transform of the transform.\n\nSee also isinvertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.apply","page":"Transforms","title":"TransformsBase.apply","text":"newobject, cache = apply(transform, object)\n\nApply transform on the object. Return the newobject and a cache to revert the transform later.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.revert","page":"Transforms","title":"TransformsBase.revert","text":"object = revert(transform, newobject, cache)\n\nRevert the transform on the newobject using the cache from the corresponding apply call and return the original object. Only defined when the transform isrevertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.reapply","page":"Transforms","title":"TransformsBase.reapply","text":"newobject = reapply(transform, object, cache)\n\nReapply the transform to (a possibly different) object using a cache that was created with a previous apply call. Fallback to apply without using the cache.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#Feature-transforms","page":"Transforms","title":"Feature transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Please check the TableTransforms.jl documentation for an updated list of feature transforms. As an example consider the following features over a Cartesian grid and their statistics:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"using DataFrames\n\n# table of features and domain\ntab = DataFrame(a=rand(1000), b=randn(1000), c=rand(1000))\ndom = CartesianGrid(100, 100)\n\n# georeference table onto domain\nΩ = georef(tab, dom)\n\n# describe features\ndescribe(values(Ω))","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"We can create a pipeline that transforms the features to their normal quantile (or scores):","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"pipe = Quantile()\n\nΩ̄, cache = apply(pipe, Ω)\n\ndescribe(values(Ω̄))","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"We can then revert the transform given any new geospatial data in the transformed sample space:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Ωₒ = revert(pipe, Ω̄, cache)\n\ndescribe(values(Ωₒ))","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"The Learn transform is another important transform from StatsLearnModels.jl:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Learn","category":"page"},{"location":"transforms/#StatsLearnModels.Learn","page":"Transforms","title":"StatsLearnModels.Learn","text":"Learn(train, model, incols => outcols)\n\nFits the statistical learning model using the input columns, selected by incols, and the output columns, selected by outcols, from the train table.\n\nThe column selection can be a single column identifier (index or name), a collection of identifiers or a regular expression (regex).\n\nExamples\n\nLearn(train, model, [1, 2, 3] => \"d\")\nLearn(train, model, [:a, :b, :c] => :d)\nLearn(train, model, [\"a\", \"b\", \"c\"] => 4)\nLearn(train, model, [1, 2, 3] => [:d, :e])\nLearn(train, model, r\"[abc]\" => [\"d\", \"e\"])\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"For more details, consider watching our JuliaCon2021 talk:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"

\n\n

","category":"page"},{"location":"transforms/#Geometric-transforms","page":"Transforms","title":"Geometric transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Please check the Meshes.jl documentation for an updated list of geometric transforms. As an example consider the rotation of geospatial data over a Cartesian grid:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# geospatial domain\nΩ = georef((Z=rand(10, 10),))\n\n# apply geometric transform\nΩr = Ω |> Rotate(Angle2d(π/4))\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.Z)\nviz(fig[1,2], Ωr.geometry, color = Ωr.Z)\nfig","category":"page"},{"location":"transforms/#Geostatistical-transforms","page":"Transforms","title":"Geostatistical transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Bellow is the current list of transforms that operate on both the geometries and features of geospatial data. They are implemented in the GeoStatsBase.jl package.","category":"page"},{"location":"transforms/#UniqueCoords","page":"Transforms","title":"UniqueCoords","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"UniqueCoords","category":"page"},{"location":"transforms/#GeoStatsTransforms.UniqueCoords","page":"Transforms","title":"GeoStatsTransforms.UniqueCoords","text":"UniqueCoords(var₁ => agg₁, var₂ => agg₂, ..., varₙ => aggₙ)\n\nRetain locations in data with unique coordinates.\n\nDuplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.\n\nExamples\n\nUniqueCoords(1 => last, 2 => maximum)\nUniqueCoords(:a => first, :b => minimum)\nUniqueCoords(\"a\" => last, \"b\" => maximum)\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# point set with repeated points\nX = rand(2, 50)\nΩ = georef((Z=rand(100),), [X X])","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# discard repeated points\n𝒰 = Ω |> UniqueCoords()","category":"page"},{"location":"transforms/#Detrend","page":"Transforms","title":"Detrend","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Detrend","category":"page"},{"location":"transforms/#GeoStatsTransforms.Detrend","page":"Transforms","title":"GeoStatsTransforms.Detrend","text":"Detrend(col₁, col₂, ..., colₙ; degree=1)\nDetrend([col₁, col₂, ..., colₙ]; degree=1)\nDetrend((col₁, col₂, ..., colₙ); degree=1)\n\nThe transform that detrends columns col₁, col₂, ..., colₙ with a polynomial of given degree.\n\nDetrend(regex; degree=1)\n\nDetrends the columns that match with regex.\n\nExamples\n\nDetrend(1, 3, 5)\nDetrend([:a, :c, :e])\nDetrend((\"a\", \"c\", \"e\"))\nDetrend(r\"[ace]\", degree=2)\nDetrend(:)\n\nReferences\n\nMenafoglio, A., Secchi, P. 2013. A Universal Kriging predictor for spatially dependent functional data of a Hilbert Space\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# quadratic trend + random noise\nr = range(-1, stop=1, length=100)\nμ = [x^2 + y^2 for x in r, y in r]\nϵ = 0.1rand(100, 100)\nΩ = georef((Z=μ+ϵ,))\n\n# detrend and obtain noise component\n𝒩 = Ω |> Detrend(:Z, degree=2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.Z)\nviz(fig[1,2], 𝒩.geometry, color = 𝒩.Z)\nfig","category":"page"},{"location":"transforms/#Potrace","page":"Transforms","title":"Potrace","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Potrace","category":"page"},{"location":"transforms/#GeoStatsTransforms.Potrace","page":"Transforms","title":"GeoStatsTransforms.Potrace","text":"Potrace(mask; [ϵ])\nPotrace(mask, var₁ => agg₁, ..., varₙ => aggₙ; [ϵ])\n\nTrace polygons on 2D image data with Selinger's Potrace algorithm.\n\nThe categories stored in column mask are converted into binary masks, which are then traced into multi-polygons. When provided, the option ϵ is forwarded to Selinger's simplification algorithm.\n\nDuplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.\n\nExamples\n\nPotrace(:mask, ϵ=0.1)\nPotrace(1, 1 => last, 2 => maximum)\nPotrace(:mask, :a => first, :b => minimum)\nPotrace(\"mask\", \"a\" => last, \"b\" => maximum)\n\nReferences\n\nSelinger, P. 2003. Potrace: A polygon-based tracing algorithm\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# continuous feature\nZ = [sin(i/10) + sin(j/10) for i in 1:100, j in 1:100]\n\n# binary mask\nM = Z .> 0\n\n# georeference data\nΩ = georef((Z=Z, M=M))\n\n# trace polygons using mask\n𝒯 = Ω |> Potrace(:M)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.Z)\nviz(fig[1,2], 𝒯.geometry, color = 𝒯.Z)\nfig","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒯.geometry","category":"page"},{"location":"transforms/#Rasterize","page":"Transforms","title":"Rasterize","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Rasterize","category":"page"},{"location":"transforms/#GeoStatsTransforms.Rasterize","page":"Transforms","title":"GeoStatsTransforms.Rasterize","text":"Rasterize(grid)\nRasterize(grid, var₁ => agg₁, ..., varₙ => aggₙ)\n\nRasterize geometries within specified grid.\n\nRasterize(nx, ny)\nRasterize(nx, ny, var₁ => agg₁, ..., varₙ => aggₙ)\n\nAlternatively, use the grid with size nx by ny obtained with discretization of the bounding box.\n\nDuplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.\n\nExamples\n\ngrid = CartesianGrid(10, 10)\nRasterize(grid)\nRasterize(10, 10)\nRasterize(grid, 1 => last, 2 => maximum)\nRasterize(10, 10, 1 => last, 2 => maximum)\nRasterize(grid, :a => first, :b => minimum)\nRasterize(10, 10, :a => first, :b => minimum)\nRasterize(grid, \"a\" => last, \"b\" => maximum)\nRasterize(10, 10, \"a\" => last, \"b\" => maximum)\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"A = [1, 2, 3, 4, 5]\nB = [1.1, 2.2, 3.3, 4.4, 5.5]\np1 = PolyArea((2, 0), (6, 2), (2, 2))\np2 = PolyArea((0, 6), (3, 8), (0, 10))\np3 = PolyArea((3, 6), (9, 6), (9, 9), (6, 9))\np4 = PolyArea((7, 0), (10, 0), (10, 4), (7, 4))\np5 = PolyArea((1, 3), (5, 3), (6, 6), (3, 8), (0, 6))\ngt = georef((; A, B), [p1, p2, p3, p4, p5])\n\nnt = gt |> Rasterize(20, 20)\n\nviz(nt.geometry, color = nt.A)","category":"page"},{"location":"transforms/#Clustering","page":"Transforms","title":"Clustering","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Unlike traditional clustering algorithms in machine learning, geostatistical clustering (a.k.a. domaining) algorithms consider both the features and the geospatial coordinates of the data.","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Consider the following data as an example:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Ω = georef((Z=[10sin(i/10) + j for i in 1:4:100, j in 1:4:100],))\n\nviz(Ω.geometry, color = Ω.Z)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"GHC","category":"page"},{"location":"transforms/#GeoStatsTransforms.GHC","page":"Transforms","title":"GeoStatsTransforms.GHC","text":"GHC(k, λ; kern=:epanechnikov, link=:ward, as=:CLUSTER)\n\nA transform for partitioning geospatial data into k clusters according to a range λ using Geostatistical Hierarchical Clustering (GHC). The larger the range the more connected are nearby samples.\n\nParameters\n\nk - Approximate number of clusters\nλ - Approximate range of kernel function in length units\nkern - Kernel function (:uniform, :triangular or :epanechnikov)\nlink - Linkage function (:single, :average, :complete, :ward or :ward_presquared)\nas - Cluster column name\n\nReferences\n\nFouedjio, F. 2016. A hierarchical clustering method for multivariate geostatistical data\n\nNotes\n\nThe range parameter controls the sparsity pattern of the pairwise distances, which can greatly affect the computational performance of the GHC algorithm. We recommend choosing a range that is small enough to connect nearby samples. For example, clustering data over a 100x100 Cartesian grid with unit spacing is possible with λ=1.0 or λ=2.0 but the problem starts to become computationally unfeasible around λ=10.0 due to the density of points.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒞 = Ω |> GHC(20, 1.0)\n\nviz(𝒞.geometry, color = 𝒞.CLUSTER)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"GSC","category":"page"},{"location":"transforms/#GeoStatsTransforms.GSC","page":"Transforms","title":"GeoStatsTransforms.GSC","text":"GSC(k, m; σ=1.0, tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)\n\nA transform for partitioning geospatial data into k clusters using Geostatistical Spectral Clustering (GSC).\n\nParameters\n\nk - Desired number of clusters\nm - Multiplicative factor for adjacent weights\nσ - Standard deviation for exponential model (default to 1.0)\ntol - Tolerance of k-means algorithm (default to 1e-4)\nmaxiter - Maximum number of iterations (default to 10)\nweights - Dictionary with weights for each attribute (default to nothing)\nas - Cluster column name\n\nReferences\n\nRomary et al. 2015. Unsupervised classification of multivariate geostatistical data: Two algorithms\n\nNotes\n\nThe algorithm implemented here is slightly different than the algorithm\n\ndescribed in Romary et al. 2015. Instead of setting Wᵢⱼ = 0 when i <-/-> j, we simply magnify the weight by a multiplicative factor Wᵢⱼ *= m when i <–> j. This leads to dense matrices but also better results in practice.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒞 = Ω |> GSC(50, 2.0)\n\nviz(𝒞.geometry, color = 𝒞.CLUSTER)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"SLIC","category":"page"},{"location":"transforms/#GeoStatsTransforms.SLIC","page":"Transforms","title":"GeoStatsTransforms.SLIC","text":"SLIC(k, m; tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)\n\nA transform for clustering geospatial data into approximately k clusters using Simple Linear Iterative Clustering (SLIC). The transform produces clusters of samples that are spatially connected based on a distance dₛ and that, at the same time, are similar in terms of vars with distance dᵥ. The tradeoff is controlled with a hyperparameter parameter m in an additive model dₜ = √(dᵥ² + m²(dₛ/s)²).\n\nParameters\n\nk - Approximate number of clusters\nm - Hyperparameter of SLIC model\ntol - Tolerance of k-means algorithm (default to 1e-4)\nmaxiter - Maximum number of iterations (default to 10)\nweights - Dictionary with weights for each attribute (default to nothing)\nas - Cluster column name\n\nReferences\n\nAchanta et al. 2011. SLIC superpixels compared to state-of-the-art superpixel methods\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒞 = Ω |> SLIC(50, 0.01)\n\nviz(𝒞.geometry, color = 𝒞.CLUSTER)","category":"page"},{"location":"transforms/#Interpolate","page":"Transforms","title":"Interpolate","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Interpolate\nInterpolateNeighbors\nInterpolateMissing\nInterpolateNaN","category":"page"},{"location":"transforms/#GeoStatsTransforms.Interpolate","page":"Transforms","title":"GeoStatsTransforms.Interpolate","text":"Interpolate(domain, vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolate([g₁, g₂, ..., gₙ], vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on given domain or vector of geometries [g₁, g₂, ..., gₙ], using geostatistical models model₁, ..., modelₙ for variables vars₁, ..., varsₙ.\n\nInterpolate(domain, model=NN(); [parameters])\nInterpolate([g₁, g₂, ..., gₙ], model=NN(); [parameters])\n\nInterpolate geospatial data on given domain or vector of geometries [g₁, g₂, ..., gₙ], using geostatistical model for all variables.\n\nParameters\n\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nSee also InterpolateNeighbors, InterpolateMissing, InterpolateNaN.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#GeoStatsTransforms.InterpolateNeighbors","page":"Transforms","title":"GeoStatsTransforms.InterpolateNeighbors","text":"InterpolateNeighbors(domain, vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolateNeighbors([g₁, g₂, ..., gₙ], vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on given domain or set of geometries g₁, g₂, ..., gₙ, using geostatistical models model₁, ..., modelₙ for variables vars₁, ..., varsₙ.\n\nInterpolateNeighbors(domain, model=NN(); [parameters])\nInterpolateNeighbors([g₁, g₂, ..., gₙ], model=NN(); [parameters])\n\nInterpolate geospatial data on given domain or set of geometries g₁, g₂, ..., gₙ, using geostatistical model for all variables.\n\nUnlike Interpolate, this transform uses neighbor search methods to fit geostatistical models at each interpolation location with a reduced number of measurements.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - A distance defined in Distances.jl (default to Euclidean())\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nThe maxneighbors parameter can be used to perform interpolation with a subset of measurements per prediction location. If maxneighbors is not provided, then all measurements are used.\n\nTwo neighborhood search methods are available:\n\nIf a neighborhood is provided, local prediction is performed by sliding the neighborhood in the domain.\nIf a neighborhood is not provided, the prediction is performed using maxneighbors nearest neighbors according to distance.\n\nSee also Interpolate, InterpolateMissing, InterpolateNaN.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#GeoStatsTransforms.InterpolateMissing","page":"Transforms","title":"GeoStatsTransforms.InterpolateMissing","text":"InterpolateMissing(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolateMissing(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical models model₁, ..., modelₙ and non-missing values of the variables vars₁, ..., varsₙ.\n\nInterpolateMissing(model=NN(); [parameters])\nInterpolateMissing(model=NN(); [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical model and non-missing values of all variables.\n\nJust like InterpolateNeighbors, this transform uses neighbor search methods to fit geostatistical models at each interpolation location with a reduced number of measurements.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - A distance defined in Distances.jl (default to Euclidean())\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nThe maxneighbors parameter can be used to perform interpolation with a subset of measurements per prediction location. If maxneighbors is not provided, then all measurements are used.\n\nTwo neighborhood search methods are available:\n\nIf a neighborhood is provided, local prediction is performed by sliding the neighborhood in the domain.\nIf a neighborhood is not provided, the prediction is performed using maxneighbors nearest neighbors according to distance.\n\nSee also InterpolateNaN, InterpolateNeighbors, Interpolate.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#GeoStatsTransforms.InterpolateNaN","page":"Transforms","title":"GeoStatsTransforms.InterpolateNaN","text":"InterpolateNaN(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolateNaN(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical models model₁, ..., modelₙ and non-NaN values of the variables vars₁, ..., varsₙ.\n\nInterpolateNaN(model=NN(); [parameters])\nInterpolateNaN(model=NN(); [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical model and non-NaN values of all variables.\n\nJust like InterpolateNeighbors, this transform uses neighbor search methods to fit geostatistical models at each interpolation location with a reduced number of measurements.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - A distance defined in Distances.jl (default to Euclidean())\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nThe maxneighbors parameter can be used to perform interpolation with a subset of measurements per prediction location. If maxneighbors is not provided, then all measurements are used.\n\nTwo neighborhood search methods are available:\n\nIf a neighborhood is provided, local prediction is performed by sliding the neighborhood in the domain.\nIf a neighborhood is not provided, the prediction is performed using maxneighbors nearest neighbors according to distance.\n\nSee also InterpolateMissing, InterpolateNeighbors, Interpolate.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"table = (; Z=[1.,0.,1.])\ncoord = [(25.,25.), (50.,75.), (75.,50.)]\ngeotable = georef(table, coord)\n\ngrid = CartesianGrid(100, 100)\n\nmodel = Kriging(GaussianVariogram(range=35.))\n\ninterp = geotable |> Interpolate(grid, model)\n\nviz(interp.geometry, color = interp.Z)","category":"page"},{"location":"transforms/#Simulate","page":"Transforms","title":"Simulate","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Simulate","category":"page"},{"location":"transforms/#GeoStatsTransforms.Simulate","page":"Transforms","title":"GeoStatsTransforms.Simulate","text":"Simulate(domain, vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\nSimulate(domain, nreals, vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\nSimulate([g₁, g₂, ..., gₙ], vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\nSimulate([g₁, g₂, ..., gₙ], nreals, vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\n\nSimulate nreals realizations of variables varsᵢ with geostatistical process processᵢ over given domain or vector of geometries [g₁, g₂, ..., gₙ].\n\nThe parameters are forwarded to the rand method of the geostatistical processes.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#CookieCutter","page":"Transforms","title":"CookieCutter","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"CookieCutter","category":"page"},{"location":"transforms/#GeoStatsTransforms.CookieCutter","page":"Transforms","title":"GeoStatsTransforms.CookieCutter","text":"CookieCutter(domain, parent => process, var₁ => procmap₁, ..., varₙ => procmapₙ; [parameters])\nCookieCutter(domain, nreals, parent => process, var₁ => procmap₁, ..., varₙ => procmapₙ; [parameters])\n\nSimulate nreals realizations of variable parent with geostatistical process process, and each child variable varsᵢ with process map procmapᵢ, over given domain.\n\nThe process map must be an iterable of pairs of the form: value => process. Each process in the map is related to a value of the parent realization, therefore the values of the child variables will be chosen according to the values of the corresponding parent realization.\n\nThe parameters are forwarded to the rand method of the geostatistical processes.\n\nExamples\n\nparent = QuiltingProcess(trainimg, (30, 30))\nchild0 = GaussianProcess(SphericalVariogram(range=20.0, sill=0.2))\nchild1 = GaussianProcess(SphericalVariogram(MetricBall((200.0, 20.0))))\ntransform = CookieCutter(domain, :parent => parent, :child => [0 => child0, 1 => child1])\n\n\n\n\n\n","category":"type"},{"location":"declustering/#Declustering","page":"Declustering","title":"Declustering","text":"","category":"section"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"Declustered statistics are statistics that make use of geospatial coordinates in an attempt to correct potential sampling bias:","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"

\n\n

","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"The following statistics have geospatial semantics:","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"mean(::AbstractGeoTable, ::Any)\nvar(::AbstractGeoTable, ::Any)\nquantile(::AbstractGeoTable, ::Any, ::Any)","category":"page"},{"location":"declustering/#Statistics.mean-Tuple{AbstractGeoTable, Any}","page":"Declustering","title":"Statistics.mean","text":"mean(data, v)\nmean(data, v, s)\n\nDeclustered mean of geospatial data. Optionally, specify the variable v and the block side s.\n\n\n\n\n\n","category":"method"},{"location":"declustering/#Statistics.var-Tuple{AbstractGeoTable, Any}","page":"Declustering","title":"Statistics.var","text":"var(data, v)\nvar(data, v, s)\n\nDeclustered variance of geospatial data. Optionally, specify the variable v and the block side s.\n\n\n\n\n\n","category":"method"},{"location":"declustering/#Statistics.quantile-Tuple{AbstractGeoTable, Any, Any}","page":"Declustering","title":"Statistics.quantile","text":"quantile(data, v, p)\nquantile(data, v, p, s)\n\nDeclustered quantile of geospatial data at probability p. Optionally, specify the variable v and the block side s.\n\n\n\n\n\n","category":"method"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"A histogram with geospatial semantics is also available where the heights of the bins are adjusted based on the coordinates of the samples:","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"EmpiricalHistogram","category":"page"},{"location":"declustering/#GeoStatsBase.EmpiricalHistogram","page":"Declustering","title":"GeoStatsBase.EmpiricalHistogram","text":"EmpiricalHistogram(sdata, var, [s]; kwargs...)\n\nSpatial histogram of variable var in spatial data sdata. Optionally, specify the block side s and the keyword arguments kwargs for the fit(Histogram, ...) call.\n\n\n\n\n\n","category":"type"},{"location":"variography/fitting/#Fitting-variograms","page":"Fitting variograms","title":"Fitting variograms","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"variography/fitting/#Overview","page":"Fitting variograms","title":"Overview","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"Fitting theoretical variograms to empirical observations is an important modeling step to ensure valid mathematical models of geospatial continuity. Given an empirical variogram, the fit function can be used to perform the fit:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"GeoStatsFunctions.fit(::Type{Variogram}, ::EmpiricalVariogram, ::VariogramFitAlgo)","category":"page"},{"location":"variography/fitting/#GeoStatsFunctions.fit-Tuple{Type{Variogram}, EmpiricalVariogram, VariogramFitAlgo}","page":"Fitting variograms","title":"GeoStatsFunctions.fit","text":"fit(V, g, algo=WeightedLeastSquares(); range=nothing, sill=nothing, nugget=nothing)\n\nFit theoretical variogram type V to empirical variogram g using algorithm algo.\n\nOptionally fix range, sill or nugget by passing them as keyword arguments, or set their maximum value with maxrange, maxsill or maxnugget.\n\nExamples\n\njulia> fit(SphericalVariogram, g)\njulia> fit(ExponentialVariogram, g)\njulia> fit(ExponentialVariogram, g, sill=1.0)\njulia> fit(ExponentialVariogram, g, maxsill=1.0)\njulia> fit(GaussianVariogram, g, WeightedLeastSquares())\n\n\n\n\n\nfit(Vs, g, algo=WeightedLeastSquares(); kwargs...)\n\nFit theoretical variogram types Vs to empirical variogram g using algorithm algo and return the one with minimum error.\n\nExamples\n\njulia> fit([SphericalVariogram, ExponentialVariogram], g)\n\n\n\n\n\nfit(Variogram, g, algo=WeightedLeastSquares(); kwargs...)\n\nFit all \"fittable\" subtypes of Variogram to empirical variogram g using algorithm algo and return the one with minimum error.\n\nExamples\n\njulia> fit(Variogram, g)\njulia> fit(Variogram, g, WeightedLeastSquares())\n\nSee also GeoStatsFunctions.fittable().\n\n\n\n\n\n","category":"method"},{"location":"variography/fitting/#Example","page":"Fitting variograms","title":"Example","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"# sinusoidal data\n𝒟 = georef((Z=[sin(i/2) + sin(j/2) for i in 1:50, j in 1:50],))\n\n# empirical variogram\ng = EmpiricalVariogram(𝒟, :Z, maxlag = 25.)\n\nMke.plot(g)","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"We can fit specific models to the empirical variogram:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"γ = GeoStatsFunctions.fit(SineHoleVariogram, g)\n\nMke.plot(g)\nMke.plot!(γ, maxlag = 25.)\nMke.current_figure()","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"or let the framework find the model with minimum error:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"γ = GeoStatsFunctions.fit(Variogram, g)\n\nMke.plot(g)\nMke.plot!(γ, maxlag = 25.)\nMke.current_figure()","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"which should be a SineHoleVariogram given that the synthetic data of this example is sinusoidal.","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"Optionally, we can specify a weighting function to give different weights to the lags:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"γ = GeoStatsFunctions.fit(SineHoleVariogram, g, h -> 1 / h^2)\n\nMke.plot(g)\nMke.plot!(γ, maxlag = 25.)\nMke.current_figure()","category":"page"},{"location":"variography/fitting/#Methods","page":"Fitting variograms","title":"Methods","text":"","category":"section"},{"location":"variography/fitting/#Weighted-least-squares","page":"Fitting variograms","title":"Weighted least squares","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"WeightedLeastSquares","category":"page"},{"location":"variography/fitting/#GeoStatsFunctions.WeightedLeastSquares","page":"Fitting variograms","title":"GeoStatsFunctions.WeightedLeastSquares","text":"WeightedLeastSquares()\nWeightedLeastSquares(w)\n\nFit theoretical variogram using weighted least squares with weighting function w (e.g. h -> 1/h). If no weighting function is provided, bin counts of empirical variogram are normalized and used as weights.\n\n\n\n\n\n","category":"type"},{"location":"quickstart/#Quickstart","page":"Quickstart","title":"Quickstart","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"A geostatistical workflow often consists of four steps:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Definition of geospatial data\nManipulation of geospatial data\nGeostatistical modeling\nScientific visualization","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"In this section, we walk through these steps to illustrate some of the features of the project. In the case of geostatistical modeling, we will specifically explore geostatistical learning models. If you prefer learning from video, check out the recording of our JuliaEO 2023 workshop:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"

\n\n

","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We assume that the following packages are loaded throughout the code examples:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"using GeoStats\nimport CairoMakie as Mke","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The GeoStats.jl package exports the full stack for geospatial data science and geostatistical modeling. The CairoMakie.jl package is one of the possible visualization backends from the Makie.jl project.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"If you are new to Julia and have never heard of Makie.jl before, here are a few tips to help you choose between the different backends:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"WGLMakie.jl is the preferred backend for interactive visualization on the web browser. It integrates well with Pluto.jl notebooks and other web-based applications.\nGLMakie.jl is the preferred backend for interactive high-performance visualization. It leverages native graphical resources and doesn't require a web browser to function.\nCairoMakie.jl is the preferred backend for publication-quality static visualization. It requires less computing power and is therefore recommended for those users with modest laptops.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"note: Note\nWe recommend importing the Makie.jl backend as Mke to avoid polluting the Julia session with names from the visualization stack.","category":"page"},{"location":"quickstart/#Loading/creating-data","page":"Quickstart","title":"Loading/creating data","text":"","category":"section"},{"location":"quickstart/#Loading-data","page":"Quickstart","title":"Loading data","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The Julia ecosystem for loading geospatial data is comprised of several low-level packages such as Shapefile.jl and GeoJSON.jl, which define their own very basic geometry types. Instead of requesting users to learn the so called GeoInterface.jl to handle these types, we provide the high-level GeoIO.jl package to load any file with geospatial data into well-tested geometries from the Meshes.jl submodule:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"using GeoIO\n\nzone = GeoIO.load(\"data/zone.shp\")\npath = GeoIO.load(\"data/path.shp\")\n\nviz(zone.geometry)\nviz!(path.geometry, color = :gray90)\nMke.current_figure()","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Various functions are defined over these geometries, for instance:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"sum(area, zone.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"sum(perimeter, zone.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Please check the Meshes.jl documentation for more details.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"note: Note\nWe highly recommend using Meshes.jl geometries in geospatial workflows as they were carefully designed to accomodate advanced features of the GeoStats.jl framework. Any other geometry type will likely fail with our geostatistical algorithms and pipelines.","category":"page"},{"location":"quickstart/#Creating-data","page":"Quickstart","title":"Creating data","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Geospatial data can be derived from other Julia variables. For example, given a Julia array, which is not attached to any coordinate system, we can georeference the array using the georef function:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Z = [10sin(i/10) + 2j for i in 1:50, j in 1:50]\n\nΩ = georef((Z=Z,))","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Default coordinates are assigned based on the size of the array, and different configurations can be obtained with different methods (see Data).","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Geospatial data can be visualized with the viz recipe function:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"viz(Ω.geometry, color = Ω.Z)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Alternatively, we provide a basic scientific viewer to visualize all viewable variables in the data with a colorbar and other interactive elements (see Visualization):","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"viewer(Ω)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"note: Note\nJulia supports unicode symbols with LaTeX syntax. We can type \\Omega and press TAB to get the symbol Ω in the example above. This autocompletion works in various text editors, including the VSCode editor with the Julia extension.","category":"page"},{"location":"quickstart/#Manipulating-data","page":"Quickstart","title":"Manipulating data","text":"","category":"section"},{"location":"quickstart/#Table-interface","page":"Quickstart","title":"Table interface","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Our geospatial data implements the Tables.jl interface, which means that they can be accessed as if they were tables with samples in the rows and variables in the columns. In this case, a special column named geometry is created on the fly, row by row, containing Meshes.jl geometries.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"For those familiar with the productive DataFrames.jl interface, there is nothing new:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω[1,:]","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω[1,:geometry]","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω.Z","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"However, notice that our implementation performs some clever optimizations behind the scenes to avoid expensive creation of geometries:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω.geometry","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We can always retrieve the table of attributes (or features) with the function values and the underlying geospatial domain with the function domain. This can be useful for writing algorithms that are type-stable and depend purely on the feature values:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"values(Ω)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"or on the geometries:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"domain(Ω)","category":"page"},{"location":"quickstart/#Geospatial-transforms","page":"Quickstart","title":"Geospatial transforms","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"It is easy to design advanced geospatial pipelines that operate on both the table of features and the underlying geospatial domain:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"# pipeline with table transforms\npipe = Quantile() → StdCoords()\n\n# feed geospatial data to pipeline\nΩ̂ = pipe(Ω)\n\n# plot distribution before and after pipeline\nfig = Mke.Figure(size = (800, 400))\nMke.hist(fig[1,1], Ω.Z, color = :gray)\nMke.hist(fig[2,1], Ω̂.Z, color = :gray)\nfig","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Coordinates before pipeline:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"boundingbox(Ω.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"and after pipeline:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"boundingbox(Ω̂.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"These pipelines are revertible meaning that we can transform the data, perform geostatistical modeling, and revert the pipelines to obtain estimates in the original sample space (see Transforms).","category":"page"},{"location":"quickstart/#Geospatial-queries","page":"Quickstart","title":"Geospatial queries","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We provide three macros @groupby, @transform and @combine for powerful geospatial split-apply-combine patterns, as well as the function geojoin for advanced geospatial joins.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"@transform(Ω, :W = 2 * :Z * area(:geometry))","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"These are very useful for geospatial data science as they hide the complexity of the geometry column. For more information, check the Queries section of the documentation.","category":"page"},{"location":"quickstart/#Geostatistical-modeling","page":"Quickstart","title":"Geostatistical modeling","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Having defined the geospatial data objects, we proceed and define the geostatistical learning model. Let's assume that we have geopatial data with some variable that we want to predict in a supervised learning setting. We load the data from a CSV file, and inspect the available columns:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"using CSV\nusing DataFrames\n\ntable = CSV.File(\"data/agriculture.csv\") |> DataFrame\n\nfirst(table, 5)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Columns band1, band2, ..., band4 represent four satellite bands for different locations (x, y) in this region. The column crop has the crop type for each location that was labeled manually with the purpose of fitting a learning model.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We can now georeference the table and plot some of the variables:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω = georef(table, (:x, :y))\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.band4)\nviz(fig[1,2], Ω.geometry, color = Ω.crop)\nfig","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Similar to a generic statistical learning workflow, we split the data into \"train\" and \"test\" sets. The main difference here is that our geospatial geosplit function accepts a separating plane specified by its normal direction (1,-1):","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ωs, Ωt = geosplit(Ω, 0.2, (1.0, -1.0))\n\nviz(Ωs.geometry)\nviz!(Ωt.geometry, color = :gray90)\nMke.current_figure()","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We can visualize the domain of the \"train\" (or source) set Ωs in blue, and the domain of the \"test\" (or target) set Ωt in gray. We reserved 20% of the samples to Ωs and 80% to Ωt. Internally, this geospatial geosplit function is implemented in terms of efficient geospatial partitions.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Let's define our geostatistical learning model to predict the crop type based on the four satellite bands. We will use the DecisionTreeClassifier model, which is suitable for the task we want to perform. Any model from the StatsLeanModels.jl model is supported, including all models from ScikitLearn.jl:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"feats = [:band1, :band2, :band3, :band4]\nlabel = :crop\n\nmodel = DecisionTreeClassifier()","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We will fit the model in Ωs where the features and labels are available and predict in Ωt where the features are available. The Learn transform automatically fits the model to the data:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"learn = Learn(Ωs, model, feats => label)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The transform can be called with new data to generate predictions:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω̂t = learn(Ωt)","category":"page"},{"location":"quickstart/#Scientific-visualization","page":"Quickstart","title":"Scientific visualization","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We note that the prediction of a geostatistical learning model is a geospatial data object, and we can inspect it with the same methods already described above. This also means that we can visualize the prediction directly, side by side with the true label in this synthetic example:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"fig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω̂t.geometry, color = Ω̂t.crop)\nviz(fig[1,2], Ωt.geometry, color = Ωt.crop)\nfig","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"With this example we conclude the basic workflow. To get familiar with other features of the project, please check the the reference guide.","category":"page"},{"location":"resources/ecosystem/#Ecosystem","page":"Ecosystem","title":"Ecosystem","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"The Julia ecosystem for geospatial modeling is maturing very quickly as the result of multiple initiatives such as JuliaEarth, JuliaClimate, and JuliaGeo. Each of these initiatives is associated with a different set of challenges that ultimatively determine the types of packages that are being developed in the corresponding GitHub organizations. In this section, we try to clarify what is available to first-time users of the language.","category":"page"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"\n\n","category":"page"},{"location":"resources/ecosystem/#JuliaEarth","page":"Ecosystem","title":"JuliaEarth","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"Originally created to host the GeoStats.jl framework, this initiative is primarily concerned with geospatial data science and geostatistical modeling. Due to the various applications in the subsurface of the Earth, most of our Julia packages were developed to work efficiently with both 2D and 3D geometries.","category":"page"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"Unlike other initiatives, JuliaEarth is 100% Julia by design. This means that we do not rely on external libraries such as GDAL or Proj4 for geospatial work.","category":"page"},{"location":"resources/ecosystem/#JuliaClimate","page":"Ecosystem","title":"JuliaClimate","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"The most recent of the three initiatives, JuliaClimate has been created to address specific challenges in climate modeling. One of these challenges is access to climate data in Julia. Packages such as INMET.jl and CDSAPI.jl serve this purpose and are quite nice to work with.","category":"page"},{"location":"resources/ecosystem/#JuliaGeo","page":"Ecosystem","title":"JuliaGeo","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"Focused on bringing well-established external libraries to Julia, JuliaGeo provides packages that are widely used by geospatial communities from other programming languages. GDAL.jl, Proj4.jl and LibGEOS.jl are good examples of such packages.","category":"page"},{"location":"validation/#Validation","page":"Validation","title":"Validation","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"GeoStats.jl was designed to, among other things, facilitate rigorous comparison of different geostatistical models in the literature. As a user of geostatistics, you may be interested in trying various models on a given data set to pick the one with best performance. As a researcher in the field, you may be interested in benchmarking your new model against other established models.","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"Errors of geostatistical solvers can be estimated with the cverror function:","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"cverror","category":"page"},{"location":"validation/#GeoStatsValidation.cverror","page":"Validation","title":"GeoStatsValidation.cverror","text":"cverror(model::GeoStatsModel, geotable, method; kwargs...)\n\nEstimate error of model in a given geotable with error estimation method using Interpolate or InterpolateNeighbors depending on the passed kwargs.\n\ncverror(model::StatsLearnModel, geotable, method)\ncverror((model, invars => outvars), geotable, method)\n\nEstimate error of model in a given geotable with error estimation method using the Learn transform.\n\n\n\n\n\n","category":"function"},{"location":"validation/","page":"Validation","title":"Validation","text":"For example, we can perform block cross-validation on a decision tree model using the following code:","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"using GeoStats\nusing GeoIO\n\n# load geospatial data\nΩ = GeoIO.load(\"data/agriculture.csv\", coords = (\"x\", \"y\"))\n\n# 20%/80% split along the (1, -1) direction\nΩₛ, Ωₜ = geosplit(Ω, 0.2, (1.0, -1.0))\n\n# features and label for supervised learning\nfeats = [:band1,:band2,:band3,:band4]\nlabel = :crop\n\n# learning model\nmodel = DecisionTreeClassifier()\n\n# loss function\nloss = MisclassLoss()\n\n# block cross-validation with r = 30.\nbcv = BlockValidation(30., loss = Dict(:crop => loss))\n\n# estimate of generalization error\nϵ̂ = cverror((model, feats => label), Ωₛ, bcv)","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"We can unhide the labels in the target domain and compute the actual error for comparison:","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"# train in Ωₛ and predict in Ωₜ\nΩ̂ₜ = Ωₜ |> Learn(Ωₛ, model, feats => label)\n\t\n# actual error of the model\nϵ = mean(loss.(Ωₜ.crop, Ω̂ₜ.crop))","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"Below is the list of currently implemented validation methods.","category":"page"},{"location":"validation/#Leave-one-out","page":"Validation","title":"Leave-one-out","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"LeaveOneOut","category":"page"},{"location":"validation/#GeoStatsValidation.LeaveOneOut","page":"Validation","title":"GeoStatsValidation.LeaveOneOut","text":"LeaveOneOut(; loss=Dict())\n\nLeave-one-out validation. Optionally, specify loss function from LossFunctions.jl for some of the variables.\n\nReferences\n\nStone. 1974. Cross-Validatory Choice and Assessment of Statistical Predictions\n\n\n\n\n\n","category":"type"},{"location":"validation/#Leave-ball-out","page":"Validation","title":"Leave-ball-out","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"LeaveBallOut","category":"page"},{"location":"validation/#GeoStatsValidation.LeaveBallOut","page":"Validation","title":"GeoStatsValidation.LeaveBallOut","text":"LeaveBallOut(ball; loss=Dict())\n\nLeave-ball-out (a.k.a. spatial leave-one-out) validation. Optionally, specify loss function from the LossFunctions.jl package for some of the variables.\n\nLeaveBallOut(radius; loss=Dict())\n\nBy default, use Euclidean ball of given radius in space.\n\nReferences\n\nLe Rest et al. 2014. Spatial leave-one-out cross-validation for variable selection in the presence of spatial autocorrelation\n\n\n\n\n\n","category":"type"},{"location":"validation/#K-fold","page":"Validation","title":"K-fold","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"KFoldValidation","category":"page"},{"location":"validation/#GeoStatsValidation.KFoldValidation","page":"Validation","title":"GeoStatsValidation.KFoldValidation","text":"KFoldValidation(k; shuffle=true, loss=Dict())\n\nk-fold cross-validation. Optionally, shuffle the data, and specify loss function from LossFunctions.jl for some of the variables.\n\nReferences\n\nGeisser, S. 1975. The predictive sample reuse method with applications\nBurman, P. 1989. A comparative study of ordinary cross-validation, v-fold cross-validation and the repeated learning-testing methods\n\n\n\n\n\n","category":"type"},{"location":"validation/#Block","page":"Validation","title":"Block","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"BlockValidation","category":"page"},{"location":"validation/#GeoStatsValidation.BlockValidation","page":"Validation","title":"GeoStatsValidation.BlockValidation","text":"BlockValidation(sides; loss=Dict())\n\nCross-validation with blocks of given sides. Optionally, specify loss function from LossFunctions.jl for some of the variables. If only one side is provided, then blocks become cubes.\n\nReferences\n\nRoberts et al. 2017. Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure\nPohjankukka et al. 2017. Estimating the prediction performance of spatial models via spatial k-fold cross-validation\n\n\n\n\n\n","category":"type"},{"location":"validation/#Weighted","page":"Validation","title":"Weighted","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"WeightedValidation","category":"page"},{"location":"validation/#GeoStatsValidation.WeightedValidation","page":"Validation","title":"GeoStatsValidation.WeightedValidation","text":"WeightedValidation(weighting, folding; lambda=1.0, loss=Dict())\n\nAn error estimation method which samples are weighted with weighting method and split into folds with folding method. Weights are raised to lambda power in [0,1]. Optionally, specify loss function from LossFunctions.jl for some of the variables.\n\nReferences\n\nSugiyama et al. 2006. Importance-weighted cross-validation for covariate shift\nSugiyama et al. 2007. Covariate shift adaptation by importance weighted cross validation\n\n\n\n\n\n","category":"type"},{"location":"validation/#Density-ratio","page":"Validation","title":"Density-ratio","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"DensityRatioValidation","category":"page"},{"location":"validation/#GeoStatsValidation.DensityRatioValidation","page":"Validation","title":"GeoStatsValidation.DensityRatioValidation","text":"DensityRatioValidation(k; [parameters])\n\nDensity ratio validation where weights are first obtained with density ratio estimation, and then used in k-fold weighted cross-validation.\n\nParameters\n\nshuffle - Shuffle the data before folding (default to true)\nestimator - Density ratio estimator (default to LSIF())\noptlib - Optimization library (default to default_optlib(estimator))\nlambda - Power of density ratios (default to 1.0)\n\nPlease see DensityRatioEstimation.jl for a list of supported estimators.\n\nReferences\n\nHoffimann et al. 2020. Geostatistical Learning: Challenges and Opportunities\n\n\n\n\n\n","category":"type"},{"location":"queries/#Geospatial-queries","page":"Queries","title":"Geospatial queries","text":"","category":"section"},{"location":"queries/#Split-apply-combine","page":"Queries","title":"Split-apply-combine","text":"","category":"section"},{"location":"queries/","page":"Queries","title":"Queries","text":"We provide a geospatial version of the split-apply-combine pattern:","category":"page"},{"location":"queries/","page":"Queries","title":"Queries","text":"

\n\n

","category":"page"},{"location":"queries/","page":"Queries","title":"Queries","text":"@groupby\n@transform\n@combine","category":"page"},{"location":"queries/#GeoTables.@groupby","page":"Queries","title":"GeoTables.@groupby","text":"@groupby(geotable, col₁, col₂, ..., colₙ)\n@groupby(geotable, [col₁, col₂, ..., colₙ])\n@groupby(geotable, (col₁, col₂, ..., colₙ))\n\nGroup geospatial geotable by columns col₁, col₂, ..., colₙ.\n\n@groupby(geotable, regex)\n\nGroup geospatial geotable by columns that match with regex.\n\nExamples\n\n@groupby(geotable, 1, 3, 5)\n@groupby(geotable, [:a, :c, :e])\n@groupby(geotable, (\"a\", \"c\", \"e\"))\n@groupby(geotable, r\"[ace]\")\n\n\n\n\n\n","category":"macro"},{"location":"queries/#GeoTables.@transform","page":"Queries","title":"GeoTables.@transform","text":"@transform(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)\n\nReturns geospatial geotable with columns col₁, col₂, ..., colₙ computed with expressions expr₁, expr₂, ..., exprₙ.\n\nSee also: @groupby.\n\nExamples\n\n@transform(geotable, :z = :x + 2*:y)\n@transform(geotable, :w = :x^2 - :y^2)\n@transform(geotable, :sinx = sin(:x), :cosy = cos(:y))\n\ngroups = @groupby(geotable, :y)\n@transform(groups, :logx = log(:x))\n@transform(groups, :expz = exp(:z))\n\n@transform(geotable, {\"z\"} = {\"x\"} - 2*{\"y\"})\nxnm, ynm, znm = :x, :y, :z\n@transform(geotable, {znm} = {xnm} - 2*{ynm})\n\n\n\n\n\n","category":"macro"},{"location":"queries/#GeoTables.@combine","page":"Queries","title":"GeoTables.@combine","text":"@combine(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)\n\nReturns geospatial geotable with columns :col₁, :col₂, ..., :colₙ computed with reduction expressions expr₁, expr₂, ..., exprₙ.\n\nIf a reduction expression is not defined for the :geometry column, the geometries will be reduced using Multi.\n\nSee also: @groupby.\n\nExamples\n\n@combine(geotable, :x_sum = sum(:x))\n@combine(geotable, :x_mean = mean(:x))\n@combine(geotable, :x_mean = mean(:x), :geometry = centroid(:geometry))\n\ngroups = @groupby(geotable, :y)\n@combine(groups, :x_prod = prod(:x))\n@combine(groups, :x_median = median(:x))\n@combine(groups, :x_median = median(:x), :geometry = centroid(:geometry))\n\n@combine(geotable, {\"z\"} = sum({\"x\"}) + prod({\"y\"}))\nxnm, ynm, znm = :x, :y, :z\n@combine(geotable, {znm} = sum({xnm}) + prod({ynm}))\n\n\n\n\n\n","category":"macro"},{"location":"queries/#Geospatial-join","page":"Queries","title":"Geospatial join","text":"","category":"section"},{"location":"queries/","page":"Queries","title":"Queries","text":"geojoin\ntablejoin","category":"page"},{"location":"queries/#GeoTables.geojoin","page":"Queries","title":"GeoTables.geojoin","text":"geojoin(geotable₁, geotable₂, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, pred=intersects, on=nothing)\n\nJoins geotable₁ with geotable₂ using a certain kind of join and predicate function pred that takes two geometries and returns a boolean ((g1, g2) -> g1 ⊆ g2).\n\nOptionally, add a variable value match to join, in addition to geometric match, by passing a single name or list of variable names (strings or symbols) to the on keyword argument. The variable value match use the isequal function.\n\nWhenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.\n\nKinds\n\n:left - Returns all rows of geotable₁ filling entries with missing when there is no match in geotable₂.\n:inner - Returns the subset of rows of geotable₁ that has a match in geotable₂.\n\nExamples\n\ngeojoin(gtb1, gtb2)\ngeojoin(gtb1, gtb2, 1 => mean)\ngeojoin(gtb1, gtb2, :a => mean, :b => std)\ngeojoin(gtb1, gtb2, \"a\" => mean, pred=issubset)\ngeojoin(gtb1, gtb2, on=:a)\ngeojoin(gtb1, gtb2, kind=:inner, on=[\"a\", \"b\"])\n\nSee also tablejoin.\n\n\n\n\n\n","category":"function"},{"location":"queries/#GeoTables.tablejoin","page":"Queries","title":"GeoTables.tablejoin","text":"tablejoin(geotable, table, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, on)\n\nJoins geotable with table using the values of the on variables to match rows with a certain kind of join.\n\non variables can be a single name or list of variable names (strings or symbols). The variable value match use the isequal function.\n\nWhenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.\n\nKinds\n\n:left - Returns all rows of geotable filling entries with missing when there is no match in table.\n:inner - Returns the subset of rows of geotable that has a match in table.\n\nExamples\n\ntablejoin(gtb, tab, on=:a)\ntablejoin(gtb, tab, 1 => mean, on=:a)\ntablejoin(gtb, tab, :a => mean, :b => std, on=:a)\ntablejoin(gtb, tab, \"a\" => mean, on=[:a, :b])\ntablejoin(gtb, tab, kind=:inner, on=[\"a\", \"b\"])\n\nSee also geojoin.\n\n\n\n\n\n","category":"function"},{"location":"","page":"Home","title":"Home","text":"GeoStats","category":"page"},{"location":"#GeoStats","page":"Home","title":"GeoStats","text":"(Image: GeoStats.jl)\n\n(Image: ) (Image: ) (Image: ) (Image: ) (Image: )\n\n(Image: ) (Image: )\n\nGeoStats.jl is an extensible framework for geospatial data science and geostatistical modeling fully written in Julia. It is comprised of several modules for advanced geometric processing, state-of-the-art geostatistical algorithms and sophisticated visualization of geospatial data.\n\nAll further information is provided in the online documentation.\n\n\n\n\n\n","category":"module"},{"location":"","page":"Home","title":"Home","text":"note: Star us on GitHub!\nIf you have found this software useful, please consider starring it on GitHub. This gives us an accurate lower bound of the (satisfied) user count.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Organizations using the framework:","category":"page"},{"location":"","page":"Home","title":"Home","text":"

\n \n \n \n \n \n \n \n

","category":"page"},{"location":"#Sponsors","page":"Home","title":"Sponsors","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"

\n \n \n \n

","category":"page"},{"location":"","page":"Home","title":"Home","text":"Would like to become a sponsor? Press the sponsor button in our GitHub repository.","category":"page"},{"location":"#Textbooks","page":"Home","title":"Textbooks","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The following textbooks can be useful to learn the framework. Click on the cover to learn more.","category":"page"},{"location":"","page":"Home","title":"Home","text":"

\n \n \n \n

","category":"page"},{"location":"#Overview","page":"Home","title":"Overview","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"In many fields of science, such as mining engineering, hydrogeology, petroleum engineering, and environmental sciences, traditional statistical methods fail to provide unbiased estimates of resources due to the presence of geospatial correlation. Geostatistics (a.k.a. geospatial statistics) is the branch of statistics developed to overcome this limitation. Particularly, it is the branch that takes geospatial coordinates of data into account.","category":"page"},{"location":"","page":"Home","title":"Home","text":"GeoStats.jl is an attempt to bring together bleeding-edge research in the geostatistics community into a comprehensive framework for geospatial data science and geostatistical modeling, as well as to empower researchers and practitioners with a toolkit for fast assessment of different modeling approaches. For a guided tour, please watch our JuliaCon2021 talk:","category":"page"},{"location":"","page":"Home","title":"Home","text":"

\n\n

","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you have questions, feature requests, or would like to brainstorm ideas, don't hesitate to start a topic in our community channel.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Get the latest stable release with Julia's package manager:","category":"page"},{"location":"","page":"Home","title":"Home","text":"] add GeoStats","category":"page"},{"location":"#Quick-example","page":"Home","title":"Quick example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Below is a quick preview of the high-level interface:","category":"page"},{"location":"","page":"Home","title":"Home","text":"using GeoStats\n\nimport CairoMakie as Mke\n\n# attribute table\ntable = (; Z=[1.,0.,1.])\n\n# coordinates for each row\ncoord = [(25.,25.), (50.,75.), (75.,50.)]\n\n# georeference data\ngeotable = georef(table, coord)\n\n# interpolation domain\ngrid = CartesianGrid(100, 100)\n\n# choose an interpolation model\nmodel = Kriging(GaussianVariogram(range=35.))\n\n# perform interpolation over grid\ninterp = geotable |> Interpolate(grid, model)\n\n# visualize the solution\nviz(interp.geometry, color = interp.Z)","category":"page"},{"location":"","page":"Home","title":"Home","text":"For a more detailed example, please consult the Quickstart.","category":"page"},{"location":"#Project-organization","page":"Home","title":"Project organization","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The project is split into various packages:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Package Description\nGeoStats.jl Main package reexporting full stack of packages for geostatistics.\nMeshes.jl Computational geometry and advanced meshing algorithms.\nGeoTables.jl Geospatial tables compatible with the framework.\nDataScienceTraits.jl Traits for geospatial data science.\nTableTransforms.jl Transforms and pipelines with tabular data.\nStatsLearnModels.jl Statistical learning models for geospatial prediction.\nGeoStatsBase.jl Base package with core geostatistical definitions.\nGeoStatsFunctions.jl Geostatistical functions and related tools.\nGeoStatsModels.jl Geostatistical models for geospatial interpolation.\nGeoStatsProcesses.jl Geostatistical processes for geospatial simulation.\nGeoStatsTransforms.jl Geostatistical transforms for geospatial data.\nGeoStatsValidation.jl Geostatistical validation methods.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Other packages can be installed separately for additional functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Package Description\nGeoIO.jl Load/save geospatial tables in various formats.\nDrillHoles.jl Desurvey/composite drillhole data.\nGeoArtifacts.jl Artifacts for geospatial data science.","category":"page"},{"location":"#Citing-the-software","page":"Home","title":"Citing the software","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you find this software useful in your work, please consider citing it: ","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: JOSS) (Image: DOI)","category":"page"},{"location":"","page":"Home","title":"Home","text":"@ARTICLE{Hoffimann2018,\n title={GeoStats.jl – High-performance geostatistics in Julia},\n author={Hoffimann, Júlio},\n journal={Journal of Open Source Software},\n publisher={The Open Journal},\n volume={3},\n pages={692},\n number={24},\n ISSN={2475-9066},\n DOI={10.21105/joss.00692},\n url={https://dx.doi.org/10.21105/joss.00692},\n year={2018},\n month={Apr}\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"We ❤ to see our list of publications growing.","category":"page"},{"location":"about/citing/","page":"Citing","title":"Citing","text":"If you find GeoStats.jl useful in your work, please consider citing it:","category":"page"},{"location":"about/citing/","page":"Citing","title":"Citing","text":"(Image: JOSS) (Image: DOI)","category":"page"},{"location":"about/citing/","page":"Citing","title":"Citing","text":"@ARTICLE{Hoffimann2018,\n title={GeoStats.jl – High-performance geostatistics in Julia},\n author={Hoffimann, Júlio},\n journal={Journal of Open Source Software},\n publisher={The Open Journal},\n volume={3},\n pages={692},\n number={24},\n ISSN={2475-9066},\n DOI={10.21105/joss.00692},\n url={https://dx.doi.org/10.21105/joss.00692},\n year={2018},\n month={Apr}\n}","category":"page"}] +[{"location":"about/community/","page":"Community","title":"Community","text":"We use the Zulip platform to chat and help the community of users. Consider creating an account and pressing ? on the keyboard there for navigation instructions.","category":"page"},{"location":"about/community/","page":"Community","title":"Community","text":"Click on the image to join the channel:","category":"page"},{"location":"about/community/","page":"Community","title":"Community","text":"(Image: Zulip)","category":"page"},{"location":"random/points/#Points","page":"Points","title":"Points","text":"","category":"section"},{"location":"random/points/","page":"Points","title":"Points","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"Base.rand(::GeoStatsProcesses.PointProcess, ::Any)","category":"page"},{"location":"random/points/#Base.rand-Tuple{GeoStatsProcesses.PointProcess, Any}","page":"Points","title":"Base.rand","text":"rand([rng], process::PointProcess, geometry, [nreals])\nrand([rng], process::PointProcess, domain, [nreals])\n\nGenerate one or nreals realizations of the point process inside geometry or domain. Optionally specify the random number generator rng.\n\n\n\n\n\n","category":"method"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nsphere = Sphere((0, 0, 0), 1)\n\n# homogeneous Poisson process\nproc = PoissonProcess(5.0)\n\n# sample two point patterns\npset = rand(proc, sphere, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], sphere)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], sphere)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"ishomogeneous","category":"page"},{"location":"random/points/#GeoStatsProcesses.ishomogeneous","page":"Points","title":"GeoStatsProcesses.ishomogeneous","text":"ishomogeneous(process::PointProcess)\n\nTells whether or not the spatial point process process is homogeneous.\n\n\n\n\n\n","category":"function"},{"location":"random/points/#Processes","page":"Points","title":"Processes","text":"","category":"section"},{"location":"random/points/","page":"Points","title":"Points","text":"BinomialProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.BinomialProcess","page":"Points","title":"GeoStatsProcesses.BinomialProcess","text":"BinomialProcess(n)\n\nA Binomial point process with n points.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# Binomial process\nproc = BinomialProcess(1000)\n\n# sample point patterns\npset = rand(proc, box, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"PoissonProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.PoissonProcess","page":"Points","title":"GeoStatsProcesses.PoissonProcess","text":"PoissonProcess(λ)\n\nA Poisson process with intensity λ. For a homogeneous process, define λ as a constant real value, while for an inhomogeneous process, define λ as a function or vector of values. If λ is a vector, it is assumed that the process is associated with a Domain with the same number of elements as λ.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# intensity function\nλ(p) = sum(to(p))^2 / 10000\n\n# homogeneous process\nproc₁ = PoissonProcess(0.5)\n\n# inhomogeneous process\nproc₂ = PoissonProcess(λ)\n\n# sample point patterns\npset₁ = rand(proc₁, box)\npset₂ = rand(proc₂, box)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"InhibitionProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.InhibitionProcess","page":"Points","title":"GeoStatsProcesses.InhibitionProcess","text":"InhibitionProcess(δ)\n\nAn inhibition point process with minimum distance δ.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# inhibition process\nproc = InhibitionProcess(2.0)\n\n# sample point pattern\npset = rand(proc, box, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"ClusterProcess","category":"page"},{"location":"random/points/#GeoStatsProcesses.ClusterProcess","page":"Points","title":"GeoStatsProcesses.ClusterProcess","text":"ClusterProcess(proc, ofun)\n\nA cluster process with parent process proc and offsprings generated with ofun. It is a function that takes a parent point and returns a point pattern from another point process.\n\nClusterProcess(proc, offs, gfun)\n\nAlternatively, specify the parent process proc, the offspring process offs and the geometry function gfun. It is a function that takes a parent point and returns a geometry or domain for the offspring process.\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (5, 5))\n\n# Matérn process\nproc₁ = ClusterProcess(\n PoissonProcess(1),\n PoissonProcess(1000),\n p -> Ball(p, 0.2)\n)\n\n# inhomogeneous parent and offspring processes\nproc₂ = ClusterProcess(\n PoissonProcess(p -> 0.1 * sum(to(p) .^ 2)),\n p -> rand(PoissonProcess(x -> 5000 * sum((x - p).^2)), Ball(p, 0.5))\n)\n\n# sample point patterns\npset₁ = rand(proc₁, box)\npset₂ = rand(proc₂, box)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"random/points/#Operations","page":"Points","title":"Operations","text":"","category":"section"},{"location":"random/points/","page":"Points","title":"Points","text":"Base.union(::GeoStatsProcesses.PointProcess, ::GeoStatsProcesses.PointProcess)","category":"page"},{"location":"random/points/#Base.union-Tuple{GeoStatsProcesses.PointProcess, GeoStatsProcesses.PointProcess}","page":"Points","title":"Base.union","text":"p₁ ∪ p₂\n\nReturn the union of point processes p₁ and p₂.\n\n\n\n\n\n","category":"method"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# superposition of two Binomial processes\nproc₁ = BinomialProcess(500)\nproc₂ = BinomialProcess(500)\nproc = proc₁ ∪ proc₂ # 1000 points\n\npset = rand(proc, box, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset[1], color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset[2], color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"thin\nRandomThinning","category":"page"},{"location":"random/points/#GeoStatsProcesses.thin","page":"Points","title":"GeoStatsProcesses.thin","text":"thin(process, method)\n\nThin spatial point process with thinning method.\n\n\n\n\n\n","category":"function"},{"location":"random/points/#GeoStatsProcesses.RandomThinning","page":"Points","title":"GeoStatsProcesses.RandomThinning","text":"RandomThinning(p)\n\nRandom thinning with retention probability p, which can be a constant probability value in [0,1] or a function mapping a point to a probability.\n\nExamples\n\nRandomThinning(0.5)\nRandomThinning(p -> sum(to(p)))\n\n\n\n\n\n","category":"type"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# reduce intensity of Poisson process by half\nproc₁ = PoissonProcess(0.5)\nproc₂ = thin(proc₁, RandomThinning(0.5))\n\n# sample point patterns\npset₁ = rand(proc₁, box)\npset₂ = rand(proc₂, box)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"random/points/","page":"Points","title":"Points","text":"# geometry of interest\nbox = Box((0, 0), (100, 100))\n\n# Binomial process\nproc = BinomialProcess(2000)\n\n# sample point pattern\npset₁ = rand(proc, box)\n\n# thin point pattern with probability 0.5\npset₂ = thin(pset₁, RandomThinning(0.5))\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], box)\nviz!(fig[1,1], pset₁, color = :black)\nviz(fig[1,2], box)\nviz!(fig[1,2], pset₂, color = :black)\nfig","category":"page"},{"location":"variography/empirical/#Empirical-variograms","page":"Empirical variograms","title":"Empirical variograms","text":"","category":"section"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Variograms are widely used in geostatistics due to their intimate connection with (cross-)variance and visual interpretability. The following video explains the concept in detail:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"

\n\n

","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"The Matheron's estimator of the empirical variogram is given by","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"widehatgamma_M(h) = frac12N(h) sum_(ij) in N(h) (z_i - z_j)^2","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"where N(h) = left(ij) mid x_i - x_j = hright is the set of pairs of locations at a distance h and N(h) is the cardinality of the set. Alternatively, the robust Cressie's estimator is given by","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"widehatgamma_C(h) = frac12fracleftfrac1N(h) sum_(ij) in N(h) z_i - z_j^12right^40457 + frac0494N(h) + frac0045N(h)^2","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Both estimators are available and can be used with general distance functions in order to for example:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Model anisotropy (e.g. ellipsoid distance)\nPerform simulation on sphere (e.g. haversine distance)","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Please see Distances.jl for a complete list of distance functions.","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"The high-performance estimation procedure implemented in the framework can consider all pairs of locations regardless of direction (ominidirectional) or a specified partition of the geospatial data (e.g. directional, planar).","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Variograms estimated along all directions in a given plane of reference are called varioplanes. Both variograms and varioplanes can be plotted directly with the following options:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"varioplot","category":"page"},{"location":"variography/empirical/#GeoStatsFunctions.varioplot","page":"Empirical variograms","title":"GeoStatsFunctions.varioplot","text":"varioplot(γ; [options])\n\nPlot the variogram or varioplane γ with given options.\n\nEmpirical variogram options:\n\nvcolor - color of variogram\npsize - size of points of variogram\nssize - size of segments of variogram\ntshow - show text counts\ntsize - size of text counts\nhshow - show histogram\nhcolor - color of histogram\n\nEmpirical varioplane options:\n\nvscheme - color scheme of varioplane\nrshow - show range of theoretical model\nrmodel - theoretical model (e.g. SphericalVariogram)\nrcolor - color of range curve\n\nTheoretical variogram options:\n\nmaxlag - maximum lag for theoretical model\n\nNotes\n\nThis function will only work in the presence of a Makie.jl backend via package extensions in Julia v1.9 or later versions of the language.\n\n\n\n\n\n","category":"function"},{"location":"variography/empirical/#(Omini)directional","page":"Empirical variograms","title":"(Omini)directional","text":"","category":"section"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"EmpiricalVariogram\nDirectionalVariogram\nPlanarVariogram\nvalues(::EmpiricalVariogram)\ndistance(::EmpiricalVariogram)\nestimator(::EmpiricalVariogram)\nmerge(::EmpiricalVariogram{V,D,E}, ::EmpiricalVariogram{V,D,E}) where {V,D,E}","category":"page"},{"location":"variography/empirical/#GeoStatsFunctions.EmpiricalVariogram","page":"Empirical variograms","title":"GeoStatsFunctions.EmpiricalVariogram","text":"EmpiricalVariogram(data, var₁, var₂=var₁; [parameters])\n\nComputes the empirical (a.k.a. experimental) omnidirectional (cross-)variogram for variables var₁ and var₂ stored in geospatial data.\n\nParameters\n\nnlags - number of lags (default to 20)\nmaxlag - maximum lag in length units (default to 1/10 of maximum lag of data)\ndistance - custom distance function (default to Euclidean distance)\nestimator - variogram estimator (default to :matheron estimator)\nalgorithm - accumulation algorithm (default to :ball)\n\nAvailable estimators:\n\n:matheron - simple estimator based on squared differences\n:cressie - robust estimator based on 4th power of differences\n\nAvailable algorithms:\n\n:full - loop over all pairs of points in the data\n:ball - loop over all points inside maximum lag ball\n\nAll implemented algorithms produce the exact same result. The :ball algorithm is considerably faster when the maximum lag is much smaller than the bounding box of the domain of the data.\n\nSee also: DirectionalVariogram, PlanarVariogram, EmpiricalVarioplane.\n\nReferences\n\nChilès, JP and Delfiner, P. 2012. Geostatistics: Modeling Spatial Uncertainty\nWebster, R and Oliver, MA. 2007. Geostatistics for Environmental Scientists\nHoffimann, J and Zadrozny, B. 2019. Efficient variography with partition variograms\n\n\n\n\n\n","category":"type"},{"location":"variography/empirical/#GeoStatsFunctions.DirectionalVariogram","page":"Empirical variograms","title":"GeoStatsFunctions.DirectionalVariogram","text":"DirectionalVariogram(direction, data, var₁, var₂=var₁; dtol=1e-6u\"m\", [parameters])\n\nComputes the empirical (cross-)variogram for the variables var₁ and var₂ stored in geospatial data along a given direction with band tolerance dtol in length units.\n\nOptionally, forward parameters for the underlying EmpiricalVariogram.\n\n\n\n\n\n","category":"function"},{"location":"variography/empirical/#GeoStatsFunctions.PlanarVariogram","page":"Empirical variograms","title":"GeoStatsFunctions.PlanarVariogram","text":"PlanarVariogram(normal, data, var₁, var₂=var₁; ntol=1e-6u\"m\", [parameters])\n\nComputes the empirical (cross-)variogram for the variables var₁ and var₂ stored in geospatial data along a plane perpendicular to a normal direction with plane tolerance ntol in length units.\n\nOptionally, forward parameters for the underlying EmpiricalVariogram.\n\n\n\n\n\n","category":"function"},{"location":"variography/empirical/#Base.values-Tuple{EmpiricalVariogram}","page":"Empirical variograms","title":"Base.values","text":"values(γ)\n\nReturns the abscissa, the ordinate, and the bin counts of the empirical variogram γ.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/#GeoStatsFunctions.distance-Tuple{EmpiricalVariogram}","page":"Empirical variograms","title":"GeoStatsFunctions.distance","text":"distance(γ)\n\nReturn the distance used to compute the empirical variogram γ.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/#GeoStatsFunctions.estimator-Tuple{EmpiricalVariogram}","page":"Empirical variograms","title":"GeoStatsFunctions.estimator","text":"estimator(γ)\n\nReturn the estimator used to compute the empirical variogram γ.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/#Base.merge-Union{Tuple{E}, Tuple{D}, Tuple{V}, Tuple{EmpiricalVariogram{V, D, E}, EmpiricalVariogram{V, D, E}}} where {V, D, E}","page":"Empirical variograms","title":"Base.merge","text":"merge(γα, γβ)\n\nMerge the empirical variogram γα with the empirical variogram γβ assuming that both variograms have the same number of lags, distance and estimator.\n\n\n\n\n\n","category":"method"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"Consider the following example image:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"using GeoArtifacts\n\n𝒟 = GeoStatsImages.get(\"Gaussian30x10\")\n\nviz(𝒟.geometry, color = 𝒟.Z)","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"We can compute ominidirectional variograms, which consider pairs of points along all directions:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γ = EmpiricalVariogram(𝒟, :Z, maxlag = 50.)\n\nMke.plot(γ)","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"directional variograms along a specific direction:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γₕ = DirectionalVariogram((1.,0.), 𝒟, :Z, maxlag = 50.)\nγᵥ = DirectionalVariogram((0.,1.), 𝒟, :Z, maxlag = 50.)\n\nMke.plot(γₕ, vcolor = :maroon, hcolor = :maroon)\nMke.plot!(γᵥ)\nMke.current_figure()","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"or planar variograms over a specific plane:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γᵥ = PlanarVariogram((1.,0.), 𝒟, :Z, maxlag = 50.)\nγₕ = PlanarVariogram((0.,1.), 𝒟, :Z, maxlag = 50.)\n\nMke.plot(γₕ, vcolor = :maroon, hcolor = :maroon)\nMke.plot!(γᵥ)\nMke.current_figure()","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"note: Note\nThe directional and planar variograms coincide in this example because planes are equal to lines in 2-dimensional space. These concepts are most useful in 3-dimensional space where we may be interested in comparing the horizontal planar range to the vertical directional range.","category":"page"},{"location":"variography/empirical/#Varioplanes","page":"Empirical variograms","title":"Varioplanes","text":"","category":"section"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"EmpiricalVarioplane","category":"page"},{"location":"variography/empirical/#GeoStatsFunctions.EmpiricalVarioplane","page":"Empirical variograms","title":"GeoStatsFunctions.EmpiricalVarioplane","text":"EmpiricalVarioplane(data, var₁, var₂=var₁;\n normal=Vec(0,0,1),\n nangs=50, ptol=0.5u\"m\", dtol=0.5u\"m\",\n [parameters])\n\nGiven a normal direction, estimate the (cross-)variogram of variables var₁ and var₂ along all directions in the corresponding plane of variation.\n\nOptionally, specify the tolerance ptol in length units for the plane partition, the tolerance dtol in length units for the direction partition, the number of angles nangs in the plane, and forward the parameters to the underlying EmpiricalVariogram.\n\n\n\n\n\n","category":"type"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"The varioplane is plotted on a polar axis for all lags and angles:","category":"page"},{"location":"variography/empirical/","page":"Empirical variograms","title":"Empirical variograms","text":"γ = EmpiricalVarioplane(𝒟, :Z, maxlag = 50.)\n\nfig = Mke.Figure()\nax = Mke.PolarAxis(fig[1,1], title = \"Varioplane\")\nMke.plot!(ax, γ)\nfig","category":"page"},{"location":"variography/theoretical/#Theoretical-variograms","page":"Theoretical variograms","title":"Theoretical variograms","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"We provide various theoretical variogram models from the literature, which can can be combined with ellipsoid distances to model geometric anisotropy and nested with scalars or matrix coefficients to express multivariate relations.","category":"page"},{"location":"variography/theoretical/#Models","page":"Theoretical variograms","title":"Models","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"In an intrinsic isotropic model, the variogram is only a function of the distance between any two points x_1x_2 in R^m:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(x_1x_2) = gamma(x_1 - x_2) = gamma(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Under the additional assumption of 2nd-order stationarity, the well-known covariance is directly related via gamma(h) = cov(0) - cov(h). This package implements a few commonly used as well as other more exotic variogram models. Most of these models share a set of default parameters (e.g. sill=1.0, range=1.0), which can be set with keyword arguments.","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Functions are provided to query properties of variogram models programmatically:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"isstationary(::Variogram)\nisisotropic(::Variogram)","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.isstationary-Tuple{Variogram}","page":"Theoretical variograms","title":"GeoStatsFunctions.isstationary","text":"isstationary(γ)\n\nCheck if variogram γ possesses the 2nd-order stationary property.\n\n\n\n\n\n","category":"method"},{"location":"variography/theoretical/#Meshes.isisotropic-Tuple{Variogram}","page":"Theoretical variograms","title":"Meshes.isisotropic","text":"isisotropic(γ)\n\nTells whether or not variogram γ is isotropic.\n\n\n\n\n\n","category":"method"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Corresponding covariance models are available for convenience. For example, the GaussianVariogram and the GaussianCovariance are two alternative representations of the same geostatistical behavior.","category":"page"},{"location":"variography/theoretical/#Gaussian","page":"Theoretical variograms","title":"Gaussian","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - expleft(-3left(frachrright)^2right)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"GaussianVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.GaussianVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.GaussianVariogram","text":"GaussianVariogram(range=r, sill=s, nugget=n)\nGaussianVariogram(ball; sill=s, nugget=n)\n\nA Gaussian variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(GaussianVariogram())","category":"page"},{"location":"variography/theoretical/#Exponential","page":"Theoretical variograms","title":"Exponential","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - expleft(-3left(frachrright)right)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"ExponentialVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.ExponentialVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.ExponentialVariogram","text":"ExponentialVariogram(range=r, sill=s, nugget=n)\nExponentialVariogram(ball; sill=s, nugget=n)\n\nAn exponential variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(ExponentialVariogram())","category":"page"},{"location":"variography/theoretical/#Matern","page":"Theoretical variograms","title":"Matern","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - frac2^1-nuGamma(nu) left(sqrt2nu 3left(frachrright)right)^nu K_nuleft(sqrt2nu 3left(frachrright)right)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"MaternVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.MaternVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.MaternVariogram","text":"MaternVariogram(range=r, sill=s, nugget=n, order=ν)\nMaternVariogram(ball; sill=s, nugget=n, order=ν)\n\nA Matérn variogram with range r, sill s and nugget n. The parameter ν is the order of the Bessel function. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(MaternVariogram())","category":"page"},{"location":"variography/theoretical/#Spherical","page":"Theoretical variograms","title":"Spherical","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(frac32left(frachrright) + frac12left(frachrright)^3right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"SphericalVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.SphericalVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.SphericalVariogram","text":"SphericalVariogram(range=r, sill=s, nugget=n)\nSphericalVariogram(ball; sill=s, nugget=n)\n\nA spherical variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(SphericalVariogram())","category":"page"},{"location":"variography/theoretical/#Cubic","page":"Theoretical variograms","title":"Cubic","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(7left(frachrright)^2 - frac354left(frachrright)^3 + frac72left(frachrright)^5 - frac34left(frachrright)^7right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"CubicVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.CubicVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.CubicVariogram","text":"CubicVariogram(range=r, sill=s, nugget=n)\nCubicVariogram(ball; sill=s, nugget=n)\n\nA cubic variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(CubicVariogram())","category":"page"},{"location":"variography/theoretical/#Pentaspherical","page":"Theoretical variograms","title":"Pentaspherical","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(frac158left(frachrright) - frac54left(frachrright)^3 + frac38left(frachrright)^5right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"PentasphericalVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.PentasphericalVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.PentasphericalVariogram","text":"PentasphericalVariogram(range=r, sill=s, nugget=n)\nPentasphericalVariogram(ball; sill=s, nugget=n)\n\nA pentaspherical variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(PentasphericalVariogram())","category":"page"},{"location":"variography/theoretical/#Power","page":"Theoretical variograms","title":"Power","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = sh^a + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"PowerVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.PowerVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.PowerVariogram","text":"PowerVariogram(scaling=s, exponent=a, nugget=n)\n\nA power variogram with scaling s, exponent a and nugget n.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(PowerVariogram())","category":"page"},{"location":"variography/theoretical/#Sine-hole","page":"Theoretical variograms","title":"Sine hole","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) left1 - fracsin(pi h r)pi h rright + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"SineHoleVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.SineHoleVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.SineHoleVariogram","text":"SineHoleVariogram(range=r, sill=s, nugget=n)\nSineHoleVariogram(ball; sill=s, nugget=n)\n\nA sine hole variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(SineHoleVariogram())","category":"page"},{"location":"variography/theoretical/#Nugget","page":"Theoretical variograms","title":"Nugget","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"NuggetEffect","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.NuggetEffect","page":"Theoretical variograms","title":"GeoStatsFunctions.NuggetEffect","text":"NuggetEffect(nugget=n)\n\nA pure nugget effect variogram with nugget n.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(NuggetEffect(1.0))","category":"page"},{"location":"variography/theoretical/#Circular","page":"Theoretical variograms","title":"Circular","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"gamma(h) = (s - n) leftleft(1 - frac2pi cos^-1left(frachrright) + frac2hpi r sqrt1 - frach^2r^2 right) cdot 1_(0r)(h) + 1_rinfty)(h)right + n cdot 1_(0infty)(h)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"CircularVariogram","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.CircularVariogram","page":"Theoretical variograms","title":"GeoStatsFunctions.CircularVariogram","text":"CircularVariogram(; range=r, sill=s, nugget=n)\nCircularVariogram(ball; sill=s, nugget=n)\n\nA circular variogram with range r, sill s and nugget n. Optionally, use a custom metric ball.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Mke.plot(CircularVariogram())","category":"page"},{"location":"variography/theoretical/#Anisotropy","page":"Theoretical variograms","title":"Anisotropy","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"Anisotropic models are easily obtained by defining an ellipsoid metric in place of the default Euclidean metric as shown in the following example. First, we create an ellipsoid that specifies the ranges and angles of rotation:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"ellipsoid = MetricBall((3.0, 2.0, 1.0), RotZXZ(0.0, 0.0, 0.0))","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"All rotations from Rotations.jl are supported as well as the following additional rotations from commercial geostatistical software:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"MinesightAngles\nDatamineAngles\nVulcanAngles\nGslibAngles","category":"page"},{"location":"variography/theoretical/#GeoStatsBase.MinesightAngles","page":"Theoretical variograms","title":"GeoStatsBase.MinesightAngles","text":"MinesightAngles(θ₁, θ₂, θ₃)\n\nMineSight z-x'-y'' intrinsic rotation convention following the right-hand rule. All angles are in degrees and the sign convention is CW, CCW, CW positive.\n\nThe first rotation θ₁ is a horizontal rotation around the Z-axis, with positive being clockwise. The second rotation θ₂ is a rotation around the new X-axis, which moves the Y-axis into the desired position, with positive direction of rotation is up. The third rotation θ₃ is a rotation around the new Y-axis, which moves the X-axis into the desired position, with positive direction of rotation is up.\n\nReferences\n\nSanchez, J. MINESIGHT® TUTORIALS\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/#GeoStatsBase.DatamineAngles","page":"Theoretical variograms","title":"GeoStatsBase.DatamineAngles","text":"DatamineAngles(θ₁, θ₂, θ₃)\n\nDatamine ZXY rotation convention following the left-hand rule. All angles are in degrees and the signal convention is CW, CW, CW positive. Y is the principal axis.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/#GeoStatsBase.VulcanAngles","page":"Theoretical variograms","title":"GeoStatsBase.VulcanAngles","text":"VulcanAngles(θ₁, θ₂, θ₃)\n\nVulcan ZYX rotation convention following the right-hand rule. All angles are in degrees and the signal convention is CW, CCW, CW positive. X is the principal axis.\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/#GeoStatsBase.GslibAngles","page":"Theoretical variograms","title":"GeoStatsBase.GslibAngles","text":"GslibAngles(θ₁, θ₂, θ₃)\n\nGSLIB z-x'-y'' intrinsic rotation convention following the left-hand rule. All angles are in degrees and the sign convention is CW, CCW, CW positive. Y is the principal axis.\n\nThe first rotation θ₁ is a rotation around the Z-axis, this is also called the azimuth. The second rotation θ₂ is a rotation around the new X-axis, this is also called the dip. The third rotation θ₃ is a rotation around the new Y-axis, this is also called the tilt. \n\nReferences\n\nDeutsch, 2015. The Angle Specification for GSLIB Software\n\n\n\n\n\n","category":"type"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"We pass the ellipsoid as the first argument to the variogram model instead of specifying a single range with a keyword argument:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"GaussianVariogram(ellipsoid, sill = 2.0)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"To illustrate the concept, consider the following 2D data set:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"using Random # hide\nRandom.seed!(2000) # hide\n\npoints = rand(Point{2}, 50) |> Scale(100)\ngeotable = georef((Z=rand(50),), points)\n\nviz(geotable.geometry, color = geotable.Z)","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"We interpolate the data with different ellipsoids by varying the angle of rotation from 0 to 2pi clockwise:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"θs = range(0.0, step = π/4, stop = 2π - π/4)\n\n# initialize figure\nfig = Mke.Figure(size = (800, 1600))\n\n# helper function to position subfigures\npos = i -> CartesianIndices((4, 2))[i].I\n\n# Kriging with different angles\nfor (i, θ) in enumerate(θs)\n # ellipsoid rotated clockwise by angle θ\n e = MetricBall((20.,5.), Angle2d(θ))\n\n # anisotropic variogram model\n γ = GaussianVariogram(e)\n\n # domain of interpolation\n grid = CartesianGrid(100, 100)\n\n # perform interpolation\n sol = geotable |> Interpolate(grid, Kriging(γ))\n\n # visualize solution at subplot i\n viz(fig[pos(i)...], sol.geometry, color = sol.Z,\n axis = (title = \"θ = $(rad2deg(θ))ᵒ\",)\n )\nend\n\nfig","category":"page"},{"location":"variography/theoretical/#Nesting","page":"Theoretical variograms","title":"Nesting","text":"","category":"section"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"A nested variogram model gamma(h) = c_1cdotgamma_1(h) + c_2cdotgamma_2(h) + cdots + c_ncdotgamma_n(h) can be constructed from multiple variogram models, including matrix coefficients. The individual structures can be recovered in canonical form with the structures function:","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"structures","category":"page"},{"location":"variography/theoretical/#GeoStatsFunctions.structures","page":"Theoretical variograms","title":"GeoStatsFunctions.structures","text":"structures(γ)\n\nReturn the individual structures of a (possibly nested) variogram as a tuple. The structures are the total nugget cₒ, and the coefficients (or contributions) c[i] for the remaining non-trivial structures g[i] after normalization (i.e. sill=1, nugget=0).\n\nExamples\n\nγ₁ = GaussianVariogram(nugget=1, sill=2)\nγ₂ = SphericalVariogram(nugget=2, sill=3)\n\nγ = 2γ₁ + 3γ₂\n\ncₒ, c, g = structures(γ)\n\n\n\n\n\n","category":"function"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"γ₁ = GaussianVariogram(nugget=1, sill=2)\nγ₂ = ExponentialVariogram(nugget=2, sill=3)\n\n# nested model with matrix coefficients\nγ = [1.0 0.0; 0.0 1.0] * γ₁ + [2.0 0.5; 0.5 3.0] * γ₂\n\n# structures in canonical form\ncₒ, c, g = structures(γ)\n\ncₒ # matrix nugget","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"c # matrix coefficients","category":"page"},{"location":"variography/theoretical/","page":"Theoretical variograms","title":"Theoretical variograms","text":"g # normalized structures","category":"page"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"First off, thank you for considering contributing to GeoStats.jl. It’s people like you that make this project so much fun. Below are a few suggestions to speed up the collaboration process:","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Please be polite, we are here to help and learn from each other.\nTry to explain your contribution with simple language.\nReferences to textbooks and papers are always welcome.\nFollow the coding standards in the source.","category":"page"},{"location":"contributing/#How-to-start-contributing?","page":"Contributing","title":"How to start contributing?","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Contributing to an open-source project for the very first time can be a very daunting task. To make the process easier and more GitHub-beginner-friendly, the community has written an article about how to start contributing to open-source and overcome the mental and technical barriers that come associated with it. The article will also take you through the steps required to make your first contribution in detail.","category":"page"},{"location":"contributing/#Reporting-issues","page":"Contributing","title":"Reporting issues","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If you are experiencing issues or have discovered a bug, please report it on GitHub. To make the resolution process easier, please include the version of Julia and GeoStats.jl in your writeup. These can be found with two commands:","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"julia> versioninfo()\njulia> using Pkg; Pkg.status()","category":"page"},{"location":"contributing/#Feature-requests","page":"Contributing","title":"Feature requests","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If you have suggestions of improvement or algorithms that you would like to see implemented, please open an issue on GitHub. Suggestions as well as feature requests are very welcome.","category":"page"},{"location":"contributing/#Code-contribution","page":"Contributing","title":"Code contribution","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If you have code that you would like to contribute that is awesome! Please open an issue or reach out in our community channel before you create the pull request on GitHub so that we make sure your idea is aligned with the project goals.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"After your idea is revised by project maintainers, you implement it online on Github or offline on your machine.","category":"page"},{"location":"contributing/#Online-changes","page":"Contributing","title":"Online changes","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If the changes to the code are minimal, we recommend pressing . on the keyboard on any file in the GitHub repository of interest. This will open the VSCode editor on the web browser where you can implement the changes, commit them and submit a pull request.","category":"page"},{"location":"contributing/#Offline-changes","page":"Contributing","title":"Offline changes","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"If the changes require additional investigation and tests, please get the development version of the project by typing the following in the package manager:","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"] activate @geo","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"This will create a fresh environment called @geo where you can edit the project modules without effects on your global user environment. Next, go ahead and ask the package manager to develop the package of interest (e.g. GeoStatsFunctions.jl):","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"] dev GeoStatsFunctions","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"You can modify the source code that was cloned in the .julia/dev folder and submit a pull request on GitHub later.","category":"page"},{"location":"links/#Index","page":"Index","title":"Index","text":"","category":"section"},{"location":"links/","page":"Index","title":"Index","text":"Below is the list of types and functions mentioned in the documentation.","category":"page"},{"location":"links/#Types","page":"Index","title":"Types","text":"","category":"section"},{"location":"links/","page":"Index","title":"Index","text":"Order = [:type]","category":"page"},{"location":"links/#Functions","page":"Index","title":"Functions","text":"","category":"section"},{"location":"links/","page":"Index","title":"Index","text":"Order = [:function]","category":"page"},{"location":"data/#Geospatial-data","page":"Data","title":"Geospatial data","text":"","category":"section"},{"location":"data/#Overview","page":"Data","title":"Overview","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Given a table or array containing data, we can georeference these objects onto a geospatial domain with the georef function. The result of the georef function is a GeoTable. If you would like to learn this concept in more depth, check out the recording of our JuliaEO 2024 workshop:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"

\n\n

","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef","category":"page"},{"location":"data/#GeoTables.georef","page":"Data","title":"GeoTables.georef","text":"georef(table, domain)\n\nGeoreference table on domain.\n\ntable must implement the Tables.jl interface (e.g., DataFrame, CSV.File, XLSX.Worksheet).\n\ndomain must implement the Meshes.jl interface (e.g., CartesianGrid, SimpleMesh, GeometrySet).\n\nExamples\n\njulia> georef((a=rand(100), b=rand(100)), CartesianGrid(10, 10))\n\n\n\n\n\ngeoref(table, geoms)\n\nGeoreference table on vector of geometries geoms.\n\ngeoms must implement the Meshes.jl interface (e.g., Point, Quadrangle, Hexahedron).\n\nExamples\n\njulia> georef((a=rand(10), b=rand(10)), rand(Point{2}, 10))\n\n\n\n\n\ngeoref(table, coords)\n\nGeoreference table on PointSet(coords) using Cartesian coords.\n\nExamples\n\njulia> georef((a=rand(10), b=rand(10)), [(rand(), rand()) for i in 1:10])\n\n\n\n\n\ngeoref(table, names; [crs])\n\nGeoreference table using coordinates stored in given column names.\n\nOptionally, specify the coordinate reference system crs, which is set by default based on heuristics.\n\nExamples\n\ngeoref((a=rand(10), x=rand(10), y=rand(10)), (\"x\", \"y\"))\ngeoref((a=rand(10), x=rand(10), y=rand(10)), [\"x\", \"y\"])\ngeoref((a=rand(10), x=rand(10), y=rand(10)), [\"x\", \"y\"], crs=Cartesian)\ngeoref((a=rand(10), x=rand(10), y=rand(10)), [\"x\", \"y\"], crs=LatLon)\n\n\n\n\n\ngeoref(tuple)\n\nGeoreference a named tuple on CartesianGrid(dims), with dims being the dimensions of the tuple arrays.\n\nExamples\n\njulia> georef((a=rand(10, 10), b=rand(10, 10))) # 2D grid\njulia> georef((a=rand(10, 10, 10), b=rand(10, 10, 10))) # 3D grid\n\n\n\n\n\n","category":"function"},{"location":"data/","page":"Data","title":"Data","text":"The functions values and domain can be used to retrieve the table of attributes and the underlying geospatial domain:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"values\ndomain","category":"page"},{"location":"data/#Base.values","page":"Data","title":"Base.values","text":"values(geotable, [rank])\n\nReturn the values of geotable for a given rank as a table.\n\nThe rank is a non-negative integer that specifies the parametric dimension of the geometries of interest:\n\n0 - points\n1 - segments\n2 - triangles, quadrangles, ...\n3 - tetrahedrons, hexahedrons, ...\n\nIf the rank is not specified, it is assumed to be the rank of the elements of the domain.\n\n\n\n\n\n","category":"function"},{"location":"data/#GeoTables.domain","page":"Data","title":"GeoTables.domain","text":"domain(geotable)\n\nReturn underlying domain of the geotable.\n\n\n\n\n\n","category":"function"},{"location":"data/","page":"Data","title":"Data","text":"The GeoIO.jl package can be used to load/save geospatial data from/to various file formats:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"GeoIO.load\nGeoIO.save\nGeoIO.formats","category":"page"},{"location":"data/#GeoIO.load","page":"Data","title":"GeoIO.load","text":"load(fname, layer=0, fix=true, kwargs...)\n\nLoad geospatial table from file fname and convert the geometry column to Meshes.jl geometries.\n\nOptionally, specify the layer of geometries to read within the file and keyword arguments kwargs accepted by Shapefile.Table, GeoJSON.read GeoParquet.read and ArchGDAL.read.\n\nThe option fix can be used to fix orientation and degeneracy issues with polygons.\n\nTo see supported formats, use the formats function.\n\n\n\n\n\n","category":"function"},{"location":"data/#GeoIO.save","page":"Data","title":"GeoIO.save","text":"save(fname, geotable; kwargs...)\n\nSave geospatial table to file fname using the appropriate format based on the file extension. Optionally, specify keyword arguments accepted by Shapefile.write and GeoJSON.write. For example, use force = true to force writing on existing .shp file.\n\nTo see supported formats, use the formats function.\n\n\n\n\n\n","category":"function"},{"location":"data/#GeoIO.formats","page":"Data","title":"GeoIO.formats","text":"formats([io]; sortby=:format)\n\nDisplays in io (defaults to stdout if io is not given) a table with all formats supported by GeoIO.jl and the packages used to load and save each of them. \n\nOptionally, sort the table by the :extension, :load or :save columns using the sortby argument.\n\n\n\n\n\n","category":"function"},{"location":"data/","page":"Data","title":"Data","text":"The GeoArtifacts.jl package provides utility functions to automatically download geospatial data from repositories on the internet.","category":"page"},{"location":"data/#Examples","page":"Data","title":"Examples","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"using GeoStats\nimport CairoMakie as Mke\n\n# helper function for plotting two\n# variables named T and P side by side\nfunction plot(data)\n fig = Mke.Figure(size = (800, 400))\n viz(fig[1,1], data.geometry, color = data.T)\n viz(fig[1,2], data.geometry, color = data.P)\n fig\nend","category":"page"},{"location":"data/#Tables","page":"Data","title":"Tables","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Consider a table (e.g. DataFrame) with 25 samples of temperature T and pressure P:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"using DataFrames\n\ntable = DataFrame(T=rand(25), P=rand(25))","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"We can georeference this table based on a given set of points:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef(table, rand(Point{2}, 25)) |> plot","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"or alternatively, georeference it on a 5x5 regular grid (5x5 = 25 samples):","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef(table, CartesianGrid(5, 5)) |> plot","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"Another common pattern in geospatial data is when the coordinates of the samples are already part of the table as columns. In this case, we can specify the column names:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"table = DataFrame(T=rand(25), P=rand(25), X=rand(25), Y=rand(25), Z=rand(25))\n\ngeoref(table, (\"X\", \"Y\", \"Z\")) |> plot","category":"page"},{"location":"data/#Arrays","page":"Data","title":"Arrays","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"Consider arrays (e.g. images) with data for various geospatial variables. We can georeference these arrays using a named tuple, and the framework will understand that the shape of the arrays should be preserved in a CartesianGrid:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"T, P = rand(5, 5), rand(5, 5)\n\ngeoref((T=T, P=P)) |> plot","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"Alternatively, we can interpret the entries of the named tuple as columns in a table:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"georef((T=vec(T), P=vec(P)), rand(Point{2}, 25)) |> plot","category":"page"},{"location":"data/#Files","page":"Data","title":"Files","text":"","category":"section"},{"location":"data/","page":"Data","title":"Data","text":"We can easily load geospatial data from disk without any specific knowledge of file formats:","category":"page"},{"location":"data/","page":"Data","title":"Data","text":"using GeoIO\n\nzone = GeoIO.load(\"data/zone.shp\")\npath = GeoIO.load(\"data/path.shp\")\n\nviz(zone.geometry)\nviz!(path.geometry, color = :gray90)\nMke.current_figure()","category":"page"},{"location":"visualization/#Visualization","page":"Visualization","title":"Visualization","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"The framework provides powerful visualization recipes for geospatial data science via the Makie.jl project. These recipes were carefully designed to maximize productivity and to protect users from GIS jargon. The main entry point is the viz function:","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"viz\nviz!","category":"page"},{"location":"visualization/#Meshes.viz","page":"Visualization","title":"Meshes.viz","text":"viz(object; [options])\n\nVisualize Meshes.jl object with various options.\n\nAvailable options\n\ncolor - color of geometries\nalpha - transparency in [0,1]\ncolormap - color scheme/map from ColorSchemes.jl\ncolorrange - minimum and maximum color values\nshowsegments - visualize segments\nsegmentcolor - color of segments\nsegmentsize - width of segments\nshowpoints - visualize points\npointcolor - color of points\npointsize - size of points\n\nThe option color can be a single scalar or a vector of scalars. For Mesh subtypes, the length of the vector of colors determines if the colors should be assigned to vertices or to elements.\n\nExamples\n\nDifferent coloring methods (vertex vs. element):\n\n# vertex coloring (i.e. linear interpolation)\nviz(mesh, color = 1:nvertices(mesh))\n\n# element coloring (i.e. discrete colors)\nviz(mesh, color = 1:nelements(mesh))\n\nDifferent strategies to show the boundary of geometries (showsegments vs. boundary):\n\n# visualize boundary with showsegments\nviz(polygon, showsegments = true)\n\n# visualize boundary with separate call\nviz(polygon)\nviz!(boundary(polygon))\n\nNotes\n\nThis function will only work in the presence of a Makie.jl backend via package extensions in Julia v1.9 or later versions of the language.\n\n\n\n\n\n","category":"function"},{"location":"visualization/#Meshes.viz!","page":"Visualization","title":"Meshes.viz!","text":"viz!(object; [options])\n\nVisualize Meshes.jl object in an existing scene with options forwarded to viz.\n\n\n\n\n\n","category":"function"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"This function takes a geospatial domain as input and provides a set of aesthetic options to style the elements (i.e. geometries) of the domain.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"note: Note\nNotice that the geometry column of our geospatial data type is a domain (i.e. data.geometry isa Domain), and that this design enables several optimizations in the visualization itself.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Users can also call Makie's plot function in the geometry column as in","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Mke.plot(data.geometry)","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"and this is equivalent to calling the viz recipe above. The plot function also works with various other objects such as EmpiricalHistogram and EmpiricalVariogram. That is convenient if you don't remember the name of the recipe.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Additionaly, we provide a basic scientific viewer to visualize all viewable variables in the data:","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"viewer","category":"page"},{"location":"visualization/#GeoTables.viewer","page":"Visualization","title":"GeoTables.viewer","text":"viewer(geotable; kwargs...)\n\nBasic scientific viewer for geospatial table geotable.\n\nAesthetic options are forwarded via kwargs to the Meshes.viz recipe.\n\n\n\n\n\n","category":"function"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"Other plots are listed below that can be useful for geostatistical analysis.","category":"page"},{"location":"visualization/#Built-in","page":"Visualization","title":"Built-in","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"A hscatter plot between two variables var1 and var2 (possibly with var2 = var1) is a simple scatter plot in which the dots represent all ordered pairs of values of var1 and var2 at a given lag h.","category":"page"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"𝒟 = georef((Z=[10sin(i/10) + j for i in 1:100, j in 1:200],))\n\n𝒮 = sample(𝒟, UniformSampling(500))\n\nfig = Mke.Figure(size = (800, 400))\nhscatter(fig[1,1], 𝒮, :Z, :Z, lag=0)\nhscatter(fig[1,2], 𝒮, :Z, :Z, lag=20)\nhscatter(fig[2,1], 𝒮, :Z, :Z, lag=40)\nhscatter(fig[2,2], 𝒮, :Z, :Z, lag=60)\nfig","category":"page"},{"location":"visualization/#PairPlots.jl","page":"Visualization","title":"PairPlots.jl","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"The PairPlots.jl package provides the pairplot function that can be used with any table, including tables of attributes obtained with the values function.","category":"page"},{"location":"visualization/#Biplots.jl","page":"Visualization","title":"Biplots.jl","text":"","category":"section"},{"location":"visualization/","page":"Visualization","title":"Visualization","text":"The Biplot.jl package provides 2D and 3D statistical biplots.","category":"page"},{"location":"resources/education/#Education","page":"Education","title":"Education","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"We recommend the following educational resources.","category":"page"},{"location":"resources/education/#Learning-resources","page":"Education","title":"Learning resources","text":"","category":"section"},{"location":"resources/education/#Textbooks","page":"Education","title":"Textbooks","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"Hoffimann, J. 2023. Geospatial Data Science with Julia - A fresh approach to data science with geospatial data and the Julia programming language.\nIsaaks, E. and Srivastava, R. 1990. An Introduction to Applied Geostatistics - An introductory book on geostatistics that covers important concepts with very simple language.\nChilès, JP and Delfiner, P. 2012. Geostatistics: Modeling Spatial Uncertainty - An incredible book for those with good mathematical background.\nWebster, R and Oliver, MA. 2007. Geostatistics for Environmental Scientists - A great book with good balance between theory and practice.\nJournel, A. and Huijbregts, Ch. 2003. Mining Geostatistics - A great book with both theoretical and practical developments.","category":"page"},{"location":"resources/education/#Video-lectures","page":"Education","title":"Video lectures","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"Júlio Hoffimann - Video lectures with the GeoStats.jl framework.\nEdward Isaaks - Video lectures on variography, Kriging and related concepts.\nJef Caers - Video lectures on two-point and multiple-point methods.","category":"page"},{"location":"resources/education/#Workshop-material","page":"Education","title":"Workshop material","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"UFMG 2024 [Portuguese] - Geociência de Dados na Mineração, UFMG 2024\nJuliaEO 2024 [English] - Global Workshop on Earth Observation, AIRCentre 2024\nUFMG 2023 [Portuguese] - Geociência de Dados na Mineração, UFMG 2023\nJuliaEO 2023 [English] - Global Workshop on Earth Observation, AIRCentre 2023\nCBMina 2021 [Portuguese] - Introução à Geoestatística, CBMina 2021\nUFMG 2021 [Portuguese] - Introdução à Geoestatística, UFMG 2021","category":"page"},{"location":"resources/education/#Related-concepts","page":"Education","title":"Related concepts","text":"","category":"section"},{"location":"resources/education/#GaussianProcesses.jl","page":"Education","title":"GaussianProcesses.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"GaussianProcesses.jl - Gaussian process regression and Simple Kriging are essentially two names for the same concept. The derivation of Kriging estimators, however; does not require distributional assumptions. It is a beautiful coincidence that for multivariate Gaussian distributions, Simple Kriging gives the conditional expectation.","category":"page"},{"location":"resources/education/#KernelFunctions.jl","page":"Education","title":"KernelFunctions.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"KernelFunctions.jl - Spatial structure can be represented in many different forms: covariance, variogram, correlogram, etc. Variograms are more general than covariance kernels according to the intrinsic stationary property. This means that there are variogram models with no covariance counterpart. Furthermore, empirical variograms can be easily estimated from the data (in various directions) with an efficient procedure. GeoStats.jl treats variograms as first-class objects.","category":"page"},{"location":"resources/education/#Interpolations.jl","page":"Education","title":"Interpolations.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"Interpolations.jl - Kriging and spline interpolation have different purposes, yet these two methods are sometimes listed as competing alternatives. Kriging estimation is about minimizing variance (or estimation error), whereas spline interpolation is about deriving smooth estimators for computer visualization. Kriging is a generalization of splines in which one has the freedom to customize geospatial structure based on data. Besides the estimate itself, Kriging also provides the variance map as a function of point patterns.","category":"page"},{"location":"resources/education/#ScikitLearn.jl","page":"Education","title":"ScikitLearn.jl","text":"","category":"section"},{"location":"resources/education/","page":"Education","title":"Education","text":"ScikitLearn.jl - Traditional statistical learning relies on core assumptions that do not hold in geospatial settings (fixed support, i.i.d. samples, ...). Geostatistical learning has been introduced recently as an attempt to push the frontiers of statistical learning with geospatial data.","category":"page"},{"location":"about/license/","page":"License","title":"License","text":"The GeoStats.jl project is licensed under the MIT license:","category":"page"},{"location":"about/license/","page":"License","title":"License","text":"MIT License\n\nCopyright (c) 2015 Júlio Hoffimann and contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","category":"page"},{"location":"domains/#Domains","page":"Domains","title":"Domains","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"domains/#Overview","page":"Domains","title":"Overview","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"A geospatial domain is a (discretized) region in physical space. For example, a collection of rain gauge stations can be represented as a PointSet in the map. Similarly, a collection of states in a given country can be represented as a GeometrySet of polygons.","category":"page"},{"location":"domains/","page":"Domains","title":"Domains","text":"We provide flexible domain types for advanced geospatial workflows via the Meshes.jl submodule. The domains can consist of sets (or \"soups\") of geometries as it is most common in GIS or be actual meshes with topological information.","category":"page"},{"location":"domains/","page":"Domains","title":"Domains","text":"Domain\nMesh","category":"page"},{"location":"domains/#Meshes.Domain","page":"Domains","title":"Meshes.Domain","text":"Domain{Dim,CRS}\n\nA domain is an indexable collection of geometries (e.g. mesh).\n\n\n\n\n\n","category":"type"},{"location":"domains/#Meshes.Mesh","page":"Domains","title":"Meshes.Mesh","text":"Mesh{Dim,CRS,TP}\n\nA mesh embedded in a Dim-dimensional space with given coordinate reference system CRS and topology of type TP.\n\n\n\n\n\n","category":"type"},{"location":"domains/#Examples","page":"Domains","title":"Examples","text":"","category":"section"},{"location":"domains/#PointSet","page":"Domains","title":"PointSet","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"PointSet","category":"page"},{"location":"domains/#Meshes.PointSet","page":"Domains","title":"Meshes.PointSet","text":"PointSet(points)\n\nA set of points (a.k.a. point cloud) representing a Domain.\n\nExamples\n\nAll point sets below are the same and contain two points in R³:\n\njulia> PointSet([Point(1,2,3), Point(4,5,6)])\njulia> PointSet(Point(1,2,3), Point(4,5,6))\njulia> PointSet([(1,2,3), (4,5,6)])\njulia> PointSet((1,2,3), (4,5,6))\n\n\n\n\n\n","category":"type"},{"location":"domains/","page":"Domains","title":"Domains","text":"pset = PointSet(rand(Point{3}, 100))\n\nviz(pset)","category":"page"},{"location":"domains/#GeometrySet","page":"Domains","title":"GeometrySet","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"GeometrySet","category":"page"},{"location":"domains/#Meshes.GeometrySet","page":"Domains","title":"Meshes.GeometrySet","text":"GeometrySet(geometries)\n\nA set of geometries representing a Domain.\n\nExamples\n\nSet containing two balls centered at (0.0, 0.0) and (1.0, 1.0):\n\njulia> GeometrySet([Ball((0.0, 0.0)), Ball((1.0, 1.0))])\n\n\n\n\n\n","category":"type"},{"location":"domains/","page":"Domains","title":"Domains","text":"tria = Triangle((0.0, 0.0), (1.0, 1.0), (0.0, 1.0))\nquad = Quadrangle((1.0, 1.0), (2.0, 1.0), (2.0, 2.0), (1.0, 2.0))\ngset = GeometrySet([tria, quad])\n\nviz(gset, showsegments = true)","category":"page"},{"location":"domains/#CartesianGrid","page":"Domains","title":"CartesianGrid","text":"","category":"section"},{"location":"domains/","page":"Domains","title":"Domains","text":"CartesianGrid","category":"page"},{"location":"domains/#Meshes.CartesianGrid","page":"Domains","title":"Meshes.CartesianGrid","text":"CartesianGrid(dims, origin, spacing)\n\nA Cartesian grid with dimensions dims, lower left corner at origin and cell spacing spacing. The three arguments must have the same length.\n\nCartesianGrid(dims, origin, spacing, offset)\n\nA Cartesian grid with dimensions dims, with lower left corner of element offset at origin and cell spacing spacing.\n\nCartesianGrid(start, finish, dims=dims)\n\nAlternatively, construct a Cartesian grid from a start point (lower left) to a finish point (upper right).\n\nCartesianGrid(start, finish, spacing)\n\nAlternatively, construct a Cartesian grid from a start point to a finish point using a given spacing.\n\nCartesianGrid(dims)\nCartesianGrid(dim1, dim2, ...)\n\nFinally, a Cartesian grid can be constructed by only passing the dimensions dims as a tuple, or by passing each dimension dim1, dim2, ... separately. In this case, the origin and spacing default to (0,0,...) and (1,1,...).\n\nExamples\n\nCreate a 3D grid with 100x100x50 hexahedrons:\n\njulia> CartesianGrid(100, 100, 50)\n\nCreate a 2D grid with 100 x 100 quadrangles and origin at (10.0, 20.0):\n\njulia> CartesianGrid((100, 100), (10.0, 20.0), (1.0, 1.0))\n\nCreate a 1D grid from -1 to 1 with 100 segments:\n\njulia> CartesianGrid((-1.0,), (1.0,), dims=(100,))\n\n\n\n\n\n","category":"type"},{"location":"domains/","page":"Domains","title":"Domains","text":"grid = CartesianGrid(10, 10, 10)\n\nviz(grid, showsegments = true)","category":"page"},{"location":"kriging/#Kriging","page":"Kriging","title":"Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"note: Note\nThis section describes the Kriging models used in the Interpolate and InterpolateNeighbors transforms, which provide options for neighborhood search, change of support, etc.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"A Kriging model has the form:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"hatZ(x_0) = lambda_1 Z(x_1) + lambda_2 Z(x_2) + cdots + lambda_n Z(x_n)quad x_i in R^m lambda_i in R","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with Zcolon R^m times Omega to R a random field.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"This package implements the following Kriging variants:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"Simple Kriging\nOrdinary Kriging\nUniversal Kriging\nExternal Drift Kriging","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"All these variants follow the same interface: an object is first created with a given set of parameters, it is then combined with the data to obtain predictions at new geometries.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The fit function takes care of building the Kriging system and factorizing the LHS with an appropriate decomposition (e.g. Cholesky, LU), and the predict (or predictprob) function performs the estimation for a given variable and geometry.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"All variants work with general Hilbert spaces, meaning that one can interpolate any data type that implements scalar multiplication, vector addition and inner product.","category":"page"},{"location":"kriging/#Simple-Kriging","page":"Kriging","title":"Simple Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In Simple Kriging, the mean mu of the random field is assumed to be constant and known. The resulting linear system is:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"beginbmatrix\ncov(x_1x_1) cov(x_1x_2) cdots cov(x_1x_n) \ncov(x_2x_1) cov(x_2x_2) cdots cov(x_2x_n) \nvdots vdots ddots vdots \ncov(x_nx_1) cov(x_nx_2) cdots cov(x_nx_n)\nendbmatrix\nbeginbmatrix\nlambda_1 \nlambda_2 \nvdots \nlambda_n\nendbmatrix\n=\nbeginbmatrix\ncov(x_1x_0) \ncov(x_2x_0) \nvdots \ncov(x_nx_0)\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"or in matricial form Cl = c. We subtract the given mean from the observations boldsymboly = z - mu 1 and compute the mean and variance at location x_0:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_0) = mu + boldsymboly^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"sigma^2(x_0) = cov(0) - c^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.SimpleKriging","category":"page"},{"location":"kriging/#GeoStatsModels.SimpleKriging","page":"Kriging","title":"GeoStatsModels.SimpleKriging","text":"SimpleKriging(γ, μ)\n\nSimple Kriging with variogram model γ and constant mean μ.\n\nNotes\n\nSimple Kriging requires stationary variograms\n\n\n\n\n\n","category":"type"},{"location":"kriging/#Ordinary-Kriging","page":"Kriging","title":"Ordinary Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In Ordinary Kriging the mean of the random field is assumed to be constant and unknown. The resulting linear system is:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"beginbmatrix\nG 1 \n1^top 0\nendbmatrix\nbeginbmatrix\nl \nnu\nendbmatrix\n=\nbeginbmatrix\ng \n1\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with nu the Lagrange multiplier associated with the constraint 1^top l = 1. The mean and variance at location x_0 are given by:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_0) = z^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"sigma^2(x_0) = beginbmatrix g 1 endbmatrix^top beginbmatrix l nu endbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.OrdinaryKriging","category":"page"},{"location":"kriging/#GeoStatsModels.OrdinaryKriging","page":"Kriging","title":"GeoStatsModels.OrdinaryKriging","text":"OrdinaryKriging(γ)\n\nOrdinary Kriging with variogram model γ.\n\n\n\n\n\n","category":"type"},{"location":"kriging/#Universal-Kriging","page":"Kriging","title":"Universal Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In Universal Kriging, the mean of the random field is assumed to be a polynomial of the geospatial coordinates:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x) = sum_k=1^N_d beta_k f_k(x)","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with N_d monomials f_k of degree up to d. For example, in 2D there are 6 monomials of degree up to 2:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_1x_2) = beta_1 1 + beta_2 x_1 + beta_3 x_2 + beta_4 x_1 x_2 + beta_5 x_1^2 + beta_6 x_2^2","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The choice of the degree d determines the size of the polynomial matrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"F =\nbeginbmatrix\nf_1(x_1) f_2(x_1) cdots f_N_d(x_1) \nf_1(x_2) f_2(x_2) cdots f_N_d(x_2) \nvdots vdots ddots vdots \nf_1(x_n) f_2(x_n) cdots f_N_d(x_n)\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"and polynomial vector f = beginbmatrix f_1(x_0) f_2(x_0) cdots f_N_d(x_0) endbmatrix^top.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The variogram determines the variogram matrix:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"G =\nbeginbmatrix\ngamma(x_1x_1) gamma(x_1x_2) cdots gamma(x_1x_n) \ngamma(x_2x_1) gamma(x_2x_2) cdots gamma(x_2x_n) \nvdots vdots ddots vdots \ngamma(x_nx_1) gamma(x_nx_2) cdots gamma(x_nx_n)\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"and the variogram vector g = beginbmatrix gamma(x_1x_0) gamma(x_2x_0) cdots gamma(x_nx_0) endbmatrix^top.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"The resulting linear system is:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"beginbmatrix\nG F \nF^top boldsymbol0\nendbmatrix\nbeginbmatrix\nl \nboldsymbolnu\nendbmatrix\n=\nbeginbmatrix\ng \nf\nendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"with boldsymbolnu the Lagrange multipliers associated with the universal constraints. The mean and variance at location x_0 are given by:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x_0) = z^top l","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"sigma^2(x_0) = beginbmatrixg fendbmatrix^top beginbmatrixl boldsymbolnuendbmatrix","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.UniversalKriging","category":"page"},{"location":"kriging/#GeoStatsModels.UniversalKriging","page":"Kriging","title":"GeoStatsModels.UniversalKriging","text":"UniversalKriging(γ, degree, dim)\n\nUniversal Kriging with variogram model γ and polynomial degree on a geospatial domain of dimension dim.\n\nNotes\n\nOrdinaryKriging is recovered for 0th degree polynomial\nFor non-polynomial mean, see ExternalDriftKriging\n\n\n\n\n\n","category":"type"},{"location":"kriging/#External-Drift-Kriging","page":"Kriging","title":"External Drift Kriging","text":"","category":"section"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"In External Drift Kriging, the mean of the random field is assumed to be a combination of known smooth functions:","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"mu(x) = sum_k beta_k m_k(x)","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"Differently than Universal Kriging, the functions m_k are not necessarily polynomials of the geospatial coordinates. In practice, they represent a list of variables that is strongly correlated (and co-located) with the variable being estimated.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"External drifts are known to cause numerical instability. Give preference to other Kriging variants if possible.","category":"page"},{"location":"kriging/","page":"Kriging","title":"Kriging","text":"GeoStatsModels.ExternalDriftKriging","category":"page"},{"location":"kriging/#GeoStatsModels.ExternalDriftKriging","page":"Kriging","title":"GeoStatsModels.ExternalDriftKriging","text":"ExternalDriftKriging(γ, drifts)\n\nExternal Drift Kriging with variogram model γ and external drifts functions.\n\nNotes\n\nExternal drift functions should be smooth\nKriging system with external drift is often unstable\nInclude a constant drift (e.g. x->1) for unbiased estimation\nOrdinaryKriging is recovered for drifts = [x->1]\nFor polynomial mean, see UniversalKriging\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#Fields","page":"Fields","title":"Fields","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Base.rand(::GeoStatsProcesses.FieldProcess, ::Domain, ::Any, ::Any)","category":"page"},{"location":"random/fields/#Base.rand-Tuple{GeoStatsProcesses.FieldProcess, Domain, Any, Any}","page":"Fields","title":"Base.rand","text":"rand([rng], process::FieldProcess, domain, data, [nreals], [method]; [parameters])\n\nGenerate one or nreals realizations of the field process with method over the domain with data and optional paramaters. Optionally, specify the random number generator rng and global parameters.\n\nThe data can be a geotable, a pair, or an iterable of pairs of the form var => T, where var is a symbol or string with the variable name and T is the corresponding data type.\n\nParameters\n\npool - Pool of worker processes (default to [myid()])\nthreads - Number of threads (default to cpucores())\nverbose - Show progress and other information (default to true)\n\nExamples\n\njulia> rand(process, domain, geotable, 3)\njulia> rand(process, domain, :z => Float64)\njulia> rand(process, domain, \"z\" => Float64)\njulia> rand(process, domain, [:a => Float64, :b => Float64])\njulia> rand(process, domain, [\"a\" => Float64, \"b\" => Float64])\n\n\n\n\n\n","category":"method"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Realizations are stored in an Ensemble as illustrated in the following example:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Ensemble","category":"page"},{"location":"random/fields/#GeoStatsBase.Ensemble","page":"Fields","title":"GeoStatsBase.Ensemble","text":"Ensemble\n\nAn ensemble of geostatistical realizations from a geostatistical process.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = CartesianGrid(100, 100)\n\n# Gaussian process\nproc = GaussianProcess(GaussianVariogram(range=30.0))\n\n# unconditional simulation\nreal = rand(proc, grid, [:Z => Float64], 100)","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"We can visualize the first two realizations:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"fig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"the mean and variance:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"m, v = mean(real), var(real)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], m.geometry, color = m.Z)\nviz(fig[1,2], v.geometry, color = v.Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"or the 25th and 75th percentiles:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"q25 = quantile(real, 0.25)\nq75 = quantile(real, 0.75)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], q25.geometry, color = q25.Z)\nviz(fig[1,2], q75.geometry, color = q75.Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"All field processes can generate realizations in parallel using multiple Julia processes. Doing so requires using the Distributed standard library, like in the following example:","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using Distributed\n\n# request additional processes\naddprocs(3)\n\n# load code on every single process\n@everywhere using GeoStats\n\n# ------------\n# main script\n# ------------\n\n# domain of interest\ngrid = CartesianGrid(100, 100)\n\n# Gaussian process\nproc = GaussianProcess(GaussianVariogram(range=30.0))\n\n# generate three realizations with three processes\nreal = rand(proc, grid, [:Z => Float64], 3, pool = workers())","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Please consult The ultimate guide to distributed computing in Julia.","category":"page"},{"location":"random/fields/#Builtin","page":"Fields","title":"Builtin","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"The following processes are shipped with the framework.","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"GaussianProcess\nLUMethod\nFFTMethod\nSEQMethod","category":"page"},{"location":"random/fields/#GeoStatsProcesses.GaussianProcess","page":"Fields","title":"GeoStatsProcesses.GaussianProcess","text":"GaussianProcess(variogram=GaussianVariogram(), mean=0.0)\n\nGaussian process with given theoretical variogram and global mean.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#GeoStatsProcesses.LUMethod","page":"Fields","title":"GeoStatsProcesses.LUMethod","text":"LUMethod(; [paramaters])\n\nThe LU Gaussian process method introduced by Alabert 1987. The full covariance matrix is built to include all locations of the process domain, and samples from the multivariate Gaussian are drawn via LU factorization.\n\nParameters\n\nfactorization - Factorization method (default to cholesky)\ncorrelation - Correlation coefficient between two covariates (default to 0)\ninit - Data initialization method (default to NearestInit())\n\nReferences\n\nAlabert 1987. The practice of fast conditional simulations through the LU decomposition of the covariance matrix\nOliver 2003. Gaussian cosimulation: modeling of the cross-covariance\n\nNotes\n\nThe method is only adequate for domains with relatively small number of elements (e.g. 100x100 grids) where it is feasible to factorize the full covariance.\nFor larger domains (e.g. 3D grids), other methods are preferred such as SEQMethod and FFTMethod.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#GeoStatsProcesses.FFTMethod","page":"Fields","title":"GeoStatsProcesses.FFTMethod","text":"FFTMethod(; [paramaters])\n\nThe FFT Gaussian process method introduced by Gutjahr 1997. The covariance function is perturbed in the frequency domain after a fast Fourier transform. White noise is added to the phase of the spectrum, and a realization is produced by an inverse Fourier transform.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - Distance used to find nearest neighbors (default to Euclidean())\n\nReferences\n\nGutjahr 1997. General joint conditional simulations using a fast Fourier transform method\nGómez-Hernández, J. & Srivastava, R. 2021. One Step at a Time: The Origins of Sequential Simulation and Beyond\n\nNotes\n\nThe method is limited to simulations on Cartesian grids, and care must be taken to make sure that the correlation length is small enough compared to the grid size.\nAs a general rule of thumb, avoid correlation lengths greater than 1/3 of the grid.\nThe method is extremely fast, and can be used to generate large 3D realizations.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#GeoStatsProcesses.SEQMethod","page":"Fields","title":"GeoStatsProcesses.SEQMethod","text":"SEQMethod(; [paramaters])\n\nThe sequential process method introduced by Gomez-Hernandez 1993. It traverses all locations of the geospatial domain according to a path, approximates the conditional Gaussian distribution within a neighborhood using simple Kriging, and assigns a value to the center of the neighborhood by sampling from this distribution.\n\nParameters\n\npath - Process path (default to LinearPath())\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 36)\nneighborhood - Search neighborhood (default to :range)\ndistance - Distance used to find nearest neighbors (default to Euclidean())\ninit - Data initialization method (default to NearestInit())\n\nFor each location in the process path, a maximum number of neighbors maxneighbors is used to fit the conditional Gaussian distribution. The neighbors are searched according to a neighborhood.\n\nThe neighborhood can be a MetricBall, the symbol :range or nothing. The symbol :range is converted to MetricBall(range(γ)) where γ is the variogram of the Gaussian process. If neighborhood is nothing, the nearest neighbors are used without additional constraints.\n\nReferences\n\nGomez-Hernandez & Journel 1993. Joint Sequential Simulation of MultiGaussian Fields\n\nNotes\n\nThis method is very sensitive to the various parameters. Care must be taken to make sure that enough neighbors are used in the underlying Kriging model.\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = CartesianGrid(100, 100)\n\n# Gaussian process\nproc = GaussianProcess(GaussianVariogram(range=30.0))\n\n# unconditional simulation\nreal = rand(proc, grid, [:Z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"LindgrenProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.LindgrenProcess","page":"Fields","title":"GeoStatsProcesses.LindgrenProcess","text":"LindgrenProcess(range=1.0, sill=1.0; init=NearestInit())\n\nLindgren process with given range (correlation length) and sill (total variance) as described in Lindgren 2011. Optionally, specify the data initialization method init.\n\nThe process relies relies on a discretization of the Laplace-Beltrami operator on meshes and is adequate for highly curved domains (e.g. surfaces).\n\nReferences\n\nLindgren et al. 2011. An explicit link between Gaussian fields and Gaussian Markov random fields: the stochastic partial differential equation approach\n\n\n\n\n\n","category":"type"},{"location":"random/fields/#External","page":"Fields","title":"External","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"The following processes are available in external packages.","category":"page"},{"location":"random/fields/#ImageQuilting.jl","page":"Fields","title":"ImageQuilting.jl","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"QuiltingProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.QuiltingProcess","page":"Fields","title":"GeoStatsProcesses.QuiltingProcess","text":"QuiltingProcess(trainimg, tilesize; [paramaters])\n\nImage quilting process with training image trainimg and tile size tilesize as described in Hoffimann et al. 2017.\n\nParameters\n\noverlap - Overlap size (default to (1/6, 1/6, ..., 1/6))\npath - Process path (:raster (default), :dilation, or :random)\ninactive - Vector of inactive voxels (i.e. CartesianIndex) in the grid\nsoft - A pair (data,dataTI) of geospatial data objects (default to nothing)\ntol - Initial relaxation tolerance in (0,1] (default to 0.1)\ninit - Data initialization method (default to NearestInit())\n\nReferences\n\nHoffimann et al 2017. Stochastic simulation by image quilting of process-based geological models\nHoffimann et al 2015. Geostatistical modeling of evolving landscapes by means of image quilting\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using ImageQuilting\nusing GeoArtifacts\n\n# domain of interest\ngrid = CartesianGrid(200, 200)\n\n# quilting process\nimg = GeoStatsImages.get(\"Strebelle\")\nproc = QuiltingProcess(img, (62, 62))\n\n# unconditional simulation\nreal = rand(proc, grid, [:facies => Int], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].facies)\nviz(fig[1,2], real[2].geometry, color = real[2].facies)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = CartesianGrid(200, 200)\n\n# quilting process\nimg = GeoStatsImages.get(\"StoneWall\")\nproc = QuiltingProcess(img, (13, 13))\n\n# unconditional simulation\nreal = rand(proc, grid, [:Z => Int], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = domain(img)\n\n# pre-existing observations\nimg = GeoStatsImages.get(\"Strebelle\")\ndata = img |> Sample(20, replace=false)\n\n# quilting process\nproc = QuiltingProcess(img, (30, 30))\n\n# conditional simulation\nreal = rand(proc, grid, data, 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].facies)\nviz(fig[1,2], real[2].geometry, color = real[2].facies)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"Voxels marked with the special symbol NaN are treated as inactive. The algorithm will skip tiles that only contain inactive voxels to save computation and will generate realizations that are consistent with the mask. This is particularly useful with complex 3D models that have large inactive portions.","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"# domain of interest\ngrid = domain(img)\n\n# skip circle at the center\nnx, ny = size(grid)\nr = 100; circle = []\nfor i in 1:nx, j in 1:ny\n if (i-nx÷2)^2 + (j-ny÷2)^2 < r^2\n push!(circle, CartesianIndex(i, j))\n end\nend\n\n# quilting process\nproc = QuiltingProcess(img, (62, 62), inactive = circle)\n\n# unconditional simulation\nreal = rand(proc, grid, [:facies => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].facies)\nviz(fig[1,2], real[2].geometry, color = real[2].facies)\nfig","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"It is possible to incorporate auxiliary variables to guide the selection of patterns from the training image.","category":"page"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using ImageFiltering\n\n# image assumed as ground truth (unknown)\ntruth = GeoStatsImages.get(\"WalkerLakeTruth\")\n\n# training image with similar patterns\nimg = GeoStatsImages.get(\"WalkerLake\")\n\n# forward model (blur filter)\nfunction forward(data)\n img = asarray(data, :Z)\n krn = KernelFactors.IIRGaussian([10,10])\n fwd = imfilter(img, krn)\n georef((; fwd=vec(fwd)), domain(data))\nend\n\n# apply forward model to both images\ndata = forward(truth)\ndataTI = forward(img)\n\nproc = QuiltingProcess(img, (27, 27), soft=(data, dataTI))\n\nreal = rand(proc, domain(truth), [:Z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].Z)\nviz(fig[1,2], real[2].geometry, color = real[2].Z)\nfig","category":"page"},{"location":"random/fields/#TuringPatterns.jl","page":"Fields","title":"TuringPatterns.jl","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"TuringProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.TuringProcess","page":"Fields","title":"GeoStatsProcesses.TuringProcess","text":"TuringProcess(; [paramaters])\n\nTuring process as described in Turing 1952.\n\nParameters\n\nparams - basic parameters (default to nothing)\nblur - blur algorithm (default to nothing)\nedge - edge condition (default to nothing)\niter - number of iterations (default to 100)\n\nReferences\n\nTuring 1952. The chemical basis of morphogenesis\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using TuringPatterns\n\n# domain of interest\ngrid = CartesianGrid(200, 200)\n\n# unconditional simulation\nreal = rand(TuringProcess(), grid, [:z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].z)\nviz(fig[1,2], real[2].geometry, color = real[2].z)\nfig","category":"page"},{"location":"random/fields/#StratiGraphics.jl","page":"Fields","title":"StratiGraphics.jl","text":"","category":"section"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"StrataProcess","category":"page"},{"location":"random/fields/#GeoStatsProcesses.StrataProcess","page":"Fields","title":"GeoStatsProcesses.StrataProcess","text":"StrataProcess(environment; [paramaters])\n\nStrata process with given geological environment as described in Hoffimann 2018.\n\nParameters\n\nstate - Initial geological state\nstack - Stacking scheme (:erosional or :depositional)\nnepochs - Number of epochs (default to 10)\n\nReferences\n\nHoffimann 2018. Morphodynamic analysis and statistical synthesis of geormorphic data\n\n\n\n\n\n","category":"type"},{"location":"random/fields/","page":"Fields","title":"Fields","text":"using StratiGraphics\n\n# domain of interest\ngrid = CartesianGrid(50, 50, 20)\n\n# stratigraphic environment\np = SmoothingProcess()\nT = [0.5 0.5; 0.5 0.5]\nΔ = ExponentialDuration(1.0)\nℰ = Environment([p, p], T, Δ)\n\n# strata simulation\nreal = rand(StrataProcess(ℰ), grid, [:z => Float64], 2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], real[1].geometry, color = real[1].z)\nviz(fig[1,2], real[2].geometry, color = real[2].z)\nfig","category":"page"},{"location":"resources/publications/#Publications","page":"Publications","title":"Publications","text":"","category":"section"},{"location":"resources/publications/","page":"Publications","title":"Publications","text":"Below is a list of publications made possible with this project:","category":"page"},{"location":"resources/publications/","page":"Publications","title":"Publications","text":"Hoffimann, J. 2023. Geospatial Data Science with Julia\nGruchalla et al. 2023. Reevaluating Contour Visualizations for Power Systems Data\nKarsanina, M. & Gerke, K. 2022. Stochastic (re)constructions of non-stationary material structures: Using ensemble averaged correlation functions and non-uniform phase distributions\nSepúlveda et al. 2022. Evaluation of multivariate Gaussian transforms for geostatistical applications\nHoffimann et al. 2022. Modeling Geospatial Uncertainty of Geometallurgical Variables with Bayesian Models and Hilbert-Kriging\nHoffimann et al. 2021. Geostatistical Learning: Challenges and Opportunities\nAsner et al. 2021. Abiotic and Human Drivers of Reef Habitat Complexity Throughout the Main Hawaiian Islands\nAsner et al. 2020. Large-scale mapping of live corals to guide reef conservation\nHoffimann, J. & Zadrozny, B. 2019. Efficient Variography with Partition Variograms\nHoffimann et al. 2019. Morphodynamic Analysis and Statistical Synthesis of Geomorphic Data: Application to a Flume Experiment\nBarfod et al. 2017. Hydrostratigraphic Modeling using Multiple-point Statistics and Airborne Transient Electromagnetic Methods\nHoffimann et al. 2017. Stochastic Simulation by Image Quilting of Process-based Geological Models","category":"page"},{"location":"transforms/#Geospatial-transforms","page":"Transforms","title":"Geospatial transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"We provide a very powerful list of transforms that were designed to work seamlessly with geospatial data. These transforms are implemented in different packages depending on how they interact with geometries.","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"The list of supported transforms is continuously growing. The following code can be used to print an updated list in any project environment:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# packages to print type tree\nusing InteractiveUtils\nusing AbstractTrees\nusing TransformsBase\n\n# packages with transforms\nusing GeoStats\n\n# define the tree of types\nAbstractTrees.children(T::Type) = subtypes(T)\n\n# print all currently available transforms\nAbstractTrees.print_tree(TransformsBase.Transform)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Transforms at the leaves of the tree above should have a docstring with more information on the available options. For example, the documentation of the Select transform is shown below:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Select","category":"page"},{"location":"transforms/#TableTransforms.Select","page":"Transforms","title":"TableTransforms.Select","text":"Select(col₁, col₂, ..., colₙ)\nSelect([col₁, col₂, ..., colₙ])\nSelect((col₁, col₂, ..., colₙ))\n\nThe transform that selects columns col₁, col₂, ..., colₙ.\n\nSelect(col₁ => newcol₁, col₂ => newcol₂, ..., colₙ => newcolₙ)\n\nSelects the columns col₁, col₂, ..., colₙ and rename them to newcol₁, newcol₂, ..., newcolₙ.\n\nSelect(regex)\n\nSelects the columns that match with regex.\n\nExamples\n\nSelect(1, 3, 5)\nSelect([:a, :c, :e])\nSelect((\"a\", \"c\", \"e\"))\nSelect(1 => :x, 3 => :y)\nSelect(:a => :x, :b => :y)\nSelect(\"a\" => \"x\", \"b\" => \"y\")\nSelect(r\"[ace]\")\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Transforms of type FeatureTransform operate on the attribute table, whereas transforms of type GeometricTransform operate on the underlying geospatial domain:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"TableTransforms.FeatureTransform\nMeshes.GeometricTransform","category":"page"},{"location":"transforms/#TableTransforms.FeatureTransform","page":"Transforms","title":"TableTransforms.FeatureTransform","text":"FeatureTransform\n\nA transform that operates on the columns of the table containing features, i.e., simple attributes such as numbers, strings, etc.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#Meshes.GeometricTransform","page":"Transforms","title":"Meshes.GeometricTransform","text":"GeometricTransform\n\nA method to transform the geometry (e.g. coordinates) of objects. See https://en.wikipedia.org/wiki/Geometric_transformation.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Other transforms such as Detrend are defined in terms of both the geospatial domain and the attribute table. All transforms and pipelines implement the following functions:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"TransformsBase.isrevertible\nTransformsBase.isinvertible\nTransformsBase.inverse\nTransformsBase.apply\nTransformsBase.revert\nTransformsBase.reapply","category":"page"},{"location":"transforms/#TransformsBase.isrevertible","page":"Transforms","title":"TransformsBase.isrevertible","text":"isrevertible(transform)\n\nTells whether or not the transform is revertible, i.e. supports a revert function. Defaults to false for new transform types.\n\nTransforms can be revertible and yet don't be invertible. Invertibility is a mathematical concept, whereas revertibility is a computational concept.\n\nSee also isinvertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.isinvertible","page":"Transforms","title":"TransformsBase.isinvertible","text":"isinvertible(transform)\n\nTells whether or not the transform is invertible, i.e. whether it implements the inverse function. Defaults to false for new transform types.\n\nTransforms can be invertible in the mathematical sense, i.e., there exists a one-to-one mapping between input and output spaces.\n\nSee also inverse, isrevertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.inverse","page":"Transforms","title":"TransformsBase.inverse","text":"inverse(transform)\n\nReturns the inverse transform of the transform.\n\nSee also isinvertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.apply","page":"Transforms","title":"TransformsBase.apply","text":"newobject, cache = apply(transform, object)\n\nApply transform on the object. Return the newobject and a cache to revert the transform later.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.revert","page":"Transforms","title":"TransformsBase.revert","text":"object = revert(transform, newobject, cache)\n\nRevert the transform on the newobject using the cache from the corresponding apply call and return the original object. Only defined when the transform isrevertible.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#TransformsBase.reapply","page":"Transforms","title":"TransformsBase.reapply","text":"newobject = reapply(transform, object, cache)\n\nReapply the transform to (a possibly different) object using a cache that was created with a previous apply call. Fallback to apply without using the cache.\n\n\n\n\n\n","category":"function"},{"location":"transforms/#Feature-transforms","page":"Transforms","title":"Feature transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Please check the TableTransforms.jl documentation for an updated list of feature transforms. As an example consider the following features over a Cartesian grid and their statistics:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"using DataFrames\n\n# table of features and domain\ntab = DataFrame(a=rand(1000), b=randn(1000), c=rand(1000))\ndom = CartesianGrid(100, 100)\n\n# georeference table onto domain\nΩ = georef(tab, dom)\n\n# describe features\ndescribe(values(Ω))","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"We can create a pipeline that transforms the features to their normal quantile (or scores):","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"pipe = Quantile()\n\nΩ̄, cache = apply(pipe, Ω)\n\ndescribe(values(Ω̄))","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"We can then revert the transform given any new geospatial data in the transformed sample space:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Ωₒ = revert(pipe, Ω̄, cache)\n\ndescribe(values(Ωₒ))","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"The Learn transform is another important transform from StatsLearnModels.jl:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Learn","category":"page"},{"location":"transforms/#StatsLearnModels.Learn","page":"Transforms","title":"StatsLearnModels.Learn","text":"Learn(train, model, incols => outcols)\n\nFits the statistical learning model using the input columns, selected by incols, and the output columns, selected by outcols, from the train table.\n\nThe column selection can be a single column identifier (index or name), a collection of identifiers or a regular expression (regex).\n\nExamples\n\nLearn(train, model, [1, 2, 3] => \"d\")\nLearn(train, model, [:a, :b, :c] => :d)\nLearn(train, model, [\"a\", \"b\", \"c\"] => 4)\nLearn(train, model, [1, 2, 3] => [:d, :e])\nLearn(train, model, r\"[abc]\" => [\"d\", \"e\"])\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"For more details, consider watching our JuliaCon2021 talk:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"

\n\n

","category":"page"},{"location":"transforms/#Geometric-transforms","page":"Transforms","title":"Geometric transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Please check the Meshes.jl documentation for an updated list of geometric transforms. As an example consider the rotation of geospatial data over a Cartesian grid:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# geospatial domain\nΩ = georef((Z=rand(10, 10),))\n\n# apply geometric transform\nΩr = Ω |> Rotate(Angle2d(π/4))\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.Z)\nviz(fig[1,2], Ωr.geometry, color = Ωr.Z)\nfig","category":"page"},{"location":"transforms/#Geostatistical-transforms","page":"Transforms","title":"Geostatistical transforms","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Bellow is the current list of transforms that operate on both the geometries and features of geospatial data. They are implemented in the GeoStatsBase.jl package.","category":"page"},{"location":"transforms/#UniqueCoords","page":"Transforms","title":"UniqueCoords","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"UniqueCoords","category":"page"},{"location":"transforms/#GeoStatsTransforms.UniqueCoords","page":"Transforms","title":"GeoStatsTransforms.UniqueCoords","text":"UniqueCoords(var₁ => agg₁, var₂ => agg₂, ..., varₙ => aggₙ)\n\nRetain locations in data with unique coordinates.\n\nDuplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.\n\nExamples\n\nUniqueCoords(1 => last, 2 => maximum)\nUniqueCoords(:a => first, :b => minimum)\nUniqueCoords(\"a\" => last, \"b\" => maximum)\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# point set with repeated points\np = rand(Point{2}, 50)\nΩ = georef((Z=rand(100),), [p; p])","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# discard repeated points\n𝒰 = Ω |> UniqueCoords()","category":"page"},{"location":"transforms/#Detrend","page":"Transforms","title":"Detrend","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Detrend","category":"page"},{"location":"transforms/#GeoStatsTransforms.Detrend","page":"Transforms","title":"GeoStatsTransforms.Detrend","text":"Detrend(col₁, col₂, ..., colₙ; degree=1)\nDetrend([col₁, col₂, ..., colₙ]; degree=1)\nDetrend((col₁, col₂, ..., colₙ); degree=1)\n\nThe transform that detrends columns col₁, col₂, ..., colₙ with a polynomial of given degree.\n\nDetrend(regex; degree=1)\n\nDetrends the columns that match with regex.\n\nExamples\n\nDetrend(1, 3, 5)\nDetrend([:a, :c, :e])\nDetrend((\"a\", \"c\", \"e\"))\nDetrend(r\"[ace]\", degree=2)\nDetrend(:)\n\nReferences\n\nMenafoglio, A., Secchi, P. 2013. A Universal Kriging predictor for spatially dependent functional data of a Hilbert Space\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# quadratic trend + random noise\nr = range(-1, stop=1, length=100)\nμ = [x^2 + y^2 for x in r, y in r]\nϵ = 0.1rand(100, 100)\nΩ = georef((Z=μ+ϵ,))\n\n# detrend and obtain noise component\n𝒩 = Ω |> Detrend(:Z, degree=2)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.Z)\nviz(fig[1,2], 𝒩.geometry, color = 𝒩.Z)\nfig","category":"page"},{"location":"transforms/#Potrace","page":"Transforms","title":"Potrace","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Potrace","category":"page"},{"location":"transforms/#GeoStatsTransforms.Potrace","page":"Transforms","title":"GeoStatsTransforms.Potrace","text":"Potrace(mask; [ϵ])\nPotrace(mask, var₁ => agg₁, ..., varₙ => aggₙ; [ϵ])\n\nTrace polygons on 2D image data with Selinger's Potrace algorithm.\n\nThe categories stored in column mask are converted into binary masks, which are then traced into multi-polygons. When provided, the option ϵ is forwarded to Selinger's simplification algorithm.\n\nDuplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.\n\nExamples\n\nPotrace(:mask, ϵ=0.1)\nPotrace(1, 1 => last, 2 => maximum)\nPotrace(:mask, :a => first, :b => minimum)\nPotrace(\"mask\", \"a\" => last, \"b\" => maximum)\n\nReferences\n\nSelinger, P. 2003. Potrace: A polygon-based tracing algorithm\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"# continuous feature\nZ = [sin(i/10) + sin(j/10) for i in 1:100, j in 1:100]\n\n# binary mask\nM = Z .> 0\n\n# georeference data\nΩ = georef((Z=Z, M=M))\n\n# trace polygons using mask\n𝒯 = Ω |> Potrace(:M)\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.Z)\nviz(fig[1,2], 𝒯.geometry, color = 𝒯.Z)\nfig","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒯.geometry","category":"page"},{"location":"transforms/#Rasterize","page":"Transforms","title":"Rasterize","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Rasterize","category":"page"},{"location":"transforms/#GeoStatsTransforms.Rasterize","page":"Transforms","title":"GeoStatsTransforms.Rasterize","text":"Rasterize(grid)\nRasterize(grid, var₁ => agg₁, ..., varₙ => aggₙ)\n\nRasterize geometries within specified grid.\n\nRasterize(nx, ny)\nRasterize(nx, ny, var₁ => agg₁, ..., varₙ => aggₙ)\n\nAlternatively, use the grid with size nx by ny obtained with discretization of the bounding box.\n\nDuplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.\n\nExamples\n\ngrid = CartesianGrid(10, 10)\nRasterize(grid)\nRasterize(10, 10)\nRasterize(grid, 1 => last, 2 => maximum)\nRasterize(10, 10, 1 => last, 2 => maximum)\nRasterize(grid, :a => first, :b => minimum)\nRasterize(10, 10, :a => first, :b => minimum)\nRasterize(grid, \"a\" => last, \"b\" => maximum)\nRasterize(10, 10, \"a\" => last, \"b\" => maximum)\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"A = [1, 2, 3, 4, 5]\nB = [1.1, 2.2, 3.3, 4.4, 5.5]\np1 = PolyArea((2, 0), (6, 2), (2, 2))\np2 = PolyArea((0, 6), (3, 8), (0, 10))\np3 = PolyArea((3, 6), (9, 6), (9, 9), (6, 9))\np4 = PolyArea((7, 0), (10, 0), (10, 4), (7, 4))\np5 = PolyArea((1, 3), (5, 3), (6, 6), (3, 8), (0, 6))\ngt = georef((; A, B), [p1, p2, p3, p4, p5])\n\nnt = gt |> Rasterize(20, 20)\n\nviz(nt.geometry, color = nt.A)","category":"page"},{"location":"transforms/#Clustering","page":"Transforms","title":"Clustering","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Unlike traditional clustering algorithms in machine learning, geostatistical clustering (a.k.a. domaining) algorithms consider both the features and the geospatial coordinates of the data.","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Consider the following data as an example:","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Ω = georef((Z=[10sin(i/10) + j for i in 1:4:100, j in 1:4:100],))\n\nviz(Ω.geometry, color = Ω.Z)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"GHC","category":"page"},{"location":"transforms/#GeoStatsTransforms.GHC","page":"Transforms","title":"GeoStatsTransforms.GHC","text":"GHC(k, λ; kern=:epanechnikov, link=:ward, as=:CLUSTER)\n\nA transform for partitioning geospatial data into k clusters according to a range λ using Geostatistical Hierarchical Clustering (GHC). The larger the range the more connected are nearby samples.\n\nParameters\n\nk - Approximate number of clusters\nλ - Approximate range of kernel function in length units\nkern - Kernel function (:uniform, :triangular or :epanechnikov)\nlink - Linkage function (:single, :average, :complete, :ward or :ward_presquared)\nas - Cluster column name\n\nReferences\n\nFouedjio, F. 2016. A hierarchical clustering method for multivariate geostatistical data\n\nNotes\n\nThe range parameter controls the sparsity pattern of the pairwise distances, which can greatly affect the computational performance of the GHC algorithm. We recommend choosing a range that is small enough to connect nearby samples. For example, clustering data over a 100x100 Cartesian grid with unit spacing is possible with λ=1.0 or λ=2.0 but the problem starts to become computationally unfeasible around λ=10.0 due to the density of points.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒞 = Ω |> GHC(20, 1.0)\n\nviz(𝒞.geometry, color = 𝒞.CLUSTER)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"GSC","category":"page"},{"location":"transforms/#GeoStatsTransforms.GSC","page":"Transforms","title":"GeoStatsTransforms.GSC","text":"GSC(k, m; σ=1.0, tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)\n\nA transform for partitioning geospatial data into k clusters using Geostatistical Spectral Clustering (GSC).\n\nParameters\n\nk - Desired number of clusters\nm - Multiplicative factor for adjacent weights\nσ - Standard deviation for exponential model (default to 1.0)\ntol - Tolerance of k-means algorithm (default to 1e-4)\nmaxiter - Maximum number of iterations (default to 10)\nweights - Dictionary with weights for each attribute (default to nothing)\nas - Cluster column name\n\nReferences\n\nRomary et al. 2015. Unsupervised classification of multivariate geostatistical data: Two algorithms\n\nNotes\n\nThe algorithm implemented here is slightly different than the algorithm\n\ndescribed in Romary et al. 2015. Instead of setting Wᵢⱼ = 0 when i <-/-> j, we simply magnify the weight by a multiplicative factor Wᵢⱼ *= m when i <–> j. This leads to dense matrices but also better results in practice.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒞 = Ω |> GSC(50, 2.0)\n\nviz(𝒞.geometry, color = 𝒞.CLUSTER)","category":"page"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"SLIC","category":"page"},{"location":"transforms/#GeoStatsTransforms.SLIC","page":"Transforms","title":"GeoStatsTransforms.SLIC","text":"SLIC(k, m; tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)\n\nA transform for clustering geospatial data into approximately k clusters using Simple Linear Iterative Clustering (SLIC). The transform produces clusters of samples that are spatially connected based on a distance dₛ and that, at the same time, are similar in terms of vars with distance dᵥ. The tradeoff is controlled with a hyperparameter parameter m in an additive model dₜ = √(dᵥ² + m²(dₛ/s)²).\n\nParameters\n\nk - Approximate number of clusters\nm - Hyperparameter of SLIC model\ntol - Tolerance of k-means algorithm (default to 1e-4)\nmaxiter - Maximum number of iterations (default to 10)\nweights - Dictionary with weights for each attribute (default to nothing)\nas - Cluster column name\n\nReferences\n\nAchanta et al. 2011. SLIC superpixels compared to state-of-the-art superpixel methods\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"𝒞 = Ω |> SLIC(50, 0.01)\n\nviz(𝒞.geometry, color = 𝒞.CLUSTER)","category":"page"},{"location":"transforms/#Interpolate","page":"Transforms","title":"Interpolate","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Interpolate\nInterpolateNeighbors\nInterpolateMissing\nInterpolateNaN","category":"page"},{"location":"transforms/#GeoStatsTransforms.Interpolate","page":"Transforms","title":"GeoStatsTransforms.Interpolate","text":"Interpolate(domain, vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolate([g₁, g₂, ..., gₙ], vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on given domain or vector of geometries [g₁, g₂, ..., gₙ], using geostatistical models model₁, ..., modelₙ for variables vars₁, ..., varsₙ.\n\nInterpolate(domain, model=NN(); [parameters])\nInterpolate([g₁, g₂, ..., gₙ], model=NN(); [parameters])\n\nInterpolate geospatial data on given domain or vector of geometries [g₁, g₂, ..., gₙ], using geostatistical model for all variables.\n\nParameters\n\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nSee also InterpolateNeighbors, InterpolateMissing, InterpolateNaN.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#GeoStatsTransforms.InterpolateNeighbors","page":"Transforms","title":"GeoStatsTransforms.InterpolateNeighbors","text":"InterpolateNeighbors(domain, vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolateNeighbors([g₁, g₂, ..., gₙ], vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on given domain or set of geometries g₁, g₂, ..., gₙ, using geostatistical models model₁, ..., modelₙ for variables vars₁, ..., varsₙ.\n\nInterpolateNeighbors(domain, model=NN(); [parameters])\nInterpolateNeighbors([g₁, g₂, ..., gₙ], model=NN(); [parameters])\n\nInterpolate geospatial data on given domain or set of geometries g₁, g₂, ..., gₙ, using geostatistical model for all variables.\n\nUnlike Interpolate, this transform uses neighbor search methods to fit geostatistical models at each interpolation location with a reduced number of measurements.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - A distance defined in Distances.jl (default to Euclidean())\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nThe maxneighbors parameter can be used to perform interpolation with a subset of measurements per prediction location. If maxneighbors is not provided, then all measurements are used.\n\nTwo neighborhood search methods are available:\n\nIf a neighborhood is provided, local prediction is performed by sliding the neighborhood in the domain.\nIf a neighborhood is not provided, the prediction is performed using maxneighbors nearest neighbors according to distance.\n\nSee also Interpolate, InterpolateMissing, InterpolateNaN.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#GeoStatsTransforms.InterpolateMissing","page":"Transforms","title":"GeoStatsTransforms.InterpolateMissing","text":"InterpolateMissing(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolateMissing(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical models model₁, ..., modelₙ and non-missing values of the variables vars₁, ..., varsₙ.\n\nInterpolateMissing(model=NN(); [parameters])\nInterpolateMissing(model=NN(); [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical model and non-missing values of all variables.\n\nJust like InterpolateNeighbors, this transform uses neighbor search methods to fit geostatistical models at each interpolation location with a reduced number of measurements.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - A distance defined in Distances.jl (default to Euclidean())\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nThe maxneighbors parameter can be used to perform interpolation with a subset of measurements per prediction location. If maxneighbors is not provided, then all measurements are used.\n\nTwo neighborhood search methods are available:\n\nIf a neighborhood is provided, local prediction is performed by sliding the neighborhood in the domain.\nIf a neighborhood is not provided, the prediction is performed using maxneighbors nearest neighbors according to distance.\n\nSee also InterpolateNaN, InterpolateNeighbors, Interpolate.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#GeoStatsTransforms.InterpolateNaN","page":"Transforms","title":"GeoStatsTransforms.InterpolateNaN","text":"InterpolateNaN(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\nInterpolateNaN(vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical models model₁, ..., modelₙ and non-NaN values of the variables vars₁, ..., varsₙ.\n\nInterpolateNaN(model=NN(); [parameters])\nInterpolateNaN(model=NN(); [parameters])\n\nInterpolate geospatial data on its own domain, using geostatistical model and non-NaN values of all variables.\n\nJust like InterpolateNeighbors, this transform uses neighbor search methods to fit geostatistical models at each interpolation location with a reduced number of measurements.\n\nParameters\n\nminneighbors - Minimum number of neighbors (default to 1)\nmaxneighbors - Maximum number of neighbors (default to 10)\nneighborhood - Search neighborhood (default to nothing)\ndistance - A distance defined in Distances.jl (default to Euclidean())\npoint - Perform interpolation on point support (default to true)\nprob - Perform probabilistic interpolation (default to false)\n\nThe maxneighbors parameter can be used to perform interpolation with a subset of measurements per prediction location. If maxneighbors is not provided, then all measurements are used.\n\nTwo neighborhood search methods are available:\n\nIf a neighborhood is provided, local prediction is performed by sliding the neighborhood in the domain.\nIf a neighborhood is not provided, the prediction is performed using maxneighbors nearest neighbors according to distance.\n\nSee also InterpolateMissing, InterpolateNeighbors, Interpolate.\n\n\n\n\n\n","category":"type"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"table = (; Z=[1.,0.,1.])\ncoord = [(25.,25.), (50.,75.), (75.,50.)]\ngeotable = georef(table, coord)\n\ngrid = CartesianGrid(100, 100)\n\nmodel = Kriging(GaussianVariogram(range=35.))\n\ninterp = geotable |> Interpolate(grid, model)\n\nviz(interp.geometry, color = interp.Z)","category":"page"},{"location":"transforms/#Simulate","page":"Transforms","title":"Simulate","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"Simulate","category":"page"},{"location":"transforms/#GeoStatsTransforms.Simulate","page":"Transforms","title":"GeoStatsTransforms.Simulate","text":"Simulate(domain, vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\nSimulate(domain, nreals, vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\nSimulate([g₁, g₂, ..., gₙ], vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\nSimulate([g₁, g₂, ..., gₙ], nreals, vars₁ => process₁, ..., varsₙ => processₙ; [parameters])\n\nSimulate nreals realizations of variables varsᵢ with geostatistical process processᵢ over given domain or vector of geometries [g₁, g₂, ..., gₙ].\n\nThe parameters are forwarded to the rand method of the geostatistical processes.\n\n\n\n\n\n","category":"type"},{"location":"transforms/#CookieCutter","page":"Transforms","title":"CookieCutter","text":"","category":"section"},{"location":"transforms/","page":"Transforms","title":"Transforms","text":"CookieCutter","category":"page"},{"location":"transforms/#GeoStatsTransforms.CookieCutter","page":"Transforms","title":"GeoStatsTransforms.CookieCutter","text":"CookieCutter(domain, parent => process, var₁ => procmap₁, ..., varₙ => procmapₙ; [parameters])\nCookieCutter(domain, nreals, parent => process, var₁ => procmap₁, ..., varₙ => procmapₙ; [parameters])\n\nSimulate nreals realizations of variable parent with geostatistical process process, and each child variable varsᵢ with process map procmapᵢ, over given domain.\n\nThe process map must be an iterable of pairs of the form: value => process. Each process in the map is related to a value of the parent realization, therefore the values of the child variables will be chosen according to the values of the corresponding parent realization.\n\nThe parameters are forwarded to the rand method of the geostatistical processes.\n\nExamples\n\nparent = QuiltingProcess(trainimg, (30, 30))\nchild0 = GaussianProcess(SphericalVariogram(range=20.0, sill=0.2))\nchild1 = GaussianProcess(SphericalVariogram(MetricBall((200.0, 20.0))))\ntransform = CookieCutter(domain, :parent => parent, :child => [0 => child0, 1 => child1])\n\n\n\n\n\n","category":"type"},{"location":"declustering/#Declustering","page":"Declustering","title":"Declustering","text":"","category":"section"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"Declustered statistics are statistics that make use of geospatial coordinates in an attempt to correct potential sampling bias:","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"

\n\n

","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"The following statistics have geospatial semantics:","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"mean(::AbstractGeoTable, ::Any)\nvar(::AbstractGeoTable, ::Any)\nquantile(::AbstractGeoTable, ::Any, ::Any)","category":"page"},{"location":"declustering/#Statistics.mean-Tuple{AbstractGeoTable, Any}","page":"Declustering","title":"Statistics.mean","text":"mean(data, v)\nmean(data, v, s)\n\nDeclustered mean of geospatial data. Optionally, specify the variable v and the block side s.\n\n\n\n\n\n","category":"method"},{"location":"declustering/#Statistics.var-Tuple{AbstractGeoTable, Any}","page":"Declustering","title":"Statistics.var","text":"var(data, v)\nvar(data, v, s)\n\nDeclustered variance of geospatial data. Optionally, specify the variable v and the block side s.\n\n\n\n\n\n","category":"method"},{"location":"declustering/#Statistics.quantile-Tuple{AbstractGeoTable, Any, Any}","page":"Declustering","title":"Statistics.quantile","text":"quantile(data, v, p)\nquantile(data, v, p, s)\n\nDeclustered quantile of geospatial data at probability p. Optionally, specify the variable v and the block side s.\n\n\n\n\n\n","category":"method"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"A histogram with geospatial semantics is also available where the heights of the bins are adjusted based on the coordinates of the samples:","category":"page"},{"location":"declustering/","page":"Declustering","title":"Declustering","text":"EmpiricalHistogram","category":"page"},{"location":"declustering/#GeoStatsBase.EmpiricalHistogram","page":"Declustering","title":"GeoStatsBase.EmpiricalHistogram","text":"EmpiricalHistogram(sdata, var, [s]; kwargs...)\n\nSpatial histogram of variable var in spatial data sdata. Optionally, specify the block side s and the keyword arguments kwargs for the fit(Histogram, ...) call.\n\n\n\n\n\n","category":"type"},{"location":"variography/fitting/#Fitting-variograms","page":"Fitting variograms","title":"Fitting variograms","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"using GeoStats # hide\nimport CairoMakie as Mke # hide","category":"page"},{"location":"variography/fitting/#Overview","page":"Fitting variograms","title":"Overview","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"Fitting theoretical variograms to empirical observations is an important modeling step to ensure valid mathematical models of geospatial continuity. Given an empirical variogram, the fit function can be used to perform the fit:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"GeoStatsFunctions.fit(::Type{Variogram}, ::EmpiricalVariogram, ::VariogramFitAlgo)","category":"page"},{"location":"variography/fitting/#GeoStatsFunctions.fit-Tuple{Type{Variogram}, EmpiricalVariogram, VariogramFitAlgo}","page":"Fitting variograms","title":"GeoStatsFunctions.fit","text":"fit(V, g, algo=WeightedLeastSquares(); range=nothing, sill=nothing, nugget=nothing)\n\nFit theoretical variogram type V to empirical variogram g using algorithm algo.\n\nOptionally fix range, sill or nugget by passing them as keyword arguments, or set their maximum value with maxrange, maxsill or maxnugget.\n\nExamples\n\njulia> fit(SphericalVariogram, g)\njulia> fit(ExponentialVariogram, g)\njulia> fit(ExponentialVariogram, g, sill=1.0)\njulia> fit(ExponentialVariogram, g, maxsill=1.0)\njulia> fit(GaussianVariogram, g, WeightedLeastSquares())\n\n\n\n\n\nfit(Vs, g, algo=WeightedLeastSquares(); kwargs...)\n\nFit theoretical variogram types Vs to empirical variogram g using algorithm algo and return the one with minimum error.\n\nExamples\n\njulia> fit([SphericalVariogram, ExponentialVariogram], g)\n\n\n\n\n\nfit(Variogram, g, algo=WeightedLeastSquares(); kwargs...)\n\nFit all \"fittable\" subtypes of Variogram to empirical variogram g using algorithm algo and return the one with minimum error.\n\nExamples\n\njulia> fit(Variogram, g)\njulia> fit(Variogram, g, WeightedLeastSquares())\n\nSee also GeoStatsFunctions.fittable().\n\n\n\n\n\n","category":"method"},{"location":"variography/fitting/#Example","page":"Fitting variograms","title":"Example","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"# sinusoidal data\n𝒟 = georef((Z=[sin(i/2) + sin(j/2) for i in 1:50, j in 1:50],))\n\n# empirical variogram\ng = EmpiricalVariogram(𝒟, :Z, maxlag = 25.)\n\nMke.plot(g)","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"We can fit specific models to the empirical variogram:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"γ = GeoStatsFunctions.fit(SineHoleVariogram, g)\n\nMke.plot(g)\nMke.plot!(γ, maxlag = 25.)\nMke.current_figure()","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"or let the framework find the model with minimum error:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"γ = GeoStatsFunctions.fit(Variogram, g)\n\nMke.plot(g)\nMke.plot!(γ, maxlag = 25.)\nMke.current_figure()","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"which should be a SineHoleVariogram given that the synthetic data of this example is sinusoidal.","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"Optionally, we can specify a weighting function to give different weights to the lags:","category":"page"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"γ = GeoStatsFunctions.fit(SineHoleVariogram, g, h -> 1 / h^2)\n\nMke.plot(g)\nMke.plot!(γ, maxlag = 25.)\nMke.current_figure()","category":"page"},{"location":"variography/fitting/#Methods","page":"Fitting variograms","title":"Methods","text":"","category":"section"},{"location":"variography/fitting/#Weighted-least-squares","page":"Fitting variograms","title":"Weighted least squares","text":"","category":"section"},{"location":"variography/fitting/","page":"Fitting variograms","title":"Fitting variograms","text":"WeightedLeastSquares","category":"page"},{"location":"variography/fitting/#GeoStatsFunctions.WeightedLeastSquares","page":"Fitting variograms","title":"GeoStatsFunctions.WeightedLeastSquares","text":"WeightedLeastSquares()\nWeightedLeastSquares(w)\n\nFit theoretical variogram using weighted least squares with weighting function w (e.g. h -> 1/h). If no weighting function is provided, bin counts of empirical variogram are normalized and used as weights.\n\n\n\n\n\n","category":"type"},{"location":"quickstart/#Quickstart","page":"Quickstart","title":"Quickstart","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"A geostatistical workflow often consists of four steps:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Definition of geospatial data\nManipulation of geospatial data\nGeostatistical modeling\nScientific visualization","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"In this section, we walk through these steps to illustrate some of the features of the project. In the case of geostatistical modeling, we will specifically explore geostatistical learning models. If you prefer learning from video, check out the recording of our JuliaEO 2023 workshop:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"

\n\n

","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We assume that the following packages are loaded throughout the code examples:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"using GeoStats\nimport CairoMakie as Mke","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The GeoStats.jl package exports the full stack for geospatial data science and geostatistical modeling. The CairoMakie.jl package is one of the possible visualization backends from the Makie.jl project.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"If you are new to Julia and have never heard of Makie.jl before, here are a few tips to help you choose between the different backends:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"WGLMakie.jl is the preferred backend for interactive visualization on the web browser. It integrates well with Pluto.jl notebooks and other web-based applications.\nGLMakie.jl is the preferred backend for interactive high-performance visualization. It leverages native graphical resources and doesn't require a web browser to function.\nCairoMakie.jl is the preferred backend for publication-quality static visualization. It requires less computing power and is therefore recommended for those users with modest laptops.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"note: Note\nWe recommend importing the Makie.jl backend as Mke to avoid polluting the Julia session with names from the visualization stack.","category":"page"},{"location":"quickstart/#Loading/creating-data","page":"Quickstart","title":"Loading/creating data","text":"","category":"section"},{"location":"quickstart/#Loading-data","page":"Quickstart","title":"Loading data","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The Julia ecosystem for loading geospatial data is comprised of several low-level packages such as Shapefile.jl and GeoJSON.jl, which define their own very basic geometry types. Instead of requesting users to learn the so called GeoInterface.jl to handle these types, we provide the high-level GeoIO.jl package to load any file with geospatial data into well-tested geometries from the Meshes.jl submodule:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"using GeoIO\n\nzone = GeoIO.load(\"data/zone.shp\")\npath = GeoIO.load(\"data/path.shp\")\n\nviz(zone.geometry)\nviz!(path.geometry, color = :gray90)\nMke.current_figure()","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Various functions are defined over these geometries, for instance:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"sum(area, zone.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"sum(perimeter, zone.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Please check the Meshes.jl documentation for more details.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"note: Note\nWe highly recommend using Meshes.jl geometries in geospatial workflows as they were carefully designed to accomodate advanced features of the GeoStats.jl framework. Any other geometry type will likely fail with our geostatistical algorithms and pipelines.","category":"page"},{"location":"quickstart/#Creating-data","page":"Quickstart","title":"Creating data","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Geospatial data can be derived from other Julia variables. For example, given a Julia array, which is not attached to any coordinate system, we can georeference the array using the georef function:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Z = [10sin(i/10) + 2j for i in 1:50, j in 1:50]\n\nΩ = georef((Z=Z,))","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Default coordinates are assigned based on the size of the array, and different configurations can be obtained with different methods (see Data).","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Geospatial data can be visualized with the viz recipe function:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"viz(Ω.geometry, color = Ω.Z)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Alternatively, we provide a basic scientific viewer to visualize all viewable variables in the data with a colorbar and other interactive elements (see Visualization):","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"viewer(Ω)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"note: Note\nJulia supports unicode symbols with LaTeX syntax. We can type \\Omega and press TAB to get the symbol Ω in the example above. This autocompletion works in various text editors, including the VSCode editor with the Julia extension.","category":"page"},{"location":"quickstart/#Manipulating-data","page":"Quickstart","title":"Manipulating data","text":"","category":"section"},{"location":"quickstart/#Table-interface","page":"Quickstart","title":"Table interface","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Our geospatial data implements the Tables.jl interface, which means that they can be accessed as if they were tables with samples in the rows and variables in the columns. In this case, a special column named geometry is created on the fly, row by row, containing Meshes.jl geometries.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"For those familiar with the productive DataFrames.jl interface, there is nothing new:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω[1,:]","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω[1,:geometry]","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω.Z","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"However, notice that our implementation performs some clever optimizations behind the scenes to avoid expensive creation of geometries:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω.geometry","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We can always retrieve the table of attributes (or features) with the function values and the underlying geospatial domain with the function domain. This can be useful for writing algorithms that are type-stable and depend purely on the feature values:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"values(Ω)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"or on the geometries:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"domain(Ω)","category":"page"},{"location":"quickstart/#Geospatial-transforms","page":"Quickstart","title":"Geospatial transforms","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"It is easy to design advanced geospatial pipelines that operate on both the table of features and the underlying geospatial domain:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"# pipeline with table transforms\npipe = Quantile() → StdCoords()\n\n# feed geospatial data to pipeline\nΩ̂ = pipe(Ω)\n\n# plot distribution before and after pipeline\nfig = Mke.Figure(size = (800, 400))\nMke.hist(fig[1,1], Ω.Z, color = :gray)\nMke.hist(fig[2,1], Ω̂.Z, color = :gray)\nfig","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Coordinates before pipeline:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"boundingbox(Ω.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"and after pipeline:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"boundingbox(Ω̂.geometry)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"These pipelines are revertible meaning that we can transform the data, perform geostatistical modeling, and revert the pipelines to obtain estimates in the original sample space (see Transforms).","category":"page"},{"location":"quickstart/#Geospatial-queries","page":"Quickstart","title":"Geospatial queries","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We provide three macros @groupby, @transform and @combine for powerful geospatial split-apply-combine patterns, as well as the function geojoin for advanced geospatial joins.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"@transform(Ω, :W = 2 * :Z * area(:geometry))","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"These are very useful for geospatial data science as they hide the complexity of the geometry column. For more information, check the Queries section of the documentation.","category":"page"},{"location":"quickstart/#Geostatistical-modeling","page":"Quickstart","title":"Geostatistical modeling","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Having defined the geospatial data objects, we proceed and define the geostatistical learning model. Let's assume that we have geopatial data with some variable that we want to predict in a supervised learning setting. We load the data from a CSV file, and inspect the available columns:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"using CSV\nusing DataFrames\n\ntable = CSV.File(\"data/agriculture.csv\") |> DataFrame\n\nfirst(table, 5)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Columns band1, band2, ..., band4 represent four satellite bands for different locations (x, y) in this region. The column crop has the crop type for each location that was labeled manually with the purpose of fitting a learning model.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We can now georeference the table and plot some of the variables:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω = georef(table, (:x, :y))\n\nfig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω.geometry, color = Ω.band4)\nviz(fig[1,2], Ω.geometry, color = Ω.crop)\nfig","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Similar to a generic statistical learning workflow, we split the data into \"train\" and \"test\" sets. The main difference here is that our geospatial geosplit function accepts a separating plane specified by its normal direction (1,-1):","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ωs, Ωt = geosplit(Ω, 0.2, (1.0, -1.0))\n\nviz(Ωs.geometry)\nviz!(Ωt.geometry, color = :gray90)\nMke.current_figure()","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We can visualize the domain of the \"train\" (or source) set Ωs in blue, and the domain of the \"test\" (or target) set Ωt in gray. We reserved 20% of the samples to Ωs and 80% to Ωt. Internally, this geospatial geosplit function is implemented in terms of efficient geospatial partitions.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Let's define our geostatistical learning model to predict the crop type based on the four satellite bands. We will use the DecisionTreeClassifier model, which is suitable for the task we want to perform. Any model from the StatsLeanModels.jl model is supported, including all models from ScikitLearn.jl:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"feats = [:band1, :band2, :band3, :band4]\nlabel = :crop\n\nmodel = DecisionTreeClassifier()","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We will fit the model in Ωs where the features and labels are available and predict in Ωt where the features are available. The Learn transform automatically fits the model to the data:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"learn = Learn(Ωs, model, feats => label)","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The transform can be called with new data to generate predictions:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Ω̂t = learn(Ωt)","category":"page"},{"location":"quickstart/#Scientific-visualization","page":"Quickstart","title":"Scientific visualization","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"We note that the prediction of a geostatistical learning model is a geospatial data object, and we can inspect it with the same methods already described above. This also means that we can visualize the prediction directly, side by side with the true label in this synthetic example:","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"fig = Mke.Figure(size = (800, 400))\nviz(fig[1,1], Ω̂t.geometry, color = Ω̂t.crop)\nviz(fig[1,2], Ωt.geometry, color = Ωt.crop)\nfig","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"With this example we conclude the basic workflow. To get familiar with other features of the project, please check the the reference guide.","category":"page"},{"location":"resources/ecosystem/#Ecosystem","page":"Ecosystem","title":"Ecosystem","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"The Julia ecosystem for geospatial modeling is maturing very quickly as the result of multiple initiatives such as JuliaEarth, JuliaClimate, and JuliaGeo. Each of these initiatives is associated with a different set of challenges that ultimatively determine the types of packages that are being developed in the corresponding GitHub organizations. In this section, we try to clarify what is available to first-time users of the language.","category":"page"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"\n\n","category":"page"},{"location":"resources/ecosystem/#JuliaEarth","page":"Ecosystem","title":"JuliaEarth","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"Originally created to host the GeoStats.jl framework, this initiative is primarily concerned with geospatial data science and geostatistical modeling. Due to the various applications in the subsurface of the Earth, most of our Julia packages were developed to work efficiently with both 2D and 3D geometries.","category":"page"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"Unlike other initiatives, JuliaEarth is 100% Julia by design. This means that we do not rely on external libraries such as GDAL or Proj4 for geospatial work.","category":"page"},{"location":"resources/ecosystem/#JuliaClimate","page":"Ecosystem","title":"JuliaClimate","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"The most recent of the three initiatives, JuliaClimate has been created to address specific challenges in climate modeling. One of these challenges is access to climate data in Julia. Packages such as INMET.jl and CDSAPI.jl serve this purpose and are quite nice to work with.","category":"page"},{"location":"resources/ecosystem/#JuliaGeo","page":"Ecosystem","title":"JuliaGeo","text":"","category":"section"},{"location":"resources/ecosystem/","page":"Ecosystem","title":"Ecosystem","text":"Focused on bringing well-established external libraries to Julia, JuliaGeo provides packages that are widely used by geospatial communities from other programming languages. GDAL.jl, Proj4.jl and LibGEOS.jl are good examples of such packages.","category":"page"},{"location":"validation/#Validation","page":"Validation","title":"Validation","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"GeoStats.jl was designed to, among other things, facilitate rigorous comparison of different geostatistical models in the literature. As a user of geostatistics, you may be interested in trying various models on a given data set to pick the one with best performance. As a researcher in the field, you may be interested in benchmarking your new model against other established models.","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"Errors of geostatistical solvers can be estimated with the cverror function:","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"cverror","category":"page"},{"location":"validation/#GeoStatsValidation.cverror","page":"Validation","title":"GeoStatsValidation.cverror","text":"cverror(model::GeoStatsModel, geotable, method; kwargs...)\n\nEstimate error of model in a given geotable with error estimation method using Interpolate or InterpolateNeighbors depending on the passed kwargs.\n\ncverror(model::StatsLearnModel, geotable, method)\ncverror((model, invars => outvars), geotable, method)\n\nEstimate error of model in a given geotable with error estimation method using the Learn transform.\n\n\n\n\n\n","category":"function"},{"location":"validation/","page":"Validation","title":"Validation","text":"For example, we can perform block cross-validation on a decision tree model using the following code:","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"using GeoStats\nusing GeoIO\n\n# load geospatial data\nΩ = GeoIO.load(\"data/agriculture.csv\", coords = (\"x\", \"y\"))\n\n# 20%/80% split along the (1, -1) direction\nΩₛ, Ωₜ = geosplit(Ω, 0.2, (1.0, -1.0))\n\n# features and label for supervised learning\nfeats = [:band1,:band2,:band3,:band4]\nlabel = :crop\n\n# learning model\nmodel = DecisionTreeClassifier()\n\n# loss function\nloss = MisclassLoss()\n\n# block cross-validation with r = 30.\nbcv = BlockValidation(30., loss = Dict(:crop => loss))\n\n# estimate of generalization error\nϵ̂ = cverror((model, feats => label), Ωₛ, bcv)","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"We can unhide the labels in the target domain and compute the actual error for comparison:","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"# train in Ωₛ and predict in Ωₜ\nΩ̂ₜ = Ωₜ |> Learn(Ωₛ, model, feats => label)\n\t\n# actual error of the model\nϵ = mean(loss.(Ωₜ.crop, Ω̂ₜ.crop))","category":"page"},{"location":"validation/","page":"Validation","title":"Validation","text":"Below is the list of currently implemented validation methods.","category":"page"},{"location":"validation/#Leave-one-out","page":"Validation","title":"Leave-one-out","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"LeaveOneOut","category":"page"},{"location":"validation/#GeoStatsValidation.LeaveOneOut","page":"Validation","title":"GeoStatsValidation.LeaveOneOut","text":"LeaveOneOut(; loss=Dict())\n\nLeave-one-out validation. Optionally, specify loss function from LossFunctions.jl for some of the variables.\n\nReferences\n\nStone. 1974. Cross-Validatory Choice and Assessment of Statistical Predictions\n\n\n\n\n\n","category":"type"},{"location":"validation/#Leave-ball-out","page":"Validation","title":"Leave-ball-out","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"LeaveBallOut","category":"page"},{"location":"validation/#GeoStatsValidation.LeaveBallOut","page":"Validation","title":"GeoStatsValidation.LeaveBallOut","text":"LeaveBallOut(ball; loss=Dict())\n\nLeave-ball-out (a.k.a. spatial leave-one-out) validation. Optionally, specify loss function from the LossFunctions.jl package for some of the variables.\n\nLeaveBallOut(radius; loss=Dict())\n\nBy default, use Euclidean ball of given radius in space.\n\nReferences\n\nLe Rest et al. 2014. Spatial leave-one-out cross-validation for variable selection in the presence of spatial autocorrelation\n\n\n\n\n\n","category":"type"},{"location":"validation/#K-fold","page":"Validation","title":"K-fold","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"KFoldValidation","category":"page"},{"location":"validation/#GeoStatsValidation.KFoldValidation","page":"Validation","title":"GeoStatsValidation.KFoldValidation","text":"KFoldValidation(k; shuffle=true, loss=Dict())\n\nk-fold cross-validation. Optionally, shuffle the data, and specify loss function from LossFunctions.jl for some of the variables.\n\nReferences\n\nGeisser, S. 1975. The predictive sample reuse method with applications\nBurman, P. 1989. A comparative study of ordinary cross-validation, v-fold cross-validation and the repeated learning-testing methods\n\n\n\n\n\n","category":"type"},{"location":"validation/#Block","page":"Validation","title":"Block","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"BlockValidation","category":"page"},{"location":"validation/#GeoStatsValidation.BlockValidation","page":"Validation","title":"GeoStatsValidation.BlockValidation","text":"BlockValidation(sides; loss=Dict())\n\nCross-validation with blocks of given sides. Optionally, specify loss function from LossFunctions.jl for some of the variables. If only one side is provided, then blocks become cubes.\n\nReferences\n\nRoberts et al. 2017. Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure\nPohjankukka et al. 2017. Estimating the prediction performance of spatial models via spatial k-fold cross-validation\n\n\n\n\n\n","category":"type"},{"location":"validation/#Weighted","page":"Validation","title":"Weighted","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"WeightedValidation","category":"page"},{"location":"validation/#GeoStatsValidation.WeightedValidation","page":"Validation","title":"GeoStatsValidation.WeightedValidation","text":"WeightedValidation(weighting, folding; lambda=1.0, loss=Dict())\n\nAn error estimation method which samples are weighted with weighting method and split into folds with folding method. Weights are raised to lambda power in [0,1]. Optionally, specify loss function from LossFunctions.jl for some of the variables.\n\nReferences\n\nSugiyama et al. 2006. Importance-weighted cross-validation for covariate shift\nSugiyama et al. 2007. Covariate shift adaptation by importance weighted cross validation\n\n\n\n\n\n","category":"type"},{"location":"validation/#Density-ratio","page":"Validation","title":"Density-ratio","text":"","category":"section"},{"location":"validation/","page":"Validation","title":"Validation","text":"DensityRatioValidation","category":"page"},{"location":"validation/#GeoStatsValidation.DensityRatioValidation","page":"Validation","title":"GeoStatsValidation.DensityRatioValidation","text":"DensityRatioValidation(k; [parameters])\n\nDensity ratio validation where weights are first obtained with density ratio estimation, and then used in k-fold weighted cross-validation.\n\nParameters\n\nshuffle - Shuffle the data before folding (default to true)\nestimator - Density ratio estimator (default to LSIF())\noptlib - Optimization library (default to default_optlib(estimator))\nlambda - Power of density ratios (default to 1.0)\n\nPlease see DensityRatioEstimation.jl for a list of supported estimators.\n\nReferences\n\nHoffimann et al. 2020. Geostatistical Learning: Challenges and Opportunities\n\n\n\n\n\n","category":"type"},{"location":"queries/#Geospatial-queries","page":"Queries","title":"Geospatial queries","text":"","category":"section"},{"location":"queries/#Split-apply-combine","page":"Queries","title":"Split-apply-combine","text":"","category":"section"},{"location":"queries/","page":"Queries","title":"Queries","text":"We provide a geospatial version of the split-apply-combine pattern:","category":"page"},{"location":"queries/","page":"Queries","title":"Queries","text":"

\n\n

","category":"page"},{"location":"queries/","page":"Queries","title":"Queries","text":"@groupby\n@transform\n@combine","category":"page"},{"location":"queries/#GeoTables.@groupby","page":"Queries","title":"GeoTables.@groupby","text":"@groupby(geotable, col₁, col₂, ..., colₙ)\n@groupby(geotable, [col₁, col₂, ..., colₙ])\n@groupby(geotable, (col₁, col₂, ..., colₙ))\n\nGroup geospatial geotable by columns col₁, col₂, ..., colₙ.\n\n@groupby(geotable, regex)\n\nGroup geospatial geotable by columns that match with regex.\n\nExamples\n\n@groupby(geotable, 1, 3, 5)\n@groupby(geotable, [:a, :c, :e])\n@groupby(geotable, (\"a\", \"c\", \"e\"))\n@groupby(geotable, r\"[ace]\")\n\n\n\n\n\n","category":"macro"},{"location":"queries/#GeoTables.@transform","page":"Queries","title":"GeoTables.@transform","text":"@transform(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)\n\nReturns geospatial geotable with columns col₁, col₂, ..., colₙ computed with expressions expr₁, expr₂, ..., exprₙ.\n\nSee also: @groupby.\n\nExamples\n\n@transform(geotable, :z = :x + 2*:y)\n@transform(geotable, :w = :x^2 - :y^2)\n@transform(geotable, :sinx = sin(:x), :cosy = cos(:y))\n\ngroups = @groupby(geotable, :y)\n@transform(groups, :logx = log(:x))\n@transform(groups, :expz = exp(:z))\n\n@transform(geotable, {\"z\"} = {\"x\"} - 2*{\"y\"})\nxnm, ynm, znm = :x, :y, :z\n@transform(geotable, {znm} = {xnm} - 2*{ynm})\n\n\n\n\n\n","category":"macro"},{"location":"queries/#GeoTables.@combine","page":"Queries","title":"GeoTables.@combine","text":"@combine(geotable, :col₁ = expr₁, :col₂ = expr₂, ..., :colₙ = exprₙ)\n\nReturns geospatial geotable with columns :col₁, :col₂, ..., :colₙ computed with reduction expressions expr₁, expr₂, ..., exprₙ.\n\nIf a reduction expression is not defined for the :geometry column, the geometries will be reduced using Multi.\n\nSee also: @groupby.\n\nExamples\n\n@combine(geotable, :x_sum = sum(:x))\n@combine(geotable, :x_mean = mean(:x))\n@combine(geotable, :x_mean = mean(:x), :geometry = centroid(:geometry))\n\ngroups = @groupby(geotable, :y)\n@combine(groups, :x_prod = prod(:x))\n@combine(groups, :x_median = median(:x))\n@combine(groups, :x_median = median(:x), :geometry = centroid(:geometry))\n\n@combine(geotable, {\"z\"} = sum({\"x\"}) + prod({\"y\"}))\nxnm, ynm, znm = :x, :y, :z\n@combine(geotable, {znm} = sum({xnm}) + prod({ynm}))\n\n\n\n\n\n","category":"macro"},{"location":"queries/#Geospatial-join","page":"Queries","title":"Geospatial join","text":"","category":"section"},{"location":"queries/","page":"Queries","title":"Queries","text":"geojoin\ntablejoin","category":"page"},{"location":"queries/#GeoTables.geojoin","page":"Queries","title":"GeoTables.geojoin","text":"geojoin(geotable₁, geotable₂, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, pred=intersects, on=nothing)\n\nJoins geotable₁ with geotable₂ using a certain kind of join and predicate function pred that takes two geometries and returns a boolean ((g1, g2) -> g1 ⊆ g2).\n\nOptionally, add a variable value match to join, in addition to geometric match, by passing a single name or list of variable names (strings or symbols) to the on keyword argument. The variable value match use the isequal function.\n\nWhenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.\n\nKinds\n\n:left - Returns all rows of geotable₁ filling entries with missing when there is no match in geotable₂.\n:inner - Returns the subset of rows of geotable₁ that has a match in geotable₂.\n\nExamples\n\ngeojoin(gtb1, gtb2)\ngeojoin(gtb1, gtb2, 1 => mean)\ngeojoin(gtb1, gtb2, :a => mean, :b => std)\ngeojoin(gtb1, gtb2, \"a\" => mean, pred=issubset)\ngeojoin(gtb1, gtb2, on=:a)\ngeojoin(gtb1, gtb2, kind=:inner, on=[\"a\", \"b\"])\n\nSee also tablejoin.\n\n\n\n\n\n","category":"function"},{"location":"queries/#GeoTables.tablejoin","page":"Queries","title":"GeoTables.tablejoin","text":"tablejoin(geotable, table, var₁ => agg₁, ..., varₙ => aggₙ; kind=:left, on)\n\nJoins geotable with table using the values of the on variables to match rows with a certain kind of join.\n\non variables can be a single name or list of variable names (strings or symbols). The variable value match use the isequal function.\n\nWhenever two or more matches are encountered, aggregate varᵢ with aggregation function aggᵢ. If no aggregation function is provided for a variable, then the aggregation function will be selected according to the scientific types: mean for continuous and first otherwise.\n\nKinds\n\n:left - Returns all rows of geotable filling entries with missing when there is no match in table.\n:inner - Returns the subset of rows of geotable that has a match in table.\n\nExamples\n\ntablejoin(gtb, tab, on=:a)\ntablejoin(gtb, tab, 1 => mean, on=:a)\ntablejoin(gtb, tab, :a => mean, :b => std, on=:a)\ntablejoin(gtb, tab, \"a\" => mean, on=[:a, :b])\ntablejoin(gtb, tab, kind=:inner, on=[\"a\", \"b\"])\n\nSee also geojoin.\n\n\n\n\n\n","category":"function"},{"location":"","page":"Home","title":"Home","text":"GeoStats","category":"page"},{"location":"#GeoStats","page":"Home","title":"GeoStats","text":"(Image: GeoStats.jl)\n\n(Image: ) (Image: ) (Image: ) (Image: ) (Image: )\n\n(Image: ) (Image: )\n\nGeoStats.jl is an extensible framework for geospatial data science and geostatistical modeling fully written in Julia. It is comprised of several modules for advanced geometric processing, state-of-the-art geostatistical algorithms and sophisticated visualization of geospatial data.\n\nAll further information is provided in the online documentation.\n\n\n\n\n\n","category":"module"},{"location":"","page":"Home","title":"Home","text":"note: Star us on GitHub!\nIf you have found this software useful, please consider starring it on GitHub. This gives us an accurate lower bound of the (satisfied) user count.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Organizations using the framework:","category":"page"},{"location":"","page":"Home","title":"Home","text":"

\n \n \n \n \n \n \n \n

","category":"page"},{"location":"#Sponsors","page":"Home","title":"Sponsors","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"

\n \n \n \n

","category":"page"},{"location":"","page":"Home","title":"Home","text":"Would like to become a sponsor? Press the sponsor button in our GitHub repository.","category":"page"},{"location":"#Textbooks","page":"Home","title":"Textbooks","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The following textbooks can be useful to learn the framework. Click on the cover to learn more.","category":"page"},{"location":"","page":"Home","title":"Home","text":"

\n \n \n \n

","category":"page"},{"location":"#Overview","page":"Home","title":"Overview","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"In many fields of science, such as mining engineering, hydrogeology, petroleum engineering, and environmental sciences, traditional statistical methods fail to provide unbiased estimates of resources due to the presence of geospatial correlation. Geostatistics (a.k.a. geospatial statistics) is the branch of statistics developed to overcome this limitation. Particularly, it is the branch that takes geospatial coordinates of data into account.","category":"page"},{"location":"","page":"Home","title":"Home","text":"GeoStats.jl is an attempt to bring together bleeding-edge research in the geostatistics community into a comprehensive framework for geospatial data science and geostatistical modeling, as well as to empower researchers and practitioners with a toolkit for fast assessment of different modeling approaches. For a guided tour, please watch our JuliaCon2021 talk:","category":"page"},{"location":"","page":"Home","title":"Home","text":"

\n\n

","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you have questions, feature requests, or would like to brainstorm ideas, don't hesitate to start a topic in our community channel.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Get the latest stable release with Julia's package manager:","category":"page"},{"location":"","page":"Home","title":"Home","text":"] add GeoStats","category":"page"},{"location":"#Quick-example","page":"Home","title":"Quick example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Below is a quick preview of the high-level interface:","category":"page"},{"location":"","page":"Home","title":"Home","text":"using GeoStats\n\nimport CairoMakie as Mke\n\n# attribute table\ntable = (; Z=[1.,0.,1.])\n\n# coordinates for each row\ncoord = [(25.,25.), (50.,75.), (75.,50.)]\n\n# georeference data\ngeotable = georef(table, coord)\n\n# interpolation domain\ngrid = CartesianGrid(100, 100)\n\n# choose an interpolation model\nmodel = Kriging(GaussianVariogram(range=35.))\n\n# perform interpolation over grid\ninterp = geotable |> Interpolate(grid, model)\n\n# visualize the solution\nviz(interp.geometry, color = interp.Z)","category":"page"},{"location":"","page":"Home","title":"Home","text":"For a more detailed example, please consult the Quickstart.","category":"page"},{"location":"#Project-organization","page":"Home","title":"Project organization","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The project is split into various packages:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Package Description\nGeoStats.jl Main package reexporting full stack of packages for geostatistics.\nMeshes.jl Computational geometry and advanced meshing algorithms.\nGeoTables.jl Geospatial tables compatible with the framework.\nDataScienceTraits.jl Traits for geospatial data science.\nTableTransforms.jl Transforms and pipelines with tabular data.\nStatsLearnModels.jl Statistical learning models for geospatial prediction.\nGeoStatsBase.jl Base package with core geostatistical definitions.\nGeoStatsFunctions.jl Geostatistical functions and related tools.\nGeoStatsModels.jl Geostatistical models for geospatial interpolation.\nGeoStatsProcesses.jl Geostatistical processes for geospatial simulation.\nGeoStatsTransforms.jl Geostatistical transforms for geospatial data.\nGeoStatsValidation.jl Geostatistical validation methods.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Other packages can be installed separately for additional functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Package Description\nGeoIO.jl Load/save geospatial tables in various formats.\nDrillHoles.jl Desurvey/composite drillhole data.\nGeoArtifacts.jl Artifacts for geospatial data science.","category":"page"},{"location":"#Citing-the-software","page":"Home","title":"Citing the software","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you find this software useful in your work, please consider citing it: ","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: JOSS) (Image: DOI)","category":"page"},{"location":"","page":"Home","title":"Home","text":"@ARTICLE{Hoffimann2018,\n title={GeoStats.jl – High-performance geostatistics in Julia},\n author={Hoffimann, Júlio},\n journal={Journal of Open Source Software},\n publisher={The Open Journal},\n volume={3},\n pages={692},\n number={24},\n ISSN={2475-9066},\n DOI={10.21105/joss.00692},\n url={https://dx.doi.org/10.21105/joss.00692},\n year={2018},\n month={Apr}\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"We ❤ to see our list of publications growing.","category":"page"},{"location":"about/citing/","page":"Citing","title":"Citing","text":"If you find GeoStats.jl useful in your work, please consider citing it:","category":"page"},{"location":"about/citing/","page":"Citing","title":"Citing","text":"(Image: JOSS) (Image: DOI)","category":"page"},{"location":"about/citing/","page":"Citing","title":"Citing","text":"@ARTICLE{Hoffimann2018,\n title={GeoStats.jl – High-performance geostatistics in Julia},\n author={Hoffimann, Júlio},\n journal={Journal of Open Source Software},\n publisher={The Open Journal},\n volume={3},\n pages={692},\n number={24},\n ISSN={2475-9066},\n DOI={10.21105/joss.00692},\n url={https://dx.doi.org/10.21105/joss.00692},\n year={2018},\n month={Apr}\n}","category":"page"}] } diff --git a/dev/transforms/25dbd166.png b/dev/transforms/25dbd166.png deleted file mode 100644 index 9c83b30..0000000 Binary files a/dev/transforms/25dbd166.png and /dev/null differ diff --git a/dev/transforms/3b285c55.png b/dev/transforms/3b285c55.png deleted file mode 100644 index 5a383ec..0000000 Binary files a/dev/transforms/3b285c55.png and /dev/null differ diff --git a/dev/transforms/6dba0553.png b/dev/transforms/6dba0553.png new file mode 100644 index 0000000..cdd712a Binary files /dev/null and b/dev/transforms/6dba0553.png differ diff --git a/dev/transforms/908c122b.png b/dev/transforms/908c122b.png deleted file mode 100644 index 4df375a..0000000 Binary files a/dev/transforms/908c122b.png and /dev/null differ diff --git a/dev/transforms/92c072e2.png b/dev/transforms/92c072e2.png new file mode 100644 index 0000000..e8bba53 Binary files /dev/null and b/dev/transforms/92c072e2.png differ diff --git a/dev/transforms/d79d6542.png b/dev/transforms/d79d6542.png new file mode 100644 index 0000000..ab4f77a Binary files /dev/null and b/dev/transforms/d79d6542.png differ diff --git a/dev/transforms/index.html b/dev/transforms/index.html index 6c605d6..cd1861d 100644 --- a/dev/transforms/index.html +++ b/dev/transforms/index.html @@ -101,7 +101,7 @@ Select(1 => :x, 3 => :y) Select(:a => :x, :b => :y) Select("a" => "x", "b" => "y") -Select(r"[ace]")source

Transforms of type FeatureTransform operate on the attribute table, whereas transforms of type GeometricTransform operate on the underlying geospatial domain:

TableTransforms.FeatureTransformType
FeatureTransform

A transform that operates on the columns of the table containing features, i.e., simple attributes such as numbers, strings, etc.

source

Other transforms such as Detrend are defined in terms of both the geospatial domain and the attribute table. All transforms and pipelines implement the following functions:

TransformsBase.isrevertibleFunction
isrevertible(transform)

Tells whether or not the transform is revertible, i.e. supports a revert function. Defaults to false for new transform types.

Transforms can be revertible and yet don't be invertible. Invertibility is a mathematical concept, whereas revertibility is a computational concept.

See also isinvertible.

source
TransformsBase.isinvertibleFunction
isinvertible(transform)

Tells whether or not the transform is invertible, i.e. whether it implements the inverse function. Defaults to false for new transform types.

Transforms can be invertible in the mathematical sense, i.e., there exists a one-to-one mapping between input and output spaces.

See also inverse, isrevertible.

source
TransformsBase.applyFunction
newobject, cache = apply(transform, object)

Apply transform on the object. Return the newobject and a cache to revert the transform later.

source
TransformsBase.revertFunction
object = revert(transform, newobject, cache)

Revert the transform on the newobject using the cache from the corresponding apply call and return the original object. Only defined when the transform isrevertible.

source
TransformsBase.reapplyFunction
newobject = reapply(transform, object, cache)

Reapply the transform to (a possibly different) object using a cache that was created with a previous apply call. Fallback to apply without using the cache.

source

Feature transforms

Please check the TableTransforms.jl documentation for an updated list of feature transforms. As an example consider the following features over a Cartesian grid and their statistics:

using DataFrames
+Select(r"[ace]")
source

Transforms of type FeatureTransform operate on the attribute table, whereas transforms of type GeometricTransform operate on the underlying geospatial domain:

TableTransforms.FeatureTransformType
FeatureTransform

A transform that operates on the columns of the table containing features, i.e., simple attributes such as numbers, strings, etc.

source

Other transforms such as Detrend are defined in terms of both the geospatial domain and the attribute table. All transforms and pipelines implement the following functions:

TransformsBase.isrevertibleFunction
isrevertible(transform)

Tells whether or not the transform is revertible, i.e. supports a revert function. Defaults to false for new transform types.

Transforms can be revertible and yet don't be invertible. Invertibility is a mathematical concept, whereas revertibility is a computational concept.

See also isinvertible.

source
TransformsBase.isinvertibleFunction
isinvertible(transform)

Tells whether or not the transform is invertible, i.e. whether it implements the inverse function. Defaults to false for new transform types.

Transforms can be invertible in the mathematical sense, i.e., there exists a one-to-one mapping between input and output spaces.

See also inverse, isrevertible.

source
TransformsBase.applyFunction
newobject, cache = apply(transform, object)

Apply transform on the object. Return the newobject and a cache to revert the transform later.

source
TransformsBase.revertFunction
object = revert(transform, newobject, cache)

Revert the transform on the newobject using the cache from the corresponding apply call and return the original object. Only defined when the transform isrevertible.

source
TransformsBase.reapplyFunction
newobject = reapply(transform, object, cache)

Reapply the transform to (a possibly different) object using a cache that was created with a previous apply call. Fallback to apply without using the cache.

source

Feature transforms

Please check the TableTransforms.jl documentation for an updated list of feature transforms. As an example consider the following features over a Cartesian grid and their statistics:

using DataFrames
 
 # table of features and domain
 tab = DataFrame(a=rand(1000), b=randn(1000), c=rand(1000))
@@ -111,13 +111,13 @@
 Ω = georef(tab, dom)
 
 # describe features
-describe(values(Ω))
3×7 DataFrame
2500×2 GeoTable over 50×50 CartesianGrid
Rowvariablemeanminmedianmaxnmissingeltype
SymbolFloat64Float64Float64Float64Int64DataType
1a0.4962640.00163830.4857710.9995370Float64
2b0.0489977-3.11077-0.007428733.24540Float64
3c0.4921650.0001656290.499820.9993070Float64

We can create a pipeline that transforms the features to their normal quantile (or scores):

pipe = Quantile()
+describe(values(Ω))
3×7 DataFrame
Rowvariablemeanminmedianmaxnmissingeltype
SymbolFloat64Float64Float64Float64Int64DataType
1a0.4877180.0004066440.4854710.9956880Float64
2b-0.0357262-3.6943-0.03681363.774610Float64
3c0.4897330.005147250.4891130.9990640Float64

We can create a pipeline that transforms the features to their normal quantile (or scores):

pipe = Quantile()
 
 Ω̄, cache = apply(pipe, Ω)
 
 describe(values(Ω̄))
3×7 DataFrame
Rowvariablemeanminmedianmaxnmissingeltype
SymbolFloat64Float64Float64Float64Int64DataType
1a0.00309023-3.090230.001253323.090230Float64
2b0.00309023-3.090230.001253323.090230Float64
3c0.00309023-3.090230.001253323.090230Float64

We can then revert the transform given any new geospatial data in the transformed sample space:

Ωₒ = revert(pipe, Ω̄, cache)
 
-describe(values(Ωₒ))
3×7 DataFrame
Rowvariablemeanminmedianmaxnmissingeltype
SymbolFloat64Float64Float64Float64Int64DataType
1a0.4967580.003359260.485860.9986840Float64
2b0.0520916-2.61514-0.006618563.179550Float64
3c0.4926540.001224590.4999820.9966520Float64

The Learn transform is another important transform from StatsLearnModels.jl:

StatsLearnModels.LearnType
Learn(train, model, incols => outcols)

Fits the statistical learning model using the input columns, selected by incols, and the output columns, selected by outcols, from the train table.

The column selection can be a single column identifier (index or name), a collection of identifiers or a regular expression (regex).

Examples

Learn(train, model, [1, 2, 3] => "d")
+describe(values(Ωₒ))
3×7 DataFrame
Rowvariablemeanminmedianmaxnmissingeltype
SymbolFloat64Float64Float64Float64Int64DataType
1a0.4882050.0007794370.4872490.9955220Float64
2b-0.032655-3.01366-0.03184993.187250Float64
3c0.4902170.007818650.4893390.9989680Float64

The Learn transform is another important transform from StatsLearnModels.jl:

StatsLearnModels.LearnType
Learn(train, model, incols => outcols)

Fits the statistical learning model using the input columns, selected by incols, and the output columns, selected by outcols, from the train table.

The column selection can be a single column identifier (index or name), a collection of identifiers or a regular expression (regex).

Examples

Learn(train, model, [1, 2, 3] => "d")
 Learn(train, model, [:a, :b, :c] => :d)
 Learn(train, model, ["a", "b", "c"] => 4)
 Learn(train, model, [1, 2, 3] => [:d, :e])
@@ -132,11 +132,11 @@
 fig = Mke.Figure(size = (800, 400))
 viz(fig[1,1], Ω.geometry, color = Ω.Z)
 viz(fig[1,2], Ωr.geometry, color = Ωr.Z)
-fig
Example block output

Geostatistical transforms

Bellow is the current list of transforms that operate on both the geometries and features of geospatial data. They are implemented in the GeoStatsBase.jl package.

UniqueCoords

GeoStatsTransforms.UniqueCoordsType
UniqueCoords(var₁ => agg₁, var₂ => agg₂, ..., varₙ => aggₙ)

Retain locations in data with unique coordinates.

Duplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.

Examples

UniqueCoords(1 => last, 2 => maximum)
+fig
Example block output

Geostatistical transforms

Bellow is the current list of transforms that operate on both the geometries and features of geospatial data. They are implemented in the GeoStatsBase.jl package.

UniqueCoords

GeoStatsTransforms.UniqueCoordsType
UniqueCoords(var₁ => agg₁, var₂ => agg₂, ..., varₙ => aggₙ)

Retain locations in data with unique coordinates.

Duplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.

Examples

UniqueCoords(1 => last, 2 => maximum)
 UniqueCoords(:a => first, :b => minimum)
 UniqueCoords("a" => last, "b" => maximum)
source
# point set with repeated points
-X = rand(2, 50)
-Ω = georef((Z=rand(100),), [X X])
+p = rand(Point{2}, 50) +Ω = georef((Z=rand(100),), [p; p])
@@ -154,44 +154,44 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -218,44 +218,44 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -281,7 +281,7 @@

DetrendExample block output

Potrace

GeoStatsTransforms.PotraceType
Potrace(mask; [ϵ])
+fig
Example block output

Potrace

GeoStatsTransforms.PotraceType
Potrace(mask; [ϵ])
 Potrace(mask, var₁ => agg₁, ..., varₙ => aggₙ; [ϵ])

Trace polygons on 2D image data with Selinger's Potrace algorithm.

The categories stored in column mask are converted into binary masks, which are then traced into multi-polygons. When provided, the option ϵ is forwarded to Selinger's simplification algorithm.

Duplicates of a variable varᵢ are aggregated with aggregation function aggᵢ. If an aggregation function is not defined for variable varᵢ, the default aggregation function will be used. Default aggregation function is mean for continuous variables and first otherwise.

Examples

Potrace(:mask, ϵ=0.1)
 Potrace(1, 1 => last, 2 => maximum)
 Potrace(:mask, :a => first, :b => minimum)
@@ -329,7 +329,7 @@ 

Detrend

Example block output
GeoStatsTransforms.GSCType
GSC(k, m; σ=1.0, tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)

A transform for partitioning geospatial data into k clusters using Geostatistical Spectral Clustering (GSC).

Parameters

  • k - Desired number of clusters
  • m - Multiplicative factor for adjacent weights
  • σ - Standard deviation for exponential model (default to 1.0)
  • tol - Tolerance of k-means algorithm (default to 1e-4)
  • maxiter - Maximum number of iterations (default to 10)
  • weights - Dictionary with weights for each attribute (default to nothing)
  • as - Cluster column name

References

Notes

  • The algorithm implemented here is slightly different than the algorithm

described in Romary et al. 2015. Instead of setting Wᵢⱼ = 0 when i <-/-> j, we simply magnify the weight by a multiplicative factor Wᵢⱼ *= m when i <–> j. This leads to dense matrices but also better results in practice.

source
𝒞 = Ω |> GSC(50, 2.0)
 
-viz(𝒞.geometry, color = 𝒞.CLUSTER)
Example block output
GeoStatsTransforms.SLICType
SLIC(k, m; tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)

A transform for clustering geospatial data into approximately k clusters using Simple Linear Iterative Clustering (SLIC). The transform produces clusters of samples that are spatially connected based on a distance dₛ and that, at the same time, are similar in terms of vars with distance dᵥ. The tradeoff is controlled with a hyperparameter parameter m in an additive model dₜ = √(dᵥ² + m²(dₛ/s)²).

Parameters

  • k - Approximate number of clusters
  • m - Hyperparameter of SLIC model
  • tol - Tolerance of k-means algorithm (default to 1e-4)
  • maxiter - Maximum number of iterations (default to 10)
  • weights - Dictionary with weights for each attribute (default to nothing)
  • as - Cluster column name

References

source
𝒞 = Ω |> SLIC(50, 0.01)
+viz(𝒞.geometry, color = 𝒞.CLUSTER)
Example block output
GeoStatsTransforms.SLICType
SLIC(k, m; tol=1e-4, maxiter=10, weights=nothing, as=:CLUSTER)

A transform for clustering geospatial data into approximately k clusters using Simple Linear Iterative Clustering (SLIC). The transform produces clusters of samples that are spatially connected based on a distance dₛ and that, at the same time, are similar in terms of vars with distance dᵥ. The tradeoff is controlled with a hyperparameter parameter m in an additive model dₜ = √(dᵥ² + m²(dₛ/s)²).

Parameters

  • k - Approximate number of clusters
  • m - Hyperparameter of SLIC model
  • tol - Tolerance of k-means algorithm (default to 1e-4)
  • maxiter - Maximum number of iterations (default to 10)
  • weights - Dictionary with weights for each attribute (default to nothing)
  • as - Cluster column name

References

source
𝒞 = Ω |> SLIC(50, 0.01)
 
 viz(𝒞.geometry, color = 𝒞.CLUSTER)
Example block output

Interpolate

GeoStatsTransforms.InterpolateType
Interpolate(domain, vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])
 Interpolate([g₁, g₂, ..., gₙ], vars₁ => model₁, ..., varsₙ => modelₙ; [parameters])

Interpolate geospatial data on given domain or vector of geometries [g₁, g₂, ..., gₙ], using geostatistical models model₁, ..., modelₙ for variables vars₁, ..., varsₙ.

Interpolate(domain, model=NN(); [parameters])
@@ -356,4 +356,4 @@ 

Detrend

Simulate nreals realizations of variable parent with geostatistical process process, and each child variable varsᵢ with process map procmapᵢ, over given domain.

The process map must be an iterable of pairs of the form: value => process. Each process in the map is related to a value of the parent realization, therefore the values of the child variables will be chosen according to the values of the corresponding parent realization.

The parameters are forwarded to the rand method of the geostatistical processes.

Examples

parent = QuiltingProcess(trainimg, (30, 30))
 child0 = GaussianProcess(SphericalVariogram(range=20.0, sill=0.2))
 child1 = GaussianProcess(SphericalVariogram(MetricBall((200.0, 20.0))))
-transform = CookieCutter(domain, :parent => parent, :child => [0 => child0, 1 => child1])
source
+transform = CookieCutter(domain, :parent => parent, :child => [0 => child0, 1 => child1])source
diff --git a/dev/validation/index.html b/dev/validation/index.html index 2967307..0332538 100644 --- a/dev/validation/index.html +++ b/dev/validation/index.html @@ -24,8 +24,8 @@ # estimate of generalization error ϵ̂ = cverror((model, feats => label), Ωₛ, bcv)
Dict{Symbol, Float64} with 1 entry:
-  :crop => 0.226704

We can unhide the labels in the target domain and compute the actual error for comparison:

# train in Ωₛ and predict in Ωₜ
+  :crop => 0.23042

We can unhide the labels in the target domain and compute the actual error for comparison:

# train in Ωₛ and predict in Ωₜ
 Ω̂ₜ = Ωₜ |> Learn(Ωₛ, model, feats => label)
 
 # actual error of the model
-ϵ = mean(loss.(Ωₜ.crop, Ω̂ₜ.crop))
0.236096537250787

Below is the list of currently implemented validation methods.

Leave-one-out

Leave-ball-out

K-fold

Block

GeoStatsValidation.BlockValidationType
BlockValidation(sides; loss=Dict())

Cross-validation with blocks of given sides. Optionally, specify loss function from LossFunctions.jl for some of the variables. If only one side is provided, then blocks become cubes.

References

source

Weighted

GeoStatsValidation.WeightedValidationType
WeightedValidation(weighting, folding; lambda=1.0, loss=Dict())

An error estimation method which samples are weighted with weighting method and split into folds with folding method. Weights are raised to lambda power in [0,1]. Optionally, specify loss function from LossFunctions.jl for some of the variables.

References

source

Density-ratio

GeoStatsValidation.DensityRatioValidationType
DensityRatioValidation(k; [parameters])

Density ratio validation where weights are first obtained with density ratio estimation, and then used in k-fold weighted cross-validation.

Parameters

  • shuffle - Shuffle the data before folding (default to true)
  • estimator - Density ratio estimator (default to LSIF())
  • optlib - Optimization library (default to default_optlib(estimator))
  • lambda - Power of density ratios (default to 1.0)

Please see DensityRatioEstimation.jl for a list of supported estimators.

References

source
+ϵ = mean(loss.(Ωₜ.crop, Ω̂ₜ.crop))
0.2340312130448542

Below is the list of currently implemented validation methods.

Leave-one-out

Leave-ball-out

K-fold

Block

GeoStatsValidation.BlockValidationType
BlockValidation(sides; loss=Dict())

Cross-validation with blocks of given sides. Optionally, specify loss function from LossFunctions.jl for some of the variables. If only one side is provided, then blocks become cubes.

References

source

Weighted

GeoStatsValidation.WeightedValidationType
WeightedValidation(weighting, folding; lambda=1.0, loss=Dict())

An error estimation method which samples are weighted with weighting method and split into folds with folding method. Weights are raised to lambda power in [0,1]. Optionally, specify loss function from LossFunctions.jl for some of the variables.

References

source

Density-ratio

GeoStatsValidation.DensityRatioValidationType
DensityRatioValidation(k; [parameters])

Density ratio validation where weights are first obtained with density ratio estimation, and then used in k-fold weighted cross-validation.

Parameters

  • shuffle - Shuffle the data before folding (default to true)
  • estimator - Density ratio estimator (default to LSIF())
  • optlib - Optimization library (default to default_optlib(estimator))
  • lambda - Power of density ratios (default to 1.0)

Please see DensityRatioEstimation.jl for a list of supported estimators.

References

source
diff --git a/dev/variography/empirical/index.html b/dev/variography/empirical/index.html index 7e06cc0..64b4e18 100644 --- a/dev/variography/empirical/index.html +++ b/dev/variography/empirical/index.html @@ -25,4 +25,4 @@ fig = Mke.Figure() ax = Mke.PolarAxis(fig[1,1], title = "Varioplane") Mke.plot!(ax, γ) -figExample block output +figExample block output diff --git a/dev/variography/fitting/index.html b/dev/variography/fitting/index.html index 31c2473..3b140f6 100644 --- a/dev/variography/fitting/index.html +++ b/dev/variography/fitting/index.html @@ -23,4 +23,4 @@ Mke.plot(g) Mke.plot!(γ, maxlag = 25.) Mke.current_figure()Example block output

Methods

Weighted least squares

GeoStatsFunctions.WeightedLeastSquaresType
WeightedLeastSquares()
-WeightedLeastSquares(w)

Fit theoretical variogram using weighted least squares with weighting function w (e.g. h -> 1/h). If no weighting function is provided, bin counts of empirical variogram are normalized and used as weights.

source
+WeightedLeastSquares(w)

Fit theoretical variogram using weighted least squares with weighting function w (e.g. h -> 1/h). If no weighting function is provided, bin counts of empirical variogram are normalized and used as weights.

source diff --git a/dev/variography/theoretical/144d313c.png b/dev/variography/theoretical/144d313c.png new file mode 100644 index 0000000..db5e9bf Binary files /dev/null and b/dev/variography/theoretical/144d313c.png differ diff --git a/dev/variography/theoretical/5281a53b.png b/dev/variography/theoretical/5281a53b.png deleted file mode 100644 index 34a7e4e..0000000 Binary files a/dev/variography/theoretical/5281a53b.png and /dev/null differ diff --git a/dev/variography/theoretical/b1bec405.png b/dev/variography/theoretical/b1bec405.png new file mode 100644 index 0000000..5170eb6 Binary files /dev/null and b/dev/variography/theoretical/b1bec405.png differ diff --git a/dev/variography/theoretical/f9680c49.png b/dev/variography/theoretical/f9680c49.png deleted file mode 100644 index b56b4cb..0000000 Binary files a/dev/variography/theoretical/f9680c49.png and /dev/null differ diff --git a/dev/variography/theoretical/index.html b/dev/variography/theoretical/index.html index 706676d..83a6713 100644 --- a/dev/variography/theoretical/index.html +++ b/dev/variography/theoretical/index.html @@ -11,9 +11,10 @@ ├─ sill: 2.0 ├─ nugget: 0.0 └─ ranges: (3.0 m, 2.0 m, 1.0 m) -└─ distance: Mahalanobis

To illustrate the concept, consider the following 2D data set:

geotable = georef((Z=rand(50),), 100rand(2, 50))
+└─ distance: Mahalanobis

To illustrate the concept, consider the following 2D data set:

points = rand(Point{2}, 50) |> Scale(100)
+geotable = georef((Z=rand(50),), points)
 
-viz(geotable.geometry, color = geotable.Z)
Example block output

We interpolate the data with different ellipsoids by varying the angle of rotation from $0$ to $2\pi$ clockwise:

θs = range(0.0, step = π/4, stop = 2π - π/4)
+viz(geotable.geometry, color = geotable.Z)
Example block output

We interpolate the data with different ellipsoids by varying the angle of rotation from $0$ to $2\pi$ clockwise:

θs = range(0.0, step = π/4, stop = 2π - π/4)
 
 # initialize figure
 fig = Mke.Figure(size = (800, 1600))
@@ -41,7 +42,7 @@
   )
 end
 
-fig
Example block output

Nesting

A nested variogram model $\gamma(h) = c_1\cdot\gamma_1(h) + c_2\cdot\gamma_2(h) + \cdots + c_n\cdot\gamma_n(h)$ can be constructed from multiple variogram models, including matrix coefficients. The individual structures can be recovered in canonical form with the structures function:

GeoStatsFunctions.structuresFunction
structures(γ)

Return the individual structures of a (possibly nested) variogram as a tuple. The structures are the total nugget cₒ, and the coefficients (or contributions) c[i] for the remaining non-trivial structures g[i] after normalization (i.e. sill=1, nugget=0).

Examples

γ₁ = GaussianVariogram(nugget=1, sill=2)
+fig
Example block output

Nesting

A nested variogram model $\gamma(h) = c_1\cdot\gamma_1(h) + c_2\cdot\gamma_2(h) + \cdots + c_n\cdot\gamma_n(h)$ can be constructed from multiple variogram models, including matrix coefficients. The individual structures can be recovered in canonical form with the structures function:

GeoStatsFunctions.structuresFunction
structures(γ)

Return the individual structures of a (possibly nested) variogram as a tuple. The structures are the total nugget cₒ, and the coefficients (or contributions) c[i] for the remaining non-trivial structures g[i] after normalization (i.e. sill=1, nugget=0).

Examples

γ₁ = GaussianVariogram(nugget=1, sill=2)
 γ₂ = SphericalVariogram(nugget=2, sill=3)
 
 γ = 2γ₁ + 3γ₂
@@ -57,4 +58,4 @@
 
 cₒ # matrix nugget
2×2 Matrix{Float64}:
  5.0  1.0
- 1.0  7.0
c # matrix coefficients
([1.0 0.0; 0.0 1.0], [2.0 0.5; 0.5 3.0])
g # normalized structures
(GaussianVariogram(sill: 1, nugget: 0, range: 1.0 m, distance: Euclidean), ExponentialVariogram(sill: 1, nugget: 0, range: 1.0 m, distance: Euclidean))
+ 1.0 7.0
c # matrix coefficients
([1.0 0.0; 0.0 1.0], [2.0 0.5; 0.5 3.0])
g # normalized structures
(GaussianVariogram(sill: 1, nugget: 0, range: 1.0 m, distance: Euclidean), ExponentialVariogram(sill: 1, nugget: 0, range: 1.0 m, distance: Euclidean))
diff --git a/dev/visualization/990030ca.png b/dev/visualization/990030ca.png new file mode 100644 index 0000000..793daf1 Binary files /dev/null and b/dev/visualization/990030ca.png differ diff --git a/dev/visualization/b6a9c6a1.png b/dev/visualization/b6a9c6a1.png deleted file mode 100644 index 7254707..0000000 Binary files a/dev/visualization/b6a9c6a1.png and /dev/null differ diff --git a/dev/visualization/index.html b/dev/visualization/index.html index b842c9c..a472b02 100644 --- a/dev/visualization/index.html +++ b/dev/visualization/index.html @@ -8,7 +8,7 @@ # visualize boundary with separate call viz(polygon) -viz!(boundary(polygon))

Notes

  • This function will only work in the presence of a Makie.jl backend via package extensions in Julia v1.9 or later versions of the language.
source
Meshes.viz!Function
viz!(object; [options])

Visualize Meshes.jl object in an existing scene with options forwarded to viz.

source

This function takes a geospatial domain as input and provides a set of aesthetic options to style the elements (i.e. geometries) of the domain.

Note

Notice that the geometry column of our geospatial data type is a domain (i.e. data.geometry isa Domain), and that this design enables several optimizations in the visualization itself.

Users can also call Makie's plot function in the geometry column as in

Mke.plot(data.geometry)

and this is equivalent to calling the viz recipe above. The plot function also works with various other objects such as EmpiricalHistogram and EmpiricalVariogram. That is convenient if you don't remember the name of the recipe.

Additionaly, we provide a basic scientific viewer to visualize all viewable variables in the data:

GeoTables.viewerFunction
viewer(geotable; kwargs...)

Basic scientific viewer for geospatial table geotable.

Aesthetic options are forwarded via kwargs to the Meshes.viz recipe.

source

Other plots are listed below that can be useful for geostatistical analysis.

Built-in

A hscatter plot between two variables var1 and var2 (possibly with var2 = var1) is a simple scatter plot in which the dots represent all ordered pairs of values of var1 and var2 at a given lag h.

𝒟 = georef((Z=[10sin(i/10) + j for i in 1:100, j in 1:200],))
+viz!(boundary(polygon))

Notes

  • This function will only work in the presence of a Makie.jl backend via package extensions in Julia v1.9 or later versions of the language.
source
Meshes.viz!Function
viz!(object; [options])

Visualize Meshes.jl object in an existing scene with options forwarded to viz.

source

This function takes a geospatial domain as input and provides a set of aesthetic options to style the elements (i.e. geometries) of the domain.

Note

Notice that the geometry column of our geospatial data type is a domain (i.e. data.geometry isa Domain), and that this design enables several optimizations in the visualization itself.

Users can also call Makie's plot function in the geometry column as in

Mke.plot(data.geometry)

and this is equivalent to calling the viz recipe above. The plot function also works with various other objects such as EmpiricalHistogram and EmpiricalVariogram. That is convenient if you don't remember the name of the recipe.

Additionaly, we provide a basic scientific viewer to visualize all viewable variables in the data:

GeoTables.viewerFunction
viewer(geotable; kwargs...)

Basic scientific viewer for geospatial table geotable.

Aesthetic options are forwarded via kwargs to the Meshes.viz recipe.

source

Other plots are listed below that can be useful for geostatistical analysis.

Built-in

A hscatter plot between two variables var1 and var2 (possibly with var2 = var1) is a simple scatter plot in which the dots represent all ordered pairs of values of var1 and var2 at a given lag h.

𝒟 = georef((Z=[10sin(i/10) + j for i in 1:100, j in 1:200],))
 
 𝒮 = sample(𝒟, UniformSampling(500))
 
@@ -17,4 +17,4 @@
 hscatter(fig[1,2], 𝒮, :Z, :Z, lag=20)
 hscatter(fig[2,1], 𝒮, :Z, :Z, lag=40)
 hscatter(fig[2,2], 𝒮, :Z, :Z, lag=60)
-fig
Example block output

PairPlots.jl

The PairPlots.jl package provides the pairplot function that can be used with any table, including tables of attributes obtained with the values function.

Biplots.jl

The Biplot.jl package provides 2D and 3D statistical biplots.

+figExample block output

PairPlots.jl

The PairPlots.jl package provides the pairplot function that can be used with any table, including tables of attributes obtained with the values function.

Biplots.jl

The Biplot.jl package provides 2D and 3D statistical biplots.

100×2 GeoTable over 100 PointSet
0.389525(x: 0.727823 m, y: 0.355876 m)0.322382(x: 0.895875 m, y: 0.303548 m)
0.727005(x: 0.551874 m, y: 0.487365 m)0.917462(x: 0.917833 m, y: 0.216882 m)
0.396792(x: 0.431493 m, y: 0.914686 m)0.167262(x: 0.0149841 m, y: 0.566885 m)
0.0391048(x: 0.0584169 m, y: 0.150285 m)0.448492(x: 0.797196 m, y: 0.803085 m)
0.699163(x: 0.850212 m, y: 0.83071 m)0.857563(x: 0.955532 m, y: 0.135928 m)
0.0944627(x: 0.013483 m, y: 0.589583 m)0.561221(x: 0.331787 m, y: 0.513999 m)
0.48832(x: 0.377305 m, y: 0.55446 m)0.664753(x: 0.0498719 m, y: 0.58489 m)
0.213098(x: 0.628593 m, y: 0.184953 m)0.655366(x: 0.536627 m, y: 0.0730521 m)
0.711282(x: 0.824611 m, y: 0.517057 m)0.356001(x: 0.572591 m, y: 0.307442 m)
0.616569(x: 0.923832 m, y: 0.153891 m)0.0598054(x: 0.164017 m, y: 0.302258 m)
0.321641(x: 0.727823 m, y: 0.355876 m)0.245424(x: 0.895875 m, y: 0.303548 m)
0.847626(x: 0.551874 m, y: 0.487365 m)0.592862(x: 0.917833 m, y: 0.216882 m)
0.543241(x: 0.431493 m, y: 0.914686 m)0.22912(x: 0.0149841 m, y: 0.566885 m)
0.190447(x: 0.0584169 m, y: 0.150285 m)0.304887(x: 0.797196 m, y: 0.803085 m)
0.477123(x: 0.850212 m, y: 0.83071 m)0.466558(x: 0.955532 m, y: 0.135928 m)
0.213204(x: 0.013483 m, y: 0.589583 m)0.67892(x: 0.331787 m, y: 0.513999 m)
0.60346(x: 0.377305 m, y: 0.55446 m)0.512832(x: 0.0498719 m, y: 0.58489 m)
0.213256(x: 0.628593 m, y: 0.184953 m)0.630508(x: 0.536627 m, y: 0.0730521 m)
0.655247(x: 0.824611 m, y: 0.517057 m)0.37296(x: 0.572591 m, y: 0.307442 m)
0.461179(x: 0.923832 m, y: 0.153891 m)0.442426(x: 0.164017 m, y: 0.302258 m)