Skip to content

Condition functions

Alex-Kent edited this page Apr 3, 2019 · 2 revisions

The Search(…), SearchByBounds(…), Closest(…), and Farthest(…) methods allow a user-supplied condition function to filter potential results.

If present, these condition functions are called for each potential search result. They should be idempotent* and could potentially be called multiple times for a given point. The code should return TRUE (e.g. 1) if a potential point should be included in the results or FALSE (e.g. 0 or undef) if the point should be excluded.

For Search(…), Closest(…) and Farthest(…), the pre_condition function runs before the distance to the result point has been calculated and the post_condition function runs after it has been calculated. For SearchByBounds(…) no distances are calculated and the function is simply called once per point.

* Functions can set outside values provided they do not affect any values used internally by Search(...) et al. and so long as those outside values have no effect on the condition's outcome. Such behavior is, of course, frowned upon.

The parameters to the condition function are, in order:

  • $_result_point - Reference to the potential search result being checked

  • $_search_point - Reference to the point at the center of the search

    For SearchByBounds(...) this is instead the bounding box: [ west, south, east, north ]

  • $user_data - Arbitrary user-supplied data

For example, the options set in the following code allows all points in the results except for the one named 'Point Nada':

$options{pre_condition} = 
    sub {
          my ( $_result_point, $_search_point, $user_data ) = @_;
          if ( $$_result_point{name} eq $user_data ) {
            return 0;  # Exclude result
          }
          return 1;    # Point is a valid search result
        };
$options{user_data} = "Point Nada";

To exclude the search point from the search results use:

$options{post_condition} = 
    sub {
          my ( $_result_point, $_search_point, $user_data ) = @_;
          return ( $_result_point != $_search_point );
        };

or more concisely

$options{post_condition} = sub { return $_[0] != $_[1]; };

In general, post_condition functions should be preferred since the overhead of the Perl function call is typically larger than that of the distance calculation. By checking the distance first, running the post_condition function might not be necessary.