Class: RGeo::Geographic::Factory

Inherits:
Object
  • Object
show all
Includes:
Feature::Factory::Instance, ImplHelper::Utils
Defined in:
lib/rgeo/geographic/factory.rb

Overview

This class implements the various factories for geography features. See methods of the RGeo::Geographic module for the API for creating geography factories.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(impl_prefix, opts = {}) ⇒ Factory

:nodoc:


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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rgeo/geographic/factory.rb', line 21

def initialize(impl_prefix, opts = {}) # :nodoc:
  @impl_prefix = impl_prefix
  @point_class = Geographic.const_get("#{impl_prefix}PointImpl")
  @line_string_class = Geographic.const_get("#{impl_prefix}LineStringImpl")
  @linear_ring_class = Geographic.const_get("#{impl_prefix}LinearRingImpl")
  @line_class = Geographic.const_get("#{impl_prefix}LineImpl")
  @polygon_class = Geographic.const_get("#{impl_prefix}PolygonImpl")
  @geometry_collection_class = Geographic.const_get("#{impl_prefix}GeometryCollectionImpl")
  @multi_point_class = Geographic.const_get("#{impl_prefix}MultiPointImpl")
  @multi_line_string_class = Geographic.const_get("#{impl_prefix}MultiLineStringImpl")
  @multi_polygon_class = Geographic.const_get("#{impl_prefix}MultiPolygonImpl")
  @support_z = opts[:has_z_coordinate] ? true : false
  @support_m = opts[:has_m_coordinate] ? true : false
  @srid = (opts[:srid] || 4326).to_i
  @proj4 = opts[:proj4]
  if @proj4 && CoordSys.check!(:proj4)
    if @proj4.is_a?(String) || @proj4.is_a?(Hash)
      @proj4 = CoordSys::Proj4.create(@proj4)
    end
  end
  @coord_sys = opts[:coord_sys]
  if @coord_sys.is_a?(String)
    @coord_sys = CoordSys::CS.create_from_wkt(@coord_sys)
  end
  @lenient_assertions = opts[:uses_lenient_assertions] ? true : false
  @buffer_resolution = opts[:buffer_resolution].to_i
  @buffer_resolution = 1 if @buffer_resolution < 1

  wkt_generator = opts[:wkt_generator]
  case wkt_generator
  when Hash
    @wkt_generator = WKRep::WKTGenerator.new(wkt_generator)
  else
    @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper)
  end
  wkb_generator = opts[:wkb_generator]
  case wkb_generator
  when Hash
    @wkb_generator = WKRep::WKBGenerator.new(wkb_generator)
  else
    @wkb_generator = WKRep::WKBGenerator.new
  end
  wkt_parser = opts[:wkt_parser]
  case wkt_parser
  when Hash
    @wkt_parser = WKRep::WKTParser.new(self, wkt_parser)
  else
    @wkt_parser = WKRep::WKTParser.new(self)
  end
  wkb_parser = opts[:wkb_parser]
  case wkb_parser
  when Hash
    @wkb_parser = WKRep::WKBParser.new(self, wkb_parser)
  else
    @wkb_parser = WKRep::WKBParser.new(self)
  end
  @projector = nil
end

Instance Attribute Details

#coord_sysObject (readonly)

See RGeo::Feature::Factory#coord_sys


377
378
379
# File 'lib/rgeo/geographic/factory.rb', line 377

def coord_sys
  @coord_sys
end

#proj4Object (readonly)

See RGeo::Feature::Factory#proj4


373
374
375
# File 'lib/rgeo/geographic/factory.rb', line 373

def proj4
  @proj4
end

#projector=(value) ⇒ Object (writeonly)

Sets the attribute projector

Parameters:

  • value

    the value to set the attribute projector to.


19
20
21
# File 'lib/rgeo/geographic/factory.rb', line 19

def projector=(value)
  @projector = value
end

#sridObject (readonly)

Returns the srid reported by this factory.


221
222
223
# File 'lib/rgeo/geographic/factory.rb', line 221

def srid
  @srid
end

Instance Method Details

#collection(elems) ⇒ Object

See RGeo::Feature::Factory#collection


349
350
351
# File 'lib/rgeo/geographic/factory.rb', line 349

