# [ANN] GeoStats.jl - Geospatial Data Science and Geostatistical Modeling in Julia

This topic will be used for future release updates of the GeoStats.jl framework. Past topics can be found at v0.10, v0.11, v0.14, v0.18, v0.24, v0.33 and v0.36.

# OVERVIEW

GeoStats.jl v0.40 is out with revised documentation using Makie.jl recipes, new algorithms for simulation of spatial point patterns, and important improvements in geometric algorithms.

This is the last release with support for Julia v1.6 (LTS), next releases will require Julia v1.9.

# RELEASE NOTES

## FEATURES

• New Repair transforms for fixing ill-formed meshes and geometries. These repair operations are parameterized with a number (e.g. Repair{0}) that is documented here.
• Parameterization of geometries meaning that now one can call geometries as segment(t) with t \in [0,1] or quad(u, v) with (u, v) \in [0,1]^2 or hex(u, v, w) with (u, v, w) \in [0,1]^3 to get points in these geometries. The function isparameterized can be used to check if an implementation is available for a given geometry.
• New JarvisMarch convex hull algorithm for 2D point sets besides the existing GrahamScan algorithm. This algorithm has O(nh) complexity where n is the number of points and h is the number of points in the hull. Compare it with the GrahamScan algorithm, which has O(n^2) complexity and you can see the speed up clearly when the convex hull has a very small number of vertices compared to the original point set (see docs).
• New merge operation between geometries and meshes.
• New vertex function to retrieve a single vertex of a Polytope geometry or Domain.
• New pointify function to extract โverticesโ of geometries even when they are not expressed in terms of a finite set of vertices. This function was useful to generalize some transforms and algorithms.
• New Primitive geometries such as Cone, ConeSurface, Torus (see docs).
• New MultiGridPath to traverse Grid subtypes in a hierarchical order.
• New Selinger simplification algorithm to simplify polygons and closed chains (see docs).
• New Potrace transform to trace closed regions with holes in raster images (see docs).
• New Detrend transform to remove trends from geospatial data over any domain (see docs).
• New inhomogeneous PoissonProcess, InhibitionProcess and ClusterProcess (see docs)

## IMPROVEMENTS

• Improvements to the default triangulation algorithm for polygons, which now performs a couple of repairs to the vertices before actual triangulation. This improvement was implemented to handle real data in agriculture projects at Arpeggeoยฎ.
• Less memory allocations in Chain algorithms that are now specialized for Ring and Rope subtypes.
• Various implementations of missing methods for various geometry types such as discretization, sampling, convexhull, etc.
• hasintersect methods for all 0D, 1D and 2D geometries. This means that we can now easily filter a heterogeneous collection of geometries that intersect any other geometry in 2D space (see docs).
• Point is now a Geometry subtype. This enabled the generalization of a few algorithms in the stack.
• Segment is now a Chain which is equivalent to a Polytope{1}.
• Improvement of IO methods for geometries to display more meaningful names in interactive use.
• Support for progress logging in all geostatistical simulation solvers.
• The new documentation now makes extensive use of the visualization stack built with Makie.jl. The visualization stack built with Plots.jl is already in maintenance mode.
• Various improvements to the GeoTables.jl package that can now load and save all types of geospatial data from disk including shp, geojson, gpkg, kml using pure Julia backends whenever possible. The package also implements fixes to the different backendโs results to improve the experience of end-users who donโt know or wanโt to deal with low-level interfaces.

## BREAKING

• Replace passive rotations from ReferenceFrameRotations.jl by active rotations from Rotations.jl
• Replace Chain concrete type by an abstract type with two subtypes Ring (for closed chains) and Rope (for open chains). This way the closedness is part of the type, and we can avoid some internal copies of vertices.
• Replace Collection by GeometrySet and add support for heterogeneous collections of geometries. This means that points, segments, rings, polygons, etc. can be processed together in some algorithms.
• Refactoring of IntersectionType to a reduced list of types. This code simplification enabled more flexible intersections with meshes and domain types and also improved maintainability.
Refactoring of Cylinder and CylinderSurface constructors for greater usability.
• Replace uniquecoords by UniqueCoords transform.

