Module: DecisionAgent::Dsl::Operators::GeospatialOperators
- Defined in:
- lib/decision_agent/dsl/operators/geospatial_operators.rb
Overview
Handles geospatial operators: within_radius, in_polygon
Class Method Summary collapse
-
.calculate_distance(point1, point2) ⇒ Object
Calculate distance between two points using Haversine formula.
-
.get_cached_distance(point1, point2, geospatial_cache: nil, geospatial_cache_mutex: nil) ⇒ Object
Get cached distance between two points.
- .handle(op, actual_value, expected_value, geospatial_cache: nil, geospatial_cache_mutex: nil) ⇒ Object
-
.parse_coordinates(value) ⇒ Object
Parse coordinates from various formats.
-
.parse_polygon(value) ⇒ Object
Parse polygon from various formats.
-
.parse_radius_params(value) ⇒ Object
Parse radius parameters.
-
.point_in_polygon?(point, polygon) ⇒ Boolean
Check if point is inside polygon using ray casting algorithm.
Class Method Details
.calculate_distance(point1, point2) ⇒ Object
Calculate distance between two points using Haversine formula
95 96 97 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 95 def self.calculate_distance(point1, point2) Helpers::GeospatialHelpers.haversine_distance(point1, point2) end |
.get_cached_distance(point1, point2, geospatial_cache: nil, geospatial_cache_mutex: nil) ⇒ Object
Get cached distance between two points
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 76 def self.get_cached_distance(point1, point2, geospatial_cache: nil, geospatial_cache_mutex: nil) cache = geospatial_cache mutex = geospatial_cache_mutex if cache.nil? || mutex.nil? cache = ConditionEvaluator.instance_variable_get(:@geospatial_cache) mutex = ConditionEvaluator.instance_variable_get(:@geospatial_cache_mutex) end # Create cache key from sorted coordinates key = [[point1[:lat], point1[:lon]], [point2[:lat], point2[:lon]]].sort.hash cached = cache[key] return cached if cached mutex.synchronize do cache[key] ||= calculate_distance(point1, point2) end end |
.handle(op, actual_value, expected_value, geospatial_cache: nil, geospatial_cache_mutex: nil) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 8 def self.handle(op, actual_value, expected_value, geospatial_cache: nil, geospatial_cache_mutex: nil) case op when "within_radius" # Checks if point is within radius of center point point = parse_coordinates(actual_value) return false unless point params = parse_radius_params(expected_value) return false unless params # Cache geospatial distance calculations distance = get_cached_distance(point, params[:center], geospatial_cache: geospatial_cache, geospatial_cache_mutex: geospatial_cache_mutex) distance <= params[:radius] when "in_polygon" # Checks if point is inside a polygon using ray casting algorithm point = parse_coordinates(actual_value) return false unless point polygon = parse_polygon(expected_value) return false unless polygon return false if polygon.size < 3 # Need at least 3 vertices point_in_polygon?(point, polygon) end # Returns nil if not handled by this module end |
.parse_coordinates(value) ⇒ Object
Parse coordinates from various formats
38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 38 def self.parse_coordinates(value) case value when Hash lat = value[:lat] || value["lat"] lon = value[:lon] || value["lon"] return nil unless lat && lon { lat: lat.to_f, lon: lon.to_f } when Array return nil unless value.size >= 2 { lat: value[0].to_f, lon: value[1].to_f } end end |
.parse_polygon(value) ⇒ Object
Parse polygon from various formats
68 69 70 71 72 73 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 68 def self.parse_polygon(value) return nil unless value.is_a?(Array) return nil if value.empty? value.map { |v| parse_coordinates(v) }.compact end |
.parse_radius_params(value) ⇒ Object
Parse radius parameters
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 54 def self.parse_radius_params(value) return nil unless value.is_a?(Hash) center = value[:center] || value["center"] radius = value[:radius] || value["radius"] return nil unless center && radius center_coords = parse_coordinates(center) return nil unless center_coords { center: center_coords, radius: radius.to_f } end |
.point_in_polygon?(point, polygon) ⇒ Boolean
Check if point is inside polygon using ray casting algorithm
100 101 102 |
# File 'lib/decision_agent/dsl/operators/geospatial_operators.rb', line 100 def self.point_in_polygon?(point, polygon) Helpers::GeospatialHelpers.point_in_polygon?(point, polygon) end |