def create_single_map(name): admin, created = get_user_model().objects.get_or_create(username='******') if created: admin.is_superuser = True admin.first_name = 'admin' admin.set_password('admin') admin.save() test_datetime = datetime.strptime('2020-01-01', '%Y-%m-%d') user = get_user_model().objects.get(username='******') ll = (name, 'lorem ipsum', name, f'{name}', [ 0, 22, 0, 22], test_datetime, ('populartag',)) title, abstract, name, alternate, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), start, kws = ll m = Map( title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', resource_type="map" ) m.save() m.set_default_permissions() m.clear_dirty_state() m.set_processing_state(enumerations.STATE_PROCESSED) return m
def layerController(request, layername): DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() layer = get_object_or_404(Layer, typename=layername) if (request.META['QUERY_STRING'] == "describe"): return _describe_layer(request,layer) if (request.META['QUERY_STRING'] == "remove"): return _removeLayer(request,layer) if (request.META['QUERY_STRING'] == "update"): return _updateLayer(request,layer) if (request.META['QUERY_STRING'] == "style"): return _changeLayerDefaultStyle(request,layer) else: if not request.user.has_perm('maps.view_layer', obj=layer): return HttpResponse(loader.render_to_string('401.html', RequestContext(request, {'error_message': _("You are not permitted to view this layer")})), status=401) metadata = layer.metadata_csw() maplayer = MapLayer(name = layer.typename, ows_url = settings.GEOSERVER_BASE_URL + "wms") # center/zoom don't matter; the viewer will center on the layer bounds map = Map(projection="EPSG:900913") qualityRecord = layer.qualitymatrix return render_to_response('quality/layer.html', RequestContext(request, { "layer": layer, "metadata": metadata, "viewer": json.dumps(map.viewer_json(* (DEFAULT_BASE_LAYERS + [maplayer]))), "permissions_json": _perms_info_json(layer, LAYER_LEV_NAMES), "GEOSERVER_BASE_URL": settings.GEOSERVER_BASE_URL, "qualityRecord": qualityRecord }))
def test_map_thumbnail(self): """Test the map save method generates a thumbnail link """ # TODO: Would be nice to ensure the name is available before # running the test... norman = get_user_model().objects.get(username="******") saved_layer = file_upload( os.path.join( gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) try: self.client.login(username='******', password='******') saved_layer.set_default_permissions() map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], 'title', '') thumbnail_url = map_obj.get_thumbnail_url() self.assertNotEqual(thumbnail_url, staticfiles.static(settings.MISSING_THUMBNAIL)) finally: # Cleanup saved_layer.delete()
def test_map_thumbnail(self): """Test the map save method generates a thumbnail link """ # TODO: Would be nice to ensure the name is available before # running the test... norman = get_user_model().objects.get(username="******") saved_layer = file_upload( os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) try: self.client.login(username='******', password='******') saved_layer.set_default_permissions() map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], 'title', '') thumbnail_url = map_obj.get_thumbnail_url() self.assertNotEqual(thumbnail_url, staticfiles.static(settings.MISSING_THUMBNAIL)) finally: # Cleanup saved_layer.delete()
def test_new_map_config(self): """Test that new map config can be properly assigned """ c = Client() c.login(username='******', password='******') # Test successful new map creation m = Map() admin_user = User.objects.get(username='******') layer_name = Layer.objects.all()[0].typename m.create_from_layer_list(admin_user, [layer_name], "title", "abstract") map_id = m.id c = Client() url = reverse('new_map_json') # Test GET method with COPY response = c.get(url,{'copy': map_id}) self.assertEquals(response.status_code,200) map_obj = Map.objects.get(id=map_id) config_map = map_obj.viewer_json() response_config_dict = json.loads(response.content) self.assertEquals(config_map['map']['layers'],response_config_dict['map']['layers']) # Test GET method no COPY and no layer in params response = c.get(url) self.assertEquals(response.status_code,200) config_default = default_map_config()[0] response_config_dict = json.loads(response.content) self.assertEquals(config_default['about']['abstract'],response_config_dict['about']['abstract']) self.assertEquals(config_default['about']['title'],response_config_dict['about']['title']) # Test GET method no COPY but with layer in params response = c.get(url,{'layer':layer_name}) self.assertEquals(response.status_code,200) response_dict = json.loads(response.content) self.assertEquals(response_dict['fromLayer'],True) # Test POST method without authentication response = c.post(url,{'layer':layer_name}) self.assertEquals(response.status_code,401) # Test POST method with authentication and a layer in params c.login(username='******', password='******') response = c.post(url,{'layer':layer_name}) # Should not accept the request self.assertEquals(response.status_code,400) # Test POST method with map data in json format response = c.post(url, data=self.viewer_config,content_type="text/json") self.assertEquals(response.status_code,200) map_id = int(json.loads(response.content)['id']) # Test methods other than GET or POST and no layer in params response = c.put(url) self.assertEquals(response.status_code,405)
def new_chapter_json(request): ''' Exracted from geonode.maps.views.new_map_json :param request: :return: ''' if request.method == 'POST': if not request.user.is_authenticated(): return HttpResponse( 'You must be logged in to save new maps', content_type="text/plain", status=401 ) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0) map_obj.is_published = False map_obj.save() map_obj.set_default_permissions() # If the body has been read already, use an empty string. # See https://github.com/django/django/commit/ # 58d555caf527d6f1bdfeab14527484e4cca68648 # for a better exception to catch when we move to Django 1.7. try: body = request.body if isinstance(body, basestring): body = json.loads(body) story_id = body.get('story_id', 0) story_obj = Story.objects.get(id=story_id) mapping = StoryChapter() mapping.chapter_index = body['chapter_index'] mapping.map = map_obj mapping.story = story_obj mapping.save() except Exception as e: print e body = '' try: map_obj.update_from_viewer(body) MapSnapshot.objects.create( config=clean_config(body), map=map_obj, user=request.user) except ValueError as e: return HttpResponse(str(e), status=400) else: return HttpResponse( json.dumps({'id': map_obj.id}), status=200, content_type='application/json' ) else: return HttpResponse(status=405)
def test_map_save(self): """POST /maps -> Test saving a new map""" # since django's test client doesn't support providing a JSON request # body, just test the model directly. # the view's hooked up right, I promise. map = Map(zoom=7, center_x=0, center_y=0) map.save() # can't attach layers to a map whose pk isn't set yet map.update_from_viewer(json.loads(self.viewer_config)) self.assertEquals(map.title, "Title") self.assertEquals(map.abstract, "Abstract") self.assertEquals(map.layer_set.all().count(), 1)
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) map_obj = None if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] try: map_obj = _resolve_map( request, mapid, 'base.view_resourcebase') except PermissionDenied: return HttpResponse(_("Not allowed"), status=403) except Exception: raise Http404(_("Not found")) if not map_obj: raise Http404(_("Not found")) map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated: map_obj.owner = request.user config = map_obj.viewer_json(request) del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) if 'layer' in params: map_obj = Map(projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')) config = add_layers_to_map_config( request, map_obj, params.getlist('layer')) else: config = DEFAULT_MAP_CONFIG if map_obj: map_obj.handle_moderated_uploads() return map_obj, json.dumps(config)
def new_map_json(request): if request.method == 'GET': config = new_map_config(request) if isinstance(config, HttpResponse): return config else: return HttpResponse(config) elif request.method == 'POST': if not request.user.is_authenticated(): return HttpResponse('You must be logged in to save new maps', mimetype="text/plain", status=401) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0) map_obj.save() map_obj.set_default_permissions() try: map_obj.update_from_viewer(request.raw_post_data) except ValueError, e: return HttpResponse(str(e), status=400) else: return HttpResponse(json.dumps({'id': map_obj.id}), status=200, mimetype='application/json')
def setUpClass(cls): super().setUpClass() if check_ogc_backend(geoserver.BACKEND_PACKAGE): # upload shape files shp_file = os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_coastline.shp") cls.layer_coast_line = file_upload(shp_file, overwrite=True) shp_file = os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_highway.shp") cls.layer_highway = file_upload(shp_file, overwrite=True) # create a map from loaded layers cls.map_composition = Map() admin_user = get_user_model().objects.get(username="******") cls.map_composition.create_from_layer_list( admin_user, [cls.layer_coast_line, cls.layer_highway], "composition", "abstract") # update MapLayers to correctly show layers' location with DisableDjangoSignals(): for maplayer in cls.map_composition.layers: if maplayer.name in [ cls.layer_coast_line.alternate, cls.layer_highway.alternate ]: maplayer.local = True maplayer.save(force_update=True) maplayer.refresh_from_db() cls.map_composition.refresh_from_db()
def setUpClass(cls): super().setUpClass() cls.user_admin = get_user_model().objects.get(username="******") admin, _ = get_user_model().objects.get_or_create(username="******") if check_ogc_backend(geoserver.BACKEND_PACKAGE): cls.dataset_coast_line = create_single_dataset('san_andres_y_providencia_coastline') cls.dataset_highway = create_single_dataset('san_andres_y_providencia_highway') # create a map from loaded layers cls.map_composition = Map() admin_user = get_user_model().objects.get(username="******") cls.map_composition.create_from_dataset_list( admin_user, [cls.dataset_coast_line, cls.dataset_highway], "composition", "abstract" ) # update MapLayers to correctly show layers' location with DisableDjangoSignals(): for maplayer in cls.map_composition.datasets: if maplayer.name in [cls.dataset_coast_line.alternate, cls.dataset_highway.alternate]: maplayer.local = True maplayer.save(force_update=True) maplayer.refresh_from_db() cls.map_composition.refresh_from_db()
def new_map_json_wm(request): if request.method == 'GET': config = new_map_config(request) if isinstance(config, HttpResponse): return config else: return HttpResponse(config) elif request.method == 'POST': if not request.user.is_authenticated(): return HttpResponse('You must be logged in to save new maps', content_type="text/plain", status=401) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0) map_obj.save() map_obj.set_default_permissions() map_obj.handle_moderated_uploads() # If the body has been read already, use an empty string. # See https://github.com/django/django/commit/58d555caf527d6f1bdfeab14527484e4cca68648 # for a better exception to catch when we move to Django 1.7. try: body = request.body except Exception: body = '' try: map_obj.update_from_viewer(body, context={ 'request': request, 'mapId': map_obj.id, 'map': map_obj }) update_ext_map(request, map_obj) MapSnapshot.objects.create(config=clean_config(body), map=map_obj, user=request.user) except ValueError as e: return HttpResponse(str(e), status=400) else: return HttpResponse(json.dumps({'id': map_obj.id}), status=200, content_type='application/json') else: return HttpResponse(status=405)
def new_map_json(request): if request.method == 'GET': config = new_map_config(request) if isinstance(config, HttpResponse): return config else: return HttpResponse(config) elif request.method == 'POST': if not request.user.is_authenticated(): return HttpResponse( 'You must be logged in to save new maps', mimetype="text/plain", status=401 ) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0) map_obj.save() map_obj.set_default_permissions() try: map_obj.update_from_viewer(request.body) MapSnapshot.objects.create(config=clean_config(request.body),map=map_obj,user=request.user) except ValueError, e: return HttpResponse(str(e), status=400) else: return HttpResponse( json.dumps({'id':map_obj.id }), status=200, mimetype='application/json' )
def new_map_json_wm(request): if request.method == 'GET': config = new_map_config(request) if isinstance(config, HttpResponse): return config else: return HttpResponse(config) elif request.method == 'POST': if not request.user.is_authenticated(): return HttpResponse( 'You must be logged in to save new maps', content_type="text/plain", status=401 ) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0) map_obj.save() map_obj.set_default_permissions() map_obj.handle_moderated_uploads() # If the body has been read already, use an empty string. # See https://github.com/django/django/commit/58d555caf527d6f1bdfeab14527484e4cca68648 # for a better exception to catch when we move to Django 1.7. try: body = request.body except Exception: body = '' try: map_obj.update_from_viewer(body, context={'request': request, 'mapId': map_obj.id, 'map': map_obj}) update_ext_map(request, map_obj) MapSnapshot.objects.create( config=clean_config(body), map=map_obj, user=request.user) except ValueError as e: return HttpResponse(str(e), status=400) else: return HttpResponse( json.dumps({'id': map_obj.id}), status=200, content_type='application/json' ) else: return HttpResponse(status=405)
def test_map_save(self): """POST /maps -> Test saving a new map""" # This is a valid map viewer config, based on the sample data provided # by andreas in issue 566. -dwins viewer_config = """ { "defaultSourceType": "gx_wmssource", "about": { "title": "Title", "abstract": "Abstract" }, "sources": { "capra": { "url":"http://localhost:8001/geoserver/wms" } }, "map": { "projection":"EPSG:900913", "units":"m", "maxResolution":156543.0339, "maxExtent":[-20037508.34,-20037508.34,20037508.34,20037508.34], "center":[-9428760.8688778,1436891.8972581], "layers":[{ "source":"capra", "buffer":0, "wms":"capra", "name":"base:nic_admin" }], "zoom":7 } } """ # since django's test client doesn't support providing a JSON request # body, just test the model directly. # the view's hooked up right, I promise. map = Map(zoom=7, center_x=0, center_y=0) map.save() # can't attach layers to a map whose pk isn't set yet map.update_from_viewer(json.loads(viewer_config)) self.assertEquals(map.title, "Title") self.assertEquals(map.abstract, "Abstract") self.assertEquals(map.layer_set.all().count(), 1)
def search(request): DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() #DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) # for non-ajax requests, render a generic search page params = dict(request.REQUEST) map = Map(projection="EPSG:900913", zoom=1, center_x=0, center_y=0) # Default Counts to 0, JS will Load the Correct Counts counts = {"map": 0, "layer": 0, "vector": 0, "raster": 0, "contact": 0, "group": 0} return render_to_response("search/search.html", RequestContext(request, { "init_search": json.dumps(params), #'viewer_config': json.dumps(map.viewer_json(added_layers=DEFAULT_BASE_LAYERS, authenticated=request.user.is_authenticated())), "viewer_config": json.dumps(map.viewer_json(*DEFAULT_BASE_LAYERS)), "GOOGLE_API_KEY": settings.GOOGLE_API_KEY, "site": settings.SITEURL, "counts": counts, "keywords": Layer.objects.gn_catalog.get_all_keywords() }))
def test_save_story_draft(self): """ Can save draft story """ user = User.objects.create_user(username='******', email='*****@*****.**', password='******') mapstory = MapStory() self.assertIsInstance(mapstory, MapStory) mapstory.title = "Test story" mapstory.owner = user mapstory.save() testMap = Map() testMap.story = mapstory testMap.zoom = 3 testMap.projection = "EPSG:900913" testMap.center_x = -7377090.47385893 testMap.center_y = 3463514.6256579063 testMap.owner = user testMap.save()
def test_map_thumbnail(self): """Test the map save method generates a thumbnail link """ client = Client() client.login(username='******', password='******') #TODO: Would be nice to ensure the name is available before #running the test... norman = User.objects.get(username="******") saved_layer = file_upload( os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], 'title', '') thumbnail_url = map_obj.get_thumbnail_url() assert thumbnail_url != staticfiles.static(settings.MISSING_THUMBNAIL)
def test_map_thumbnail(self): """Test the map save method generates a thumbnail link """ client = Client() client.login(username='******', password='******') #TODO: Would be nice to ensure the name is available before #running the test... norman = User.objects.get(username="******") saved_layer = file_upload( os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], 'title','') thumbnail_url = map_obj.get_thumbnail_url() assert thumbnail_url != staticfiles.static(settings.MISSING_THUMBNAIL)
def create_map_withlayers(self, user_name, ws_name, map_id): """ Create Map """ if Map.objects.filter(pk=map_id).exists(): print('A map with id %s already exist. Choose another id' % map_id) return User = get_user_model() map_owner = User.objects.get(username=user_name) layers = Layer.objects.filter(workspace=ws_name).all() new_map = Map() self.create_from_layer_list(new_map, map_owner, layers, "UrbanMap", "Urban Map. Be carefull")
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) if 'access_token' in request.session: access_token = request.session['access_token'] else: access_token = None if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] map_obj = _resolve_map(request, mapid, 'base.view_resourcebase') map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json(request.user, access_token) map_obj.handle_moderated_uploads() del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) if 'layer' in params: map_obj = Map( projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')) config = add_layers_to_map_config(request, map_obj, params.getlist('layer')) else: config = DEFAULT_MAP_CONFIG return json.dumps(config)
def new_map_json(request): if request.method == "GET": config = new_map_config(request) if isinstance(config, HttpResponse): return config else: return HttpResponse(config) elif request.method == "POST": if not request.user.is_authenticated(): return HttpResponse("You must be logged in to save new maps", mimetype="text/plain", status=401) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0) map_obj.save() map_obj.set_default_permissions() try: map_obj.update_from_viewer(request.raw_post_data) except ValueError, e: return HttpResponse(str(e), status=400) else: return HttpResponse(json.dumps({"id": map_obj.id}), status=200, mimetype="application/json")
def create_from_layer_list(user, layers, title, abstract): newmap = Map() """Copied from maps.models and fixed """ newmap.owner = user newmap.title = title newmap.abstract = abstract newmap.projection = "EPSG:900913" newmap.zoom = 0 newmap.center_x = 0 newmap.center_y = 0 #bbox = None index = 0 incr_bbox = None DEFAULT_BASE_LAYERS = settings.MAP_BASELAYERS is_published = True if settings.RESOURCE_PUBLISHING: is_published = False newmap.is_published = is_published # Save the map in order to create an id in the database # used below for the maplayers. newmap.save() # Add background layers for layer in DEFAULT_BASE_LAYERS: logger.info("Adding baselayer %r", layer) maplayer = layer_from_viewer_config( MapLayer, layer, layer['source'], # source index) if not maplayer.group == 'background': logger.info("Skipping not base layer %r", layer) continue if 'name' not in layer or not layer['name']: logger.info("Unnamed base layer %r", layer) maplayer.name = 'UNNAMED BACKGROUND LAYER' maplayer.map = newmap maplayer.save() index += 1 # Add local layers for layer in layers: if not isinstance(layer, Layer): try: layer = Layer.objects.get(typename=layer) except ObjectDoesNotExist: raise Exception('Could not find layer with name %s' % layer) if not user.has_perm('base.view_resourcebase', obj=layer.resourcebase_ptr): # invisible layer, skip inclusion or raise Exception? raise Exception( 'User %s tried to create a map with layer %s without having premissions' % (user, layer)) ### Add required parameters for GXP lazy-loading # compute (incremental) bbox layer_bbox = layer.bbox if incr_bbox is None: incr_bbox = list(layer_bbox[0:4]) else: incr_bbox[0] = min(incr_bbox[0], layer_bbox[0]) incr_bbox[1] = max(incr_bbox[1], layer_bbox[1]) incr_bbox[2] = min(incr_bbox[2], layer_bbox[2]) incr_bbox[3] = max(incr_bbox[3], layer_bbox[3]) config = layer.attribute_config() config["title"] = layer.title config["queryable"] = True config[ "srs"] = layer.srid if layer.srid != "EPSG:4326" else "EPSG:900913" config["bbox"] = llbbox_to_mercator( [float(coord) for coord in incr_bbox]) #if layer.storeType == "remoteStore": #service = layer.service #maplayer = MapLayer(map=map_obj, #name=layer.typename, #ows_url=layer.ows_url, #layer_params=json.dumps(config), #visibility=True, #source_params=json.dumps({ #"ptype": service.ptype, #"remote": True, #"url": service.base_url, #"name": service.name})) #else: #maplayer = MapLayer( #map=map_obj, #name=layer.typename, #ows_url=layer.ows_url, #layer_params=json.dumps(config), #visibility=True #) MapLayer.objects.create(map=newmap, name=layer.typename, ows_url=layer.ows_url, stack_order=index, visibility=True, layer_params=json.dumps(config)) index += 1 # Set bounding box based on all layers extents. bbox = newmap.get_bbox_from_layers(newmap.local_layers) newmap.set_bounds_from_bbox(bbox) newmap.set_missing_info() # Save again to persist the zoom and bbox changes and # to generate the thumbnail. newmap.save() return newmap
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) if 'access_token' in request.session: access_token = request.session['access_token'] else: access_token = None if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] map_obj = _resolve_map(request, mapid, 'base.view_resourcebase') map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json(request.user, access_token) del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) if 'layer' in params: bbox = None map_obj = Map(projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')) layers = [] for layer_name in params.getlist('layer'): try: layer = _resolve_layer(request, layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm( 'view_resourcebase', obj=layer.get_self_resource()): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = max(bbox[1], layer_bbox[1]) bbox[2] = min(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) config = layer.attribute_config() # Add required parameters for GXP lazy-loading config["title"] = layer.title config["queryable"] = True config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \ else llbbox_to_mercator([float(coord) for coord in bbox]) if layer.storeType == "remoteStore": service = layer.service # Probably not a good idea to send the access token to every remote service. # This should never match, so no access token should be sent to remote services. ogc_server_url = urlparse.urlsplit(ogc_server_settings.PUBLIC_LOCATION).netloc service_url = urlparse.urlsplit(service.base_url).netloc if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url: url = service.base_url+'?access_token='+access_token else: url = service.base_url maplayer = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True, source_params=json.dumps({ "ptype": service.ptype, "remote": True, "url": url, "name": service.name})) else: ogc_server_url = urlparse.urlsplit(ogc_server_settings.PUBLIC_LOCATION).netloc layer_url = urlparse.urlsplit(layer.ows_url).netloc if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url: url = layer.ows_url+'?access_token='+access_token else: url = layer.ows_url maplayer = MapLayer( map=map_obj, name=layer.typename, ows_url=url, # use DjangoJSONEncoder to handle Decimal values layer_params=json.dumps(config, cls=DjangoJSONEncoder), visibility=True ) layers.append(maplayer) if bbox is not None: minx, miny, maxx, maxy = [float(coord) for coord in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326": center = list((x, y)) else: center = list(forward_mercator((x, y))) if center[1] == float('-inf'): center[1] = 0 BBOX_DIFFERENCE_THRESHOLD = 1e-5 # Check if the bbox is invalid valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD if valid_x: width_zoom = math.log(360 / abs(maxx - minx), 2) else: width_zoom = 15 if valid_y: height_zoom = math.log(360 / abs(maxy - miny), 2) else: height_zoom = 15 map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) config = map_obj.viewer_json( request.user, access_token, *(DEFAULT_BASE_LAYERS + layers)) config['fromLayer'] = True else: config = DEFAULT_MAP_CONFIG return json.dumps(config)
def testPrintProxy(self): """ Test the PrintProxyMiddleware if activated. It should respect the permissions on private layers. """ if 'geonode.middleware.PrintProxyMiddleware' in settings.MIDDLEWARE_CLASSES: # STEP 1: Import a layer from geonode.maps.models import Map self.client.login(username='******', password='******') # TODO: Would be nice to ensure the name is available before # running the test... norman = get_user_model().objects.get(username="******") saved_layer = file_upload( os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) # Set the layer private saved_layer.set_permissions( {'users': { 'AnonymousUser': ['view_resourcebase'] }}) url = reverse('layer_metadata', args=[saved_layer.service_typename]) # check is accessible while logged in resp = self.client.get(url) self.assertEquals(resp.status_code, 200) # check is inaccessible when not logged in self.client.logout() resp = self.client.get(url) self.assertEquals(resp.status_code, 302) # STEP 2: Create a Map with that layer map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], 'title', '') # STEP 3: Print the map print_url = settings.OGC_SERVER['default'][ 'LOCATION'] + 'pdf/create.json' post_payload = { 'dpi': 75, 'layers': [{ 'baseURL': settings.OGC_SERVER['default']['LOCATION'] + 'wms?SERVICE=WMS&', 'format': "image/png", 'customParams': { 'TILED': True, 'TRANSPARENT': True }, 'layers': [saved_layer.service_typename], 'opacity': 1, 'singleTile': False, 'type': 'WMS' }], 'layout': 'A4 portrait', 'mapTitle': 'test', 'outputFilename': 'print', 'srs': getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'), 'units': 'm' } self.client.post(print_url, post_payload) # Test the layer is still inaccessible as non authenticated resp = self.client.get(url) self.assertEquals(resp.status_code, 302) else: pass
def new_linked_map(request, smapid, snapshot=None, template='maps/map_view.html'): """ The view that returns the map composer opened to the map with the given map ID. """ smap=StaticMap.objects.filter(id=smapid) DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() m = Map() user = request.user m.owner = user m.title = 'GISMap_%s' % smap[0].title m.abstract = DEFAULT_ABSTRACT m.projection = "EPSG:900913" m.zoom = 0 m.center_x = 0 m.center_y = 0 m.save() smap.update(linked_map=m.id) if snapshot is None: config = m.viewer_json(request.user, *DEFAULT_BASE_LAYERS) else: config = snapshot_config(snapshot, m, request.user) return render_to_response(template, RequestContext(request, { 'config': json.dumps(config), 'map': m }))
def get_context_data(self, **kwargs): request = self.request if request and 'access_token' in request.session: access_token = request.session['access_token'] else: access_token = None snapshot = self.kwargs.get('snapshot') DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) layers = Layer.objects.all() if request.method == 'GET' and 'copy' in request.GET: """Prepare context data.""" request = self.request mapid = self.request.GET['copy'] map_obj = _resolve_map( request, mapid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) if snapshot is None: config = map_obj.viewer_json(request) else: config = snapshot_config(snapshot, map_obj, request) # list all required layers map_layers = MapLayer.objects.filter( map_id=mapid).order_by('stack_order') context = { 'config': json.dumps(config), 'create': False, 'layers': layers, 'map': map_obj, 'map_layers': map_layers, 'preview': getattr( settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', '') } return context else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return self.render_to_response(status=405) if 'layer' in params: bbox = None map_obj = Map(projection=getattr( settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')) for layer_name in params.getlist('layer'): try: layer = _resolve_layer(request, layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm( 'view_resourcebase', obj=layer.get_self_resource()): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = min(bbox[1], layer_bbox[1]) bbox[2] = max(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) config = layer.attribute_config() # Add required parameters for GXP lazy-loading config["title"] = layer.title config["queryable"] = True config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') config["bbox"] = bbox if config["srs"] != 'EPSG:3857' \ else llbbox_to_mercator( [float(coord) for coord in bbox]) if layer.storeType == "remoteStore": service = layer.remote_service # Probably not a good idea to send the access token to every remote service. # This should never match, so no access token should be sent to remote services. ogc_server_url = urlparse.urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc service_url = urlparse.urlsplit( service.base_url).netloc if access_token and ogc_server_url == service_url and \ 'access_token' not in service.base_url: url = '%s?access_token=%s' % (service.base_url, access_token) else: url = service.base_url map_layers = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True, source_params=json.dumps({ "ptype": service.ptype, "remote": True, "url": url, "name": service.name, "title": "[R] %s" % service.title})) else: ogc_server_url = urlparse.urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc layer_url = urlparse.urlsplit(layer.ows_url).netloc if access_token and ogc_server_url == layer_url and \ 'access_token' not in layer.ows_url: url = layer.ows_url + '?access_token=' + \ access_token else: url = layer.ows_url map_layers = MapLayer( map=map_obj, name=layer.typename, ows_url=url, # use DjangoJSONEncoder to handle Decimal values layer_params=json.dumps( config, cls=DjangoJSONEncoder), visibility=True ) if bbox and len(bbox) >= 4: minx, miny, maxx, maxy = [float(coord) for coord in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') == "EPSG:4326": center = list((x, y)) else: center = list(forward_mercator((x, y))) if center[1] == float('-inf'): center[1] = 0 BBOX_DIFFERENCE_THRESHOLD = 1e-5 # Check if the bbox is invalid valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD if valid_x: width_zoom = math.log(360 / abs(maxx - minx), 2) else: width_zoom = 15 if valid_y: height_zoom = math.log(360 / abs(maxy - miny), 2) else: height_zoom = 15 map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) map_obj.handle_moderated_uploads() if snapshot is None: config = map_obj.viewer_json(request) else: config = snapshot_config(snapshot, map_obj, request) config['fromLayer'] = True context = { 'config': json.dumps(config), 'create': True, 'layers': layers, 'map': map_obj, 'map_layers': map_layers, 'preview': getattr( settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', '') } else: # list all required layers layers = Layer.objects.all() context = { 'create': True, 'layers': layers } return context
def test_new_map_config(self): """Test that new map config can be properly assigned """ self.client.login(username='******', password='******') # Test successful new map creation m = Map() admin_user = get_user_model().objects.get(username='******') layer_name = Layer.objects.all()[0].alternate m.create_from_layer_list(admin_user, [layer_name], "title", "abstract") map_id = m.id url = reverse('new_map_json') # Test GET method with COPY response = self.client.get(url, {'copy': map_id}) self.assertEquals(response.status_code, 200) map_obj = Map.objects.get(id=map_id) config_map = map_obj.viewer_json(None, None) response_config_dict = json.loads(response.content) self.assertEquals( config_map['map']['layers'], response_config_dict['map']['layers']) # Test GET method no COPY and no layer in params response = self.client.get(url) self.assertEquals(response.status_code, 200) config_default = default_map_config(None)[0] response_config_dict = json.loads(response.content) self.assertEquals( config_default['about']['abstract'], response_config_dict['about']['abstract']) self.assertEquals( config_default['about']['title'], response_config_dict['about']['title']) # Test GET method no COPY but with layer in params response = self.client.get(url, {'layer': layer_name}) self.assertEquals(response.status_code, 200) response_dict = json.loads(response.content) self.assertEquals(response_dict['fromLayer'], True) # Test POST method without authentication self.client.logout() response = self.client.post(url, {'layer': layer_name}) self.assertEquals(response.status_code, 401) # Test POST method with authentication and a layer in params self.client.login(username='******', password='******') response = self.client.post(url, {'layer': layer_name}) # Should not accept the request self.assertEquals(response.status_code, 400) # Test POST method with map data in json format response = self.client.post( url, data=self.viewer_config, content_type="text/json") self.assertEquals(response.status_code, 200) map_id = int(json.loads(response.content)['id']) # Check new map saved map_obj = Map.objects.get(id=map_id) # Check # BBox format: [xmin, xmax, ymin, ymax bbox_str = [ '-90.1932079140', '-79.2067920625', '9.0592199045', '16.5407800920', 'EPSG:4326'] self.assertEqual( bbox_str, [str(c) for c in map_obj.bbox]) bbox_long_str = '-90.1932079140,9.0592199045,' \ '-79.2067920625,16.5407800920' self.assertEqual(bbox_long_str, map_obj.bbox_string) # Test methods other than GET or POST and no layer in params response = self.client.put(url) self.assertEquals(response.status_code, 405)
def create_from_layer_list(user, layers, title, abstract): newmap = Map() """Copied from maps.models and fixed """ newmap.owner = user newmap.title = title newmap.abstract = abstract newmap.projection = "EPSG:900913" newmap.zoom = 0 newmap.center_x = 0 newmap.center_y = 0 #bbox = None index = 0 incr_bbox = None DEFAULT_BASE_LAYERS = settings.MAP_BASELAYERS is_published = True if settings.RESOURCE_PUBLISHING: is_published = False newmap.is_published = is_published # Save the map in order to create an id in the database # used below for the maplayers. newmap.save() # Add background layers for layer in DEFAULT_BASE_LAYERS: logger.info("Adding baselayer %r", layer) maplayer = layer_from_viewer_config(MapLayer, layer, layer['source'], # source index) if not maplayer.group == 'background': logger.info("Skipping not base layer %r", layer) continue if 'name' not in layer or not layer['name']: logger.info("Unnamed base layer %r", layer) maplayer.name = 'UNNAMED BACKGROUND LAYER' maplayer.map = newmap maplayer.save() index += 1 # Add local layers for layer in layers: if not isinstance(layer, Layer): try: layer = Layer.objects.get(typename=layer) except ObjectDoesNotExist: raise Exception( 'Could not find layer with name %s' % layer) if not user.has_perm( 'base.view_resourcebase', obj=layer.resourcebase_ptr): # invisible layer, skip inclusion or raise Exception? raise Exception( 'User %s tried to create a map with layer %s without having premissions' % (user, layer)) ### Add required parameters for GXP lazy-loading # compute (incremental) bbox layer_bbox = layer.bbox if incr_bbox is None: incr_bbox = list(layer_bbox[0:4]) else: incr_bbox[0] = min(incr_bbox[0], layer_bbox[0]) incr_bbox[1] = max(incr_bbox[1], layer_bbox[1]) incr_bbox[2] = min(incr_bbox[2], layer_bbox[2]) incr_bbox[3] = max(incr_bbox[3], layer_bbox[3]) config = layer.attribute_config() config["title"] = layer.title config["queryable"] = True config["srs"] = layer.srid if layer.srid != "EPSG:4326" else "EPSG:900913" config["bbox"] = llbbox_to_mercator([float(coord) for coord in incr_bbox]) #if layer.storeType == "remoteStore": #service = layer.service #maplayer = MapLayer(map=map_obj, #name=layer.typename, #ows_url=layer.ows_url, #layer_params=json.dumps(config), #visibility=True, #source_params=json.dumps({ #"ptype": service.ptype, #"remote": True, #"url": service.base_url, #"name": service.name})) #else: #maplayer = MapLayer( #map=map_obj, #name=layer.typename, #ows_url=layer.ows_url, #layer_params=json.dumps(config), #visibility=True #) MapLayer.objects.create( map=newmap, name=layer.typename, ows_url=layer.ows_url, stack_order=index, visibility=True, layer_params=json.dumps(config) ) index += 1 # Set bounding box based on all layers extents. bbox = newmap.get_bbox_from_layers(newmap.local_layers) newmap.set_bounds_from_bbox(bbox) newmap.set_missing_info() # Save again to persist the zoom and bbox changes and # to generate the thumbnail. newmap.save() return newmap
def create_models(type=None): from django.contrib.auth.models import Group map_data, user_data, people_data, layer_data, document_data = create_fixtures() anonymous_group, created = Group.objects.get_or_create(name='anonymous') u, _ = get_user_model().objects.get_or_create(username='******', is_superuser=True, first_name='admin') u.set_password('admin') u.save() users = [] for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud u, created = get_user_model().objects.get_or_create(username=user_name) if created: u.first_name = first_name u.last_name = last_name u.save() u.groups.add(anonymous_group) users.append(u) get_user_model().objects.get(username='******').groups.add(anonymous_group) if not type or type == 'map': for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = md m = Map(title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, category=category, ) m.save() for kw in kws: m.keywords.add(kw) m.save() if not type or type == 'document': for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = dd m = Document(title=title, abstract=abstract, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, category=category, doc_file=f) m.save() for kw in kws: m.keywords.add(kw) m.save() if not type or type == 'layer': for ld, owner, storeType in zip(layer_data, cycle(users), cycle(('coverageStore', 'dataStore'))): title, abstract, name, typename, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), dt, kws, category = ld year, month, day = map(int, (dt[:4], dt[4:6], dt[6:])) start = datetime(year, month, day) end = start + timedelta(days=365) l = Layer(title=title, abstract=abstract, name=name, typename=typename, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, date=start, storeType=storeType, category=category, ) l.save() for kw in kws: l.keywords.add(kw) l.save()
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] map_obj = _resolve_map(request, mapid, 'maps.view_map') map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json() del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) if 'layer' in params: bbox = None map_obj = Map(projection="EPSG:900913") layers = [] for layer_name in params.getlist('layer'): try: layer = Layer.objects.get(typename=layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm('layers.view_layer', obj=layer): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = max(bbox[1], layer_bbox[1]) bbox[2] = min(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) layers.append( MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url(), layer_params=json.dumps(layer.attribute_config()), visibility=True)) if bbox is not None: minx, miny, maxx, maxy = [float(c) for c in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 center = forward_mercator((x, y)) if center[1] == float('-inf'): center[1] = 0 if maxx == minx: width_zoom = 15 else: width_zoom = math.log(360 / (maxx - minx), 2) if maxy == miny: height_zoom = 15 else: height_zoom = math.log(360 / (maxy - miny), 2) map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) config = map_obj.viewer_json(*(DEFAULT_BASE_LAYERS + layers)) config['fromLayer'] = True else: config = DEFAULT_MAP_CONFIG return json.dumps(config)
def set_geonode_map(self, caller, serializer, map_obj=None, data=None, attributes=None): def decode_base64(data): """Decode base64, padding being optional. :param data: Base64 data as an ASCII byte string :returns: The decoded byte string. """ _thumbnail_format = 'png' _invalid_padding = data.find(';base64,') if _invalid_padding: _thumbnail_format = data[data.find('image/') + len('image/'):_invalid_padding] data = data[_invalid_padding + len(';base64,'):] missing_padding = len(data) % 4 if missing_padding != 0: data += b'=' * (4 - missing_padding) return (base64.b64decode(data), _thumbnail_format) _map_name = None _map_title = None _map_abstract = None _map_thumbnail = None _map_thumbnail_format = 'png' if attributes: for _a in attributes: if _a['name'] == 'name' and 'value' in _a: _map_name = _a['value'] if _a['name'] == 'title' and 'value' in _a: _map_title = _a['value'] if _a['name'] == 'abstract' and 'value' in _a: _map_abstract = _a['value'] if 'thumb' in _a['name'] and 'value' in _a: try: (_map_thumbnail, _map_thumbnail_format) = decode_base64(_a['value']) except Exception: if _a['value']: _map_thumbnail = _a['value'] _map_thumbnail_format = 'link' elif map_obj: _map_title = map_obj.title _map_abstract = map_obj.abstract _map_name = _map_name or None if not _map_name and 'name' in serializer.validated_data: _map_name = serializer.validated_data['name'] _map_title = _map_title or _map_name _map_abstract = _map_abstract or "" if data: try: _map_conf = dict(data) _map_conf["about"] = { "name": _map_name, "title": _map_title, "abstract": _map_abstract } _map_conf['sources'] = {} from geonode.layers.views import layer_detail _map_obj = data.pop('map', None) if _map_obj: _map_bbox = [] for _lyr in _map_obj['layers']: _lyr_context = {} _lyr_store = _lyr['store'] if 'store' in _lyr else None if not _lyr_store: try: _url = urlparse(_lyr['catalogURL']) _lyr_store = Layer.objects.get( uuid=parse_qs(_url.query)['id'][0]).store except Exception: try: _lyr_store = Layer.objects.get( alternate=_lyr['name'], remote_service__base_url=_lyr['url'] ).store except Exception: _lyr_store = None _lyr_name = "%s:%s" % ( _lyr_store, _lyr['name']) if _lyr_store else _lyr['name'] try: # Retrieve the Layer Params back from GeoNode _gn_layer = layer_detail(caller.request, _lyr_name) if _gn_layer and _gn_layer.context_data: _context_data = json.loads( _gn_layer.context_data['viewer']) for _gn_layer_ctx in _context_data['map'][ 'layers']: if 'name' in _gn_layer_ctx and _gn_layer_ctx[ 'name'] == _lyr['name']: _lyr['store'] = _lyr_store if 'style' in _lyr: _lyr_context['style'] = _lyr[ 'style'] _lyr_context = _gn_layer_ctx _src_idx = _lyr_context['source'] _map_conf['sources'][ _src_idx] = _context_data[ 'sources'][_src_idx] except Http404: tb = traceback.format_exc() logger.debug(tb) except Exception: raise # Store ms2 layer idq if "id" in _lyr and _lyr["id"]: _lyr['extraParams'] = {"msId": _lyr["id"]} # Store the Capabilities Document into the Layer Params of GeoNode if _lyr_context: if 'ftInfoTemplate' in _lyr_context: _lyr['ftInfoTemplate'] = _lyr_context[ 'ftInfoTemplate'] if 'getFeatureInfo' in _lyr_context: _lyr['getFeatureInfo'] = _lyr_context[ 'getFeatureInfo'] if 'capability' in _lyr_context: _lyr['capability'] = _lyr_context['capability'] if 'bbox' in _lyr_context['capability']: _lyr_bbox = _lyr_context['capability'][ 'bbox'] if _map_obj['projection'] in _lyr_bbox: x0 = _lyr_bbox[ _map_obj['projection']]['bbox'][0] x1 = _lyr_bbox[ _map_obj['projection']]['bbox'][2] y0 = _lyr_bbox[ _map_obj['projection']]['bbox'][1] y1 = _lyr_bbox[ _map_obj['projection']]['bbox'][3] if len(_map_bbox) == 0: _map_bbox = [x0, x1, y0, y1] else: from geonode.utils import bbox_to_wkt from django.contrib.gis.geos import GEOSGeometry _l_wkt = bbox_to_wkt( x0, x1, y0, y1, srid=_map_obj['projection']) _m_wkt = bbox_to_wkt( _map_bbox[0], _map_bbox[2], _map_bbox[1], _map_bbox[3], srid=_map_obj['projection']) _map_srid = int( _map_obj['projection'][5:]) _l_poly = GEOSGeometry( _l_wkt, srid=_map_srid) _m_poly = GEOSGeometry( _m_wkt, srid=_map_srid).union(_l_poly) _map_bbox = _m_poly.extent if 'source' in _lyr_context: _source = _map_conf['sources'][ _lyr_context['source']] if 'remote' in _source and _source[ 'remote'] is True: _lyr['source'] = _lyr_context['source'] elif 'source' in _lyr: _map_conf['sources'][_lyr['source']] = {} event_type = None if is_analytics_enabled: event_type = EventType.EVENT_CHANGE if not map_obj: # Update Map BBox if 'bbox' not in _map_obj and (not _map_bbox or len(_map_bbox) != 4): _map_bbox = _map_obj['maxExtent'] # Must be in the form : [x0, x1, y0, y1] _map_obj['bbox'] = [ _map_bbox[0], _map_bbox[1], _map_bbox[2], _map_bbox[3] ] # Create a new GeoNode Map from geonode.maps.models import Map map_obj = Map(title=_map_title, owner=caller.request.user, center_x=_map_obj['center']['x'], center_y=_map_obj['center']['y'], projection=_map_obj['projection'], zoom=_map_obj['zoom'], srid=_map_obj['projection']) if 'bbox' in _map_obj: if hasattr(map_obj, 'bbox_polygon'): map_obj.bbox_polygon = BBOXHelper.from_xy( _map_obj['bbox']).as_polygon() else: map_obj.bbox_x0 = _map_obj['bbox'][0] map_obj.bbox_y0 = _map_obj['bbox'][1] map_obj.bbox_x1 = _map_obj['bbox'][2] map_obj.bbox_y1 = _map_obj['bbox'][3] map_obj.save() if is_analytics_enabled: event_type = EventType.EVENT_CREATE # Dumps thumbnail from MapStore2 Interface if _map_thumbnail: # note: dumping a thumbnail should be performed before update_from_viewer(), to remove # a race hazard. update_from_viewer() saves an existing map without a thumbnail, # triggering asynchronous generation of a default thumbnail, which may overwrite uploaded thumb if _map_thumbnail_format == 'link': map_obj.thumbnail_url = _map_thumbnail else: _map_thumbnail_filename = "map-%s-thumb.%s" % ( map_obj.uuid, _map_thumbnail_format) map_obj.save_thumbnail(_map_thumbnail_filename, _map_thumbnail) # Update GeoNode Map _map_conf['map'] = _map_obj map_obj.update_from_viewer(_map_conf, context={'config': _map_conf}) if is_analytics_enabled: register_event(caller.request, event_type, map_obj) serializer.validated_data['id'] = map_obj.id serializer.save(user=caller.request.user) except Exception as e: tb = traceback.format_exc() logger.error(tb) raise APIException(e) else: raise APIException("Map Configuration (data) is Mandatory!")
def set_geonode_map(self, caller, serializer, map_obj=None, data=None): _map_name = serializer.validated_data['title'] or map_obj.title _map_title = serializer.validated_data['title'] or map_obj.title _map_abstract = serializer.validated_data.get( 'abstract', '') or '' if not hasattr(map_obj, 'abstract') else map_obj.abstract if data: try: data_blob = data.copy() _map_conf = dict(data) _map_conf["about"] = { "name": _map_name, "title": _map_title, "abstract": _map_abstract } _map_conf['sources'] = {} from geonode.layers.views import layer_detail _map_obj = data.pop('map', None) if _map_obj: _map_bbox = [] for _lyr in _map_obj['layers']: _lyr_context = {} _lyr_store = _lyr['store'] if 'store' in _lyr else None if not _lyr_store: try: _url = urlparse(_lyr['catalogURL']) _lyr_store = Layer.objects.get( uuid=parse_qs(_url.query)['id'][0]).store except Exception: try: _lyr_store = Layer.objects.get( alternate=_lyr['name'], remote_service__base_url=_lyr['url'] ).store except Exception: _lyr_store = None _lyr_name = f"{_lyr_store}:{_lyr['name']}" if _lyr_store else _lyr[ 'name'] try: # Retrieve the Layer Params back from GeoNode _gn_layer = layer_detail(caller.request, _lyr_name) if _gn_layer and _gn_layer.context_data: _context_data = json.loads( _gn_layer.context_data['viewer']) for _gn_layer_ctx in _context_data['map'][ 'layers']: if 'name' in _gn_layer_ctx and _gn_layer_ctx[ 'name'] == _lyr['name']: _lyr['store'] = _lyr_store if 'style' in _lyr: _lyr_context['style'] = _lyr[ 'style'] if 'capability' in _gn_layer_ctx: # Add selected style to capability in layer_params _gn_layer_ctx['capability'][ 'style'] = _lyr['style'] _lyr_context = _gn_layer_ctx _src_idx = _lyr_context['source'] _map_conf['sources'][ _src_idx] = _context_data[ 'sources'][_src_idx] except Http404: tb = traceback.format_exc() logger.debug(tb) except Exception: raise # Store ms2 layer idq if "id" in _lyr and _lyr["id"]: _lyr['extraParams'] = {"msId": _lyr["id"]} # Store the Capabilities Document into the Layer Params of GeoNode if _lyr_context: if 'ftInfoTemplate' in _lyr_context: _lyr['ftInfoTemplate'] = _lyr_context[ 'ftInfoTemplate'] if 'getFeatureInfo' in _lyr_context: _lyr['getFeatureInfo'] = _lyr_context[ 'getFeatureInfo'] if 'capability' in _lyr_context: _lyr['capability'] = _lyr_context['capability'] if 'bbox' in _lyr_context['capability']: _lyr_bbox = _lyr_context['capability'][ 'bbox'] if _map_obj['projection'] in _lyr_bbox: x0 = _lyr_bbox[ _map_obj['projection']]['bbox'][0] x1 = _lyr_bbox[ _map_obj['projection']]['bbox'][2] y0 = _lyr_bbox[ _map_obj['projection']]['bbox'][1] y1 = _lyr_bbox[ _map_obj['projection']]['bbox'][3] if len(_map_bbox) == 0: _map_bbox = [x0, x1, y0, y1] else: from geonode.utils import bbox_to_wkt from django.contrib.gis.geos import GEOSGeometry _l_wkt = bbox_to_wkt( x0, x1, y0, y1, srid=_map_obj['projection']) _m_wkt = bbox_to_wkt( _map_bbox[0], _map_bbox[2], _map_bbox[1], _map_bbox[3], srid=_map_obj['projection']) _map_srid = int( _map_obj['projection'][5:]) _l_poly = GEOSGeometry( _l_wkt, srid=_map_srid) _m_poly = GEOSGeometry( _m_wkt, srid=_map_srid).union(_l_poly) _map_bbox = _m_poly.extent if 'source' in _lyr_context: _source = _map_conf['sources'][ _lyr_context['source']] if 'remote' in _source and _source[ 'remote'] is True: _lyr['source'] = _lyr_context['source'] elif 'source' in _lyr: _map_conf['sources'][_lyr['source']] = {} event_type = None if is_analytics_enabled: event_type = EventType.EVENT_CHANGE if not map_obj: # Create a new GeoNode Map from geonode.maps.models import Map map_obj = Map(title=_map_title, abstract=_map_abstract, owner=caller.request.user, center_x=_map_obj['center']['x'], center_y=_map_obj['center']['y'], projection=_map_obj['projection'], zoom=_map_obj['zoom'], srid=_map_obj['projection'], resource_type="map") if 'bbox' in _map_obj: if hasattr(map_obj, 'bbox_polygon'): map_obj.bbox_polygon = BBOXHelper.from_xy( _map_obj['bbox']).as_polygon() else: map_obj.bbox_x0 = _map_obj['bbox'][0] map_obj.bbox_y0 = _map_obj['bbox'][1] map_obj.bbox_x1 = _map_obj['bbox'][2] map_obj.bbox_y1 = _map_obj['bbox'][3] elif hasattr(map_obj, 'bbox_polygon' ) and map_obj.bbox_polygon is None: # set the bbox_polygon to the obj and then to serializer instance map_obj.set_bounds_from_center_and_zoom( _map_obj['center']['x'], _map_obj['center']['y'], _map_obj['zoom']) if is_analytics_enabled: event_type = EventType.EVENT_CREATE else: map_obj.title = _map_title map_obj.abstract = _map_abstract if not map_obj.uuid: map_obj.uuid = str(uuid4()) map_obj.blob = data_blob # Update GeoNode Map _map_conf['map'] = _map_obj if is_analytics_enabled: register_event(caller.request, event_type, map_obj) serializer.instance = map_obj serializer.save() serializer.instance.update_from_viewer( _map_conf, context={'config': _map_conf}) return serializer except Exception as e: tb = traceback.format_exc() logger.error(tb) raise APIException(e) else: raise APIException("Map Configuration (data) is Mandatory!")
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' # 3 cases in this function # 1. copy a map # 2. a new map with one or more layers # 3. a new map with no layers DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) if 'access_token' in request.session: access_token = request.session['access_token'] else: access_token = None # TODO support map copy if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] map_obj = _resolve_map(request, mapid, 'base.view_resourcebase') map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json(request.user, access_token) del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) # a new map with a layer if 'layer' in params: bbox = None map_obj = Map( projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')) layers = [] for layer_name in params.getlist('layer'): try: layer = _resolve_layer(request, layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm('view_resourcebase', obj=layer.get_self_resource()): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = max(bbox[1], layer_bbox[1]) bbox[2] = min(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) config = layer.attribute_config() # Add required parameters for GXP lazy-loading config["title"] = layer.title config["queryable"] = True config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \ else llbbox_to_mercator([float(coord) for coord in bbox]) if layer.storeType == "remoteStore": service = layer.service # Probably not a good idea to send the access token to every remote service. # This should never match, so no access token should be sent to remote services. ogc_server_url = urlparse.urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc service_url = urlparse.urlsplit(service.base_url).netloc if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url: url = service.base_url + '?access_token=' + access_token else: url = service.base_url maplayer = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True, source_params=json.dumps({ "ptype": service.ptype, "remote": True, "url": url, "name": service.name })) else: ogc_server_url = urlparse.urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc layer_url = urlparse.urlsplit(layer.ows_url).netloc if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url: url = layer.ows_url + '?access_token=' + access_token else: url = layer.ows_url maplayer = MapLayer( map=map_obj, name=layer.typename, ows_url=url, # use DjangoJSONEncoder to handle Decimal values layer_params=json.dumps(config, cls=DjangoJSONEncoder), visibility=True) layers.append(maplayer) if bbox is not None: minx, miny, maxx, maxy = [float(coord) for coord in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326": center = list((x, y)) else: center = list(forward_mercator((x, y))) if center[1] == float('-inf'): center[1] = 0 BBOX_DIFFERENCE_THRESHOLD = 1e-5 # Check if the bbox is invalid valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD if valid_x: width_zoom = math.log(360 / abs(maxx - minx), 2) else: width_zoom = 15 if valid_y: height_zoom = math.log(360 / abs(maxy - miny), 2) else: height_zoom = 15 map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) config = map_obj.viewer_json(request.user, access_token, *(DEFAULT_BASE_LAYERS + layers)) config['fromLayer'] = True geoexplorer2worldmap(config, map_obj, layers) else: # a new map with no layer config = DEFAULT_MAP_CONFIG geoexplorer2worldmap(config, map_obj) return json.dumps(config)
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] map_obj = _resolve_map(request, mapid, 'base.view_resourcebase') map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json(request.user) del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) if 'layer' in params: bbox = None map_obj = Map(projection="EPSG:900913") layers = [] for layer_name in params.getlist('layer'): try: layer = _resolve_layer(request, layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm( 'view_resourcebase', obj=layer.get_self_resource()): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = max(bbox[1], layer_bbox[1]) bbox[2] = min(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) config = layer.attribute_config() # Add required parameters for GXP lazy-loading config["srs"] = layer.srid config["title"] = layer.title config["bbox"] = [ float(coord) for coord in bbox] if layer.srid == "EPSG:4326" else llbbox_to_mercator( [ float(coord) for coord in bbox]) config["queryable"] = True if layer.storeType == "remoteStore": service = layer.service maplayer = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True, source_params=json.dumps({ "ptype": service.ptype, "remote": True, "url": service.base_url, "name": service.name})) else: maplayer = MapLayer( map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True ) layers.append(maplayer) if bbox is not None: minx, miny, maxx, maxy = [float(c) for c in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 center = list(forward_mercator((x, y))) if center[1] == float('-inf'): center[1] = 0 BBOX_DIFFERENCE_THRESHOLD = 1e-5 # Check if the bbox is invalid valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD if valid_x: width_zoom = math.log(360 / abs(maxx - minx), 2) else: width_zoom = 15 if valid_y: height_zoom = math.log(360 / abs(maxy - miny), 2) else: height_zoom = 15 map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) config = map_obj.viewer_json( request.user, *(DEFAULT_BASE_LAYERS + layers)) config['fromLayer'] = True else: config = DEFAULT_MAP_CONFIG return json.dumps(config)
def _create_viewer_config(): DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() _map = Map(projection="EPSG:900913", zoom=1, center_x=0, center_y=0) return json.dumps(_map.viewer_json(*DEFAULT_BASE_LAYERS))
def create_models(): u, _ = User.objects.get_or_create(username='******',is_superuser=True) u.set_password('admin') u.save() users = [] for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud profile = pd[0] u = User.objects.create_user(user_name) u.first_name = first_name u.last_name = last_name u.save() contact = Profile.objects.get(user=u) contact.profile = profile contact.save() users.append(u) for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1) = md m = Map(title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, ) m.save() for kw in kws: m.keywords.add(kw) m.save() for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1) = dd m = Document(title=title, abstract=abstract, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, ) m.save() for kw in kws: m.keywords.add(kw) m.save() for ld, owner, storeType in zip(layer_data, cycle(users), cycle(('raster','vector'))): title, abstract, name, typename, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), dt, kws = ld year, month, day = map(int, (dt[:4], dt[4:6], dt[6:])) start = datetime(year, month, day) end = start + timedelta(days=365) l = Layer(title=title, abstract=abstract, name=name, typename=typename, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, storeType=storeType ) l.save() for kw in kws: l.keywords.add(kw) l.save()
def create_models(type=None): from django.contrib.auth.models import Group map_data, user_data, people_data, layer_data, document_data = create_fixtures() anonymous_group, created = Group.objects.get_or_create(name='anonymous') u, _ = get_user_model().objects.get_or_create(username='******', is_superuser=True, first_name='admin') u.set_password('admin') u.save() users = [] for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud u, created = get_user_model().objects.get_or_create(username=user_name) if created: u.first_name = first_name u.last_name = last_name u.save() u.groups.add(anonymous_group) users.append(u) get_user_model().objects.get(username='******').groups.add(anonymous_group) if not type or type == 'map': for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = md m = Map(title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, category=category, ) m.save() for kw in kws: m.keywords.add(kw) m.save() if not type or type == 'document': for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = dd m = Document(title=title, abstract=abstract, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, category=category, doc_file=f) m.save() for kw in kws: m.keywords.add(kw) m.save() if not type or type == 'layer': for ld, owner, storeType in zip(layer_data, cycle(users), cycle(('coverageStore', 'dataStore'))): title, abstract, name, alternate, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), start, kws, category = ld end = start + timedelta(days=365) l = Layer(title=title, abstract=abstract, name=name, alternate=alternate, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, date=start, storeType=storeType, category=category, ) l.save() for kw in kws: l.keywords.add(kw) l.save()
def test_create_new_map(self): testMap = Map() self.assertIsInstance(testMap, Map)
def testPrintProxy(self): """ Test the PrintProxyMiddleware if activated. It should respect the permissions on private layers. """ if 'geonode.middleware.PrintProxyMiddleware' in settings.MIDDLEWARE_CLASSES: # STEP 1: Import a layer from geonode.maps.models import Map self.client.login(username='******', password='******') # TODO: Would be nice to ensure the name is available before # running the test... norman = get_user_model().objects.get(username="******") saved_layer = file_upload( os.path.join( gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) # Set the layer private saved_layer.set_permissions( {'users': {'AnonymousUser': ['view_resourcebase']}}) url = reverse( 'layer_metadata', args=[ saved_layer.service_typename]) # check is accessible while logged in resp = self.client.get(url) self.assertEquals(resp.status_code, 200) # check is inaccessible when not logged in self.client.logout() resp = self.client.get(url) self.assertEquals(resp.status_code, 302) # STEP 2: Create a Map with that layer map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], 'title', '') # STEP 3: Print the map print_url = settings.OGC_SERVER['default'][ 'LOCATION'] + 'pdf/create.json' post_payload = { 'dpi': 75, 'layers': [ { 'baseURL': settings.OGC_SERVER['default']['LOCATION'] + 'wms?SERVICE=WMS&', 'format': "image/png", 'customParams': { 'TILED': True, 'TRANSPARENT': True}, 'layers': [ saved_layer.service_typename], 'opacity': 1, 'singleTile': False, 'type': 'WMS'}], 'layout': 'A4 portrait', 'mapTitle': 'test', 'outputFilename': 'print', 'srs': 'EPSG:900913', 'units': 'm'} self.client.post(print_url, post_payload) # Test the layer is still inaccessible as non authenticated resp = self.client.get(url) self.assertEquals(resp.status_code, 302) else: pass
def set_geonode_map(self, caller, serializer, map_obj=None, data=None, attributes=None): def decode_base64(data): """Decode base64, padding being optional. :param data: Base64 data as an ASCII byte string :returns: The decoded byte string. """ _thumbnail_format = 'png' _invalid_padding = data.find(';base64,') if _invalid_padding: _thumbnail_format = data[data.find('image/') + len('image/'):_invalid_padding] data = data[_invalid_padding + len(';base64,'):] missing_padding = len(data) % 4 if missing_padding != 0: data += b'=' * (4 - missing_padding) return (data.decode('base64'), _thumbnail_format) _map_name = None _map_title = None _map_abstract = None _map_thumbnail = None _map_thumbnail_format = 'png' if attributes: for _a in attributes: if _a['name'] == 'name': _map_name = _a['value'] if _a['name'] == 'title': _map_title = _a['value'] if _a['name'] == 'abstract': _map_abstract = _a['value'] if 'thumb' in _a['name']: (_map_thumbnail, _map_thumbnail_format) = decode_base64(_a['value']) elif map_obj: _map_title = map_obj.title _map_abstract = map_obj.abstract _map_name = _map_name or None if not _map_name and 'name' in serializer.validated_data: _map_name = serializer.validated_data['name'] _map_title = _map_title or _map_name _map_abstract = _map_abstract or "" if data: try: _map_conf = dict(data) _map_conf["about"] = { "name": _map_name, "title": _map_title, "abstract": _map_abstract } _map_conf['sources'] = {} from geonode.layers.views import layer_detail _map_obj = data.pop('map', None) if _map_obj: _map_bbox = [] for _lyr in _map_obj['layers']: _lyr_context = {} try: # Retrieve the Layer Params back from GeoNode _gn_layer = layer_detail(caller.request, _lyr['name']) if _gn_layer and _gn_layer.context_data: _context_data = json.loads( _gn_layer.context_data['viewer']) for _gn_layer_ctx in _context_data['map'][ 'layers']: if 'name' in _gn_layer_ctx and _gn_layer_ctx[ 'name'] == _lyr['name']: if 'style' in _lyr: _lyr_context['style'] = _lyr[ 'style'] _lyr_context = _gn_layer_ctx _src_idx = _lyr_context['source'] _map_conf['sources'][ _src_idx] = _context_data[ 'sources'][_src_idx] except Http404: tb = traceback.format_exc() logger.debug(tb) except BaseException: raise # Store ms2 layer idq if "id" in _lyr and _lyr["id"]: _lyr['extraParams'] = {"msId": _lyr["id"]} # Store the Capabilities Document into the Layer Params of GeoNode if _lyr_context: if 'capability' in _lyr_context: _lyr['capability'] = _lyr_context['capability'] if 'bbox' in _lyr_context['capability']: _lyr_bbox = _lyr_context['capability'][ 'bbox'] if _map_obj['projection'] in _lyr_bbox: x0 = _lyr_bbox[ _map_obj['projection']]['bbox'][0] x1 = _lyr_bbox[ _map_obj['projection']]['bbox'][2] y0 = _lyr_bbox[ _map_obj['projection']]['bbox'][1] y1 = _lyr_bbox[ _map_obj['projection']]['bbox'][3] if len(_map_bbox) == 0: _map_bbox = [x0, x1, y0, y1] else: from geonode.utils import bbox_to_wkt from django.contrib.gis.geos import GEOSGeometry _l_wkt = bbox_to_wkt( x0, x1, y0, y1, srid=_map_obj['projection']) _m_wkt = bbox_to_wkt( _map_bbox[0], _map_bbox[2], _map_bbox[1], _map_bbox[3], srid=_map_obj['projection']) _map_srid = int( _map_obj['projection'][5:]) _l_poly = GEOSGeometry( _l_wkt, srid=_map_srid) _m_poly = GEOSGeometry( _m_wkt, srid=_map_srid).union(_l_poly) _map_bbox = _m_poly.extent if 'source' in _lyr_context: _source = _map_conf['sources'][ _lyr_context['source']] if 'remote' in _source and _source[ 'remote'] is True: _lyr['source'] = _lyr_context['source'] elif 'source' in _lyr: _map_conf['sources'][_lyr['source']] = {} # Update Map BBox if not _map_bbox or len(_map_bbox) != 4: _map_bbox = _map_obj['maxExtent'] # Must be in the form : [x0, x1, y0, y1] _map_obj['bbox'] = [ _map_bbox[0], _map_bbox[1], _map_bbox[2], _map_bbox[3] ] if not map_obj: # Create a new GeoNode Map from geonode.maps.models import Map map_obj = Map(title=_map_title, owner=caller.request.user, center_x=_map_obj['center']['x'], center_y=_map_obj['center']['y'], projection=_map_obj['projection'], zoom=_map_obj['zoom'], bbox_x0=_map_obj['bbox'][0], bbox_x1=_map_obj['bbox'][1], bbox_y0=_map_obj['bbox'][2], bbox_y1=_map_obj['bbox'][3], srid=_map_obj['projection']) map_obj.save() # Update GeoNode Map _map_conf['map'] = _map_obj map_obj.update_from_viewer(_map_conf, context={'config': _map_conf}) # Dumps thumbnail from MapStore2 Interface if _map_thumbnail: _map_thumbnail_filename = "map-%s-thumb.%s" % ( map_obj.uuid, _map_thumbnail_format) map_obj.save_thumbnail(_map_thumbnail_filename, _map_thumbnail) serializer.validated_data['id'] = map_obj.id serializer.save(user=caller.request.user) except BaseException: tb = traceback.format_exc() logger.error(tb) raise APIException(tb) else: raise APIException("Map Configuration (data) is Mandatory!")
def create_models(type=None, integration=False): map_data, user_data, people_data, layer_data, document_data = create_fixtures( ) anonymous_group, created = Group.objects.get_or_create(name='anonymous') with transaction.atomic(): logger.info("[SetUp] Get or create user admin") u = get_user_model().objects.filter(username='******').first() if not u: try: u = get_user_model().objects.create(username='******', is_superuser=True, first_name='admin') except Exception: raise if u: u.set_password('admin') u.save() users = [] for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud with transaction.atomic(): try: logger.info(f"[SetUp] Get or create user {user_name}") u, created = get_user_model().objects.get_or_create( username=user_name) if created: u.set_password(password) u.first_name = first_name u.last_name = last_name u.save() u.groups.add(anonymous_group) users.append(u) except Exception: raise logger.info(f"[SetUp] Add group {anonymous_group}") get_user_model().objects.get( username='******').groups.add(anonymous_group) obj_ids = [] from geonode.utils import DisableDjangoSignals with DisableDjangoSignals(skip=integration): if not type or ensure_string(type) == 'map': for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = md logger.info(f"[SetUp] Add map {title}") m = Map(title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', category=category) m.save() m.set_default_permissions() obj_ids.append(m.id) for kw in kws: m.keywords.add(kw) m.save() if not type or ensure_string(type) == 'document': for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = dd logger.info(f"[SetUp] Add document {title}") m = Document(title=title, abstract=abstract, owner=user, bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', category=category, doc_file=f) m.save() m.set_default_permissions() obj_ids.append(m.id) for kw in kws: m.keywords.add(kw) m.save() if not type or ensure_string(type) == 'layer': for ld, owner, storeType in zip( layer_data, cycle(users), cycle(('coverageStore', 'dataStore'))): title, abstract, name, alternate, ( bbox_x0, bbox_x1, bbox_y0, bbox_y1), start, kws, category = ld end = start + timedelta(days=365) logger.info(f"[SetUp] Add layer {title}") layer = Layer(title=title, abstract=abstract, name=name, alternate=alternate, bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, date=start, storeType=storeType, category=category) layer.save() layer.set_default_permissions() obj_ids.append(layer.id) for kw in kws: layer.keywords.add(kw) layer.save() return obj_ids
def new_map_json(request): if request.method == 'GET': config = new_map_config(request) if isinstance(config, HttpResponse): return config else: return HttpResponse(config) elif request.method == 'POST': if not request.user.is_authenticated(): return HttpResponse( 'You must be logged in to save new maps', content_type="text/plain", status=401 ) data = json.loads(request.body) title = data['about']['title'] category_id = int(data['about']['category']) organization_id = int(data['about']['organization']) group = GroupProfile.objects.get(id=organization_id) map_obj = Map(owner=request.user, zoom=0, center_x=0, center_y=0, category=TopicCategory.objects.get(id=category_id), group=group, title=title) map_obj.save() map_obj.set_default_permissions() permissions = _perms_info_json(map_obj) perm_dict = json.loads(permissions) if 'download_resourcebase' in perm_dict['groups']['anonymous']: perm_dict['groups']['anonymous'].remove('download_resourcebase') if 'view_resourcebase' in perm_dict['groups']['anonymous']: perm_dict['groups']['anonymous'].remove('view_resourcebase') # map_obj.set_permissions(perm_dict) # If the body has been read already, use an empty string. # See https://github.com/django/django/commit/58d555caf527d6f1bdfeab14527484e4cca68648 # for a better exception to catch when we move to Django 1.7. try: body = request.body except Exception: body = '' try: map_obj.update_from_viewer(body) # notify layer owners that this layer is used to create this map layers = map_obj.layers layer_owners = [layer.owner for layer in map_obj.local_layers] notify.send(request.user, recipient_list=layer_owners, actor=request.user, verb='created map using your layer', target=map_obj) MapSnapshot.objects.create( config=clean_config(body), map=map_obj, user=request.user) except ValueError as e: return HttpResponse(str(e), status=400) else: return HttpResponse( json.dumps({'id': map_obj.id}), status=200, content_type='application/json' ) else: return HttpResponse(status=405)
def get_context_data(self, **kwargs): request = self.request if request and 'access_token' in request.session: access_token = request.session['access_token'] else: access_token = None DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request) layers = Layer.objects.all() if request.method == 'GET' and 'copy' in request.GET: """Prepare context data.""" request = self.request mapid = self.request.GET['copy'] map_obj = _resolve_map(request, mapid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) config = map_obj.viewer_json(request) # list all required layers map_layers = MapLayer.objects.filter( map_id=mapid).order_by('stack_order') context = { 'config': json.dumps(config), 'create': False, 'layers': layers, 'map': map_obj, 'map_layers': map_layers, 'preview': getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'leaflet') } return context else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return self.render_to_response(status=405) if 'layer' in params: bbox = None map_obj = Map(projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')) for layer_name in params.getlist('layer'): try: layer = _resolve_layer(request, layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm( 'view_resourcebase', obj=layer.get_self_resource()): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = min(bbox[1], layer_bbox[1]) bbox[2] = max(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) config = layer.attribute_config() # Add required parameters for GXP lazy-loading config["title"] = layer.title config["queryable"] = True config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') config["bbox"] = bbox if config["srs"] != 'EPSG:3857' \ else llbbox_to_mercator( [float(coord) for coord in bbox]) if layer.storeType == "remoteStore": service = layer.remote_service # Probably not a good idea to send the access token to every remote service. # This should never match, so no access token should be sent to remote services. ogc_server_url = urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc service_url = urlsplit(service.base_url).netloc if access_token and ogc_server_url == service_url and \ 'access_token' not in service.base_url: url = '%s?access_token=%s' % (service.base_url, access_token) else: url = service.base_url map_layers = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True, source_params=json.dumps({ "ptype": service.ptype, "remote": True, "url": url, "name": service.name, "title": "[R] %s" % service.title })) else: ogc_server_url = urlsplit( ogc_server_settings.PUBLIC_LOCATION).netloc layer_url = urlsplit(layer.ows_url).netloc if access_token and ogc_server_url == layer_url and \ 'access_token' not in layer.ows_url: url = layer.ows_url + '?access_token=' + \ access_token else: url = layer.ows_url map_layers = MapLayer( map=map_obj, name=layer.typename, ows_url=url, # use DjangoJSONEncoder to handle Decimal values layer_params=json.dumps(config, cls=DjangoJSONEncoder), visibility=True) if bbox and len(bbox) >= 4: minx, miny, maxx, maxy = [float(coord) for coord in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') == "EPSG:4326": center = list((x, y)) else: center = list(forward_mercator((x, y))) if center[1] == float('-inf'): center[1] = 0 BBOX_DIFFERENCE_THRESHOLD = 1e-5 # Check if the bbox is invalid valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD if valid_x: width_zoom = math.log(360 / abs(maxx - minx), 2) else: width_zoom = 15 if valid_y: height_zoom = math.log(360 / abs(maxy - miny), 2) else: height_zoom = 15 map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) map_obj.handle_moderated_uploads() config = map_obj.viewer_json(request) config['fromLayer'] = True context = { 'config': json.dumps(config), 'create': True, 'layers': layers, 'map': map_obj, 'map_layers': map_layers, 'preview': getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'leaflet') } else: # list all required layers layers = Layer.objects.all() context = {'create': True, 'layers': layers} return context
def new_map_config(request): ''' View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. ''' DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() if request.method == 'GET' and 'copy' in request.GET: mapid = request.GET['copy'] map_obj = _resolve_map(request, mapid, 'base.view_resourcebase') map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json(request.user) del config['id'] else: if request.method == 'GET': params = request.GET elif request.method == 'POST': params = request.POST else: return HttpResponse(status=405) if 'layer' in params: bbox = None map_obj = Map( projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')) layers = [] for layer_name in params.getlist('layer'): try: layer = _resolve_layer(request, layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm('view_resourcebase', obj=layer.get_self_resource()): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = max(bbox[1], layer_bbox[1]) bbox[2] = min(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) config = layer.attribute_config() # Add required parameters for GXP lazy-loading config["title"] = layer.title config["queryable"] = True config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \ else llbbox_to_mercator([float(coord) for coord in bbox]) if layer.storeType == "remoteStore": service = layer.service maplayer = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True, source_params=json.dumps({ "ptype": service.ptype, "remote": True, "url": service.base_url, "name": service.name })) else: maplayer = MapLayer(map=map_obj, name=layer.typename, ows_url=layer.ows_url, layer_params=json.dumps(config), visibility=True) layers.append(maplayer) if bbox is not None: minx, miny, maxx, maxy = [float(c) for c in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326": center = list((x, y)) else: center = list(forward_mercator((x, y))) if center[1] == float('-inf'): center[1] = 0 BBOX_DIFFERENCE_THRESHOLD = 1e-5 # Check if the bbox is invalid valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD if valid_x: width_zoom = math.log(360 / abs(maxx - minx), 2) else: width_zoom = 15 if valid_y: height_zoom = math.log(360 / abs(maxy - miny), 2) else: height_zoom = 15 map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) config = map_obj.viewer_json(request.user, *(DEFAULT_BASE_LAYERS + layers)) config['fromLayer'] = True else: config = DEFAULT_MAP_CONFIG return json.dumps(config)
def create_models(type=None): map_data, user_data, people_data, layer_data, document_data = create_fixtures( ) u, _ = User.objects.get_or_create(username='******', is_superuser=True) u.set_password('admin') u.save() users = [] for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud profile = pd[0] u, created = User.objects.get_or_create(username=user_name) if created: u.first_name = first_name u.last_name = last_name u.save() contact = Profile.objects.get(user=u) contact.profile = profile contact.save() users.append(u) if not type or type == 'map': for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = md m = Map( title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, category=category, ) m.save() for kw in kws: m.keywords.add(kw) m.save() if not type or type == 'document': for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = dd m = Document(title=title, abstract=abstract, owner=user, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, category=category, doc_file=f) m.save() for kw in kws: m.keywords.add(kw) m.save() if not type or type == 'layer': for ld, owner, storeType in zip(layer_data, cycle(users), cycle(('coverageStore', 'dataStore'))): title, abstract, name, typename, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), dt, kws, category = ld year, month, day = map(int, (dt[:4], dt[4:6], dt[6:])) start = datetime(year, month, day) end = start + timedelta(days=365) l = Layer( title=title, abstract=abstract, name=name, typename=typename, bbox_x0=bbox_x0, bbox_x1=bbox_x1, bbox_y0=bbox_y0, bbox_y1=bbox_y1, uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, date=start, storeType=storeType, category=category, ) l.save() for kw in kws: l.keywords.add(kw) l.save()
def _create_viewer_config(): DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() _map = Map(projection="EPSG:900913", zoom = 1, center_x = 0, center_y = 0) return json.dumps(_map.viewer_json(*DEFAULT_BASE_LAYERS))
def new_map_config(request): """ View that creates a new map. If the query argument 'copy' is given, the initial map is a copy of the map with the id specified, otherwise the default map configuration is used. If copy is specified and the map specified does not exist a 404 is returned. """ DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config() if request.method == "GET" and "copy" in request.GET: mapid = request.GET["copy"] map_obj = _resolve_map(request, mapid, "maps.view_map") map_obj.abstract = DEFAULT_ABSTRACT map_obj.title = DEFAULT_TITLE if request.user.is_authenticated(): map_obj.owner = request.user config = map_obj.viewer_json() del config["id"] else: if request.method == "GET": params = request.GET elif request.method == "POST": params = request.POST else: return HttpResponse(status=405) if "layer" in params: bbox = None map_obj = Map(projection="EPSG:900913") layers = [] for layer_name in params.getlist("layer"): try: layer = Layer.objects.get(typename=layer_name) except ObjectDoesNotExist: # bad layer, skip continue if not request.user.has_perm("layers.view_layer", obj=layer): # invisible layer, skip inclusion continue layer_bbox = layer.bbox # assert False, str(layer_bbox) if bbox is None: bbox = list(layer_bbox[0:4]) else: bbox[0] = min(bbox[0], layer_bbox[0]) bbox[1] = max(bbox[1], layer_bbox[1]) bbox[2] = min(bbox[2], layer_bbox[2]) bbox[3] = max(bbox[3], layer_bbox[3]) layers.append( MapLayer( map=map_obj, name=layer.typename, ows_url=ogc_server_settings.public_url + "wms", layer_params=json.dumps(layer.attribute_config()), visibility=True, ) ) if bbox is not None: minx, miny, maxx, maxy = [float(c) for c in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 center = forward_mercator((x, y)) if center[1] == float("-inf"): center[1] = 0 if maxx == minx: width_zoom = 15 else: width_zoom = math.log(360 / (maxx - minx), 2) if maxy == miny: height_zoom = 15 else: height_zoom = math.log(360 / (maxy - miny), 2) map_obj.center_x = center[0] map_obj.center_y = center[1] map_obj.zoom = math.ceil(min(width_zoom, height_zoom)) config = map_obj.viewer_json(*(DEFAULT_BASE_LAYERS + layers)) config["fromLayer"] = True else: config = DEFAULT_MAP_CONFIG return json.dumps(config)
def create_models(type=None, integration=False): users = [] obj_ids = [] with transaction.atomic(): map_data, user_data, people_data, dataset_data, document_data = create_fixtures() registeredmembers_group, created = Group.objects.get_or_create(name='registered-members') anonymous_group, created = Group.objects.get_or_create(name='anonymous') cont_group, created = Group.objects.get_or_create(name='contributors') perm = Permission.objects.get(codename='add_resourcebase') cont_group.permissions.add(perm) logger.debug("[SetUp] Get or create user admin") u, created = get_user_model().objects.get_or_create(username='******') u.set_password('admin') u.is_superuser = True u.first_name = 'admin' u.save() u.groups.add(anonymous_group) users.append(u) for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud logger.debug(f"[SetUp] Get or create user {user_name}") u, created = get_user_model().objects.get_or_create(username=user_name) u.set_password(password) u.first_name = first_name u.last_name = last_name u.save() u.groups.add(anonymous_group) if not (u.is_superuser or u.is_staff or u.is_anonymous): u.groups.add(cont_group) users.append(u) logger.debug(f"[SetUp] Add group {anonymous_group}") get_user_model().objects.get(username='******').groups.add(anonymous_group) from geonode.utils import DisableDjangoSignals with DisableDjangoSignals(skip=integration): if not type or ensure_string(type) == 'map': for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = md logger.debug(f"[SetUp] Add map {title}") m = Map( title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', category=category, metadata_only=title == 'map metadata true' ) m.save() m.set_default_permissions() m.clear_dirty_state() m.set_processing_state(enumerations.STATE_PROCESSED) obj_ids.append(m.id) for kw in kws: m.keywords.add(kw) m.save() if not type or ensure_string(type) == 'document': for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = dd logger.debug(f"[SetUp] Add document {title}") m = Document( title=title, abstract=abstract, owner=user, bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', files=dfile, extension="gif", metadata_only=title == 'doc metadata true' ) m.save() m.set_default_permissions() m.clear_dirty_state() m.set_processing_state(enumerations.STATE_PROCESSED) obj_ids.append(m.id) for kw in kws: m.keywords.add(kw) m.save() if not type or ensure_string(type) == 'dataset': for ld, owner, subtype in zip(dataset_data, cycle(users), cycle(('raster', 'vector'))): title, abstract, name, alternate, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), start, kws, category = ld end = start + timedelta(days=365) logger.debug(f"[SetUp] Add dataset {title}") dataset = Dataset( title=title, abstract=abstract, name=name, alternate=alternate, bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox((bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, date=start, subtype=subtype, category=category, metadata_only=title == 'dataset metadata true' ) dataset.save() dataset.set_default_permissions() dataset.clear_dirty_state() dataset.set_processing_state(enumerations.STATE_PROCESSED) obj_ids.append(dataset.id) for kw in kws: dataset.keywords.add(kw) dataset.save() return obj_ids
def test_new_map_config(self): """Test that new map config can be properly assigned """ self.client.login(username='******', password='******') # Test successful new map creation m = Map() admin_user = get_user_model().objects.get(username='******') layer_name = Layer.objects.all().first().alternate m.create_from_layer_list(admin_user, [layer_name], "title", "abstract") map_id = m.id url = reverse('new_map_json') # Test GET method with COPY response = self.client.get(url, {'copy': map_id}) self.assertEqual(response.status_code, 200) map_obj = Map.objects.get(id=map_id) config_map = map_obj.viewer_json(None) content = response.content if isinstance(content, bytes): content = content.decode('UTF-8') response_config_dict = json.loads(content) self.assertEqual(config_map['map']['layers'], response_config_dict['map']['layers']) # Test GET method no COPY and no layer in params response = self.client.get(url) self.assertEqual(response.status_code, 200) config_default = default_map_config(None)[0] content = response.content if isinstance(content, bytes): content = content.decode('UTF-8') response_config_dict = json.loads(content) self.assertEqual(config_default['about']['abstract'], response_config_dict['about']['abstract']) self.assertEqual(config_default['about']['title'], response_config_dict['about']['title']) # Test GET method no COPY but with layer in params response = self.client.get(url, {'layer': layer_name}) self.assertEqual(response.status_code, 200) content = response.content if isinstance(content, bytes): content = content.decode('UTF-8') response_dict = json.loads(content) self.assertEqual(response_dict['fromLayer'], True) # Test POST method without authentication self.client.logout() response = self.client.post(url, {'layer': layer_name}) self.assertEqual(response.status_code, 401) # Test POST method with authentication and a layer in params self.client.login(username='******', password='******') try: response = self.client.post(url, {'layer': layer_name}) # Should not accept the request self.assertEqual(response.status_code, 400) # Test POST method with map data in json format response = self.client.post(url, data=self.viewer_config, content_type="text/json") self.assertEqual(response.status_code, 200) content = response.content if isinstance(content, bytes): content = content.decode('UTF-8') map_id = int(json.loads(content)['id']) # Check new map saved map_obj = Map.objects.get(id=map_id) # Check # BBox format: [xmin, xmax, ymin, ymax bbox_str = [ '-90.193207913954200', '-79.206792062465500', '9.059219904470890', '16.540780092025600', 'EPSG:4326' ] self.assertEqual(bbox_str, [str(c) for c in map_obj.bbox]) bbox_long_str = '-90.193207913954200,9.059219904470890,' \ '-79.206792062465500,16.540780092025600' self.assertEqual(bbox_long_str, map_obj.bbox_string) # Test methods other than GET or POST and no layer in params response = self.client.put(url) self.assertEqual(response.status_code, 405) except Exception: pass
def testPrintProxy(self): """ Test the PrintProxyMiddleware if activated. It should respect the permissions on private layers. """ if "geonode.middleware.PrintProxyMiddleware" in settings.MIDDLEWARE_CLASSES: # STEP 1: Import a layer from geonode.maps.models import Map self.client.login(username="******", password="******") # TODO: Would be nice to ensure the name is available before # running the test... norman = get_user_model().objects.get(username="******") saved_layer = file_upload( os.path.join(gisdata.VECTOR_DATA, "san_andres_y_providencia_poi.shp"), name="san_andres_y_providencia_poi_by_norman", user=norman, overwrite=True, ) # Set the layer private saved_layer.set_permissions({"users": {"AnonymousUser": ["view_resourcebase"]}}) url = reverse("layer_metadata", args=[saved_layer.service_typename]) # check is accessible while logged in resp = self.client.get(url) self.assertEquals(resp.status_code, 200) # check is inaccessible when not logged in self.client.logout() resp = self.client.get(url) self.assertEquals(resp.status_code, 302) # STEP 2: Create a Map with that layer map_obj = Map(owner=norman, zoom=0, center_x=0, center_y=0) map_obj.create_from_layer_list(norman, [saved_layer], "title", "") # STEP 3: Print the map print_url = settings.OGC_SERVER["default"]["LOCATION"] + "pdf/create.json" post_payload = { "dpi": 75, "layers": [ { "baseURL": settings.OGC_SERVER["default"]["LOCATION"] + "wms?SERVICE=WMS&", "format": "image/png", "customParams": {"TILED": True, "TRANSPARENT": True}, "layers": [saved_layer.service_typename], "opacity": 1, "singleTile": False, "type": "WMS", } ], "layout": "A4 portrait", "mapTitle": "test", "outputFilename": "print", "srs": getattr(settings, "DEFAULT_MAP_CRS", "EPSG:900913"), "units": "m", } self.client.post(print_url, post_payload) # Test the layer is still inaccessible as non authenticated resp = self.client.get(url) self.assertEquals(resp.status_code, 302) else: pass