Class: RGeo::Geos::ZMFactory

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

Overview

A factory for Geos that handles both Z and M.

Constant Summary collapse

TYPE_KLASSES =

:stopdoc:

{
  Feature::Point => ZMPointImpl,
  Feature::LineString => ZMLineStringImpl,
  Feature::Line => ZMLineImpl,
  Feature::LinearRing => ZMLinearRingImpl,
  Feature::Polygon => ZMPolygonImpl,
  Feature::GeometryCollection => ZMGeometryCollectionImpl,
  Feature::MultiPoint => ZMMultiPointImpl,
  Feature::MultiLineString => ZMMultiLineStringImpl,
  Feature::MultiPolygon => ZMMultiPolygonImpl
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ ZMFactory

:nodoc:


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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rgeo/geos/zm_factory.rb', line 43

def initialize(opts = {}) # :nodoc:
  proj4 = opts[:proj4]
  coord_sys = opts[:coord_sys]
  srid = opts[:srid]
  if (!proj4 || !coord_sys) && srid && (db = opts[:srs_database])
    entry = db.get(srid.to_i)
    if entry
      proj4 ||= entry.proj4
      coord_sys ||= entry.coord_sys
    end
  end
  srid ||= coord_sys.authority_code if coord_sys
  config = {
    uses_lenient_multi_polygon_assertions: opts[:lenient_multi_polygon_assertions] ||
      opts[:uses_lenient_multi_polygon_assertions],
    buffer_resolution: opts[:buffer_resolution], auto_prepare: opts[:auto_prepare],
    wkt_generator: opts[:wkt_generator], wkt_parser: opts[:wkt_parser],
    wkb_generator: opts[:wkb_generator], wkb_parser: opts[:wkb_parser],
    srid: srid.to_i, proj4: proj4, coord_sys: coord_sys
  }
  native_interface = opts[:native_interface] || Geos.preferred_native_interface
  if native_interface == :ffi
    @zfactory = FFIFactory.new(config.merge(has_z_coordinate: true))
    @mfactory = FFIFactory.new(config.merge(has_m_coordinate: true))
  else
    @zfactory = CAPIFactory.create(config.merge(has_z_coordinate: true))
    @mfactory = CAPIFactory.create(config.merge(has_m_coordinate: true))
  end

  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
end

Class Method Details

.create(opts = {}) ⇒ Object

Create a new factory. Returns nil if the GEOS implementation is not supported.


37
38
39
40
# File 'lib/rgeo/geos/zm_factory.rb', line 37

def create(opts = {})
  return unless Geos.supported?
  new(opts)
end

Instance Method Details

#buffer_resolutionObject

Returns the resolution used by buffer calculations on geometries created by this factory


215
216
217
# File 'lib/rgeo/geos/zm_factory.rb', line 215

def buffer_resolution
  @zfactory.buffer_resolution
end

#collection(elems) ⇒ Object

See RGeo::Feature::Factory#collection


303
304
305
# File 'lib/rgeo/geos/zm_factory.rb', line 303

def collection(elems)
  create_feature(ZMGeometryCollectionImpl, @zfactory.collection(elems), @mfactory.collection(elems))
end

#coord_sysObject

See RGeo::Feature::Factory#coord_sys


333
334
335
# File 'lib/rgeo/geos/zm_factory.rb', line 333

def coord_sys
  @zfactory.coord_sys
end

#create_feature(klass, zgeometry, mgeometry) ⇒ Object

:nodoc:


370
371
372
373
# File 'lib/rgeo/geos/zm_factory.rb', line 370

def create_feature(klass, zgeometry, mgeometry) # :nodoc:
  klass ||= TYPE_KLASSES[zgeometry.geometry_type] || ZMGeometryImpl
  zgeometry && mgeometry ? klass.new(self, zgeometry, mgeometry) : nil
end

#encode_with(coder) ⇒ Object

Psych support


154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rgeo/geos/zm_factory.rb', line 154

def encode_with(coder) # :nodoc:
  coder["srid"] = @zfactory.srid
  coder["buffer_resolution"] = @zfactory.buffer_resolution
  coder["lenient_multi_polygon_assertions"] = @zfactory.lenient_multi_polygon_assertions?
  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["auto_prepare"] = @zfactory.property(:auto_prepare).to_s
  coder["native_interface"] = @zfactory.is_a?(FFIFactory) ? "ffi" : "capi"
  if (proj4 = @zfactory.proj4)
    str = proj4.original_str || proj4.canonical_str
    coder["proj4"] = proj4.radians? ? { "proj4" => str, "radians" => true } : str
  end
  if (coord_sys = @zfactory.coord_sys)
    coder["coord_sys"] = coord_sys.to_wkt
  end
end

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

Factory equivalence test.

Returns:

  • (Boolean)

239
240
241
# File 'lib/rgeo/geos/zm_factory.rb', line 239

def eql?(rhs)
  rhs.is_a?(ZMFactory) && rhs.z_factory == @zfactory
end

#hashObject

Standard hash code


246
247
248
# File 'lib/rgeo/geos/zm_factory.rb', line 246

def hash
  @hash ||= [@zfactory, @mfactory].hash
end

#init_with(coder) ⇒ Object

:nodoc:


173
174
175
176
177
178
179
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
# File 'lib/rgeo/geos/zm_factory.rb', line 173

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(
    native_interface: coder["native_interface"] == "ffi" ? :ffi : :capi,
    has_z_coordinate: coder["has_z_coordinate"],
    has_m_coordinate: coder["has_m_coordinate"],
    srid: coder["srid"],
    buffer_resolution: coder["buffer_resolution"],
    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"]),
    auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
    uses_lenient_multi_polygon_assertions: coder["lenient_multi_polygon_assertions"],
    proj4: proj4,
    coord_sys: coord_sys
  )
end

#lenient_multi_polygon_assertions?Boolean

Returns true if this factory is lenient with MultiPolygon assertions

Returns:

  • (Boolean)

221
222
223
# File 'lib/rgeo/geos/zm_factory.rb', line 221

def lenient_multi_polygon_assertions?
  @zfactory.lenient_multi_polygon_assertions?
end

#line(start, stop) ⇒ Object

See RGeo::Feature::Factory#line


285
286
287
# File 'lib/rgeo/geos/zm_factory.rb', line 285

def line(start, stop)
  create_feature(ZMLineImpl, @zfactory.line(start, stop), @mfactory.line(start, stop))
end

#line_string(points) ⇒ Object

See RGeo::Feature::Factory#line_string


279
280
281
# File 'lib/rgeo/geos/zm_factory.rb', line 279

def line_string(points)
  create_feature(ZMLineStringImpl, @zfactory.line_string(points), @mfactory.line_string(points))
end

#linear_ring(points) ⇒ Object

See RGeo::Feature::Factory#linear_ring


291
292
293
# File 'lib/rgeo/geos/zm_factory.rb', line 291

def linear_ring(points)
  create_feature(ZMLinearRingImpl, @zfactory.linear_ring(points), @mfactory.linear_ring(points))
end

#m_factoryObject

Returns the m-only factory corresponding to this factory.


233
234
235
# File 'lib/rgeo/geos/zm_factory.rb', line 233

def m_factory
  @mfactory
end

#marshal_dumpObject

Marshal support


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

def marshal_dump # :nodoc:
  hash = {
    "srid" => @zfactory.srid,
    "bufr" => @zfactory.buffer_resolution,
    "wktg" => @wkt_generator.properties,
    "wkbg" => @wkb_generator.properties,
    "wktp" => @wkt_parser.properties,
    "wkbp" => @wkb_parser.properties,
    "lmpa" => @zfactory.lenient_multi_polygon_assertions?,
    "apre" => @zfactory.property(:auto_prepare) == :simple,
    "nffi" => @zfactory.is_a?(FFIFactory)
  }
  proj4 = @zfactory.proj4
  coord_sys = @zfactory.coord_sys
  hash["proj4"] = proj4.marshal_dump if proj4
  hash["cs"] = coord_sys.to_wkt if coord_sys
  hash
end

#marshal_load(data) ⇒ Object

:nodoc:


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
# File 'lib/rgeo/geos/zm_factory.rb', line 123

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(
    native_interface: (data["nffi"] ? :ffi : :capi),
    has_z_coordinate: data["hasz"],
    has_m_coordinate: data["hasm"],
    srid: data["srid"],
    buffer_resolution: data["bufr"],
    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_multi_polygon_assertions: data["lmpa"],
    auto_prepare: (data["apre"] ? :simple : :disabled),
    proj4: proj4,
    coord_sys: coord_sys
  )
end

#marshal_wkb_generatorObject


375
376
377
# File 'lib/rgeo/geos/zm_factory.rb', line 375

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

#marshal_wkb_parserObject


379
380
381
# File 'lib/rgeo/geos/zm_factory.rb', line 379

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


315
316
317
# File 'lib/rgeo/geos/zm_factory.rb', line 315

def multi_line_string(elems)
  create_feature(ZMMultiLineStringImpl, @zfactory.multi_line_string(elems), @mfactory.multi_line_string(elems))
end

#multi_point(elems) ⇒ Object

See RGeo::Feature::Factory#multi_point


309
310
311
# File 'lib/rgeo/geos/zm_factory.rb', line 309

def multi_point(elems)
  create_feature(ZMMultiPointImpl, @zfactory.multi_point(elems), @mfactory.multi_point(elems))
end

#multi_polygon(elems) ⇒ Object

See RGeo::Feature::Factory#multi_polygon


321
322
323
# File 'lib/rgeo/geos/zm_factory.rb', line 321

def multi_polygon(elems)
  create_feature(ZMMultiPolygonImpl, @zfactory.multi_polygon(elems), @mfactory.multi_polygon(elems))
end

#override_cast(original, ntype, flags) ⇒ Object

See RGeo::Feature::Factory#override_cast


339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/rgeo/geos/zm_factory.rb', line 339

def override_cast(original, ntype, flags)
  return unless Geos.supported?
  keep_subtype = flags[:keep_subtype]
  project = flags[:project]
  type = original.geometry_type
  ntype = type if keep_subtype && type.include?(ntype)
  case original
  when ZMGeometryMethods
    # Optimization if we're just changing factories, but to
    # another ZM factory.
    if original.factory != self && ntype == type &&
        (!project || original.factory.proj4 == @proj4)
      zresult = original.z_geometry.dup
      zresult.factory = @zfactory
      mresult = original.m_geometry.dup
      mresult.factory = @mfactory
      return original.class.create(self, zresult, mresult)
    end
    # LineString conversion optimization.
    if (original.factory != self || ntype != type) &&
        (!project || original.factory.proj4 == @proj4) &&
        type.subtypeof?(Feature::LineString) && ntype.subtypeof?(Feature::LineString)
      klass = Factory::IMPL_CLASSES[ntype]
      zresult = klass._copy_from(@zfactory, original.z_geometry)
      mresult = klass._copy_from(@mfactory, original.m_geometry)
      return ZMLineStringImpl.create(self, zresult, mresult)
    end
  end
  false
end

#parse_wkb(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkb


267
268
269
# File 'lib/rgeo/geos/zm_factory.rb', line 267

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

#parse_wkt(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkt


261
262
263
# File 'lib/rgeo/geos/zm_factory.rb', line 261

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

#point(x, y, z = 0, m = 0) ⇒ Object

See RGeo::Feature::Factory#point


273
274
275
# File 'lib/rgeo/geos/zm_factory.rb', line 273

def point(x, y, z = 0, m = 0)
  create_feature(ZMPointImpl, @zfactory.point(x, y, z), @mfactory.point(x, y, m))
end

#polygon(outer_ring, inner_rings = nil) ⇒ Object

See RGeo::Feature::Factory#polygon


297
298
299
# File 'lib/rgeo/geos/zm_factory.rb', line 297

def polygon(outer_ring, inner_rings = nil)
  create_feature(ZMPolygonImpl, @zfactory.polygon(outer_ring, inner_rings), @mfactory.polygon(outer_ring, inner_rings))
end

#proj4Object

See RGeo::Feature::Factory#proj4


327
328
329
# File 'lib/rgeo/geos/zm_factory.rb', line 327

def proj4
  @zfactory.proj4
end

#property(name) ⇒ Object

See RGeo::Feature::Factory#property


252
253
254
255
256
257
# File 'lib/rgeo/geos/zm_factory.rb', line 252

def property(name)
  case name
  when :has_z_coordinate, :has_m_coordinate, :is_cartesian
    true
  end
end

#psych_wkt_generatorObject


383
384
385
# File 'lib/rgeo/geos/zm_factory.rb', line 383

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

#psych_wkt_parserObject


387
388
389
# File 'lib/rgeo/geos/zm_factory.rb', line 387

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

#sridObject

Returns the SRID of geometries created by this factory.


208
209
210
# File 'lib/rgeo/geos/zm_factory.rb', line 208

def srid
  @zfactory.srid
end

#z_factoryObject

Returns the z-only factory corresponding to this factory.


227
228
229
# File 'lib/rgeo/geos/zm_factory.rb', line 227

def z_factory
  @zfactory
end