Skip to content

Commit

Permalink
Merge pull request #576 from EOxServer/wms-heatmap
Browse files Browse the repository at this point in the history
feat(heatmap): add heatmap sub-layer for collection layers
  • Loading branch information
jankovicgd authored Nov 8, 2024
2 parents f9c8a21 + 429de94 commit 0f352d9
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 16 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ jobs:
- name: Start the services and install test dependencies
run: |
echo "DB=spatialite" >> sample.env
docker-compose config
docker-compose up -d
docker-compose ps
docker exec -i eoxserver_autotest_1 pip3 install scipy
docker compose config
docker compose up -d
docker compose ps
docker exec -i eoxserver-autotest-1 pip3 install scipy
- name: Run the tests
env:
COMPOSE_INTERACTIVE_NO_CLI: 1
run: |
docker exec -i eoxserver_autotest_1 python3 ${{ matrix.command }}
docker exec -i eoxserver-autotest-1 python3 ${{ matrix.command }}
- name: Upload logs and outputs of failed tests
uses: 'actions/upload-artifact@v2'
uses: 'actions/upload-artifact@v3'
with:
name: logs ${{ matrix.command }}
path: |
Expand Down
88 changes: 86 additions & 2 deletions autotest/autotest/data/meris/meris_products_rgb.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@
{
"model": "coverages.eoobject",
"pk": 15,
"fields": {
"identifier": "product_mosaic_MER_FRS_1PNPDE20060822_092058_000001972050_00308_23408_0077_RGB_reduced",
"begin_time": "2006-08-22T09:20:58Z",
"end_time": "2006-08-22T09:24:15Z",
"footprint": "SRID=4326;MULTIPOLYGON (((11.45216499930154 46.21538203826643, 12.56460056524387 46.07713899233252, 13.88709473239655 45.89816054555529, 15.27428923693798 45.68087382785627, 16.73263457380611 45.44978576355449, 18.91093599972647 45.05191679046387, 20.40860552393306 44.74801169950303, 21.96696659827764 44.41194128767518, 23.51904328524226 44.04201602215931, 25.09349524830671 43.64372208846083, 24.69762334871068 42.82058014584347, 24.09572551417862 41.52681585719382, 23.44873586198113 40.08086776323874, 22.98946525457247 39.02515181830724, 22.50232224402901 37.85145204973027, 22.01522231099019 36.64248172093542, 21.49885247842534 35.30701482357061, 20.94415866775533 33.81513728290902, 20.38639122031948 32.26692667976634, 19.56420468222143 32.47301341272738, 18.2080921891265 32.79995702514136, 16.63597483093452 33.15675496605559, 15.04583039593244 33.49010596857972, 13.46867305396488 33.80242022189355, 11.78865627996702 34.11762771456879, 10.10198645739054 34.40475932684974, 8.778925655898064 34.61206991018219, 9.065762626406386 35.93773536210887, 9.314689072633191 37.04263450498039, 9.571219329906695 38.21169286827537, 9.910891562982675 39.70883235016088, 10.25693665372459 41.23523865932673, 10.57063808257736 42.57173906512232, 10.80473516394502 43.56727382751684, 11.06940217936636 44.65704022384523, 11.28225456261711 45.55003941502519, 11.45216499930154 46.21538203826643)))",
"inserted": "2019-01-01T00:00:00.000Z",
"updated": "2019-01-01T00:00:00.000Z"
}
},
{
"model": "coverages.eoobject",
"pk": 16,
"fields": {
"identifier": "mosaic_MER_FRS_1PNPDE20060830_100949_000001972050_00423_23523_0079_RGB_reduced",
"begin_time": "2006-08-30T10:09:49Z",
"end_time": "2006-08-30T10:13:06Z",
"footprint": "SRID=4326;MULTIPOLYGON (((-0.7697718236173799 46.21844540418552, 0.288547363821689 46.08290644415141, 2.733419759721718 45.73636263672618, 4.815657039292408 45.39947037754385, 6.894775798282314 45.00948175187284, 8.154913571318612 44.75018471574041, 9.634245839133294 44.41952395308687, 11.00618247148604 44.10606584164272, 12.27883282764158 43.79980935386448, 12.87473445741455 43.64035642239579, 12.22874811272635 42.2970241539363, 11.42842470078386 40.54055904761669, 10.66098787948851 38.74418401722271, 9.927539260629768 36.9630879853842, 9.239587579469651 35.18226041011476, 8.728287480275119 33.80781071010245, 8.174463354403226 32.26454057758526, 7.346658308388547 32.47445746391359, 5.48900097684443 32.9147209085525, 3.594912710998026 33.32929471736243, 1.679561673218221 33.71894896552116, -0.256213475006078 34.08288220106373, -1.744083689584682 34.34057243249224, -3.43798101398678 34.6029479595267, -3.312138031931722 35.20050022128398, -2.96861379128801 36.75709370137025, -2.682010254826003 38.05579573474809, -2.350758514252345 39.51733579731436, -1.942069312500661 41.30092067756908, -1.553859522839208 42.94621606148156, -1.166995203885614 44.59251101422208, -0.7697718236173799 46.21844540418552)))",
"inserted": "2019-01-01T00:00:00.000Z",
"updated": "2019-01-01T00:00:00.000Z"
}
},
{
"model": "coverages.eoobject",
"pk": 17,
"fields": {
"identifier": "MER_FRS_1P_reduced_products_RGB",
"begin_time": "2006-08-16T09:09:29Z",
Expand All @@ -30,7 +54,29 @@
"product_type": 1,
"package": null,
"collections": [
15
17
]
}
},
{
"model": "coverages.product",
"pk": 15,
"fields": {
"product_type": 1,
"package": null,
"collections": [
17
]
}
},
{
"model": "coverages.product",
"pk": 16,
"fields": {
"product_type": 1,
"package": null,
"collections": [
17
]
}
},
Expand All @@ -44,7 +90,7 @@
},
{
"model": "coverages.collection",
"pk": 15,
"pk": 17,
"fields": {
"collection_type": 1,
"grid": null
Expand Down Expand Up @@ -80,6 +126,44 @@
"height": 449
}
},
{
"model": "coverages.browse",
"pk": 2,
"fields": {
"storage": null,
"location": "/opt/instance/autotest/data/meris/mosaic_MER_FRS_1P_reduced_RGB/mosaic_ENVISAT-MER_FRS_1PNPDE20060822_092058_000001972050_00308_23408_0077_RGB_reduced.tif",
"format": null,
"product": 15,
"browse_type": null,
"style": null,
"coordinate_reference_system": "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433],AUTHORITY[\"EPSG\",\"4326\"]]",
"min_x": 8.47845,
"min_y": 32.19025,
"max_x": 25.4101500,
"max_y": 46.268645,
"width": 540,
"height": 449
}
},
{
"model": "coverages.browse",
"pk": 3,
"fields": {
"storage": null,
"location": "/opt/instance/autotest/data/meris/mosaic_MER_FRS_1P_reduced_RGB/mosaic_ENVISAT-MER_FRS_1PNPDE20060830_100949_000001972050_00423_23523_0079_RGB_reduced.tif",
"format": null,
"product": 16,
"browse_type": null,
"style": null,
"coordinate_reference_system": "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433],AUTHORITY[\"EPSG\",\"4326\"]]",
"min_x": -3.75,
"min_y": 32.19025,
"max_x": 13.213055,
"max_y": 46.268645,
"width": 541,
"height": 449
}
},
{
"model": "coverages.masktype",
"pk": 1,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions autotest/autotest_services/tests/wms/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class WMS13GetMapTestCase(testbase.RasterTestCase):
frmt = "image/jpeg"
time = None
dim_bands = None
dim_range = None

swap_axes = True

Expand Down Expand Up @@ -128,6 +129,9 @@ def getRequest(self):
if self.dim_bands:
params += "&dim_bands=%s" % self.dim_bands

if self.dim_range:
params += "&dim_range=%s" % self.dim_range

if self.httpHeaders is None:
return (params, "kvp")
else:
Expand Down
16 changes: 16 additions & 0 deletions autotest/autotest_services/tests/wms/test_v13.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,22 @@ class WMS13GetMapDatasetStyledTestCase(wmsbase.WMS13GetMapTestCase):
styles = ("color",)
frmt = "image/png"


# ==============================================================================
# Heatmap
# ==============================================================================

class WMS13GetMapCollectionHeatmapTestCase(wmsbase.WMS13GetMapTestCase):
fixtures = MASK_FIXTURES

layers = ["MER_FRS_1P_reduced_products_RGB__heatmap"]
height = 50
width = 100
bbox = [-3.75, 32.158895, 28.326165, 46.3]
dim_range = "0 5"
frmt = "image/png"


#===============================================================================
# Feature Info
#===============================================================================
Expand Down
11 changes: 11 additions & 0 deletions documentation/users/instance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,19 @@ EOXS_MAPSERVER_LAYER_FACTORIES
'eoxserver.render.mapserver.factories.MaskLayerFactory',
'eoxserver.render.mapserver.factories.MaskedBrowseLayerFactory',
'eoxserver.render.mapserver.factories.OutlinesLayerFactory',
'eoxserver.render.mapserver.factories.HeatmapLayerFactory',
]
DEFAULT_EOXS_MAPSERVER_HEATMAP_RANGE_DEFAULT = (0, 10)
The default range for heatmap layers when none are provided via ``dim_range``.

