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



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

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



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'app/models/document/geom_validator.rb', line 49

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

  # Guard against coplanar points
  if geom == "POLYGON((-180.0 90.0, 180.0 90.0, 180.0 -90.0, -180.0 -90.0, -180.0 90.0))"
    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)


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
118
119
120
121
122
123
124
125
# File 'app/models/document/geom_validator.rb', line 79

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



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

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