Skip to content

Commit

Permalink
Code improvements for different CRS
Browse files Browse the repository at this point in the history
- Convert bbox to EPSG:4326 for displaying layers
- Try to retrieve layer projection and save Layer CRS
- Standardize thumbnail generation to use EPSG:4326
  • Loading branch information
lucernae committed Jul 4, 2017
1 parent 87fe525 commit 462aba6
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 28 deletions.
6 changes: 3 additions & 3 deletions geonode/layers/templates/layers/layer_leaflet_map.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,15 @@

L.control.watermark = function(opts) {
return new L.Control.Watermark(opts);
}
};

L.control.watermark({ position: 'bottomright' }).addTo(map);

// L.control.measureControl.addTo(map);
map.addLayer(OpenMapSurfer_Roads);

{% if resource.bbox_string %}
zoom_to_box(map, [{{ resource.bbox_string }}]);
{% if layer_bbox %}
zoom_to_box(map, [{{ layer_bbox }}]);
{% endif %}

var tile_layer;
Expand Down
4 changes: 2 additions & 2 deletions geonode/layers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import json

import gisdata
from django.test import TestCase
from django.test import TestCase, LiveServerTestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import ValidationError
from django.contrib.contenttypes.models import ContentType
Expand Down Expand Up @@ -850,7 +850,7 @@ def test_unpublished_layer(self):
layer.save()


class LayerModerationTestCase(TestCase):
class LayerModerationTestCase(LiveServerTestCase):

fixtures = ['initial_data.json', 'bobby']

Expand Down
12 changes: 12 additions & 0 deletions geonode/layers/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
import traceback
import uuid
import decimal

import re

from django.contrib.gis.geos import GEOSGeometry
from requests import Request

from guardian.shortcuts import get_perms
Expand Down Expand Up @@ -329,6 +333,14 @@ def layer_detail(request, layername, template='layers/layer_detail.html'):
'DEFAULT_MAP_CRS',
'EPSG:900913')

# provide bbox in EPSG:4326 for leaflet
if context_dict["preview"] == 'leaflet':
srid, wkt = layer.geographic_bounding_box.split(';')
srid = re.findall(r'\d+', srid)
geom = GEOSGeometry(wkt, srid=int(srid[0]))
geom.transform(4326)
context_dict["layer_bbox"] = ','.join([str(c) for c in geom.extent])

if layer.storeType == 'dataStore':
links = layer.link_set.download().filter(
name__in=settings.DOWNLOAD_FORMATS_VECTOR)
Expand Down
36 changes: 29 additions & 7 deletions geonode/qgis_server/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
#########################################################################
import logging
import os
import re
import shutil
from urlparse import urljoin

import math
import requests
from django.conf import settings
from django.contrib.gis.gdal import CoordTransform, SpatialReference
from django.contrib.gis.geos import Point
from django.contrib.gis.geos import GEOSGeometry, Point
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse
from requests import Request
Expand Down Expand Up @@ -100,6 +102,26 @@ def validate_django_settings():
return True


def transform_layer_bbox(layer, target_crs):
"""
:param layer: Layer to take the bounding box from
:type layer: Layer
:param target_crs: Integer of EPSG crs ID
:type target_crs: int
:return: list converted BBox in target CRS, in the format:
[xmin,ymin,xmax,ymax]
:rtype: list(int)
"""
srid, wkt = layer.geographic_bounding_box.split(';')
srid = re.findall(r'\d+', srid)
geom = GEOSGeometry(wkt, srid=int(srid[0]))
geom.transform(target_crs)
return list(geom.extent)


