Class: Geos::STRtree

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Tools
Defined in:
lib/ffi-geos/strtree.rb

Constant Summary

Constants included from GeomTypes

GeomTypes::GEOS_GEOMETRYCOLLECTION, GeomTypes::GEOS_LINEARRING, GeomTypes::GEOS_LINESTRING, GeomTypes::GEOS_MULTILINESTRING, GeomTypes::GEOS_MULTIPOINT, GeomTypes::GEOS_MULTIPOLYGON, GeomTypes::GEOS_POINT, GeomTypes::GEOS_POLYGON

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Tools

#bool_result, #cast_geometry_ptr, #check_enum_value, #check_geometry, #pick_srid_according_to_policy, #pick_srid_from_geoms, #symbol_for_enum

Constructor Details

#initialize(*args) ⇒ STRtree

:call-seq:

new(capacity)
new(geoms_and_objects)


16
17
18
19
20
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
# File 'lib/ffi-geos/strtree.rb', line 16

def initialize(*args)
  geoms_and_objects = nil # forward declaration

  capacity = if args.length == 1 && args.first.is_a?(Fixnum)
    args.first
  else
    geoms_and_objects = if args.first.first.is_a?(Array)
      args.first
    else
      args
    end

    geoms_and_objects.each do |geom, obj|
      check_geometry(geom)
    end

    geoms_and_objects.length
  end

  if capacity <= 0
    raise ArgumentError.new("STRtree capacity must be greater than 0")
  end

  ptr = FFIGeos.GEOSSTRtree_create_r(Geos.current_handle, capacity)

  @ptr = FFI::AutoPointer.new(
    ptr,
    self.class.method(:release)
  )

  @storage = {}
  @ptrs = {}

  @storage_key = 0
  @built = false

  if geoms_and_objects
    geoms_and_objects.each do |geom, obj|
      self.insert(geom, obj)
    end
  end
end

Instance Attribute Details

#ptrObject (readonly)

Returns the value of attribute ptr.



8
9
10
# File 'lib/ffi-geos/strtree.rb', line 8

def ptr
  @ptr
end

Class Method Details

.release(ptr) ⇒ Object

:nodoc:



59
60
61
# File 'lib/ffi-geos/strtree.rb', line 59

def self.release(ptr) #:nodoc:
  FFIGeos.GEOSSTRtree_destroy_r(Geos.current_handle, ptr)
end

Instance Method Details

#built?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/ffi-geos/strtree.rb', line 63

def built?
  @built
end

#insert(geom, item) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ffi-geos/strtree.rb', line 72

def insert(geom, item)
  if self.built?
    raise RuntimeError.new("STRtree has already been built")
  else
    check_geometry(geom)

    key = next_key
    key_ptr = FFI::MemoryPointer.new(:pointer)
    key_ptr.write_int(key)

    @storage[key] = {
      :item => item,
      :geometry => geom
    }
    @ptrs[key] = key_ptr

    FFIGeos.GEOSSTRtree_insert_r(Geos.current_handle, self.ptr, geom.ptr, key_ptr)
  end
end

#iterateObject



170
171
172
173
174
# File 'lib/ffi-geos/strtree.rb', line 170

def iterate
  @storage.values.each do |v|
    yield(v)
  end
end

#query(geom, ret = :item) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ffi-geos/strtree.rb', line 137

def query(geom, ret = :item)
  self.query_all(geom).collect { |storage|
    item = if ret.is_a?(Array)
      storage.inject({}) do |memo, k|
        memo.tap {
          memo[k] = storage[k]
        }
      end
    elsif ret == :all
      storage
    else
      storage[ret]
    end

    item.tap {
      if block_given?
        yield(item)
      end
    }
  }.compact
end

#query_all(geom) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ffi-geos/strtree.rb', line 110

def query_all(geom)
  check_geometry(geom)

  @built = true
  retval = []

  callback = proc { |*args|
    key = args.first.read_int
    storage = @storage[key]
    retval << storage

    if block_given?
      yield(storage)
    end
  }

  FFIGeos.GEOSSTRtree_query_r(
    Geos.current_handle,
    self.ptr,
    geom.ptr,
    callback,
    nil
  )

  retval
end

#query_geometries(geom) ⇒ Object Also known as: query_geoms



159
160
161
162
163
164
165
166
167
# File 'lib/ffi-geos/strtree.rb', line 159

def query_geometries(geom)
  self.query_all(geom).collect { |storage|
    storage[:geometry].tap { |val|
      if block_given?
        yield(val)
      end
    }
  }.compact
end

#remove(geom, item) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/ffi-geos/strtree.rb', line 92

def remove(geom, item)
  check_geometry(geom)

  key = if storage = @storage.detect { |k, v| v[:item] == item }
    storage[0]
  end

  if key
    key_ptr = @ptrs[key]
    result = FFIGeos.GEOSSTRtree_remove_r(Geos.current_handle, self.ptr, geom.ptr, key_ptr)
    @built = true

    if result == 1
      @storage.delete(key)
    end
  end
end