# \[ANN\]: GeoStats.jl v0.14

**URL:** <https://discourse.julialang.org/t/ann-geostats-jl-v0-14/43230>\
**Category:** Package Announcements\
**Tags:** package, announcement, statistics, geo\
**Created:** [July 17, 2020, 12:07pm UTC](https://discourse.julialang.org/t/ann-geostats-jl-v0-14/43230 "2020-07-17T12:07:39Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [July 17, 2020, 12:07pm UTC](https://discourse.julialang.org/t/ann-geostats-jl-v0-14/43230/1 "2020-07-17T12:07:40Z")

</div>

Dear geospatial community, I am very happy to announce a quite exciting release of [GeoStats.jl](https://juliaearth.github.io/GeoStats.jl/stable)!

In this release, we’ve introduced a cleaner, unified approach to georeferencing data (e.g. tables and arrays). To demonstrate this feature, I will copy a section of the updated documentation below. Everything is done via the new `georef` function, which supersedes the old spatial data types.

# Tables

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

```julia
table = DataFrame(T=rand(25), P=rand(25))

```

```julia-auto
25×2 DataFrame
│ Row │ T │ P │
│ │ Float64 │ Float64 │
├─────┼────────────┼───────────┤
│ 1 │ 0.0084492 │ 0.515809 │
│ 2 │ 0.681805 │ 0.995751 │
│ 3 │ 0.420886 │ 0.803035 │
│ 4 │ 0.0636994 │ 0.752871 │
│ 5 │ 0.00587529 │ 0.547591 │
│ 6 │ 0.224369 │ 0.193632 │
│ 7 │ 0.618545 │ 0.594453 │
│ 8 │ 0.225633 │ 0.376591 │
│ 9 │ 0.234539 │ 0.505964 │
│ 10 │ 0.375081 │ 0.119859 │
│ 11 │ 0.0907714 │ 0.630515 │
│ 12 │ 0.865484 │ 0.668259 │
│ 13 │ 0.893234 │ 0.544639 │
│ 14 │ 0.574129 │ 0.707787 │
│ 15 │ 0.0179491 │ 0.665882 │
│ 16 │ 0.112314 │ 0.738942 │
│ 17 │ 0.432444 │ 0.24519 │
│ 18 │ 0.600183 │ 0.0963012 │
│ 19 │ 0.0213318 │ 0.380986 │
│ 20 │ 0.161603 │ 0.725747 │
│ 21 │ 0.195581 │ 0.661791 │
│ 22 │ 0.105743 │ 0.726038 │
│ 23 │ 0.893519 │ 0.0609867 │
│ 24 │ 0.540797 │ 0.484521 │
│ 25 │ 0.543858 │ 0.740442 │

```

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

```julia
𝒟 = georef(table, PointSet(rand(2,25)))

plot(𝒟)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/8/e8511cb29a9dedf3e40383aee9eec47b6d97ed55.png)

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

```julia
𝒟 = georef(table, RegularGrid(5,5))

plot(𝒟)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/8/38cc9dfd48c3374f0e24e03f23bf977895513401.png)

In the first case, the [`PointSet`](https://juliaearth.github.io/GeoStats.jl/stable/domains/#GeoStatsBase.PointSet) domain type can be omitted, and GeoStats.jl will understand that the matrix passed as the second argument contains the coordinates of a point set:

```julia
𝒟 = georef(table, rand(2,25))

```

```julia
25 PointSet{Float64,2}
  variables
    └─P (Float64)
    └─T (Float64)

```

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

```julia-auto
table = DataFrame(T=rand(25), P=rand(25), X=rand(25), Y=rand(25), Z=rand(25))

𝒟 = georef(table, (:X,:Y,:Z))

plot(𝒟)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/6/1/616e56c286971599a6cd5e2645501535cee3ab40.png)

Any table implementing the [Tables.jl](https://github.com/JuliaData/Tables.jl) API is supported, which means that now we are targeting all kinds of tables including very large geospatial databases. ❤ We can georeference these very large tables on memory-free domains such as [RegularGrid](https://juliaearth.github.io/GeoStats.jl/stable/domains/#GeoStatsBase.RegularGrid) that are stack-allocated in GeoStats.jl:

```julia
@allocated RegularGrid(10^6, 10^6)

```

```julia-auto
0

```

# Arrays

Consider arrays (e.g. images) with data for various spatial variables. We can georeference these arrays using a named tuple:

```julia-auto
T, P = rand(5,5), rand(5,5)

𝒟 = georef((T=T, P=P), rand(2,25))

plot(𝒟)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/f/dfe3cb6d816d7c7ebc86f0231a38c2b3550d5761.png)

Alternatively, we can omit the coordinates and GeoStats.jl will understand that the shape of the arrays should be preserved in a regular grid:

```julia-auto
𝒟 = georef((T=T, P=P))

plot(𝒟)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/c/9c3a7b9d78800b47b541bb1a32b216e4dddbabfb.png)

Optionally, we can specify the origin and spacing of the grid using keyword arguments:

```julia-auto
𝒟₁ = georef((T=T, P=P), origin=(0.,0.), spacing=(1.,1.))
𝒟₂ = georef((T=T, P=P), origin=(10.,10.), spacing=(2.,2.))

plot(𝒟₁)
plot!(𝒟₂)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/3/73a11bb8bf16a73f7b67c952b44cb29c16c791c4.png)

