-
Notifications
You must be signed in to change notification settings - Fork 2
/
coordinate.rb
62 lines (49 loc) · 1.66 KB
/
coordinate.rb
1
2
3
4
5
6
7
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# encoding: utf-8
module Stanford
module Mods
##
# Geospatial coordinate parsing
class Coordinate
require 'stanford-mods/geo_utils'
include ::Stanford::Mods::GeoUtils
attr_reader :value
def initialize(value)
@value = value
end
# @return [String] the coordinate in WKT/CQL ENVELOPE representation
def as_envelope
return unless valid?
"ENVELOPE(#{bounds[:min_x]}, #{bounds[:max_x]}, #{bounds[:max_y]}, #{bounds[:min_y]})"
end
# @return [String] the coordinate in Solr 4.x+ bbox-format representation
def as_bbox
return unless valid?
"#{bounds[:min_x]} #{bounds[:min_y]} #{bounds[:max_x]} #{bounds[:max_y]}"
end
# @return [Boolean] true iff the coordinates are geographically valid
def valid?
return false if bounds.empty?
range_x = -180.0..180.0
range_y = -90.0..90.0
range_x.include?(bounds[:min_x]) &&
range_x.include?(bounds[:max_x]) &&
range_y.include?(bounds[:min_y]) &&
range_y.include?(bounds[:max_y])
end
private
def bounds
@bounds ||= begin
matches = cleaner_coordinate(value).match %r{\A(?<lat>[EW].+-+.+)\s*/\s*(?<lng>[NS].+-+.+)\Z}
return {} unless matches
min_x, max_x = matches['lat'].split(/-+/).map { |x| coord_to_decimal(x) }.minmax
min_y, max_y = matches['lng'].split(/-+/).map { |y| coord_to_decimal(y) }.minmax
{ min_x: min_x, min_y: min_y, max_x: max_x, max_y: max_y }
end
end
# @deprecated see GeoUtils
def coord
cleaner_coordinate(value)
end
end
end
end