### Acknowledgements

Thanks to all contributors that made this release possible

DianaPat jwscook vickydeka lihua-cat @stla @dorn-gerhard @jackbeagley @cserteGT3 @kylebeggs @ErickChacon @mfsch @longemen3000 @hyrodium conordoherty spaette @eliascarv

Would like to support us? Leave a on GitHub if you didnโt already!

20 Likes

# GeoStats.jl v0.42

## OVERVIEW

This release comes with various performance improvements after a complete review of Meshes.jl internals to use static lists of vertices in geometries whenever possible. We reviewed many algorithms, which are now free of unnecessary memory allocations, implemented geometric optimizations, and fixed various bugs found within industrial applications.

The project now uses package extensions from Julia v1.9 to load Makie.jl recipes automatically for end users. This means that all recipe packages (e.g. GeoStatsPlots.jl and GeoStatsViz.jl) are deprecated.

Users can now start their geospatial data science workflows with:

using GeoStats

import GLMakie as Mke # choose a backend


We highly recommend reading the updated Quickstart.

## FEATURES

• New robust estimator of variograms by Cressie & Hawkins (see docs)
• New CylindricalTrajectory domain to represent wells in geosciences (see docs)
• New recipes for plotting variograms and varioplanes (see docs)

## IMPROVEMENTS

• Estimation solvers (Kriging, IDW, LWR) now make use of a consistent set of neighborhood search methods and domain traversal options
• Estimation (a.k.a. Interpolation) with Unitful.jl objects works with all solvers now, including affine units, which are automatically converted to absolute units (e.g. Celsius โ Kelvin)
• All loss functions from the LossFunctions.jl submodule are reexported by default
• DensityRationEstimation.jl now loads optimization backends with package extensions
• Better documentation for our geometric predicates (see docs)

### Acknowledgements

We would like to acknowledge all contributors and supporters of this project. It is been super fun to develop it more, and continuously apply it in industry. We fixed tons of bugs and corner cases these last months with real data, and will continue to do so.

This last week we reached 5k tests in our Meshes.jl submodule alone, and this is evidence of our commitment to provide a robust experience to our users.

https://julialang.zulipchat.com/#narrow/stream/276201-geostats.2Ejl

11 Likes

# GeoStats.jl v0.47

## OVERVIEW

Various new features described in the Geospatial Data Science with Julia book and other improvements to the end-user experience.

## FEATURES

