GeoBlocks
Digital geo services rely on high resolution big data coming from multiple real-time sources. We developed GeoBlocks to make it easier to process and analyse (real-time) that data to create a digital geo service.
GeoBlocks is a GIS modelling toolbox that allows you to make on-the-fly analyses using raster & vector data stored in Lizard. Geoblocks consists of numerous classes which describe geographical operations. An individual class is called a Block and a combination of multiple Blocks is called a Graph.
Lizard uses GeoBlocks technology to derive two different types of data: Rasters and Labels. On top of the basic set of block operations (RasterBlocks) there is an additional set specifically for label computation (Geometry and Series Blocks). Geoblock rasters can be visualized through the WMS, analyzed through the API or exported to GeoTIFF. Geoblock labeltypes are used for computing labels on-the-fly or in a batch so that they are stored and available via the API.
GeoBlocks derives information on-the-fly, creating a “view” on your data. This is also the reason why it’s very efficient in data storage, as intermediate results do not have to be stored!
All Blocks are modular and can be combined with each other to create extensive models.
You can apply GeoBlocks on real-time data-flows that expand in space and time (e.g. remote sensing data), immediately processing data as it becomes available!
You can combine temporal and static datasets. For example, you can combine a static land cover raster with a daily soil moisture raster.
Unlike conventional GIS raster calculator solutions, you can combine data with different resolutions and varying spatial extent.
Open Source
The computational core of GeoBlocks is published open source under the name dask-geomodeling. Most operations are identical. Only the I/O filetype and configuration differs. The open source library can be used to build on-the-fly models on your own PC. Dask-geomodeling has a limitation in the complexity of the models that you can run locally. This is determined by your memory and processor capacity.
If you want to scale up your model or increase complexity you can do publish your model and data to Lizard using the Lizard API. The GeoBlocks engine uses the powerful Lizard backend allowing you to scale up your models and integrate the model in your geo services using the Lizard API and Lizard WMS capabilities.
Working with GeoBlocks
GeoBlocks are configured in JSON. Your graph can be edited by POSTing or PATCHing to the Lizard API. For this we advise using Postman, but any application with an API component can be used. Methods for POSTing geoblocks to Lizard are similar for rasters and labeltypes. The difference is that the a raster requires a RasterBlock as Graph endpoint and the labeltypes a GeometryBlock. On these pages explanation is provided on how to create or update a GeoBlock in Lizard.
Graphs
A graph is a combination of multiple Blocks that work together to create a “view” of one or more datasources in Lizard. A valid graph always contains one or more source Blocks and one endpoint, which is the final product of your GeoBlock. Once you’ve configured a graph, a visualisation of the graph is automatically generated. This visualisation can be requested using the API request below:
https://demo.lizard.net/api/v4/rasters/{uuid of raster}/visualize/?format=svg
Example of a graph
Below is an example of a valid Raster graph which calculates the difference between the digitial elevation rasters AHN3 and AHN2.
{
"graph": {
"AHN3": [
"lizard_nxt.blocks.LizardRasterSource",
"a60ad336-c95b-4fb6-b852-96fc352ee808"
],
"AHN2": [
"lizard_nxt.blocks.LizardRasterSource",
"65912f43-0b70-425a-b471-1883378578eb"
],
"difference": [
"geoblocks.raster.elemwise.Subtract",
"AHN3",
"AHN2"
]
},
"name": "difference",
}
This graph contains two SourceBlocks linking to the individual digital elevation rasters. Furthermore it contains only one operation which calculates the difference between the two inputs. This difference is also the endpoint as marked by the “name” field. The final “view” on the input data thus contains the difference between AHN3 and AHN2.
Getting familiar with GeoBlocks
We like helping you get more familiar with GeoBlocks. We’ve created a Jupyter Notebook to give you a hands-on experience with the basics of GeoBlocks. You can download it on our Github page. Make sure to follow the right installation procedures.
Any questions? We’re happy to help! You can contact our servicedesk on servicedesk@nelen-schuurmans.nl
API specification
RasterBlocks
RasterBlocks are the GeoBlocks that work with rasterdata. RasterBlocks operate on Lizard Rasterdata.
Creating a new RasterBlock
The first step of creating a new raster GeoBlock is making a new Lizard raster instance that will contain your graph. This can be done on the Lizard management page or by performing a POST on the API endpoint https://demo.lizard.net/api/v4/rasters/
The second step is PATCHing the source
element of your new raster. This element will contain the graph of your GeoBlock.
To PATCH your raster provide a valid JSON object for its source element, and perform a patch on https://demo.lizard.net/api/v4/rasters/{uuid of the new raster}/
An example of a valid PATCH object is provided below.
{
"source": {
"name": "difference",
"graph": {
"AHN3": [
"lizard_nxt.blocks.LizardRasterSource",
"a60ad336-c95b-4fb6-b852-96fc352ee808"
],
"AHN2": [
"lizard_nxt.blocks.LizardRasterSource",
"65912f43-0b70-425a-b471-1883378578eb"
],
"difference": [
"geoblocks.raster.elemwise.Subtract",
"AHN3",
"AHN2"
]
}
}
}
PATCHing a raster can be done multiple times, until you are happy with the final output.
Raster output
After you PATCH your raster, the changes immediately take effect. To view your GeoBlocks results you can access the raster via the Catalogue, Raster API endpoint or the Lizard WMS service.
If you want to show the result of your raster Geoblock it is easiest to use the Catalogue.
Search for your raster in the catalogue.
Open the raster in the API using the Open in API button.
Follow the link mentioned in the source_url attribute.
Operations
Raster data sources
- class lizard_nxt.blocks.LizardRasterSource
A RasterBlock that interfaces a Lizard RasterSource model instance
- Parameters:
uuid (string) – the UUID of the RasterSource object
Note
If a UUID of a raster (instead of a rastersource) is given, it will automatically be replaced by the Geoblock graph of that raster.
RasterBlocks that combine rasters
Module containing raster blocks that combine rasters.
- class dask_geomodeling.raster.combine.Group(*args)
Combine multiple rasters into a single one.
Operation to combine multiple rasters into one along all three axes (x, y and temporal). To only fill ‘no data’ values of input rasters that have the same temporal resolution
dask_geomodeling.raster.elemwise.FillNoData
is preferred.Values at equal timesteps in the contributing rasters are considered starting with the leftmost input raster. Therefore, values from rasters that are more ‘to the right’ are shown in the result. ‘no data’ values are transparent and will show data of rasters more ‘to the left’.
- Parameters:
*args (list of RasterBlocks) – list of rasters to be combined.
- Returns:
RasterBlock that combines all input rasters
- class lizard_nxt.blocks.LizardRasterGroup
A raster source that groups Lizard RasterLayers
- Parameters:
*args (uuid) – uuids of RasterLayers to group
Values in the contributing rasters are stacked left to right. Therefore values from rasters that are more ‘to the left’ are shadowed by values from rasters more ‘to the right’. However, ‘no data’ values are transparent and do not shadow underlying data values.
The temporal behavior of this block is different than the Group geoblock:
if a single time instance is requested, all frames nearest to the requested time are grouped into one raster
if no time is requested, all most recent frames are grouped into one raster
if a time period is requested a NotImplementedError is raised
This block also returns a raster containing the primary keys of the data origins. Use LizardRasterId to use that data.
- class lizard_nxt.blocks.LizardRasterId
This geoblock should be combined with LizardRasterGroup to obtain the id (primary key) of the RasterStore from which the data is coming.
- Parameters:
source (GroupLizardRaster) – grouped Lizard rasters to obtain origins from
Elementwise RasterBlocks
Module containing elementwise raster blocks.
- class dask_geomodeling.raster.elemwise.Add(a, b)
Add two rasters together or add a constant value to a raster.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Addition term a
b (RasterBlock, number) – Addition term b
- Returns:
RasterBlock containing the result of the addition.
- class dask_geomodeling.raster.elemwise.And(a, b)
Returns True where both inputs are True.
Either one or both of the inputs should be a boolean RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, boolean) – Logical term a
b (RasterBlock, boolean) – Logical term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.Divide(a, b)
Divide two rasters or divide a raster by a constant value.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Numerator
b (RasterBlock, number) – Denominator
- Returns:
RasterBlock containing the result of the division.
- class dask_geomodeling.raster.elemwise.Equal(a, b)
Compares the values of two rasters and returns True for equal elements.
This operation can be used to compare two rasters or to compare a raster with a static value. Note that ‘no data’ is not equal to ‘no data’: False is returned if any of the two terms is ‘no data’.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Comparison term a
b (RasterBlock, number) – Comparison term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.Exp(x)
Return e raised to the power of the raster values.
Out-of-range results (not representable by the resulting datatype) are set to no data.
- Parameters:
x (RasterBlock) – Raster
- Returns:
RasterBlock.
- class dask_geomodeling.raster.elemwise.FillNoData(*args)
Combines multiple rasters filling ‘no data’ values.
Values at equal timesteps in the contributing rasters are considered starting with the leftmost input raster. Therefore, values from rasters that are more ‘to the right’ are shown in the result. ‘no data’ values are transparent and will show data of rasters more ‘to the left’.
The temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
*args (list of RasterBlocks) – Rasters to be combined.
- Returns:
RasterBlock that combines values from the inputs.
- class dask_geomodeling.raster.elemwise.Greater(a, b)
Compares the values of two rasters and returns True if an element in the first term is greater.
This operation can be used to compare two rasters or to compare a raster with a static value. Note that False is returned if any of the two terms is ‘no data’.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Comparison term a
b (RasterBlock, number) – Comparison term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.GreaterEqual(a, b)
” Compares the values of two rasters and returns True if an element in the first term is greater or equal.
This operation can be used to compare two rasters or to compare a raster with a static value. Note that False is returned if any of the two terms is ‘no data’.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Comparison term a
b (RasterBlock, number) – Comparison term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.Invert(x)
Logically invert a raster (swap True and False).
Takes a single input raster containing boolean values and outputs a boolean raster with the same spatial and temportal properties.
- Parameters:
x (RasterBlock) – Boolean raster with values to invert
- Returns:
RasterBlock with boolean values opposite to the input raster.
- class dask_geomodeling.raster.elemwise.IsData(store)
Returns True where raster has data.
Takes a single input raster and outputs a boolean raster with the same spatial and temporal properties.
- Parameters:
store (RasterBlock) – Input raster
- Returns:
RasterBlock with boolean values.
- class dask_geomodeling.raster.elemwise.IsNoData(store)
Returns True where raster has no data.
Takes a single input raster and outputs a boolean raster with the same spatial and temporal properties.
- Parameters:
store (RasterBlock) – Input raster
- Returns:
RasterBlock with boolean values.
- class dask_geomodeling.raster.elemwise.Less(a, b)
Compares the values of two rasters and returns True if an element in the first term is less.
This operation can be used to compare two rasters or to compare a raster with a static value. Note that False is returned if any of the two terms is ‘no data’.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Comparison term a
b (RasterBlock, number) – Comparison term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.LessEqual(a, b)
Compares the values of two rasters and returns True if an element in the first term is less or equal.
This operation can be used to compare two rasters or to compare a raster with a static value. Note that False is returned if any of the two terms is ‘no data’.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Comparison term a
b (RasterBlock, number) – Comparison term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.Log(x)
Return natural logarithm of the raster values.
Out-of-range results (not representable by the resulting datatype) are set to no data as well as the result of input values < 0.
- Parameters:
x (RasterBlock) – Raster
- Returns:
RasterBlock.
- class dask_geomodeling.raster.elemwise.Log10(x)
Return the base 10 logarithm of the raster values.
Out-of-range results (not representable by the resulting datatype) are set to no data as well as the result of input values < 0.
- Parameters:
x (RasterBlock) – Raster
- Returns:
RasterBlock.
- class dask_geomodeling.raster.elemwise.Multiply(a, b)
Multiply two rasters or multiply a raster by a constant value.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Multiplication factor a
b (RasterBlock, number) – Multiplication factor b
- Returns:
RasterBlock containing the result of the multiplication.
- class dask_geomodeling.raster.elemwise.NotEqual(a, b)
Compares the values of two rasters and returns False for equal elements.
This operation can be used to compare two rasters or to compare a raster with a static value. Note that ‘no data’ is not equal to ‘no data’: True is returned if any of the two terms is ‘no data’.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Comparison term a
b (RasterBlock, number) – Comparison term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.Or(a, b)
Returns True where any of inputs is True.
Either one or both of the inputs should be a boolean RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, boolean) – Logical term a
b (RasterBlock, boolean) – Logical term b
- Returns:
RasterBlock containing boolean values
- class dask_geomodeling.raster.elemwise.Power(a, b)
Exponential function with either a raster and a number or two rasters.
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Base
b (RasterBlock, number) – Exponent
- Returns:
RasterBlock containing the result of the exponential function.
- class dask_geomodeling.raster.elemwise.Subtract(a, b)
Subtract two rasters or subtract a constant value from a raster
Either one or both of the inputs should be a RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, number) – Term be subtracted from
b (RasterBlock, number) – Term to be subtracted
- Returns:
RasterBlock containing the result of the function subtract.
- class dask_geomodeling.raster.elemwise.Xor(a, b)
Exclusive or: returns True where exactly one of the inputs is True.
Where both inputs are True, False is returned.
Either one or both of the inputs should be a boolean RasterBlock. In case of two raster inputs the temporal properties of the rasters should be equal, however spatial properties can be different.
- Parameters:
a (RasterBlock, boolean) – Logical term a
b (RasterBlock, boolean) – Logical term b
- Returns:
RasterBlock containing boolean values
Spatial RasterBlocks
Module containing raster blocks for spatial operations.
- class dask_geomodeling.raster.spatial.Dilate(store, values)
Perform spatial dilation on specific cell values.
Cells with values in the supplied list are spatially dilated by one cell in each direction, including diagonals.
Dilation is performed in the order of the values parameter.
- Parameters:
store (RasterBlock) – Raster to perform dilation on.
values (list) – Only cells with these values are dilated.
- Returns:
RasterBlock where cells in values list are dilated.
- class dask_geomodeling.raster.spatial.HillShade(store, altitude=45, azimuth=315, fill=0)
Calculate a hillshade from the raster values.
- Parameters:
store (RasterBlock) – Raster to which the hillshade algorithm is applied.
size (number) – Size of the effect in projected units.
altitude (number) – Light source altitude in degrees, defaults to 45.
azimuth (number) – Light source azimuth in degrees, defaults to 315.
fill (number) – Fill value to be used for ‘no data’ values.
- Returns:
Hillshaded raster
- class dask_geomodeling.raster.spatial.MovingMax(store, size)
Apply a spatial maximum filter to the data using a circular footprint.
This can be used for visualization of sparse data.
- Parameters:
store (RasterBlock) – Raster to which the filter is applied
size (integer) – Diameter of the circular footprint. This should always be an odd number larger than 1.
- Returns:
RasterBlock with maximum values inside the footprint of each input cell.
- class dask_geomodeling.raster.spatial.Place(store, place_projection, anchor, coordinates, statistic='last')
Place an input raster at given coordinates
Note that if the store’s projection is different from the requested one, the data will be reprojected before placing it at a different position.
- Parameters:
store (RasterBlock) – Raster that will be placed.
place_projection (str) – The projection in which this operation is done. This also specifies the projection of the
anchor
andcoordinates
args.anchor (list of 2 numbers) – The anchor into the source raster that will be placed at given coordinates.
coordinates (list of lists of 2 numbers) – The target coordinates. The center of the bbox will be placed on each of these coordinates.
statistic (str) – What method to use to merge overlapping rasters. One of: {“last”, “first”, “count”, “sum”, “mean”, “min”, “max”, “argmin”, “argmax”, “product”, “std”, “var”, “p<number>”}
- Returns:
RasterBlock with the source raster placed
- class dask_geomodeling.raster.spatial.Smooth(store, size, fill=0)
Smooth the values from a raster spatially using Gaussian smoothing.
- Parameters:
store (RasterBlock) – Raster to be smoothed
size (number) – The extent of the smoothing in meters. The ‘sigma’ value for the Gaussian kernal equals
size / 3
.fill (number) – ‘no data’ are replaced by this value during smoothing, defaults to 0.
- Returns:
RasterBlock with spatially smoothed values.
Temporal RasterBlocks
Module containing raster blocks for temporal operations.
- class dask_geomodeling.raster.temporal.Cumulative(source, statistic='sum', frequency=None, timezone='UTC')
Compute the cumulative of a raster over time.
Contrary to
dask_geomodeling.raster.temporal.TemporalAggregate
, in this operation the timedelta of the resulting raster equals the timedelta of the input raster. Cell values are accumulated over the supplied period. At the end of each period the accumulation is reset.- Parameters:
source (RasterBlock) – The input raster whose timesteps are accumulated.
statistic (string) – The type of accumulation to perform. Can be
"sum"
or"count"
. Defaults to"sum"
.frequency (string or None) – The period over which accumulation is performed. Supply a pandas offset string (see the references below). If this value is None, the accumulation will continue indefinitely. Defaults to None.
timezone (string) – Timezone in which the accumulation is performed, defaults to
"UTC"
.
- Returns:
RasterBlock with temporally accumulated data.
- class dask_geomodeling.raster.temporal.Shift(store, time)
Shift a temporal raster by some timedelta.
A positive timedelta shifts into the future and a negative timedelta shifts into the past.
- Parameters:
store (RasterBlock) – The store whose timestamps are to be shifted
time (integer) – The timedelta to shift the store, in milliseconds.
- Returns:
RasterBlock with its timestamps shifted.
- class dask_geomodeling.raster.temporal.Snap(store, index)
Snap the time structure of a raster to that of another raster.
This operations allows to take the cell values from one raster (‘store’) and the temporal properties of another raster (‘index’).
If the store is not a temporal raster, its cell values are copied to each timestep of the index raster. If the store is also a temporal raster, this operation looks at each ‘index’ timestamp and takes the closest ‘store’ timestamp as cell values.
- Parameters:
store (RasterBlock) – Return cell values from this raster
index (RasterBlock) – Snap values to the timestamps from this raster
- Returns:
RasterBlock with temporal properties of the index.
- class dask_geomodeling.raster.temporal.TemporalAggregate(source, frequency, statistic='sum', closed=None, label=None, timezone='UTC')
Resample a raster in time.
This operation performs temporal aggregation of rasters, for example a hourly average of data that has a 5 minute resolution.. The timedelta of the resulting raster is determined by the ‘frequency’ parameter.
- Parameters:
source (RasterBlock) – The input raster whose timesteps are aggregated
frequency (string or None) – The frequency to resample to, as pandas offset string (see the references below). If this value is None, this block will return the temporal statistic over the complete time range, with output timestamp at the end of the source raster period. Defaults to None.
statistic (string) – The type of statistic to perform. Can be one of
{"sum", "count", "min", "max", "mean", "median", "std", "var", "p<percentile>"}
. Defaults to"sum"
.closed (string or None) – Determines what side of the interval is closed. Can be
"left"
or"right"
. The default depends on the frequency.label (string or None) – Determines what side of the interval is closed. Can be
"left"
or"right"
. The default depends on the frequency.timezone (string) – Timezone to perform the resampling in, defaults to
"UTC"
.
- Returns:
RasterBlock with temporally aggregated data.
Miscelleneous RasterBlocks
Module containing miscellaneous raster blocks.
- class dask_geomodeling.raster.misc.Classify(store, bins, right=False)
Classify raster data into binned categories
Takes a RasterBlock and classifies its values based on bins. The bins are supplied as a list of increasing bin edges.
For each raster cell this operation returns the index of the bin to which the raster cell belongs. The lowest possible output cell value is 0, which means that the input value was lower than the lowest bin edge. The highest possible output value is equal to the number of supplied bin edges.
- Parameters:
store (RasterBlock) – The raster whose cell values are to be classified
bins (list) – An increasing list of bin edges
right (boolean) – Whether the intervals include the right or the left bin edge, defaults to False.
- Returns:
RasterBlock with classified values
- class dask_geomodeling.raster.misc.Clip(store, source)
Clip one raster to the extent of another raster.
Takes two raster inputs, one raster (‘store’) whose values are returned in the output and one raster (‘source’) that is used as the extent. Cells of the ‘store’ raster are replaced with ‘no data’ if there is no data in the ‘source’ raster.
If the ‘source’ raster is a boolean raster, False will result in ‘no data’.
Note that the input rasters are required to have the same time resolution.
- Parameters:
store (RasterBlock) – Raster whose values are clipped
source (RasterBlock) – Raster that is used as the clipping mask
- Returns:
RasterBlock with clipped values.
- property period
Return period datetime tuple.
- class dask_geomodeling.raster.misc.Mask(store, value)
Replace values in a raster with a single constant value. ‘no data’ values are preserved.
- Parameters:
store (RasterBlock) – The raster whose values are to be converted.
value (number) – The constant value to be given to ‘data’ values.
- Returns:
RasterBlock containing a single value
- class dask_geomodeling.raster.misc.MaskBelow(store, value)
Converts raster cells below the supplied value to ‘no data’.
Raster cells with values greater than or equal to the supplied value are returned unchanged.
- Parameters:
store (RasterBlock) – The raster whose values are to be masked.
value (number) – The constant value below which values are masked.
- Returns:
RasterBlock with cells below the input value converted to ‘no data’.
- class dask_geomodeling.raster.misc.Rasterize(source, column_name=None, dtype=None, limit=None)
Converts geometry source to raster
This operation is used to transform GeometryBlocks into RasterBlocks. Here geometries (from for example a shapefile) are converted to a raster, using the values from one of the columns.
Note that to rasterize floating point values, it is necessary to pass
dtype="float"
.- Parameters:
source (GeometryBlock) – The geometry source to be rasterized
column_name (string) – The name of the column whose values will be returned in the raster. If column_name is not provided, a boolean raster will be generated indicating where there are geometries.
dtype (string) – A numpy datatype specification to return the array. Defaults to ‘int32’ if column_name is provided, or to ‘bool’ otherwise.
- Returns:
RasterBlock with values from ‘column_name’ or a boolean raster.
- The global geometry-limit setting can be adapted as follows:
>>> from dask import config >>> config.set({"geomodeling.geometry-limit": 100000})
- class dask_geomodeling.raster.misc.RasterizeWKT(wkt, projection)
Converts a single geometry to a raster mask
- Parameters:
wkt (string) – the WKT representation of a geometry
projection (string) – the projection of the geometry
- Returns:
RasterBlock with True for cells that are inside the geometry.
- class dask_geomodeling.raster.misc.Reclassify(store, data, select=False)
Reclassify a raster of integer values.
This operation can be used to reclassify a classified raster into desired values. Reclassification is done by supplying a list of [from, to] pairs.
- Parameters:
store (RasterBlock) – The raster whose cell values are to be reclassified
bins (list) – A list of [from, to] pairs defining the reclassification. The from values can be of bool or int datatype; the to values can be of int or float datatype
select (boolean) – Whether to set all non-reclassified cells to ‘no data’, defaults to False.
- Returns:
RasterBlock with reclassified values
- class dask_geomodeling.raster.misc.Step(store, left=0, right=1, value=0, at=None)
Apply a step function to a raster.
This operation classifies the elements of a raster into three categories: less than, equal to, and greater than a value.
The step function is defined as follows, with x being the value of a raster cell:
‘left’ if x < value
‘at’ if x == value
‘right’ if x > value
- Parameters:
store (RasterBlock) – The input raster
left (number) – Value given to cells lower than the input value, defaults to 0
right (number) – Value given to cells higher than the input value, defaults to 1
value (number) – The constant value which raster cells are compared to, defaults to 0
at (number) – Value given to cells equal to the input value, defaults to the average of left and right
- Returns:
RasterBlock containing three values; left, right and at.
Geometry and Series Blocks
GeometryBlocks are the GeoBlocks that modify geometries or integrate rasterdata into geometries.
They can sample rasters and perform geometric operations like intersections and geometric differences.
The output from a Geometry GeoBlock is a label value.
This means that the operation should always end with a classification of one of the feature properties into a "label_value"
column.
Also, the generated label should be related to a Lizard object through the "object_id"
column. The object_type (e.g. "building"
) is configured when creating the labeltype.
The result of the GeometryBlock can be requested through the API.
Such request returns the label for a geometric feature along with a predefined list of intermediate results.
Creating a new GeometryBlock
To create a new GeometryBlock you have to POST the graph directly to the labeltypes api endpoint: https://demo.lizard.net/api/v4/labeltypes/.
Unlike for RasterBlocks it is not possible to define a GeometryBlock without the API.
Once the graph has been posted it is possible to PATCH changes and alter the structure of the graph.
If you want to patch changes to the graph this can be done by providing a valid JSON object for its source element,
and perform a patch on https://demo.lizard.net/api/v4/labeltypes/{uuid of the new labeltype}/
.
Currently it is not possible to visualize the resulting labels in the Lizard Viewer.
Individual labels can be computed with a GET request on the labeltype endpoint. For example with:
https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/compute/?geom_intersects=POINT(4.46648 51.92938)
.
It is also possible to pre-compute larger amounts of labels, which will either be exported to a downloadable file, or become available via https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/labels/.
By doing so it becomes possible to quickly request multiple labels or label statistics.
To pre-compute labels for a specific region you have to send a POST request on the labeltype endpoint, for example:
https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/compute/?boundary_id=95246&start=2018-10-01T01:00:00Z&tile_size=500&tile_projection=EPSG:28992&mode=centroid
.
For details about file exports, consult the documentation at https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/compute/
.
Labels that have been pre-computed are stored in the labels endpoint of the API: https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/labels/. By using this endpoint it is possible to request both individual labels and label statistics. Through a GET request it is possible to determine statistics of the entire labeltype or specific regions: https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/labels/counts/.
Examples of a graph
Geometry example: classify build year of buildings.
{
"source": {
"graph": {
"buildings": [
"geoblocks.geometry.sources.GeoDjangoSource",
"hydra_core",
"building",
{
"id": "object_id",
"build_year": "building_build_year"
},
"geometry",
"start",
"end"
],
"buildyear": [
"geoblocks.geometry.base.GetSeriesBlock",
"buildings",
"building_build_year"
],
"label": [
"geoblocks.geometry.field_operations.Classify",
"buildyear",
[
1900,
1940,
1970,
1990
],
[
"A",
"B",
"C",
"D",
"E"
]
],
"result": [
"geoblocks.geometry.base.SetSeriesBlock",
"buildings",
"label_value",
"label"
]
},
"name": "result"
}
}
Geometry output
Geometry outputs are stored in labels. Labels are always linked to your Vectors stored in the Vector Server, for instance flood risk for parcels or buildings. Labels are grouped in Labeltypes. The graph can be found via the labeltypes endpoint:
https://demo.lizard.net/api/v4/labeltypes/{label type uuid}/visualize/?format=svg
Individual labels (e.g. label linked to one building or parcel) can be found on the labels endpoint. Labels can be computed on the fly using the compute endpoint or a-sync using the Lizard Task Server.
Operations
Source GeometryBlocks
The following Geoblocks are current geometry source of geometry-type geoblocks. The geometry data comes from internal Lizard tables.
- class django_geoblocks.blocks.sources.GeoDjangoSource
Query a geodjango model.
- Parameters:
app_label (string) – The django app label
model_name (string) – Name of the django model
fields (dict) – a mapping
{<model field name>: <column name>, ...}
geometry_field_name (string) – geometry field name. Default ‘geometry’`.
start_field_name (string) – field name to use as start. Default None.
end_field_name (string) – field name to use as end. Default None.
filters (dict) – filters to apply to the model to select the records to add, of the form:
{<field lookup>: <value>, ...}
If
fields
is empty, only the geometry field is added by default. Ifstart_field_name
andend_field_name
are not given, this source will not use a temporal filters.
Note
app_label
should be “hydra_core” and model_name
should be one of “building”, “administrativeboundary”, “parcel”, “pumpeddrainagearea”, “fixeddrainagelevelarea”, “leveezone”, “pumpstation”, “groundwaterstation”, “measuringstation”, “polder”
- class django_geoblocks.blocks.sources.AddDjangoFields
Add a column to a GeometryBlock with data from a django model.
- Parameters:
source (GeometryBlock) – the data source to add extra properties to
app_label (string) – the django app label
model_name (string) – the name of the django model
filters (dict) – filters to apply to the model to select the records to add, of the form:
{<field lookup>: <value>, ...}
lookup (dict) – a single mapping to match the data from the source to the data being added:
{<field name>: <column name>}
fields (dict) – determines what fields will be added and how these will be named:
{<field name>: <column name>, ...}
start_field_name (string) – field name to use as start
end_field_name (string) – field name to use as end
The filters and lookup should be such that every existing geometry is matched to exactly one django model instance. If this is not the case, an arbitrary record will be taken.
If
start_field_name
andend_field_name
are not given, this source will not use a temporal filters.
Note
app_label
should be “lizard_nxt” and model_name
should be one of “labelparameter”, “labeltype”, “rasterlayer”
Aggregate GeometryBlocks
Module containing raster blocks that aggregate rasters.
- class dask_geomodeling.geometry.aggregate.AggregateRaster(source, raster, statistic='sum', projection=None, pixel_size=None, max_pixels=None, column_name='agg', auto_pixel_size=False, *args)
Compute statistics of a raster for each geometry in a geometry source.
A statistic is computed in a specific projection and with a specified cell size. If
projection
orpixel_size
are not given, these default to the native projection of the provided raster source.Should the combination of the requested pixel_size and the extent of the source geometry cause the required raster size to exceed
max_pixels
, thepixel_size
can be adjusted automatically ifauto_pixel_size
is set toTrue
, else (the default) a RuntimeError is raised.Please note that for any field operation on the result of this block a GetSeriesBlock should be used to retrieve data from the added column. The name of the added column is determined by the
column_name
parameter.- Parameters:
source (GeometryBlock) – The geometry source for which the statistics are determined.
raster (RasterBlock) – The raster source that is sampled.
statistic (str) – The type of statistical analysis that should be performed. The options are:
{"sum", "count", "min", "max", "mean", "median", "p<percentile>"}
. Percentiles are provided for example as follows:"p50"
. Default"sum"
.projection (str, optional) – Projection to perform the aggregation in, for example
"EPSG:28992"
. Defaults to the native projection of the supplied raster.pixel_size (float, optional) – The raster cell size used in the aggregation. Defaults to the cell size of the supplied raster.
max_pixels (int, optional) – The maximum number of pixels (cells) in the aggregation. Defaults to the
geomodeling.raster-limit
setting.column_name (str, optional) – The name of the column where the result should be placed. Defaults to
"agg"
.auto_pixel_size (boolean) – Determines whether the pixel size is adjusted automatically when
"max_pixels"
is exceeded. Default False.
- Returns:
GeometryBlock with aggregation results in an added column
- The global raster-limit setting can be adapted as follows:
>>> from dask import config >>> config.set({"geomodeling.raster-limit": 10 ** 9})
- class dask_geomodeling.geometry.aggregate.AggregateRasterAboveThreshold(source, raster, statistic='sum', projection=None, pixel_size=None, max_pixels=None, column_name='agg', auto_pixel_size=False, threshold_name=None)
Compute statistics of a per-feature masked raster for each geometry in a geometry source.
Per feature, a threshold can be supplied to mask the raster with. Only values that exceed the threshold of a specific feature are included for the statistical value of that feature.
See :class:
dask_geomodeling.geometry.aggregate.AggregateRaster
for further information.- Parameters:
*args – See :class:
dask_geomodeling.geometry.aggregate.AggregateRaster
threshold_name (str) – The column that holds the thresholds.
- Returns:
GeometryBlock with aggregation results in an added column
GeometryBlocks for set operations
Module containing geometry block set operations
- class dask_geomodeling.geometry.set_operations.Difference(source, other)
Calculate the geometric difference of two GeometryBlocks.
All geometries in the source GeometryBlock will be adapted by geometries with the same index from the second GeometryBlock. The difference operation removes any overlap between the geometries from the first geometry.
- Parameters:
source (GeometryBlock) – First geometry source.
other (GeometryBlock) – Second geometry source.
- Returns:
A GeometryBlock with altered geometries. Properties are preserved.
- class dask_geomodeling.geometry.set_operations.Intersection(source, other=None)
Calculate the intersection of a GeometryBlock with the request geometry.
Normally, geometries returned by a GeometryBlock may be partially outside of the requested geometry. This block ensures that the geometries are strictly inside the requested geometry by taking the intersection of each geometry with the request geometry.
- Parameters:
source (GeometryBlock) – Input geometry source.
- Returns:
A GeometryBlock with altered geometries. Properties are preserved.
Constructive for constructive operations
Module containing geometry block constructive operations
- class dask_geomodeling.geometry.constructive.Buffer(source, distance, projection, resolution=16)
Buffer (‘expand’) geometries with a given value.
A GeometryBlock and a buffer distance are provided. Each feature in the GeometryBlock is buffered with the distance provided, resulting in updated geometries.
- Parameters:
source (GeometryBlock) – The source GeometryBlock whose geometry will be updated.
distance (float) – The distance used to buffer all features. The distance is measured in the unit of the given projection (e.g. m, °).
projection (str) – The projection used in the operation provided in the format:
"EPSG:28992"
.resolution (integer, optional) – The resolution of the buffer provided as the number of points used to represent a quarter of a circle. The default value is
16
.
- Returns:
GeometryBlock with buffered geometries.
- class dask_geomodeling.geometry.constructive.Simplify(source, tolerance=None, preserve_topology=True)
Simplify geometries, mainly to make them computationally more efficient.
Provide a GeometryBlock and a tolerance value to simplify the geometries. As a result all features in the GeometryBlock are simplified.
- Parameters:
source (GeometryBlock) – Source of the geometries to be simplified.
tolerance (float) – The tolerance used in the simplification. If no tolerance is given the
"min_size"
request parameter is used.preserve_topology (boolean, optional) – Determines whether the topology should be preserved in the operation. Defaults to
True
.
- Returns:
GeometryBlock which was provided as input with a simplified geometry.
GeometryBlocks that operate on non-geometry fields
Module containing geometry block operations that act on non-geometry fields
- class dask_geomodeling.geometry.field_operations.Add(source, other)
Element-wise addition of SeriesBlock or number to another SeriesBlock.
- Parameters:
source (SeriesBlock) – First addition term
other (SeriesBlock or number) – Second addition term
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.And(source, other)
Perform an elementwise logical AND between two SeriesBlocks.
If a feature has a True value in both SeriesBlocks, True is returned, else False is returned.
- Parameters:
source (SeriesBlock) – First boolean term
other (SeriesBlock) – Second boolean term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.Classify(source, bins, labels, right=True)
Classify a value column into different bins
For example: every value below 3 becomes “A”, every value between 3 and 5 becomes “B”, and every value above 5 becomes “C”.
The provided SeriesBlock will be classified according to the given classification parameters. These parameters consist of two lists, one with the edges of the classification bins (i.e.
[3, 5]
) and one with the desired class output (i.e.["A", "B", "C"]
). The input data is then compared to the classification bins. In this example a value 1 is below 3 so it gets class"A"
. A value 4 is between 3 and 5 so it gets label"B"
.How values outside of the bins are classified depends on the length of the labels list. If the length of the labels equals the length of the binedges plus 1 (the above example), then values outside of the bins are classified to the first and last elements of the labels list. If the length of the labels equals the length of the bins minus 1, then values outside of the bins are classified to ‘no data’.
- Parameters:
source (SeriesBlock) – The (numeric) data which should be classified.
bins (list) – The edges of the classification intervals (i.e.
[3, 5]
).labels (list) – The classification returned if a value falls in a specific bin (i.e.
["A", "B", "C"]
). The length of this list is either one larger or one less than the length of thebins
argument. Labels should be unique.right (boolean, optional) – Determines what side of the intervals are closed. Defaults to True (the right side of the bin is closed so a value assigned to the bin on the left if it is exactly on a bin edge).
- Returns:
A SeriesBlock with classified values instead of the original numbers.
- class dask_geomodeling.geometry.field_operations.ClassifyFromColumns(source, value_column, bin_columns, labels, right=True)
Classify a continuous-valued geometry property based on bins located in other columns.
See :class:
dask_geomodeling.geometry.field_operations.Classify
for further information.- Parameters:
source (GeometryBlock) – The GeometryBlock which contains the column which should be clasified as well as columns with the bin edges.
value_column (str) – The column with (float) data which should be classified.
bin_columns (list) – A list of columns that contain the bins for the classification. The order of the columns should be from low to high values.
labels (list) – The classification returned if a value falls in a specific bin (i.e.
["A", "B", "C"]
). The length of this list is either one larger or one less than the length of thebins
argument. Labels should be unique.right (boolean, optional) – Determines what side of the intervals are closed. Defaults to True (the right side of the bin is closed so a value assigned to the bin on the left if it is exactly on a bin edge).
- Returns:
A SeriesBlock with classified values instead of the original floats.
- class dask_geomodeling.geometry.field_operations.Divide(source, other)
Element-wise division of SeriesBlock or number with another SeriesBlock.
Note that if you want to divide a constant value by a SeriesBlock (like
3 / series
, you have to doMultiply(3, Power(series, -1))
.- Parameters:
source (SeriesBlock) – Numerator
other (SeriesBlock or number) – Denominator
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.Equal(source, other)
Determine whether a SeriesBlock and a second SeriesBlock or a constant value are equal.
Note that ‘no data’ does not equal ‘no data’.
- Parameters:
source (SeriesBlock) – First comparison term
other (SeriesBlock or number) – Second comparison term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.FloorDivide(source, other)
Element-wise integer division of SeriesBlock or number with another SeriesBlock.
The outcome of the division is converted to the closest integer below (i.e. 3.4 becomes 3, 3.9 becomes 3 and -3.4 becomes -4)
- Parameters:
source (SeriesBlock) – Numerator
other (SeriesBlock or number) – Denominator
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.Greater(source, other)
Determine for each value in a SeriesBlock whether it is greater than a comparison value from a SeriesBlock or constant.
- Parameters:
source (SeriesBlock) – First comparison term
other (SeriesBlock or number) – Second comparison term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.GreaterEqual(source, other)
Determine for each value in a SeriesBlock whether it is greater than or equal to a comparison value from a SeriesBlock or constant.
- Parameters:
source (SeriesBlock) – First comparison term
other (SeriesBlock or number) – Second comparison term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.Invert(source, *args)
Invert a boolean SeriesBlock (swap True and False)
- Parameters:
source (SeriesBlock) – SeriesBlock with boolean values.
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.Less(source, other)
Determine for each value in a SeriesBlock whether it is less than a comparison value from a SeriesBlock or constant.
- Parameters:
source (SeriesBlock) – First comparison term
other (SeriesBlock or number) – Second comparison term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.LessEqual(source, other)
Determine for each value in a SeriesBlock whether it is less than or equal to a comparison value from a SeriesBlock or constant.
- Parameters:
source (SeriesBlock) – First comparison term
other (SeriesBlock or number) – Second comparison term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.Mask(source, cond, other)
Replace values in a SeriesBlock where values in another SeriesBlock are True.
Provide a source SeriesBlock, a conditional SeriesBlock (True/False) and a replacement value which can either be a SeriesBlock or a constant value. All entries in the source that correspond to a True value in the conditional are left unchanged. The values in the source that correspond to a True value in the conditional are replaced with the value from ‘other’.
- Parameters:
source (SeriesBlock) – Source SeriesBlock that is going to be updated
cond (SeriesBlock) – Conditional (boolean) SeriesBlock that determines whether features in the source SeriesBlock will be updated.
other (SeriesBlock or constant) – The value that should be used as a replacement for the source SeriesBlock where the conditional SeriesBlock is True.
- Returns:
SeriesBlock with updated values where condition is True.
- class dask_geomodeling.geometry.field_operations.Modulo(source, other)
Element-wise modulo (remainder after division) of SeriesBlock or number with another SeriesBlock.
Example: if the input is
[31, 5.3, -4]
and the modulus is3
, the outcome would be[1, 2.3, 2]
. The outcome is always postive and less than the modulus.- Parameters:
source (SeriesBlock) – Number
other (SeriesBlock or number) – Modulus
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.Multiply(source, other)
Element-wise multiplication of SeriesBlock or number with another SeriesBlock.
- Parameters:
source (SeriesBlock) – First multiplication factor
other (SeriesBlock or number) – Second multiplication factor
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.NotEqual(source, other)
Determine whether a SeriesBlock and a second SeriesBlock or a constant value are not equal.
Note that ‘no data’ does not equal ‘no data’.
- Parameters:
source (SeriesBlock) – First comparison term
other (SeriesBlock or number) – Second comparison term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.Or(source, other)
Perform an elementwise logical OR between two SeriesBlocks.
If a feature has a True value in any of the input SeriesBlocks, True is returned, else False is returned.
- Parameters:
source (SeriesBlock) – First boolean term
other (SeriesBlock) – Second boolean term
- Returns:
SeriesBlock with boolean values
- class dask_geomodeling.geometry.field_operations.Power(source, other)
Element-wise raise a SeriesBlock to the power of a number or another SeriesBlock.
For example, the inputs
[2, 4]
and2
will give output[4, 16]
.- Parameters:
source (SeriesBlock) – Base
other (SeriesBlock or number) – Exponent
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.Round(source, decimals=0)
Round each value in a SeriesBlock to the given number of decimals
- Parameters:
source (SeriesBlock) – SeriesBlock with float data that is rounded to the provided number of decimals.
decimals (int, optional) – number of decimal places to round to (default: 0). If decimals is negative, it specifies the number of positions to the left of the decimal point.
- Returns:
SeriesBlock with rounded values.
- class dask_geomodeling.geometry.field_operations.Subtract(source, other)
Element-wise subtraction of SeriesBlock or number with another SeriesBlock.
Note that if you want to subtract a SeriesBlock from a constant value (like
4 - series
, you have to doAdd(Multiply(series, -1), 4)
.- Parameters:
source (SeriesBlock) – First subtraction term
other (SeriesBlock or number) – Second subtraction term
- Returns:
SeriesBlock
- class dask_geomodeling.geometry.field_operations.Where(source, cond, other)
Replace values in a SeriesBlock where values in another SeriesBlock are False.
Provide a source SeriesBlock, a conditional SeriesBlock (True/False) and a replacement value which can either be a SeriesBlock or a constant value. All entries in the source that correspond to a True value in the conditional are left unchanged. The values in the source that correspond to a False value in the conditional are replaced with the value from ‘other’.
- Parameters:
source (SeriesBlock) – Source SeriesBlock that is going to be updated
cond (SeriesBlock) – Conditional (boolean) SeriesBlock that determines whether features in the source SeriesBlock will be updated.
other (SeriesBlock or constant) – The value that should be used as a replacement for the source SeriesBlock where the conditional SeriesBlock is False.
- Returns:
SeriesBlock with updated values where condition is False.
- class dask_geomodeling.geometry.field_operations.Xor(source, other)
Perform an elementwise logical exclusive OR between two SeriesBlocks.
If a feature has a True value in precisely one of the input SeriesBlocks, True is returned, else False is returned.
- Parameters:
source (SeriesBlock) – First boolean term
other (SeriesBlock) – Second boolean term
- Returns:
SeriesBlock with boolean values
Module containing text column operations that act on geometry blocks
- class dask_geomodeling.geometry.text.ParseTextColumn(source, source_column, key_mapping)
Parses a text column into (possibly multiple) value columns.
Key, value pairs need to be separated by an equal (
=
) sign.- Parameters:
source (GeometryBlock) – Data source
source_column (str) – Existing column in source.
key_mapping (dict) – Mapping containing pairs {key_name: column_name}:
Miscelleneous GeometryBlocks
Module containing operations that return series from geometry fields
- class dask_geomodeling.geometry.geom_operations.Area(source, projection)
Calculate the area of features in a GeometryBlock.
Provide a GeometryBlock and a projection. Returns the area of each individual geometry in the input block, in that projection.
- Parameters:
source (GeometryBlock) – Source GeometryBlock which contains the features.
projection (str) – Projection in which to compute the area (i.e.
"epsg:28992"
).
- Returns:
SeriesBlock with only the computed area
Module containing merge operation that act on geometry blocks
- class dask_geomodeling.geometry.merge.MergeGeometryBlocks(left, right, how='inner', suffixes=('', '_right'))
Merge two GeometryBlocks into one by index
Provide two GeometryBlocks with the same original source to make sure they can be matched on index. The additional SeriesBlocks that have been added to the GeometryBlock will be combined to one GeometryBlock that contains all the information.
- Parameters:
left (GeometryBlock) – The left GeometryBlock to be combined.
right (GeometryBlock) – The right GeometryBlock to be combined.
how (str, optional) –
The parameter that describes how the merge should be performed. There are four options:
"left"
: The resulting GeometryBlock will have all the features that are present in the left GeometryBlock, no matter the features in the right GeometryBlock."right"
: The resulting GeometryBlock will have all the features that are present in the right GeometryBlock, no matter the features in the left GeometryBlock."inner"
(default): The outcome will contain all the features that are present in both input GeometryBlocks. Features that are absent in one of the GeometryBlocks will be absent in the result.outer
: The result will contain all the features which are present in one of the input GeometryBlocks.
suffixes (tuple, optional) – Text to be added to the column names to distinguish whether they originate from the left or right GeometryBlock. Default:
("", "_right")
.
- Returns:
GeometryBlock that contains a combination of features and columns of the two input GeometryBlocks.