In the previous recipe, you loaded a shapefile with REST. A data store and a layer were created and your data is now published on WMS. If you go to the layer preview page and select the ne_110m_coastline layer layer, you should see a map like this:
A style is applied to the data and all mandatory layer parameters were compiled by GeoServer when you issued the data store creation request.
While this is enough to get data properly configured on your server, in a real-world case your automation workflow should provide more control over data publication. The GeoServer REST interface gives you control over the layer item. In this recipe, you will see how to create a new layer and edit an existing one.
$ curl -u admin:geoserver -XGET -H 'Accept: text/xml' http://localhost:8080/geoserver/rest/layers/ne_110m_coastline -o ne_110m_coastline.xml
>>> myUrl = 'http://localhost:8080/geoserver/rest/layers/ne_110m_coastline' >>> headers = {'Accept': 'text/xml'} >>> resp = requests.get(myUrl, auth=('admin','geoserver'), headers=headers)
<layer> <name>ne_110m_coastline</name> <type>VECTOR</type> <defaultStyle> <name>line</name> <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/styles/line.xml" type="application/xml"/> </defaultStyle> <resource class="featureType"> <name>ne_110m_coastline</name> <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline.xml" type="application/xml"/> </resource> <attribution> <logoWidth>0</logoWidth> <logoHeight>0</logoHeight> </attribution> </layer>
$ curl -u admin:geoserver -XGET -H 'Accept: text/xml' http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline.xml -o ne_110m_coastline_ft.xml
>>> myUrl = 'http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline.xml' >>> headers = {'Accept': 'text/xml'} >>> resp = requests.get(myUrl, auth=('admin','geoserver'), headers=headers)
<featureType> <name>ne_110m_coastline</name> <nativeName>ne_110m_coastline</nativeName> <namespace> <name>NaturalEarth</name> <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/namespaces/NaturalEarth.xml" type="application/xml"/> </namespace> <title>ne_110m_coastline</title> <keywords> <string>ne_110m_coastline</string> <string>features</string> </keywords> <nativeCRS> … </nativeCRS> <srs>EPSG:4326</srs> <nativeBoundingBox> <minx>-180.0</minx> <maxx>180.00000044181039</maxx> <miny>-85.60903777459774</miny> <maxy>83.64513</maxy> <crs> … </crs> </nativeBoundingBox> <latLonBoundingBox> … </latLonBoundingBox> <projectionPolicy>NONE</projectionPolicy> <enabled>true</enabled> <store class="dataStore"> <name>Coastline</name> <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline.xml" type="application/xml"/> </store> <maxFeatures>0</maxFeatures> <numDecimals>0</numDecimals> <attributes> <attribute> <name>the_geom</name> <minOccurs>0</minOccurs> <maxOccurs>1</maxOccurs> <nillable>true</nillable> <binding>com.vividsolutions.jts.geom.MultiLineString</binding> </attribute> … </attributes> </featureType>
changeStyle.xml
:<layer> <defaultStyle> <name>simple_roads</name> </defaultStyle> <enabled>true</enabled> </layer>
PUT
request to change configuration for the layer:$ curl -u admin:geoserver -XPUT -H 'Content-type: text/xml' -d @changeStyle.xml http://localhost:8080/geoserver/rest/layers/ne_110m_coastline
>>> myUrl = 'http://localhost:8080/geoserver/rest/layers/ne_110m_coastline' >>> file = open('changeStyle.zip','r') >>> payload = file.read() >>> headers = {'Content-type': 'application/zip'} >>> resp = requests.put(myUrl, auth=('admin','geoserver'), data=payload, headers=headers) >>> resp.status_code 200
Layers and feature types are strictly linked and some users get confused about them. If you check the Layer properties in the GeoServer web interface, you'll find a lot of information. However, when you retrieved the information for the coastline layer, the response contained only a few of the properties. Most of the missing information was in the response to your request for feature type:
$ curl -u admin:geoserver -XGET -H 'Accept: text/xml' http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline.xml -o ne_110m_coastline_ft.xml
A feature type is a vector dataset configured on GeoServer, while a layer is its representation. The former contains most of the details about the data.
You may have more layers pointing to the same feature type if you want to represent them in different ways, for instance using different styles.
As most of the vector datasets are contained in the feature type, you need to send a request to it if you want to update layer properties.
You can change the keyword and layer name and description by issuing a PUT
request.
First of all, you need to prepare an XML file with the desired changes. You will again use the coastline layer, giving it a more concise name and a proper description:
<featureType> <name>Coastline</name> <nativeName>ne_110m_coastline</nativeName> <title>Coastline</title> <keywords> <string>Coastline</string> <string>Natural Earth Data</string> </keywords> <abstract>Ocean coastline, including major islands. Coastline is matched to land and water polygons. Courtesy of Natural Earth project</abstract> <enabled>true</enabled> </featureType>
Then, you will send it to GeoServer:
$ curl -u admin:geoserver -XPUT -H 'Content-type: text/xml' -d @coastline.xml http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline
Alternatively, the same using Python:
>>> myUrl = 'http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline' >>> file = open('coastline.xml','r') >>> payload = file.read() >>> headers = {'Content-type': 'application/zip'} >>> resp = requests.put(myUrl, auth=('admin','geoserver'), data=payload, headers=headers) >>> resp.status_code 200
If your data is not static, the bounding boxes should be recalculated. If you add new features that are put of the bounding box that was calculated when you first added the layer on GeoServer, you can't see them in the map until you inform GeoServer of the extent.
Again you need a PUT
request, a very simple one, as in this case you don't need to send any XML code:
$ curl -u admin:geoserver -XPUT -H 'Content-type: text/xml' -d @coastline.xml http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/datastores/Coastline/featuretypes/ne_110m_coastline&recalculate=nativebbox,latlonbbox
18.189.189.67