librtree 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b253861945be28133a07d5041b080939164dc3725a4b5b458319899d1ad9b66
4
- data.tar.gz: 56704611278f67678693ce56e4cec85ae436ba41d534803e0fb8694c39d5b45b
3
+ metadata.gz: 1d23f82b41d0757dbca1d30fc447bd2573db6d1584727c3244c84bbae0bc6b83
4
+ data.tar.gz: 36b7cda50a05140949537890a4ab99ebc555f08d7f7789cd7d4d0bd14c7b4c27
5
5
  SHA512:
6
- metadata.gz: 904eacdcbbe518f91ccc41d2c03da9191591a0af6e17be87874be1d74525707a10815e68ed0c9c3dacf91afe70384f982723487f3b6434241ec51097745f0f3e
7
- data.tar.gz: 8be9c36a56b92d1bea25a2ef352cb1e3062b1d197983c92cd11d0f753451573b454b3af22327c05fa300d52f3036561555bd1464faa79ea304d87811ddd4acd2
6
+ metadata.gz: 5ad5636536266f5ac027bd9f7ee59b359f4a3b00c07107057c7b83d378122be21343ebb54db36fe0e7683c926e674a7c8e4f3a6013b4a38c3019078851995c38
7
+ data.tar.gz: 22292e552cd05823802107094df3ff12c0a0a04129e26dd0fe8a9dd1c1b966f47b1b1cf4a1ac046f0965710965235c5e3a195c4de87b5612aa968e042a3c38fb
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  Changelog
2
2
  ---------
3
3
 
4
+ ### 1.0.6, 07-04-2024
5
+
6
+ - Update to librtree 1.3.0
7
+ - Adds `#envelope` `#csv_write`, `#to_csv`
8
+
9
+ ### 1.0.5, 16-01-2024
10
+
11
+ - All methods which take a `File` object (i.e., a stream), now
12
+ also accept a `String` or `Pathname` to the file instead.
13
+
4
14
  ### 1.0.4, 30-10-2023
5
15
 
6
16
  - Check for `__builtin_ctzl` (and use if found)
@@ -20,6 +20,22 @@
20
20
  #define UL_BYTES sizeof(unsigned long)
21
21
  #define UL_BITS (UL_BYTES << 3)
22
22
 
23
+ /*
24
+ config.h may contain HAVE___BUILTIN_CTZL defined from an autoconf
25
+ check (for the standalone C library, there will be such a check),
26
+ but in the embedded case, performing that check may be tricky, so
27
+ in that case we fall-back onto the __has_builtin macro which has
28
+ been present in clang for many years, and in gcc since version 10.
29
+ */
30
+
31
+ #ifndef HAVE___BUILTIN_CTZL
32
+ #ifdef __has_builtin
33
+ #if __has_builtin(__builtin_ctzl)
34
+ #define HAVE___BUILTIN_CTZL 1
35
+ #endif
36
+ #endif
37
+ #endif
38
+
23
39
  /* see note on branch_sizeof in branch.c */
24
40
 
25
41
  static size_t bindex_sizeof(size_t n)
data/ext/rtree/lib/csv.c CHANGED
@@ -81,3 +81,78 @@ rtree_t* csv_rtree_read(FILE *stream, size_t dims, state_flags_t flags)
81
81
 
82
82
  return NULL;
83
83
  }
