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.