• New GeoTables.jl implementation with better methods, including efficient show methods with PrettyTables.jl:
julia> georef((a=rand(10, 10), b=rand(Int, 10, 10)))
100ร3 GeoTable over 10ร10 CartesianGrid{2,Float64}
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ     a      โ          b           โ                geometry                 โ
โ Continuous โ     Categorical      โ               Quadrangle                โ
โ [NoUnits]  โ      [NoUnits]       โ                                         โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ  0.516603  โ 6789588642647594681  โ Quadrangle((0.0, 0.0), ..., (0.0, 1.0)) โ
โ  0.998433  โ 9150524320540539883  โ Quadrangle((1.0, 0.0), ..., (1.0, 1.0)) โ
โ  0.263977  โ 4931893769895542016  โ Quadrangle((2.0, 0.0), ..., (2.0, 1.0)) โ
โ  0.427032  โ -3491437907112294822 โ Quadrangle((3.0, 0.0), ..., (3.0, 1.0)) โ
โ  0.906068  โ -7822066656579038303 โ Quadrangle((4.0, 0.0), ..., (4.0, 1.0)) โ
โ  0.556998  โ -2408182908005467907 โ Quadrangle((5.0, 0.0), ..., (5.0, 1.0)) โ
โ  0.881187  โ -1985601647472655905 โ Quadrangle((6.0, 0.0), ..., (6.0, 1.0)) โ
โ  0.64524   โ -4982792138183876424 โ Quadrangle((7.0, 0.0), ..., (7.0, 1.0)) โ
โ  0.495152  โ -5114448186852198900 โ Quadrangle((8.0, 0.0), ..., (8.0, 1.0)) โ
โ  0.288213  โ 8738486151747287386  โ Quadrangle((9.0, 0.0), ..., (9.0, 1.0)) โ
โ 0.0709234  โ -4113799560159813356 โ Quadrangle((0.0, 1.0), ..., (0.0, 2.0)) โ
โ  0.223479  โ 5773465236920674180  โ Quadrangle((1.0, 1.0), ..., (1.0, 2.0)) โ
โ  0.940171  โ -3409105571799614662 โ Quadrangle((2.0, 1.0), ..., (2.0, 2.0)) โ
โ  0.139222  โ 4016690596386790401  โ Quadrangle((3.0, 1.0), ..., (3.0, 2.0)) โ
โ  0.81553   โ 5437077184799252660  โ Quadrangle((4.0, 1.0), ..., (4.0, 2.0)) โ
โ  0.734611  โ -9116300046534728476 โ Quadrangle((5.0, 1.0), ..., (5.0, 2.0)) โ
โ  0.827469  โ -1031902277811757514 โ Quadrangle((6.0, 1.0), ..., (6.0, 2.0)) โ
โ  0.463852  โ -7694874758022304794 โ Quadrangle((7.0, 1.0), ..., (7.0, 2.0)) โ
โ  0.430009  โ  383006486861661319  โ Quadrangle((8.0, 1.0), ..., (8.0, 2.0)) โ
โ  0.114523  โ -6621173923176021272 โ Quadrangle((9.0, 1.0), ..., (9.0, 2.0)) โ
โ  0.453332  โ -9063031855995266727 โ Quadrangle((0.0, 2.0), ..., (0.0, 3.0)) โ
โ  0.848071  โ -2619300603579320095 โ Quadrangle((1.0, 2.0), ..., (1.0, 3.0)) โ
โ  0.791306  โ 5963621929024569325  โ Quadrangle((2.0, 2.0), ..., (2.0, 3.0)) โ
โ 0.0642176  โ 2203217482885317616  โ Quadrangle((3.0, 2.0), ..., (3.0, 3.0)) โ
โ  0.420784  โ -5727490695202776996 โ Quadrangle((4.0, 2.0), ..., (4.0, 3.0)) โ
โ  0.468374  โ 9193956341378230306  โ Quadrangle((5.0, 2.0), ..., (5.0, 3.0)) โ
โ  0.836219  โ 8769101217160787406  โ Quadrangle((6.0, 2.0), ..., (6.0, 3.0)) โ
โ  0.473154  โ 7874585605426519179  โ Quadrangle((7.0, 2.0), ..., (7.0, 3.0)) โ
โ  0.507466  โ -3296044975691403512 โ Quadrangle((8.0, 2.0), ..., (8.0, 3.0)) โ
โ  0.973035  โ 2395941252317957301  โ Quadrangle((9.0, 2.0), ..., (9.0, 3.0)) โ
โ  0.12081   โ 7515712133164922671  โ Quadrangle((0.0, 3.0), ..., (0.0, 4.0)) โ
โ     โฎ      โ          โฎ           โ                    โฎ                    โ
โโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
69 rows omitted