# Roadmap

What is coming next? Well, we would like to scale! We want to show the world that Julia can compete in the geospatial business alongside Python and R that already have large user bases. We do believe that we have an advantage here though given the amazing work that is being done by the Julia community to standardize table APIs and to make implementations extremely fast (thanks @bkamins @quinnj and others involved in Tables.jl, DataFrames.jl, CSV.jl, JuliaDB, …). Unlike other communities where “geospatial” tables are re-implemented with various “tricks” to get performance, here we can rely on a generic interface and load the appropriate table for the task.

The Tables.jl development is one side of the story. The other side of the story is happening in [Meshes.jl](https://github.com/JuliaGeometry/Meshes.jl) where I am trying to standardize basic operations in general meshes to improve the interoperability across different ecosystems operating with spatial data. This initiative is very connected to other initiatives such as [GeometryBasics.jl](https://github.com/JuliaGeometry/GeometryBasics.jl) and [GeoInterfaceRFC.jl](https://github.com/JuliaGeo/GeoInterfaceRFC.jl). The ultimate goal is to be able to seamlessly navigate a full scientific pipeline that starts with _spatial modeling and analysis_ (e.g. [GeoStats.jl](https://github.com/JuliaEarth/GeoStats.jl)), then _physical simulation_ with spatial data (e.g. [Gridap.jl](https://github.com/gridap/Gridap.jl)), and finally _interactive visualization_ of the phenomena (e.g. [Makie.jl](https://github.com/JuliaPlots/Makie.jl)). This won’t be easy to accomplish, but certainly worth to try!

This brings me to my last point, which is: **we need help**. The codebase is becoming too large to maintain and I am sure many corner cases aren’t covered. Particularly, I am sure that my mental model of Tables.jl is incomplete and that probably various parts of the codebase are assuming a more strict “DataFrame-like” API. It would be lovely if people with more experience in tables could stress/test the package and submit PRs fixing issues they encounter with tables other than DataFrames.jl tables. Any other form of help is welcome and highly appreciated.

Finally, I would like to thank the community for the amazing feedback and help so far during these years of development in Julia. Thank you @oxinabox for the Julia anti-patterns post, that helped me a lot in this release. Thank you again @bkamins @quinnj for the amazing work in the Julia tables ecosystem, thank you @evetion @visr for helping with the project and fixing my Project.toml mistakes 🙂 Thank you @briochemc for raising issues when you find them, we need more of those, and thank you @jheinen for always taking action with plotting issues ❤
