Skip to content

Commit

Permalink
Merge pull request #502 from mrmap-community/epsg-api-proxy
Browse files Browse the repository at this point in the history
Epsg api proxy
  • Loading branch information
jokiefer authored Apr 9, 2024
2 parents 6490b3b + ef9f236 commit 88eadee
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 23 deletions.
4 changes: 2 additions & 2 deletions mrmap/.requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ psycopg[binary]==3.1.14
# adds class based xml mappers
eulxml==1.1.3
# library to process xml
lxml==4.9.3
lxml==5.2.0
# ISO 8601 date/time parser
isodate==0.6.1
# Python Imaging Library to create security images for example
Expand Down Expand Up @@ -68,7 +68,7 @@ odin==2.9.0

drf-spectacular-jsonapi==0.4.1

django-ows-lib==0.14.3
django-ows-lib==0.14.5

camel-converter==3.0.0

Expand Down
2 changes: 1 addition & 1 deletion mrmap/MrMap/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"csw",
CswServiceView.as_view(),
name="csw-endpoint"
),
)

]

Expand Down
4 changes: 2 additions & 2 deletions mrmap/registry/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def find_orphan_metadata_objects(sender, **kwargs):
resource_relation__isnull=True)
# TODO: move this to a manager as check function
# print info object instead
print("orphans:", orphans.count())
print("metadata orphans:", orphans.count())


class RegistryConfig(AppConfig):
Expand All @@ -54,5 +54,5 @@ def ready(self):
post_migrate.connect(create_wms_operations, sender=self)
post_migrate.connect(create_wfs_operations, sender=self)

# post_migrate.connect(create_file_system_import_task, sender=self)
# post_migrate.connect(create_file_system_import_task, sender=self)
post_migrate.connect(find_orphan_metadata_objects, sender=self)
37 changes: 37 additions & 0 deletions mrmap/registry/models/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.gis.db.models import MultiPolygonField
from django.contrib.gis.gdal.error import GDALException
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q
from django.db.models.expressions import CombinedExpression, F
from django.db.models.fields.generated import GeneratedField
from django.utils.translation import gettext_lazy as _
from epsg_cache.registry import Registry
from eulxml import xmlmap
from extras.managers import (DefaultHistoryManager,
UniqueConstraintDefaultValueManager)
Expand All @@ -26,9 +28,12 @@
from registry.models.metadata_query import VALID_RELATIONS
from requests import Request, Session
from requests.adapters import HTTPAdapter
from requests.exceptions import ConnectionError
from simple_history.models import HistoricalRecords
from urllib3 import Retry

CRS_Registry = Registry(proxies=PROXIES)


