-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Try to simplify the layers * Add api to retrive context data * Add IsAuthenticated * Update flake8 * Add function to generate pmtiles (#13) * Add support for pmtiles (#14) * Add support for pmtiles * Generate pmtiles in upload task * update maputnik --------- Co-authored-by: Danang Massandy <[email protected]>
- Loading branch information
1 parent
60fecc9
commit 6449ade
Showing
18 changed files
with
712 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# coding=utf-8 | ||
"""Cloud Native GIS.""" | ||
|
||
from rest_framework import status | ||
from rest_framework.permissions import IsAuthenticated | ||
from rest_framework.response import Response | ||
from rest_framework.views import APIView | ||
|
||
from cloud_native_gis.utils.geometry import ( | ||
query_features | ||
) | ||
from cloud_native_gis.models.layer import Layer | ||
|
||
|
||
class ContextAPIView(APIView): | ||
""" | ||
Context API endpoint for collection queries. | ||
Only accessible to authenticated users. | ||
Validates the query, processes data, and returns results. | ||
""" | ||
|
||
permission_classes = [IsAuthenticated] | ||
|
||
def get(self, request): | ||
"""Handle GET requests.""" | ||
try: | ||
key = request.GET.get('key', None) | ||
attributes = request.GET.get('attr', '') | ||
x = request.GET.get('x', None) | ||
y = request.GET.get('y', None) | ||
if None in [key, x, y]: | ||
raise KeyError('Required request argument (' | ||
'registry, key, x, y) missing.') | ||
|
||
srid = request.GET.get('srid', 4326) | ||
|
||
x_list = x.split(',') | ||
y_list = y.split(',') | ||
|
||
if len(x_list) != len(y_list): | ||
raise ValueError( | ||
'The number of x and y coordinates must be the same') | ||
|
||
try: | ||
coordinates = [ | ||
(float(x), float(y)) for x, y in zip(x_list, y_list)] | ||
except ValueError: | ||
raise ValueError( | ||
'All x and y values must be valid floats.') | ||
|
||
try: | ||
tolerance = float(request.GET.get('tolerance', 10.0)) | ||
except ValueError: | ||
raise ValueError('Tolerance should be a float') | ||
|
||
registry = request.GET.get('registry', '') | ||
if registry.lower() not in [ | ||
'collection', 'service', 'group', 'native']: | ||
raise ValueError('Registry should be "collection", ' | ||
'"service" or "group".') | ||
|
||
outformat = request.GET.get('outformat', 'geojson').lower() | ||
if outformat not in ['geojson', 'json']: | ||
raise ValueError('Output format should be either ' | ||
'json or geojson') | ||
|
||
data = [] | ||
|
||
if registry == 'native': | ||
try: | ||
layer = Layer.objects.get(unique_id=key) | ||
if attributes: | ||
attributes = attributes.split(',') | ||
else: | ||
attributes = layer.attribute_names | ||
data = query_features( | ||
layer.query_table_name, | ||
field_names=attributes, | ||
coordinates=coordinates, | ||
tolerance=tolerance, | ||
srid=srid | ||
) | ||
except Layer.DoesNotExist as e: | ||
return Response(str(e), status=status.HTTP_404_NOT_FOUND) | ||
|
||
# Todo : for non native layer | ||
# point = parse_coord(x, y, srid) | ||
# data = Worker( | ||
# registry, key, point, tolerance, outformat).retrieve_all() | ||
|
||
return Response(data, status=status.HTTP_200_OK) | ||
except KeyError as e: | ||
return Response(str(e), status=status.HTTP_400_BAD_REQUEST) | ||
except Exception as e: | ||
return Response( | ||
str(e), status=status.HTTP_500_INTERNAL_SERVER_ERROR) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# coding=utf-8 | ||
"""Cloud Native GIS.""" | ||
import os | ||
import re | ||
|
||
from django.http import FileResponse, Http404, HttpResponse | ||
from django.shortcuts import get_object_or_404 | ||
|
||
from cloud_native_gis.models import Layer | ||
|
||
|
||
def serve_pmtiles(request, layer_uuid): | ||
"""Serve pmtiles.""" | ||
layer = get_object_or_404(Layer, unique_id=layer_uuid) | ||
|
||
if not layer.pmtile: | ||
raise Http404("PMTile file not found for this layer.") | ||
|
||
full_path = layer.pmtile.path | ||
|
||
if not os.path.exists(full_path): | ||
raise Http404("PMTile file does not exist.") | ||
|
||
range_header = request.headers.get('Range') | ||
if range_header: | ||
range_match = re.match( | ||
r'bytes=(\d+)-(\d*)', range_header) | ||
if range_match: | ||
start_byte = int(range_match.group(1)) | ||
end_byte = int( | ||
range_match.group(2)) if ( | ||
range_match.group(2)) else ( | ||
os.path.getsize(full_path) - 1) | ||
|
||
file_size = os.path.getsize(full_path) | ||
content_length = end_byte - start_byte + 1 | ||
content_range = f'bytes {start_byte}-{end_byte}/{file_size}' | ||
|
||
file = open(full_path, 'rb') | ||
file.seek(start_byte) | ||
|
||
response = HttpResponse( | ||
file.read(content_length), | ||
status=206, | ||
content_type='application/octet-stream') | ||
response['Content-Length'] = content_length | ||
response['Content-Range'] = content_range | ||
response['Accept-Ranges'] = 'bytes' | ||
return response | ||
|
||
return FileResponse( | ||
open(full_path, 'rb'), | ||
content_type='application/octet-stream') |
18 changes: 18 additions & 0 deletions
18
django_project/cloud_native_gis/migrations/0002_layer_pmtile.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Generated by Django 4.2.16 on 2024-10-09 14:07 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('cloud_native_gis', '0001_initial'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='layer', | ||
name='pmtile', | ||
field=models.FileField(blank=True, help_text='Optional PMTile file associated with the layer.', null=True, upload_to='pmtile_files/'), | ||
), | ||
] |
Oops, something went wrong.