def collection(elems)
  @geometry_collection_class.new(self, elems)
end

#encode_with(coder) ⇒ Object

Psych support


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/rgeo/geographic/factory.rb', line 158

def encode_with(coder) # :nodoc:
  coder["impl_prefix"] = @impl_prefix
  coder["has_z_coordinate"] = @support_z
  coder["has_m_coordinate"] = @support_m
  coder["srid"] = @srid
  coder["wkt_generator"] = @wkt_generator.properties
  coder["wkb_generator"] = @wkb_generator.properties
  coder["wkt_parser"] = @wkt_parser.properties
  coder["wkb_parser"] = @wkb_parser.properties
  coder["lenient_assertions"] = @lenient_assertions
  coder["buffer_resolution"] = @buffer_resolution
  if @proj4
    str = @proj4.original_str || @proj4.canonical_str
    coder["proj4"] = @proj4.radians? ? { "proj4" => str, "radians" => true } : str
  end
  coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys
  if @projector
    coder["projectorclass"] = @projector.class.name.sub(/.*::/, "")
    coder["projection_factory"] = @projector.projection_factory
  end
end

#eql?(rhs_) ⇒ Boolean Also known as: ==

Equivalence test.

Returns:

  • (Boolean)

82
83
84
85
86
87
88
# File 'lib/rgeo/geographic/factory.rb', line 82

def eql?(rhs_)
  rhs_.is_a?(Geographic::Factory) &&
    @impl_prefix == rhs_.instance_variable_get(:@impl_prefix) &&
    @support_z == rhs_.instance_variable_get(:@support_z) &&
    @support_m == rhs_.instance_variable_get(:@support_m) &&
    @proj4 == rhs_.instance_variable_get(:@proj4)
end

#generate_wkb(obj) ⇒ Object

:nodoc:


383
384
385
# File 'lib/rgeo/geographic/factory.rb', line 383

def generate_wkb(obj) # :nodoc:
  @wkb_generator.generate(obj)
end

#generate_wkt(obj) ⇒ Object


379
380
381
# File 'lib/rgeo/geographic/factory.rb', line 379

def generate_wkt(obj)
  @wkt_generator.generate(obj)
end

#has_projection?Boolean

Returns true if this factory supports a projection.

Returns:

  • (Boolean)

225
226
227
# File 'lib/rgeo/geographic/factory.rb', line 225

def has_projection?
  !@projector.nil?
end

#hashObject

Standard hash code


93
94
95
# File 'lib/rgeo/geographic/factory.rb', line 93

def hash
  @hash ||= [@impl_prefix, @support_z, @support_m, @proj4].hash
end

#init_with(coder) ⇒ Object

:nodoc:


180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/rgeo/geographic/factory.rb', line 180

def init_with(coder) # :nodoc:
  if (proj4_data = coder["proj4"])
    CoordSys.check!(:proj4)
    if proj4_data.is_a?(Hash)
      proj4 = CoordSys::Proj4.create(proj4_data["proj4"], radians: proj4_data["radians"])
    else
      proj4 = CoordSys::Proj4.create(proj4_data.to_s)
    end
  else
    proj4 = nil
  end
  if (coord_sys_data = coder["cs"])
    coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data.to_s)
  else
    coord_sys = nil
  end
  initialize(coder["impl_prefix"],
    has_z_coordinate: coder["has_z_coordinate"],
    has_m_coordinate: coder["has_m_coordinate"],
    srid: coder["srid"],
    wkt_generator: symbolize_hash(coder["wkt_generator"]),
    wkb_generator: symbolize_hash(coder["wkb_generator"]),
    wkt_parser: symbolize_hash(coder["wkt_parser"]),
    wkb_parser: symbolize_hash(coder["wkb_parser"]),
    uses_lenient_assertions: coder["lenient_assertions"],
    buffer_resolution: coder["buffer_resolution"],
    proj4: proj4,
    coord_sys: coord_sys
  )
  if (proj_klass = coder["projectorclass"]) && (proj_factory = coder["projection_factory"])
    klass_ = RGeo::Geographic.const_get(proj_klass)
    if klass_
      projector = klass_.allocate
      projector.set_factories(self, proj_factory)
      @projector = projector
    end
  end