def qgis_server_endpoint(internal=True):
"""Return QGIS Server endpoint.
Expand Down Expand Up @@ -262,7 +284,8 @@ def map_thumbnail_url(instance, bbox=None, internal=True):

if not bbox:
# We get the extent of these layers.
bbox = [float(i) for i in instance.bbox_string.split(',')]
# Reproject, in case of different CRS
bbox = transform_layer_bbox(instance, 4326)
return thumbnail_url(
bbox, qgis_map.qgis_map_name, qgis_project, internal=internal)

Expand Down Expand Up @@ -297,11 +320,8 @@ def layer_thumbnail_url(instance, bbox=None, internal=True):

if not bbox:
# We get the extent of the layer.
x_min = instance.resourcebase_ptr.bbox_x0
x_max = instance.resourcebase_ptr.bbox_x1
y_min = instance.resourcebase_ptr.bbox_y0
y_max = instance.resourcebase_ptr.bbox_y1
bbox = [x_min, y_min, x_max, y_max]
# Reproject, in case of different CRS
bbox = transform_layer_bbox(instance, 4326)

return thumbnail_url(bbox, layers, qgis_project, internal=internal)

Expand Down Expand Up @@ -329,7 +349,9 @@ def thumbnail_url(bbox, layers, qgis_project, internal=True):
# We calculate the margins according to 10 percent.
percent = 10
delta_x = (x_max - x_min) / 100 * percent
delta_x = math.fabs(delta_x)
delta_y = (y_max - y_min) / 100 * percent
delta_y = math.fabs(delta_y)
# We apply the margins to the extent.
margin = [
y_min - delta_y,
Expand Down
22 changes: 22 additions & 0 deletions geonode/qgis_server/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import os
import shutil

from osgeo import ogr, osr, gdal
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db.models import signals
Expand Down Expand Up @@ -140,6 +141,27 @@ def qgis_server_post_save(instance, sender, **kwargs):
)
qgis_layer.save()

# Set layer crs
try:
if is_shapefile:
dataset = ogr.Open(geonode_layer_path)
layer = dataset.GetLayer()
spatial_ref = layer.GetSpatialRef()
srid = spatial_ref.GetAuthorityCode(None)
if srid:
instance.srid = srid
else:
dataset = gdal.Open(geonode_layer_path)
prj = dataset.GetProjection()
srs = osr.SpatialReference(wkt=prj)
srid = srs.GetAuthorityCode(None)
if srid:
instance.srid = srid
except Exception as e:
logger.debug("Can't retrieve projection: {layer}".format(
layer=geonode_layer_path))
logger.exception(e)

# base url for geonode
base_url = settings.SITEURL

Expand Down
35 changes: 19 additions & 16 deletions geonode/qgis_server/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def qml_style(request, layername):
qml_path = qgis_layer.qml_path

if not os.path.exists(qml_path):
return Http404(
raise Http404(
'This layer does not have current default QML style.')

response = HttpResponse(
Expand Down Expand Up @@ -445,23 +445,25 @@ def qml_style(request, layername):
layerfile_set = layer.upload_session.layerfile_set
qml_layer_file, created = layerfile_set.get_or_create(name='qml')

if created:
try:
qml_path = qml_layer_file.file.path
content = uploaded_qml.read()
with open(qml_path, mode='w') as f:
f.write(content)
except ValueError:
layer_base_path, __ = layer.get_base_file()
layer_prefix, __ = os.path.splitext(layer_base_path)
layer_prefix, __ = os.path.splitext(
layer_base_path.file.path)
qml_path = '{prefix}.qml'.format(prefix=layer_prefix)
else:
qml_path = qml_layer_file.file.path

content = uploaded_qml.read()

with open(qml_path, mode='w') as f:
f.write(content)
content = uploaded_qml.read()

if created:
qml_layer_file.file = File(f)
qml_layer_file.base = False
qml_layer_file.upload_session = layer.upload_session
qml_layer_file.save()
qml_layer_file.file = File(
uploaded_qml,
name=os.path.basename(qml_path))
qml_layer_file.base = False
qml_layer_file.upload_session = layer.upload_session
qml_layer_file.save()

# update qml in QGIS Layer folder
qgis_layer = get_object_or_404(QGISServerLayer, layer=layer)
Expand Down Expand Up @@ -501,7 +503,8 @@ def qml_style(request, layername):
},
status=200).render()

except:
except Exception as e:
logger.exception(e)
return HttpResponseServerError()

return HttpResponseBadRequest()
Expand All @@ -528,7 +531,7 @@ def set_thumbnail(request, layername):

# extract bbox
bbox_string = request.POST['bbox']
# BBox should be in the format: [xmin,ymin,xmax,ymax]
# BBox should be in the format: [xmin,ymin,xmax,ymax], EPSG:4326
bbox = bbox_string.split(',')
bbox = [float(s) for s in bbox]

Expand Down

0 comments on commit 462aba6

Please sign in to comment.