• New DataScienceTraits.jl in place of ScientificTypes.jl with better support for Unitful.jl, DynamicQuantities.jl and missing values.
• New GeoStatsProcesses.jl with stochastic fields and point processes
• New GeoStatsTransforms.jl with various advanced geostatistical transforms
• Support for geotables with geometry column only:
julia> georef(nothing, CartesianGrid(10,10))
100ร1 GeoTable over 10ร10 CartesianGrid{2,Float64}
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ                geometry                 โ
โ                                         โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Quadrangle((0.0, 0.0), ..., (0.0, 1.0)) โ
โ Quadrangle((1.0, 0.0), ..., (1.0, 1.0)) โ
โ Quadrangle((2.0, 0.0), ..., (2.0, 1.0)) โ
โ Quadrangle((3.0, 0.0), ..., (3.0, 1.0)) โ
โ Quadrangle((4.0, 0.0), ..., (4.0, 1.0)) โ
โ Quadrangle((5.0, 0.0), ..., (5.0, 1.0)) โ
โ Quadrangle((6.0, 0.0), ..., (6.0, 1.0)) โ
โ Quadrangle((7.0, 0.0), ..., (7.0, 1.0)) โ
โ Quadrangle((8.0, 0.0), ..., (8.0, 1.0)) โ
โ Quadrangle((9.0, 0.0), ..., (9.0, 1.0)) โ
โ Quadrangle((0.0, 1.0), ..., (0.0, 2.0)) โ
โ Quadrangle((1.0, 1.0), ..., (1.0, 2.0)) โ
โ Quadrangle((2.0, 1.0), ..., (2.0, 2.0)) โ
โ Quadrangle((3.0, 1.0), ..., (3.0, 2.0)) โ
โ Quadrangle((4.0, 1.0), ..., (4.0, 2.0)) โ
โ Quadrangle((5.0, 1.0), ..., (5.0, 2.0)) โ
โ Quadrangle((6.0, 1.0), ..., (6.0, 2.0)) โ
โ Quadrangle((7.0, 1.0), ..., (7.0, 2.0)) โ
โ Quadrangle((8.0, 1.0), ..., (8.0, 2.0)) โ
โ Quadrangle((9.0, 1.0), ..., (9.0, 2.0)) โ
โ Quadrangle((0.0, 2.0), ..., (0.0, 3.0)) โ
โ Quadrangle((1.0, 2.0), ..., (1.0, 3.0)) โ
โ Quadrangle((2.0, 2.0), ..., (2.0, 3.0)) โ
โ Quadrangle((3.0, 2.0), ..., (3.0, 3.0)) โ
โ Quadrangle((4.0, 2.0), ..., (4.0, 3.0)) โ
โ Quadrangle((5.0, 2.0), ..., (5.0, 3.0)) โ
โ Quadrangle((6.0, 2.0), ..., (6.0, 3.0)) โ
โ Quadrangle((7.0, 2.0), ..., (7.0, 3.0)) โ
โ Quadrangle((8.0, 2.0), ..., (8.0, 3.0)) โ
โ Quadrangle((9.0, 2.0), ..., (9.0, 3.0)) โ
โ Quadrangle((0.0, 3.0), ..., (0.0, 4.0)) โ
โ                    โฎ                    โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
69 rows omitted


## BREAKING

• Deprecation of GeoClustering.jl, which now lives in GeoStatsTransforms.jl
• Deprecation of PointPatterns.jl, which now lives in GeoStatsProcesses.jl
• Kriging, IDW, etc. are now GeoStatsModels.jl instead of solvers
• GeoTables.jl now only holds the GeoTable type, and GeoIO.jl is the new home of load/save functions

7 Likes

Amazing.

Is, by any chance, anyone thinking/working on levereging the new Makie datashader for geo visualization?

Not working at the moment, but any contribution is welcome.

1 Like

# GeoStats.jl v0.49

New exciting features, including lazy transforms on meshes. This means that we can now map large geotiff, netcdf, grib, etc files to lazy TransformedGrid with the correct coordinates from the file, without any memory allocation:

using GeoStats
using GeoIO


