Tuesday 23 October 2018

Dynamic geographic extent finder

This uses a power set to return all the applicable geographic extents based on a requested value. The code is based upon the functions detailed in David Cassel's blog

declare function search:ignore-word($word as element(cts:word-query)) as xs:boolean {
 $word/cts:text/lower-case(.) = $search:stopWords and not($word/@qtextpre = '"' and $word/@qtextpost = '"')
};


declare function search:print($index, $values, $selections, $connector) {
    fn:concat(fn:string-join($values[$selections], $connector))
};

declare function search:apply-on-power-set($seq as item()*, $function as xdmp:function, $data) {
    let $len := fn:count($seq)
    for $i in (1 to xs:int(math:pow(2, $len) - 1))
    let $targets :=
        for $bit in (1 to $len)
        let $shifted :=
            if ($bit > 1) then
                xs:int($i div (math:pow(2, $bit - 1)))
            else $i
        return
            if (math:fmod($shifted, 2) eq 1) then
                $bit
            else ()
    return
        xdmp:apply($function, $i, $seq, $targets, $data)
};

declare variable $search:extents as xs:string+ := ('E', 'W', 'S', 'N.I.', 'E.U.');

declare variable $search:extentcombinations as xs:string+ := search:apply-on-power-set(($search:extents), xdmp:function(xs:QName("search:print")), '+');

declare function search:extent-combinations($extents as xs:string+) as xs:string* {
distinct-values(
    for $e in $extents
    return
        if ($e = ('england', 'E')) then $search:extentcombinations[matches(., 'E$|E\+')]
       else if ($e = ('wales', 'W')) then $search:extentcombinations[matches(., 'W')]
       else if ($e = ('scotland', 'S')) then $search:extentcombinations[matches(., 'S')]
       else if ($e = ('ni', 'N.I.')) then $search:extentcombinations[matches(., 'N\.I\.')]
       else if ($e = ('eu', 'E.U.')) then $search:extentcombinations[matches(., 'E\.U\.')]
       else ()
      )
};

No comments:

Post a Comment