summaryrefslogtreecommitdiff
path: root/t/44_rtree.t
diff options
context:
space:
mode:
Diffstat (limited to 't/44_rtree.t')
-rw-r--r--t/44_rtree.t113
1 files changed, 113 insertions, 0 deletions
diff --git a/t/44_rtree.t b/t/44_rtree.t
new file mode 100644
index 0000000..d2afc66
--- /dev/null
+++ b/t/44_rtree.t
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+
+use strict;
+BEGIN {
+ $| = 1;
+ $^W = 1;
+}
+
+use t::lib::Test;
+use Test::More;
+use DBD::SQLite;
+use Data::Dumper;
+
+# NOTE: It seems to be better to compare rounded values
+# because stored coordinate values may have slight errors
+# since SQLite 3.7.13 (DBD::SQLite 1.38_01).
+
+sub is_deeply_approx {
+ my ($got, $expected, $name) = @_;
+ my $got_approx = [map { sprintf "%0.2f", $_ } @$got];
+ my $expected_approx = [map { sprintf "%0.2f", $_ } @$expected];
+ is_deeply($got_approx, $expected_approx, $name);
+}
+
+my @coords = (
+ # id, minX, maxX, minY, maxY
+ [1, 1, 200, 1, 200], # outside bounding box
+ [2, 25, 100, 25, 50],
+ [3, 50, 125, 40, 150],
+ [4, 25, 200, 125, 125], # hor. line
+ [5, 100, 100, 75, 175], # vert. line
+ [6, 100, 100, 75, 75], # point
+ [7, 150, 175, 150, 175]
+);
+
+my @test_regions = (
+ # minX, maxX, minY, maxY
+ [75, 75, 45, 45], # query point
+ [10, 140, 10, 175], # ... box
+ [30, 100, 75, 75] # ... hor. line
+);
+
+my @test_results = (
+ # results for contains tests (what does this region contain?)
+ [],
+ [2, 3, 5, 6],
+ [6],
+
+ # results for overlaps tests (what does this region overlap with?)
+ [1..3],
+ [1..6],
+ [1, 3, 5, 6]
+);
+
+BEGIN {
+ if (!grep /ENABLE_RTREE/, DBD::SQLite::compile_options()) {
+ plan skip_all => 'RTREE is disabled for this DBD::SQLite';
+ }
+}
+use Test::NoWarnings;
+
+plan tests => @coords + (2 * @test_regions) + 4;
+
+# connect
+my $dbh = connect_ok( RaiseError => 1 );
+
+# TODO: test rtree and rtree_i32 tables
+
+# create R* Tree table
+$dbh->do(<<"") or die DBI::errstr;
+ CREATE VIRTUAL TABLE try_rtree
+ USING rtree_i32(id, minX, maxX, minY, maxY);
+
+# populate it
+my $insert_sth = $dbh->prepare(<<"") or die DBI::errstr;
+INSERT INTO try_rtree VALUES (?,?,?,?,?)
+
+for my $coord (@coords) {
+ ok $insert_sth->execute(@$coord);
+}
+
+# find by primary key
+my $sql = "SELECT * FROM try_rtree WHERE id = ?";
+
+my $idx = 0;
+for my $id (1..2) {
+ my $results = $dbh->selectrow_arrayref($sql, undef, $id);
+ is_deeply_approx($results, $coords[$idx], "Coords for $id match");
+ $idx++;
+}
+
+# find contained regions
+my $contained_sql = <<"";
+SELECT id FROM try_rtree
+ WHERE minX >= ? AND maxX <= ?
+ AND minY >= ? AND maxY <= ?
+
+# Since SQLite 3.7.13, coordinate values may have slight errors.
+for my $region (@test_regions) {
+ my $results = $dbh->selectcol_arrayref($contained_sql, undef, @$region);
+ is_deeply_approx($results, shift @test_results);
+}
+
+# find overlapping regions
+my $overlap_sql = <<"";
+SELECT id FROM try_rtree
+ WHERE maxX >= ? AND minX <= ?
+ AND maxY >= ? AND minY <= ?
+
+for my $region (@test_regions) {
+ my $results = $dbh->selectcol_arrayref($overlap_sql, undef, @$region);
+ is_deeply_approx($results, shift @test_results);
+}