2097152ร4 GeoTable over 2097152 TransformedGrid{2,Float64}
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ    BAND1    โ    BAND2    โ    BAND3    โ                        geometry                        โ
โ Categorical โ Categorical โ Categorical โ                       Quadrangle                       โ
โ  [NoUnits]  โ  [NoUnits]  โ  [NoUnits]  โ                                                        โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ     12      โ     11      โ     68      โ   Quadrangle((-180.0, 90.0), ..., (-180.0, 89.8242))   โ
โ     12      โ     11      โ     68      โ Quadrangle((-179.824, 90.0), ..., (-179.824, 89.8242)) โ
โ     12      โ     11      โ     68      โ Quadrangle((-179.648, 90.0), ..., (-179.648, 89.8242)) โ
โ     12      โ     11      โ     68      โ Quadrangle((-179.473, 90.0), ..., (-179.473, 89.8242)) โ
โ     12      โ     11      โ     68      โ Quadrangle((-179.297, 90.0), ..., (-179.297, 89.8242)) โ
โ     12      โ     11      โ     68      โ Quadrangle((-179.121, 90.0), ..., (-179.121, 89.8242)) โ
โ      โฎ      โ      โฎ      โ      โฎ      โ                           โฎ                            โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2097146 rows omitted


Even though this grid has 2048 x 1024 quadrangles, we can see that the size of the geometry column is 120 bytes:

sizeof(geotable.geometry)

120


We can still visualize the grid efficiently with Makie:

import GLMakie as Mke

viz(geotable.geometry, color = geotable.BAND1)


This puts us one step closer to the new coordinate system infrastructure, which is planned for the first semester of 2024.

Happy new year!

6 Likes

# GeoStats.jl v0.49.2

• Multi-threaded geojoin
• 3D intersects
• viz of large Polygon sets

and other small improvements on simulation of geospatial stochastic processes (e.g. Gaussian).

2 Likes

# GeoStats.jl v0.53

• New transforms:
• Aggregate
• Transfer
• Downscale
• Upscale

Given a geotable over a grid:

X = [i/20 * cos(3ฯ/2 * (j-1) / (30-1)) for i in 1:20, j in 1:30]
Y = [i/20 * sin(3ฯ/2 * (j-1) / (30-1)) for i in 1:20, j in 1:30]
sgrid = StructuredGrid(X, Y)
gtb = georef((a=rand(Float64, 551), b=rand(Int, 551)), sgrid)


These transforms can be used to change the resolution, or transfer the variables to other domains with nearest neighbor interpolation:

ngtb = gtb |> Downscale(2, 2)


They work with any Grid subtype, including CartesianGrid, RectilinearGrid and StructuredGrid. Please check the docstrings to learn more.

3 Likes

# GeoStats.jl v0.54

Various fixes and improvements to color treatment in viz and viewer.

## Breaking

• showfacets has been renamed to showsegments and showpoints
• facetcolor has been renamed to segmentcolor and pointcolor
• colorscheme has been renamed to colormap

## Features

• Now it is possible to pass the colorrange option to customize the color limits associated with a vector of values.
• New cbar for colorbars based on custom vectors of arbitrary Julia objects, including missing values, categorical, Distributions.jl, etc.
5 Likes

# GeoStats.jl v0.57

We are super excited with this release, which comes with full support for coordinate reference systems (CRS). Highly recommend the update if you are still using old versions of the project:

julia> using GeoStats

julia> grid = CartesianGrid(10, 10)
10ร10 CartesianGrid
โโ minimum: Point(x: 0.0 m, y: 0.0 m)
โโ maximum: Point(x: 10.0 m, y: 10.0 m)
โโ spacing: (1.0 m, 1.0 m)

