Skip to content

Commit

Permalink
implement pygeoapi
Browse files Browse the repository at this point in the history
  • Loading branch information
nicokant committed Nov 14, 2023
1 parent b0f9d15 commit e687d6d
Show file tree
Hide file tree
Showing 21 changed files with 1,331 additions and 32 deletions.
6 changes: 6 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
"metadata_catalogue.core",
"metadata_catalogue.datasets",
"metadata_catalogue.datasets.csw",
"metadata_catalogue.datasets.geoapi",
]
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Expand Down Expand Up @@ -310,3 +311,8 @@
"repository": "metadata_catalogue.datasets.repository.DatasetsRepository",
"mappings": "metadata_catalogue.datasets.mappings",
}

GEOAPI = {
"cors": False,
"gzip": False,
}
1 change: 1 addition & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
path("accounts/", include("allauth.urls")),
path("ht/", include("health_check.urls")),
path("csw/", include("metadata_catalogue.datasets.csw.urls")),
path("geoapi/", include("metadata_catalogue.datasets.geoapi.urls")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


Expand Down
3 changes: 1 addition & 2 deletions metadata_catalogue/datasets/csw/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


class CSWConfig(SingletonModel):
language = models.CharField(max_length=7, null=True, blank=True)
max_records = models.IntegerField(default=10)
profiles = models.TextField(default="apiso", blank=True)
pretty_print = models.BooleanField(default=False)
Expand All @@ -21,7 +20,7 @@ def get_config(self, url=""):
"home": ".",
"mimetype": "application/xml; charset=UTF-8",
"encoding": "UTF-8",
"language": self.language or "en-US",
"language": info.language or "en-US",
"maxrecords": str(self.max_records),
"pretty_print": "true" if self.pretty_print else "false",
"url": url,
Expand Down
Empty file.
6 changes: 6 additions & 0 deletions metadata_catalogue/datasets/geoapi/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin
from solo.admin import SingletonModelAdmin

from .models import GeoAPIConfig

admin.site.register(GeoAPIConfig, SingletonModelAdmin)
7 changes: 7 additions & 0 deletions metadata_catalogue/datasets/geoapi/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _


class GeoapiConfig(AppConfig):
name = "metadata_catalogue.datasets.geoapi"
verbose_name = _("GeoAPI")
30 changes: 30 additions & 0 deletions metadata_catalogue/datasets/geoapi/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 4.2.6 on 2023-11-13 12:28

from django.db import migrations, models


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="GeoAPIConfig",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("max_records", models.IntegerField(default=10)),
("pretty_print", models.BooleanField(default=False)),
("map_url", models.URLField(default="https://tile.openstreetmap.org/{z}/{x}/{y}.png")),
(
"map_attribution",
models.TextField(
default='&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
),
),
],
options={
"abstract": False,
},
),
]
Empty file.
77 changes: 77 additions & 0 deletions metadata_catalogue/datasets/geoapi/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from pathlib import Path

from django.apps import apps
from django.db import models
from solo.models import SingletonModel

from ..libs.utils import safe_get


class GeoAPIConfig(SingletonModel):
max_records = models.IntegerField(default=10)
pretty_print = models.BooleanField(default=False)
map_url = models.URLField(default="https://tile.openstreetmap.org/{z}/{x}/{y}.png")
map_attribution = models.TextField(
default='&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
)

def get_config(self, url=""):
ServiceInfo = apps.get_model("datasets", "ServiceInfo")
Dataset = apps.get_model("datasets", "Dataset")
info = ServiceInfo.objects.select_related("contact", "license", "provider").get()

resources = {id: value for id, value in Dataset.objects.select_related("metadata").all().as_geoapi_resource()}

return {
"server": {
"mimetype": "application/xml; charset=UTF-8",
"encoding": "utf-8",
"language": info.language or "en-US",
"limit": str(self.max_records),
"pretty_print": self.pretty_print,
"url": url,
"templates": {"static": str(Path(__name__).parent / "statics" / "geoapi")},
"map": {
"url": self.map_url,
"attribute": self.map_attribution,
},
},
"logging": {
"level": "DEBUG",
},
"metadata": {
"identification": {
"title": info.identification_title,
"description": info.identification_abstract,
"keywords": info.identification_keywords.split(",") if info.identification_keywords else "",
"keywords_type": "theme",
"terms_of_service": info.identification_accessconstraints,
"url": "",
},
"license": {
"name": info.license.name if info.license else "",
"url": info.license.url if info.license else "",
},
"provider": {
"name": info.provider,
"url": "",
},
"contact": {
"name": str(info.contact),
"position": safe_get(info.contact, "position"),
"address": safe_get(info.contact, "delivery_point"),
"city": safe_get(info.contact, "city"),
"stateorprovince": safe_get(info.contact, "country"),
"postalcode": safe_get(info.contact, "postal_code"),
"country": safe_get(info.contact, "country"),
"phone": safe_get(info.contact, "phone"),
"fax": safe_get(info.contact, "phone"),
"email": safe_get(info.contact, "email"),
"url": "",
"hours": info.contact_hours or "",
"instructions": info.contact_instructions or "",
"role": "pointOfContact",
},
},
"resources": resources,
}
158 changes: 158 additions & 0 deletions metadata_catalogue/datasets/geoapi/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path