84
+
85
+ static int write_node(const state_t*, const node_t*, FILE *);
86
+
87
+ static int write_internal_branch(const state_t *state,
88
+ const branch_t *branch,
89
+ void *arg)
90
+ {
91
+ return write_node(state, branch_get_child(branch), arg);
92
+ }
93
+
94
+ #if SIZEOF_RTREE_COORD_T == 4
95
+ #define PRECISION 6
96
+ #elif SIZEOF_RTREE_COORD_T == 8
97
+ #define PRECISION 14
98
+ #else
99
+ #error "strange size for rtree_coord_t"
100
+ #endif
101
+
102
+ static int write_leaf_branch(const state_t *state,
103
+ const branch_t *branch,
104
+ void *arg)
105
+ {
106
+ FILE *stream = arg;
107
+ rtree_id_t id = branch_get_id(branch);
108
+
109
+ fprintf(stream, "%li", (long int)id);
110
+
111
+ const rtree_coord_t *rect = branch_get_rect(branch);
112
+ size_t n = state_dims(state);
113
+
114
+ for (size_t i = 0 ; i < 2 * n ; i++)
115
+ fprintf(stream, ",%.*e", PRECISION, (double)rect[i]);
116
+
117
+ fprintf(stream, "\r\n");
118
+
119
+ return RTREE_OK;
120
+ }
121
+
122
+ #undef PRECISION
123
+
124
+ static int write_internal_node(const state_t *state,
125
+ const node_t *node,
126
+ FILE *stream)
127
+ {
128
+ return node_branch_each(state, node, write_internal_branch, stream);
129
+ }
130
+
131
+ static int write_leaf_node(const state_t *state,
132
+ const node_t *node,
133
+ FILE *stream)
134
+ {
135
+ return node_branch_each(state, node, write_leaf_branch, stream);
136
+ }
137
+
138
+ static int write_node(const state_t *state,
139
+ const node_t *node,
140
+ FILE *stream)
141
+ {
142
+ int err;
143
+
144
+ if (node_level(node) > 0)
145
+ err = write_internal_node(state, node, stream);
146
+ else
147
+ err = write_leaf_node(state, node, stream);
148
+
149
+ return err;
150
+ }
151
+
152
+ int csv_rtree_write(const rtree_t *rtree, FILE *stream)
153
+ {
154
+ if ((rtree == NULL) || (stream == NULL))
155
+ return RTREE_ERR_INVAL;
156
+
157
+ return write_node(rtree->state, rtree->root, stream);
158
+ }
@@ -23,7 +23,7 @@ const char* strerror_rtree(int err)
23
23
  { RTREE_ERR_NOCSV, "Compiled without CSV support" },
24
24
  { RTREE_ERR_JANSSON, "Error from the Jansson library" },
25
25
  { RTREE_ERR_NOJSON, "Compiled without JSON support" },
26
- { RTREE_ERR_NOJSON, "Compiled without BSRT support" },
26
+ { RTREE_ERR_NOBSRT, "Compiled without BSRT support" },
27
27
  { RTREE_ERR_GETBRANCH, "Error getting branch" },
28
28
  { RTREE_ERR_GETCHILD, "Error getting child node" },
29
29
  { RTREE_ERR_NODECLONE, "Error cloning node" },
@@ -1,3 +1,9 @@
1
- HDR := rtree/branch.h rtree/error.h rtree/extent.h rtree/node.h \
2
- rtree/package.h rtree/postscript.h rtree/rectf.h rtree/search.h \
3
- rtree/state.h rtree/types.h rtree.h
1
+ HDR := rtree.h \
2
+ rtree/error.h \
3
+ rtree/extent.h \
4
+ rtree/node.h \
5
+ rtree/package.h \
6
+ rtree/postscript.h \
7
+ rtree/search.h \
8
+ rtree/state.h \
9
+ rtree/types.h
@@ -5,7 +5,7 @@
5
5
 
6
6
  #include "rtree/package.h"
7
7
 
8
- const char rtree_package_version[] = "1.3.0";
8
+ const char rtree_package_version[] = "1.3.1";
9
9
  const char rtree_package_name[] = "librtree";
10
10
  const char rtree_package_url[] = "https://gitlab.com/jjg/librtree";
11
11
  const char rtree_package_bugreport[] = "j.j.green@gmx.co.uk";
@@ -13,6 +13,7 @@
13
13
  #include <time.h>
14
14
  #include <errno.h>
