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
79
80
81
82
# 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
  @coordinate_dimension = 2
  @coordinate_dimension += 1 if @support_z
  @coordinate_dimension += 1 if @support_m
  @spatial_dimension = @support_z ? 3 : 2

  @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
  @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


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

def coord_sys
  @coord_sys
end

#coordinate_dimensionObject (readonly)

Returns the value of attribute coordinate_dimension.


83
84
85
# File 'lib/rgeo/geographic/factory.rb', line 83

def coordinate_dimension
  @coordinate_dimension
end

#proj4Object (readonly)

See RGeo::Feature::Factory#proj4


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

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

#spatial_dimensionObject (readonly)

Returns the value of attribute spatial_dimension.


83
84
85
# File 'lib/rgeo/geographic/factory.rb', line 83

def spatial_dimension
  @spatial_dimension
end

#sridObject (readonly)

Returns the srid reported by this factory.


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

def srid
  @srid
end

Instance Method Details

#collection(elems) ⇒ Object

See RGeo::Feature::Factory#collection


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

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

#encode_with(coder) ⇒ Object

Psych support


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

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["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)

87
88
89
90
91
92
93
# File 'lib/rgeo/geographic/factory.rb', line 87

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:


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

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

#generate_wkt(obj) ⇒ Object


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

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

#has_projection?Boolean

Returns true if this factory supports a projection.

Returns:

  • (Boolean)

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

def has_projection?
  !@projector.nil?
end

#hashObject

Standard hash code


98
99
100
# File 'lib/rgeo/geographic/factory.rb', line 98

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

#init_with(coder) ⇒ Object

:nodoc:


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
218
# File 'lib/rgeo/geographic/factory.rb', line 182

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"]),
    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


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

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

#line_string(points) ⇒ Object

See RGeo::Feature::Factory#line_string


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

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

#linear_ring(points) ⇒ Object

See RGeo::Feature::Factory#linear_ring


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

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

#marshal_dumpObject

Marshal support


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rgeo/geographic/factory.rb', line 104

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,
    "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:


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
155
156
157
# File 'lib/rgeo/geographic/factory.rb', line 125

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"]),
    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


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

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

#marshal_wkb_parserObject


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

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


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

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

#multi_point(elems) ⇒ Object

See RGeo::Feature::Factory#multi_point


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

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

#multi_polygon(elems) ⇒ Object

See RGeo::Feature::Factory#multi_polygon


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

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

#parse_wkb(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkb


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

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

#parse_wkt(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkt


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

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

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

See RGeo::Feature::Factory#point


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

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


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

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.


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

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.


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

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.


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

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)

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

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

#property(name) ⇒ Object

See RGeo::Feature::Factory#property


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

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

#psych_wkt_generatorObject


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

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

#psych_wkt_parserObject


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

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.


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

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