end

#line(start, stop) ⇒ Object

See RGeo::Feature::Factory#line


331
332
333
# File 'lib/rgeo/geographic/factory.rb', line 331

def line(start, stop)
  @line_class.new(self, start, stop)
end

#line_string(points) ⇒ Object

See RGeo::Feature::Factory#line_string


325
326
327
# File 'lib/rgeo/geographic/factory.rb', line 325

def line_string(points)
  @line_string_class.new(self, points)
end

#linear_ring(points) ⇒ Object

See RGeo::Feature::Factory#linear_ring


337
338
339
# File 'lib/rgeo/geographic/factory.rb', line 337

def linear_ring(points)
  @linear_ring_class.new(self, points)
end

#marshal_dumpObject

Marshal support


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/rgeo/geographic/factory.rb', line 99

def marshal_dump # :nodoc:
  hash_ = {
    "pref" => @impl_prefix,
    "hasz" => @support_z,
    "hasm" => @support_m,
    "srid" => @srid,
    "wktg" => @wkt_generator.properties,
    "wkbg" => @wkb_generator.properties,
    "wktp" => @wkt_parser.properties,
    "wkbp" => @wkb_parser.properties,
    "lena" => @lenient_assertions,
    "bufr" => @buffer_resolution
  }
  hash_["proj4"] = @proj4.marshal_dump if @proj4
  hash_["cs"] = @coord_sys.to_wkt if @coord_sys
  if @projector
    hash_["prjc"] = @projector.class.name.sub(/.*::/, "")
    hash_["prjf"] = @projector.projection_factory
  end
  hash_
end

#marshal_load(data_) ⇒ Object

:nodoc:


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/rgeo/geographic/factory.rb', line 121

def marshal_load(data_) # :nodoc:
  if (proj4_data = data_["proj4"]) && CoordSys.check!(:proj4)
    proj4 = CoordSys::Proj4.allocate
    proj4.marshal_load(proj4_data)
  else
    proj4 = nil
  end
  if (coord_sys_data = data_["cs"])
    coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data)
  else
    coord_sys = nil
  end
  initialize(data_["pref"],
    has_z_coordinate: data_["hasz"],
    has_m_coordinate: data_["hasm"],
    srid: data_["srid"],
    wkt_generator: symbolize_hash(data_["wktg"]),
    wkb_generator: symbolize_hash(data_["wkbg"]),
    wkt_parser: symbolize_hash(data_["wktp"]),
    wkb_parser: symbolize_hash(data_["wkbp"]),
    uses_lenient_assertions: data_["lena"],
    buffer_resolution: data_["bufr"],
    proj4: proj4,
    coord_sys: coord_sys
  )
  if (proj_klass = data_["prjc"]) && (proj_factory = data_["prjf"])
    klass_ = RGeo::Geographic.const_get(proj_klass)
    if klass_
      projector = klass_.allocate
      projector.set_factories(self, proj_factory)
      @projector = projector
    end
  end
end

#marshal_wkb_generatorObject


387
388
389
# File 'lib/rgeo/geographic/factory.rb', line 387

def marshal_wkb_generator
  @marshal_wkb_generator ||= RGeo::WKRep::WKBGenerator.new(type_format: :wkb12)
end

#marshal_wkb_parserObject


391
392
393
# File 'lib/rgeo/geographic/factory.rb', line 391

def marshal_wkb_parser
  @marshal_wkb_parser ||= RGeo::WKRep::WKBParser.new(self, support_wkb12: true)
end

#multi_line_string(elems) ⇒ Object

See RGeo::Feature::Factory#multi_line_string


361
362
363
# File 'lib/rgeo/geographic/factory.rb', line 361

def multi_line_string(elems)
  @multi_line_string_class.new(self, elems)
end

#multi_point(elems) ⇒ Object

See RGeo::Feature::Factory#multi_point


355
356
357
# File 'lib/rgeo/geographic/factory.rb', line 355

def multi_point(elems)
  @multi_point_class.new(self, elems)
end

#multi_polygon(elems) ⇒ Object

See RGeo::Feature::Factory#multi_polygon


367
368
369
# File 'lib/rgeo/geographic/factory.rb', line 367

def multi_polygon(elems)
  @multi_polygon_class.new(self, elems)
end

#parse_wkb(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkb


313
314
315
# File 'lib/rgeo/geographic/factory.rb', line 313

def parse_wkb(str)
  @wkb_parser.parse(str)
end

#parse_wkt(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkt


307
308
309
# File 'lib/rgeo/geographic/factory.rb', line 307

def parse_wkt(str)
  @wkt_parser.parse(str)
end

#point(x, y, *extra) ⇒ Object

See RGeo::Feature::Factory#point


319
320
321
# File 'lib/rgeo/geographic/factory.rb', line 319

def point(x, y, *extra)
  @point_class.new(self, x, y, *extra)
end

#polygon(outer_ring, inner_rings = nil) ⇒ Object

See RGeo::Feature::Factory#polygon


343
344
345
# File 'lib/rgeo/geographic/factory.rb', line 343

def polygon(outer_ring, inner_rings = nil)
  @polygon_class.new(self, outer_ring, inner_rings)
end

#project(geometry) ⇒ Object

Projects the given geometry into the projected coordinate space, and returns the projected geometry. Returns nil if this factory does not support a projection. Raises Error::InvalidGeometry if the given geometry is not of this factory.


242
243
244
245
246
247
248
# File 'lib/rgeo/geographic/factory.rb', line 242

def project(geometry)
  return unless @projector && geometry
  unless geometry.factory == self
    raise Error::InvalidGeometry, "Wrong geometry type"
  end
  @projector.project(geometry)
end

#projection_factoryObject

Returns the factory for the projected coordinate space, or nil if this factory does not support a projection.


232
233
234
# File 'lib/rgeo/geographic/factory.rb', line 232

def projection_factory
  @projector&.projection_factory
end

#projection_limits_windowObject

Returns a ProjectedWindow specifying the limits of the domain of the projection space. Returns nil if this factory does not support a projection, or the projection limits are not known.


279
280
281
282
283
284
285
286
# File 'lib/rgeo/geographic/factory.rb', line 279

def projection_limits_window
  if @projector
    unless defined?(@projection_limits_window)
      @projection_limits_window = @projector.limits_window
    end
    @projection_limits_window
  end
end

#projection_wraps?Boolean

Returns true if this factory supports a projection and the projection wraps its x (easting) direction. For example, a Mercator projection wraps, but a local projection that is valid only for a small area does not wrap. Returns nil if this factory does not support or a projection, or if it is not known whether or not it wraps.

Returns:

  • (Boolean)

270
271
272
# File 'lib/rgeo/geographic/factory.rb', line 270

def projection_wraps?
  @projector ? @projector.wraps? : nil
end

#property(name) ⇒ Object

See RGeo::Feature::Factory#property


290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/rgeo/geographic/factory.rb', line 290

def property(name)
  case name
  when :has_z_coordinate
    @support_z
  when :has_m_coordinate
    @support_m
  when :uses_lenient_assertions
    @lenient_assertions
  when :buffer_resolution
    @buffer_resolution
  when :is_geographic
    true
  end
end

#psych_wkt_generatorObject


395
396
397
# File 'lib/rgeo/geographic/factory.rb', line 395

def psych_wkt_generator
  @psych_wkt_generator ||= RGeo::WKRep::WKTGenerator.new(tag_format: :wkt12)
end

#psych_wkt_parserObject


399
400
401
# File 'lib/rgeo/geographic/factory.rb', line 399

def psych_wkt_parser
  @psych_wkt_parser ||= RGeo::WKRep::WKTParser.new(self, support_wkt12: true, support_ewkt: true)
end

#unproject(geometry) ⇒ Object

Reverse-projects the given geometry from the projected coordinate space into lat-long space. Raises Error::InvalidGeometry if the given geometry is not of the projection defined by this factory.


255
256
257
258
259
260
261
# File 'lib/rgeo/geographic/factory.rb', line 255

def unproject(geometry)
  return unless geometry
  unless @projector && @projector.projection_factory == geometry.factory
    raise Error::InvalidGeometry, "You can unproject only features that are in the projected coordinate space."
  end
  @projector.unproject(geometry)
end