geostyler / geostyler

Generic Styler for geodata
http://geostyler.org
BSD 2-Clause "Simplified" License
256 stars 59 forks source link

Serialize filter expressions #996

Closed KaiVolland closed 5 years ago

KaiVolland commented 5 years ago

FEATUREREQUEST

We need to find a way to serialize Filter expressions, e.g. transformation function and mathematical function for the RasterCalculator #935.

As we're close to the mapbox syntax we should make use of theses expressions: https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-math

glenselle commented 5 years ago

We are in need of creating a filter like so:

  <Or>
    <PropertyIsLike>
      <Function name="strMatches">
        <PropertyName>year</PropertyName>
        <Literal>^( )??2019,.*</Literal>
      </Function>
      <Literal>true</Literal>
    </PropertyIsLike>
    <PropertyIsLike>
      <Function name="strMatches">
        <PropertyName>year</PropertyName>
        <Literal>.*,( )??2019( )??,.*</Literal>
      </Function>
      <Literal>true</Literal>
    </PropertyIsLike>
  </Or>

I attempted to do the following, hoping it would just insert index 1 as the contents of the tag at index 0. I believe this issue is designed to support filter expressions, which would include Function tags. But in the interim, would it be easy to add support for just a string version of the filter? Or is this already possible and I'm just doing it wrong? I would be willing to submit a PR to add support for this if you think it wouldn't be that hard to add support for this.

filter: ['||',
    ['*=', '<Function name="strMatches"><PropertyName>year</PropertyName><Literal>^( )??2019,.*</Literal></Function><Literal>true</Literal>'],
    ['*=', '<Function name="strMatches"><PropertyName>year</PropertyName><Literal>.*,( )??2019( )??,.*</Literal></Function><Literal>true</Literal>']
],
glenselle commented 5 years ago

I've created a PR which demonstrates what I think could work as a stopgap before filters are natively supported: https://github.com/terrestris/geostyler-sld-parser/pull/195

KaiVolland commented 5 years ago

Hey @glenselle, appreciate that you'd like to support the project.

Instead of using xml-strings in the geostyler-filter a function expression could look like this:

['strMatches', PROPERTY_NAME, REGULAR_EXPRESSION]

…for your example:

['||',
  ['*=',
    ['strMatches', 'year', '^( )??2019,.*'],
    'true'
  ],
  ['*=',
    ['strMatches', 'year', '.*,( )??2019( )??,.*'],
    'true'
  ]
]

The syntax in the example above is just an example and doesn't represent the correct syntax of function expressions. Have a look at https://github.com/terrestris/geostyler-style for more details.

Would you be willing to provide a PR for this here? This might last longer than the stopgap.

To do so, you'd have to add a definition for the function expressions to the geostyler-style.

/**
 * The possible operators used for functional operations.
 */
export type FunctionOperator = 'strMatch';

… and a defintion for the strMatches function itself (see above).

Then you just have to adjust the parsers you need (e.g SLD to read and write the function properly. Almost as you did in: https://github.com/terrestris/geostyler-sld-parser/pull/195

KaiVolland commented 5 years ago

I'll try to do the need steps for the geostyler-style now.

KaiVolland commented 5 years ago

Two things are missing:

hwbllmnn commented 5 years ago

CQL parser part is implemented in terrestris/geostyler-cql-parser/pull/56

glenselle commented 5 years ago

Thanks for making this happen! Works great!

drodenberg commented 5 years ago

Hi, I'm currently trying to pass this filter

['||',
      ['*=',
        ['strMatches', 'year', '^( )??2019,.*'],
        'true'
      ],
      ['*=',
        ['strMatches', 'year', '.*,( )??2019( )??,.*'],
        'true'
      ]
    ]

along to my sld but it translates that array with 'strMatches' to the property name. How am I supposed to get that to add a function xml tag?

this is the output i get

            <Or>
              <PropertyIsLike wildCard="*" singleChar="." escape="!">
                <PropertyName>
                  <0>s</0>
                  <1>t</1>
                  <2>r</2>
                  <3>M</3>
                  <4>a</4>
                  <5>t</5>
                  <6>c</6>
                  <7>h</7>
                  <8>e</8>
                  <9>s</9>
                  <0>y</0>
                  <1>e</1>
                  <2>a</2>
                  <3>r</3>
                  <0>^</0>
                  <1>(</1>
                  <2> </2>
                  <3>)</3>
                  <4>?</4>
                  <5>?</5>
                  <6>2</6>
                  <7>0</7>
                  <8>1</8>
                  <9>9</9>
                  <10>,</10>
                  <11>.</11>
                  <12>*</12>
                </PropertyName>
                <Literal>true</Literal>
              </PropertyIsLike>
              <PropertyIsLike wildCard="*" singleChar="." escape="!">
                <PropertyName>
                  <0>s</0>
                  <1>t</1>
                  <2>r</2>
                  <3>M</3>
                  <4>a</4>
                  <5>t</5>
                  <6>c</6>
                  <7>h</7>
                  <8>e</8>
                  <9>s</9>
                  <0>y</0>
                  <1>e</1>
                  <2>a</2>
                  <3>r</3>
                  <0>.</0>
                  <1>*</1>
                  <2>,</2>
                  <3>(</3>
                  <4> </4>
                  <5>)</5>
                  <6>?</6>
                  <7>?</7>
                  <8>2</8>
                  <9>0</9>
                  <10>1</10>
                  <11>9</11>
                  <12>(</12>
                  <13> </13>
                  <14>)</14>
                  <15>?</15>
                  <16>?</16>
                  <17>,</17>
                  <18>.</18>
                  <19>*</19>
                </PropertyName>
                <Literal>true</Literal>
              </PropertyIsLike>
            </Or>
jansule commented 5 years ago

Hi @drodenberg, thanks for noticing us. Which version of geostyler and geostyler-sld-parser are you using?

jansule commented 5 years ago

The error might be due to the Filter not being exactly as described in geostyler-style.

Could you try following filter expresssion and check if it works?

['||',
      ['*=',
        ['FN_strMatches', 'year', '^( )??2019,.*'],
        true
      ],
      ['*=',
        ['FN_strMatches', 'year', '.*,( )??2019( )??,.*'],
        true
      ]
    ]

Changed strMatches to FN_strMatches and 'true' to true.

drodenberg commented 5 years ago

Thanks a ton! That worked!