Class: Document::GeomValidator

Inherits:
ActiveModel::Validator
  • Object
show all
Defined in:
app/models/document/geom_validator.rb

Overview

GeomValidator

Instance Method Summary collapse

Instance Method Details

#proper_envelope(record) ⇒ Object

Validates ENVELOPE



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/models/document/geom_validator.rb', line 30

def proper_envelope(record)
  geom = record.send(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry])
  begin
    valid_geom, error_message = valid_envelope?(geom.delete("ENVELOPE()"))
  rescue => e
    valid_geom = false
    record.errors.add(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry], "Invalid envelope: #{e}")
  end

  unless valid_geom
    record.errors.add(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry],
      "Invalid envelope: #{error_message}")
  end

  valid_geom
end

#proper_geom(record) ⇒ Object

Validates POLYGON and MULTIPOLYGON



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'app/models/document/geom_validator.rb', line 48

def proper_geom(record)
  geom = record.send(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry])
  begin
    valid_geom = if RGeo::Cartesian::Factory.new.parse_wkt(geom)
      true
    else
      false
    end
  rescue => e
    valid_geom = false
    record.errors.add(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry], "Invalid geometry: #{e}")
  end

  # Guard against a whole world polygons
  if geom == "POLYGON((-180 90, 180 90, 180 -90, -180 -90, -180 90))"
    valid_geom = false
    record.errors.add(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry],
      "Invalid polygon: all points are coplanar input, Solr will not index")
  end

  valid_geom
end

#valid_envelope?(envelope) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'app/models/document/geom_validator.rb', line 71

def valid_envelope?(envelope)
  # Default to true
  valid_envelope = true
  error_message = ""

  # Min/Max - W,E,N,S
  # ENVELOPE(-180,180,90,-90)
  min_max = [-180.0, 180.0, 90.0, -90.0]
  envelope = envelope.split(",")

  # Reject ENVELOPE(-118.00.0000,-88.00.0000,51.00.0000,42.00.0000)
  # - Double period float-ish things?
  envelope.each do |val|
    if val.count(".") >= 2
      valid_envelope = false
      error_message = "invalid ENVELOPE(W,E,N,S) syntax - found multiple periods in coordinate value(s)."
    end
  end

  # @TODO: Essentially duplicated logic from bbox_validator.rb, DRY it up
  if envelope.size != 4
    valid_envelope = false
    error_message = "invalid ENVELOPE(W,E,N,S) syntax"
  # W
  elsif envelope[0].to_f < min_max[0]
    valid_envelope = false
    error_message = "invalid minX present"
  # E
  elsif envelope[1].to_f > min_max[1]
    valid_envelope = false
    error_message = "invalid maX present"
  # N
  elsif envelope[2].to_f > min_max[2]
    valid_envelope = false
    error_message = "invalid maxY present"
  # S
  elsif envelope[3].to_f < min_max[3]
    valid_envelope = false
    error_message = "invalid minY present"
  # Solr - maxY must be >= minY
  elsif envelope[3].to_f >= envelope[2].to_f
    valid_envelope = false
    error_message = "maxY must be >= minY"
  end

  [valid_envelope, error_message]
end

#validate(record) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'app/models/document/geom_validator.rb', line 12

def validate(record)
  # Assume true for empty values
  valid_geom = true

  if record.send(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry]).present?
    valid_geom = if record.send(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry]).start_with?("ENVELOPE")
      # Sane ENVELOPE?
      proper_envelope(record)
    else
      # Sane GEOM?
      proper_geom(record)
    end
  end

  valid_geom
end