goat-community / goat

This is the home of Geo Open Accessibility Tool (GOAT)
GNU General Public License v3.0
92 stars 47 forks source link

Write CRUD endpoints to manage styles from style library #1340

Closed EPajares closed 2 years ago

EPajares commented 2 years ago

We manage the styles for the layers in the table _customer.stylelibrary It should be possible to read, add, modify or delete a style.

For the styles, we are using the Geostyler format: https://geostyler.org/

Validation: We could test whether it will be possible to validate the styles using this library. There might be a python wrapper or similar for the library. Another thing we could validate is the translation. For each rule of the style, there should be a translation for the value "name". We have to make sure that if we have a translation all "names" are translated.

URL We can discuss the right URL for this endpoint.

metemaddar commented 2 years ago

To find all names in the style we can use the following cool function: reference: https://stackoverflow.com/a/19871956/1951027

d = { "id" : "abcde",
    "key1" : "blah",
    "key2" : "blah blah",
    "nestedlist" : [
    { "id" : "qwerty",
        "nestednestedlist" : [
        { "id" : "xyz", "keyA" : "blah blah blah" },
        { "id" : "fghi", "keyZ" : "blah blah blah" }],
        "anothernestednestedlist" : [
        { "id" : "asdf", "keyQ" : "blah blah" },
        { "id" : "yuiop", "keyW" : "blah" }] } ] }

def findkeys(node, kv):
    if isinstance(node, list):
        for i in node:
            for x in findkeys(i, kv):
               yield x
    elif isinstance(node, dict):
        if kv in node:
            yield node[kv]
        for j in node.values():
            for x in findkeys(j, kv):
                yield x

print(list(findkeys(d, 'id')))

Output: ['abcde', 'qwerty', 'xyz', 'fghi', 'asdf', 'yuiop']

metemaddar commented 2 years ago

Things I have found about our map styling:

  1. We are using Geostyler by the geostyler-openlayers-parser library which implements Geostyler for our OpenLayers library.
  2. GeoStyler uses different standards and can convert them together.
  3. GeoStyler basicly doesn't have validators. It has only converters. (Didn't find any validators)
  4. The python bridge-style which is a wrapper or translated from Geostyler and is used by QGIS bridge pluggin, Also has no validator by itself. But we can convert the data to another standard for example sld to get the warnings or even an exception.

For example for the following Json:

{
    "name": "Sub Study Area",
    "rules": [{
        "name": "Sub Study Area",
        "symbolizers": [{
            "kind": "Fill",
            "color": "#7F7FBF",
            "opacity": 0.4,
            "fillOpacity": 0.3,
            "outlineColor": "#7F7FBF",
            "outlineWidth": 2
        }]
    }]
}

We will have an exception while converting it from geostyler into sld:

...
    outlineOpacity = float(_symbolProperty(sl, "outlineOpacity"))
TypeError: float() argument must be a string or a number, not 'NoneType'

Which expects to have outlineOpacity property.

By handling such exceptions we can inform the client about the error. However in this error, we got a type error, which has no enough information to inform maybe. Of course here the exception is not a validator maybe. Because the float() got a None as argument. Which maybe a bug at bridgestyler. Maybe we can PR to fix or fork to have fixed also.

EPajares commented 2 years ago

Thanks for this summary. I understand. So, there is no easy solution. We might have to change the strategy for validation. We could test the style in the client (once we have a dashboard). And basically, the user of the dashboard will see a map with a styled layer like how geostyler has it here: https://geostyler.github.io/geostyler-demo/