julia> geotable = georef((; T = rand(100)u"K"), grid)
100ร2 GeoTable over 10ร10 CartesianGrid
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ     T      โ                          geometry                           โ
โ    [K]     โ                                                             โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 0.18959 K  โ Quadrangle((x: 0.0 m, y: 0.0 m), ..., (x: 0.0 m, y: 1.0 m)) โ
โ 0.620354 K โ Quadrangle((x: 1.0 m, y: 0.0 m), ..., (x: 1.0 m, y: 1.0 m)) โ
โ 0.609181 K โ Quadrangle((x: 2.0 m, y: 0.0 m), ..., (x: 2.0 m, y: 1.0 m)) โ
โ 0.577826 K โ Quadrangle((x: 3.0 m, y: 0.0 m), ..., (x: 3.0 m, y: 1.0 m)) โ
โ 0.417657 K โ Quadrangle((x: 4.0 m, y: 0.0 m), ..., (x: 4.0 m, y: 1.0 m)) โ
โ 0.995937 K โ Quadrangle((x: 5.0 m, y: 0.0 m), ..., (x: 5.0 m, y: 1.0 m)) โ
โ 0.134751 K โ Quadrangle((x: 6.0 m, y: 0.0 m), ..., (x: 6.0 m, y: 1.0 m)) โ
โ 0.581671 K โ Quadrangle((x: 7.0 m, y: 0.0 m), ..., (x: 7.0 m, y: 1.0 m)) โ
โ 0.968301 K โ Quadrangle((x: 8.0 m, y: 0.0 m), ..., (x: 8.0 m, y: 1.0 m)) โ
โ 0.89252 K  โ Quadrangle((x: 9.0 m, y: 0.0 m), ..., (x: 9.0 m, y: 1.0 m)) โ
โ 0.570824 K โ Quadrangle((x: 0.0 m, y: 1.0 m), ..., (x: 0.0 m, y: 2.0 m)) โ
โ     โฎ      โ                              โฎ                              โ
โโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
89 rows omitted


For example, notice the units in the regionalized variable and in the lags of empirical variograms:

julia> EmpiricalVariogram(geotable, :T)
EmpiricalVariogram
โโ abscissa: [0.0353553 m, 0.106066 m, 0.176777 m, ..., 1.23744 m, 1.30815 m, 1.41421 m]
โโ ordinate: [0.0 K^2, 0.0 K^2, 0.0 K^2, ..., 0.0 K^2, 0.0 K^2, 0.0783147 K^2]
โโ distance: Euclidean(0.0)
โโ estimator: MatheronEstimator()
โโ npairs: 342


Every single geometry and domain now has well-defined units, which is useful for various sorts of estimates in the physical world:

julia> quad = grid[1]
โโ Point(x: 0.0 m, y: 0.0 m)
โโ Point(x: 1.0 m, y: 0.0 m)
โโ Point(x: 1.0 m, y: 1.0 m)
โโ Point(x: 0.0 m, y: 1.0 m)

1.0 m^2

6 Likes

# GeoStats.jl v0.58

A quick release that makes the CRS explicit in GeoTables:

Notice the ๐ Cartesian{NoDatum} in the sub-header of the geometry column.

2 Likes

# GeoStats.jl v0.59

Another quick release to track the improvements in the Meshes.jl submodule:

3 Likes

For someone who has not used GeoStats.jl before, is there a tutorial to get started? I am interested in coordinates transform. Ie. Get my GPS utm Datum and transform them into X,Y,Z coordinates to compare WGS84 with AGD56 points.

Did you check the official documentation and the GDSJL book? They are the recommended resources. The book is a good starting point.

# GeoStats.jl v0.60

A few quality of life updates and speedups:

• New sideof(point, ring) and point โ poly with Hao et al. algorithm, which we implemented with multiple-threads. Speedup of ~12x. The algorithm is quite robust, and can handle all sorts of degenerate cases in 2D polygonal areas:
Code
using GeoStats
import GLMakie as Mke

r = rand(Ring{2})
b = boundingbox(r)
g = CartesianGrid(minimum(b), maximum(b), dims=(300,300))
ps = (centroid(g, i) for i in 1:nelements(g))
ss = sideof(ps, r)

viz(r)
viz!(g, color = ss .== IN, alpha = 0.5)


• GeoTables can now be explored in the VSCode viewer:

• GeoJSON files are now loaded with native Julia CRS:
5 Likes

# GeoStats.jl v0.62

Starting in this release, viz and viewer are aware of CRS and manifold of geometries stored in geotables. To give an example, here is how you visualize a geotable with LatLon coordinates:

