Public API

Types

GeoBasics.FastInGeometryType
FastInGeometry{T} <: Geometry{🌐, LatLon{WGS84Latest,Deg{T}}}

Abstract type identifying geometries over Earth's surface where a fast custom algorithm for checking point inclusion is available.

This package define a single concrete subtype GeoBorders. Custom subtypes in downstream packages should in most cases contain a field with GeoBorders type.

Extended Help

Type Parameter

The type parameter T represents the machine precision of the underlying coordinates and is expected to be a subtype of AbstractFloat for the public API. This is in line with the public API of Meshes.jl and CoordRefSystems.jl that this package heavily relies on.

Fast Inclusion Algorithm

The fast inclusion algorithm is quite simple and relies on having a bounding box defined for each polygon part of the FastInGeometry. The custom inclusion algorithm simply iterates through all polygons and prefilter points by checking inclusion in the bounding box (which is an almost free operation). This can have significant speed ups especially if the polygons have a lot of points.

The following methods are added to Base.in to exploit the fast inclusion algorithm for custom subtypes adhering to the FastInGeometry (or FastInDomain) interface:

  • Base.in(p, x::FastInGeometry)
  • Base.in(p, x::VALID_DOMAINS)
Input Types

The point p provided as input is internally converted to within the function by using to_cartesian_point(valuetype(x), p), so custom types representing points on the Earth's surface can also be used with Base.in by having a valid method for to_cartesian_point or to GeoPlottingHelpers.to_raw_lonlat which the former falls back to.

The VALID_DOMAINS type alias encompasses FastInDomain, GeometrySet with FastInGeometry elements and SubDomains of either of the previous domains.

Interface

For custom subtypes of FastInGeometry that do not contain a field that is a subtype of GeoBorders, the following methods are expected to be implemented:

  • geoborders: This should return the GeoBorders instance associated to the input. If this method is implemented, all the others are not strictly needed
  • polyareas: This should return an iterable of PolyArea instances contained in the custom geometry.
  • bboxes: This should return an iterable of Box instances representing the boundingboxes of each PolyArea returned by polyareas.

See the docstrings of the respective methods for more details.

source
GeoBasics.GeoBordersType
GeoBorders{T} <: FastInGeometry{T}

Basic geometry used to represent borders of countries/regions on Earth's surface, supporting a fast algorithm for checking point inclusion.

The polygons contained within a GeoBorders object are expected to satisfy the following two conditions (mainly in line with the GeoJSON standard):

  • The polygons must not cross the antimeridian (the 180° latitude line). If a polygon should encompass a region crossing the antimeridian, it shall be split into multiple polygons.
  • Each polygon must have its exterior/outer ring following a counter-clockwise orientation, and all of its interior rings (holes) having a clockwise orientation.

The parametric type T represent the machine precision of the underlying coordinates and should be a subtype of AbstractFloat.

Constructors

GeoBorders{T}(inp; fix_antimeridian_crossing)
GeoBorders(inp; fix_antimeridian_crossing)

Take an input object which can be a Geometry, Domain or a Vector (of geometries) and returns the GeoBorders instance containing all the polyareas contained in the provided object, optionally forcing the machine precision of all underlying coordinates to T <: AbstractFloat

For input geometries of the following plain types from Meshes.jl:

  • Multi
  • PolyArea
  • Box

the constructor will ensure the two conditions specified above, by eventually fixing both antimeridian crossings and ensuring correct orientation of polygons rings.

For input geometries that are already satisfying the FastInGeometry interface, the constructor will simply extract the polyareas assuming they are already in a correct form.

The fix_antimeridian_crossing keyword argument is only respected for plain Meshes geometries and can be set to false to disable fixing the antimeridian crossing by splitting polygons. This can be useful in some cases where polygons are purposedly made of long segments (spanning more than 180° of longitude) which would otherwise be split into multiple polyareas.

When the input is a single Geometry or Domain, the type parameter T can be omitted from the constructor and will be inferred using valuetype(input). When using a vector of geometries as input to the function, the machine precision T must be provided explicitly.

Note

The GeoBorders constructor will remove duplicate polyareas if any are present in the input polyareas after processing.

See also FastInGeometry, polyareas, bboxes, geoborders.

source
GeoBasics.FastInDomainType
FastInDomain{T} <: Domain{🌐, LatLon{WGS84Latest, Deg{T}}}

Abstract type representing a domain of FastInGeometry{T} geometries.

This type can be subtypes by custom types that represent domains and want to participate in the FastInGeometry interface for fast point inclusion.

See also: FastInGeometry, to_gset

Extended Help

Type Parameter

The type parameter T represents the machine precision of the underlying coordinates and is expected to be a subtype of AbstractFloat for the public API. This is in line with the public API of Meshes.jl and CoordRefSystems.jl that this package heavily relies on.

Fast Inclusion Algorithm

The fast inclusion algorithm is quite simple and relies on having a bounding box defined for each polygon part of the FastInGeometry. The custom inclusion algorithm simply iterates through all polygons and prefilter points by checking inclusion in the bounding box (which is an almost free operation). This can have significant speed ups especially if the polygons have a lot of points.

The following methods are added to Base.in to exploit the fast inclusion algorithm for custom subtypes adhering to the FastInGeometry (or FastInDomain) interface:

  • Base.in(p, x::FastInGeometry)
  • Base.in(p, x::VALID_DOMAINS)
Input Types

The point p provided as input is internally converted to within the function by using to_cartesian_point(valuetype(x), p), so custom types representing points on the Earth's surface can also be used with Base.in by having a valid method for to_cartesian_point or to GeoPlottingHelpers.to_raw_lonlat which the former falls back to.

The VALID_DOMAINS type alias encompasses FastInDomain, GeometrySet with FastInGeometry elements and SubDomains of either of the previous domains.

Interface

To properly work for fast point inclusion, the custom subtypes of FastInDomain need as a minimum to add valid methods to the following two functions from Meshes.jl:

  • Meshes.nelements(custom_domain): This should return the number of geometries within the domain
  • Meshes.element(custom_domain, ind): This should return the ind-th geometry from the domain
source

Interface Functions

GeoBasics.geobordersFunction
geoborders(geom)

Extract the Geo borders of the region/geometry provided as input.

This function expects the output to be an instance of the GeoBorders type.

By default, this function will try to extract the first field in the given type whose type is GeoBorders, so custom types do not need to add a method for this function explicitly if they do have a field that satisfies field isa GeoBorders.

Having a valid method of this function for custom geometries is sufficient to satisfy the FastInGeometry interface, as polyareas and bboxes have a default fallback which exploit this method.

See also polyareas, bboxes, FastInGeometry, to_multi.

source
GeoBasics.polyareasFunction
polyareas(crs, geom)
polyareas(crs)

Returns an iterable of the 2D PolyAreas associated to the input geometry defined over the Earth's surface.

Antimeridian

The PolyArea objects returned by this function are expected to represent polygons which never cross the antimeridian line (if a polygon is expected to cross the antimeridian line, it should be split into separate polygons divided at the antimeridian line). See the documentation of the package for more details.

Arguments

  • crs::Union{Type{LatLon}, Type{Cartesian}}: Specifies whether the returned vector of PolyArea elements should have LatLon{WGS84LatLon} or Cartesian2D{WGS84Latest} as underlying CRS.
  • geom: The input geometry.

When only the crs argument is provided, the function simply returns Base.Fix1(polyareas, crs).

See also geoborders, bboxes, FastInGeometry, to_multi.

Extended Help

When implementing the FastInGeometry interface for types where geoborders does not return a valid GeoBorders object (or for which a custom implementation of polyareas is preferred), one should implement the following two methods:

  • polyareas(::Type{Cartesian}, custom_geom)
  • polyareas(::Type{LatLon}, custom_geom)
Performance

To ensure optimal speed for the inclusion algorithm, it is recommended that this function returns a pre-computed iterable of PolyAreas rather than computing it at runtime, at least for the method with Cartesian as crs as that is used by the fast point inclusion algorithm.

source
GeoBasics.bboxesFunction
bboxes(crs, geom)
bboxes(crs)

Returns an iterable of the 2D Boxs associated to the input geometry defined over the Earth's surface.

Note

Each of the Box in the returned iterable is expected to be tied 1 to 1 to the PolyAreas returned by polyareas for the same input geometry and represents the PolyArea's bounding box (as returned by Meshes.boundingbox(poly)).

Arguments

  • crs::Union{Type{LatLon}, Type{Cartesian}}: Specifies whether the returned vector of Box elements should have LatLon{WGS84LatLon} or Cartesian2D{WGS84Latest} as underlying CRS.
  • geom: The input geometry.

When only the crs argument is provided, the function simply returns Base.Fix1(bboxes, crs).

See also geoborders, polyareas, FastInGeometry.

Extended Help

When implementing the FastInGeometry interface for types where geoborders does not return a valid GeoBorders object (or for which a custom implementation of bboxes is preferred), one should implement the following two methods:

  • bboxes(::Type{Cartesian}, custom_geom)
  • bboxes(::Type{LatLon}, custom_geom)
Performance

To ensure optimal speed for the inclusion algorithm, it is recommended that this function returns a pre-computed iterable of Boxs rather than computing it at runtime, at least for the method with Cartesian as crs as that is used by the fast point inclusion algorithm.

source

Helpers

GeoBasics.to_multiFunction
to_multi(crs, geom)
to_multi(crs)

Returns a Multi object containing the PolyAreas associated to the input geometry and returned by calling polyareas(crs, geom).

When called with just the crs type as argument, it simply returns Base.Fix1(to_multi, crs).

This is intended to simplify the generation of a plain Multi object for further processing using standard functions from Meshes.jl.

GeoBasics explicitly avoids extending methods from Meshes.jl on FastInGeometry objects to encourage users to explicitly decide whether to use the LatLon or Cartesian CRS instead of magically taking a decision on their behalf.

Performance

The computational cost of this function for types which have a valid method for geoborders is almost free (~1-2 nanoseconds).

See also geoborders, polyareas, bboxes, FastInGeometry.

source
GeoBasics.to_gsetFunction
to_gset(crs, dmn)
to_gset(crs)

Returns a GeometrySet object containing the PolyAreas associated to the input domain and returned by concatenating the output of polyareas(crs, geom) for each geometry geom in the input domain dmn.

When called with just the crs type as argument, it simply returns Base.Fix1(to_gset, crs).

This is intended to simplify the generation of a plain GeometrySet object of the desired CRS for further processing using standard functions from Meshes.jl. It is the parallel of to_multi for domains rather than geometries.

GeoBasics explicitly avoids extending methods from Meshes.jl on domains of FastInGeometry objects to encourage users to explicitly decide whether to use the LatLon or Cartesian CRS instead of magically taking a decision on their behalf.

See also to_multi, polyareas, bboxes, FastInGeometry.

source
GeoBasics.to_cartesian_pointFunction
to_cartesian_point(T::Type{<:AbstractFloat}, obj)
to_cartesian_point(T::Type{<:AbstractFloat})
to_cartesian_point(obj)

Extracts the lat/lon coordinates associated to input obj and return them as a Point from Meshes with Cartesian2D{WGS84Latest} as CRS and optionally forcing the underlying machine precision of the coordinates to T.

The second method simply returns Base.Fix1(to_cartesian_point, T).

The third method, will try to extract the machine precision from obj by calling BasicTypes.valuetype(obj).

Note

This function exploits GeoPlottingHelpers.to_row_lonlat internally so any object that has a valid method for to_row_lonlat will work as input.

Examples

julia> using GeoBasics

julia> to_cartesian_point(Float32, (10, 20)) # Force precision to `Float32`
Point with Cartesian{WGS84Latest} coordinates
├─ x: 10.0f0 m
└─ y: 20.0f0 m

julia> to_cartesian_point(LatLon(20,10)) # Extract precision from `LatLon` input
Point with Cartesian{WGS84Latest} coordinates
├─ x: 10.0 m
└─ y: 20.0 m

See also to_latlon_point, to_point.

source
GeoBasics.to_latlon_pointFunction
to_latlon_point(T::Type{<:AbstractFloat}, obj)
to_latlon_point(T::Type{<:AbstractFloat})
to_latlon_point(obj)

Extracts the lat/lon coordinates associated to input obj and return them as a Point from Meshes with LatLon{WGS84Latest} as CRS and optionally forcing the underlying machine precision of the coordinates to T.

The second method simply returns Base.Fix1(to_latlon_point, T).

The third method, will try to extract the machine precision from obj by calling BasicTypes.valuetype(obj).

Note

This function exploits GeoPlottingHelpers.to_row_lonlat internally so any object that has a valid method for to_row_lonlat will work as input.

Examples

julia> using GeoBasics

julia> to_latlon_point(Float32, (10, 20)) # Force precision to `Float32`
Point with GeodeticLatLon{WGS84Latest} coordinates
├─ lat: 20.0f0°
└─ lon: 10.0f0°

julia> to_latlon_point(LatLon(20,10)) # Extract precision from `LatLon` input
Point with GeodeticLatLon{WGS84Latest} coordinates
├─ lat: 20.0°
└─ lon: 10.0°

See also to_cartesian_point, to_point.

source
GeoBasics.to_pointFunction
to_point(crs::VALID_CRS)
to_point(crs::VALID_CRS, args...)

Convenience method to call either to_cartesian_point or to_latlon_point depending on the input CRS (either LatLon or Cartesian).

The first method simply returns the specific function depending on the CRS provided

The second method will forward the extra args... to the specfic function based on the CRS provided as first argument.

See also to_cartesian_point, to_latlon_point.

source
GeoBasics.get_latFunction
get_lat(p)

Extracts the latitude from a point p and returns it expressed in degrees and without a unit.

Note

This function exploits GeoPlottingHelpers.to_row_lonlat internally so any object that has a valid method for to_row_lonlat will work as input.

See also get_lon.

source
GeoBasics.get_lonFunction
get_lon(p)

Extracts the longitude from a point p and returns it expressed in degrees and without a unit.

Note

This function exploits GeoPlottingHelpers.to_row_lonlat internally so any object that has a valid method for to_row_lonlat will work as input.

See also get_lat.

source
Base.keepat!Method
Base.keepat!(gb::GeoBorders, inds)

Keep the polyareas and bboxes (for both CRSs) associated to the provided indices inds from the GeoBorders object.

Note

This is simply calling Base.keepat! with provided indices to all the arrays of polyareas/bboxes contained in GeoBorders. It is just intended as an easier and more consistent way to remove specific elements from GeoBorders instances, as removal have to be done from all the underlying arrays at the same time.

source
Base.deleteat!Method
Base.deleteat!(gb::GeoBorders, inds)

Remove the polyareas and bboxes (for both CRSs) associated to the provided indices inds from the GeoBorders object.

Note

This is simply calling Base.deleteat! with provided indices to all the arrays of polyareas/bboxes contained in GeoBorders. It is just intended as an easier and more consistent way to remove specific elements from GeoBorders instances, as removal have to be done from all the underlying arrays at the same time.

source