15
15
  #include <stdbool.h>
16
+ #include <stdlib.h>
16
17
 
17
18
  #ifdef HAVE_TGMATH_H
18
19
  #include <tgmath.h>
@@ -11,6 +11,7 @@
11
11
 
12
12
  #include <stdio.h>
13
13
 
14
+ int csv_rtree_write(const rtree_t*, FILE*);
14
15
  rtree_t* csv_rtree_read(FILE*, size_t, state_flags_t);
15
16
 
16
17
  #endif
@@ -104,9 +104,9 @@ void rtree_destroy(rtree_t *rtree)
104
104
  free(rtree);
105
105
  }
106
106
 
107
- rtree_height_t rtree_height(const rtree_t *rtree)
107
+ int rtree_csv_write(const rtree_t *rtree, FILE *stream)
108
108
  {
109
- return node_height(rtree->state, rtree->root);
109
+ return csv_rtree_write(rtree, stream);
110
110
  }
111
111
 
112
112
  rtree_t* rtree_csv_read(FILE *stream, size_t dim, state_flags_t flags)
@@ -182,6 +182,11 @@ const char* rtree_strerror(int err)
182
182
  return strerror_rtree(err);
183
183
  }
184
184
 
185
+ rtree_height_t rtree_height(const rtree_t *rtree)
186
+ {
187
+ return node_height(rtree->state, rtree->root);
188
+ }
189
+
185
190
  size_t rtree_bytes(const rtree_t *rtree)
186
191
  {
187
192
  if (rtree == NULL)
@@ -255,3 +260,11 @@ bool rtree_empty(const rtree_t *rtree)
255
260
  (rtree == NULL) ||
256
261
  (! node_nonempty(rtree->state, rtree->root));
257
262
  }
263
+
264
+ int rtree_envelope(const rtree_t *rtree, rtree_coord_t *rect)
265
+ {
266
+ if (rtree_empty(rtree))
267
+ return 1;
268
+ else
269
+ return node_envelope(rtree->state, rtree->root, rect);
270
+ }
@@ -34,6 +34,7 @@ int rtree_search(const rtree_t*, const rtree_coord_t*, rtree_search_t*, void*);
34
34
  int rtree_add_rect(rtree_t*, rtree_id_t, rtree_coord_t*);
35
35
  int rtree_update(rtree_t*, rtree_update_t*, void*);
36
36
  bool rtree_identical(const rtree_t*, const rtree_t*);
37
+ int rtree_csv_write(const rtree_t*, FILE*);
37
38
  rtree_t* rtree_csv_read(FILE*, size_t, state_flags_t);
38
39
  int rtree_json_write(const rtree_t*, FILE*);
39
40
  rtree_t* rtree_json_read(FILE*);
@@ -50,6 +51,7 @@ size_t rtree_branch_size(const rtree_t*);
50
51
  size_t rtree_branching_factor(const rtree_t*);
51
52
  double rtree_unit_sphere_volume(const rtree_t*);
52
53
  bool rtree_empty(const rtree_t*);
54
+ int rtree_envelope(const rtree_t*, rtree_coord_t*);
53
55
 
54
56
  #ifdef __cplusplus
55
57
  }
data/ext/rtree/rtree.c CHANGED
@@ -35,7 +35,7 @@ static VALUE rt_init(VALUE self, VALUE dim_obj, VALUE flags_obj)
35
35
  Check_Type(dim_obj, T_FIXNUM);
36
36
  size_t dim = FIX2ULONG(dim_obj);
37
37
 
38
- Check_Type(dim_obj, T_FIXNUM);
38
+ Check_Type(flags_obj, T_FIXNUM);
39
39
  state_flags_t flags = FIX2UINT(flags_obj);
40
40
 
41
41
  rtree_t *rtree;