using GeoStats
using GeoArtifacts

import GLMakie as Mke

viz(table.geometry)


You can also send the geotable to the viewer to explore different variables over the globe. For example, I selected the variable ABBREV in the dropdown menu:

table |> viewer


6 Likes

A few tweaks here and there, and we are now able to visualize moderately large โrasterโ data stored in GeoTIFF files with any CRS in native Julia.

To illustrate the feature, consider the following example with data from the NaturalEarth project:

using GeoStats
using GeoIO

import GLMakie as Mke

# upscale for 3D mesh visualization
coarse = raster |> Upscale(10, 10) # needs to be optimized

# send coarse scale to viewer
coarse |> viewer


# https://www.naturalearthdata.com/downloads/50m-cultural-vectors

viz!(bounds, color="cyan")


Now letโs add a random set of points with LatLon coordinates:

points = rand(Point, 100, crs=LatLon)

viz!(points, color="yellow")


Now letโs demonstrate the real benefit of native Julia CRS as opposed to โrawโ numbers with the PROJ library. Letโs project our data to a Robinson CRS and visualize again:

projcoarse = coarse |> Proj(Robinson)
projbounds = bounds |> Proj(Robinson)
projpoints = points |> Proj(Robinson)

projcoarse |> viewer
viz!(projbounds, color="cyan")
viz!(projpoints, color="yellow")


Letโs do the same with another favorite of mine, the WinkelTripel:

projcoarse = coarse |> Proj(WinkelTripel)
projbounds = bounds |> Proj(WinkelTripel)
projpoints = points |> Proj(WinkelTripel)

projcoarse |> viewer
viz!(projbounds, color="cyan")
viz!(projpoints, color="yellow")


Notice how the visualization automatically chooses a 2D axis for the Projected CRS types using Juliaโs multiple-dispatch. It is very easy to build advanced geographic maps in a few lines of code, and to parallelize things with multiple threads.

Of course there are tons of optimizations pending to make this experience more interactive and fast. We are working on it, and welcome pull requests with performance improvements.

You can reproduce the example above with the latest stable release of the stack.

13 Likes

It is so easy to optimize code in Julia In less than a week we addressed a couple of performance bottlenecks:

• The Upscale, Downscale, Aggregate and Transfer transforms were specialized for domains that are Grid using TiledIteration.jl instead of NearestNeighbors.jl. This means that they can be used with arbitrarily large โrastersโ now, and will produce instant results.
• GeoIO.jl now loads GeoTIFF datasets using true Colors.jl, and the viewer has been updated accordingly to show these colors. Below is an example with another NaturalEarth dataset:
using GeoStats
using GeoIO

coarse = raster |> Upscale(10, 10)
coarse |> viewer


• It turns out that many of our transforms were taking some time to precompile. For example, Rasterize was taking 12s. We added these transforms to our precompilation workload with PrecompileTools.jl and they are instant now on the first usage.

You can take advantage of these new features and speedups by updating your environment.

8 Likes

This is pretty cool! It looks like the normals on that spherical mesh are inverted though.

# GeoStats.jl v0.64

The viz and viewer were refactored to eliminate intermediate allocations. We are now calling the most efficient Makie.jl functions based on the rich information that is stored in our parametric geometry/mesh types.

To give a concrete example, we can now visualize large transformed โrastersโ transformed with any transform pipeline, including nonlinear transforms like Proj. You can repeat the example I gave in previous posts with Upscale(2, 2) and the resulting geotable with 5400x2700 pixels will be displayed in ~20s:

### Breaking changes

1. All topological relations (Boundary, Coboundary and Adjacency) return tuples instead of vectors. They no longer allocate for GridTopology, which gives a huge speed up in various parts of the project.
2. Nonlinear transforms with Primitive geometries are delayed with a new TransformedGeometry type. For example, we can Proj a geodesic Ball over the ellipsoid of the Earth to a flat Euclidean space and its boundary will be properly transformed.
6 Likes