def test_importer_configuration(self): database_settings = self.DATABASE_DEFAULT_SETTINGS.copy() ogc_server_settings = self.OGC_DEFAULT_SETTINGS.copy() uploader_settings = self.UPLOADER_DEFAULT_SETTINGS.copy() uploader_settings['BACKEND'] = 'geonode.importer' self.assertTrue(['geonode_imports' not in database_settings.keys()]) # Test the importer backend without specifying a datastore or # corresponding database. with self.settings(UPLOADER=uploader_settings, OGC_SERVER=ogc_server_settings, DATABASES=database_settings): OGC_Servers_Handler(ogc_server_settings)['default'] ogc_server_settings['default']['DATASTORE'] = 'geonode_imports' # Test the importer backend with a datastore but no corresponding # database. with self.settings(UPLOADER=uploader_settings, OGC_SERVER=ogc_server_settings, DATABASES=database_settings): OGC_Servers_Handler(ogc_server_settings)['default'] database_settings['geonode_imports'] = database_settings[ 'default'].copy() database_settings['geonode_imports'].update( {'NAME': 'geonode_imports'}) # Test the importer backend with a datastore and a corresponding # database, no exceptions should be thrown. with self.settings(UPLOADER=uploader_settings, OGC_SERVER=ogc_server_settings, DATABASES=database_settings): OGC_Servers_Handler(ogc_server_settings)['default']
def test_ogc_server_settings(self): """ Tests the OGC Servers Handler class. """ with override_settings(OGC_SERVER=self.OGC_DEFAULT_SETTINGS, UPLOADER=self.UPLOADER_DEFAULT_SETTINGS): OGC_SERVER = self.OGC_DEFAULT_SETTINGS.copy() OGC_SERVER.update( {'PUBLIC_LOCATION': 'http://localhost:8080/geoserver/'}) ogc_settings = OGC_Servers_Handler(OGC_SERVER)['default'] default = OGC_SERVER.get('default') self.assertEqual(ogc_settings.server, default) self.assertEqual(ogc_settings.BACKEND, default.get('BACKEND')) self.assertEqual(ogc_settings.LOCATION, default.get('LOCATION')) self.assertEqual(ogc_settings.PUBLIC_LOCATION, default.get('PUBLIC_LOCATION')) self.assertEqual(ogc_settings.USER, default.get('USER')) self.assertEqual(ogc_settings.PASSWORD, default.get('PASSWORD')) self.assertEqual(ogc_settings.DATASTORE, str()) self.assertEqual(ogc_settings.credentials, ('admin', 'geoserver')) self.assertTrue(ogc_settings.MAPFISH_PRINT_ENABLED) self.assertTrue(ogc_settings.PRINT_NG_ENABLED) self.assertTrue(ogc_settings.GEONODE_SECURITY_ENABLED) self.assertFalse(ogc_settings.GEOGIG_ENABLED) self.assertFalse(ogc_settings.WMST_ENABLED) self.assertTrue(ogc_settings.BACKEND_WRITE_ENABLED) self.assertFalse(ogc_settings.WPS_ENABLED)
def create_gs_thumbnail_geonode(instance, overwrite=False, check_bbox=False): """ Create a thumbnail with a GeoServer request. """ ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"] wms_version = getattr(ogc_server_settings, "WMS_VERSION") or "1.1.1" create_thumbnail( instance, wms_version=wms_version, overwrite=overwrite, )
def test_ogc_server_defaults(self): """ Tests that OGC_SERVER_SETTINGS are built if they do not exist in the settings. """ OGC_SERVER = {'default': dict()} defaults = self.OGC_DEFAULT_SETTINGS.get('default') ogc_settings = OGC_Servers_Handler(OGC_SERVER)['default'] self.assertEqual(ogc_settings.server, defaults) self.assertEqual(ogc_settings.rest, defaults['LOCATION'] + 'rest') self.assertEqual(ogc_settings.ows, defaults['LOCATION'] + 'ows') # Make sure we get None vs a KeyError when the key does not exist self.assertIsNone(ogc_settings.SFDSDFDSF)
def test_ogc_server_defaults(self): """ Tests that OGC_SERVER_SETTINGS are built if they do not exist in the settings. """ OGC_SERVER = {'default': dict()} defaults = self.OGC_DEFAULT_SETTINGS.get('default') ogc_settings = OGC_Servers_Handler(OGC_SERVER)['default'] self.assertEqual(ogc_settings.server, defaults) self.assertEqual(ogc_settings.rest, defaults['LOCATION'] + 'rest') self.assertEqual(ogc_settings.ows, defaults['LOCATION'] + 'ows') # Make sure we get None vs a KeyError when the key does not exist self.assertIsNone(ogc_settings.SFDSDFDSF) # Testing OWS endpoints from urlparse import urljoin from django.core.urlresolvers import reverse from .ows import _wcs_get_capabilities, _wfs_get_capabilities, _wms_get_capabilities wcs = _wcs_get_capabilities() logger.debug(wcs) self.assertIsNotNone(wcs) try: wcs_url = urljoin(settings.SITEURL, reverse('wcs_endpoint')) except BaseException: wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertEquals( wcs, '%s?version=2.0.1&request=GetCapabilities&service=WCS' % wcs_url) wfs = _wfs_get_capabilities() logger.debug(wfs) self.assertIsNotNone(wfs) try: wfs_url = urljoin(settings.SITEURL, reverse('wfs_endpoint')) except BaseException: wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertEquals( wfs, '%s?version=1.1.0&request=GetCapabilities&service=WFS' % wfs_url) wms = _wms_get_capabilities() logger.debug(wms) self.assertIsNotNone(wms) try: wms_url = urljoin(settings.SITEURL, reverse('wms_endpoint')) except BaseException: wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertEquals( wms, '%s?version=1.1.1&request=GetCapabilities&service=WMS' % wms_url) # Test OWS Download Links import urllib from geonode.geoserver.ows import wcs_links, wfs_links, wms_links instance = Layer.objects.all()[0] bbox = instance.bbox srid = instance.srid height = 512 width = 512 # WMS Links wms_links = wms_links(ogc_settings.public_url + 'wms?', instance.alternate.encode('utf-8'), bbox, srid, height, width) self.assertIsNotNone(wms_links) self.assertEquals(len(wms_links), 3) wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wms') identifier = urllib.urlencode( {'layers': instance.alternate.encode('utf-8')}) for _link in wms_links: logger.debug('%s --> %s' % (wms_url, _link[3])) self.assertTrue(wms_url in _link[3]) logger.debug('%s --> %s' % (identifier, _link[3])) self.assertTrue(identifier in _link[3]) # WFS Links wfs_links = wfs_links(ogc_settings.public_url + 'wfs?', instance.alternate.encode('utf-8'), bbox, srid) self.assertIsNotNone(wfs_links) self.assertEquals(len(wfs_links), 6) wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wfs') identifier = urllib.urlencode( {'typename': instance.alternate.encode('utf-8')}) for _link in wfs_links: logger.debug('%s --> %s' % (wfs_url, _link[3])) self.assertTrue(wfs_url in _link[3]) logger.debug('%s --> %s' % (identifier, _link[3])) self.assertTrue(identifier in _link[3]) # WCS Links wcs_links = wcs_links(ogc_settings.public_url + 'wcs?', instance.alternate.encode('utf-8'), bbox, srid) self.assertIsNotNone(wcs_links) self.assertEquals(len(wcs_links), 2) wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wcs') identifier = urllib.urlencode( {'coverageid': instance.alternate.encode('utf-8')}) for _link in wcs_links: logger.debug('%s --> %s' % (wcs_url, _link[3])) self.assertTrue(wcs_url in _link[3]) logger.debug('%s --> %s' % (identifier, _link[3])) self.assertTrue(identifier in _link[3])
def _layers_locations( instance: Union[Layer, Map], compute_bbox: bool = False, target_crs: str = "EPSG:3857" ) -> Tuple[List[List], List]: """ Function returning a list mapping instance's layers to their locations, enabling to construct a minimum number of WMS request for multiple layers of the same OGC source (ensuring layers order for Maps) :param instance: instance of Layer or Map models :param compute_bbox: flag determining whether a BBOX containing the instance should be computed, based on instance's layers :param target_crs: valid only when compute_bbox is True - CRS of the returned BBOX :return: a tuple with a list, which maps layers to their locations in a correct layers order e.g. [ ["http://localhost:8080/geoserver/": ["geonode:layer1", "geonode:layer2]] ] and a list optionally consisting of 5 elements containing west, east, south, north instance's boundaries and CRS """ ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"] locations = [] bbox = [] if isinstance(instance, Layer): # for local layers if instance.remote_service is None: locations.append([ogc_server_settings.LOCATION, [instance.alternate]]) # for remote layers else: locations.append([instance.remote_service.service_url, [instance.alternate]]) if compute_bbox: # handle exceeding the area of use of the default thumb's CRS if ( instance.bbox[-1].upper() != 'EPSG:3857' and target_crs.upper() == 'EPSG:3857' and utils.exceeds_epsg3857_area_of_use(instance.bbox) ): bbox = utils.transform_bbox(utils.crop_to_3857_area_of_use(instance.bbox), target_crs.lower()) else: bbox = utils.transform_bbox(instance.bbox, target_crs.lower()) elif isinstance(instance, Map): map_layers = instance.layers.copy() # ensure correct order of layers in the map (higher stack_order are printed on top of lower) map_layers.sort(key=lambda l: l.stack_order) for map_layer in map_layers: if not map_layer.visibility: logger.debug("Skipping not visible layer in the thumbnail generation.") continue if not map_layer.local and not map_layer.ows_url: logger.warning( "Incorrectly defined remote layer encountered (no OWS URL defined)." "Skipping it in the thumbnail generation." ) continue name = get_layer_name(map_layer) store = map_layer.store workspace = get_layer_workspace(map_layer) if store and Layer.objects.filter(store=store, workspace=workspace, name=name).count() > 0: layer = Layer.objects.filter(store=store, workspace=workspace, name=name).first() elif workspace and Layer.objects.filter(workspace=workspace, name=name).count() > 0: layer = Layer.objects.filter(workspace=workspace, name=name).first() elif Layer.objects.filter(alternate=map_layer.name).count() > 0: layer = Layer.objects.filter(alternate=map_layer.name).first() else: logger.warning(f"Layer for MapLayer {name} was not found. Skipping it in the thumbnail.") continue if layer.storetype in ['tileStore', 'remote']: # limit number of locations, ensuring layer order if len(locations) and locations[-1][0] == layer.remote_service.service_url: # if previous layer's location is the same as the current one - append current layer there locations[-1][1].append(layer.alternate) else: locations.append([layer.remote_service.service_url, [layer.alternate]]) else: # limit number of locations, ensuring layer order if len(locations) and locations[-1][0] == settings.OGC_SERVER["default"]["LOCATION"]: # if previous layer's location is the same as the current one - append current layer there locations[-1][1].append(layer.alternate) else: locations.append([settings.OGC_SERVER["default"]["LOCATION"], [layer.alternate]]) if compute_bbox: # handle exceeding the area of use of the default thumb's CRS if ( layer.bbox[-1].upper() != 'EPSG:3857' and target_crs.upper() == 'EPSG:3857' and utils.exceeds_epsg3857_area_of_use(layer.bbox) ): layer_bbox = utils.transform_bbox(utils.crop_to_3857_area_of_use(layer.bbox), target_crs.lower()) else: layer_bbox = utils.transform_bbox(layer.bbox, target_crs.lower()) if not bbox: bbox = layer_bbox else: # layer's BBOX: (left, right, bottom, top) bbox = [ min(bbox[0], layer_bbox[0]), max(bbox[1], layer_bbox[1]), min(bbox[2], layer_bbox[2]), max(bbox[3], layer_bbox[3]), ] if bbox and len(bbox) < 5: bbox = list(bbox) + [target_crs] # convert bbox to list, if it's tuple return locations, bbox
from django.contrib.gis.gdal import CoordTransform, SpatialReference from django.contrib.gis.geos import GEOSGeometry, Point from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import reverse from lxml import etree from requests import Request from geonode import qgis_server from geonode.geoserver.helpers import OGC_Servers_Handler from geonode.layers.models import Layer from geonode.qgis_server.gis_tools import num2deg from geonode.qgis_server.models import (QGISServerLayer, QGISServerMap, QGISServerStyle) logger = logging.getLogger("geonode.qgis_server.helpers") ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)['default'] def validate_django_settings(): """Check that settings file configured correctly for qgis_server backend. """ # geonode.qgis_server must exists in INSTALLED_APPS and not geoserver if 'geonode.qgis_server' not in settings.INSTALLED_APPS: raise ImproperlyConfigured( 'geonode.qgis_server module not included in INSTALLED_APPS.') if 'geonode.geoserver' in settings.INSTALLED_APPS: raise ImproperlyConfigured( 'You want to use QGIS Server backend, but geonode.geoserver module' ' is still included in INSTALLED_APPS.') # LOCAL_GEOSERVER settings should not exists
def get_map( ogc_server_location: str, layers: List, bbox: List, wms_version: str = settings.OGC_SERVER["default"].get( "WMS_VERSION", "1.1.1"), mime_type: str = "image/png", styles: List = None, width: int = 240, height: int = 200, max_retries: int = 3, retry_delay: int = 1, ): """ Function fetching an image from OGC server. For the requests to the configured OGC backend (ogc_server_settings.LOCATION) the function tries to generate an access_token and attach it to the URL. If access_token is not added ant the request is against Geoserver Basic Authentication is used instead. If image retrieval fails, function retries to fetch the image max_retries times, waiting retry_delay seconds between consecutive requests. :param ogc_server_location: OGC server URL :param layers: layers which should be fetched from the OGC server :param bbox: area's bounding box in format: [west, east, south, north, CRS] :param wms_version: WMS version of the query (default: 1.1.1) :param mime_type: mime type of the returned image :param styles: styles, which OGC server should use for rendering an image :param width: width of the returned image :param height: height of the returned image :param max_retries: maximum number of retries before skipping retrieval :param retry_delay: number of seconds waited between retries :returns: retrieved image """ ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"] if ogc_server_location is not None: thumbnail_url = ogc_server_location else: thumbnail_url = ogc_server_settings.LOCATION wms_endpoint = "" additional_kwargs = {} if thumbnail_url == ogc_server_settings.LOCATION: # add access token to requests to Geoserver (logic based on the previous implementation) username = ogc_server_settings.credentials.username user = get_user_model().objects.filter(username=username).first() if user: access_token = get_or_create_token(user) if access_token and not access_token.is_expired(): additional_kwargs['access_token'] = access_token.token # add WMS endpoint to requests to Geoserver wms_endpoint = getattr(ogc_server_settings, "WMS_ENDPOINT") or "ows" # prepare authorization for WMS service headers = {} if "access_token" not in additional_kwargs.keys(): if thumbnail_url.startswith( settings.OGC_SERVER["default"]["LOCATION"]): # for the Geoserver backend, use Basic Auth, if access_token is not provided _user = settings.OGC_SERVER["default"].get("USER") _pwd = settings.OGC_SERVER["default"].get("PASSWORD") encoded_credentials = base64.b64encode( f"{_user}:{_pwd}".encode("UTF-8")).decode("ascii") headers["Authorization"] = f"Basic {encoded_credentials}" wms = WebMapService(f"{thumbnail_url}{wms_endpoint}", version=wms_version, headers=headers) image = None for retry in range(max_retries): try: # fetch data image = wms.getmap( layers=layers, styles=styles, srs=bbox[-1], bbox=[bbox[0], bbox[2], bbox[1], bbox[3]], size=(width, height), format=mime_type, transparent=True, timeout=getattr(ogc_server_settings, "TIMEOUT", None), **additional_kwargs, ) # validate response if not image or "ServiceException" in str(image.read()): raise ThumbnailError( f"Fetching partial thumbnail from {thumbnail_url} failed with response: {str(image)}" ) except Exception as e: if retry + 1 >= max_retries: logger.exception(e) return time.sleep(retry_delay) continue else: break return image.read()
def test_ogc_server_defaults(self): """ Tests that OGC_SERVER_SETTINGS are built if they do not exist in the settings. """ from django.urls import reverse, resolve from ..ows import _wcs_get_capabilities, _wfs_get_capabilities, _wms_get_capabilities OGC_SERVER = {'default': dict()} defaults = self.OGC_DEFAULT_SETTINGS.get('default') ogc_settings = OGC_Servers_Handler(OGC_SERVER)['default'] self.assertEqual(ogc_settings.server, defaults) self.assertEqual(ogc_settings.rest, defaults['LOCATION'] + 'rest') self.assertEqual(ogc_settings.ows, defaults['LOCATION'] + 'ows') # Make sure we get None vs a KeyError when the key does not exist self.assertIsNone(ogc_settings.SFDSDFDSF) # Testing REST endpoints route = resolve('/gs/rest/layers').route self.assertEqual(route, '^gs/rest/layers') route = resolve('/gs/rest/imports').route self.assertEqual(route, '^gs/rest/imports') route = resolve('/gs/rest/sldservice').route self.assertEqual(route, '^gs/rest/sldservice') store_resolver = resolve('/gs/rest/stores/geonode_data/') self.assertEqual(store_resolver.url_name, 'stores') self.assertEqual(store_resolver.kwargs['store_type'], 'geonode_data') self.assertEqual(store_resolver.route, '^gs/rest/stores/(?P<store_type>\\w+)/$') sld_resolver = resolve('/gs/rest/styles') self.assertIsNone(sld_resolver.url_name) self.assertTrue('workspace' not in sld_resolver.kwargs) self.assertEqual(sld_resolver.kwargs['proxy_path'], '/gs/rest/styles') self.assertEqual(sld_resolver.kwargs['downstream_path'], 'rest/styles') self.assertEqual(sld_resolver.route, '^gs/rest/styles') sld_resolver = resolve('/gs/rest/workspaces/geonode/styles') self.assertIsNone(sld_resolver.url_name) self.assertEqual(sld_resolver.kwargs['workspace'], 'geonode') self.assertEqual(sld_resolver.kwargs['proxy_path'], '/gs/rest/workspaces') self.assertEqual(sld_resolver.kwargs['downstream_path'], 'rest/workspaces') self.assertEqual(sld_resolver.route, '^gs/rest/workspaces/(?P<workspace>\\w+)') # Testing OWS endpoints wcs = _wcs_get_capabilities() logger.debug(wcs) self.assertIsNotNone(wcs) try: wcs_url = urljoin(settings.SITEURL, reverse('ows_endpoint')) except Exception: wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertTrue(wcs.startswith(wcs_url)) self.assertIn("service=WCS", wcs) self.assertIn("request=GetCapabilities", wcs) self.assertIn("version=2.0.1", wcs) wfs = _wfs_get_capabilities() logger.debug(wfs) self.assertIsNotNone(wfs) try: wfs_url = urljoin(settings.SITEURL, reverse('ows_endpoint')) except Exception: wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertTrue(wfs.startswith(wfs_url)) self.assertIn("service=WFS", wfs) self.assertIn("request=GetCapabilities", wfs) self.assertIn("version=1.1.0", wfs) wms = _wms_get_capabilities() logger.debug(wms) self.assertIsNotNone(wms) try: wms_url = urljoin(settings.SITEURL, reverse('ows_endpoint')) except Exception: wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertTrue(wms.startswith(wms_url)) self.assertIn("service=WMS", wms) self.assertIn("request=GetCapabilities", wms) self.assertIn("version=1.3.0", wms) # Test OWS Download Links from geonode.geoserver.ows import wcs_links, wfs_links, wms_links instance = Layer.objects.all()[0] bbox = instance.bbox srid = instance.srid height = 512 width = 512 # Default Style (expect exception since we are offline) try: style = get_sld_for(gs_catalog, instance) except Exception: style = gs_catalog.get_style("line") self.assertIsNotNone(style) instance.default_style, _ = Style.objects.get_or_create( name=style.name, defaults=dict( sld_title=style.sld_title, sld_body=style.sld_body ) ) self.assertIsNotNone(instance.default_style) self.assertIsNotNone(instance.default_style.name) # WMS Links wms_links = wms_links(ogc_settings.public_url + 'wms?', instance.alternate, bbox, srid, height, width) self.assertIsNotNone(wms_links) self.assertEqual(len(wms_links), 3) wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wms') identifier = urlencode({'layers': instance.alternate}) for _link in wms_links: logger.debug(f'{wms_url} --> {_link[3]}') self.assertTrue(wms_url in _link[3]) logger.debug(f'{identifier} --> {_link[3]}') self.assertTrue(identifier in _link[3]) # WFS Links wfs_links = wfs_links(ogc_settings.public_url + 'wfs?', instance.alternate, bbox, srid) self.assertIsNotNone(wfs_links) self.assertEqual(len(wfs_links), 6) wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wfs') identifier = urlencode({'typename': instance.alternate}) for _link in wfs_links: logger.debug(f'{wfs_url} --> {_link[3]}') self.assertTrue(wfs_url in _link[3]) logger.debug(f'{identifier} --> {_link[3]}') self.assertTrue(identifier in _link[3]) # WCS Links wcs_links = wcs_links(ogc_settings.public_url + 'wcs?', instance.alternate, bbox, srid) self.assertIsNotNone(wcs_links) self.assertEqual(len(wcs_links), 2) wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wcs') identifier = urlencode({'coverageid': instance.alternate.replace(':', '__', 1)}) for _link in wcs_links: logger.debug(f'{wcs_url} --> {_link[3]}') self.assertTrue(wcs_url in _link[3]) logger.debug(f'{identifier} --> {_link[3]}') self.assertTrue(identifier in _link[3])
def test_ogc_server_defaults(self): """ Tests that OGC_SERVER_SETTINGS are built if they do not exist in the settings. """ OGC_SERVER = {'default': dict()} defaults = self.OGC_DEFAULT_SETTINGS.get('default') ogc_settings = OGC_Servers_Handler(OGC_SERVER)['default'] self.assertEqual(ogc_settings.server, defaults) self.assertEqual(ogc_settings.rest, defaults['LOCATION'] + 'rest') self.assertEqual(ogc_settings.ows, defaults['LOCATION'] + 'ows') # Make sure we get None vs a KeyError when the key does not exist self.assertIsNone(ogc_settings.SFDSDFDSF) # Testing OWS endpoints from django.urls import reverse from ..ows import _wcs_get_capabilities, _wfs_get_capabilities, _wms_get_capabilities wcs = _wcs_get_capabilities() logger.debug(wcs) self.assertIsNotNone(wcs) try: wcs_url = urljoin(settings.SITEURL, reverse('ows_endpoint')) except BaseException: wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertTrue(wcs.startswith(wcs_url)) self.assertIn("service=WCS", wcs) self.assertIn("request=GetCapabilities", wcs) self.assertIn("version=2.0.1", wcs) wfs = _wfs_get_capabilities() logger.debug(wfs) self.assertIsNotNone(wfs) try: wfs_url = urljoin(settings.SITEURL, reverse('ows_endpoint')) except BaseException: wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertTrue(wfs.startswith(wfs_url)) self.assertIn("service=WFS", wfs) self.assertIn("request=GetCapabilities", wfs) self.assertIn("version=1.1.0", wfs) wms = _wms_get_capabilities() logger.debug(wms) self.assertIsNotNone(wms) try: wms_url = urljoin(settings.SITEURL, reverse('ows_endpoint')) except BaseException: wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'ows') self.assertTrue(wms.startswith(wms_url)) self.assertIn("service=WMS", wms) self.assertIn("request=GetCapabilities", wms) self.assertIn("version=1.3.0", wms) # Test OWS Download Links from geonode.geoserver.ows import wcs_links, wfs_links, wms_links instance = Layer.objects.all()[0] bbox = instance.bbox srid = instance.srid height = 512 width = 512 # Default Style (expect exception since we are offline) style = None with self.assertRaises(GeoNodeException): style = get_sld_for(gs_catalog, instance) self.assertIsNone(style) style = gs_catalog.get_style("line") self.assertIsNotNone(style) instance.default_style, _ = Style.objects.get_or_create( name=style.name, defaults=dict( sld_title=style.sld_title, sld_body=style.sld_body ) ) self.assertIsNotNone(instance.default_style) self.assertIsNotNone(instance.default_style.name) # WMS Links wms_links = wms_links(ogc_settings.public_url + 'wms?', instance.alternate, bbox, srid, height, width) self.assertIsNotNone(wms_links) self.assertEquals(len(wms_links), 3) wms_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wms') identifier = urlencode({'layers': instance.alternate}) for _link in wms_links: logger.debug('%s --> %s' % (wms_url, _link[3])) self.assertTrue(wms_url in _link[3]) logger.debug('%s --> %s' % (identifier, _link[3])) self.assertTrue(identifier in _link[3]) # WFS Links wfs_links = wfs_links(ogc_settings.public_url + 'wfs?', instance.alternate, bbox, srid) self.assertIsNotNone(wfs_links) self.assertEquals(len(wfs_links), 6) wfs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wfs') identifier = urlencode({'typename': instance.alternate}) for _link in wfs_links: logger.debug('%s --> %s' % (wfs_url, _link[3])) self.assertTrue(wfs_url in _link[3]) logger.debug('%s --> %s' % (identifier, _link[3])) self.assertTrue(identifier in _link[3]) # WCS Links wcs_links = wcs_links(ogc_settings.public_url + 'wcs?', instance.alternate, bbox, srid) self.assertIsNotNone(wcs_links) self.assertEquals(len(wcs_links), 2) wcs_url = urljoin(ogc_settings.PUBLIC_LOCATION, 'wcs') identifier = urlencode({'coverageid': instance.alternate}) for _link in wcs_links: logger.debug('%s --> %s' % (wcs_url, _link[3])) self.assertTrue(wcs_url in _link[3]) logger.debug('%s --> %s' % (identifier, _link[3])) self.assertTrue(identifier in _link[3]) # Thumbnails Generation Default create_gs_thumbnail(instance, overwrite=True) self.assertIsNotNone(instance.get_thumbnail_url()) # Thumbnails Generation Through "remote url" create_gs_thumbnail_geonode(instance, overwrite=True, check_bbox=True) # Thumbnails Generation Through "image" request_body = { 'width': width, 'height': height, 'layers': instance.alternate } if hasattr(instance, 'default_style'): if instance.default_style: request_body['styles'] = instance.default_style.name self.assertIsNotNone(request_body['styles']) try: image = _prepare_thumbnail_body_from_opts(request_body) except BaseException as e: logger.exception(e) image = None # We are offline here, the layer does not exists in GeoServer # - we expect the image is None self.assertIsNone(image)
def construct_wms_url( ogc_server_location: str, layers: List, bbox: List, wms_version: str = settings.OGC_SERVER["default"].get( "WMS_VERSION", "1.1.0"), mime_type: str = "image/png", styles: str = None, width: int = 240, height: int = 200, ) -> str: """ Method constructing a GetMap URL to the OGC server. :param ogc_server_location: OGC server URL :param layers: layers which should be fetched from the OGC server :param bbox: area's bounding box in format: [west, east, south, north, CRS] :param wms_version: WMS version of the query :param mime_type: mime type of the returned image :param styles: styles, which OGC server should use for rendering an image :param width: width of the returned image :param height: height of the returned image :return: GetMap URL """ # create GetMap query parameters params = { "service": "WMS", "version": wms_version, "request": "GetMap", "layers": ",".join(layers), "bbox": ",".join([str(bbox[0]), str(bbox[2]), str(bbox[1]), str(bbox[3])]), "crs": bbox[-1], "width": width, "height": height, "format": mime_type, "transparent": True, } if styles is not None: params["styles"] = styles # create GetMap request ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"] if ogc_server_location is not None: thumbnail_url = ogc_server_location else: thumbnail_url = ogc_server_settings.LOCATION wms_endpoint = "" if thumbnail_url == ogc_server_settings.LOCATION: # add access token to requests to Geoserver (logic based on the previous implementation) username = ogc_server_settings.credentials.username user = get_user_model().objects.filter(username=username).first() if user: access_token = get_or_create_token(user) if access_token and not access_token.is_expired(): params["access_token"] = access_token.token # add WMS endpoint to requests to Geoserver wms_endpoint = getattr(ogc_server_settings, "WMS_ENDPOINT") or "ows" thumbnail_url = f"{thumbnail_url}{wms_endpoint}?{'&'.join(f'{key}={val}' for key, val in params.items())}" return thumbnail_url