@@ -241,7 +241,7 @@ static VALUE rt_csv_read(VALUE cls,
241
241
  Check_Type(dim_obj, T_FIXNUM);
242
242
  size_t dim = FIX2ULONG(dim_obj);
243
243
 
244
- Check_Type(dim_obj, T_FIXNUM);
244
+ Check_Type(flags_obj, T_FIXNUM);
245
245
  state_flags_t flags = FIX2UINT(flags_obj);
246
246
 
247
247
  rtree_t *rtree;
@@ -281,14 +281,19 @@ static VALUE serialise(VALUE self, VALUE io_obj, serialise_t *f)
281
281
  return self;
282
282
  }
283
283
 
284
- static VALUE rt_json_write(VALUE self, VALUE io_obj)
284
+ static VALUE rt_bsrt_write(VALUE self, VALUE io_obj)
285
285
  {
286
- return serialise(self, io_obj, rtree_json_write);
286
+ return serialise(self, io_obj, rtree_bsrt_write);
287
287
  }
288
288
 
289
- static VALUE rt_bsrt_write(VALUE self, VALUE io_obj)
289
+ static VALUE rt_csv_write(VALUE self, VALUE io_obj)
290
290
  {
291
- return serialise(self, io_obj, rtree_bsrt_write);
291
+ return serialise(self, io_obj, rtree_csv_write);
292
+ }
293
+
294
+ static VALUE rt_json_write(VALUE self, VALUE io_obj)
295
+ {
296
+ return serialise(self, io_obj, rtree_json_write);
292
297
  }
293
298
 
294
299
  static VALUE rt_identical(VALUE self, VALUE other)
@@ -373,6 +378,28 @@ static VALUE rt_size(VALUE self)
373
378
  return INT2NUM(rtree_bytes(rtree));
374
379
  }
375
380
 
381
+ static VALUE rt_envelope(VALUE self)
382
+ {
383
+ rtree_t *rtree;
384
+ TypedData_Get_Struct(self, rtree_t, &rtree_type, rtree);
385
+
386
+ if (rtree_empty(rtree))
387
+ return Qnil;
388
+
389
+ size_t n = 2 * rtree_dims(rtree);
390
+ double u[n];
391
+
392
+ if (rtree_envelope(rtree, u) != 0)
393
+ rb_sys_fail(__func__);
394
+
395
+ VALUE v = rb_ary_new_capa(n);
396
+
397
+ for (size_t i = 0 ; i < n ; i++)
398
+ rb_ary_store(v, i, DBL2NUM(u[i]));
399
+
400
+ return v;
401
+ }
402
+
376
403
  static VALUE rt_version(VALUE self)