class MimeType(models.Model):
mime_type = models.CharField(max_length=500,
Expand Down Expand Up @@ -125,6 +130,38 @@ def __str__(self):
def __eq__(self, __value: object) -> bool:
return self.code == __value.code and self.prefix == __value.prefix

@property
def crs(self):
if self.prefix == ReferenceSystemPrefixEnum.EPSG:
try:
return CRS_Registry.get(srid=self.code)
except (ConnectionError, GDALException):
pass

@property
def wkt(self):
_crs = self.crs
if _crs:
return _crs.wkt

@property
def extent(self):
_crs = self.crs
if _crs:
return _crs.extent

@property
def is_xy_order(self):
_crs = self.crs
if _crs:
return _crs.is_xy_order

@property
def is_yx_order(self):
_crs = self.crs
if _crs:
return _crs.is_yx_order


class MetadataContact(models.Model):
name = models.CharField(max_length=256,
Expand Down
8 changes: 4 additions & 4 deletions mrmap/registry/models/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,21 @@ class OperationUrl(models.Model):
# 2048 is the technically specified max length of an url. Some services urls scratches this limit.
url: str = models.URLField(
max_length=4096,
editable=False,
# editable=False,
verbose_name=_("url"),
help_text=_("the url for this operation"),
)
operation: str = models.CharField(
max_length=30,
choices=OGCOperationEnum.choices,
editable=False,
# editable=False,
verbose_name=_("operation"),
help_text=_("the operation you can perform with this url."),
)
mime_types = models.ManyToManyField(
to="MimeType", # use string to avoid from circular import error
blank=True,
editable=False,
# editable=False,
related_name="%(class)s_operation_urls",
related_query_name="%(class)s_operation_url",
verbose_name=_("internet mime type"),
Expand Down Expand Up @@ -241,7 +241,7 @@ class WebMapServiceOperationUrl(OperationUrl):
service = models.ForeignKey(
to=WebMapService,
on_delete=models.CASCADE,
editable=False,
# editable=False,
related_name="operation_urls",
related_query_name="operation_url",
verbose_name=_("related web map service"),
Expand Down
2 changes: 1 addition & 1 deletion mrmap/registry/proxy/wfs_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import json

from axis_order_cache.utils import adjust_axis_order
from django.contrib.gis.geos import GEOSGeometry
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from epsg_cache.utils import adjust_axis_order
from ows_lib.client.wfs.mixins import \
WebFeatureServiceMixin as WebFeatureServiceClient
from registry.models.service import WebFeatureService
Expand Down
34 changes: 33 additions & 1 deletion mrmap/registry/serializers/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from registry.models.metadata import (DatasetMetadataRecord, Keyword, Licence,
MetadataContact, ReferenceSystem, Style)
from registry.models.service import CatalogueService, FeatureType, Layer
from rest_framework.fields import SerializerMethodField
from rest_framework.relations import HyperlinkedIdentityField
from rest_framework_json_api.relations import ResourceRelatedField
from rest_framework_json_api.serializers import ModelSerializer
Expand Down Expand Up @@ -33,7 +34,7 @@ class Meta:
fields = "__all__"


class ReferenceSystemSerializer(
class ReferenceSystemDefaultSerializer(
StringRepresentationSerializer,
ModelSerializer):

Expand All @@ -46,6 +47,37 @@ class Meta:
fields = "__all__"


class ReferenceSystemRetrieveSerializer(
StringRepresentationSerializer,
ModelSerializer):

wkt = SerializerMethodField()
bbox = SerializerMethodField()
is_xy_order = SerializerMethodField()
is_yx_order = SerializerMethodField()

url = HyperlinkedIdentityField(
view_name="registry:referencesystem-detail",
)

class Meta:
model = ReferenceSystem
fields = "__all__"

def get_wkt(self, obj):
return obj.wkt

def get_bbox(self, obj):
if obj.extent:
return obj.extent.envelope.geojson

def get_is_xy_order(self, obj):
return obj.is_xy_order

def get_is_yx_order(self, obj):
return obj.is_yx_order


class StyleSerializer(
StringRepresentationSerializer,
ModelSerializer):
Expand Down
7 changes: 3 additions & 4 deletions mrmap/registry/serializers/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@
from registry.serializers.metadata import (DatasetMetadataRecordSerializer,
KeywordSerializer,
MetadataContactSerializer,
ReferenceSystemSerializer,
ReferenceSystemDefaultSerializer,
StyleSerializer)
from registry.serializers.security import WebFeatureServiceOperationSerializer
from rest_framework.fields import (BooleanField, IntegerField,
SerializerMethodField, URLField, UUIDField)
from rest_framework_gis.fields import GeometryField
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from rest_framework_json_api.relations import (
ResourceRelatedField, SerializerMethodResourceRelatedField)
from rest_framework_json_api.serializers import (HyperlinkedIdentityField,
Expand Down Expand Up @@ -165,7 +164,7 @@ class LayerSerializer(
"keywords": KeywordSerializer,
"created_by": UserSerializer,
"last_modified_by": UserSerializer,
"reference_systems": ReferenceSystemSerializer,
"reference_systems": ReferenceSystemDefaultSerializer,
# "dimensions": DimensionSerializer,
}

Expand Down Expand Up @@ -415,7 +414,7 @@ class FeatureTypeSerializer(
"keywords": KeywordSerializer,
"created_by": UserSerializer,
"last_modified_by": UserSerializer,
# TODO: "reference_systems": ReferenceSystemSerializer
# TODO: "reference_systems": ReferenceSystemDefaultSerializer
}

class Meta:
Expand Down
1 change: 0 additions & 1 deletion mrmap/registry/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.urls import path
from registry.views import harvesting as harvesting_views
from registry.views import mapcontext as mapcontext_views
from registry.views import metadata as metadata_views
Expand Down
12 changes: 8 additions & 4 deletions mrmap/registry/views/metadata.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from django.db.models.query import Prefetch
from extras.permissions import DjangoObjectPermissionsOrAnonReadOnly
from extras.viewsets import NestedModelViewSet
from extras.viewsets import NestedModelViewSet, SerializerClassesMixin
from registry.models.metadata import (DatasetMetadataRecord, Keyword, Licence,
MetadataContact, ReferenceSystem, Style)
from registry.models.service import CatalogueService, FeatureType, Layer
from registry.serializers.metadata import (DatasetMetadataRecordSerializer,
KeywordSerializer,
LicenceSerializer,
MetadataContactSerializer,
ReferenceSystemSerializer,
ReferenceSystemDefaultSerializer,
ReferenceSystemRetrieveSerializer,
StyleSerializer)
from rest_framework_json_api.views import ModelViewSet

Expand Down Expand Up @@ -60,9 +61,12 @@ class NestedLicenceViewSet(
pass


class ReferenceSystemViewSetMixin():
class ReferenceSystemViewSetMixin(SerializerClassesMixin):
queryset = ReferenceSystem.objects.all()
serializer_class = ReferenceSystemSerializer
serializer_classes = {
"default": ReferenceSystemDefaultSerializer,
"retrieve": ReferenceSystemRetrieveSerializer,
}
filterset_fields = {
"code": ["exact", "icontains", "contains"],
"prefix": ["exact", "icontains", "contains"]
Expand Down
2 changes: 1 addition & 1 deletion mrmap/tests/django/registry/mrmap-proxy/tests_wfs_proxy.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

from accounts.models.users import User
from axis_order_cache.utils import adjust_axis_order
from django.contrib.gis.geos import GEOSGeometry
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.management import call_command
from django.db.models.query_utils import Q
from django.test import Client, TestCase
from epsg_cache.utils import adjust_axis_order
from eulxml.xmlmap import load_xmlobject_from_string
from MrMap.settings import BASE_DIR
from ows_lib.xml_mapper.xml_requests.wfs.get_feature import (GetFeatureRequest,
Expand Down
4 changes: 2 additions & 2 deletions mrmap/tests/django/registry/mrmap-proxy/tests_wms_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
from unittest.mock import patch

from accounts.models.users import User
from axis_order_cache.models import Origin, SpatialReference
from axis_order_cache.registry import Registry
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.management import call_command
from django.db.models.query_utils import Q
from django.test import Client, TestCase
from epsg_cache.models import Origin, SpatialReference
from epsg_cache.registry import Registry
from lxml import etree, objectify
from MrMap.settings import BASE_DIR
from PIL import Image, ImageChops
Expand Down

0 comments on commit 88eadee

Please sign in to comment.