def get_styles_for_layer(layer_name): """Given a layer_name, return the available layer styles Example of url sent to Geoserver where layer name is "income_2so" http://localhost:8080/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=income_2so """ if not layer_name: MessageHelperJSON.get_json_msg(success=False, msg="The layer name was not specified") # Does this layer exist if Layer.objects.filter(name=layer_name).count() == 0: MessageHelperJSON.get_json_msg( success=False, msg="The layer name, \"%s\" was not found in the system." % layer_name) # Create geoserver query url query_url = 'wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=%s' % ( layer_name) get_styles_url = urljoin(settings.GEOSERVER_BASE_URL, query_url) print get_styles_url response, content = make_geoserver_get_request(get_styles_url) print response print content
def view_create_new_layer_style(request): """ Send in a POST request with parameters that conform to the attributes in the sld_helper_form.SLDHelperForm Encapsulates 3 steps: (1) Based on parameters, create new classfication rules and embed in SLD XML (2) Make the classification rules the default style for the given layer (3) Return links to the newly styled layer -- or an error message :returns: JSON message with either an error or data containing links to the update classification layer """ if not has_proper_auth(request): json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Authentication failed.") return HttpResponse(status=401, content=json_msg, content_type="application/json") if not request.POST: json_msg = MessageHelperJSON.get_json_msg(success=False, msg="use a POST request") return HttpResponse(status=405, content=json_msg, content_type="application/json") ls = LayerStyler(request.POST) ls.style_layer() print 'post style' if ls.err_found: print 'has an error!' print '\n'.join(ls.err_msgs) else: print 'not bad' json_msg = ls.get_json_message() # Will determine success/failure and appropriate params return HttpResponse(content=json_msg, content_type="application/json")
def get_sld_rules(params): """ Given the parameters defined in the SLDHelperForm: (1) Format the parameters as a GeoServer REST request (2) Make the request and retrieve the new XML rules :params dict: see the SLD HelperForm :returns: JSON message with data or error message Example of successful response: {"success": true, "data": {"style_rules": "<Rules><Rule><Title> > -2.7786 AND <= 2.4966</Title><Filter><And><PropertyIsGreaterThanOrEqualTo><PropertyName>Violence_4</PropertyName><Literal>-2.7786</Literal></PropertyIsGreaterThanOrEqualTo><PropertyIsLessThanOrEqualTo><PropertyName>Violence_4</PropertyName><Literal>2.4966</Literal></PropertyIsLessThanOrEqualTo></And></Filter><PolygonSymbolizer><Fill><CssParameter name=\"fill\">#424242</CssParameter></Fill><Stroke/></PolygonSymbolizer></Rule><Rule><Title> > 2.4966 AND <= 7.7718</Title><Filter><And><PropertyIsGreaterThan><PropertyName>Violence_4</PropertyName><Literal>2.4966</Literal></PropertyIsGreaterThan><PropertyIsLessThanOrEqualTo><PropertyName>Violence_4</PropertyName><Literal>7.7718</Literal></PropertyIsLessThanOrEqualTo></And></Filter><PolygonSymbolizer><Fill><CssParameter name=\"fill\">#676767</CssParameter></Fill><Stroke/></PolygonSymbolizer></Rule></Rules>"}} d = json.loads(json_response_str) xml_rules = d.get('data', {}).get('style_rules', None) Example of url sent to Geoserver: http://localhost:8080/geoserver/rest/sldservice/geonode:income_2so/classify.xml?reverse=&attribute=B19013_Med&ramp=Gray&endColor=%23A50F15&intervals=5&startColor=%23FEE5D9&method=equalInterval """ print('get_sld_rules.sld type: %s, params: %s' % (type(params), params)) if not type(params) in (QueryDict, dict): return None f = SLDHelperForm(params) if not f.is_valid(): print('form failed') return MessageHelperJSON.get_json_msg( success=False, msg='The following errors were encounted:', data_dict=f.get_error_list()) # Create geoserver query url sld_rules_url = get_retrieve_sld_rules_url(f.get_url_params_dict()) print '-' * 40 print sld_rules_url print '-' * 40 response, content = make_geoserver_get_request(sld_rules_url) print response # New rules not created -- possible bad data if content is not None and content == '<list/>': return MessageHelperJSON.get_json_msg( success=False, msg='Error in creating style rules for layer. Bad parameters.') # Remove whitespace from XML content = remove_whitespace_from_xml(content) if content is None: return MessageHelperJSON.get_json_msg( success=False, msg='Failed to remove whitespace from XML') # Were rules created? if not content.startswith('<Rules>'): return MessageHelperJSON.get_json_msg( success=False, msg='Not able to create style rules for layer') # Wrap the XML rules in JSON and send them back return MessageHelperJSON.get_json_msg(success=True, msg='', data_dict={'style_rules': content})
def get_sld_rules(params): """ Given the parameters defined in the SLDHelperForm: (1) Format the parameters as a GeoServer REST request (2) Make the request and retrieve the new XML rules :params dict: see the SLD HelperForm :returns: JSON message with data or error message Example of successful response: {"success": true, "data": {"style_rules": "<Rules><Rule><Title> > -2.7786 AND <= 2.4966</Title><Filter><And><PropertyIsGreaterThanOrEqualTo><PropertyName>Violence_4</PropertyName><Literal>-2.7786</Literal></PropertyIsGreaterThanOrEqualTo><PropertyIsLessThanOrEqualTo><PropertyName>Violence_4</PropertyName><Literal>2.4966</Literal></PropertyIsLessThanOrEqualTo></And></Filter><PolygonSymbolizer><Fill><CssParameter name=\"fill\">#424242</CssParameter></Fill><Stroke/></PolygonSymbolizer></Rule><Rule><Title> > 2.4966 AND <= 7.7718</Title><Filter><And><PropertyIsGreaterThan><PropertyName>Violence_4</PropertyName><Literal>2.4966</Literal></PropertyIsGreaterThan><PropertyIsLessThanOrEqualTo><PropertyName>Violence_4</PropertyName><Literal>7.7718</Literal></PropertyIsLessThanOrEqualTo></And></Filter><PolygonSymbolizer><Fill><CssParameter name=\"fill\">#676767</CssParameter></Fill><Stroke/></PolygonSymbolizer></Rule></Rules>"}} d = json.loads(json_response_str) xml_rules = d.get('data', {}).get('style_rules', None) Example of url sent to Geoserver: http://localhost:8080/geoserver/rest/sldservice/geonode:income_2so/classify.xml?reverse=&attribute=B19013_Med&ramp=Gray&endColor=%23A50F15&intervals=5&startColor=%23FEE5D9&method=equalInterval """ print('get_sld_rules.sld type: %s, params: %s' % (type(params), params)) if not type(params) in (QueryDict, dict): return None f = SLDHelperForm(params) if not f.is_valid(): print ('form failed') return MessageHelperJSON.get_json_msg(success=False, msg='The following errors were encounted:', data_dict=f.get_error_list()) # Create geoserver query url sld_rules_url = get_retrieve_sld_rules_url(f.get_url_params_dict()) print '-' *40 print sld_rules_url print '-' *40 response, content = make_geoserver_get_request(sld_rules_url) print response # New rules not created -- possible bad data if content is not None and content == '<list/>': return MessageHelperJSON.get_json_msg(success=False, msg='Error in creating style rules for layer. Bad parameters.') # Remove whitespace from XML content = remove_whitespace_from_xml(content) if content is None: return MessageHelperJSON.get_json_msg(success=False, msg='Failed to remove whitespace from XML') # Were rules created? if not content.startswith('<Rules>'): return MessageHelperJSON.get_json_msg(success=False, msg='Not able to create style rules for layer') # Wrap the XML rules in JSON and send them back return MessageHelperJSON.get_json_msg(success=True, msg='', data_dict={ 'style_rules' : content })
def get_json_message(self): if self.layer_metadata is not None: metadata_dict = self.layer_metadata.get_metadata_dict() if metadata_dict: return MessageHelperJSON.get_json_msg(success=True, msg='', data_dict=metadata_dict) else: logger.error('LayerStyler. Failed to retrieve metadata dict for layer [%s]' % (self.layer_name)) return MessageHelperJSON.get_json_msg(success=False, msg='Fail to create metadata dict') err_msg = '\n'.join(self.err_msgs) if not err_msg: err_msg = 'Failed to create layer. Please try again' return MessageHelperJSON.get_json_msg(success=False, msg=err_msg)
def get_layer_features_definition(layer_name): """Given a layer name, return the feature definition in JSON format :param layer_name: str :returns: JSON message with 'success' - true or false; and either 'message' or 'data' Example of successful JSON message: { "success": true", data": [{"name": "STATE", "type": "String"}, {"name": "Nbhd", "type": "String"}, {"name": "CT_ID_1", "type": "String"}, {"name": "UniqueID", "type": "Double"}, {"name": "NSA_ID_1", "type": "String"}, {"name": "B19013_Med", "type": "Double"}, {"name": "HOODS_PD_I", "type": "Double"}, {"name": "PERIMETER", "type": "Double"}, {"name": "COUNTY", "type": "String"}, {"name": "NSA_NAME", "type": "String"}, {"name": "Quality_of", "type": "Double"}, {"name": "DRY_PCT", "type": "Double"}, {"name": "DRY_ACRES", "type": "Double"}, {"name": "TRACT", "type": "String"}, {"name": "OBJECTID", "type": "Long"}, {"name": "BLK_COUNT", "type": "Integer"}, {"name": "AREA", "type": "Double"}, {"name": "NbhdCRM", "type": "String"}, {"name": "DRY_SQMI", "type": "Double"}, {"name": "the_geom", "type": "MultiPolygon"}, {"name": "SHAPE_LEN", "type": "Double"}, {"name": "LOGRECNO", "type": "String"}, {"name": "DRY_SQKM", "type": "Double"}, {"name": "UniqueID_1", "type": "Integer"}, {"name": "SHAPE_AREA", "type": "Double"}, {"name": "WALKABILIT", "type": "Double"}, {"name": "CT_ID", "type": "String"}, {"name": "Nbhd_1", "type": "String"}]} Example of failed JSON message: {"success": false, "message": "Definition not found for layer: \"income34x5\""} Example of url sent to Geoserver, where layer_name is "income_2so" http://localhost:8080/geoserver/rest/sldservice/geonode:income_2so/attributes.xml """ if not layer_name: MessageHelperJSON.get_json_msg(success=False, msg="The layer name was not specified") # Does this layer exist if Layer.objects.filter(name=layer_name).count() == 0: MessageHelperJSON.get_json_msg( success=False, msg="The layer name, \"%s\" was not found in the system." % layer_name) # Create geoserver query url #query_url = 'rest/sldservice/geonode:%s/attributes.xml' % layer_name layer_defn_url = get_layer_features_definition_url(layer_name) print(layer_defn_url) response, content = make_geoserver_get_request(layer_defn_url) # Layer definition not found! if content is not None and content == '<list/>': return MessageHelperJSON.get_json_msg( success=False, msg="Layer not found for name: \"%s\"" % layer_name) try: dict_content = xmltodict.parse(content) except: return MessageHelperJSON.get_json_msg( success=False, msg="Not able to convert field names for layer: \"%s\"" % layer_name) field_list = dict_content.get('Attributes', {}).get('Attribute', None) if field_list is None: return MessageHelperJSON.get_json_msg( success=False, msg="Field names not found for layer: \"%s\"" % layer_name) return MessageHelperJSON.get_json_msg(success=True, msg='', data_dict=field_list)
def view_create_new_layer_style(request): """ Send in a POST request with parameters that conform to the attributes in the sld_helper_form.SLDHelperForm Encapsulates 3 steps: (1) Based on parameters, create new classfication rules and embed in SLD XML (2) Make the classification rules the default style for the given layer (3) Return links to the newly styled layer -- or an error message :returns: JSON message with either an error or data containing links to the update classification layer """ if not has_proper_auth(request): json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Authentication failed.") return HttpResponse(status=401, content=json_msg, content_type="application/json") if not request.POST: json_msg = MessageHelperJSON.get_json_msg(success=False, msg="use a POST request") return HttpResponse(status=405, content=json_msg, content_type="application/json") ls = LayerStyler(request.POST) ls.style_layer() print 'post style' if ls.err_found: print 'has an error!' print '\n'.join(ls.err_msgs) else: print 'not bad' json_msg = ls.get_json_message( ) # Will determine success/failure and appropriate params return HttpResponse(content=json_msg, content_type="application/json")
def view_layer_feature_defn(request, layer_name): """ Given a layer name, retrieve a desciption of the field names in values. This will be in XML format. example: http://localhost:8000/dvn/describe-features/income_4x5/ """ if not has_proper_auth(request): json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Authentication failed.") return HttpResponse(status=401, content=json_msg, content_type="application/json") json_msg = get_layer_features_definition(layer_name) return HttpResponse(content=json_msg, content_type="application/json")
def get_styles_for_layer(layer_name): """Given a layer_name, return the available layer styles Example of url sent to Geoserver where layer name is "income_2so" http://localhost:8080/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=income_2so """ if not layer_name: MessageHelperJSON.get_json_msg(success=False, msg="The layer name was not specified") # Does this layer exist if Layer.objects.filter(name=layer_name).count() == 0: MessageHelperJSON.get_json_msg(success=False, msg="The layer name, \"%s\" was not found in the system." % layer_name) # Create geoserver query url query_url = 'wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=%s' % (layer_name) get_styles_url = urljoin(settings.GEOSERVER_BASE_URL, query_url) print get_styles_url response, content = make_geoserver_get_request(get_styles_url) print response print content
def get_layer_features_definition(layer_name): """Given a layer name, return the feature definition in JSON format :param layer_name: str :returns: JSON message with 'success' - true or false; and either 'message' or 'data' Example of successful JSON message: { "success": true", data": [{"name": "STATE", "type": "String"}, {"name": "Nbhd", "type": "String"}, {"name": "CT_ID_1", "type": "String"}, {"name": "UniqueID", "type": "Double"}, {"name": "NSA_ID_1", "type": "String"}, {"name": "B19013_Med", "type": "Double"}, {"name": "HOODS_PD_I", "type": "Double"}, {"name": "PERIMETER", "type": "Double"}, {"name": "COUNTY", "type": "String"}, {"name": "NSA_NAME", "type": "String"}, {"name": "Quality_of", "type": "Double"}, {"name": "DRY_PCT", "type": "Double"}, {"name": "DRY_ACRES", "type": "Double"}, {"name": "TRACT", "type": "String"}, {"name": "OBJECTID", "type": "Long"}, {"name": "BLK_COUNT", "type": "Integer"}, {"name": "AREA", "type": "Double"}, {"name": "NbhdCRM", "type": "String"}, {"name": "DRY_SQMI", "type": "Double"}, {"name": "the_geom", "type": "MultiPolygon"}, {"name": "SHAPE_LEN", "type": "Double"}, {"name": "LOGRECNO", "type": "String"}, {"name": "DRY_SQKM", "type": "Double"}, {"name": "UniqueID_1", "type": "Integer"}, {"name": "SHAPE_AREA", "type": "Double"}, {"name": "WALKABILIT", "type": "Double"}, {"name": "CT_ID", "type": "String"}, {"name": "Nbhd_1", "type": "String"}]} Example of failed JSON message: {"success": false, "message": "Definition not found for layer: \"income34x5\""} Example of url sent to Geoserver, where layer_name is "income_2so" http://localhost:8080/geoserver/rest/sldservice/geonode:income_2so/attributes.xml """ if not layer_name: MessageHelperJSON.get_json_msg(success=False, msg="The layer name was not specified") # Does this layer exist if Layer.objects.filter(name=layer_name).count() == 0: MessageHelperJSON.get_json_msg(success=False, msg="The layer name, \"%s\" was not found in the system." % layer_name) # Create geoserver query url #query_url = 'rest/sldservice/geonode:%s/attributes.xml' % layer_name layer_defn_url =get_layer_features_definition_url(layer_name) print (layer_defn_url) response, content = make_geoserver_get_request(layer_defn_url) # Layer definition not found! if content is not None and content == '<list/>': return MessageHelperJSON.get_json_msg(success=False, msg="Layer not found for name: \"%s\"" % layer_name) try: dict_content = xmltodict.parse(content) except: return MessageHelperJSON.get_json_msg(success=False, msg="Not able to convert field names for layer: \"%s\"" % layer_name) field_list = dict_content.get('Attributes', {}).get('Attribute', None) if field_list is None: return MessageHelperJSON.get_json_msg(success=False, msg="Field names not found for layer: \"%s\"" % layer_name) return MessageHelperJSON.get_json_msg(success=True, msg='', data_dict=field_list)
def view_layer_classify_params(request, layer_name): """ Given a layer name, return attributes needed to run a GeoConnect classification form. This includes: - attributes - formulas - colors on Geo a desciption of the field names in values. This will be in XML format. example: http://localhost:8000/dvn/describe-features/income_4x5/ """ if not has_proper_auth(request): json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Authentication failed.") return HttpResponse(status=401, content=json_msg, content_type="application/json") json_msg = get_layer_features_definition(layer_name) return HttpResponse(content=json_msg, content_type="application/json")
def dvn_import(request): if not has_proper_auth(request): json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Authentication failed.") return HttpResponse(status=401, content=json_msg, content_type="application/json") if request.POST: user = None title = request.POST["title"] abstract = request.POST["abstract"] email = request.POST["email"] content = request.FILES.values()[0] name = request.POST["shapefile_name"] #dataverse_info = request.POST.get('dataverse_info', None) keywords = "" if "keywords" not in request.POST else request.POST["keywords"] #print request.POST.items() if "worldmap_username" in request.POST: try: user = User.objects.get(username=request.POST["username"]) except: pass if user is None: existing_user = User.objects.filter(email=email) if existing_user.count() > 0: user = existing_user[0] else: user = _create_new_user(email, None, None, None) if not user: json_msg = MessageHelperJSON.get_json_msg(success=False, msg="A user account could not be created for email %s" % email) return HttpResponse(status=200, content=json_msg, content_type="application/json") else: name = slugify(name.replace(".","_")) file_obj = write_file(content) try: # Save the actual layer saved_layer = save(name, file_obj, user, overwrite = False, abstract = abstract, title = title, keywords = keywords.split() ) # Look for DataverseInfo in the request.POST # If it exists, create a DataverseLayerMetadata object # add_dataverse_layer_metadata(saved_layer, request.POST) # Prepare a JSON reponse # layer_metadata_obj = LayerMetadata(**{ 'geonode_layer_object' : saved_layer}) # Return the response! json_msg = MessageHelperJSON.get_json_msg(success=True, msg='worked', data_dict=layer_metadata_obj.get_metadata_dict()) #print '-' * 40 #print 'json_msg', json_msg return HttpResponse(status=200, content=json_msg, content_type="application/json") """ return HttpResponse(status=200, content=json.dumps({ "success": True, "layer_name": saved_layer.typename, "layer_link": "%sdata/%s" % (settings.SITEURL, saved_layer.typename), "embed_map_link": "%smaps/embed/?layer=%s" % (settings.SITEURL, saved_layer.typename), "worldmap_username": user.username })) """ except: e = sys.exc_info()[0] logger.error("Unexpected error during dvn import: %s : %s" % (name, escape(str(e)))) err_msg = "Unexpected error during upload: %s" % escape(str(e)) json_msg = MessageHelperJSON.get_json_msg(success=False, msg=err_msg) return HttpResponse(content=json_msg, content_type="application/json") else: json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Requests must be POST not GET") return HttpResponse(status=401, content=json_msg, content_type="application/json")
def dvn_import(request): if not has_proper_auth(request): json_msg = MessageHelperJSON.get_json_msg(success=False, msg="Authentication failed.") return HttpResponse(status=401, content=json_msg, content_type="application/json") if request.POST: user = None title = request.POST["title"] abstract = request.POST["abstract"] email = request.POST["email"] content = request.FILES.values()[0] name = request.POST["shapefile_name"] #dataverse_info = request.POST.get('dataverse_info', None) keywords = "" if "keywords" not in request.POST else request.POST[ "keywords"] #print request.POST.items() if "worldmap_username" in request.POST: try: user = User.objects.get(username=request.POST["username"]) except: pass if user is None: existing_user = User.objects.filter(email=email) if existing_user.count() > 0: user = existing_user[0] else: user = _create_new_user(email, None, None, None) if not user: json_msg = MessageHelperJSON.get_json_msg( success=False, msg="A user account could not be created for email %s" % email) return HttpResponse(status=200, content=json_msg, content_type="application/json") else: name = slugify(name.replace(".", "_")) file_obj = write_file(content) try: # Save the actual layer saved_layer = save(name, file_obj, user, overwrite=False, abstract=abstract, title=title, keywords=keywords.split()) # Look for DataverseInfo in the request.POST # If it exists, create a DataverseLayerMetadata object # add_dataverse_layer_metadata(saved_layer, request.POST) # Prepare a JSON reponse # layer_metadata_obj = LayerMetadata( **{'geonode_layer_object': saved_layer}) # Return the response! json_msg = MessageHelperJSON.get_json_msg( success=True, msg='worked', data_dict=layer_metadata_obj.get_metadata_dict()) #print '-' * 40 #print 'json_msg', json_msg return HttpResponse(status=200, content=json_msg, content_type="application/json") """ return HttpResponse(status=200, content=json.dumps({ "success": True, "layer_name": saved_layer.typename, "layer_link": "%sdata/%s" % (settings.SITEURL, saved_layer.typename), "embed_map_link": "%smaps/embed/?layer=%s" % (settings.SITEURL, saved_layer.typename), "worldmap_username": user.username })) """ except: e = sys.exc_info()[0] logger.error("Unexpected error during dvn import: %s : %s" % (name, escape(str(e)))) err_msg = "Unexpected error during upload: %s" % escape(str(e)) json_msg = MessageHelperJSON.get_json_msg(success=False, msg=err_msg) return HttpResponse(content=json_msg, content_type="application/json") else: json_msg = MessageHelperJSON.get_json_msg( success=False, msg="Requests must be POST not GET") return HttpResponse(status=401, content=json_msg, content_type="application/json")