377
404
  {
378
405
  return rb_str_new_cstr(rtree_package_version);
@@ -415,14 +442,13 @@ static VALUE rt_postscript(VALUE self,
415
442
  Check_Type(axis_obj, T_FIXNUM);
416
443
  extent_axis_t axis = FIX2UINT(axis_obj);
417
444
 
418
- rtree_postscript_t opt =
419
- {
420
- .style = style,
421
- .axis = axis,
422
- .extent = extent,
423
- .margin = margin,
424
- .title = "librtree-ruby output"
425
- };
445
+ rtree_postscript_t opt = {
446
+ .style = style,
447
+ .axis = axis,
448
+ .extent = extent,
449
+ .margin = margin,
450
+ .title = "librtree-ruby output"
451
+ };
426
452
 
427
453
  int err;
428
454
  if ((err = rtree_postscript(rtree, &opt, fp)) != 0)
@@ -519,11 +545,13 @@ void Init_rtree(void)
519
545
  rb_define_method(cRTreeBase, "height", rt_height, 0);
520
546
  rb_define_method(cRTreeBase, "add_rect", rt_add_rect, 2);
521
547
  rb_define_method(cRTreeBase, "search", rt_search, 1);
522
- rb_define_method(cRTreeBase, "json_write", rt_json_write, 1);
523
548
  rb_define_method(cRTreeBase, "bsrt_write", rt_bsrt_write, 1);
549
+ rb_define_method(cRTreeBase, "csv_write", rt_csv_write, 1);
550
+ rb_define_method(cRTreeBase, "json_write", rt_json_write, 1);
524
551
  rb_define_method(cRTreeBase, "eq?", rt_identical, 1);
525
552
  rb_define_method(cRTreeBase, "dim", rt_dim, 0);
526
553
  rb_define_method(cRTreeBase, "size", rt_size, 0);
554
+ rb_define_method(cRTreeBase, "envelope", rt_envelope, 0);
527
555
  rb_define_method(cRTreeBase, "page_size", rt_page_size, 0);
528
556
  rb_define_method(cRTreeBase, "node_size", rt_node_size, 0);
529
557
  rb_define_method(cRTreeBase, "rect_size", rt_rect_size, 0);
data/lib/rtree.rb CHANGED
@@ -15,7 +15,7 @@ require 'fcntl'
15
15
  # @author RTree J. J. Green
16
16
  #
17
17
  # A Ruby native extension implementing the R-tree spatial index of
18
- # Guttman-Green. The code is an emebded version of
18
+ # Guttman-Green. The code is an embedded version of
19
19
  # {http://soliton.vm.bytemark.co.uk/pub/jjg/en/code/librtree librtree}.
20
20
  #
21
21
  # Use
@@ -69,6 +69,21 @@ class RTree < RTreeBase
69
69
  module IOUtil
70
70
  extend self
71
71
 
72
+ # @!visibility private
73
+ #
74
+ def io_with_mode(arg, mode)
75
+ case arg
76
+ when String, Pathname
77
+ File.open(arg, mode) do |io|
78
+ yield io
79
+ end
80
+ when File, IO
81
+ yield arg
82
+ else
83
+ raise TypeError, arg
84
+ end
85
+ end
86
+
72
87
  # @!visibility private
73
88
  #
74
89
  def deserialise(string, encoding)
@@ -138,15 +153,19 @@ class RTree < RTreeBase
138
153
 
139
154
  class << self
140
155
 
141
- # Create a new RTree instance from JSON stream
142
- # @param io [IO] a readable stream object
156
+ # Create a new RTree instance from JSON path or stream
157
+ # @param io_arg [String|IO] a path or readable stream
143
158
  # @return [RTree] the newly instantiated RTree
144
159
  # @see #json_write
145
- # @example Read from file
160
+ # @example Using a path
161
+ # rtree = RTree.json_read('rtree.json')
162
+ # @example Using a stream
146
163
  # rtree = File.open('rtree.json', 'r') { |io| RTree.json_read(io) }
147
164
  #
148
- def json_read(io)
149
- super
165
+ def json_read(io_arg)
166
+ RTree::IOUtil.io_with_mode(io_arg, 'r') do |io|
167
+ super(io)
168
+ end
150
169
  end
151
170
 
152
171
  # Create a new RTree instance from JSON string
@@ -159,15 +178,17 @@ class RTree < RTreeBase
159
178
  end
160
179
 
161
180
  # Create a new RTree instance from BSRT (binary serialised R-tree)
162
- # stream
163
- # @param io [IO] a readable stream object
181
+ # path or stream
182
+ # @param io_arg [String|IO] a path or readable stream
164
183
  # @return [RTree] the newly instantiated RTree
165
184
  # @see #bsrt_write
166
- # @example Read from file
167
- # rtree = File.open('rtree.bsrt', 'r') { |io| RTree.bsrt_read(io) }
185
+ # @example Read from path
186
+ # rtree = RTree.bsrt_read('rtree.bsrt')
168
187
  #
169
- def bsrt_read(io)
170
- super
188
+ def bsrt_read(io_arg)
189
+ RTree::IOUtil.io_with_mode(io_arg, 'rb') do |io|
190
+ super(io)
191
+ end
171
192
  end
172
193
 
173
194
  # Create a new RTree instance from BSRT (binary serialised R-tree)
@@ -180,8 +201,8 @@ class RTree < RTreeBase
180
201
  deserialise(bsrt, Encoding::BINARY) { |io| bsrt_read(io) }
181
202
  end
182
203
 
183
- # Build a new RTree instance from CSV stream
184
- # @param io [IO] a readable stream object
204
+ # Build a new RTree instance from CSV path or stream
205
+ # @param io_arg [String|IO] a path or readable stream
185
206
  # @param dim [Integer] the dimension of the tree
186
207
  # @param split [:linear, :quadratic, :greene] See {#initialize}
187
208
  # @param node_page [Integer] See {#initialize}
@@ -192,9 +213,11 @@ class RTree < RTreeBase
192
213
  # useful feature is the reason that the dimension is a required
193
214
  # argument).
194
215
  #
195
- def csv_read(io, dim, split: :quadratic, node_page: 0)
216
+ def csv_read(io_arg, dim, split: :quadratic, node_page: 0)
196
217
  flags = split_flag(split) | node_page_flag(node_page)
197
- super(io, dim, flags)
218
+ RTree::IOUtil.io_with_mode(io_arg, 'r') do |io|
219
+ super(io, dim, flags)
220
+ end
198
221
  end
199
222
 
200
223
  # Build a new RTree instance from CSV string
@@ -363,34 +386,40 @@ class RTree < RTreeBase
363
386
  super
364
387
  end
365
388
 
366
- # Serialise to JSON stream
367
- # @param io [IO] a writable stream
389
+ # Serialise to BSRT (binary serialised R-tree)
390
+ # @param io_arg [String|IO] a path or writable stream
368
391
  # @return [self]
369
- # @see .json_read
392
+ # @see .bsrt_read
370
393
  # @example Write to file
371
- # File.open('rtree.json', 'w') { |io| rtree.json_write(io) }
394
+ # rtree.bsrt_write('rtree.bsrt')
372
395
  #
373
- def json_write(io)
374
- super
396
+ def bsrt_write(io_arg)
397
+ RTree::IOUtil.io_with_mode(io_arg, 'wb') { |io| super(io) }
398
+ self
375
399
  end
376
400
 
377
- # Serialise to BSRT (binary serialised R-tree) stream
378
- # @param io [IO] a writable stream
401
+ # Serialise to CSV
402
+ # @param io_arg [String|IO] a path or writable stream
379
403
  # @return [self]
380
- # @see .bsrt_read
404
+ # @see .csv_read
381
405
  # @example Write to file
382
- # File.open('rtree.bsrt', 'w') { |io| rtree.bsrt_write(io) }
406
+ # rtree.csv_write('rtree.csv')
383
407
  #
384
- def bsrt_write(io)
385
- super
408
+ def csv_write(io_arg)
409
+ RTree::IOUtil.io_with_mode(io_arg, 'wb') { |io| super(io) }
410
+ self
386
411
  end
387
412
 
388
- # Serialise to JSON string
389
- # @return [String] the UTF-8 encoded JSON
390
- # @see .from_json
413
+ # Serialise to JSON
414
+ # @param io_arg [String|IO] a path or writable stream
415
+ # @return [self]
416
+ # @see .json_read
417
+ # @example Write to file
418
+ # rtree.json_write('rtree.json')
391
419
  #
392
- def to_json
393
- serialise(Encoding::UTF_8) { |io| json_write(io) }
420
+ def json_write(io_arg)
421
+ RTree::IOUtil.io_with_mode(io_arg, 'w') { |io| super(io) }
422
+ self
394
423
  end
395
424
 
396
425
  # Serialise to BSRT string
@@ -401,6 +430,22 @@ class RTree < RTreeBase
401
430
  serialise(Encoding::BINARY) { |io| bsrt_write(io) }
402
431
  end
403
432
 
433
+ # Serialise to CSV string
434
+ # @return [String] the CSV
435
+ # @see .from_csv
436
+ #
437
+ def to_csv
438
+ serialise(Encoding::BINARY) { |io| csv_write(io) }
439
+ end
440
+
441
+ # Serialise to JSON string
442
+ # @return [String] the UTF-8 encoded JSON
443
+ # @see .from_json
444
+ #
445
+ def to_json
446
+ serialise(Encoding::UTF_8) { |io| json_write(io) }
447
+ end
448
+
404
449
  # The RTree structure in hash form
405
450
  # @return [Hash]
406
451
  #
@@ -437,6 +482,15 @@ class RTree < RTreeBase
437
482
  super
438
483
  end
439
484
 
485
+ # @return [Array[float]] the bounding rectangle
486
+ # @note Ruturns the bounding rectangle (in the same format
487
+ # as the rectangle input) for all rectangles in the tree.
488
+ # In the case that the input is empty, returns nil.
489
+ #
490
+ def envelope
491
+ super
492
+ end
493
+
440
494
  # @return [Integer] the bytes in a page of memory
441
495
  #
442
496
  def page_size
@@ -476,7 +530,7 @@ class RTree < RTreeBase
476
530
 
477
531
  # Create a PostScript plot of the RTree
478
532
  #
479
- # @param io [IO] a writeable stream object
533
+ # @param io_arg [String|IO] a path or writeable stream
480
534
  # @param style [RTree::Style] a style object describing the fill
481
535
  # colour and stroke width and colour for each level of the tree.
482
536
  # @param height [Float] the height of the plot in units of PostScript
@@ -487,7 +541,7 @@ class RTree < RTreeBase
487
541
  # @param margin [Float] extra space around the plot in units of
488
542
  # PostScript point (1/72 inch), default zero
489
543
  #
490
- def postscript(io, style, height: nil, width: nil, margin: 0)
544
+ def postscript(io_arg, style, height: nil, width: nil, margin: 0)
491
545
  if height && width then
492
546
  raise ArgumentError, 'cannot specify both height and width'
493
547
  end
@@ -498,7 +552,9 @@ class RTree < RTreeBase
498
552
  axis = AXIS_WIDTH
499
553
  extent = width || 216
500
554
  end
501
- super(style, axis, extent, margin, io)
555
+ RTree::IOUtil.io_with_mode(io_arg, 'w') do |io|
556
+ super(style, axis, extent, margin, io)
557
+ end
502
558
  end
503
559
 
504
560
  private
@@ -523,7 +579,7 @@ class RTree < RTreeBase
523
579
 
524
580
  end
525
581
 
526
- # @author RTree::Style J. J. Green
582
+ # @author RTree::Style J.J. Green
527
583
  #
528
584
  # A Ruby wrapper around RTree styles, used in PostScript plotting.
529
585
  # in particular by {RTree#postscript}.
@@ -532,16 +588,14 @@ class RTree::Style < RTreeStyleBase
532
588
 
533
589
  class << self
534
590
 
535
- # Create a new Style instance from JSON stream
536
- # @param io [IO] a readable stream object
591
+ # Create a new Style instance from JSON path or stream
592
+ # @param io_arg [String|IO] a path or readable stream
537
593
  # @return [RTree::Style] the newly instantiated Style
538
594
  # @example Read from file
539
- # style = File.open('some.style', 'r') do |io|
540
- # RTree::Style.json_read(io)
541
- # end
595
+ # style = RTree::Style.json_read('some.style')
542
596
  #
543
- def json_read(io)
544
- super
597
+ def json_read(io_arg)
598
+ RTree::IOUtil.io_with_mode(io_arg, 'r') { |io| super(io) }
545
599
  end
546
600
 
547
601
  # Create a new Style instance from JSON string
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librtree
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - J.J. Green
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-30 00:00:00.000000000 Z
11
+ date: 2024-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler