Public API
Types
GeoBasics.FastInGeometry
— TypeFastInGeometry{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)
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 SubDomain
s 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 theGeoBorders
instance associated to the input. If this method is implemented, all the others are not strictly neededpolyareas
: This should return an iterable ofPolyArea
instances contained in the custom geometry.bboxes
: This should return an iterable ofBox
instances representing the boundingboxes of eachPolyArea
returned bypolyareas
.
See the docstrings of the respective methods for more details.
GeoBasics.GeoBorders
— TypeGeoBorders{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.
The GeoBorders
constructor will remove duplicate polyareas if any are present in the input polyareas after processing.
See also FastInGeometry
, polyareas
, bboxes
, geoborders
.
GeoBasics.FastInDomain
— TypeFastInDomain{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)
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 SubDomain
s 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 domainMeshes.element(custom_domain, ind)
: This should return theind
-th geometry from the domain
Interface Functions
GeoBasics.geoborders
— Functiongeoborders(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
.
GeoBasics.polyareas
— Functionpolyareas(crs, geom)
polyareas(crs)
Returns an iterable of the 2D PolyArea
s associated to the input geometry defined over the Earth's surface.
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 ofPolyArea
elements should haveLatLon{WGS84LatLon}
orCartesian2D{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)
GeoBasics.bboxes
— Functionbboxes(crs, geom)
bboxes(crs)
Returns an iterable of the 2D Box
s associated to the input geometry defined over the Earth's surface.
Each of the Box
in the returned iterable is expected to be tied 1 to 1 to the PolyArea
s 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 ofBox
elements should haveLatLon{WGS84LatLon}
orCartesian2D{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)
Helpers
GeoBasics.to_multi
— Functionto_multi(crs, geom)
to_multi(crs)
Returns a Multi
object containing the PolyArea
s 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.
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
.
GeoBasics.to_gset
— Functionto_gset(crs, dmn)
to_gset(crs)
Returns a GeometrySet
object containing the PolyArea
s 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
.
GeoBasics.to_cartesian_point
— Functionto_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)
.
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
.
GeoBasics.to_latlon_point
— Functionto_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)
.
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
.
GeoBasics.to_point
— Functionto_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
.
GeoBasics.get_lat
— Functionget_lat(p)
Extracts the latitude from a point p
and returns it expressed in degrees and without a unit.
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
.
GeoBasics.get_lon
— Functionget_lon(p)
Extracts the longitude from a point p
and returns it expressed in degrees and without a unit.
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
.
Base.keepat!
— MethodBase.keepat!(gb::GeoBorders, inds)
Keep the polyareas and bboxes (for both CRSs) associated to the provided indices inds
from the GeoBorders
object.
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.
Base.deleteat!
— MethodBase.deleteat!(gb::GeoBorders, inds)
Remove the polyareas and bboxes (for both CRSs) associated to the provided indices inds
from the GeoBorders
object.
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.