Default:

.. code-block:: python
(0, 10)
EOXS_COVERAGE_METADATA_FORMAT_READERS
The list of coverage metadata readers that will be employed to read metadata
when a new coverage is registered.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions documentation/users/operations/management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ This results in a catalog of the following available layers:
geometries.
- ``Collection__outlined``: this is a combination of the previous two layers:
each Product is rendered in ``TRUE_COLOR`` with its outlines highlighted.
- ``Collection__heatmap``: this renders the heatmap of the Products footprints.
- ``Collection__TRUE_COLOR``, ``Collection__FALSE_COLOR``,
``Collection__NDVI``: these are the browse visualizations with the
definintions from earlier.
Expand Down Expand Up @@ -435,6 +436,8 @@ The following list shows all of these rendering options with an example product
+-----------------------------------+---------------------------------------------------+
| ``Collection__outlined`` | .. figure:: images/product_outlined.png |
+-----------------------------------+---------------------------------------------------+
| ``Collection__heatmap`` | .. figure:: images/product_heatmap.png |
+-----------------------------------+---------------------------------------------------+
| ``Collection__validity`` | .. figure:: images/product_validity.png |
+-----------------------------------+---------------------------------------------------+
| ``Collection__masked_validity`` | .. figure:: images/product_masked_validity.png |
Expand Down
6 changes: 5 additions & 1 deletion documentation/users/services/wms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ parameters that are available with GetMap requests.
| | mask of the provided ``mask-name``. | | |
| | - ``<browse-type-name>``: renders the product(s) | | |
| | according to the browse types instructions (or uses | | |
| | an already existing browse if available. | | |
| | an already existing browse if available) | | |
| | | | |
| | - ``Collection`` | | |
| | - ``heatmap``: renders the contained products in a | | |
| | heatmap. | | |
+---------------------------+-----------------------------------------------------------+----------------------------------+--------------------------------+
| styles | The style for each of the rendered layers to be | | M |
| | rendered with. This must be either empty or a | | |
Expand Down
22 changes: 21 additions & 1 deletion eoxserver/render/map/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
# ------------------------------------------------------------------------------

