class LogStash::Filters::Wmts

This filter converts data from OGC WMTS (Web Map Tile Service) URLs to geospatial information, and expands the logstash event accordingly. See www.opengeospatial.org/standards/wmts for more information about WMTS.

Given a grid, WMTS urls contain all the necessary information to find out which coordinates a requested tile belongs to. Using a simple grok filter you can extract all the relevant information. This plugin then translates these information into coordinates in LV03 and WGS84.

Here is an example of such a request:

The current filter can be configured as follows in the configuration file:

source,ruby

filter {

 # First, waiting for varnish log file formats (combined apache logs)
 grok { match => [ "message", "%{COMBINEDAPACHELOG}" ] }
 # Then, parameters
 grok {
   match => {
     "request" => "https?://%{IPORHOST}/%{DATA:[wmts][version]}/%{DATA:[wmts][layer]}/default/%{POSINT:[wmts][release]}/%{DATA:[wmts][reference-system]}/%{POSINT:[wmts][zoomlevel]}/%{POSINT:[wmts][row]}/%{POSINT:[wmts][col]}\.%{WORD:[wmts][filetype]}" 
   }
 }
 # actually passes the previously parsed message to the wmts plugin
 wmts { }
}

By default, the filter is configured to parse requests made on WMTS servers configured with the Swisstopo WMTS grid, but this can be customized through the `x_origin`,`y_origin`,`tile_width`,`tile_height` and `resolutions` parameters.

Public Instance Methods

filter(event) click to toggle source
# File lib/logstash/filters/wmts.rb, line 95
def filter(event)
  begin
    # cast values extracted upstream into integers
    zoomlevel = Integer(event[@zoomlevel_field])
    col = Integer(event[@column_field])
    row = Integer(event[@row_field])

    # checks if a mapping exists for the reference system extracted
    translated_epsg = @epsg_mapping[event[@refsys_field]] || event[@refsys_field] 
    input_epsg = "epsg:#{translated_epsg}"

    resolution = @resolutions[zoomlevel]
    raise ArgumentError if resolution.nil?
  rescue ArgumentError, TypeError, NoMethodError
    event["[#{@target}][errmsg]"] = "Bad parameter received from upstream filter"
    return
  end

  begin
    input_x = @x_origin + (((col+0.5)*@tile_width*resolution).floor)
    input_y = @y_origin - (((row+0.5)*@tile_height*resolution).floor)

    event["[#{@target}][service]"] = "wmts"

    event["[#{@target}][input_epsg]"] = input_epsg
    event["[#{@target}][input_x]"] = input_x
    event["[#{@target}][input_y]"] = input_y
    # add a combined field to the event. used for elaticsearch facets (heatmap!)
    event["[#{@target}][input_xy]"] = "#{input_x},#{input_y}"

    # convert from input_epsg to output_epsg (if necessary)
    event["[#{@target}][output_epsg]"] = @output_epsg

    unless input_epsg == @output_epsg
      input_p = GeoScript::Geom::Point.new input_x, input_y
      output_p = GeoScript::Projection.reproject input_p, input_epsg, @output_epsg
      event["[#{@target}][output_xy]"] = "#{output_p.x},#{output_p.y}"
      event["[#{@target}][output_x]"] = output_p.x
      event["[#{@target}][output_y]"] = output_p.y
    else
      # no reprojection needed
      event["[#{@target}][output_xy]"] = "#{input_x},#{input_y}"
      event["[#{@target}][output_x]"] = input_x
      event["[#{@target}][output_y]"] = input_y
    end
  rescue 
    event["[#{@target}][errmsg]"] = "Unable to reproject tile coordinates"
  end
  filter_matched(event)
end
register() click to toggle source
# File lib/logstash/filters/wmts.rb, line 90
def register
  require "geoscript"
end