from . import views

urlpatterns = [
path("", views.landing_page, name="landing-page"),
path("openapi/", views.openapi, name="openapi"),
path("conformance/", views.conformance, name="conformance"),
path("collections/", views.collections, name="collections"),
path(
"collections/<str:collection_id>",
views.collections,
name="collection-detail",
),
path(
"collections/<str:collection_id>/queryables/",
views.collection_queryables,
name="collection-queryables",
),
path(
"collections/<str:collection_id>/items/",
views.collection_items,
name="collection-items",
),
path(
"collections/<str:collection_id>/items/<str:item_id>",
views.collection_item,
name="collection-item",
),
path(
"collections/<str:collection_id>/coverage/",
views.collection_coverage,
name="collection-coverage",
),
path(
"collections/<str:collection_id>/coverage/domainset/", # noqa
views.collection_coverage_domainset,
name="collection-coverage-domainset",
),
path(
"collections/<str:collection_id>/coverage/rangetype/", # noqa
views.collection_coverage_rangetype,
name="collection-coverage-rangetype",
),
path(
"collections/<str:collection_id>/map",
views.collection_map,
name="collection-map",
),
path(
"collections/<str:collection_id>/styles/<str:style_id>/map",
views.collection_style_map,
name="collection-style-map",
),
path(
"collections/<str:collection_id>/tiles/",
views.collection_tiles,
name="collection-tiles",
),
path(
"collections/<str:collection_id>/tiles/<str:tileMatrixSetId>",
views.collection_tiles_metadata,
name="collection-tiles-metadata",
),
path(
"collections/<str:collection_id>/tiles/<str:tileMatrixSetId>/metadata",
views.collection_tiles_metadata,
name="collection-tiles-metadata",
),
path(
"collections/<str:collection_id>/tiles/\
<str:tileMatrixSetId>/<str:tile_matrix>/<str:tileRow>/<str:tileCol>",
views.collection_item_tiles,
name="collection-item-tiles",
),
path(
"collections/<str:collection_id>/position",
views.get_collection_edr_query,
name="collection-edr-position",
),
path(
"collections/<str:collection_id>/area",
views.get_collection_edr_query,
name="collection-edr-area",
),
path(
"collections/<str:collection_id>/cube",
views.get_collection_edr_query,
name="collection-edr-cube",
),
path(
"collections/<str:collection_id>/radius",
views.get_collection_edr_query,
name="collection-edr-radius",
),
path(
"collections/<str:collection_id>/trajectory",
views.get_collection_edr_query,
name="collection-edr-trajectory",
),
path(
"collections/<str:collection_id>/corridor",
views.get_collection_edr_query,
name="collection-edr-corridor",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/position",
views.get_collection_edr_query,
name="collection-edr-instance-position",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/area",
views.get_collection_edr_query,
name="collection-edr-instance-area",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/cube",
views.get_collection_edr_query,
name="collection-edr-instance-cube",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/radius",
views.get_collection_edr_query,
name="collection-edr-instance-radius",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/trajectory", # noqa
views.get_collection_edr_query,
name="collection-edr-instance-trajectory",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/corridor",
views.get_collection_edr_query,
name="collection-edr-instance-corridor",
),
path("processes/", views.processes, name="processes"),
path("processes/<str:process_id>", views.processes, name="process-detail"),
path("jobs/", views.jobs, name="jobs"),
path("jobs/<str:job_id>", views.jobs, name="job"),
path(
"jobs/<str:job_id>/results/",
views.job_results,
name="job-results",
),
path(
"jobs/<str:job_id>/results/<str:resource>",
views.job_results_resource,
name="job-results-resource",
),
path("stac/", views.stac_catalog_root, name="stac-catalog-root"),
path("stac/<str:path>", views.stac_catalog_path, name="stac-catalog-path"),
path("stac/search/", views.stac_catalog_search, name="stac-catalog-search"),
]

# Add static URLs to serve pygeoapi statics
urlpatterns += static(settings.STATIC_URL, document_root=str(settings.APPS_DIR / "static" / "geoapi"))
Loading

0 comments on commit e687d6d

Please sign in to comment.