from weakref import proxy
from typing import List
from typing import List, Optional, Tuple

from django.contrib.gis.geos import GEOSGeometry

from eoxserver.render.coverage.objects import (
GRID_TYPE_TEMPORAL, GRID_TYPE_ELEVATION, Coverage, Mosaic,
Expand Down Expand Up @@ -293,6 +295,24 @@ def fill(self):
return self._fill


class HeatmapLayer(Layer):
""" Representation of a heatmap layer.
"""
def __init__(self, name: str, style: str, footprints: List[GEOSGeometry],
range: Optional[Tuple[float, float]] = None):
super(HeatmapLayer, self).__init__(name, style)
self._footprints = footprints
self._range = range

@property
def footprints(self) -> List[GEOSGeometry]:
return self._footprints

@property
def range(self) -> Optional[Tuple[float, float]]:
return self._range


class Map(object):
""" Abstract interpretation of a map to be drawn.
"""
Expand Down
7 changes: 7 additions & 0 deletions eoxserver/render/mapserver/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,11 @@
'eoxserver.render.mapserver.factories.MaskLayerFactory',
'eoxserver.render.mapserver.factories.MaskedBrowseLayerFactory',
'eoxserver.render.mapserver.factories.OutlinesLayerFactory',
'eoxserver.render.mapserver.factories.HeatmapLayerFactory',
]


# default for EOXS_MAPSERVER_HEATMAP_RANGE_DEFAULT: the default range for Heatmap
# render requests

DEFAULT_EOXS_MAPSERVER_HEATMAP_RANGE_DEFAULT = (0, 10)
Loading

0 comments on commit 0f352d9

Please sign in to comment.