Class: Georeference::GeoLocate

Inherits:
Georeference
  • Object
show all
Defined in:
app/models/georeference/geo_locate.rb

Overview

A Georeference derived from a call to the Tulane GeoLocate API.

Defined Under Namespace

Classes: Request, RequestUI, Response

Constant Summary collapse

API_HOST =
'www.geo-locate.org'.freeze
API_PATH =
'/webservices/geolocatesvcv2/glcwrap.aspx?'.freeze
EMBED_PATH =
'/web/webgeoreflight.aspx?'.freeze
EMBED_HOST =
'www.geo-locate.org'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#api_responseObject

Returns the value of attribute api_response.



4
5
6
# File 'app/models/georeference/geo_locate.rb', line 4

def api_response
  @api_response
end

#error_polygon_errorObject

Errors set during attribute assignment of the above don't contribute during save validation, so save any errors to be re-set then.



7
8
9
# File 'app/models/georeference/geo_locate.rb', line 7

def error_polygon_error
  @error_polygon_error
end

#iframe_responseObject

Returns the value of attribute iframe_response.



4
5
6
# File 'app/models/georeference/geo_locate.rb', line 4

def iframe_response
  @iframe_response
end

Class Method Details

.build(request_params) ⇒ GeoLocate

Build a georeference starting with a set of request parameters.

Parameters:

  • request_params (ActionController::Parameters)

Returns:



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'app/models/georeference/geo_locate.rb', line 191

def self.build(request_params)
  g = self.new

  # @todo write a Request.valid_params? method to use here
  # @todo #1: Just what will be the validation criteria for the request?
  # @todo #2: Why not judge validity from the response?
  if request_params.nil?
    g.errors.add(:base, 'invalid or no request parameters provided.')
    return g
  end

  request = Request.new(request_params)
  request.locate

  if request.succeeded?
    g.api_response = request.response
    g.api_request  = request.request_param_string
  else
    g.errors.add(:api_request, 'requested parameters did not succeed in returning a result')
  end
  g
end

.parse_iframe_result(response_string) ⇒ Array

Returns parsing the four possible bits of a response into an array.

Parameters:

  • response_string (String)

    from Tulane

Returns:

  • (Array)

    parsing the four possible bits of a response into an array



167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/models/georeference/geo_locate.rb', line 167

def self.parse_iframe_result(response_string)
  s = unify_response_string(response_string)
  lat, long, error_radius, uncertainty_polygon = s.split('|')
  uncertainty_points = nil
  unless uncertainty_polygon.nil?
    if uncertainty_polygon =~ /unavailable/i # todo: there are many more possible error conditions
      uncertainty_points = nil
    else
      uncertainty_points = uncertainty_polygon.split(',').reverse.in_groups_of(2)
    end
  end
  [lat, long, error_radius, uncertainty_points]
end

.unify_response_string(response_string) ⇒ Object

TODO: move ti iframe getter/setter



182
183
184
185
186
# File 'app/models/georeference/geo_locate.rb', line 182

def self.unify_response_string(response_string)
  response_string.gsub!(/[\t]/, '|')
  response_string.gsub!(/\s+/, '|')
  response_string
end

Instance Method Details

#dwc_georeference_attributesObject



21
22
23
24
25
26
27
28
29
# File 'app/models/georeference/geo_locate.rb', line 21

def dwc_georeference_attributes
  h = {}
  super(h)
  h.merge!(
    georeferenceSources: 'GEOLocate ',
    georeferenceRemarks: 'Typically created by copy-pasting one or more values from a collecting event into a GEOLocate form.')
  h[:georeferenceProtocol] = 'Generated via a query through the GEOLocate web interface' if h[:georeferenceProtocol].blank?
  h
end

#error_polygon_is_validObject



15
16
17
18
19
# File 'app/models/georeference/geo_locate.rb', line 15

def error_polygon_is_valid
  # Errors set during attribute assignment don't count toward validations, so
  # re-set any errors encountered then.
  errors.add(:base, error_polygon_error) if error_polygon_error
end

#make_err_polygon(wkb) ⇒ GeographicItem::Polygon

Returns GeographicItem::Polygon, either found, or created.

Parameters:

  • wkb (String)

Returns:

  • (GeographicItem::Polygon)

    GeographicItem::Polygon, either found, or created



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/models/georeference/geo_locate.rb', line 78

def make_err_polygon(wkb)
  polygon = Gis::FACTORY.parse_wkb(wkb)
  # ActiveRecord::Base.send(:sanitize_sql_array, ['polygon = ST_GeographyFromText(?)', polygon.to_s])
  test_grs = GeographicItem
    # && is a fast indexed-bounding-box comparison
    .where('geography && ST_GeographyFromText(:wkt) AND ' \
           'geography = ST_GeographyFromText(:wkt)',
      wkt: polygon.to_s
    )
  if test_grs.empty?
    test_grs = [GeographicItem.new(geography: polygon)]
  end
  if test_grs.first.new_record?
    test_grs.first.save
  else
    test_grs.first
  end
  test_grs.first
end

#make_error_geographic_item(uncertainty_polygon, uncertainty_radius) ⇒ Object

TODO:

get geoJson results and handle all this automatically?

Parameters:

  • uncertainty_polygon (RGeo::Polygon)
  • uncertainty_radius (Integer)

    in meters



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'app/models/georeference/geo_locate.rb', line 148

def make_error_geographic_item(uncertainty_polygon, uncertainty_radius)
  self.error_radius = uncertainty_radius if !uncertainty_radius.nil?
  return if uncertainty_polygon.nil?

  err_array = []

  uncertainty_polygon.each { |point| err_array.push(Gis::FACTORY.point(point[0], point[1])) }

  begin
    self.error_geographic_item = GeographicItem.new(geography: Gis::FACTORY.polygon(Gis::FACTORY.line_string(err_array)))
  rescue RGeo::Error::InvalidGeometry => e
    self.error_polygon_error = "Error polygon error: '#{e}'"
    return
  end
end

#make_geographic_point(x, y, z = '0.0') ⇒ Object

Returns Point GeographicItem, either found or created.

Parameters:

  • x (String)

    longitude

  • y (String)

    latitude

  • z (String) (defaults to: '0.0')

    elevation, defaults to 0.0

Returns:

  • (Object)

    Point GeographicItem, either found or created.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/models/georeference/geo_locate.rb', line 102

def make_geographic_point(x, y, z = '0.0')
  if x.blank? || y.blank?
    test_grs = []
  else
    test_grs = GeographicItem
      # && is a fast indexed-bounding-box comparison
      .where('geography && ST_GeographyFromText(:wkt) AND ' \
             'geography = ST_GeographyFromText(:wkt)',
        wkt: "POINT(#{x.to_f} #{y.to_f} #{z.to_f})"
      )
      # .where(['ST_Z(point::geometry) = ?', z.to_f])
  end
  if test_grs.empty? # put a new one in the array
    test_grs = [GeographicItem.new(geography: Gis::FACTORY.point(x, y, z))]
  end
  test_grs.first
end

#request_hashHash

Returns of api request pieces.

Returns:

  • (Hash)

    of api request pieces



72
73
74
# File 'app/models/georeference/geo_locate.rb', line 72

def request_hash
  Hash[*self.api_request.split('&').collect { |a| a.split('=', 2) }.flatten]
end