2

I'm uploading user-defined rasters to geoserver through its REST API, using the Python requests library. I would like to classify and style the rasters based on users' choices, so the styles should change on each upload.

I have tried amending an idea found here in python. It appears to work, and returns a code of 200. But when I look at the layer preview in geoserver, it's unchanged, and the previous style is still assigned to the layer. I used the following code:

import requests
import json
from urllib.parse import urljoin

api_entry = 'http://localhost:8080/geoserver/rest/'
credential = ('admin', 'geoserver')

resource = 'sldservice/TEST_cycling_friction/rasterize.sld?min=0&max=100&classes=5&type=RAMP&ramp=CUSTOM&startColor=#1a9641&endColor=#d7191c&midColor=#feedaa'
request_url = urljoin(api_entry, resource)
headers = {'Accept': 'application/json'}

r = requests.get(
  request_url,
  #headers=headers,
  auth=credential)

print(r.status_code)
print(r.json)

Is there anyway to change styles dynamically? If this is not possible, is there any other way to change the attributes in an existing SLD?

EDIT 29/12/2017 - I think @IanTurton's suggestion may work, but I tried it by implementing the SLD file content as a python string, and then each time the SLD is uploaded, the string is amended accordingly. Something like the following:

def make_sld(cost_distance_threshold):
    hrs_dist = cost_distance_threshold * 60

    #string that will be parsed into SLD(XML) file  
    sld_string = '<?xml version="1.0" encoding="UTF-8"?>\n'
    sld_string += '<StyledLayerDescriptor version="1.0.0"\n'
    sld_string += '\txsi:schemaLocation="http://www.opengis.net/sld\n'
    sld_string += '\thttp://schemas.opengis.net/sld/1.0.0/\n'
    sld_string += '\tStyledLayerDescriptor.xsd"\n'
    sld_string += '\txmlns="http://www.opengis.net/sld"\n'
    sld_string += '\txmlns:ogc="http://www.opengis.net/ogc"\n'
    sld_string += '\txmlns:xlink="http://www.w3.org/1999/xlink"\n'
    sld_string += '\txmlns:xsi="http://www.w3.org/2001/\n'
    sld_string += '\tXMLSchema-instance">\n'
    sld_string += '\t\t<NamedLayer>\n'
    sld_string += '\t\t<Name>Time-cost style</Name>\n'
    sld_string += '\t\t<UserStyle>\n'
    sld_string += '\t\t<Title>Time-cost style</Title>\n'
    sld_string += '\t\t\t<FeatureTypeStyle>\n'
    sld_string += '\t\t\t\t<Rule>\n'
    sld_string += '\t\t\t\t\t<RasterSymbolizer>\n'
    sld_string += '\t\t\t\t\t\t<ColorMap>\n'
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#ffffcc" quantity="-1" opacity="0" />\n'
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#1a9641" quantity="{}" opacity="0.6" />\n'.format(0)            
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#58b353" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist)
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#96d165" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*2)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#c3e586" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*3)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#ebf6ac" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*4)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#feedaa" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*5)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#fdc980" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*6)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#f89d59" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*7)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#e75b3a" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*8)               
    sld_string += '\t\t\t\t\t\t\t<ColorMapEntry color="#d7191c" quantity="{}" opacity="0.6"/>\n'.format(hrs_dist*9)               
    sld_string += '\t\t\t\t\t\t</ColorMap>\n'
    sld_string += '\t\t\t\t\t</RasterSymbolizer>\n'
    sld_string += '\t\t\t\t</Rule>\n'
    sld_string += '\t\t\t</FeatureTypeStyle>\n'
    sld_string += '\t\t</UserStyle>\n'
    sld_string += '\t</NamedLayer>\n'
    sld_string += '</StyledLayerDescriptor>\n'

    #read string into file and save
    sld_name = 'time-cost-style.sld'
    filename = "opt/geoserver/data_dir/produced_rasters/{}".format(sld_name)
    fh = open(filename, 'w')
    fh.write(sld_string)
    fh.close()

    #create a style and upload the file 
    upload_SLD(filename, sld_name)

I uploaded the SLD as follows:

def upload_SLD(filename, sld_name):
    resource = 'styles/{}'.format(sld_name)
    file_name = filename
    headers = {'content-type': 'application/vnd.ogc.sld+xml'}
    request_url = urljoin(api_entry, resource)

    with open(file_name, 'rb') as f:
        r = requests.put(
            request_url,
            data=f,
            headers=headers,
            auth=credential
        )
    print "SLD uploading"
    print r.status_code
    print r.text

This seems a bit verbose, so if anyone knows a simpler method, I'd be happy to try it.

  • 1
    One feature of WMS is to allow the user to send an SLD to change the map style, not sure if it'll work with a raster though. Nothing to do with REST. – nmtoken Dec 26 '17 at 21:56
  • did you specify the new style name in the WMS request? – Ian Turton Dec 27 '17 at 10:41
  • @IanTurton I haven't got as far as calling it as a WMS yet, I'm just checking it in the Layer preview in the Geoserver interface. Would the name then be rasterize.sld? Thanks. – David Dec 27 '17 at 11:05
  • the name would be whatever you called it when you posted it to the rest api. – Ian Turton Dec 27 '17 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.