Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expression discussion #26

Open
ebocher opened this issue Aug 26, 2020 · 4 comments
Open

Expression discussion #26

ebocher opened this issue Aug 26, 2020 · 4 comments

Comments

@ebocher
Copy link
Member

ebocher commented Aug 26, 2020

All ParameterValue that permit to custom symbol elements in Feature2DTypeStyle support expression.
See examples

<Color>rgb(expression(22),expression(15),expression(120))</Color>
<PerpendicularOffset>expression(CASE WHEN ST_AREA(the_geom)&lt; 1000 then 10 else 0 end)</PerpendicularOffset>
<Width>expression(CASE WHEN TYPE='cereals' THEN 0.25 ELSE 0.4 END)</Width>

We use the term expression to set when the ParameterValue is an Expression.

Currently there is no specification at OGC to define in a human way (as SQL does) an expression.

The most important work has been done by the geotools community with the ECQL (Extended Common Query Language).
See https://github.com/geotools/geotools/tree/master/modules/library/cql

With next OGC API - Features - Part 3: Common Query Language (http://docs.opengeospatial.org/DRAFTS/19-079.html#simple-cql_filter-expression) proposes to formalize the definition of an expression and shows possible encoding with json (https://github.com/tschaub/ogcapi-features/tree/json-array-expression/extensions/cql/jfe).

At the OrbisMap side an expression is currently a fragment of a SQL query. So in a style, when you have

<Width>expression(CASE WHEN TYPE='cereals' THEN 0.25 ELSE 0.4 END)</Width>

the data background system runs

select CASE WHEN TYPE='cereals' THEN 0.25 ELSE 0.4 END from myInputData; 

or

<Rule>
 <Filter>id>2</Filter>
<Rule>

the data background system runs

select * from myInputData where id>2; 

Using SQL as the expression provider has several advantages :

  • the language is very documented,
  • easy to understand (for the basic queries we use)
  • it integrates spatial functions.
  • you can delegate the execution of the expression to the datasource

and cons

  • the expression capabilities are linked to the implementation of the parser on the datasource side.
    This means that it is possible not to have the same functions from one datasource to another (e.g POSTGIS vs H2GIS vs SpatialLite).
  • Some functions such as interpolate values or temporal filter may not be available.
  • The rendering engine will have a behavior related to the datasource provider. This issue can be resolved with a local parser that executes a SQL query locally when the datasource does not have the expected functionality. JSqlParser is a good candidate for that (https://github.com/JSQLParser/JSqlParser).
@ebocher
Copy link
Member Author

ebocher commented Aug 26, 2020

To avoid possible misunderstandings about the capabilities of the expression engine, it may be a good idea to specify the type of expression.
like this

<Width>sql(st_area( the_geom )/10000)</Width>
<Width>ecql(area( the_geom )/10000)</Width>

@ebocher
Copy link
Member Author

ebocher commented Aug 27, 2020

In SE spec
11.6 Symbology Encoding Functions
"The value of the fallbackValue attribute is used as a default value, if the SE implementation does not support the function. If the implementation supports the function, then the result value is determined by executing the function. "

so we can imagine
expression(st_area( the_geom )/10000, 12)
12 is the default value

@ebocher
Copy link
Member Author

ebocher commented May 21, 2021

Following the concept of Tranform element exposed in the VEGA-LITE specification (https://vega.github.io/vega-lite/docs/transform.html) we can offer a simple way to define if the style model must used a SQL or a CQL-TEXT (http://docs.opengeospatial.org/DRAFTS/19-079.html) mechanism.

Expose SQL

{
    "Feature2DStyle": {
        "Name": "Unnamed Style",
        "Rule": {
            "Name": "Default Rule",
            "Transform": {
                "SQL": {
                    "Filter": "where id >12"
                }
            },
            "PointSymbolizer": {
                "Name": "Point symbolizer",
                "Uom": "PX",
                "Geometry": "the_geom",
                "Level": 0,
                "MarkGraphic": {
                    "WellKnownName": "circle",
                    "Size": 10,
                    "PenStroke": {
                        "SolidFill": {
                            "Color": "#000000",
                            "Opacity": 1
                        },
                        "Width": 0.25,
                        "LineCap": "BUTT",
                        "LineJoin": "MITRE"
                    },
                    "SolidFill": {
                        "Color": "#000000",
                        "Opacity": 1
                    }
                }
            }
        }
    }
}

Expose CQL-TEXT

{
    "Feature2DStyle": {
        "Name": "Unnamed Style",
        "Rule": {
            "Name": "Default Rule",
            "Transform": {
                "CQL-text": {
                    "Filter": "id >12"
                }
            },
            "PointSymbolizer": {
                "Name": "Point symbolizer",
                "Uom": "PX",
                "Geometry": "the_geom",
                "Level": 0,
                "MarkGraphic": {
                    "WellKnownName": "circle",
                    "Size": 10,
                    "PenStroke": {
                        "SolidFill": {
                            "Color": "#000000",
                            "Opacity": 1
                        },
                        "Width": 0.25,
                        "LineCap": "BUTT",
                        "LineJoin": "MITRE"
                    },
                    "SolidFill": {
                        "Color": "#000000",
                        "Opacity": 1
                    }
                }
            }
        }
    }
}

@ebocher
Copy link
Member Author

ebocher commented May 21, 2021

Because CQL-TEXT is only dedicated to filter we can removed the Filter field and write

"Transform": {
                "CQL-text":  "id >12"                
            },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant