aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kislyuk <weaver@gentoo.org>2011-07-31 21:14:37 -0400
committerAndrey Kislyuk <weaver@gentoo.org>2011-07-31 21:14:37 -0400
commit0052a59b4635e455654932d725fc5b9a1aa5e057 (patch)
treebecac7c25b6bc4af1dc2dcff5d65b9db5e38f5be /sci-libs/libspatialindex
parentMake sure portage does not run gbrowse_metadb_config.pl otherwise sandbox vio... (diff)
downloadsci-0052a59b4635e455654932d725fc5b9a1aa5e057.tar.gz
sci-0052a59b4635e455654932d725fc5b9a1aa5e057.tar.bz2
sci-0052a59b4635e455654932d725fc5b9a1aa5e057.zip
New package
Diffstat (limited to 'sci-libs/libspatialindex')
-rw-r--r--sci-libs/libspatialindex/ChangeLog10
-rw-r--r--sci-libs/libspatialindex/Manifest4
-rw-r--r--sci-libs/libspatialindex/URL1
-rw-r--r--sci-libs/libspatialindex/libspatialindex-1.6.1.ebuild26
-rw-r--r--sci-libs/libspatialindex/metadata.xml5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/all-wcprops113
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/dir-prop-base20
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/entries652
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/HOWTORELEASE.txt.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/INSTALL.svn-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/README.svn-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/autogen.sh.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/install-sh.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/mkinstalldirs.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.sln.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.suo.svn-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/AUTHORS.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/COPYING.svn-base504
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/ChangeLog.svn-base1206
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/HOWTORELEASE.txt.svn-base82
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.WIN.svn-base28
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.svn-base231
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/Makefile.am.svn-base23
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/NEWS.svn-base0
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/README.svn-base423
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/autogen.sh.svn-base42
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/configure.ac.svn-base71
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/depcomp.svn-base522
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/install-sh.svn-base322
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/makefile.vc.svn-base217
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/missing.svn-base353
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/mkinstalldirs.svn-base150
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.sln.svn-base91
-rw-r--r--sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.suo.svn-basebin0 -> 195072 bytes
-rw-r--r--sci-libs/libspatialindex/svn/trunk/AUTHORS5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/COPYING504
-rw-r--r--sci-libs/libspatialindex/svn/trunk/ChangeLog1206
-rw-r--r--sci-libs/libspatialindex/svn/trunk/HOWTORELEASE.txt82
-rw-r--r--sci-libs/libspatialindex/svn/trunk/INSTALL231
-rw-r--r--sci-libs/libspatialindex/svn/trunk/INSTALL.WIN28
-rw-r--r--sci-libs/libspatialindex/svn/trunk/Makefile.am23
-rw-r--r--sci-libs/libspatialindex/svn/trunk/NEWS0
-rw-r--r--sci-libs/libspatialindex/svn/trunk/README423
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/autogen.sh42
-rw-r--r--sci-libs/libspatialindex/svn/trunk/configure.ac71
-rw-r--r--sci-libs/libspatialindex/svn/trunk/depcomp522
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/all-wcprops83
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/entries476
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/LineSegment.h.svn-base83
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MVRTree.h.svn-base83
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Makefile.am.svn-base16
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingPoint.h.svn-base79
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingRegion.h.svn-base155
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Point.h.svn-base77
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/RTree.h.svn-base102
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Region.h.svn-base97
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/SpatialIndex.h.svn-base250
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TPRTree.h.svn-base78
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimePoint.h.svn-base89
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimeRegion.h.svn-base102
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Version.h.svn-base42
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/LineSegment.h83
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/MVRTree.h83
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/Makefile.am16
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/MovingPoint.h79
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/MovingRegion.h155
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/Point.h77
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/RTree.h102
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/Region.h97
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/SpatialIndex.h250
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/TPRTree.h78
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/TimePoint.h89
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/TimeRegion.h102
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/Version.h42
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/all-wcprops89
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/entries504
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/BoundsQuery.h.svn-base45
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CountVisitor.h.svn-base45
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CustomStorage.h.svn-base73
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/DataStream.h.svn-base53
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Error.h.svn-base51
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/IdVisitor.h.svn-base47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Index.h.svn-base68
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/LeafQuery.h.svn-base70
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Makefile.am.svn-base17
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/ObjVisitor.h.svn-base48
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Utility.h.svn-base30
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_api.h.svn-base213
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_config.h.svn-base121
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_impl.h.svn-base46
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/BoundsQuery.h45
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/CountVisitor.h45
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/CustomStorage.h73
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/DataStream.h53
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/Error.h51
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/IdVisitor.h47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/Index.h68
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/LeafQuery.h70
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/Makefile.am17
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/ObjVisitor.h48
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/Utility.h30
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/sidx_api.h213
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/sidx_config.h121
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/capi/sidx_impl.h46
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/all-wcprops41
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/entries232
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PointerPool.h.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PoolPointer.h.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/SmartPointer.h.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/Tools.h.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Makefile.am.svn-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PointerPool.h.svn-base117
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PoolPointer.h.svn-base96
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/SmartPointer.h.svn-base78
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Tools.h.svn-base513
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/rand48.h.svn-base11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/Makefile.am7
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/include/tools/PointerPool.h117
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/include/tools/PoolPointer.h96
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/include/tools/SmartPointer.h78
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/include/tools/Tools.h513
-rw-r--r--sci-libs/libspatialindex/svn/trunk/include/tools/rand48.h11
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/install-sh322
-rw-r--r--sci-libs/libspatialindex/svn/trunk/makefile.vc217
-rw-r--r--sci-libs/libspatialindex/svn/trunk/missing353
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/mkinstalldirs150
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/entries71
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/text-base/Makefile.am.svn-base2
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/Makefile.am2
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/all-wcprops35
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/dir-prop-base13
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/entries204
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Exhaustive.cc.svn-base225
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Generator.cc.svn-base175
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeLoad.cc.svn-base209
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeQuery.cc.svn-base268
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Makefile.am.svn-base12
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Exhaustive.cc225
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Generator.cc175
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeLoad.cc209
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeQuery.cc268
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Makefile.am12
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/text-base/run.svn-base29
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/run29
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/dir-prop-base6
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/text-base/run.svn-base22
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/run22
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/all-wcprops71
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/dir-prop-base16
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/entries414
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeBulkLoad.vcproj.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeExhaustive.vcproj.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeGenerator.vcproj.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeLoad.vcproj.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeQuery.vcproj.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Exhaustive.cc.svn-base214
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Generator.cc.svn-base128
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Makefile.am.svn-base13
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.cc.svn-base162
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.vcproj.svn-base360
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeExhaustive.vcproj.svn-base360
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeGenerator.vcproj.svn-base364
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.cc.svn-base202
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.vcproj.svn-base360
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.cc.svn-base272
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.vcproj.svn-base360
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Exhaustive.cc214
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Generator.cc128
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Makefile.am13
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.cc162
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.vcproj360
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeExhaustive.vcproj360
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeGenerator.vcproj364
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.cc202
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.vcproj360
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.cc272
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.vcproj360
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/text-base/run.svn-base29
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/run29
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/dir-prop-base6
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/text-base/run.svn-base23
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/run23
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/dir-prop-base8
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/text-base/run.svn-base30
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/run30
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/text-base/run.svn-base29
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/run29
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/all-wcprops47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/dir-prop-base13
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/entries272
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Exhaustive.cc.svn-base272
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Generator.cc.svn-base98
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Makefile.am.svn-base11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.cc.svn-base176
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.h.svn-base138
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeLoad.cc.svn-base197
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeQuery.cc.svn-base298
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Exhaustive.cc272
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Generator.cc98
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Makefile.am11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.cc176
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.h138
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeLoad.cc197
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeQuery.cc298
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/dir-prop-base14
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/text-base/run.svn-base29
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/run29
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/dir-prop-base13
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/prop-base/run.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/text-base/run.svn-base23
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/run23
-rw-r--r--sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/entries62
-rw-r--r--sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/prop-base/spatialindex.vcproj.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/text-base/spatialindex.vcproj.svn-base960
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/spatialindex-vc/spatialindex.vcproj960
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/spatialindex.sln91
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/spatialindex.suobin0 -> 195072 bytes
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/.svn/all-wcprops11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/.svn/dir-prop-base7
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/.svn/entries83
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/.svn/text-base/Makefile.am.svn-base2
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/Makefile.am2
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/all-wcprops77
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/dir-prop-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/entries436
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/BoundsQuery.cc.svn-base45
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CountVisitor.cc.svn-base52
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CustomStorage.cc.svn-base110
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/DataStream.cc.svn-base103
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Error.cc.svn-base54
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/IdVisitor.cc.svn-base53
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Index.cc.svn-base381
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/LeafQuery.cc.svn-base126
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Makefile.am.svn-base14
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/ObjVisitor.cc.svn-base60
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Utility.cc.svn-base150
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/sidx_api.cc.svn-base2518
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/BoundsQuery.cc45
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/CountVisitor.cc52
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/CustomStorage.cc110
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/DataStream.cc103
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/Error.cc54
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/IdVisitor.cc53
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/Index.cc381
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/LeafQuery.cc126
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/Makefile.am14
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/ObjVisitor.cc60
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/Utility.cc150
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/capi/sidx_api.cc2518
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/all-wcprops77
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/dir-prop-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/entries436
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.cc.svn-base429
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.h.svn-base75
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.cc.svn-base103
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.h.svn-base48
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.cc.svn-base1423
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.h.svn-base222
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Makefile.am.svn-base4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.cc.svn-base1512
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.h.svn-base184
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/PointerPoolNode.h.svn-base133
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.cc.svn-base191
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.h.svn-base99
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.cc429
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.h75
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.cc103
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.h48
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.cc1423
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.h222
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Makefile.am4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.cc1512
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.h184
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/PointerPoolNode.h133
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.cc191
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.h99
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/all-wcprops89
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/dir-prop-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/entries504
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.cc.svn-base458
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.h.svn-base131
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.cc.svn-base372
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.h.svn-base73
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.cc.svn-base138
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.h.svn-base47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Makefile.am.svn-base4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.cc.svn-base1074
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.h.svn-base188
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/PointerPoolNode.h.svn-base138
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.cc.svn-base1551
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.h.svn-base201
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.cc.svn-base172
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.h.svn-base93
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.cc458
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.h131
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Index.cc372
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Index.h73
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.cc138
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.h47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Makefile.am4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Node.cc1074
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Node.h188
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/PointerPoolNode.h138
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.cc1551
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.h201
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.cc172
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.h93
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/all-wcprops65
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/dir-prop-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/entries368
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/LineSegment.cc.svn-base388
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Makefile.am.svn-base4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingPoint.cc.svn-base299
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingRegion.cc.svn-base1231
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Point.cc.svn-base262
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Region.cc.svn-base554
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.cc.svn-base93
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.h.svn-base32
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimePoint.cc.svn-base297
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimeRegion.cc.svn-base419
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/LineSegment.cc388
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/Makefile.am4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingPoint.cc299
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingRegion.cc1231
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/Point.cc262
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/Region.cc554
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.cc93
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.h32
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimePoint.cc297
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimeRegion.cc419
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/all-wcprops59
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/dir-prop-base10
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/entries334
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.cc.svn-base142
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.h.svn-base78
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.cc.svn-base501
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.h.svn-base58
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Makefile.am.svn-base4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.cc.svn-base126
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.h.svn-base61
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.cc.svn-base94
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.h.svn-base42
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.cc142
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.h78
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.cc501
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.h58
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/Makefile.am4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.cc126
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.h61
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.cc94
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.h42
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/all-wcprops23
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/dir-prop-base11
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/entries130
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/prop-base/Makefile.am.svn-base5
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Makefile.am.svn-base4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Tools.cc.svn-base1365
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/rand48.cc.svn-base145
-rwxr-xr-xsci-libs/libspatialindex/svn/trunk/src/tools/Makefile.am4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/Tools.cc1365
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tools/rand48.cc145
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/all-wcprops77
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/dir-prop-base9
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/entries436
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.cc.svn-base400
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.h.svn-base73
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.cc.svn-base135
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.h.svn-base47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Makefile.am.svn-base4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.cc.svn-base1253
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.h.svn-base200
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/PointerPoolNode.h.svn-base133
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.cc.svn-base171
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.h.svn-base93
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.cc.svn-base1352
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.h.svn-base199
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.cc400
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.h73
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.cc135
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.h47
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Makefile.am4
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.cc1253
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.h200
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/PointerPoolNode.h133
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.cc171
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.h93
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.cc1352
-rw-r--r--sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.h199
420 files changed, 80225 insertions, 0 deletions
diff --git a/sci-libs/libspatialindex/ChangeLog b/sci-libs/libspatialindex/ChangeLog
new file mode 100644
index 000000000..3264865b2
--- /dev/null
+++ b/sci-libs/libspatialindex/ChangeLog
@@ -0,0 +1,10 @@
+# ChangeLog for sci-libs/libspatialindex
+# Copyright 1999-2011 Gentoo Foundation; Distributed under the GPL v2
+# $Header: $
+
+*libspatialindex-1.6.1 (01 Aug 2011)
+
+ 01 Aug 2011; Andrey Kislyuk <weaver@gentoo.org>
+ +libspatialindex-1.6.1.ebuild, +metadata.xml:
+ New package, ebuild written by me
+
diff --git a/sci-libs/libspatialindex/Manifest b/sci-libs/libspatialindex/Manifest
new file mode 100644
index 000000000..7b52d262f
--- /dev/null
+++ b/sci-libs/libspatialindex/Manifest
@@ -0,0 +1,4 @@
+DIST spatialindex-src-1.6.1.tar.bz2 346819 RMD160 19d22e77305364d5e5d23ffe67fd5c9cf5e8e72c SHA1 b2044558c7af036b14f155f9228ad5eac7e20943 SHA256 42dc4149c04f7436632b3e15d5470fe80172e91f16a16665ffc5587b8c576fe4
+EBUILD libspatialindex-1.6.1.ebuild 548 RMD160 53bfd1216b24a257a64aa82c376d1dbb3d66363e SHA1 be114c019d5648e1151af4958b824f24b25191ac SHA256 7ee05e5efacb20dc89801742257eff2fc95aee68626e7bae09123b2b9569a876
+MISC ChangeLog 298 RMD160 8e48e08c243eb1c5f4768f86664f0eea987a126e SHA1 7d83c5f45daddd24415f82fbf73e551461ab696a SHA256 6128a205c3290c58521d69caa89cfe6a1a849876054bc11868c7142ef12f0786
+MISC metadata.xml 169 RMD160 e1db75ae5d177dffc400468c7d76a7e1fe41876d SHA1 0c953712f9b97d5ab3f95ae71997ffbc96c4007d SHA256 36837b011d26f0b83477c7a8632cb0099aedbcba5a3e45c61f20292e079f6180
diff --git a/sci-libs/libspatialindex/URL b/sci-libs/libspatialindex/URL
new file mode 100644
index 000000000..0a95fd560
--- /dev/null
+++ b/sci-libs/libspatialindex/URL
@@ -0,0 +1 @@
+http://www2.research.att.com/~marioh/spatialindex/index.html
diff --git a/sci-libs/libspatialindex/libspatialindex-1.6.1.ebuild b/sci-libs/libspatialindex/libspatialindex-1.6.1.ebuild
new file mode 100644
index 000000000..9286f0250
--- /dev/null
+++ b/sci-libs/libspatialindex/libspatialindex-1.6.1.ebuild
@@ -0,0 +1,26 @@
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header$
+
+EAPI=4
+
+MY_PN="spatialindex-src"
+MY_P="${MY_PN}-${PV}"
+
+DESCRIPTION="General framework for developing spatial indices"
+HOMEPAGE="http://trac.gispython.org/spatialindex/wiki"
+SRC_URI="http://download.osgeo.org/libspatialindex/${MY_P}.tar.bz2"
+LICENSE="GPL-2"
+
+KEYWORDS="~x86 ~amd64"
+SLOT="0"
+IUSE=""
+
+RDEPEND=""
+DEPEND="${RDEPEND}"
+
+S="${WORKDIR}/${MY_P}"
+
+src_install() {
+ emake DESTDIR="${D}" install || die "einstall failed"
+}
diff --git a/sci-libs/libspatialindex/metadata.xml b/sci-libs/libspatialindex/metadata.xml
new file mode 100644
index 000000000..3190fbf9c
--- /dev/null
+++ b/sci-libs/libspatialindex/metadata.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+ <herd>sci-geosciences</herd>
+</pkgmetadata>
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/.svn/all-wcprops
new file mode 100644
index 000000000..eb133b767
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/all-wcprops
@@ -0,0 +1,113 @@
+K 25
+svn:wc:ra_dav:version-url
+V 45
+/spatialindex/!svn/ver/203/spatialindex/trunk
+END
+HOWTORELEASE.txt
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/178/spatialindex/trunk/HOWTORELEASE.txt
+END
+spatialindex.sln
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/112/spatialindex/trunk/spatialindex.sln
+END
+mkinstalldirs
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/spatialindex/!svn/ver/75/spatialindex/trunk/mkinstalldirs
+END
+makefile.vc
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/spatialindex/!svn/ver/199/spatialindex/trunk/makefile.vc
+END
+AUTHORS
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/spatialindex/!svn/ver/62/spatialindex/trunk/AUTHORS
+END
+ChangeLog
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/spatialindex/!svn/ver/199/spatialindex/trunk/ChangeLog
+END
+depcomp
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/spatialindex/!svn/ver/2/spatialindex/trunk/depcomp
+END
+spatialindex.suo
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/203/spatialindex/trunk/spatialindex.suo
+END
+README
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/spatialindex/!svn/ver/203/spatialindex/trunk/README
+END
+INSTALL.WIN
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/spatialindex/!svn/ver/106/spatialindex/trunk/INSTALL.WIN
+END
+configure.ac
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/spatialindex/!svn/ver/199/spatialindex/trunk/configure.ac
+END
+INSTALL
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/spatialindex/!svn/ver/75/spatialindex/trunk/INSTALL
+END
+COPYING
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/spatialindex/!svn/ver/2/spatialindex/trunk/COPYING
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/spatialindex/!svn/ver/189/spatialindex/trunk/Makefile.am
+END
+missing
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/spatialindex/!svn/ver/2/spatialindex/trunk/missing
+END
+autogen.sh
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/spatialindex/!svn/ver/44/spatialindex/trunk/autogen.sh
+END
+NEWS
+K 25
+svn:wc:ra_dav:version-url
+V 48
+/spatialindex/!svn/ver/2/spatialindex/trunk/NEWS
+END
+install-sh
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/spatialindex/!svn/ver/2/spatialindex/trunk/install-sh
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/.svn/dir-prop-base
new file mode 100644
index 000000000..710cc907e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/dir-prop-base
@@ -0,0 +1,20 @@
+K 10
+svn:ignore
+V 147
+Makefile
+Makefile.in
+libtool
+configure
+config.log
+config.status
+config.guess
+config.sub
+autom4te.cache
+.libs
+aclocal.m4
+.deps
+ltmain.sh
+*.bz2
+*.gz
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/entries b/sci-libs/libspatialindex/svn/trunk/.svn/entries
new file mode 100644
index 000000000..3cefe7e25
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/entries
@@ -0,0 +1,652 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk
+http://svn.gispython.org/spatialindex
+
+
+
+2011-05-18T15:20:08.186979Z
+203
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+HOWTORELEASE.txt
+file
+
+
+
+
+2011-08-01T00:42:34.941167Z
+fd5e6466719bdf7d4f2a2831fb93a9e3
+2010-03-05T14:19:51.578751Z
+178
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2086
+
+spatialindex.sln
+file
+
+
+
+
+2011-08-01T00:42:34.941167Z
+90029cb0f3beefca12a84ccc350807de
+2009-07-22T15:18:42.091942Z
+112
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5948
+
+mkinstalldirs
+file
+
+
+
+
+2011-08-01T00:42:34.941167Z
+cfbd1f0cc32bb4f6feb804354401e61a
+2008-04-29T18:03:50.201853Z
+75
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3421
+
+regressiontest
+dir
+
+include
+dir
+
+makefile.vc
+file
+
+
+
+
+2011-08-01T00:42:34.945167Z
+2da5d6e2c73779033a306b0a93fb7279
+2010-12-04T21:22:32.514652Z
+199
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7044
+
+AUTHORS
+file
+
+
+
+
+2011-08-01T00:42:34.945167Z
+c9b5ecb6aa425ce8962ad5f522951705
+2008-01-19T18:37:39.389909Z
+62
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+147
+
+ChangeLog
+file
+
+
+
+
+2011-08-01T00:42:34.945167Z
+04ead0a3343ea4c13d62d75fecb0b001
+2010-12-04T21:22:32.514652Z
+199
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+36795
+
+depcomp
+file
+
+
+
+
+2011-08-01T00:42:34.945167Z
+e181e2c8720c60522c4c4c981108e367
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+15205
+
+src
+dir
+
+spatialindex.suo
+file
+
+
+
+
+2011-08-01T00:42:34.945167Z
+1816e890081a67e65fca615bf1b9e8f5
+2011-05-18T15:20:08.186979Z
+203
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+195072
+
+spatialindex-vc
+dir
+
+README
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+27ea41808f9c80b750d7561645a91419
+2011-05-18T15:20:08.186979Z
+203
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21730
+
+INSTALL.WIN
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+441f8f9aba5ec1e8ebb71cd1fa942e8b
+2009-07-19T01:26:54.003010Z
+106
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+831
+
+configure.ac
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+e8ca308c5d7c89c72cbd78dcc1829f28
+2010-12-04T21:22:32.514652Z
+199
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2257
+
+INSTALL
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+5d4638159851671944108691f23e4f28
+2008-04-29T18:03:50.201853Z
+75
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9273
+
+COPYING
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+fbc093901857fcd118f065f900982c24
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+26436
+
+missing
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+fd5dd60aa8cefab9462677280ea74a61
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10587
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+a54749f5751c911a46f8e0e35f7a685a
+2010-09-16T13:56:14.957953Z
+189
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+725
+
+autogen.sh
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+f535d156563a1c45c84cf546d418017f
+2008-01-17T17:06:18.561657Z
+44
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+938
+
+NEWS
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+d41d8cd98f00b204e9800998ecf8427e
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+
+install-sh
+file
+
+
+
+
+2011-08-01T00:42:34.949134Z
+2947b9daa4c6c8bddac15717f3548ab6
+2007-08-01T20:37:49.786254Z
+2
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9206
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/HOWTORELEASE.txt.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/HOWTORELEASE.txt.svn-base
new file mode 100644
index 000000000..1f66a2852
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/HOWTORELEASE.txt.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 18
+Id Rev Date Author
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/INSTALL.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/INSTALL.svn-base
new file mode 100644
index 000000000..f59aac5c2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/INSTALL.svn-base
@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 18
+Id Rev Author Date
+K 13
+svn:mime-type
+V 10
+text/x-rst
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/README.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/README.svn-base
new file mode 100644
index 000000000..f59aac5c2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/README.svn-base
@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 18
+Id Rev Author Date
+K 13
+svn:mime-type
+V 10
+text/x-rst
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/autogen.sh.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/autogen.sh.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/autogen.sh.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/install-sh.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/install-sh.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/install-sh.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/mkinstalldirs.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/mkinstalldirs.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/mkinstalldirs.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.sln.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.sln.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.sln.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.suo.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.suo.svn-base
new file mode 100644
index 000000000..dbc918b06
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/prop-base/spatialindex.suo.svn-base
@@ -0,0 +1,9 @@
+K 14
+svn:executable
+V 1
+*
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/AUTHORS.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/AUTHORS.svn-base
new file mode 100644
index 000000000..c68fc7c6f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/AUTHORS.svn-base
@@ -0,0 +1,5 @@
+Marios Hadjieleftheriou -- Main author
+mhadji@gmail.com
+
+Howard Butler -- minor packaging, Trac/SVN stuff, and some Windows work
+hobu.inc@gmail.com \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/COPYING.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/COPYING.svn-base
new file mode 100644
index 000000000..5ab7695ab
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/COPYING.svn-base
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/ChangeLog.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/ChangeLog.svn-base
new file mode 100644
index 000000000..9e1c580d6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/ChangeLog.svn-base
@@ -0,0 +1,1206 @@
+2010-11-22 19:53 seang
+
+ * src/capi/sidx_api.cc: Fix test of length value
+
+2010-11-22 19:23 hobu
+
+ * src/capi/sidx_api.cc: whitespace normalization
+
+2010-11-22 19:00 seang
+
+ * src/capi/sidx_api.cc: Add up deltas for multidimensional input
+
+2010-11-22 18:49 seang
+
+ * src/capi/sidx_api.cc: Add up deltas for multidimensional input
+
+2010-11-22 18:46 hobu
+
+ * src/capi/sidx_api.cc: revert r193
+
+2010-11-22 16:02 hobu
+
+ * src/capi/sidx_api.cc: we should set isPoint to true if we pass
+ our epsilon test -- this didn't work before
+
+2010-10-14 13:18 mhadji
+
+ * include/tools/Tools.h, src/tools/Tools.cc: Removed
+ nextUnifromLongDouble. It was incorrect
+
+2010-10-13 15:10 mhadji
+
+ * include/tools/Tools.h, src/tools/Tools.cc: Added
+ nextUniformLongDouble
+
+2010-09-16 13:56 hobu
+
+ * Makefile.am: fix #25 and include visual studio files in the
+ release
+
+2010-09-16 13:53 hobu
+
+ * makefile.vc: bump versions in preparation for release
+
+2010-09-16 13:52 hobu
+
+ * configure.ac, include/Version.h: bump versions in preparation for
+ release
+
+2010-06-19 20:34 hobu
+
+ * include/capi/CustomStorage.h, include/capi/Index.h,
+ include/capi/Makefile.am, include/capi/sidx_api.h,
+ include/capi/sidx_config.h, include/capi/sidx_impl.h,
+ makefile.vc, src/capi/CustomStorage.cc, src/capi/Index.cc,
+ src/capi/Makefile.am, src/capi/Utility.cc, src/capi/sidx_api.cc:
+ add Matthias' CustomStorage backend for C API
+
+2010-04-21 18:50 hobu
+
+ * README: Add Marios' pagesize diatribe to the docs
+
+2010-04-12 19:56 hobu
+
+ * ChangeLog: update ChangeLog
+
+2010-04-12 17:17 mhadji
+
+ * regressiontest/rtree/Exhaustive.cc:
+
+2010-04-12 17:07 mhadji
+
+ * regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/test3/run, spatialindex.suo,
+ src/rtree/BulkLoader.cc: Fixed rtree/BulkLoader infinit loop bug
+
+2010-03-31 15:33 hobu
+
+ * src/capi/BoundsQuery.cc, src/capi/CountVisitor.cc,
+ src/capi/DataStream.cc, src/capi/IdVisitor.cc, src/capi/Index.cc,
+ src/capi/ObjVisitor.cc, src/capi/Utility.cc: format and layout
+ normalization
+
+2010-03-30 20:18 hobu
+
+ * src/spatialindex/MovingRegion.cc: ensure that we instantiate the
+ ivOut with at least the ivIn so we have a properly constructed
+ Tools::Interval #16
+
+2010-03-05 14:19 hobu
+
+ * ., HOWTORELEASE.txt: add doc describing how to release
+
+2010-03-05 02:56 hobu
+
+ * regressiontest/tprtree/test1, regressiontest/tprtree/test2:
+ propsets to ignore test output:
+
+2010-03-05 02:53 hobu
+
+ * configure.ac: use subdir-objects for automake and rename the make
+ dist output to spatialindex-src
+
+2010-03-05 02:52 hobu
+
+ * include/Version.h: increment version info in preparation for
+ release
+
+2010-03-05 01:59 hobu
+
+ * ChangeLog: update for release
+
+2010-03-04 16:33 hobu
+
+ * include/capi/CountVisitor.h, include/capi/Makefile.am,
+ include/capi/sidx_api.h, include/capi/sidx_impl.h, makefile.vc,
+ src/capi/CountVisitor.cc, src/capi/Makefile.am,
+ src/capi/sidx_api.cc: add CountVisitor to the CAPI to provide a
+ cumulation of the number of hits that land within a query
+
+2010-03-03 21:55 hobu
+
+ * include/capi/IdVisitor.h, include/capi/ObjVisitor.h,
+ include/capi/sidx_api.h, regressiontest/rtree/test3/run,
+ src/capi/LeafQuery.cc, src/capi/sidx_api.cc: use uint64_t for
+ result counts instead of uint32_t in C API
+
+2009-12-29 02:35 hobu
+
+ * regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/tprtree/Exhaustive.cc: fix up for gcc 4.4
+
+2009-12-04 21:57 mhadji
+
+ * spatialindex.suo, src/spatialindex/Region.cc:
+
+2009-12-04 18:46 mhadji
+
+ * src/spatialindex/Region.cc: Fixed Region::touchesRegion member
+ function bug.
+
+2009-11-05 16:26 hobu
+
+ * src/spatialindex/Region.cc: don't thrown an error when -DDEBUG is
+ on and we initialize an infinite Region
+
+2009-11-03 03:10 hobu
+
+ * src/capi/sidx_api.cc: pass in a reference for the query bounds
+
+2009-11-03 03:04 hobu
+
+ * src/capi/sidx_api.cc: try to do no harm when calling Index_Free
+ on something that's null
+
+2009-11-03 03:00 hobu
+
+ * src/capi/sidx_api.cc: pass in a reference for the query bounds
+
+2009-11-03 02:15 hobu
+
+ * src/capi/sidx_api.cc: copy the array using memcpy because we
+ can't free() something created with new
+
+2009-11-03 01:48 hobu
+
+ * src/capi/sidx_api.cc: put the data in a newly malloc'd array to
+ match our std::free call of Index_Delete
+
+2009-11-02 21:32 hobu
+
+ * src/capi/LeafQuery.cc: make sure to delete our shape when we're
+ done
+
+2009-11-02 21:32 hobu
+
+ * src/capi/sidx_api.cc: get dimension from the Region, no need to
+ fetch from index properties
+
+2009-11-02 20:53 hobu
+
+ * src/capi/sidx_api.cc: make sure we clean up the bounds and region
+
+2009-11-02 20:08 hobu
+
+ * regressiontest/mvrtree/Generator.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/tprtree/Generator.cc,
+ regressiontest/tprtree/TPRTreeLoad.cc,
+ regressiontest/tprtree/TPRTreeQuery.cc, src/capi/sidx_api.cc,
+ src/mvrtree/Index.cc, src/mvrtree/MVRTree.cc,
+ src/mvrtree/Node.cc, src/rtree/Index.cc, src/rtree/Node.cc,
+ src/rtree/RTree.cc, src/spatialindex/LineSegment.cc,
+ src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc, src/spatialindex/TimePoint.cc,
+ src/spatialindex/TimeRegion.cc, src/tools/Tools.cc,
+ src/tprtree/Index.cc, src/tprtree/Node.cc,
+ src/tprtree/TPRTree.cc: only #include <limits> where needed, and
+ not in the global Tools.h file
+
+2009-10-30 17:09 hobu
+
+ * include/tools/Tools.h, regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/mvrtree/Generator.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/tprtree/Generator.cc, src/mvrtree/Node.cc,
+ src/rtree/BulkLoader.cc, src/rtree/Node.cc, src/rtree/RTree.cc,
+ src/spatialindex/LineSegment.cc, src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc,
+ src/storagemanager/RandomEvictionsBuffer.cc, src/tprtree/Node.cc:
+ remove <cmath> <limits> and <climits> from Tools.h and include
+ them seperately in each file that needs them
+
+2009-10-30 16:37 hobu
+
+ * include/capi/sidx_api.h: define to denote we're C API
+
+2009-10-30 15:03 hobu
+
+ * include/capi/sidx_config.h: add a newline
+
+2009-10-22 02:42 hobu
+
+ * src/capi/sidx_api.cc: make sure we use new/delete instead of
+ new/free
+
+2009-10-21 17:35 hobu
+
+ * ., include/LineSegment.h, include/Point.h, include/Region.h,
+ include/SpatialIndex.h, include/capi, src/capi,
+ src/spatialindex/LineSegment.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc: remove namespace pollution of Tools::
+ into the globally include'd header SpatialIndex.h
+
+2009-10-20 15:24 hobu
+
+ * configure.ac, makefile.vc: bump versions in preparation for
+ release
+
+2009-10-19 20:31 hobu
+
+ * include/capi/sidx_api.h: add SIDX_Version prototype
+
+2009-10-19 20:23 hobu
+
+ * ltmain.sh: ltmain.sh doesn't belong in svn
+
+2009-10-19 20:23 hobu
+
+ * include/capi/Makefile.in, src/capi/Makefile.in: Makefile.in's
+ don't belong in svn
+
+2009-10-19 18:50 hobu
+
+ * makefile.vc: C API compilation fix
+
+2009-10-19 18:50 hobu
+
+ * src/tools/Tools.cc: tmpname fixes so we compile on msvc2003
+
+2009-10-19 18:29 hobu
+
+ * makefile.vc: don't define a variable to "" or cl will complain
+
+2009-10-08 19:32 hobu
+
+ * src/rtree/BulkLoader.cc: bleaf and bindex switched around in
+ createLevel call
+
+2009-09-17 20:40 hobu
+
+ * include/capi/LeafQuery.h, include/capi/sidx_api.h,
+ src/capi/LeafQuery.cc, src/capi/sidx_api.cc: more leaf querying
+ code
+
+2009-09-16 18:45 hobu
+
+ * include/capi/LeafQuery.h, include/capi/Makefile.am,
+ include/capi/Makefile.in, include/capi/sidx_impl.h,
+ src/capi/LeafQuery.cc, src/capi/Makefile.am,
+ src/capi/Makefile.in, src/capi/sidx_api.cc: add beginnings of
+ leaf querying to C API
+
+2009-09-16 03:34 hobu
+
+ * include/capi/Item.h, include/capi/ObjVisitor.h,
+ include/capi/sidx_config.h, include/capi/sidx_impl.h,
+ src/capi/Item.cc, src/capi/Makefile.am, src/capi/Makefile.in,
+ src/capi/ObjVisitor.cc, src/capi/sidx_api.cc: remove the
+ duplicate and unnecessary Item construct that was masking the
+ already existing IData interface
+
+2009-08-31 15:32 hobu
+
+ * makefile.vc: support building the c api
+
+2009-08-24 13:25 hobu
+
+ * regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/tprtree/Exhaustive.cc: fix issue with uint32_t by
+ copying macros from Tools.h
+
+2009-08-19 20:47 hobu
+
+ * Makefile.am: try to ensure -lstdc++ is linked
+
+2009-08-19 19:56 hobu
+
+ * include/capi, src/capi: ignores
+
+2009-08-19 16:37 hobu
+
+ * Makefile.am, configure.ac, include/Makefile.am, include/capi,
+ include/capi/BoundsQuery.h, include/capi/DataStream.h,
+ include/capi/Error.h, include/capi/IdVisitor.h,
+ include/capi/Index.h, include/capi/Item.h,
+ include/capi/Makefile.am, include/capi/Makefile.in,
+ include/capi/ObjVisitor.h, include/capi/Utility.h,
+ include/capi/sidx_api.h, include/capi/sidx_config.h,
+ include/capi/sidx_impl.h, include/tools/Makefile.am,
+ src/Makefile.am, src/capi, src/capi/BoundsQuery.cc,
+ src/capi/DataStream.cc, src/capi/Error.cc, src/capi/IdVisitor.cc,
+ src/capi/Index.cc, src/capi/Item.cc, src/capi/Makefile.am,
+ src/capi/Makefile.in, src/capi/ObjVisitor.cc,
+ src/capi/Utility.cc, src/capi/sidx_api.cc: add C API (not
+ currently built on windows)
+
+2009-08-19 15:25 hobu
+
+ * .: ignore propset
+
+2009-08-19 15:24 hobu
+
+ * regressiontest/mvrtree/test1, regressiontest/mvrtree/test2,
+ regressiontest/rtree, regressiontest/rtree/test1,
+ regressiontest/rtree/test2, regressiontest/rtree/test3,
+ regressiontest/rtree/test4, regressiontest/tprtree/test1,
+ regressiontest/tprtree/test2: propsets to ignore test results
+
+2009-08-18 18:07 hobu
+
+ * include/tools/Tools.h, src/tools/Tools.cc: locking for
+ Tools::PropertySet (commented out though because it doesn't work
+
+2009-08-14 17:41 hobu
+
+ * src/tools/Tools.cc: comment out PropertySet locking for now
+
+2009-08-14 15:19 hobu
+
+ * include/tools/Tools.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/rtree/RTree.cc, src/rtree/RTree.h,
+ src/tools/Tools.cc, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h: use HAVE_PTHREAD_H for #ifdef, make
+ Tools::PropertySet threadsafe for read/write
+
+2009-08-13 19:10 mhadji
+
+ * spatialindex.suo, src/rtree/BulkLoader.cc,
+ src/rtree/BulkLoader.h, src/rtree/RTree.cc:
+
+2009-08-13 15:42 mhadji
+
+ * spatialindex-vc/spatialindex.vcproj, spatialindex.suo:
+
+2009-08-13 15:24 mhadji
+
+ * include/LineSegment.h, include/MVRTree.h, include/MovingPoint.h,
+ include/MovingRegion.h, include/Point.h, include/RTree.h,
+ include/Region.h, include/SpatialIndex.h, include/TPRTree.h,
+ include/TimePoint.h, include/TimeRegion.h,
+ include/tools/PointerPool.h, include/tools/Tools.h,
+ regressiontest/rtree/RTreeBulkLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc,
+ regressiontest/rtree/test1/run, regressiontest/rtree/test2/run,
+ spatialindex.suo, src/mvrtree/Index.cc, src/mvrtree/Index.h,
+ src/mvrtree/Leaf.cc, src/mvrtree/Leaf.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/mvrtree/PointerPoolNode.h, src/mvrtree/Statistics.cc,
+ src/mvrtree/Statistics.h, src/rtree/BulkLoader.cc,
+ src/rtree/BulkLoader.h, src/rtree/Index.cc, src/rtree/Index.h,
+ src/rtree/Leaf.cc, src/rtree/Leaf.h, src/rtree/Node.cc,
+ src/rtree/Node.h, src/rtree/PointerPoolNode.h,
+ src/rtree/RTree.cc, src/rtree/RTree.h, src/rtree/Statistics.cc,
+ src/rtree/Statistics.h, src/spatialindex/LineSegment.cc,
+ src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc, src/spatialindex/TimePoint.cc,
+ src/spatialindex/TimeRegion.cc, src/storagemanager/Buffer.cc,
+ src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h,
+ src/storagemanager/RandomEvictionsBuffer.cc, src/tools/Tools.cc,
+ src/tprtree/Index.cc, src/tprtree/Index.h, src/tprtree/Leaf.cc,
+ src/tprtree/Leaf.h, src/tprtree/Node.cc, src/tprtree/Node.h,
+ src/tprtree/PointerPoolNode.h, src/tprtree/Statistics.cc,
+ src/tprtree/Statistics.h, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h: 1. Replace size_t with uint32_t to fix
+ 64/32 bit compatibility issues
+ 2. Fixed memory bug related to data array and bulk loading for
+ RTree.
+
+2009-08-10 13:35 hobu
+
+ * include/SpatialIndex.h, include/tools/Tools.h: remove #define
+ interface, use class
+
+2009-08-06 01:11 hobu
+
+ * makefile.vc: osgeo4w packaging
+
+2009-08-05 20:21 hobu
+
+ * include/tools/Tools.h: don't redefine interface if it is already
+ defined (/me scowls at windows
+
+2009-08-05 19:27 hobu
+
+ * src/rtree/BulkLoader.cc: comment out record deletion entirely
+
+2009-08-05 17:58 hobu
+
+ * src/rtree/BulkLoader.cc: guard against invalid delete
+
+2009-07-30 18:48 hobu
+
+ * Makefile.am, configure.ac: bump version to 1.4.0 in prep for
+ release, add a windows docs to the dist
+
+2009-07-30 16:57 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: Add a
+ CheckFilesExists(Tools::PropertySet&) method instead of the cheap
+ way we were checking for existence before. This takes into
+ account the file extensions and only returns true if both files
+ exist
+
+2009-07-30 16:56 hobu
+
+ * include/tools/Tools.h: move the warning about 4251 down into
+ _MSC_VER
+
+2009-07-30 03:10 hobu
+
+ * ChangeLog, configure.ac: new changelog
+
+2009-07-30 02:32 hobu
+
+ * makefile.vc: update for new layout. make sure to build dll
+ appropriately
+
+2009-07-29 21:24 hobu
+
+ * include/tools/Tools.h: turn off warning 4251
+
+2009-07-29 20:57 hobu
+
+ * include/Makefile.am, include/SpatialIndex.h, include/Version.h:
+ fix #15 and provide a way to determine the library version at
+ compile time
+
+2009-07-29 20:50 hobu
+
+ * makefile.vc: add back makefile.vc
+
+2009-07-22 19:29 hobu
+
+ * src/spatialindex/Region.cc: a note about the debugging lint that
+ is incorrect when the bounds are infinity
+
+2009-07-22 19:24 hobu
+
+ * regressiontest/rtree/Exhaustive.cc: make sure to #include
+ <cstring> to satisfy gcc 4.3+
+
+2009-07-22 15:23 mhadji
+
+ * regressiontest/rtree/RTreeBulkLoad.vcproj,
+ regressiontest/rtree/RTreeExhaustive.vcproj,
+ regressiontest/rtree/RTreeGenerator.vcproj,
+ regressiontest/rtree/RTreeLoad.vcproj,
+ regressiontest/rtree/RTreeQuery.vcproj,
+ spatialindex-vc/spatialindex.vcproj, spatialindex.suo:
+
+2009-07-22 15:18 mhadji
+
+ * spatialindex.sln, spatialindex.suo:
+
+2009-07-21 13:11 mhadji
+
+ * src/tools/Tools.cc:
+
+2009-07-20 20:32 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: attempt to fix #8 and
+ allow users to specify extensions for the dat and idx files of
+ the diskstorage manager
+
+2009-07-20 17:35 hobu
+
+ * src/tools/Tools.cc: make sure to update existing values in
+ setProperties instead of assuming it doesn't exist in the map
+
+2009-07-20 15:01 mhadji
+
+ * spatialindex.suo, src/mvrtree/MVRTree.cc, src/rtree/RTree.cc,
+ src/tprtree/TPRTree.cc:
+
+2009-07-19 14:51 mhadji
+
+ * include/LineSegment.h, include/MVRTree.h, include/MovingPoint.h,
+ include/MovingRegion.h, include/Point.h, include/RTree.h,
+ include/Region.h, include/SpatialIndex.h, include/TPRTree.h,
+ include/TimePoint.h, include/TimeRegion.h, include/tools/Tools.h,
+ spatialindex.suo:
+
+2009-07-19 01:26 mhadji
+
+ * INSTALL.WIN:
+
+2009-07-19 01:15 mhadji
+
+ * spatialindex-vc/spatialindex.vcproj, spatialindex.suo:
+
+2009-07-19 01:13 mhadji
+
+ * spatialindex.suo:
+
+2009-07-19 01:09 mhadji
+
+ * makefile.vc, regressiontest/rtree/RTreeBulkLoad.vcproj,
+ spatialindex.suo:
+
+2009-07-19 01:02 mhadji
+
+ * INSTALL.WIN, regressiontest/rtree/RTreeBulkLoad.vcproj,
+ regressiontest/rtree/RTreeExhaustive.vcproj,
+ regressiontest/rtree/RTreeGenerator.vcproj,
+ regressiontest/rtree/RTreeLoad.vcproj,
+ regressiontest/rtree/RTreeQuery.vcproj,
+ regressiontest/rtree/test3/run,
+ spatialindex-vc/spatialindex.vcproj, spatialindex.sln,
+ spatialindex.suo:
+
+2009-07-18 22:52 mhadji
+
+ * include/SpatialIndex.h, include/tools/Tools.h:
+
+2009-07-18 22:19 mhadji
+
+ * spatialindex-vc/spatialindex.vcproj.RESEARCH.marioh.user:
+
+2009-07-18 22:19 mhadji
+
+ * include/LineSegment.h, include/MVRTree.h, include/MovingPoint.h,
+ include/MovingRegion.h, include/Point.h, include/RTree.h,
+ include/Region.h, include/SpatialIndex.h, include/TPRTree.h,
+ include/TimePoint.h, include/TimeRegion.h,
+ include/tools/Makefile.am, include/tools/PointerPool.h,
+ include/tools/PoolPointer.h, include/tools/SmartPointer.h,
+ include/tools/TemporaryFile.h, include/tools/Tools.h,
+ include/tools/rand48.h, makefile.vc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/rtree/RTreeBulkLoad.cc,
+ regressiontest/rtree/RTreeBulkLoad.vcproj,
+ regressiontest/rtree/RTreeExhaustive.vcproj,
+ regressiontest/rtree/RTreeGenerator.vcproj,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeLoad.vcproj,
+ regressiontest/rtree/RTreeQuery.vcproj,
+ regressiontest/rtree/test3/run, spatialindex-vc,
+ spatialindex-vc/spatialindex.vcproj,
+ spatialindex-vc/spatialindex.vcproj.RESEARCH.marioh.user,
+ src/mvrtree/Index.cc, src/mvrtree/Index.h, src/mvrtree/Leaf.cc,
+ src/mvrtree/Leaf.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/mvrtree/PointerPoolNode.h, src/mvrtree/Statistics.h,
+ src/rtree/BulkLoader.cc, src/rtree/BulkLoader.h,
+ src/rtree/Index.h, src/rtree/Leaf.h, src/rtree/Node.h,
+ src/rtree/PointerPoolNode.h, src/rtree/RTree.cc,
+ src/rtree/RTree.h, src/rtree/Statistics.h,
+ src/spatialindex/MovingRegion.cc,
+ src/spatialindex/SpatialIndexImpl.cc,
+ src/spatialindex/SpatialIndexImpl.h,
+ src/storagemanager/Buffer.cc, src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/storagemanager/RandomEvictionsBuffer.h,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/Makefile.am, src/tools/TemporaryFile.cc,
+ src/tools/Tools.cc, src/tprtree/Index.h, src/tprtree/Leaf.h,
+ src/tprtree/Node.h, src/tprtree/PointerPoolNode.h,
+ src/tprtree/Statistics.h, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h:
+
+2009-07-15 14:39 hobu
+
+ * include/SpatialIndex.h, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/rtree/Node.cc, src/rtree/Node.h, src/rtree/RTree.cc,
+ src/rtree/RTree.h, src/tprtree/Node.cc, src/tprtree/Node.h: apply
+ Willem's patch for #14
+
+2009-07-06 22:23 hobu
+
+ * src/rtree/RTree.cc: more descriptive and separate exception
+ descriptions for FillFactor inconsistencies
+
+2009-07-06 14:38 hobu
+
+ * include/SpatialIndex.h, ltmain.sh: silence warnings about windows
+ compiler complaints on non-windows systems
+
+2009-05-28 17:52 hobu
+
+ * makefile.vc: rename dlls to not have lib* in front of them
+
+2009-05-28 16:31 hobu
+
+ * makefile.vc: A much improved windows makefile based in libLAS'
+
+2009-05-28 16:31 hobu
+
+ * include/SpatialIndex.h: On MSVC, just about every class complains
+ about 4250, inheritance by dominance. We'll just shut that up for
+ now.
+
+2009-05-14 18:26 hobu
+
+ * src/tools/TemporaryFile.cc: apply Patrick Mézard's patch for the
+ inverted use of mktemp on windows #13
+
+2009-05-14 18:21 hobu
+
+ * src/tools/Tools.cc: Fix #12, add time.h so msvc9 works
+
+2009-05-04 17:10 hobu
+
+ * regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/mvrtree/MVRTreeLoad.cc,
+ regressiontest/mvrtree/MVRTreeQuery.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc,
+ regressiontest/tprtree/Generator.cc, src/mvrtree/MVRTree.cc,
+ src/mvrtree/Node.cc, src/rtree/BulkLoader.cc, src/rtree/Leaf.cc,
+ src/rtree/Node.cc, src/rtree/RTree.cc,
+ src/spatialindex/LineSegment.cc, src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc, src/spatialindex/TimePoint.cc,
+ src/spatialindex/TimeRegion.cc, src/storagemanager/Buffer.cc,
+ src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h, src/tools/Tools.cc,
+ src/tprtree/Leaf.cc, src/tprtree/Node.cc, src/tprtree/TPRTree.cc:
+ apply the patch for #11 - cstring and limits includes so gcc 4.3+
+ works
+
+2008-05-30 19:42 mhadji
+
+ * src/tools/Makefile.am, src/tools/Tools.cc:
+
+2008-05-23 18:27 mhadji
+
+ * makefile.vc:
+
+2008-05-23 17:55 mhadji
+
+ * configure.ac:
+
+2008-05-23 17:28 mhadji
+
+ * regressiontest/rtree/RTreeLoad.cc,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h:
+
+2008-05-18 12:35 mhadji
+
+ * ltmain.sh:
+
+2008-04-30 05:39 hobu
+
+ * .: propset to ignore aclocal.m4
+
+2008-04-30 05:39 hobu
+
+ * aclocal.m4: aclocal.m4 is autogenerated. removing
+
+2008-04-30 05:35 hobu
+
+ * ., include, include/tools, regressiontest,
+ regressiontest/mvrtree, regressiontest/rtree,
+ regressiontest/tprtree, src, src/mvrtree, src/rtree,
+ src/spatialindex, src/storagemanager, src/tools, src/tprtree: set
+ svn:ignore properties for autogenerated files and automake cruft
+
+2008-04-30 05:27 hobu
+
+ * Makefile.in, include/Makefile.in, include/tools/Makefile.in,
+ regressiontest/Makefile.in, regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in, src/Makefile.in,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tools/Makefile.in, src/tprtree/Makefile.in: delete
+ Makefile.in's from source tree. Use autogen.sh to remake them if
+ building from svn source yourself
+
+2008-04-30 05:26 hobu
+
+ * include/tools/Makefile.am: add rand48.h to dist target
+
+2008-04-29 19:47 mhadji
+
+ * regressiontest/rtree/test1/data,
+ regressiontest/rtree/test1/queries:
+
+2008-04-29 18:17 mhadji
+
+ * include/tools/rand48.hpp:
+
+2008-04-29 18:06 mhadji
+
+ * include/tools/rand48.h:
+
+2008-04-29 18:03 mhadji
+
+ * INSTALL, Makefile.in, aclocal.m4, configure.ac, mkinstalldirs,
+ regressiontest/Makefile.in, regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/TemporaryFile.cc, src/tools/Tools.cc:
+
+2008-04-29 16:36 mhadji
+
+ * makefile.vc:
+
+2008-04-29 16:36 mhadji
+
+ * include/Makefile.in, include/SpatialIndex.h,
+ include/tools/Makefile.in, include/tools/Tools.h:
+
+2008-04-29 16:36 mhadji
+
+ * src/Makefile.in, src/mvrtree/Makefile.in, src/mvrtree/Node.cc,
+ src/rtree/Makefile.in, src/spatialindex/LineSegment.cc,
+ src/spatialindex/Makefile.in, src/spatialindex/MovingRegion.cc,
+ src/storagemanager/Makefile.in,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/Makefile.in, src/tprtree/Makefile.in:
+
+2008-04-29 15:40 mhadji
+
+ * src/spatialindex/MovingRegion.cc: Fixex malloc memory leak.
+
+2008-04-29 15:40 mhadji
+
+ * src/spatialindex/LineSegment.cc: Fixed malloc memory leak
+
+2008-02-26 16:15 hobu
+
+ * src/tools/rand48.cc: oops. Add missing file
+
+2008-02-26 16:14 hobu
+
+ * include/tools/rand48.hpp: oops. Add missing file
+
+2008-01-25 19:43 hobu
+
+ * include/MVRTree.h, include/RTree.h, include/SpatialIndex.h,
+ include/TPRTree.h, include/tools/Tools.h, makefile.vc,
+ src/mvrtree/Index.cc, src/mvrtree/Leaf.cc, src/mvrtree/Node.cc,
+ src/rtree/BulkLoader.cc, src/rtree/Index.cc, src/rtree/Leaf.cc,
+ src/rtree/Node.cc, src/spatialindex/LineSegment.cc,
+ src/spatialindex/MovingRegion.cc, src/storagemanager/Buffer.cc,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/TemporaryFile.cc, src/tools/Tools.cc,
+ src/tprtree/Index.cc, src/tprtree/Leaf.cc, src/tprtree/Node.cc:
+ Initial push of windows patches
+
+2008-01-23 16:25 mhadji
+
+ * INSTALL:
+
+2008-01-21 14:19 mhadji
+
+ * README, regressiontest/rtree/test3/run:
+
+2008-01-19 20:51 hobu
+
+ * configure.ac, makefile.vc: bump version to 1.3
+
+2008-01-19 18:42 hobu
+
+ * ChangeLog: Add an auto-generated ChangeLog
+
+2008-01-19 18:37 hobu
+
+ * AUTHORS: add myself and some notes
+
+2008-01-19 18:36 hobu
+
+ * INSTALL: update to ReST
+
+2008-01-19 18:09 hobu
+
+ * README: update ReST
+
+2008-01-19 18:09 hobu
+
+ * README: update ReST
+
+2008-01-19 18:03 hobu
+
+ * README: update ReST
+
+2008-01-19 18:02 hobu
+
+ * README: update ReST
+
+2008-01-19 18:02 hobu
+
+ * README: update ReST
+
+2008-01-19 18:01 hobu
+
+ * README: update ReST
+
+2008-01-19 17:59 hobu
+
+ * README: update ReST
+
+2008-01-19 17:59 hobu
+
+ * README: update ReST
+
+2008-01-19 17:58 hobu
+
+ * README: update ReST
+
+2008-01-19 17:58 hobu
+
+ * README: update ReST
+
+2008-01-19 17:56 hobu
+
+ * README: update ReST
+
+2008-01-19 17:55 hobu
+
+ * README: update ReST
+
+2008-01-19 17:29 hobu
+
+ * README: update ReST
+
+2008-01-19 17:26 hobu
+
+ * README: update to ReST
+
+2008-01-19 17:02 hobu
+
+ * README: set mimetype to reStructured text so Trac will render it
+ for us in the browser
+
+2008-01-17 23:34 hobu
+
+ * regressiontest/tprtree/Makefile.am,
+ regressiontest/tprtree/Makefile.in, src/mvrtree/Makefile.am,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.am,
+ src/rtree/Makefile.in, src/spatialindex/Makefile.am,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.am,
+ src/storagemanager/Makefile.in, src/tprtree/Makefile.am,
+ src/tprtree/Makefile.in: add internal headers to the _SOURCES
+ targets so they get included in make dist
+
+2008-01-17 17:06 hobu
+
+ * Makefile.in, aclocal.m4, autogen.sh, include/Makefile.in,
+ include/tools/Makefile.in, ltmain.sh, regressiontest/Makefile.in,
+ regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in, src/Makefile.in,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tools/Makefile.in, src/tprtree/Makefile.in: add autogen.sh to
+ simplify auto stuff
+
+2008-01-17 17:04 hobu
+
+ * debian: move debian packaging stuff out of trunk
+
+2008-01-15 19:33 hobu
+
+ * makefile.vc: add nmake makefile
+
+2007-12-07 20:44 kenneth
+
+ * debian/libspatialindex1.dirs, debian/libspatialindex1.install,
+ debian/libspatialindex11.dirs, debian/libspatialindex11.install:
+ Wrong names
+
+2007-12-07 19:58 kenneth
+
+ * configure, debian/rules: Fixed rules file
+
+2007-12-07 18:10 kenneth
+
+ * config.guess, config.sub, debian/control: Updates to the control
+ file (packaging)
+ Removal of files that shouldn't be in SVN
+
+2007-11-30 18:04 mhadji
+
+ * Makefile.in, configure, configure.ac:
+
+2007-11-30 16:50 seang
+
+ * Makefile.am: Version info to 1:0:0
+
+2007-11-29 22:26 mhadji
+
+ * INSTALL, configure, configure.ac:
+
+2007-11-29 21:54 mhadji
+
+ * include/LineSegment.h, include/Point.h, include/Region.h,
+ include/tools/LineSegment.h, include/tools/Point.h,
+ include/tools/Region.h, src/spatialindex/LineSegment.cc,
+ src/spatialindex/Point.cc, src/spatialindex/Region.cc,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/TemporaryFile.cc, src/tools/Tools.cc:
+
+2007-11-29 21:48 mhadji
+
+ * Makefile.am, Makefile.in, aclocal.m4, configure, configure.ac,
+ include/Makefile.am, include/Makefile.in, include/MovingPoint.h,
+ include/MovingRegion.h, include/SpatialIndex.h,
+ include/TimePoint.h, include/TimeRegion.h,
+ include/tools/Makefile.am, include/tools/Makefile.in,
+ include/tools/PointerPool.h, include/tools/PoolPointer.h,
+ include/tools/SmartPointer.h, include/tools/TemporaryFile.h,
+ include/tools/Tools.h, regressiontest/Makefile.in,
+ regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Generator.cc,
+ regressiontest/tprtree/Makefile.in,
+ regressiontest/tprtree/RandomGenerator.cc,
+ regressiontest/tprtree/RandomGenerator.h, src/Makefile.in,
+ src/mvrtree/Index.cc, src/mvrtree/Leaf.cc,
+ src/mvrtree/MVRTree.cc, src/mvrtree/Makefile.in,
+ src/mvrtree/Node.cc, src/mvrtree/Statistics.cc,
+ src/rtree/BulkLoader.cc, src/rtree/Index.cc, src/rtree/Leaf.cc,
+ src/rtree/Makefile.in, src/rtree/Node.cc, src/rtree/RTree.cc,
+ src/rtree/Statistics.cc, src/spatialindex/Makefile.am,
+ src/spatialindex/Makefile.in, src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc,
+ src/spatialindex/SpatialIndexImpl.h,
+ src/spatialindex/TimePoint.cc, src/spatialindex/TimeRegion.cc,
+ src/storagemanager/Buffer.cc,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/Makefile.in,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/Makefile.am, src/tools/Makefile.in, src/tools/geometry,
+ src/tools/tools, src/tprtree/Index.cc, src/tprtree/Leaf.cc,
+ src/tprtree/Makefile.in, src/tprtree/Node.cc,
+ src/tprtree/Statistics.cc, src/tprtree/TPRTree.cc:
+
+2007-11-29 18:00 seang
+
+ * debian, debian/README, debian/README.Debian, debian/changelog,
+ debian/compat, debian/control, debian/copyright, debian/dirs,
+ debian/docs, debian/libspatialindex1-dev.dirs,
+ debian/libspatialindex1-dev.install,
+ debian/libspatialindex1.doc-base.EX,
+ debian/libspatialindex11.dirs, debian/libspatialindex11.install,
+ debian/rules: Add debian directory created by dh_make
+
+2007-11-29 04:05 hobu
+
+ * Makefile.am, Makefile.in: use -version-info instead of -release
+
+2007-11-29 00:59 hobu
+
+ * include/Makefile.in, include/tools/Makefile.in: include
+ Makefile.in's
+
+2007-11-29 00:55 hobu
+
+ * Makefile.am, Makefile.in: use .'s to separate version info and
+ don't do -no-undefined
+
+2007-11-29 00:19 hobu
+
+ * Makefile.am: tweak formatting
+
+2007-11-29 00:11 seang
+
+ * Makefile.am: Add version-info to Makefile.am
+
+2007-11-28 23:54 hobu
+
+ * Makefile.am, Makefile.in, include/Makefile.am,
+ include/tools/Makefile.am: finish incorporating -ltools
+
+2007-11-28 22:48 hobu
+
+ * Makefile.am, Makefile.in, configure, configure.ac,
+ include/Makefile.am, include/tools/Makefile.am: more progress on
+ automake for includes directories... close, but not quite
+
+2007-11-28 22:38 hobu
+
+ * include/Makefile.am, include/tools/Makefile.am: Add automake
+ files for includes
+
+2007-11-28 21:03 hobu
+
+ * Makefile.am, Makefile.in, aclocal.m4, configure, configure.ac,
+ include/tools, regressiontest/Makefile.in,
+ regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in, src/Makefile.am,
+ src/Makefile.in, src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tools, src/tools/Makefile.in, src/tools/geometry/Makefile.am,
+ src/tools/geometry/Makefile.in, src/tools/tools/Makefile.am,
+ src/tools/tools/Makefile.in, src/tprtree/Makefile.in: start
+ incorporating -ltools into the tree
+
+2007-08-30 15:16 mhadji
+
+ * INSTALL, a: README should be INSTALL, and INSTALL should be
+ README
+
+2007-08-30 15:15 mhadji
+
+ * INSTALL, README: README should be INSTALL, and INSTALL should be
+ README
+
+2007-08-30 15:13 mhadji
+
+ * README, a: README file should be INSTALL, and INSTALL should be
+ README
+
+2007-08-02 04:37 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: revert r9
+
+2007-08-02 04:37 hobu
+
+ * src/rtree/Leaf.cc: revert r10
+
+2007-08-02 04:36 hobu
+
+ * src/rtree/Node.cc: revert r11
+
+2007-08-02 04:36 hobu
+
+ * src/rtree/RTree.cc: revert r12
+
+2007-08-02 04:35 hobu
+
+ * src/mvrtree/MVRTree.cc: revert r13
+
+2007-08-02 04:34 hobu
+
+ * src/spatialindex/SpatialIndexImpl.h: add strings.h
+
+2007-08-02 04:27 hobu
+
+ * src/mvrtree/MVRTree.cc: add strings.h
+
+2007-08-02 04:26 hobu
+
+ * src/rtree/RTree.cc: add strings.h
+
+2007-08-02 04:25 hobu
+
+ * src/rtree/Node.cc: add strings.h
+
+2007-08-02 02:23 hobu
+
+ * src/rtree/Leaf.cc: include <strings.h>
+
+2007-08-02 02:21 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: include <strings.h> in
+ DiskStorageManager (this is not available on Solaris by default)
+
+2007-08-01 20:49 hobu
+
+ * regressiontest/rtree/test1/data,
+ regressiontest/rtree/test1/queries: add data and queries for
+ tests
+
+2007-08-01 20:48 hobu
+
+ * INSTALL, Makefile.in, README, aclocal.m4,
+ regressiontest/Makefile.in, regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc,
+ regressiontest/tprtree/Makefile.in, src/Makefile.in,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tprtree/Makefile.in: add Marios' latest updates
+
+2007-08-01 20:40 hobu
+
+ * spatialindex.111.zip: oops, don't include zip files
+
+2007-08-01 20:37 hobu
+
+ * AUTHORS, COPYING, ChangeLog, INSTALL, Makefile.am, Makefile.in,
+ NEWS, README, aclocal.m4, config.guess, config.sub, configure,
+ configure.ac, depcomp, include, include/MVRTree.h,
+ include/MovingPoint.h, include/MovingRegion.h, include/RTree.h,
+ include/SpatialIndex.h, include/TPRTree.h, include/TimePoint.h,
+ include/TimeRegion.h, install-sh, ltmain.sh, missing,
+ mkinstalldirs, regressiontest, regressiontest/Makefile.am,
+ regressiontest/Makefile.in, regressiontest/mvrtree,
+ regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/mvrtree/Generator.cc,
+ regressiontest/mvrtree/MVRTreeLoad.cc,
+ regressiontest/mvrtree/MVRTreeQuery.cc,
+ regressiontest/mvrtree/Makefile.am,
+ regressiontest/mvrtree/Makefile.in, regressiontest/mvrtree/test1,
+ regressiontest/mvrtree/test1/run, regressiontest/mvrtree/test2,
+ regressiontest/mvrtree/test2/run, regressiontest/rtree,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/rtree/Makefile.am,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/rtree/RTreeBulkLoad.cc,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc, regressiontest/rtree/test1,
+ regressiontest/rtree/test1/run, regressiontest/rtree/test2,
+ regressiontest/rtree/test2/run, regressiontest/rtree/test3,
+ regressiontest/rtree/test3/run, regressiontest/rtree/test4,
+ regressiontest/rtree/test4/run, regressiontest/tprtree,
+ regressiontest/tprtree/Exhaustive.cc,
+ regressiontest/tprtree/Generator.cc,
+ regressiontest/tprtree/Makefile.am,
+ regressiontest/tprtree/Makefile.in,
+ regressiontest/tprtree/RandomGenerator.cc,
+ regressiontest/tprtree/RandomGenerator.h,
+ regressiontest/tprtree/TPRTreeLoad.cc,
+ regressiontest/tprtree/TPRTreeQuery.cc,
+ regressiontest/tprtree/test1, regressiontest/tprtree/test1/run,
+ regressiontest/tprtree/test2, regressiontest/tprtree/test2/run,
+ spatialindex.111.zip, src, src/Makefile.am, src/Makefile.in,
+ src/mvrtree, src/mvrtree/Index.cc, src/mvrtree/Index.h,
+ src/mvrtree/Leaf.cc, src/mvrtree/Leaf.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/mvrtree/Makefile.am,
+ src/mvrtree/Makefile.in, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/mvrtree/PointerPoolNode.h, src/mvrtree/Statistics.cc,
+ src/mvrtree/Statistics.h, src/rtree, src/rtree/BulkLoader.cc,
+ src/rtree/BulkLoader.h, src/rtree/Index.cc, src/rtree/Index.h,
+ src/rtree/Leaf.cc, src/rtree/Leaf.h, src/rtree/Makefile.am,
+ src/rtree/Makefile.in, src/rtree/Node.cc, src/rtree/Node.h,
+ src/rtree/PointerPoolNode.h, src/rtree/RTree.cc,
+ src/rtree/RTree.h, src/rtree/Statistics.cc,
+ src/rtree/Statistics.h, src/spatialindex,
+ src/spatialindex/Makefile.am, src/spatialindex/Makefile.in,
+ src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc,
+ src/spatialindex/SpatialIndexImpl.cc,
+ src/spatialindex/SpatialIndexImpl.h,
+ src/spatialindex/TimePoint.cc, src/spatialindex/TimeRegion.cc,
+ src/storagemanager, src/storagemanager/Buffer.cc,
+ src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h,
+ src/storagemanager/Makefile.am, src/storagemanager/Makefile.in,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/storagemanager/RandomEvictionsBuffer.h, src/tprtree,
+ src/tprtree/Index.cc, src/tprtree/Index.h, src/tprtree/Leaf.cc,
+ src/tprtree/Leaf.h, src/tprtree/Makefile.am,
+ src/tprtree/Makefile.in, src/tprtree/Node.cc, src/tprtree/Node.h,
+ src/tprtree/PointerPoolNode.h, src/tprtree/Statistics.cc,
+ src/tprtree/Statistics.h, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h: add 1.1.1 version of library
+
+2007-08-01 20:32 hobu
+
+ * .: basic layout
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/HOWTORELEASE.txt.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/HOWTORELEASE.txt.svn-base
new file mode 100644
index 000000000..4853b3b23
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/HOWTORELEASE.txt.svn-base
@@ -0,0 +1,82 @@
+
+Steps for Making a libLAS Release
+==============================================================================
+
+:Author: Howard Butler
+:Contact: hobu.inc@gmail.com
+:Revision: $Revision$
+:Date: $Date$
+
+This document describes the process for releasing a new version of libspatialindex.
+
+General Notes
+------------------------------------------------------------------------------
+
+Release Process
+
+1) Increment Version Numbers
+
+ - configure.ac
+ * sidx_version_major
+ * sidx_version_minor
+ * sidx_version_micro
+ - include/Version.h
+ * SIDX_VERSION_MAJOR
+ * SIDX_VERSION_MINOR
+ * SIDX_VERSION_REV
+ * SIDX_RELEASE_NAME
+ - makefile.vc's
+ *PACKAGE_VERSION
+
+2) Update README to include any relevant info about the release that
+ might have changed.
+
+3) Update ChangeLog with svn2cl
+
+4) Run the regression tests. Really.
+
+5) Build Windows version
+
+ - Issue nmake and nmake install commands
+
+ ::
+
+ nmake /f makefile.vc clean
+ nmake /f makefile.vc
+ nmake /f makefile.vc install
+ nmake /f makefile.vc package
+
+
+6) Make the source distribution
+
+ ::
+
+ make dist
+
+
+7) Generate MD5 sums
+
+ ::
+
+ md5 spatialindex-src-1.5.0.tar.bz2 > spatialindex-src-1.5.0.tar.bz2.md5
+ md5 spatialindex-src-1.5.0.tar.gz > spatialindex-src-1.5.0.tar.gz.md5
+ md5 liblas-1.3.1-win32.zip > liblas-1.3.1-win32.zip.md5
+
+8) Update http://trac.gispython.org/spatialindex/wiki/Releases
+
+9) Upload windows and source package as attachments to the new release page.
+
+10) Tag the release. Use the ``-f`` switch if you are retagging because you
+ missed something.
+
+ ::
+
+ svn cp http://svn.gispython.org/svn/spatialindex/spatialindex/trunk http://svn.gispython.org/svn/spatialindex/spatialindex/tags/1.5.0
+
+11) Write the release notes. Place a copy of the release notes on the release
+ page you created as well as send an email to spatalindex list announcing the
+ new release.
+
+
+
+$Id$
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.WIN.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.WIN.svn-base
new file mode 100644
index 000000000..52649de1a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.WIN.svn-base
@@ -0,0 +1,28 @@
+Visual Studio 2005:
+You have to open the spatialindex.sln solution from the IDE and build.
+Unfortunatelly, vcbuild.exe does not work as expected, hence you cannot
+build the DLL from the command line.
+
+Visutal Studio 2008:
+Either use the IDE or use vcbuild to compile from the command line:
+
+To create 32bit DLL:
+1. Open a Visual Studio command prompt (or open any shell
+ and run vcvars32.bat).
+
+2a. Release build:
+ Run vcbuild.exe /useenv spatialindex.sln "Release|Win32"
+2b. Debug build:
+ Run vcbuild.exe /useenv spatialindex.sln "Debug|Win32"
+
+To create 64bit DLL:
+1. Open a Visual Studio x64 command prompt (or open any shell
+ and run vcvarsall.bat x64).
+
+2a. Release build:
+ Run vcbuild.exe /useenv spatialindex.sln "Release|x64"
+2b. Debug build:
+ Run vcbuild.exe /useenv spatialindex.sln "Debug|x64"
+
+Enjoy!
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.svn-base
new file mode 100644
index 000000000..095b1eb40
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/INSTALL.svn-base
@@ -0,0 +1,231 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PREFIX', the package will
+use PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..9b4c2eced
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,23 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+SUBDIRS = src . regressiontest include
+
+lib_LTLIBRARIES = libspatialindex.la libspatialindex_c.la
+
+libspatialindex_la_SOURCES =
+libspatialindex_la_LIBADD = \
+ src/spatialindex/liblibrary.la \
+ src/storagemanager/libstoragemanager.la \
+ src/rtree/librtree.la \
+ src/mvrtree/libmvrtree.la \
+ src/tprtree/libtprtree.la \
+ src/tools/libtools.la
+
+libspatialindex_c_la_SOURCES =
+libspatialindex_c_la_LIBADD = \
+ libspatialindex.la \
+ src/capi/libsidxc.la
+
+libspatialindex_la_LDFLAGS = -version-info 1:0:0
+libspatialindex_c_la_LDFLAGS = -version-info 1:0:0 -lstdc++
+
+EXTRA_DIST = makefile.vc INSTALL.WIN spatialindex.sln spatialindex-vc/spatialindex.vcproj
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/NEWS.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/NEWS.svn-base
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/NEWS.svn-base
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/README.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/README.svn-base
new file mode 100644
index 000000000..62f8132b8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/README.svn-base
@@ -0,0 +1,423 @@
+*****************************************************************************
+ SpatialIndex Reference
+*****************************************************************************
+
+:Author: Marios Hadjieleftheriou
+:Contact: mhadji@gmail.com
+:Revision: $Revision$
+:Date: $Date$
+
+.. The next heading encountered becomes our H2
+..
+
+.. sectnum::
+
+.. contents::
+ :depth: 2
+ :backlinks: top
+
+------------------------------------------------------------------------------
+Introduction
+------------------------------------------------------------------------------
+
+You have downloaded the SpatialIndex Library. This is free software under LGPL.
+The library is in beta testing stage. Use at your own risk.
+
+The purpose of this library is to provide:
+ 1. An extensible framework that will support robust spatial indexing
+ methods.
+ 2. Support for sophisticated spatial queries. Range, point location,
+ nearest neighbor and k-nearest neighbor as well as parametric
+ queries (defined by spatial constraints) should be easy to deploy and run.
+ 3. Easy to use interfaces for inserting, deleting and updating information.
+ 4. Wide variety of customization capabilities. Basic index and storage
+ characteristics like the page size, node capacity, minimum fan-out,
+ splitting algorithm, etc. should be easy to customize.
+ 5. Index persistence. Internal memory and external memory structures
+ should be supported. Clustered and non-clustered indices should
+ be easy to be persisted.
+
+------------------------------------------------------------------------------
+Installation
+------------------------------------------------------------------------------
+
+First run autogen.sh to generate the configure scripts.
+By default include files and library files will be installed in /usr/local. If
+you would like to use a different installation directory (e.g., in case
+that you do not have root access) run the configure script with
+the --prefix option:
+
+::
+
+ ./configure --prefix=/home/marioh/usr
+
+Make the library::
+
+ make
+
+Install the library::
+
+ make install
+
+------------------------------------------------------------------------------
+Using the Library
+------------------------------------------------------------------------------
+
+You are ready to use the library. All you have to
+do is to include the file SpatialIndex.h in your source
+files and then compile with the following options:
+
+::
+
+ g++ MyFile.cc -o MyFile -L/home/marioh/usr/lib -I/home/marioh/usr/include -lpthread -lspatialindex
+
+If the library is installed in the default /usr/local path, then the
+-I and -L options are not necessary.
+
+If you are compiling on Mac OS X you will need to add the -bind_at_load
+option when linking against the dynamic link libraries. OS X Tiger should
+work out of the box, however, with XCode 3.0.
+
+------------------------------------------------------------------------------
+Library Overview
+------------------------------------------------------------------------------
+
+The library currently consists of six packages:
+ 1. The core spatialindex utilities.
+ 2. The storagemanager files.
+ 3. The spatialindex interfaces.
+ 4. The rtree index.
+ 5. The mvrtree index.
+ 6. The tprtree index.
+
+I will briefly present the basic features supported by each package.
+For more details you will have to refer to the code, for now.
+
+Spatial Index Utilities
+------------------------------------------------------------------------------
+
+To provide common constructors and uniform initialization for all objects
+provided by the library a PropertySet class is provided. A PropertySet
+associates strings with Variants. Each property corresponds to one string.
+
+A basic implementation of a Variant is also provided that supports a
+number of data types. The supported data types can be found in SpatialIndex.h
+
+PropertySet supports three functions:
+
+ 1. getProperty returns the Variant associated with the given string.
+ 2. setProperty associates the given Variant with the given string.
+ 3. removeProperty removes the specified property from the PropertySet.
+
+A number of exceptions are also defined here. All exceptions extend
+Exception and thus provide the what() method that returns a string
+representation of the exception with useful comments. It is advisable to
+use enclosing try/catch blocks when using any library objects. Many
+constructors throw exceptions when invalid initialization properties are specified.
+
+A general IShape interface is defined. All shape classes should extend
+IShape. Basic Region and Point classes are already provided. Please
+check Region.h and Point.h for further details.
+
+Storage Manager
+------------------------------------------------------------------------------
+
+The library provides a common interface for storage management of all
+indices. It consists of the IStorageManager interface, which provides functions
+for storing and retrieving entities. An entity is viewed as a simple byte
+array; hence it can be an index entry, a data entry or anything else that the
+user wants to store. The storage manager interface is generic and does not apply
+only to spatial indices.
+
+Classes that implement the IStorageManager interface decide on how to
+store entities. simple main memory implementation is provided, for example,
+that stores the entities using a vector, associating every entity with a
+unique ID (the entry's index in the vector). A disk based storage manager
+could choose to store the entities in a simple random access file, or a
+database storage manager could store them in a relational table, etc. as long
+as unique IDs are associated with every entity. Also, storage managers should
+implement their own paging, compaction and deletion policies transparently
+from the callers (be it an index or a user).
+
+The storeByteArray method gets a byte array and its length and an entity ID.
+If the caller specifies NewPage as the input ID, the storage manager allocates
+a new ID, stores the entity and returns the ID associated with the entity.
+If, instead, the user specifies an already existing ID the storage manager
+overwrites the old data. An exception is thrown if the caller requests
+an invalid ID to be overwritten.
+
+The loadByteArray method gets an entity ID and returns the associated byte
+array along with its length. If an invalid ID is requested, an exception is thrown.
+
+The deleteByteArray method removes the requested entity from storage.
+
+The storage managers should have no information about the types of entities
+that are stored. There are three main reasons for this decision:
+
+ 1. Any number of spatial indices can be stored in a single storage manager
+ (i.e. the same relational table, or binary file, or hash table, etc., can
+ be used to store many indices) using an arbitrary number of pages and
+ a unique index ID per index (this will be discussed shortly).
+ 2. Both clustered and non-clustered indices can be supported. A clustered
+ index stores the data associated with the entries that it contains along
+ with the spatial information that it indexes. A non-clustered index stores
+ only the spatial information of its entries. Any associated data are
+ stored separately and are associated with the index entries by a unique ID.
+ To support both types of indices, the storage manager interface should be
+ quite generic, allowing the index to decide how to store its data.
+ Otherwise clustered and non-clustered indices would have to be
+ implemented separately.
+ 3. Decision flexibility. For example, the users can choose a clustered index
+ that will take care of storing everything. They can choose a main memory
+ non-clustered index and store the actual data in MySQL. They can choose
+ a disk based non-clustered index and store the data manually in a
+ separate binary file or even in the same storage manager but doing a low
+ level customized data processing.
+
+Two storage managers are provided in the current implementation:
+
+ 1) MemoryStorageManager
+ 2) DiskStorageManager
+
+MemoryStorageManager
+~~~~~~~~~~~~~~~~~~~~~~~
+
+As it is implied be the name, this is a main memory implementation. Everything
+is stored in main memory using a simple vector. No properties are needed to
+initialize a MemoryStorageManager object. When a MemoryStorageManager instance
+goes out of scope, all data that it contains are lost.
+
+DiskStorageManager
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The disk storage manager uses two random access files for storing information.
+One with extension .idx and the other with extension .dat.
+
+A list of all the supported properties that can be provided during
+initialization, follows:
+
+========= ======== ===========================================================
+Property Type Description
+========= ======== ===========================================================
+FileName VT_PCHAR The base name of the file to open (no extension)
+Overwrite VT_BOOL If Overwrite is true and a storage manager with the
+ specified filename already exists, it will be
+ truncated and overwritten. All data will be lost.
+PageSize VT_ULONG The page size to use. If the specified filename
+ already exists and Overwrite is false, PageSize is ignored.
+========= ======== ===========================================================
+
+For entities that are larger than the page size, multiple pages are used.
+Although, the empty space on the last page is lost. Also, there is no effort
+whatsoever to use as many sequential pages as possible. A future version
+might support sequential I/O. Thus, real clustered indices cannot be supported yet.
+
+The purpose of the .idx file is to store vital information like the page size,
+the next available page, a list of empty pages and the sequence of pages
+associated with every entity ID.
+
+This class also provides a flush method that practically overwrites the
+.idx file and syncs both file pointers.
+
+The .idx file is loaded into main memory during initialization and is
+written to disk only after flushing the storage manager or during object
+destruction. In case of an unexpected failure changes to the storage manager
+will be lost due to a stale .idx file. Avoiding such disasters is future work.
+
+SpatialIndex Interfaces
+------------------------------------------------------------------------------
+
+A spatial index is any index structure that accesses spatial information
+efficiently. It could range from a simple grid file to a complicated tree
+structure. A spatial index indexes entries of type IEntry, which can be index
+nodes, leaf nodes, data etc. depending on the structure characteristics.
+The appropriate interfaces with useful accessor methods should be provided
+for all types of entries.
+
+A spatial index should implement the ISpatialIndex interface.
+
+The containmentQuery method requires a query shape and a reference to a
+valid IVisitor instance (described shortly). The intersectionQuery method
+is the same. Both accept an IShape as the query. If the query shape is a simple
+Region, than a classic range query is performed. The user though has the
+ability to create her own shapes, thus defining her own intersection and
+containment methods making possible to run any kind of range query without
+having to modify the index. An example of a trapezoidal query is given in the
+regressiontest directory. Have in mind that it is the users responsibility
+to implement the correct intersection and containment methods between their
+shape and the type of shapes that are stored by the specific index that they
+are planning to use. For example, if an rtree index will be used, a trapezoid
+should define intersection and containment between itself and Regions, since
+all rtree nodes are of type Region. Hence, the user should have some knowledge
+about the index internal representation, to run more sophisticated queries.
+
+A point location query is performed using the pointLocationQuery method. It
+takes the query point and a visitor as arguments.
+
+Nearest neighbor queries can be performed with the nearestNeighborQuery method.
+Its first argument is the number k of nearest neighbors requested. This
+method also requires the query shape and a visitor object. The default
+implementation uses the getMinimumDistance function of IShape for calculating
+the distance of the query from the rectangular node and data entries stored
+in the tree. A more sophisticated distance measure can be used by implementing
+the INearestNeighborComparator interface and passing it as the last argument
+of nearestNeighborQuery. For example, a comparator is necessary when the query
+needs to be checked against the actual data stored in the tree, instead of
+the rectangular data entry approximations stored in the leaves.
+
+For customizing queries the IVisitor interface (based on the Visitor
+pattern [gamma94]) provides callback functions for visiting index and
+leaf nodes, as well as data entries. Node and data information can be obtained
+using the INode and IData interfaces (both extend IEntry). Examples of using
+this interface include visualizing a query, counting the number of leaf
+or index nodes visited for a specific query, throwing alerts when a
+specific spatial region is accessed, etc.
+
+The queryStrategy method provides the ability to design more sophisticated
+queries. It uses the IQueryStrategy interface as a callback that is called
+continuously until no more entries are requested. It can be used to
+implement custom query algorithms (based on the strategy pattern [gamma94]).
+
+A data entry can be inserted using the insertData method. The insertion
+function will convert any shape into an internal representation depending on
+the index. Every inserted object should be assigned an ID (called object
+identifier) that will allow updating, deleting and reporting the object.
+It is the responsibility of the caller to provide the index with IDs
+(unique or not). Also, a byte array can be associated with an entry. The
+byte arrays are stored along with the spatial information inside the leaf
+nodes. Clustered indices can be supported in that way. The byte array can
+also by null (in which case the length field should be zero), and no extra
+space should be used per node.
+
+A data entry can be deleted using the deleteData method. The object shape
+and ID should be provided. Spatial indices cluster objects according to
+spatial characteristics and not IDs. Hence, the shape is essential for
+locating and deleting an entry.
+
+Useful statistics are provided through the IStatistics interface and
+the getStatistics method.
+
+Method getIndexProperties returns a PropertySet with all useful index
+properties like dimensionality etc.
+
+A NodeCommand interface is provided for customizing Node operations. Using
+the addWriteNodeCommand, addReadNodeCommand and addDeleteNodeCommand methods,
+custom command objects are added in listener lists and get executed after
+the corresponding operations.
+
+The isIndexValid method performs internal checks for testing the
+integrity of a structure. It is used for debugging purposes.
+
+When a new index is created a unique index ID should be assigned to it, that
+will be used when reloading the index from persistent storage. This index ID
+should be returned as an IndexIdentifier property in the instance of the
+PropsertySet that was used for constructing the index instance. Using
+index IDs, multiple indices can be stored in the same storage manager.
+It is the users responsibility to manager the index IDs. Associating the
+wrong index ID with the wrong storage manager or index type has undefined
+results.
+
+The RTree Package
+------------------------------------------------------------------------------
+
+The RTree index [guttman84] is a balanced tree structure that consists of
+index nodes, leaf nodes and data. Every node (leaf and index) has a fixed
+capacity of entries, (the node capacity) chosen at index creation An RTree
+abstracts the data with their Minimum Bounding Region (MBR) and clusters
+these MBRs according to various heuristics in the leaf nodes. Queries are
+evaluated from the root of the tree down the leaves. Since the index is
+balanced nodes can be under full. They cannot be empty though. A fill
+factor specifies the minimum number of entries allowed in any node. The
+fill factor is usually close to 70%.
+
+RTree creation involves:
+
+ 1. Deciding if the index will be internal or external memory and selecting
+ the appropriate storage manager.
+ 2. Choosing the index and leaf capacity (also known as fan-out).
+ 3. Choosing the fill factor (from 1% to 99% of the node capacity).
+ 4. Choosing the dimensionality of the data.
+ 5. Choosing the insert/update policy (the RTree variant).
+
+If an already stored RTree is being reloaded for reuse, only the index ID
+needs to be supplied during construction. In that case, some options cannot
+be modified. These include: the index and leaf capacity, the fill factor and
+the dimensionality. Note here, that the RTree variant can actually be
+modified. The variant affects only when and how splitting occurs, and
+thus can be changed at any time.
+
+An initialization PropertySet is used for setting the above options,
+complying with the following property strings:
+
+========================== =========== ============================================================
+Property Type Description
+========================== =========== ============================================================
+IndexIndentifier VT_LONG If specified an existing index will be
+ opened from the supplied storage manager with
+ the given index id. Behavior is unspecified
+ if the index id or the storage manager are incorrect.
+Dimension VT_ULONG Dimensionality of the data that will be inserted.
+IndexCapacity VT_ULONG The index node capacity. Default is 100.
+LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+FillFactor VT_DOUBLE The fill factor. Default is 70%
+TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+NearMinimumOverlapFactor VT_ULONG Default is 32.
+SplitDistributionFactor VT_DOUBLE Default is 0.4
+ReinsertFactor VT_DOUBLE Default is 0.3
+EnsureTightMBRs VT_BOOL Default is true
+IndexPoolCapacity VT_LONG Default is 100
+LeafPoolCapacity VT_LONG Default is 100
+RegionPoolCapacity VT_LONG Default is 1000
+PointPoolCapacity VT_LONG Default is 500
+========================== =========== ============================================================
+
+Performance
+------------------------------------------------------------------------------
+
+Dataset size, data density, etc. have nothing to do with capacity and page
+size. What you are trying to achieve is fast reads from the disk and take
+advantage of disk buffering and prefetching.
+
+Normally, you select the page size to be equal to the disk page size (depends
+on how you format the drive). Then you choose the node capacity to be enough
+to fill the whole page (including data entries if you have any).
+
+There is a tradeoff though in making node capacity too large. The larger the
+capacity, the longer the "for loops" for inserting, deleting, locating node
+entries take (CPU time). On the other hand, the larger the capacity the
+shorter the tree becomes, reducing the number of random IOs to reach the
+leaves. Hence, you might want to fit multiple nodes (of smaller capacity)
+inside a single page to balance I/O and CPU cost, in case your disk page size
+is too large.
+
+Finally, if you have enough buffer space to fit most of the index nodes in
+main memory, then large capacities do not make too much sense, because the
+height of the tree does not matter any more. Of course, the smaller the
+capacity, the larger the number of leaf nodes you will have to retrieve from
+disk for range queries (point queries and nearest neighbor queries will not
+suffer that much). So very small capacities hurt as well.
+
+There is another issue when trying to fit multiple nodes per page: Leftover
+space. You might have leftover space due to data entries that do not have a
+fixed size. Unfortunately, in that case, leftover space per page is lost,
+negatively impacting space usage.
+
+Selecting the right page size is easy; make it equal to the disk page size.
+Selecting the right node capacity is an art...
+
+------------------------------------------------------------------------------
+Contact Information
+------------------------------------------------------------------------------
+
+You can contact me at mhadji@gmail.com for further assistance. Please read the
+above information carefully and also do not be afraid to browse through the
+code and especially the test files inside regressiontest directory.
+
+------------------------------------------------------------------------------
+References
+------------------------------------------------------------------------------
+[guttman84] "R-Trees: A Dynamic Index Structure for Spatial Searching"
+ Antonin Guttman, Proc. 1984 ACM-SIGMOD Conference on Management of Data (1985), 47-57.
+[gamma94] "Design Patterns: Elements of Reusable Object-Oriented Software"
+ Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison Wesley. October 1994.
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/autogen.sh.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/autogen.sh.svn-base
new file mode 100644
index 000000000..0c5823b7f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/autogen.sh.svn-base
@@ -0,0 +1,42 @@
+#!/bin/sh
+# $Id: autogen.sh 61 2007-12-11 20:13:48Z hobu $
+#
+# Autotools boostrapping script
+#
+giveup()
+{
+ echo
+ echo " Something went wrong, giving up!"
+ echo
+ exit 1
+}
+
+OSTYPE=`uname -s`
+
+for libtoolize in glibtoolize libtoolize; do
+ LIBTOOLIZE=`which $libtoolize 2>/dev/null`
+ if test "$LIBTOOLIZE"; then
+ break;
+ fi
+done
+
+#AMFLAGS="--add-missing --copy --force-missing"
+AMFLAGS="--add-missing --copy"
+if test "$OSTYPE" = "IRIX" -o "$OSTYPE" = "IRIX64"; then
+ AMFLAGS=$AMFLAGS" --include-deps";
+fi
+
+echo "Running aclocal"
+aclocal || giveup
+#echo "Running autoheader"
+#autoheader || giveup
+echo "Running libtoolize"
+$LIBTOOLIZE --force --copy || giveup
+echo "Running automake"
+automake $AMFLAGS # || giveup
+echo "Running autoconf"
+autoconf || giveup
+
+echo "======================================"
+echo "Now you are ready to run './configure'"
+echo "======================================"
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/configure.ac.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/configure.ac.svn-base
new file mode 100644
index 000000000..dcf4e1cd1
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/configure.ac.svn-base
@@ -0,0 +1,71 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+
+m4_define([sidx_version_major], [1])
+m4_define([sidx_version_minor], [6])
+m4_define([sidx_version_micro], [1])
+m4_define([sidx_version],
+ [sidx_version_major.sidx_version_minor.sidx_version_micro])
+
+AC_INIT([spatialindex], [sidx_version], [mhadji@gmail.com], [spatialindex-src])
+AC_CANONICAL_BUILD
+
+debug_default="no"
+CXXFLAGS="$CXXFLAGS"
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CXXCPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects])
+
+# Checks for header files.
+AC_CHECK_HEADERS(fcntl.h,, [AC_MSG_ERROR([cannot find fcntl.h, bailing out])])
+AC_CHECK_HEADERS(unistd.h,, [AC_MSG_ERROR([cannot find unistd.h, bailing out])])
+AC_CHECK_HEADERS(sys/types.h,, [AC_MSG_ERROR([cannot find sys/types.h, bailing out])])
+AC_CHECK_HEADERS(sys/stat.h,, [AC_MSG_ERROR([cannot find sys/stat.h, bailing out])])
+AC_CHECK_HEADERS(pthread.h, [LIBS="$LIBS -lpthread"])
+AC_CHECK_HEADERS(sys/resource.h,, [AC_MSG_ERROR([cannot find sys/resource.h, bailing out])])
+AC_CHECK_HEADERS(sys/time.h,, [AC_MSG_ERROR([cannot find sys/time.h, bailing out])])
+AC_CHECK_HEADERS(stdint.h,, [AC_MSG_ERROR([cannot find stdint.h, bailing out])])
+#MH_CXX_HEADER_TOOLS
+
+LIBS="$LIBS"
+
+AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging [default=$debug_default]],, enable_debug=$debug_default)
+
+if test "x$enable_debug" = "xyes"; then
+ CXXFLAGS="$CXXFLAGS -g -DDEBUG"
+ AC_MSG_RESULT(checking wether debug information is enabled... yes)
+else
+ CXXFLAGS="$CXXFLAGS -O2 -DNDEBUG"
+ AC_MSG_RESULT(checking wether debug information is enabled... no)
+fi
+
+# Checks for library functions.
+AC_CHECK_FUNCS([gettimeofday bzero memset memcpy bcopy])
+
+AC_CONFIG_FILES([ Makefile
+ include/Makefile
+ include/capi/Makefile
+ include/tools/Makefile
+ src/Makefile
+ src/capi/Makefile
+ src/spatialindex/Makefile
+ src/storagemanager/Makefile
+ src/rtree/Makefile
+ src/mvrtree/Makefile
+ src/tprtree/Makefile
+ src/tools/Makefile
+ regressiontest/Makefile
+ regressiontest/rtree/Makefile
+ regressiontest/mvrtree/Makefile
+ regressiontest/tprtree/Makefile])
+
+AC_OUTPUT
+
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/depcomp.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/depcomp.svn-base
new file mode 100644
index 000000000..11e2d3bfe
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/depcomp.svn-base
@@ -0,0 +1,522 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2004-05-31.23
+
+# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit 0
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit 0
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # Dependencies are output in .lo.d with libtool 1.4.
+ # With libtool 1.5 they are output both in $dir.libs/$base.o.d
+ # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the
+ # latter, because the former will be cleaned when $dir.libs is
+ # erased.
+ tmpdepfile1="$dir.libs/$base.lo.d"
+ tmpdepfile2="$dir$base.o.d"
+ tmpdepfile3="$dir.libs/$base.d"
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1="$dir$base.o.d"
+ tmpdepfile2="$dir$base.d"
+ tmpdepfile3="$dir$base.d"
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ elif test -f "$tmpdepfile2"; then
+ tmpdepfile="$tmpdepfile2"
+ else
+ tmpdepfile="$tmpdepfile3"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/install-sh.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/install-sh.svn-base
new file mode 100644
index 000000000..dd97db7aa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/install-sh.svn-base
@@ -0,0 +1,322 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2004-09-10.20
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c (ignored)
+-d create directories instead of installing files.
+-g GROUP $chgrpprog installed files to GROUP.
+-m MODE $chmodprog installed files to MODE.
+-o USER $chownprog installed files to USER.
+-s $stripprog installed files.
+-t DIRECTORY install into DIRECTORY.
+-T report an error if DSTFILE is a directory.
+--help display this help and exit.
+--version display version info and exit.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+ case $1 in
+ -c) shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ --help) echo "$usage"; exit 0;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t) dstarg=$2
+ shift
+ shift
+ continue;;
+
+ -T) no_target_directory=true
+ shift
+ continue;;
+
+ --version) echo "$0 $scriptversion"; exit 0;;
+
+ *) # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ test -n "$dir_arg$dstarg" && break
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dstarg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dstarg"
+ shift # fnord
+ fi
+ shift # arg
+ dstarg=$arg
+ done
+ break;;
+ esac
+done
+
+if test -z "$1"; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src ;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ src=
+
+ if test -d "$dst"; then
+ mkdircmd=:
+ chmodcmd=
+ else
+ mkdircmd=$mkdirprog
+ fi
+ else
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dstarg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dstarg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst ;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dstarg: Is a directory" >&2
+ exit 1
+ fi
+ dst=$dst/`basename "$src"`
+ fi
+ fi
+
+ # This sed command emulates the dirname command.
+ dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+ # Make sure that the destination directory exists.
+
+ # Skip lots of stat calls in the usual case.
+ if test ! -d "$dstdir"; then
+ defaultIFS='
+ '
+ IFS="${IFS-$defaultIFS}"
+
+ oIFS=$IFS
+ # Some sh's can't handle IFS=/ for some reason.
+ IFS='%'
+ set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+ IFS=$oIFS
+
+ pathcomp=
+
+ while test $# -ne 0 ; do
+ pathcomp=$pathcomp$1
+ shift
+ if test ! -d "$pathcomp"; then
+ $mkdirprog "$pathcomp"
+ # mkdir can fail with a `File exist' error in case several
+ # install-sh are creating the directory concurrently. This
+ # is OK.
+ test -d "$pathcomp" || exit
+ fi
+ pathcomp=$pathcomp/
+ done
+ fi
+
+ if test -n "$dir_arg"; then
+ $doit $mkdircmd "$dst" \
+ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+ else
+ dstfile=`basename "$dst"`
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Copy the file name to the temp name.
+ $doit $cpprog "$src" "$dsttmp" &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+ # Now rename the file to the real destination.
+ { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+ || {
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ if test -f "$dstdir/$dstfile"; then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+ || {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit
+ }
+ else
+ :
+ fi
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+ }
+ }
+ fi || { (exit 1); exit; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+ (exit 0); exit
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/makefile.vc.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/makefile.vc.svn-base
new file mode 100644
index 000000000..6d018a383
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/makefile.vc.svn-base
@@ -0,0 +1,217 @@
+
+.SUFFIXES: .cc
+
+SPATIALINDEX_HOME=c:\cvs\buildkit\spatialindex
+DLL_VERSION = 1
+
+BINDIR=$(SPATIALINDEX_HOME)\bin
+OSGEO4W_DIR = $(SPATIALINDEX_HOME)\osgeo4w
+
+
+###############################################################################
+# Set BUILD_DEBUG balue to YES if you want to make debug build
+# and to prepare not optimized binaries.
+!IFNDEF BUILD_DEBUG
+BUILD_DEBUG = NO
+!ENDIF
+
+
+###############################################################################
+# Derive version of Visual C++ being used from NMAKE if not specified
+#
+# WARNING:
+# If we should expect variety of NMAKE build versions, tests below may fail
+# and we will need to fall back to setting MSVCVER as command line parameter.
+#
+!IF "$(_NMAKE_VER)" == ""
+MSVCVER = 4.0
+!ERROR *** Failed to determine version of Visual C++
+!ELSEIF "$(_NMAKE_VER)" == "162"
+MSVCVER = 5.0
+!ERROR *** Detected Visual C++ 5.0 - NOT SUPPORTED
+!ELSEIF "$(_NMAKE_VER)" == "6.00.8168.0"
+MSVCVER = 6.0
+!ERROR *** Detected Visual C++ 6.0 - NOT SUPPORTED
+!ELSEIF "$(_NMAKE_VER)" == "7.00.9466"
+MSVCVER = 7.0
+!ELSEIF "$(_NMAKE_VER)" == "7.10.3077"
+MSVCVER = 7.1
+!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.42"
+MSVCVER = 8.0
+!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.762"
+MSVCVER = 8.0
+!ELSEIF "$(_NMAKE_VER)" == "9.00.21022.08"
+MSVCVER = 9.0
+!ELSEIF "$(_NMAKE_VER)" == "9.00.30729.01"
+MSVCVER = 9.0
+!ELSE
+MSVCVER = 0.0
+!ENDIF
+
+!IF "$(MSVCVER)" == "0.0"
+!MESSAGE *** Cannot determined Visual C++ version
+!ERROR *** Aborting make job
+!ELSE
+!MESSAGE *** Using Microsoft NMAKE version $(_NMAKE_VER)
+!MESSAGE *** Using Microsoft Visual C++ version $(MSVCVER)
+!ENDIF
+
+###############################################################################
+# Compilation flags for Release and Debug modes
+
+!IF "$(BUILD_DEBUG)" == "YES"
+OPTFLAGS=/nologo /MDd /EHsc /Z7 /W4 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /DDEBUG /D_DEBUG /DDEBUG /Fd$(SPATIALINDEX_HOME)\spatialindex.pdb
+LAS_LIB = spatialindex_d.lib
+LAS_DLL = spatialindex_d$(DLL_VERSION).dll
+LAS_LIB_DLL = spatialindex_i.lib
+!ELSE
+
+# You may need to remove /GR if you are statically linking libLAS
+OPTFLAGS=/nologo /MD /EHsc /Ox /GR /W2 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /DNDEBUG /D "PACKAGE_BUGREPORT=\"hobu.inc@gmail.com\"" /DSPATIALINDEX_CREATE_DLL=1
+LAS_LIB = spatialindex.lib
+LAS_DLL = spatialindex$(DLL_VERSION).dll
+CDLLNAME = spatialindex$(DLL_VERSION)_c.dll
+CLIBNAME = spatialindex_c_i.lib
+LAS_LIB_DLL = spatialindex_i.lib
+!ENDIF
+
+# Check if multiple process build available
+!IF "$(MSVCVER)" == "9.0"
+MPFLAGS=/MP
+!MESSAGE *** Using /MP flag with number of effective processors
+!ELSE
+MPFLAGS=
+!ENDIF
+
+PACKAGE_VERSION=1.6.1
+
+INCLUDES=-I$(SPATIALINDEX_HOME)/include -I$(SPATIALINDEX_HOME)/include/capi
+CFLAGS= $(MPFLAGS) $(OPTFLAGS) $(INCLUDES)
+
+
+# Commands
+#
+MAKE = nmake
+RM = -del
+CC= cl
+LINK= link
+
+LAS_DIRLIST = src\mvrtree \
+ src\rtree \
+ src\spatialindex \
+ src\storagemanager \
+ src\tools \
+ src\tprtree \
+ src\capi
+
+OBJS = src\mvrtree\Index.obj \
+ src\mvrtree\Leaf.obj \
+ src\mvrtree\MVRtree.obj \
+ src\mvrtree\Node.obj \
+ src\mvrtree\Statistics.obj \
+ src\rtree\BulkLoader.obj \
+ src\rtree\Index.obj \
+ src\rtree\Leaf.obj \
+ src\rtree\Node.obj \
+ src\rtree\RTree.obj \
+ src\rtree\Statistics.obj \
+ src\spatialindex\LineSegment.obj \
+ src\spatialindex\MovingPoint.obj \
+ src\spatialindex\MovingRegion.obj \
+ src\spatialindex\Point.obj \
+ src\spatialindex\Region.obj \
+ src\spatialindex\SpatialIndexImpl.obj \
+ src\spatialindex\TimePoint.obj \
+ src\spatialindex\TimeRegion.obj \
+ src\storagemanager\Buffer.obj \
+ src\storagemanager\DiskStorageManager.obj \
+ src\storagemanager\MemoryStorageManager.obj \
+ src\storagemanager\RandomEvictionsBuffer.obj \
+ src\tools\rand48.obj \
+ src\tools\Tools.obj \
+ src\tprtree\Index.obj \
+ src\tprtree\Leaf.obj \
+ src\tprtree\Node.obj \
+ src\tprtree\Statistics.obj \
+ src\tprtree\TPRTree.obj
+
+COBJS = src\capi\BoundsQuery.obj \
+ src\capi\CountVisitor.obj \
+ src\capi\CustomStorage.obj \
+ src\capi\DataStream.obj \
+ src\capi\Error.obj \
+ src\capi\IdVisitor.obj \
+ src\capi\Index.obj \
+ src\capi\LeafQuery.obj \
+ src\capi\ObjVisitor.obj \
+ src\capi\sidx_api.obj\
+ src\capi\Utility.obj
+
+default: $(LAS_DLL) $(CDLLNAME)
+
+all: default
+
+
+$(LAS_LIB): $(OBJS)
+ if exist $(LAS_LIB) del $(LAS_LIB)
+ $(LINK) /lib /nologo /out:$(LAS_LIB) $(OBJS)
+
+$(LAS_DLL): $(LAS_LIB) $(RES)
+ $(LINK) /dll \
+ $(OBJS) $(LAS_LIB) \
+ /out:$(LAS_DLL) /implib:$(LAS_LIB_DLL)
+ if exist $(LAS_DLL).manifest mt -manifest $(LAS_DLL).manifest -outputresource:$(LAS_DLL);2
+
+$(CDLLNAME): $(COBJS) $(LAS_DLL)
+ $(LINK) /dll /debug $(COBJS) $(LAS_LIB_DLL) /out:$(CDLLNAME) /implib:$(CLIBNAME)
+ if exist $(CDLLNAME).manifest mt -manifest $(CDLLNAME).manifest -outputresource:$(CDLLNAME);2
+
+
+install: default
+ -mkdir $(BINDIR)
+ -mkdir $(SPATIALINDEX_HOME)\packages
+ -mkdir $(BINDIR)\lib
+ -mkdir $(BINDIR)\include\spatialindex
+ -mkdir $(OSGEO4W_DIR)
+ -mkdir $(OSGEO4W_DIR)\lib
+ -mkdir $(OSGEO4W_DIR)\devel
+ -mkdir $(OSGEO4W_DIR)\lib\bin
+ -mkdir $(OSGEO4W_DIR)\devel\include
+ -mkdir $(OSGEO4W_DIR)\devel\include\spatialindex
+ -mkdir $(OSGEO4W_DIR)\devel\lib
+ xcopy /y /r /d /f spatialindex_i.lib $(BINDIR)\lib
+ xcopy /y /r /d /f spatialindex_i.lib $(OSGEO4W_DIR)\devel\lib
+ xcopy /y /r /d /f spatialindex.lib $(BINDIR)\lib
+ xcopy /y /r /d /f spatialindex.lib $(OSGEO4W_DIR)\devel\lib
+ xcopy /y /r /d /f /s include\* $(BINDIR)\include\spatialindex
+ xcopy /y /r /d /f /s include\* $(OSGEO4W_DIR)\devel\include\spatialindex
+ xcopy /y /r /d /f $(LAS_DLL) $(BINDIR)
+ xcopy /y /r /d /f $(LAS_DLL) $(OSGEO4W_DIR)\lib\bin
+
+.cc.obj:
+ $(CC) $(CFLAGS) /c $*.cc /Fo$@
+
+.c.obj:
+ $(CC) $(CFLAGS) /c $*.c /Fo$@
+
+clean:
+ $(RM) $(LAS_LIB)
+ $(RM) $(LAS_DLL)
+ $(RM) *.ilk
+ $(RM) *.manifest
+ $(RM) *.obj
+ $(RM) *.pdb
+ for %d in ( $(LAS_DIRLIST) ) do \
+ del %d\*.obj
+
+package: install
+ cd $(SPATIALINDEX_HOME)/osgeo4w/lib
+ C:\cygwin\bin\tar.exe cvf ../../packages/libspatialindex-$(PACKAGE_VERSION).tar *
+ c:\cygwin\bin\bzip2.exe -f /cygdrive/c/cvs/buildkit/spatialindex/packages/libspatialindex-$(PACKAGE_VERSION).tar
+ cd $(SPATIALINDEX_HOME)/osgeo4w/
+ cd $(SPATIALINDEX_HOME)/osgeo4w/devel
+ C:\cygwin\bin\tar.exe cvf ../../packages/libspatialindex-devel-$(PACKAGE_VERSION).tar *
+ c:\cygwin\bin\bzip2.exe -f /cygdrive/c/cvs/buildkit/spatialindex/packages/libspatialindex-devel-$(PACKAGE_VERSION).tar
+ cd $(SPATIALINDEX_HOME)/osgeo4w/
+ cd $(SPATIALINDEX_HOME)/
+ c:\cygwin\bin\zip.exe -r packages/libspatialindex-$(PACKAGE_VERSION)-win32.zip bin
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/missing.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/missing.svn-base
new file mode 100644
index 000000000..64b5f901d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/missing.svn-base
@@ -0,0 +1,353 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2004-09-07.08
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit 0
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit 0
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+ lex|yacc)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/mkinstalldirs.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/mkinstalldirs.svn-base
new file mode 100644
index 000000000..6fbe5e117
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/mkinstalldirs.svn-base
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2004-02-15.20
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit 0
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.sln.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.sln.svn-base
new file mode 100644
index 000000000..c0f1d6048
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.sln.svn-base
@@ -0,0 +1,91 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spatialindex-vc", "spatialindex-vc\spatialindex.vcproj", "{38FBBD59-8344-4D8E-B728-3D51763B6A70}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeBulkLoad", "regressiontest\rtree\RTreeBulkLoad.vcproj", "{7D9C8655-0155-4EE3-B04C-6D831E2982CE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeGenerator", "regressiontest\rtree\RTreeGenerator.vcproj", "{03504DB7-ACF3-40CF-A8A7-310E80666DC0}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeLoad", "regressiontest\rtree\RTreeLoad.vcproj", "{551D683C-E5DC-4713-9D9F-F629D15BE5DA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeQuery", "regressiontest\rtree\RTreeQuery.vcproj", "{1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeExhaustive", "regressiontest\rtree\RTreeExhaustive.vcproj", "{D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|Win32.ActiveCfg = Debug|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|Win32.Build.0 = Debug|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|x64.ActiveCfg = Debug|x64
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|x64.Build.0 = Debug|x64
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|Win32.ActiveCfg = Release|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|Win32.Build.0 = Release|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|x64.ActiveCfg = Release|x64
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|x64.Build.0 = Release|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|x64.Build.0 = Debug|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|Win32.Build.0 = Release|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|x64.ActiveCfg = Release|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|x64.Build.0 = Release|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|Win32.Build.0 = Debug|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|x64.ActiveCfg = Debug|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|x64.Build.0 = Debug|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|Win32.ActiveCfg = Release|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|Win32.Build.0 = Release|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|x64.ActiveCfg = Release|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|x64.Build.0 = Release|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|Win32.Build.0 = Debug|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|x64.ActiveCfg = Debug|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|x64.Build.0 = Debug|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|Win32.ActiveCfg = Release|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|Win32.Build.0 = Release|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|x64.ActiveCfg = Release|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|x64.Build.0 = Release|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|Win32.Build.0 = Debug|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|x64.ActiveCfg = Debug|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|x64.Build.0 = Debug|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|Win32.ActiveCfg = Release|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|Win32.Build.0 = Release|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|x64.ActiveCfg = Release|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|x64.Build.0 = Release|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|Win32.Build.0 = Debug|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|x64.ActiveCfg = Debug|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|x64.Build.0 = Debug|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|Win32.ActiveCfg = Release|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|Win32.Build.0 = Release|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|x64.ActiveCfg = Release|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.suo.svn-base b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.suo.svn-base
new file mode 100644
index 000000000..040272d1d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/.svn/text-base/spatialindex.suo.svn-base
Binary files differ
diff --git a/sci-libs/libspatialindex/svn/trunk/AUTHORS b/sci-libs/libspatialindex/svn/trunk/AUTHORS
new file mode 100644
index 000000000..c68fc7c6f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/AUTHORS
@@ -0,0 +1,5 @@
+Marios Hadjieleftheriou -- Main author
+mhadji@gmail.com
+
+Howard Butler -- minor packaging, Trac/SVN stuff, and some Windows work
+hobu.inc@gmail.com \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/COPYING b/sci-libs/libspatialindex/svn/trunk/COPYING
new file mode 100644
index 000000000..5ab7695ab
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/sci-libs/libspatialindex/svn/trunk/ChangeLog b/sci-libs/libspatialindex/svn/trunk/ChangeLog
new file mode 100644
index 000000000..9e1c580d6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/ChangeLog
@@ -0,0 +1,1206 @@
+2010-11-22 19:53 seang
+
+ * src/capi/sidx_api.cc: Fix test of length value
+
+2010-11-22 19:23 hobu
+
+ * src/capi/sidx_api.cc: whitespace normalization
+
+2010-11-22 19:00 seang
+
+ * src/capi/sidx_api.cc: Add up deltas for multidimensional input
+
+2010-11-22 18:49 seang
+
+ * src/capi/sidx_api.cc: Add up deltas for multidimensional input
+
+2010-11-22 18:46 hobu
+
+ * src/capi/sidx_api.cc: revert r193
+
+2010-11-22 16:02 hobu
+
+ * src/capi/sidx_api.cc: we should set isPoint to true if we pass
+ our epsilon test -- this didn't work before
+
+2010-10-14 13:18 mhadji
+
+ * include/tools/Tools.h, src/tools/Tools.cc: Removed
+ nextUnifromLongDouble. It was incorrect
+
+2010-10-13 15:10 mhadji
+
+ * include/tools/Tools.h, src/tools/Tools.cc: Added
+ nextUniformLongDouble
+
+2010-09-16 13:56 hobu
+
+ * Makefile.am: fix #25 and include visual studio files in the
+ release
+
+2010-09-16 13:53 hobu
+
+ * makefile.vc: bump versions in preparation for release
+
+2010-09-16 13:52 hobu
+
+ * configure.ac, include/Version.h: bump versions in preparation for
+ release
+
+2010-06-19 20:34 hobu
+
+ * include/capi/CustomStorage.h, include/capi/Index.h,
+ include/capi/Makefile.am, include/capi/sidx_api.h,
+ include/capi/sidx_config.h, include/capi/sidx_impl.h,
+ makefile.vc, src/capi/CustomStorage.cc, src/capi/Index.cc,
+ src/capi/Makefile.am, src/capi/Utility.cc, src/capi/sidx_api.cc:
+ add Matthias' CustomStorage backend for C API
+
+2010-04-21 18:50 hobu
+
+ * README: Add Marios' pagesize diatribe to the docs
+
+2010-04-12 19:56 hobu
+
+ * ChangeLog: update ChangeLog
+
+2010-04-12 17:17 mhadji
+
+ * regressiontest/rtree/Exhaustive.cc:
+
+2010-04-12 17:07 mhadji
+
+ * regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/test3/run, spatialindex.suo,
+ src/rtree/BulkLoader.cc: Fixed rtree/BulkLoader infinit loop bug
+
+2010-03-31 15:33 hobu
+
+ * src/capi/BoundsQuery.cc, src/capi/CountVisitor.cc,
+ src/capi/DataStream.cc, src/capi/IdVisitor.cc, src/capi/Index.cc,
+ src/capi/ObjVisitor.cc, src/capi/Utility.cc: format and layout
+ normalization
+
+2010-03-30 20:18 hobu
+
+ * src/spatialindex/MovingRegion.cc: ensure that we instantiate the
+ ivOut with at least the ivIn so we have a properly constructed
+ Tools::Interval #16
+
+2010-03-05 14:19 hobu
+
+ * ., HOWTORELEASE.txt: add doc describing how to release
+
+2010-03-05 02:56 hobu
+
+ * regressiontest/tprtree/test1, regressiontest/tprtree/test2:
+ propsets to ignore test output:
+
+2010-03-05 02:53 hobu
+
+ * configure.ac: use subdir-objects for automake and rename the make
+ dist output to spatialindex-src
+
+2010-03-05 02:52 hobu
+
+ * include/Version.h: increment version info in preparation for
+ release
+
+2010-03-05 01:59 hobu
+
+ * ChangeLog: update for release
+
+2010-03-04 16:33 hobu
+
+ * include/capi/CountVisitor.h, include/capi/Makefile.am,
+ include/capi/sidx_api.h, include/capi/sidx_impl.h, makefile.vc,
+ src/capi/CountVisitor.cc, src/capi/Makefile.am,
+ src/capi/sidx_api.cc: add CountVisitor to the CAPI to provide a
+ cumulation of the number of hits that land within a query
+
+2010-03-03 21:55 hobu
+
+ * include/capi/IdVisitor.h, include/capi/ObjVisitor.h,
+ include/capi/sidx_api.h, regressiontest/rtree/test3/run,
+ src/capi/LeafQuery.cc, src/capi/sidx_api.cc: use uint64_t for
+ result counts instead of uint32_t in C API
+
+2009-12-29 02:35 hobu
+
+ * regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/tprtree/Exhaustive.cc: fix up for gcc 4.4
+
+2009-12-04 21:57 mhadji
+
+ * spatialindex.suo, src/spatialindex/Region.cc:
+
+2009-12-04 18:46 mhadji
+
+ * src/spatialindex/Region.cc: Fixed Region::touchesRegion member
+ function bug.
+
+2009-11-05 16:26 hobu
+
+ * src/spatialindex/Region.cc: don't thrown an error when -DDEBUG is
+ on and we initialize an infinite Region
+
+2009-11-03 03:10 hobu
+
+ * src/capi/sidx_api.cc: pass in a reference for the query bounds
+
+2009-11-03 03:04 hobu
+
+ * src/capi/sidx_api.cc: try to do no harm when calling Index_Free
+ on something that's null
+
+2009-11-03 03:00 hobu
+
+ * src/capi/sidx_api.cc: pass in a reference for the query bounds
+
+2009-11-03 02:15 hobu
+
+ * src/capi/sidx_api.cc: copy the array using memcpy because we
+ can't free() something created with new
+
+2009-11-03 01:48 hobu
+
+ * src/capi/sidx_api.cc: put the data in a newly malloc'd array to
+ match our std::free call of Index_Delete
+
+2009-11-02 21:32 hobu
+
+ * src/capi/LeafQuery.cc: make sure to delete our shape when we're
+ done
+
+2009-11-02 21:32 hobu
+
+ * src/capi/sidx_api.cc: get dimension from the Region, no need to
+ fetch from index properties
+
+2009-11-02 20:53 hobu
+
+ * src/capi/sidx_api.cc: make sure we clean up the bounds and region
+
+2009-11-02 20:08 hobu
+
+ * regressiontest/mvrtree/Generator.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/tprtree/Generator.cc,
+ regressiontest/tprtree/TPRTreeLoad.cc,
+ regressiontest/tprtree/TPRTreeQuery.cc, src/capi/sidx_api.cc,
+ src/mvrtree/Index.cc, src/mvrtree/MVRTree.cc,
+ src/mvrtree/Node.cc, src/rtree/Index.cc, src/rtree/Node.cc,
+ src/rtree/RTree.cc, src/spatialindex/LineSegment.cc,
+ src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc, src/spatialindex/TimePoint.cc,
+ src/spatialindex/TimeRegion.cc, src/tools/Tools.cc,
+ src/tprtree/Index.cc, src/tprtree/Node.cc,
+ src/tprtree/TPRTree.cc: only #include <limits> where needed, and
+ not in the global Tools.h file
+
+2009-10-30 17:09 hobu
+
+ * include/tools/Tools.h, regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/mvrtree/Generator.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/tprtree/Generator.cc, src/mvrtree/Node.cc,
+ src/rtree/BulkLoader.cc, src/rtree/Node.cc, src/rtree/RTree.cc,
+ src/spatialindex/LineSegment.cc, src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc,
+ src/storagemanager/RandomEvictionsBuffer.cc, src/tprtree/Node.cc:
+ remove <cmath> <limits> and <climits> from Tools.h and include
+ them seperately in each file that needs them
+
+2009-10-30 16:37 hobu
+
+ * include/capi/sidx_api.h: define to denote we're C API
+
+2009-10-30 15:03 hobu
+
+ * include/capi/sidx_config.h: add a newline
+
+2009-10-22 02:42 hobu
+
+ * src/capi/sidx_api.cc: make sure we use new/delete instead of
+ new/free
+
+2009-10-21 17:35 hobu
+
+ * ., include/LineSegment.h, include/Point.h, include/Region.h,
+ include/SpatialIndex.h, include/capi, src/capi,
+ src/spatialindex/LineSegment.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc: remove namespace pollution of Tools::
+ into the globally include'd header SpatialIndex.h
+
+2009-10-20 15:24 hobu
+
+ * configure.ac, makefile.vc: bump versions in preparation for
+ release
+
+2009-10-19 20:31 hobu
+
+ * include/capi/sidx_api.h: add SIDX_Version prototype
+
+2009-10-19 20:23 hobu
+
+ * ltmain.sh: ltmain.sh doesn't belong in svn
+
+2009-10-19 20:23 hobu
+
+ * include/capi/Makefile.in, src/capi/Makefile.in: Makefile.in's
+ don't belong in svn
+
+2009-10-19 18:50 hobu
+
+ * makefile.vc: C API compilation fix
+
+2009-10-19 18:50 hobu
+
+ * src/tools/Tools.cc: tmpname fixes so we compile on msvc2003
+
+2009-10-19 18:29 hobu
+
+ * makefile.vc: don't define a variable to "" or cl will complain
+
+2009-10-08 19:32 hobu
+
+ * src/rtree/BulkLoader.cc: bleaf and bindex switched around in
+ createLevel call
+
+2009-09-17 20:40 hobu
+
+ * include/capi/LeafQuery.h, include/capi/sidx_api.h,
+ src/capi/LeafQuery.cc, src/capi/sidx_api.cc: more leaf querying
+ code
+
+2009-09-16 18:45 hobu
+
+ * include/capi/LeafQuery.h, include/capi/Makefile.am,
+ include/capi/Makefile.in, include/capi/sidx_impl.h,
+ src/capi/LeafQuery.cc, src/capi/Makefile.am,
+ src/capi/Makefile.in, src/capi/sidx_api.cc: add beginnings of
+ leaf querying to C API
+
+2009-09-16 03:34 hobu
+
+ * include/capi/Item.h, include/capi/ObjVisitor.h,
+ include/capi/sidx_config.h, include/capi/sidx_impl.h,
+ src/capi/Item.cc, src/capi/Makefile.am, src/capi/Makefile.in,
+ src/capi/ObjVisitor.cc, src/capi/sidx_api.cc: remove the
+ duplicate and unnecessary Item construct that was masking the
+ already existing IData interface
+
+2009-08-31 15:32 hobu
+
+ * makefile.vc: support building the c api
+
+2009-08-24 13:25 hobu
+
+ * regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/tprtree/Exhaustive.cc: fix issue with uint32_t by
+ copying macros from Tools.h
+
+2009-08-19 20:47 hobu
+
+ * Makefile.am: try to ensure -lstdc++ is linked
+
+2009-08-19 19:56 hobu
+
+ * include/capi, src/capi: ignores
+
+2009-08-19 16:37 hobu
+
+ * Makefile.am, configure.ac, include/Makefile.am, include/capi,
+ include/capi/BoundsQuery.h, include/capi/DataStream.h,
+ include/capi/Error.h, include/capi/IdVisitor.h,
+ include/capi/Index.h, include/capi/Item.h,
+ include/capi/Makefile.am, include/capi/Makefile.in,
+ include/capi/ObjVisitor.h, include/capi/Utility.h,
+ include/capi/sidx_api.h, include/capi/sidx_config.h,
+ include/capi/sidx_impl.h, include/tools/Makefile.am,
+ src/Makefile.am, src/capi, src/capi/BoundsQuery.cc,
+ src/capi/DataStream.cc, src/capi/Error.cc, src/capi/IdVisitor.cc,
+ src/capi/Index.cc, src/capi/Item.cc, src/capi/Makefile.am,
+ src/capi/Makefile.in, src/capi/ObjVisitor.cc,
+ src/capi/Utility.cc, src/capi/sidx_api.cc: add C API (not
+ currently built on windows)
+
+2009-08-19 15:25 hobu
+
+ * .: ignore propset
+
+2009-08-19 15:24 hobu
+
+ * regressiontest/mvrtree/test1, regressiontest/mvrtree/test2,
+ regressiontest/rtree, regressiontest/rtree/test1,
+ regressiontest/rtree/test2, regressiontest/rtree/test3,
+ regressiontest/rtree/test4, regressiontest/tprtree/test1,
+ regressiontest/tprtree/test2: propsets to ignore test results
+
+2009-08-18 18:07 hobu
+
+ * include/tools/Tools.h, src/tools/Tools.cc: locking for
+ Tools::PropertySet (commented out though because it doesn't work
+
+2009-08-14 17:41 hobu
+
+ * src/tools/Tools.cc: comment out PropertySet locking for now
+
+2009-08-14 15:19 hobu
+
+ * include/tools/Tools.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/rtree/RTree.cc, src/rtree/RTree.h,
+ src/tools/Tools.cc, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h: use HAVE_PTHREAD_H for #ifdef, make
+ Tools::PropertySet threadsafe for read/write
+
+2009-08-13 19:10 mhadji
+
+ * spatialindex.suo, src/rtree/BulkLoader.cc,
+ src/rtree/BulkLoader.h, src/rtree/RTree.cc:
+
+2009-08-13 15:42 mhadji
+
+ * spatialindex-vc/spatialindex.vcproj, spatialindex.suo:
+
+2009-08-13 15:24 mhadji
+
+ * include/LineSegment.h, include/MVRTree.h, include/MovingPoint.h,
+ include/MovingRegion.h, include/Point.h, include/RTree.h,
+ include/Region.h, include/SpatialIndex.h, include/TPRTree.h,
+ include/TimePoint.h, include/TimeRegion.h,
+ include/tools/PointerPool.h, include/tools/Tools.h,
+ regressiontest/rtree/RTreeBulkLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc,
+ regressiontest/rtree/test1/run, regressiontest/rtree/test2/run,
+ spatialindex.suo, src/mvrtree/Index.cc, src/mvrtree/Index.h,
+ src/mvrtree/Leaf.cc, src/mvrtree/Leaf.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/mvrtree/PointerPoolNode.h, src/mvrtree/Statistics.cc,
+ src/mvrtree/Statistics.h, src/rtree/BulkLoader.cc,
+ src/rtree/BulkLoader.h, src/rtree/Index.cc, src/rtree/Index.h,
+ src/rtree/Leaf.cc, src/rtree/Leaf.h, src/rtree/Node.cc,
+ src/rtree/Node.h, src/rtree/PointerPoolNode.h,
+ src/rtree/RTree.cc, src/rtree/RTree.h, src/rtree/Statistics.cc,
+ src/rtree/Statistics.h, src/spatialindex/LineSegment.cc,
+ src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc, src/spatialindex/TimePoint.cc,
+ src/spatialindex/TimeRegion.cc, src/storagemanager/Buffer.cc,
+ src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h,
+ src/storagemanager/RandomEvictionsBuffer.cc, src/tools/Tools.cc,
+ src/tprtree/Index.cc, src/tprtree/Index.h, src/tprtree/Leaf.cc,
+ src/tprtree/Leaf.h, src/tprtree/Node.cc, src/tprtree/Node.h,
+ src/tprtree/PointerPoolNode.h, src/tprtree/Statistics.cc,
+ src/tprtree/Statistics.h, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h: 1. Replace size_t with uint32_t to fix
+ 64/32 bit compatibility issues
+ 2. Fixed memory bug related to data array and bulk loading for
+ RTree.
+
+2009-08-10 13:35 hobu
+
+ * include/SpatialIndex.h, include/tools/Tools.h: remove #define
+ interface, use class
+
+2009-08-06 01:11 hobu
+
+ * makefile.vc: osgeo4w packaging
+
+2009-08-05 20:21 hobu
+
+ * include/tools/Tools.h: don't redefine interface if it is already
+ defined (/me scowls at windows
+
+2009-08-05 19:27 hobu
+
+ * src/rtree/BulkLoader.cc: comment out record deletion entirely
+
+2009-08-05 17:58 hobu
+
+ * src/rtree/BulkLoader.cc: guard against invalid delete
+
+2009-07-30 18:48 hobu
+
+ * Makefile.am, configure.ac: bump version to 1.4.0 in prep for
+ release, add a windows docs to the dist
+
+2009-07-30 16:57 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: Add a
+ CheckFilesExists(Tools::PropertySet&) method instead of the cheap
+ way we were checking for existence before. This takes into
+ account the file extensions and only returns true if both files
+ exist
+
+2009-07-30 16:56 hobu
+
+ * include/tools/Tools.h: move the warning about 4251 down into
+ _MSC_VER
+
+2009-07-30 03:10 hobu
+
+ * ChangeLog, configure.ac: new changelog
+
+2009-07-30 02:32 hobu
+
+ * makefile.vc: update for new layout. make sure to build dll
+ appropriately
+
+2009-07-29 21:24 hobu
+
+ * include/tools/Tools.h: turn off warning 4251
+
+2009-07-29 20:57 hobu
+
+ * include/Makefile.am, include/SpatialIndex.h, include/Version.h:
+ fix #15 and provide a way to determine the library version at
+ compile time
+
+2009-07-29 20:50 hobu
+
+ * makefile.vc: add back makefile.vc
+
+2009-07-22 19:29 hobu
+
+ * src/spatialindex/Region.cc: a note about the debugging lint that
+ is incorrect when the bounds are infinity
+
+2009-07-22 19:24 hobu
+
+ * regressiontest/rtree/Exhaustive.cc: make sure to #include
+ <cstring> to satisfy gcc 4.3+
+
+2009-07-22 15:23 mhadji
+
+ * regressiontest/rtree/RTreeBulkLoad.vcproj,
+ regressiontest/rtree/RTreeExhaustive.vcproj,
+ regressiontest/rtree/RTreeGenerator.vcproj,
+ regressiontest/rtree/RTreeLoad.vcproj,
+ regressiontest/rtree/RTreeQuery.vcproj,
+ spatialindex-vc/spatialindex.vcproj, spatialindex.suo:
+
+2009-07-22 15:18 mhadji
+
+ * spatialindex.sln, spatialindex.suo:
+
+2009-07-21 13:11 mhadji
+
+ * src/tools/Tools.cc:
+
+2009-07-20 20:32 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: attempt to fix #8 and
+ allow users to specify extensions for the dat and idx files of
+ the diskstorage manager
+
+2009-07-20 17:35 hobu
+
+ * src/tools/Tools.cc: make sure to update existing values in
+ setProperties instead of assuming it doesn't exist in the map
+
+2009-07-20 15:01 mhadji
+
+ * spatialindex.suo, src/mvrtree/MVRTree.cc, src/rtree/RTree.cc,
+ src/tprtree/TPRTree.cc:
+
+2009-07-19 14:51 mhadji
+
+ * include/LineSegment.h, include/MVRTree.h, include/MovingPoint.h,
+ include/MovingRegion.h, include/Point.h, include/RTree.h,
+ include/Region.h, include/SpatialIndex.h, include/TPRTree.h,
+ include/TimePoint.h, include/TimeRegion.h, include/tools/Tools.h,
+ spatialindex.suo:
+
+2009-07-19 01:26 mhadji
+
+ * INSTALL.WIN:
+
+2009-07-19 01:15 mhadji
+
+ * spatialindex-vc/spatialindex.vcproj, spatialindex.suo:
+
+2009-07-19 01:13 mhadji
+
+ * spatialindex.suo:
+
+2009-07-19 01:09 mhadji
+
+ * makefile.vc, regressiontest/rtree/RTreeBulkLoad.vcproj,
+ spatialindex.suo:
+
+2009-07-19 01:02 mhadji
+
+ * INSTALL.WIN, regressiontest/rtree/RTreeBulkLoad.vcproj,
+ regressiontest/rtree/RTreeExhaustive.vcproj,
+ regressiontest/rtree/RTreeGenerator.vcproj,
+ regressiontest/rtree/RTreeLoad.vcproj,
+ regressiontest/rtree/RTreeQuery.vcproj,
+ regressiontest/rtree/test3/run,
+ spatialindex-vc/spatialindex.vcproj, spatialindex.sln,
+ spatialindex.suo:
+
+2009-07-18 22:52 mhadji
+
+ * include/SpatialIndex.h, include/tools/Tools.h:
+
+2009-07-18 22:19 mhadji
+
+ * spatialindex-vc/spatialindex.vcproj.RESEARCH.marioh.user:
+
+2009-07-18 22:19 mhadji
+
+ * include/LineSegment.h, include/MVRTree.h, include/MovingPoint.h,
+ include/MovingRegion.h, include/Point.h, include/RTree.h,
+ include/Region.h, include/SpatialIndex.h, include/TPRTree.h,
+ include/TimePoint.h, include/TimeRegion.h,
+ include/tools/Makefile.am, include/tools/PointerPool.h,
+ include/tools/PoolPointer.h, include/tools/SmartPointer.h,
+ include/tools/TemporaryFile.h, include/tools/Tools.h,
+ include/tools/rand48.h, makefile.vc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/rtree/RTreeBulkLoad.cc,
+ regressiontest/rtree/RTreeBulkLoad.vcproj,
+ regressiontest/rtree/RTreeExhaustive.vcproj,
+ regressiontest/rtree/RTreeGenerator.vcproj,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeLoad.vcproj,
+ regressiontest/rtree/RTreeQuery.vcproj,
+ regressiontest/rtree/test3/run, spatialindex-vc,
+ spatialindex-vc/spatialindex.vcproj,
+ spatialindex-vc/spatialindex.vcproj.RESEARCH.marioh.user,
+ src/mvrtree/Index.cc, src/mvrtree/Index.h, src/mvrtree/Leaf.cc,
+ src/mvrtree/Leaf.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/mvrtree/PointerPoolNode.h, src/mvrtree/Statistics.h,
+ src/rtree/BulkLoader.cc, src/rtree/BulkLoader.h,
+ src/rtree/Index.h, src/rtree/Leaf.h, src/rtree/Node.h,
+ src/rtree/PointerPoolNode.h, src/rtree/RTree.cc,
+ src/rtree/RTree.h, src/rtree/Statistics.h,
+ src/spatialindex/MovingRegion.cc,
+ src/spatialindex/SpatialIndexImpl.cc,
+ src/spatialindex/SpatialIndexImpl.h,
+ src/storagemanager/Buffer.cc, src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/storagemanager/RandomEvictionsBuffer.h,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/Makefile.am, src/tools/TemporaryFile.cc,
+ src/tools/Tools.cc, src/tprtree/Index.h, src/tprtree/Leaf.h,
+ src/tprtree/Node.h, src/tprtree/PointerPoolNode.h,
+ src/tprtree/Statistics.h, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h:
+
+2009-07-15 14:39 hobu
+
+ * include/SpatialIndex.h, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/rtree/Node.cc, src/rtree/Node.h, src/rtree/RTree.cc,
+ src/rtree/RTree.h, src/tprtree/Node.cc, src/tprtree/Node.h: apply
+ Willem's patch for #14
+
+2009-07-06 22:23 hobu
+
+ * src/rtree/RTree.cc: more descriptive and separate exception
+ descriptions for FillFactor inconsistencies
+
+2009-07-06 14:38 hobu
+
+ * include/SpatialIndex.h, ltmain.sh: silence warnings about windows
+ compiler complaints on non-windows systems
+
+2009-05-28 17:52 hobu
+
+ * makefile.vc: rename dlls to not have lib* in front of them
+
+2009-05-28 16:31 hobu
+
+ * makefile.vc: A much improved windows makefile based in libLAS'
+
+2009-05-28 16:31 hobu
+
+ * include/SpatialIndex.h: On MSVC, just about every class complains
+ about 4250, inheritance by dominance. We'll just shut that up for
+ now.
+
+2009-05-14 18:26 hobu
+
+ * src/tools/TemporaryFile.cc: apply Patrick Mézard's patch for the
+ inverted use of mktemp on windows #13
+
+2009-05-14 18:21 hobu
+
+ * src/tools/Tools.cc: Fix #12, add time.h so msvc9 works
+
+2009-05-04 17:10 hobu
+
+ * regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/mvrtree/MVRTreeLoad.cc,
+ regressiontest/mvrtree/MVRTreeQuery.cc,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc,
+ regressiontest/tprtree/Generator.cc, src/mvrtree/MVRTree.cc,
+ src/mvrtree/Node.cc, src/rtree/BulkLoader.cc, src/rtree/Leaf.cc,
+ src/rtree/Node.cc, src/rtree/RTree.cc,
+ src/spatialindex/LineSegment.cc, src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc, src/spatialindex/Point.cc,
+ src/spatialindex/Region.cc, src/spatialindex/TimePoint.cc,
+ src/spatialindex/TimeRegion.cc, src/storagemanager/Buffer.cc,
+ src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h, src/tools/Tools.cc,
+ src/tprtree/Leaf.cc, src/tprtree/Node.cc, src/tprtree/TPRTree.cc:
+ apply the patch for #11 - cstring and limits includes so gcc 4.3+
+ works
+
+2008-05-30 19:42 mhadji
+
+ * src/tools/Makefile.am, src/tools/Tools.cc:
+
+2008-05-23 18:27 mhadji
+
+ * makefile.vc:
+
+2008-05-23 17:55 mhadji
+
+ * configure.ac:
+
+2008-05-23 17:28 mhadji
+
+ * regressiontest/rtree/RTreeLoad.cc,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h:
+
+2008-05-18 12:35 mhadji
+
+ * ltmain.sh:
+
+2008-04-30 05:39 hobu
+
+ * .: propset to ignore aclocal.m4
+
+2008-04-30 05:39 hobu
+
+ * aclocal.m4: aclocal.m4 is autogenerated. removing
+
+2008-04-30 05:35 hobu
+
+ * ., include, include/tools, regressiontest,
+ regressiontest/mvrtree, regressiontest/rtree,
+ regressiontest/tprtree, src, src/mvrtree, src/rtree,
+ src/spatialindex, src/storagemanager, src/tools, src/tprtree: set
+ svn:ignore properties for autogenerated files and automake cruft
+
+2008-04-30 05:27 hobu
+
+ * Makefile.in, include/Makefile.in, include/tools/Makefile.in,
+ regressiontest/Makefile.in, regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in, src/Makefile.in,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tools/Makefile.in, src/tprtree/Makefile.in: delete
+ Makefile.in's from source tree. Use autogen.sh to remake them if
+ building from svn source yourself
+
+2008-04-30 05:26 hobu
+
+ * include/tools/Makefile.am: add rand48.h to dist target
+
+2008-04-29 19:47 mhadji
+
+ * regressiontest/rtree/test1/data,
+ regressiontest/rtree/test1/queries:
+
+2008-04-29 18:17 mhadji
+
+ * include/tools/rand48.hpp:
+
+2008-04-29 18:06 mhadji
+
+ * include/tools/rand48.h:
+
+2008-04-29 18:03 mhadji
+
+ * INSTALL, Makefile.in, aclocal.m4, configure.ac, mkinstalldirs,
+ regressiontest/Makefile.in, regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/TemporaryFile.cc, src/tools/Tools.cc:
+
+2008-04-29 16:36 mhadji
+
+ * makefile.vc:
+
+2008-04-29 16:36 mhadji
+
+ * include/Makefile.in, include/SpatialIndex.h,
+ include/tools/Makefile.in, include/tools/Tools.h:
+
+2008-04-29 16:36 mhadji
+
+ * src/Makefile.in, src/mvrtree/Makefile.in, src/mvrtree/Node.cc,
+ src/rtree/Makefile.in, src/spatialindex/LineSegment.cc,
+ src/spatialindex/Makefile.in, src/spatialindex/MovingRegion.cc,
+ src/storagemanager/Makefile.in,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/Makefile.in, src/tprtree/Makefile.in:
+
+2008-04-29 15:40 mhadji
+
+ * src/spatialindex/MovingRegion.cc: Fixex malloc memory leak.
+
+2008-04-29 15:40 mhadji
+
+ * src/spatialindex/LineSegment.cc: Fixed malloc memory leak
+
+2008-02-26 16:15 hobu
+
+ * src/tools/rand48.cc: oops. Add missing file
+
+2008-02-26 16:14 hobu
+
+ * include/tools/rand48.hpp: oops. Add missing file
+
+2008-01-25 19:43 hobu
+
+ * include/MVRTree.h, include/RTree.h, include/SpatialIndex.h,
+ include/TPRTree.h, include/tools/Tools.h, makefile.vc,
+ src/mvrtree/Index.cc, src/mvrtree/Leaf.cc, src/mvrtree/Node.cc,
+ src/rtree/BulkLoader.cc, src/rtree/Index.cc, src/rtree/Leaf.cc,
+ src/rtree/Node.cc, src/spatialindex/LineSegment.cc,
+ src/spatialindex/MovingRegion.cc, src/storagemanager/Buffer.cc,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/TemporaryFile.cc, src/tools/Tools.cc,
+ src/tprtree/Index.cc, src/tprtree/Leaf.cc, src/tprtree/Node.cc:
+ Initial push of windows patches
+
+2008-01-23 16:25 mhadji
+
+ * INSTALL:
+
+2008-01-21 14:19 mhadji
+
+ * README, regressiontest/rtree/test3/run:
+
+2008-01-19 20:51 hobu
+
+ * configure.ac, makefile.vc: bump version to 1.3
+
+2008-01-19 18:42 hobu
+
+ * ChangeLog: Add an auto-generated ChangeLog
+
+2008-01-19 18:37 hobu
+
+ * AUTHORS: add myself and some notes
+
+2008-01-19 18:36 hobu
+
+ * INSTALL: update to ReST
+
+2008-01-19 18:09 hobu
+
+ * README: update ReST
+
+2008-01-19 18:09 hobu
+
+ * README: update ReST
+
+2008-01-19 18:03 hobu
+
+ * README: update ReST
+
+2008-01-19 18:02 hobu
+
+ * README: update ReST
+
+2008-01-19 18:02 hobu
+
+ * README: update ReST
+
+2008-01-19 18:01 hobu
+
+ * README: update ReST
+
+2008-01-19 17:59 hobu
+
+ * README: update ReST
+
+2008-01-19 17:59 hobu
+
+ * README: update ReST
+
+2008-01-19 17:58 hobu
+
+ * README: update ReST
+
+2008-01-19 17:58 hobu
+
+ * README: update ReST
+
+2008-01-19 17:56 hobu
+
+ * README: update ReST
+
+2008-01-19 17:55 hobu
+
+ * README: update ReST
+
+2008-01-19 17:29 hobu
+
+ * README: update ReST
+
+2008-01-19 17:26 hobu
+
+ * README: update to ReST
+
+2008-01-19 17:02 hobu
+
+ * README: set mimetype to reStructured text so Trac will render it
+ for us in the browser
+
+2008-01-17 23:34 hobu
+
+ * regressiontest/tprtree/Makefile.am,
+ regressiontest/tprtree/Makefile.in, src/mvrtree/Makefile.am,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.am,
+ src/rtree/Makefile.in, src/spatialindex/Makefile.am,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.am,
+ src/storagemanager/Makefile.in, src/tprtree/Makefile.am,
+ src/tprtree/Makefile.in: add internal headers to the _SOURCES
+ targets so they get included in make dist
+
+2008-01-17 17:06 hobu
+
+ * Makefile.in, aclocal.m4, autogen.sh, include/Makefile.in,
+ include/tools/Makefile.in, ltmain.sh, regressiontest/Makefile.in,
+ regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in, src/Makefile.in,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tools/Makefile.in, src/tprtree/Makefile.in: add autogen.sh to
+ simplify auto stuff
+
+2008-01-17 17:04 hobu
+
+ * debian: move debian packaging stuff out of trunk
+
+2008-01-15 19:33 hobu
+
+ * makefile.vc: add nmake makefile
+
+2007-12-07 20:44 kenneth
+
+ * debian/libspatialindex1.dirs, debian/libspatialindex1.install,
+ debian/libspatialindex11.dirs, debian/libspatialindex11.install:
+ Wrong names
+
+2007-12-07 19:58 kenneth
+
+ * configure, debian/rules: Fixed rules file
+
+2007-12-07 18:10 kenneth
+
+ * config.guess, config.sub, debian/control: Updates to the control
+ file (packaging)
+ Removal of files that shouldn't be in SVN
+
+2007-11-30 18:04 mhadji
+
+ * Makefile.in, configure, configure.ac:
+
+2007-11-30 16:50 seang
+
+ * Makefile.am: Version info to 1:0:0
+
+2007-11-29 22:26 mhadji
+
+ * INSTALL, configure, configure.ac:
+
+2007-11-29 21:54 mhadji
+
+ * include/LineSegment.h, include/Point.h, include/Region.h,
+ include/tools/LineSegment.h, include/tools/Point.h,
+ include/tools/Region.h, src/spatialindex/LineSegment.cc,
+ src/spatialindex/Point.cc, src/spatialindex/Region.cc,
+ src/tools/ExternalSort.cc, src/tools/ExternalSort.h,
+ src/tools/TemporaryFile.cc, src/tools/Tools.cc:
+
+2007-11-29 21:48 mhadji
+
+ * Makefile.am, Makefile.in, aclocal.m4, configure, configure.ac,
+ include/Makefile.am, include/Makefile.in, include/MovingPoint.h,
+ include/MovingRegion.h, include/SpatialIndex.h,
+ include/TimePoint.h, include/TimeRegion.h,
+ include/tools/Makefile.am, include/tools/Makefile.in,
+ include/tools/PointerPool.h, include/tools/PoolPointer.h,
+ include/tools/SmartPointer.h, include/tools/TemporaryFile.h,
+ include/tools/Tools.h, regressiontest/Makefile.in,
+ regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Generator.cc,
+ regressiontest/tprtree/Makefile.in,
+ regressiontest/tprtree/RandomGenerator.cc,
+ regressiontest/tprtree/RandomGenerator.h, src/Makefile.in,
+ src/mvrtree/Index.cc, src/mvrtree/Leaf.cc,
+ src/mvrtree/MVRTree.cc, src/mvrtree/Makefile.in,
+ src/mvrtree/Node.cc, src/mvrtree/Statistics.cc,
+ src/rtree/BulkLoader.cc, src/rtree/Index.cc, src/rtree/Leaf.cc,
+ src/rtree/Makefile.in, src/rtree/Node.cc, src/rtree/RTree.cc,
+ src/rtree/Statistics.cc, src/spatialindex/Makefile.am,
+ src/spatialindex/Makefile.in, src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc,
+ src/spatialindex/SpatialIndexImpl.h,
+ src/spatialindex/TimePoint.cc, src/spatialindex/TimeRegion.cc,
+ src/storagemanager/Buffer.cc,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/Makefile.in,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/tools/Makefile.am, src/tools/Makefile.in, src/tools/geometry,
+ src/tools/tools, src/tprtree/Index.cc, src/tprtree/Leaf.cc,
+ src/tprtree/Makefile.in, src/tprtree/Node.cc,
+ src/tprtree/Statistics.cc, src/tprtree/TPRTree.cc:
+
+2007-11-29 18:00 seang
+
+ * debian, debian/README, debian/README.Debian, debian/changelog,
+ debian/compat, debian/control, debian/copyright, debian/dirs,
+ debian/docs, debian/libspatialindex1-dev.dirs,
+ debian/libspatialindex1-dev.install,
+ debian/libspatialindex1.doc-base.EX,
+ debian/libspatialindex11.dirs, debian/libspatialindex11.install,
+ debian/rules: Add debian directory created by dh_make
+
+2007-11-29 04:05 hobu
+
+ * Makefile.am, Makefile.in: use -version-info instead of -release
+
+2007-11-29 00:59 hobu
+
+ * include/Makefile.in, include/tools/Makefile.in: include
+ Makefile.in's
+
+2007-11-29 00:55 hobu
+
+ * Makefile.am, Makefile.in: use .'s to separate version info and
+ don't do -no-undefined
+
+2007-11-29 00:19 hobu
+
+ * Makefile.am: tweak formatting
+
+2007-11-29 00:11 seang
+
+ * Makefile.am: Add version-info to Makefile.am
+
+2007-11-28 23:54 hobu
+
+ * Makefile.am, Makefile.in, include/Makefile.am,
+ include/tools/Makefile.am: finish incorporating -ltools
+
+2007-11-28 22:48 hobu
+
+ * Makefile.am, Makefile.in, configure, configure.ac,
+ include/Makefile.am, include/tools/Makefile.am: more progress on
+ automake for includes directories... close, but not quite
+
+2007-11-28 22:38 hobu
+
+ * include/Makefile.am, include/tools/Makefile.am: Add automake
+ files for includes
+
+2007-11-28 21:03 hobu
+
+ * Makefile.am, Makefile.in, aclocal.m4, configure, configure.ac,
+ include/tools, regressiontest/Makefile.in,
+ regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/tprtree/Makefile.in, src/Makefile.am,
+ src/Makefile.in, src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tools, src/tools/Makefile.in, src/tools/geometry/Makefile.am,
+ src/tools/geometry/Makefile.in, src/tools/tools/Makefile.am,
+ src/tools/tools/Makefile.in, src/tprtree/Makefile.in: start
+ incorporating -ltools into the tree
+
+2007-08-30 15:16 mhadji
+
+ * INSTALL, a: README should be INSTALL, and INSTALL should be
+ README
+
+2007-08-30 15:15 mhadji
+
+ * INSTALL, README: README should be INSTALL, and INSTALL should be
+ README
+
+2007-08-30 15:13 mhadji
+
+ * README, a: README file should be INSTALL, and INSTALL should be
+ README
+
+2007-08-02 04:37 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: revert r9
+
+2007-08-02 04:37 hobu
+
+ * src/rtree/Leaf.cc: revert r10
+
+2007-08-02 04:36 hobu
+
+ * src/rtree/Node.cc: revert r11
+
+2007-08-02 04:36 hobu
+
+ * src/rtree/RTree.cc: revert r12
+
+2007-08-02 04:35 hobu
+
+ * src/mvrtree/MVRTree.cc: revert r13
+
+2007-08-02 04:34 hobu
+
+ * src/spatialindex/SpatialIndexImpl.h: add strings.h
+
+2007-08-02 04:27 hobu
+
+ * src/mvrtree/MVRTree.cc: add strings.h
+
+2007-08-02 04:26 hobu
+
+ * src/rtree/RTree.cc: add strings.h
+
+2007-08-02 04:25 hobu
+
+ * src/rtree/Node.cc: add strings.h
+
+2007-08-02 02:23 hobu
+
+ * src/rtree/Leaf.cc: include <strings.h>
+
+2007-08-02 02:21 hobu
+
+ * src/storagemanager/DiskStorageManager.cc: include <strings.h> in
+ DiskStorageManager (this is not available on Solaris by default)
+
+2007-08-01 20:49 hobu
+
+ * regressiontest/rtree/test1/data,
+ regressiontest/rtree/test1/queries: add data and queries for
+ tests
+
+2007-08-01 20:48 hobu
+
+ * INSTALL, Makefile.in, README, aclocal.m4,
+ regressiontest/Makefile.in, regressiontest/mvrtree/Makefile.in,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc,
+ regressiontest/tprtree/Makefile.in, src/Makefile.in,
+ src/mvrtree/Makefile.in, src/rtree/Makefile.in,
+ src/spatialindex/Makefile.in, src/storagemanager/Makefile.in,
+ src/tprtree/Makefile.in: add Marios' latest updates
+
+2007-08-01 20:40 hobu
+
+ * spatialindex.111.zip: oops, don't include zip files
+
+2007-08-01 20:37 hobu
+
+ * AUTHORS, COPYING, ChangeLog, INSTALL, Makefile.am, Makefile.in,
+ NEWS, README, aclocal.m4, config.guess, config.sub, configure,
+ configure.ac, depcomp, include, include/MVRTree.h,
+ include/MovingPoint.h, include/MovingRegion.h, include/RTree.h,
+ include/SpatialIndex.h, include/TPRTree.h, include/TimePoint.h,
+ include/TimeRegion.h, install-sh, ltmain.sh, missing,
+ mkinstalldirs, regressiontest, regressiontest/Makefile.am,
+ regressiontest/Makefile.in, regressiontest/mvrtree,
+ regressiontest/mvrtree/Exhaustive.cc,
+ regressiontest/mvrtree/Generator.cc,
+ regressiontest/mvrtree/MVRTreeLoad.cc,
+ regressiontest/mvrtree/MVRTreeQuery.cc,
+ regressiontest/mvrtree/Makefile.am,
+ regressiontest/mvrtree/Makefile.in, regressiontest/mvrtree/test1,
+ regressiontest/mvrtree/test1/run, regressiontest/mvrtree/test2,
+ regressiontest/mvrtree/test2/run, regressiontest/rtree,
+ regressiontest/rtree/Exhaustive.cc,
+ regressiontest/rtree/Generator.cc,
+ regressiontest/rtree/Makefile.am,
+ regressiontest/rtree/Makefile.in,
+ regressiontest/rtree/RTreeBulkLoad.cc,
+ regressiontest/rtree/RTreeLoad.cc,
+ regressiontest/rtree/RTreeQuery.cc, regressiontest/rtree/test1,
+ regressiontest/rtree/test1/run, regressiontest/rtree/test2,
+ regressiontest/rtree/test2/run, regressiontest/rtree/test3,
+ regressiontest/rtree/test3/run, regressiontest/rtree/test4,
+ regressiontest/rtree/test4/run, regressiontest/tprtree,
+ regressiontest/tprtree/Exhaustive.cc,
+ regressiontest/tprtree/Generator.cc,
+ regressiontest/tprtree/Makefile.am,
+ regressiontest/tprtree/Makefile.in,
+ regressiontest/tprtree/RandomGenerator.cc,
+ regressiontest/tprtree/RandomGenerator.h,
+ regressiontest/tprtree/TPRTreeLoad.cc,
+ regressiontest/tprtree/TPRTreeQuery.cc,
+ regressiontest/tprtree/test1, regressiontest/tprtree/test1/run,
+ regressiontest/tprtree/test2, regressiontest/tprtree/test2/run,
+ spatialindex.111.zip, src, src/Makefile.am, src/Makefile.in,
+ src/mvrtree, src/mvrtree/Index.cc, src/mvrtree/Index.h,
+ src/mvrtree/Leaf.cc, src/mvrtree/Leaf.h, src/mvrtree/MVRTree.cc,
+ src/mvrtree/MVRTree.h, src/mvrtree/Makefile.am,
+ src/mvrtree/Makefile.in, src/mvrtree/Node.cc, src/mvrtree/Node.h,
+ src/mvrtree/PointerPoolNode.h, src/mvrtree/Statistics.cc,
+ src/mvrtree/Statistics.h, src/rtree, src/rtree/BulkLoader.cc,
+ src/rtree/BulkLoader.h, src/rtree/Index.cc, src/rtree/Index.h,
+ src/rtree/Leaf.cc, src/rtree/Leaf.h, src/rtree/Makefile.am,
+ src/rtree/Makefile.in, src/rtree/Node.cc, src/rtree/Node.h,
+ src/rtree/PointerPoolNode.h, src/rtree/RTree.cc,
+ src/rtree/RTree.h, src/rtree/Statistics.cc,
+ src/rtree/Statistics.h, src/spatialindex,
+ src/spatialindex/Makefile.am, src/spatialindex/Makefile.in,
+ src/spatialindex/MovingPoint.cc,
+ src/spatialindex/MovingRegion.cc,
+ src/spatialindex/SpatialIndexImpl.cc,
+ src/spatialindex/SpatialIndexImpl.h,
+ src/spatialindex/TimePoint.cc, src/spatialindex/TimeRegion.cc,
+ src/storagemanager, src/storagemanager/Buffer.cc,
+ src/storagemanager/Buffer.h,
+ src/storagemanager/DiskStorageManager.cc,
+ src/storagemanager/DiskStorageManager.h,
+ src/storagemanager/Makefile.am, src/storagemanager/Makefile.in,
+ src/storagemanager/MemoryStorageManager.cc,
+ src/storagemanager/MemoryStorageManager.h,
+ src/storagemanager/RandomEvictionsBuffer.cc,
+ src/storagemanager/RandomEvictionsBuffer.h, src/tprtree,
+ src/tprtree/Index.cc, src/tprtree/Index.h, src/tprtree/Leaf.cc,
+ src/tprtree/Leaf.h, src/tprtree/Makefile.am,
+ src/tprtree/Makefile.in, src/tprtree/Node.cc, src/tprtree/Node.h,
+ src/tprtree/PointerPoolNode.h, src/tprtree/Statistics.cc,
+ src/tprtree/Statistics.h, src/tprtree/TPRTree.cc,
+ src/tprtree/TPRTree.h: add 1.1.1 version of library
+
+2007-08-01 20:32 hobu
+
+ * .: basic layout
+
diff --git a/sci-libs/libspatialindex/svn/trunk/HOWTORELEASE.txt b/sci-libs/libspatialindex/svn/trunk/HOWTORELEASE.txt
new file mode 100644
index 000000000..10bbac934
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/HOWTORELEASE.txt
@@ -0,0 +1,82 @@
+
+Steps for Making a libLAS Release
+==============================================================================
+
+:Author: Howard Butler
+:Contact: hobu.inc@gmail.com
+:Revision: $Revision: 178 $
+:Date: $Date: 2010-03-05 09:19:51 -0500 (Fri, 05 Mar 2010) $
+
+This document describes the process for releasing a new version of libspatialindex.
+
+General Notes
+------------------------------------------------------------------------------
+
+Release Process
+
+1) Increment Version Numbers
+
+ - configure.ac
+ * sidx_version_major
+ * sidx_version_minor
+ * sidx_version_micro
+ - include/Version.h
+ * SIDX_VERSION_MAJOR
+ * SIDX_VERSION_MINOR
+ * SIDX_VERSION_REV
+ * SIDX_RELEASE_NAME
+ - makefile.vc's
+ *PACKAGE_VERSION
+
+2) Update README to include any relevant info about the release that
+ might have changed.
+
+3) Update ChangeLog with svn2cl
+
+4) Run the regression tests. Really.
+
+5) Build Windows version
+
+ - Issue nmake and nmake install commands
+
+ ::
+
+ nmake /f makefile.vc clean
+ nmake /f makefile.vc
+ nmake /f makefile.vc install
+ nmake /f makefile.vc package
+
+
+6) Make the source distribution
+
+ ::
+
+ make dist
+
+
+7) Generate MD5 sums
+
+ ::
+
+ md5 spatialindex-src-1.5.0.tar.bz2 > spatialindex-src-1.5.0.tar.bz2.md5
+ md5 spatialindex-src-1.5.0.tar.gz > spatialindex-src-1.5.0.tar.gz.md5
+ md5 liblas-1.3.1-win32.zip > liblas-1.3.1-win32.zip.md5
+
+8) Update http://trac.gispython.org/spatialindex/wiki/Releases
+
+9) Upload windows and source package as attachments to the new release page.
+
+10) Tag the release. Use the ``-f`` switch if you are retagging because you
+ missed something.
+
+ ::
+
+ svn cp http://svn.gispython.org/svn/spatialindex/spatialindex/trunk http://svn.gispython.org/svn/spatialindex/spatialindex/tags/1.5.0
+
+11) Write the release notes. Place a copy of the release notes on the release
+ page you created as well as send an email to spatalindex list announcing the
+ new release.
+
+
+
+$Id: HOWTORELEASE.txt 178 2010-03-05 14:19:51Z hobu $
diff --git a/sci-libs/libspatialindex/svn/trunk/INSTALL b/sci-libs/libspatialindex/svn/trunk/INSTALL
new file mode 100644
index 000000000..095b1eb40
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/INSTALL
@@ -0,0 +1,231 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PREFIX', the package will
+use PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/sci-libs/libspatialindex/svn/trunk/INSTALL.WIN b/sci-libs/libspatialindex/svn/trunk/INSTALL.WIN
new file mode 100644
index 000000000..52649de1a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/INSTALL.WIN
@@ -0,0 +1,28 @@
+Visual Studio 2005:
+You have to open the spatialindex.sln solution from the IDE and build.
+Unfortunatelly, vcbuild.exe does not work as expected, hence you cannot
+build the DLL from the command line.
+
+Visutal Studio 2008:
+Either use the IDE or use vcbuild to compile from the command line:
+
+To create 32bit DLL:
+1. Open a Visual Studio command prompt (or open any shell
+ and run vcvars32.bat).
+
+2a. Release build:
+ Run vcbuild.exe /useenv spatialindex.sln "Release|Win32"
+2b. Debug build:
+ Run vcbuild.exe /useenv spatialindex.sln "Debug|Win32"
+
+To create 64bit DLL:
+1. Open a Visual Studio x64 command prompt (or open any shell
+ and run vcvarsall.bat x64).
+
+2a. Release build:
+ Run vcbuild.exe /useenv spatialindex.sln "Release|x64"
+2b. Debug build:
+ Run vcbuild.exe /useenv spatialindex.sln "Debug|x64"
+
+Enjoy!
+
diff --git a/sci-libs/libspatialindex/svn/trunk/Makefile.am b/sci-libs/libspatialindex/svn/trunk/Makefile.am
new file mode 100644
index 000000000..9b4c2eced
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/Makefile.am
@@ -0,0 +1,23 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+SUBDIRS = src . regressiontest include
+
+lib_LTLIBRARIES = libspatialindex.la libspatialindex_c.la
+
+libspatialindex_la_SOURCES =
+libspatialindex_la_LIBADD = \
+ src/spatialindex/liblibrary.la \
+ src/storagemanager/libstoragemanager.la \
+ src/rtree/librtree.la \
+ src/mvrtree/libmvrtree.la \
+ src/tprtree/libtprtree.la \
+ src/tools/libtools.la
+
+libspatialindex_c_la_SOURCES =
+libspatialindex_c_la_LIBADD = \
+ libspatialindex.la \
+ src/capi/libsidxc.la
+
+libspatialindex_la_LDFLAGS = -version-info 1:0:0
+libspatialindex_c_la_LDFLAGS = -version-info 1:0:0 -lstdc++
+
+EXTRA_DIST = makefile.vc INSTALL.WIN spatialindex.sln spatialindex-vc/spatialindex.vcproj
diff --git a/sci-libs/libspatialindex/svn/trunk/NEWS b/sci-libs/libspatialindex/svn/trunk/NEWS
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/NEWS
diff --git a/sci-libs/libspatialindex/svn/trunk/README b/sci-libs/libspatialindex/svn/trunk/README
new file mode 100644
index 000000000..a5f50a4e0
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/README
@@ -0,0 +1,423 @@
+*****************************************************************************
+ SpatialIndex Reference
+*****************************************************************************
+
+:Author: Marios Hadjieleftheriou
+:Contact: mhadji@gmail.com
+:Revision: $Revision: 203 $
+:Date: $Date: 2011-05-18 11:20:08 -0400 (Wed, 18 May 2011) $
+
+.. The next heading encountered becomes our H2
+..
+
+.. sectnum::
+
+.. contents::
+ :depth: 2
+ :backlinks: top
+
+------------------------------------------------------------------------------
+Introduction
+------------------------------------------------------------------------------
+
+You have downloaded the SpatialIndex Library. This is free software under LGPL.
+The library is in beta testing stage. Use at your own risk.
+
+The purpose of this library is to provide:
+ 1. An extensible framework that will support robust spatial indexing
+ methods.
+ 2. Support for sophisticated spatial queries. Range, point location,
+ nearest neighbor and k-nearest neighbor as well as parametric
+ queries (defined by spatial constraints) should be easy to deploy and run.
+ 3. Easy to use interfaces for inserting, deleting and updating information.
+ 4. Wide variety of customization capabilities. Basic index and storage
+ characteristics like the page size, node capacity, minimum fan-out,
+ splitting algorithm, etc. should be easy to customize.
+ 5. Index persistence. Internal memory and external memory structures
+ should be supported. Clustered and non-clustered indices should
+ be easy to be persisted.
+
+------------------------------------------------------------------------------
+Installation
+------------------------------------------------------------------------------
+
+First run autogen.sh to generate the configure scripts.
+By default include files and library files will be installed in /usr/local. If
+you would like to use a different installation directory (e.g., in case
+that you do not have root access) run the configure script with
+the --prefix option:
+
+::
+
+ ./configure --prefix=/home/marioh/usr
+
+Make the library::
+
+ make
+
+Install the library::
+
+ make install
+
+------------------------------------------------------------------------------
+Using the Library
+------------------------------------------------------------------------------
+
+You are ready to use the library. All you have to
+do is to include the file SpatialIndex.h in your source
+files and then compile with the following options:
+
+::
+
+ g++ MyFile.cc -o MyFile -L/home/marioh/usr/lib -I/home/marioh/usr/include -lpthread -lspatialindex
+
+If the library is installed in the default /usr/local path, then the
+-I and -L options are not necessary.
+
+If you are compiling on Mac OS X you will need to add the -bind_at_load
+option when linking against the dynamic link libraries. OS X Tiger should
+work out of the box, however, with XCode 3.0.
+
+------------------------------------------------------------------------------
+Library Overview
+------------------------------------------------------------------------------
+
+The library currently consists of six packages:
+ 1. The core spatialindex utilities.
+ 2. The storagemanager files.
+ 3. The spatialindex interfaces.
+ 4. The rtree index.
+ 5. The mvrtree index.
+ 6. The tprtree index.
+
+I will briefly present the basic features supported by each package.
+For more details you will have to refer to the code, for now.
+
+Spatial Index Utilities
+------------------------------------------------------------------------------
+
+To provide common constructors and uniform initialization for all objects
+provided by the library a PropertySet class is provided. A PropertySet
+associates strings with Variants. Each property corresponds to one string.
+
+A basic implementation of a Variant is also provided that supports a
+number of data types. The supported data types can be found in SpatialIndex.h
+
+PropertySet supports three functions:
+
+ 1. getProperty returns the Variant associated with the given string.
+ 2. setProperty associates the given Variant with the given string.
+ 3. removeProperty removes the specified property from the PropertySet.
+
+A number of exceptions are also defined here. All exceptions extend
+Exception and thus provide the what() method that returns a string
+representation of the exception with useful comments. It is advisable to
+use enclosing try/catch blocks when using any library objects. Many
+constructors throw exceptions when invalid initialization properties are specified.
+
+A general IShape interface is defined. All shape classes should extend
+IShape. Basic Region and Point classes are already provided. Please
+check Region.h and Point.h for further details.
+
+Storage Manager
+------------------------------------------------------------------------------
+
+The library provides a common interface for storage management of all
+indices. It consists of the IStorageManager interface, which provides functions
+for storing and retrieving entities. An entity is viewed as a simple byte
+array; hence it can be an index entry, a data entry or anything else that the
+user wants to store. The storage manager interface is generic and does not apply
+only to spatial indices.
+
+Classes that implement the IStorageManager interface decide on how to
+store entities. simple main memory implementation is provided, for example,
+that stores the entities using a vector, associating every entity with a
+unique ID (the entry's index in the vector). A disk based storage manager
+could choose to store the entities in a simple random access file, or a
+database storage manager could store them in a relational table, etc. as long
+as unique IDs are associated with every entity. Also, storage managers should
+implement their own paging, compaction and deletion policies transparently
+from the callers (be it an index or a user).
+
+The storeByteArray method gets a byte array and its length and an entity ID.
+If the caller specifies NewPage as the input ID, the storage manager allocates
+a new ID, stores the entity and returns the ID associated with the entity.
+If, instead, the user specifies an already existing ID the storage manager
+overwrites the old data. An exception is thrown if the caller requests
+an invalid ID to be overwritten.
+
+The loadByteArray method gets an entity ID and returns the associated byte
+array along with its length. If an invalid ID is requested, an exception is thrown.
+
+The deleteByteArray method removes the requested entity from storage.
+
+The storage managers should have no information about the types of entities
+that are stored. There are three main reasons for this decision:
+
+ 1. Any number of spatial indices can be stored in a single storage manager
+ (i.e. the same relational table, or binary file, or hash table, etc., can
+ be used to store many indices) using an arbitrary number of pages and
+ a unique index ID per index (this will be discussed shortly).
+ 2. Both clustered and non-clustered indices can be supported. A clustered
+ index stores the data associated with the entries that it contains along
+ with the spatial information that it indexes. A non-clustered index stores
+ only the spatial information of its entries. Any associated data are
+ stored separately and are associated with the index entries by a unique ID.
+ To support both types of indices, the storage manager interface should be
+ quite generic, allowing the index to decide how to store its data.
+ Otherwise clustered and non-clustered indices would have to be
+ implemented separately.
+ 3. Decision flexibility. For example, the users can choose a clustered index
+ that will take care of storing everything. They can choose a main memory
+ non-clustered index and store the actual data in MySQL. They can choose
+ a disk based non-clustered index and store the data manually in a
+ separate binary file or even in the same storage manager but doing a low
+ level customized data processing.
+
+Two storage managers are provided in the current implementation:
+
+ 1) MemoryStorageManager
+ 2) DiskStorageManager
+
+MemoryStorageManager
+~~~~~~~~~~~~~~~~~~~~~~~
+
+As it is implied be the name, this is a main memory implementation. Everything
+is stored in main memory using a simple vector. No properties are needed to
+initialize a MemoryStorageManager object. When a MemoryStorageManager instance
+goes out of scope, all data that it contains are lost.
+
+DiskStorageManager
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The disk storage manager uses two random access files for storing information.
+One with extension .idx and the other with extension .dat.
+
+A list of all the supported properties that can be provided during
+initialization, follows:
+
+========= ======== ===========================================================
+Property Type Description
+========= ======== ===========================================================
+FileName VT_PCHAR The base name of the file to open (no extension)
+Overwrite VT_BOOL If Overwrite is true and a storage manager with the
+ specified filename already exists, it will be
+ truncated and overwritten. All data will be lost.
+PageSize VT_ULONG The page size to use. If the specified filename
+ already exists and Overwrite is false, PageSize is ignored.
+========= ======== ===========================================================
+
+For entities that are larger than the page size, multiple pages are used.
+Although, the empty space on the last page is lost. Also, there is no effort
+whatsoever to use as many sequential pages as possible. A future version
+might support sequential I/O. Thus, real clustered indices cannot be supported yet.
+
+The purpose of the .idx file is to store vital information like the page size,
+the next available page, a list of empty pages and the sequence of pages
+associated with every entity ID.
+
+This class also provides a flush method that practically overwrites the
+.idx file and syncs both file pointers.
+
+The .idx file is loaded into main memory during initialization and is
+written to disk only after flushing the storage manager or during object
+destruction. In case of an unexpected failure changes to the storage manager
+will be lost due to a stale .idx file. Avoiding such disasters is future work.
+
+SpatialIndex Interfaces
+------------------------------------------------------------------------------
+
+A spatial index is any index structure that accesses spatial information
+efficiently. It could range from a simple grid file to a complicated tree
+structure. A spatial index indexes entries of type IEntry, which can be index
+nodes, leaf nodes, data etc. depending on the structure characteristics.
+The appropriate interfaces with useful accessor methods should be provided
+for all types of entries.
+
+A spatial index should implement the ISpatialIndex interface.
+
+The containmentQuery method requires a query shape and a reference to a
+valid IVisitor instance (described shortly). The intersectionQuery method
+is the same. Both accept an IShape as the query. If the query shape is a simple
+Region, than a classic range query is performed. The user though has the
+ability to create her own shapes, thus defining her own intersection and
+containment methods making possible to run any kind of range query without
+having to modify the index. An example of a trapezoidal query is given in the
+regressiontest directory. Have in mind that it is the users responsibility
+to implement the correct intersection and containment methods between their
+shape and the type of shapes that are stored by the specific index that they
+are planning to use. For example, if an rtree index will be used, a trapezoid
+should define intersection and containment between itself and Regions, since
+all rtree nodes are of type Region. Hence, the user should have some knowledge
+about the index internal representation, to run more sophisticated queries.
+
+A point location query is performed using the pointLocationQuery method. It
+takes the query point and a visitor as arguments.
+
+Nearest neighbor queries can be performed with the nearestNeighborQuery method.
+Its first argument is the number k of nearest neighbors requested. This
+method also requires the query shape and a visitor object. The default
+implementation uses the getMinimumDistance function of IShape for calculating
+the distance of the query from the rectangular node and data entries stored
+in the tree. A more sophisticated distance measure can be used by implementing
+the INearestNeighborComparator interface and passing it as the last argument
+of nearestNeighborQuery. For example, a comparator is necessary when the query
+needs to be checked against the actual data stored in the tree, instead of
+the rectangular data entry approximations stored in the leaves.
+
+For customizing queries the IVisitor interface (based on the Visitor
+pattern [gamma94]) provides callback functions for visiting index and
+leaf nodes, as well as data entries. Node and data information can be obtained
+using the INode and IData interfaces (both extend IEntry). Examples of using
+this interface include visualizing a query, counting the number of leaf
+or index nodes visited for a specific query, throwing alerts when a
+specific spatial region is accessed, etc.
+
+The queryStrategy method provides the ability to design more sophisticated
+queries. It uses the IQueryStrategy interface as a callback that is called
+continuously until no more entries are requested. It can be used to
+implement custom query algorithms (based on the strategy pattern [gamma94]).
+
+A data entry can be inserted using the insertData method. The insertion
+function will convert any shape into an internal representation depending on
+the index. Every inserted object should be assigned an ID (called object
+identifier) that will allow updating, deleting and reporting the object.
+It is the responsibility of the caller to provide the index with IDs
+(unique or not). Also, a byte array can be associated with an entry. The
+byte arrays are stored along with the spatial information inside the leaf
+nodes. Clustered indices can be supported in that way. The byte array can
+also by null (in which case the length field should be zero), and no extra
+space should be used per node.
+
+A data entry can be deleted using the deleteData method. The object shape
+and ID should be provided. Spatial indices cluster objects according to
+spatial characteristics and not IDs. Hence, the shape is essential for
+locating and deleting an entry.
+
+Useful statistics are provided through the IStatistics interface and
+the getStatistics method.
+
+Method getIndexProperties returns a PropertySet with all useful index
+properties like dimensionality etc.
+
+A NodeCommand interface is provided for customizing Node operations. Using
+the addWriteNodeCommand, addReadNodeCommand and addDeleteNodeCommand methods,
+custom command objects are added in listener lists and get executed after
+the corresponding operations.
+
+The isIndexValid method performs internal checks for testing the
+integrity of a structure. It is used for debugging purposes.
+
+When a new index is created a unique index ID should be assigned to it, that
+will be used when reloading the index from persistent storage. This index ID
+should be returned as an IndexIdentifier property in the instance of the
+PropsertySet that was used for constructing the index instance. Using
+index IDs, multiple indices can be stored in the same storage manager.
+It is the users responsibility to manager the index IDs. Associating the
+wrong index ID with the wrong storage manager or index type has undefined
+results.
+
+The RTree Package
+------------------------------------------------------------------------------
+
+The RTree index [guttman84] is a balanced tree structure that consists of
+index nodes, leaf nodes and data. Every node (leaf and index) has a fixed
+capacity of entries, (the node capacity) chosen at index creation An RTree
+abstracts the data with their Minimum Bounding Region (MBR) and clusters
+these MBRs according to various heuristics in the leaf nodes. Queries are
+evaluated from the root of the tree down the leaves. Since the index is
+balanced nodes can be under full. They cannot be empty though. A fill
+factor specifies the minimum number of entries allowed in any node. The
+fill factor is usually close to 70%.
+
+RTree creation involves:
+
+ 1. Deciding if the index will be internal or external memory and selecting
+ the appropriate storage manager.
+ 2. Choosing the index and leaf capacity (also known as fan-out).
+ 3. Choosing the fill factor (from 1% to 99% of the node capacity).
+ 4. Choosing the dimensionality of the data.
+ 5. Choosing the insert/update policy (the RTree variant).
+
+If an already stored RTree is being reloaded for reuse, only the index ID
+needs to be supplied during construction. In that case, some options cannot
+be modified. These include: the index and leaf capacity, the fill factor and
+the dimensionality. Note here, that the RTree variant can actually be
+modified. The variant affects only when and how splitting occurs, and
+thus can be changed at any time.
+
+An initialization PropertySet is used for setting the above options,
+complying with the following property strings:
+
+========================== =========== ============================================================
+Property Type Description
+========================== =========== ============================================================
+IndexIndentifier VT_LONG If specified an existing index will be
+ opened from the supplied storage manager with
+ the given index id. Behavior is unspecified
+ if the index id or the storage manager are incorrect.
+Dimension VT_ULONG Dimensionality of the data that will be inserted.
+IndexCapacity VT_ULONG The index node capacity. Default is 100.
+LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+FillFactor VT_DOUBLE The fill factor. Default is 70%
+TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+NearMinimumOverlapFactor VT_ULONG Default is 32.
+SplitDistributionFactor VT_DOUBLE Default is 0.4
+ReinsertFactor VT_DOUBLE Default is 0.3
+EnsureTightMBRs VT_BOOL Default is true
+IndexPoolCapacity VT_LONG Default is 100
+LeafPoolCapacity VT_LONG Default is 100
+RegionPoolCapacity VT_LONG Default is 1000
+PointPoolCapacity VT_LONG Default is 500
+========================== =========== ============================================================
+
+Performance
+------------------------------------------------------------------------------
+
+Dataset size, data density, etc. have nothing to do with capacity and page
+size. What you are trying to achieve is fast reads from the disk and take
+advantage of disk buffering and prefetching.
+
+Normally, you select the page size to be equal to the disk page size (depends
+on how you format the drive). Then you choose the node capacity to be enough
+to fill the whole page (including data entries if you have any).
+
+There is a tradeoff though in making node capacity too large. The larger the
+capacity, the longer the "for loops" for inserting, deleting, locating node
+entries take (CPU time). On the other hand, the larger the capacity the
+shorter the tree becomes, reducing the number of random IOs to reach the
+leaves. Hence, you might want to fit multiple nodes (of smaller capacity)
+inside a single page to balance I/O and CPU cost, in case your disk page size
+is too large.
+
+Finally, if you have enough buffer space to fit most of the index nodes in
+main memory, then large capacities do not make too much sense, because the
+height of the tree does not matter any more. Of course, the smaller the
+capacity, the larger the number of leaf nodes you will have to retrieve from
+disk for range queries (point queries and nearest neighbor queries will not
+suffer that much). So very small capacities hurt as well.
+
+There is another issue when trying to fit multiple nodes per page: Leftover
+space. You might have leftover space due to data entries that do not have a
+fixed size. Unfortunately, in that case, leftover space per page is lost,
+negatively impacting space usage.
+
+Selecting the right page size is easy; make it equal to the disk page size.
+Selecting the right node capacity is an art...
+
+------------------------------------------------------------------------------
+Contact Information
+------------------------------------------------------------------------------
+
+You can contact me at mhadji@gmail.com for further assistance. Please read the
+above information carefully and also do not be afraid to browse through the
+code and especially the test files inside regressiontest directory.
+
+------------------------------------------------------------------------------
+References
+------------------------------------------------------------------------------
+[guttman84] "R-Trees: A Dynamic Index Structure for Spatial Searching"
+ Antonin Guttman, Proc. 1984 ACM-SIGMOD Conference on Management of Data (1985), 47-57.
+[gamma94] "Design Patterns: Elements of Reusable Object-Oriented Software"
+ Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison Wesley. October 1994.
+
diff --git a/sci-libs/libspatialindex/svn/trunk/autogen.sh b/sci-libs/libspatialindex/svn/trunk/autogen.sh
new file mode 100755
index 000000000..0c5823b7f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/autogen.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# $Id: autogen.sh 61 2007-12-11 20:13:48Z hobu $
+#
+# Autotools boostrapping script
+#
+giveup()
+{
+ echo
+ echo " Something went wrong, giving up!"
+ echo
+ exit 1
+}
+
+OSTYPE=`uname -s`
+
+for libtoolize in glibtoolize libtoolize; do
+ LIBTOOLIZE=`which $libtoolize 2>/dev/null`
+ if test "$LIBTOOLIZE"; then
+ break;
+ fi
+done
+
+#AMFLAGS="--add-missing --copy --force-missing"
+AMFLAGS="--add-missing --copy"
+if test "$OSTYPE" = "IRIX" -o "$OSTYPE" = "IRIX64"; then
+ AMFLAGS=$AMFLAGS" --include-deps";
+fi
+
+echo "Running aclocal"
+aclocal || giveup
+#echo "Running autoheader"
+#autoheader || giveup
+echo "Running libtoolize"
+$LIBTOOLIZE --force --copy || giveup
+echo "Running automake"
+automake $AMFLAGS # || giveup
+echo "Running autoconf"
+autoconf || giveup
+
+echo "======================================"
+echo "Now you are ready to run './configure'"
+echo "======================================"
diff --git a/sci-libs/libspatialindex/svn/trunk/configure.ac b/sci-libs/libspatialindex/svn/trunk/configure.ac
new file mode 100644
index 000000000..dcf4e1cd1
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/configure.ac
@@ -0,0 +1,71 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+
+m4_define([sidx_version_major], [1])
+m4_define([sidx_version_minor], [6])
+m4_define([sidx_version_micro], [1])
+m4_define([sidx_version],
+ [sidx_version_major.sidx_version_minor.sidx_version_micro])
+
+AC_INIT([spatialindex], [sidx_version], [mhadji@gmail.com], [spatialindex-src])
+AC_CANONICAL_BUILD
+
+debug_default="no"
+CXXFLAGS="$CXXFLAGS"
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CXXCPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects])
+
+# Checks for header files.
+AC_CHECK_HEADERS(fcntl.h,, [AC_MSG_ERROR([cannot find fcntl.h, bailing out])])
+AC_CHECK_HEADERS(unistd.h,, [AC_MSG_ERROR([cannot find unistd.h, bailing out])])
+AC_CHECK_HEADERS(sys/types.h,, [AC_MSG_ERROR([cannot find sys/types.h, bailing out])])
+AC_CHECK_HEADERS(sys/stat.h,, [AC_MSG_ERROR([cannot find sys/stat.h, bailing out])])
+AC_CHECK_HEADERS(pthread.h, [LIBS="$LIBS -lpthread"])
+AC_CHECK_HEADERS(sys/resource.h,, [AC_MSG_ERROR([cannot find sys/resource.h, bailing out])])
+AC_CHECK_HEADERS(sys/time.h,, [AC_MSG_ERROR([cannot find sys/time.h, bailing out])])
+AC_CHECK_HEADERS(stdint.h,, [AC_MSG_ERROR([cannot find stdint.h, bailing out])])
+#MH_CXX_HEADER_TOOLS
+
+LIBS="$LIBS"
+
+AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging [default=$debug_default]],, enable_debug=$debug_default)
+
+if test "x$enable_debug" = "xyes"; then
+ CXXFLAGS="$CXXFLAGS -g -DDEBUG"
+ AC_MSG_RESULT(checking wether debug information is enabled... yes)
+else
+ CXXFLAGS="$CXXFLAGS -O2 -DNDEBUG"
+ AC_MSG_RESULT(checking wether debug information is enabled... no)
+fi
+
+# Checks for library functions.
+AC_CHECK_FUNCS([gettimeofday bzero memset memcpy bcopy])
+
+AC_CONFIG_FILES([ Makefile
+ include/Makefile
+ include/capi/Makefile
+ include/tools/Makefile
+ src/Makefile
+ src/capi/Makefile
+ src/spatialindex/Makefile
+ src/storagemanager/Makefile
+ src/rtree/Makefile
+ src/mvrtree/Makefile
+ src/tprtree/Makefile
+ src/tools/Makefile
+ regressiontest/Makefile
+ regressiontest/rtree/Makefile
+ regressiontest/mvrtree/Makefile
+ regressiontest/tprtree/Makefile])
+
+AC_OUTPUT
+
diff --git a/sci-libs/libspatialindex/svn/trunk/depcomp b/sci-libs/libspatialindex/svn/trunk/depcomp
new file mode 100644
index 000000000..11e2d3bfe
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/depcomp
@@ -0,0 +1,522 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2004-05-31.23
+
+# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit 0
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit 0
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # Dependencies are output in .lo.d with libtool 1.4.
+ # With libtool 1.5 they are output both in $dir.libs/$base.o.d
+ # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the
+ # latter, because the former will be cleaned when $dir.libs is
+ # erased.
+ tmpdepfile1="$dir.libs/$base.lo.d"
+ tmpdepfile2="$dir$base.o.d"
+ tmpdepfile3="$dir.libs/$base.d"
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1="$dir$base.o.d"
+ tmpdepfile2="$dir$base.d"
+ tmpdepfile3="$dir$base.d"
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ elif test -f "$tmpdepfile2"; then
+ tmpdepfile="$tmpdepfile2"
+ else
+ tmpdepfile="$tmpdepfile3"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/include/.svn/all-wcprops
new file mode 100644
index 000000000..f3def12ad
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/all-wcprops
@@ -0,0 +1,83 @@
+K 25
+svn:wc:ra_dav:version-url
+V 53
+/spatialindex/!svn/ver/199/spatialindex/trunk/include
+END
+MovingPoint.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/MovingPoint.h
+END
+Point.h
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/spatialindex/!svn/ver/154/spatialindex/trunk/include/Point.h
+END
+LineSegment.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/154/spatialindex/trunk/include/LineSegment.h
+END
+RTree.h
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/RTree.h
+END
+TimeRegion.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/TimeRegion.h
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/138/spatialindex/trunk/include/Makefile.am
+END
+MovingRegion.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/MovingRegion.h
+END
+Region.h
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/154/spatialindex/trunk/include/Region.h
+END
+MVRTree.h
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/MVRTree.h
+END
+SpatialIndex.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/154/spatialindex/trunk/include/SpatialIndex.h
+END
+TPRTree.h
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/TPRTree.h
+END
+Version.h
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/199/spatialindex/trunk/include/Version.h
+END
+TimePoint.h
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/TimePoint.h
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/dir-prop-base
new file mode 100644
index 000000000..a57f5442b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 21
+Makefile
+Makefile.in
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/entries b/sci-libs/libspatialindex/svn/trunk/include/.svn/entries
new file mode 100644
index 000000000..aeddcb130
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/entries
@@ -0,0 +1,476 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/include
+http://svn.gispython.org/spatialindex
+
+
+
+2010-12-04T21:22:32.514652Z
+199
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Point.h
+file
+
+
+
+
+2011-08-01T00:42:34.325197Z
+1ed931b7af77efe583a8337fa71fcf6d
+2009-10-21T17:35:24.248978Z
+154
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2294
+
+TimeRegion.h
+file
+
+
+
+
+2011-08-01T00:42:34.325197Z
+555523ea6f23f79e31f683e7f65b308a
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4037
+
+MovingRegion.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+00337cf9f8e1f3b6faee2fbfb434176e
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5995
+
+TimePoint.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+740894d437638cb0b385159a3d0f270a
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3299
+
+MovingPoint.h
+file
+
+
+
+
+2011-08-01T00:42:34.325197Z
+f547925166984beeec6b0ad48ad1d6ff
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2610
+
+LineSegment.h
+file
+
+
+
+
+2011-08-01T00:42:34.325197Z
+ccf565aff106626f0cb6361e6221d02d
+2009-10-21T17:35:24.248978Z
+154
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2695
+
+tools
+dir
+
+RTree.h
+file
+
+
+
+
+2011-08-01T00:42:34.325197Z
+0028957bca65f395aaee0ccfa3ff4d4a
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2669
+
+Region.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+7a5710c13bc43656d443e9af1881bfc5
+2009-10-21T17:35:24.248978Z
+154
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3156
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.325197Z
+118d4947ba41634c80fdcebe9227658b
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+341
+
+MVRTree.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+5e61009edcb9b663ab57d80d5e86cbd0
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2191
+
+Version.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+545d424eb2913568593a3760f1c6daa9
+2010-12-04T21:22:32.514652Z
+199
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1311
+
+TPRTree.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+56a57e2e61cf2a644972d4a6ebd697ae
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2170
+
+SpatialIndex.h
+file
+
+
+
+
+2011-08-01T00:42:34.329111Z
+6b31cbdc93b1939610009bd5e6643e1c
+2009-10-21T17:35:24.248978Z
+154
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7886
+
+capi
+dir
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/LineSegment.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/LineSegment.h.svn-base
new file mode 100644
index 000000000..ab09e5291
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/LineSegment.h.svn-base
@@ -0,0 +1,83 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL LineSegment : public Tools::IObject, public virtual IShape
+ {
+ public:
+ LineSegment();
+ LineSegment(const double* startPoint, const double* endPoint, uint32_t dimension);
+ LineSegment(const Point& startPoint, const Point& endPoint);
+ LineSegment(const LineSegment& l);
+ virtual ~LineSegment();
+
+ virtual LineSegment& operator=(const LineSegment& p);
+ virtual bool operator==(const LineSegment& p) const;
+
+ //
+ // IObject interface
+ //
+ virtual LineSegment* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ //
+ // IShape interface
+ //
+ virtual bool intersectsShape(const IShape& in) const;
+ virtual bool containsShape(const IShape& in) const;
+ virtual bool touchesShape(const IShape& in) const;
+ virtual void getCenter(Point& out) const;
+ virtual uint32_t getDimension() const;
+ virtual void getMBR(Region& out) const;
+ virtual double getArea() const;
+ virtual double getMinimumDistance(const IShape& in) const;
+
+ virtual double getMinimumDistance(const Point& p) const;
+ //virtual double getMinimumDistance(const Region& r) const;
+ virtual double getRelativeMinimumDistance(const Point& p) const;
+ virtual double getRelativeMaximumDistance(const Region& r) const;
+ virtual double getAngleOfPerpendicularRay();
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ uint32_t m_dimension;
+ double* m_pStartPoint;
+ double* m_pEndPoint;
+
+ friend class Region;
+ friend class Point;
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const LineSegment& pt);
+ }; // Point
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const LineSegment& pt);
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MVRTree.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MVRTree.h.svn-base
new file mode 100644
index 000000000..aa1aeaab5
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MVRTree.h.svn-base
@@ -0,0 +1,83 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ SIDX_DLL enum MVRTreeVariant
+ {
+ RV_LINEAR = 0x0,
+ RV_QUADRATIC,
+ RV_RSTAR
+ };
+
+ SIDX_DLL enum PersistenObjectIdentifier
+ {
+ PersistentIndex = 0x1,
+ PersistentLeaf = 0x2
+ };
+
+ SIDX_DLL enum RangeQueryType
+ {
+ ContainmentQuery = 0x1,
+ IntersectionQuery = 0x2
+ };
+
+ class SIDX_DLL Data : public IData, public Tools::ISerializable
+ {
+ public:
+ Data(uint32_t len, byte* pData, TimeRegion& r, id_type id);
+ virtual ~Data();
+
+ virtual Data* clone();
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+ virtual void getData(uint32_t& len, byte** data) const;
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ id_type m_id;
+ TimeRegion m_region;
+ byte* m_pData;
+ uint32_t m_dataLength;
+ }; // Data
+
+ SIDX_DLL ISpatialIndex* returnMVRTree(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL ISpatialIndex* createNewMVRTree(
+ IStorageManager& in,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ MVRTreeVariant rv,
+ id_type& out_indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* loadMVRTree(
+ IStorageManager& in,
+ id_type indexIdentifier
+ );
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..e061275ce
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,16 @@
+SUBDIRS = tools capi
+
+spatialindexdir = $(includedir)/spatialindex
+
+spatialindex_HEADERS = SpatialIndex.h \
+ RTree.h \
+ MVRTree.h \
+ TPRTree.h \
+ Point.h \
+ Region.h \
+ LineSegment.h \
+ TimePoint.h \
+ TimeRegion.h \
+ MovingPoint.h \
+ MovingRegion.h \
+ Version.h \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingPoint.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingPoint.h.svn-base
new file mode 100644
index 000000000..bca600a5b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingPoint.h.svn-base
@@ -0,0 +1,79 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL MovingPoint : public TimePoint, public IEvolvingShape
+ {
+ public:
+ MovingPoint();
+ MovingPoint(const double* pCoords, const double* pVCoords, const Tools::IInterval& ti, uint32_t dimension);
+ MovingPoint(const double* pCoords, const double* pVCoords, double tStart, double tEnd, uint32_t dimension);
+ MovingPoint(const Point& p, const Point& vp, const Tools::IInterval& ti);
+ MovingPoint(const Point& p, const Point& vp, double tStart, double tEnd);
+ MovingPoint(const MovingPoint& p);
+ virtual ~MovingPoint();
+
+ virtual MovingPoint& operator=(const MovingPoint& p);
+ virtual bool operator==(const MovingPoint& p) const;
+
+ virtual double getCoord(uint32_t index, double t) const;
+ virtual double getProjectedCoord(uint32_t index, double t) const;
+ virtual double getVCoord(uint32_t index) const;
+ virtual void getPointAtTime(double t, Point& out) const;
+
+ //
+ // IObject interface
+ //
+ virtual MovingPoint* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // IEvolvingShape interface
+ //
+ virtual void getVMBR(Region& out) const;
+ virtual void getMBRAtTime(double t, Region& out) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ private:
+ void initialize(
+ const double* pCoords, const double* pVCoords,
+ double tStart, double tEnd, uint32_t dimension);
+
+ public:
+ double* m_pVCoords;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingPoint& pt);
+ }; // MovingPoint
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingPoint& pt);
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingRegion.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingRegion.h.svn-base
new file mode 100644
index 000000000..d25c50688
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/MovingRegion.h.svn-base
@@ -0,0 +1,155 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL MovingRegion : public TimeRegion, public IEvolvingShape
+ {
+ public:
+ MovingRegion();
+ MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ const Tools::IInterval& ti, uint32_t dimension);
+ MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension);
+ MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ const Tools::IInterval& ti);
+ MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ double tStart, double tEnd);
+ MovingRegion(const Region& mbr, const Region& vbr, const Tools::IInterval& ivI);
+ MovingRegion(const Region& mbr, const Region& vbr, double tStart, double tEnd);
+ MovingRegion(const MovingPoint& low, const MovingPoint& high);
+ MovingRegion(const MovingRegion& in);
+ virtual ~MovingRegion();
+
+ virtual MovingRegion& operator=(const MovingRegion& r);
+ virtual bool operator==(const MovingRegion&) const;
+
+ bool isShrinking() const;
+
+ virtual double getLow(uint32_t index, double t) const;
+ virtual double getHigh(uint32_t index, double t) const;
+ virtual double getExtrapolatedLow(uint32_t index, double t) const;
+ virtual double getExtrapolatedHigh(uint32_t index, double t) const;
+ virtual double getVLow(uint32_t index) const;
+ virtual double getVHigh(uint32_t index) const;
+
+ virtual bool intersectsRegionInTime(const MovingRegion& r) const;
+ virtual bool intersectsRegionInTime(const MovingRegion& r, Tools::IInterval& out) const;
+ virtual bool intersectsRegionInTime(const Tools::IInterval& ivI, const MovingRegion& r, Tools::IInterval& ret) const;
+ virtual bool containsRegionInTime(const MovingRegion& r) const;
+ virtual bool containsRegionInTime(const Tools::IInterval& ivI, const MovingRegion& r) const;
+ virtual bool containsRegionAfterTime(double t, const MovingRegion& r) const;
+
+ virtual double getProjectedSurfaceAreaInTime() const;
+ virtual double getProjectedSurfaceAreaInTime(const Tools::IInterval& ivI) const;
+
+ virtual double getCenterDistanceInTime(const MovingRegion& r) const;
+ virtual double getCenterDistanceInTime(const Tools::IInterval& ivI, const MovingRegion& r) const;
+
+ virtual bool intersectsRegionAtTime(double t, const MovingRegion& r) const;
+ virtual bool containsRegionAtTime(double t, const MovingRegion& r) const;
+
+ virtual bool intersectsPointInTime(const MovingPoint& p) const;
+ virtual bool intersectsPointInTime(const MovingPoint& p, Tools::IInterval& out) const;
+ virtual bool intersectsPointInTime(const Tools::IInterval& ivI, const MovingPoint& p, Tools::IInterval& out) const;
+ virtual bool containsPointInTime(const MovingPoint& p) const;
+ virtual bool containsPointInTime(const Tools::IInterval& ivI, const MovingPoint& p) const;
+
+ //virtual bool intersectsPointAtTime(double t, const MovingRegion& in) const;
+ //virtual bool containsPointAtTime(double t, const MovingRegion& in) const;
+
+ virtual void combineRegionInTime(const MovingRegion& r);
+ virtual void combineRegionAfterTime(double t, const MovingRegion& r);
+ virtual void getCombinedRegionInTime(MovingRegion& out, const MovingRegion& in) const;
+ virtual void getCombinedRegionAfterTime(double t, MovingRegion& out, const MovingRegion& in) const;
+
+ virtual double getIntersectingAreaInTime(const MovingRegion& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const MovingRegion& r) const;
+
+ //
+ // IObject interface
+ //
+ virtual MovingRegion* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // IEvolvingShape interface
+ //
+ virtual void getVMBR(Region& out) const;
+ virtual void getMBRAtTime(double t, Region& out) const;
+
+ //
+ // ITimeShape interface
+ //
+ virtual double getAreaInTime() const;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ private:
+ void initialize(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension);
+
+ public:
+ class CrossPoint
+ {
+ public:
+ double m_t;
+ uint32_t m_dimension;
+ uint32_t m_boundary;
+ const MovingRegion* m_to;
+
+ struct ascending: public std::binary_function<CrossPoint&, CrossPoint&, bool>
+ {
+ bool operator()(const CrossPoint& __x, const CrossPoint& __y) const { return __x.m_t > __y.m_t; }
+ };
+ }; // CrossPoint
+
+ public:
+ double* m_pVLow;
+ double* m_pVHigh;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingRegion& r);
+ }; // MovingRegion
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingRegion& r);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Point.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Point.h.svn-base
new file mode 100644
index 000000000..51cb4b618
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Point.h.svn-base
@@ -0,0 +1,77 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL Point : public Tools::IObject, public virtual IShape
+ {
+ public:
+ Point();
+ Point(const double* pCoords, uint32_t dimension);
+ Point(const Point& p);
+ virtual ~Point();
+
+ virtual Point& operator=(const Point& p);
+ virtual bool operator==(const Point& p) const;
+
+ //
+ // IObject interface
+ //
+ virtual Point* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ //
+ // IShape interface
+ //
+ virtual bool intersectsShape(const IShape& in) const;
+ virtual bool containsShape(const IShape& in) const;
+ virtual bool touchesShape(const IShape& in) const;
+ virtual void getCenter(Point& out) const;
+ virtual uint32_t getDimension() const;
+ virtual void getMBR(Region& out) const;
+ virtual double getArea() const;
+ virtual double getMinimumDistance(const IShape& in) const;
+
+ virtual double getMinimumDistance(const Point& p) const;
+
+ virtual double getCoordinate(uint32_t index) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ uint32_t m_dimension;
+ double* m_pCoords;
+
+ friend class Region;
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const Point& pt);
+ }; // Point
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Point& pt);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/RTree.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/RTree.h.svn-base
new file mode 100644
index 000000000..4303b9e96
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/RTree.h.svn-base
@@ -0,0 +1,102 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ SIDX_DLL enum RTreeVariant
+ {
+ RV_LINEAR = 0x0,
+ RV_QUADRATIC,
+ RV_RSTAR
+ };
+
+ SIDX_DLL enum BulkLoadMethod
+ {
+ BLM_STR = 0x0
+ };
+
+ SIDX_DLL enum PersistenObjectIdentifier
+ {
+ PersistentIndex = 0x1,
+ PersistentLeaf = 0x2
+ };
+
+ SIDX_DLL enum RangeQueryType
+ {
+ ContainmentQuery = 0x1,
+ IntersectionQuery = 0x2
+ };
+
+ class SIDX_DLL Data : public IData, public Tools::ISerializable
+ {
+ public:
+ Data(uint32_t len, byte* pData, Region& r, id_type id);
+ virtual ~Data();
+
+ virtual Data* clone();
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+ virtual void getData(uint32_t& len, byte** data) const;
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ id_type m_id;
+ Region m_region;
+ byte* m_pData;
+ uint32_t m_dataLength;
+ }; // Data
+
+ SIDX_DLL ISpatialIndex* returnRTree(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL ISpatialIndex* createNewRTree(
+ IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ RTreeVariant rv,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ RTreeVariant rv,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ IStorageManager& sm,
+ Tools::PropertySet& ps,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* loadRTree(IStorageManager& in, id_type indexIdentifier);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Region.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Region.h.svn-base
new file mode 100644
index 000000000..feddaee10
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Region.h.svn-base
@@ -0,0 +1,97 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL Region : public Tools::IObject, public virtual IShape
+ {
+ public:
+ Region();
+ Region(const double* pLow, const double* pHigh, uint32_t dimension);
+ Region(const Point& low, const Point& high);
+ Region(const Region& in);
+ virtual ~Region();
+
+ virtual Region& operator=(const Region& r);
+ virtual bool operator==(const Region&) const;
+
+ //
+ // IObject interface
+ //
+ virtual Region* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ //
+ // IShape interface
+ //
+ virtual bool intersectsShape(const IShape& in) const;
+ virtual bool containsShape(const IShape& in) const;
+ virtual bool touchesShape(const IShape& in) const;
+ virtual void getCenter(Point& out) const;
+ virtual uint32_t getDimension() const;
+ virtual void getMBR(Region& out) const;
+ virtual double getArea() const;
+ virtual double getMinimumDistance(const IShape& in) const;
+
+ virtual bool intersectsRegion(const Region& in) const;
+ virtual bool containsRegion(const Region& in) const;
+ virtual bool touchesRegion(const Region& in) const;
+ virtual double getMinimumDistance(const Region& in) const;
+
+ virtual bool containsPoint(const Point& in) const;
+ virtual bool touchesPoint(const Point& in) const;
+ virtual double getMinimumDistance(const Point& in) const;
+
+ virtual Region getIntersectingRegion(const Region& r) const;
+ virtual double getIntersectingArea(const Region& in) const;
+ virtual double getMargin() const;
+
+ virtual void combineRegion(const Region& in);
+ virtual void combinePoint(const Point& in);
+ virtual void getCombinedRegion(Region& out, const Region& in) const;
+
+ virtual double getLow(uint32_t index) const;
+ virtual double getHigh(uint32_t index) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ private:
+ void initialize(const double* pLow, const double* pHigh, uint32_t dimension);
+
+ public:
+ uint32_t m_dimension;
+ double* m_pLow;
+ double* m_pHigh;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const Region& r);
+ }; // Region
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Region& r);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/SpatialIndex.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/SpatialIndex.h.svn-base
new file mode 100644
index 000000000..fe6cf679b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/SpatialIndex.h.svn-base
@@ -0,0 +1,250 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "tools/Tools.h"
+
+# if !HAVE_BZERO
+# define bzero(d, n) memset((d), 0, (n))
+# endif
+
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661922
+#endif
+
+namespace SpatialIndex
+{
+ class Point;
+ class Region;
+
+ typedef int64_t id_type;
+
+ SIDX_DLL enum CommandType
+ {
+ CT_NODEREAD = 0x0,
+ CT_NODEDELETE,
+ CT_NODEWRITE
+ };
+
+ class SIDX_DLL InvalidPageException : public Tools::Exception
+ {
+ public:
+ InvalidPageException(id_type id);
+ virtual ~InvalidPageException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // InvalidPageException
+
+ //
+ // Interfaces
+ //
+
+ class SIDX_DLL IShape : public Tools::ISerializable
+ {
+ public:
+ virtual bool intersectsShape(const IShape& in) const = 0;
+ virtual bool containsShape(const IShape& in) const = 0;
+ virtual bool touchesShape(const IShape& in) const = 0;
+ virtual void getCenter(Point& out) const = 0;
+ virtual uint32_t getDimension() const = 0;
+ virtual void getMBR(Region& out) const = 0;
+ virtual double getArea() const = 0;
+ virtual double getMinimumDistance(const IShape& in) const = 0;
+ virtual ~IShape() {}
+ }; // IShape
+
+ class SIDX_DLL ITimeShape : public Tools::IInterval
+ {
+ public:
+ virtual bool intersectsShapeInTime(const ITimeShape& in) const = 0;
+ virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0;
+ virtual bool containsShapeInTime(const ITimeShape& in) const = 0;
+ virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0;
+ virtual bool touchesShapeInTime(const ITimeShape& in) const = 0;
+ virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0;
+ virtual double getAreaInTime() const = 0;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const = 0;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const = 0;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const = 0;
+ virtual ~ITimeShape() {}
+ }; // ITimeShape
+
+ class SIDX_DLL IEvolvingShape
+ {
+ public:
+ virtual void getVMBR(Region& out) const = 0;
+ virtual void getMBRAtTime(double t, Region& out) const = 0;
+ virtual ~IEvolvingShape() {}
+ }; // IEvolvingShape
+
+ class SIDX_DLL IEntry : public Tools::IObject
+ {
+ public:
+ virtual id_type getIdentifier() const = 0;
+ virtual void getShape(IShape** out) const = 0;
+ virtual ~IEntry() {}
+ }; // IEntry
+
+ class SIDX_DLL INode : public IEntry, public Tools::ISerializable
+ {
+ public:
+ virtual uint32_t getChildrenCount() const = 0;
+ virtual id_type getChildIdentifier(uint32_t index) const = 0;
+ virtual void getChildData(uint32_t index, uint32_t& len, byte** data) const = 0;
+ virtual void getChildShape(uint32_t index, IShape** out) const = 0;
+ virtual uint32_t getLevel() const = 0;
+ virtual bool isIndex() const = 0;
+ virtual bool isLeaf() const = 0;
+ virtual ~INode() {}
+ }; // INode
+
+ class SIDX_DLL IData : public IEntry
+ {
+ public:
+ virtual void getData(uint32_t& len, byte** data) const = 0;
+ virtual ~IData() {}
+ }; // IData
+
+ class SIDX_DLL IDataStream : public Tools::IObjectStream
+ {
+ public:
+ virtual IData* getNext() = 0;
+ virtual ~IDataStream() {}
+ }; // IDataStream
+
+ class SIDX_DLL ICommand
+ {
+ public:
+ virtual void execute(const INode& in) = 0;
+ virtual ~ICommand() {}
+ }; // ICommand
+
+ class SIDX_DLL INearestNeighborComparator
+ {
+ public:
+ virtual double getMinimumDistance(const IShape& query, const IShape& entry) = 0;
+ virtual double getMinimumDistance(const IShape& query, const IData& data) = 0;
+ virtual ~INearestNeighborComparator() {}
+ }; // INearestNeighborComparator
+
+ class SIDX_DLL IStorageManager
+ {
+ public:
+ virtual void loadByteArray(const id_type id, uint32_t& len, byte** data) = 0;
+ virtual void storeByteArray(id_type& id, const uint32_t len, const byte* const data) = 0;
+ virtual void deleteByteArray(const id_type id) = 0;
+ virtual ~IStorageManager() {}
+ }; // IStorageManager
+
+ class SIDX_DLL IVisitor
+ {
+ public:
+ virtual void visitNode(const INode& in) = 0;
+ virtual void visitData(const IData& in) = 0;
+ virtual void visitData(std::vector<const IData*>& v) = 0;
+ virtual ~IVisitor() {}
+ }; // IVisitor
+
+ class SIDX_DLL IQueryStrategy
+ {
+ public:
+ virtual void getNextEntry(const IEntry& previouslyFetched, id_type& nextEntryToFetch, bool& bFetchNextEntry) = 0;
+ virtual ~IQueryStrategy() {}
+ }; // IQueryStrategy
+
+ class SIDX_DLL IStatistics
+ {
+ public:
+ virtual uint64_t getReads() const = 0;
+ virtual uint64_t getWrites() const = 0;
+ virtual uint32_t getNumberOfNodes() const = 0;
+ virtual uint64_t getNumberOfData() const = 0;
+ virtual ~IStatistics() {}
+ }; // IStatistics
+
+ class SIDX_DLL ISpatialIndex
+ {
+ public:
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier) = 0;
+ virtual bool deleteData(const IShape& shape, id_type shapeIdentifier) = 0;
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v) = 0;
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v) = 0;
+ virtual void pointLocationQuery(const Point& query, IVisitor& v) = 0;
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc) = 0;
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v) = 0;
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v) = 0;
+ virtual void queryStrategy(IQueryStrategy& qs) = 0;
+ virtual void getIndexProperties(Tools::PropertySet& out) const = 0;
+ virtual void addCommand(ICommand* in, CommandType ct) = 0;
+ virtual bool isIndexValid() = 0;
+ virtual void getStatistics(IStatistics** out) const = 0;
+ virtual ~ISpatialIndex() {}
+
+ }; // ISpatialIndex
+
+ namespace StorageManager
+ {
+ SIDX_DLL enum StorageManagerConstants
+ {
+ EmptyPage = -0x1,
+ NewPage = -0x1
+ };
+
+ class SIDX_DLL IBuffer : public IStorageManager
+ {
+ public:
+ virtual uint64_t getHits() = 0;
+ virtual void clear() = 0;
+ virtual ~IBuffer() {}
+ }; // IBuffer
+
+ SIDX_DLL IStorageManager* returnMemoryStorageManager(Tools::PropertySet& in);
+ SIDX_DLL IStorageManager* createNewMemoryStorageManager();
+
+ SIDX_DLL IStorageManager* returnDiskStorageManager(Tools::PropertySet& in);
+ SIDX_DLL IStorageManager* createNewDiskStorageManager(std::string& baseName, uint32_t pageSize);
+ SIDX_DLL IStorageManager* loadDiskStorageManager(std::string& baseName);
+
+ SIDX_DLL IBuffer* returnRandomEvictionsBuffer(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL IBuffer* createNewRandomEvictionsBuffer(IStorageManager& in, uint32_t capacity, bool bWriteThrough);
+ }
+
+ //
+ // Global functions
+ //
+ SIDX_DLL std::ostream& operator<<(std::ostream&, const ISpatialIndex&);
+ SIDX_DLL std::ostream& operator<<(std::ostream&, const IStatistics&);
+}
+
+#include "Point.h"
+#include "Region.h"
+#include "LineSegment.h"
+#include "TimePoint.h"
+#include "TimeRegion.h"
+#include "MovingPoint.h"
+#include "MovingRegion.h"
+#include "RTree.h"
+#include "MVRTree.h"
+#include "TPRTree.h"
+#include "Version.h"
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TPRTree.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TPRTree.h.svn-base
new file mode 100644
index 000000000..1af9818f9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TPRTree.h.svn-base
@@ -0,0 +1,78 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ SIDX_DLL enum TPRTreeVariant
+ {
+ TPRV_RSTAR = 0x0
+ };
+
+ SIDX_DLL enum PersistenObjectIdentifier
+ {
+ PersistentIndex = 0x1,
+ PersistentLeaf = 0x2
+ };
+
+ SIDX_DLL enum RangeQueryType
+ {
+ ContainmentQuery = 0x1,
+ IntersectionQuery = 0x2
+ };
+
+ class SIDX_DLL Data : public IData, public Tools::ISerializable
+ {
+ public:
+ Data(uint32_t len, byte* pData, MovingRegion& r, id_type id);
+ virtual ~Data();
+
+ virtual Data* clone();
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+ virtual void getData(uint32_t& len, byte** data) const;
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ id_type m_id;
+ MovingRegion m_region;
+ byte* m_pData;
+ uint32_t m_dataLength;
+ }; // Data
+
+ SIDX_DLL ISpatialIndex* returnTPRTree(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL ISpatialIndex* createNewTPRTree(
+ IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ TPRTreeVariant rv,
+ double horizon,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* loadTPRTree(IStorageManager& in, id_type indexIdentifier);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimePoint.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimePoint.h.svn-base
new file mode 100644
index 000000000..3d1de4e7d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimePoint.h.svn-base
@@ -0,0 +1,89 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL TimePoint : public Point, public ITimeShape
+ {
+ public:
+ TimePoint();
+ TimePoint(const double* pCoords, const Tools::IInterval& ti, uint32_t dimension);
+ TimePoint(const double* pCoords, double tStart, double tEnd, uint32_t dimension);
+ TimePoint(const Point& p, const Tools::IInterval& ti);
+ TimePoint(const Point& p, double tStart, double tEnd);
+ TimePoint(const TimePoint& p);
+ virtual ~TimePoint();
+
+ virtual TimePoint& operator=(const TimePoint& p);
+ virtual bool operator==(const TimePoint& p) const;
+
+ //
+ // IObject interface
+ //
+ virtual TimePoint* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // ITimeShape interface
+ //
+ virtual bool intersectsShapeInTime(const ITimeShape& in) const;
+ virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual double getAreaInTime() const;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const;
+
+ //
+ // IInterval interface
+ //
+ virtual Tools::IInterval& operator=(const Tools::IInterval&);
+ virtual double getLowerBound() const;
+ virtual double getUpperBound() const;
+ virtual void setBounds(double, double);
+ virtual bool intersectsInterval(const Tools::IInterval& ti) const;
+ virtual bool intersectsInterval(Tools::IntervalType t, const double start, const double end) const;
+ virtual bool containsInterval(const Tools::IInterval& ti) const;
+ virtual Tools::IntervalType getIntervalType() const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ double m_startTime;
+ double m_endTime;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimePoint& pt);
+ }; // TimePoint
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimePoint& pt);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimeRegion.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimeRegion.h.svn-base
new file mode 100644
index 000000000..46b720b45
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/TimeRegion.h.svn-base
@@ -0,0 +1,102 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL TimeRegion : public Region, public ITimeShape
+ {
+ public:
+ TimeRegion();
+ TimeRegion(const double* pLow, const double* pHigh, const Tools::IInterval& ti, uint32_t dimension);
+ TimeRegion(const double* pLow, const double* pHigh, double tStart, double tEnd, uint32_t dimension);
+ TimeRegion(const Point& low, const Point& high, const Tools::IInterval& ti);
+ TimeRegion(const Point& low, const Point& high, double tStart, double tEnd);
+ TimeRegion(const Region& in, const Tools::IInterval& ti);
+ TimeRegion(const Region& in, double tStart, double tEnd);
+ TimeRegion(const TimePoint& low, const TimePoint& high);
+ TimeRegion(const TimeRegion& in);
+ virtual ~TimeRegion();
+
+ virtual TimeRegion& operator=(const TimeRegion& r);
+ virtual bool operator==(const TimeRegion&) const;
+
+ virtual bool intersectsRegionInTime(const TimeRegion& in) const;
+ virtual bool containsRegionInTime(const TimeRegion& in) const;
+ virtual bool touchesRegionInTime(const TimeRegion& in) const;
+
+ virtual bool containsPointInTime(const TimePoint& in) const;
+ virtual bool touchesPointInTime(const TimePoint& in) const;
+
+ virtual void combineRegionInTime(const TimeRegion& in);
+ virtual void getCombinedRegionInTime(TimeRegion& out, const TimeRegion& in) const;
+
+ //
+ // IObject interface
+ //
+ virtual TimeRegion* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // ITimeShape interface
+ //
+ virtual bool intersectsShapeInTime(const ITimeShape& in) const;
+ virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual double getAreaInTime() const;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const;
+
+ //
+ // IInterval interface
+ //
+ virtual Tools::IInterval& operator=(const Tools::IInterval&);
+ virtual double getLowerBound() const;
+ virtual double getUpperBound() const;
+ virtual void setBounds(double, double);
+ virtual bool intersectsInterval(const Tools::IInterval& ti) const;
+ virtual bool intersectsInterval(Tools::IntervalType t, const double start, const double end) const;
+ virtual bool containsInterval(const Tools::IInterval& ti) const;
+ virtual Tools::IntervalType getIntervalType() const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ double m_startTime;
+ double m_endTime;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimeRegion& r);
+ }; // TimeRegion
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimeRegion& r);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Version.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Version.h.svn-base
new file mode 100644
index 000000000..3ecf5f687
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/.svn/text-base/Version.h.svn-base
@@ -0,0 +1,42 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#ifndef SIDX_VERSION_MAJOR
+#define SIDX_VERSION_MAJOR 1
+#define SIDX_VERSION_MINOR 6
+#define SIDX_VERSION_REV 1
+#define SIDX_VERSION_BUILD 0
+#endif
+
+#ifndef SIDX_VERSION_NUM
+#define SIDX_VERSION_NUM (SIDX_VERSION_MAJOR*1000+SIDX_VERSION_MINOR*100+SIDX_VERSION_REV*10+SIDX_VERSION_BUILD)
+#endif
+
+#ifndef SIDX_RELEASE_DATE
+#define SIDX_RELEASE_DATE 20101204
+#endif
+
+#ifndef SIDX_RELEASE_NAME
+#define SIDX_RELEASE_NAME "1.6.1"
+#endif
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/LineSegment.h b/sci-libs/libspatialindex/svn/trunk/include/LineSegment.h
new file mode 100644
index 000000000..ab09e5291
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/LineSegment.h
@@ -0,0 +1,83 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL LineSegment : public Tools::IObject, public virtual IShape
+ {
+ public:
+ LineSegment();
+ LineSegment(const double* startPoint, const double* endPoint, uint32_t dimension);
+ LineSegment(const Point& startPoint, const Point& endPoint);
+ LineSegment(const LineSegment& l);
+ virtual ~LineSegment();
+
+ virtual LineSegment& operator=(const LineSegment& p);
+ virtual bool operator==(const LineSegment& p) const;
+
+ //
+ // IObject interface
+ //
+ virtual LineSegment* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ //
+ // IShape interface
+ //
+ virtual bool intersectsShape(const IShape& in) const;
+ virtual bool containsShape(const IShape& in) const;
+ virtual bool touchesShape(const IShape& in) const;
+ virtual void getCenter(Point& out) const;
+ virtual uint32_t getDimension() const;
+ virtual void getMBR(Region& out) const;
+ virtual double getArea() const;
+ virtual double getMinimumDistance(const IShape& in) const;
+
+ virtual double getMinimumDistance(const Point& p) const;
+ //virtual double getMinimumDistance(const Region& r) const;
+ virtual double getRelativeMinimumDistance(const Point& p) const;
+ virtual double getRelativeMaximumDistance(const Region& r) const;
+ virtual double getAngleOfPerpendicularRay();
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ uint32_t m_dimension;
+ double* m_pStartPoint;
+ double* m_pEndPoint;
+
+ friend class Region;
+ friend class Point;
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const LineSegment& pt);
+ }; // Point
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const LineSegment& pt);
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/MVRTree.h b/sci-libs/libspatialindex/svn/trunk/include/MVRTree.h
new file mode 100644
index 000000000..aa1aeaab5
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/MVRTree.h
@@ -0,0 +1,83 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ SIDX_DLL enum MVRTreeVariant
+ {
+ RV_LINEAR = 0x0,
+ RV_QUADRATIC,
+ RV_RSTAR
+ };
+
+ SIDX_DLL enum PersistenObjectIdentifier
+ {
+ PersistentIndex = 0x1,
+ PersistentLeaf = 0x2
+ };
+
+ SIDX_DLL enum RangeQueryType
+ {
+ ContainmentQuery = 0x1,
+ IntersectionQuery = 0x2
+ };
+
+ class SIDX_DLL Data : public IData, public Tools::ISerializable
+ {
+ public:
+ Data(uint32_t len, byte* pData, TimeRegion& r, id_type id);
+ virtual ~Data();
+
+ virtual Data* clone();
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+ virtual void getData(uint32_t& len, byte** data) const;
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ id_type m_id;
+ TimeRegion m_region;
+ byte* m_pData;
+ uint32_t m_dataLength;
+ }; // Data
+
+ SIDX_DLL ISpatialIndex* returnMVRTree(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL ISpatialIndex* createNewMVRTree(
+ IStorageManager& in,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ MVRTreeVariant rv,
+ id_type& out_indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* loadMVRTree(
+ IStorageManager& in,
+ id_type indexIdentifier
+ );
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/Makefile.am b/sci-libs/libspatialindex/svn/trunk/include/Makefile.am
new file mode 100644
index 000000000..e061275ce
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS = tools capi
+
+spatialindexdir = $(includedir)/spatialindex
+
+spatialindex_HEADERS = SpatialIndex.h \
+ RTree.h \
+ MVRTree.h \
+ TPRTree.h \
+ Point.h \
+ Region.h \
+ LineSegment.h \
+ TimePoint.h \
+ TimeRegion.h \
+ MovingPoint.h \
+ MovingRegion.h \
+ Version.h \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/include/MovingPoint.h b/sci-libs/libspatialindex/svn/trunk/include/MovingPoint.h
new file mode 100644
index 000000000..bca600a5b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/MovingPoint.h
@@ -0,0 +1,79 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL MovingPoint : public TimePoint, public IEvolvingShape
+ {
+ public:
+ MovingPoint();
+ MovingPoint(const double* pCoords, const double* pVCoords, const Tools::IInterval& ti, uint32_t dimension);
+ MovingPoint(const double* pCoords, const double* pVCoords, double tStart, double tEnd, uint32_t dimension);
+ MovingPoint(const Point& p, const Point& vp, const Tools::IInterval& ti);
+ MovingPoint(const Point& p, const Point& vp, double tStart, double tEnd);
+ MovingPoint(const MovingPoint& p);
+ virtual ~MovingPoint();
+
+ virtual MovingPoint& operator=(const MovingPoint& p);
+ virtual bool operator==(const MovingPoint& p) const;
+
+ virtual double getCoord(uint32_t index, double t) const;
+ virtual double getProjectedCoord(uint32_t index, double t) const;
+ virtual double getVCoord(uint32_t index) const;
+ virtual void getPointAtTime(double t, Point& out) const;
+
+ //
+ // IObject interface
+ //
+ virtual MovingPoint* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // IEvolvingShape interface
+ //
+ virtual void getVMBR(Region& out) const;
+ virtual void getMBRAtTime(double t, Region& out) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ private:
+ void initialize(
+ const double* pCoords, const double* pVCoords,
+ double tStart, double tEnd, uint32_t dimension);
+
+ public:
+ double* m_pVCoords;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingPoint& pt);
+ }; // MovingPoint
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingPoint& pt);
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/MovingRegion.h b/sci-libs/libspatialindex/svn/trunk/include/MovingRegion.h
new file mode 100644
index 000000000..d25c50688
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/MovingRegion.h
@@ -0,0 +1,155 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL MovingRegion : public TimeRegion, public IEvolvingShape
+ {
+ public:
+ MovingRegion();
+ MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ const Tools::IInterval& ti, uint32_t dimension);
+ MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension);
+ MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ const Tools::IInterval& ti);
+ MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ double tStart, double tEnd);
+ MovingRegion(const Region& mbr, const Region& vbr, const Tools::IInterval& ivI);
+ MovingRegion(const Region& mbr, const Region& vbr, double tStart, double tEnd);
+ MovingRegion(const MovingPoint& low, const MovingPoint& high);
+ MovingRegion(const MovingRegion& in);
+ virtual ~MovingRegion();
+
+ virtual MovingRegion& operator=(const MovingRegion& r);
+ virtual bool operator==(const MovingRegion&) const;
+
+ bool isShrinking() const;
+
+ virtual double getLow(uint32_t index, double t) const;
+ virtual double getHigh(uint32_t index, double t) const;
+ virtual double getExtrapolatedLow(uint32_t index, double t) const;
+ virtual double getExtrapolatedHigh(uint32_t index, double t) const;
+ virtual double getVLow(uint32_t index) const;
+ virtual double getVHigh(uint32_t index) const;
+
+ virtual bool intersectsRegionInTime(const MovingRegion& r) const;
+ virtual bool intersectsRegionInTime(const MovingRegion& r, Tools::IInterval& out) const;
+ virtual bool intersectsRegionInTime(const Tools::IInterval& ivI, const MovingRegion& r, Tools::IInterval& ret) const;
+ virtual bool containsRegionInTime(const MovingRegion& r) const;
+ virtual bool containsRegionInTime(const Tools::IInterval& ivI, const MovingRegion& r) const;
+ virtual bool containsRegionAfterTime(double t, const MovingRegion& r) const;
+
+ virtual double getProjectedSurfaceAreaInTime() const;
+ virtual double getProjectedSurfaceAreaInTime(const Tools::IInterval& ivI) const;
+
+ virtual double getCenterDistanceInTime(const MovingRegion& r) const;
+ virtual double getCenterDistanceInTime(const Tools::IInterval& ivI, const MovingRegion& r) const;
+
+ virtual bool intersectsRegionAtTime(double t, const MovingRegion& r) const;
+ virtual bool containsRegionAtTime(double t, const MovingRegion& r) const;
+
+ virtual bool intersectsPointInTime(const MovingPoint& p) const;
+ virtual bool intersectsPointInTime(const MovingPoint& p, Tools::IInterval& out) const;
+ virtual bool intersectsPointInTime(const Tools::IInterval& ivI, const MovingPoint& p, Tools::IInterval& out) const;
+ virtual bool containsPointInTime(const MovingPoint& p) const;
+ virtual bool containsPointInTime(const Tools::IInterval& ivI, const MovingPoint& p) const;
+
+ //virtual bool intersectsPointAtTime(double t, const MovingRegion& in) const;
+ //virtual bool containsPointAtTime(double t, const MovingRegion& in) const;
+
+ virtual void combineRegionInTime(const MovingRegion& r);
+ virtual void combineRegionAfterTime(double t, const MovingRegion& r);
+ virtual void getCombinedRegionInTime(MovingRegion& out, const MovingRegion& in) const;
+ virtual void getCombinedRegionAfterTime(double t, MovingRegion& out, const MovingRegion& in) const;
+
+ virtual double getIntersectingAreaInTime(const MovingRegion& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const MovingRegion& r) const;
+
+ //
+ // IObject interface
+ //
+ virtual MovingRegion* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // IEvolvingShape interface
+ //
+ virtual void getVMBR(Region& out) const;
+ virtual void getMBRAtTime(double t, Region& out) const;
+
+ //
+ // ITimeShape interface
+ //
+ virtual double getAreaInTime() const;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ private:
+ void initialize(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension);
+
+ public:
+ class CrossPoint
+ {
+ public:
+ double m_t;
+ uint32_t m_dimension;
+ uint32_t m_boundary;
+ const MovingRegion* m_to;
+
+ struct ascending: public std::binary_function<CrossPoint&, CrossPoint&, bool>
+ {
+ bool operator()(const CrossPoint& __x, const CrossPoint& __y) const { return __x.m_t > __y.m_t; }
+ };
+ }; // CrossPoint
+
+ public:
+ double* m_pVLow;
+ double* m_pVHigh;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingRegion& r);
+ }; // MovingRegion
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingRegion& r);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/Point.h b/sci-libs/libspatialindex/svn/trunk/include/Point.h
new file mode 100644
index 000000000..51cb4b618
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/Point.h
@@ -0,0 +1,77 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL Point : public Tools::IObject, public virtual IShape
+ {
+ public:
+ Point();
+ Point(const double* pCoords, uint32_t dimension);
+ Point(const Point& p);
+ virtual ~Point();
+
+ virtual Point& operator=(const Point& p);
+ virtual bool operator==(const Point& p) const;
+
+ //
+ // IObject interface
+ //
+ virtual Point* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ //
+ // IShape interface
+ //
+ virtual bool intersectsShape(const IShape& in) const;
+ virtual bool containsShape(const IShape& in) const;
+ virtual bool touchesShape(const IShape& in) const;
+ virtual void getCenter(Point& out) const;
+ virtual uint32_t getDimension() const;
+ virtual void getMBR(Region& out) const;
+ virtual double getArea() const;
+ virtual double getMinimumDistance(const IShape& in) const;
+
+ virtual double getMinimumDistance(const Point& p) const;
+
+ virtual double getCoordinate(uint32_t index) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ uint32_t m_dimension;
+ double* m_pCoords;
+
+ friend class Region;
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const Point& pt);
+ }; // Point
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Point& pt);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/RTree.h b/sci-libs/libspatialindex/svn/trunk/include/RTree.h
new file mode 100644
index 000000000..4303b9e96
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/RTree.h
@@ -0,0 +1,102 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ SIDX_DLL enum RTreeVariant
+ {
+ RV_LINEAR = 0x0,
+ RV_QUADRATIC,
+ RV_RSTAR
+ };
+
+ SIDX_DLL enum BulkLoadMethod
+ {
+ BLM_STR = 0x0
+ };
+
+ SIDX_DLL enum PersistenObjectIdentifier
+ {
+ PersistentIndex = 0x1,
+ PersistentLeaf = 0x2
+ };
+
+ SIDX_DLL enum RangeQueryType
+ {
+ ContainmentQuery = 0x1,
+ IntersectionQuery = 0x2
+ };
+
+ class SIDX_DLL Data : public IData, public Tools::ISerializable
+ {
+ public:
+ Data(uint32_t len, byte* pData, Region& r, id_type id);
+ virtual ~Data();
+
+ virtual Data* clone();
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+ virtual void getData(uint32_t& len, byte** data) const;
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ id_type m_id;
+ Region m_region;
+ byte* m_pData;
+ uint32_t m_dataLength;
+ }; // Data
+
+ SIDX_DLL ISpatialIndex* returnRTree(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL ISpatialIndex* createNewRTree(
+ IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ RTreeVariant rv,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ RTreeVariant rv,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ IStorageManager& sm,
+ Tools::PropertySet& ps,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* loadRTree(IStorageManager& in, id_type indexIdentifier);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/Region.h b/sci-libs/libspatialindex/svn/trunk/include/Region.h
new file mode 100644
index 000000000..feddaee10
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/Region.h
@@ -0,0 +1,97 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL Region : public Tools::IObject, public virtual IShape
+ {
+ public:
+ Region();
+ Region(const double* pLow, const double* pHigh, uint32_t dimension);
+ Region(const Point& low, const Point& high);
+ Region(const Region& in);
+ virtual ~Region();
+
+ virtual Region& operator=(const Region& r);
+ virtual bool operator==(const Region&) const;
+
+ //
+ // IObject interface
+ //
+ virtual Region* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ //
+ // IShape interface
+ //
+ virtual bool intersectsShape(const IShape& in) const;
+ virtual bool containsShape(const IShape& in) const;
+ virtual bool touchesShape(const IShape& in) const;
+ virtual void getCenter(Point& out) const;
+ virtual uint32_t getDimension() const;
+ virtual void getMBR(Region& out) const;
+ virtual double getArea() const;
+ virtual double getMinimumDistance(const IShape& in) const;
+
+ virtual bool intersectsRegion(const Region& in) const;
+ virtual bool containsRegion(const Region& in) const;
+ virtual bool touchesRegion(const Region& in) const;
+ virtual double getMinimumDistance(const Region& in) const;
+
+ virtual bool containsPoint(const Point& in) const;
+ virtual bool touchesPoint(const Point& in) const;
+ virtual double getMinimumDistance(const Point& in) const;
+
+ virtual Region getIntersectingRegion(const Region& r) const;
+ virtual double getIntersectingArea(const Region& in) const;
+ virtual double getMargin() const;
+
+ virtual void combineRegion(const Region& in);
+ virtual void combinePoint(const Point& in);
+ virtual void getCombinedRegion(Region& out, const Region& in) const;
+
+ virtual double getLow(uint32_t index) const;
+ virtual double getHigh(uint32_t index) const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ private:
+ void initialize(const double* pLow, const double* pHigh, uint32_t dimension);
+
+ public:
+ uint32_t m_dimension;
+ double* m_pLow;
+ double* m_pHigh;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const Region& r);
+ }; // Region
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Region& r);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/SpatialIndex.h b/sci-libs/libspatialindex/svn/trunk/include/SpatialIndex.h
new file mode 100644
index 000000000..fe6cf679b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/SpatialIndex.h
@@ -0,0 +1,250 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "tools/Tools.h"
+
+# if !HAVE_BZERO
+# define bzero(d, n) memset((d), 0, (n))
+# endif
+
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661922
+#endif
+
+namespace SpatialIndex
+{
+ class Point;
+ class Region;
+
+ typedef int64_t id_type;
+
+ SIDX_DLL enum CommandType
+ {
+ CT_NODEREAD = 0x0,
+ CT_NODEDELETE,
+ CT_NODEWRITE
+ };
+
+ class SIDX_DLL InvalidPageException : public Tools::Exception
+ {
+ public:
+ InvalidPageException(id_type id);
+ virtual ~InvalidPageException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // InvalidPageException
+
+ //
+ // Interfaces
+ //
+
+ class SIDX_DLL IShape : public Tools::ISerializable
+ {
+ public:
+ virtual bool intersectsShape(const IShape& in) const = 0;
+ virtual bool containsShape(const IShape& in) const = 0;
+ virtual bool touchesShape(const IShape& in) const = 0;
+ virtual void getCenter(Point& out) const = 0;
+ virtual uint32_t getDimension() const = 0;
+ virtual void getMBR(Region& out) const = 0;
+ virtual double getArea() const = 0;
+ virtual double getMinimumDistance(const IShape& in) const = 0;
+ virtual ~IShape() {}
+ }; // IShape
+
+ class SIDX_DLL ITimeShape : public Tools::IInterval
+ {
+ public:
+ virtual bool intersectsShapeInTime(const ITimeShape& in) const = 0;
+ virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0;
+ virtual bool containsShapeInTime(const ITimeShape& in) const = 0;
+ virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0;
+ virtual bool touchesShapeInTime(const ITimeShape& in) const = 0;
+ virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0;
+ virtual double getAreaInTime() const = 0;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const = 0;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const = 0;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const = 0;
+ virtual ~ITimeShape() {}
+ }; // ITimeShape
+
+ class SIDX_DLL IEvolvingShape
+ {
+ public:
+ virtual void getVMBR(Region& out) const = 0;
+ virtual void getMBRAtTime(double t, Region& out) const = 0;
+ virtual ~IEvolvingShape() {}
+ }; // IEvolvingShape
+
+ class SIDX_DLL IEntry : public Tools::IObject
+ {
+ public:
+ virtual id_type getIdentifier() const = 0;
+ virtual void getShape(IShape** out) const = 0;
+ virtual ~IEntry() {}
+ }; // IEntry
+
+ class SIDX_DLL INode : public IEntry, public Tools::ISerializable
+ {
+ public:
+ virtual uint32_t getChildrenCount() const = 0;
+ virtual id_type getChildIdentifier(uint32_t index) const = 0;
+ virtual void getChildData(uint32_t index, uint32_t& len, byte** data) const = 0;
+ virtual void getChildShape(uint32_t index, IShape** out) const = 0;
+ virtual uint32_t getLevel() const = 0;
+ virtual bool isIndex() const = 0;
+ virtual bool isLeaf() const = 0;
+ virtual ~INode() {}
+ }; // INode
+
+ class SIDX_DLL IData : public IEntry
+ {
+ public:
+ virtual void getData(uint32_t& len, byte** data) const = 0;
+ virtual ~IData() {}
+ }; // IData
+
+ class SIDX_DLL IDataStream : public Tools::IObjectStream
+ {
+ public:
+ virtual IData* getNext() = 0;
+ virtual ~IDataStream() {}
+ }; // IDataStream
+
+ class SIDX_DLL ICommand
+ {
+ public:
+ virtual void execute(const INode& in) = 0;
+ virtual ~ICommand() {}
+ }; // ICommand
+
+ class SIDX_DLL INearestNeighborComparator
+ {
+ public:
+ virtual double getMinimumDistance(const IShape& query, const IShape& entry) = 0;
+ virtual double getMinimumDistance(const IShape& query, const IData& data) = 0;
+ virtual ~INearestNeighborComparator() {}
+ }; // INearestNeighborComparator
+
+ class SIDX_DLL IStorageManager
+ {
+ public:
+ virtual void loadByteArray(const id_type id, uint32_t& len, byte** data) = 0;
+ virtual void storeByteArray(id_type& id, const uint32_t len, const byte* const data) = 0;
+ virtual void deleteByteArray(const id_type id) = 0;
+ virtual ~IStorageManager() {}
+ }; // IStorageManager
+
+ class SIDX_DLL IVisitor
+ {
+ public:
+ virtual void visitNode(const INode& in) = 0;
+ virtual void visitData(const IData& in) = 0;
+ virtual void visitData(std::vector<const IData*>& v) = 0;
+ virtual ~IVisitor() {}
+ }; // IVisitor
+
+ class SIDX_DLL IQueryStrategy
+ {
+ public:
+ virtual void getNextEntry(const IEntry& previouslyFetched, id_type& nextEntryToFetch, bool& bFetchNextEntry) = 0;
+ virtual ~IQueryStrategy() {}
+ }; // IQueryStrategy
+
+ class SIDX_DLL IStatistics
+ {
+ public:
+ virtual uint64_t getReads() const = 0;
+ virtual uint64_t getWrites() const = 0;
+ virtual uint32_t getNumberOfNodes() const = 0;
+ virtual uint64_t getNumberOfData() const = 0;
+ virtual ~IStatistics() {}
+ }; // IStatistics
+
+ class SIDX_DLL ISpatialIndex
+ {
+ public:
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier) = 0;
+ virtual bool deleteData(const IShape& shape, id_type shapeIdentifier) = 0;
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v) = 0;
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v) = 0;
+ virtual void pointLocationQuery(const Point& query, IVisitor& v) = 0;
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc) = 0;
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v) = 0;
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v) = 0;
+ virtual void queryStrategy(IQueryStrategy& qs) = 0;
+ virtual void getIndexProperties(Tools::PropertySet& out) const = 0;
+ virtual void addCommand(ICommand* in, CommandType ct) = 0;
+ virtual bool isIndexValid() = 0;
+ virtual void getStatistics(IStatistics** out) const = 0;
+ virtual ~ISpatialIndex() {}
+
+ }; // ISpatialIndex
+
+ namespace StorageManager
+ {
+ SIDX_DLL enum StorageManagerConstants
+ {
+ EmptyPage = -0x1,
+ NewPage = -0x1
+ };
+
+ class SIDX_DLL IBuffer : public IStorageManager
+ {
+ public:
+ virtual uint64_t getHits() = 0;
+ virtual void clear() = 0;
+ virtual ~IBuffer() {}
+ }; // IBuffer
+
+ SIDX_DLL IStorageManager* returnMemoryStorageManager(Tools::PropertySet& in);
+ SIDX_DLL IStorageManager* createNewMemoryStorageManager();
+
+ SIDX_DLL IStorageManager* returnDiskStorageManager(Tools::PropertySet& in);
+ SIDX_DLL IStorageManager* createNewDiskStorageManager(std::string& baseName, uint32_t pageSize);
+ SIDX_DLL IStorageManager* loadDiskStorageManager(std::string& baseName);
+
+ SIDX_DLL IBuffer* returnRandomEvictionsBuffer(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL IBuffer* createNewRandomEvictionsBuffer(IStorageManager& in, uint32_t capacity, bool bWriteThrough);
+ }
+
+ //
+ // Global functions
+ //
+ SIDX_DLL std::ostream& operator<<(std::ostream&, const ISpatialIndex&);
+ SIDX_DLL std::ostream& operator<<(std::ostream&, const IStatistics&);
+}
+
+#include "Point.h"
+#include "Region.h"
+#include "LineSegment.h"
+#include "TimePoint.h"
+#include "TimeRegion.h"
+#include "MovingPoint.h"
+#include "MovingRegion.h"
+#include "RTree.h"
+#include "MVRTree.h"
+#include "TPRTree.h"
+#include "Version.h"
diff --git a/sci-libs/libspatialindex/svn/trunk/include/TPRTree.h b/sci-libs/libspatialindex/svn/trunk/include/TPRTree.h
new file mode 100644
index 000000000..1af9818f9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/TPRTree.h
@@ -0,0 +1,78 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ SIDX_DLL enum TPRTreeVariant
+ {
+ TPRV_RSTAR = 0x0
+ };
+
+ SIDX_DLL enum PersistenObjectIdentifier
+ {
+ PersistentIndex = 0x1,
+ PersistentLeaf = 0x2
+ };
+
+ SIDX_DLL enum RangeQueryType
+ {
+ ContainmentQuery = 0x1,
+ IntersectionQuery = 0x2
+ };
+
+ class SIDX_DLL Data : public IData, public Tools::ISerializable
+ {
+ public:
+ Data(uint32_t len, byte* pData, MovingRegion& r, id_type id);
+ virtual ~Data();
+
+ virtual Data* clone();
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+ virtual void getData(uint32_t& len, byte** data) const;
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ id_type m_id;
+ MovingRegion m_region;
+ byte* m_pData;
+ uint32_t m_dataLength;
+ }; // Data
+
+ SIDX_DLL ISpatialIndex* returnTPRTree(IStorageManager& ind, Tools::PropertySet& in);
+ SIDX_DLL ISpatialIndex* createNewTPRTree(
+ IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ TPRTreeVariant rv,
+ double horizon,
+ id_type& indexIdentifier
+ );
+ SIDX_DLL ISpatialIndex* loadTPRTree(IStorageManager& in, id_type indexIdentifier);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/TimePoint.h b/sci-libs/libspatialindex/svn/trunk/include/TimePoint.h
new file mode 100644
index 000000000..3d1de4e7d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/TimePoint.h
@@ -0,0 +1,89 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL TimePoint : public Point, public ITimeShape
+ {
+ public:
+ TimePoint();
+ TimePoint(const double* pCoords, const Tools::IInterval& ti, uint32_t dimension);
+ TimePoint(const double* pCoords, double tStart, double tEnd, uint32_t dimension);
+ TimePoint(const Point& p, const Tools::IInterval& ti);
+ TimePoint(const Point& p, double tStart, double tEnd);
+ TimePoint(const TimePoint& p);
+ virtual ~TimePoint();
+
+ virtual TimePoint& operator=(const TimePoint& p);
+ virtual bool operator==(const TimePoint& p) const;
+
+ //
+ // IObject interface
+ //
+ virtual TimePoint* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // ITimeShape interface
+ //
+ virtual bool intersectsShapeInTime(const ITimeShape& in) const;
+ virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual double getAreaInTime() const;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const;
+
+ //
+ // IInterval interface
+ //
+ virtual Tools::IInterval& operator=(const Tools::IInterval&);
+ virtual double getLowerBound() const;
+ virtual double getUpperBound() const;
+ virtual void setBounds(double, double);
+ virtual bool intersectsInterval(const Tools::IInterval& ti) const;
+ virtual bool intersectsInterval(Tools::IntervalType t, const double start, const double end) const;
+ virtual bool containsInterval(const Tools::IInterval& ti) const;
+ virtual Tools::IntervalType getIntervalType() const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ double m_startTime;
+ double m_endTime;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimePoint& pt);
+ }; // TimePoint
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimePoint& pt);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/TimeRegion.h b/sci-libs/libspatialindex/svn/trunk/include/TimeRegion.h
new file mode 100644
index 000000000..46b720b45
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/TimeRegion.h
@@ -0,0 +1,102 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ class SIDX_DLL TimeRegion : public Region, public ITimeShape
+ {
+ public:
+ TimeRegion();
+ TimeRegion(const double* pLow, const double* pHigh, const Tools::IInterval& ti, uint32_t dimension);
+ TimeRegion(const double* pLow, const double* pHigh, double tStart, double tEnd, uint32_t dimension);
+ TimeRegion(const Point& low, const Point& high, const Tools::IInterval& ti);
+ TimeRegion(const Point& low, const Point& high, double tStart, double tEnd);
+ TimeRegion(const Region& in, const Tools::IInterval& ti);
+ TimeRegion(const Region& in, double tStart, double tEnd);
+ TimeRegion(const TimePoint& low, const TimePoint& high);
+ TimeRegion(const TimeRegion& in);
+ virtual ~TimeRegion();
+
+ virtual TimeRegion& operator=(const TimeRegion& r);
+ virtual bool operator==(const TimeRegion&) const;
+
+ virtual bool intersectsRegionInTime(const TimeRegion& in) const;
+ virtual bool containsRegionInTime(const TimeRegion& in) const;
+ virtual bool touchesRegionInTime(const TimeRegion& in) const;
+
+ virtual bool containsPointInTime(const TimePoint& in) const;
+ virtual bool touchesPointInTime(const TimePoint& in) const;
+
+ virtual void combineRegionInTime(const TimeRegion& in);
+ virtual void getCombinedRegionInTime(TimeRegion& out, const TimeRegion& in) const;
+
+ //
+ // IObject interface
+ //
+ virtual TimeRegion* clone();
+
+ //
+ // ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // ITimeShape interface
+ //
+ virtual bool intersectsShapeInTime(const ITimeShape& in) const;
+ virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const ITimeShape& in) const;
+ virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const ITimeShape& in) const;
+ virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const;
+ virtual double getAreaInTime() const;
+ virtual double getAreaInTime(const Tools::IInterval& ivI) const;
+ virtual double getIntersectingAreaInTime(const ITimeShape& r) const;
+ virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const;
+
+ //
+ // IInterval interface
+ //
+ virtual Tools::IInterval& operator=(const Tools::IInterval&);
+ virtual double getLowerBound() const;
+ virtual double getUpperBound() const;
+ virtual void setBounds(double, double);
+ virtual bool intersectsInterval(const Tools::IInterval& ti) const;
+ virtual bool intersectsInterval(Tools::IntervalType t, const double start, const double end) const;
+ virtual bool containsInterval(const Tools::IInterval& ti) const;
+ virtual Tools::IntervalType getIntervalType() const;
+
+ virtual void makeInfinite(uint32_t dimension);
+ virtual void makeDimension(uint32_t dimension);
+
+ public:
+ double m_startTime;
+ double m_endTime;
+
+ friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimeRegion& r);
+ }; // TimeRegion
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimeRegion& r);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/include/Version.h b/sci-libs/libspatialindex/svn/trunk/include/Version.h
new file mode 100644
index 000000000..3ecf5f687
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/Version.h
@@ -0,0 +1,42 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#ifndef SIDX_VERSION_MAJOR
+#define SIDX_VERSION_MAJOR 1
+#define SIDX_VERSION_MINOR 6
+#define SIDX_VERSION_REV 1
+#define SIDX_VERSION_BUILD 0
+#endif
+
+#ifndef SIDX_VERSION_NUM
+#define SIDX_VERSION_NUM (SIDX_VERSION_MAJOR*1000+SIDX_VERSION_MINOR*100+SIDX_VERSION_REV*10+SIDX_VERSION_BUILD)
+#endif
+
+#ifndef SIDX_RELEASE_DATE
+#define SIDX_RELEASE_DATE 20101204
+#endif
+
+#ifndef SIDX_RELEASE_NAME
+#define SIDX_RELEASE_NAME "1.6.1"
+#endif
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/all-wcprops
new file mode 100644
index 000000000..58b86056f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/all-wcprops
@@ -0,0 +1,89 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi
+END
+Error.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/138/spatialindex/trunk/include/capi/Error.h
+END
+ObjVisitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/172/spatialindex/trunk/include/capi/ObjVisitor.h
+END
+IdVisitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/172/spatialindex/trunk/include/capi/IdVisitor.h
+END
+sidx_config.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi/sidx_config.h
+END
+LeafQuery.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/145/spatialindex/trunk/include/capi/LeafQuery.h
+END
+CustomStorage.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi/CustomStorage.h
+END
+BoundsQuery.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/138/spatialindex/trunk/include/capi/BoundsQuery.h
+END
+sidx_api.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi/sidx_api.h
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi/Makefile.am
+END
+Utility.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/138/spatialindex/trunk/include/capi/Utility.h
+END
+DataStream.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/138/spatialindex/trunk/include/capi/DataStream.h
+END
+Index.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi/Index.h
+END
+CountVisitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/spatialindex/!svn/ver/173/spatialindex/trunk/include/capi/CountVisitor.h
+END
+sidx_impl.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/186/spatialindex/trunk/include/capi/sidx_impl.h
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/dir-prop-base
new file mode 100644
index 000000000..a57f5442b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 21
+Makefile
+Makefile.in
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/entries b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/entries
new file mode 100644
index 000000000..8f2ebbd0c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/entries
@@ -0,0 +1,504 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/include/capi
+http://svn.gispython.org/spatialindex
+
+
+
+2010-06-19T20:34:19.329614Z
+186
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Error.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+05b09bc45890b74bc65c8caa0fc3fbe5
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1786
+
+ObjVisitor.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+272e39b06c1b8b9c61a6e6f282e6e5e3
+2010-03-03T21:55:09.207890Z
+172
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1787
+
+IdVisitor.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+5334daab2cd686d7dfc3baeb20d3a6ce
+2010-03-03T21:55:09.207890Z
+172
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1751
+
+sidx_config.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+105ee8687b2829f08473a8a0badfcc82
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2866
+
+LeafQuery.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+5e44029672cef4bc0c31072218b80d94
+2009-09-17T20:40:25.584745Z
+145
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2499
+
+CustomStorage.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+1033a25bfcdcca8968bdb5b81088b03d
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3153
+
+BoundsQuery.h
+file
+
+
+
+
+2011-08-01T00:42:34.309378Z
+303f7d59f62a452a312c3acc1d757c4e
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1728
+
+sidx_api.h
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+f035d9a6d98a51c0a8d033d71e48eb23
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8592
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+cbe5fb6149f497314f16b3145ca76f3d
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+368
+
+Utility.h
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+cb8761d7dc01f8ffa518db4aebd8fc12
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1324
+
+DataStream.h
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+e73f67a514dd56ce697e8e5c7ab2b062
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2046
+
+Index.h
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+d7808f62d2ad6851b808e587553686b7
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2530
+
+CountVisitor.h
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+f5c5acacea25040af7e548cd9ee23c91
+2010-03-04T16:33:28.494647Z
+173
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1592
+
+sidx_impl.h
+file
+
+
+
+
+2011-08-01T00:42:34.321137Z
+9bda93160a69daca518d4a5381b0f273
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1708
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/BoundsQuery.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/BoundsQuery.h.svn-base
new file mode 100644
index 000000000..42fa6582a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/BoundsQuery.h.svn-base
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * $Id: boundsquery.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the bounds query.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class BoundsQuery : public SpatialIndex::IQueryStrategy
+{
+private:
+ SpatialIndex::Region* m_bounds;
+
+public:
+
+ BoundsQuery();
+ ~BoundsQuery() { if (m_bounds !=0) delete m_bounds;}
+ void getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext);
+
+ SpatialIndex::Region* GetBounds() const {return m_bounds; }
+};
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CountVisitor.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CountVisitor.h.svn-base
new file mode 100644
index 000000000..323f90aa9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CountVisitor.h.svn-base
@@ -0,0 +1,45 @@
+/******************************************************************************
+* $Id$
+*
+* Project: libsidx - A C API wrapper around libspatialindex
+* Purpose: C++ objects to implement the count visitor.
+* Author: Leonard Norrgård, leonard.norrgard@refactor.fi
+*
+******************************************************************************
+* Copyright (c) 2010, Leonard Norrgård
+*
+* All rights reserved.
+*
+* This library is free software; you can redistribute it and/or modify it under
+* the terms of the GNU Lesser General Public License as published by the Free
+* Software Foundation; either version 2.1 of the License, or (at your option)
+* any later version.
+
+* This library is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+* details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#pragma once
+
+class CountVisitor : public SpatialIndex::IVisitor
+{
+private:
+ uint64_t nResults;
+
+public:
+
+ CountVisitor();
+ ~CountVisitor();
+
+ uint64_t GetResultCount() const { return nResults; }
+
+ void visitNode(const SpatialIndex::INode& n);
+ void visitData(const SpatialIndex::IData& d);
+ void visitData(std::vector<const SpatialIndex::IData*>& v);
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CustomStorage.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CustomStorage.h.svn-base
new file mode 100644
index 000000000..35f208273
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/CustomStorage.h.svn-base
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * $Id: CustomStorage.h 1385 2009-06-17 13:45:16Z nitro $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the custom storage manager.
+ * Author: Matthias (nitro)
+ *
+ ******************************************************************************
+ * Copyright (c) 2010, Matthias (nitro)
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ struct CustomStorageManagerCallbacks
+ {
+ CustomStorageManagerCallbacks() : context(0), createCallback(0), destroyCallback(0), loadByteArrayCallback(0), storeByteArrayCallback(0), deleteByteArrayCallback(0)
+ {}
+
+ void* context;
+ void (*createCallback)( const void* context, int* errorCode );
+ void (*destroyCallback)( const void* context, int* errorCode );
+ void (*loadByteArrayCallback)( const void* context, const id_type page, uint32_t* len, byte** data, int* errorCode );
+ void (*storeByteArrayCallback)( const void* context, id_type* page, const uint32_t len, const byte* const data, int* errorCode );
+ void (*deleteByteArrayCallback)( const void* context, const id_type page, int* errorCode );
+ };
+
+ class CustomStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ // I'd like this to be an enum, but casting between enums and ints is not nice
+ static const int NoError = 0;
+ static const int InvalidPageError = 1;
+ static const int IllegalStateError = 2;
+
+ CustomStorageManager(Tools::PropertySet&);
+
+ virtual ~CustomStorageManager();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ private:
+ CustomStorageManagerCallbacks callbacks;
+
+ inline void processErrorCode(int errorCode, const id_type page);
+ }; // CustomStorageManager
+
+ // factory function
+ IStorageManager* returnCustomStorageManager(Tools::PropertySet& in);
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/DataStream.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/DataStream.h.svn-base
new file mode 100644
index 000000000..93a7f12a6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/DataStream.h.svn-base
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * $Id: datastream.hpp 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the datastream.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class DataStream : public SpatialIndex::IDataStream
+{
+public:
+ DataStream(int (*readNext)(SpatialIndex::id_type* id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength));
+ ~DataStream();
+
+ SpatialIndex::IData* getNext();
+ bool hasNext() throw (Tools::NotSupportedException);
+
+ uint32_t size() throw (Tools::NotSupportedException);
+ void rewind() throw (Tools::NotSupportedException);
+
+protected:
+ SpatialIndex::RTree::Data* m_pNext;
+ SpatialIndex::id_type m_id;
+
+private:
+ int (*iterfunct)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength);
+
+ bool readData();
+ bool m_bDoneReading;
+
+};
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Error.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Error.h.svn-base
new file mode 100644
index 000000000..69d805d44
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Error.h.svn-base
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * $Id: error.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the error object.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class Error
+{
+public:
+
+ Error(int code, std::string const& message, std::string const& method);
+
+ /// Copy constructor.
+ Error(Error const& other);
+
+ /// Assignment operator.
+ Error& operator=(Error const& rhs);
+
+ int GetCode() const { return m_code; };
+ const char* GetMessage() const { return m_message.c_str(); };
+ const char* GetMethod() const { return m_method.c_str(); };
+
+private:
+
+ int m_code;
+ std::string m_message;
+ std::string m_method;
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/IdVisitor.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/IdVisitor.h.svn-base
new file mode 100644
index 000000000..81d745651
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/IdVisitor.h.svn-base
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * $Id: idvisitor.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class IdVisitor : public SpatialIndex::IVisitor
+{
+private:
+ std::vector<uint64_t> m_vector;
+ uint64_t nResults;
+
+public:
+
+ IdVisitor();
+ ~IdVisitor();
+
+ uint64_t GetResultCount() const { return nResults; }
+ std::vector<uint64_t>& GetResults() { return m_vector; }
+
+ void visitNode(const SpatialIndex::INode& n);
+ void visitData(const SpatialIndex::IData& d);
+ void visitData(std::vector<const SpatialIndex::IData*>& v);
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Index.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Index.h.svn-base
new file mode 100644
index 000000000..8f6ac52d3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Index.h.svn-base
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * $Id: index.hpp 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class Index
+{
+
+public:
+ Index(const Tools::PropertySet& poProperties);
+ Index(const Tools::PropertySet& poProperties, int (*readNext)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength));
+ ~Index();
+
+ const Tools::PropertySet& GetProperties() { return m_properties; }
+
+ bool insertFeature(uint64_t id, double *min, double *max);
+
+ RTIndexType GetIndexType();
+ void SetIndexType(RTIndexType v);
+
+ RTStorageType GetIndexStorage();
+ void SetIndexStorage(RTStorageType v);
+
+ RTIndexVariant GetIndexVariant();
+ void SetIndexVariant(RTStorageType v);
+
+ SpatialIndex::ISpatialIndex& index() {return *m_rtree;}
+ SpatialIndex::StorageManager::IBuffer& buffer() {return *m_buffer;}
+
+private:
+
+ void Initialize();
+ SpatialIndex::IStorageManager* m_storage;
+ SpatialIndex::StorageManager::IBuffer* m_buffer;
+ SpatialIndex::ISpatialIndex* m_rtree;
+
+ Tools::PropertySet m_properties;
+
+
+ void Setup();
+ SpatialIndex::IStorageManager* CreateStorage();
+ SpatialIndex::StorageManager::IBuffer* CreateIndexBuffer(SpatialIndex::IStorageManager& storage);
+ SpatialIndex::ISpatialIndex* CreateIndex();
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/LeafQuery.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/LeafQuery.h.svn-base
new file mode 100644
index 000000000..c1ba053e0
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/LeafQuery.h.svn-base
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * $Id: boundsquery.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement a query of the index's leaves.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class LeafQueryResult;
+
+class LeafQuery : public SpatialIndex::IQueryStrategy
+{
+private:
+ std::queue<SpatialIndex::id_type> m_ids;
+ std::vector<LeafQueryResult> m_results;
+public:
+
+ LeafQuery();
+ ~LeafQuery() { }
+ void getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext);
+ std::vector<LeafQueryResult> const& GetResults() const {return m_results;}
+};
+
+class LeafQueryResult
+{
+private:
+ std::vector<SpatialIndex::id_type> ids;
+ SpatialIndex::Region* bounds;
+ uint32_t m_id;
+ LeafQueryResult();
+public:
+ LeafQueryResult(uint32_t id) : bounds(0), m_id(id){};
+ ~LeafQueryResult() {if (bounds!=0) delete bounds;};
+
+ /// Copy constructor.
+ LeafQueryResult(LeafQueryResult const& other);
+
+ /// Assignment operator.
+ LeafQueryResult& operator=(LeafQueryResult const& rhs);
+
+ std::vector<SpatialIndex::id_type> const& GetIDs() const;
+ void SetIDs(std::vector<SpatialIndex::id_type>& v);
+ const SpatialIndex::Region* GetBounds() const;
+ void SetBounds(const SpatialIndex::Region* b);
+ uint32_t getIdentifier() const {return m_id;}
+ void setIdentifier(uint32_t v) {m_id = v;}
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..3bdb8be2b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,17 @@
+spatialindexdir = $(includedir)/spatialindex/capi
+
+dist_spatialindex_HEADERS = \
+ BoundsQuery.h \
+ CountVisitor.h \
+ CustomStorage.h \
+ DataStream.h \
+ Error.h \
+ IdVisitor.h \
+ Index.h \
+ LeafQuery.h \
+ ObjVisitor.h \
+ sidx_api.h \
+ sidx_config.h \
+ sidx_impl.h \
+ Utility.h
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/ObjVisitor.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/ObjVisitor.h.svn-base
new file mode 100644
index 000000000..13438ba3d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/ObjVisitor.h.svn-base
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * $Id: objvisitor.hpp 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the object visitor.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class ObjVisitor : public SpatialIndex::IVisitor
+{
+private:
+ std::vector<SpatialIndex::IData*> m_vector;
+ uint64_t nResults;
+
+public:
+
+ ObjVisitor();
+ ~ObjVisitor();
+
+ uint32_t GetResultCount() const { return nResults; }
+ std::vector<SpatialIndex::IData*>& GetResults() { return m_vector; }
+
+ void visitNode(const SpatialIndex::INode& n);
+ void visitData(const SpatialIndex::IData& d);
+ void visitData(std::vector<const SpatialIndex::IData*>& v);
+};
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Utility.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Utility.h.svn-base
new file mode 100644
index 000000000..58dc1e9b6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/Utility.h.svn-base
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * $Id: util.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement utilities.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+Tools::PropertySet* GetDefaults();
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_api.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_api.h.svn-base
new file mode 100644
index 000000000..a07131b77
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_api.h.svn-base
@@ -0,0 +1,213 @@
+/******************************************************************************
+ * $Id: sidx_api.h 1371 2009-08-05 04:39:21Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C API.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+
+#ifndef SIDX_API_H_INCLUDED
+#define SIDX_API_H_INCLUDED
+
+#define SIDX_C_API 1
+
+#include "sidx_config.h"
+
+IDX_C_START
+
+SIDX_DLL IndexH Index_Create(IndexPropertyH properties);
+
+SIDX_DLL IndexH Index_CreateWithStream( IndexPropertyH properties,
+ int (*readNext)(uint64_t *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, size_t *nDataLength)
+ );
+
+SIDX_DLL void Index_Destroy(IndexH index);
+SIDX_DLL IndexPropertyH Index_GetProperties(IndexH index);
+
+SIDX_DLL RTError Index_DeleteData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension);
+
+SIDX_DLL RTError Index_InsertData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ const uint8_t* pData,
+ size_t nDataLength);
+
+SIDX_DLL uint32_t Index_IsValid(IndexH index);
+
+SIDX_DLL RTError Index_Intersects_obj( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_Intersects_id( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_Intersects_count( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t* nResults);
+SIDX_DLL RTError Index_NearestNeighbors_obj(IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_NearestNeighbors_id( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_GetBounds( IndexH index,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension);
+
+
+SIDX_C_DLL RTError Index_GetLeaves( IndexH index,
+ uint32_t* nLeafNodes,
+ uint32_t** nLeafSizes,
+ int64_t** nLeafIDs,
+ int64_t*** nLeafChildIDs,
+ double*** pppdMin,
+ double*** pppdMax,
+ uint32_t* nDimension);
+
+SIDX_DLL void Index_DestroyObjResults(IndexItemH* results, uint32_t nResults);
+SIDX_DLL void Index_ClearBuffer(IndexH index);
+SIDX_DLL void Index_Free(void* object);
+
+SIDX_DLL void IndexItem_Destroy(IndexItemH item);
+SIDX_DLL uint64_t IndexItem_GetID(IndexItemH item);
+
+SIDX_DLL RTError IndexItem_GetData(IndexItemH item, uint8_t** data, uint64_t* length);
+
+SIDX_DLL RTError IndexItem_GetBounds( IndexItemH item,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension);
+
+SIDX_DLL IndexPropertyH IndexProperty_Create();
+SIDX_DLL void IndexProperty_Destroy(IndexPropertyH hProp);
+
+SIDX_DLL RTError IndexProperty_SetIndexType(IndexPropertyH iprop, RTIndexType value);
+SIDX_DLL RTIndexType IndexProperty_GetIndexType(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetDimension(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetDimension(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexVariant(IndexPropertyH iprop, RTIndexVariant value);
+SIDX_DLL RTIndexVariant IndexProperty_GetIndexVariant(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexStorage(IndexPropertyH iprop, RTStorageType value);
+SIDX_DLL RTStorageType IndexProperty_GetIndexStorage(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetPagesize(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetPagesize(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetIndexCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetLeafCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetLeafCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetLeafPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetLeafPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetIndexPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetRegionPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetRegionPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetPointPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetPointPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetBufferingCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetBufferingCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetEnsureTightMBRs(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetEnsureTightMBRs(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetOverwrite(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetOverwrite(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetNearMinimumOverlapFactor(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetNearMinimumOverlapFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetWriteThrough(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetWriteThrough(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFillFactor(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetFillFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetSplitDistributionFactor(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetSplitDistributionFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetTPRHorizon(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetTPRHorizon(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetReinsertFactor(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetReinsertFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFileName(IndexPropertyH iprop, const char* value);
+SIDX_DLL char* IndexProperty_GetFileName(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFileNameExtensionDat(IndexPropertyH iprop, const char* value);
+SIDX_DLL char* IndexProperty_GetFileNameExtensionDat(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFileNameExtensionIdx(IndexPropertyH iprop, const char* value);
+SIDX_DLL char* IndexProperty_GetFileNameExtensionIdx(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetCustomStorageCallbacksSize(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetCustomStorageCallbacksSize(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetCustomStorageCallbacks(IndexPropertyH iprop, const void* value);
+SIDX_DLL void* IndexProperty_GetCustomStorageCallbacks(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexID(IndexPropertyH iprop, int64_t value);
+SIDX_DLL int64_t IndexProperty_GetIndexID(IndexPropertyH iprop);
+
+SIDX_C_DLL void* SIDX_NewBuffer(size_t bytes);
+SIDX_C_DLL void SIDX_DeleteBuffer(void* buffer);
+
+SIDX_C_DLL char* SIDX_Version();
+
+IDX_C_END
+
+#endif \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_config.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_config.h.svn-base
new file mode 100644
index 000000000..439c701ce
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_config.h.svn-base
@@ -0,0 +1,121 @@
+/******************************************************************************
+ * $Id: sidx_config.h 1359 2009-07-31 04:44:50Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C API configuration
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef SIDX_CONFIG_H_INCLUDED
+#define SIDX_CONFIG_H_INCLUDED
+
+
+#ifdef _MSC_VER
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+ #include <windows.h>
+ #define STRDUP _strdup
+ #include "SpatialIndex.h"
+ #include <windows.h>
+
+#else
+
+ #include <stdint.h>
+ #define SIDX_THREAD __thread
+ #include <SpatialIndex.h>
+ #define STRDUP strdup
+#endif
+
+#include <sys/stat.h>
+
+
+
+class Item;
+class Index;
+
+typedef enum
+{
+ RT_None = 0,
+ RT_Debug = 1,
+ RT_Warning = 2,
+ RT_Failure = 3,
+ RT_Fatal = 4
+} RTError;
+
+typedef enum
+{
+ RT_RTree = 0,
+ RT_MVRTree = 1,
+ RT_TPRTree = 2,
+ RT_InvalidIndexType = -99
+} RTIndexType;
+
+typedef enum
+{
+ RT_Memory = 0,
+ RT_Disk = 1,
+ RT_Custom = 2,
+ RT_InvalidStorageType = -99
+} RTStorageType;
+
+typedef enum
+{
+ RT_Linear = 0,
+ RT_Quadratic = 1,
+ RT_Star = 2,
+ RT_InvalidIndexVariant = -99
+} RTIndexVariant;
+
+
+#ifdef __cplusplus
+# define IDX_C_START extern "C" {
+# define IDX_C_END }
+#else
+# define IDX_C_START
+# define IDX_C_END
+#endif
+
+typedef Index *IndexH;
+typedef SpatialIndex::IData *IndexItemH;
+typedef Tools::PropertySet *IndexPropertyH;
+
+#ifndef SIDX_C_DLL
+#if defined(_MSC_VER)
+# define SIDX_C_DLL __declspec(dllexport)
+#else
+# if defined(USE_GCC_VISIBILITY_FLAG)
+# define SIDX_C_DLL __attribute__ ((visibility("default")))
+# else
+# define SIDX_C_DLL
+# endif
+#endif
+#endif
+
+
+#endif
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_impl.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_impl.h.svn-base
new file mode 100644
index 000000000..25416a924
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/.svn/text-base/sidx_impl.h.svn-base
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * $Id: sidx_impl.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <stack>
+#include <string>
+#include <vector>
+#include <stdexcept>
+#include <sstream>
+#include <cstring>
+
+#include <capi/sidx_config.h>
+
+#include <capi/Utility.h>
+#include <capi/ObjVisitor.h>
+#include <capi/IdVisitor.h>
+#include <capi/CountVisitor.h>
+#include <capi/BoundsQuery.h>
+#include <capi/LeafQuery.h>
+#include <capi/Error.h>
+#include <capi/DataStream.h>
+#include <capi/Index.h>
+#include <capi/CustomStorage.h>
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/BoundsQuery.h b/sci-libs/libspatialindex/svn/trunk/include/capi/BoundsQuery.h
new file mode 100644
index 000000000..42fa6582a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/BoundsQuery.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * $Id: boundsquery.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the bounds query.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class BoundsQuery : public SpatialIndex::IQueryStrategy
+{
+private:
+ SpatialIndex::Region* m_bounds;
+
+public:
+
+ BoundsQuery();
+ ~BoundsQuery() { if (m_bounds !=0) delete m_bounds;}
+ void getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext);
+
+ SpatialIndex::Region* GetBounds() const {return m_bounds; }
+};
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/CountVisitor.h b/sci-libs/libspatialindex/svn/trunk/include/capi/CountVisitor.h
new file mode 100644
index 000000000..323f90aa9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/CountVisitor.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+* $Id$
+*
+* Project: libsidx - A C API wrapper around libspatialindex
+* Purpose: C++ objects to implement the count visitor.
+* Author: Leonard Norrgård, leonard.norrgard@refactor.fi
+*
+******************************************************************************
+* Copyright (c) 2010, Leonard Norrgård
+*
+* All rights reserved.
+*
+* This library is free software; you can redistribute it and/or modify it under
+* the terms of the GNU Lesser General Public License as published by the Free
+* Software Foundation; either version 2.1 of the License, or (at your option)
+* any later version.
+
+* This library is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+* details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#pragma once
+
+class CountVisitor : public SpatialIndex::IVisitor
+{
+private:
+ uint64_t nResults;
+
+public:
+
+ CountVisitor();
+ ~CountVisitor();
+
+ uint64_t GetResultCount() const { return nResults; }
+
+ void visitNode(const SpatialIndex::INode& n);
+ void visitData(const SpatialIndex::IData& d);
+ void visitData(std::vector<const SpatialIndex::IData*>& v);
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/CustomStorage.h b/sci-libs/libspatialindex/svn/trunk/include/capi/CustomStorage.h
new file mode 100644
index 000000000..35f208273
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/CustomStorage.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * $Id: CustomStorage.h 1385 2009-06-17 13:45:16Z nitro $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the custom storage manager.
+ * Author: Matthias (nitro)
+ *
+ ******************************************************************************
+ * Copyright (c) 2010, Matthias (nitro)
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ struct CustomStorageManagerCallbacks
+ {
+ CustomStorageManagerCallbacks() : context(0), createCallback(0), destroyCallback(0), loadByteArrayCallback(0), storeByteArrayCallback(0), deleteByteArrayCallback(0)
+ {}
+
+ void* context;
+ void (*createCallback)( const void* context, int* errorCode );
+ void (*destroyCallback)( const void* context, int* errorCode );
+ void (*loadByteArrayCallback)( const void* context, const id_type page, uint32_t* len, byte** data, int* errorCode );
+ void (*storeByteArrayCallback)( const void* context, id_type* page, const uint32_t len, const byte* const data, int* errorCode );
+ void (*deleteByteArrayCallback)( const void* context, const id_type page, int* errorCode );
+ };
+
+ class CustomStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ // I'd like this to be an enum, but casting between enums and ints is not nice
+ static const int NoError = 0;
+ static const int InvalidPageError = 1;
+ static const int IllegalStateError = 2;
+
+ CustomStorageManager(Tools::PropertySet&);
+
+ virtual ~CustomStorageManager();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ private:
+ CustomStorageManagerCallbacks callbacks;
+
+ inline void processErrorCode(int errorCode, const id_type page);
+ }; // CustomStorageManager
+
+ // factory function
+ IStorageManager* returnCustomStorageManager(Tools::PropertySet& in);
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/DataStream.h b/sci-libs/libspatialindex/svn/trunk/include/capi/DataStream.h
new file mode 100644
index 000000000..93a7f12a6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/DataStream.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * $Id: datastream.hpp 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the datastream.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class DataStream : public SpatialIndex::IDataStream
+{
+public:
+ DataStream(int (*readNext)(SpatialIndex::id_type* id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength));
+ ~DataStream();
+
+ SpatialIndex::IData* getNext();
+ bool hasNext() throw (Tools::NotSupportedException);
+
+ uint32_t size() throw (Tools::NotSupportedException);
+ void rewind() throw (Tools::NotSupportedException);
+
+protected:
+ SpatialIndex::RTree::Data* m_pNext;
+ SpatialIndex::id_type m_id;
+
+private:
+ int (*iterfunct)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength);
+
+ bool readData();
+ bool m_bDoneReading;
+
+};
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/Error.h b/sci-libs/libspatialindex/svn/trunk/include/capi/Error.h
new file mode 100644
index 000000000..69d805d44
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/Error.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * $Id: error.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the error object.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class Error
+{
+public:
+
+ Error(int code, std::string const& message, std::string const& method);
+
+ /// Copy constructor.
+ Error(Error const& other);
+
+ /// Assignment operator.
+ Error& operator=(Error const& rhs);
+
+ int GetCode() const { return m_code; };
+ const char* GetMessage() const { return m_message.c_str(); };
+ const char* GetMethod() const { return m_method.c_str(); };
+
+private:
+
+ int m_code;
+ std::string m_message;
+ std::string m_method;
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/IdVisitor.h b/sci-libs/libspatialindex/svn/trunk/include/capi/IdVisitor.h
new file mode 100644
index 000000000..81d745651
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/IdVisitor.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * $Id: idvisitor.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class IdVisitor : public SpatialIndex::IVisitor
+{
+private:
+ std::vector<uint64_t> m_vector;
+ uint64_t nResults;
+
+public:
+
+ IdVisitor();
+ ~IdVisitor();
+
+ uint64_t GetResultCount() const { return nResults; }
+ std::vector<uint64_t>& GetResults() { return m_vector; }
+
+ void visitNode(const SpatialIndex::INode& n);
+ void visitData(const SpatialIndex::IData& d);
+ void visitData(std::vector<const SpatialIndex::IData*>& v);
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/Index.h b/sci-libs/libspatialindex/svn/trunk/include/capi/Index.h
new file mode 100644
index 000000000..8f6ac52d3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/Index.h
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * $Id: index.hpp 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class Index
+{
+
+public:
+ Index(const Tools::PropertySet& poProperties);
+ Index(const Tools::PropertySet& poProperties, int (*readNext)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength));
+ ~Index();
+
+ const Tools::PropertySet& GetProperties() { return m_properties; }
+
+ bool insertFeature(uint64_t id, double *min, double *max);
+
+ RTIndexType GetIndexType();
+ void SetIndexType(RTIndexType v);
+
+ RTStorageType GetIndexStorage();
+ void SetIndexStorage(RTStorageType v);
+
+ RTIndexVariant GetIndexVariant();
+ void SetIndexVariant(RTStorageType v);
+
+ SpatialIndex::ISpatialIndex& index() {return *m_rtree;}
+ SpatialIndex::StorageManager::IBuffer& buffer() {return *m_buffer;}
+
+private:
+
+ void Initialize();
+ SpatialIndex::IStorageManager* m_storage;
+ SpatialIndex::StorageManager::IBuffer* m_buffer;
+ SpatialIndex::ISpatialIndex* m_rtree;
+
+ Tools::PropertySet m_properties;
+
+
+ void Setup();
+ SpatialIndex::IStorageManager* CreateStorage();
+ SpatialIndex::StorageManager::IBuffer* CreateIndexBuffer(SpatialIndex::IStorageManager& storage);
+ SpatialIndex::ISpatialIndex* CreateIndex();
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/LeafQuery.h b/sci-libs/libspatialindex/svn/trunk/include/capi/LeafQuery.h
new file mode 100644
index 000000000..c1ba053e0
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/LeafQuery.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * $Id: boundsquery.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement a query of the index's leaves.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class LeafQueryResult;
+
+class LeafQuery : public SpatialIndex::IQueryStrategy
+{
+private:
+ std::queue<SpatialIndex::id_type> m_ids;
+ std::vector<LeafQueryResult> m_results;
+public:
+
+ LeafQuery();
+ ~LeafQuery() { }
+ void getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext);
+ std::vector<LeafQueryResult> const& GetResults() const {return m_results;}
+};
+
+class LeafQueryResult
+{
+private:
+ std::vector<SpatialIndex::id_type> ids;
+ SpatialIndex::Region* bounds;
+ uint32_t m_id;
+ LeafQueryResult();
+public:
+ LeafQueryResult(uint32_t id) : bounds(0), m_id(id){};
+ ~LeafQueryResult() {if (bounds!=0) delete bounds;};
+
+ /// Copy constructor.
+ LeafQueryResult(LeafQueryResult const& other);
+
+ /// Assignment operator.
+ LeafQueryResult& operator=(LeafQueryResult const& rhs);
+
+ std::vector<SpatialIndex::id_type> const& GetIDs() const;
+ void SetIDs(std::vector<SpatialIndex::id_type>& v);
+ const SpatialIndex::Region* GetBounds() const;
+ void SetBounds(const SpatialIndex::Region* b);
+ uint32_t getIdentifier() const {return m_id;}
+ void setIdentifier(uint32_t v) {m_id = v;}
+};
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/Makefile.am b/sci-libs/libspatialindex/svn/trunk/include/capi/Makefile.am
new file mode 100644
index 000000000..3bdb8be2b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/Makefile.am
@@ -0,0 +1,17 @@
+spatialindexdir = $(includedir)/spatialindex/capi
+
+dist_spatialindex_HEADERS = \
+ BoundsQuery.h \
+ CountVisitor.h \
+ CustomStorage.h \
+ DataStream.h \
+ Error.h \
+ IdVisitor.h \
+ Index.h \
+ LeafQuery.h \
+ ObjVisitor.h \
+ sidx_api.h \
+ sidx_config.h \
+ sidx_impl.h \
+ Utility.h
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/ObjVisitor.h b/sci-libs/libspatialindex/svn/trunk/include/capi/ObjVisitor.h
new file mode 100644
index 000000000..13438ba3d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/ObjVisitor.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * $Id: objvisitor.hpp 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the object visitor.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+class ObjVisitor : public SpatialIndex::IVisitor
+{
+private:
+ std::vector<SpatialIndex::IData*> m_vector;
+ uint64_t nResults;
+
+public:
+
+ ObjVisitor();
+ ~ObjVisitor();
+
+ uint32_t GetResultCount() const { return nResults; }
+ std::vector<SpatialIndex::IData*>& GetResults() { return m_vector; }
+
+ void visitNode(const SpatialIndex::INode& n);
+ void visitData(const SpatialIndex::IData& d);
+ void visitData(std::vector<const SpatialIndex::IData*>& v);
+};
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/Utility.h b/sci-libs/libspatialindex/svn/trunk/include/capi/Utility.h
new file mode 100644
index 000000000..58dc1e9b6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/Utility.h
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * $Id: util.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement utilities.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#pragma once
+
+Tools::PropertySet* GetDefaults();
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_api.h b/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_api.h
new file mode 100644
index 000000000..a07131b77
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_api.h
@@ -0,0 +1,213 @@
+/******************************************************************************
+ * $Id: sidx_api.h 1371 2009-08-05 04:39:21Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C API.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+
+#ifndef SIDX_API_H_INCLUDED
+#define SIDX_API_H_INCLUDED
+
+#define SIDX_C_API 1
+
+#include "sidx_config.h"
+
+IDX_C_START
+
+SIDX_DLL IndexH Index_Create(IndexPropertyH properties);
+
+SIDX_DLL IndexH Index_CreateWithStream( IndexPropertyH properties,
+ int (*readNext)(uint64_t *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, size_t *nDataLength)
+ );
+
+SIDX_DLL void Index_Destroy(IndexH index);
+SIDX_DLL IndexPropertyH Index_GetProperties(IndexH index);
+
+SIDX_DLL RTError Index_DeleteData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension);
+
+SIDX_DLL RTError Index_InsertData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ const uint8_t* pData,
+ size_t nDataLength);
+
+SIDX_DLL uint32_t Index_IsValid(IndexH index);
+
+SIDX_DLL RTError Index_Intersects_obj( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_Intersects_id( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_Intersects_count( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t* nResults);
+SIDX_DLL RTError Index_NearestNeighbors_obj(IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_NearestNeighbors_id( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** items,
+ uint64_t* nResults);
+
+SIDX_DLL RTError Index_GetBounds( IndexH index,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension);
+
+
+SIDX_C_DLL RTError Index_GetLeaves( IndexH index,
+ uint32_t* nLeafNodes,
+ uint32_t** nLeafSizes,
+ int64_t** nLeafIDs,
+ int64_t*** nLeafChildIDs,
+ double*** pppdMin,
+ double*** pppdMax,
+ uint32_t* nDimension);
+
+SIDX_DLL void Index_DestroyObjResults(IndexItemH* results, uint32_t nResults);
+SIDX_DLL void Index_ClearBuffer(IndexH index);
+SIDX_DLL void Index_Free(void* object);
+
+SIDX_DLL void IndexItem_Destroy(IndexItemH item);
+SIDX_DLL uint64_t IndexItem_GetID(IndexItemH item);
+
+SIDX_DLL RTError IndexItem_GetData(IndexItemH item, uint8_t** data, uint64_t* length);
+
+SIDX_DLL RTError IndexItem_GetBounds( IndexItemH item,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension);
+
+SIDX_DLL IndexPropertyH IndexProperty_Create();
+SIDX_DLL void IndexProperty_Destroy(IndexPropertyH hProp);
+
+SIDX_DLL RTError IndexProperty_SetIndexType(IndexPropertyH iprop, RTIndexType value);
+SIDX_DLL RTIndexType IndexProperty_GetIndexType(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetDimension(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetDimension(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexVariant(IndexPropertyH iprop, RTIndexVariant value);
+SIDX_DLL RTIndexVariant IndexProperty_GetIndexVariant(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexStorage(IndexPropertyH iprop, RTStorageType value);
+SIDX_DLL RTStorageType IndexProperty_GetIndexStorage(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetPagesize(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetPagesize(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetIndexCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetLeafCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetLeafCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetLeafPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetLeafPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetIndexPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetRegionPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetRegionPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetPointPoolCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetPointPoolCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetBufferingCapacity(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetBufferingCapacity(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetEnsureTightMBRs(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetEnsureTightMBRs(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetOverwrite(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetOverwrite(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetNearMinimumOverlapFactor(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetNearMinimumOverlapFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetWriteThrough(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetWriteThrough(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFillFactor(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetFillFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetSplitDistributionFactor(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetSplitDistributionFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetTPRHorizon(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetTPRHorizon(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetReinsertFactor(IndexPropertyH iprop, double value);
+SIDX_DLL double IndexProperty_GetReinsertFactor(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFileName(IndexPropertyH iprop, const char* value);
+SIDX_DLL char* IndexProperty_GetFileName(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFileNameExtensionDat(IndexPropertyH iprop, const char* value);
+SIDX_DLL char* IndexProperty_GetFileNameExtensionDat(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetFileNameExtensionIdx(IndexPropertyH iprop, const char* value);
+SIDX_DLL char* IndexProperty_GetFileNameExtensionIdx(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetCustomStorageCallbacksSize(IndexPropertyH iprop, uint32_t value);
+SIDX_DLL uint32_t IndexProperty_GetCustomStorageCallbacksSize(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetCustomStorageCallbacks(IndexPropertyH iprop, const void* value);
+SIDX_DLL void* IndexProperty_GetCustomStorageCallbacks(IndexPropertyH iprop);
+
+SIDX_DLL RTError IndexProperty_SetIndexID(IndexPropertyH iprop, int64_t value);
+SIDX_DLL int64_t IndexProperty_GetIndexID(IndexPropertyH iprop);
+
+SIDX_C_DLL void* SIDX_NewBuffer(size_t bytes);
+SIDX_C_DLL void SIDX_DeleteBuffer(void* buffer);
+
+SIDX_C_DLL char* SIDX_Version();
+
+IDX_C_END
+
+#endif \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_config.h b/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_config.h
new file mode 100644
index 000000000..439c701ce
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_config.h
@@ -0,0 +1,121 @@
+/******************************************************************************
+ * $Id: sidx_config.h 1359 2009-07-31 04:44:50Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C API configuration
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#ifndef SIDX_CONFIG_H_INCLUDED
+#define SIDX_CONFIG_H_INCLUDED
+
+
+#ifdef _MSC_VER
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+ #include <windows.h>
+ #define STRDUP _strdup
+ #include "SpatialIndex.h"
+ #include <windows.h>
+
+#else
+
+ #include <stdint.h>
+ #define SIDX_THREAD __thread
+ #include <SpatialIndex.h>
+ #define STRDUP strdup
+#endif
+
+#include <sys/stat.h>
+
+
+
+class Item;
+class Index;
+
+typedef enum
+{
+ RT_None = 0,
+ RT_Debug = 1,
+ RT_Warning = 2,
+ RT_Failure = 3,
+ RT_Fatal = 4
+} RTError;
+
+typedef enum
+{
+ RT_RTree = 0,
+ RT_MVRTree = 1,
+ RT_TPRTree = 2,
+ RT_InvalidIndexType = -99
+} RTIndexType;
+
+typedef enum
+{
+ RT_Memory = 0,
+ RT_Disk = 1,
+ RT_Custom = 2,
+ RT_InvalidStorageType = -99
+} RTStorageType;
+
+typedef enum
+{
+ RT_Linear = 0,
+ RT_Quadratic = 1,
+ RT_Star = 2,
+ RT_InvalidIndexVariant = -99
+} RTIndexVariant;
+
+
+#ifdef __cplusplus
+# define IDX_C_START extern "C" {
+# define IDX_C_END }
+#else
+# define IDX_C_START
+# define IDX_C_END
+#endif
+
+typedef Index *IndexH;
+typedef SpatialIndex::IData *IndexItemH;
+typedef Tools::PropertySet *IndexPropertyH;
+
+#ifndef SIDX_C_DLL
+#if defined(_MSC_VER)
+# define SIDX_C_DLL __declspec(dllexport)
+#else
+# if defined(USE_GCC_VISIBILITY_FLAG)
+# define SIDX_C_DLL __attribute__ ((visibility("default")))
+# else
+# define SIDX_C_DLL
+# endif
+#endif
+#endif
+
+
+#endif
diff --git a/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_impl.h b/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_impl.h
new file mode 100644
index 000000000..25416a924
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/capi/sidx_impl.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * $Id: sidx_impl.hpp 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <stack>
+#include <string>
+#include <vector>
+#include <stdexcept>
+#include <sstream>
+#include <cstring>
+
+#include <capi/sidx_config.h>
+
+#include <capi/Utility.h>
+#include <capi/ObjVisitor.h>
+#include <capi/IdVisitor.h>
+#include <capi/CountVisitor.h>
+#include <capi/BoundsQuery.h>
+#include <capi/LeafQuery.h>
+#include <capi/Error.h>
+#include <capi/DataStream.h>
+#include <capi/Index.h>
+#include <capi/CustomStorage.h>
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/all-wcprops
new file mode 100644
index 000000000..3aa082be9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/all-wcprops
@@ -0,0 +1,41 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/spatialindex/!svn/ver/192/spatialindex/trunk/include/tools
+END
+PointerPool.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/spatialindex/!svn/ver/130/spatialindex/trunk/include/tools/PointerPool.h
+END
+PoolPointer.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/99/spatialindex/trunk/include/tools/PoolPointer.h
+END
+Tools.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/192/spatialindex/trunk/include/tools/Tools.h
+END
+rand48.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/99/spatialindex/trunk/include/tools/rand48.h
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/138/spatialindex/trunk/include/tools/Makefile.am
+END
+SmartPointer.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/spatialindex/!svn/ver/99/spatialindex/trunk/include/tools/SmartPointer.h
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/dir-prop-base
new file mode 100644
index 000000000..a57f5442b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 21
+Makefile
+Makefile.in
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/entries b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/entries
new file mode 100644
index 000000000..e863e3800
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/entries
@@ -0,0 +1,232 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/include/tools
+http://svn.gispython.org/spatialindex
+
+
+
+2010-10-14T13:18:23.380119Z
+192
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+PointerPool.h
+file
+
+
+
+
+2011-08-01T00:42:34.214469Z
+6cd7bba0452721df79787831b0e380e9
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2232
+
+PoolPointer.h
+file
+
+
+
+
+2011-08-01T00:42:34.214469Z
+0b9575f543d7a54dd89aa3ec884b6e44
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2412
+
+Tools.h
+file
+
+
+
+
+2011-08-01T00:42:34.214469Z
+f383cf79a414e56857149c09eaf8f5d0
+2010-10-14T13:18:23.380119Z
+192
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13393
+
+rand48.h
+file
+
+
+
+
+2011-08-01T00:42:34.214469Z
+931a08a36d9cc3cd6d7f2295d1c90d7b
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+367
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.214469Z
+86eb1cf3433f87d161f17cc083feaab8
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+163
+
+SmartPointer.h
+file
+
+
+
+
+2011-08-01T00:42:34.217427Z
+db9e23168b4d63476a2d06ad39b492df
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2012
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PointerPool.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PointerPool.h.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PointerPool.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PoolPointer.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PoolPointer.h.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/PoolPointer.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/SmartPointer.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/SmartPointer.h.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/SmartPointer.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/Tools.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/Tools.h.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/prop-base/Tools.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..ebad2dde3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,7 @@
+spatialindexdir = $(includedir)/spatialindex/tools
+
+dist_spatialindex_HEADERS = Tools.h \
+ PointerPool.h \
+ PoolPointer.h \
+ SmartPointer.h \
+ rand48.h \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PointerPool.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PointerPool.h.svn-base
new file mode 100644
index 000000000..7431ffc13
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PointerPool.h.svn-base
@@ -0,0 +1,117 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "PoolPointer.h"
+
+namespace Tools
+{
+ template <class X> class PointerPool
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ X* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<X> acquire()
+ {
+ X* p = 0;
+
+ if (! m_pool.empty())
+ {
+ p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ m_hits++;
+ #endif
+ }
+ else
+ {
+ p = new X();
+ #ifndef NDEBUG
+ m_pointerCount++;
+ m_misses++;
+ #endif
+ }
+
+ return PoolPointer<X>(p, this);
+ }
+
+ void release(X* p)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ private:
+ uint32_t m_capacity;
+ std::stack<X*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PoolPointer.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PoolPointer.h.svn-base
new file mode 100644
index 000000000..3382e8487
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/PoolPointer.h.svn-base
@@ -0,0 +1,96 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "PointerPool.h"
+
+namespace Tools
+{
+ template <class X> class PointerPool;
+
+ template <class X> class PoolPointer
+ {
+ public:
+ explicit PoolPointer(X* p = 0) : m_pointer(p), m_pPool(0) { m_prev = m_next = this; }
+ explicit PoolPointer(X* p, PointerPool<X>* pPool) throw() : m_pointer(p), m_pPool(pPool) { m_prev = m_next = this; }
+ ~PoolPointer() { release(); }
+ PoolPointer(const PoolPointer& p) throw() { acquire(p); }
+ PoolPointer& operator=(const PoolPointer& p)
+ {
+ if (this != &p)
+ {
+ release();
+ acquire(p);
+ }
+ return *this;
+ }
+
+ X& operator*() const throw() { return *m_pointer; }
+ X* operator->() const throw() { return m_pointer; }
+ X* get() const throw() { return m_pointer; }
+ bool unique() const throw() { return m_prev ? m_prev == this : true; }
+ void relinquish() throw()
+ {
+ m_pPool = 0;
+ m_pointer = 0;
+ release();
+ }
+
+ private:
+ X* m_pointer;
+ mutable const PoolPointer* m_prev;
+ mutable const PoolPointer* m_next;
+ PointerPool<X>* m_pPool;
+
+ void acquire(const PoolPointer& p) throw()
+ {
+ m_pPool = p.m_pPool;
+ m_pointer = p.m_pointer;
+ m_next = p.m_next;
+ m_next->m_prev = this;
+ m_prev = &p;
+ #ifndef mutable
+ p.m_next = this;
+ #else
+ (const_cast<linked_ptr<X>*>(&p))->m_next = this;
+ #endif
+ }
+
+ void release()
+ {
+ if (unique())
+ {
+ if (m_pPool != 0) m_pPool->release(m_pointer);
+ else delete m_pointer;
+ }
+ else
+ {
+ m_prev->m_next = m_next;
+ m_next->m_prev = m_prev;
+ m_prev = m_next = 0;
+ }
+ m_pointer = 0;
+ m_pPool = 0;
+ }
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/SmartPointer.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/SmartPointer.h.svn-base
new file mode 100644
index 000000000..d9ef7a57b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/SmartPointer.h.svn-base
@@ -0,0 +1,78 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace Tools
+{
+ template <class X> class SmartPointer
+ {
+ public:
+ explicit SmartPointer(X* p = 0) throw() : m_pointer(p) { m_prev = m_next = this; }
+ ~SmartPointer() { release(); }
+ SmartPointer(const SmartPointer& p) throw() { acquire(p); }
+ SmartPointer& operator=(const SmartPointer& p)
+ {
+ if (this != &p)
+ {
+ release();
+ acquire(p);
+ }
+ return *this;
+ }
+
+ X& operator*() const throw() { return *m_pointer; }
+ X* operator->() const throw() { return m_pointer; }
+ X* get() const throw() { return m_pointer; }
+ bool unique() const throw() { return m_prev ? m_prev == this : true; }
+
+ private:
+ X* m_pointer;
+ mutable const SmartPointer* m_prev;
+ mutable const SmartPointer* m_next;
+
+ void acquire(const SmartPointer& p) throw()
+ {
+ m_pointer = p.m_pointer;
+ m_next = p.m_next;
+ m_next->m_prev = this;
+ m_prev = &p;
+ #ifndef mutable
+ p.m_next = this;
+ #else
+ (const_cast<linked_ptr<X>*>(&p))->m_next = this;
+ #endif
+ }
+
+ void release()
+ {
+ if (unique()) delete m_pointer;
+ else
+ {
+ m_prev->m_next = m_next;
+ m_next->m_prev = m_prev;
+ m_prev = m_next = 0;
+ }
+ m_pointer = 0;
+ }
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Tools.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Tools.h.svn-base
new file mode 100644
index 000000000..f41ed9d65
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/Tools.h.svn-base
@@ -0,0 +1,513 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+#pragma warning( disable: 4251 )
+
+#else
+ #include <stdint.h>
+#endif
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ #ifdef SPATIALINDEX_CREATE_DLL
+ #define SIDX_DLL __declspec(dllexport)
+ #else
+ #define SIDX_DLL __declspec(dllimport)
+ #endif
+#else
+ #define SIDX_DLL
+#endif
+
+#include <assert.h>
+#include <iostream>
+#include <iomanip>
+#include <iterator>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <queue>
+#include <vector>
+#include <map>
+#include <set>
+#include <stack>
+#include <list>
+#include <algorithm>
+// #include <cmath>
+// #include <limits>
+// #include <climits>
+
+#if HAVE_PTHREAD_H
+ #include <pthread.h>
+#endif
+
+#include "SmartPointer.h"
+#include "PointerPool.h"
+#include "PoolPointer.h"
+
+typedef uint8_t byte;
+
+namespace Tools
+{
+ SIDX_DLL enum IntervalType
+ {
+ IT_RIGHTOPEN = 0x0,
+ IT_LEFTOPEN,
+ IT_OPEN,
+ IT_CLOSED
+ };
+
+ SIDX_DLL enum VariantType
+ {
+ VT_LONG = 0x0,
+ VT_BYTE,
+ VT_SHORT,
+ VT_FLOAT,
+ VT_DOUBLE,
+ VT_CHAR,
+ VT_USHORT,
+ VT_ULONG,
+ VT_INT,
+ VT_UINT,
+ VT_BOOL,
+ VT_PCHAR,
+ VT_PVOID,
+ VT_EMPTY,
+ VT_LONGLONG,
+ VT_ULONGLONG
+ };
+
+ SIDX_DLL enum FileMode
+ {
+ APPEND = 0x0,
+ CREATE
+ };
+
+ //
+ // Exceptions
+ //
+ class SIDX_DLL Exception
+ {
+ public:
+ virtual std::string what() = 0;
+ virtual ~Exception() {}
+ };
+
+ class SIDX_DLL IndexOutOfBoundsException : public Exception
+ {
+ public:
+ IndexOutOfBoundsException(size_t i);
+ virtual ~IndexOutOfBoundsException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // IndexOutOfBoundsException
+
+ class SIDX_DLL IllegalArgumentException : public Exception
+ {
+ public:
+ IllegalArgumentException(std::string s);
+ virtual ~IllegalArgumentException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // IllegalArgumentException
+
+ class SIDX_DLL IllegalStateException : public Exception
+ {
+ public:
+ IllegalStateException(std::string s);
+ virtual ~IllegalStateException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // IllegalStateException
+
+ class SIDX_DLL EndOfStreamException : public Exception
+ {
+ public:
+ EndOfStreamException(std::string s);
+ virtual ~EndOfStreamException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // EndOfStreamException
+
+ class SIDX_DLL ResourceLockedException : public Exception
+ {
+ public:
+ ResourceLockedException(std::string s);
+ virtual ~ResourceLockedException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // ResourceLockedException
+
+ class SIDX_DLL NotSupportedException : public Exception
+ {
+ public:
+ NotSupportedException(std::string s);
+ virtual ~NotSupportedException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // NotSupportedException
+
+ //
+ // Interfaces
+ //
+ class SIDX_DLL IInterval
+ {
+ public:
+ virtual ~IInterval() {}
+
+ virtual double getLowerBound() const = 0;
+ virtual double getUpperBound() const = 0;
+ virtual void setBounds(double, double) = 0;
+ virtual bool intersectsInterval(const IInterval&) const = 0;
+ virtual bool intersectsInterval(IntervalType type, const double start, const double end) const = 0;
+ virtual bool containsInterval(const IInterval&) const = 0;
+ virtual IntervalType getIntervalType() const = 0;
+ }; // IInterval
+
+ class SIDX_DLL IObject
+ {
+ public:
+ virtual ~IObject() {}
+
+ virtual IObject* clone() = 0;
+ // return a new object that is an exact copy of this one.
+ // IMPORTANT: do not return the this pointer!
+ }; // IObject
+
+ class SIDX_DLL ISerializable
+ {
+ public:
+ virtual ~ISerializable() {}
+
+ virtual uint32_t getByteArraySize() = 0;
+ // returns the size of the required byte array.
+ virtual void loadFromByteArray(const byte* data) = 0;
+ // load this object using the byte array.
+ virtual void storeToByteArray(byte** data, uint32_t& length) = 0;
+ // store this object in the byte array.
+ };
+
+ class SIDX_DLL IComparable
+ {
+ public:
+ virtual ~IComparable() {}
+
+ virtual bool operator<(const IComparable& o) const = 0;
+ virtual bool operator>(const IComparable& o) const = 0;
+ virtual bool operator==(const IComparable& o) const = 0;
+ }; //IComparable
+
+ class SIDX_DLL IObjectComparator
+ {
+ public:
+ virtual ~IObjectComparator() {}
+
+ virtual int compare(IObject* o1, IObject* o2) = 0;
+ }; // IObjectComparator
+
+ class SIDX_DLL IObjectStream
+ {
+ public:
+ virtual ~IObjectStream() {}
+
+ virtual IObject* getNext() = 0;
+ // returns a pointer to the next entry in the
+ // stream or 0 at the end of the stream.
+
+ virtual bool hasNext() = 0;
+ // returns true if there are more items in the stream.
+
+ virtual uint32_t size() = 0;
+ // returns the total number of entries available in the stream.
+
+ virtual void rewind() = 0;
+ // sets the stream pointer to the first entry, if possible.
+ }; // IObjectStream
+
+ //
+ // Classes & Functions
+ //
+
+ class SIDX_DLL Variant
+ {
+ public:
+ Variant();
+
+ VariantType m_varType;
+
+ union
+ {
+ int16_t iVal; // VT_SHORT
+ int32_t lVal; // VT_LONG
+ int64_t llVal; // VT_LONGLONG
+ byte bVal; // VT_BYTE
+ float fltVal; // VT_FLOAT
+ double dblVal; // VT_DOUBLE
+ char cVal; // VT_CHAR
+ uint16_t uiVal; // VT_USHORT
+ uint32_t ulVal; // VT_ULONG
+ uint64_t ullVal; // VT_ULONGLONG
+ bool blVal; // VT_BOOL
+ char* pcVal; // VT_PCHAR
+ void* pvVal; // VT_PVOID
+ } m_val;
+ }; // Variant
+
+ class SIDX_DLL PropertySet;
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::PropertySet& p);
+
+ class SIDX_DLL PropertySet : public ISerializable
+ {
+ public:
+ PropertySet();
+ PropertySet(const byte* data);
+ virtual ~PropertySet();
+
+ Variant getProperty(std::string property);
+ void setProperty(std::string property, Variant& v);
+ void removeProperty(std::string property);
+
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ private:
+ std::map<std::string, Variant> m_propertySet;
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+ friend SIDX_DLL std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p);
+ }; // PropertySet
+
+ // does not support degenerate intervals.
+ class SIDX_DLL Interval : public IInterval
+ {
+ public:
+ Interval();
+ Interval(IntervalType, double, double);
+ Interval(double, double);
+ Interval(const Interval&);
+ virtual ~Interval() {}
+ virtual IInterval& operator=(const IInterval&);
+
+ virtual bool operator==(const Interval&) const;
+ virtual bool operator!=(const Interval&) const;
+ virtual double getLowerBound() const;
+ virtual double getUpperBound() const;
+ virtual void setBounds(double, double);
+ virtual bool intersectsInterval(const IInterval&) const;
+ virtual bool intersectsInterval(IntervalType type, const double start, const double end) const;
+ virtual bool containsInterval(const IInterval&) const;
+ virtual IntervalType getIntervalType() const;
+
+ IntervalType m_type;
+ double m_low;
+ double m_high;
+ }; // Interval
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::Interval& iv);
+
+ class SIDX_DLL Random
+ {
+ public:
+ Random();
+ Random(uint32_t seed, uint16_t xsubi0);
+ virtual ~Random();
+
+ int32_t nextUniformLong();
+ // returns a uniformly distributed long.
+ uint32_t nextUniformUnsignedLong();
+ // returns a uniformly distributed unsigned long.
+ int32_t nextUniformLong(int32_t low, int32_t high);
+ // returns a uniformly distributed long in the range [low, high).
+ uint32_t nextUniformUnsignedLong(uint32_t low, uint32_t high);
+ // returns a uniformly distributed unsigned long in the range [low, high).
+ int64_t nextUniformLongLong();
+ // returns a uniformly distributed long long.
+ uint64_t nextUniformUnsignedLongLong();
+ // returns a uniformly distributed unsigned long long.
+ int64_t nextUniformLongLong(int64_t low, int64_t high);
+ // returns a uniformly distributed unsigned long long in the range [low, high).
+ uint64_t nextUniformUnsignedLongLong(uint64_t low, uint64_t high);
+ // returns a uniformly distributed unsigned long long in the range [low, high).
+ int16_t nextUniformShort();
+ // returns a uniformly distributed short.
+ uint16_t nextUniformUnsignedShort();
+ // returns a uniformly distributed unsigned short.
+ double nextUniformDouble();
+ // returns a uniformly distributed double in the range [0, 1).
+ double nextUniformDouble(double low, double high);
+ // returns a uniformly distributed double in the range [low, high).
+
+ bool flipCoin();
+
+ private:
+ void initDrand(uint32_t seed, uint16_t xsubi0);
+
+ uint16_t* m_pBuffer;
+ }; // Random
+
+ class SIDX_DLL SharedLock
+ {
+ public:
+ #if HAVE_PTHREAD_H
+ SharedLock(pthread_rwlock_t* pLock);
+ ~SharedLock();
+
+ private:
+ pthread_rwlock_t* m_pLock;
+ #endif
+ }; // SharedLock
+
+ class SIDX_DLL ExclusiveLock
+ {
+ public:
+ #if HAVE_PTHREAD_H
+ ExclusiveLock(pthread_rwlock_t* pLock);
+ ~ExclusiveLock();
+
+ private:
+ pthread_rwlock_t* m_pLock;
+ #endif
+ }; // ExclusiveLock
+
+ class SIDX_DLL BufferedFile
+ {
+ public:
+ BufferedFile(uint32_t u32BufferSize = 16384);
+ virtual ~BufferedFile();
+
+ virtual void close();
+ virtual bool eof();
+ virtual void rewind() = 0;
+ virtual void seek(std::fstream::off_type offset) = 0;
+
+ protected:
+ std::fstream m_file;
+ char* m_buffer;
+ uint32_t m_u32BufferSize;
+ bool m_bEOF;
+ };
+
+ class SIDX_DLL BufferedFileReader : public BufferedFile
+ {
+ public:
+ BufferedFileReader();
+ BufferedFileReader(const std::string& sFileName, uint32_t u32BufferSize = 32768);
+ virtual ~BufferedFileReader();
+
+ virtual void open(const std::string& sFileName);
+ virtual void rewind();
+ virtual void seek(std::fstream::off_type offset);
+
+ virtual uint8_t readUInt8();
+ virtual uint16_t readUInt16();
+ virtual uint32_t readUInt32();
+ virtual uint64_t readUInt64();
+ virtual float readFloat();
+ virtual double readDouble();
+ virtual bool readBoolean();
+ virtual std::string readString();
+ virtual void readBytes(uint32_t u32Len, byte** pData);
+ };
+
+ class SIDX_DLL BufferedFileWriter : public BufferedFile
+ {
+ public:
+ BufferedFileWriter();
+ BufferedFileWriter(const std::string& sFileName, FileMode mode = CREATE, uint32_t u32BufferSize = 32768);
+ virtual ~BufferedFileWriter();
+
+ virtual void open(const std::string& sFileName, FileMode mode = CREATE);
+ virtual void rewind();
+ virtual void seek(std::fstream::off_type offset);
+
+ virtual void write(uint8_t i);
+ virtual void write(uint16_t i);
+ virtual void write(uint32_t i);
+ virtual void write(uint64_t i);
+ virtual void write(float i);
+ virtual void write(double i);
+ virtual void write(bool b);
+ virtual void write(const std::string& s);
+ virtual void write(uint32_t u32Len, byte* pData);
+ };
+
+ class SIDX_DLL TemporaryFile
+ {
+ public:
+ TemporaryFile();
+ virtual ~TemporaryFile();
+
+ void rewindForReading();
+ void rewindForWriting();
+ bool eof();
+ std::string getFileName() const;
+
+ uint8_t readUInt8();
+ uint16_t readUInt16();
+ uint32_t readUInt32();
+ uint64_t readUInt64();
+ float readFloat();
+ double readDouble();
+ std::string readString();
+ void readBytes(uint32_t u32Len, byte** pData);
+
+ void write(uint8_t i);
+ void write(uint16_t i);
+ void write(uint32_t i);
+ void write(uint64_t i);
+ void write(float i);
+ void write(double i);
+ void write(const std::string& s);
+ void write(uint32_t u32Len, byte* pData);
+
+ private:
+ std::string m_sFile;
+ BufferedFile* m_pFile;
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/rand48.h.svn-base b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/rand48.h.svn-base
new file mode 100644
index 000000000..fd2063ef7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/.svn/text-base/rand48.h.svn-base
@@ -0,0 +1,11 @@
+#pragma once
+
+extern void srand48(long seed);
+extern unsigned short *seed48(unsigned short xseed[3]);
+extern long nrand48(unsigned short xseed[3]);
+extern long mrand48(void);
+extern long lrand48(void);
+extern void lcong48(unsigned short p[7]);
+extern long jrand48(unsigned short xseed[3]);
+extern double erand48(unsigned short xseed[3]);
+extern double drand48(void);
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/Makefile.am b/sci-libs/libspatialindex/svn/trunk/include/tools/Makefile.am
new file mode 100644
index 000000000..ebad2dde3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/Makefile.am
@@ -0,0 +1,7 @@
+spatialindexdir = $(includedir)/spatialindex/tools
+
+dist_spatialindex_HEADERS = Tools.h \
+ PointerPool.h \
+ PoolPointer.h \
+ SmartPointer.h \
+ rand48.h \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/PointerPool.h b/sci-libs/libspatialindex/svn/trunk/include/tools/PointerPool.h
new file mode 100755
index 000000000..7431ffc13
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/PointerPool.h
@@ -0,0 +1,117 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "PoolPointer.h"
+
+namespace Tools
+{
+ template <class X> class PointerPool
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ X* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<X> acquire()
+ {
+ X* p = 0;
+
+ if (! m_pool.empty())
+ {
+ p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ m_hits++;
+ #endif
+ }
+ else
+ {
+ p = new X();
+ #ifndef NDEBUG
+ m_pointerCount++;
+ m_misses++;
+ #endif
+ }
+
+ return PoolPointer<X>(p, this);
+ }
+
+ void release(X* p)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ private:
+ uint32_t m_capacity;
+ std::stack<X*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/PoolPointer.h b/sci-libs/libspatialindex/svn/trunk/include/tools/PoolPointer.h
new file mode 100755
index 000000000..3382e8487
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/PoolPointer.h
@@ -0,0 +1,96 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "PointerPool.h"
+
+namespace Tools
+{
+ template <class X> class PointerPool;
+
+ template <class X> class PoolPointer
+ {
+ public:
+ explicit PoolPointer(X* p = 0) : m_pointer(p), m_pPool(0) { m_prev = m_next = this; }
+ explicit PoolPointer(X* p, PointerPool<X>* pPool) throw() : m_pointer(p), m_pPool(pPool) { m_prev = m_next = this; }
+ ~PoolPointer() { release(); }
+ PoolPointer(const PoolPointer& p) throw() { acquire(p); }
+ PoolPointer& operator=(const PoolPointer& p)
+ {
+ if (this != &p)
+ {
+ release();
+ acquire(p);
+ }
+ return *this;
+ }
+
+ X& operator*() const throw() { return *m_pointer; }
+ X* operator->() const throw() { return m_pointer; }
+ X* get() const throw() { return m_pointer; }
+ bool unique() const throw() { return m_prev ? m_prev == this : true; }
+ void relinquish() throw()
+ {
+ m_pPool = 0;
+ m_pointer = 0;
+ release();
+ }
+
+ private:
+ X* m_pointer;
+ mutable const PoolPointer* m_prev;
+ mutable const PoolPointer* m_next;
+ PointerPool<X>* m_pPool;
+
+ void acquire(const PoolPointer& p) throw()
+ {
+ m_pPool = p.m_pPool;
+ m_pointer = p.m_pointer;
+ m_next = p.m_next;
+ m_next->m_prev = this;
+ m_prev = &p;
+ #ifndef mutable
+ p.m_next = this;
+ #else
+ (const_cast<linked_ptr<X>*>(&p))->m_next = this;
+ #endif
+ }
+
+ void release()
+ {
+ if (unique())
+ {
+ if (m_pPool != 0) m_pPool->release(m_pointer);
+ else delete m_pointer;
+ }
+ else
+ {
+ m_prev->m_next = m_next;
+ m_next->m_prev = m_prev;
+ m_prev = m_next = 0;
+ }
+ m_pointer = 0;
+ m_pPool = 0;
+ }
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/SmartPointer.h b/sci-libs/libspatialindex/svn/trunk/include/tools/SmartPointer.h
new file mode 100755
index 000000000..d9ef7a57b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/SmartPointer.h
@@ -0,0 +1,78 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace Tools
+{
+ template <class X> class SmartPointer
+ {
+ public:
+ explicit SmartPointer(X* p = 0) throw() : m_pointer(p) { m_prev = m_next = this; }
+ ~SmartPointer() { release(); }
+ SmartPointer(const SmartPointer& p) throw() { acquire(p); }
+ SmartPointer& operator=(const SmartPointer& p)
+ {
+ if (this != &p)
+ {
+ release();
+ acquire(p);
+ }
+ return *this;
+ }
+
+ X& operator*() const throw() { return *m_pointer; }
+ X* operator->() const throw() { return m_pointer; }
+ X* get() const throw() { return m_pointer; }
+ bool unique() const throw() { return m_prev ? m_prev == this : true; }
+
+ private:
+ X* m_pointer;
+ mutable const SmartPointer* m_prev;
+ mutable const SmartPointer* m_next;
+
+ void acquire(const SmartPointer& p) throw()
+ {
+ m_pointer = p.m_pointer;
+ m_next = p.m_next;
+ m_next->m_prev = this;
+ m_prev = &p;
+ #ifndef mutable
+ p.m_next = this;
+ #else
+ (const_cast<linked_ptr<X>*>(&p))->m_next = this;
+ #endif
+ }
+
+ void release()
+ {
+ if (unique()) delete m_pointer;
+ else
+ {
+ m_prev->m_next = m_next;
+ m_next->m_prev = m_prev;
+ m_prev = m_next = 0;
+ }
+ m_pointer = 0;
+ }
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/Tools.h b/sci-libs/libspatialindex/svn/trunk/include/tools/Tools.h
new file mode 100755
index 000000000..f41ed9d65
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/Tools.h
@@ -0,0 +1,513 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+#pragma warning( disable: 4251 )
+
+#else
+ #include <stdint.h>
+#endif
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ #ifdef SPATIALINDEX_CREATE_DLL
+ #define SIDX_DLL __declspec(dllexport)
+ #else
+ #define SIDX_DLL __declspec(dllimport)
+ #endif
+#else
+ #define SIDX_DLL
+#endif
+
+#include <assert.h>
+#include <iostream>
+#include <iomanip>
+#include <iterator>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <queue>
+#include <vector>
+#include <map>
+#include <set>
+#include <stack>
+#include <list>
+#include <algorithm>
+// #include <cmath>
+// #include <limits>
+// #include <climits>
+
+#if HAVE_PTHREAD_H
+ #include <pthread.h>
+#endif
+
+#include "SmartPointer.h"
+#include "PointerPool.h"
+#include "PoolPointer.h"
+
+typedef uint8_t byte;
+
+namespace Tools
+{
+ SIDX_DLL enum IntervalType
+ {
+ IT_RIGHTOPEN = 0x0,
+ IT_LEFTOPEN,
+ IT_OPEN,
+ IT_CLOSED
+ };
+
+ SIDX_DLL enum VariantType
+ {
+ VT_LONG = 0x0,
+ VT_BYTE,
+ VT_SHORT,
+ VT_FLOAT,
+ VT_DOUBLE,
+ VT_CHAR,
+ VT_USHORT,
+ VT_ULONG,
+ VT_INT,
+ VT_UINT,
+ VT_BOOL,
+ VT_PCHAR,
+ VT_PVOID,
+ VT_EMPTY,
+ VT_LONGLONG,
+ VT_ULONGLONG
+ };
+
+ SIDX_DLL enum FileMode
+ {
+ APPEND = 0x0,
+ CREATE
+ };
+
+ //
+ // Exceptions
+ //
+ class SIDX_DLL Exception
+ {
+ public:
+ virtual std::string what() = 0;
+ virtual ~Exception() {}
+ };
+
+ class SIDX_DLL IndexOutOfBoundsException : public Exception
+ {
+ public:
+ IndexOutOfBoundsException(size_t i);
+ virtual ~IndexOutOfBoundsException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // IndexOutOfBoundsException
+
+ class SIDX_DLL IllegalArgumentException : public Exception
+ {
+ public:
+ IllegalArgumentException(std::string s);
+ virtual ~IllegalArgumentException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // IllegalArgumentException
+
+ class SIDX_DLL IllegalStateException : public Exception
+ {
+ public:
+ IllegalStateException(std::string s);
+ virtual ~IllegalStateException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // IllegalStateException
+
+ class SIDX_DLL EndOfStreamException : public Exception
+ {
+ public:
+ EndOfStreamException(std::string s);
+ virtual ~EndOfStreamException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // EndOfStreamException
+
+ class SIDX_DLL ResourceLockedException : public Exception
+ {
+ public:
+ ResourceLockedException(std::string s);
+ virtual ~ResourceLockedException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // ResourceLockedException
+
+ class SIDX_DLL NotSupportedException : public Exception
+ {
+ public:
+ NotSupportedException(std::string s);
+ virtual ~NotSupportedException() {}
+ virtual std::string what();
+
+ private:
+ std::string m_error;
+ }; // NotSupportedException
+
+ //
+ // Interfaces
+ //
+ class SIDX_DLL IInterval
+ {
+ public:
+ virtual ~IInterval() {}
+
+ virtual double getLowerBound() const = 0;
+ virtual double getUpperBound() const = 0;
+ virtual void setBounds(double, double) = 0;
+ virtual bool intersectsInterval(const IInterval&) const = 0;
+ virtual bool intersectsInterval(IntervalType type, const double start, const double end) const = 0;
+ virtual bool containsInterval(const IInterval&) const = 0;
+ virtual IntervalType getIntervalType() const = 0;
+ }; // IInterval
+
+ class SIDX_DLL IObject
+ {
+ public:
+ virtual ~IObject() {}
+
+ virtual IObject* clone() = 0;
+ // return a new object that is an exact copy of this one.
+ // IMPORTANT: do not return the this pointer!
+ }; // IObject
+
+ class SIDX_DLL ISerializable
+ {
+ public:
+ virtual ~ISerializable() {}
+
+ virtual uint32_t getByteArraySize() = 0;
+ // returns the size of the required byte array.
+ virtual void loadFromByteArray(const byte* data) = 0;
+ // load this object using the byte array.
+ virtual void storeToByteArray(byte** data, uint32_t& length) = 0;
+ // store this object in the byte array.
+ };
+
+ class SIDX_DLL IComparable
+ {
+ public:
+ virtual ~IComparable() {}
+
+ virtual bool operator<(const IComparable& o) const = 0;
+ virtual bool operator>(const IComparable& o) const = 0;
+ virtual bool operator==(const IComparable& o) const = 0;
+ }; //IComparable
+
+ class SIDX_DLL IObjectComparator
+ {
+ public:
+ virtual ~IObjectComparator() {}
+
+ virtual int compare(IObject* o1, IObject* o2) = 0;
+ }; // IObjectComparator
+
+ class SIDX_DLL IObjectStream
+ {
+ public:
+ virtual ~IObjectStream() {}
+
+ virtual IObject* getNext() = 0;
+ // returns a pointer to the next entry in the
+ // stream or 0 at the end of the stream.
+
+ virtual bool hasNext() = 0;
+ // returns true if there are more items in the stream.
+
+ virtual uint32_t size() = 0;
+ // returns the total number of entries available in the stream.
+
+ virtual void rewind() = 0;
+ // sets the stream pointer to the first entry, if possible.
+ }; // IObjectStream
+
+ //
+ // Classes & Functions
+ //
+
+ class SIDX_DLL Variant
+ {
+ public:
+ Variant();
+
+ VariantType m_varType;
+
+ union
+ {
+ int16_t iVal; // VT_SHORT
+ int32_t lVal; // VT_LONG
+ int64_t llVal; // VT_LONGLONG
+ byte bVal; // VT_BYTE
+ float fltVal; // VT_FLOAT
+ double dblVal; // VT_DOUBLE
+ char cVal; // VT_CHAR
+ uint16_t uiVal; // VT_USHORT
+ uint32_t ulVal; // VT_ULONG
+ uint64_t ullVal; // VT_ULONGLONG
+ bool blVal; // VT_BOOL
+ char* pcVal; // VT_PCHAR
+ void* pvVal; // VT_PVOID
+ } m_val;
+ }; // Variant
+
+ class SIDX_DLL PropertySet;
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::PropertySet& p);
+
+ class SIDX_DLL PropertySet : public ISerializable
+ {
+ public:
+ PropertySet();
+ PropertySet(const byte* data);
+ virtual ~PropertySet();
+
+ Variant getProperty(std::string property);
+ void setProperty(std::string property, Variant& v);
+ void removeProperty(std::string property);
+
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& length);
+
+ private:
+ std::map<std::string, Variant> m_propertySet;
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+ friend SIDX_DLL std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p);
+ }; // PropertySet
+
+ // does not support degenerate intervals.
+ class SIDX_DLL Interval : public IInterval
+ {
+ public:
+ Interval();
+ Interval(IntervalType, double, double);
+ Interval(double, double);
+ Interval(const Interval&);
+ virtual ~Interval() {}
+ virtual IInterval& operator=(const IInterval&);
+
+ virtual bool operator==(const Interval&) const;
+ virtual bool operator!=(const Interval&) const;
+ virtual double getLowerBound() const;
+ virtual double getUpperBound() const;
+ virtual void setBounds(double, double);
+ virtual bool intersectsInterval(const IInterval&) const;
+ virtual bool intersectsInterval(IntervalType type, const double start, const double end) const;
+ virtual bool containsInterval(const IInterval&) const;
+ virtual IntervalType getIntervalType() const;
+
+ IntervalType m_type;
+ double m_low;
+ double m_high;
+ }; // Interval
+
+ SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::Interval& iv);
+
+ class SIDX_DLL Random
+ {
+ public:
+ Random();
+ Random(uint32_t seed, uint16_t xsubi0);
+ virtual ~Random();
+
+ int32_t nextUniformLong();
+ // returns a uniformly distributed long.
+ uint32_t nextUniformUnsignedLong();
+ // returns a uniformly distributed unsigned long.
+ int32_t nextUniformLong(int32_t low, int32_t high);
+ // returns a uniformly distributed long in the range [low, high).
+ uint32_t nextUniformUnsignedLong(uint32_t low, uint32_t high);
+ // returns a uniformly distributed unsigned long in the range [low, high).
+ int64_t nextUniformLongLong();
+ // returns a uniformly distributed long long.
+ uint64_t nextUniformUnsignedLongLong();
+ // returns a uniformly distributed unsigned long long.
+ int64_t nextUniformLongLong(int64_t low, int64_t high);
+ // returns a uniformly distributed unsigned long long in the range [low, high).
+ uint64_t nextUniformUnsignedLongLong(uint64_t low, uint64_t high);
+ // returns a uniformly distributed unsigned long long in the range [low, high).
+ int16_t nextUniformShort();
+ // returns a uniformly distributed short.
+ uint16_t nextUniformUnsignedShort();
+ // returns a uniformly distributed unsigned short.
+ double nextUniformDouble();
+ // returns a uniformly distributed double in the range [0, 1).
+ double nextUniformDouble(double low, double high);
+ // returns a uniformly distributed double in the range [low, high).
+
+ bool flipCoin();
+
+ private:
+ void initDrand(uint32_t seed, uint16_t xsubi0);
+
+ uint16_t* m_pBuffer;
+ }; // Random
+
+ class SIDX_DLL SharedLock
+ {
+ public:
+ #if HAVE_PTHREAD_H
+ SharedLock(pthread_rwlock_t* pLock);
+ ~SharedLock();
+
+ private:
+ pthread_rwlock_t* m_pLock;
+ #endif
+ }; // SharedLock
+
+ class SIDX_DLL ExclusiveLock
+ {
+ public:
+ #if HAVE_PTHREAD_H
+ ExclusiveLock(pthread_rwlock_t* pLock);
+ ~ExclusiveLock();
+
+ private:
+ pthread_rwlock_t* m_pLock;
+ #endif
+ }; // ExclusiveLock
+
+ class SIDX_DLL BufferedFile
+ {
+ public:
+ BufferedFile(uint32_t u32BufferSize = 16384);
+ virtual ~BufferedFile();
+
+ virtual void close();
+ virtual bool eof();
+ virtual void rewind() = 0;
+ virtual void seek(std::fstream::off_type offset) = 0;
+
+ protected:
+ std::fstream m_file;
+ char* m_buffer;
+ uint32_t m_u32BufferSize;
+ bool m_bEOF;
+ };
+
+ class SIDX_DLL BufferedFileReader : public BufferedFile
+ {
+ public:
+ BufferedFileReader();
+ BufferedFileReader(const std::string& sFileName, uint32_t u32BufferSize = 32768);
+ virtual ~BufferedFileReader();
+
+ virtual void open(const std::string& sFileName);
+ virtual void rewind();
+ virtual void seek(std::fstream::off_type offset);
+
+ virtual uint8_t readUInt8();
+ virtual uint16_t readUInt16();
+ virtual uint32_t readUInt32();
+ virtual uint64_t readUInt64();
+ virtual float readFloat();
+ virtual double readDouble();
+ virtual bool readBoolean();
+ virtual std::string readString();
+ virtual void readBytes(uint32_t u32Len, byte** pData);
+ };
+
+ class SIDX_DLL BufferedFileWriter : public BufferedFile
+ {
+ public:
+ BufferedFileWriter();
+ BufferedFileWriter(const std::string& sFileName, FileMode mode = CREATE, uint32_t u32BufferSize = 32768);
+ virtual ~BufferedFileWriter();
+
+ virtual void open(const std::string& sFileName, FileMode mode = CREATE);
+ virtual void rewind();
+ virtual void seek(std::fstream::off_type offset);
+
+ virtual void write(uint8_t i);
+ virtual void write(uint16_t i);
+ virtual void write(uint32_t i);
+ virtual void write(uint64_t i);
+ virtual void write(float i);
+ virtual void write(double i);
+ virtual void write(bool b);
+ virtual void write(const std::string& s);
+ virtual void write(uint32_t u32Len, byte* pData);
+ };
+
+ class SIDX_DLL TemporaryFile
+ {
+ public:
+ TemporaryFile();
+ virtual ~TemporaryFile();
+
+ void rewindForReading();
+ void rewindForWriting();
+ bool eof();
+ std::string getFileName() const;
+
+ uint8_t readUInt8();
+ uint16_t readUInt16();
+ uint32_t readUInt32();
+ uint64_t readUInt64();
+ float readFloat();
+ double readDouble();
+ std::string readString();
+ void readBytes(uint32_t u32Len, byte** pData);
+
+ void write(uint8_t i);
+ void write(uint16_t i);
+ void write(uint32_t i);
+ void write(uint64_t i);
+ void write(float i);
+ void write(double i);
+ void write(const std::string& s);
+ void write(uint32_t u32Len, byte* pData);
+
+ private:
+ std::string m_sFile;
+ BufferedFile* m_pFile;
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/include/tools/rand48.h b/sci-libs/libspatialindex/svn/trunk/include/tools/rand48.h
new file mode 100644
index 000000000..fd2063ef7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/include/tools/rand48.h
@@ -0,0 +1,11 @@
+#pragma once
+
+extern void srand48(long seed);
+extern unsigned short *seed48(unsigned short xseed[3]);
+extern long nrand48(unsigned short xseed[3]);
+extern long mrand48(void);
+extern long lrand48(void);
+extern void lcong48(unsigned short p[7]);
+extern long jrand48(unsigned short xseed[3]);
+extern double erand48(unsigned short xseed[3]);
+extern double drand48(void);
diff --git a/sci-libs/libspatialindex/svn/trunk/install-sh b/sci-libs/libspatialindex/svn/trunk/install-sh
new file mode 100755
index 000000000..dd97db7aa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/install-sh
@@ -0,0 +1,322 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2004-09-10.20
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c (ignored)
+-d create directories instead of installing files.
+-g GROUP $chgrpprog installed files to GROUP.
+-m MODE $chmodprog installed files to MODE.
+-o USER $chownprog installed files to USER.
+-s $stripprog installed files.
+-t DIRECTORY install into DIRECTORY.
+-T report an error if DSTFILE is a directory.
+--help display this help and exit.
+--version display version info and exit.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+ case $1 in
+ -c) shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ --help) echo "$usage"; exit 0;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t) dstarg=$2
+ shift
+ shift
+ continue;;
+
+ -T) no_target_directory=true
+ shift
+ continue;;
+
+ --version) echo "$0 $scriptversion"; exit 0;;
+
+ *) # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ test -n "$dir_arg$dstarg" && break
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dstarg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dstarg"
+ shift # fnord
+ fi
+ shift # arg
+ dstarg=$arg
+ done
+ break;;
+ esac
+done
+
+if test -z "$1"; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src ;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ src=
+
+ if test -d "$dst"; then
+ mkdircmd=:
+ chmodcmd=
+ else
+ mkdircmd=$mkdirprog
+ fi
+ else
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dstarg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dstarg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst ;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dstarg: Is a directory" >&2
+ exit 1
+ fi
+ dst=$dst/`basename "$src"`
+ fi
+ fi
+
+ # This sed command emulates the dirname command.
+ dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+ # Make sure that the destination directory exists.
+
+ # Skip lots of stat calls in the usual case.
+ if test ! -d "$dstdir"; then
+ defaultIFS='
+ '
+ IFS="${IFS-$defaultIFS}"
+
+ oIFS=$IFS
+ # Some sh's can't handle IFS=/ for some reason.
+ IFS='%'
+ set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+ IFS=$oIFS
+
+ pathcomp=
+
+ while test $# -ne 0 ; do
+ pathcomp=$pathcomp$1
+ shift
+ if test ! -d "$pathcomp"; then
+ $mkdirprog "$pathcomp"
+ # mkdir can fail with a `File exist' error in case several
+ # install-sh are creating the directory concurrently. This
+ # is OK.
+ test -d "$pathcomp" || exit
+ fi
+ pathcomp=$pathcomp/
+ done
+ fi
+
+ if test -n "$dir_arg"; then
+ $doit $mkdircmd "$dst" \
+ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+ else
+ dstfile=`basename "$dst"`
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Copy the file name to the temp name.
+ $doit $cpprog "$src" "$dsttmp" &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+ # Now rename the file to the real destination.
+ { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+ || {
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ if test -f "$dstdir/$dstfile"; then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+ || {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit
+ }
+ else
+ :
+ fi
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+ }
+ }
+ fi || { (exit 1); exit; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+ (exit 0); exit
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/makefile.vc b/sci-libs/libspatialindex/svn/trunk/makefile.vc
new file mode 100644
index 000000000..6d018a383
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/makefile.vc
@@ -0,0 +1,217 @@
+
+.SUFFIXES: .cc
+
+SPATIALINDEX_HOME=c:\cvs\buildkit\spatialindex
+DLL_VERSION = 1
+
+BINDIR=$(SPATIALINDEX_HOME)\bin
+OSGEO4W_DIR = $(SPATIALINDEX_HOME)\osgeo4w
+
+
+###############################################################################
+# Set BUILD_DEBUG balue to YES if you want to make debug build
+# and to prepare not optimized binaries.
+!IFNDEF BUILD_DEBUG
+BUILD_DEBUG = NO
+!ENDIF
+
+
+###############################################################################
+# Derive version of Visual C++ being used from NMAKE if not specified
+#
+# WARNING:
+# If we should expect variety of NMAKE build versions, tests below may fail
+# and we will need to fall back to setting MSVCVER as command line parameter.
+#
+!IF "$(_NMAKE_VER)" == ""
+MSVCVER = 4.0
+!ERROR *** Failed to determine version of Visual C++
+!ELSEIF "$(_NMAKE_VER)" == "162"
+MSVCVER = 5.0
+!ERROR *** Detected Visual C++ 5.0 - NOT SUPPORTED
+!ELSEIF "$(_NMAKE_VER)" == "6.00.8168.0"
+MSVCVER = 6.0
+!ERROR *** Detected Visual C++ 6.0 - NOT SUPPORTED
+!ELSEIF "$(_NMAKE_VER)" == "7.00.9466"
+MSVCVER = 7.0
+!ELSEIF "$(_NMAKE_VER)" == "7.10.3077"
+MSVCVER = 7.1
+!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.42"
+MSVCVER = 8.0
+!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.762"
+MSVCVER = 8.0
+!ELSEIF "$(_NMAKE_VER)" == "9.00.21022.08"
+MSVCVER = 9.0
+!ELSEIF "$(_NMAKE_VER)" == "9.00.30729.01"
+MSVCVER = 9.0
+!ELSE
+MSVCVER = 0.0
+!ENDIF
+
+!IF "$(MSVCVER)" == "0.0"
+!MESSAGE *** Cannot determined Visual C++ version
+!ERROR *** Aborting make job
+!ELSE
+!MESSAGE *** Using Microsoft NMAKE version $(_NMAKE_VER)
+!MESSAGE *** Using Microsoft Visual C++ version $(MSVCVER)
+!ENDIF
+
+###############################################################################
+# Compilation flags for Release and Debug modes
+
+!IF "$(BUILD_DEBUG)" == "YES"
+OPTFLAGS=/nologo /MDd /EHsc /Z7 /W4 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /DDEBUG /D_DEBUG /DDEBUG /Fd$(SPATIALINDEX_HOME)\spatialindex.pdb
+LAS_LIB = spatialindex_d.lib
+LAS_DLL = spatialindex_d$(DLL_VERSION).dll
+LAS_LIB_DLL = spatialindex_i.lib
+!ELSE
+
+# You may need to remove /GR if you are statically linking libLAS
+OPTFLAGS=/nologo /MD /EHsc /Ox /GR /W2 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /DNDEBUG /D "PACKAGE_BUGREPORT=\"hobu.inc@gmail.com\"" /DSPATIALINDEX_CREATE_DLL=1
+LAS_LIB = spatialindex.lib
+LAS_DLL = spatialindex$(DLL_VERSION).dll
+CDLLNAME = spatialindex$(DLL_VERSION)_c.dll
+CLIBNAME = spatialindex_c_i.lib
+LAS_LIB_DLL = spatialindex_i.lib
+!ENDIF
+
+# Check if multiple process build available
+!IF "$(MSVCVER)" == "9.0"
+MPFLAGS=/MP
+!MESSAGE *** Using /MP flag with number of effective processors
+!ELSE
+MPFLAGS=
+!ENDIF
+
+PACKAGE_VERSION=1.6.1
+
+INCLUDES=-I$(SPATIALINDEX_HOME)/include -I$(SPATIALINDEX_HOME)/include/capi
+CFLAGS= $(MPFLAGS) $(OPTFLAGS) $(INCLUDES)
+
+
+# Commands
+#
+MAKE = nmake
+RM = -del
+CC= cl
+LINK= link
+
+LAS_DIRLIST = src\mvrtree \
+ src\rtree \
+ src\spatialindex \
+ src\storagemanager \
+ src\tools \
+ src\tprtree \
+ src\capi
+
+OBJS = src\mvrtree\Index.obj \
+ src\mvrtree\Leaf.obj \
+ src\mvrtree\MVRtree.obj \
+ src\mvrtree\Node.obj \
+ src\mvrtree\Statistics.obj \
+ src\rtree\BulkLoader.obj \
+ src\rtree\Index.obj \
+ src\rtree\Leaf.obj \
+ src\rtree\Node.obj \
+ src\rtree\RTree.obj \
+ src\rtree\Statistics.obj \
+ src\spatialindex\LineSegment.obj \
+ src\spatialindex\MovingPoint.obj \
+ src\spatialindex\MovingRegion.obj \
+ src\spatialindex\Point.obj \
+ src\spatialindex\Region.obj \
+ src\spatialindex\SpatialIndexImpl.obj \
+ src\spatialindex\TimePoint.obj \
+ src\spatialindex\TimeRegion.obj \
+ src\storagemanager\Buffer.obj \
+ src\storagemanager\DiskStorageManager.obj \
+ src\storagemanager\MemoryStorageManager.obj \
+ src\storagemanager\RandomEvictionsBuffer.obj \
+ src\tools\rand48.obj \
+ src\tools\Tools.obj \
+ src\tprtree\Index.obj \
+ src\tprtree\Leaf.obj \
+ src\tprtree\Node.obj \
+ src\tprtree\Statistics.obj \
+ src\tprtree\TPRTree.obj
+
+COBJS = src\capi\BoundsQuery.obj \
+ src\capi\CountVisitor.obj \
+ src\capi\CustomStorage.obj \
+ src\capi\DataStream.obj \
+ src\capi\Error.obj \
+ src\capi\IdVisitor.obj \
+ src\capi\Index.obj \
+ src\capi\LeafQuery.obj \
+ src\capi\ObjVisitor.obj \
+ src\capi\sidx_api.obj\
+ src\capi\Utility.obj
+
+default: $(LAS_DLL) $(CDLLNAME)
+
+all: default
+
+
+$(LAS_LIB): $(OBJS)
+ if exist $(LAS_LIB) del $(LAS_LIB)
+ $(LINK) /lib /nologo /out:$(LAS_LIB) $(OBJS)
+
+$(LAS_DLL): $(LAS_LIB) $(RES)
+ $(LINK) /dll \
+ $(OBJS) $(LAS_LIB) \
+ /out:$(LAS_DLL) /implib:$(LAS_LIB_DLL)
+ if exist $(LAS_DLL).manifest mt -manifest $(LAS_DLL).manifest -outputresource:$(LAS_DLL);2
+
+$(CDLLNAME): $(COBJS) $(LAS_DLL)
+ $(LINK) /dll /debug $(COBJS) $(LAS_LIB_DLL) /out:$(CDLLNAME) /implib:$(CLIBNAME)
+ if exist $(CDLLNAME).manifest mt -manifest $(CDLLNAME).manifest -outputresource:$(CDLLNAME);2
+
+
+install: default
+ -mkdir $(BINDIR)
+ -mkdir $(SPATIALINDEX_HOME)\packages
+ -mkdir $(BINDIR)\lib
+ -mkdir $(BINDIR)\include\spatialindex
+ -mkdir $(OSGEO4W_DIR)
+ -mkdir $(OSGEO4W_DIR)\lib
+ -mkdir $(OSGEO4W_DIR)\devel
+ -mkdir $(OSGEO4W_DIR)\lib\bin
+ -mkdir $(OSGEO4W_DIR)\devel\include
+ -mkdir $(OSGEO4W_DIR)\devel\include\spatialindex
+ -mkdir $(OSGEO4W_DIR)\devel\lib
+ xcopy /y /r /d /f spatialindex_i.lib $(BINDIR)\lib
+ xcopy /y /r /d /f spatialindex_i.lib $(OSGEO4W_DIR)\devel\lib
+ xcopy /y /r /d /f spatialindex.lib $(BINDIR)\lib
+ xcopy /y /r /d /f spatialindex.lib $(OSGEO4W_DIR)\devel\lib
+ xcopy /y /r /d /f /s include\* $(BINDIR)\include\spatialindex
+ xcopy /y /r /d /f /s include\* $(OSGEO4W_DIR)\devel\include\spatialindex
+ xcopy /y /r /d /f $(LAS_DLL) $(BINDIR)
+ xcopy /y /r /d /f $(LAS_DLL) $(OSGEO4W_DIR)\lib\bin
+
+.cc.obj:
+ $(CC) $(CFLAGS) /c $*.cc /Fo$@
+
+.c.obj:
+ $(CC) $(CFLAGS) /c $*.c /Fo$@
+
+clean:
+ $(RM) $(LAS_LIB)
+ $(RM) $(LAS_DLL)
+ $(RM) *.ilk
+ $(RM) *.manifest
+ $(RM) *.obj
+ $(RM) *.pdb
+ for %d in ( $(LAS_DIRLIST) ) do \
+ del %d\*.obj
+
+package: install
+ cd $(SPATIALINDEX_HOME)/osgeo4w/lib
+ C:\cygwin\bin\tar.exe cvf ../../packages/libspatialindex-$(PACKAGE_VERSION).tar *
+ c:\cygwin\bin\bzip2.exe -f /cygdrive/c/cvs/buildkit/spatialindex/packages/libspatialindex-$(PACKAGE_VERSION).tar
+ cd $(SPATIALINDEX_HOME)/osgeo4w/
+ cd $(SPATIALINDEX_HOME)/osgeo4w/devel
+ C:\cygwin\bin\tar.exe cvf ../../packages/libspatialindex-devel-$(PACKAGE_VERSION).tar *
+ c:\cygwin\bin\bzip2.exe -f /cygdrive/c/cvs/buildkit/spatialindex/packages/libspatialindex-devel-$(PACKAGE_VERSION).tar
+ cd $(SPATIALINDEX_HOME)/osgeo4w/
+ cd $(SPATIALINDEX_HOME)/
+ c:\cygwin\bin\zip.exe -r packages/libspatialindex-$(PACKAGE_VERSION)-win32.zip bin
diff --git a/sci-libs/libspatialindex/svn/trunk/missing b/sci-libs/libspatialindex/svn/trunk/missing
new file mode 100644
index 000000000..64b5f901d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/missing
@@ -0,0 +1,353 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2004-09-07.08
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit 0
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit 0
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+ lex|yacc)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/mkinstalldirs b/sci-libs/libspatialindex/svn/trunk/mkinstalldirs
new file mode 100755
index 000000000..6fbe5e117
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/mkinstalldirs
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2004-02-15.20
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit 0
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/all-wcprops
new file mode 100644
index 000000000..bda49c2b9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/spatialindex/!svn/ver/182/spatialindex/trunk/regressiontest
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/Makefile.am
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/dir-prop-base
new file mode 100644
index 000000000..a57f5442b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 21
+Makefile
+Makefile.in
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/entries
new file mode 100644
index 000000000..fe126ca06
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/entries
@@ -0,0 +1,71 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest
+http://svn.gispython.org/spatialindex
+
+
+
+2010-04-12T17:17:47.459585Z
+182
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+rtree
+dir
+
+mvrtree
+dir
+
+tprtree
+dir
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.161195Z
+a1b35b54bda110ef312d7f2b23d61b3f
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+105
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..555767682
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,2 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+SUBDIRS = rtree mvrtree tprtree
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/Makefile.am b/sci-libs/libspatialindex/svn/trunk/regressiontest/Makefile.am
new file mode 100644
index 000000000..555767682
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/Makefile.am
@@ -0,0 +1,2 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+SUBDIRS = rtree mvrtree tprtree
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/all-wcprops
new file mode 100644
index 000000000..34202bd6c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/all-wcprops
@@ -0,0 +1,35 @@
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/171/spatialindex/trunk/regressiontest/mvrtree
+END
+MVRTreeLoad.cc
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/spatialindex/!svn/ver/90/spatialindex/trunk/regressiontest/mvrtree/MVRTreeLoad.cc
+END
+Exhaustive.cc
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/spatialindex/!svn/ver/171/spatialindex/trunk/regressiontest/mvrtree/Exhaustive.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/mvrtree/Makefile.am
+END
+Generator.cc
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/spatialindex/!svn/ver/159/spatialindex/trunk/regressiontest/mvrtree/Generator.cc
+END
+MVRTreeQuery.cc
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/spatialindex/!svn/ver/90/spatialindex/trunk/regressiontest/mvrtree/MVRTreeQuery.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/dir-prop-base
new file mode 100644
index 000000000..42643052a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/dir-prop-base
@@ -0,0 +1,13 @@
+K 10
+svn:ignore
+V 79
+Makefile.in
+MVRTreeLoad
+Exhaustive
+Generator
+.libs
+.deps
+MVRTreeQuery
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/entries
new file mode 100644
index 000000000..04525f3aa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/entries
@@ -0,0 +1,204 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/mvrtree
+http://svn.gispython.org/spatialindex
+
+
+
+2009-12-29T02:35:01.217521Z
+171
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+test1
+dir
+
+test2
+dir
+
+MVRTreeLoad.cc
+file
+
+
+
+
+2011-08-01T00:42:34.101428Z
+76ba58f70f4c319c96fbf89fbb0602d4
+2009-05-04T17:10:20.890704Z
+90
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6439
+
+Exhaustive.cc
+file
+
+
+
+
+2011-08-01T00:42:34.101428Z
+acea00cc466cbd5c29c44b202e2afa5f
+2009-12-29T02:35:01.217521Z
+171
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5419
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.101428Z
+1e94b0b0a67c7e0ddc2847eb564da76a
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+492
+
+Generator.cc
+file
+
+
+
+
+2011-08-01T00:42:34.101428Z
+2a7d166c94bbd2157757920195dac6f4
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5705
+
+MVRTreeQuery.cc
+file
+
+
+
+
+2011-08-01T00:42:34.101428Z
+1754e0a954b06cf1038209bb65f2c798
+2009-05-04T17:10:20.890704Z
+90
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6570
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Exhaustive.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Exhaustive.cc.svn-base
new file mode 100644
index 000000000..b73fdf74e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Exhaustive.cc.svn-base
@@ -0,0 +1,225 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <assert.h>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <queue>
+#include <cmath>
+#include <cstring>
+#include <limits>
+#include <cmath>
+#include <stdint.h>
+
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+#pragma warning( disable: 4251 )
+
+#else
+ #include <stdint.h>
+#endif
+
+class TimeRegion
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+ double m_startTime, m_endTime;
+
+ TimeRegion() {}
+
+ TimeRegion(double x1, double y1, double x2, double y2, double t1, double t2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ m_startTime = t1;
+ m_endTime = (t2 <= 0) ? std::numeric_limits<double>::max() : t2;
+ }
+
+ bool intersects(TimeRegion& r)
+ {
+ if (m_xmin > r.m_xmax || m_xmax < r.m_xmin ||
+ m_ymin > r.m_ymax || m_ymax < r.m_ymin) return false;
+
+ return true;
+ }
+
+ bool intersectsInTime(TimeRegion& r)
+ {
+ //if (m_startTime != r.m_startTime && (m_endTime <= r.m_startTime || m_startTime >= r.m_endTime)) return false;
+ if (m_endTime <= r.m_startTime || m_startTime >= r.m_endTime) return false;
+ return intersects(r);
+ }
+
+ double getMinDist(const TimeRegion& r)
+ {
+ double ret = 0.0;
+
+ if (r.m_xmax < m_xmin)
+ ret += std::pow(m_xmin - r.m_xmax, 2.0);
+ else if (r.m_xmin > m_xmax)
+ ret += std::pow(r.m_xmin - m_xmax, 2.0);
+
+ if (r.m_ymax < m_ymin)
+ ret += std::pow(m_ymin - r.m_ymax, 2.0);
+ else if (r.m_ymin > m_ymax)
+ ret += std::pow(r.m_ymin - m_ymax, 2.0);
+
+ return ret;
+ }
+};
+
+class NNEntry
+{
+public:
+ size_t m_id;
+ double m_dist;
+
+ NNEntry(size_t id, double dist) : m_id(id), m_dist(dist) {}
+
+ struct greater : public binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_dist > __y->m_dist; }
+ };
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ cerr << "Usage: " << argv[0] << " data_file query_type [intersection | 10NN]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[2], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[2], "10NN") == 0) queryType = 1;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file" << argv[1] << "." << endl;
+ return -1;
+ }
+
+ multimap<size_t, TimeRegion> data;
+ size_t id;
+ uint32_t op;
+ double x1, x2, y1, y2, t;
+
+ while (fin)
+ {
+ fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue;
+
+ if (op == INSERT)
+ {
+ //insert
+ data.insert(pair<size_t, TimeRegion>(id, TimeRegion(x1, y1, x2, y2, t, std::numeric_limits<double>::max())));
+ }
+ else if (op == DELETE)
+ {
+ //delete
+ // find the live instance of id.
+ multimap<size_t, TimeRegion>::iterator it = data.find(id);
+ assert(it != data.end());
+ while (it->first == id && it->second.m_endTime < std::numeric_limits<double>::max()) it++;
+ assert(it->first == id);
+ (*it).second.m_endTime = t;
+ }
+ else if (op == QUERY)
+ {
+ size_t qt1, qt2;
+ fin >> qt1 >> qt2;
+ if (! fin.good()) continue;
+
+ //query
+ if (queryType == 0)
+ {
+ TimeRegion query = TimeRegion(x1, y1, x2, y2, qt1, qt2);
+ for (multimap<size_t, TimeRegion>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ if (query.intersectsInTime((*it).second)) cout << (*it).first << endl;
+ }
+ }
+ else
+ {
+ /*
+ TimeRegion query = TimeRegion(x1, y1, x1, y1, qt1, qt2);
+
+ priority_queue<NNEntry*, vector<NNEntry*>, NNEntry::greater > queue;
+
+ for (multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ queue.push(new NNEntry((*it).first, (*it).second.getMinDist(query)));
+ }
+
+ size_t count = 0;
+ double knearest = 0.0;
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+
+ if (count >= 10 && e->m_dist > knearest) break;
+
+ //cout << e->m_id << " " << e->m_dist << endl;
+ cout << e->m_id << endl;
+ count++;
+ knearest = e->m_dist;
+ delete e;
+ }
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+ delete e;
+ }
+ */
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Generator.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Generator.cc.svn-base
new file mode 100644
index 000000000..288684c69
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Generator.cc.svn-base
@@ -0,0 +1,175 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <tools/Tools.h>
+#include <cmath>
+#include <limits>
+
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+class Region
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+ bool m_bIsDead;
+
+ Region() : m_xmin(numeric_limits<double>::max()), m_ymin(numeric_limits<double>::max()),
+ m_xmax(numeric_limits<double>::max()), m_ymax(numeric_limits<double>::max()) {}
+
+ Region(double x1, double y1, double x2, double y2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ m_bIsDead = false;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ cerr << "Usage: " << argv[0] << " number_of_data." << endl;
+ return -1;
+ }
+
+ size_t numberOfObjects = atoi(argv[1]);
+ map<size_t, Region> data;
+ Tools::Random rnd;
+
+ for (size_t i = 0; i < numberOfObjects; i++)
+ {
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(pair<size_t, Region>(i, r));
+
+ cout << "0 " << INSERT << " " << i << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << endl;
+ }
+
+ size_t nextID = numberOfObjects;
+ size_t A = static_cast<size_t>(std::floor(static_cast<double>(numberOfObjects) * 0.05));
+
+ for (size_t T = 1; T <= 100; T++)
+ {
+ cerr << (101 - T) << endl;
+
+ if (T == 50)
+ {
+ // delete all entries and reinsert
+ for (map<size_t, Region>::iterator itMap = data.begin(); itMap != data.end(); itMap++)
+ {
+ if (! (*itMap).second.m_bIsDead)
+ {
+ (*itMap).second.m_bIsDead = true;
+ cout << "50 " << DELETE << " " << (*itMap).first << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << endl;
+ }
+ }
+
+ for (size_t i = nextID; i < nextID + numberOfObjects; i++)
+ {
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(pair<size_t, Region>(i, r));
+
+ cout << "50 " << INSERT << " " << i << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << endl;
+ }
+
+ nextID += numberOfObjects;
+ continue;
+ }
+
+ set<size_t> examined;
+
+ for (size_t a = 0; a < A; a++)
+ {
+ // find an id that is not examined yet.
+ size_t id = static_cast<size_t>(rnd.nextUniformLongLong(0, nextID));
+ set<size_t>::iterator itSet = examined.find(id);
+ while (itSet != examined.end() || data[id].m_bIsDead == true)
+ {
+ id = static_cast<size_t>(rnd.nextUniformLongLong(0, nextID));
+ itSet = examined.find(id);
+ }
+ examined.insert(id);
+
+ map<size_t, Region>::iterator itMap = data.find(id);
+ assert(itMap != data.end() && (*itMap).second.m_bIsDead == false);
+
+ cout << T << " " << DELETE << " " << id << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << endl;
+ (*itMap).second.m_bIsDead = true;
+
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(pair<size_t, Region>(nextID, r));
+
+ cout << T << " " << INSERT << " " << nextID << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << endl;
+ examined.insert(nextID);
+ nextID++;
+ }
+
+ double stx = rnd.nextUniformDouble();
+ double sty = rnd.nextUniformDouble();
+ size_t qt = rnd.nextUniformLongLong(0, T);
+ cout << T << " " << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << " " << qt << " " << qt + 2<< endl;
+ stx = rnd.nextUniformDouble();
+ sty = rnd.nextUniformDouble();
+ qt = rnd.nextUniformLongLong(0, T);
+ cout << T << " " << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << " " << qt << " " << qt + 2<< endl;
+ stx = rnd.nextUniformDouble();
+ sty = rnd.nextUniformDouble();
+ qt = rnd.nextUniformLongLong(0, T);
+ cout << T << " " << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << " " << qt << " " << qt + 2<< endl;
+ }
+
+ // delete everything at the end (for testing the special case when the tree dies out completely)
+ for (map<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ if (! it->second.m_bIsDead)
+ {
+ cout << 102 << " " << DELETE << " " << it->first << " " << it->second.m_xmin << " " << it->second.m_ymin << " "
+ << it->second.m_xmax << " " << it->second.m_ymax << endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeLoad.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeLoad.cc.svn-base
new file mode 100644
index 000000000..7e07e2731
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeLoad.cc.svn-base
@@ -0,0 +1,209 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+// example of a Visitor pattern.
+// see MVRTreeQuery for a more elaborate example.
+class MyVisitor : public IVisitor
+{
+public:
+ void visitNode(const INode& n) {}
+
+ void visitData(const IData& d)
+ {
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 5)
+ {
+ cerr << "Usage: " << argv[0] << " input_file tree_file capacity query_type [intersection | 10NN]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[4], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[4], "10NN") == 0) queryType = 1;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ // Create a new storage manager with the provided base name and a 4K page size.
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+ //StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // Create a new, empty, MVRTree with dimensionality 2, minimum load 70%, using "file" as
+ // the StorageManager and the RSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = MVRTree::createNewMVRTree(*diskfile, 0.7, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::MVRTree::RV_RSTAR, indexIdentifier);
+
+ size_t count = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2, t;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ TimeRegion r = TimeRegion(plow, phigh, t, t, 2);
+
+ //ostringstream os;
+ //os << r;
+ //string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see MVRTree::Node::load and MVRTree::Node::store for
+ // an example of how to do that).
+
+ //tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ TimeRegion r = TimeRegion(plow, phigh, t, t, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "Cannot delete id: " << id << " , count: " << count << endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ size_t qt1, qt2;
+ fin >> qt1 >> qt2;
+ if (! fin.good()) continue;
+
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ TimeRegion r = TimeRegion(plow, phigh, qt1, qt2, 2);
+
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else
+ {
+ //Point p = Point(plow, 2);
+ //tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ //cerr << "Buffer hits: " << file->getHits() << endl;
+ cerr << "Index ID: " << indexIdentifier << endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) cerr << "ERROR: Structure is invalid!" << endl;
+ else cerr << "The stucture seems O.K." << endl;
+
+ delete tree;
+ //delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeQuery.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeQuery.cc.svn-base
new file mode 100644
index 000000000..f8e367bc7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/MVRTreeQuery.cc.svn-base
@@ -0,0 +1,268 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+// example of a Visitor pattern.
+// findes the index and leaf IO for answering the query and prints
+// the resulting data IDs to stdout.
+class MyVisitor : public IVisitor
+{
+public:
+ size_t m_indexIO;
+ size_t m_leafIO;
+
+public:
+ MyVisitor() : m_indexIO(0), m_leafIO(0) {}
+
+ void visitNode(const INode& n)
+ {
+ if (n.isLeaf()) m_leafIO++;
+ else m_indexIO++;
+ }
+
+ void visitData(const IData& d)
+ {
+ //IShape* pS;
+ //d.getShape(&pS);
+ // do something.
+ //delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ //byte* pData = 0;
+ //size_t cLen = 0;
+ //d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ //delete[] pData;
+
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+// example of a Strategy pattern.
+// traverses the tree by level.
+class MyQueryStrategy : public SpatialIndex::IQueryStrategy
+{
+private:
+ queue<id_type> ids;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ IShape* ps;
+ entry.getShape(&ps);
+ Region* pr = dynamic_cast<Region*>(ps);
+
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl << endl << endl;
+ // print node MBRs gnuplot style!
+
+ delete ps;
+
+ const INode* n = dynamic_cast<const INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 1)
+ {
+ for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (! ids.empty())
+ {
+ nextEntry = ids.front(); ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+};
+
+// example of a Strategy pattern.
+// find the total indexed space managed by the index (the MBR of the root).
+class MyQueryStrategy2 : public IQueryStrategy
+{
+public:
+ Region m_indexedSpace;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ // the first time we are called, entry points to the root.
+
+ // stop after the root.
+ hasNext = false;
+
+ IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(m_indexedSpace);
+ delete ps;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 4)
+ {
+ cerr << "Usage: " << argv[0] << " query_file tree_file query_type [intersection | 10NN]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[3], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[3], "10NN") == 0) queryType = 1;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open query file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName);
+ // this will try to locate and open an already existing storage manager.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // If we need to open an existing tree stored in the storage manager, we only
+ // have to specify the index identifier as follows
+ ISpatialIndex* tree = MVRTree::loadMVRTree(*file, 1);
+
+ size_t count = 0;
+ size_t indexIO = 0;
+ size_t leafIO = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2, t;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == QUERY)
+ {
+ size_t qt1, qt2;
+ fin >> qt1 >> qt2;
+ if (! fin.good()) continue;
+
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ TimeRegion r = TimeRegion(plow, phigh, qt1, qt2, 2);
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else
+ {
+ //Point p = Point(plow, 2);
+ //tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+
+ indexIO += vis.m_indexIO;
+ leafIO += vis.m_leafIO;
+ // example of the Visitor pattern usage, for calculating how many nodes
+ // were visited.
+ }
+ else
+ {
+ cerr << "This is not a query operation." << endl;
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ MyQueryStrategy2 qs;
+ tree->queryStrategy(qs);
+
+ cerr << "Indexed space: " << qs.m_indexedSpace << endl;
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Index I/O: " << indexIO << endl;
+ cerr << "Leaf I/O: " << leafIO << endl;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail writting the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..77a83a1e3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,12 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_PROGRAMS = Generator Exhaustive MVRTreeLoad MVRTreeQuery
+INCLUDES = -I../../include
+Generator_SOURCES = Generator.cc
+Generator_LDADD = ../../libspatialindex.la
+Exhaustive_SOURCES = Exhaustive.cc
+Exhaustive_LDADD = ../../libspatialindex.la
+MVRTreeLoad_SOURCES = MVRTreeLoad.cc
+MVRTreeLoad_LDADD = ../../libspatialindex.la
+MVRTreeQuery_SOURCES = MVRTreeQuery.cc
+MVRTreeQuery_LDADD = ../../libspatialindex.la
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Exhaustive.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Exhaustive.cc
new file mode 100644
index 000000000..b73fdf74e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Exhaustive.cc
@@ -0,0 +1,225 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <assert.h>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <queue>
+#include <cmath>
+#include <cstring>
+#include <limits>
+#include <cmath>
+#include <stdint.h>
+
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+#pragma warning( disable: 4251 )
+
+#else
+ #include <stdint.h>
+#endif
+
+class TimeRegion
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+ double m_startTime, m_endTime;
+
+ TimeRegion() {}
+
+ TimeRegion(double x1, double y1, double x2, double y2, double t1, double t2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ m_startTime = t1;
+ m_endTime = (t2 <= 0) ? std::numeric_limits<double>::max() : t2;
+ }
+
+ bool intersects(TimeRegion& r)
+ {
+ if (m_xmin > r.m_xmax || m_xmax < r.m_xmin ||
+ m_ymin > r.m_ymax || m_ymax < r.m_ymin) return false;
+
+ return true;
+ }
+
+ bool intersectsInTime(TimeRegion& r)
+ {
+ //if (m_startTime != r.m_startTime && (m_endTime <= r.m_startTime || m_startTime >= r.m_endTime)) return false;
+ if (m_endTime <= r.m_startTime || m_startTime >= r.m_endTime) return false;
+ return intersects(r);
+ }
+
+ double getMinDist(const TimeRegion& r)
+ {
+ double ret = 0.0;
+
+ if (r.m_xmax < m_xmin)
+ ret += std::pow(m_xmin - r.m_xmax, 2.0);
+ else if (r.m_xmin > m_xmax)
+ ret += std::pow(r.m_xmin - m_xmax, 2.0);
+
+ if (r.m_ymax < m_ymin)
+ ret += std::pow(m_ymin - r.m_ymax, 2.0);
+ else if (r.m_ymin > m_ymax)
+ ret += std::pow(r.m_ymin - m_ymax, 2.0);
+
+ return ret;
+ }
+};
+
+class NNEntry
+{
+public:
+ size_t m_id;
+ double m_dist;
+
+ NNEntry(size_t id, double dist) : m_id(id), m_dist(dist) {}
+
+ struct greater : public binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_dist > __y->m_dist; }
+ };
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ cerr << "Usage: " << argv[0] << " data_file query_type [intersection | 10NN]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[2], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[2], "10NN") == 0) queryType = 1;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file" << argv[1] << "." << endl;
+ return -1;
+ }
+
+ multimap<size_t, TimeRegion> data;
+ size_t id;
+ uint32_t op;
+ double x1, x2, y1, y2, t;
+
+ while (fin)
+ {
+ fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue;
+
+ if (op == INSERT)
+ {
+ //insert
+ data.insert(pair<size_t, TimeRegion>(id, TimeRegion(x1, y1, x2, y2, t, std::numeric_limits<double>::max())));
+ }
+ else if (op == DELETE)
+ {
+ //delete
+ // find the live instance of id.
+ multimap<size_t, TimeRegion>::iterator it = data.find(id);
+ assert(it != data.end());
+ while (it->first == id && it->second.m_endTime < std::numeric_limits<double>::max()) it++;
+ assert(it->first == id);
+ (*it).second.m_endTime = t;
+ }
+ else if (op == QUERY)
+ {
+ size_t qt1, qt2;
+ fin >> qt1 >> qt2;
+ if (! fin.good()) continue;
+
+ //query
+ if (queryType == 0)
+ {
+ TimeRegion query = TimeRegion(x1, y1, x2, y2, qt1, qt2);
+ for (multimap<size_t, TimeRegion>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ if (query.intersectsInTime((*it).second)) cout << (*it).first << endl;
+ }
+ }
+ else
+ {
+ /*
+ TimeRegion query = TimeRegion(x1, y1, x1, y1, qt1, qt2);
+
+ priority_queue<NNEntry*, vector<NNEntry*>, NNEntry::greater > queue;
+
+ for (multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ queue.push(new NNEntry((*it).first, (*it).second.getMinDist(query)));
+ }
+
+ size_t count = 0;
+ double knearest = 0.0;
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+
+ if (count >= 10 && e->m_dist > knearest) break;
+
+ //cout << e->m_id << " " << e->m_dist << endl;
+ cout << e->m_id << endl;
+ count++;
+ knearest = e->m_dist;
+ delete e;
+ }
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+ delete e;
+ }
+ */
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Generator.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Generator.cc
new file mode 100644
index 000000000..288684c69
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Generator.cc
@@ -0,0 +1,175 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <tools/Tools.h>
+#include <cmath>
+#include <limits>
+
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+class Region
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+ bool m_bIsDead;
+
+ Region() : m_xmin(numeric_limits<double>::max()), m_ymin(numeric_limits<double>::max()),
+ m_xmax(numeric_limits<double>::max()), m_ymax(numeric_limits<double>::max()) {}
+
+ Region(double x1, double y1, double x2, double y2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ m_bIsDead = false;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ cerr << "Usage: " << argv[0] << " number_of_data." << endl;
+ return -1;
+ }
+
+ size_t numberOfObjects = atoi(argv[1]);
+ map<size_t, Region> data;
+ Tools::Random rnd;
+
+ for (size_t i = 0; i < numberOfObjects; i++)
+ {
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(pair<size_t, Region>(i, r));
+
+ cout << "0 " << INSERT << " " << i << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << endl;
+ }
+
+ size_t nextID = numberOfObjects;
+ size_t A = static_cast<size_t>(std::floor(static_cast<double>(numberOfObjects) * 0.05));
+
+ for (size_t T = 1; T <= 100; T++)
+ {
+ cerr << (101 - T) << endl;
+
+ if (T == 50)
+ {
+ // delete all entries and reinsert
+ for (map<size_t, Region>::iterator itMap = data.begin(); itMap != data.end(); itMap++)
+ {
+ if (! (*itMap).second.m_bIsDead)
+ {
+ (*itMap).second.m_bIsDead = true;
+ cout << "50 " << DELETE << " " << (*itMap).first << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << endl;
+ }
+ }
+
+ for (size_t i = nextID; i < nextID + numberOfObjects; i++)
+ {
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(pair<size_t, Region>(i, r));
+
+ cout << "50 " << INSERT << " " << i << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << endl;
+ }
+
+ nextID += numberOfObjects;
+ continue;
+ }
+
+ set<size_t> examined;
+
+ for (size_t a = 0; a < A; a++)
+ {
+ // find an id that is not examined yet.
+ size_t id = static_cast<size_t>(rnd.nextUniformLongLong(0, nextID));
+ set<size_t>::iterator itSet = examined.find(id);
+ while (itSet != examined.end() || data[id].m_bIsDead == true)
+ {
+ id = static_cast<size_t>(rnd.nextUniformLongLong(0, nextID));
+ itSet = examined.find(id);
+ }
+ examined.insert(id);
+
+ map<size_t, Region>::iterator itMap = data.find(id);
+ assert(itMap != data.end() && (*itMap).second.m_bIsDead == false);
+
+ cout << T << " " << DELETE << " " << id << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << endl;
+ (*itMap).second.m_bIsDead = true;
+
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(pair<size_t, Region>(nextID, r));
+
+ cout << T << " " << INSERT << " " << nextID << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << endl;
+ examined.insert(nextID);
+ nextID++;
+ }
+
+ double stx = rnd.nextUniformDouble();
+ double sty = rnd.nextUniformDouble();
+ size_t qt = rnd.nextUniformLongLong(0, T);
+ cout << T << " " << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << " " << qt << " " << qt + 2<< endl;
+ stx = rnd.nextUniformDouble();
+ sty = rnd.nextUniformDouble();
+ qt = rnd.nextUniformLongLong(0, T);
+ cout << T << " " << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << " " << qt << " " << qt + 2<< endl;
+ stx = rnd.nextUniformDouble();
+ sty = rnd.nextUniformDouble();
+ qt = rnd.nextUniformLongLong(0, T);
+ cout << T << " " << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << " " << qt << " " << qt + 2<< endl;
+ }
+
+ // delete everything at the end (for testing the special case when the tree dies out completely)
+ for (map<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ if (! it->second.m_bIsDead)
+ {
+ cout << 102 << " " << DELETE << " " << it->first << " " << it->second.m_xmin << " " << it->second.m_ymin << " "
+ << it->second.m_xmax << " " << it->second.m_ymax << endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeLoad.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeLoad.cc
new file mode 100644
index 000000000..7e07e2731
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeLoad.cc
@@ -0,0 +1,209 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+// example of a Visitor pattern.
+// see MVRTreeQuery for a more elaborate example.
+class MyVisitor : public IVisitor
+{
+public:
+ void visitNode(const INode& n) {}
+
+ void visitData(const IData& d)
+ {
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 5)
+ {
+ cerr << "Usage: " << argv[0] << " input_file tree_file capacity query_type [intersection | 10NN]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[4], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[4], "10NN") == 0) queryType = 1;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ // Create a new storage manager with the provided base name and a 4K page size.
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+ //StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // Create a new, empty, MVRTree with dimensionality 2, minimum load 70%, using "file" as
+ // the StorageManager and the RSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = MVRTree::createNewMVRTree(*diskfile, 0.7, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::MVRTree::RV_RSTAR, indexIdentifier);
+
+ size_t count = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2, t;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ TimeRegion r = TimeRegion(plow, phigh, t, t, 2);
+
+ //ostringstream os;
+ //os << r;
+ //string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see MVRTree::Node::load and MVRTree::Node::store for
+ // an example of how to do that).
+
+ //tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ TimeRegion r = TimeRegion(plow, phigh, t, t, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "Cannot delete id: " << id << " , count: " << count << endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ size_t qt1, qt2;
+ fin >> qt1 >> qt2;
+ if (! fin.good()) continue;
+
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ TimeRegion r = TimeRegion(plow, phigh, qt1, qt2, 2);
+
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else
+ {
+ //Point p = Point(plow, 2);
+ //tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ //cerr << "Buffer hits: " << file->getHits() << endl;
+ cerr << "Index ID: " << indexIdentifier << endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) cerr << "ERROR: Structure is invalid!" << endl;
+ else cerr << "The stucture seems O.K." << endl;
+
+ delete tree;
+ //delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeQuery.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeQuery.cc
new file mode 100644
index 000000000..f8e367bc7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/MVRTreeQuery.cc
@@ -0,0 +1,268 @@
+// Spatial Index Library
+//
+// Copyright (C) 2003 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+// example of a Visitor pattern.
+// findes the index and leaf IO for answering the query and prints
+// the resulting data IDs to stdout.
+class MyVisitor : public IVisitor
+{
+public:
+ size_t m_indexIO;
+ size_t m_leafIO;
+
+public:
+ MyVisitor() : m_indexIO(0), m_leafIO(0) {}
+
+ void visitNode(const INode& n)
+ {
+ if (n.isLeaf()) m_leafIO++;
+ else m_indexIO++;
+ }
+
+ void visitData(const IData& d)
+ {
+ //IShape* pS;
+ //d.getShape(&pS);
+ // do something.
+ //delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ //byte* pData = 0;
+ //size_t cLen = 0;
+ //d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ //delete[] pData;
+
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+// example of a Strategy pattern.
+// traverses the tree by level.
+class MyQueryStrategy : public SpatialIndex::IQueryStrategy
+{
+private:
+ queue<id_type> ids;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ IShape* ps;
+ entry.getShape(&ps);
+ Region* pr = dynamic_cast<Region*>(ps);
+
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl << endl << endl;
+ // print node MBRs gnuplot style!
+
+ delete ps;
+
+ const INode* n = dynamic_cast<const INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 1)
+ {
+ for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (! ids.empty())
+ {
+ nextEntry = ids.front(); ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+};
+
+// example of a Strategy pattern.
+// find the total indexed space managed by the index (the MBR of the root).
+class MyQueryStrategy2 : public IQueryStrategy
+{
+public:
+ Region m_indexedSpace;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ // the first time we are called, entry points to the root.
+
+ // stop after the root.
+ hasNext = false;
+
+ IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(m_indexedSpace);
+ delete ps;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 4)
+ {
+ cerr << "Usage: " << argv[0] << " query_file tree_file query_type [intersection | 10NN]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[3], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[3], "10NN") == 0) queryType = 1;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open query file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName);
+ // this will try to locate and open an already existing storage manager.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // If we need to open an existing tree stored in the storage manager, we only
+ // have to specify the index identifier as follows
+ ISpatialIndex* tree = MVRTree::loadMVRTree(*file, 1);
+
+ size_t count = 0;
+ size_t indexIO = 0;
+ size_t leafIO = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2, t;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> t >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == QUERY)
+ {
+ size_t qt1, qt2;
+ fin >> qt1 >> qt2;
+ if (! fin.good()) continue;
+
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ TimeRegion r = TimeRegion(plow, phigh, qt1, qt2, 2);
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else
+ {
+ //Point p = Point(plow, 2);
+ //tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+
+ indexIO += vis.m_indexIO;
+ leafIO += vis.m_leafIO;
+ // example of the Visitor pattern usage, for calculating how many nodes
+ // were visited.
+ }
+ else
+ {
+ cerr << "This is not a query operation." << endl;
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ MyQueryStrategy2 qs;
+ tree->queryStrategy(qs);
+
+ cerr << "Indexed space: " << qs.m_indexedSpace << endl;
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Index I/O: " << indexIO << endl;
+ cerr << "Leaf I/O: " << leafIO << endl;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail writting the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Makefile.am b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Makefile.am
new file mode 100644
index 000000000..77a83a1e3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/Makefile.am
@@ -0,0 +1,12 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_PROGRAMS = Generator Exhaustive MVRTreeLoad MVRTreeQuery
+INCLUDES = -I../../include
+Generator_SOURCES = Generator.cc
+Generator_LDADD = ../../libspatialindex.la
+Exhaustive_SOURCES = Exhaustive.cc
+Exhaustive_LDADD = ../../libspatialindex.la
+MVRTreeLoad_SOURCES = MVRTreeLoad.cc
+MVRTreeLoad_LDADD = ../../libspatialindex.la
+MVRTreeQuery_SOURCES = MVRTreeQuery.cc
+MVRTreeQuery_LDADD = ../../libspatialindex.la
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/all-wcprops
new file mode 100644
index 000000000..2c9e9f07b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/136/spatialindex/trunk/regressiontest/mvrtree/test1
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/mvrtree/test1/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/dir-prop-base
new file mode 100644
index 000000000..3359090b2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 13
+data
+queries
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/entries
new file mode 100644
index 000000000..ef81df3eb
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/mvrtree/test1
+http://svn.gispython.org/spatialindex
+
+
+
+2009-08-19T15:24:15.611139Z
+136
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.077108Z
+6762ea822eddbf5712b4dd0420bf00ab
+2007-08-01T20:37:49.786254Z
+2
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+654
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..1aaa9c7f8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/.svn/text-base/run.svn-base
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 1000 > d
+awk '{if ($2 != 2) print $0}' < d > data
+awk '{if ($2 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new MVR-Tree
+../MVRTreeLoad data tree 20 intersection
+
+echo Querying MVR-Tree
+../MVRTreeQuery queries tree intersection > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/run
new file mode 100755
index 000000000..1aaa9c7f8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test1/run
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 1000 > d
+awk '{if ($2 != 2) print $0}' < d > data
+awk '{if ($2 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new MVR-Tree
+../MVRTreeLoad data tree 20 intersection
+
+echo Querying MVR-Tree
+../MVRTreeQuery queries tree intersection > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/all-wcprops
new file mode 100644
index 000000000..205654832
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/136/spatialindex/trunk/regressiontest/mvrtree/test2
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/mvrtree/test2/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/dir-prop-base
new file mode 100644
index 000000000..4d3f4094b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/dir-prop-base
@@ -0,0 +1,6 @@
+K 10
+svn:ignore
+V 4
+mix
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/entries
new file mode 100644
index 000000000..d10344f44
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/mvrtree/test2
+http://svn.gispython.org/spatialindex
+
+
+
+2009-08-19T15:24:15.611139Z
+136
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.077108Z
+3b371868b8e43606fa2a9044dea88d92
+2007-08-01T20:37:49.786254Z
+2
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+484
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..de5cb8ba9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/.svn/text-base/run.svn-base
@@ -0,0 +1,22 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 1000 > mix
+
+echo Creating new MVR-Tree and Querying
+../MVRTreeLoad mix tree 20 intersection > res
+
+echo Running exhaustive search
+../Exhaustive mix intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/run
new file mode 100755
index 000000000..de5cb8ba9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/mvrtree/test2/run
@@ -0,0 +1,22 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 1000 > mix
+
+echo Creating new MVR-Tree and Querying
+../MVRTreeLoad mix tree 20 intersection > res
+
+echo Running exhaustive search
+../Exhaustive mix intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/all-wcprops
new file mode 100644
index 000000000..223a872a1
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/all-wcprops
@@ -0,0 +1,71 @@
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/182/spatialindex/trunk/regressiontest/rtree
+END
+RTreeBulkLoad.vcproj
+K 25
+svn:wc:ra_dav:version-url
+V 87
+/spatialindex/!svn/ver/113/spatialindex/trunk/regressiontest/rtree/RTreeBulkLoad.vcproj
+END
+RTreeBulkLoad.cc
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/spatialindex/!svn/ver/130/spatialindex/trunk/regressiontest/rtree/RTreeBulkLoad.cc
+END
+RTreeLoad.vcproj
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/spatialindex/!svn/ver/113/spatialindex/trunk/regressiontest/rtree/RTreeLoad.vcproj
+END
+RTreeLoad.cc
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/spatialindex/!svn/ver/99/spatialindex/trunk/regressiontest/rtree/RTreeLoad.cc
+END
+Exhaustive.cc
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/spatialindex/!svn/ver/182/spatialindex/trunk/regressiontest/rtree/Exhaustive.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/rtree/Makefile.am
+END
+RTreeExhaustive.vcproj
+K 25
+svn:wc:ra_dav:version-url
+V 89
+/spatialindex/!svn/ver/113/spatialindex/trunk/regressiontest/rtree/RTreeExhaustive.vcproj
+END
+RTreeQuery.vcproj
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/spatialindex/!svn/ver/113/spatialindex/trunk/regressiontest/rtree/RTreeQuery.vcproj
+END
+Generator.cc
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/spatialindex/!svn/ver/159/spatialindex/trunk/regressiontest/rtree/Generator.cc
+END
+RTreeGenerator.vcproj
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/spatialindex/!svn/ver/113/spatialindex/trunk/regressiontest/rtree/RTreeGenerator.vcproj
+END
+RTreeQuery.cc
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/spatialindex/!svn/ver/130/spatialindex/trunk/regressiontest/rtree/RTreeQuery.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/dir-prop-base
new file mode 100644
index 000000000..7bb6f48a7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/dir-prop-base
@@ -0,0 +1,16 @@
+K 10
+svn:ignore
+V 102
+RTreeLoad
+Makefile.in
+Exhaustive
+Generator
+RTreeBulkLoad
+.libs
+RTreeQuery
+.deps
+Makefile
+data
+queries
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/entries
new file mode 100644
index 000000000..291098630
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/entries
@@ -0,0 +1,414 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/rtree
+http://svn.gispython.org/spatialindex
+
+
+
+2010-04-12T17:17:47.459585Z
+182
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+RTreeLoad.vcproj
+file
+
+
+
+
+2011-08-01T00:42:34.061219Z
+e5a576790eb8a17371fe4d62be9509bb
+2009-07-22T15:23:22.023161Z
+113
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7300
+
+RTreeBulkLoad.cc
+file
+
+
+
+
+2011-08-01T00:42:34.061219Z
+85ac7ce7d927d1ab1728b722f81f3f14
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4240
+
+RTreeExhaustive.vcproj
+file
+
+
+
+
+2011-08-01T00:42:34.065127Z
+b6c4f117d41237d7994facd78cdb33e3
+2009-07-22T15:23:22.023161Z
+113
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7289
+
+RTreeGenerator.vcproj
+file
+
+
+
+
+2011-08-01T00:42:34.069111Z
+b986cef2bcefb6343a4566f2442fcd27
+2009-07-22T15:23:22.023161Z
+113
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7478
+
+RTreeQuery.cc
+file
+
+
+
+
+2011-08-01T00:42:34.069111Z
+6dc96f005443f88ef8087011d1aa9377
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6704
+
+test1
+dir
+
+RTreeBulkLoad.vcproj
+file
+
+
+
+
+2011-08-01T00:42:34.061219Z
+7fa437b6694ddfea6d0c117dc4e76ac6
+2009-07-22T15:23:22.023161Z
+113
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7313
+
+test2
+dir
+
+test3
+dir
+
+test4
+dir
+
+RTreeLoad.cc
+file
+
+
+
+
+2011-08-01T00:42:34.065127Z
+ff1c54dece8ceec010ebd2ceeeebadd7
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6476
+
+RTreeQuery.vcproj
+file
+
+
+
+
+2011-08-01T00:42:34.069111Z
+45626bc58899caae7830f30897d41237
+2009-07-22T15:23:22.023161Z
+113
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7303
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.065127Z
+a5ed39045d9e34d87d9041738559ee68
+2007-08-01T20:37:49.786254Z
+2
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+578
+
+Exhaustive.cc
+file
+
+
+
+
+2011-08-01T00:42:34.065127Z
+3cbcbf3303ed8e0bd3e816fcc40bd42e
+2010-04-12T17:17:47.459585Z
+182
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5133
+
+Generator.cc
+file
+
+
+
+
+2011-08-01T00:42:34.069111Z
+bdec99e2c151385e7bbb0c3b2dcb1da3
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3854
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeBulkLoad.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeBulkLoad.vcproj.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeBulkLoad.vcproj.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeExhaustive.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeExhaustive.vcproj.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeExhaustive.vcproj.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeGenerator.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeGenerator.vcproj.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeGenerator.vcproj.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeLoad.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeLoad.vcproj.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeLoad.vcproj.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeQuery.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeQuery.vcproj.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/prop-base/RTreeQuery.vcproj.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Exhaustive.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Exhaustive.cc.svn-base
new file mode 100644
index 000000000..62fc971ef
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Exhaustive.cc.svn-base
@@ -0,0 +1,214 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <tools/Tools.h>
+#include <cstring>
+#include <cmath>
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+ // Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+ #pragma warning( disable: 4251 )
+#else
+ #include <stdint.h>
+#endif
+
+class Region
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+
+ Region(double x1, double y1, double x2, double y2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ }
+
+ bool intersects(Region& r)
+ {
+ if (
+ m_xmin > r.m_xmax || m_xmax < r.m_xmin ||
+ m_ymin > r.m_ymax || m_ymax < r.m_ymin)
+ return false;
+
+ return true;
+ }
+
+ double getMinDist(const Region& r)
+ {
+ double ret = 0.0;
+
+ if (r.m_xmax < m_xmin)
+ ret += std::pow(m_xmin - r.m_xmax, 2.0);
+ else if (r.m_xmin > m_xmax)
+ ret += std::pow(r.m_xmin - m_xmax, 2.0);
+
+ if (r.m_ymax < m_ymin)
+ ret += std::pow(m_ymin - r.m_ymax, 2.0);
+ else if (r.m_ymin > m_ymax)
+ ret += std::pow(r.m_ymin - m_ymax, 2.0);
+
+ return ret;
+ }
+};
+
+class NNEntry
+{
+public:
+ size_t m_id;
+ double m_dist;
+
+ NNEntry(size_t id, double dist) : m_id(id), m_dist(dist) {}
+
+ struct greater : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_dist > __y->m_dist; }
+ };
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << " data_file query_type [intersection | 10NN | selfjoin]." << std::endl;
+ return -1;
+ }
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[2], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[2], "10NN") == 0) queryType = 1;
+ else if (strcmp(argv[2], "selfjoin") == 0) queryType = 2;
+ else
+ {
+ std::cerr << "Unknown query type." << std::endl;
+ return -1;
+ }
+
+ std::ifstream fin(argv[1]);
+ if (! fin)
+ {
+ std::cerr << "Cannot open data file" << argv[1] << "." << std::endl;
+ return -1;
+ }
+
+ std::multimap<size_t, Region> data;
+ size_t id;
+ uint32_t op;
+ double x1, x2, y1, y2;
+
+ while (fin)
+ {
+ fin >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue;
+
+ if (op == INSERT)
+ {
+ //insert
+ data.insert(std::pair<size_t, Region>(id, Region(x1, y1, x2, y2)));
+ }
+ else if (op == DELETE)
+ {
+ data.erase(id);
+ }
+ else if (op == QUERY)
+ {
+ //query
+ if (queryType == 0)
+ {
+ Region query = Region(x1, y1, x2, y2);
+ for (std::multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ if (query.intersects((*it).second)) std::cout << (*it).first << std::endl;
+ }
+ }
+ else if (queryType == 1)
+ {
+ Region query = Region(x1, y1, x1, y1);
+
+ std::priority_queue<NNEntry*, std::vector<NNEntry*>, NNEntry::greater > queue;
+
+ for (std::multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ queue.push(new NNEntry((*it).first, (*it).second.getMinDist(query)));
+ }
+
+ size_t count = 0;
+ double knearest = 0.0;
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+
+ if (count >= 10 && e->m_dist > knearest) break;
+
+ //std::cout << e->m_id << " " << e->m_dist << std::endl;
+ std::cout << e->m_id << std::endl;
+ count++;
+ knearest = e->m_dist;
+ delete e;
+ }
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+ delete e;
+ }
+ }
+ else
+ {
+ Region query = Region(x1, y1, x2, y2);
+
+ for (std::multimap<size_t, Region>::iterator it1 = data.begin(); it1 != data.end(); it1++)
+ {
+ if (query.intersects((*it1).second))
+ {
+ for (std::multimap<size_t, Region>::iterator it2 = data.begin(); it2 != data.end(); it2++)
+ {
+ if (
+ (*it1).first != (*it2).first &&
+ query.intersects((*it2).second) &&
+ (*it1).second.intersects((*it2).second))
+ {
+ std::cout << (*it1).first << " " << (*it2).first << std::endl;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Generator.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Generator.cc.svn-base
new file mode 100644
index 000000000..41f696811
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Generator.cc.svn-base
@@ -0,0 +1,128 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <tools/Tools.h>
+#include <cmath>
+#include <limits>
+
+#include <set>
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+class Region
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+
+ Region(double x1, double y1, double x2, double y2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << " number_of_data time_instants." << std::endl;
+ return -1;
+ }
+
+ size_t simulationLength = atol(argv[2]);
+ size_t numberOfObjects = atol(argv[1]);
+ std::map<size_t, Region> data;
+ Tools::Random rnd;
+
+ for (size_t i = 0; i < numberOfObjects; i++)
+ {
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(std::pair<size_t, Region>(i, r));
+
+ std::cout << INSERT << " " << i << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << std::endl;
+ }
+
+ if (simulationLength == 0)
+ {
+ for (size_t i = 0; i < 10; i++)
+ {
+ double stx = rnd.nextUniformDouble();
+ double sty = rnd.nextUniformDouble();
+ std::cout << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << std::endl;
+ }
+ }
+
+ size_t A = static_cast<size_t>(std::floor(static_cast<double>(numberOfObjects) * 0.05));
+
+ for (size_t T = 1; T <= simulationLength; T++)
+ {
+ std::cerr << (simulationLength + 1 - T) << std::endl;
+ std::set<size_t> examined;
+
+ for (size_t a = 0; a < A; a++)
+ {
+ // find an id that is not yet examined.
+ size_t id = static_cast<size_t>(rnd.nextUniformLong(0, numberOfObjects));
+ std::set<size_t>::iterator itSet = examined.find(id);
+
+ while (itSet != examined.end())
+ {
+ id = static_cast<size_t>(rnd.nextUniformLong(0, numberOfObjects));
+ itSet = examined.find(id);
+ }
+ examined.insert(id);
+
+ std::map<size_t, Region>::iterator itMap = data.find(id);
+ assert(itMap != data.end());
+
+ std::cout << DELETE << " " << id << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << std::endl;
+
+ double x = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ (*itMap).second.m_xmin = x;
+ (*itMap).second.m_xmax = x + dx;
+ double y = rnd.nextUniformDouble();
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ (*itMap).second.m_ymin = y;
+ (*itMap).second.m_ymax = y + dy;
+
+ std::cout << INSERT << " " << id << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << std::endl;
+ }
+
+ double stx = rnd.nextUniformDouble();
+ double sty = rnd.nextUniformDouble();
+ std::cout << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << std::endl;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..820f9dd07
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,13 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_PROGRAMS = Generator Exhaustive RTreeLoad RTreeQuery RTreeBulkLoad
+INCLUDES = -I../../include
+Generator_SOURCES = Generator.cc
+Generator_LDADD = ../../libspatialindex.la
+Exhaustive_SOURCES = Exhaustive.cc
+Exhaustive_LDADD = ../../libspatialindex.la
+RTreeLoad_SOURCES = RTreeLoad.cc
+RTreeLoad_LDADD = ../../libspatialindex.la
+RTreeQuery_SOURCES = RTreeQuery.cc
+RTreeQuery_LDADD = ../../libspatialindex.la
+RTreeBulkLoad_SOURCES = RTreeBulkLoad.cc
+RTreeBulkLoad_LDADD = ../../libspatialindex.la
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.cc.svn-base
new file mode 100644
index 000000000..0726d3d08
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.cc.svn-base
@@ -0,0 +1,162 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+class MyDataStream : public IDataStream
+{
+public:
+ MyDataStream(std::string inputFile) : m_pNext(0)
+ {
+ m_fin.open(inputFile.c_str());
+
+ if (! m_fin)
+ throw Tools::IllegalArgumentException("Input file not found.");
+
+ readNextEntry();
+ }
+
+ virtual ~MyDataStream()
+ {
+ if (m_pNext != 0) delete m_pNext;
+ }
+
+ virtual IData* getNext()
+ {
+ if (m_pNext == 0) return 0;
+
+ RTree::Data* ret = m_pNext;
+ m_pNext = 0;
+ readNextEntry();
+ return ret;
+ }
+
+ virtual bool hasNext()
+ {
+ return (m_pNext != 0);
+ }
+
+ virtual uint32_t size()
+ {
+ throw Tools::NotSupportedException("Operation not supported.");
+ }
+
+ virtual void rewind()
+ {
+ if (m_pNext != 0)
+ {
+ delete m_pNext;
+ m_pNext = 0;
+ }
+
+ m_fin.seekg(0, std::ios::beg);
+ readNextEntry();
+ }
+
+ void readNextEntry()
+ {
+ id_type id;
+ uint32_t op;
+ double low[2], high[2];
+
+ m_fin >> op >> id >> low[0] >> low[1] >> high[0] >> high[1];
+
+ if (m_fin.good())
+ {
+ if (op != INSERT)
+ throw Tools::IllegalArgumentException(
+ "The data input should contain insertions only."
+ );
+
+ Region r(low, high, 2);
+ m_pNext = new RTree::Data(sizeof(double), reinterpret_cast<byte*>(low), r, id);
+ // Associate a bogus data array with every entry for testing purposes.
+ // Once the data array is given to RTRee:Data a local copy will be created.
+ // Hence, the input data array can be deleted after this operation if not
+ // needed anymore.
+ }
+ }
+
+ std::ifstream m_fin;
+ RTree::Data* m_pNext;
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 5)
+ {
+ std::cerr << "Usage: " << argv[0] << " input_file tree_file capacity utilization." << std::endl;
+ return -1;
+ }
+
+ std::string baseName = argv[2];
+ double utilization = atof(argv[4]);
+
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+ // Create a new storage manager with the provided base name and a 4K page size.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ MyDataStream stream(argv[1]);
+
+ // Create and bulk load a new RTree with dimensionality 2, using "file" as
+ // the StorageManager and the RSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = RTree::createAndBulkLoadNewRTree(
+ RTree::BLM_STR, stream, *file, utilization, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::RTree::RV_RSTAR, indexIdentifier);
+
+ std::cerr << *tree;
+ std::cerr << "Buffer hits: " << file->getHits() << std::endl;
+ std::cerr << "Index ID: " << indexIdentifier << std::endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) std::cerr << "ERROR: Structure is invalid!" << std::endl;
+ else std::cerr << "The stucture seems O.K." << std::endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ std::cerr << "******ERROR******" << std::endl;
+ std::string s = e.what();
+ std::cerr << s << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.vcproj.svn-base
new file mode 100644
index 000000000..3e8526057
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeBulkLoad.vcproj.svn-base
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeBulkLoad"
+ ProjectGUID="{7D9C8655-0155-4EE3-B04C-6D831E2982CE}"
+ RootNamespace="regressiontest"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\RTreeBulkLoad.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeExhaustive.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeExhaustive.vcproj.svn-base
new file mode 100644
index 000000000..208fa4e5f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeExhaustive.vcproj.svn-base
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeExhaustive"
+ ProjectGUID="{D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}"
+ RootNamespace="RTreeExhaustive"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Exhaustive.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeGenerator.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeGenerator.vcproj.svn-base
new file mode 100644
index 000000000..b0585e096
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeGenerator.vcproj.svn-base
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeGenerator"
+ ProjectGUID="{03504DB7-ACF3-40CF-A8A7-310E80666DC0}"
+ RootNamespace="RTreeGenerator"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Generator.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.cc.svn-base
new file mode 100644
index 000000000..4b0b97bc3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.cc.svn-base
@@ -0,0 +1,202 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// see RTreeQuery for a more elaborate example.
+class MyVisitor : public IVisitor
+{
+public:
+ void visitNode(const INode& n) {}
+
+ void visitData(const IData& d)
+ {
+ std::cout << d.getIdentifier() << std::endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 5)
+ {
+ std::cerr << "Usage: " << argv[0] << " input_file tree_file capacity query_type [intersection | 10NN | selfjoin]." << std::endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[4], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[4], "10NN") == 0) queryType = 1;
+ else if (strcmp(argv[4], "selfjoin") == 0) queryType = 2;
+ else
+ {
+ std::cerr << "Unknown query type." << std::endl;
+ return -1;
+ }
+
+ std::ifstream fin(argv[1]);
+ if (! fin)
+ {
+ std::cerr << "Cannot open data file " << argv[1] << "." << std::endl;
+ return -1;
+ }
+
+ // Create a new storage manager with the provided base name and a 4K page size.
+ std::string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // Create a new, empty, RTree with dimensionality 2, minimum load 70%, using "file" as
+ // the StorageManager and the RSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = RTree::createNewRTree(*file, 0.7, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::RTree::RV_RSTAR, indexIdentifier);
+
+ size_t count = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ Region r = Region(plow, phigh, 2);
+
+ std::ostringstream os;
+ os << r;
+ std::string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see RTree::Node::load and RTree::Node::store for
+ // an example of how to do that).
+
+ tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ //tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ Region r = Region(plow, phigh, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ std::cerr << "******ERROR******" << std::endl;
+ std::cerr << "Cannot delete id: " << id << " , count: " << count << std::endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else if (queryType == 1)
+ {
+ Point p = Point(plow, 2);
+ tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+ else
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->selfJoinQuery(r, vis);
+ }
+ }
+
+ if ((count % 1000) == 0)
+ std::cerr << count << std::endl;
+
+ count++;
+ }
+
+ std::cerr << "Operations: " << count << std::endl;
+ std::cerr << *tree;
+ std::cerr << "Buffer hits: " << file->getHits() << std::endl;
+ std::cerr << "Index ID: " << indexIdentifier << std::endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) std::cerr << "ERROR: Structure is invalid!" << std::endl;
+ else std::cerr << "The stucture seems O.K." << std::endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ std::cerr << "******ERROR******" << std::endl;
+ std::string s = e.what();
+ std::cerr << s << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.vcproj.svn-base
new file mode 100644
index 000000000..e91e5e64a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeLoad.vcproj.svn-base
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeLoad"
+ ProjectGUID="{551D683C-E5DC-4713-9D9F-F629D15BE5DA}"
+ RootNamespace="RTreeLoad"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\RTreeLoad.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.cc.svn-base
new file mode 100644
index 000000000..865054ebe
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.cc.svn-base
@@ -0,0 +1,272 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// findes the index and leaf IO for answering the query and prints
+// the resulting data IDs to stdout.
+class MyVisitor : public IVisitor
+{
+public:
+ size_t m_indexIO;
+ size_t m_leafIO;
+
+public:
+ MyVisitor() : m_indexIO(0), m_leafIO(0) {}
+
+ void visitNode(const INode& n)
+ {
+ if (n.isLeaf()) m_leafIO++;
+ else m_indexIO++;
+ }
+
+ void visitData(const IData& d)
+ {
+ IShape* pS;
+ d.getShape(&pS);
+ // do something.
+ delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ byte* pData = 0;
+ uint32_t cLen = 0;
+ d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ delete[] pData;
+
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v)
+ {
+ cout << v[0]->getIdentifier() << " " << v[1]->getIdentifier() << endl;
+ }
+};
+
+// example of a Strategy pattern.
+// traverses the tree by level.
+class MyQueryStrategy : public SpatialIndex::IQueryStrategy
+{
+private:
+ queue<id_type> ids;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ IShape* ps;
+ entry.getShape(&ps);
+ Region* pr = dynamic_cast<Region*>(ps);
+
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl << endl << endl;
+ // print node MBRs gnuplot style!
+
+ delete ps;
+
+ const INode* n = dynamic_cast<const INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 1)
+ {
+ for (uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (! ids.empty())
+ {
+ nextEntry = ids.front(); ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+};
+
+// example of a Strategy pattern.
+// find the total indexed space managed by the index (the MBR of the root).
+class MyQueryStrategy2 : public IQueryStrategy
+{
+public:
+ Region m_indexedSpace;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ // the first time we are called, entry points to the root.
+
+ // stop after the root.
+ hasNext = false;
+
+ IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(m_indexedSpace);
+ delete ps;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 4)
+ {
+ cerr << "Usage: " << argv[0] << " query_file tree_file query_type [intersection | 10NN | selfjoin]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[3], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[3], "10NN") == 0) queryType = 1;
+ else if (strcmp(argv[3], "selfjoin") == 0) queryType = 2;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open query file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName);
+ // this will try to locate and open an already existing storage manager.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // If we need to open an existing tree stored in the storage manager, we only
+ // have to specify the index identifier as follows
+ ISpatialIndex* tree = RTree::loadRTree(*file, 1);
+
+ size_t count = 0;
+ size_t indexIO = 0;
+ size_t leafIO = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == QUERY)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else if (queryType == 1)
+ {
+ Point p = Point(plow, 2);
+ tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+ else
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->selfJoinQuery(r, vis);
+ }
+
+ indexIO += vis.m_indexIO;
+ leafIO += vis.m_leafIO;
+ // example of the Visitor pattern usage, for calculating how many nodes
+ // were visited.
+ }
+ else
+ {
+ cerr << "This is not a query operation." << endl;
+ }
+
+ if ((count % 1000) == 0) cerr << count << endl;
+
+ count++;
+ }
+
+ MyQueryStrategy2 qs;
+ tree->queryStrategy(qs);
+
+ cerr << "Indexed space: " << qs.m_indexedSpace << endl;
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Index I/O: " << indexIO << endl;
+ cerr << "Leaf I/O: " << leafIO << endl;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail writting the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.vcproj.svn-base
new file mode 100644
index 000000000..c5fe4b981
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/.svn/text-base/RTreeQuery.vcproj.svn-base
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeQuery"
+ ProjectGUID="{1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}"
+ RootNamespace="RTreeQuery"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\RTreeQuery.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Exhaustive.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Exhaustive.cc
new file mode 100644
index 000000000..62fc971ef
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Exhaustive.cc
@@ -0,0 +1,214 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <tools/Tools.h>
+#include <cstring>
+#include <cmath>
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+ // Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+ #pragma warning( disable: 4251 )
+#else
+ #include <stdint.h>
+#endif
+
+class Region
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+
+ Region(double x1, double y1, double x2, double y2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ }
+
+ bool intersects(Region& r)
+ {
+ if (
+ m_xmin > r.m_xmax || m_xmax < r.m_xmin ||
+ m_ymin > r.m_ymax || m_ymax < r.m_ymin)
+ return false;
+
+ return true;
+ }
+
+ double getMinDist(const Region& r)
+ {
+ double ret = 0.0;
+
+ if (r.m_xmax < m_xmin)
+ ret += std::pow(m_xmin - r.m_xmax, 2.0);
+ else if (r.m_xmin > m_xmax)
+ ret += std::pow(r.m_xmin - m_xmax, 2.0);
+
+ if (r.m_ymax < m_ymin)
+ ret += std::pow(m_ymin - r.m_ymax, 2.0);
+ else if (r.m_ymin > m_ymax)
+ ret += std::pow(r.m_ymin - m_ymax, 2.0);
+
+ return ret;
+ }
+};
+
+class NNEntry
+{
+public:
+ size_t m_id;
+ double m_dist;
+
+ NNEntry(size_t id, double dist) : m_id(id), m_dist(dist) {}
+
+ struct greater : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_dist > __y->m_dist; }
+ };
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << " data_file query_type [intersection | 10NN | selfjoin]." << std::endl;
+ return -1;
+ }
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[2], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[2], "10NN") == 0) queryType = 1;
+ else if (strcmp(argv[2], "selfjoin") == 0) queryType = 2;
+ else
+ {
+ std::cerr << "Unknown query type." << std::endl;
+ return -1;
+ }
+
+ std::ifstream fin(argv[1]);
+ if (! fin)
+ {
+ std::cerr << "Cannot open data file" << argv[1] << "." << std::endl;
+ return -1;
+ }
+
+ std::multimap<size_t, Region> data;
+ size_t id;
+ uint32_t op;
+ double x1, x2, y1, y2;
+
+ while (fin)
+ {
+ fin >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue;
+
+ if (op == INSERT)
+ {
+ //insert
+ data.insert(std::pair<size_t, Region>(id, Region(x1, y1, x2, y2)));
+ }
+ else if (op == DELETE)
+ {
+ data.erase(id);
+ }
+ else if (op == QUERY)
+ {
+ //query
+ if (queryType == 0)
+ {
+ Region query = Region(x1, y1, x2, y2);
+ for (std::multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ if (query.intersects((*it).second)) std::cout << (*it).first << std::endl;
+ }
+ }
+ else if (queryType == 1)
+ {
+ Region query = Region(x1, y1, x1, y1);
+
+ std::priority_queue<NNEntry*, std::vector<NNEntry*>, NNEntry::greater > queue;
+
+ for (std::multimap<size_t, Region>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ queue.push(new NNEntry((*it).first, (*it).second.getMinDist(query)));
+ }
+
+ size_t count = 0;
+ double knearest = 0.0;
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+
+ if (count >= 10 && e->m_dist > knearest) break;
+
+ //std::cout << e->m_id << " " << e->m_dist << std::endl;
+ std::cout << e->m_id << std::endl;
+ count++;
+ knearest = e->m_dist;
+ delete e;
+ }
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+ delete e;
+ }
+ }
+ else
+ {
+ Region query = Region(x1, y1, x2, y2);
+
+ for (std::multimap<size_t, Region>::iterator it1 = data.begin(); it1 != data.end(); it1++)
+ {
+ if (query.intersects((*it1).second))
+ {
+ for (std::multimap<size_t, Region>::iterator it2 = data.begin(); it2 != data.end(); it2++)
+ {
+ if (
+ (*it1).first != (*it2).first &&
+ query.intersects((*it2).second) &&
+ (*it1).second.intersects((*it2).second))
+ {
+ std::cout << (*it1).first << " " << (*it2).first << std::endl;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Generator.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Generator.cc
new file mode 100644
index 000000000..41f696811
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Generator.cc
@@ -0,0 +1,128 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <tools/Tools.h>
+#include <cmath>
+#include <limits>
+
+#include <set>
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+class Region
+{
+public:
+ double m_xmin, m_ymin, m_xmax, m_ymax;
+
+ Region(double x1, double y1, double x2, double y2)
+ {
+ m_xmin = (x1 < x2) ? x1 : x2;
+ m_ymin = (y1 < y2) ? y1 : y2;
+ m_xmax = (x1 > x2) ? x1 : x2;
+ m_ymax = (y1 > y2) ? y1 : y2;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << " number_of_data time_instants." << std::endl;
+ return -1;
+ }
+
+ size_t simulationLength = atol(argv[2]);
+ size_t numberOfObjects = atol(argv[1]);
+ std::map<size_t, Region> data;
+ Tools::Random rnd;
+
+ for (size_t i = 0; i < numberOfObjects; i++)
+ {
+ double x = rnd.nextUniformDouble();
+ double y = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ Region r = Region(x, y, x + dx, y + dy);
+
+ data.insert(std::pair<size_t, Region>(i, r));
+
+ std::cout << INSERT << " " << i << " " << r.m_xmin << " " << r.m_ymin << " "
+ << r.m_xmax << " " << r.m_ymax << std::endl;
+ }
+
+ if (simulationLength == 0)
+ {
+ for (size_t i = 0; i < 10; i++)
+ {
+ double stx = rnd.nextUniformDouble();
+ double sty = rnd.nextUniformDouble();
+ std::cout << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << std::endl;
+ }
+ }
+
+ size_t A = static_cast<size_t>(std::floor(static_cast<double>(numberOfObjects) * 0.05));
+
+ for (size_t T = 1; T <= simulationLength; T++)
+ {
+ std::cerr << (simulationLength + 1 - T) << std::endl;
+ std::set<size_t> examined;
+
+ for (size_t a = 0; a < A; a++)
+ {
+ // find an id that is not yet examined.
+ size_t id = static_cast<size_t>(rnd.nextUniformLong(0, numberOfObjects));
+ std::set<size_t>::iterator itSet = examined.find(id);
+
+ while (itSet != examined.end())
+ {
+ id = static_cast<size_t>(rnd.nextUniformLong(0, numberOfObjects));
+ itSet = examined.find(id);
+ }
+ examined.insert(id);
+
+ std::map<size_t, Region>::iterator itMap = data.find(id);
+ assert(itMap != data.end());
+
+ std::cout << DELETE << " " << id << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << std::endl;
+
+ double x = rnd.nextUniformDouble();
+ double dx = rnd.nextUniformDouble(0.0001, 0.1);
+ (*itMap).second.m_xmin = x;
+ (*itMap).second.m_xmax = x + dx;
+ double y = rnd.nextUniformDouble();
+ double dy = rnd.nextUniformDouble(0.0001, 0.1);
+ (*itMap).second.m_ymin = y;
+ (*itMap).second.m_ymax = y + dy;
+
+ std::cout << INSERT << " " << id << " " << (*itMap).second.m_xmin << " " << (*itMap).second.m_ymin << " "
+ << (*itMap).second.m_xmax << " " << (*itMap).second.m_ymax << std::endl;
+ }
+
+ double stx = rnd.nextUniformDouble();
+ double sty = rnd.nextUniformDouble();
+ std::cout << QUERY << " 9999999 " << stx << " " << sty << " " << (stx + 0.01) << " " << (sty + 0.01) << std::endl;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Makefile.am b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Makefile.am
new file mode 100644
index 000000000..820f9dd07
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/Makefile.am
@@ -0,0 +1,13 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_PROGRAMS = Generator Exhaustive RTreeLoad RTreeQuery RTreeBulkLoad
+INCLUDES = -I../../include
+Generator_SOURCES = Generator.cc
+Generator_LDADD = ../../libspatialindex.la
+Exhaustive_SOURCES = Exhaustive.cc
+Exhaustive_LDADD = ../../libspatialindex.la
+RTreeLoad_SOURCES = RTreeLoad.cc
+RTreeLoad_LDADD = ../../libspatialindex.la
+RTreeQuery_SOURCES = RTreeQuery.cc
+RTreeQuery_LDADD = ../../libspatialindex.la
+RTreeBulkLoad_SOURCES = RTreeBulkLoad.cc
+RTreeBulkLoad_LDADD = ../../libspatialindex.la
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.cc
new file mode 100644
index 000000000..0726d3d08
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.cc
@@ -0,0 +1,162 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+class MyDataStream : public IDataStream
+{
+public:
+ MyDataStream(std::string inputFile) : m_pNext(0)
+ {
+ m_fin.open(inputFile.c_str());
+
+ if (! m_fin)
+ throw Tools::IllegalArgumentException("Input file not found.");
+
+ readNextEntry();
+ }
+
+ virtual ~MyDataStream()
+ {
+ if (m_pNext != 0) delete m_pNext;
+ }
+
+ virtual IData* getNext()
+ {
+ if (m_pNext == 0) return 0;
+
+ RTree::Data* ret = m_pNext;
+ m_pNext = 0;
+ readNextEntry();
+ return ret;
+ }
+
+ virtual bool hasNext()
+ {
+ return (m_pNext != 0);
+ }
+
+ virtual uint32_t size()
+ {
+ throw Tools::NotSupportedException("Operation not supported.");
+ }
+
+ virtual void rewind()
+ {
+ if (m_pNext != 0)
+ {
+ delete m_pNext;
+ m_pNext = 0;
+ }
+
+ m_fin.seekg(0, std::ios::beg);
+ readNextEntry();
+ }
+
+ void readNextEntry()
+ {
+ id_type id;
+ uint32_t op;
+ double low[2], high[2];
+
+ m_fin >> op >> id >> low[0] >> low[1] >> high[0] >> high[1];
+
+ if (m_fin.good())
+ {
+ if (op != INSERT)
+ throw Tools::IllegalArgumentException(
+ "The data input should contain insertions only."
+ );
+
+ Region r(low, high, 2);
+ m_pNext = new RTree::Data(sizeof(double), reinterpret_cast<byte*>(low), r, id);
+ // Associate a bogus data array with every entry for testing purposes.
+ // Once the data array is given to RTRee:Data a local copy will be created.
+ // Hence, the input data array can be deleted after this operation if not
+ // needed anymore.
+ }
+ }
+
+ std::ifstream m_fin;
+ RTree::Data* m_pNext;
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 5)
+ {
+ std::cerr << "Usage: " << argv[0] << " input_file tree_file capacity utilization." << std::endl;
+ return -1;
+ }
+
+ std::string baseName = argv[2];
+ double utilization = atof(argv[4]);
+
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+ // Create a new storage manager with the provided base name and a 4K page size.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ MyDataStream stream(argv[1]);
+
+ // Create and bulk load a new RTree with dimensionality 2, using "file" as
+ // the StorageManager and the RSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = RTree::createAndBulkLoadNewRTree(
+ RTree::BLM_STR, stream, *file, utilization, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::RTree::RV_RSTAR, indexIdentifier);
+
+ std::cerr << *tree;
+ std::cerr << "Buffer hits: " << file->getHits() << std::endl;
+ std::cerr << "Index ID: " << indexIdentifier << std::endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) std::cerr << "ERROR: Structure is invalid!" << std::endl;
+ else std::cerr << "The stucture seems O.K." << std::endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ std::cerr << "******ERROR******" << std::endl;
+ std::string s = e.what();
+ std::cerr << s << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.vcproj b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.vcproj
new file mode 100755
index 000000000..3e8526057
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeBulkLoad.vcproj
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeBulkLoad"
+ ProjectGUID="{7D9C8655-0155-4EE3-B04C-6D831E2982CE}"
+ RootNamespace="regressiontest"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\RTreeBulkLoad.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeExhaustive.vcproj b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeExhaustive.vcproj
new file mode 100755
index 000000000..208fa4e5f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeExhaustive.vcproj
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeExhaustive"
+ ProjectGUID="{D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}"
+ RootNamespace="RTreeExhaustive"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\Exhaustive.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Exhaustive.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeGenerator.vcproj b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeGenerator.vcproj
new file mode 100755
index 000000000..b0585e096
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeGenerator.vcproj
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeGenerator"
+ ProjectGUID="{03504DB7-ACF3-40CF-A8A7-310E80666DC0}"
+ RootNamespace="RTreeGenerator"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ OutputFile="$(OutDir)\Generator.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Generator.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.cc
new file mode 100644
index 000000000..4b0b97bc3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.cc
@@ -0,0 +1,202 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// see RTreeQuery for a more elaborate example.
+class MyVisitor : public IVisitor
+{
+public:
+ void visitNode(const INode& n) {}
+
+ void visitData(const IData& d)
+ {
+ std::cout << d.getIdentifier() << std::endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 5)
+ {
+ std::cerr << "Usage: " << argv[0] << " input_file tree_file capacity query_type [intersection | 10NN | selfjoin]." << std::endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[4], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[4], "10NN") == 0) queryType = 1;
+ else if (strcmp(argv[4], "selfjoin") == 0) queryType = 2;
+ else
+ {
+ std::cerr << "Unknown query type." << std::endl;
+ return -1;
+ }
+
+ std::ifstream fin(argv[1]);
+ if (! fin)
+ {
+ std::cerr << "Cannot open data file " << argv[1] << "." << std::endl;
+ return -1;
+ }
+
+ // Create a new storage manager with the provided base name and a 4K page size.
+ std::string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // Create a new, empty, RTree with dimensionality 2, minimum load 70%, using "file" as
+ // the StorageManager and the RSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = RTree::createNewRTree(*file, 0.7, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::RTree::RV_RSTAR, indexIdentifier);
+
+ size_t count = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ Region r = Region(plow, phigh, 2);
+
+ std::ostringstream os;
+ os << r;
+ std::string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see RTree::Node::load and RTree::Node::store for
+ // an example of how to do that).
+
+ tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ //tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+ Region r = Region(plow, phigh, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ std::cerr << "******ERROR******" << std::endl;
+ std::cerr << "Cannot delete id: " << id << " , count: " << count << std::endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else if (queryType == 1)
+ {
+ Point p = Point(plow, 2);
+ tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+ else
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->selfJoinQuery(r, vis);
+ }
+ }
+
+ if ((count % 1000) == 0)
+ std::cerr << count << std::endl;
+
+ count++;
+ }
+
+ std::cerr << "Operations: " << count << std::endl;
+ std::cerr << *tree;
+ std::cerr << "Buffer hits: " << file->getHits() << std::endl;
+ std::cerr << "Index ID: " << indexIdentifier << std::endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) std::cerr << "ERROR: Structure is invalid!" << std::endl;
+ else std::cerr << "The stucture seems O.K." << std::endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ std::cerr << "******ERROR******" << std::endl;
+ std::string s = e.what();
+ std::cerr << s << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.vcproj b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.vcproj
new file mode 100755
index 000000000..e91e5e64a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeLoad.vcproj
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeLoad"
+ ProjectGUID="{551D683C-E5DC-4713-9D9F-F629D15BE5DA}"
+ RootNamespace="RTreeLoad"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\RTreeLoad.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.cc
new file mode 100644
index 000000000..865054ebe
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.cc
@@ -0,0 +1,272 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+#include <cstring>
+
+// include library header file.
+#include <SpatialIndex.h>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// findes the index and leaf IO for answering the query and prints
+// the resulting data IDs to stdout.
+class MyVisitor : public IVisitor
+{
+public:
+ size_t m_indexIO;
+ size_t m_leafIO;
+
+public:
+ MyVisitor() : m_indexIO(0), m_leafIO(0) {}
+
+ void visitNode(const INode& n)
+ {
+ if (n.isLeaf()) m_leafIO++;
+ else m_indexIO++;
+ }
+
+ void visitData(const IData& d)
+ {
+ IShape* pS;
+ d.getShape(&pS);
+ // do something.
+ delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ byte* pData = 0;
+ uint32_t cLen = 0;
+ d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ delete[] pData;
+
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v)
+ {
+ cout << v[0]->getIdentifier() << " " << v[1]->getIdentifier() << endl;
+ }
+};
+
+// example of a Strategy pattern.
+// traverses the tree by level.
+class MyQueryStrategy : public SpatialIndex::IQueryStrategy
+{
+private:
+ queue<id_type> ids;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ IShape* ps;
+ entry.getShape(&ps);
+ Region* pr = dynamic_cast<Region*>(ps);
+
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl << endl << endl;
+ // print node MBRs gnuplot style!
+
+ delete ps;
+
+ const INode* n = dynamic_cast<const INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 1)
+ {
+ for (uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (! ids.empty())
+ {
+ nextEntry = ids.front(); ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+};
+
+// example of a Strategy pattern.
+// find the total indexed space managed by the index (the MBR of the root).
+class MyQueryStrategy2 : public IQueryStrategy
+{
+public:
+ Region m_indexedSpace;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ // the first time we are called, entry points to the root.
+
+ // stop after the root.
+ hasNext = false;
+
+ IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(m_indexedSpace);
+ delete ps;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 4)
+ {
+ cerr << "Usage: " << argv[0] << " query_file tree_file query_type [intersection | 10NN | selfjoin]." << endl;
+ return -1;
+ }
+
+ uint32_t queryType = 0;
+
+ if (strcmp(argv[3], "intersection") == 0) queryType = 0;
+ else if (strcmp(argv[3], "10NN") == 0) queryType = 1;
+ else if (strcmp(argv[3], "selfjoin") == 0) queryType = 2;
+ else
+ {
+ cerr << "Unknown query type." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open query file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName);
+ // this will try to locate and open an already existing storage manager.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // If we need to open an existing tree stored in the storage manager, we only
+ // have to specify the index identifier as follows
+ ISpatialIndex* tree = RTree::loadRTree(*file, 1);
+
+ size_t count = 0;
+ size_t indexIO = 0;
+ size_t leafIO = 0;
+ id_type id;
+ uint32_t op;
+ double x1, x2, y1, y2;
+ double plow[2], phigh[2];
+
+ while (fin)
+ {
+ fin >> op >> id >> x1 >> y1 >> x2 >> y2;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == QUERY)
+ {
+ plow[0] = x1; plow[1] = y1;
+ phigh[0] = x2; phigh[1] = y2;
+
+ MyVisitor vis;
+
+ if (queryType == 0)
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+ else if (queryType == 1)
+ {
+ Point p = Point(plow, 2);
+ tree->nearestNeighborQuery(10, p, vis);
+ // this will find the 10 nearest neighbors.
+ }
+ else
+ {
+ Region r = Region(plow, phigh, 2);
+ tree->selfJoinQuery(r, vis);
+ }
+
+ indexIO += vis.m_indexIO;
+ leafIO += vis.m_leafIO;
+ // example of the Visitor pattern usage, for calculating how many nodes
+ // were visited.
+ }
+ else
+ {
+ cerr << "This is not a query operation." << endl;
+ }
+
+ if ((count % 1000) == 0) cerr << count << endl;
+
+ count++;
+ }
+
+ MyQueryStrategy2 qs;
+ tree->queryStrategy(qs);
+
+ cerr << "Indexed space: " << qs.m_indexedSpace << endl;
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Index I/O: " << indexIO << endl;
+ cerr << "Leaf I/O: " << leafIO << endl;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail writting the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.vcproj b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.vcproj
new file mode 100755
index 000000000..c5fe4b981
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/RTreeQuery.vcproj
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="RTreeQuery"
+ ProjectGUID="{1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}"
+ RootNamespace="RTreeQuery"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64_d.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN64;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="spatialindex64.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../.."
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\RTreeQuery.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/all-wcprops
new file mode 100644
index 000000000..6b4b31fb5
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/136/spatialindex/trunk/regressiontest/rtree/test1
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/130/spatialindex/trunk/regressiontest/rtree/test1/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/dir-prop-base
new file mode 100644
index 000000000..3359090b2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 13
+data
+queries
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/entries
new file mode 100644
index 000000000..e4258db19
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/rtree/test1
+http://svn.gispython.org/spatialindex
+
+
+
+2009-08-19T15:24:15.611139Z
+136
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:33.997369Z
+f1779b89f1e882bfe22d720ea9262390
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+627
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..350c2bcb9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/.svn/text-base/run.svn-base
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 10000 100 > d
+awk '{if ($1 != 2) print $0}' < d > data
+awk '{if ($1 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new R-Tree
+../RTreeLoad data tree 20 10NN
+
+echo Querying R-Tree
+../RTreeQuery queries tree 10NN > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t 10NN > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/run
new file mode 100755
index 000000000..350c2bcb9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test1/run
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 10000 100 > d
+awk '{if ($1 != 2) print $0}' < d > data
+awk '{if ($1 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new R-Tree
+../RTreeLoad data tree 20 10NN
+
+echo Querying R-Tree
+../RTreeQuery queries tree 10NN > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t 10NN > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/all-wcprops
new file mode 100644
index 000000000..693c12f57
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/136/spatialindex/trunk/regressiontest/rtree/test2
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/130/spatialindex/trunk/regressiontest/rtree/test2/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/dir-prop-base
new file mode 100644
index 000000000..4d3f4094b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/dir-prop-base
@@ -0,0 +1,6 @@
+K 10
+svn:ignore
+V 4
+mix
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/entries
new file mode 100644
index 000000000..421efd4e2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/rtree/test2
+http://svn.gispython.org/spatialindex
+
+
+
+2009-08-19T15:24:15.611139Z
+136
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.013138Z
+9acfc48b3c207cd65522443a6a4ee9dd
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+486
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..9e7ccf2fa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/.svn/text-base/run.svn-base
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 10000 100 > mix
+
+echo Creating new R-Tree and Querying
+../RTreeLoad mix tree 20 intersection > res
+
+echo Running exhaustive search
+../Exhaustive mix intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/run
new file mode 100755
index 000000000..9e7ccf2fa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test2/run
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 10000 100 > mix
+
+echo Creating new R-Tree and Querying
+../RTreeLoad mix tree 20 intersection > res
+
+echo Running exhaustive search
+../Exhaustive mix intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/all-wcprops
new file mode 100644
index 000000000..cfbd70929
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/181/spatialindex/trunk/regressiontest/rtree/test3
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/181/spatialindex/trunk/regressiontest/rtree/test3/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/dir-prop-base
new file mode 100644
index 000000000..a9b1f04be
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/dir-prop-base
@@ -0,0 +1,8 @@
+K 10
+svn:ignore
+V 15
+d
+data
+queries
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/entries
new file mode 100644
index 000000000..1a5c24425
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/rtree/test3
+http://svn.gispython.org/spatialindex
+
+
+
+2010-04-12T17:07:13.774013Z
+181
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.013138Z
+e0262019820ab52ac9bd600911e49116
+2010-04-12T17:07:13.774013Z
+181
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+739
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..3392dcb1b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/.svn/text-base/run.svn-base
@@ -0,0 +1,30 @@
+#! /bin/bash
+
+export PATH=$PATH:../../..
+
+#echo Generating 10 million entries. This might take a while
+#echo Generating dataset
+../Generator 1000000 0 > d
+awk '{if ($1 == 1) print $0}' < d > data
+awk '{if ($1 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new R-Tree
+../RTreeBulkLoad data tree 1000 0.9
+
+echo Querying R-Tree
+../RTreeQuery queries tree intersection > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then echo "Same results with exhaustive search. Everything seems fine."
+else echo "PROBLEM! We got different results from exhaustive search!"
+fi
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/run
new file mode 100755
index 000000000..3392dcb1b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test3/run
@@ -0,0 +1,30 @@
+#! /bin/bash
+
+export PATH=$PATH:../../..
+
+#echo Generating 10 million entries. This might take a while
+#echo Generating dataset
+../Generator 1000000 0 > d
+awk '{if ($1 == 1) print $0}' < d > data
+awk '{if ($1 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new R-Tree
+../RTreeBulkLoad data tree 1000 0.9
+
+echo Querying R-Tree
+../RTreeQuery queries tree intersection > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t intersection > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then echo "Same results with exhaustive search. Everything seems fine."
+else echo "PROBLEM! We got different results from exhaustive search!"
+fi
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/all-wcprops
new file mode 100644
index 000000000..ce1cd5e26
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/136/spatialindex/trunk/regressiontest/rtree/test4
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/rtree/test4/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/dir-prop-base
new file mode 100644
index 000000000..3359090b2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 13
+data
+queries
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/entries
new file mode 100644
index 000000000..0f02ec24f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/rtree/test4
+http://svn.gispython.org/spatialindex
+
+
+
+2009-08-19T15:24:15.611139Z
+136
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.041166Z
+d8cd8171ed1338905973134f9f2f189c
+2007-08-01T20:37:49.786254Z
+2
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+637
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..8bef71b9c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/.svn/text-base/run.svn-base
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 10000 0 > d
+awk '{if ($1 == 1) print $0}' < d > data
+awk '{if ($1 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new R-Tree
+../RTreeLoad data tree 20 selfjoin
+
+echo Querying R-Tree
+../RTreeQuery queries tree selfjoin > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t selfjoin > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/run
new file mode 100755
index 000000000..8bef71b9c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/rtree/test4/run
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator 10000 0 > d
+awk '{if ($1 == 1) print $0}' < d > data
+awk '{if ($1 == 2) print $0}' < d > queries
+rm -rf d
+
+echo Creating new R-Tree
+../RTreeLoad data tree 20 selfjoin
+
+echo Querying R-Tree
+../RTreeQuery queries tree selfjoin > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t selfjoin > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/all-wcprops
new file mode 100644
index 000000000..9a33cca87
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/all-wcprops
@@ -0,0 +1,47 @@
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/177/spatialindex/trunk/regressiontest/tprtree
+END
+TPRTreeQuery.cc
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/spatialindex/!svn/ver/159/spatialindex/trunk/regressiontest/tprtree/TPRTreeQuery.cc
+END
+Exhaustive.cc
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/spatialindex/!svn/ver/171/spatialindex/trunk/regressiontest/tprtree/Exhaustive.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/spatialindex/!svn/ver/45/spatialindex/trunk/regressiontest/tprtree/Makefile.am
+END
+TPRTreeLoad.cc
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/spatialindex/!svn/ver/159/spatialindex/trunk/regressiontest/tprtree/TPRTreeLoad.cc
+END
+Generator.cc
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/spatialindex/!svn/ver/159/spatialindex/trunk/regressiontest/tprtree/Generator.cc
+END
+RandomGenerator.cc
+K 25
+svn:wc:ra_dav:version-url
+V 86
+/spatialindex/!svn/ver/33/spatialindex/trunk/regressiontest/tprtree/RandomGenerator.cc
+END
+RandomGenerator.h
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/spatialindex/!svn/ver/33/spatialindex/trunk/regressiontest/tprtree/RandomGenerator.h
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/dir-prop-base
new file mode 100644
index 000000000..7a64f684a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/dir-prop-base
@@ -0,0 +1,13 @@
+K 10
+svn:ignore
+V 79
+Makefile.in
+Exhaustive
+TPRTreeLoad
+Generator
+.libs
+.deps
+TPRTreeQuery
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/entries
new file mode 100644
index 000000000..96a10fc75
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/entries
@@ -0,0 +1,272 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/tprtree
+http://svn.gispython.org/spatialindex
+
+
+
+2010-03-05T02:56:08.483796Z
+177
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+TPRTreeQuery.cc
+file
+
+
+
+
+2011-08-01T00:42:34.157878Z
+2f27d0d210ed9bfa79b33129ca241216
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8486
+
+test1
+dir
+
+test2
+dir
+
+Exhaustive.cc
+file
+
+
+
+
+2011-08-01T00:42:34.157878Z
+b19017e32516181ba22d090ed4193b4c
+2009-12-29T02:35:01.217521Z
+171
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6368
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.157878Z
+1a96c16fc63a9fa550021027cd994742
+2008-01-17T23:34:01.575758Z
+45
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+527
+
+TPRTreeLoad.cc
+file
+
+
+
+
+2011-08-01T00:42:34.157878Z
+f30e8d027f206e8b447b9346258abba0
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6388
+
+Generator.cc
+file
+
+
+
+
+2011-08-01T00:42:34.157878Z
+9a7e1fa26d98c69faf729f6a62c89a1d
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2478
+
+RandomGenerator.cc
+file
+
+
+
+
+2011-08-01T00:42:34.161195Z
+9815f67f60f52f3a96132401716eec3d
+2007-11-29T21:48:42.077730Z
+33
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5120
+
+RandomGenerator.h
+file
+
+
+
+
+2011-08-01T00:42:34.161195Z
+8308d1342713b6b403aae9992cbaac93
+2007-11-29T21:48:42.077730Z
+33
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3198
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Exhaustive.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Exhaustive.cc.svn-base
new file mode 100644
index 000000000..2fe6ca848
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Exhaustive.cc.svn-base
@@ -0,0 +1,272 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <assert.h>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <queue>
+#include <cmath>
+#include <stdint.h>
+
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+#pragma warning( disable: 4251 )
+
+#else
+ #include <stdint.h>
+#endif
+
+class Rectangle
+{
+public:
+ Rectangle(double xlow, double xhigh, double ylow, double yhigh)
+ : m_xlow(xlow), m_xhigh(xhigh), m_ylow(ylow), m_yhigh(yhigh) {}
+
+ size_t computeCode(double x, double y)
+ {
+ size_t c = 0;
+ if(y > m_yhigh) c |= TOP;
+ else if(y < m_ylow) c |= BOTTOM;
+ if( x > m_xhigh) c |= RIGHT;
+ else if(x < m_xlow) c |= LEFT;
+ return c;
+ }
+
+ bool intersectsPoint(double x, double y)
+ {
+ if (m_xlow <= x && x <= m_xhigh &&
+ m_ylow <= y && y <= m_yhigh) return true;
+ return false;
+ }
+
+ bool intersectsSegment(double x0, double x1, double y0, double y1)
+ {
+ size_t C0, C1, C;
+ double x,y;
+
+ C0 = computeCode(x0, y0);
+ C1 = computeCode(x1, y1);
+
+ for(;;)
+ {
+ /*
+ * trivial accept: both ends inside rectangle
+ */
+ if((C0 | C1) == 0)
+ {
+ return true;
+ }
+
+ /*
+ * trivial reject: both ends on the external side
+ * of the rectanlge
+ */
+ if((C0 & C1) != 0)
+ {
+ return false;
+ }
+
+ /*
+ * normal case: clip end outside rectangle
+ */
+ C = C0 ? C0 : C1;
+ if(C & TOP)
+ {
+ x = x0 + (x1 - x0) * (m_yhigh - y0) / (y1 - y0);
+ y = m_yhigh;
+ }
+ else if(C & BOTTOM)
+ {
+ x = x0 + (x1 - x0) * (m_ylow - y0) / (y1 - y0);
+ y = m_ylow;
+ }
+ else if(C & RIGHT)
+ {
+ x = m_xhigh;
+ y = y0 + (y1 - y0) * (m_xhigh - x0) / (x1 - x0);
+ }
+ else
+ {
+ x = m_xlow;
+ y = y0 + (y1 - y0) * (m_xlow - x0) / (x1 - x0);
+ }
+
+ /*
+ * set new end point and iterate
+ */
+ if(C == C0)
+ {
+ x0 = x; y0 = y;
+ C0 = computeCode(x0, y0);
+ }
+ else
+ {
+ x1 =x; y1 = y;
+ C1 = computeCode(x1, y1);
+ }
+ }
+ }
+
+ static const size_t TOP = 0x1;
+ static const size_t BOTTOM = 0x2;
+ static const size_t RIGHT = 0x4;
+ static const size_t LEFT = 0x8;
+
+ double m_xlow, m_xhigh, m_ylow, m_yhigh;
+};
+
+class MovingPoint
+{
+public:
+ MovingPoint(double ax, double vx, double ay, double vy, double rt)
+ : m_ax(ax), m_vx(vx), m_ay(ay), m_vy(vy), m_rt(rt) {}
+
+ double getX(double t) { return m_ax + m_vx * (t - m_rt); }
+ double getY(double t) { return m_ay + m_vy * (t - m_rt); }
+
+ double m_ax, m_vx, m_ay, m_vy;
+ double m_rt;
+};
+
+class TimeRectangle
+{
+public:
+ TimeRectangle(double xlow, double xhigh, double ylow, double yhigh, double tlow, double thigh)
+ : m_xlow(xlow), m_xhigh(xhigh), m_ylow(ylow), m_yhigh(yhigh), m_tlow(tlow), m_thigh(thigh) {}
+
+ bool intersects(MovingPoint& mp)
+ {
+ double x0 = mp.getX(m_tlow);
+ double x1 = mp.getX(m_thigh);
+ double y0 = mp.getY(m_tlow);
+ double y1 = mp.getY(m_thigh);
+ //double t0 = m_tlow;
+ //double t1 = m_thigh;
+
+ Rectangle rxy(m_xlow, m_xhigh, m_ylow, m_yhigh);
+ return rxy.intersectsSegment(x0, x1, y0, y1);
+
+/*
+ // not needed to check all planes since it is
+ // guaranteed that on the time dimension
+ // the line segment and the query cube have
+ // exactly the same length (thus, if they intersect
+ // they should intersect on the X-Y projection for sure).
+
+ Rectangle rxy(m_xlow, m_xhigh, m_ylow, m_yhigh);
+ if (rxy.intersectsSegment(x0, x1, y0, y1))
+ {
+ Rectangle rxt(m_xlow, m_xhigh, m_tlow, m_thigh);
+ if (rxt.intersectsSegment(x0, x1, t0, t1))
+ {
+ Rectangle ryt(m_ylow, m_yhigh, m_tlow, m_thigh);
+ if (ryt.intersectsSegment(y0, y1, t0, t1)) return true;
+ }
+ }
+*/
+
+ return false;
+ }
+
+ bool intersectsStupid(MovingPoint& mp)
+ {
+ size_t t0 = static_cast<size_t>(std::floor(m_tlow));
+ size_t t1 = static_cast<size_t>(std::floor(m_thigh));
+
+ Rectangle rxy(m_xlow, m_xhigh, m_ylow, m_yhigh);
+
+ for (size_t T = t0; T <= t1; T++)
+ {
+ if (rxy.intersectsPoint(mp.getX(T), mp.getY(T))) return true;
+ }
+ return false;
+ }
+
+ double m_xlow, m_xhigh, m_ylow, m_yhigh;
+ double m_tlow, m_thigh;
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ cerr << "Usage: " << argv[0] << " data_file." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file" << argv[1] << "." << endl;
+ return -1;
+ }
+
+ map<size_t, MovingPoint> data;
+ size_t id, op;
+ double ax, vx, ay, vy, ct, rt, unused;
+
+ while (fin)
+ {
+ fin >> id >> op >> ct >> rt >> unused >> ax >> vx >> unused >> ay >> vy;
+ if (! fin.good()) continue;
+
+ if (op == INSERT)
+ {
+ data.insert(pair<size_t, MovingPoint>(id, MovingPoint(ax, vx, ay, vy, ct)));
+ }
+ else if (op == DELETE)
+ {
+ data.erase(id);
+ }
+ else if (op == QUERY)
+ {
+ TimeRectangle query = TimeRectangle(ax, vx, ay, vy, ct, rt);
+ for (multimap<size_t, MovingPoint>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ //assert(query.intersects((*it).second) == query.intersectsStupid((*it).second));
+ if (query.intersects((*it).second) == false && query.intersectsStupid((*it).second) == true)
+ {
+ cerr << "Something is wrong: " << ct << " " << (*it).first << endl;
+ return -1;
+ }
+ if (query.intersects((*it).second)) cout << (*it).first << endl;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Generator.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Generator.cc.svn-base
new file mode 100644
index 000000000..3a4ce6ad3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Generator.cc.svn-base
@@ -0,0 +1,98 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "RandomGenerator.h"
+
+int main(int argc, char** argv)
+{
+ size_t ds = 1000, sl = 100, mui = 20, id = UNIFORM;
+ double a = 0.01;
+
+ for (int i = 1; i < argc; i++)
+ {
+ if (! strcmp(argv[i], "-ds"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing dataset size." << endl;
+ return -1;
+ }
+ ds = atoi(argv[i]);
+ }
+ else if (! strcmp(argv[i], "-sl"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing simulation length." << endl;
+ return -1;
+ }
+ sl = atoi(argv[i]);
+ }
+ else if (! strcmp(argv[i], "-a"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing agility." << endl;
+ return -1;
+ }
+ a = atof(argv[i]);
+ }
+ else if (! strcmp(argv[i], "-mui"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing update rate." << endl;
+ return -1;
+ }
+ mui = atoi(argv[i]);
+ }
+ else
+ {
+ cerr << "Usage: " << endl
+ << " -ds dataset size" << endl
+ << " -sl simulation length" << endl
+ << " -a agility" << endl
+ << " -sd speed distribution" << endl
+ << " -id initial distribution" << endl
+ << " -mui maximum update interval" << endl;
+ return -1;
+ }
+ }
+
+ RandomGenerator g = RandomGenerator(ds, sl, mui, a);
+ g.m_initialDistribution = id;
+ g.m_maxX = 1.0; g.m_maxY = 1.0;
+ g.m_minQueryExtent = 0.05; g.m_maxQueryExtent = 0.1;
+ g.m_minSpeed = 0.0025; // 15 miles/hour = 0.25 miles/minute
+ g.m_maxSpeed = 0.0166; // 100 miles/hour = 1.66 miles/minute
+ g.m_speedMean = 0.005; // 30 miles/hour = 0.5 miles/minute
+ g.m_speedStandardDeviation = 0.0033; // 20 miles/hour = 0.33 miles/minute
+
+ g.generate();
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..da64516f7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,11 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_PROGRAMS = Generator Exhaustive TPRTreeLoad TPRTreeQuery
+INCLUDES = -I../../include
+Generator_SOURCES = RandomGenerator.cc Generator.cc RandomGenerator.h
+Generator_LDADD = ../../libspatialindex.la
+Exhaustive_SOURCES = Exhaustive.cc
+Exhaustive_LDADD = ../../libspatialindex.la
+TPRTreeLoad_SOURCES = TPRTreeLoad.cc
+TPRTreeLoad_LDADD = ../../libspatialindex.la
+TPRTreeQuery_SOURCES = TPRTreeQuery.cc
+TPRTreeQuery_LDADD = ../../libspatialindex.la
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.cc.svn-base
new file mode 100644
index 000000000..df4f396e8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.cc.svn-base
@@ -0,0 +1,176 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "RandomGenerator.h"
+
+RandomGenerator::MyMovingObject* RandomGenerator::createObject(int id, int st, double xmin, double xmax, double ymin, double ymax)
+{
+ double x, y;
+ x = m_random.nextUniformDouble(xmin, xmax);
+ y = m_random.nextUniformDouble(ymin, ymax);
+
+ return createObject(id, st, x, y);
+}
+
+RandomGenerator::MyMovingObject* RandomGenerator::createObject(int id, int st, double x, double y)
+{
+ MyMovingObject* o = new MyMovingObject();
+
+ o->m_id = id;
+ o->m_sx = x;
+ o->m_sy = y;
+ o->m_st = st;
+ o->m_kt = -1;
+
+ double v = generateSpeed();
+ if (m_random.flipCoin()) v *= -1.0;
+
+ double angle = m_random.nextUniformDouble(-M_PI_2 , M_PI_2);
+ if (m_random.flipCoin()) angle *= -1.0;
+
+ o->m_vx = cos(angle) * v;
+ o->m_vy = sin(angle) * v;
+
+ cout << o->m_id << " " << INSERT << " " << st << " " << o->m_st << " 1 " << o->m_sx << " " << o->m_vx
+ << " 1 " << o->m_sy << " " << o->m_vy << endl;
+
+ map<int, MyMovingObject*>::iterator itDataset = m_dataset.find(o->m_id);
+ if (itDataset != m_dataset.end()) m_dataset.erase(itDataset);
+ m_dataset.insert(pair<int, MyMovingObject*>(o->m_id, o));
+
+ int t1 = o->m_st + m_maximumUpdateInterval;
+ int t2;
+
+ for (t2 = st; t2 <= m_simulationLength; t2++)
+ {
+ if (o->getX(t2) > m_maxX || o->getY(t2) > m_maxY || o->getX(t2) < 0.0 || o->getY(t2) < 0.0) break;
+ }
+
+ o->m_outOfBounds = (t2 < t1) ? true : false;
+ int t = min(t1, t2);
+
+ if (t == st) t++;
+ if (t < m_simulationLength)
+ {
+ m_updateArray[t].insert(o->m_id);
+ o->m_kt = t;
+ }
+
+ return o;
+}
+
+double RandomGenerator::generateSpeed()
+{
+ return m_random.nextUniformDouble(m_minSpeed, m_maxSpeed);
+}
+
+void RandomGenerator::generate()
+{
+ for (map<int, MyMovingObject*>::iterator itDataset = m_dataset.begin(); itDataset != m_dataset.end(); itDataset++)
+ {
+ delete (*itDataset).second;
+ }
+ m_dataset.clear();
+
+ for (int cIndex = 0; cIndex < m_simulationLength; cIndex++)
+ {
+ m_updateArray[cIndex].clear();
+ }
+
+ int updatesPerTimeInstant = (int) ceil(((double) m_datasetSize) * m_agility);
+
+ for (int cObject = 0; cObject < m_datasetSize; cObject++)
+ {
+ createObject(cObject, 0, 0.0, m_maxX, 0.0, m_maxY);
+
+ if (cObject % 10000 == 0) cerr << cObject << endl;
+ }
+
+ for (int Tnow = 1; Tnow < m_simulationLength; Tnow++)
+ {
+ cerr << "Time: " << Tnow;
+
+ int cTotalUpdates = 0;
+ int cNeedToUpdate = updatesPerTimeInstant;
+ set<int> updated;
+ set<int>::iterator itUpdateArray = m_updateArray[Tnow].begin();
+
+ while (cNeedToUpdate > 0 || itUpdateArray != m_updateArray[Tnow].end())
+ {
+ int id;
+ bool bKilled = false;
+ if (itUpdateArray != m_updateArray[Tnow].end())
+ {
+ bKilled = true;
+ id = *itUpdateArray;
+ itUpdateArray++;
+ }
+ else
+ {
+ id = m_random.nextUniformLong(0, m_datasetSize);
+ set<int>::iterator itUpdated = updated.find(id);
+
+ while (itUpdated != updated.end())
+ {
+ id = m_random.nextUniformLong(0, m_datasetSize);
+ itUpdated = updated.find(id);
+ }
+ }
+ updated.insert(id);
+ cNeedToUpdate--;
+ cTotalUpdates++;
+
+ map<int,MyMovingObject*>::iterator itDataset = m_dataset.find(id);
+ assert(itDataset != m_dataset.end());
+ MyMovingObject* o = (*itDataset).second;
+ m_dataset.erase(itDataset);
+ if (o->m_kt >= 0) m_updateArray[o->m_kt].erase(o->m_id);
+
+ cout << o->m_id << " " << DELETE << " " << Tnow << " " << o->m_st << " 1 " << o->m_sx << " " << o->m_vx
+ << " 1 " << o->m_sy << " " << o->m_vy << endl;
+
+ if (bKilled && o->m_outOfBounds)
+ {
+ createObject(o->m_id, Tnow, 0.0, m_maxX, 0.0, m_maxY);
+ }
+ else
+ {
+ createObject(o->m_id, Tnow, o->getX(Tnow), o->getY(Tnow));
+ }
+
+ delete o;
+ }
+
+ for (int cQuery = 0; cQuery < m_queriesPerTimeInstant; cQuery++)
+ {
+ double x = m_random.nextUniformDouble(0.0, m_maxX);
+ double y = m_random.nextUniformDouble(0.0, m_maxY);
+ double dx = m_random.nextUniformDouble(m_minQueryExtent, m_maxQueryExtent);
+ double dy = m_random.nextUniformDouble(m_minQueryExtent, m_maxQueryExtent);
+ int dt = m_random.nextUniformLong(m_minQueryInterval, m_maxQueryInterval);
+ int t = m_random.nextUniformLong(Tnow, Tnow + m_horizon - dt);
+
+ cout << "9999999 " << QUERY << " " << t << " " << t + dt << " 1 " << x - dx << " " << x + dx << " 1 " << y - dy << " " << y + dy << endl;
+ }
+
+ cerr << ", Updates: " << cTotalUpdates << endl;
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.h.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.h.svn-base
new file mode 100644
index 000000000..9748fb0bd
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/RandomGenerator.h.svn-base
@@ -0,0 +1,138 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#ifndef _random_generator_h
+#define _random_generator_h
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <math.h>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <cmath>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <set>
+#include <stack>
+
+#include <tools/Tools.h>
+
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+#define UNIFORM 1
+
+class RandomGenerator
+{
+public:
+ RandomGenerator(int ds, int sl, int mui, double a)
+ : m_datasetSize(ds),
+ m_simulationLength(sl),
+ m_initialDistribution(UNIFORM),
+ m_maximumUpdateInterval(mui),
+ m_queriesPerTimeInstant(5),
+ m_minQueryExtent(5),
+ m_maxQueryExtent(10),
+ m_horizon(20),
+ m_maxQueryInterval(10),
+ m_minQueryInterval(2),
+ m_agility(a),
+ m_minSpeed(0.25), // 15 miles/hour = 0.25 miles/minute
+ m_maxSpeed(1.66), // 100 miles/hour = 1.66 miles/minute
+ m_speedMean(0.5), // 30 miles/hour = 0.5 miles/minute
+ m_speedStandardDeviation(0.33), // 20 miles/hour = 0.33 miles/minute
+ m_maxX(100.0),
+ m_maxY(100.0),
+ m_updateArray(0)
+ {
+ m_updateArray = new set<int>[m_simulationLength];
+ }
+
+ virtual ~RandomGenerator()
+ {
+ for (map<int, MyMovingObject*>::iterator it = m_dataset.begin(); it != m_dataset.end(); it++)
+ {
+ delete (*it).second;
+ }
+ delete[] m_updateArray;
+ }
+
+ class MyMovingObject
+ {
+ public:
+ double getX(int t)
+ {
+ return m_sx + m_vx * (t - m_st);
+ }
+
+ double getY(int t)
+ {
+ return m_sy + m_vy * (t - m_st);
+ }
+
+ public:
+ int m_id;
+ int m_st;
+ int m_kt;
+ double m_sx, m_sy;
+ double m_vx, m_vy;
+ bool m_outOfBounds;
+ };
+
+ virtual void generate();
+ MyMovingObject* createObject(int id, int st, double xmin, double xmax, double ymin, double ymax);
+ MyMovingObject* createObject(int id, int st, double x, double y);
+ double generateSpeed();
+
+public:
+ int m_datasetSize;
+ int m_simulationLength;
+ int m_initialDistribution;
+ int m_maximumUpdateInterval;
+ int m_queriesPerTimeInstant;
+ double m_minQueryExtent;
+ double m_maxQueryExtent;
+ int m_horizon;
+ int m_maxQueryInterval;
+ int m_minQueryInterval;
+ double m_agility;
+ double m_minSpeed;
+ double m_maxSpeed;
+ double m_speedMean;
+ double m_speedStandardDeviation;
+ double m_maxX;
+ double m_maxY;
+
+ map<int, MyMovingObject*> m_dataset;
+ set<int>* m_updateArray;
+ Tools::Random m_random;
+};
+
+#endif
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeLoad.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeLoad.cc.svn-base
new file mode 100644
index 000000000..084396bcc
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeLoad.cc.svn-base
@@ -0,0 +1,197 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+// include library header file.
+
+#include <SpatialIndex.h>
+
+#include <limits>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// see RTreeQuery for a more elaborate example.
+class MyVisitor : public IVisitor
+{
+public:
+ void visitNode(const INode& n) {}
+
+ void visitData(const IData& d)
+ {
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 4)
+ {
+ cerr << "Usage: " << argv[0] << " input_file tree_file capacity." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ // Create a new storage manager with the provided base name and a 4K page size.
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // Create a new, empty, TPRTree with dimensionality 2, minimum load 70%, horizon 20 time instants, using "file" as
+ // the StorageManager and the TPRSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = TPRTree::createNewTPRTree(*file, 0.7, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::TPRTree::TPRV_RSTAR, 20, indexIdentifier);
+
+ size_t count = 0;
+ id_type id;
+ size_t op;
+ double ax, vx, ay, vy, ct, rt, unused;
+ double plow[2], phigh[2];
+ double pvlow[2], pvhigh[2];
+
+ while (fin)
+ {
+ fin >> id >> op >> ct >> rt >> unused >> ax >> vx >> unused >> ay >> vy;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(ct, std::numeric_limits<double>::max());
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ //ostringstream os;
+ //os << r;
+ //string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see RTree::Node::load and RTree::Node::store for
+ // an example of how to do that).
+
+ //tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(rt, ct);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "Cannot delete id: " << id << " , count: " << count << endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = vx; phigh[1] = vy;
+ pvlow[0] = 0.0; pvlow[1] = 0.0;
+ pvhigh[0] = 0.0; pvhigh[1] = 0.0;
+
+ Tools::Interval ivT(ct, rt);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+ MyVisitor vis;
+
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+ cerr << "Index ID: " << indexIdentifier << endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) cerr << "ERROR: Structure is invalid!" << endl;
+ else cerr << "The stucture seems O.K." << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeQuery.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeQuery.cc.svn-base
new file mode 100644
index 000000000..52ae42f58
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/.svn/text-base/TPRTreeQuery.cc.svn-base
@@ -0,0 +1,298 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+// include library header file.
+
+#include <SpatialIndex.h>
+
+#include <limits>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// findes the index and leaf IO for answering the query and prints
+// the resulting data IDs to stdout.
+class MyVisitor : public IVisitor
+{
+public:
+ size_t m_indexIO;
+ size_t m_leafIO;
+
+public:
+ MyVisitor() : m_indexIO(0), m_leafIO(0) {}
+
+ void visitNode(const INode& n)
+ {
+ if (n.isLeaf()) m_leafIO++;
+ else m_indexIO++;
+ }
+
+ void visitData(const IData& d)
+ {
+ IShape* pS;
+ d.getShape(&pS);
+ // do something.
+ delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ //byte* pData = 0;
+ //size_t cLen = 0;
+ //d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ //delete[] pData;
+
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+// example of a Strategy pattern.
+// traverses the tree by level.
+class MyQueryStrategy : public SpatialIndex::IQueryStrategy
+{
+private:
+ queue<id_type> ids;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ IShape* ps;
+ entry.getShape(&ps);
+ MovingRegion* pr = dynamic_cast<MovingRegion*>(ps);
+
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl << endl << endl;
+ // print node MBRs gnuplot style!
+
+ delete ps;
+
+ const INode* n = dynamic_cast<const INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 1)
+ {
+ for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (! ids.empty())
+ {
+ nextEntry = ids.front(); ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+};
+
+// example of a Strategy pattern.
+// find the total indexed space managed by the index (the MBR of the root).
+class MyQueryStrategy2 : public IQueryStrategy
+{
+public:
+ Region m_indexedSpace;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ // the first time we are called, entry points to the root.
+
+ // stop after the root.
+ hasNext = false;
+
+ IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(m_indexedSpace);
+ delete ps;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 3)
+ {
+ cerr << "Usage: " << argv[0] << " input_file tree_file." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName);
+ // this will try to locate and open an already existing storage manager.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // If we need to open an existing tree stored in the storage manager, we only
+ // have to specify the index identifier as follows
+ ISpatialIndex* tree = TPRTree::loadTPRTree(*file, 1);
+
+ size_t count = 0;
+ id_type id;
+ size_t op;
+ double ax, vx, ay, vy, ct, rt, unused;
+ double plow[2], phigh[2];
+ double pvlow[2], pvhigh[2];
+ size_t indexIO = 0;
+ size_t leafIO = 0;
+
+ while (fin)
+ {
+ fin >> id >> op >> ct >> rt >> unused >> ax >> vx >> unused >> ay >> vy;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(ct, std::numeric_limits<double>::max());
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ //ostringstream os;
+ //os << r;
+ //string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see RTree::Node::load and RTree::Node::store for
+ // an example of how to do that).
+
+ //tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(rt, ct);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "Cannot delete id: " << id << " , count: " << count << endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = vx; phigh[1] = vy;
+ pvlow[0] = 0.0; pvlow[1] = 0.0;
+ pvhigh[0] = 0.0; pvhigh[1] = 0.0;
+
+ Tools::Interval ivT(ct, rt);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+ MyVisitor vis;
+
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+
+ indexIO += vis.m_indexIO;
+ leafIO += vis.m_leafIO;
+ // example of the Visitor pattern usage, for calculating how many nodes
+ // were visited.
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ MyQueryStrategy2 qs;
+ tree->queryStrategy(qs);
+
+ cerr << "Indexed space: " << qs.m_indexedSpace << endl;
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Index I/O: " << indexIO << endl;
+ cerr << "Leaf I/O: " << leafIO << endl;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail writting the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Exhaustive.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Exhaustive.cc
new file mode 100644
index 000000000..2fe6ca848
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Exhaustive.cc
@@ -0,0 +1,272 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <assert.h>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <queue>
+#include <cmath>
+#include <stdint.h>
+
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+#if defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
+#pragma warning( disable: 4251 )
+
+#else
+ #include <stdint.h>
+#endif
+
+class Rectangle
+{
+public:
+ Rectangle(double xlow, double xhigh, double ylow, double yhigh)
+ : m_xlow(xlow), m_xhigh(xhigh), m_ylow(ylow), m_yhigh(yhigh) {}
+
+ size_t computeCode(double x, double y)
+ {
+ size_t c = 0;
+ if(y > m_yhigh) c |= TOP;
+ else if(y < m_ylow) c |= BOTTOM;
+ if( x > m_xhigh) c |= RIGHT;
+ else if(x < m_xlow) c |= LEFT;
+ return c;
+ }
+
+ bool intersectsPoint(double x, double y)
+ {
+ if (m_xlow <= x && x <= m_xhigh &&
+ m_ylow <= y && y <= m_yhigh) return true;
+ return false;
+ }
+
+ bool intersectsSegment(double x0, double x1, double y0, double y1)
+ {
+ size_t C0, C1, C;
+ double x,y;
+
+ C0 = computeCode(x0, y0);
+ C1 = computeCode(x1, y1);
+
+ for(;;)
+ {
+ /*
+ * trivial accept: both ends inside rectangle
+ */
+ if((C0 | C1) == 0)
+ {
+ return true;
+ }
+
+ /*
+ * trivial reject: both ends on the external side
+ * of the rectanlge
+ */
+ if((C0 & C1) != 0)
+ {
+ return false;
+ }
+
+ /*
+ * normal case: clip end outside rectangle
+ */
+ C = C0 ? C0 : C1;
+ if(C & TOP)
+ {
+ x = x0 + (x1 - x0) * (m_yhigh - y0) / (y1 - y0);
+ y = m_yhigh;
+ }
+ else if(C & BOTTOM)
+ {
+ x = x0 + (x1 - x0) * (m_ylow - y0) / (y1 - y0);
+ y = m_ylow;
+ }
+ else if(C & RIGHT)
+ {
+ x = m_xhigh;
+ y = y0 + (y1 - y0) * (m_xhigh - x0) / (x1 - x0);
+ }
+ else
+ {
+ x = m_xlow;
+ y = y0 + (y1 - y0) * (m_xlow - x0) / (x1 - x0);
+ }
+
+ /*
+ * set new end point and iterate
+ */
+ if(C == C0)
+ {
+ x0 = x; y0 = y;
+ C0 = computeCode(x0, y0);
+ }
+ else
+ {
+ x1 =x; y1 = y;
+ C1 = computeCode(x1, y1);
+ }
+ }
+ }
+
+ static const size_t TOP = 0x1;
+ static const size_t BOTTOM = 0x2;
+ static const size_t RIGHT = 0x4;
+ static const size_t LEFT = 0x8;
+
+ double m_xlow, m_xhigh, m_ylow, m_yhigh;
+};
+
+class MovingPoint
+{
+public:
+ MovingPoint(double ax, double vx, double ay, double vy, double rt)
+ : m_ax(ax), m_vx(vx), m_ay(ay), m_vy(vy), m_rt(rt) {}
+
+ double getX(double t) { return m_ax + m_vx * (t - m_rt); }
+ double getY(double t) { return m_ay + m_vy * (t - m_rt); }
+
+ double m_ax, m_vx, m_ay, m_vy;
+ double m_rt;
+};
+
+class TimeRectangle
+{
+public:
+ TimeRectangle(double xlow, double xhigh, double ylow, double yhigh, double tlow, double thigh)
+ : m_xlow(xlow), m_xhigh(xhigh), m_ylow(ylow), m_yhigh(yhigh), m_tlow(tlow), m_thigh(thigh) {}
+
+ bool intersects(MovingPoint& mp)
+ {
+ double x0 = mp.getX(m_tlow);
+ double x1 = mp.getX(m_thigh);
+ double y0 = mp.getY(m_tlow);
+ double y1 = mp.getY(m_thigh);
+ //double t0 = m_tlow;
+ //double t1 = m_thigh;
+
+ Rectangle rxy(m_xlow, m_xhigh, m_ylow, m_yhigh);
+ return rxy.intersectsSegment(x0, x1, y0, y1);
+
+/*
+ // not needed to check all planes since it is
+ // guaranteed that on the time dimension
+ // the line segment and the query cube have
+ // exactly the same length (thus, if they intersect
+ // they should intersect on the X-Y projection for sure).
+
+ Rectangle rxy(m_xlow, m_xhigh, m_ylow, m_yhigh);
+ if (rxy.intersectsSegment(x0, x1, y0, y1))
+ {
+ Rectangle rxt(m_xlow, m_xhigh, m_tlow, m_thigh);
+ if (rxt.intersectsSegment(x0, x1, t0, t1))
+ {
+ Rectangle ryt(m_ylow, m_yhigh, m_tlow, m_thigh);
+ if (ryt.intersectsSegment(y0, y1, t0, t1)) return true;
+ }
+ }
+*/
+
+ return false;
+ }
+
+ bool intersectsStupid(MovingPoint& mp)
+ {
+ size_t t0 = static_cast<size_t>(std::floor(m_tlow));
+ size_t t1 = static_cast<size_t>(std::floor(m_thigh));
+
+ Rectangle rxy(m_xlow, m_xhigh, m_ylow, m_yhigh);
+
+ for (size_t T = t0; T <= t1; T++)
+ {
+ if (rxy.intersectsPoint(mp.getX(T), mp.getY(T))) return true;
+ }
+ return false;
+ }
+
+ double m_xlow, m_xhigh, m_ylow, m_yhigh;
+ double m_tlow, m_thigh;
+};
+
+int main(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ cerr << "Usage: " << argv[0] << " data_file." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file" << argv[1] << "." << endl;
+ return -1;
+ }
+
+ map<size_t, MovingPoint> data;
+ size_t id, op;
+ double ax, vx, ay, vy, ct, rt, unused;
+
+ while (fin)
+ {
+ fin >> id >> op >> ct >> rt >> unused >> ax >> vx >> unused >> ay >> vy;
+ if (! fin.good()) continue;
+
+ if (op == INSERT)
+ {
+ data.insert(pair<size_t, MovingPoint>(id, MovingPoint(ax, vx, ay, vy, ct)));
+ }
+ else if (op == DELETE)
+ {
+ data.erase(id);
+ }
+ else if (op == QUERY)
+ {
+ TimeRectangle query = TimeRectangle(ax, vx, ay, vy, ct, rt);
+ for (multimap<size_t, MovingPoint>::iterator it = data.begin(); it != data.end(); it++)
+ {
+ //assert(query.intersects((*it).second) == query.intersectsStupid((*it).second));
+ if (query.intersects((*it).second) == false && query.intersectsStupid((*it).second) == true)
+ {
+ cerr << "Something is wrong: " << ct << " " << (*it).first << endl;
+ return -1;
+ }
+ if (query.intersects((*it).second)) cout << (*it).first << endl;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Generator.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Generator.cc
new file mode 100644
index 000000000..3a4ce6ad3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Generator.cc
@@ -0,0 +1,98 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "RandomGenerator.h"
+
+int main(int argc, char** argv)
+{
+ size_t ds = 1000, sl = 100, mui = 20, id = UNIFORM;
+ double a = 0.01;
+
+ for (int i = 1; i < argc; i++)
+ {
+ if (! strcmp(argv[i], "-ds"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing dataset size." << endl;
+ return -1;
+ }
+ ds = atoi(argv[i]);
+ }
+ else if (! strcmp(argv[i], "-sl"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing simulation length." << endl;
+ return -1;
+ }
+ sl = atoi(argv[i]);
+ }
+ else if (! strcmp(argv[i], "-a"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing agility." << endl;
+ return -1;
+ }
+ a = atof(argv[i]);
+ }
+ else if (! strcmp(argv[i], "-mui"))
+ {
+ i++;
+ if (i >= argc)
+ {
+ cerr << "Missing update rate." << endl;
+ return -1;
+ }
+ mui = atoi(argv[i]);
+ }
+ else
+ {
+ cerr << "Usage: " << endl
+ << " -ds dataset size" << endl
+ << " -sl simulation length" << endl
+ << " -a agility" << endl
+ << " -sd speed distribution" << endl
+ << " -id initial distribution" << endl
+ << " -mui maximum update interval" << endl;
+ return -1;
+ }
+ }
+
+ RandomGenerator g = RandomGenerator(ds, sl, mui, a);
+ g.m_initialDistribution = id;
+ g.m_maxX = 1.0; g.m_maxY = 1.0;
+ g.m_minQueryExtent = 0.05; g.m_maxQueryExtent = 0.1;
+ g.m_minSpeed = 0.0025; // 15 miles/hour = 0.25 miles/minute
+ g.m_maxSpeed = 0.0166; // 100 miles/hour = 1.66 miles/minute
+ g.m_speedMean = 0.005; // 30 miles/hour = 0.5 miles/minute
+ g.m_speedStandardDeviation = 0.0033; // 20 miles/hour = 0.33 miles/minute
+
+ g.generate();
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Makefile.am b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Makefile.am
new file mode 100644
index 000000000..da64516f7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/Makefile.am
@@ -0,0 +1,11 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_PROGRAMS = Generator Exhaustive TPRTreeLoad TPRTreeQuery
+INCLUDES = -I../../include
+Generator_SOURCES = RandomGenerator.cc Generator.cc RandomGenerator.h
+Generator_LDADD = ../../libspatialindex.la
+Exhaustive_SOURCES = Exhaustive.cc
+Exhaustive_LDADD = ../../libspatialindex.la
+TPRTreeLoad_SOURCES = TPRTreeLoad.cc
+TPRTreeLoad_LDADD = ../../libspatialindex.la
+TPRTreeQuery_SOURCES = TPRTreeQuery.cc
+TPRTreeQuery_LDADD = ../../libspatialindex.la
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.cc
new file mode 100644
index 000000000..df4f396e8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.cc
@@ -0,0 +1,176 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "RandomGenerator.h"
+
+RandomGenerator::MyMovingObject* RandomGenerator::createObject(int id, int st, double xmin, double xmax, double ymin, double ymax)
+{
+ double x, y;
+ x = m_random.nextUniformDouble(xmin, xmax);
+ y = m_random.nextUniformDouble(ymin, ymax);
+
+ return createObject(id, st, x, y);
+}
+
+RandomGenerator::MyMovingObject* RandomGenerator::createObject(int id, int st, double x, double y)
+{
+ MyMovingObject* o = new MyMovingObject();
+
+ o->m_id = id;
+ o->m_sx = x;
+ o->m_sy = y;
+ o->m_st = st;
+ o->m_kt = -1;
+
+ double v = generateSpeed();
+ if (m_random.flipCoin()) v *= -1.0;
+
+ double angle = m_random.nextUniformDouble(-M_PI_2 , M_PI_2);
+ if (m_random.flipCoin()) angle *= -1.0;
+
+ o->m_vx = cos(angle) * v;
+ o->m_vy = sin(angle) * v;
+
+ cout << o->m_id << " " << INSERT << " " << st << " " << o->m_st << " 1 " << o->m_sx << " " << o->m_vx
+ << " 1 " << o->m_sy << " " << o->m_vy << endl;
+
+ map<int, MyMovingObject*>::iterator itDataset = m_dataset.find(o->m_id);
+ if (itDataset != m_dataset.end()) m_dataset.erase(itDataset);
+ m_dataset.insert(pair<int, MyMovingObject*>(o->m_id, o));
+
+ int t1 = o->m_st + m_maximumUpdateInterval;
+ int t2;
+
+ for (t2 = st; t2 <= m_simulationLength; t2++)
+ {
+ if (o->getX(t2) > m_maxX || o->getY(t2) > m_maxY || o->getX(t2) < 0.0 || o->getY(t2) < 0.0) break;
+ }
+
+ o->m_outOfBounds = (t2 < t1) ? true : false;
+ int t = min(t1, t2);
+
+ if (t == st) t++;
+ if (t < m_simulationLength)
+ {
+ m_updateArray[t].insert(o->m_id);
+ o->m_kt = t;
+ }
+
+ return o;
+}
+
+double RandomGenerator::generateSpeed()
+{
+ return m_random.nextUniformDouble(m_minSpeed, m_maxSpeed);
+}
+
+void RandomGenerator::generate()
+{
+ for (map<int, MyMovingObject*>::iterator itDataset = m_dataset.begin(); itDataset != m_dataset.end(); itDataset++)
+ {
+ delete (*itDataset).second;
+ }
+ m_dataset.clear();
+
+ for (int cIndex = 0; cIndex < m_simulationLength; cIndex++)
+ {
+ m_updateArray[cIndex].clear();
+ }
+
+ int updatesPerTimeInstant = (int) ceil(((double) m_datasetSize) * m_agility);
+
+ for (int cObject = 0; cObject < m_datasetSize; cObject++)
+ {
+ createObject(cObject, 0, 0.0, m_maxX, 0.0, m_maxY);
+
+ if (cObject % 10000 == 0) cerr << cObject << endl;
+ }
+
+ for (int Tnow = 1; Tnow < m_simulationLength; Tnow++)
+ {
+ cerr << "Time: " << Tnow;
+
+ int cTotalUpdates = 0;
+ int cNeedToUpdate = updatesPerTimeInstant;
+ set<int> updated;
+ set<int>::iterator itUpdateArray = m_updateArray[Tnow].begin();
+
+ while (cNeedToUpdate > 0 || itUpdateArray != m_updateArray[Tnow].end())
+ {
+ int id;
+ bool bKilled = false;
+ if (itUpdateArray != m_updateArray[Tnow].end())
+ {
+ bKilled = true;
+ id = *itUpdateArray;
+ itUpdateArray++;
+ }
+ else
+ {
+ id = m_random.nextUniformLong(0, m_datasetSize);
+ set<int>::iterator itUpdated = updated.find(id);
+
+ while (itUpdated != updated.end())
+ {
+ id = m_random.nextUniformLong(0, m_datasetSize);
+ itUpdated = updated.find(id);
+ }
+ }
+ updated.insert(id);
+ cNeedToUpdate--;
+ cTotalUpdates++;
+
+ map<int,MyMovingObject*>::iterator itDataset = m_dataset.find(id);
+ assert(itDataset != m_dataset.end());
+ MyMovingObject* o = (*itDataset).second;
+ m_dataset.erase(itDataset);
+ if (o->m_kt >= 0) m_updateArray[o->m_kt].erase(o->m_id);
+
+ cout << o->m_id << " " << DELETE << " " << Tnow << " " << o->m_st << " 1 " << o->m_sx << " " << o->m_vx
+ << " 1 " << o->m_sy << " " << o->m_vy << endl;
+
+ if (bKilled && o->m_outOfBounds)
+ {
+ createObject(o->m_id, Tnow, 0.0, m_maxX, 0.0, m_maxY);
+ }
+ else
+ {
+ createObject(o->m_id, Tnow, o->getX(Tnow), o->getY(Tnow));
+ }
+
+ delete o;
+ }
+
+ for (int cQuery = 0; cQuery < m_queriesPerTimeInstant; cQuery++)
+ {
+ double x = m_random.nextUniformDouble(0.0, m_maxX);
+ double y = m_random.nextUniformDouble(0.0, m_maxY);
+ double dx = m_random.nextUniformDouble(m_minQueryExtent, m_maxQueryExtent);
+ double dy = m_random.nextUniformDouble(m_minQueryExtent, m_maxQueryExtent);
+ int dt = m_random.nextUniformLong(m_minQueryInterval, m_maxQueryInterval);
+ int t = m_random.nextUniformLong(Tnow, Tnow + m_horizon - dt);
+
+ cout << "9999999 " << QUERY << " " << t << " " << t + dt << " 1 " << x - dx << " " << x + dx << " 1 " << y - dy << " " << y + dy << endl;
+ }
+
+ cerr << ", Updates: " << cTotalUpdates << endl;
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.h b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.h
new file mode 100644
index 000000000..9748fb0bd
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/RandomGenerator.h
@@ -0,0 +1,138 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#ifndef _random_generator_h
+#define _random_generator_h
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <math.h>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <cmath>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <set>
+#include <stack>
+
+#include <tools/Tools.h>
+
+using namespace std;
+
+#define DELETE 0
+#define INSERT 1
+#define QUERY 2
+
+#define UNIFORM 1
+
+class RandomGenerator
+{
+public:
+ RandomGenerator(int ds, int sl, int mui, double a)
+ : m_datasetSize(ds),
+ m_simulationLength(sl),
+ m_initialDistribution(UNIFORM),
+ m_maximumUpdateInterval(mui),
+ m_queriesPerTimeInstant(5),
+ m_minQueryExtent(5),
+ m_maxQueryExtent(10),
+ m_horizon(20),
+ m_maxQueryInterval(10),
+ m_minQueryInterval(2),
+ m_agility(a),
+ m_minSpeed(0.25), // 15 miles/hour = 0.25 miles/minute
+ m_maxSpeed(1.66), // 100 miles/hour = 1.66 miles/minute
+ m_speedMean(0.5), // 30 miles/hour = 0.5 miles/minute
+ m_speedStandardDeviation(0.33), // 20 miles/hour = 0.33 miles/minute
+ m_maxX(100.0),
+ m_maxY(100.0),
+ m_updateArray(0)
+ {
+ m_updateArray = new set<int>[m_simulationLength];
+ }
+
+ virtual ~RandomGenerator()
+ {
+ for (map<int, MyMovingObject*>::iterator it = m_dataset.begin(); it != m_dataset.end(); it++)
+ {
+ delete (*it).second;
+ }
+ delete[] m_updateArray;
+ }
+
+ class MyMovingObject
+ {
+ public:
+ double getX(int t)
+ {
+ return m_sx + m_vx * (t - m_st);
+ }
+
+ double getY(int t)
+ {
+ return m_sy + m_vy * (t - m_st);
+ }
+
+ public:
+ int m_id;
+ int m_st;
+ int m_kt;
+ double m_sx, m_sy;
+ double m_vx, m_vy;
+ bool m_outOfBounds;
+ };
+
+ virtual void generate();
+ MyMovingObject* createObject(int id, int st, double xmin, double xmax, double ymin, double ymax);
+ MyMovingObject* createObject(int id, int st, double x, double y);
+ double generateSpeed();
+
+public:
+ int m_datasetSize;
+ int m_simulationLength;
+ int m_initialDistribution;
+ int m_maximumUpdateInterval;
+ int m_queriesPerTimeInstant;
+ double m_minQueryExtent;
+ double m_maxQueryExtent;
+ int m_horizon;
+ int m_maxQueryInterval;
+ int m_minQueryInterval;
+ double m_agility;
+ double m_minSpeed;
+ double m_maxSpeed;
+ double m_speedMean;
+ double m_speedStandardDeviation;
+ double m_maxX;
+ double m_maxY;
+
+ map<int, MyMovingObject*> m_dataset;
+ set<int>* m_updateArray;
+ Tools::Random m_random;
+};
+
+#endif
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeLoad.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeLoad.cc
new file mode 100644
index 000000000..084396bcc
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeLoad.cc
@@ -0,0 +1,197 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+// include library header file.
+
+#include <SpatialIndex.h>
+
+#include <limits>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// see RTreeQuery for a more elaborate example.
+class MyVisitor : public IVisitor
+{
+public:
+ void visitNode(const INode& n) {}
+
+ void visitData(const IData& d)
+ {
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 4)
+ {
+ cerr << "Usage: " << argv[0] << " input_file tree_file capacity." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ // Create a new storage manager with the provided base name and a 4K page size.
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // Create a new, empty, TPRTree with dimensionality 2, minimum load 70%, horizon 20 time instants, using "file" as
+ // the StorageManager and the TPRSTAR splitting policy.
+ id_type indexIdentifier;
+ ISpatialIndex* tree = TPRTree::createNewTPRTree(*file, 0.7, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::TPRTree::TPRV_RSTAR, 20, indexIdentifier);
+
+ size_t count = 0;
+ id_type id;
+ size_t op;
+ double ax, vx, ay, vy, ct, rt, unused;
+ double plow[2], phigh[2];
+ double pvlow[2], pvhigh[2];
+
+ while (fin)
+ {
+ fin >> id >> op >> ct >> rt >> unused >> ax >> vx >> unused >> ay >> vy;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(ct, std::numeric_limits<double>::max());
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ //ostringstream os;
+ //os << r;
+ //string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see RTree::Node::load and RTree::Node::store for
+ // an example of how to do that).
+
+ //tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(rt, ct);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "Cannot delete id: " << id << " , count: " << count << endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = vx; phigh[1] = vy;
+ pvlow[0] = 0.0; pvlow[1] = 0.0;
+ pvhigh[0] = 0.0; pvhigh[1] = 0.0;
+
+ Tools::Interval ivT(ct, rt);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+ MyVisitor vis;
+
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+ cerr << "Index ID: " << indexIdentifier << endl;
+
+ bool ret = tree->isIndexValid();
+ if (ret == false) cerr << "ERROR: Structure is invalid!" << endl;
+ else cerr << "The stucture seems O.K." << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail trying to write the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeQuery.cc b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeQuery.cc
new file mode 100644
index 000000000..52ae42f58
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/TPRTreeQuery.cc
@@ -0,0 +1,298 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+// NOTE: Please read README.txt before browsing this code.
+
+// include library header file.
+
+#include <SpatialIndex.h>
+
+#include <limits>
+
+using namespace SpatialIndex;
+using namespace std;
+
+#define INSERT 1
+#define DELETE 0
+#define QUERY 2
+
+// example of a Visitor pattern.
+// findes the index and leaf IO for answering the query and prints
+// the resulting data IDs to stdout.
+class MyVisitor : public IVisitor
+{
+public:
+ size_t m_indexIO;
+ size_t m_leafIO;
+
+public:
+ MyVisitor() : m_indexIO(0), m_leafIO(0) {}
+
+ void visitNode(const INode& n)
+ {
+ if (n.isLeaf()) m_leafIO++;
+ else m_indexIO++;
+ }
+
+ void visitData(const IData& d)
+ {
+ IShape* pS;
+ d.getShape(&pS);
+ // do something.
+ delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ //byte* pData = 0;
+ //size_t cLen = 0;
+ //d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ //delete[] pData;
+
+ cout << d.getIdentifier() << endl;
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const IData*>& v) {}
+};
+
+// example of a Strategy pattern.
+// traverses the tree by level.
+class MyQueryStrategy : public SpatialIndex::IQueryStrategy
+{
+private:
+ queue<id_type> ids;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ IShape* ps;
+ entry.getShape(&ps);
+ MovingRegion* pr = dynamic_cast<MovingRegion*>(ps);
+
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pLow[1] << endl;
+ cout << pr->m_pHigh[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pHigh[1] << endl;
+ cout << pr->m_pLow[0] << " " << pr->m_pLow[1] << endl << endl << endl;
+ // print node MBRs gnuplot style!
+
+ delete ps;
+
+ const INode* n = dynamic_cast<const INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 1)
+ {
+ for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (! ids.empty())
+ {
+ nextEntry = ids.front(); ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+};
+
+// example of a Strategy pattern.
+// find the total indexed space managed by the index (the MBR of the root).
+class MyQueryStrategy2 : public IQueryStrategy
+{
+public:
+ Region m_indexedSpace;
+
+public:
+ void getNextEntry(const IEntry& entry, id_type& nextEntry, bool& hasNext)
+ {
+ // the first time we are called, entry points to the root.
+
+ // stop after the root.
+ hasNext = false;
+
+ IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(m_indexedSpace);
+ delete ps;
+ }
+};
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ if (argc != 3)
+ {
+ cerr << "Usage: " << argv[0] << " input_file tree_file." << endl;
+ return -1;
+ }
+
+ ifstream fin(argv[1]);
+ if (! fin)
+ {
+ cerr << "Cannot open data file " << argv[1] << "." << endl;
+ return -1;
+ }
+
+ string baseName = argv[2];
+ IStorageManager* diskfile = StorageManager::loadDiskStorageManager(baseName);
+ // this will try to locate and open an already existing storage manager.
+
+ StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
+ // applies a main memory random buffer on top of the persistent storage manager
+ // (LRU buffer, etc can be created the same way).
+
+ // If we need to open an existing tree stored in the storage manager, we only
+ // have to specify the index identifier as follows
+ ISpatialIndex* tree = TPRTree::loadTPRTree(*file, 1);
+
+ size_t count = 0;
+ id_type id;
+ size_t op;
+ double ax, vx, ay, vy, ct, rt, unused;
+ double plow[2], phigh[2];
+ double pvlow[2], pvhigh[2];
+ size_t indexIO = 0;
+ size_t leafIO = 0;
+
+ while (fin)
+ {
+ fin >> id >> op >> ct >> rt >> unused >> ax >> vx >> unused >> ay >> vy;
+ if (! fin.good()) continue; // skip newlines, etc.
+
+ if (op == INSERT)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(ct, std::numeric_limits<double>::max());
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ //ostringstream os;
+ //os << r;
+ //string data = os.str();
+ // associate some data with this region. I will use a string that represents the
+ // region itself, as an example.
+ // NOTE: It is not necessary to associate any data here. A null pointer can be used. In that
+ // case you should store the data externally. The index will provide the data IDs of
+ // the answers to any query, which can be used to access the actual data from the external
+ // storage (e.g. a hash table or a database table, etc.).
+ // Storing the data in the index is convinient and in case a clustered storage manager is
+ // provided (one that stores any node in consecutive pages) performance will improve substantially,
+ // since disk accesses will be mostly sequential. On the other hand, the index will need to
+ // manipulate the data, resulting in larger overhead. If you use a main memory storage manager,
+ // storing the data externally is highly recommended (clustering has no effect).
+ // A clustered storage manager is NOT provided yet.
+ // Also you will have to take care of converting you data to and from binary format, since only
+ // array of bytes can be inserted in the index (see RTree::Node::load and RTree::Node::store for
+ // an example of how to do that).
+
+ //tree->insertData(data.size() + 1, reinterpret_cast<const byte*>(data.c_str()), r, id);
+
+ tree->insertData(0, 0, r, id);
+ // example of passing zero size and a null pointer as the associated data.
+ }
+ else if (op == DELETE)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = ax; phigh[1] = ay;
+ pvlow[0] = vx; pvlow[1] = vy;
+ pvhigh[0] = vx; pvhigh[1] = vy;
+ Tools::Interval ivT(rt, ct);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+
+ if (tree->deleteData(r, id) == false)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "Cannot delete id: " << id << " , count: " << count << endl;
+ return -1;
+ }
+ }
+ else if (op == QUERY)
+ {
+ plow[0] = ax; plow[1] = ay;
+ phigh[0] = vx; phigh[1] = vy;
+ pvlow[0] = 0.0; pvlow[1] = 0.0;
+ pvhigh[0] = 0.0; pvhigh[1] = 0.0;
+
+ Tools::Interval ivT(ct, rt);
+
+ MovingRegion r = MovingRegion(plow, phigh, pvlow, pvhigh, ivT, 2);
+ MyVisitor vis;
+
+ tree->intersectsWithQuery(r, vis);
+ // this will find all data that intersect with the query range.
+
+ indexIO += vis.m_indexIO;
+ leafIO += vis.m_leafIO;
+ // example of the Visitor pattern usage, for calculating how many nodes
+ // were visited.
+ }
+
+ if ((count % 1000) == 0)
+ cerr << count << endl;
+
+ count++;
+ }
+
+ MyQueryStrategy2 qs;
+ tree->queryStrategy(qs);
+
+ cerr << "Indexed space: " << qs.m_indexedSpace << endl;
+ cerr << "Operations: " << count << endl;
+ cerr << *tree;
+ cerr << "Index I/O: " << indexIO << endl;
+ cerr << "Leaf I/O: " << leafIO << endl;
+ cerr << "Buffer hits: " << file->getHits() << endl;
+
+ delete tree;
+ delete file;
+ delete diskfile;
+ // delete the buffer first, then the storage manager
+ // (otherwise the the buffer will fail writting the dirty entries).
+ }
+ catch (Tools::Exception& e)
+ {
+ cerr << "******ERROR******" << endl;
+ std::string s = e.what();
+ cerr << s << endl;
+ return -1;
+ }
+ catch (...)
+ {
+ cerr << "******ERROR******" << endl;
+ cerr << "other exception" << endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/all-wcprops
new file mode 100644
index 000000000..bd2090d0d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/177/spatialindex/trunk/regressiontest/tprtree/test1
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/tprtree/test1/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/dir-prop-base
new file mode 100644
index 000000000..4dbf9b51e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/dir-prop-base
@@ -0,0 +1,14 @@
+K 10
+svn:ignore
+V 47
+data
+queries
+.t
+b
+a
+tree.idx
+tree.dat
+res
+res2
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/entries
new file mode 100644
index 000000000..fda6ee83b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/tprtree/test1
+http://svn.gispython.org/spatialindex
+
+
+
+2010-03-05T02:56:08.483796Z
+177
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.117561Z
+72e6ad4acd768c35d10f4c7389374a04
+2007-08-01T20:37:49.786254Z
+2
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+640
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..613cd992a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/.svn/text-base/run.svn-base
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator -ds 1000 -sl 100 > d
+awk '{if ($2 != 2) print $0}' < d > data
+awk '{if ($2 == 2 && $3 >= 100) print $0}' < d > queries
+rm -rf d
+
+echo Creating new TPR-Tree
+../TPRTreeLoad data tree 20
+
+echo Querying TPR-Tree
+../TPRTreeQuery queries tree > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/run
new file mode 100755
index 000000000..613cd992a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test1/run
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator -ds 1000 -sl 100 > d
+awk '{if ($2 != 2) print $0}' < d > data
+awk '{if ($2 == 2 && $3 >= 100) print $0}' < d > queries
+rm -rf d
+
+echo Creating new TPR-Tree
+../TPRTreeLoad data tree 20
+
+echo Querying TPR-Tree
+../TPRTreeQuery queries tree > res
+cat data queries > .t
+
+echo Running exhaustive search
+../Exhaustive .t > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 .t tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/all-wcprops
new file mode 100644
index 000000000..a5d2765a1
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/177/spatialindex/trunk/regressiontest/tprtree/test2
+END
+run
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/2/spatialindex/trunk/regressiontest/tprtree/test2/run
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/dir-prop-base
new file mode 100644
index 000000000..31056d0f6
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/dir-prop-base
@@ -0,0 +1,13 @@
+K 10
+svn:ignore
+V 36
+mix
+a
+b
+tree.idx
+tree.dat
+res
+res2
+
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/entries b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/entries
new file mode 100644
index 000000000..e5ed11142
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/regressiontest/tprtree/test2
+http://svn.gispython.org/spatialindex
+
+
+
+2010-03-05T02:56:08.483796Z
+177
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+run
+file
+
+
+
+
+2011-08-01T00:42:34.117561Z
+056a30f92ba10da3bc595ac8539caea3
+2007-08-01T20:37:49.786254Z
+2
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+471
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/prop-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/prop-base/run.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/prop-base/run.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/text-base/run.svn-base b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/text-base/run.svn-base
new file mode 100644
index 000000000..f13ea2c9a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/.svn/text-base/run.svn-base
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator -ds 1000 -sl 100 > mix
+
+echo Creating new TPR-Tree and Querying
+../TPRTreeLoad mix tree 10 > res
+
+echo Running exhaustive search
+../Exhaustive mix > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
+
diff --git a/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/run b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/run
new file mode 100755
index 000000000..f13ea2c9a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/regressiontest/tprtree/test2/run
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+echo Generating dataset
+../Generator -ds 1000 -sl 100 > mix
+
+echo Creating new TPR-Tree and Querying
+../TPRTreeLoad mix tree 10 > res
+
+echo Running exhaustive search
+../Exhaustive mix > res2
+
+echo Comparing results
+sort -n res > a
+sort -n res2 > b
+if diff a b
+then
+echo "Same results with exhaustive search. Everything seems fine."
+echo Results: `wc -l a`
+rm -rf a b res res2 tree.*
+else
+echo "PROBLEM! We got different results from exhaustive search!"
+fi
+
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/all-wcprops
new file mode 100644
index 000000000..491b0bba4
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/spatialindex/!svn/ver/131/spatialindex/trunk/spatialindex-vc
+END
+spatialindex.vcproj
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/spatialindex/!svn/ver/131/spatialindex/trunk/spatialindex-vc/spatialindex.vcproj
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/entries b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/entries
new file mode 100644
index 000000000..6ac4ba5b1
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/spatialindex-vc
+http://svn.gispython.org/spatialindex
+
+
+
+2009-08-13T15:42:43.408031Z
+131
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+spatialindex.vcproj
+file
+
+
+
+
+2011-08-01T00:42:34.901111Z
+0e4fff33d029e3291366d1e2752acbce
+2009-08-13T15:42:43.408031Z
+131
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21771
+
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/prop-base/spatialindex.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/prop-base/spatialindex.vcproj.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/prop-base/spatialindex.vcproj.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/text-base/spatialindex.vcproj.svn-base b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/text-base/spatialindex.vcproj.svn-base
new file mode 100644
index 000000000..42b100f1b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/.svn/text-base/spatialindex.vcproj.svn-base
@@ -0,0 +1,960 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="spatialindex-vc"
+ ProjectGUID="{38FBBD59-8344-4D8E-B728-3D51763B6A70}"
+ RootNamespace="spatialindex"
+ Keyword="ManagedCProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex_d.dll"
+ Version="1.5.0"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ AssemblyDebug="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN64;_DEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex64_d.dll"
+ Version="1.5.0"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ AssemblyDebug="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex.dll"
+ Version="1.5.0"
+ LinkIncremental="1"
+ GenerateDebugInformation="false"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN64;NDEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex64.dll"
+ Version="1.5.0"
+ LinkIncremental="1"
+ GenerateDebugInformation="false"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <AssemblyReference
+ RelativePath="System.dll"
+ AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+ />
+ <AssemblyReference
+ RelativePath="System.Data.dll"
+ AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
+ />
+ <AssemblyReference
+ RelativePath="System.XML.dll"
+ AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <Filter
+ Name="mvrtree"
+ >
+ <File
+ RelativePath="..\src\mvrtree\Index.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Leaf.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Leaf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\MVRTree.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\MVRTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Node.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Node.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\PointerPoolNode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Statistics.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Statistics.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="rtree"
+ >
+ <File
+ RelativePath="..\src\rtree\BulkLoader.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\BulkLoader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Index.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Leaf.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Leaf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Node.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Node.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\PointerPoolNode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\RTree.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\RTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Statistics.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Statistics.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="spatialindex"
+ >
+ <File
+ RelativePath="..\src\spatialindex\LineSegment.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\MovingPoint.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\MovingRegion.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\Point.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\Region.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\SpatialIndexImpl.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\SpatialIndexImpl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\TimePoint.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\TimeRegion.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="storagemanager"
+ >
+ <File
+ RelativePath="..\src\storagemanager\Buffer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\Buffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\DiskStorageManager.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\DiskStorageManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\MemoryStorageManager.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\MemoryStorageManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\RandomEvictionsBuffer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\RandomEvictionsBuffer.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="tools"
+ >
+ <File
+ RelativePath="..\src\tools\rand48.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tools\Tools.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="tprtree"
+ >
+ <File
+ RelativePath="..\src\tprtree\Index.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Leaf.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Leaf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Node.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Node.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\PointerPoolNode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Statistics.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Statistics.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\TPRTree.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\TPRTree.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\include\LineSegment.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\MovingPoint.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\MovingRegion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\MVRTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\Point.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\Region.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\RTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\SpatialIndex.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\TimePoint.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\TimeRegion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\TPRTree.h"
+ >
+ </File>
+ <Filter
+ Name="tools"
+ >
+ <File
+ RelativePath="..\include\tools\PointerPool.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\PoolPointer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\rand48.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\SmartPointer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\Tools.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/spatialindex.vcproj b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/spatialindex.vcproj
new file mode 100755
index 000000000..42b100f1b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex-vc/spatialindex.vcproj
@@ -0,0 +1,960 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="spatialindex-vc"
+ ProjectGUID="{38FBBD59-8344-4D8E-B728-3D51763B6A70}"
+ RootNamespace="spatialindex"
+ Keyword="ManagedCProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex_d.dll"
+ Version="1.5.0"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ AssemblyDebug="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN64;_DEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex64_d.dll"
+ Version="1.5.0"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ AssemblyDebug="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex.dll"
+ Version="1.5.0"
+ LinkIncremental="1"
+ GenerateDebugInformation="false"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ ManagedExtensions="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN64;NDEBUG;SPATIALINDEX_CREATE_DLL"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(NoInherit)"
+ OutputFile="$(OutDir)\spatialindex64.dll"
+ Version="1.5.0"
+ LinkIncremental="1"
+ GenerateDebugInformation="false"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <AssemblyReference
+ RelativePath="System.dll"
+ AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+ />
+ <AssemblyReference
+ RelativePath="System.Data.dll"
+ AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
+ />
+ <AssemblyReference
+ RelativePath="System.XML.dll"
+ AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <Filter
+ Name="mvrtree"
+ >
+ <File
+ RelativePath="..\src\mvrtree\Index.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Leaf.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Leaf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\MVRTree.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\MVRTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Node.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Node.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\PointerPoolNode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Statistics.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\mvrtree\Statistics.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="rtree"
+ >
+ <File
+ RelativePath="..\src\rtree\BulkLoader.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\BulkLoader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Index.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Leaf.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Leaf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Node.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Node.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\PointerPoolNode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\RTree.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\RTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\rtree\Statistics.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\rtree\Statistics.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="spatialindex"
+ >
+ <File
+ RelativePath="..\src\spatialindex\LineSegment.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\MovingPoint.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\MovingRegion.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\Point.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\Region.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\SpatialIndexImpl.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\SpatialIndexImpl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\TimePoint.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\spatialindex\TimeRegion.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="storagemanager"
+ >
+ <File
+ RelativePath="..\src\storagemanager\Buffer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\Buffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\DiskStorageManager.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\DiskStorageManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\MemoryStorageManager.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\MemoryStorageManager.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\RandomEvictionsBuffer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\storagemanager\RandomEvictionsBuffer.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="tools"
+ >
+ <File
+ RelativePath="..\src\tools\rand48.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tools\Tools.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="tprtree"
+ >
+ <File
+ RelativePath="..\src\tprtree\Index.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Leaf.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Leaf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Node.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Node.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\PointerPoolNode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Statistics.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)2.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\tprtree\Statistics.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\TPRTree.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\tprtree\TPRTree.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\include\LineSegment.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\MovingPoint.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\MovingRegion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\MVRTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\Point.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\Region.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\RTree.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\SpatialIndex.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\TimePoint.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\TimeRegion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\TPRTree.h"
+ >
+ </File>
+ <Filter
+ Name="tools"
+ >
+ <File
+ RelativePath="..\include\tools\PointerPool.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\PoolPointer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\rand48.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\SmartPointer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\tools\Tools.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex.sln b/sci-libs/libspatialindex/svn/trunk/spatialindex.sln
new file mode 100755
index 000000000..c0f1d6048
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex.sln
@@ -0,0 +1,91 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spatialindex-vc", "spatialindex-vc\spatialindex.vcproj", "{38FBBD59-8344-4D8E-B728-3D51763B6A70}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeBulkLoad", "regressiontest\rtree\RTreeBulkLoad.vcproj", "{7D9C8655-0155-4EE3-B04C-6D831E2982CE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeGenerator", "regressiontest\rtree\RTreeGenerator.vcproj", "{03504DB7-ACF3-40CF-A8A7-310E80666DC0}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeLoad", "regressiontest\rtree\RTreeLoad.vcproj", "{551D683C-E5DC-4713-9D9F-F629D15BE5DA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeQuery", "regressiontest\rtree\RTreeQuery.vcproj", "{1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTreeExhaustive", "regressiontest\rtree\RTreeExhaustive.vcproj", "{D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70} = {38FBBD59-8344-4D8E-B728-3D51763B6A70}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|Win32.ActiveCfg = Debug|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|Win32.Build.0 = Debug|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|x64.ActiveCfg = Debug|x64
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Debug|x64.Build.0 = Debug|x64
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|Win32.ActiveCfg = Release|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|Win32.Build.0 = Release|Win32
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|x64.ActiveCfg = Release|x64
+ {38FBBD59-8344-4D8E-B728-3D51763B6A70}.Release|x64.Build.0 = Release|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Debug|x64.Build.0 = Debug|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|Win32.Build.0 = Release|Win32
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|x64.ActiveCfg = Release|x64
+ {7D9C8655-0155-4EE3-B04C-6D831E2982CE}.Release|x64.Build.0 = Release|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|Win32.Build.0 = Debug|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|x64.ActiveCfg = Debug|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Debug|x64.Build.0 = Debug|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|Win32.ActiveCfg = Release|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|Win32.Build.0 = Release|Win32
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|x64.ActiveCfg = Release|x64
+ {03504DB7-ACF3-40CF-A8A7-310E80666DC0}.Release|x64.Build.0 = Release|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|Win32.Build.0 = Debug|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|x64.ActiveCfg = Debug|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Debug|x64.Build.0 = Debug|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|Win32.ActiveCfg = Release|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|Win32.Build.0 = Release|Win32
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|x64.ActiveCfg = Release|x64
+ {551D683C-E5DC-4713-9D9F-F629D15BE5DA}.Release|x64.Build.0 = Release|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|Win32.Build.0 = Debug|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|x64.ActiveCfg = Debug|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Debug|x64.Build.0 = Debug|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|Win32.ActiveCfg = Release|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|Win32.Build.0 = Release|Win32
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|x64.ActiveCfg = Release|x64
+ {1FBCCD7B-2641-4B93-9CF0-44E1EE8D55B9}.Release|x64.Build.0 = Release|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|Win32.Build.0 = Debug|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|x64.ActiveCfg = Debug|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Debug|x64.Build.0 = Debug|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|Win32.ActiveCfg = Release|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|Win32.Build.0 = Release|Win32
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|x64.ActiveCfg = Release|x64
+ {D2C6947B-5527-4D6A-88CB-842DDCCFB2FF}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/sci-libs/libspatialindex/svn/trunk/spatialindex.suo b/sci-libs/libspatialindex/svn/trunk/spatialindex.suo
new file mode 100755
index 000000000..040272d1d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/spatialindex.suo
Binary files differ
diff --git a/sci-libs/libspatialindex/svn/trunk/src/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/.svn/all-wcprops
new file mode 100644
index 000000000..17135f71d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 49
+/spatialindex/!svn/ver/202/spatialindex/trunk/src
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/spatialindex/!svn/ver/138/spatialindex/trunk/src/Makefile.am
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/.svn/dir-prop-base
new file mode 100644
index 000000000..a57f5442b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/.svn/dir-prop-base
@@ -0,0 +1,7 @@
+K 10
+svn:ignore
+V 21
+Makefile
+Makefile.in
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/.svn/entries
new file mode 100644
index 000000000..df1617524
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/.svn/entries
@@ -0,0 +1,83 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src
+http://svn.gispython.org/spatialindex
+
+
+
+2011-03-01T14:50:59.673579Z
+202
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+storagemanager
+dir
+
+tools
+dir
+
+rtree
+dir
+
+mvrtree
+dir
+
+spatialindex
+dir
+
+tprtree
+dir
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.861109Z
+cb96872c0e82412e0c970ff5fa9eaa74
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+144
+
+capi
+dir
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..a5889abfd
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,2 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+SUBDIRS = storagemanager spatialindex rtree mvrtree tprtree tools capi
diff --git a/sci-libs/libspatialindex/svn/trunk/src/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/Makefile.am
new file mode 100644
index 000000000..a5889abfd
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/Makefile.am
@@ -0,0 +1,2 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+SUBDIRS = storagemanager spatialindex rtree mvrtree tprtree tools capi
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/all-wcprops
new file mode 100644
index 000000000..ef1a5819f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/all-wcprops
@@ -0,0 +1,77 @@
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/spatialindex/!svn/ver/198/spatialindex/trunk/src/capi
+END
+IdVisitor.cc
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/180/spatialindex/trunk/src/capi/IdVisitor.cc
+END
+LeafQuery.cc
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/172/spatialindex/trunk/src/capi/LeafQuery.cc
+END
+CustomStorage.cc
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/186/spatialindex/trunk/src/capi/CustomStorage.cc
+END
+BoundsQuery.cc
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/spatialindex/!svn/ver/180/spatialindex/trunk/src/capi/BoundsQuery.cc
+END
+sidx_api.cc
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/198/spatialindex/trunk/src/capi/sidx_api.cc
+END
+Utility.cc
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/186/spatialindex/trunk/src/capi/Utility.cc
+END
+DataStream.cc
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/180/spatialindex/trunk/src/capi/DataStream.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/186/spatialindex/trunk/src/capi/Makefile.am
+END
+Index.cc
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/186/spatialindex/trunk/src/capi/Index.cc
+END
+CountVisitor.cc
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/180/spatialindex/trunk/src/capi/CountVisitor.cc
+END
+Error.cc
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/138/spatialindex/trunk/src/capi/Error.cc
+END
+ObjVisitor.cc
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/180/spatialindex/trunk/src/capi/ObjVisitor.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/dir-prop-base
new file mode 100644
index 000000000..0d2dbedbc
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/dir-prop-base
@@ -0,0 +1,9 @@
+K 10
+svn:ignore
+V 33
+.libs
+.deps
+Makefile
+Makefile.in
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/entries
new file mode 100644
index 000000000..d480bc000
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/entries
@@ -0,0 +1,436 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/capi
+http://svn.gispython.org/spatialindex
+
+
+
+2010-11-22T19:53:16.458648Z
+198
+seang
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+IdVisitor.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+d12e408e6df0d373f5cdb4d6fcb81097
+2010-03-31T15:33:43.168720Z
+180
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1619
+
+LeafQuery.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+f6b4eae1e229f385cf64610c582940c1
+2010-03-03T21:55:09.207890Z
+172
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3403
+
+CustomStorage.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+58a25cb12d8b11020f570bcbd8a310a3
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4069
+
+BoundsQuery.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+d200a112925a958aebb12c6235894c8a
+2010-03-31T15:33:43.168720Z
+180
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1618
+
+sidx_api.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+fa077621a77a780cb0e761fbad90bea9
+2010-11-22T19:53:16.458648Z
+198
+seang
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+65363
+
+Utility.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+6b75c01958ed9b9cddca8c66afc00981
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4379
+
+DataStream.cc
+file
+
+
+
+
+2011-08-01T00:42:34.853116Z
+709f65e3f1c1a7d5fa9d0f94df6d563d
+2010-03-31T15:33:43.168720Z
+180
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2813
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.857211Z
+2db54e386d4ab8d48bc41a60165804ec
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+399
+
+Index.cc
+file
+
+
+
+
+2011-08-01T00:42:34.857211Z
+b62ed5931fdca6c78d952c64439d3dc0
+2010-06-19T20:34:19.329614Z
+186
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9970
+
+CountVisitor.cc
+file
+
+
+
+
+2011-08-01T00:42:34.857211Z
+c1d1818ffc8fb2baacca20078c902795
+2010-03-31T15:33:43.168720Z
+180
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1550
+
+Error.cc
+file
+
+
+
+
+2011-08-01T00:42:34.857211Z
+a7231de96e05364398b4d1b89c43453b
+2009-08-19T16:37:50.582862Z
+138
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1765
+
+ObjVisitor.cc
+file
+
+
+
+
+2011-08-01T00:42:34.857211Z
+d0a9780a05d2a58f42449ffcc52d40f9
+2010-03-31T15:33:43.168720Z
+180
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1851
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/BoundsQuery.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/BoundsQuery.cc.svn-base
new file mode 100644
index 000000000..a7cedb2c4
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/BoundsQuery.cc.svn-base
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * $Id: boundsquery.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the bounds query.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <capi/sidx_impl.h>
+
+BoundsQuery::BoundsQuery()
+{
+ m_bounds = new SpatialIndex::Region;
+}
+
+void BoundsQuery::getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext)
+{
+ SpatialIndex::IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(*m_bounds);
+ delete ps;
+
+ hasNext = false;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CountVisitor.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CountVisitor.cc.svn-base
new file mode 100644
index 000000000..2fe7e940c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CountVisitor.cc.svn-base
@@ -0,0 +1,52 @@
+
+/******************************************************************************
+* $Id$
+*
+* Project: libsidx - A C API wrapper around libspatialindex
+* Purpose: C++ objects to implement the count visitor.
+* Author: Leonard Norrgård, leonard.norrgard@refactor.fi
+*
+******************************************************************************
+* Copyright (c) 2010, Leonard Norrgård
+*
+* All rights reserved.
+*
+* This library is free software; you can redistribute it and/or modify it under
+* the terms of the GNU Lesser General Public License as published by the Free
+* Software Foundation; either version 2.1 of the License, or (at your option)
+* any later version.
+
+* This library is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+* details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#include "sidx_impl.h"
+
+CountVisitor::CountVisitor(): nResults(0)
+{
+}
+
+CountVisitor::~CountVisitor()
+{
+
+}
+
+void CountVisitor::visitNode(const SpatialIndex::INode& n)
+{
+
+}
+
+void CountVisitor::visitData(const SpatialIndex::IData& d)
+{
+ nResults += 1;
+}
+
+void CountVisitor::visitData(std::vector<const SpatialIndex::IData*>& v)
+{
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CustomStorage.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CustomStorage.cc.svn-base
new file mode 100644
index 000000000..e35c00e4d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/CustomStorage.cc.svn-base
@@ -0,0 +1,110 @@
+/******************************************************************************
+ * $Id: CustomStorage.cc 1385 2009-06-17 13:45:16Z nitro $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the custom storage manager.
+ * Author: Matthias (nitro)
+ *
+ ******************************************************************************
+ * Copyright (c) 2010, Matthias (nitro)
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "sidx_impl.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+
+IStorageManager* SpatialIndex::StorageManager::returnCustomStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new CustomStorageManager(ps);
+ return sm;
+}
+
+CustomStorageManager::CustomStorageManager(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+ var = ps.getProperty("CustomStorageCallbacks");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PVOID)
+ throw Tools::IllegalArgumentException("CustomStorageManager: Property CustomStorageCallbacks must be Tools::VT_PVOID");
+
+ if (!var.m_val.pvVal)
+ throw Tools::IllegalArgumentException("CustomStorageManager: Property CustomStorageCallbacks must not be 0.");
+
+ // we already checked for validity in IndexProperty_SetCustomStorageCallbacks
+ CustomStorageManagerCallbacks* callbackArray = static_cast<CustomStorageManagerCallbacks*>(var.m_val.pvVal);
+ callbacks = *callbackArray;
+ }
+
+ int errorCode( NoError );
+ if ( callbacks.createCallback ) callbacks.createCallback( callbacks.context, &errorCode );
+ processErrorCode( errorCode, NewPage );
+}
+
+CustomStorageManager::~CustomStorageManager()
+{
+ int errorCode( NoError );
+ if ( callbacks.destroyCallback ) callbacks.destroyCallback( callbacks.context, &errorCode );
+ processErrorCode( errorCode, NewPage );
+}
+
+void CustomStorageManager::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ int errorCode( NoError );
+ if ( callbacks.loadByteArrayCallback ) callbacks.loadByteArrayCallback( callbacks.context, page, &len, data, &errorCode );
+ processErrorCode( errorCode, page );
+}
+
+void CustomStorageManager::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ int errorCode( NoError );
+ if ( callbacks.storeByteArrayCallback ) callbacks.storeByteArrayCallback( callbacks.context, &page, len, data, &errorCode );
+ processErrorCode( errorCode, page );
+}
+
+void CustomStorageManager::deleteByteArray(const id_type page)
+{
+ int errorCode( NoError );
+ if ( callbacks.deleteByteArrayCallback ) callbacks.deleteByteArrayCallback( callbacks.context, page, &errorCode );
+ processErrorCode( errorCode, page );
+}
+
+inline void CustomStorageManager::processErrorCode(int errorCode, const id_type page)
+{
+ switch (errorCode)
+ {
+ case NoError:
+ break;
+
+ case InvalidPageError:
+ throw InvalidPageException( page );
+ break;
+
+ case IllegalStateError:
+ throw Tools::IllegalStateException( "CustomStorageManager: Error in user implementation." );
+ break;
+
+ default:
+ throw Tools::IllegalStateException( "CustomStorageManager: Unknown error." );
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/DataStream.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/DataStream.cc.svn-base
new file mode 100644
index 000000000..d30d70ec8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/DataStream.cc.svn-base
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * $Id: datastream.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the datastream.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+
+DataStream::DataStream(int (*readNext)(SpatialIndex::id_type * id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t** pData, uint32_t *nDataLength)) :m_pNext(0),m_bDoneReading(false)
+{
+ iterfunct = readNext;
+
+ // Read the first one.
+ readData();
+}
+
+DataStream::~DataStream()
+{
+ if (m_pNext != 0) delete m_pNext;
+}
+
+bool DataStream::readData()
+{
+ SpatialIndex::id_type id;
+ double *pMin=0;
+ double *pMax=0;
+ uint32_t nDimension=0;
+ const uint8_t *p_data=0;
+ uint32_t nDataLength=0;
+
+ if (m_bDoneReading == true) {
+ return false;
+ }
+
+ int ret = iterfunct(&id, &pMin, &pMax, &nDimension, &p_data, &nDataLength);
+
+ // The callback should return anything other than 0
+ // when it is done.
+ if (ret != 0)
+ {
+ m_bDoneReading = true;
+ return false;
+ }
+
+ SpatialIndex::Region r = SpatialIndex::Region(pMin, pMax, nDimension);
+ m_pNext = new SpatialIndex::RTree::Data(nDataLength, (byte*)p_data, r, id);
+
+ return true;
+}
+
+
+SpatialIndex::IData* DataStream::getNext()
+{
+ if (m_pNext == 0) return 0;
+
+ SpatialIndex::RTree::Data* ret = m_pNext;
+ m_pNext = 0;
+ readData();
+ return ret;
+}
+
+bool DataStream::hasNext() throw (Tools::NotSupportedException)
+{
+ return (m_pNext != 0);
+}
+
+uint32_t DataStream::size() throw (Tools::NotSupportedException)
+{
+ throw Tools::NotSupportedException("Operation not supported.");
+}
+
+void DataStream::rewind() throw (Tools::NotSupportedException)
+{
+ throw Tools::NotSupportedException("Operation not supported.");
+
+ if (m_pNext != 0)
+ {
+ delete m_pNext;
+ m_pNext = 0;
+ }
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Error.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Error.cc.svn-base
new file mode 100644
index 000000000..19239710b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Error.cc.svn-base
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * $Id: error.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the error object.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+Error::Error(int code, std::string const& message, std::string const& method) :
+ m_code(code),
+ m_message(message),
+ m_method(method)
+{
+}
+
+Error::Error(Error const& other) :
+ m_code(other.m_code),
+ m_message(other.m_message),
+ m_method(other.m_method)
+{
+}
+
+Error& Error::operator=(Error const& rhs)
+{
+ if (&rhs != this)
+ {
+ m_code = rhs.m_code;
+ m_message = rhs.m_message;
+ m_method = rhs.m_method;
+
+ }
+ return *this;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/IdVisitor.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/IdVisitor.cc.svn-base
new file mode 100644
index 000000000..7e0e0b615
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/IdVisitor.cc.svn-base
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * $Id: idvisitor.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the id visitor.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+IdVisitor::IdVisitor(): nResults(0)
+{
+}
+
+IdVisitor::~IdVisitor()
+{
+
+}
+
+void IdVisitor::visitNode(const SpatialIndex::INode& n)
+{
+
+}
+
+void IdVisitor::visitData(const SpatialIndex::IData& d)
+{
+ nResults += 1;
+
+ m_vector.push_back(d.getIdentifier());
+}
+
+void IdVisitor::visitData(std::vector<const SpatialIndex::IData*>& v)
+{
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Index.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Index.cc.svn-base
new file mode 100644
index 000000000..98736043c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Index.cc.svn-base
@@ -0,0 +1,381 @@
+/******************************************************************************
+ * $Id: index.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the index.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+SpatialIndex::ISpatialIndex* Index::CreateIndex()
+{
+ using namespace SpatialIndex;
+
+ ISpatialIndex* index = 0;
+
+ Tools::Variant var;
+
+ if (GetIndexType() == RT_RTree) {
+
+ try {
+ index = RTree::returnRTree( *m_buffer, m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ }
+
+ else if (GetIndexType() == RT_MVRTree) {
+
+ try {
+ index = MVRTree::returnMVRTree( *m_buffer, m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ }
+
+ else if (GetIndexType() == RT_TPRTree) {
+
+ try {
+ index = TPRTree::returnTPRTree( *m_buffer,m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ }
+
+ return index;
+}
+
+
+Index::Index(const Tools::PropertySet& poProperties)
+{
+ Setup();
+
+ m_properties = poProperties;
+
+ Initialize();
+}
+
+
+Index::~Index()
+{
+ if (m_rtree != 0)
+ delete m_rtree;
+ if (m_buffer != 0)
+ delete m_buffer;
+ if (m_storage != 0)
+ delete m_storage;
+
+}
+
+Index::Index( const Tools::PropertySet& poProperties,
+ int (*readNext)(SpatialIndex::id_type *id,
+ double **pMin,
+ double **pMax,
+ uint32_t *nDimension,
+ const uint8_t **pData,
+ uint32_t *nDataLength))
+{
+ using namespace SpatialIndex;
+
+ Setup();
+
+ m_properties = poProperties;
+
+ m_storage = CreateStorage();
+ m_buffer = CreateIndexBuffer(*m_storage);
+
+ DataStream ds(readNext);
+
+ double dFillFactor = 0.7;
+ uint32_t nIdxCapacity = 100;
+ uint32_t nIdxLeafCap = 100;
+ uint32_t nIdxDimension = 2;
+ SpatialIndex::RTree::RTreeVariant eVariant = SpatialIndex::RTree::RV_RSTAR;
+ SpatialIndex::id_type m_IdxIdentifier;
+
+ // Fetch a bunch of properties. We can't bulk load an rtree using merely
+ // properties, we have to use the helper method(s).
+
+ Tools::Variant var;
+ var = m_properties.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE)
+ throw std::runtime_error("Index::Index (streaming):"
+ " Property FillFactor must be Tools::VT_DOUBLE");
+
+ dFillFactor = var.m_val.dblVal;
+ }
+
+ var = m_properties.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property IndexCapacity must be Tools::VT_ULONG");
+
+ nIdxCapacity = var.m_val.ulVal;
+ }
+
+ var = m_properties.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property LeafCapacity must be Tools::VT_ULONG");
+
+ nIdxLeafCap = var.m_val.ulVal;
+ }
+
+ var = m_properties.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property Dimension must be Tools::VT_ULONG");
+
+ nIdxDimension = var.m_val.ulVal;
+ }
+
+ var = m_properties.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property TreeVariant must be Tools::VT_LONG");
+
+ eVariant = static_cast<SpatialIndex::RTree::RTreeVariant>(var.m_val.lVal);
+ }
+
+ var = m_properties.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONGLONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ m_IdxIdentifier = var.m_val.llVal;
+ }
+
+ m_rtree = RTree::createAndBulkLoadNewRTree( SpatialIndex::RTree::BLM_STR,
+ ds,
+ *m_buffer,
+ dFillFactor,
+ nIdxCapacity,
+ nIdxLeafCap,
+ nIdxDimension,
+ eVariant,
+ m_IdxIdentifier);
+}
+
+
+SpatialIndex::StorageManager::IBuffer* Index::CreateIndexBuffer(SpatialIndex::IStorageManager& storage)
+{
+ using namespace SpatialIndex::StorageManager;
+ IBuffer* buffer = 0;
+ try {
+ if ( m_storage == 0 )
+ throw std::runtime_error("Storage was invalid to create index buffer");
+ buffer = returnRandomEvictionsBuffer(storage, m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ return buffer;
+}
+
+
+SpatialIndex::IStorageManager* Index::CreateStorage()
+{
+ using namespace SpatialIndex::StorageManager;
+
+ SpatialIndex::IStorageManager* storage = 0;
+ std::string filename("");
+
+ Tools::Variant var;
+ var = m_properties.getProperty("FileName");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR)
+ throw std::runtime_error("Index::CreateStorage: "
+ "Property FileName must be Tools::VT_PCHAR");
+
+ filename = std::string(var.m_val.pcVal);
+ }
+
+ if (GetIndexStorage() == RT_Disk) {
+ if (filename.empty()) {
+ std::ostringstream os;
+ os << "Spatial Index Error: filename was empty."
+ " Set IndexStorageType to RT_Memory";
+ throw std::runtime_error(os.str());
+ }
+ try {
+ storage = returnDiskStorageManager(m_properties);
+ return storage;
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+
+ } else if (GetIndexStorage() == RT_Memory) {
+
+ try {
+ storage = returnMemoryStorageManager(m_properties);
+ return storage;
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+
+ } else if (GetIndexStorage() == RT_Custom) {
+
+ try {
+ storage = returnCustomStorageManager(m_properties);
+ return storage;
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+
+ }
+ return storage;
+}
+
+
+
+
+void Index::Initialize()
+{
+ m_storage = CreateStorage();
+ m_buffer = CreateIndexBuffer(*m_storage);
+ m_rtree = CreateIndex();
+}
+
+void Index::Setup()
+
+{
+ m_buffer = 0;
+ m_storage = 0;
+ m_rtree = 0;
+}
+
+RTIndexType Index::GetIndexType()
+{
+ Tools::Variant var;
+ var = m_properties.getProperty("IndexType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::GetIndexType: "
+ "Property IndexType must be Tools::VT_ULONG");
+
+ return static_cast<RTIndexType>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ return RT_InvalidIndexType;
+
+}
+void Index::SetIndexType(RTIndexType v)
+{
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = v;
+ m_properties.setProperty("IndexType", var);
+}
+
+RTStorageType Index::GetIndexStorage()
+{
+
+ Tools::Variant var;
+ var = m_properties.getProperty("IndexStorageType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::GetIndexStorage: "
+ "Property IndexStorageType must be Tools::VT_ULONG");
+
+ return static_cast<RTStorageType>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ return RT_InvalidStorageType;
+}
+
+void Index::SetIndexStorage(RTStorageType v)
+{
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = v;
+ m_properties.setProperty("IndexStorageType", var);
+}
+
+RTIndexVariant Index::GetIndexVariant()
+{
+
+ Tools::Variant var;
+ var = m_properties.getProperty("TreeVariant");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::GetIndexVariant: "
+ "Property TreeVariant must be Tools::VT_ULONG");
+
+ return static_cast<RTIndexVariant>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ return RT_InvalidIndexVariant;
+}
+
+void Index::SetIndexVariant(RTStorageType v)
+{
+ using namespace SpatialIndex;
+ Tools::Variant var;
+
+ if (GetIndexType() == RT_RTree) {
+ var.m_val.ulVal = static_cast<RTree::RTreeVariant>(v);
+ m_properties.setProperty("TreeVariant", var);
+ } else if (GetIndexType() == RT_MVRTree) {
+ var.m_val.ulVal = static_cast<MVRTree::MVRTreeVariant>(v);
+ m_properties.setProperty("TreeVariant", var);
+ } else if (GetIndexType() == RT_TPRTree) {
+ var.m_val.ulVal = static_cast<TPRTree::TPRTreeVariant>(v);
+ m_properties.setProperty("TreeVariant", var);
+ }
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/LeafQuery.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/LeafQuery.cc.svn-base
new file mode 100644
index 000000000..0d0998278
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/LeafQuery.cc.svn-base
@@ -0,0 +1,126 @@
+/******************************************************************************
+ * $Id: boundsquery.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement a query of the index's leaves.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <capi/sidx_impl.h>
+
+LeafQuery::LeafQuery()
+{
+
+}
+
+LeafQueryResult get_results(const SpatialIndex::INode* n)
+{
+ LeafQueryResult result (n->getIdentifier());
+
+ SpatialIndex::IShape* ps;
+ n->getShape(&ps);
+ SpatialIndex::Region* pr = dynamic_cast<SpatialIndex::Region*>(ps);
+ std::vector<SpatialIndex::id_type> ids;
+ for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push_back(n->getChildIdentifier(cChild));
+ }
+
+ result.SetIDs(ids);
+ result.SetBounds(pr);
+ delete ps;
+
+ return result;
+}
+void LeafQuery::getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext)
+{
+
+ const SpatialIndex::INode* n = dynamic_cast<const SpatialIndex::INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 0)
+ {
+ for (uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ m_ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (n->isLeaf()) {
+ m_results.push_back(get_results(n));
+ }
+
+ if (! m_ids.empty())
+ {
+ nextEntry = m_ids.front(); m_ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+}
+
+
+std::vector<SpatialIndex::id_type> const& LeafQueryResult::GetIDs() const
+{
+ return ids;
+}
+
+void LeafQueryResult::SetIDs(std::vector<SpatialIndex::id_type>& v)
+{
+ ids.resize(v.size());
+ std::copy(v.begin(), v.end(), ids.begin());
+}
+const SpatialIndex::Region* LeafQueryResult::GetBounds() const
+{
+ return bounds;
+}
+
+void LeafQueryResult::SetBounds(const SpatialIndex::Region* b)
+{
+ bounds = new SpatialIndex::Region(*b);
+}
+
+LeafQueryResult::LeafQueryResult(LeafQueryResult const& other)
+{
+ ids.resize(other.ids.size());
+ std::copy(other.ids.begin(), other.ids.end(), ids.begin());
+ m_id = other.m_id;
+
+ bounds = other.bounds->clone();
+}
+
+LeafQueryResult& LeafQueryResult::operator=(LeafQueryResult const& rhs)
+{
+ if (&rhs != this)
+ {
+ ids.resize(rhs.ids.size());
+ std::copy(rhs.ids.begin(), rhs.ids.end(), ids.begin());
+ m_id = rhs.m_id;
+ bounds = rhs.bounds->clone();
+ }
+ return *this;
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..2c35d4002
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,14 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libsidxc.la
+INCLUDES = -I../../include -I../../include/capi
+libsidxc_la_SOURCES = BoundsQuery.cc \
+ CountVisitor.cc \
+ CustomStorage.cc \
+ DataStream.cc \
+ Error.cc \
+ IdVisitor.cc \
+ Index.cc \
+ LeafQuery.cc \
+ ObjVisitor.cc \
+ sidx_api.cc \
+ Utility.cc
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/ObjVisitor.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/ObjVisitor.cc.svn-base
new file mode 100644
index 000000000..436f7b9a9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/ObjVisitor.cc.svn-base
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * $Id: objvisitor.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+ObjVisitor::ObjVisitor(): nResults(0)
+{
+}
+
+ObjVisitor::~ObjVisitor()
+{
+ std::vector<SpatialIndex::IData*>::iterator it;
+ for (it = m_vector.begin(); it != m_vector.end(); it++) {
+ delete *it;
+ }
+
+}
+
+void ObjVisitor::visitNode(const SpatialIndex::INode& n)
+{
+}
+
+void ObjVisitor::visitData(const SpatialIndex::IData& d)
+{
+
+ SpatialIndex::IData* item = dynamic_cast<SpatialIndex::IData*>(const_cast<SpatialIndex::IData&>(d).clone()) ;
+
+ nResults += 1;
+
+ m_vector.push_back(item);
+}
+
+void ObjVisitor::visitData(std::vector<const SpatialIndex::IData*>& v)
+{
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Utility.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Utility.cc.svn-base
new file mode 100644
index 000000000..e441853c3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/Utility.cc.svn-base
@@ -0,0 +1,150 @@
+/******************************************************************************
+ * $Id: util.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement utilities.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+Tools::PropertySet* GetDefaults()
+{
+ Tools::PropertySet* ps = new Tools::PropertySet;
+
+ Tools::Variant var;
+
+ // Rtree defaults
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 0.7;
+ ps->setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = SpatialIndex::RTree::RV_RSTAR;
+ ps->setProperty("TreeVariant", var);
+
+ // var.m_varType = Tools::VT_LONGLONG;
+ // var.m_val.llVal = 0;
+ // ps->setProperty("IndexIdentifier", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 32;
+ ps->setProperty("NearMinimumOverlapFactor", var);
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 0.4;
+ ps->setProperty("SplitDistributionFactor", var);
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 0.3;
+ ps->setProperty("ReinsertFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 2;
+ ps->setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.bVal = true;
+ ps->setProperty("EnsureTightMBRs", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("IndexPoolCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("LeafPoolCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 1000;
+ ps->setProperty("RegionPoolCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 500;
+ ps->setProperty("PointPoolCapacity", var);
+
+ // horizon for TPRTree
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 20.0;
+ ps->setProperty("Horizon", var);
+
+ // Buffering defaults
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 10;
+ ps->setProperty("Capacity", var);
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.bVal = false;
+ ps->setProperty("WriteThrough", var);
+
+ // Disk Storage Manager defaults
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.bVal = true;
+ ps->setProperty("Overwrite", var);
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>("");
+ ps->setProperty("FileName", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 4096;
+ ps->setProperty("PageSize", var);
+
+ // Our custom properties related to whether
+ // or not we are using a disk or memory storage manager
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = RT_Disk;
+ ps->setProperty("IndexStorageType", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = RT_RTree;
+ ps->setProperty("IndexType", var);
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>("dat");
+ ps->setProperty("FileNameDat", var);
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>("idx");
+ ps->setProperty("FileNameIdx", var);
+
+ // Custom storage manager properties
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.pcVal = 0;
+ ps->setProperty("CustomStorageCallbacksSize", var);
+
+ var.m_varType = Tools::VT_PVOID;
+ var.m_val.pcVal = 0;
+ ps->setProperty("CustomStorageCallbacks", var);
+
+ return ps;
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/sidx_api.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/sidx_api.cc.svn-base
new file mode 100644
index 000000000..e2b24c98f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/.svn/text-base/sidx_api.cc.svn-base
@@ -0,0 +1,2518 @@
+/******************************************************************************
+ * $Id: sidx_api.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C API wrapper implementation
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <cmath>
+#include <limits>
+#include "sidx_impl.h"
+
+static std::stack<Error> errors;
+
+#define VALIDATE_POINTER0(ptr, func) \
+ do { if( NULL == ptr ) { \
+ RTError const ret = RT_Failure; \
+ std::ostringstream msg; \
+ msg << "Pointer \'" << #ptr << "\' is NULL in \'" << (func) <<"\'."; \
+ std::string message(msg.str()); \
+ Error_PushError( ret, message.c_str(), (func)); \
+ return; \
+ }} while(0)
+
+#define VALIDATE_POINTER1(ptr, func, rc) \
+ do { if( NULL == ptr ) { \
+ RTError const ret = RT_Failure; \
+ std::ostringstream msg; \
+ msg << "Pointer \'" << #ptr << "\' is NULL in \'" << (func) <<"\'."; \
+ std::string message(msg.str()); \
+ Error_PushError( ret, message.c_str(), (func)); \
+ return (rc); \
+ }} while(0)
+
+IDX_C_START
+
+SIDX_C_DLL void Error_Reset(void) {
+ if (errors.empty()) return;
+ for (std::size_t i=0;i<errors.size();i++) errors.pop();
+}
+
+SIDX_C_DLL void Error_Pop(void) {
+ if (errors.empty()) return;
+ errors.pop();
+}
+
+SIDX_C_DLL int Error_GetLastErrorNum(void){
+ if (errors.empty())
+ return 0;
+ else {
+ Error err = errors.top();
+ return err.GetCode();
+ }
+}
+
+SIDX_C_DLL char* Error_GetLastErrorMsg(void){
+ if (errors.empty())
+ return NULL;
+ else {
+ Error err = errors.top();
+ return STRDUP(err.GetMessage());
+ }
+}
+
+SIDX_C_DLL char* Error_GetLastErrorMethod(void){
+ if (errors.empty())
+ return NULL;
+ else {
+ Error err = errors.top();
+ return STRDUP(err.GetMethod());
+ }
+}
+
+SIDX_C_DLL void Error_PushError(int code, const char *message, const char *method) {
+ Error err = Error(code, std::string(message), std::string(method));
+ errors.push(err);
+}
+
+SIDX_C_DLL int Error_GetErrorCount(void) {
+ return static_cast<int>(errors.size());
+}
+
+SIDX_C_DLL IndexH Index_Create(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "Index_Create", NULL);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try {
+ return (IndexH) new Index(*prop);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Create");
+ return NULL;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Create");
+ return NULL;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Create");
+ return NULL;
+ }
+ return NULL;
+}
+
+SIDX_C_DLL IndexH Index_CreateWithStream( IndexPropertyH hProp,
+ int (*readNext)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength)
+ )
+{
+ VALIDATE_POINTER1(hProp, "Index_CreateWithStream", NULL);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+
+ try {
+ return (IndexH) new Index(*prop, readNext);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_CreateWithStream");
+ return NULL;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_CreateWithStream");
+ return NULL;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_CreateWithStream");
+ return NULL;
+ }
+ return NULL;
+}
+
+SIDX_C_DLL void Index_Destroy(IndexH index)
+{
+ VALIDATE_POINTER0(index, "Index_Destroy");
+ Index* idx = (Index*) index;
+ if (idx) delete idx;
+}
+
+SIDX_C_DLL RTError Index_DeleteData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension)
+{
+ VALIDATE_POINTER1(index, "Index_DeleteData", RT_Failure);
+
+ Index* idx = static_cast<Index*>(index);
+
+ try {
+ idx->index().deleteData(SpatialIndex::Region(pdMin, pdMax, nDimension), id);
+ return RT_None;
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_DeleteData");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_DeleteData");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_DeleteData");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_InsertData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ const uint8_t* pData,
+ uint32_t nDataLength)
+{
+ VALIDATE_POINTER1(index, "Index_InsertData", RT_Failure);
+
+ Index* idx = static_cast<Index*>(index);
+
+ // Test the data and check for the case when minx == maxx, miny == maxy
+ // and minz == maxz. In that case, we will insert a SpatialIndex::Point
+ // instead of a SpatialIndex::Region
+
+ bool isPoint = false;
+ SpatialIndex::IShape* shape = 0;
+ double const epsilon = std::numeric_limits<double>::epsilon();
+
+ double length(0);
+ for (uint32_t i = 0; i < nDimension; ++i) {
+ double delta = pdMin[i] - pdMax[i];
+ length += std::fabs(delta);
+ }
+
+ if (length <= epsilon) {
+ isPoint = true;
+ }
+
+ if (isPoint == true) {
+ shape = new SpatialIndex::Point(pdMin, nDimension);
+ } else {
+ shape = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ }
+ try {
+ idx->index().insertData(nDataLength,
+ pData,
+ *shape,
+ id);
+
+ delete shape;
+ return RT_None;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_InsertData");
+ delete shape;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_InsertData");
+ delete shape;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_InsertData");
+ delete shape;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_Intersects_obj( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_Intersects_obj", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ ObjVisitor* visitor = new ObjVisitor;
+ try {
+ SpatialIndex::Region* r = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ idx->index().intersectsWithQuery( *r,
+ *visitor);
+
+ *items = (SpatialIndex::IData**) malloc (visitor->GetResultCount() * sizeof(SpatialIndex::IData*));
+
+ std::vector<SpatialIndex::IData*>& results = visitor->GetResults();
+
+ // copy the Items into the newly allocated item array
+ // we need to make sure to copy the actual Item instead
+ // of just the pointers, as the visitor will nuke them
+ // upon ~
+ for (uint32_t i=0; i < visitor->GetResultCount(); ++i)
+ {
+ SpatialIndex::IData* result =results[i];
+ (*items)[i] = dynamic_cast<SpatialIndex::IData*>(result->clone());
+
+ }
+ *nResults = visitor->GetResultCount();
+
+ delete r;
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Intersects_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Intersects_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Intersects_obj");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_Intersects_id( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** ids,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_Intersects_id", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ IdVisitor* visitor = new IdVisitor;
+ try {
+ SpatialIndex::Region* r = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ idx->index().intersectsWithQuery( *r,
+ *visitor);
+
+ *nResults = visitor->GetResultCount();
+
+ *ids = (uint64_t*) malloc (*nResults * sizeof(uint64_t));
+
+ std::vector<uint64_t>& results = visitor->GetResults();
+
+ for (uint32_t i=0; i < *nResults; ++i)
+ {
+ (*ids)[i] = results[i];
+
+ }
+
+ delete r;
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Intersects_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Intersects_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Intersects_id");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_Intersects_count( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_Intersects_count", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ CountVisitor* visitor = new CountVisitor;
+ try {
+ SpatialIndex::Region* r = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ idx->index().intersectsWithQuery( *r,
+ *visitor);
+
+ *nResults = visitor->GetResultCount();
+
+ delete r;
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Intersects_count");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Intersects_count");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Intersects_count");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_NearestNeighbors_id(IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** ids,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_NearestNeighbors_id", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ IdVisitor* visitor = new IdVisitor;
+
+ try {
+ idx->index().nearestNeighborQuery( *nResults,
+ SpatialIndex::Region(pdMin, pdMax, nDimension),
+ *visitor);
+
+ *ids = (uint64_t*) malloc (visitor->GetResultCount() * sizeof(uint64_t));
+
+ std::vector<uint64_t>& results = visitor->GetResults();
+
+ *nResults = results.size();
+
+ for (uint32_t i=0; i < *nResults; ++i)
+ {
+ (*ids)[i] = results[i];
+
+ }
+
+
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_NearestNeighbors_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_NearestNeighbors_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_NearestNeighbors_id");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_NearestNeighbors_obj(IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_NearestNeighbors_obj", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ ObjVisitor* visitor = new ObjVisitor;
+ try {
+ idx->index().nearestNeighborQuery( *nResults,
+ SpatialIndex::Region(pdMin, pdMax, nDimension),
+ *visitor);
+
+
+ *items = (SpatialIndex::IData**) malloc (visitor->GetResultCount() * sizeof(Item*));
+
+ std::vector<SpatialIndex::IData*> results = visitor->GetResults();
+ *nResults = results.size();
+
+ // copy the Items into the newly allocated item array
+ // we need to make sure to copy the actual Item instead
+ // of just the pointers, as the visitor will nuke them
+ // upon ~
+ for (uint32_t i=0; i < visitor->GetResultCount(); ++i)
+ {
+ SpatialIndex::IData* result = results[i];
+ (*items)[i] = dynamic_cast<SpatialIndex::IData*>(result->clone());
+
+ }
+
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_NearestNeighbors_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_NearestNeighbors_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_NearestNeighbors_obj");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_GetBounds( IndexH index,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension)
+{
+ VALIDATE_POINTER1(index, "Index_GetBounds", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ BoundsQuery* query = new BoundsQuery;
+
+ try {
+ idx->index().queryStrategy( *query);
+
+ const SpatialIndex::Region* bounds = query->GetBounds();
+ if (bounds == 0) {
+ *nDimension = 0;
+ delete query;
+ return RT_None;
+ }
+
+ *nDimension =bounds->getDimension();
+
+ *ppdMin = (double*) malloc (*nDimension * sizeof(double));
+ *ppdMax = (double*) malloc (*nDimension * sizeof(double));
+
+ for (uint32_t i=0; i< *nDimension; ++i) {
+ (*ppdMin)[i] = bounds->getLow(i);
+ (*ppdMax)[i] = bounds->getHigh(i);
+ }
+
+ delete query;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_GetBounds");
+ delete query;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_GetBounds");
+ delete query;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_GetBounds");
+ delete query;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t Index_IsValid(IndexH index)
+{
+ VALIDATE_POINTER1(index, "Index_IsValid", 0);
+ Index* idx = static_cast<Index*>(index);
+ return static_cast<uint32_t>(idx->index().isIndexValid());
+}
+
+SIDX_C_DLL IndexPropertyH Index_GetProperties(IndexH index)
+{
+ VALIDATE_POINTER1(index, "Index_GetProperties", 0);
+ Index* idx = static_cast<Index*>(index);
+ Tools::PropertySet* ps = new Tools::PropertySet;
+
+ idx->index().getIndexProperties(*ps);
+ return (IndexPropertyH)ps;
+}
+
+SIDX_C_DLL IndexPropertyH Index_ClearBuffer(IndexH index)
+{
+ VALIDATE_POINTER1(index, "Index_ClearBuffer", 0);
+ Index* idx = static_cast<Index*>(index);
+ idx->buffer().clear();
+}
+
+SIDX_C_DLL void Index_DestroyObjResults(IndexItemH* results, uint32_t nResults)
+{
+ VALIDATE_POINTER0(results, "Index_DestroyObjResults");
+ SpatialIndex::IData* it;
+ for (uint32_t i=0; i< nResults; ++i) {
+ if (results[i] != NULL) {
+ it = static_cast<SpatialIndex::IData*>(results[i]);
+ if (it != 0)
+ delete it;
+ }
+ }
+
+ std::free(results);
+}
+
+
+SIDX_C_DLL void Index_Free(void* results)
+{
+ VALIDATE_POINTER0(results, "Index_Free");
+ if (results != 0)
+ std::free(results);
+}
+
+SIDX_C_DLL RTError Index_GetLeaves( IndexH index,
+ uint32_t* nNumLeafNodes,
+ uint32_t** nLeafSizes,
+ int64_t** nLeafIDs,
+ int64_t*** nLeafChildIDs,
+ double*** pppdMin,
+ double*** pppdMax,
+ uint32_t* nDimension)
+{
+ VALIDATE_POINTER1(index, "Index_GetLeaves", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ std::vector<LeafQueryResult>::const_iterator i;
+ LeafQuery* query = new LeafQuery;
+
+ // Fetch the dimensionality of the index
+ Tools::PropertySet ps;
+ idx->index().getIndexProperties(ps);
+
+ Tools::Variant var;
+ var = ps.getProperty("Dimension");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property Dimension must be Tools::VT_ULONG",
+ "Index_GetLeaves");
+ return RT_Failure;
+ }
+ }
+
+ *nDimension = var.m_val.ulVal;
+
+ try {
+ idx->index().queryStrategy( *query);
+
+ const std::vector<LeafQueryResult>& results = query->GetResults();
+
+ *nNumLeafNodes = results.size();
+
+ *nLeafSizes = (uint32_t*) malloc (*nNumLeafNodes * sizeof(uint32_t));
+ *nLeafIDs = (int64_t*) malloc (*nNumLeafNodes * sizeof(int64_t));
+
+ *nLeafChildIDs = (int64_t**) malloc(*nNumLeafNodes * sizeof(int64_t*));
+ *pppdMin = (double**) malloc (*nNumLeafNodes * sizeof(double*));
+ *pppdMax = (double**) malloc (*nNumLeafNodes * sizeof(double*));
+
+ uint32_t k=0;
+ for (i = results.begin(); i != results.end(); ++i)
+ {
+ std::vector<SpatialIndex::id_type> const& ids = (*i).GetIDs();
+ const SpatialIndex::Region* b = (*i).GetBounds();
+
+ (*nLeafIDs)[k] = (*i).getIdentifier();
+ (*nLeafSizes)[k] = ids.size();
+
+ (*nLeafChildIDs)[k] = (int64_t*) malloc( (*nLeafSizes)[k] * sizeof(int64_t));
+ (*pppdMin)[k] = (double*) malloc ( (*nLeafSizes)[k] * sizeof(double));
+ (*pppdMax)[k] = (double*) malloc ( (*nLeafSizes)[k] * sizeof(double));
+ for (uint32_t i=0; i< *nDimension; ++i) {
+ (*pppdMin)[k][i] = b->getLow(i);
+ (*pppdMax)[k][i] = b->getHigh(i);
+ }
+ for (uint32_t cChild = 0; cChild < ids.size(); cChild++)
+ {
+ (*nLeafChildIDs)[k][cChild] = ids[cChild];
+ }
+ ++k;
+ }
+
+
+ delete query;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_GetLeaves");
+ delete query;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_GetLeaves");
+ delete query;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_GetLeaves");
+ delete query;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+
+SIDX_C_DLL void IndexItem_Destroy(IndexItemH item)
+{
+ VALIDATE_POINTER0(item, "IndexItem_Destroy");
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+ if (it != 0) delete it;
+}
+
+SIDX_C_DLL RTError IndexItem_GetData( IndexItemH item,
+ uint8_t** data,
+ uint64_t* length)
+{
+ VALIDATE_POINTER1(item, "IndexItem_GetData", RT_Failure);
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+ uint8_t* p_data;
+ uint32_t* l= new uint32_t;
+
+ it->getData(*l,&p_data);
+ *length = (uint64_t)*l;
+ *data = (uint8_t*) malloc (*length * sizeof(uint8_t));
+
+ memcpy(*data, p_data, *length);
+ delete[] p_data;
+ delete l;
+ return RT_None;
+
+}
+
+SIDX_C_DLL uint64_t IndexItem_GetID(IndexItemH item)
+{
+ VALIDATE_POINTER1(item, "IndexItem_GetID",0);
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+ uint64_t value = it->getIdentifier();
+ return value;
+}
+
+SIDX_C_DLL RTError IndexItem_GetBounds( IndexItemH item,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension)
+{
+ VALIDATE_POINTER1(item, "IndexItem_GetBounds", RT_Failure);
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+
+ SpatialIndex::IShape* s;
+ it->getShape(&s);
+
+ SpatialIndex::Region *bounds = new SpatialIndex::Region();
+ s->getMBR(*bounds);
+
+ if (bounds == 0) {
+ *nDimension = 0;
+ delete bounds;
+ delete s;
+ return RT_None;
+ }
+ *nDimension = bounds->getDimension();
+
+ *ppdMin = (double*) malloc (*nDimension * sizeof(double));
+ *ppdMax = (double*) malloc (*nDimension * sizeof(double));
+
+ if (ppdMin == NULL || ppdMax == NULL) {
+ Error_PushError(RT_Failure,
+ "Unable to allocation bounds array(s)",
+ "IndexItem_GetBounds");
+ return RT_Failure;
+ }
+
+ for (uint32_t i=0; i< *nDimension; ++i) {
+ (*ppdMin)[i] = bounds->getLow(i);
+ (*ppdMax)[i] = bounds->getHigh(i);
+ }
+ delete bounds;
+ delete s;
+ return RT_None;
+}
+SIDX_C_DLL IndexPropertyH IndexProperty_Create()
+{
+ Tools::PropertySet* ps = GetDefaults();
+ Tools::Variant var;
+ return (IndexPropertyH)ps;
+}
+
+SIDX_C_DLL void IndexProperty_Destroy(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER0(hProp, "IndexProperty_Destroy");
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+ if (prop != 0) delete prop;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexType(IndexPropertyH hProp,
+ RTIndexType value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexType", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (!(value == RT_RTree || value == RT_MVRTree || value == RT_TPRTree)) {
+ throw std::runtime_error("Inputted value is not a valid index type");
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexType", var);
+
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexType");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexType");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexType");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTIndexType IndexProperty_GetIndexType(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexType", RT_InvalidIndexType);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexType must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexType");
+ return RT_InvalidIndexType;
+ }
+ return (RTIndexType) var.m_val.ulVal;
+ }
+
+ Error_PushError(RT_Failure,
+ "Property IndexType was empty",
+ "IndexProperty_GetIndexType");
+ return RT_InvalidIndexType;
+
+}
+
+SIDX_C_DLL RTError IndexProperty_SetDimension(IndexPropertyH hProp, uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetDimension", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("Dimension", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetDimension");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetDimension");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetDimension");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetDimension(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetDimension", RT_InvalidIndexType);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Dimension");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexType must be Tools::VT_ULONG",
+ "IndexProperty_GetDimension");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // A zero dimension index is invalid.
+ Error_PushError(RT_Failure,
+ "Property Dimension was empty",
+ "IndexProperty_GetDimension");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexVariant( IndexPropertyH hProp,
+ RTIndexVariant value)
+{
+ using namespace SpatialIndex;
+
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexVariant", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+
+ try
+ {
+
+ if (!(value == RT_Linear || value == RT_Quadratic || value == RT_Star)) {
+ throw std::runtime_error("Inputted value is not a valid index variant");
+ }
+
+ var.m_varType = Tools::VT_LONG;
+ RTIndexType type = IndexProperty_GetIndexType(hProp);
+ if (type == RT_InvalidIndexType ) {
+ Error_PushError(RT_Failure,
+ "Index type is not properly set",
+ "IndexProperty_SetIndexVariant");
+ return RT_Failure;
+ }
+ if (type == RT_RTree) {
+ var.m_val.lVal = static_cast<RTree::RTreeVariant>(value);
+ prop->setProperty("TreeVariant", var);
+ } else if (type == RT_MVRTree) {
+ var.m_val.lVal = static_cast<MVRTree::MVRTreeVariant>(value);
+ prop->setProperty("TreeVariant", var);
+ } else if (type == RT_TPRTree) {
+ var.m_val.lVal = static_cast<TPRTree::TPRTreeVariant>(value);
+ prop->setProperty("TreeVariant", var);
+ }
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexVariant");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTIndexVariant IndexProperty_GetIndexVariant(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_GetIndexVariant",
+ RT_InvalidIndexVariant);
+
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("TreeVariant");
+
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexVariant must be Tools::VT_LONG",
+ "IndexProperty_GetIndexVariant");
+ return RT_InvalidIndexVariant;
+ }
+
+ return static_cast<RTIndexVariant>(var.m_val.lVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ Error_PushError(RT_Failure,
+ "Property IndexVariant was empty",
+ "IndexProperty_GetIndexVariant");
+ return RT_InvalidIndexVariant;
+
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexStorage( IndexPropertyH hProp,
+ RTStorageType value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexStorage", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (!(value == RT_Disk || value == RT_Memory || value == RT_Custom)) {
+ throw std::runtime_error("Inputted value is not a valid index storage type");
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexStorageType", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexStorage");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexStorage");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexStorage");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTStorageType IndexProperty_GetIndexStorage(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_GetIndexStorage",
+ RT_InvalidStorageType);
+
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexStorageType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexStorage must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexStorage");
+ return RT_InvalidStorageType;
+ }
+
+ return static_cast<RTStorageType>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ Error_PushError(RT_Failure,
+ "Property IndexStorage was empty",
+ "IndexProperty_GetIndexStorage");
+ return RT_InvalidStorageType;
+
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetIndexCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property IndexCapacity was empty",
+ "IndexProperty_GetIndexCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetLeafCapacity( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetLeafCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("LeafCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetLeafCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetLeafCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetLeafCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetLeafCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetLeafCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("LeafCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property LeafCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetLeafCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property LeafCapacity was empty",
+ "IndexProperty_GetLeafCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetPagesize( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetPagesize", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("PageSize", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetPagesize");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetPagesize");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetPagesize");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetPagesize(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetPagesize", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("PageSize");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property PageSize must be Tools::VT_ULONG",
+ "IndexProperty_GetPagesize");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property PageSize was empty",
+ "IndexProperty_GetPagesize");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetLeafPoolCapacity( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetLeafPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("LeafPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetLeafPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetLeafPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetLeafPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetLeafPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetLeafPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("LeafPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property LeafPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetLeafPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property LeafPoolCapacity was empty",
+ "IndexProperty_GetLeafPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexPoolCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetIndexPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property IndexPoolCapacity was empty",
+ "IndexProperty_GetIndexPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetRegionPoolCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetRegionPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("RegionPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetRegionPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetRegionPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetRegionPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetRegionPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetRegionPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("RegionPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property RegionPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetRegionPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property RegionPoolCapacity was empty",
+ "IndexProperty_GetRegionPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetPointPoolCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetPointPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("PointPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetPointPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetPointPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetPointPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetPointPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetPointPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("PointPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property PointPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetPointPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property PointPoolCapacity was empty",
+ "IndexProperty_GetPointPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetNearMinimumOverlapFactor( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetNearMinimumOverlapFactor",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("NearMinimumOverlapFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetNearMinimumOverlapFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetNearMinimumOverlapFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetNearMinimumOverlapFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetNearMinimumOverlapFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetNearMinimumOverlapFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("NearMinimumOverlapFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property NearMinimumOverlapFactor must be Tools::VT_ULONG",
+ "IndexProperty_GetNearMinimumOverlapFactor");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property NearMinimumOverlapFactor was empty",
+ "IndexProperty_GetNearMinimumOverlapFactor");
+ return 0;
+}
+
+
+SIDX_C_DLL RTError IndexProperty_SetBufferingCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetBufferingCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("Capacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetBufferingCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetBufferingCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetBufferingCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetBufferingCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetBufferingCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Capacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property Capacity must be Tools::VT_ULONG",
+ "IndexProperty_GetBufferingCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property Capacity was empty",
+ "IndexProperty_GetBufferingCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetEnsureTightMBRs( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetEnsureTightMBRs", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (value > 1 ) {
+ Error_PushError(RT_Failure,
+ "EnsureTightMBRs is a boolean value and must be 1 or 0",
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = (bool)value;
+ prop->setProperty("EnsureTightMBRs", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetEnsureTightMBRs(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetEnsureTightMBRs", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("EnsureTightMBRs");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) {
+ Error_PushError(RT_Failure,
+ "Property EnsureTightMBRs must be Tools::VT_BOOL",
+ "IndexProperty_GetEnsureTightMBRs");
+ return 0;
+ }
+
+ return var.m_val.blVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property EnsureTightMBRs was empty",
+ "IndexProperty_GetEnsureTightMBRs");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetWriteThrough(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetWriteThrough", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (value > 1 ) {
+ Error_PushError(RT_Failure,
+ "WriteThrough is a boolean value and must be 1 or 0",
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = value;
+ prop->setProperty("WriteThrough", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetWriteThrough(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetWriteThrough", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("WriteThrough");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) {
+ Error_PushError(RT_Failure,
+ "Property WriteThrough must be Tools::VT_BOOL",
+ "IndexProperty_GetWriteThrough");
+ return 0;
+ }
+
+ return var.m_val.blVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property WriteThrough was empty",
+ "IndexProperty_GetWriteThrough");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetOverwrite(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetOverwrite", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (value > 1 ) {
+ Error_PushError(RT_Failure,
+ "Overwrite is a boolean value and must be 1 or 0",
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = value;
+ prop->setProperty("Overwrite", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetOverwrite(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetOverwrite", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Overwrite");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) {
+ Error_PushError(RT_Failure,
+ "Property Overwrite must be Tools::VT_BOOL",
+ "IndexProperty_GetOverwrite");
+ return 0;
+ }
+
+ return var.m_val.blVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property Overwrite was empty",
+ "IndexProperty_GetOverwrite");
+ return 0;
+}
+
+
+SIDX_C_DLL RTError IndexProperty_SetFillFactor( IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetFillFactor", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("FillFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFillFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFillFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFillFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetFillFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFillFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FillFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property FillFactor must be Tools::VT_DOUBLE",
+ "IndexProperty_GetFillFactor");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FillFactor was empty",
+ "IndexProperty_GetFillFactor");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetSplitDistributionFactor( IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetSplitDistributionFactor",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("SplitDistributionFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetSplitDistributionFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetSplitDistributionFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetSplitDistributionFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetSplitDistributionFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetSplitDistributionFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("SplitDistributionFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property SplitDistributionFactor must be Tools::VT_DOUBLE",
+ "IndexProperty_GetSplitDistributionFactor");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property SplitDistributionFactor was empty",
+ "IndexProperty_GetSplitDistributionFactor");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetTPRHorizon(IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetTPRHorizon",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("Horizon", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetTPRHorizon");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetTPRHorizon");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetTPRHorizon");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetTPRHorizon(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetTPRHorizon", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Horizon");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property Horizon must be Tools::VT_DOUBLE",
+ "IndexProperty_GetTPRHorizon");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property Horizon was empty",
+ "IndexProperty_GetTPRHorizon");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetReinsertFactor( IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetReinsertFactor",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("ReinsertFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetReinsertFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetReinsertFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetReinsertFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetReinsertFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetReinsertFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("ReinsertFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property ReinsertFactor must be Tools::VT_DOUBLE",
+ "IndexProperty_GetReinsertFactor");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property ReinsertFactor was empty",
+ "IndexProperty_GetReinsertFactor");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetFileName( IndexPropertyH hProp,
+ const char* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetFileName",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = STRDUP(value); // not sure if we should copy here
+ prop->setProperty("FileName", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFileName");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFileName");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFileName");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL char* IndexProperty_GetFileName(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFileName", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FileName");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR) {
+ Error_PushError(RT_Failure,
+ "Property FileName must be Tools::VT_PCHAR",
+ "IndexProperty_GetFileName");
+ return NULL;
+ }
+
+ return STRDUP(var.m_val.pcVal);
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FileName was empty",
+ "IndexProperty_GetFileName");
+ return NULL;
+}
+
+
+SIDX_C_DLL RTError IndexProperty_SetFileNameExtensionDat( IndexPropertyH hProp,
+ const char* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetFileNameExtensionDat",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = STRDUP(value); // not sure if we should copy here
+ prop->setProperty("FileNameDat", var);
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFileNameExtensionDat");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFileNameExtensionDat");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFileNameExtensionDat");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL char* IndexProperty_GetFileNameExtensionDat(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFileNameExtensionDat", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FileNameDat");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR) {
+ Error_PushError(RT_Failure,
+ "Property FileNameDat must be Tools::VT_PCHAR",
+ "IndexProperty_GetFileNameExtensionDat");
+ return NULL;
+ }
+
+ return STRDUP(var.m_val.pcVal);
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FileNameDat was empty",
+ "IndexProperty_GetFileNameExtensionDat");
+ return NULL;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetFileNameExtensionIdx( IndexPropertyH hProp,
+ const char* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetFileNameExtensionIdx",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = STRDUP(value); // not sure if we should copy here
+ prop->setProperty("FileNameIdx", var);
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFileNameExtensionIdx");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFileNameExtensionIdx");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFileNameExtensionIdx");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL char* IndexProperty_GetFileNameExtensionIdx(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFileNameExtensionIdx", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FileNameIdx");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR) {
+ Error_PushError(RT_Failure,
+ "Property FileNameIdx must be Tools::VT_PCHAR",
+ "IndexProperty_GetFileNameExtensionIdx");
+ return NULL;
+ }
+
+ return STRDUP(var.m_val.pcVal);
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FileNameIdx was empty",
+ "IndexProperty_GetFileNameExtensionIdx");
+ return NULL;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetCustomStorageCallbacksSize(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetCustomStorageCallbacksSize", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("CustomStorageCallbacksSize", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetCustomStorageCallbacksSize");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetCustomStorageCallbacksSize");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetCustomStorageCallbacksSize");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetCustomStorageCallbacksSize(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetCustomStorageCallbacksSize", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("CustomStorageCallbacksSize");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacksSize must be Tools::VT_ULONG",
+ "IndexProperty_GetCustomStorageCallbacksSize");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacksSize was empty",
+ "IndexProperty_GetCustomStorageCallbacksSize");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetCustomStorageCallbacks( IndexPropertyH hProp,
+ const void* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetCustomStorageCallbacks",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ // check if the CustomStorageCallbacksSize is alright, so we can make a copy of the passed in structure
+ Tools::Variant varSize;
+ varSize = prop->getProperty("CustomStorageCallbacksSize");
+ if ( varSize.m_val.ulVal != sizeof(SpatialIndex::StorageManager::CustomStorageManagerCallbacks) )
+ {
+ std::ostringstream ss;
+ ss << "The supplied storage callbacks size is wrong, expected "
+ << sizeof(SpatialIndex::StorageManager::CustomStorageManagerCallbacks)
+ << ", got " << varSize.m_val.ulVal;
+ Error_PushError(RT_Failure,
+ ss.str().c_str(),
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ }
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PVOID;
+ var.m_val.pvVal = value ?
+ new SpatialIndex::StorageManager::CustomStorageManagerCallbacks(
+ *static_cast<const SpatialIndex::StorageManager::CustomStorageManagerCallbacks*>(value)
+ )
+ : 0;
+ prop->setProperty("CustomStorageCallbacks", var);
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL void* IndexProperty_GetCustomStorageCallbacks(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetCustomStorageCallbacks", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("CustomStorageCallbacks");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PVOID) {
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacks must be Tools::VT_PVOID",
+ "IndexProperty_GetCustomStorageCallbacks");
+ return NULL;
+ }
+
+ return var.m_val.pvVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacks was empty",
+ "IndexProperty_GetCustomStorageCallbacks");
+ return NULL;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexID(IndexPropertyH hProp,
+ int64_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexID", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = value;
+ prop->setProperty("IndexIdentifier", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexID");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexID");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexID");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL int64_t IndexProperty_GetIndexID(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexID", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexIdentifier");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONGLONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexIdentifier must be Tools::VT_LONGLONG",
+ "IndexProperty_GetIndexID");
+ return 0;
+ }
+
+ return var.m_val.llVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property IndexIdentifier was empty",
+ "IndexProperty_GetIndexID");
+ return 0;
+}
+
+SIDX_C_DLL void* SIDX_NewBuffer(size_t length)
+{
+ return new char[length];
+}
+
+SIDX_C_DLL void SIDX_DeleteBuffer(void* buffer)
+{
+ delete []buffer;
+}
+
+
+SIDX_C_DLL char* SIDX_Version()
+{
+
+ std::ostringstream ot;
+
+#ifdef SIDX_RELEASE_NAME
+ ot << SIDX_RELEASE_NAME;
+#else
+ ot << "1.3.2";
+#endif
+
+ std::string out(ot.str());
+ return STRDUP(out.c_str());
+
+}
+IDX_C_END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/BoundsQuery.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/BoundsQuery.cc
new file mode 100644
index 000000000..a7cedb2c4
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/BoundsQuery.cc
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * $Id: boundsquery.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the bounds query.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <capi/sidx_impl.h>
+
+BoundsQuery::BoundsQuery()
+{
+ m_bounds = new SpatialIndex::Region;
+}
+
+void BoundsQuery::getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext)
+{
+ SpatialIndex::IShape* ps;
+ entry.getShape(&ps);
+ ps->getMBR(*m_bounds);
+ delete ps;
+
+ hasNext = false;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/CountVisitor.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/CountVisitor.cc
new file mode 100644
index 000000000..2fe7e940c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/CountVisitor.cc
@@ -0,0 +1,52 @@
+
+/******************************************************************************
+* $Id$
+*
+* Project: libsidx - A C API wrapper around libspatialindex
+* Purpose: C++ objects to implement the count visitor.
+* Author: Leonard Norrgård, leonard.norrgard@refactor.fi
+*
+******************************************************************************
+* Copyright (c) 2010, Leonard Norrgård
+*
+* All rights reserved.
+*
+* This library is free software; you can redistribute it and/or modify it under
+* the terms of the GNU Lesser General Public License as published by the Free
+* Software Foundation; either version 2.1 of the License, or (at your option)
+* any later version.
+
+* This library is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+* details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+****************************************************************************/
+
+#include "sidx_impl.h"
+
+CountVisitor::CountVisitor(): nResults(0)
+{
+}
+
+CountVisitor::~CountVisitor()
+{
+
+}
+
+void CountVisitor::visitNode(const SpatialIndex::INode& n)
+{
+
+}
+
+void CountVisitor::visitData(const SpatialIndex::IData& d)
+{
+ nResults += 1;
+}
+
+void CountVisitor::visitData(std::vector<const SpatialIndex::IData*>& v)
+{
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/CustomStorage.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/CustomStorage.cc
new file mode 100644
index 000000000..e35c00e4d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/CustomStorage.cc
@@ -0,0 +1,110 @@
+/******************************************************************************
+ * $Id: CustomStorage.cc 1385 2009-06-17 13:45:16Z nitro $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ object declarations to implement the custom storage manager.
+ * Author: Matthias (nitro)
+ *
+ ******************************************************************************
+ * Copyright (c) 2010, Matthias (nitro)
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "sidx_impl.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+
+IStorageManager* SpatialIndex::StorageManager::returnCustomStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new CustomStorageManager(ps);
+ return sm;
+}
+
+CustomStorageManager::CustomStorageManager(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+ var = ps.getProperty("CustomStorageCallbacks");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PVOID)
+ throw Tools::IllegalArgumentException("CustomStorageManager: Property CustomStorageCallbacks must be Tools::VT_PVOID");
+
+ if (!var.m_val.pvVal)
+ throw Tools::IllegalArgumentException("CustomStorageManager: Property CustomStorageCallbacks must not be 0.");
+
+ // we already checked for validity in IndexProperty_SetCustomStorageCallbacks
+ CustomStorageManagerCallbacks* callbackArray = static_cast<CustomStorageManagerCallbacks*>(var.m_val.pvVal);
+ callbacks = *callbackArray;
+ }
+
+ int errorCode( NoError );
+ if ( callbacks.createCallback ) callbacks.createCallback( callbacks.context, &errorCode );
+ processErrorCode( errorCode, NewPage );
+}
+
+CustomStorageManager::~CustomStorageManager()
+{
+ int errorCode( NoError );
+ if ( callbacks.destroyCallback ) callbacks.destroyCallback( callbacks.context, &errorCode );
+ processErrorCode( errorCode, NewPage );
+}
+
+void CustomStorageManager::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ int errorCode( NoError );
+ if ( callbacks.loadByteArrayCallback ) callbacks.loadByteArrayCallback( callbacks.context, page, &len, data, &errorCode );
+ processErrorCode( errorCode, page );
+}
+
+void CustomStorageManager::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ int errorCode( NoError );
+ if ( callbacks.storeByteArrayCallback ) callbacks.storeByteArrayCallback( callbacks.context, &page, len, data, &errorCode );
+ processErrorCode( errorCode, page );
+}
+
+void CustomStorageManager::deleteByteArray(const id_type page)
+{
+ int errorCode( NoError );
+ if ( callbacks.deleteByteArrayCallback ) callbacks.deleteByteArrayCallback( callbacks.context, page, &errorCode );
+ processErrorCode( errorCode, page );
+}
+
+inline void CustomStorageManager::processErrorCode(int errorCode, const id_type page)
+{
+ switch (errorCode)
+ {
+ case NoError:
+ break;
+
+ case InvalidPageError:
+ throw InvalidPageException( page );
+ break;
+
+ case IllegalStateError:
+ throw Tools::IllegalStateException( "CustomStorageManager: Error in user implementation." );
+ break;
+
+ default:
+ throw Tools::IllegalStateException( "CustomStorageManager: Unknown error." );
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/DataStream.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/DataStream.cc
new file mode 100644
index 000000000..d30d70ec8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/DataStream.cc
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * $Id: datastream.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the datastream.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+
+DataStream::DataStream(int (*readNext)(SpatialIndex::id_type * id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t** pData, uint32_t *nDataLength)) :m_pNext(0),m_bDoneReading(false)
+{
+ iterfunct = readNext;
+
+ // Read the first one.
+ readData();
+}
+
+DataStream::~DataStream()
+{
+ if (m_pNext != 0) delete m_pNext;
+}
+
+bool DataStream::readData()
+{
+ SpatialIndex::id_type id;
+ double *pMin=0;
+ double *pMax=0;
+ uint32_t nDimension=0;
+ const uint8_t *p_data=0;
+ uint32_t nDataLength=0;
+
+ if (m_bDoneReading == true) {
+ return false;
+ }
+
+ int ret = iterfunct(&id, &pMin, &pMax, &nDimension, &p_data, &nDataLength);
+
+ // The callback should return anything other than 0
+ // when it is done.
+ if (ret != 0)
+ {
+ m_bDoneReading = true;
+ return false;
+ }
+
+ SpatialIndex::Region r = SpatialIndex::Region(pMin, pMax, nDimension);
+ m_pNext = new SpatialIndex::RTree::Data(nDataLength, (byte*)p_data, r, id);
+
+ return true;
+}
+
+
+SpatialIndex::IData* DataStream::getNext()
+{
+ if (m_pNext == 0) return 0;
+
+ SpatialIndex::RTree::Data* ret = m_pNext;
+ m_pNext = 0;
+ readData();
+ return ret;
+}
+
+bool DataStream::hasNext() throw (Tools::NotSupportedException)
+{
+ return (m_pNext != 0);
+}
+
+uint32_t DataStream::size() throw (Tools::NotSupportedException)
+{
+ throw Tools::NotSupportedException("Operation not supported.");
+}
+
+void DataStream::rewind() throw (Tools::NotSupportedException)
+{
+ throw Tools::NotSupportedException("Operation not supported.");
+
+ if (m_pNext != 0)
+ {
+ delete m_pNext;
+ m_pNext = 0;
+ }
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/Error.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/Error.cc
new file mode 100644
index 000000000..19239710b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/Error.cc
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * $Id: error.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the error object.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+Error::Error(int code, std::string const& message, std::string const& method) :
+ m_code(code),
+ m_message(message),
+ m_method(method)
+{
+}
+
+Error::Error(Error const& other) :
+ m_code(other.m_code),
+ m_message(other.m_message),
+ m_method(other.m_method)
+{
+}
+
+Error& Error::operator=(Error const& rhs)
+{
+ if (&rhs != this)
+ {
+ m_code = rhs.m_code;
+ m_message = rhs.m_message;
+ m_method = rhs.m_method;
+
+ }
+ return *this;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/IdVisitor.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/IdVisitor.cc
new file mode 100644
index 000000000..7e0e0b615
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/IdVisitor.cc
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * $Id: idvisitor.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the id visitor.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+IdVisitor::IdVisitor(): nResults(0)
+{
+}
+
+IdVisitor::~IdVisitor()
+{
+
+}
+
+void IdVisitor::visitNode(const SpatialIndex::INode& n)
+{
+
+}
+
+void IdVisitor::visitData(const SpatialIndex::IData& d)
+{
+ nResults += 1;
+
+ m_vector.push_back(d.getIdentifier());
+}
+
+void IdVisitor::visitData(std::vector<const SpatialIndex::IData*>& v)
+{
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/Index.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/Index.cc
new file mode 100644
index 000000000..98736043c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/Index.cc
@@ -0,0 +1,381 @@
+/******************************************************************************
+ * $Id: index.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the index.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+SpatialIndex::ISpatialIndex* Index::CreateIndex()
+{
+ using namespace SpatialIndex;
+
+ ISpatialIndex* index = 0;
+
+ Tools::Variant var;
+
+ if (GetIndexType() == RT_RTree) {
+
+ try {
+ index = RTree::returnRTree( *m_buffer, m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ }
+
+ else if (GetIndexType() == RT_MVRTree) {
+
+ try {
+ index = MVRTree::returnMVRTree( *m_buffer, m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ }
+
+ else if (GetIndexType() == RT_TPRTree) {
+
+ try {
+ index = TPRTree::returnTPRTree( *m_buffer,m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ }
+
+ return index;
+}
+
+
+Index::Index(const Tools::PropertySet& poProperties)
+{
+ Setup();
+
+ m_properties = poProperties;
+
+ Initialize();
+}
+
+
+Index::~Index()
+{
+ if (m_rtree != 0)
+ delete m_rtree;
+ if (m_buffer != 0)
+ delete m_buffer;
+ if (m_storage != 0)
+ delete m_storage;
+
+}
+
+Index::Index( const Tools::PropertySet& poProperties,
+ int (*readNext)(SpatialIndex::id_type *id,
+ double **pMin,
+ double **pMax,
+ uint32_t *nDimension,
+ const uint8_t **pData,
+ uint32_t *nDataLength))
+{
+ using namespace SpatialIndex;
+
+ Setup();
+
+ m_properties = poProperties;
+
+ m_storage = CreateStorage();
+ m_buffer = CreateIndexBuffer(*m_storage);
+
+ DataStream ds(readNext);
+
+ double dFillFactor = 0.7;
+ uint32_t nIdxCapacity = 100;
+ uint32_t nIdxLeafCap = 100;
+ uint32_t nIdxDimension = 2;
+ SpatialIndex::RTree::RTreeVariant eVariant = SpatialIndex::RTree::RV_RSTAR;
+ SpatialIndex::id_type m_IdxIdentifier;
+
+ // Fetch a bunch of properties. We can't bulk load an rtree using merely
+ // properties, we have to use the helper method(s).
+
+ Tools::Variant var;
+ var = m_properties.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE)
+ throw std::runtime_error("Index::Index (streaming):"
+ " Property FillFactor must be Tools::VT_DOUBLE");
+
+ dFillFactor = var.m_val.dblVal;
+ }
+
+ var = m_properties.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property IndexCapacity must be Tools::VT_ULONG");
+
+ nIdxCapacity = var.m_val.ulVal;
+ }
+
+ var = m_properties.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property LeafCapacity must be Tools::VT_ULONG");
+
+ nIdxLeafCap = var.m_val.ulVal;
+ }
+
+ var = m_properties.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property Dimension must be Tools::VT_ULONG");
+
+ nIdxDimension = var.m_val.ulVal;
+ }
+
+ var = m_properties.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property TreeVariant must be Tools::VT_LONG");
+
+ eVariant = static_cast<SpatialIndex::RTree::RTreeVariant>(var.m_val.lVal);
+ }
+
+ var = m_properties.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONGLONG)
+ throw std::runtime_error("Index::Index (streaming): "
+ "Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ m_IdxIdentifier = var.m_val.llVal;
+ }
+
+ m_rtree = RTree::createAndBulkLoadNewRTree( SpatialIndex::RTree::BLM_STR,
+ ds,
+ *m_buffer,
+ dFillFactor,
+ nIdxCapacity,
+ nIdxLeafCap,
+ nIdxDimension,
+ eVariant,
+ m_IdxIdentifier);
+}
+
+
+SpatialIndex::StorageManager::IBuffer* Index::CreateIndexBuffer(SpatialIndex::IStorageManager& storage)
+{
+ using namespace SpatialIndex::StorageManager;
+ IBuffer* buffer = 0;
+ try {
+ if ( m_storage == 0 )
+ throw std::runtime_error("Storage was invalid to create index buffer");
+ buffer = returnRandomEvictionsBuffer(storage, m_properties);
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+ return buffer;
+}
+
+
+SpatialIndex::IStorageManager* Index::CreateStorage()
+{
+ using namespace SpatialIndex::StorageManager;
+
+ SpatialIndex::IStorageManager* storage = 0;
+ std::string filename("");
+
+ Tools::Variant var;
+ var = m_properties.getProperty("FileName");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR)
+ throw std::runtime_error("Index::CreateStorage: "
+ "Property FileName must be Tools::VT_PCHAR");
+
+ filename = std::string(var.m_val.pcVal);
+ }
+
+ if (GetIndexStorage() == RT_Disk) {
+ if (filename.empty()) {
+ std::ostringstream os;
+ os << "Spatial Index Error: filename was empty."
+ " Set IndexStorageType to RT_Memory";
+ throw std::runtime_error(os.str());
+ }
+ try {
+ storage = returnDiskStorageManager(m_properties);
+ return storage;
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+
+ } else if (GetIndexStorage() == RT_Memory) {
+
+ try {
+ storage = returnMemoryStorageManager(m_properties);
+ return storage;
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+
+ } else if (GetIndexStorage() == RT_Custom) {
+
+ try {
+ storage = returnCustomStorageManager(m_properties);
+ return storage;
+ } catch (Tools::Exception& e) {
+ std::ostringstream os;
+ os << "Spatial Index Error: " << e.what();
+ throw std::runtime_error(os.str());
+ }
+
+ }
+ return storage;
+}
+
+
+
+
+void Index::Initialize()
+{
+ m_storage = CreateStorage();
+ m_buffer = CreateIndexBuffer(*m_storage);
+ m_rtree = CreateIndex();
+}
+
+void Index::Setup()
+
+{
+ m_buffer = 0;
+ m_storage = 0;
+ m_rtree = 0;
+}
+
+RTIndexType Index::GetIndexType()
+{
+ Tools::Variant var;
+ var = m_properties.getProperty("IndexType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::GetIndexType: "
+ "Property IndexType must be Tools::VT_ULONG");
+
+ return static_cast<RTIndexType>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ return RT_InvalidIndexType;
+
+}
+void Index::SetIndexType(RTIndexType v)
+{
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = v;
+ m_properties.setProperty("IndexType", var);
+}
+
+RTStorageType Index::GetIndexStorage()
+{
+
+ Tools::Variant var;
+ var = m_properties.getProperty("IndexStorageType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::GetIndexStorage: "
+ "Property IndexStorageType must be Tools::VT_ULONG");
+
+ return static_cast<RTStorageType>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ return RT_InvalidStorageType;
+}
+
+void Index::SetIndexStorage(RTStorageType v)
+{
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = v;
+ m_properties.setProperty("IndexStorageType", var);
+}
+
+RTIndexVariant Index::GetIndexVariant()
+{
+
+ Tools::Variant var;
+ var = m_properties.getProperty("TreeVariant");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw std::runtime_error("Index::GetIndexVariant: "
+ "Property TreeVariant must be Tools::VT_ULONG");
+
+ return static_cast<RTIndexVariant>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ return RT_InvalidIndexVariant;
+}
+
+void Index::SetIndexVariant(RTStorageType v)
+{
+ using namespace SpatialIndex;
+ Tools::Variant var;
+
+ if (GetIndexType() == RT_RTree) {
+ var.m_val.ulVal = static_cast<RTree::RTreeVariant>(v);
+ m_properties.setProperty("TreeVariant", var);
+ } else if (GetIndexType() == RT_MVRTree) {
+ var.m_val.ulVal = static_cast<MVRTree::MVRTreeVariant>(v);
+ m_properties.setProperty("TreeVariant", var);
+ } else if (GetIndexType() == RT_TPRTree) {
+ var.m_val.ulVal = static_cast<TPRTree::TPRTreeVariant>(v);
+ m_properties.setProperty("TreeVariant", var);
+ }
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/LeafQuery.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/LeafQuery.cc
new file mode 100644
index 000000000..0d0998278
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/LeafQuery.cc
@@ -0,0 +1,126 @@
+/******************************************************************************
+ * $Id: boundsquery.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement a query of the index's leaves.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <capi/sidx_impl.h>
+
+LeafQuery::LeafQuery()
+{
+
+}
+
+LeafQueryResult get_results(const SpatialIndex::INode* n)
+{
+ LeafQueryResult result (n->getIdentifier());
+
+ SpatialIndex::IShape* ps;
+ n->getShape(&ps);
+ SpatialIndex::Region* pr = dynamic_cast<SpatialIndex::Region*>(ps);
+ std::vector<SpatialIndex::id_type> ids;
+ for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ ids.push_back(n->getChildIdentifier(cChild));
+ }
+
+ result.SetIDs(ids);
+ result.SetBounds(pr);
+ delete ps;
+
+ return result;
+}
+void LeafQuery::getNextEntry( const SpatialIndex::IEntry& entry,
+ SpatialIndex::id_type& nextEntry,
+ bool& hasNext)
+{
+
+ const SpatialIndex::INode* n = dynamic_cast<const SpatialIndex::INode*>(&entry);
+
+ // traverse only index nodes at levels 2 and higher.
+ if (n != 0 && n->getLevel() > 0)
+ {
+ for (uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+ {
+ m_ids.push(n->getChildIdentifier(cChild));
+ }
+ }
+
+ if (n->isLeaf()) {
+ m_results.push_back(get_results(n));
+ }
+
+ if (! m_ids.empty())
+ {
+ nextEntry = m_ids.front(); m_ids.pop();
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+}
+
+
+std::vector<SpatialIndex::id_type> const& LeafQueryResult::GetIDs() const
+{
+ return ids;
+}
+
+void LeafQueryResult::SetIDs(std::vector<SpatialIndex::id_type>& v)
+{
+ ids.resize(v.size());
+ std::copy(v.begin(), v.end(), ids.begin());
+}
+const SpatialIndex::Region* LeafQueryResult::GetBounds() const
+{
+ return bounds;
+}
+
+void LeafQueryResult::SetBounds(const SpatialIndex::Region* b)
+{
+ bounds = new SpatialIndex::Region(*b);
+}
+
+LeafQueryResult::LeafQueryResult(LeafQueryResult const& other)
+{
+ ids.resize(other.ids.size());
+ std::copy(other.ids.begin(), other.ids.end(), ids.begin());
+ m_id = other.m_id;
+
+ bounds = other.bounds->clone();
+}
+
+LeafQueryResult& LeafQueryResult::operator=(LeafQueryResult const& rhs)
+{
+ if (&rhs != this)
+ {
+ ids.resize(rhs.ids.size());
+ std::copy(rhs.ids.begin(), rhs.ids.end(), ids.begin());
+ m_id = rhs.m_id;
+ bounds = rhs.bounds->clone();
+ }
+ return *this;
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/capi/Makefile.am
new file mode 100644
index 000000000..2c35d4002
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/Makefile.am
@@ -0,0 +1,14 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libsidxc.la
+INCLUDES = -I../../include -I../../include/capi
+libsidxc_la_SOURCES = BoundsQuery.cc \
+ CountVisitor.cc \
+ CustomStorage.cc \
+ DataStream.cc \
+ Error.cc \
+ IdVisitor.cc \
+ Index.cc \
+ LeafQuery.cc \
+ ObjVisitor.cc \
+ sidx_api.cc \
+ Utility.cc
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/ObjVisitor.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/ObjVisitor.cc
new file mode 100644
index 000000000..436f7b9a9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/ObjVisitor.cc
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * $Id: objvisitor.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement the wrapper.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+ObjVisitor::ObjVisitor(): nResults(0)
+{
+}
+
+ObjVisitor::~ObjVisitor()
+{
+ std::vector<SpatialIndex::IData*>::iterator it;
+ for (it = m_vector.begin(); it != m_vector.end(); it++) {
+ delete *it;
+ }
+
+}
+
+void ObjVisitor::visitNode(const SpatialIndex::INode& n)
+{
+}
+
+void ObjVisitor::visitData(const SpatialIndex::IData& d)
+{
+
+ SpatialIndex::IData* item = dynamic_cast<SpatialIndex::IData*>(const_cast<SpatialIndex::IData&>(d).clone()) ;
+
+ nResults += 1;
+
+ m_vector.push_back(item);
+}
+
+void ObjVisitor::visitData(std::vector<const SpatialIndex::IData*>& v)
+{
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/Utility.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/Utility.cc
new file mode 100644
index 000000000..e441853c3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/Utility.cc
@@ -0,0 +1,150 @@
+/******************************************************************************
+ * $Id: util.cc 1361 2009-08-02 17:53:31Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C++ objects to implement utilities.
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include "sidx_impl.h"
+
+Tools::PropertySet* GetDefaults()
+{
+ Tools::PropertySet* ps = new Tools::PropertySet;
+
+ Tools::Variant var;
+
+ // Rtree defaults
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 0.7;
+ ps->setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = SpatialIndex::RTree::RV_RSTAR;
+ ps->setProperty("TreeVariant", var);
+
+ // var.m_varType = Tools::VT_LONGLONG;
+ // var.m_val.llVal = 0;
+ // ps->setProperty("IndexIdentifier", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 32;
+ ps->setProperty("NearMinimumOverlapFactor", var);
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 0.4;
+ ps->setProperty("SplitDistributionFactor", var);
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 0.3;
+ ps->setProperty("ReinsertFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 2;
+ ps->setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.bVal = true;
+ ps->setProperty("EnsureTightMBRs", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("IndexPoolCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 100;
+ ps->setProperty("LeafPoolCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 1000;
+ ps->setProperty("RegionPoolCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 500;
+ ps->setProperty("PointPoolCapacity", var);
+
+ // horizon for TPRTree
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = 20.0;
+ ps->setProperty("Horizon", var);
+
+ // Buffering defaults
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 10;
+ ps->setProperty("Capacity", var);
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.bVal = false;
+ ps->setProperty("WriteThrough", var);
+
+ // Disk Storage Manager defaults
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.bVal = true;
+ ps->setProperty("Overwrite", var);
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>("");
+ ps->setProperty("FileName", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = 4096;
+ ps->setProperty("PageSize", var);
+
+ // Our custom properties related to whether
+ // or not we are using a disk or memory storage manager
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = RT_Disk;
+ ps->setProperty("IndexStorageType", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = RT_RTree;
+ ps->setProperty("IndexType", var);
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>("dat");
+ ps->setProperty("FileNameDat", var);
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>("idx");
+ ps->setProperty("FileNameIdx", var);
+
+ // Custom storage manager properties
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.pcVal = 0;
+ ps->setProperty("CustomStorageCallbacksSize", var);
+
+ var.m_varType = Tools::VT_PVOID;
+ var.m_val.pcVal = 0;
+ ps->setProperty("CustomStorageCallbacks", var);
+
+ return ps;
+} \ No newline at end of file
diff --git a/sci-libs/libspatialindex/svn/trunk/src/capi/sidx_api.cc b/sci-libs/libspatialindex/svn/trunk/src/capi/sidx_api.cc
new file mode 100644
index 000000000..e2b24c98f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/capi/sidx_api.cc
@@ -0,0 +1,2518 @@
+/******************************************************************************
+ * $Id: sidx_api.cc 1385 2009-08-13 15:45:16Z hobu $
+ *
+ * Project: libsidx - A C API wrapper around libspatialindex
+ * Purpose: C API wrapper implementation
+ * Author: Howard Butler, hobu.inc@gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2009, Howard Butler
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ****************************************************************************/
+
+#include <cmath>
+#include <limits>
+#include "sidx_impl.h"
+
+static std::stack<Error> errors;
+
+#define VALIDATE_POINTER0(ptr, func) \
+ do { if( NULL == ptr ) { \
+ RTError const ret = RT_Failure; \
+ std::ostringstream msg; \
+ msg << "Pointer \'" << #ptr << "\' is NULL in \'" << (func) <<"\'."; \
+ std::string message(msg.str()); \
+ Error_PushError( ret, message.c_str(), (func)); \
+ return; \
+ }} while(0)
+
+#define VALIDATE_POINTER1(ptr, func, rc) \
+ do { if( NULL == ptr ) { \
+ RTError const ret = RT_Failure; \
+ std::ostringstream msg; \
+ msg << "Pointer \'" << #ptr << "\' is NULL in \'" << (func) <<"\'."; \
+ std::string message(msg.str()); \
+ Error_PushError( ret, message.c_str(), (func)); \
+ return (rc); \
+ }} while(0)
+
+IDX_C_START
+
+SIDX_C_DLL void Error_Reset(void) {
+ if (errors.empty()) return;
+ for (std::size_t i=0;i<errors.size();i++) errors.pop();
+}
+
+SIDX_C_DLL void Error_Pop(void) {
+ if (errors.empty()) return;
+ errors.pop();
+}
+
+SIDX_C_DLL int Error_GetLastErrorNum(void){
+ if (errors.empty())
+ return 0;
+ else {
+ Error err = errors.top();
+ return err.GetCode();
+ }
+}
+
+SIDX_C_DLL char* Error_GetLastErrorMsg(void){
+ if (errors.empty())
+ return NULL;
+ else {
+ Error err = errors.top();
+ return STRDUP(err.GetMessage());
+ }
+}
+
+SIDX_C_DLL char* Error_GetLastErrorMethod(void){
+ if (errors.empty())
+ return NULL;
+ else {
+ Error err = errors.top();
+ return STRDUP(err.GetMethod());
+ }
+}
+
+SIDX_C_DLL void Error_PushError(int code, const char *message, const char *method) {
+ Error err = Error(code, std::string(message), std::string(method));
+ errors.push(err);
+}
+
+SIDX_C_DLL int Error_GetErrorCount(void) {
+ return static_cast<int>(errors.size());
+}
+
+SIDX_C_DLL IndexH Index_Create(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "Index_Create", NULL);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try {
+ return (IndexH) new Index(*prop);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Create");
+ return NULL;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Create");
+ return NULL;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Create");
+ return NULL;
+ }
+ return NULL;
+}
+
+SIDX_C_DLL IndexH Index_CreateWithStream( IndexPropertyH hProp,
+ int (*readNext)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength)
+ )
+{
+ VALIDATE_POINTER1(hProp, "Index_CreateWithStream", NULL);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+
+ try {
+ return (IndexH) new Index(*prop, readNext);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_CreateWithStream");
+ return NULL;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_CreateWithStream");
+ return NULL;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_CreateWithStream");
+ return NULL;
+ }
+ return NULL;
+}
+
+SIDX_C_DLL void Index_Destroy(IndexH index)
+{
+ VALIDATE_POINTER0(index, "Index_Destroy");
+ Index* idx = (Index*) index;
+ if (idx) delete idx;
+}
+
+SIDX_C_DLL RTError Index_DeleteData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension)
+{
+ VALIDATE_POINTER1(index, "Index_DeleteData", RT_Failure);
+
+ Index* idx = static_cast<Index*>(index);
+
+ try {
+ idx->index().deleteData(SpatialIndex::Region(pdMin, pdMax, nDimension), id);
+ return RT_None;
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_DeleteData");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_DeleteData");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_DeleteData");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_InsertData( IndexH index,
+ uint64_t id,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ const uint8_t* pData,
+ uint32_t nDataLength)
+{
+ VALIDATE_POINTER1(index, "Index_InsertData", RT_Failure);
+
+ Index* idx = static_cast<Index*>(index);
+
+ // Test the data and check for the case when minx == maxx, miny == maxy
+ // and minz == maxz. In that case, we will insert a SpatialIndex::Point
+ // instead of a SpatialIndex::Region
+
+ bool isPoint = false;
+ SpatialIndex::IShape* shape = 0;
+ double const epsilon = std::numeric_limits<double>::epsilon();
+
+ double length(0);
+ for (uint32_t i = 0; i < nDimension; ++i) {
+ double delta = pdMin[i] - pdMax[i];
+ length += std::fabs(delta);
+ }
+
+ if (length <= epsilon) {
+ isPoint = true;
+ }
+
+ if (isPoint == true) {
+ shape = new SpatialIndex::Point(pdMin, nDimension);
+ } else {
+ shape = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ }
+ try {
+ idx->index().insertData(nDataLength,
+ pData,
+ *shape,
+ id);
+
+ delete shape;
+ return RT_None;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_InsertData");
+ delete shape;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_InsertData");
+ delete shape;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_InsertData");
+ delete shape;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_Intersects_obj( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_Intersects_obj", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ ObjVisitor* visitor = new ObjVisitor;
+ try {
+ SpatialIndex::Region* r = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ idx->index().intersectsWithQuery( *r,
+ *visitor);
+
+ *items = (SpatialIndex::IData**) malloc (visitor->GetResultCount() * sizeof(SpatialIndex::IData*));
+
+ std::vector<SpatialIndex::IData*>& results = visitor->GetResults();
+
+ // copy the Items into the newly allocated item array
+ // we need to make sure to copy the actual Item instead
+ // of just the pointers, as the visitor will nuke them
+ // upon ~
+ for (uint32_t i=0; i < visitor->GetResultCount(); ++i)
+ {
+ SpatialIndex::IData* result =results[i];
+ (*items)[i] = dynamic_cast<SpatialIndex::IData*>(result->clone());
+
+ }
+ *nResults = visitor->GetResultCount();
+
+ delete r;
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Intersects_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Intersects_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Intersects_obj");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_Intersects_id( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** ids,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_Intersects_id", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ IdVisitor* visitor = new IdVisitor;
+ try {
+ SpatialIndex::Region* r = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ idx->index().intersectsWithQuery( *r,
+ *visitor);
+
+ *nResults = visitor->GetResultCount();
+
+ *ids = (uint64_t*) malloc (*nResults * sizeof(uint64_t));
+
+ std::vector<uint64_t>& results = visitor->GetResults();
+
+ for (uint32_t i=0; i < *nResults; ++i)
+ {
+ (*ids)[i] = results[i];
+
+ }
+
+ delete r;
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Intersects_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Intersects_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Intersects_id");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_Intersects_count( IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_Intersects_count", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ CountVisitor* visitor = new CountVisitor;
+ try {
+ SpatialIndex::Region* r = new SpatialIndex::Region(pdMin, pdMax, nDimension);
+ idx->index().intersectsWithQuery( *r,
+ *visitor);
+
+ *nResults = visitor->GetResultCount();
+
+ delete r;
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_Intersects_count");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_Intersects_count");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_Intersects_count");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_NearestNeighbors_id(IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ uint64_t** ids,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_NearestNeighbors_id", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ IdVisitor* visitor = new IdVisitor;
+
+ try {
+ idx->index().nearestNeighborQuery( *nResults,
+ SpatialIndex::Region(pdMin, pdMax, nDimension),
+ *visitor);
+
+ *ids = (uint64_t*) malloc (visitor->GetResultCount() * sizeof(uint64_t));
+
+ std::vector<uint64_t>& results = visitor->GetResults();
+
+ *nResults = results.size();
+
+ for (uint32_t i=0; i < *nResults; ++i)
+ {
+ (*ids)[i] = results[i];
+
+ }
+
+
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_NearestNeighbors_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_NearestNeighbors_id");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_NearestNeighbors_id");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_NearestNeighbors_obj(IndexH index,
+ double* pdMin,
+ double* pdMax,
+ uint32_t nDimension,
+ IndexItemH** items,
+ uint64_t* nResults)
+{
+ VALIDATE_POINTER1(index, "Index_NearestNeighbors_obj", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ ObjVisitor* visitor = new ObjVisitor;
+ try {
+ idx->index().nearestNeighborQuery( *nResults,
+ SpatialIndex::Region(pdMin, pdMax, nDimension),
+ *visitor);
+
+
+ *items = (SpatialIndex::IData**) malloc (visitor->GetResultCount() * sizeof(Item*));
+
+ std::vector<SpatialIndex::IData*> results = visitor->GetResults();
+ *nResults = results.size();
+
+ // copy the Items into the newly allocated item array
+ // we need to make sure to copy the actual Item instead
+ // of just the pointers, as the visitor will nuke them
+ // upon ~
+ for (uint32_t i=0; i < visitor->GetResultCount(); ++i)
+ {
+ SpatialIndex::IData* result = results[i];
+ (*items)[i] = dynamic_cast<SpatialIndex::IData*>(result->clone());
+
+ }
+
+ delete visitor;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_NearestNeighbors_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_NearestNeighbors_obj");
+ delete visitor;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_NearestNeighbors_obj");
+ delete visitor;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTError Index_GetBounds( IndexH index,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension)
+{
+ VALIDATE_POINTER1(index, "Index_GetBounds", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ BoundsQuery* query = new BoundsQuery;
+
+ try {
+ idx->index().queryStrategy( *query);
+
+ const SpatialIndex::Region* bounds = query->GetBounds();
+ if (bounds == 0) {
+ *nDimension = 0;
+ delete query;
+ return RT_None;
+ }
+
+ *nDimension =bounds->getDimension();
+
+ *ppdMin = (double*) malloc (*nDimension * sizeof(double));
+ *ppdMax = (double*) malloc (*nDimension * sizeof(double));
+
+ for (uint32_t i=0; i< *nDimension; ++i) {
+ (*ppdMin)[i] = bounds->getLow(i);
+ (*ppdMax)[i] = bounds->getHigh(i);
+ }
+
+ delete query;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_GetBounds");
+ delete query;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_GetBounds");
+ delete query;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_GetBounds");
+ delete query;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t Index_IsValid(IndexH index)
+{
+ VALIDATE_POINTER1(index, "Index_IsValid", 0);
+ Index* idx = static_cast<Index*>(index);
+ return static_cast<uint32_t>(idx->index().isIndexValid());
+}
+
+SIDX_C_DLL IndexPropertyH Index_GetProperties(IndexH index)
+{
+ VALIDATE_POINTER1(index, "Index_GetProperties", 0);
+ Index* idx = static_cast<Index*>(index);
+ Tools::PropertySet* ps = new Tools::PropertySet;
+
+ idx->index().getIndexProperties(*ps);
+ return (IndexPropertyH)ps;
+}
+
+SIDX_C_DLL IndexPropertyH Index_ClearBuffer(IndexH index)
+{
+ VALIDATE_POINTER1(index, "Index_ClearBuffer", 0);
+ Index* idx = static_cast<Index*>(index);
+ idx->buffer().clear();
+}
+
+SIDX_C_DLL void Index_DestroyObjResults(IndexItemH* results, uint32_t nResults)
+{
+ VALIDATE_POINTER0(results, "Index_DestroyObjResults");
+ SpatialIndex::IData* it;
+ for (uint32_t i=0; i< nResults; ++i) {
+ if (results[i] != NULL) {
+ it = static_cast<SpatialIndex::IData*>(results[i]);
+ if (it != 0)
+ delete it;
+ }
+ }
+
+ std::free(results);
+}
+
+
+SIDX_C_DLL void Index_Free(void* results)
+{
+ VALIDATE_POINTER0(results, "Index_Free");
+ if (results != 0)
+ std::free(results);
+}
+
+SIDX_C_DLL RTError Index_GetLeaves( IndexH index,
+ uint32_t* nNumLeafNodes,
+ uint32_t** nLeafSizes,
+ int64_t** nLeafIDs,
+ int64_t*** nLeafChildIDs,
+ double*** pppdMin,
+ double*** pppdMax,
+ uint32_t* nDimension)
+{
+ VALIDATE_POINTER1(index, "Index_GetLeaves", RT_Failure);
+ Index* idx = static_cast<Index*>(index);
+
+ std::vector<LeafQueryResult>::const_iterator i;
+ LeafQuery* query = new LeafQuery;
+
+ // Fetch the dimensionality of the index
+ Tools::PropertySet ps;
+ idx->index().getIndexProperties(ps);
+
+ Tools::Variant var;
+ var = ps.getProperty("Dimension");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property Dimension must be Tools::VT_ULONG",
+ "Index_GetLeaves");
+ return RT_Failure;
+ }
+ }
+
+ *nDimension = var.m_val.ulVal;
+
+ try {
+ idx->index().queryStrategy( *query);
+
+ const std::vector<LeafQueryResult>& results = query->GetResults();
+
+ *nNumLeafNodes = results.size();
+
+ *nLeafSizes = (uint32_t*) malloc (*nNumLeafNodes * sizeof(uint32_t));
+ *nLeafIDs = (int64_t*) malloc (*nNumLeafNodes * sizeof(int64_t));
+
+ *nLeafChildIDs = (int64_t**) malloc(*nNumLeafNodes * sizeof(int64_t*));
+ *pppdMin = (double**) malloc (*nNumLeafNodes * sizeof(double*));
+ *pppdMax = (double**) malloc (*nNumLeafNodes * sizeof(double*));
+
+ uint32_t k=0;
+ for (i = results.begin(); i != results.end(); ++i)
+ {
+ std::vector<SpatialIndex::id_type> const& ids = (*i).GetIDs();
+ const SpatialIndex::Region* b = (*i).GetBounds();
+
+ (*nLeafIDs)[k] = (*i).getIdentifier();
+ (*nLeafSizes)[k] = ids.size();
+
+ (*nLeafChildIDs)[k] = (int64_t*) malloc( (*nLeafSizes)[k] * sizeof(int64_t));
+ (*pppdMin)[k] = (double*) malloc ( (*nLeafSizes)[k] * sizeof(double));
+ (*pppdMax)[k] = (double*) malloc ( (*nLeafSizes)[k] * sizeof(double));
+ for (uint32_t i=0; i< *nDimension; ++i) {
+ (*pppdMin)[k][i] = b->getLow(i);
+ (*pppdMax)[k][i] = b->getHigh(i);
+ }
+ for (uint32_t cChild = 0; cChild < ids.size(); cChild++)
+ {
+ (*nLeafChildIDs)[k][cChild] = ids[cChild];
+ }
+ ++k;
+ }
+
+
+ delete query;
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "Index_GetLeaves");
+ delete query;
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "Index_GetLeaves");
+ delete query;
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "Index_GetLeaves");
+ delete query;
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+
+SIDX_C_DLL void IndexItem_Destroy(IndexItemH item)
+{
+ VALIDATE_POINTER0(item, "IndexItem_Destroy");
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+ if (it != 0) delete it;
+}
+
+SIDX_C_DLL RTError IndexItem_GetData( IndexItemH item,
+ uint8_t** data,
+ uint64_t* length)
+{
+ VALIDATE_POINTER1(item, "IndexItem_GetData", RT_Failure);
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+ uint8_t* p_data;
+ uint32_t* l= new uint32_t;
+
+ it->getData(*l,&p_data);
+ *length = (uint64_t)*l;
+ *data = (uint8_t*) malloc (*length * sizeof(uint8_t));
+
+ memcpy(*data, p_data, *length);
+ delete[] p_data;
+ delete l;
+ return RT_None;
+
+}
+
+SIDX_C_DLL uint64_t IndexItem_GetID(IndexItemH item)
+{
+ VALIDATE_POINTER1(item, "IndexItem_GetID",0);
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+ uint64_t value = it->getIdentifier();
+ return value;
+}
+
+SIDX_C_DLL RTError IndexItem_GetBounds( IndexItemH item,
+ double** ppdMin,
+ double** ppdMax,
+ uint32_t* nDimension)
+{
+ VALIDATE_POINTER1(item, "IndexItem_GetBounds", RT_Failure);
+ SpatialIndex::IData* it = static_cast<SpatialIndex::IData*>(item);
+
+ SpatialIndex::IShape* s;
+ it->getShape(&s);
+
+ SpatialIndex::Region *bounds = new SpatialIndex::Region();
+ s->getMBR(*bounds);
+
+ if (bounds == 0) {
+ *nDimension = 0;
+ delete bounds;
+ delete s;
+ return RT_None;
+ }
+ *nDimension = bounds->getDimension();
+
+ *ppdMin = (double*) malloc (*nDimension * sizeof(double));
+ *ppdMax = (double*) malloc (*nDimension * sizeof(double));
+
+ if (ppdMin == NULL || ppdMax == NULL) {
+ Error_PushError(RT_Failure,
+ "Unable to allocation bounds array(s)",
+ "IndexItem_GetBounds");
+ return RT_Failure;
+ }
+
+ for (uint32_t i=0; i< *nDimension; ++i) {
+ (*ppdMin)[i] = bounds->getLow(i);
+ (*ppdMax)[i] = bounds->getHigh(i);
+ }
+ delete bounds;
+ delete s;
+ return RT_None;
+}
+SIDX_C_DLL IndexPropertyH IndexProperty_Create()
+{
+ Tools::PropertySet* ps = GetDefaults();
+ Tools::Variant var;
+ return (IndexPropertyH)ps;
+}
+
+SIDX_C_DLL void IndexProperty_Destroy(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER0(hProp, "IndexProperty_Destroy");
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+ if (prop != 0) delete prop;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexType(IndexPropertyH hProp,
+ RTIndexType value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexType", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (!(value == RT_RTree || value == RT_MVRTree || value == RT_TPRTree)) {
+ throw std::runtime_error("Inputted value is not a valid index type");
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexType", var);
+
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexType");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexType");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexType");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTIndexType IndexProperty_GetIndexType(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexType", RT_InvalidIndexType);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexType must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexType");
+ return RT_InvalidIndexType;
+ }
+ return (RTIndexType) var.m_val.ulVal;
+ }
+
+ Error_PushError(RT_Failure,
+ "Property IndexType was empty",
+ "IndexProperty_GetIndexType");
+ return RT_InvalidIndexType;
+
+}
+
+SIDX_C_DLL RTError IndexProperty_SetDimension(IndexPropertyH hProp, uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetDimension", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("Dimension", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetDimension");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetDimension");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetDimension");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetDimension(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetDimension", RT_InvalidIndexType);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Dimension");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexType must be Tools::VT_ULONG",
+ "IndexProperty_GetDimension");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // A zero dimension index is invalid.
+ Error_PushError(RT_Failure,
+ "Property Dimension was empty",
+ "IndexProperty_GetDimension");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexVariant( IndexPropertyH hProp,
+ RTIndexVariant value)
+{
+ using namespace SpatialIndex;
+
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexVariant", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+
+ try
+ {
+
+ if (!(value == RT_Linear || value == RT_Quadratic || value == RT_Star)) {
+ throw std::runtime_error("Inputted value is not a valid index variant");
+ }
+
+ var.m_varType = Tools::VT_LONG;
+ RTIndexType type = IndexProperty_GetIndexType(hProp);
+ if (type == RT_InvalidIndexType ) {
+ Error_PushError(RT_Failure,
+ "Index type is not properly set",
+ "IndexProperty_SetIndexVariant");
+ return RT_Failure;
+ }
+ if (type == RT_RTree) {
+ var.m_val.lVal = static_cast<RTree::RTreeVariant>(value);
+ prop->setProperty("TreeVariant", var);
+ } else if (type == RT_MVRTree) {
+ var.m_val.lVal = static_cast<MVRTree::MVRTreeVariant>(value);
+ prop->setProperty("TreeVariant", var);
+ } else if (type == RT_TPRTree) {
+ var.m_val.lVal = static_cast<TPRTree::TPRTreeVariant>(value);
+ prop->setProperty("TreeVariant", var);
+ }
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexVariant");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTIndexVariant IndexProperty_GetIndexVariant(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_GetIndexVariant",
+ RT_InvalidIndexVariant);
+
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("TreeVariant");
+
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexVariant must be Tools::VT_LONG",
+ "IndexProperty_GetIndexVariant");
+ return RT_InvalidIndexVariant;
+ }
+
+ return static_cast<RTIndexVariant>(var.m_val.lVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ Error_PushError(RT_Failure,
+ "Property IndexVariant was empty",
+ "IndexProperty_GetIndexVariant");
+ return RT_InvalidIndexVariant;
+
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexStorage( IndexPropertyH hProp,
+ RTStorageType value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexStorage", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (!(value == RT_Disk || value == RT_Memory || value == RT_Custom)) {
+ throw std::runtime_error("Inputted value is not a valid index storage type");
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexStorageType", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexStorage");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexStorage");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexStorage");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL RTStorageType IndexProperty_GetIndexStorage(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_GetIndexStorage",
+ RT_InvalidStorageType);
+
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexStorageType");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexStorage must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexStorage");
+ return RT_InvalidStorageType;
+ }
+
+ return static_cast<RTStorageType>(var.m_val.ulVal);
+ }
+
+ // if we didn't get anything, we're returning an error condition
+ Error_PushError(RT_Failure,
+ "Property IndexStorage was empty",
+ "IndexProperty_GetIndexStorage");
+ return RT_InvalidStorageType;
+
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetIndexCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property IndexCapacity was empty",
+ "IndexProperty_GetIndexCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetLeafCapacity( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetLeafCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("LeafCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetLeafCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetLeafCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetLeafCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetLeafCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetLeafCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("LeafCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property LeafCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetLeafCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property LeafCapacity was empty",
+ "IndexProperty_GetLeafCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetPagesize( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetPagesize", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("PageSize", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetPagesize");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetPagesize");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetPagesize");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetPagesize(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetPagesize", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("PageSize");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property PageSize must be Tools::VT_ULONG",
+ "IndexProperty_GetPagesize");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property PageSize was empty",
+ "IndexProperty_GetPagesize");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetLeafPoolCapacity( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetLeafPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("LeafPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetLeafPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetLeafPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetLeafPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetLeafPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetLeafPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("LeafPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property LeafPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetLeafPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property LeafPoolCapacity was empty",
+ "IndexProperty_GetLeafPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexPoolCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("IndexPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetIndexPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetIndexPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property IndexPoolCapacity was empty",
+ "IndexProperty_GetIndexPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetRegionPoolCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetRegionPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("RegionPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetRegionPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetRegionPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetRegionPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetRegionPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetRegionPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("RegionPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property RegionPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetRegionPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property RegionPoolCapacity was empty",
+ "IndexProperty_GetRegionPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetPointPoolCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetPointPoolCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("PointPoolCapacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetPointPoolCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetPointPoolCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetPointPoolCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetPointPoolCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetPointPoolCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("PointPoolCapacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property PointPoolCapacity must be Tools::VT_ULONG",
+ "IndexProperty_GetPointPoolCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property PointPoolCapacity was empty",
+ "IndexProperty_GetPointPoolCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetNearMinimumOverlapFactor( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetNearMinimumOverlapFactor",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("NearMinimumOverlapFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetNearMinimumOverlapFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetNearMinimumOverlapFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetNearMinimumOverlapFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetNearMinimumOverlapFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetNearMinimumOverlapFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("NearMinimumOverlapFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property NearMinimumOverlapFactor must be Tools::VT_ULONG",
+ "IndexProperty_GetNearMinimumOverlapFactor");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property NearMinimumOverlapFactor was empty",
+ "IndexProperty_GetNearMinimumOverlapFactor");
+ return 0;
+}
+
+
+SIDX_C_DLL RTError IndexProperty_SetBufferingCapacity(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetBufferingCapacity", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("Capacity", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetBufferingCapacity");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetBufferingCapacity");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetBufferingCapacity");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetBufferingCapacity(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetBufferingCapacity", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Capacity");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property Capacity must be Tools::VT_ULONG",
+ "IndexProperty_GetBufferingCapacity");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property Capacity was empty",
+ "IndexProperty_GetBufferingCapacity");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetEnsureTightMBRs( IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetEnsureTightMBRs", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (value > 1 ) {
+ Error_PushError(RT_Failure,
+ "EnsureTightMBRs is a boolean value and must be 1 or 0",
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = (bool)value;
+ prop->setProperty("EnsureTightMBRs", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetEnsureTightMBRs");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetEnsureTightMBRs(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetEnsureTightMBRs", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("EnsureTightMBRs");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) {
+ Error_PushError(RT_Failure,
+ "Property EnsureTightMBRs must be Tools::VT_BOOL",
+ "IndexProperty_GetEnsureTightMBRs");
+ return 0;
+ }
+
+ return var.m_val.blVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property EnsureTightMBRs was empty",
+ "IndexProperty_GetEnsureTightMBRs");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetWriteThrough(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetWriteThrough", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (value > 1 ) {
+ Error_PushError(RT_Failure,
+ "WriteThrough is a boolean value and must be 1 or 0",
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = value;
+ prop->setProperty("WriteThrough", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetWriteThrough");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetWriteThrough(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetWriteThrough", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("WriteThrough");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) {
+ Error_PushError(RT_Failure,
+ "Property WriteThrough must be Tools::VT_BOOL",
+ "IndexProperty_GetWriteThrough");
+ return 0;
+ }
+
+ return var.m_val.blVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property WriteThrough was empty",
+ "IndexProperty_GetWriteThrough");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetOverwrite(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetOverwrite", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ if (value > 1 ) {
+ Error_PushError(RT_Failure,
+ "Overwrite is a boolean value and must be 1 or 0",
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ }
+ Tools::Variant var;
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = value;
+ prop->setProperty("Overwrite", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetOverwrite");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetOverwrite(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetOverwrite", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Overwrite");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) {
+ Error_PushError(RT_Failure,
+ "Property Overwrite must be Tools::VT_BOOL",
+ "IndexProperty_GetOverwrite");
+ return 0;
+ }
+
+ return var.m_val.blVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property Overwrite was empty",
+ "IndexProperty_GetOverwrite");
+ return 0;
+}
+
+
+SIDX_C_DLL RTError IndexProperty_SetFillFactor( IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetFillFactor", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("FillFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFillFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFillFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFillFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetFillFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFillFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FillFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property FillFactor must be Tools::VT_DOUBLE",
+ "IndexProperty_GetFillFactor");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FillFactor was empty",
+ "IndexProperty_GetFillFactor");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetSplitDistributionFactor( IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetSplitDistributionFactor",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("SplitDistributionFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetSplitDistributionFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetSplitDistributionFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetSplitDistributionFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetSplitDistributionFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetSplitDistributionFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("SplitDistributionFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property SplitDistributionFactor must be Tools::VT_DOUBLE",
+ "IndexProperty_GetSplitDistributionFactor");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property SplitDistributionFactor was empty",
+ "IndexProperty_GetSplitDistributionFactor");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetTPRHorizon(IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetTPRHorizon",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("Horizon", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetTPRHorizon");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetTPRHorizon");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetTPRHorizon");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetTPRHorizon(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetTPRHorizon", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("Horizon");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property Horizon must be Tools::VT_DOUBLE",
+ "IndexProperty_GetTPRHorizon");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property Horizon was empty",
+ "IndexProperty_GetTPRHorizon");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetReinsertFactor( IndexPropertyH hProp,
+ double value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetReinsertFactor",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = value;
+ prop->setProperty("ReinsertFactor", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetReinsertFactor");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetReinsertFactor");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetReinsertFactor");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL double IndexProperty_GetReinsertFactor(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetReinsertFactor", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("ReinsertFactor");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE) {
+ Error_PushError(RT_Failure,
+ "Property ReinsertFactor must be Tools::VT_DOUBLE",
+ "IndexProperty_GetReinsertFactor");
+ return 0;
+ }
+
+ return var.m_val.dblVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property ReinsertFactor was empty",
+ "IndexProperty_GetReinsertFactor");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetFileName( IndexPropertyH hProp,
+ const char* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetFileName",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = STRDUP(value); // not sure if we should copy here
+ prop->setProperty("FileName", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFileName");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFileName");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFileName");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL char* IndexProperty_GetFileName(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFileName", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FileName");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR) {
+ Error_PushError(RT_Failure,
+ "Property FileName must be Tools::VT_PCHAR",
+ "IndexProperty_GetFileName");
+ return NULL;
+ }
+
+ return STRDUP(var.m_val.pcVal);
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FileName was empty",
+ "IndexProperty_GetFileName");
+ return NULL;
+}
+
+
+SIDX_C_DLL RTError IndexProperty_SetFileNameExtensionDat( IndexPropertyH hProp,
+ const char* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetFileNameExtensionDat",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = STRDUP(value); // not sure if we should copy here
+ prop->setProperty("FileNameDat", var);
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFileNameExtensionDat");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFileNameExtensionDat");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFileNameExtensionDat");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL char* IndexProperty_GetFileNameExtensionDat(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFileNameExtensionDat", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FileNameDat");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR) {
+ Error_PushError(RT_Failure,
+ "Property FileNameDat must be Tools::VT_PCHAR",
+ "IndexProperty_GetFileNameExtensionDat");
+ return NULL;
+ }
+
+ return STRDUP(var.m_val.pcVal);
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FileNameDat was empty",
+ "IndexProperty_GetFileNameExtensionDat");
+ return NULL;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetFileNameExtensionIdx( IndexPropertyH hProp,
+ const char* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetFileNameExtensionIdx",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = STRDUP(value); // not sure if we should copy here
+ prop->setProperty("FileNameIdx", var);
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetFileNameExtensionIdx");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetFileNameExtensionIdx");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetFileNameExtensionIdx");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL char* IndexProperty_GetFileNameExtensionIdx(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetFileNameExtensionIdx", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("FileNameIdx");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR) {
+ Error_PushError(RT_Failure,
+ "Property FileNameIdx must be Tools::VT_PCHAR",
+ "IndexProperty_GetFileNameExtensionIdx");
+ return NULL;
+ }
+
+ return STRDUP(var.m_val.pcVal);
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property FileNameIdx was empty",
+ "IndexProperty_GetFileNameExtensionIdx");
+ return NULL;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetCustomStorageCallbacksSize(IndexPropertyH hProp,
+ uint32_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetCustomStorageCallbacksSize", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = value;
+ prop->setProperty("CustomStorageCallbacksSize", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetCustomStorageCallbacksSize");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetCustomStorageCallbacksSize");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetCustomStorageCallbacksSize");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL uint32_t IndexProperty_GetCustomStorageCallbacksSize(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetCustomStorageCallbacksSize", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("CustomStorageCallbacksSize");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) {
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacksSize must be Tools::VT_ULONG",
+ "IndexProperty_GetCustomStorageCallbacksSize");
+ return 0;
+ }
+
+ return var.m_val.ulVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacksSize was empty",
+ "IndexProperty_GetCustomStorageCallbacksSize");
+ return 0;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetCustomStorageCallbacks( IndexPropertyH hProp,
+ const void* value)
+{
+ VALIDATE_POINTER1( hProp,
+ "IndexProperty_SetCustomStorageCallbacks",
+ RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ // check if the CustomStorageCallbacksSize is alright, so we can make a copy of the passed in structure
+ Tools::Variant varSize;
+ varSize = prop->getProperty("CustomStorageCallbacksSize");
+ if ( varSize.m_val.ulVal != sizeof(SpatialIndex::StorageManager::CustomStorageManagerCallbacks) )
+ {
+ std::ostringstream ss;
+ ss << "The supplied storage callbacks size is wrong, expected "
+ << sizeof(SpatialIndex::StorageManager::CustomStorageManagerCallbacks)
+ << ", got " << varSize.m_val.ulVal;
+ Error_PushError(RT_Failure,
+ ss.str().c_str(),
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ }
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_PVOID;
+ var.m_val.pvVal = value ?
+ new SpatialIndex::StorageManager::CustomStorageManagerCallbacks(
+ *static_cast<const SpatialIndex::StorageManager::CustomStorageManagerCallbacks*>(value)
+ )
+ : 0;
+ prop->setProperty("CustomStorageCallbacks", var);
+
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetCustomStorageCallbacks");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL void* IndexProperty_GetCustomStorageCallbacks(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetCustomStorageCallbacks", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("CustomStorageCallbacks");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PVOID) {
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacks must be Tools::VT_PVOID",
+ "IndexProperty_GetCustomStorageCallbacks");
+ return NULL;
+ }
+
+ return var.m_val.pvVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property CustomStorageCallbacks was empty",
+ "IndexProperty_GetCustomStorageCallbacks");
+ return NULL;
+}
+
+SIDX_C_DLL RTError IndexProperty_SetIndexID(IndexPropertyH hProp,
+ int64_t value)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_SetIndexID", RT_Failure);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ try
+ {
+ Tools::Variant var;
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = value;
+ prop->setProperty("IndexIdentifier", var);
+ } catch (Tools::Exception& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what().c_str(),
+ "IndexProperty_SetIndexID");
+ return RT_Failure;
+ } catch (std::exception const& e)
+ {
+ Error_PushError(RT_Failure,
+ e.what(),
+ "IndexProperty_SetIndexID");
+ return RT_Failure;
+ } catch (...) {
+ Error_PushError(RT_Failure,
+ "Unknown Error",
+ "IndexProperty_SetIndexID");
+ return RT_Failure;
+ }
+ return RT_None;
+}
+
+SIDX_C_DLL int64_t IndexProperty_GetIndexID(IndexPropertyH hProp)
+{
+ VALIDATE_POINTER1(hProp, "IndexProperty_GetIndexID", 0);
+ Tools::PropertySet* prop = static_cast<Tools::PropertySet*>(hProp);
+
+ Tools::Variant var;
+ var = prop->getProperty("IndexIdentifier");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONGLONG) {
+ Error_PushError(RT_Failure,
+ "Property IndexIdentifier must be Tools::VT_LONGLONG",
+ "IndexProperty_GetIndexID");
+ return 0;
+ }
+
+ return var.m_val.llVal;
+ }
+
+ // return nothing for an error
+ Error_PushError(RT_Failure,
+ "Property IndexIdentifier was empty",
+ "IndexProperty_GetIndexID");
+ return 0;
+}
+
+SIDX_C_DLL void* SIDX_NewBuffer(size_t length)
+{
+ return new char[length];
+}
+
+SIDX_C_DLL void SIDX_DeleteBuffer(void* buffer)
+{
+ delete []buffer;
+}
+
+
+SIDX_C_DLL char* SIDX_Version()
+{
+
+ std::ostringstream ot;
+
+#ifdef SIDX_RELEASE_NAME
+ ot << SIDX_RELEASE_NAME;
+#else
+ ot << "1.3.2";
+#endif
+
+ std::string out(ot.str());
+ return STRDUP(out.c_str());
+
+}
+IDX_C_END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/all-wcprops
new file mode 100644
index 000000000..870c8c628
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/all-wcprops
@@ -0,0 +1,77 @@
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/mvrtree
+END
+Statistics.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/Statistics.h
+END
+PointerPoolNode.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/PointerPoolNode.h
+END
+MVRTree.cc
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/mvrtree/MVRTree.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/45/spatialindex/trunk/src/mvrtree/Makefile.am
+END
+Node.cc
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/mvrtree/Node.cc
+END
+MVRTree.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/133/spatialindex/trunk/src/mvrtree/MVRTree.h
+END
+Index.cc
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/mvrtree/Index.cc
+END
+Leaf.cc
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/Leaf.cc
+END
+Node.h
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/Node.h
+END
+Index.h
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/Index.h
+END
+Leaf.h
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/Leaf.h
+END
+Statistics.cc
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/mvrtree/Statistics.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/dir-prop-base
new file mode 100644
index 000000000..ea9b95e8a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/dir-prop-base
@@ -0,0 +1,9 @@
+K 10
+svn:ignore
+V 33
+Makefile.in
+.libs
+.deps
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/entries
new file mode 100644
index 000000000..7578fc788
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/entries
@@ -0,0 +1,436 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/mvrtree
+http://svn.gispython.org/spatialindex
+
+
+
+2009-11-02T20:08:16.754818Z
+159
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Statistics.h
+file
+
+
+
+
+2011-08-01T00:42:34.585398Z
+46097afdf587be1e2946c68370a63c58
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2378
+
+PointerPoolNode.h
+file
+
+
+
+
+2011-08-01T00:42:34.585398Z
+28baf97a05d4debc58e4560ec41bb6da
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2788
+
+MVRTree.cc
+file
+
+
+
+
+2011-08-01T00:42:34.585398Z
+db395a4df8ffff429090625d6e9c3801
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+42471
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.585398Z
+d9c9482e6c8fc615fa50b171bc4b519c
+2008-01-17T23:34:01.575758Z
+45
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+273
+
+Node.cc
+file
+
+
+
+
+2011-08-01T00:42:34.585398Z
+133b545522606cb58fc3decd6fe9d8de
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+45560
+
+MVRTree.h
+file
+
+
+
+
+2011-08-01T00:42:34.589408Z
+696b326d73b2b9882492dfd6c9532011
+2009-08-14T15:19:40.553411Z
+133
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7501
+
+Index.cc
+file
+
+
+
+
+2011-08-01T00:42:34.589408Z
+764bad93562eae7f748a4fb2cd8f24cc
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+12251
+
+Leaf.cc
+file
+
+
+
+
+2011-08-01T00:42:34.617112Z
+31d2b21592badd5cdd98748c86c230e0
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3353
+
+Node.h
+file
+
+
+
+
+2011-08-01T00:42:34.654108Z
+0c92c89effd91685adc289817b5cd248
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6069
+
+Index.h
+file
+
+
+
+
+2011-08-01T00:42:34.654108Z
+3d4f0e095cf33749ba3869a0ab7cf0a7
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2236
+
+Leaf.h
+file
+
+
+
+
+2011-08-01T00:42:34.654108Z
+c9fc6307581bd2bdfd33ee7ce084888c
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1464
+
+Statistics.cc
+file
+
+
+
+
+2011-08-01T00:42:34.654108Z
+9e2c3dfd9b9c9bc027858a52a1660a27
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4515
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.cc.svn-base
new file mode 100644
index 000000000..ba5d0e113
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.cc.svn-base
@@ -0,0 +1,429 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MVRTree.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+
+using namespace SpatialIndex::MVRTree;
+
+Index::~Index()
+{
+}
+
+Index::Index(SpatialIndex::MVRTree::MVRTree* pTree, id_type id, uint32_t level) : Node(pTree, id, level, pTree->m_indexCapacity)
+{
+}
+
+NodePtr Index::chooseSubtree(const TimeRegion& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
+{
+ if (m_level == insertionLevel) return NodePtr(this, &(m_pTree->m_indexPool));
+
+ pathBuffer.push(m_identifier);
+
+ uint32_t child = 0;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ child = findLeastEnlargement(mbr);
+ break;
+ case RV_RSTAR:
+ if (m_level == 1)
+ {
+ // if this node points to leaves...
+ child = findLeastOverlap(mbr);
+ }
+ else
+ {
+ child = findLeastEnlargement(mbr);
+ }
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::chooseSubtree: Tree variant not supported.");
+ }
+ assert (child != std::numeric_limits<uint32_t>::max());
+
+ NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
+ NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
+ assert(n.unique());
+ if (ret.get() == n.get()) n.relinquish();
+
+ return ret;
+}
+
+NodePtr Index::findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // check live nodes only.
+ if (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max()) continue;
+ //if (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max() ||
+ // m_ptrMBR[cChild]->m_startTime > mbr.m_startTime) continue;
+
+ if (m_ptrMBR[cChild]->containsRegion(mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findLeaf(mbr, id, pathBuffer);
+ if (n.get() == l.get()) n.relinquish();
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
+
+void Index::split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_indexPool.acquire();
+ pRight = m_pTree->m_indexPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(0, 0, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(0, 0, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ }
+}
+
+uint32_t Index::findLeastEnlargement(const TimeRegion& r) const
+{
+ double area = std::numeric_limits<double>::max();
+ uint32_t best = std::numeric_limits<uint32_t>::max();
+
+ TimeRegionPtr t = m_pTree->m_regionPool.acquire();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // if this child is already dead do not consider it.
+ if (m_ptrMBR[cChild]->m_endTime <= r.m_startTime) continue;
+
+ m_ptrMBR[cChild]->getCombinedRegion(*t, r);
+
+ double a = m_ptrMBR[cChild]->getArea();
+ double enl = t->getArea() - a;
+
+ if (enl < area)
+ {
+ area = enl;
+ best = cChild;
+ }
+ else if (
+ enl > area - std::numeric_limits<double>::epsilon() &&
+ enl < area + std::numeric_limits<double>::epsilon())
+ {
+ if (a < m_ptrMBR[best]->getArea()) best = cChild;
+ }
+ }
+
+#ifndef NDEBUG
+ if (best == std::numeric_limits<uint32_t>::max())
+ {
+ std::ostringstream s;
+ s << "findLeastEnlargement: All entries of node " << m_identifier << " are dead.";
+ throw Tools::IllegalStateException(s.str());
+ }
+#endif
+
+ return best;
+}
+
+uint32_t Index::findLeastOverlap(const TimeRegion& r) const
+{
+ OverlapEntry** entries = new OverlapEntry*[m_children];
+
+ double leastOverlap = std::numeric_limits<double>::max();
+ double me = std::numeric_limits<double>::max();
+ OverlapEntry* best = 0;
+ uint32_t cLiveEntries = 0;
+
+ // find combined region and enlargement of every entry and store it.
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->m_endTime <= r.m_startTime) continue;
+
+ try
+ {
+ entries[cLiveEntries] = new OverlapEntry();
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cLiveEntries; ++i) delete entries[i];
+ delete[] entries;
+ throw;
+ }
+
+ entries[cLiveEntries]->m_index = cChild;
+ entries[cLiveEntries]->m_original = m_ptrMBR[cChild];
+ entries[cLiveEntries]->m_combined = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->getCombinedRegion(*(entries[cLiveEntries]->m_combined), r);
+ entries[cLiveEntries]->m_oa = entries[cLiveEntries]->m_original->getArea();
+ entries[cLiveEntries]->m_ca = entries[cLiveEntries]->m_combined->getArea();
+ entries[cLiveEntries]->m_enlargement = entries[cLiveEntries]->m_ca - entries[cLiveEntries]->m_oa;
+
+ if (entries[cLiveEntries]->m_enlargement < me)
+ {
+ me = entries[cLiveEntries]->m_enlargement;
+ best = entries[cLiveEntries];
+ }
+ else if (entries[cLiveEntries]->m_enlargement == me && entries[cLiveEntries]->m_oa < best->m_oa)
+ {
+ best = entries[cLiveEntries];
+ }
+ ++cLiveEntries;
+ }
+
+#ifndef NDEBUG
+ if (cLiveEntries == 0)
+ {
+ std::ostringstream s;
+ s << "findLeastOverlap: All entries of node " << m_identifier << " are dead.";
+ throw Tools::IllegalStateException(s.str());
+ }
+#endif
+
+ if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
+ {
+ uint32_t cIterations;
+
+ if (cLiveEntries > m_pTree->m_nearMinimumOverlapFactor)
+ {
+ // sort entries in increasing order of enlargement.
+ ::qsort(entries, cLiveEntries,
+ sizeof(OverlapEntry*),
+ OverlapEntry::compareEntries);
+ assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
+
+ cIterations = m_pTree->m_nearMinimumOverlapFactor;
+ }
+ else
+ {
+ cIterations = cLiveEntries;
+ }
+
+ // calculate overlap of most important original entries (near minimum overlap cost).
+ for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
+ {
+ double dif = 0.0;
+ OverlapEntry* e = entries[cIndex];
+
+ for (uint32_t cChild = 0; cChild < cLiveEntries; ++cChild)
+ {
+ if (cIndex != cChild)
+ {
+ double f = e->m_combined->getIntersectingArea(*(entries[cChild]->m_original));
+ if (f != 0.0) dif += f - e->m_original->getIntersectingArea(*(entries[cChild]->m_original));
+ }
+ } // for (cChild)
+
+ if (dif < leastOverlap)
+ {
+ leastOverlap = dif;
+ best = e;
+ }
+ else if (dif == leastOverlap)
+ {
+ if (e->m_enlargement == best->m_enlargement)
+ {
+ // keep the one with least area.
+ if (e->m_original->getArea() < best->m_original->getArea()) best = e;
+ }
+ else
+ {
+ // keep the one with least enlargement.
+ if (e->m_enlargement < best->m_enlargement) best = e;
+ }
+ }
+ } // for (cIndex)
+ }
+
+ uint32_t ret = best->m_index;
+
+ for (uint32_t cChild = 0; cChild < cLiveEntries; ++cChild)
+ {
+ delete entries[cChild];
+ }
+ delete[] entries;
+
+ return ret;
+}
+
+void Index::adjustTree(Node* n, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ bool bContained = m_nodeMBR.containsRegion(n->m_nodeMBR);
+ bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
+
+ // we should not adjust time here
+ double st = m_ptrMBR[child]->m_startTime;
+ double en = m_ptrMBR[child]->m_endTime;
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+ m_ptrMBR[child]->m_startTime = st;
+ m_ptrMBR[child]->m_endTime = en;
+
+ if (bRecompute)
+ {
+ // no need to update times here. The inserted MBR is younger than all nodes.
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ if (bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
+
+void Index::adjustTree(Node* n, Node* nn, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child, child2 = m_capacity;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == nn->m_identifier) child2 = child;
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+
+ if (child2 == m_capacity)
+ {
+ for (child2 = child + 1; child2 < m_children; ++child2)
+ {
+ if (m_pIdentifier[child2] == nn->m_identifier) break;
+ }
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ // 3. the SIBLING MBR is touching.
+ bool b1 = m_nodeMBR.containsRegion(n->m_nodeMBR);
+ bool b2 = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool b3 = m_nodeMBR.touchesRegion(*(m_ptrMBR[child2]));
+ bool bRecompute = (! b1) || ((b2 || b3) && m_pTree->m_bTightMBRs);
+
+ // we should not adjust time here
+ double st = m_ptrMBR[child]->m_startTime;
+ double en = m_ptrMBR[child]->m_endTime;
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+ m_ptrMBR[child]->m_startTime = st;
+ m_ptrMBR[child]->m_endTime = en;
+
+ st = m_ptrMBR[child2]->m_startTime;
+ en = m_ptrMBR[child2]->m_endTime;
+ *(m_ptrMBR[child2]) = nn->m_nodeMBR;
+ m_ptrMBR[child2]->m_startTime = st;
+ m_ptrMBR[child2]->m_endTime = en;
+
+ if (bRecompute)
+ {
+ // no need to update times here. The inserted MBR is younger than all nodes.
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ if (bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.h.svn-base
new file mode 100644
index 000000000..e5fa86a8c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Index.h.svn-base
@@ -0,0 +1,75 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class Index : public Node
+ {
+ public:
+ virtual ~Index();
+
+ private:
+ Index(MVRTree* pTree, id_type id, uint32_t level);
+
+ virtual NodePtr chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& left, NodePtr& right,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+
+ uint32_t findLeastEnlargement(const TimeRegion&) const;
+ uint32_t findLeastOverlap(const TimeRegion&) const;
+
+ void adjustTree(Node*, std::stack<id_type>&);
+ void adjustTree(Node* n, Node* nn, std::stack<id_type>& pathBuffer);
+
+ class OverlapEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_enlargement;
+ TimeRegionPtr m_original;
+ TimeRegionPtr m_combined;
+ double m_oa;
+ double m_ca;
+
+ static int compareEntries(const void* pv1, const void* pv2)
+ {
+ OverlapEntry* pe1 = * (OverlapEntry**) pv1;
+ OverlapEntry* pe2 = * (OverlapEntry**) pv2;
+
+ if (pe1->m_enlargement < pe2->m_enlargement) return -1;
+ if (pe1->m_enlargement > pe2->m_enlargement) return 1;
+ return 0;
+ }
+ }; // OverlapEntry
+
+ friend class MVRTree;
+ friend class Node;
+ }; // Index
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.cc.svn-base
new file mode 100644
index 000000000..925c170da
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.cc.svn-base
@@ -0,0 +1,103 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MVRTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::MVRTree;
+
+Leaf::~Leaf()
+{
+}
+
+Leaf::Leaf(SpatialIndex::MVRTree::MVRTree* pTree, id_type id): Node(pTree, id, 0, pTree->m_leafCapacity)
+{
+}
+
+NodePtr Leaf::chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer)
+{
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ return NodePtr(this, &(m_pTree->m_leafPool));
+}
+
+NodePtr Leaf::findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ if (m_pIdentifier[cChild] == id && static_cast<Region>(mbr) == static_cast<Region>(*(m_ptrMBR[cChild])))
+ return NodePtr(this, &(m_pTree->m_leafPool));
+ }
+
+ return NodePtr();
+}
+
+void Leaf::split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_leafPool.acquire();
+ pRight = m_pTree->m_leafPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g1[cIndex]] = 0;
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g2[cIndex]] = 0;
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.h.svn-base
new file mode 100644
index 000000000..02d653c45
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Leaf.h.svn-base
@@ -0,0 +1,48 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class Leaf : public Node
+ {
+ public:
+ virtual ~Leaf();
+
+ private:
+ Leaf(MVRTree* pTree, id_type id);
+
+ virtual NodePtr chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& left, NodePtr& right,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+
+ friend class MVRTree;
+ friend class Node;
+ }; // Leaf
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.cc.svn-base
new file mode 100644
index 000000000..7520e6689
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.cc.svn-base
@@ -0,0 +1,1423 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "MVRTree.h"
+
+#include <cstring>
+
+using namespace SpatialIndex::MVRTree;
+
+SpatialIndex::MVRTree::Data::Data(uint32_t len, byte* pData, TimeRegion& r, id_type id)
+ : m_id(id), m_region(r), m_pData(0), m_dataLength(len)
+{
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, pData, m_dataLength);
+ }
+}
+
+SpatialIndex::MVRTree::Data::~Data()
+{
+ delete[] m_pData;
+}
+
+SpatialIndex::MVRTree::Data* SpatialIndex::MVRTree::Data::clone()
+{
+ return new Data(m_dataLength, m_pData, m_region, m_id);
+}
+
+SpatialIndex::id_type SpatialIndex::MVRTree::Data::getIdentifier() const
+{
+ return m_id;
+}
+
+void SpatialIndex::MVRTree::Data::getShape(IShape** out) const
+{
+ *out = new TimeRegion(m_region);
+}
+
+void SpatialIndex::MVRTree::Data::getData(uint32_t& len, byte** data) const
+{
+ len = m_dataLength;
+ *data = 0;
+
+ if (m_dataLength > 0)
+ {
+ *data = new byte[m_dataLength];
+ memcpy(*data, m_pData, m_dataLength);
+ }
+}
+
+uint32_t SpatialIndex::MVRTree::Data::getByteArraySize()
+{
+ return
+ sizeof(id_type) +
+ sizeof(uint32_t) +
+ m_dataLength +
+ m_region.getByteArraySize();
+}
+
+void SpatialIndex::MVRTree::Data::loadFromByteArray(const byte* ptr)
+{
+ memcpy(&m_id, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ delete[] m_pData;
+ m_pData = 0;
+
+ memcpy(&m_dataLength, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, ptr, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ m_region.loadFromByteArray(ptr);
+}
+
+void SpatialIndex::MVRTree::Data::storeToByteArray(byte** data, uint32_t& len)
+{
+ // it is thread safe this way.
+ uint32_t regionsize;
+ byte* regiondata = 0;
+ m_region.storeToByteArray(&regiondata, regionsize);
+
+ len = sizeof(id_type) + sizeof(uint32_t) + m_dataLength + regionsize;
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_id, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_dataLength, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ memcpy(ptr, m_pData, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ memcpy(ptr, regiondata, regionsize);
+ delete[] regiondata;
+ // ptr += regionsize;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::MVRTree::returnMVRTree(SpatialIndex::IStorageManager& sm, Tools::PropertySet& ps)
+{
+ SpatialIndex::ISpatialIndex* si = new SpatialIndex::MVRTree::MVRTree(sm, ps);
+ return si;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::MVRTree::createNewMVRTree(
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ MVRTreeVariant rv,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = fillFactor;
+ ps.setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = indexCapacity;
+ ps.setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = leafCapacity;
+ ps.setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = dimension;
+ ps.setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = rv;
+ ps.setProperty("TreeVariant", var);
+
+ ISpatialIndex* ret = returnMVRTree(sm, ps);
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var = ps.getProperty("IndexIdentifier");
+ indexIdentifier = var.m_val.llVal;
+
+ return ret;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::MVRTree::loadMVRTree(IStorageManager& sm, id_type indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = indexIdentifier;
+ ps.setProperty("IndexIdentifier", var);
+
+ return returnMVRTree(sm, ps);
+}
+
+SpatialIndex::MVRTree::MVRTree::MVRTree(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_pStorageManager(&sm),
+ m_headerID(StorageManager::NewPage),
+ m_treeVariant(RV_RSTAR),
+ m_fillFactor(0.7),
+ m_indexCapacity(100),
+ m_leafCapacity(100),
+ m_nearMinimumOverlapFactor(32),
+ m_splitDistributionFactor(0.4),
+ m_reinsertFactor(0.3),
+ m_strongVersionOverflow(0.8),
+ //m_strongVersionUnderflow(0.2),
+ m_versionUnderflow(0.3),
+ m_dimension(2),
+ m_bTightMBRs(true),
+ m_bHasVersionCopied(false),
+ m_currentTime(0.0),
+ m_pointPool(500),
+ m_regionPool(1000),
+ m_indexPool(100),
+ m_leafPool(100)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+
+ Tools::Variant var = ps.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType == Tools::VT_LONGLONG) m_headerID = var.m_val.llVal;
+ else if (var.m_varType == Tools::VT_LONG) m_headerID = var.m_val.lVal;
+ // for backward compatibility only.
+ else throw Tools::IllegalArgumentException("MVRTree: Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ initOld(ps);
+ }
+ else
+ {
+ initNew(ps);
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = m_headerID;
+ ps.setProperty("IndexIdentifier", var);
+ }
+}
+
+SpatialIndex::MVRTree::MVRTree::~MVRTree()
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_destroy(&m_rwLock);
+#endif
+
+ storeHeader();
+}
+
+//
+// ISpatialIndex interface
+//
+
+void SpatialIndex::MVRTree::MVRTree::insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (ti == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IInterval interface.");
+ if (ti->getLowerBound() < m_currentTime) throw Tools::IllegalArgumentException("insertData: Shape start time is older than tree current time.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("insertData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ // convert the shape into a TimeRegion (R-Trees index regions only; i.e., approximations of the shapes).
+ Region mbrold;
+ shape.getMBR(mbrold);
+
+ TimeRegionPtr mbr = m_regionPool.acquire();
+ mbr->makeDimension(mbrold.m_dimension);
+
+ memcpy(mbr->m_pLow, mbrold.m_pLow, mbrold.m_dimension * sizeof(double));
+ memcpy(mbr->m_pHigh, mbrold.m_pHigh, mbrold.m_dimension * sizeof(double));
+ mbr->m_startTime = ti->getLowerBound();
+ mbr->m_endTime = std::numeric_limits<double>::max();
+
+ byte* buffer = 0;
+
+ if (len > 0)
+ {
+ buffer = new byte[len];
+ memcpy(buffer, pData, len);
+ }
+
+ insertData_impl(len, buffer, *mbr, id);
+ // the buffer is stored in the tree. Do not delete here.
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+bool SpatialIndex::MVRTree::MVRTree::deleteData(const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("deleteData: Shape has the wrong number of dimensions.");
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (ti == 0) throw Tools::IllegalArgumentException("deleteData: Shape does not support the Tools::IInterval interface.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("deleteData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ Region mbrold;
+ shape.getMBR(mbrold);
+
+ TimeRegionPtr mbr = m_regionPool.acquire();
+ mbr->makeDimension(mbrold.m_dimension);
+
+ memcpy(mbr->m_pLow, mbrold.m_pLow, mbrold.m_dimension * sizeof(double));
+ memcpy(mbr->m_pHigh, mbrold.m_pHigh, mbrold.m_dimension * sizeof(double));
+ mbr->m_startTime = ti->getLowerBound();
+ mbr->m_endTime = ti->getUpperBound();
+
+ bool ret = deleteData_impl(*mbr, id);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ return ret;
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::containsWhatQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("containsWhatQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(ContainmentQuery, query, v);
+}
+
+void SpatialIndex::MVRTree::MVRTree::intersectsWithQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("intersectsWithQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(IntersectionQuery, query, v);
+}
+
+void SpatialIndex::MVRTree::MVRTree::pointLocationQuery(const Point& query, IVisitor& v)
+{
+ if (query.m_dimension != m_dimension) throw Tools::IllegalArgumentException("pointLocationQuery: Shape has the wrong number of dimensions.");
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&query);
+ if (ti == 0) throw Tools::IllegalArgumentException("pointLocationQuery: Shape does not support the Tools::IInterval interface.");
+ TimeRegion r(query, query, *ti);
+ rangeQuery(IntersectionQuery, r, v);
+}
+
+void SpatialIndex::MVRTree::MVRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc)
+{
+ throw Tools::IllegalStateException("nearestNeighborQuery: not impelmented yet.");
+}
+
+void SpatialIndex::MVRTree::MVRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+ NNComparator nnc;
+ nearestNeighborQuery(k, query, v, nnc);
+}
+
+void SpatialIndex::MVRTree::MVRTree::selfJoinQuery(const IShape& query, IVisitor& v)
+{
+ throw Tools::IllegalStateException("selfJoinQuery: not impelmented yet.");
+}
+
+void SpatialIndex::MVRTree::MVRTree::queryStrategy(IQueryStrategy& qs)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");
+#endif
+
+ id_type next = m_roots[m_roots.size() - 1].m_id;
+ bool hasNext = true;
+
+ try
+ {
+ while (hasNext)
+ {
+ NodePtr n = readNode(next);
+ qs.getNextEntry(*n, next, hasNext);
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::getIndexProperties(Tools::PropertySet& out) const
+{
+ Tools::Variant var;
+
+ // dimension
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_dimension;
+ out.setProperty("Dimension", var);
+
+ // index capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexCapacity;
+ out.setProperty("IndexCapacity", var);
+
+ // leaf capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafCapacity;
+ out.setProperty("LeafCapacity", var);
+
+ // Tree variant
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = m_treeVariant;
+ out.setProperty("TreeVariant", var);
+
+ // fill factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_fillFactor;
+ out.setProperty("FillFactor", var);
+
+ // near minimum overlap factor
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_nearMinimumOverlapFactor;
+ out.setProperty("NearMinimumOverlapFactor", var);
+
+ // split distribution factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_splitDistributionFactor;
+ out.setProperty("SplitDistributionFactor", var);
+
+ // reinsert factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_reinsertFactor;
+ out.setProperty("ReinsertFactor", var);
+
+ // tight MBRs
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = m_bTightMBRs;
+ out.setProperty("EnsureTightMBRs", var);
+
+ // index pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexPool.getCapacity();
+ out.setProperty("IndexPoolCapacity", var);
+
+ // leaf pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafPool.getCapacity();
+ out.setProperty("LeafPoolCapacity", var);
+
+ // region pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_regionPool.getCapacity();
+ out.setProperty("RegionPoolCapacity", var);
+
+ // point pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_pointPool.getCapacity();
+ out.setProperty("PointPoolCapacity", var);
+
+ // strong version overflow
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_strongVersionOverflow;
+ out.setProperty("StrongVersionOverflow", var);
+
+ // strong version underflow
+ //var.m_varType = Tools::VT_DOUBLE;
+ //var.m_val.dblVal = m_strongVersionUnderflow;
+ //out.setProperty("StrongVersionUnderflow", var);
+
+ // weak version underflow
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_versionUnderflow;
+ out.setProperty("VersionUnderflow", var);
+}
+
+void SpatialIndex::MVRTree::MVRTree::addCommand(ICommand* pCommand, CommandType ct)
+{
+ switch (ct)
+ {
+ case CT_NODEREAD:
+ m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEWRITE:
+ m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEDELETE:
+ m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ }
+}
+
+bool SpatialIndex::MVRTree::MVRTree::isIndexValid()
+{
+ bool ret = true;
+ std::stack<ValidateEntry> st;
+ std::set<id_type> visitedEntries;
+ uint32_t degenerateEntries = 0;
+
+ for (uint32_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
+ {
+ NodePtr root = readNode(m_roots[cRoot].m_id);
+
+ if (root->m_level != m_stats.m_treeHeight[cRoot] - 1)
+ {
+ std::cerr << "Invalid tree height." << std::endl;
+ return false;
+ }
+
+ ValidateEntry e(0, root->m_nodeMBR, root);
+ e.m_bIsDead = (root->m_nodeMBR.m_endTime < std::numeric_limits<double>::max()) ? true : false;
+ st.push(e);
+ }
+
+ while (! st.empty())
+ {
+ ValidateEntry e = st.top(); st.pop();
+
+ std::set<id_type>::iterator itSet = visitedEntries.find(e.m_pNode->m_identifier);
+ if (itSet == visitedEntries.end())
+ {
+ visitedEntries.insert(e.m_pNode->m_identifier);
+ if (e.m_pNode->m_nodeMBR.m_startTime == e.m_pNode->m_nodeMBR.m_endTime) ++degenerateEntries;
+ }
+
+ TimeRegion tmpRegion;
+ tmpRegion = m_infiniteRegion;
+
+ for (uint32_t cDim = 0; cDim < tmpRegion.m_dimension; ++cDim)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]);
+ tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+
+ tmpRegion.m_startTime = e.m_pNode->m_nodeMBR.m_startTime;
+ tmpRegion.m_endTime = e.m_pNode->m_nodeMBR.m_endTime;
+ if (! (tmpRegion == e.m_pNode->m_nodeMBR))
+ {
+ std::cerr << "Invalid parent information." << std::endl;
+ ret = false;
+ }
+
+ if (! e.m_bIsDead)
+ {
+ tmpRegion.m_startTime = e.m_parentMBR.m_startTime;
+ tmpRegion.m_endTime = e.m_parentMBR.m_endTime;
+ if (! (tmpRegion == e.m_parentMBR))
+ {
+ std::cerr << "Error in parent (Node id: " << e.m_pNode->m_identifier << ", Parent id: " << e.m_parentID << ")." << std::endl;
+ ret = false;
+ }
+ }
+
+ if (e.m_pNode->m_level != 0)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
+
+ bool bIsDead =
+ (e.m_pNode->m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max() || e.m_bIsDead) ? true : false;
+
+ // if the parent says that this child is dead, force it dead since
+ // this information is not propagated for efficiency and is inconsistent.
+ if (bIsDead) ptrN->m_nodeMBR.m_endTime = e.m_pNode->m_ptrMBR[cChild]->m_endTime;
+
+ ValidateEntry tmpEntry(e.m_pNode->m_identifier, *(e.m_pNode->m_ptrMBR[cChild]), ptrN);
+ tmpEntry.m_bIsDead = bIsDead;
+ st.push(tmpEntry);
+ }
+ }
+ }
+
+ //std::cerr << "Total accessible nodes: " << visitedEntries.size() << std::endl;
+ //std::cerr << "Degenerate nodes: " << degenerateEntries << std::endl;
+
+ return ret;
+}
+
+void SpatialIndex::MVRTree::MVRTree::getStatistics(IStatistics** out) const
+{
+ *out = new Statistics(m_stats);
+}
+
+void SpatialIndex::MVRTree::MVRTree::initNew(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG || (var.m_val.lVal != RV_LINEAR && var.m_val.lVal != RV_QUADRATIC && var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of MVRTreeVariant type");
+
+ m_treeVariant = static_cast<MVRTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ //((m_treeVariant == RV_LINEAR || m_treeVariant == RV_QUADRATIC) && var.m_val.dblVal > 0.5) ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor must be Tools::VT_DOUBLE and in (0.0, 1.0) for RSTAR, (0.0, 0.5) for LINEAR and QUADRATIC");
+
+ m_fillFactor = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 10)
+ throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 10");
+
+ m_indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 10)
+ throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 10");
+
+ m_leafCapacity = var.m_val.ulVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 1 || var.m_val.ulVal > m_indexCapacity || var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1) throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1");
+
+ m_dimension = var.m_val.ulVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // strong version overflow
+ var = ps.getProperty("StrongVersionOverflow");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property StrongVersionOverflow must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_strongVersionOverflow = var.m_val.dblVal;
+ }
+
+ // strong version underflow
+ //var = ps.getProperty("StrongVersionUnderflow");
+ //if (var.m_varType != Tools::VT_EMPTY)
+ //{
+ // if (var.m_varType != Tools::VT_DOUBLE ||
+ // var.m_val.dblVal <= 0.0 ||
+ // var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("Property StrongVersionUnderflow must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ // m_strongVersionUnderflow = var.m_val.dblVal;
+ //}
+
+ // weak version underflow
+ var = ps.getProperty("VersionUnderflow");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property VersionUnderflow must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_versionUnderflow = var.m_val.dblVal;
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+
+ m_stats.m_treeHeight.push_back(1);
+ m_stats.m_nodesInLevel.push_back(1);
+
+ Leaf root(this, -1);
+ root.m_nodeMBR.m_startTime = 0.0;
+ root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ writeNode(&root);
+ m_roots.push_back(RootEntry(root.m_identifier, root.m_nodeMBR.m_startTime, root.m_nodeMBR.m_endTime));
+
+ storeHeader();
+}
+
+void SpatialIndex::MVRTree::MVRTree::initOld(Tools::PropertySet& ps)
+{
+ loadHeader();
+
+ // only some of the properties may be changed.
+ // the rest are just ignored.
+
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG || (var.m_val.lVal != RV_LINEAR && var.m_val.lVal != RV_QUADRATIC && var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of MVRTreeVariant type");
+
+ m_treeVariant = static_cast<MVRTreeVariant>(var.m_val.lVal);
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 1 || var.m_val.ulVal > m_indexCapacity || var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE ||var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+}
+
+void SpatialIndex::MVRTree::MVRTree::storeHeader()
+{
+ const uint32_t headerSize =
+ sizeof(uint32_t) + // size of m_roots
+ static_cast<uint32_t>(m_roots.size())
+ * (sizeof(id_type) + 2 * sizeof(double)) + // m_roots
+ sizeof(MVRTreeVariant) + // m_treeVariant
+ sizeof(double)+ // m_fillFactor
+ sizeof(uint32_t) + // m_indexCapacity
+ sizeof(uint32_t) + // m_leafCapacity
+ sizeof(uint32_t) + // m_nearMinimumOverlapFactor
+ sizeof(double) + // m_splitDistributionFactor
+ sizeof(double) + // m_reinsertFactor
+ sizeof(uint32_t) + // m_dimension
+ sizeof(byte) + // m_bTightMBRs
+ sizeof(uint32_t) + // m_stats.m_nodes
+ sizeof(uint64_t) + // m_stats.m_totalData
+ sizeof(uint32_t) + // m_stats.m_deadIndexNodes
+ sizeof(uint32_t) + // m_stats.m_deadLeafNodes
+ sizeof(uint64_t) + // m_stats.m_data
+ sizeof(uint32_t) + // size of m_stats.m_treeHeight
+ static_cast<uint32_t>(m_stats.m_treeHeight.size())
+ * sizeof(uint32_t) + // m_stats.m_treeHeight
+ sizeof(double) + // m_strongVersionOverflow
+ //sizeof(double) + // m_strongVersionUnderflow
+ sizeof(double) + // m_versionUnderflow
+ sizeof(double) + // m_currentTime
+ sizeof(uint32_t) + // m_nodesInLevel size
+ static_cast<uint32_t>(m_stats.m_nodesInLevel.size())
+ * sizeof(uint32_t); // m_nodesInLevel values
+
+ byte* header = new byte[headerSize];
+ byte* ptr = header;
+
+ uint32_t u32I = static_cast<uint32_t>(m_roots.size());
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (size_t cIndex = 0; cIndex < m_roots.size(); ++cIndex)
+ {
+ RootEntry& e = m_roots[cIndex];
+ memcpy(ptr, &(e.m_id), sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &(e.m_startTime), sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(e.m_endTime), sizeof(double));
+ ptr += sizeof(double);
+ }
+
+ memcpy(ptr, &m_treeVariant, sizeof(MVRTreeVariant));
+ ptr += sizeof(MVRTreeVariant);
+ memcpy(ptr, &m_fillFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_indexCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_leafCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_splitDistributionFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_reinsertFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ byte c = (byte) m_bTightMBRs;
+ memcpy(ptr, &c, sizeof(byte));
+ ptr += sizeof(byte);
+ memcpy(ptr, &(m_stats.m_u32Nodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u64TotalData), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(ptr, &(m_stats.m_u32DeadIndexNodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u32DeadLeafNodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u64Data), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+
+ u32I = static_cast<uint32_t>(m_stats.m_treeHeight.size());
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (size_t cIndex = 0; cIndex < m_stats.m_treeHeight.size(); ++cIndex)
+ {
+ u32I = m_stats.m_treeHeight[cIndex];
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ memcpy(ptr, &m_strongVersionOverflow, sizeof(double));
+ ptr += sizeof(double);
+ //memcpy(ptr, &m_strongVersionUnderflow, sizeof(double));
+ //ptr += sizeof(double);
+ memcpy(ptr, &m_versionUnderflow, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_currentTime, sizeof(double));
+ ptr += sizeof(double);
+
+ u32I = static_cast<uint32_t>(m_stats.m_nodesInLevel.size());
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (size_t cLevel = 0; cLevel < m_stats.m_nodesInLevel.size(); ++cLevel)
+ {
+ u32I = m_stats.m_nodesInLevel[cLevel];
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
+
+ delete[] header;
+}
+
+void SpatialIndex::MVRTree::MVRTree::loadHeader()
+{
+ uint32_t headerSize;
+ byte* header = 0;
+ m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
+
+ byte* ptr = header;
+
+ uint32_t rootsSize;
+ memcpy(&rootsSize, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cIndex = 0; cIndex < rootsSize; ++cIndex)
+ {
+ RootEntry e;
+ memcpy(&(e.m_id), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&(e.m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(e.m_endTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ m_roots.push_back(e);
+ }
+
+ memcpy(&m_treeVariant, ptr, sizeof(MVRTreeVariant));
+ ptr += sizeof(MVRTreeVariant);
+ memcpy(&m_fillFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_indexCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_leafCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_splitDistributionFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_reinsertFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ byte c;
+ memcpy(&c, ptr, sizeof(byte));
+ m_bTightMBRs = (c != 0);
+ ptr += sizeof(byte);
+ memcpy(&(m_stats.m_u32Nodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u64TotalData), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(&(m_stats.m_u32DeadIndexNodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u32DeadLeafNodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u64Data), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+
+ uint32_t treeHeightSize;
+ memcpy(&treeHeightSize, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cIndex = 0; cIndex < treeHeightSize; ++cIndex)
+ {
+ uint32_t u32I;
+ memcpy(&u32I, ptr, sizeof(uint32_t));
+ m_stats.m_treeHeight.push_back(u32I);
+ ptr += sizeof(uint32_t);
+ }
+
+ memcpy(&m_strongVersionOverflow, ptr, sizeof(double));
+ ptr += sizeof(double);
+ //memcpy(&m_strongVersionUnderflow, ptr, sizeof(double));
+ //ptr += sizeof(double);
+ memcpy(&m_versionUnderflow, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_currentTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ uint32_t nodesInLevelSize;
+ memcpy(&nodesInLevelSize, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < nodesInLevelSize; ++cLevel)
+ {
+ uint32_t u32I;
+ memcpy(&u32I, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ m_stats.m_nodesInLevel.push_back(u32I);
+ }
+
+ delete[] header;
+}
+
+void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id)
+{
+ assert(mbr.getDimension() == m_dimension);
+ assert(m_currentTime <= mbr.m_startTime);
+
+ std::stack<id_type> pathBuffer;
+ m_currentTime = mbr.m_startTime;
+
+ NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
+ NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);
+
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mbr, id, pathBuffer, m_infiniteRegion, -1, false);
+
+ ++(m_stats.m_u64Data);
+ ++(m_stats.m_u64TotalData);
+}
+
+void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, uint32_t level)
+{
+ assert(mbr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+
+ NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
+ NodePtr l = root->chooseSubtree(mbr, level, pathBuffer);
+
+ assert(l->m_level == level);
+
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mbr, id, pathBuffer, m_infiniteRegion, -1, false);
+}
+
+bool SpatialIndex::MVRTree::MVRTree::deleteData_impl(const TimeRegion& mbr, id_type id)
+{
+ assert(mbr.m_dimension == m_dimension);
+
+ m_currentTime = mbr.m_endTime;
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
+ NodePtr l = root->findLeaf(mbr, id, pathBuffer);
+
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+
+ if (l.get() != 0)
+ {
+ l->deleteData(id, mbr.m_endTime, pathBuffer);
+ --(m_stats.m_u64Data);
+ return true;
+ }
+
+ return false;
+}
+
+SpatialIndex::id_type SpatialIndex::MVRTree::MVRTree::writeNode(Node* n)
+{
+ byte* buffer;
+ uint32_t dataLength;
+ n->storeToByteArray(&buffer, dataLength);
+
+ id_type page;
+ if (n->m_identifier < 0) page = StorageManager::NewPage;
+ else page = n->m_identifier;
+
+ try
+ {
+ m_pStorageManager->storeByteArray(page, dataLength, buffer);
+ delete[] buffer;
+ }
+ catch (InvalidPageException& e)
+ {
+ delete[] buffer;
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("writeNode: failed with Tools::InvalidPageException");
+ }
+
+ if (n->m_identifier < 0)
+ {
+ n->m_identifier = page;
+ ++(m_stats.m_u32Nodes);
+ }
+
+ ++(m_stats.m_u64Writes);
+
+ for (size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
+ {
+ m_writeNodeCommands[cIndex]->execute(*n);
+ }
+
+ return page;
+}
+
+SpatialIndex::MVRTree::NodePtr SpatialIndex::MVRTree::MVRTree::readNode(id_type id)
+{
+ uint32_t dataLength;
+ byte* buffer;
+
+ try
+ {
+ m_pStorageManager->loadByteArray(id, dataLength, &buffer);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("readNode: failed with Tools::InvalidPageException");
+ }
+
+ try
+ {
+ uint32_t nodeType;
+ memcpy(&nodeType, buffer, sizeof(uint32_t));
+
+ NodePtr n;
+
+ if (nodeType == PersistentIndex) n = m_indexPool.acquire();
+ else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();
+ else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");
+
+ if (n.get() == 0)
+ {
+ if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);
+ else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);
+ }
+
+ //n->m_pTree = this;
+ n->m_identifier = id;
+ n->loadFromByteArray(buffer);
+
+ ++(m_stats.m_u64Reads);
+
+ for (size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
+ {
+ m_readNodeCommands[cIndex]->execute(*n);
+ }
+
+ delete[] buffer;
+ return n;
+ }
+ catch (...)
+ {
+ delete[] buffer;
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::deleteNode(Node* n)
+{
+ try
+ {
+ m_pStorageManager->deleteByteArray(n->m_identifier);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("deleteNode: failed with Tools::InvalidPageException");
+ }
+
+ --(m_stats.m_u32Nodes);
+
+ for (size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
+ {
+ m_deleteNodeCommands[cIndex]->execute(*n);
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v)
+{
+ // any shape that implements IInterval and IShape, can be used here.
+ // FIXME: I am not using ITimeShape yet, even though I should.
+
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&query);
+ if (ti == 0) throw Tools::IllegalArgumentException("rangeQuery: Shape does not support the Tools::IInterval interface.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::set<id_type> visitedNodes;
+ std::set<id_type> visitedData;
+ std::stack<NodePtr> st;
+ std::vector<id_type> ids;
+ findRootIdentifiers(*ti, ids);
+
+ for (size_t cRoot = 0; cRoot < ids.size(); ++cRoot)
+ {
+ NodePtr root = readNode(ids[cRoot]);
+ if (root->m_children > 0 && query.intersectsShape(root->m_nodeMBR)) st.push(root);
+ }
+
+ while (! st.empty())
+ {
+ NodePtr n = st.top(); st.pop();
+ visitedNodes.insert(n->m_identifier);
+
+ if (n->m_level == 0)
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (visitedData.find(n->m_pIdentifier[cChild]) != visitedData.end()) continue;
+
+ bool b;
+ if (type == ContainmentQuery) b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.containsShape(*(n->m_ptrMBR[cChild]));
+ else b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.intersectsShape(*(n->m_ptrMBR[cChild]));
+
+ if (b)
+ {
+ visitedData.insert(n->m_pIdentifier[cChild]);
+ Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ v.visitData(data);
+ ++(m_stats.m_u64QueryResults);
+ }
+ }
+ }
+ else
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (
+ visitedNodes.find(n->m_pIdentifier[cChild]) == visitedNodes.end() &&
+ n->m_ptrMBR[cChild]->intersectsInterval(*ti) &&
+ query.intersectsShape(*(n->m_ptrMBR[cChild])))
+ st.push(readNode(n->m_pIdentifier[cChild]));
+ }
+ }
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::findRootIdentifiers(const Tools::IInterval& ti, std::vector<id_type>& ids)
+{
+ ids.clear();
+
+ for (size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
+ {
+ RootEntry& e = m_roots[cRoot];
+ if (ti.intersectsInterval(Tools::IT_RIGHTOPEN, e.m_startTime, e.m_endTime)) ids.push_back(e.m_id);
+ }
+}
+
+std::string SpatialIndex::MVRTree::MVRTree::printRootInfo() const
+{
+ std::ostringstream s;
+
+ for (size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
+ {
+ const RootEntry& e = m_roots[cRoot];
+
+ s << "Root " << cRoot << ": Start " << e.m_startTime << ", End " << e.m_endTime << std::endl;
+ }
+
+ return s.str();
+}
+
+std::ostream& SpatialIndex::MVRTree::operator<<(std::ostream& os, const MVRTree& t)
+{
+ os << "Dimension: " << t.m_dimension << std::endl
+ << "Fill factor: " << t.m_fillFactor << std::endl
+ << "Index capacity: " << t.m_indexCapacity << std::endl
+ << "Leaf capacity: " << t.m_leafCapacity << std::endl
+ << "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << std::endl;
+
+ if (t.m_treeVariant == RV_RSTAR)
+ {
+ os << "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
+ << "Reinsert factor: " << t.m_reinsertFactor << std::endl
+ << "Split distribution factor: " << t.m_splitDistributionFactor << std::endl
+ << "Strong version overflow: " << t.m_strongVersionOverflow << std::endl
+ //<< "Strong version underflow: " << t.m_strongVersionUnderflow << std::endl
+ << "Weak version underflow: " << t.m_versionUnderflow << std::endl;
+ }
+
+ // it is difficult to count utilization
+ //os << "Utilization: " << 100 * t.m_stats.m_totalData / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << std::endl
+
+ os << t.m_stats;
+ os << t.printRootInfo();
+
+ #ifndef NDEBUG
+ os << "Leaf pool hits: " << t.m_leafPool.m_hits << std::endl
+ << "Leaf pool misses: " << t.m_leafPool.m_misses << std::endl
+ << "Index pool hits: " << t.m_indexPool.m_hits << std::endl
+ << "Index pool misses: " << t.m_indexPool.m_misses << std::endl
+ << "Region pool hits: " << t.m_regionPool.m_hits << std::endl
+ << "Region pool misses: " << t.m_regionPool.m_misses << std::endl
+ << "Point pool hits: " << t.m_pointPool.m_hits << std::endl
+ << "Point pool misses: " << t.m_pointPool.m_misses << std::endl;
+ #endif
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.h.svn-base
new file mode 100644
index 000000000..cfbe33c1e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/MVRTree.h.svn-base
@@ -0,0 +1,222 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Statistics.h"
+#include "Node.h"
+#include "PointerPoolNode.h"
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class MVRTree : public ISpatialIndex
+ {
+ class NNEntry;
+ class RootEntry;
+
+ public:
+ MVRTree(IStorageManager&, Tools::PropertySet&);
+ // String Value Description
+ // ----------------------------------------------
+ // IndexIndentifier VT_LONG If specified an existing index will be openened from the supplied
+ // storage manager with the given index id. Behaviour is unspecified
+ // if the index id or the storage manager are incorrect.
+ // Dimension VT_ULONG Dimensionality of the data that will be inserted.
+ // IndexCapacity VT_ULONG The index node capacity. Default is 100.
+ // LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+ // FillFactor VT_DOUBLE The fill factor. Default is 70%
+ // TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+ // NearMinimumOverlapFactor VT_ULONG Default is 32.
+ // SplitDistributionFactor VT_DOUBLE Default is 0.4
+ // ReinsertFactor VT_DOUBLE Default is 0.3
+ // EnsureTightMBRs VT_BOOL Default is true
+ // IndexPoolCapacity VT_LONG Default is 100
+ // LeafPoolCapacity VT_LONG Default is 100
+ // RegionPoolCapacity VT_LONG Default is 1000
+ // PointPoolCapacity VT_LONG Default is 500
+ // StrongVersionOverflow VT_DOUBLE Default is 0.8
+ // VersionUnderflow VT_DOUBLE Default is 0.3
+
+ virtual ~MVRTree();
+
+ //
+ // ISpatialIndex interface
+ //
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id);
+ virtual bool deleteData(const IShape& shape, id_type id);
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v);
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v);
+ virtual void pointLocationQuery(const Point& query, IVisitor& v);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator&);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v);
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v);
+ virtual void queryStrategy(IQueryStrategy& qs);
+ virtual void getIndexProperties(Tools::PropertySet& out) const;
+ virtual void addCommand(ICommand* pCommand, CommandType ct);
+ virtual bool isIndexValid();
+ virtual void getStatistics(IStatistics** out) const;
+
+ private:
+ void initNew(Tools::PropertySet&);
+ void initOld(Tools::PropertySet& ps);
+ void storeHeader();
+ void loadHeader();
+
+ void insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id);
+ void insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, uint32_t level);
+ bool deleteData_impl(const TimeRegion& mbr, id_type id);
+
+ id_type writeNode(Node*);
+ NodePtr readNode(id_type id);
+ void deleteNode(Node* n);
+
+ void rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v);
+
+ void findRootIdentifiers(const Tools::IInterval& ti, std::vector<id_type>& ids);
+ std::string printRootInfo() const;
+
+ IStorageManager* m_pStorageManager;
+
+ std::vector<RootEntry> m_roots;
+ id_type m_headerID;
+
+ MVRTreeVariant m_treeVariant;
+
+ double m_fillFactor;
+
+ uint32_t m_indexCapacity;
+
+ uint32_t m_leafCapacity;
+
+ uint32_t m_nearMinimumOverlapFactor;
+ // The R*-Tree 'p' constant, for calculating nearly minimum overlap cost.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles, Section 4.1]
+
+ double m_splitDistributionFactor;
+ // The R*-Tree 'm' constant, for calculating spliting distributions.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles, Section 4.2]
+
+ double m_reinsertFactor;
+ // The R*-Tree 'p' constant, for removing entries at reinserts.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles, Section 4.3]
+
+ double m_strongVersionOverflow;
+ //double m_strongVersionUnderflow;
+ double m_versionUnderflow;
+
+ uint32_t m_dimension;
+
+ TimeRegion m_infiniteRegion;
+
+ SpatialIndex::MVRTree::Statistics m_stats;
+
+ bool m_bTightMBRs;
+
+ bool m_bHasVersionCopied;
+
+ double m_currentTime;
+
+ Tools::PointerPool<Point> m_pointPool;
+ Tools::PointerPool<TimeRegion> m_regionPool;
+ Tools::PointerPool<Node> m_indexPool;
+ Tools::PointerPool<Node> m_leafPool;
+
+ std::vector<Tools::SmartPointer<ICommand> > m_writeNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_readNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_deleteNodeCommands;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+
+ class RootEntry
+ {
+ public:
+ RootEntry() {}
+ RootEntry(id_type id, double s, double e) : m_id(id), m_startTime(s), m_endTime(e) {}
+
+ id_type m_id;
+ double m_startTime;
+ double m_endTime;
+ }; // RootEntry
+
+ class NNEntry
+ {
+ public:
+ id_type m_id;
+ IEntry* m_pEntry;
+ double m_minDist;
+
+ NNEntry(id_type id, IEntry* e, double f) : m_id(id), m_pEntry(e), m_minDist(f) {}
+ ~NNEntry() {}
+
+ struct greater : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_minDist > __y->m_minDist; }
+ };
+ }; // NNEntry
+
+ class NNComparator : public INearestNeighborComparator
+ {
+ public:
+ double getMinimumDistance(const IShape& query, const IShape& entry)
+ {
+ return query.getMinimumDistance(entry);
+ }
+ double getMinimumDistance(const IShape& query, const IData& data)
+ {
+ IShape* pR;
+ data.getShape(&pR);
+ double ret = query.getMinimumDistance(*pR);
+ delete pR;
+ return ret;
+ }
+ }; // NNComparator
+
+ class ValidateEntry
+ {
+ public:
+ ValidateEntry(id_type pid, TimeRegion& r, NodePtr& pNode) : m_parentID(pid), m_parentMBR(r), m_pNode(pNode), m_bIsDead(false) {}
+
+ id_type m_parentID;
+ TimeRegion m_parentMBR;
+ NodePtr m_pNode;
+ bool m_bIsDead;
+ }; // ValidateEntry
+
+ friend class Node;
+ friend class Leaf;
+ friend class Index;
+
+ friend std::ostream& operator<<(std::ostream& os, const MVRTree& t);
+ }; // MVRTree
+
+ std::ostream& operator<<(std::ostream& os, const MVRTree& t);
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..8c28ebe12
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libmvrtree.la
+INCLUDES = -I../../include
+libmvrtree_la_SOURCES = Index.cc Leaf.cc Node.cc MVRTree.cc Statistics.cc Index.h Leaf.h MVRTree.h Node.h PointerPoolNode.h Statistics.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.cc.svn-base
new file mode 100644
index 000000000..b69e665c2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.cc.svn-base
@@ -0,0 +1,1512 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MVRTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::MVRTree;
+
+//
+// Tools::IObject interface
+//
+Tools::IObject* Node::clone()
+{
+ throw Tools::NotSupportedException("IObject::clone should never be called.");
+}
+
+//
+// Tools::ISerializable interface
+//
+uint32_t Node::getByteArraySize()
+{
+ return
+ (sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(double) +
+ sizeof(double) +
+ (m_children * (m_pTree->m_dimension * sizeof(double) * 2 + sizeof(id_type) + 2 * sizeof(double) + sizeof(uint32_t))) +
+ m_totalDataLength +
+ (2 * m_pTree->m_dimension * sizeof(double)));
+}
+
+void Node::loadFromByteArray(const byte* ptr)
+{
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ // skip the node type information, it is not needed.
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_level, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_children, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&(m_nodeMBR.m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(m_nodeMBR.m_endTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_ptrMBR[cChild] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[cChild]) = m_pTree->m_infiniteRegion;
+
+ memcpy(m_ptrMBR[cChild]->m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(&(m_pIdentifier[cChild]), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&(m_ptrMBR[cChild]->m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(m_ptrMBR[cChild]->m_endTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(&(m_pDataLength[cChild]), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ m_totalDataLength += m_pDataLength[cChild];
+ m_pData[cChild] = new byte[m_pDataLength[cChild]];
+ memcpy(m_pData[cChild], ptr, m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ else
+ {
+ m_pData[cChild] = 0;
+ }
+
+ //m_nodeMBR.combineRegion(*(m_ptrMBR[cChild]));
+ }
+
+ memcpy(m_nodeMBR.m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+void Node::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ uint32_t nodeType;
+
+ if (m_level == 0) nodeType = PersistentLeaf;
+ else nodeType = PersistentIndex;
+
+ memcpy(ptr, &nodeType, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_level, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_children, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &(m_nodeMBR.m_startTime), sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(m_nodeMBR.m_endTime), sizeof(double));
+ ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ memcpy(ptr, m_ptrMBR[cChild]->m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, &(m_pIdentifier[cChild]), sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &(m_ptrMBR[cChild]->m_startTime), sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(m_ptrMBR[cChild]->m_endTime), sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, &(m_pDataLength[cChild]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ memcpy(ptr, m_pData[cChild], m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ }
+
+ // store the node MBR for efficiency. This increases the node size a little bit.
+ memcpy(ptr, m_nodeMBR.m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pHigh, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+//
+// SpatialIndex::IEntry interface
+//
+SpatialIndex::id_type Node::getIdentifier() const
+{
+ return m_identifier;
+}
+
+void Node::getShape(IShape** out) const
+{
+ *out = new TimeRegion(m_nodeMBR);
+}
+
+//
+// SpatialIndex::INode interface
+//
+uint32_t Node::getChildrenCount() const
+{
+ return m_children;
+}
+
+SpatialIndex::id_type Node::getChildIdentifier(uint32_t index) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pIdentifier[index];
+}
+
+void Node::getChildShape(uint32_t index, IShape** out) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ *out = new TimeRegion(*(m_ptrMBR[index]));
+}
+
+
+void Node::getChildData(uint32_t index, uint32_t& length, byte** data) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+ if (m_pData[index] == NULL)
+ {
+ length = 0;
+ data = NULL;
+ }
+ else
+ {
+ length = m_pDataLength[index];
+ *data = m_pData[index];
+ }
+}
+
+uint32_t Node::getLevel() const
+{
+ return m_level;
+}
+
+bool Node::isLeaf() const
+{
+ return (m_level == 0);
+}
+
+bool Node::isIndex() const
+{
+ return (m_level != 0);
+}
+
+//
+// Internal
+//
+
+Node::Node() :
+ m_pTree(0),
+ m_level(0),
+ m_identifier(-1),
+ m_children(0),
+ m_capacity(0),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+}
+
+ Node::Node(SpatialIndex::MVRTree::MVRTree* pTree, id_type id, uint32_t level, uint32_t capacity) :
+ m_pTree(pTree),
+ m_level(level),
+ m_identifier(id),
+ m_children(0),
+ m_capacity(capacity),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+ m_nodeMBR.makeInfinite(m_pTree->m_dimension);
+
+ try
+ {
+ m_pDataLength = new uint32_t[m_capacity + 2];
+ m_pData = new byte*[m_capacity + 2];
+ m_ptrMBR = new TimeRegionPtr[m_capacity + 2];
+ m_pIdentifier = new id_type[m_capacity + 2];
+ }
+ catch (...)
+ {
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+ throw;
+ }
+}
+
+Node::~Node()
+{
+ if (m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_pData[cChild] != 0) delete[] m_pData[cChild];
+ }
+
+ delete[] m_pData;
+ delete[] m_pDataLength;
+ }
+
+ if (m_ptrMBR != 0) delete[] m_ptrMBR;
+ if (m_pIdentifier != 0) delete[] m_pIdentifier;
+}
+
+Node& Node::operator=(const Node& n)
+{
+ throw Tools::IllegalStateException("operator =: This should never be called.");
+}
+
+void Node::insertEntry(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id)
+{
+ assert(m_children < m_capacity);
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ m_totalDataLength += dataLength;
+ ++m_children;
+
+ m_nodeMBR.combineRegionInTime(mbr);
+}
+
+bool Node::deleteEntry(uint32_t index)
+{
+ assert(index >= 0 && index < m_children);
+
+ // cache it, since I might need it for "touches" later.
+ TimeRegionPtr ptrR = m_ptrMBR[index];
+
+ m_totalDataLength -= m_pDataLength[index];
+ if (m_pData[index] != 0) delete[] m_pData[index];
+
+ if (m_children > 1 && index != m_children - 1)
+ {
+ m_pDataLength[index] = m_pDataLength[m_children - 1];
+ m_pData[index] = m_pData[m_children - 1];
+ m_ptrMBR[index] = m_ptrMBR[m_children - 1];
+ m_pIdentifier[index] = m_pIdentifier[m_children - 1];
+ }
+
+ --m_children;
+
+ // WARNING: index has now changed. Do not use it below here.
+
+ if (m_children == 0)
+ {
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+ return true;
+ }
+ else if (m_pTree->m_bTightMBRs && m_nodeMBR.touchesShape(*ptrR))
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool Node::insertData(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2, bool bForceAdjust)
+{
+ // we should be certain that when bInsertMbr2 is true the node needs to be version split
+
+ // this function returns true only if the node under modification has been stored (writeNode(this))
+ // it is needed since some times after a version copy we do not need to actually store the node. Only
+ // the parent has to be notified to modify the entry pointing
+ // to this node with the appropriate deletion time (thus we save one disk access)
+
+ if ((! bInsertMbr2) && m_children < m_capacity)
+ {
+ // the node has empty space. Insert the entry here
+
+ // this has to happen before insertEntry modifies m_nodeMBR.
+ bool b = m_nodeMBR.containsShape(mbr);
+
+ insertEntry(dataLength, pData, mbr, id);
+ m_pTree->writeNode(this);
+
+ // a forced adjust might be needed when a child has modified it MBR due to an entry deletion
+ // (when the entry start time becomes equal to the entry end time after a version copy)
+ if ((! b || bForceAdjust) && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+
+ return true;
+ }
+ else
+ {
+ // do a version copy
+
+ bool bIsRoot = pathBuffer.empty();
+
+ NodePtr ptrCopy;
+
+ // copy live entries of this node into a new node. Create an index or a leaf respectively
+ if (m_level == 0)
+ {
+ ptrCopy = m_pTree->m_leafPool.acquire();
+ if (ptrCopy.get() == 0) ptrCopy = NodePtr(new Leaf(m_pTree, - 1), &(m_pTree->m_leafPool));
+ else ptrCopy->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ else
+ {
+ ptrCopy = m_pTree->m_indexPool.acquire();
+ if (ptrCopy.get() == 0) ptrCopy = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+ else
+ {
+ ptrCopy->m_level = m_level;
+ ptrCopy->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ }
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (! (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ byte* data = 0;
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ data = new byte[m_pDataLength[cChild]];
+ memcpy(data, m_pData[cChild], m_pDataLength[cChild] * sizeof(byte));
+ }
+ ptrCopy->insertEntry(m_pDataLength[cChild], data, *(m_ptrMBR[cChild]), m_pIdentifier[cChild]);
+ ptrCopy->m_ptrMBR[ptrCopy->m_children - 1]->m_startTime = mbr.m_startTime;
+ }
+ }
+
+ ptrCopy->m_nodeMBR.m_startTime = mbr.m_startTime;
+ m_nodeMBR.m_endTime = mbr.m_startTime;
+
+ uint32_t children = (bInsertMbr2) ? ptrCopy->m_children + 2 : ptrCopy->m_children + 1;
+ assert(children > 0);
+
+ if (children >= m_pTree->m_strongVersionOverflow * m_capacity)
+ {
+ // strong version overflow. Split!
+ NodePtr n;
+ NodePtr nn;
+ ptrCopy->split(dataLength, pData, mbr, id, n, nn, mbr2, id2, bInsertMbr2);
+ assert(n->m_children > 1 && nn->m_children > 1);
+
+ if (bIsRoot)
+ {
+ // it is a root node. Special handling required.
+ n->m_level = ptrCopy->m_level;
+ nn->m_level = ptrCopy->m_level;
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ NodePtr ptrR = m_pTree->m_indexPool.acquire();
+ if (ptrR.get() == 0) ptrR = NodePtr(new Index(m_pTree, -1, ptrCopy->m_level + 1), &(m_pTree->m_indexPool));
+ else
+ {
+ //ptrR->m_pTree = m_pTree;
+ //ptrR->m_identifier = -1;
+ ptrR->m_level = ptrCopy->m_level + 1;
+ ptrR->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+
+ ptrR->insertEntry(0, 0, n->m_nodeMBR, n->m_identifier);
+ ptrR->insertEntry(0, 0, nn->m_nodeMBR, nn->m_identifier);
+
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ ptrR->m_identifier = m_identifier;
+ m_pTree->writeNode(ptrR.get());
+ m_pTree->m_stats.m_treeHeight[m_pTree->m_stats.m_treeHeight.size() - 1] = ptrR->m_level + 1;
+ m_pTree->m_stats.m_nodesInLevel.at(n->m_level) = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 1;
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime == ptrCopy->m_nodeMBR.m_startTime &&
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime == ptrCopy->m_nodeMBR.m_endTime);
+ }
+ else
+ {
+ m_pTree->writeNode(this);
+ m_pTree->writeNode(ptrR.get());
+
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_id == m_identifier);
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime = m_nodeMBR.m_startTime;
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime = m_nodeMBR.m_endTime;
+ m_pTree->m_roots.push_back(MVRTree::RootEntry(ptrR->m_identifier, ptrR->m_nodeMBR.m_startTime, ptrR->m_nodeMBR.m_endTime));
+ m_pTree->m_stats.m_treeHeight.push_back(ptrR->m_level + 1);
+ m_pTree->m_stats.m_nodesInLevel.at(n->m_level) = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 2;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+ }
+
+ if (ptrR->m_level >= m_pTree->m_stats.m_nodesInLevel.size()) m_pTree->m_stats.m_nodesInLevel.push_back(1);
+ else m_pTree->m_stats.m_nodesInLevel.at(ptrR->m_level) = m_pTree->m_stats.m_nodesInLevel[ptrR->m_level] + 1;
+
+ return true;
+ }
+ else
+ {
+ bool b = false;
+
+ n->m_level = ptrCopy->m_level;
+ nn->m_level = ptrCopy->m_level;
+/*
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ n->m_identifier = m_identifier;
+ m_pTree->m_stats.m_nodesInLevel[n->m_level] = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 1;
+ b = true;
+ }
+ else
+ {
+ n->m_identifier = -1;
+ m_pTree->m_stats.m_nodesInLevel[n->m_level] = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 2;
+ }
+*/
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+
+ m_pTree->m_stats.m_nodesInLevel.at(n->m_level) = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 2;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // this is the special insertion function for two new nodes, defined below
+ p->insertData(n->m_nodeMBR, n->m_identifier, nn->m_nodeMBR, nn->m_identifier, this, pathBuffer);
+
+ return b;
+ }
+ }
+ //else if (children < m_pTree->m_strongVersionUnderflow * m_capacity)
+ //{
+ // do not do this for now
+ //}
+ else
+ {
+ // the entry contains the appropriate number of live entries
+
+ ptrCopy->insertEntry(dataLength, pData, mbr, id);
+ if (bInsertMbr2) ptrCopy->insertEntry(0, 0, mbr2, id2);
+
+ if (bIsRoot)
+ {
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ ptrCopy->m_identifier = m_identifier;
+ m_pTree->writeNode(ptrCopy.get());
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime == ptrCopy->m_nodeMBR.m_startTime &&
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime == ptrCopy->m_nodeMBR.m_endTime);
+ }
+ else
+ {
+ m_pTree->writeNode(ptrCopy.get());
+ m_pTree->writeNode(this);
+
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_id == m_identifier);
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime = m_nodeMBR.m_startTime;
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime = m_nodeMBR.m_endTime;
+ m_pTree->m_roots.push_back(MVRTree::RootEntry(ptrCopy->m_identifier, ptrCopy->m_nodeMBR.m_startTime, ptrCopy->m_nodeMBR.m_endTime));
+ m_pTree->m_stats.m_treeHeight.push_back(ptrCopy->m_level + 1);
+
+ m_pTree->m_stats.m_nodesInLevel.at(ptrCopy->m_level) = m_pTree->m_stats.m_nodesInLevel[ptrCopy->m_level] + 1;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+ }
+
+ return true;
+ }
+ else
+ {
+ m_pTree->writeNode(ptrCopy.get());
+
+ m_pTree->m_stats.m_nodesInLevel.at(ptrCopy->m_level) = m_pTree->m_stats.m_nodesInLevel[ptrCopy->m_level] + 1;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ uint32_t child;
+ for (child = 0; child < p->m_children; ++child)
+ {
+ if (p->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ // it might be needed to update the MBR since the child MBR might have changed
+ // from an entry deletion (from insertData, below, when m_startTime == m_endTime)
+ double st = p->m_ptrMBR[child]->m_startTime;
+ *(p->m_ptrMBR[child]) = m_nodeMBR;
+ p->m_ptrMBR[child]->m_startTime = st;
+ //p->m_ptrMBR[child]->m_endTime = mbr.m_startTime;
+
+ // insert this new version copy into the parent
+ p->insertData(0, 0, ptrCopy->m_nodeMBR, ptrCopy->m_identifier, pathBuffer, m_pTree->m_infiniteRegion, -1, false);
+
+ return false;
+ }
+ }
+ }
+}
+
+void Node::insertData(TimeRegion& mbr1, id_type id1, TimeRegion& mbr2, id_type id2, Node* oldVersion, std::stack<id_type>& pathBuffer)
+{
+ // this should be called only from insertData above
+ // it tries to fit two new entries into the node
+
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == oldVersion->m_identifier) break;
+ }
+
+ // save the original node MBR
+ bool bAdjust = false;
+ TimeRegionPtr ptrR = m_pTree->m_regionPool.acquire();
+ *ptrR = m_nodeMBR;
+
+ // it might be needed to update the MBR since the child MBR might have changed
+ // from an entry deletion (when m_startTime == m_endTime)
+ double st = m_ptrMBR[child]->m_startTime;
+ *(m_ptrMBR[child]) = oldVersion->m_nodeMBR;
+ m_ptrMBR[child]->m_startTime = st;
+ //m_ptrMBR[child]->m_endTime = oldVersion->m_nodeMBR.m_endTime;
+
+ if (m_children < m_capacity - 1)
+ {
+ // there is enough space for both new entries
+
+ insertEntry(0, 0, mbr1, id1);
+ insertEntry(0, 0, mbr2, id2);
+
+ m_pTree->writeNode(this);
+
+ if ((! pathBuffer.empty()) && (bAdjust || ! (ptrR->containsShape(mbr1) && ptrR->containsShape(mbr2))))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+ }
+ else
+ {
+ // call a normal insertData which will trigger a version copy
+ // insertData will adjust the parent since this node will certainly do a version copy
+ bool bStored = insertData(0, 0, mbr1, id1, pathBuffer, mbr2, id2, true);
+ if (! bStored) m_pTree->writeNode(this);
+ }
+}
+
+bool Node::deleteData(id_type id, double delTime, std::stack<id_type>& pathBuffer, bool bForceAdjust)
+{
+ // it returns true if a new root has been created because all the entries of the old root have died.
+ // This is needed in case the root dies while there are pending reinsertions from multiple levels
+
+ uint32_t child = m_capacity;
+ uint32_t alive = 0;
+ bool bAdjustParent = false;
+ TimeRegionPtr oldNodeMBR = m_pTree->m_regionPool.acquire();
+ *oldNodeMBR = m_nodeMBR;
+ NodePtr parent;
+
+ // make sure that there are no "snapshot" entries
+ // find how many children are alive and locate the entry to be deleted
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_level != 0 || (m_ptrMBR[cChild]->m_startTime != m_ptrMBR[cChild]->m_endTime));
+ if (! (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max())) ++alive;
+ if (m_pIdentifier[cChild] == id) child = cChild;
+ }
+
+ assert(child < m_capacity);
+
+ // either make the entry dead or, if its start time is equal to the deletion time,
+ // delete it from the node completely (in which case the parent MBR might need adjustment)
+ bool bAdjusted = false;
+
+ if (m_level == 0 && m_ptrMBR[child]->m_startTime == delTime)
+ {
+ bAdjusted = deleteEntry(child);
+ bAdjustParent = bAdjusted;
+ }
+ else
+ {
+ m_ptrMBR[child]->m_endTime = delTime;
+ }
+
+ // if it has not been adjusted yet (by deleteEntry) and it should be adjusted, do it.
+ // a forced adjustment is needed when a child node has adjusted its own MBR and signals
+ // the parent to adjust it, also.
+ if ((! bAdjusted) && bForceAdjust)
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ // signal our parent to adjust its MBR also
+ bAdjustParent = true;
+ }
+
+ // one less live entry from now on
+ --alive;
+
+ if (alive < m_pTree->m_versionUnderflow * m_capacity && (! pathBuffer.empty()))
+ {
+ // if the weak version condition is broken, try to resolve it
+ // if this is a leaf and it can still hold some entries (since all entries might be dead now and
+ // the node full) try to borrow a live entry from a sibling
+ // [Yufei Tao, Dimitris Papadias, 'MV3R-Tree: A Spatio-Temporal Access Method for Timestamp and
+ // Interval Queries', Section 3.3]
+ if (m_level == 0 && m_children < m_capacity)
+ {
+ parent = m_pTree->readNode(pathBuffer.top());
+ pathBuffer.pop();
+
+ // find us in our parent
+ for (child = 0; child < parent->m_children; ++child)
+ {
+ if (parent->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ // remember that the parent might be younger than us, pointing to us through a pointer
+ // created with a version copy. So the actual start time of this node through the path
+ // from the root might actually be different than the stored start time.
+ double actualNodeStartTime = parent->m_ptrMBR[child]->m_startTime;
+
+ // find an appropriate sibling
+ for (uint32_t cSibling = 0; cSibling < parent->m_children; ++cSibling)
+ {
+ // it has to be different than us, it has to be alive and its MBR should intersect ours
+ if (
+ parent->m_pIdentifier[cSibling] != m_identifier &&
+ ! (parent->m_ptrMBR[cSibling]->m_endTime < std::numeric_limits<double>::max()) &&
+ parent->m_ptrMBR[cSibling]->intersectsShape(m_nodeMBR))
+ {
+ NodePtr sibling = m_pTree->readNode(parent->m_pIdentifier[cSibling]);
+ std::vector<DeleteDataEntry> toCheck;
+ alive = 0;
+
+ // if this child does not have a single parent, we cannot borrow an entry.
+ bool bSingleParent = true;
+
+ for (uint32_t cSiblingChild = 0; cSiblingChild < sibling->m_children; ++cSiblingChild)
+ {
+ // if the insertion time of any child is smaller than the starting time stored in the
+ // parent of this node than the node has more than one parent
+ if (sibling->m_ptrMBR[cSiblingChild]->m_startTime < parent->m_ptrMBR[cSibling]->m_startTime)
+ {
+ bSingleParent = false;
+ break;
+ }
+
+ // find the live sibling entries, and also the ones that can be moved to this node
+ // sort them by area enlargement
+ if (! (sibling->m_ptrMBR[cSiblingChild]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ ++alive;
+ if (sibling->m_ptrMBR[cSiblingChild]->m_startTime >= actualNodeStartTime)
+ {
+ TimeRegionPtr tmpR = m_pTree->m_regionPool.acquire();
+ *tmpR = m_nodeMBR;
+ tmpR->combineRegion(*(sibling->m_ptrMBR[cSiblingChild]));
+ double a = tmpR->getArea();
+ if (a <= m_nodeMBR.getArea() * 1.1) toCheck.push_back(DeleteDataEntry(cSiblingChild, a));
+ }
+ }
+ }
+
+ // if the sibling has more than one parent or if we cannot remove an entry because we will
+ // cause a weak version overflow, this sibling is not appropriate
+ if ((! bSingleParent) || toCheck.empty() || alive == m_pTree->m_versionUnderflow * sibling->m_capacity + 1) continue;
+
+ // create interval counters for checking weak version condition
+ // [Yufei Tao, Dimitris Papadias, 'MV3R-Tree: A Spatio-Temporal Access Method for Timestamp and
+ // Interval Queries', Section 3.2]
+ std::set<double> Si;
+ for (uint32_t cSiblingChild = 0; cSiblingChild < sibling->m_children; ++cSiblingChild)
+ {
+ Si.insert(sibling->m_ptrMBR[cSiblingChild]->m_startTime);
+ Si.insert(sibling->m_ptrMBR[cSiblingChild]->m_endTime);
+ }
+ // duplicate entries have been removed and the set is sorted
+ uint32_t* SiCounts = new uint32_t[Si.size() - 1];
+ bzero(SiCounts, (Si.size() - 1) * sizeof(uint32_t));
+
+ for (uint32_t cSiblingChild = 0; cSiblingChild < sibling->m_children; ++cSiblingChild)
+ {
+ std::set<double>::iterator it1 = Si.begin();
+ std::set<double>::iterator it2 = Si.begin();
+ for (size_t cIndex = 0; cIndex < Si.size() - 1; ++cIndex)
+ {
+ ++it2;
+ if (
+ sibling->m_ptrMBR[cSiblingChild]->m_startTime <= *it1 &&
+ sibling->m_ptrMBR[cSiblingChild]->m_endTime >= *it2
+ ) ++(SiCounts[cIndex]);
+ ++it1;
+ }
+ }
+
+ std::vector<DeleteDataEntry> Sdel;
+
+ for (size_t cCheck = 0; cCheck < toCheck.size(); ++cCheck)
+ {
+ bool good = true;
+
+ // check if it can be removed without a weak version underflow
+ std::set<double>::iterator it1 = Si.begin();
+ std::set<double>::iterator it2 = Si.begin();
+ for (size_t cIndex = 0; cIndex < Si.size() - 1; ++cIndex)
+ {
+ ++it2;
+ if (
+ sibling->m_ptrMBR[toCheck[cCheck].m_index]->m_startTime <= *it1 &&
+ sibling->m_ptrMBR[toCheck[cCheck].m_index]->m_endTime >= *it2 &&
+ SiCounts[cIndex] <= m_pTree->m_versionUnderflow * sibling->m_capacity)
+ {
+ good = false;
+ break;
+ }
+ ++it1;
+ }
+ if (good) Sdel.push_back(toCheck[cCheck]);
+ }
+
+ delete[] SiCounts;
+
+ if (Sdel.empty()) continue;
+
+ // we found some entries. Sort them according to least enlargement, insert the best entry into
+ // this node, remove it from the sibling and update the MBRs of the parent
+
+ sort(Sdel.begin(), Sdel.end(), DeleteDataEntry::compare);
+ uint32_t entry = Sdel[0].m_index;
+ bool b1 = m_nodeMBR.containsShape(*(sibling->m_ptrMBR[entry]));
+ bool b2 = sibling->m_nodeMBR.touchesShape(*(sibling->m_ptrMBR[entry]));
+
+ insertEntry(sibling->m_pDataLength[entry], sibling->m_pData[entry], *(sibling->m_ptrMBR[entry]), sibling->m_pIdentifier[entry]);
+ sibling->m_pData[entry] = 0;
+
+ // the weak version condition check above, guarantees that.
+ assert(sibling->m_children > 1);
+ sibling->deleteEntry(entry);
+
+ m_pTree->writeNode(this);
+ m_pTree->writeNode(sibling.get());
+
+ Index* p = static_cast<Index*>(parent.get());
+ if (((! b1) || bAdjustParent) && b2) p->adjustTree(this, sibling.get(), pathBuffer);
+ else if ((! b1) || bAdjustParent) p->adjustTree(this, pathBuffer);
+ else if (b2) p->adjustTree(sibling.get(), pathBuffer);
+
+ return false;
+ }
+ }
+ }
+
+ // either this is not a leaf, or an appropriate sibling was not found, so make this node dead
+ // and reinsert all live entries from the root
+ m_nodeMBR.m_endTime = delTime;
+ m_pTree->writeNode(this);
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ if (parent.get() == 0)
+ {
+ parent = m_pTree->readNode(pathBuffer.top());
+ pathBuffer.pop();
+ }
+
+ if (bAdjustParent)
+ {
+ // the correct child pointer might have been calculated already from earlier
+ if (child < parent->m_children && m_identifier != parent->m_pIdentifier[child])
+ {
+ for (child = 0; child < parent->m_children; ++child)
+ {
+ if (parent->m_pIdentifier[child] == m_identifier) break;
+ }
+ }
+
+ // both start time and end time should be preserved since deleteData below needs
+ // to know how many entries where alive, including this one
+ double st = parent->m_ptrMBR[child]->m_startTime;
+ double en = parent->m_ptrMBR[child]->m_endTime;
+ *(parent->m_ptrMBR[child]) = m_nodeMBR;
+ parent->m_ptrMBR[child]->m_startTime = st;
+ parent->m_ptrMBR[child]->m_endTime = en;
+ }
+
+ // delete this node from the parent node.
+ // if this node had been adjusted and its old MBR was touching the parent MBR, the
+ // parent MBR needs to be adjusted also.
+ // the deletion has to happen first, since the reinsertions might modify the path to this node
+ bool bNewRoot = parent->deleteData(m_identifier, delTime, pathBuffer, (bAdjustParent && parent->m_nodeMBR.touchesShape(*oldNodeMBR)));
+
+ // reinsert all the live entries from the root
+
+ // normally I should not modify any node instances, since writeNode might be caching nodes
+ // in main memory, even though I have persisted them, so I have to make copies
+
+ // this code will try and reinsert whole paths if possible. It might be the case, though,
+ // that a root died, which means that all the live data entries have to be scanned and reinserted themselves
+ for (child = 0; child < m_children; ++child)
+ {
+ if (! (m_ptrMBR[child]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ if (! bNewRoot || m_level == 0)
+ {
+ m_ptrMBR[child]->m_startTime = delTime;
+ m_pTree->insertData_impl(m_pDataLength[child], m_pData[child], *(m_ptrMBR[child]), m_pIdentifier[child], m_level);
+ // make sure we do not delete the data array from this node's destructor
+ m_pData[child] = 0;
+ }
+ else
+ {
+ std::stack<NodePtr> Sins;
+ Sins.push(m_pTree->readNode(m_pIdentifier[child]));
+ while (! Sins.empty())
+ {
+ NodePtr p = Sins.top(); Sins.pop();
+ if (p->m_level == 0)
+ {
+ for (uint32_t cIndex= 0; cIndex < p->m_children; ++cIndex)
+ {
+ if (! (p->m_ptrMBR[cIndex]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ p->m_ptrMBR[cIndex]->m_startTime = delTime;
+ m_pTree->insertData_impl(p->m_pDataLength[cIndex], p->m_pData[cIndex], *(p->m_ptrMBR[cIndex]), p->m_pIdentifier[cIndex], p->m_level);
+ // make sure we do not delete the data array from this node's destructor
+ p->m_pData[cIndex] = 0;
+ }
+ }
+ }
+ else
+ {
+ for (uint32_t cIndex= 0; cIndex < p->m_children; ++cIndex)
+ {
+ if (! (p->m_ptrMBR[cIndex]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ Sins.push(m_pTree->readNode(p->m_pIdentifier[cIndex]));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // either this is a root node or there is no weak version condition
+
+ if (alive == 0 && pathBuffer.empty())
+ {
+ if (m_children > 0)
+ {
+ // all root children are dead. Create a new root
+ m_nodeMBR.m_endTime = delTime;
+ m_pTree->m_bHasVersionCopied = false;
+
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ Leaf root(m_pTree, m_identifier);
+ root.m_nodeMBR.m_startTime = m_nodeMBR.m_endTime;
+ root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ m_pTree->writeNode(&root);
+
+ m_pTree->m_stats.m_treeHeight[m_pTree->m_stats.m_treeHeight.size() - 1] = 1;
+ if (m_pTree->m_stats.m_nodesInLevel.at(m_level) == 1) m_pTree->m_stats.m_nodesInLevel.pop_back();
+ else m_pTree->m_stats.m_nodesInLevel.at(m_level) = m_pTree->m_stats.m_nodesInLevel[m_level] - 1;
+ m_pTree->m_stats.m_nodesInLevel.at(0) = m_pTree->m_stats.m_nodesInLevel[0] + 1;
+ }
+ else
+ {
+ m_pTree->writeNode(this);
+
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ Leaf root(m_pTree, -1);
+ root.m_nodeMBR.m_startTime = m_nodeMBR.m_endTime;
+ root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ m_pTree->writeNode(&root);
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_id == m_identifier);
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime = m_nodeMBR.m_startTime;
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime = m_nodeMBR.m_endTime;
+ m_pTree->m_roots.push_back(MVRTree::RootEntry(root.m_identifier, root.m_nodeMBR.m_startTime, root.m_nodeMBR.m_endTime));
+
+ m_pTree->m_stats.m_treeHeight.push_back(1);
+ m_pTree->m_stats.m_nodesInLevel.at(root.m_level) = m_pTree->m_stats.m_nodesInLevel[root.m_level] + 1;
+ }
+ return true;
+ }
+ else
+ {
+ assert(m_level == 0);
+ m_pTree->writeNode(this);
+ m_pTree->m_bHasVersionCopied = false;
+ return false;
+ }
+ }
+ else if (bAdjustParent && (! pathBuffer.empty()))
+ {
+ // the parent needs to be adjusted
+ m_pTree->writeNode(this);
+ parent = m_pTree->readNode(pathBuffer.top());
+ pathBuffer.pop();
+ Index* p = static_cast<Index*>(parent.get());
+ p->adjustTree(this, pathBuffer);
+ }
+ else
+ {
+ m_pTree->writeNode(this);
+ }
+ }
+
+ return false;
+}
+
+void Node::rtreeSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ uint32_t cChild;
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ uint32_t cTotal = (bInsertMbr2) ? m_children + 2 : m_children + 1;
+
+ // use this mask array for marking visited entries.
+ byte* mask = new byte[cTotal];
+ bzero(mask, cTotal);
+
+ // insert new data in the node for easier manipulation. Data arrays are always
+ // by two larger than node capacity.
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ if (bInsertMbr2)
+ {
+ m_pDataLength[m_children + 1] = 0;
+ m_pData[m_children + 1] = 0;
+ m_ptrMBR[m_children + 1] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children + 1]) = mbr2;
+ m_pIdentifier[m_children + 1] = id2;
+ }
+
+ // initialize each group with the seed entries.
+ uint32_t seed1, seed2;
+ pickSeeds(seed1, seed2, cTotal);
+
+ group1.push_back(seed1);
+ group2.push_back(seed2);
+
+ mask[seed1] = 1;
+ mask[seed2] = 1;
+
+ // find MBR of each group.
+ TimeRegionPtr mbrA = m_pTree->m_regionPool.acquire();
+ *mbrA = *(m_ptrMBR[seed1]);
+ TimeRegionPtr mbrB = m_pTree->m_regionPool.acquire();
+ *mbrB = *(m_ptrMBR[seed2]);
+
+ // count how many entries are left unchecked (exclude the seeds here.)
+ uint32_t cRemaining = cTotal - 2;
+
+ while (cRemaining > 0)
+ {
+ if (minimumLoad - group1.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group1 to comply with minimun load requirement.
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group1.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else if (minimumLoad - group2.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group2 to comply with minimun load requirement.
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group2.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else
+ {
+ // For all remaining entries compute the difference of the cost of grouping an
+ // entry in either group. When done, choose the entry that yielded the maximum
+ // difference. In case of linear split, select any entry (e.g. the first one.)
+ uint32_t sel;
+ double md1 = 0.0, md2 = 0.0;
+ double m = -std::numeric_limits<double>::max();
+ double d1, d2, d;
+ double a1 = mbrA->getArea();
+ double a2 = mbrB->getArea();
+
+ TimeRegionPtr a = m_pTree->m_regionPool.acquire();
+ TimeRegionPtr b = m_pTree->m_regionPool.acquire();
+
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ mbrA->getCombinedRegion(*a, *(m_ptrMBR[cChild]));
+ d1 = a->getArea() - a1;
+ mbrB->getCombinedRegion(*b, *(m_ptrMBR[cChild]));
+ d2 = b->getArea() - a2;
+ d = std::abs(d1 - d2);
+
+ if (d > m)
+ {
+ m = d;
+ md1 = d1; md2 = d2;
+ sel = cChild;
+ if (m_pTree->m_treeVariant== RV_LINEAR || m_pTree->m_treeVariant == RV_RSTAR) break;
+ }
+ }
+ }
+
+ // determine the group where we should add the new entry.
+ int32_t group = 1;
+
+ if (md1 < md2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (md2 < md1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (a1 < a2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (a2 < a1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (group1.size() < group2.size())
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (group2.size() < group1.size())
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ mask[sel] = 1;
+ --cRemaining;
+ if (group == 1)
+ {
+ mbrA->combineRegion(*(m_ptrMBR[sel]));
+ }
+ else
+ {
+ mbrB->combineRegion(*(m_ptrMBR[sel]));
+ }
+ }
+ }
+
+ delete[] mask;
+}
+
+void Node::rstarSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ RstarSplitEntry** dataLow = 0;
+ RstarSplitEntry** dataHigh = 0;
+
+ uint32_t cTotal = (bInsertMbr2) ? m_children + 2 : m_children + 1;
+
+ try
+ {
+ dataLow = new RstarSplitEntry*[cTotal];
+ dataHigh = new RstarSplitEntry*[cTotal];
+ }
+ catch (...)
+ {
+ delete[] dataLow;
+ throw;
+ }
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ if (bInsertMbr2)
+ {
+ m_pDataLength[m_children + 1] = 0;
+ m_pData[m_children + 1] = 0;
+ m_ptrMBR[m_children + 1] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children + 1]) = mbr2;
+ m_pIdentifier[m_children + 1] = id2;
+ }
+
+ uint32_t nodeSPF = static_cast<uint32_t>(std::floor(cTotal * m_pTree->m_splitDistributionFactor));
+ uint32_t splitDistribution = cTotal - (2 * nodeSPF) + 2;
+
+ uint32_t cChild = 0, cDim, cIndex;
+
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ try
+ {
+ dataLow[cChild] = new RstarSplitEntry(m_ptrMBR[cChild].get(), cChild, 0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete dataLow[i];
+ delete[] dataLow;
+ delete[] dataHigh;
+ throw;
+ }
+
+ dataHigh[cChild] = dataLow[cChild];
+ }
+
+ double minimumMargin = std::numeric_limits<double>::max();
+ uint32_t splitAxis = std::numeric_limits<uint32_t>::max();
+ uint32_t sortOrder = std::numeric_limits<uint32_t>::max();
+
+ // chooseSplitAxis.
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ ::qsort(dataLow,
+ cTotal,
+ sizeof(RstarSplitEntry*),
+ RstarSplitEntry::compareLow);
+
+ ::qsort(dataHigh,
+ cTotal,
+ sizeof(RstarSplitEntry*),
+ RstarSplitEntry::compareHigh);
+
+ // calculate sum of margins and overlap for all distributions.
+ double marginl = 0.0;
+ double marginh = 0.0;
+
+ TimeRegion bbl1, bbl2, bbh1, bbh2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bbl1 = *(dataLow[0]->m_pRegion);
+ bbh1 = *(dataHigh[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bbl1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh1.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ bbl2 = *(dataLow[l]->m_pRegion);
+ bbh2 = *(dataHigh[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex < cTotal; ++cIndex)
+ {
+ bbl2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh2.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ marginl += bbl1.getMargin() + bbl2.getMargin();
+ marginh += bbh1.getMargin() + bbh2.getMargin();
+ } // for (cChild)
+
+ double margin = std::min(marginl, marginh);
+
+ // keep minimum margin as split axis.
+ if (margin < minimumMargin)
+ {
+ minimumMargin = margin;
+ splitAxis = cDim;
+ sortOrder = (marginl < marginh) ? 0 : 1;
+ }
+
+ // increase the dimension according to which the data entries should be sorted.
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = cDim + 1;
+ }
+ } // for (cDim)
+
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = splitAxis;
+ }
+
+ ::qsort(
+ dataLow,
+ cTotal,
+ sizeof(RstarSplitEntry*),
+ (sortOrder == 0) ? RstarSplitEntry::compareLow : RstarSplitEntry::compareHigh);
+
+ double ma = std::numeric_limits<double>::max();
+ double mo = std::numeric_limits<double>::max();
+ uint32_t splitPoint = std::numeric_limits<uint32_t>::max();
+
+ TimeRegion bb1, bb2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bb1 = *(dataLow[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bb1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ bb2 = *(dataLow[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex < cTotal; ++cIndex)
+ {
+ bb2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ double o = bb1.getIntersectingArea(bb2);
+
+ if (o < mo)
+ {
+ splitPoint = cChild;
+ mo = o;
+ ma = bb1.getArea() + bb2.getArea();
+ }
+ else if (o == mo)
+ {
+ double a = bb1.getArea() + bb2.getArea();
+
+ if (a < ma)
+ {
+ splitPoint = cChild;
+ ma = a;
+ }
+ }
+ } // for (cChild)
+
+ uint32_t l1 = nodeSPF - 1 + splitPoint;
+
+ for (cIndex = 0; cIndex < l1; ++cIndex)
+ {
+ group1.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ for (cIndex = l1; cIndex < cTotal; ++cIndex)
+ {
+ group2.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ delete[] dataLow;
+ delete[] dataHigh;
+}
+
+void Node::pickSeeds(uint32_t& index1, uint32_t& index2, uint32_t total)
+{
+ double separation = -std::numeric_limits<double>::max();
+ double inefficiency = -std::numeric_limits<double>::max();
+ uint32_t cDim, cChild, cIndex;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_RSTAR:
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ double leastLower = m_ptrMBR[0]->m_pLow[cDim];
+ double greatestUpper = m_ptrMBR[0]->m_pHigh[cDim];
+ uint32_t greatestLower = 0;
+ uint32_t leastUpper = 0;
+ double width;
+
+ for (cChild = 1; cChild < total; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->m_pLow[cDim] > m_ptrMBR[greatestLower]->m_pLow[cDim]) greatestLower = cChild;
+ if (m_ptrMBR[cChild]->m_pHigh[cDim] < m_ptrMBR[leastUpper]->m_pHigh[cDim]) leastUpper = cChild;
+
+ leastLower = std::min(m_ptrMBR[cChild]->m_pLow[cDim], leastLower);
+ greatestUpper = std::max(m_ptrMBR[cChild]->m_pHigh[cDim], greatestUpper);
+ }
+
+ width = greatestUpper - leastLower;
+ if (width <= 0) width = 1;
+
+ double f = (m_ptrMBR[greatestLower]->m_pLow[cDim] - m_ptrMBR[leastUpper]->m_pHigh[cDim]) / width;
+
+ if (f > separation)
+ {
+ index1 = leastUpper;
+ index2 = greatestLower;
+ separation = f;
+ }
+ } // for (cDim)
+
+ if (index1 == index2)
+ {
+ if (index2 == 0) ++index2;
+ else --index2;
+ }
+
+ break;
+ case RV_QUADRATIC:
+ // for each pair of Regions (account for overflow Region too!)
+ for (cChild = 0; cChild < total - 1; ++cChild)
+ {
+ double a = m_ptrMBR[cChild]->getArea();
+
+ for (cIndex = cChild + 1; cIndex < total; ++cIndex)
+ {
+ // get the combined MBR of those two entries.
+ TimeRegion r;
+ m_ptrMBR[cChild]->getCombinedRegion(r, *(m_ptrMBR[cIndex]));
+
+ // find the inefficiency of grouping these entries together.
+ double d = r.getArea() - a - m_ptrMBR[cIndex]->getArea();
+
+ if (d > inefficiency)
+ {
+ inefficiency = d;
+ index1 = cChild;
+ index2 = cIndex;
+ }
+ } // for (cIndex)
+ } // for (cChild)
+
+ break;
+ default:
+ throw Tools::NotSupportedException("Node::pickSeeds: Tree variant not supported.");
+ }
+}
+
+NodePtr Node::findNode(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_pIdentifier[cChild] == id)
+ return m_pTree->readNode(m_pIdentifier[cChild]);
+
+ if (m_ptrMBR[cChild]->containsShape(mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findNode(mbr, id, pathBuffer);
+ assert(n.get() != l.get());
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.h.svn-base
new file mode 100644
index 000000000..187435e43
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Node.h.svn-base
@@ -0,0 +1,184 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class MVRTree;
+ class Leaf;
+ class Index;
+ class Node;
+
+ typedef Tools::PoolPointer<Node> NodePtr;
+
+ class Node : public SpatialIndex::INode
+ {
+ public:
+ virtual ~Node();
+
+ //
+ // Tools::IObject interface
+ //
+ virtual IObject* clone();
+
+ //
+ // Tools::ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // SpatialIndex::IEntry interface
+ //
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+
+ //
+ // SpatialIndex::INode interface
+ //
+ virtual uint32_t getChildrenCount() const;
+ virtual id_type getChildIdentifier(uint32_t index) const;
+ virtual void getChildShape(uint32_t index, IShape** out) const;
+ virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
+ virtual uint32_t getLevel() const;
+ virtual bool isIndex() const;
+ virtual bool isLeaf() const;
+
+ private:
+ Node();
+ Node(MVRTree* pTree, id_type id, uint32_t level, uint32_t capacity);
+
+ virtual Node& operator=(const Node&);
+
+ virtual void insertEntry(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id);
+ virtual bool deleteEntry(uint32_t index);
+
+ virtual bool insertData(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false, bool forceAdjust = false);
+ virtual void insertData(TimeRegion& mbr1, id_type id1, TimeRegion& mbr2, id_type id2, Node* oldVersion, std::stack<id_type>& pathBuffer);
+ virtual bool deleteData(id_type id, double delTime, std::stack<id_type>& pathBuffer, bool adjustMBR = false);
+
+ virtual void rtreeSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+ virtual void rstarSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+
+ virtual void pickSeeds(uint32_t& index1, uint32_t& index2, uint32_t total);
+
+ virtual NodePtr chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findNode(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& left, NodePtr& right,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false) = 0;
+
+ MVRTree* m_pTree;
+ // Parent of all nodes.
+
+ uint32_t m_level;
+ // The level of the node in the tree.
+ // Leaves are always at level 0.
+
+ id_type m_identifier;
+ // The unique ID of this node.
+
+ uint32_t m_children;
+ // The number of children pointed by this node.
+
+ uint32_t m_capacity;
+ // Specifies the node capacity.
+
+ TimeRegion m_nodeMBR;
+ // The minimum bounding region enclosing all data contained in the node.
+
+ byte** m_pData;
+ // The data stored in the node.
+
+ TimeRegionPtr* m_ptrMBR;
+ // The corresponding data MBRs.
+
+ id_type* m_pIdentifier;
+ // The corresponding data identifiers.
+
+ uint32_t* m_pDataLength;
+
+ uint32_t m_totalDataLength;
+
+ class RstarSplitEntry
+ {
+ public:
+ RstarSplitEntry(TimeRegion* pr, uint32_t index, uint32_t dimension) :
+ m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
+
+ static int compareLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+
+ TimeRegion* m_pRegion;
+ uint32_t m_index;
+ uint32_t m_sortDim;
+ }; // RstarSplitEntry
+
+ class DeleteDataEntry
+ {
+ public:
+ DeleteDataEntry(uint32_t index, double d) : m_index(index), m_increase(d) {}
+
+ static bool compare(DeleteDataEntry e1, DeleteDataEntry e2) { return e1.m_increase < e2.m_increase; }
+
+ uint32_t m_index;
+ double m_increase;
+ }; // DeleteDataEntry
+
+ // Needed to access protected members without having to cast from Node.
+ // It is more efficient than using member functions to access protected members.
+ friend class MVRTree;
+ friend class Leaf;
+ friend class Index;
+ friend class Tools::PointerPool<Node>;
+ }; // Node
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/PointerPoolNode.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/PointerPoolNode.h.svn-base
new file mode 100644
index 000000000..33407df02
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/PointerPoolNode.h.svn-base
@@ -0,0 +1,133 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Node.h"
+
+namespace Tools
+{
+ template<> class PointerPool<SpatialIndex::MVRTree::Node>
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ SpatialIndex::MVRTree::Node* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<SpatialIndex::MVRTree::Node> acquire()
+ {
+ if (! m_pool.empty())
+ {
+ SpatialIndex::MVRTree::Node* p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ ++m_hits;
+ #endif
+
+ return PoolPointer<SpatialIndex::MVRTree::Node>(p, this);
+ }
+ #ifndef NDEBUG
+ else
+ {
+ // fixme: well sort of...
+ ++m_pointerCount;
+ ++m_misses;
+ }
+ #endif
+
+ return PoolPointer<SpatialIndex::MVRTree::Node>();
+ }
+
+ void release(SpatialIndex::MVRTree::Node* p)
+ {
+ if (p != 0)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ if (p->m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ if (p->m_pData[cChild] != 0) delete[] p->m_pData[cChild];
+ }
+ }
+
+ p->m_level = 0;
+ p->m_identifier = -1;
+ p->m_children = 0;
+ p->m_totalDataLength = 0;
+
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ protected:
+ uint32_t m_capacity;
+ std::stack<SpatialIndex::MVRTree::Node*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.cc.svn-base
new file mode 100644
index 000000000..3ffbcefae
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.cc.svn-base
@@ -0,0 +1,191 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Statistics.h"
+
+using namespace SpatialIndex::MVRTree;
+
+Statistics::Statistics()
+{
+ reset();
+}
+
+Statistics::Statistics(const Statistics& s)
+{
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u32DeadIndexNodes = s.m_u32DeadIndexNodes;
+ m_u32DeadLeafNodes = s.m_u32DeadLeafNodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u64TotalData = s.m_u64TotalData;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+}
+
+Statistics::~Statistics()
+{
+}
+
+Statistics& Statistics::operator=(const Statistics& s)
+{
+ if (this != &s)
+ {
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u32DeadIndexNodes = s.m_u32DeadIndexNodes;
+ m_u32DeadLeafNodes = s.m_u32DeadLeafNodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u64TotalData = s.m_u64TotalData;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+ }
+
+ return *this;
+}
+
+uint64_t Statistics::getReads() const
+{
+ return m_u64Reads;
+}
+
+uint64_t Statistics::getWrites() const
+{
+ return m_u64Writes;
+}
+
+uint32_t Statistics::getNumberOfNodes() const
+{
+ return m_u32Nodes;
+}
+
+uint64_t Statistics::getNumberOfData() const
+{
+ return m_u64Data;
+}
+
+uint64_t Statistics::getSplits() const
+{
+ return m_u64Splits;
+}
+
+uint64_t Statistics::getHits() const
+{
+ return m_u64Hits;
+}
+
+uint64_t Statistics::getMisses() const
+{
+ return m_u64Misses;
+}
+
+uint64_t Statistics::getAdjustments() const
+{
+ return m_u64Adjustments;
+}
+
+uint64_t Statistics::getQueryResults() const
+{
+ return m_u64QueryResults;
+}
+
+uint32_t Statistics::getTreeHeight() const
+{
+ uint32_t ret = 0;
+
+ for (size_t cIndex = 0; cIndex < m_treeHeight.size(); ++cIndex)
+ {
+ ret = std::max(ret, m_treeHeight[cIndex]);
+ }
+
+ return ret;
+}
+
+uint32_t Statistics::getNumberOfNodesInLevel(uint32_t l) const
+{
+ try
+ {
+ return m_nodesInLevel.at(l);
+ }
+ catch (...)
+ {
+ throw Tools::IndexOutOfBoundsException(l);
+ }
+}
+
+void Statistics::reset()
+{
+ m_u64Reads = 0;
+ m_u64Writes = 0;
+ m_u64Splits = 0;
+ m_u64Hits = 0;
+ m_u64Misses = 0;
+ m_u32Nodes = 0;
+ m_u32DeadIndexNodes = 0;
+ m_u32DeadLeafNodes = 0;
+ m_u64Adjustments = 0;
+ m_u64QueryResults = 0;
+ m_u64Data = 0;
+ m_u64TotalData = 0;
+ m_treeHeight.clear();
+ m_nodesInLevel.clear();
+}
+
+std::ostream& SpatialIndex::MVRTree::operator<<(std::ostream& os, const Statistics& s)
+{
+ os << "Reads: " << s.m_u64Reads << std::endl
+ << "Writes: " << s.m_u64Writes << std::endl
+ << "Hits: " << s.m_u64Hits << std::endl
+ << "Misses: " << s.m_u64Misses << std::endl
+ << "Number of live data: " << s.m_u64Data << std::endl
+ << "Total number of data: " << s.m_u64TotalData << std::endl
+ << "Number of nodes: " << s.m_u32Nodes << std::endl
+ << "Numer of dead index nodes: " << s.m_u32DeadIndexNodes << std::endl
+ << "Numer of dead leaf nodes: " << s.m_u32DeadLeafNodes << std::endl;
+
+ for (size_t cTree = 0; cTree < s.m_treeHeight.size(); ++cTree)
+ {
+ os << "Tree " << cTree << ", Height " << s.m_treeHeight[cTree] << std::endl;
+ }
+
+ for (size_t cLevel = 0; cLevel < s.m_nodesInLevel.size(); ++cLevel)
+ {
+ os << "Level " << cLevel << " pages: " << s.m_nodesInLevel[cLevel] << std::endl;
+ }
+
+ os << "Splits: " << s.m_u64Splits << std::endl
+ << "Adjustments: " << s.m_u64Adjustments << std::endl
+ << "Query results: " << s.m_u64QueryResults << std::endl;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.h.svn-base
new file mode 100644
index 000000000..249a98cac
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/.svn/text-base/Statistics.h.svn-base
@@ -0,0 +1,99 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class MVRTree;
+ class Node;
+ class Leaf;
+ class Index;
+
+ class Statistics : public SpatialIndex::IStatistics
+ {
+ public:
+ Statistics();
+ Statistics(const Statistics&);
+ virtual ~Statistics();
+ Statistics& operator=(const Statistics&);
+
+ //
+ // IStatistics interface
+ //
+ virtual uint64_t getReads() const;
+ virtual uint64_t getWrites() const;
+ virtual uint32_t getNumberOfNodes() const;
+ virtual uint64_t getNumberOfData() const;
+
+ virtual uint64_t getSplits() const;
+ virtual uint64_t getHits() const;
+ virtual uint64_t getMisses() const;
+ virtual uint64_t getAdjustments() const;
+ virtual uint64_t getQueryResults() const;
+ virtual uint32_t getTreeHeight() const;
+ virtual uint32_t getNumberOfNodesInLevel(uint32_t l) const;
+
+ private:
+ void reset();
+
+ uint64_t m_u64Reads;
+
+ uint64_t m_u64Writes;
+
+ uint64_t m_u64Splits;
+
+ uint64_t m_u64Hits;
+
+ uint64_t m_u64Misses;
+
+ uint32_t m_u32Nodes;
+
+ uint32_t m_u32DeadIndexNodes;
+
+ uint32_t m_u32DeadLeafNodes;
+
+ uint64_t m_u64Adjustments;
+
+ uint64_t m_u64QueryResults;
+
+ uint64_t m_u64Data;
+
+ uint64_t m_u64TotalData;
+
+ std::vector<uint32_t> m_treeHeight;
+
+ std::vector<uint32_t> m_nodesInLevel;
+
+ friend class MVRTree;
+ friend class Node;
+ friend class Index;
+ friend class Leaf;
+
+ friend std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }; // Statistics
+
+ std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.cc b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.cc
new file mode 100644
index 000000000..ba5d0e113
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.cc
@@ -0,0 +1,429 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MVRTree.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+
+using namespace SpatialIndex::MVRTree;
+
+Index::~Index()
+{
+}
+
+Index::Index(SpatialIndex::MVRTree::MVRTree* pTree, id_type id, uint32_t level) : Node(pTree, id, level, pTree->m_indexCapacity)
+{
+}
+
+NodePtr Index::chooseSubtree(const TimeRegion& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
+{
+ if (m_level == insertionLevel) return NodePtr(this, &(m_pTree->m_indexPool));
+
+ pathBuffer.push(m_identifier);
+
+ uint32_t child = 0;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ child = findLeastEnlargement(mbr);
+ break;
+ case RV_RSTAR:
+ if (m_level == 1)
+ {
+ // if this node points to leaves...
+ child = findLeastOverlap(mbr);
+ }
+ else
+ {
+ child = findLeastEnlargement(mbr);
+ }
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::chooseSubtree: Tree variant not supported.");
+ }
+ assert (child != std::numeric_limits<uint32_t>::max());
+
+ NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
+ NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
+ assert(n.unique());
+ if (ret.get() == n.get()) n.relinquish();
+
+ return ret;
+}
+
+NodePtr Index::findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // check live nodes only.
+ if (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max()) continue;
+ //if (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max() ||
+ // m_ptrMBR[cChild]->m_startTime > mbr.m_startTime) continue;
+
+ if (m_ptrMBR[cChild]->containsRegion(mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findLeaf(mbr, id, pathBuffer);
+ if (n.get() == l.get()) n.relinquish();
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
+
+void Index::split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_indexPool.acquire();
+ pRight = m_pTree->m_indexPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(0, 0, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(0, 0, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ }
+}
+
+uint32_t Index::findLeastEnlargement(const TimeRegion& r) const
+{
+ double area = std::numeric_limits<double>::max();
+ uint32_t best = std::numeric_limits<uint32_t>::max();
+
+ TimeRegionPtr t = m_pTree->m_regionPool.acquire();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // if this child is already dead do not consider it.
+ if (m_ptrMBR[cChild]->m_endTime <= r.m_startTime) continue;
+
+ m_ptrMBR[cChild]->getCombinedRegion(*t, r);
+
+ double a = m_ptrMBR[cChild]->getArea();
+ double enl = t->getArea() - a;
+
+ if (enl < area)
+ {
+ area = enl;
+ best = cChild;
+ }
+ else if (
+ enl > area - std::numeric_limits<double>::epsilon() &&
+ enl < area + std::numeric_limits<double>::epsilon())
+ {
+ if (a < m_ptrMBR[best]->getArea()) best = cChild;
+ }
+ }
+
+#ifndef NDEBUG
+ if (best == std::numeric_limits<uint32_t>::max())
+ {
+ std::ostringstream s;
+ s << "findLeastEnlargement: All entries of node " << m_identifier << " are dead.";
+ throw Tools::IllegalStateException(s.str());
+ }
+#endif
+
+ return best;
+}
+
+uint32_t Index::findLeastOverlap(const TimeRegion& r) const
+{
+ OverlapEntry** entries = new OverlapEntry*[m_children];
+
+ double leastOverlap = std::numeric_limits<double>::max();
+ double me = std::numeric_limits<double>::max();
+ OverlapEntry* best = 0;
+ uint32_t cLiveEntries = 0;
+
+ // find combined region and enlargement of every entry and store it.
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->m_endTime <= r.m_startTime) continue;
+
+ try
+ {
+ entries[cLiveEntries] = new OverlapEntry();
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cLiveEntries; ++i) delete entries[i];
+ delete[] entries;
+ throw;
+ }
+
+ entries[cLiveEntries]->m_index = cChild;
+ entries[cLiveEntries]->m_original = m_ptrMBR[cChild];
+ entries[cLiveEntries]->m_combined = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->getCombinedRegion(*(entries[cLiveEntries]->m_combined), r);
+ entries[cLiveEntries]->m_oa = entries[cLiveEntries]->m_original->getArea();
+ entries[cLiveEntries]->m_ca = entries[cLiveEntries]->m_combined->getArea();
+ entries[cLiveEntries]->m_enlargement = entries[cLiveEntries]->m_ca - entries[cLiveEntries]->m_oa;
+
+ if (entries[cLiveEntries]->m_enlargement < me)
+ {
+ me = entries[cLiveEntries]->m_enlargement;
+ best = entries[cLiveEntries];
+ }
+ else if (entries[cLiveEntries]->m_enlargement == me && entries[cLiveEntries]->m_oa < best->m_oa)
+ {
+ best = entries[cLiveEntries];
+ }
+ ++cLiveEntries;
+ }
+
+#ifndef NDEBUG
+ if (cLiveEntries == 0)
+ {
+ std::ostringstream s;
+ s << "findLeastOverlap: All entries of node " << m_identifier << " are dead.";
+ throw Tools::IllegalStateException(s.str());
+ }
+#endif
+
+ if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
+ {
+ uint32_t cIterations;
+
+ if (cLiveEntries > m_pTree->m_nearMinimumOverlapFactor)
+ {
+ // sort entries in increasing order of enlargement.
+ ::qsort(entries, cLiveEntries,
+ sizeof(OverlapEntry*),
+ OverlapEntry::compareEntries);
+ assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
+
+ cIterations = m_pTree->m_nearMinimumOverlapFactor;
+ }
+ else
+ {
+ cIterations = cLiveEntries;
+ }
+
+ // calculate overlap of most important original entries (near minimum overlap cost).
+ for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
+ {
+ double dif = 0.0;
+ OverlapEntry* e = entries[cIndex];
+
+ for (uint32_t cChild = 0; cChild < cLiveEntries; ++cChild)
+ {
+ if (cIndex != cChild)
+ {
+ double f = e->m_combined->getIntersectingArea(*(entries[cChild]->m_original));
+ if (f != 0.0) dif += f - e->m_original->getIntersectingArea(*(entries[cChild]->m_original));
+ }
+ } // for (cChild)
+
+ if (dif < leastOverlap)
+ {
+ leastOverlap = dif;
+ best = e;
+ }
+ else if (dif == leastOverlap)
+ {
+ if (e->m_enlargement == best->m_enlargement)
+ {
+ // keep the one with least area.
+ if (e->m_original->getArea() < best->m_original->getArea()) best = e;
+ }
+ else
+ {
+ // keep the one with least enlargement.
+ if (e->m_enlargement < best->m_enlargement) best = e;
+ }
+ }
+ } // for (cIndex)
+ }
+
+ uint32_t ret = best->m_index;
+
+ for (uint32_t cChild = 0; cChild < cLiveEntries; ++cChild)
+ {
+ delete entries[cChild];
+ }
+ delete[] entries;
+
+ return ret;
+}
+
+void Index::adjustTree(Node* n, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ bool bContained = m_nodeMBR.containsRegion(n->m_nodeMBR);
+ bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
+
+ // we should not adjust time here
+ double st = m_ptrMBR[child]->m_startTime;
+ double en = m_ptrMBR[child]->m_endTime;
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+ m_ptrMBR[child]->m_startTime = st;
+ m_ptrMBR[child]->m_endTime = en;
+
+ if (bRecompute)
+ {
+ // no need to update times here. The inserted MBR is younger than all nodes.
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ if (bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
+
+void Index::adjustTree(Node* n, Node* nn, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child, child2 = m_capacity;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == nn->m_identifier) child2 = child;
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+
+ if (child2 == m_capacity)
+ {
+ for (child2 = child + 1; child2 < m_children; ++child2)
+ {
+ if (m_pIdentifier[child2] == nn->m_identifier) break;
+ }
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ // 3. the SIBLING MBR is touching.
+ bool b1 = m_nodeMBR.containsRegion(n->m_nodeMBR);
+ bool b2 = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool b3 = m_nodeMBR.touchesRegion(*(m_ptrMBR[child2]));
+ bool bRecompute = (! b1) || ((b2 || b3) && m_pTree->m_bTightMBRs);
+
+ // we should not adjust time here
+ double st = m_ptrMBR[child]->m_startTime;
+ double en = m_ptrMBR[child]->m_endTime;
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+ m_ptrMBR[child]->m_startTime = st;
+ m_ptrMBR[child]->m_endTime = en;
+
+ st = m_ptrMBR[child2]->m_startTime;
+ en = m_ptrMBR[child2]->m_endTime;
+ *(m_ptrMBR[child2]) = nn->m_nodeMBR;
+ m_ptrMBR[child2]->m_startTime = st;
+ m_ptrMBR[child2]->m_endTime = en;
+
+ if (bRecompute)
+ {
+ // no need to update times here. The inserted MBR is younger than all nodes.
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ if (bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.h b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.h
new file mode 100644
index 000000000..e5fa86a8c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Index.h
@@ -0,0 +1,75 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class Index : public Node
+ {
+ public:
+ virtual ~Index();
+
+ private:
+ Index(MVRTree* pTree, id_type id, uint32_t level);
+
+ virtual NodePtr chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& left, NodePtr& right,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+
+ uint32_t findLeastEnlargement(const TimeRegion&) const;
+ uint32_t findLeastOverlap(const TimeRegion&) const;
+
+ void adjustTree(Node*, std::stack<id_type>&);
+ void adjustTree(Node* n, Node* nn, std::stack<id_type>& pathBuffer);
+
+ class OverlapEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_enlargement;
+ TimeRegionPtr m_original;
+ TimeRegionPtr m_combined;
+ double m_oa;
+ double m_ca;
+
+ static int compareEntries(const void* pv1, const void* pv2)
+ {
+ OverlapEntry* pe1 = * (OverlapEntry**) pv1;
+ OverlapEntry* pe2 = * (OverlapEntry**) pv2;
+
+ if (pe1->m_enlargement < pe2->m_enlargement) return -1;
+ if (pe1->m_enlargement > pe2->m_enlargement) return 1;
+ return 0;
+ }
+ }; // OverlapEntry
+
+ friend class MVRTree;
+ friend class Node;
+ }; // Index
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.cc b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.cc
new file mode 100644
index 000000000..925c170da
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.cc
@@ -0,0 +1,103 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MVRTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::MVRTree;
+
+Leaf::~Leaf()
+{
+}
+
+Leaf::Leaf(SpatialIndex::MVRTree::MVRTree* pTree, id_type id): Node(pTree, id, 0, pTree->m_leafCapacity)
+{
+}
+
+NodePtr Leaf::chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer)
+{
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ return NodePtr(this, &(m_pTree->m_leafPool));
+}
+
+NodePtr Leaf::findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ if (m_pIdentifier[cChild] == id && static_cast<Region>(mbr) == static_cast<Region>(*(m_ptrMBR[cChild])))
+ return NodePtr(this, &(m_pTree->m_leafPool));
+ }
+
+ return NodePtr();
+}
+
+void Leaf::split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2, mbr2, id2, bInsertMbr2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_leafPool.acquire();
+ pRight = m_pTree->m_leafPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g1[cIndex]] = 0;
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g2[cIndex]] = 0;
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.h b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.h
new file mode 100644
index 000000000..02d653c45
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Leaf.h
@@ -0,0 +1,48 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class Leaf : public Node
+ {
+ public:
+ virtual ~Leaf();
+
+ private:
+ Leaf(MVRTree* pTree, id_type id);
+
+ virtual NodePtr chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& left, NodePtr& right,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+
+ friend class MVRTree;
+ friend class Node;
+ }; // Leaf
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.cc b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.cc
new file mode 100644
index 000000000..7520e6689
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.cc
@@ -0,0 +1,1423 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "MVRTree.h"
+
+#include <cstring>
+
+using namespace SpatialIndex::MVRTree;
+
+SpatialIndex::MVRTree::Data::Data(uint32_t len, byte* pData, TimeRegion& r, id_type id)
+ : m_id(id), m_region(r), m_pData(0), m_dataLength(len)
+{
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, pData, m_dataLength);
+ }
+}
+
+SpatialIndex::MVRTree::Data::~Data()
+{
+ delete[] m_pData;
+}
+
+SpatialIndex::MVRTree::Data* SpatialIndex::MVRTree::Data::clone()
+{
+ return new Data(m_dataLength, m_pData, m_region, m_id);
+}
+
+SpatialIndex::id_type SpatialIndex::MVRTree::Data::getIdentifier() const
+{
+ return m_id;
+}
+
+void SpatialIndex::MVRTree::Data::getShape(IShape** out) const
+{
+ *out = new TimeRegion(m_region);
+}
+
+void SpatialIndex::MVRTree::Data::getData(uint32_t& len, byte** data) const
+{
+ len = m_dataLength;
+ *data = 0;
+
+ if (m_dataLength > 0)
+ {
+ *data = new byte[m_dataLength];
+ memcpy(*data, m_pData, m_dataLength);
+ }
+}
+
+uint32_t SpatialIndex::MVRTree::Data::getByteArraySize()
+{
+ return
+ sizeof(id_type) +
+ sizeof(uint32_t) +
+ m_dataLength +
+ m_region.getByteArraySize();
+}
+
+void SpatialIndex::MVRTree::Data::loadFromByteArray(const byte* ptr)
+{
+ memcpy(&m_id, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ delete[] m_pData;
+ m_pData = 0;
+
+ memcpy(&m_dataLength, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, ptr, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ m_region.loadFromByteArray(ptr);
+}
+
+void SpatialIndex::MVRTree::Data::storeToByteArray(byte** data, uint32_t& len)
+{
+ // it is thread safe this way.
+ uint32_t regionsize;
+ byte* regiondata = 0;
+ m_region.storeToByteArray(&regiondata, regionsize);
+
+ len = sizeof(id_type) + sizeof(uint32_t) + m_dataLength + regionsize;
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_id, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_dataLength, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ memcpy(ptr, m_pData, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ memcpy(ptr, regiondata, regionsize);
+ delete[] regiondata;
+ // ptr += regionsize;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::MVRTree::returnMVRTree(SpatialIndex::IStorageManager& sm, Tools::PropertySet& ps)
+{
+ SpatialIndex::ISpatialIndex* si = new SpatialIndex::MVRTree::MVRTree(sm, ps);
+ return si;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::MVRTree::createNewMVRTree(
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ MVRTreeVariant rv,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = fillFactor;
+ ps.setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = indexCapacity;
+ ps.setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = leafCapacity;
+ ps.setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = dimension;
+ ps.setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = rv;
+ ps.setProperty("TreeVariant", var);
+
+ ISpatialIndex* ret = returnMVRTree(sm, ps);
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var = ps.getProperty("IndexIdentifier");
+ indexIdentifier = var.m_val.llVal;
+
+ return ret;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::MVRTree::loadMVRTree(IStorageManager& sm, id_type indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = indexIdentifier;
+ ps.setProperty("IndexIdentifier", var);
+
+ return returnMVRTree(sm, ps);
+}
+
+SpatialIndex::MVRTree::MVRTree::MVRTree(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_pStorageManager(&sm),
+ m_headerID(StorageManager::NewPage),
+ m_treeVariant(RV_RSTAR),
+ m_fillFactor(0.7),
+ m_indexCapacity(100),
+ m_leafCapacity(100),
+ m_nearMinimumOverlapFactor(32),
+ m_splitDistributionFactor(0.4),
+ m_reinsertFactor(0.3),
+ m_strongVersionOverflow(0.8),
+ //m_strongVersionUnderflow(0.2),
+ m_versionUnderflow(0.3),
+ m_dimension(2),
+ m_bTightMBRs(true),
+ m_bHasVersionCopied(false),
+ m_currentTime(0.0),
+ m_pointPool(500),
+ m_regionPool(1000),
+ m_indexPool(100),
+ m_leafPool(100)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+
+ Tools::Variant var = ps.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType == Tools::VT_LONGLONG) m_headerID = var.m_val.llVal;
+ else if (var.m_varType == Tools::VT_LONG) m_headerID = var.m_val.lVal;
+ // for backward compatibility only.
+ else throw Tools::IllegalArgumentException("MVRTree: Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ initOld(ps);
+ }
+ else
+ {
+ initNew(ps);
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = m_headerID;
+ ps.setProperty("IndexIdentifier", var);
+ }
+}
+
+SpatialIndex::MVRTree::MVRTree::~MVRTree()
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_destroy(&m_rwLock);
+#endif
+
+ storeHeader();
+}
+
+//
+// ISpatialIndex interface
+//
+
+void SpatialIndex::MVRTree::MVRTree::insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (ti == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IInterval interface.");
+ if (ti->getLowerBound() < m_currentTime) throw Tools::IllegalArgumentException("insertData: Shape start time is older than tree current time.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("insertData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ // convert the shape into a TimeRegion (R-Trees index regions only; i.e., approximations of the shapes).
+ Region mbrold;
+ shape.getMBR(mbrold);
+
+ TimeRegionPtr mbr = m_regionPool.acquire();
+ mbr->makeDimension(mbrold.m_dimension);
+
+ memcpy(mbr->m_pLow, mbrold.m_pLow, mbrold.m_dimension * sizeof(double));
+ memcpy(mbr->m_pHigh, mbrold.m_pHigh, mbrold.m_dimension * sizeof(double));
+ mbr->m_startTime = ti->getLowerBound();
+ mbr->m_endTime = std::numeric_limits<double>::max();
+
+ byte* buffer = 0;
+
+ if (len > 0)
+ {
+ buffer = new byte[len];
+ memcpy(buffer, pData, len);
+ }
+
+ insertData_impl(len, buffer, *mbr, id);
+ // the buffer is stored in the tree. Do not delete here.
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+bool SpatialIndex::MVRTree::MVRTree::deleteData(const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("deleteData: Shape has the wrong number of dimensions.");
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (ti == 0) throw Tools::IllegalArgumentException("deleteData: Shape does not support the Tools::IInterval interface.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("deleteData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ Region mbrold;
+ shape.getMBR(mbrold);
+
+ TimeRegionPtr mbr = m_regionPool.acquire();
+ mbr->makeDimension(mbrold.m_dimension);
+
+ memcpy(mbr->m_pLow, mbrold.m_pLow, mbrold.m_dimension * sizeof(double));
+ memcpy(mbr->m_pHigh, mbrold.m_pHigh, mbrold.m_dimension * sizeof(double));
+ mbr->m_startTime = ti->getLowerBound();
+ mbr->m_endTime = ti->getUpperBound();
+
+ bool ret = deleteData_impl(*mbr, id);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ return ret;
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::containsWhatQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("containsWhatQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(ContainmentQuery, query, v);
+}
+
+void SpatialIndex::MVRTree::MVRTree::intersectsWithQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("intersectsWithQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(IntersectionQuery, query, v);
+}
+
+void SpatialIndex::MVRTree::MVRTree::pointLocationQuery(const Point& query, IVisitor& v)
+{
+ if (query.m_dimension != m_dimension) throw Tools::IllegalArgumentException("pointLocationQuery: Shape has the wrong number of dimensions.");
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&query);
+ if (ti == 0) throw Tools::IllegalArgumentException("pointLocationQuery: Shape does not support the Tools::IInterval interface.");
+ TimeRegion r(query, query, *ti);
+ rangeQuery(IntersectionQuery, r, v);
+}
+
+void SpatialIndex::MVRTree::MVRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc)
+{
+ throw Tools::IllegalStateException("nearestNeighborQuery: not impelmented yet.");
+}
+
+void SpatialIndex::MVRTree::MVRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+ NNComparator nnc;
+ nearestNeighborQuery(k, query, v, nnc);
+}
+
+void SpatialIndex::MVRTree::MVRTree::selfJoinQuery(const IShape& query, IVisitor& v)
+{
+ throw Tools::IllegalStateException("selfJoinQuery: not impelmented yet.");
+}
+
+void SpatialIndex::MVRTree::MVRTree::queryStrategy(IQueryStrategy& qs)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");
+#endif
+
+ id_type next = m_roots[m_roots.size() - 1].m_id;
+ bool hasNext = true;
+
+ try
+ {
+ while (hasNext)
+ {
+ NodePtr n = readNode(next);
+ qs.getNextEntry(*n, next, hasNext);
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::getIndexProperties(Tools::PropertySet& out) const
+{
+ Tools::Variant var;
+
+ // dimension
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_dimension;
+ out.setProperty("Dimension", var);
+
+ // index capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexCapacity;
+ out.setProperty("IndexCapacity", var);
+
+ // leaf capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafCapacity;
+ out.setProperty("LeafCapacity", var);
+
+ // Tree variant
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = m_treeVariant;
+ out.setProperty("TreeVariant", var);
+
+ // fill factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_fillFactor;
+ out.setProperty("FillFactor", var);
+
+ // near minimum overlap factor
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_nearMinimumOverlapFactor;
+ out.setProperty("NearMinimumOverlapFactor", var);
+
+ // split distribution factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_splitDistributionFactor;
+ out.setProperty("SplitDistributionFactor", var);
+
+ // reinsert factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_reinsertFactor;
+ out.setProperty("ReinsertFactor", var);
+
+ // tight MBRs
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = m_bTightMBRs;
+ out.setProperty("EnsureTightMBRs", var);
+
+ // index pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexPool.getCapacity();
+ out.setProperty("IndexPoolCapacity", var);
+
+ // leaf pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafPool.getCapacity();
+ out.setProperty("LeafPoolCapacity", var);
+
+ // region pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_regionPool.getCapacity();
+ out.setProperty("RegionPoolCapacity", var);
+
+ // point pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_pointPool.getCapacity();
+ out.setProperty("PointPoolCapacity", var);
+
+ // strong version overflow
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_strongVersionOverflow;
+ out.setProperty("StrongVersionOverflow", var);
+
+ // strong version underflow
+ //var.m_varType = Tools::VT_DOUBLE;
+ //var.m_val.dblVal = m_strongVersionUnderflow;
+ //out.setProperty("StrongVersionUnderflow", var);
+
+ // weak version underflow
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_versionUnderflow;
+ out.setProperty("VersionUnderflow", var);
+}
+
+void SpatialIndex::MVRTree::MVRTree::addCommand(ICommand* pCommand, CommandType ct)
+{
+ switch (ct)
+ {
+ case CT_NODEREAD:
+ m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEWRITE:
+ m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEDELETE:
+ m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ }
+}
+
+bool SpatialIndex::MVRTree::MVRTree::isIndexValid()
+{
+ bool ret = true;
+ std::stack<ValidateEntry> st;
+ std::set<id_type> visitedEntries;
+ uint32_t degenerateEntries = 0;
+
+ for (uint32_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
+ {
+ NodePtr root = readNode(m_roots[cRoot].m_id);
+
+ if (root->m_level != m_stats.m_treeHeight[cRoot] - 1)
+ {
+ std::cerr << "Invalid tree height." << std::endl;
+ return false;
+ }
+
+ ValidateEntry e(0, root->m_nodeMBR, root);
+ e.m_bIsDead = (root->m_nodeMBR.m_endTime < std::numeric_limits<double>::max()) ? true : false;
+ st.push(e);
+ }
+
+ while (! st.empty())
+ {
+ ValidateEntry e = st.top(); st.pop();
+
+ std::set<id_type>::iterator itSet = visitedEntries.find(e.m_pNode->m_identifier);
+ if (itSet == visitedEntries.end())
+ {
+ visitedEntries.insert(e.m_pNode->m_identifier);
+ if (e.m_pNode->m_nodeMBR.m_startTime == e.m_pNode->m_nodeMBR.m_endTime) ++degenerateEntries;
+ }
+
+ TimeRegion tmpRegion;
+ tmpRegion = m_infiniteRegion;
+
+ for (uint32_t cDim = 0; cDim < tmpRegion.m_dimension; ++cDim)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]);
+ tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+
+ tmpRegion.m_startTime = e.m_pNode->m_nodeMBR.m_startTime;
+ tmpRegion.m_endTime = e.m_pNode->m_nodeMBR.m_endTime;
+ if (! (tmpRegion == e.m_pNode->m_nodeMBR))
+ {
+ std::cerr << "Invalid parent information." << std::endl;
+ ret = false;
+ }
+
+ if (! e.m_bIsDead)
+ {
+ tmpRegion.m_startTime = e.m_parentMBR.m_startTime;
+ tmpRegion.m_endTime = e.m_parentMBR.m_endTime;
+ if (! (tmpRegion == e.m_parentMBR))
+ {
+ std::cerr << "Error in parent (Node id: " << e.m_pNode->m_identifier << ", Parent id: " << e.m_parentID << ")." << std::endl;
+ ret = false;
+ }
+ }
+
+ if (e.m_pNode->m_level != 0)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
+
+ bool bIsDead =
+ (e.m_pNode->m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max() || e.m_bIsDead) ? true : false;
+
+ // if the parent says that this child is dead, force it dead since
+ // this information is not propagated for efficiency and is inconsistent.
+ if (bIsDead) ptrN->m_nodeMBR.m_endTime = e.m_pNode->m_ptrMBR[cChild]->m_endTime;
+
+ ValidateEntry tmpEntry(e.m_pNode->m_identifier, *(e.m_pNode->m_ptrMBR[cChild]), ptrN);
+ tmpEntry.m_bIsDead = bIsDead;
+ st.push(tmpEntry);
+ }
+ }
+ }
+
+ //std::cerr << "Total accessible nodes: " << visitedEntries.size() << std::endl;
+ //std::cerr << "Degenerate nodes: " << degenerateEntries << std::endl;
+
+ return ret;
+}
+
+void SpatialIndex::MVRTree::MVRTree::getStatistics(IStatistics** out) const
+{
+ *out = new Statistics(m_stats);
+}
+
+void SpatialIndex::MVRTree::MVRTree::initNew(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG || (var.m_val.lVal != RV_LINEAR && var.m_val.lVal != RV_QUADRATIC && var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of MVRTreeVariant type");
+
+ m_treeVariant = static_cast<MVRTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ //((m_treeVariant == RV_LINEAR || m_treeVariant == RV_QUADRATIC) && var.m_val.dblVal > 0.5) ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor must be Tools::VT_DOUBLE and in (0.0, 1.0) for RSTAR, (0.0, 0.5) for LINEAR and QUADRATIC");
+
+ m_fillFactor = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 10)
+ throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 10");
+
+ m_indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 10)
+ throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 10");
+
+ m_leafCapacity = var.m_val.ulVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 1 || var.m_val.ulVal > m_indexCapacity || var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1) throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1");
+
+ m_dimension = var.m_val.ulVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // strong version overflow
+ var = ps.getProperty("StrongVersionOverflow");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property StrongVersionOverflow must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_strongVersionOverflow = var.m_val.dblVal;
+ }
+
+ // strong version underflow
+ //var = ps.getProperty("StrongVersionUnderflow");
+ //if (var.m_varType != Tools::VT_EMPTY)
+ //{
+ // if (var.m_varType != Tools::VT_DOUBLE ||
+ // var.m_val.dblVal <= 0.0 ||
+ // var.m_val.dblVal >= 1.0) throw Tools::IllegalArgumentException("Property StrongVersionUnderflow must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ // m_strongVersionUnderflow = var.m_val.dblVal;
+ //}
+
+ // weak version underflow
+ var = ps.getProperty("VersionUnderflow");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property VersionUnderflow must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_versionUnderflow = var.m_val.dblVal;
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+
+ m_stats.m_treeHeight.push_back(1);
+ m_stats.m_nodesInLevel.push_back(1);
+
+ Leaf root(this, -1);
+ root.m_nodeMBR.m_startTime = 0.0;
+ root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ writeNode(&root);
+ m_roots.push_back(RootEntry(root.m_identifier, root.m_nodeMBR.m_startTime, root.m_nodeMBR.m_endTime));
+
+ storeHeader();
+}
+
+void SpatialIndex::MVRTree::MVRTree::initOld(Tools::PropertySet& ps)
+{
+ loadHeader();
+
+ // only some of the properties may be changed.
+ // the rest are just ignored.
+
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_LONG || (var.m_val.lVal != RV_LINEAR && var.m_val.lVal != RV_QUADRATIC && var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of MVRTreeVariant type");
+
+ m_treeVariant = static_cast<MVRTreeVariant>(var.m_val.lVal);
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 1 || var.m_val.ulVal > m_indexCapacity || var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE ||var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+}
+
+void SpatialIndex::MVRTree::MVRTree::storeHeader()
+{
+ const uint32_t headerSize =
+ sizeof(uint32_t) + // size of m_roots
+ static_cast<uint32_t>(m_roots.size())
+ * (sizeof(id_type) + 2 * sizeof(double)) + // m_roots
+ sizeof(MVRTreeVariant) + // m_treeVariant
+ sizeof(double)+ // m_fillFactor
+ sizeof(uint32_t) + // m_indexCapacity
+ sizeof(uint32_t) + // m_leafCapacity
+ sizeof(uint32_t) + // m_nearMinimumOverlapFactor
+ sizeof(double) + // m_splitDistributionFactor
+ sizeof(double) + // m_reinsertFactor
+ sizeof(uint32_t) + // m_dimension
+ sizeof(byte) + // m_bTightMBRs
+ sizeof(uint32_t) + // m_stats.m_nodes
+ sizeof(uint64_t) + // m_stats.m_totalData
+ sizeof(uint32_t) + // m_stats.m_deadIndexNodes
+ sizeof(uint32_t) + // m_stats.m_deadLeafNodes
+ sizeof(uint64_t) + // m_stats.m_data
+ sizeof(uint32_t) + // size of m_stats.m_treeHeight
+ static_cast<uint32_t>(m_stats.m_treeHeight.size())
+ * sizeof(uint32_t) + // m_stats.m_treeHeight
+ sizeof(double) + // m_strongVersionOverflow
+ //sizeof(double) + // m_strongVersionUnderflow
+ sizeof(double) + // m_versionUnderflow
+ sizeof(double) + // m_currentTime
+ sizeof(uint32_t) + // m_nodesInLevel size
+ static_cast<uint32_t>(m_stats.m_nodesInLevel.size())
+ * sizeof(uint32_t); // m_nodesInLevel values
+
+ byte* header = new byte[headerSize];
+ byte* ptr = header;
+
+ uint32_t u32I = static_cast<uint32_t>(m_roots.size());
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (size_t cIndex = 0; cIndex < m_roots.size(); ++cIndex)
+ {
+ RootEntry& e = m_roots[cIndex];
+ memcpy(ptr, &(e.m_id), sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &(e.m_startTime), sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(e.m_endTime), sizeof(double));
+ ptr += sizeof(double);
+ }
+
+ memcpy(ptr, &m_treeVariant, sizeof(MVRTreeVariant));
+ ptr += sizeof(MVRTreeVariant);
+ memcpy(ptr, &m_fillFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_indexCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_leafCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_splitDistributionFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_reinsertFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ byte c = (byte) m_bTightMBRs;
+ memcpy(ptr, &c, sizeof(byte));
+ ptr += sizeof(byte);
+ memcpy(ptr, &(m_stats.m_u32Nodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u64TotalData), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(ptr, &(m_stats.m_u32DeadIndexNodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u32DeadLeafNodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u64Data), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+
+ u32I = static_cast<uint32_t>(m_stats.m_treeHeight.size());
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (size_t cIndex = 0; cIndex < m_stats.m_treeHeight.size(); ++cIndex)
+ {
+ u32I = m_stats.m_treeHeight[cIndex];
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ memcpy(ptr, &m_strongVersionOverflow, sizeof(double));
+ ptr += sizeof(double);
+ //memcpy(ptr, &m_strongVersionUnderflow, sizeof(double));
+ //ptr += sizeof(double);
+ memcpy(ptr, &m_versionUnderflow, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_currentTime, sizeof(double));
+ ptr += sizeof(double);
+
+ u32I = static_cast<uint32_t>(m_stats.m_nodesInLevel.size());
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (size_t cLevel = 0; cLevel < m_stats.m_nodesInLevel.size(); ++cLevel)
+ {
+ u32I = m_stats.m_nodesInLevel[cLevel];
+ memcpy(ptr, &u32I, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
+
+ delete[] header;
+}
+
+void SpatialIndex::MVRTree::MVRTree::loadHeader()
+{
+ uint32_t headerSize;
+ byte* header = 0;
+ m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
+
+ byte* ptr = header;
+
+ uint32_t rootsSize;
+ memcpy(&rootsSize, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cIndex = 0; cIndex < rootsSize; ++cIndex)
+ {
+ RootEntry e;
+ memcpy(&(e.m_id), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&(e.m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(e.m_endTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ m_roots.push_back(e);
+ }
+
+ memcpy(&m_treeVariant, ptr, sizeof(MVRTreeVariant));
+ ptr += sizeof(MVRTreeVariant);
+ memcpy(&m_fillFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_indexCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_leafCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_splitDistributionFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_reinsertFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ byte c;
+ memcpy(&c, ptr, sizeof(byte));
+ m_bTightMBRs = (c != 0);
+ ptr += sizeof(byte);
+ memcpy(&(m_stats.m_u32Nodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u64TotalData), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(&(m_stats.m_u32DeadIndexNodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u32DeadLeafNodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u64Data), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+
+ uint32_t treeHeightSize;
+ memcpy(&treeHeightSize, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cIndex = 0; cIndex < treeHeightSize; ++cIndex)
+ {
+ uint32_t u32I;
+ memcpy(&u32I, ptr, sizeof(uint32_t));
+ m_stats.m_treeHeight.push_back(u32I);
+ ptr += sizeof(uint32_t);
+ }
+
+ memcpy(&m_strongVersionOverflow, ptr, sizeof(double));
+ ptr += sizeof(double);
+ //memcpy(&m_strongVersionUnderflow, ptr, sizeof(double));
+ //ptr += sizeof(double);
+ memcpy(&m_versionUnderflow, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_currentTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ uint32_t nodesInLevelSize;
+ memcpy(&nodesInLevelSize, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < nodesInLevelSize; ++cLevel)
+ {
+ uint32_t u32I;
+ memcpy(&u32I, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ m_stats.m_nodesInLevel.push_back(u32I);
+ }
+
+ delete[] header;
+}
+
+void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id)
+{
+ assert(mbr.getDimension() == m_dimension);
+ assert(m_currentTime <= mbr.m_startTime);
+
+ std::stack<id_type> pathBuffer;
+ m_currentTime = mbr.m_startTime;
+
+ NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
+ NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);
+
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mbr, id, pathBuffer, m_infiniteRegion, -1, false);
+
+ ++(m_stats.m_u64Data);
+ ++(m_stats.m_u64TotalData);
+}
+
+void SpatialIndex::MVRTree::MVRTree::insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, uint32_t level)
+{
+ assert(mbr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+
+ NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
+ NodePtr l = root->chooseSubtree(mbr, level, pathBuffer);
+
+ assert(l->m_level == level);
+
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mbr, id, pathBuffer, m_infiniteRegion, -1, false);
+}
+
+bool SpatialIndex::MVRTree::MVRTree::deleteData_impl(const TimeRegion& mbr, id_type id)
+{
+ assert(mbr.m_dimension == m_dimension);
+
+ m_currentTime = mbr.m_endTime;
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_roots[m_roots.size() - 1].m_id);
+ NodePtr l = root->findLeaf(mbr, id, pathBuffer);
+
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+
+ if (l.get() != 0)
+ {
+ l->deleteData(id, mbr.m_endTime, pathBuffer);
+ --(m_stats.m_u64Data);
+ return true;
+ }
+
+ return false;
+}
+
+SpatialIndex::id_type SpatialIndex::MVRTree::MVRTree::writeNode(Node* n)
+{
+ byte* buffer;
+ uint32_t dataLength;
+ n->storeToByteArray(&buffer, dataLength);
+
+ id_type page;
+ if (n->m_identifier < 0) page = StorageManager::NewPage;
+ else page = n->m_identifier;
+
+ try
+ {
+ m_pStorageManager->storeByteArray(page, dataLength, buffer);
+ delete[] buffer;
+ }
+ catch (InvalidPageException& e)
+ {
+ delete[] buffer;
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("writeNode: failed with Tools::InvalidPageException");
+ }
+
+ if (n->m_identifier < 0)
+ {
+ n->m_identifier = page;
+ ++(m_stats.m_u32Nodes);
+ }
+
+ ++(m_stats.m_u64Writes);
+
+ for (size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
+ {
+ m_writeNodeCommands[cIndex]->execute(*n);
+ }
+
+ return page;
+}
+
+SpatialIndex::MVRTree::NodePtr SpatialIndex::MVRTree::MVRTree::readNode(id_type id)
+{
+ uint32_t dataLength;
+ byte* buffer;
+
+ try
+ {
+ m_pStorageManager->loadByteArray(id, dataLength, &buffer);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("readNode: failed with Tools::InvalidPageException");
+ }
+
+ try
+ {
+ uint32_t nodeType;
+ memcpy(&nodeType, buffer, sizeof(uint32_t));
+
+ NodePtr n;
+
+ if (nodeType == PersistentIndex) n = m_indexPool.acquire();
+ else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();
+ else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");
+
+ if (n.get() == 0)
+ {
+ if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);
+ else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);
+ }
+
+ //n->m_pTree = this;
+ n->m_identifier = id;
+ n->loadFromByteArray(buffer);
+
+ ++(m_stats.m_u64Reads);
+
+ for (size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
+ {
+ m_readNodeCommands[cIndex]->execute(*n);
+ }
+
+ delete[] buffer;
+ return n;
+ }
+ catch (...)
+ {
+ delete[] buffer;
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::deleteNode(Node* n)
+{
+ try
+ {
+ m_pStorageManager->deleteByteArray(n->m_identifier);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("deleteNode: failed with Tools::InvalidPageException");
+ }
+
+ --(m_stats.m_u32Nodes);
+
+ for (size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
+ {
+ m_deleteNodeCommands[cIndex]->execute(*n);
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v)
+{
+ // any shape that implements IInterval and IShape, can be used here.
+ // FIXME: I am not using ITimeShape yet, even though I should.
+
+ const Tools::IInterval* ti = dynamic_cast<const Tools::IInterval*>(&query);
+ if (ti == 0) throw Tools::IllegalArgumentException("rangeQuery: Shape does not support the Tools::IInterval interface.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::set<id_type> visitedNodes;
+ std::set<id_type> visitedData;
+ std::stack<NodePtr> st;
+ std::vector<id_type> ids;
+ findRootIdentifiers(*ti, ids);
+
+ for (size_t cRoot = 0; cRoot < ids.size(); ++cRoot)
+ {
+ NodePtr root = readNode(ids[cRoot]);
+ if (root->m_children > 0 && query.intersectsShape(root->m_nodeMBR)) st.push(root);
+ }
+
+ while (! st.empty())
+ {
+ NodePtr n = st.top(); st.pop();
+ visitedNodes.insert(n->m_identifier);
+
+ if (n->m_level == 0)
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (visitedData.find(n->m_pIdentifier[cChild]) != visitedData.end()) continue;
+
+ bool b;
+ if (type == ContainmentQuery) b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.containsShape(*(n->m_ptrMBR[cChild]));
+ else b = (n->m_ptrMBR[cChild])->intersectsInterval(*ti) && query.intersectsShape(*(n->m_ptrMBR[cChild]));
+
+ if (b)
+ {
+ visitedData.insert(n->m_pIdentifier[cChild]);
+ Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ v.visitData(data);
+ ++(m_stats.m_u64QueryResults);
+ }
+ }
+ }
+ else
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (
+ visitedNodes.find(n->m_pIdentifier[cChild]) == visitedNodes.end() &&
+ n->m_ptrMBR[cChild]->intersectsInterval(*ti) &&
+ query.intersectsShape(*(n->m_ptrMBR[cChild])))
+ st.push(readNode(n->m_pIdentifier[cChild]));
+ }
+ }
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::MVRTree::MVRTree::findRootIdentifiers(const Tools::IInterval& ti, std::vector<id_type>& ids)
+{
+ ids.clear();
+
+ for (size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
+ {
+ RootEntry& e = m_roots[cRoot];
+ if (ti.intersectsInterval(Tools::IT_RIGHTOPEN, e.m_startTime, e.m_endTime)) ids.push_back(e.m_id);
+ }
+}
+
+std::string SpatialIndex::MVRTree::MVRTree::printRootInfo() const
+{
+ std::ostringstream s;
+
+ for (size_t cRoot = 0; cRoot < m_roots.size(); ++cRoot)
+ {
+ const RootEntry& e = m_roots[cRoot];
+
+ s << "Root " << cRoot << ": Start " << e.m_startTime << ", End " << e.m_endTime << std::endl;
+ }
+
+ return s.str();
+}
+
+std::ostream& SpatialIndex::MVRTree::operator<<(std::ostream& os, const MVRTree& t)
+{
+ os << "Dimension: " << t.m_dimension << std::endl
+ << "Fill factor: " << t.m_fillFactor << std::endl
+ << "Index capacity: " << t.m_indexCapacity << std::endl
+ << "Leaf capacity: " << t.m_leafCapacity << std::endl
+ << "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << std::endl;
+
+ if (t.m_treeVariant == RV_RSTAR)
+ {
+ os << "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
+ << "Reinsert factor: " << t.m_reinsertFactor << std::endl
+ << "Split distribution factor: " << t.m_splitDistributionFactor << std::endl
+ << "Strong version overflow: " << t.m_strongVersionOverflow << std::endl
+ //<< "Strong version underflow: " << t.m_strongVersionUnderflow << std::endl
+ << "Weak version underflow: " << t.m_versionUnderflow << std::endl;
+ }
+
+ // it is difficult to count utilization
+ //os << "Utilization: " << 100 * t.m_stats.m_totalData / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << std::endl
+
+ os << t.m_stats;
+ os << t.printRootInfo();
+
+ #ifndef NDEBUG
+ os << "Leaf pool hits: " << t.m_leafPool.m_hits << std::endl
+ << "Leaf pool misses: " << t.m_leafPool.m_misses << std::endl
+ << "Index pool hits: " << t.m_indexPool.m_hits << std::endl
+ << "Index pool misses: " << t.m_indexPool.m_misses << std::endl
+ << "Region pool hits: " << t.m_regionPool.m_hits << std::endl
+ << "Region pool misses: " << t.m_regionPool.m_misses << std::endl
+ << "Point pool hits: " << t.m_pointPool.m_hits << std::endl
+ << "Point pool misses: " << t.m_pointPool.m_misses << std::endl;
+ #endif
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.h b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.h
new file mode 100644
index 000000000..cfbe33c1e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/MVRTree.h
@@ -0,0 +1,222 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Statistics.h"
+#include "Node.h"
+#include "PointerPoolNode.h"
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class MVRTree : public ISpatialIndex
+ {
+ class NNEntry;
+ class RootEntry;
+
+ public:
+ MVRTree(IStorageManager&, Tools::PropertySet&);
+ // String Value Description
+ // ----------------------------------------------
+ // IndexIndentifier VT_LONG If specified an existing index will be openened from the supplied
+ // storage manager with the given index id. Behaviour is unspecified
+ // if the index id or the storage manager are incorrect.
+ // Dimension VT_ULONG Dimensionality of the data that will be inserted.
+ // IndexCapacity VT_ULONG The index node capacity. Default is 100.
+ // LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+ // FillFactor VT_DOUBLE The fill factor. Default is 70%
+ // TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+ // NearMinimumOverlapFactor VT_ULONG Default is 32.
+ // SplitDistributionFactor VT_DOUBLE Default is 0.4
+ // ReinsertFactor VT_DOUBLE Default is 0.3
+ // EnsureTightMBRs VT_BOOL Default is true
+ // IndexPoolCapacity VT_LONG Default is 100
+ // LeafPoolCapacity VT_LONG Default is 100
+ // RegionPoolCapacity VT_LONG Default is 1000
+ // PointPoolCapacity VT_LONG Default is 500
+ // StrongVersionOverflow VT_DOUBLE Default is 0.8
+ // VersionUnderflow VT_DOUBLE Default is 0.3
+
+ virtual ~MVRTree();
+
+ //
+ // ISpatialIndex interface
+ //
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id);
+ virtual bool deleteData(const IShape& shape, id_type id);
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v);
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v);
+ virtual void pointLocationQuery(const Point& query, IVisitor& v);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator&);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v);
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v);
+ virtual void queryStrategy(IQueryStrategy& qs);
+ virtual void getIndexProperties(Tools::PropertySet& out) const;
+ virtual void addCommand(ICommand* pCommand, CommandType ct);
+ virtual bool isIndexValid();
+ virtual void getStatistics(IStatistics** out) const;
+
+ private:
+ void initNew(Tools::PropertySet&);
+ void initOld(Tools::PropertySet& ps);
+ void storeHeader();
+ void loadHeader();
+
+ void insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id);
+ void insertData_impl(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, uint32_t level);
+ bool deleteData_impl(const TimeRegion& mbr, id_type id);
+
+ id_type writeNode(Node*);
+ NodePtr readNode(id_type id);
+ void deleteNode(Node* n);
+
+ void rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v);
+
+ void findRootIdentifiers(const Tools::IInterval& ti, std::vector<id_type>& ids);
+ std::string printRootInfo() const;
+
+ IStorageManager* m_pStorageManager;
+
+ std::vector<RootEntry> m_roots;
+ id_type m_headerID;
+
+ MVRTreeVariant m_treeVariant;
+
+ double m_fillFactor;
+
+ uint32_t m_indexCapacity;
+
+ uint32_t m_leafCapacity;
+
+ uint32_t m_nearMinimumOverlapFactor;
+ // The R*-Tree 'p' constant, for calculating nearly minimum overlap cost.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles, Section 4.1]
+
+ double m_splitDistributionFactor;
+ // The R*-Tree 'm' constant, for calculating spliting distributions.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles, Section 4.2]
+
+ double m_reinsertFactor;
+ // The R*-Tree 'p' constant, for removing entries at reinserts.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles, Section 4.3]
+
+ double m_strongVersionOverflow;
+ //double m_strongVersionUnderflow;
+ double m_versionUnderflow;
+
+ uint32_t m_dimension;
+
+ TimeRegion m_infiniteRegion;
+
+ SpatialIndex::MVRTree::Statistics m_stats;
+
+ bool m_bTightMBRs;
+
+ bool m_bHasVersionCopied;
+
+ double m_currentTime;
+
+ Tools::PointerPool<Point> m_pointPool;
+ Tools::PointerPool<TimeRegion> m_regionPool;
+ Tools::PointerPool<Node> m_indexPool;
+ Tools::PointerPool<Node> m_leafPool;
+
+ std::vector<Tools::SmartPointer<ICommand> > m_writeNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_readNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_deleteNodeCommands;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+
+ class RootEntry
+ {
+ public:
+ RootEntry() {}
+ RootEntry(id_type id, double s, double e) : m_id(id), m_startTime(s), m_endTime(e) {}
+
+ id_type m_id;
+ double m_startTime;
+ double m_endTime;
+ }; // RootEntry
+
+ class NNEntry
+ {
+ public:
+ id_type m_id;
+ IEntry* m_pEntry;
+ double m_minDist;
+
+ NNEntry(id_type id, IEntry* e, double f) : m_id(id), m_pEntry(e), m_minDist(f) {}
+ ~NNEntry() {}
+
+ struct greater : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_minDist > __y->m_minDist; }
+ };
+ }; // NNEntry
+
+ class NNComparator : public INearestNeighborComparator
+ {
+ public:
+ double getMinimumDistance(const IShape& query, const IShape& entry)
+ {
+ return query.getMinimumDistance(entry);
+ }
+ double getMinimumDistance(const IShape& query, const IData& data)
+ {
+ IShape* pR;
+ data.getShape(&pR);
+ double ret = query.getMinimumDistance(*pR);
+ delete pR;
+ return ret;
+ }
+ }; // NNComparator
+
+ class ValidateEntry
+ {
+ public:
+ ValidateEntry(id_type pid, TimeRegion& r, NodePtr& pNode) : m_parentID(pid), m_parentMBR(r), m_pNode(pNode), m_bIsDead(false) {}
+
+ id_type m_parentID;
+ TimeRegion m_parentMBR;
+ NodePtr m_pNode;
+ bool m_bIsDead;
+ }; // ValidateEntry
+
+ friend class Node;
+ friend class Leaf;
+ friend class Index;
+
+ friend std::ostream& operator<<(std::ostream& os, const MVRTree& t);
+ }; // MVRTree
+
+ std::ostream& operator<<(std::ostream& os, const MVRTree& t);
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Makefile.am
new file mode 100644
index 000000000..8c28ebe12
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Makefile.am
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libmvrtree.la
+INCLUDES = -I../../include
+libmvrtree_la_SOURCES = Index.cc Leaf.cc Node.cc MVRTree.cc Statistics.cc Index.h Leaf.h MVRTree.h Node.h PointerPoolNode.h Statistics.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.cc b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.cc
new file mode 100644
index 000000000..b69e665c2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.cc
@@ -0,0 +1,1512 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MVRTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::MVRTree;
+
+//
+// Tools::IObject interface
+//
+Tools::IObject* Node::clone()
+{
+ throw Tools::NotSupportedException("IObject::clone should never be called.");
+}
+
+//
+// Tools::ISerializable interface
+//
+uint32_t Node::getByteArraySize()
+{
+ return
+ (sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(double) +
+ sizeof(double) +
+ (m_children * (m_pTree->m_dimension * sizeof(double) * 2 + sizeof(id_type) + 2 * sizeof(double) + sizeof(uint32_t))) +
+ m_totalDataLength +
+ (2 * m_pTree->m_dimension * sizeof(double)));
+}
+
+void Node::loadFromByteArray(const byte* ptr)
+{
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ // skip the node type information, it is not needed.
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_level, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_children, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&(m_nodeMBR.m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(m_nodeMBR.m_endTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_ptrMBR[cChild] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[cChild]) = m_pTree->m_infiniteRegion;
+
+ memcpy(m_ptrMBR[cChild]->m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(&(m_pIdentifier[cChild]), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&(m_ptrMBR[cChild]->m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(m_ptrMBR[cChild]->m_endTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(&(m_pDataLength[cChild]), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ m_totalDataLength += m_pDataLength[cChild];
+ m_pData[cChild] = new byte[m_pDataLength[cChild]];
+ memcpy(m_pData[cChild], ptr, m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ else
+ {
+ m_pData[cChild] = 0;
+ }
+
+ //m_nodeMBR.combineRegion(*(m_ptrMBR[cChild]));
+ }
+
+ memcpy(m_nodeMBR.m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+void Node::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ uint32_t nodeType;
+
+ if (m_level == 0) nodeType = PersistentLeaf;
+ else nodeType = PersistentIndex;
+
+ memcpy(ptr, &nodeType, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_level, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_children, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &(m_nodeMBR.m_startTime), sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(m_nodeMBR.m_endTime), sizeof(double));
+ ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ memcpy(ptr, m_ptrMBR[cChild]->m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, &(m_pIdentifier[cChild]), sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &(m_ptrMBR[cChild]->m_startTime), sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(m_ptrMBR[cChild]->m_endTime), sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, &(m_pDataLength[cChild]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ memcpy(ptr, m_pData[cChild], m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ }
+
+ // store the node MBR for efficiency. This increases the node size a little bit.
+ memcpy(ptr, m_nodeMBR.m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pHigh, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+//
+// SpatialIndex::IEntry interface
+//
+SpatialIndex::id_type Node::getIdentifier() const
+{
+ return m_identifier;
+}
+
+void Node::getShape(IShape** out) const
+{
+ *out = new TimeRegion(m_nodeMBR);
+}
+
+//
+// SpatialIndex::INode interface
+//
+uint32_t Node::getChildrenCount() const
+{
+ return m_children;
+}
+
+SpatialIndex::id_type Node::getChildIdentifier(uint32_t index) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pIdentifier[index];
+}
+
+void Node::getChildShape(uint32_t index, IShape** out) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ *out = new TimeRegion(*(m_ptrMBR[index]));
+}
+
+
+void Node::getChildData(uint32_t index, uint32_t& length, byte** data) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+ if (m_pData[index] == NULL)
+ {
+ length = 0;
+ data = NULL;
+ }
+ else
+ {
+ length = m_pDataLength[index];
+ *data = m_pData[index];
+ }
+}
+
+uint32_t Node::getLevel() const
+{
+ return m_level;
+}
+
+bool Node::isLeaf() const
+{
+ return (m_level == 0);
+}
+
+bool Node::isIndex() const
+{
+ return (m_level != 0);
+}
+
+//
+// Internal
+//
+
+Node::Node() :
+ m_pTree(0),
+ m_level(0),
+ m_identifier(-1),
+ m_children(0),
+ m_capacity(0),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+}
+
+ Node::Node(SpatialIndex::MVRTree::MVRTree* pTree, id_type id, uint32_t level, uint32_t capacity) :
+ m_pTree(pTree),
+ m_level(level),
+ m_identifier(id),
+ m_children(0),
+ m_capacity(capacity),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+ m_nodeMBR.makeInfinite(m_pTree->m_dimension);
+
+ try
+ {
+ m_pDataLength = new uint32_t[m_capacity + 2];
+ m_pData = new byte*[m_capacity + 2];
+ m_ptrMBR = new TimeRegionPtr[m_capacity + 2];
+ m_pIdentifier = new id_type[m_capacity + 2];
+ }
+ catch (...)
+ {
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+ throw;
+ }
+}
+
+Node::~Node()
+{
+ if (m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_pData[cChild] != 0) delete[] m_pData[cChild];
+ }
+
+ delete[] m_pData;
+ delete[] m_pDataLength;
+ }
+
+ if (m_ptrMBR != 0) delete[] m_ptrMBR;
+ if (m_pIdentifier != 0) delete[] m_pIdentifier;
+}
+
+Node& Node::operator=(const Node& n)
+{
+ throw Tools::IllegalStateException("operator =: This should never be called.");
+}
+
+void Node::insertEntry(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id)
+{
+ assert(m_children < m_capacity);
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ m_totalDataLength += dataLength;
+ ++m_children;
+
+ m_nodeMBR.combineRegionInTime(mbr);
+}
+
+bool Node::deleteEntry(uint32_t index)
+{
+ assert(index >= 0 && index < m_children);
+
+ // cache it, since I might need it for "touches" later.
+ TimeRegionPtr ptrR = m_ptrMBR[index];
+
+ m_totalDataLength -= m_pDataLength[index];
+ if (m_pData[index] != 0) delete[] m_pData[index];
+
+ if (m_children > 1 && index != m_children - 1)
+ {
+ m_pDataLength[index] = m_pDataLength[m_children - 1];
+ m_pData[index] = m_pData[m_children - 1];
+ m_ptrMBR[index] = m_ptrMBR[m_children - 1];
+ m_pIdentifier[index] = m_pIdentifier[m_children - 1];
+ }
+
+ --m_children;
+
+ // WARNING: index has now changed. Do not use it below here.
+
+ if (m_children == 0)
+ {
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+ return true;
+ }
+ else if (m_pTree->m_bTightMBRs && m_nodeMBR.touchesShape(*ptrR))
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool Node::insertData(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2, bool bForceAdjust)
+{
+ // we should be certain that when bInsertMbr2 is true the node needs to be version split
+
+ // this function returns true only if the node under modification has been stored (writeNode(this))
+ // it is needed since some times after a version copy we do not need to actually store the node. Only
+ // the parent has to be notified to modify the entry pointing
+ // to this node with the appropriate deletion time (thus we save one disk access)
+
+ if ((! bInsertMbr2) && m_children < m_capacity)
+ {
+ // the node has empty space. Insert the entry here
+
+ // this has to happen before insertEntry modifies m_nodeMBR.
+ bool b = m_nodeMBR.containsShape(mbr);
+
+ insertEntry(dataLength, pData, mbr, id);
+ m_pTree->writeNode(this);
+
+ // a forced adjust might be needed when a child has modified it MBR due to an entry deletion
+ // (when the entry start time becomes equal to the entry end time after a version copy)
+ if ((! b || bForceAdjust) && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+
+ return true;
+ }
+ else
+ {
+ // do a version copy
+
+ bool bIsRoot = pathBuffer.empty();
+
+ NodePtr ptrCopy;
+
+ // copy live entries of this node into a new node. Create an index or a leaf respectively
+ if (m_level == 0)
+ {
+ ptrCopy = m_pTree->m_leafPool.acquire();
+ if (ptrCopy.get() == 0) ptrCopy = NodePtr(new Leaf(m_pTree, - 1), &(m_pTree->m_leafPool));
+ else ptrCopy->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ else
+ {
+ ptrCopy = m_pTree->m_indexPool.acquire();
+ if (ptrCopy.get() == 0) ptrCopy = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+ else
+ {
+ ptrCopy->m_level = m_level;
+ ptrCopy->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ }
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (! (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ byte* data = 0;
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ data = new byte[m_pDataLength[cChild]];
+ memcpy(data, m_pData[cChild], m_pDataLength[cChild] * sizeof(byte));
+ }
+ ptrCopy->insertEntry(m_pDataLength[cChild], data, *(m_ptrMBR[cChild]), m_pIdentifier[cChild]);
+ ptrCopy->m_ptrMBR[ptrCopy->m_children - 1]->m_startTime = mbr.m_startTime;
+ }
+ }
+
+ ptrCopy->m_nodeMBR.m_startTime = mbr.m_startTime;
+ m_nodeMBR.m_endTime = mbr.m_startTime;
+
+ uint32_t children = (bInsertMbr2) ? ptrCopy->m_children + 2 : ptrCopy->m_children + 1;
+ assert(children > 0);
+
+ if (children >= m_pTree->m_strongVersionOverflow * m_capacity)
+ {
+ // strong version overflow. Split!
+ NodePtr n;
+ NodePtr nn;
+ ptrCopy->split(dataLength, pData, mbr, id, n, nn, mbr2, id2, bInsertMbr2);
+ assert(n->m_children > 1 && nn->m_children > 1);
+
+ if (bIsRoot)
+ {
+ // it is a root node. Special handling required.
+ n->m_level = ptrCopy->m_level;
+ nn->m_level = ptrCopy->m_level;
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ NodePtr ptrR = m_pTree->m_indexPool.acquire();
+ if (ptrR.get() == 0) ptrR = NodePtr(new Index(m_pTree, -1, ptrCopy->m_level + 1), &(m_pTree->m_indexPool));
+ else
+ {
+ //ptrR->m_pTree = m_pTree;
+ //ptrR->m_identifier = -1;
+ ptrR->m_level = ptrCopy->m_level + 1;
+ ptrR->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+
+ ptrR->insertEntry(0, 0, n->m_nodeMBR, n->m_identifier);
+ ptrR->insertEntry(0, 0, nn->m_nodeMBR, nn->m_identifier);
+
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ ptrR->m_identifier = m_identifier;
+ m_pTree->writeNode(ptrR.get());
+ m_pTree->m_stats.m_treeHeight[m_pTree->m_stats.m_treeHeight.size() - 1] = ptrR->m_level + 1;
+ m_pTree->m_stats.m_nodesInLevel.at(n->m_level) = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 1;
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime == ptrCopy->m_nodeMBR.m_startTime &&
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime == ptrCopy->m_nodeMBR.m_endTime);
+ }
+ else
+ {
+ m_pTree->writeNode(this);
+ m_pTree->writeNode(ptrR.get());
+
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_id == m_identifier);
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime = m_nodeMBR.m_startTime;
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime = m_nodeMBR.m_endTime;
+ m_pTree->m_roots.push_back(MVRTree::RootEntry(ptrR->m_identifier, ptrR->m_nodeMBR.m_startTime, ptrR->m_nodeMBR.m_endTime));
+ m_pTree->m_stats.m_treeHeight.push_back(ptrR->m_level + 1);
+ m_pTree->m_stats.m_nodesInLevel.at(n->m_level) = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 2;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+ }
+
+ if (ptrR->m_level >= m_pTree->m_stats.m_nodesInLevel.size()) m_pTree->m_stats.m_nodesInLevel.push_back(1);
+ else m_pTree->m_stats.m_nodesInLevel.at(ptrR->m_level) = m_pTree->m_stats.m_nodesInLevel[ptrR->m_level] + 1;
+
+ return true;
+ }
+ else
+ {
+ bool b = false;
+
+ n->m_level = ptrCopy->m_level;
+ nn->m_level = ptrCopy->m_level;
+/*
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ n->m_identifier = m_identifier;
+ m_pTree->m_stats.m_nodesInLevel[n->m_level] = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 1;
+ b = true;
+ }
+ else
+ {
+ n->m_identifier = -1;
+ m_pTree->m_stats.m_nodesInLevel[n->m_level] = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 2;
+ }
+*/
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+
+ m_pTree->m_stats.m_nodesInLevel.at(n->m_level) = m_pTree->m_stats.m_nodesInLevel[n->m_level] + 2;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // this is the special insertion function for two new nodes, defined below
+ p->insertData(n->m_nodeMBR, n->m_identifier, nn->m_nodeMBR, nn->m_identifier, this, pathBuffer);
+
+ return b;
+ }
+ }
+ //else if (children < m_pTree->m_strongVersionUnderflow * m_capacity)
+ //{
+ // do not do this for now
+ //}
+ else
+ {
+ // the entry contains the appropriate number of live entries
+
+ ptrCopy->insertEntry(dataLength, pData, mbr, id);
+ if (bInsertMbr2) ptrCopy->insertEntry(0, 0, mbr2, id2);
+
+ if (bIsRoot)
+ {
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ ptrCopy->m_identifier = m_identifier;
+ m_pTree->writeNode(ptrCopy.get());
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime == ptrCopy->m_nodeMBR.m_startTime &&
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime == ptrCopy->m_nodeMBR.m_endTime);
+ }
+ else
+ {
+ m_pTree->writeNode(ptrCopy.get());
+ m_pTree->writeNode(this);
+
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_id == m_identifier);
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime = m_nodeMBR.m_startTime;
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime = m_nodeMBR.m_endTime;
+ m_pTree->m_roots.push_back(MVRTree::RootEntry(ptrCopy->m_identifier, ptrCopy->m_nodeMBR.m_startTime, ptrCopy->m_nodeMBR.m_endTime));
+ m_pTree->m_stats.m_treeHeight.push_back(ptrCopy->m_level + 1);
+
+ m_pTree->m_stats.m_nodesInLevel.at(ptrCopy->m_level) = m_pTree->m_stats.m_nodesInLevel[ptrCopy->m_level] + 1;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+ }
+
+ return true;
+ }
+ else
+ {
+ m_pTree->writeNode(ptrCopy.get());
+
+ m_pTree->m_stats.m_nodesInLevel.at(ptrCopy->m_level) = m_pTree->m_stats.m_nodesInLevel[ptrCopy->m_level] + 1;
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ uint32_t child;
+ for (child = 0; child < p->m_children; ++child)
+ {
+ if (p->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ // it might be needed to update the MBR since the child MBR might have changed
+ // from an entry deletion (from insertData, below, when m_startTime == m_endTime)
+ double st = p->m_ptrMBR[child]->m_startTime;
+ *(p->m_ptrMBR[child]) = m_nodeMBR;
+ p->m_ptrMBR[child]->m_startTime = st;
+ //p->m_ptrMBR[child]->m_endTime = mbr.m_startTime;
+
+ // insert this new version copy into the parent
+ p->insertData(0, 0, ptrCopy->m_nodeMBR, ptrCopy->m_identifier, pathBuffer, m_pTree->m_infiniteRegion, -1, false);
+
+ return false;
+ }
+ }
+ }
+}
+
+void Node::insertData(TimeRegion& mbr1, id_type id1, TimeRegion& mbr2, id_type id2, Node* oldVersion, std::stack<id_type>& pathBuffer)
+{
+ // this should be called only from insertData above
+ // it tries to fit two new entries into the node
+
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == oldVersion->m_identifier) break;
+ }
+
+ // save the original node MBR
+ bool bAdjust = false;
+ TimeRegionPtr ptrR = m_pTree->m_regionPool.acquire();
+ *ptrR = m_nodeMBR;
+
+ // it might be needed to update the MBR since the child MBR might have changed
+ // from an entry deletion (when m_startTime == m_endTime)
+ double st = m_ptrMBR[child]->m_startTime;
+ *(m_ptrMBR[child]) = oldVersion->m_nodeMBR;
+ m_ptrMBR[child]->m_startTime = st;
+ //m_ptrMBR[child]->m_endTime = oldVersion->m_nodeMBR.m_endTime;
+
+ if (m_children < m_capacity - 1)
+ {
+ // there is enough space for both new entries
+
+ insertEntry(0, 0, mbr1, id1);
+ insertEntry(0, 0, mbr2, id2);
+
+ m_pTree->writeNode(this);
+
+ if ((! pathBuffer.empty()) && (bAdjust || ! (ptrR->containsShape(mbr1) && ptrR->containsShape(mbr2))))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+ }
+ else
+ {
+ // call a normal insertData which will trigger a version copy
+ // insertData will adjust the parent since this node will certainly do a version copy
+ bool bStored = insertData(0, 0, mbr1, id1, pathBuffer, mbr2, id2, true);
+ if (! bStored) m_pTree->writeNode(this);
+ }
+}
+
+bool Node::deleteData(id_type id, double delTime, std::stack<id_type>& pathBuffer, bool bForceAdjust)
+{
+ // it returns true if a new root has been created because all the entries of the old root have died.
+ // This is needed in case the root dies while there are pending reinsertions from multiple levels
+
+ uint32_t child = m_capacity;
+ uint32_t alive = 0;
+ bool bAdjustParent = false;
+ TimeRegionPtr oldNodeMBR = m_pTree->m_regionPool.acquire();
+ *oldNodeMBR = m_nodeMBR;
+ NodePtr parent;
+
+ // make sure that there are no "snapshot" entries
+ // find how many children are alive and locate the entry to be deleted
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_level != 0 || (m_ptrMBR[cChild]->m_startTime != m_ptrMBR[cChild]->m_endTime));
+ if (! (m_ptrMBR[cChild]->m_endTime < std::numeric_limits<double>::max())) ++alive;
+ if (m_pIdentifier[cChild] == id) child = cChild;
+ }
+
+ assert(child < m_capacity);
+
+ // either make the entry dead or, if its start time is equal to the deletion time,
+ // delete it from the node completely (in which case the parent MBR might need adjustment)
+ bool bAdjusted = false;
+
+ if (m_level == 0 && m_ptrMBR[child]->m_startTime == delTime)
+ {
+ bAdjusted = deleteEntry(child);
+ bAdjustParent = bAdjusted;
+ }
+ else
+ {
+ m_ptrMBR[child]->m_endTime = delTime;
+ }
+
+ // if it has not been adjusted yet (by deleteEntry) and it should be adjusted, do it.
+ // a forced adjustment is needed when a child node has adjusted its own MBR and signals
+ // the parent to adjust it, also.
+ if ((! bAdjusted) && bForceAdjust)
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ // signal our parent to adjust its MBR also
+ bAdjustParent = true;
+ }
+
+ // one less live entry from now on
+ --alive;
+
+ if (alive < m_pTree->m_versionUnderflow * m_capacity && (! pathBuffer.empty()))
+ {
+ // if the weak version condition is broken, try to resolve it
+ // if this is a leaf and it can still hold some entries (since all entries might be dead now and
+ // the node full) try to borrow a live entry from a sibling
+ // [Yufei Tao, Dimitris Papadias, 'MV3R-Tree: A Spatio-Temporal Access Method for Timestamp and
+ // Interval Queries', Section 3.3]
+ if (m_level == 0 && m_children < m_capacity)
+ {
+ parent = m_pTree->readNode(pathBuffer.top());
+ pathBuffer.pop();
+
+ // find us in our parent
+ for (child = 0; child < parent->m_children; ++child)
+ {
+ if (parent->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ // remember that the parent might be younger than us, pointing to us through a pointer
+ // created with a version copy. So the actual start time of this node through the path
+ // from the root might actually be different than the stored start time.
+ double actualNodeStartTime = parent->m_ptrMBR[child]->m_startTime;
+
+ // find an appropriate sibling
+ for (uint32_t cSibling = 0; cSibling < parent->m_children; ++cSibling)
+ {
+ // it has to be different than us, it has to be alive and its MBR should intersect ours
+ if (
+ parent->m_pIdentifier[cSibling] != m_identifier &&
+ ! (parent->m_ptrMBR[cSibling]->m_endTime < std::numeric_limits<double>::max()) &&
+ parent->m_ptrMBR[cSibling]->intersectsShape(m_nodeMBR))
+ {
+ NodePtr sibling = m_pTree->readNode(parent->m_pIdentifier[cSibling]);
+ std::vector<DeleteDataEntry> toCheck;
+ alive = 0;
+
+ // if this child does not have a single parent, we cannot borrow an entry.
+ bool bSingleParent = true;
+
+ for (uint32_t cSiblingChild = 0; cSiblingChild < sibling->m_children; ++cSiblingChild)
+ {
+ // if the insertion time of any child is smaller than the starting time stored in the
+ // parent of this node than the node has more than one parent
+ if (sibling->m_ptrMBR[cSiblingChild]->m_startTime < parent->m_ptrMBR[cSibling]->m_startTime)
+ {
+ bSingleParent = false;
+ break;
+ }
+
+ // find the live sibling entries, and also the ones that can be moved to this node
+ // sort them by area enlargement
+ if (! (sibling->m_ptrMBR[cSiblingChild]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ ++alive;
+ if (sibling->m_ptrMBR[cSiblingChild]->m_startTime >= actualNodeStartTime)
+ {
+ TimeRegionPtr tmpR = m_pTree->m_regionPool.acquire();
+ *tmpR = m_nodeMBR;
+ tmpR->combineRegion(*(sibling->m_ptrMBR[cSiblingChild]));
+ double a = tmpR->getArea();
+ if (a <= m_nodeMBR.getArea() * 1.1) toCheck.push_back(DeleteDataEntry(cSiblingChild, a));
+ }
+ }
+ }
+
+ // if the sibling has more than one parent or if we cannot remove an entry because we will
+ // cause a weak version overflow, this sibling is not appropriate
+ if ((! bSingleParent) || toCheck.empty() || alive == m_pTree->m_versionUnderflow * sibling->m_capacity + 1) continue;
+
+ // create interval counters for checking weak version condition
+ // [Yufei Tao, Dimitris Papadias, 'MV3R-Tree: A Spatio-Temporal Access Method for Timestamp and
+ // Interval Queries', Section 3.2]
+ std::set<double> Si;
+ for (uint32_t cSiblingChild = 0; cSiblingChild < sibling->m_children; ++cSiblingChild)
+ {
+ Si.insert(sibling->m_ptrMBR[cSiblingChild]->m_startTime);
+ Si.insert(sibling->m_ptrMBR[cSiblingChild]->m_endTime);
+ }
+ // duplicate entries have been removed and the set is sorted
+ uint32_t* SiCounts = new uint32_t[Si.size() - 1];
+ bzero(SiCounts, (Si.size() - 1) * sizeof(uint32_t));
+
+ for (uint32_t cSiblingChild = 0; cSiblingChild < sibling->m_children; ++cSiblingChild)
+ {
+ std::set<double>::iterator it1 = Si.begin();
+ std::set<double>::iterator it2 = Si.begin();
+ for (size_t cIndex = 0; cIndex < Si.size() - 1; ++cIndex)
+ {
+ ++it2;
+ if (
+ sibling->m_ptrMBR[cSiblingChild]->m_startTime <= *it1 &&
+ sibling->m_ptrMBR[cSiblingChild]->m_endTime >= *it2
+ ) ++(SiCounts[cIndex]);
+ ++it1;
+ }
+ }
+
+ std::vector<DeleteDataEntry> Sdel;
+
+ for (size_t cCheck = 0; cCheck < toCheck.size(); ++cCheck)
+ {
+ bool good = true;
+
+ // check if it can be removed without a weak version underflow
+ std::set<double>::iterator it1 = Si.begin();
+ std::set<double>::iterator it2 = Si.begin();
+ for (size_t cIndex = 0; cIndex < Si.size() - 1; ++cIndex)
+ {
+ ++it2;
+ if (
+ sibling->m_ptrMBR[toCheck[cCheck].m_index]->m_startTime <= *it1 &&
+ sibling->m_ptrMBR[toCheck[cCheck].m_index]->m_endTime >= *it2 &&
+ SiCounts[cIndex] <= m_pTree->m_versionUnderflow * sibling->m_capacity)
+ {
+ good = false;
+ break;
+ }
+ ++it1;
+ }
+ if (good) Sdel.push_back(toCheck[cCheck]);
+ }
+
+ delete[] SiCounts;
+
+ if (Sdel.empty()) continue;
+
+ // we found some entries. Sort them according to least enlargement, insert the best entry into
+ // this node, remove it from the sibling and update the MBRs of the parent
+
+ sort(Sdel.begin(), Sdel.end(), DeleteDataEntry::compare);
+ uint32_t entry = Sdel[0].m_index;
+ bool b1 = m_nodeMBR.containsShape(*(sibling->m_ptrMBR[entry]));
+ bool b2 = sibling->m_nodeMBR.touchesShape(*(sibling->m_ptrMBR[entry]));
+
+ insertEntry(sibling->m_pDataLength[entry], sibling->m_pData[entry], *(sibling->m_ptrMBR[entry]), sibling->m_pIdentifier[entry]);
+ sibling->m_pData[entry] = 0;
+
+ // the weak version condition check above, guarantees that.
+ assert(sibling->m_children > 1);
+ sibling->deleteEntry(entry);
+
+ m_pTree->writeNode(this);
+ m_pTree->writeNode(sibling.get());
+
+ Index* p = static_cast<Index*>(parent.get());
+ if (((! b1) || bAdjustParent) && b2) p->adjustTree(this, sibling.get(), pathBuffer);
+ else if ((! b1) || bAdjustParent) p->adjustTree(this, pathBuffer);
+ else if (b2) p->adjustTree(sibling.get(), pathBuffer);
+
+ return false;
+ }
+ }
+ }
+
+ // either this is not a leaf, or an appropriate sibling was not found, so make this node dead
+ // and reinsert all live entries from the root
+ m_nodeMBR.m_endTime = delTime;
+ m_pTree->writeNode(this);
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ if (parent.get() == 0)
+ {
+ parent = m_pTree->readNode(pathBuffer.top());
+ pathBuffer.pop();
+ }
+
+ if (bAdjustParent)
+ {
+ // the correct child pointer might have been calculated already from earlier
+ if (child < parent->m_children && m_identifier != parent->m_pIdentifier[child])
+ {
+ for (child = 0; child < parent->m_children; ++child)
+ {
+ if (parent->m_pIdentifier[child] == m_identifier) break;
+ }
+ }
+
+ // both start time and end time should be preserved since deleteData below needs
+ // to know how many entries where alive, including this one
+ double st = parent->m_ptrMBR[child]->m_startTime;
+ double en = parent->m_ptrMBR[child]->m_endTime;
+ *(parent->m_ptrMBR[child]) = m_nodeMBR;
+ parent->m_ptrMBR[child]->m_startTime = st;
+ parent->m_ptrMBR[child]->m_endTime = en;
+ }
+
+ // delete this node from the parent node.
+ // if this node had been adjusted and its old MBR was touching the parent MBR, the
+ // parent MBR needs to be adjusted also.
+ // the deletion has to happen first, since the reinsertions might modify the path to this node
+ bool bNewRoot = parent->deleteData(m_identifier, delTime, pathBuffer, (bAdjustParent && parent->m_nodeMBR.touchesShape(*oldNodeMBR)));
+
+ // reinsert all the live entries from the root
+
+ // normally I should not modify any node instances, since writeNode might be caching nodes
+ // in main memory, even though I have persisted them, so I have to make copies
+
+ // this code will try and reinsert whole paths if possible. It might be the case, though,
+ // that a root died, which means that all the live data entries have to be scanned and reinserted themselves
+ for (child = 0; child < m_children; ++child)
+ {
+ if (! (m_ptrMBR[child]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ if (! bNewRoot || m_level == 0)
+ {
+ m_ptrMBR[child]->m_startTime = delTime;
+ m_pTree->insertData_impl(m_pDataLength[child], m_pData[child], *(m_ptrMBR[child]), m_pIdentifier[child], m_level);
+ // make sure we do not delete the data array from this node's destructor
+ m_pData[child] = 0;
+ }
+ else
+ {
+ std::stack<NodePtr> Sins;
+ Sins.push(m_pTree->readNode(m_pIdentifier[child]));
+ while (! Sins.empty())
+ {
+ NodePtr p = Sins.top(); Sins.pop();
+ if (p->m_level == 0)
+ {
+ for (uint32_t cIndex= 0; cIndex < p->m_children; ++cIndex)
+ {
+ if (! (p->m_ptrMBR[cIndex]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ p->m_ptrMBR[cIndex]->m_startTime = delTime;
+ m_pTree->insertData_impl(p->m_pDataLength[cIndex], p->m_pData[cIndex], *(p->m_ptrMBR[cIndex]), p->m_pIdentifier[cIndex], p->m_level);
+ // make sure we do not delete the data array from this node's destructor
+ p->m_pData[cIndex] = 0;
+ }
+ }
+ }
+ else
+ {
+ for (uint32_t cIndex= 0; cIndex < p->m_children; ++cIndex)
+ {
+ if (! (p->m_ptrMBR[cIndex]->m_endTime < std::numeric_limits<double>::max()))
+ {
+ Sins.push(m_pTree->readNode(p->m_pIdentifier[cIndex]));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // either this is a root node or there is no weak version condition
+
+ if (alive == 0 && pathBuffer.empty())
+ {
+ if (m_children > 0)
+ {
+ // all root children are dead. Create a new root
+ m_nodeMBR.m_endTime = delTime;
+ m_pTree->m_bHasVersionCopied = false;
+
+ if (m_nodeMBR.m_startTime == m_nodeMBR.m_endTime)
+ {
+ Leaf root(m_pTree, m_identifier);
+ root.m_nodeMBR.m_startTime = m_nodeMBR.m_endTime;
+ root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ m_pTree->writeNode(&root);
+
+ m_pTree->m_stats.m_treeHeight[m_pTree->m_stats.m_treeHeight.size() - 1] = 1;
+ if (m_pTree->m_stats.m_nodesInLevel.at(m_level) == 1) m_pTree->m_stats.m_nodesInLevel.pop_back();
+ else m_pTree->m_stats.m_nodesInLevel.at(m_level) = m_pTree->m_stats.m_nodesInLevel[m_level] - 1;
+ m_pTree->m_stats.m_nodesInLevel.at(0) = m_pTree->m_stats.m_nodesInLevel[0] + 1;
+ }
+ else
+ {
+ m_pTree->writeNode(this);
+
+ if (m_level > 0) ++(m_pTree->m_stats.m_u32DeadIndexNodes);
+ else ++(m_pTree->m_stats.m_u32DeadLeafNodes);
+
+ Leaf root(m_pTree, -1);
+ root.m_nodeMBR.m_startTime = m_nodeMBR.m_endTime;
+ root.m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ m_pTree->writeNode(&root);
+ assert(m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_id == m_identifier);
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_startTime = m_nodeMBR.m_startTime;
+ m_pTree->m_roots[m_pTree->m_roots.size() - 1].m_endTime = m_nodeMBR.m_endTime;
+ m_pTree->m_roots.push_back(MVRTree::RootEntry(root.m_identifier, root.m_nodeMBR.m_startTime, root.m_nodeMBR.m_endTime));
+
+ m_pTree->m_stats.m_treeHeight.push_back(1);
+ m_pTree->m_stats.m_nodesInLevel.at(root.m_level) = m_pTree->m_stats.m_nodesInLevel[root.m_level] + 1;
+ }
+ return true;
+ }
+ else
+ {
+ assert(m_level == 0);
+ m_pTree->writeNode(this);
+ m_pTree->m_bHasVersionCopied = false;
+ return false;
+ }
+ }
+ else if (bAdjustParent && (! pathBuffer.empty()))
+ {
+ // the parent needs to be adjusted
+ m_pTree->writeNode(this);
+ parent = m_pTree->readNode(pathBuffer.top());
+ pathBuffer.pop();
+ Index* p = static_cast<Index*>(parent.get());
+ p->adjustTree(this, pathBuffer);
+ }
+ else
+ {
+ m_pTree->writeNode(this);
+ }
+ }
+
+ return false;
+}
+
+void Node::rtreeSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ uint32_t cChild;
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ uint32_t cTotal = (bInsertMbr2) ? m_children + 2 : m_children + 1;
+
+ // use this mask array for marking visited entries.
+ byte* mask = new byte[cTotal];
+ bzero(mask, cTotal);
+
+ // insert new data in the node for easier manipulation. Data arrays are always
+ // by two larger than node capacity.
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ if (bInsertMbr2)
+ {
+ m_pDataLength[m_children + 1] = 0;
+ m_pData[m_children + 1] = 0;
+ m_ptrMBR[m_children + 1] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children + 1]) = mbr2;
+ m_pIdentifier[m_children + 1] = id2;
+ }
+
+ // initialize each group with the seed entries.
+ uint32_t seed1, seed2;
+ pickSeeds(seed1, seed2, cTotal);
+
+ group1.push_back(seed1);
+ group2.push_back(seed2);
+
+ mask[seed1] = 1;
+ mask[seed2] = 1;
+
+ // find MBR of each group.
+ TimeRegionPtr mbrA = m_pTree->m_regionPool.acquire();
+ *mbrA = *(m_ptrMBR[seed1]);
+ TimeRegionPtr mbrB = m_pTree->m_regionPool.acquire();
+ *mbrB = *(m_ptrMBR[seed2]);
+
+ // count how many entries are left unchecked (exclude the seeds here.)
+ uint32_t cRemaining = cTotal - 2;
+
+ while (cRemaining > 0)
+ {
+ if (minimumLoad - group1.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group1 to comply with minimun load requirement.
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group1.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else if (minimumLoad - group2.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group2 to comply with minimun load requirement.
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group2.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else
+ {
+ // For all remaining entries compute the difference of the cost of grouping an
+ // entry in either group. When done, choose the entry that yielded the maximum
+ // difference. In case of linear split, select any entry (e.g. the first one.)
+ uint32_t sel;
+ double md1 = 0.0, md2 = 0.0;
+ double m = -std::numeric_limits<double>::max();
+ double d1, d2, d;
+ double a1 = mbrA->getArea();
+ double a2 = mbrB->getArea();
+
+ TimeRegionPtr a = m_pTree->m_regionPool.acquire();
+ TimeRegionPtr b = m_pTree->m_regionPool.acquire();
+
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ mbrA->getCombinedRegion(*a, *(m_ptrMBR[cChild]));
+ d1 = a->getArea() - a1;
+ mbrB->getCombinedRegion(*b, *(m_ptrMBR[cChild]));
+ d2 = b->getArea() - a2;
+ d = std::abs(d1 - d2);
+
+ if (d > m)
+ {
+ m = d;
+ md1 = d1; md2 = d2;
+ sel = cChild;
+ if (m_pTree->m_treeVariant== RV_LINEAR || m_pTree->m_treeVariant == RV_RSTAR) break;
+ }
+ }
+ }
+
+ // determine the group where we should add the new entry.
+ int32_t group = 1;
+
+ if (md1 < md2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (md2 < md1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (a1 < a2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (a2 < a1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (group1.size() < group2.size())
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (group2.size() < group1.size())
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ mask[sel] = 1;
+ --cRemaining;
+ if (group == 1)
+ {
+ mbrA->combineRegion(*(m_ptrMBR[sel]));
+ }
+ else
+ {
+ mbrB->combineRegion(*(m_ptrMBR[sel]));
+ }
+ }
+ }
+
+ delete[] mask;
+}
+
+void Node::rstarSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2)
+{
+ RstarSplitEntry** dataLow = 0;
+ RstarSplitEntry** dataHigh = 0;
+
+ uint32_t cTotal = (bInsertMbr2) ? m_children + 2 : m_children + 1;
+
+ try
+ {
+ dataLow = new RstarSplitEntry*[cTotal];
+ dataHigh = new RstarSplitEntry*[cTotal];
+ }
+ catch (...)
+ {
+ delete[] dataLow;
+ throw;
+ }
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ if (bInsertMbr2)
+ {
+ m_pDataLength[m_children + 1] = 0;
+ m_pData[m_children + 1] = 0;
+ m_ptrMBR[m_children + 1] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children + 1]) = mbr2;
+ m_pIdentifier[m_children + 1] = id2;
+ }
+
+ uint32_t nodeSPF = static_cast<uint32_t>(std::floor(cTotal * m_pTree->m_splitDistributionFactor));
+ uint32_t splitDistribution = cTotal - (2 * nodeSPF) + 2;
+
+ uint32_t cChild = 0, cDim, cIndex;
+
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ try
+ {
+ dataLow[cChild] = new RstarSplitEntry(m_ptrMBR[cChild].get(), cChild, 0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete dataLow[i];
+ delete[] dataLow;
+ delete[] dataHigh;
+ throw;
+ }
+
+ dataHigh[cChild] = dataLow[cChild];
+ }
+
+ double minimumMargin = std::numeric_limits<double>::max();
+ uint32_t splitAxis = std::numeric_limits<uint32_t>::max();
+ uint32_t sortOrder = std::numeric_limits<uint32_t>::max();
+
+ // chooseSplitAxis.
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ ::qsort(dataLow,
+ cTotal,
+ sizeof(RstarSplitEntry*),
+ RstarSplitEntry::compareLow);
+
+ ::qsort(dataHigh,
+ cTotal,
+ sizeof(RstarSplitEntry*),
+ RstarSplitEntry::compareHigh);
+
+ // calculate sum of margins and overlap for all distributions.
+ double marginl = 0.0;
+ double marginh = 0.0;
+
+ TimeRegion bbl1, bbl2, bbh1, bbh2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bbl1 = *(dataLow[0]->m_pRegion);
+ bbh1 = *(dataHigh[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bbl1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh1.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ bbl2 = *(dataLow[l]->m_pRegion);
+ bbh2 = *(dataHigh[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex < cTotal; ++cIndex)
+ {
+ bbl2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh2.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ marginl += bbl1.getMargin() + bbl2.getMargin();
+ marginh += bbh1.getMargin() + bbh2.getMargin();
+ } // for (cChild)
+
+ double margin = std::min(marginl, marginh);
+
+ // keep minimum margin as split axis.
+ if (margin < minimumMargin)
+ {
+ minimumMargin = margin;
+ splitAxis = cDim;
+ sortOrder = (marginl < marginh) ? 0 : 1;
+ }
+
+ // increase the dimension according to which the data entries should be sorted.
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = cDim + 1;
+ }
+ } // for (cDim)
+
+ for (cChild = 0; cChild < cTotal; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = splitAxis;
+ }
+
+ ::qsort(
+ dataLow,
+ cTotal,
+ sizeof(RstarSplitEntry*),
+ (sortOrder == 0) ? RstarSplitEntry::compareLow : RstarSplitEntry::compareHigh);
+
+ double ma = std::numeric_limits<double>::max();
+ double mo = std::numeric_limits<double>::max();
+ uint32_t splitPoint = std::numeric_limits<uint32_t>::max();
+
+ TimeRegion bb1, bb2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bb1 = *(dataLow[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bb1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ bb2 = *(dataLow[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex < cTotal; ++cIndex)
+ {
+ bb2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ double o = bb1.getIntersectingArea(bb2);
+
+ if (o < mo)
+ {
+ splitPoint = cChild;
+ mo = o;
+ ma = bb1.getArea() + bb2.getArea();
+ }
+ else if (o == mo)
+ {
+ double a = bb1.getArea() + bb2.getArea();
+
+ if (a < ma)
+ {
+ splitPoint = cChild;
+ ma = a;
+ }
+ }
+ } // for (cChild)
+
+ uint32_t l1 = nodeSPF - 1 + splitPoint;
+
+ for (cIndex = 0; cIndex < l1; ++cIndex)
+ {
+ group1.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ for (cIndex = l1; cIndex < cTotal; ++cIndex)
+ {
+ group2.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ delete[] dataLow;
+ delete[] dataHigh;
+}
+
+void Node::pickSeeds(uint32_t& index1, uint32_t& index2, uint32_t total)
+{
+ double separation = -std::numeric_limits<double>::max();
+ double inefficiency = -std::numeric_limits<double>::max();
+ uint32_t cDim, cChild, cIndex;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_RSTAR:
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ double leastLower = m_ptrMBR[0]->m_pLow[cDim];
+ double greatestUpper = m_ptrMBR[0]->m_pHigh[cDim];
+ uint32_t greatestLower = 0;
+ uint32_t leastUpper = 0;
+ double width;
+
+ for (cChild = 1; cChild < total; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->m_pLow[cDim] > m_ptrMBR[greatestLower]->m_pLow[cDim]) greatestLower = cChild;
+ if (m_ptrMBR[cChild]->m_pHigh[cDim] < m_ptrMBR[leastUpper]->m_pHigh[cDim]) leastUpper = cChild;
+
+ leastLower = std::min(m_ptrMBR[cChild]->m_pLow[cDim], leastLower);
+ greatestUpper = std::max(m_ptrMBR[cChild]->m_pHigh[cDim], greatestUpper);
+ }
+
+ width = greatestUpper - leastLower;
+ if (width <= 0) width = 1;
+
+ double f = (m_ptrMBR[greatestLower]->m_pLow[cDim] - m_ptrMBR[leastUpper]->m_pHigh[cDim]) / width;
+
+ if (f > separation)
+ {
+ index1 = leastUpper;
+ index2 = greatestLower;
+ separation = f;
+ }
+ } // for (cDim)
+
+ if (index1 == index2)
+ {
+ if (index2 == 0) ++index2;
+ else --index2;
+ }
+
+ break;
+ case RV_QUADRATIC:
+ // for each pair of Regions (account for overflow Region too!)
+ for (cChild = 0; cChild < total - 1; ++cChild)
+ {
+ double a = m_ptrMBR[cChild]->getArea();
+
+ for (cIndex = cChild + 1; cIndex < total; ++cIndex)
+ {
+ // get the combined MBR of those two entries.
+ TimeRegion r;
+ m_ptrMBR[cChild]->getCombinedRegion(r, *(m_ptrMBR[cIndex]));
+
+ // find the inefficiency of grouping these entries together.
+ double d = r.getArea() - a - m_ptrMBR[cIndex]->getArea();
+
+ if (d > inefficiency)
+ {
+ inefficiency = d;
+ index1 = cChild;
+ index2 = cIndex;
+ }
+ } // for (cIndex)
+ } // for (cChild)
+
+ break;
+ default:
+ throw Tools::NotSupportedException("Node::pickSeeds: Tree variant not supported.");
+ }
+}
+
+NodePtr Node::findNode(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_pIdentifier[cChild] == id)
+ return m_pTree->readNode(m_pIdentifier[cChild]);
+
+ if (m_ptrMBR[cChild]->containsShape(mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findNode(mbr, id, pathBuffer);
+ assert(n.get() != l.get());
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.h b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.h
new file mode 100644
index 000000000..187435e43
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Node.h
@@ -0,0 +1,184 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class MVRTree;
+ class Leaf;
+ class Index;
+ class Node;
+
+ typedef Tools::PoolPointer<Node> NodePtr;
+
+ class Node : public SpatialIndex::INode
+ {
+ public:
+ virtual ~Node();
+
+ //
+ // Tools::IObject interface
+ //
+ virtual IObject* clone();
+
+ //
+ // Tools::ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // SpatialIndex::IEntry interface
+ //
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+
+ //
+ // SpatialIndex::INode interface
+ //
+ virtual uint32_t getChildrenCount() const;
+ virtual id_type getChildIdentifier(uint32_t index) const;
+ virtual void getChildShape(uint32_t index, IShape** out) const;
+ virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
+ virtual uint32_t getLevel() const;
+ virtual bool isIndex() const;
+ virtual bool isLeaf() const;
+
+ private:
+ Node();
+ Node(MVRTree* pTree, id_type id, uint32_t level, uint32_t capacity);
+
+ virtual Node& operator=(const Node&);
+
+ virtual void insertEntry(uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id);
+ virtual bool deleteEntry(uint32_t index);
+
+ virtual bool insertData(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false, bool forceAdjust = false);
+ virtual void insertData(TimeRegion& mbr1, id_type id1, TimeRegion& mbr2, id_type id2, Node* oldVersion, std::stack<id_type>& pathBuffer);
+ virtual bool deleteData(id_type id, double delTime, std::stack<id_type>& pathBuffer, bool adjustMBR = false);
+
+ virtual void rtreeSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+ virtual void rstarSplit(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false);
+
+ virtual void pickSeeds(uint32_t& index1, uint32_t& index2, uint32_t total);
+
+ virtual NodePtr chooseSubtree(const TimeRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findLeaf(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findNode(const TimeRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(
+ uint32_t dataLength, byte* pData, TimeRegion& mbr, id_type id, NodePtr& left, NodePtr& right,
+ TimeRegion& mbr2, id_type id2, bool bInsertMbr2 = false) = 0;
+
+ MVRTree* m_pTree;
+ // Parent of all nodes.
+
+ uint32_t m_level;
+ // The level of the node in the tree.
+ // Leaves are always at level 0.
+
+ id_type m_identifier;
+ // The unique ID of this node.
+
+ uint32_t m_children;
+ // The number of children pointed by this node.
+
+ uint32_t m_capacity;
+ // Specifies the node capacity.
+
+ TimeRegion m_nodeMBR;
+ // The minimum bounding region enclosing all data contained in the node.
+
+ byte** m_pData;
+ // The data stored in the node.
+
+ TimeRegionPtr* m_ptrMBR;
+ // The corresponding data MBRs.
+
+ id_type* m_pIdentifier;
+ // The corresponding data identifiers.
+
+ uint32_t* m_pDataLength;
+
+ uint32_t m_totalDataLength;
+
+ class RstarSplitEntry
+ {
+ public:
+ RstarSplitEntry(TimeRegion* pr, uint32_t index, uint32_t dimension) :
+ m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
+
+ static int compareLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+
+ TimeRegion* m_pRegion;
+ uint32_t m_index;
+ uint32_t m_sortDim;
+ }; // RstarSplitEntry
+
+ class DeleteDataEntry
+ {
+ public:
+ DeleteDataEntry(uint32_t index, double d) : m_index(index), m_increase(d) {}
+
+ static bool compare(DeleteDataEntry e1, DeleteDataEntry e2) { return e1.m_increase < e2.m_increase; }
+
+ uint32_t m_index;
+ double m_increase;
+ }; // DeleteDataEntry
+
+ // Needed to access protected members without having to cast from Node.
+ // It is more efficient than using member functions to access protected members.
+ friend class MVRTree;
+ friend class Leaf;
+ friend class Index;
+ friend class Tools::PointerPool<Node>;
+ }; // Node
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/PointerPoolNode.h b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/PointerPoolNode.h
new file mode 100644
index 000000000..33407df02
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/PointerPoolNode.h
@@ -0,0 +1,133 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Node.h"
+
+namespace Tools
+{
+ template<> class PointerPool<SpatialIndex::MVRTree::Node>
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ SpatialIndex::MVRTree::Node* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<SpatialIndex::MVRTree::Node> acquire()
+ {
+ if (! m_pool.empty())
+ {
+ SpatialIndex::MVRTree::Node* p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ ++m_hits;
+ #endif
+
+ return PoolPointer<SpatialIndex::MVRTree::Node>(p, this);
+ }
+ #ifndef NDEBUG
+ else
+ {
+ // fixme: well sort of...
+ ++m_pointerCount;
+ ++m_misses;
+ }
+ #endif
+
+ return PoolPointer<SpatialIndex::MVRTree::Node>();
+ }
+
+ void release(SpatialIndex::MVRTree::Node* p)
+ {
+ if (p != 0)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ if (p->m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ if (p->m_pData[cChild] != 0) delete[] p->m_pData[cChild];
+ }
+ }
+
+ p->m_level = 0;
+ p->m_identifier = -1;
+ p->m_children = 0;
+ p->m_totalDataLength = 0;
+
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ protected:
+ uint32_t m_capacity;
+ std::stack<SpatialIndex::MVRTree::Node*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.cc b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.cc
new file mode 100644
index 000000000..3ffbcefae
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.cc
@@ -0,0 +1,191 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Statistics.h"
+
+using namespace SpatialIndex::MVRTree;
+
+Statistics::Statistics()
+{
+ reset();
+}
+
+Statistics::Statistics(const Statistics& s)
+{
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u32DeadIndexNodes = s.m_u32DeadIndexNodes;
+ m_u32DeadLeafNodes = s.m_u32DeadLeafNodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u64TotalData = s.m_u64TotalData;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+}
+
+Statistics::~Statistics()
+{
+}
+
+Statistics& Statistics::operator=(const Statistics& s)
+{
+ if (this != &s)
+ {
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u32DeadIndexNodes = s.m_u32DeadIndexNodes;
+ m_u32DeadLeafNodes = s.m_u32DeadLeafNodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u64TotalData = s.m_u64TotalData;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+ }
+
+ return *this;
+}
+
+uint64_t Statistics::getReads() const
+{
+ return m_u64Reads;
+}
+
+uint64_t Statistics::getWrites() const
+{
+ return m_u64Writes;
+}
+
+uint32_t Statistics::getNumberOfNodes() const
+{
+ return m_u32Nodes;
+}
+
+uint64_t Statistics::getNumberOfData() const
+{
+ return m_u64Data;
+}
+
+uint64_t Statistics::getSplits() const
+{
+ return m_u64Splits;
+}
+
+uint64_t Statistics::getHits() const
+{
+ return m_u64Hits;
+}
+
+uint64_t Statistics::getMisses() const
+{
+ return m_u64Misses;
+}
+
+uint64_t Statistics::getAdjustments() const
+{
+ return m_u64Adjustments;
+}
+
+uint64_t Statistics::getQueryResults() const
+{
+ return m_u64QueryResults;
+}
+
+uint32_t Statistics::getTreeHeight() const
+{
+ uint32_t ret = 0;
+
+ for (size_t cIndex = 0; cIndex < m_treeHeight.size(); ++cIndex)
+ {
+ ret = std::max(ret, m_treeHeight[cIndex]);
+ }
+
+ return ret;
+}
+
+uint32_t Statistics::getNumberOfNodesInLevel(uint32_t l) const
+{
+ try
+ {
+ return m_nodesInLevel.at(l);
+ }
+ catch (...)
+ {
+ throw Tools::IndexOutOfBoundsException(l);
+ }
+}
+
+void Statistics::reset()
+{
+ m_u64Reads = 0;
+ m_u64Writes = 0;
+ m_u64Splits = 0;
+ m_u64Hits = 0;
+ m_u64Misses = 0;
+ m_u32Nodes = 0;
+ m_u32DeadIndexNodes = 0;
+ m_u32DeadLeafNodes = 0;
+ m_u64Adjustments = 0;
+ m_u64QueryResults = 0;
+ m_u64Data = 0;
+ m_u64TotalData = 0;
+ m_treeHeight.clear();
+ m_nodesInLevel.clear();
+}
+
+std::ostream& SpatialIndex::MVRTree::operator<<(std::ostream& os, const Statistics& s)
+{
+ os << "Reads: " << s.m_u64Reads << std::endl
+ << "Writes: " << s.m_u64Writes << std::endl
+ << "Hits: " << s.m_u64Hits << std::endl
+ << "Misses: " << s.m_u64Misses << std::endl
+ << "Number of live data: " << s.m_u64Data << std::endl
+ << "Total number of data: " << s.m_u64TotalData << std::endl
+ << "Number of nodes: " << s.m_u32Nodes << std::endl
+ << "Numer of dead index nodes: " << s.m_u32DeadIndexNodes << std::endl
+ << "Numer of dead leaf nodes: " << s.m_u32DeadLeafNodes << std::endl;
+
+ for (size_t cTree = 0; cTree < s.m_treeHeight.size(); ++cTree)
+ {
+ os << "Tree " << cTree << ", Height " << s.m_treeHeight[cTree] << std::endl;
+ }
+
+ for (size_t cLevel = 0; cLevel < s.m_nodesInLevel.size(); ++cLevel)
+ {
+ os << "Level " << cLevel << " pages: " << s.m_nodesInLevel[cLevel] << std::endl;
+ }
+
+ os << "Splits: " << s.m_u64Splits << std::endl
+ << "Adjustments: " << s.m_u64Adjustments << std::endl
+ << "Query results: " << s.m_u64QueryResults << std::endl;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.h b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.h
new file mode 100644
index 000000000..249a98cac
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/mvrtree/Statistics.h
@@ -0,0 +1,99 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace MVRTree
+ {
+ class MVRTree;
+ class Node;
+ class Leaf;
+ class Index;
+
+ class Statistics : public SpatialIndex::IStatistics
+ {
+ public:
+ Statistics();
+ Statistics(const Statistics&);
+ virtual ~Statistics();
+ Statistics& operator=(const Statistics&);
+
+ //
+ // IStatistics interface
+ //
+ virtual uint64_t getReads() const;
+ virtual uint64_t getWrites() const;
+ virtual uint32_t getNumberOfNodes() const;
+ virtual uint64_t getNumberOfData() const;
+
+ virtual uint64_t getSplits() const;
+ virtual uint64_t getHits() const;
+ virtual uint64_t getMisses() const;
+ virtual uint64_t getAdjustments() const;
+ virtual uint64_t getQueryResults() const;
+ virtual uint32_t getTreeHeight() const;
+ virtual uint32_t getNumberOfNodesInLevel(uint32_t l) const;
+
+ private:
+ void reset();
+
+ uint64_t m_u64Reads;
+
+ uint64_t m_u64Writes;
+
+ uint64_t m_u64Splits;
+
+ uint64_t m_u64Hits;
+
+ uint64_t m_u64Misses;
+
+ uint32_t m_u32Nodes;
+
+ uint32_t m_u32DeadIndexNodes;
+
+ uint32_t m_u32DeadLeafNodes;
+
+ uint64_t m_u64Adjustments;
+
+ uint64_t m_u64QueryResults;
+
+ uint64_t m_u64Data;
+
+ uint64_t m_u64TotalData;
+
+ std::vector<uint32_t> m_treeHeight;
+
+ std::vector<uint32_t> m_nodesInLevel;
+
+ friend class MVRTree;
+ friend class Node;
+ friend class Index;
+ friend class Leaf;
+
+ friend std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }; // Statistics
+
+ std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/all-wcprops
new file mode 100644
index 000000000..064065c70
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/all-wcprops
@@ -0,0 +1,89 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/spatialindex/!svn/ver/181/spatialindex/trunk/src/rtree
+END
+Statistics.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/Statistics.h
+END
+RTree.cc
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/rtree/RTree.cc
+END
+PointerPoolNode.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/PointerPoolNode.h
+END
+RTree.h
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/133/spatialindex/trunk/src/rtree/RTree.h
+END
+BulkLoader.cc
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/spatialindex/!svn/ver/181/spatialindex/trunk/src/rtree/BulkLoader.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/45/spatialindex/trunk/src/rtree/Makefile.am
+END
+Node.cc
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/rtree/Node.cc
+END
+BulkLoader.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/132/spatialindex/trunk/src/rtree/BulkLoader.h
+END
+Index.cc
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/rtree/Index.cc
+END
+Leaf.cc
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/Leaf.cc
+END
+Node.h
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/Node.h
+END
+Index.h
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/Index.h
+END
+Leaf.h
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/Leaf.h
+END
+Statistics.cc
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/rtree/Statistics.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/dir-prop-base
new file mode 100644
index 000000000..ea9b95e8a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/dir-prop-base
@@ -0,0 +1,9 @@
+K 10
+svn:ignore
+V 33
+Makefile.in
+.libs
+.deps
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/entries
new file mode 100644
index 000000000..a74e15d59
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/entries
@@ -0,0 +1,504 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/rtree
+http://svn.gispython.org/spatialindex
+
+
+
+2010-04-12T17:07:13.774013Z
+181
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Statistics.h
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+94cda4c818ca1f8fb5df3636155f1819
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2293
+
+RTree.cc
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+a74add8050d27a9000c9c1c888c55e5a
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+43344
+
+PointerPoolNode.h
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+31296acf2a6c706a54f63b8cd48de5e2
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3015
+
+RTree.h
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+eab591c68b607cb7ef47ad3fe537a92f
+2009-08-14T15:19:40.553411Z
+133
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6821
+
+BulkLoader.cc
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+46d2cff70e12f219e608643fb7b5dd7e
+2010-04-12T17:07:13.774013Z
+181
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11307
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+1d38b85a74c38e0ec673a16952349697
+2008-01-17T23:34:01.575758Z
+45
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+292
+
+Node.cc
+file
+
+
+
+
+2011-08-01T00:42:34.549134Z
+8ff5747378f669668ff10a1fd50f544a
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+28187
+
+BulkLoader.h
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+e7ab0daf9fbba3f120bd7c92595f9061
+2009-08-13T19:10:02.395894Z
+132
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3195
+
+Index.cc
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+df5cd482aeed566ba127b36ad268b374
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10474
+
+Leaf.cc
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+319461954ec844a6c37547bb57e7e3a5
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4268
+
+Node.h
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+95ebf90b30308c1f27bcac12fa6a2948
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5954
+
+Index.h
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+2cdb5447b856942f246d29240996bf2d
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2170
+
+Leaf.h
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+c6f78b493a99573bad11f79b9e6ead4e
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1461
+
+Statistics.cc
+file
+
+
+
+
+2011-08-01T00:42:34.553152Z
+1354a1c5c0d19bef42dea03eff069ab4
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3817
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.cc.svn-base
new file mode 100644
index 000000000..5fb14963d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.cc.svn-base
@@ -0,0 +1,458 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <stdio.h>
+#include <cmath>
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "BulkLoader.h"
+
+using namespace SpatialIndex::RTree;
+
+//
+// ExternalSorter::Record
+//
+ExternalSorter::Record::Record()
+: m_pData(0)
+{
+}
+
+ExternalSorter::Record::Record(const Region& r, id_type id, uint32_t len, byte* pData, uint32_t s)
+: m_r(r), m_id(id), m_len(len), m_pData(pData), m_s(s)
+{
+}
+
+ExternalSorter::Record::~Record()
+{
+ delete[] m_pData;
+}
+
+bool ExternalSorter::Record::operator<(const Record& r) const
+{
+ if (m_s != r.m_s)
+ throw Tools::IllegalStateException("ExternalSorter::Record::operator<: Incompatible sorting dimensions.");
+
+ if (m_r.m_pHigh[m_s] + m_r.m_pLow[m_s] < r.m_r.m_pHigh[m_s] + r.m_r.m_pLow[m_s])
+ return true;
+ else
+ return false;
+}
+
+void ExternalSorter::Record::storeToFile(Tools::TemporaryFile& f)
+{
+ f.write(static_cast<uint64_t>(m_id));
+ f.write(m_r.m_dimension);
+ f.write(m_s);
+
+ for (uint32_t i = 0; i < m_r.m_dimension; ++i)
+ {
+ f.write(m_r.m_pLow[i]);
+ f.write(m_r.m_pHigh[i]);
+ }
+
+ f.write(m_len);
+ if (m_len > 0) f.write(m_len, m_pData);
+}
+
+void ExternalSorter::Record::loadFromFile(Tools::TemporaryFile& f)
+{
+ m_id = static_cast<id_type>(f.readUInt64());
+ uint32_t dim = f.readUInt32();
+ m_s = f.readUInt32();
+
+ if (dim != m_r.m_dimension)
+ {
+ delete[] m_r.m_pLow;
+ delete[] m_r.m_pHigh;
+ m_r.m_dimension = dim;
+ m_r.m_pLow = new double[dim];
+ m_r.m_pHigh = new double[dim];
+ }
+
+ for (uint32_t i = 0; i < m_r.m_dimension; ++i)
+ {
+ m_r.m_pLow[i] = f.readDouble();
+ m_r.m_pHigh[i] = f.readDouble();
+ }
+
+ m_len = f.readUInt32();
+ delete[] m_pData; m_pData = 0;
+ if (m_len > 0) f.readBytes(m_len, &m_pData);
+}
+
+//
+// ExternalSorter
+//
+ExternalSorter::ExternalSorter(uint32_t u32PageSize, uint32_t u32BufferPages)
+: m_bInsertionPhase(true), m_u32PageSize(u32PageSize),
+ m_u32BufferPages(u32BufferPages), m_u64TotalEntries(0), m_stI(0)
+{
+}
+
+ExternalSorter::~ExternalSorter()
+{
+ for (m_stI = 0; m_stI < m_buffer.size(); ++m_stI) delete m_buffer[m_stI];
+}
+
+void ExternalSorter::insert(Record* r)
+{
+ if (m_bInsertionPhase == false)
+ throw Tools::IllegalStateException("ExternalSorter::insert: Input has already been sorted.");
+
+ m_buffer.push_back(r);
+ ++m_u64TotalEntries;
+
+ // this will create the initial, sorted buckets before the
+ // external merge sort.
+ if (m_buffer.size() >= m_u32PageSize * m_u32BufferPages)
+ {
+ std::sort(m_buffer.begin(), m_buffer.end(), Record::SortAscending());
+ Tools::TemporaryFile* tf = new Tools::TemporaryFile();
+ for (size_t j = 0; j < m_buffer.size(); ++j)
+ {
+ m_buffer[j]->storeToFile(*tf);
+ delete m_buffer[j];
+ }
+ m_buffer.clear();
+ tf->rewindForReading();
+ m_runs.push_back(Tools::SmartPointer<Tools::TemporaryFile>(tf));
+ }
+}
+
+void ExternalSorter::sort()
+{
+ if (m_bInsertionPhase == false)
+ throw Tools::IllegalStateException("ExternalSorter::sort: Input has already been sorted.");
+
+ if (m_runs.empty())
+ {
+ // The data fits in main memory. No need to store to disk.
+ std::sort(m_buffer.begin(), m_buffer.end(), Record::SortAscending());
+ m_bInsertionPhase = false;
+ return;
+ }
+
+ if (m_buffer.size() > 0)
+ {
+ // Whatever remained in the buffer (if not filled) needs to be stored
+ // as the final bucket.
+ std::sort(m_buffer.begin(), m_buffer.end(), Record::SortAscending());
+ Tools::TemporaryFile* tf = new Tools::TemporaryFile();
+ for (size_t j = 0; j < m_buffer.size(); ++j)
+ {
+ m_buffer[j]->storeToFile(*tf);
+ delete m_buffer[j];
+ }
+ m_buffer.clear();
+ tf->rewindForReading();
+ m_runs.push_back(Tools::SmartPointer<Tools::TemporaryFile>(tf));
+ }
+
+ if (m_runs.size() == 1)
+ {
+ m_sortedFile = m_runs.front();
+ }
+ else
+ {
+ Record* r;
+
+ while (m_runs.size() > 1)
+ {
+ Tools::SmartPointer<Tools::TemporaryFile> tf(new Tools::TemporaryFile());
+ std::vector<Tools::SmartPointer<Tools::TemporaryFile> > buckets;
+ std::vector<std::queue<Record*> > buffers;
+ std::priority_queue<PQEntry, std::vector<PQEntry>, PQEntry::SortAscending> pq;
+
+ // initialize buffers and priority queue.
+ std::list<Tools::SmartPointer<Tools::TemporaryFile> >::iterator it = m_runs.begin();
+ for (uint32_t i = 0; i < (std::min)(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages); ++i)
+ {
+ buckets.push_back(*it);
+ buffers.push_back(std::queue<Record*>());
+
+ r = new Record();
+ r->loadFromFile(**it);
+ // a run cannot be empty initially, so this should never fail.
+ pq.push(PQEntry(r, i));
+
+ for (uint32_t j = 0; j < m_u32PageSize - 1; ++j)
+ {
+ // fill the buffer with the rest of the page of records.
+ try
+ {
+ r = new Record();
+ r->loadFromFile(**it);
+ buffers.back().push(r);
+ }
+ catch (Tools::EndOfStreamException)
+ {
+ delete r;
+ break;
+ }
+ }
+ ++it;
+ }
+
+ // exhaust buckets, buffers, and priority queue.
+ while (! pq.empty())
+ {
+ PQEntry e = pq.top(); pq.pop();
+ e.m_r->storeToFile(*tf);
+ delete e.m_r;
+
+ if (! buckets[e.m_u32Index]->eof() && buffers[e.m_u32Index].empty())
+ {
+ for (uint32_t j = 0; j < m_u32PageSize; ++j)
+ {
+ try
+ {
+ r = new Record();
+ r->loadFromFile(*buckets[e.m_u32Index]);
+ buffers[e.m_u32Index].push(r);
+ }
+ catch (Tools::EndOfStreamException)
+ {
+ delete r;
+ break;
+ }
+ }
+ }
+
+ if (! buffers[e.m_u32Index].empty())
+ {
+ e.m_r = buffers[e.m_u32Index].front();
+ buffers[e.m_u32Index].pop();
+ pq.push(e);
+ }
+ }
+
+ tf->rewindForReading();
+
+ // check if another pass is needed.
+ uint32_t u32Count = std::min(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages);
+ for (uint32_t i = 0; i < u32Count; ++i)
+ {
+ m_runs.pop_front();
+ }
+
+ if (m_runs.size() == 0)
+ {
+ m_sortedFile = tf;
+ break;
+ }
+ else
+ {
+ m_runs.push_back(tf);
+ }
+ }
+ }
+
+ m_bInsertionPhase = false;
+}
+
+ExternalSorter::Record* ExternalSorter::getNextRecord()
+{
+ if (m_bInsertionPhase == true)
+ throw Tools::IllegalStateException("ExternalSorter::getNextRecord: Input has not been sorted yet.");
+
+ Record* ret;
+
+ if (m_sortedFile.get() == 0)
+ {
+ if (m_stI < m_buffer.size())
+ {
+ ret = m_buffer[m_stI];
+ m_buffer[m_stI] = 0;
+ ++m_stI;
+ }
+ else
+ throw Tools::EndOfStreamException("");
+ }
+ else
+ {
+ ret = new Record();
+ ret->loadFromFile(*m_sortedFile);
+ }
+
+ return ret;
+}
+
+inline uint64_t ExternalSorter::getTotalEntries() const
+{
+ return m_u64TotalEntries;
+}
+
+//
+// BulkLoader
+//
+void BulkLoader::bulkLoadUsingSTR(
+ SpatialIndex::RTree::RTree* pTree,
+ IDataStream& stream,
+ uint32_t bindex,
+ uint32_t bleaf,
+ uint32_t pageSize,
+ uint32_t numberOfPages
+) {
+ if (! stream.hasNext())
+ throw Tools::IllegalArgumentException(
+ "RTree::BulkLoader::bulkLoadUsingSTR: Empty data stream given."
+ );
+
+ NodePtr n = pTree->readNode(pTree->m_rootID);
+ pTree->deleteNode(n.get());
+
+ #ifndef NDEBUG
+ std::cerr << "RTree::BulkLoader: Sorting data." << std::endl;
+ #endif
+
+ Tools::SmartPointer<ExternalSorter> es = Tools::SmartPointer<ExternalSorter>(new ExternalSorter(pageSize, numberOfPages));
+
+ while (stream.hasNext())
+ {
+ Data* d = reinterpret_cast<Data*>(stream.getNext());
+ if (d == 0)
+ throw Tools::IllegalArgumentException(
+ "bulkLoadUsingSTR: RTree bulk load expects SpatialIndex::RTree::Data entries."
+ );
+
+ es->insert(new ExternalSorter::Record(d->m_region, d->m_id, d->m_dataLength, d->m_pData, 0));
+ d->m_pData = 0;
+ delete d;
+ }
+ es->sort();
+
+ pTree->m_stats.m_u64Data = es->getTotalEntries();
+
+ // create index levels.
+ uint32_t level = 0;
+
+ while (true)
+ {
+ #ifndef NDEBUG
+ std::cerr << "RTree::BulkLoader: Building level " << level << std::endl;
+ #endif
+
+ pTree->m_stats.m_nodesInLevel.push_back(0);
+
+ Tools::SmartPointer<ExternalSorter> es2 = Tools::SmartPointer<ExternalSorter>(new ExternalSorter(pageSize, numberOfPages));
+ createLevel(pTree, es, 0, bleaf, bindex, level++, es2, pageSize, numberOfPages);
+ es = es2;
+
+ if (es->getTotalEntries() == 1) break;
+ es->sort();
+ }
+
+ pTree->m_stats.m_u32TreeHeight = level;
+ pTree->storeHeader();
+}
+
+void BulkLoader::createLevel(
+ SpatialIndex::RTree::RTree* pTree,
+ Tools::SmartPointer<ExternalSorter> es,
+ uint32_t dimension,
+ uint32_t bleaf,
+ uint32_t bindex,
+ uint32_t level,
+ Tools::SmartPointer<ExternalSorter> es2,
+ uint32_t pageSize,
+ uint32_t numberOfPages
+) {
+ uint64_t b = (level == 0) ? bleaf : bindex;
+ uint64_t P = static_cast<uint64_t>(std::ceil(static_cast<double>(es->getTotalEntries()) / static_cast<double>(b)));
+ uint64_t S = static_cast<uint64_t>(std::ceil(std::sqrt(static_cast<double>(P))));
+
+ if (S == 1 || dimension == pTree->m_dimension - 1 || S * b == es->getTotalEntries())
+ {
+ std::vector<ExternalSorter::Record*> node;
+ ExternalSorter::Record* r;
+
+ while (true)
+ {
+ try { r = es->getNextRecord(); } catch (Tools::EndOfStreamException) { break; }
+ node.push_back(r);
+
+ if (node.size() == b)
+ {
+ Node* n = createNode(pTree, node, level);
+ node.clear();
+ pTree->writeNode(n);
+ es2->insert(new ExternalSorter::Record(n->m_nodeMBR, n->m_identifier, 0, 0, 0));
+ pTree->m_rootID = n->m_identifier;
+ // special case when the root has exactly bindex entries.
+ delete n;
+ }
+ }
+
+ if (! node.empty())
+ {
+ Node* n = createNode(pTree, node, level);
+ pTree->writeNode(n);
+ es2->insert(new ExternalSorter::Record(n->m_nodeMBR, n->m_identifier, 0, 0, 0));
+ pTree->m_rootID = n->m_identifier;
+ delete n;
+ }
+ }
+ else
+ {
+ bool bMore = true;
+
+ while (bMore)
+ {
+ ExternalSorter::Record* pR;
+ Tools::SmartPointer<ExternalSorter> es3 = Tools::SmartPointer<ExternalSorter>(new ExternalSorter(pageSize, numberOfPages));
+
+ for (uint64_t i = 0; i < S * b; ++i)
+ {
+ try { pR = es->getNextRecord(); }
+ catch (Tools::EndOfStreamException) { bMore = false; break; }
+ pR->m_s = dimension + 1;
+ es3->insert(pR);
+ }
+ es3->sort();
+ createLevel(pTree, es3, dimension + 1, bleaf, bindex, level, es2, pageSize, numberOfPages);
+ }
+ }
+}
+
+Node* BulkLoader::createNode(SpatialIndex::RTree::RTree* pTree, std::vector<ExternalSorter::Record*>& e, uint32_t level)
+{
+ Node* n;
+
+ if (level == 0) n = new Leaf(pTree, -1);
+ else n = new Index(pTree, -1, level);
+
+ for (size_t cChild = 0; cChild < e.size(); ++cChild)
+ {
+ n->insertEntry(e[cChild]->m_len, e[cChild]->m_pData, e[cChild]->m_r, e[cChild]->m_id);
+ e[cChild]->m_pData = 0;
+ delete e[cChild];
+ }
+
+ return n;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.h.svn-base
new file mode 100644
index 000000000..17d8f71fb
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/BulkLoader.h.svn-base
@@ -0,0 +1,131 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class ExternalSorter
+ {
+ public:
+ class Record
+ {
+ public:
+ Record();
+ Record(const Region& r, id_type id, uint32_t len, byte* pData, uint32_t s);
+ ~Record();
+
+ bool operator<(const Record& r) const;
+
+ void storeToFile(Tools::TemporaryFile& f);
+ void loadFromFile(Tools::TemporaryFile& f);
+
+ struct SortAscending : public std::binary_function<Record* const, Record* const, bool>
+ {
+ bool operator()(Record* const r1, Record* const r2)
+ {
+ if (*r1 < *r2) return true;
+ else return false;
+ }
+ };
+
+ public:
+ Region m_r;
+ id_type m_id;
+ byte* m_pData;
+ uint32_t m_len;
+ uint32_t m_s;
+ };
+
+ public:
+ ExternalSorter(uint32_t u32PageSize, uint32_t u32BufferPages);
+ virtual ~ExternalSorter();
+
+ void insert(Record* r);
+ void sort();
+ Record* getNextRecord();
+ uint64_t getTotalEntries() const;
+
+ private:
+ class PQEntry
+ {
+ public:
+ PQEntry(Record* r, uint32_t u32Index) : m_r(r), m_u32Index(u32Index) {}
+
+ struct SortAscending : public std::binary_function<const PQEntry&, const PQEntry&, bool>
+ {
+ bool operator()(const PQEntry& e1, const PQEntry& e2)
+ {
+ if (*(e1.m_r) < *(e2.m_r)) return true;
+ else return false;
+ }
+ };
+
+ Record* m_r;
+ uint32_t m_u32Index;
+ };
+
+ private:
+ bool m_bInsertionPhase;
+ uint32_t m_u32PageSize;
+ uint32_t m_u32BufferPages;
+ Tools::SmartPointer<Tools::TemporaryFile> m_sortedFile;
+ std::list<Tools::SmartPointer<Tools::TemporaryFile> > m_runs;
+ std::vector<Record*> m_buffer;
+ uint64_t m_u64TotalEntries;
+ uint32_t m_stI;
+ };
+
+ class BulkLoader
+ {
+ public:
+ void bulkLoadUsingSTR(
+ RTree* pTree,
+ IDataStream& stream,
+ uint32_t bindex,
+ uint32_t bleaf,
+ uint32_t pageSize, // The number of node entries per page.
+ uint32_t numberOfPages // The total number of pages to use.
+ );
+
+ protected:
+ void createLevel(
+ RTree* pTree,
+ Tools::SmartPointer<ExternalSorter> es,
+ uint32_t dimension,
+ uint32_t indexSize,
+ uint32_t leafSize,
+ uint32_t level,
+ Tools::SmartPointer<ExternalSorter> es2,
+ uint32_t pageSize,
+ uint32_t numberOfPages
+ );
+
+ Node* createNode(
+ RTree* pTree,
+ std::vector<ExternalSorter::Record*>& e,
+ uint32_t level
+ );
+ };
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.cc.svn-base
new file mode 100644
index 000000000..9a3209683
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.cc.svn-base
@@ -0,0 +1,372 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+
+using namespace SpatialIndex::RTree;
+
+Index::~Index()
+{
+}
+
+Index::Index(SpatialIndex::RTree::RTree* pTree, id_type id, uint32_t level) : Node(pTree, id, level, pTree->m_indexCapacity)
+{
+}
+
+NodePtr Index::chooseSubtree(const Region& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
+{
+ if (m_level == insertionLevel) return NodePtr(this, &(m_pTree->m_indexPool));
+
+ pathBuffer.push(m_identifier);
+
+ uint32_t child = 0;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ child = findLeastEnlargement(mbr);
+ break;
+ case RV_RSTAR:
+ if (m_level == 1)
+ {
+ // if this node points to leaves...
+ child = findLeastOverlap(mbr);
+ }
+ else
+ {
+ child = findLeastEnlargement(mbr);
+ }
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::chooseSubtree: Tree variant not supported.");
+ }
+ assert(child != std::numeric_limits<uint32_t>::max());
+
+ NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
+ NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
+ assert(n.unique());
+ if (ret.get() == n.get()) n.relinquish();
+
+ return ret;
+}
+
+NodePtr Index::findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->containsRegion(mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findLeaf(mbr, id, pathBuffer);
+ if (n.get() == l.get()) n.relinquish();
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
+
+void Index::split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& ptrLeft, NodePtr& ptrRight)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::split: Tree variant not supported.");
+ }
+
+ ptrLeft = m_pTree->m_indexPool.acquire();
+ ptrRight = m_pTree->m_indexPool.acquire();
+
+ if (ptrLeft.get() == 0) ptrLeft = NodePtr(new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
+ if (ptrRight.get() == 0) ptrRight = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+
+ ptrLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ ptrRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ ptrLeft->insertEntry(0, 0, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ ptrRight->insertEntry(0, 0, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ }
+}
+
+uint32_t Index::findLeastEnlargement(const Region& r) const
+{
+ double area = std::numeric_limits<double>::max();
+ uint32_t best = std::numeric_limits<uint32_t>::max();
+
+ RegionPtr t = m_pTree->m_regionPool.acquire();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_ptrMBR[cChild]->getCombinedRegion(*t, r);
+
+ double a = m_ptrMBR[cChild]->getArea();
+ double enl = t->getArea() - a;
+
+ if (enl < area)
+ {
+ area = enl;
+ best = cChild;
+ }
+ else if (enl == area)
+ {
+ // this will rarely happen, so compute best area on the fly only
+ // when necessary.
+ if (a < m_ptrMBR[best]->getArea()) best = cChild;
+ }
+ }
+
+ return best;
+}
+
+uint32_t Index::findLeastOverlap(const Region& r) const
+{
+ OverlapEntry** entries = new OverlapEntry*[m_children];
+
+ double leastOverlap = std::numeric_limits<double>::max();
+ double me = std::numeric_limits<double>::max();
+ OverlapEntry* best = 0;
+
+ // find combined region and enlargement of every entry and store it.
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ try
+ {
+ entries[cChild] = new OverlapEntry();
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete entries[i];
+ delete[] entries;
+ throw;
+ }
+
+ entries[cChild]->m_index = cChild;
+ entries[cChild]->m_original = m_ptrMBR[cChild];
+ entries[cChild]->m_combined = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->getCombinedRegion(*(entries[cChild]->m_combined), r);
+ entries[cChild]->m_oa = entries[cChild]->m_original->getArea();
+ entries[cChild]->m_ca = entries[cChild]->m_combined->getArea();
+ entries[cChild]->m_enlargement = entries[cChild]->m_ca - entries[cChild]->m_oa;
+
+ if (entries[cChild]->m_enlargement < me)
+ {
+ me = entries[cChild]->m_enlargement;
+ best = entries[cChild];
+ }
+ else if (entries[cChild]->m_enlargement == me && entries[cChild]->m_oa < best->m_oa)
+ {
+ best = entries[cChild];
+ }
+ }
+
+ if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
+ {
+ uint32_t cIterations;
+
+ if (m_children > m_pTree->m_nearMinimumOverlapFactor)
+ {
+ // sort entries in increasing order of enlargement.
+ ::qsort(entries, m_children,
+ sizeof(OverlapEntry*),
+ OverlapEntry::compareEntries);
+ assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
+
+ cIterations = m_pTree->m_nearMinimumOverlapFactor;
+ }
+ else
+ {
+ cIterations = m_children;
+ }
+
+ // calculate overlap of most important original entries (near minimum overlap cost).
+ for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
+ {
+ double dif = 0.0;
+ OverlapEntry* e = entries[cIndex];
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (e->m_index != cChild)
+ {
+ double f = e->m_combined->getIntersectingArea(*(m_ptrMBR[cChild]));
+ if (f != 0.0) dif += f - e->m_original->getIntersectingArea(*(m_ptrMBR[cChild]));
+ }
+ } // for (cChild)
+
+ if (dif < leastOverlap)
+ {
+ leastOverlap = dif;
+ best = entries[cIndex];
+ }
+ else if (dif == leastOverlap)
+ {
+ if (e->m_enlargement == best->m_enlargement)
+ {
+ // keep the one with least area.
+ if (e->m_original->getArea() < best->m_original->getArea()) best = entries[cIndex];
+ }
+ else
+ {
+ // keep the one with least enlargement.
+ if (e->m_enlargement < best->m_enlargement) best = entries[cIndex];
+ }
+ }
+ } // for (cIndex)
+ }
+
+ uint32_t ret = best->m_index;
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ delete entries[cChild];
+ }
+ delete[] entries;
+
+ return ret;
+}
+
+void Index::adjustTree(Node* n, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ bool bContained = m_nodeMBR.containsRegion(n->m_nodeMBR);
+ bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
+
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+
+ if (bRecompute)
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ if (bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
+
+void Index::adjustTree(Node* n1, Node* n2, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n1->m_identifier) break;
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ bool bContained = m_nodeMBR.containsRegion(n1->m_nodeMBR);
+ bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
+
+ *(m_ptrMBR[child]) = n1->m_nodeMBR;
+
+ if (bRecompute)
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ // No write necessary here. insertData will write the node if needed.
+ //m_pTree->writeNode(this);
+
+ bool bAdjusted = insertData(0, 0, n2->m_nodeMBR, n2->m_identifier, pathBuffer, overflowTable);
+
+ // if n2 is contained in the node and there was no split or reinsert,
+ // we need to adjust only if recalculation took place.
+ // In all other cases insertData above took care of adjustment.
+ if ((! bAdjusted) && bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.h.svn-base
new file mode 100644
index 000000000..ce0510dff
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Index.h.svn-base
@@ -0,0 +1,73 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class Index : public Node
+ {
+ public:
+ virtual ~Index();
+
+ protected:
+ Index(RTree* pTree, id_type id, uint32_t level);
+
+ virtual NodePtr chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ uint32_t findLeastEnlargement(const Region&) const;
+ uint32_t findLeastOverlap(const Region&) const;
+
+ void adjustTree(Node*, std::stack<id_type>&);
+ void adjustTree(Node*, Node*, std::stack<id_type>&, byte* overflowTable);
+
+ class OverlapEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_enlargement;
+ RegionPtr m_original;
+ RegionPtr m_combined;
+ double m_oa;
+ double m_ca;
+
+ static int compareEntries(const void* pv1, const void* pv2)
+ {
+ OverlapEntry* pe1 = * (OverlapEntry**) pv1;
+ OverlapEntry* pe2 = * (OverlapEntry**) pv2;
+
+ if (pe1->m_enlargement < pe2->m_enlargement) return -1;
+ if (pe1->m_enlargement > pe2->m_enlargement) return 1;
+ return 0;
+ }
+ }; // OverlapEntry
+
+ friend class RTree;
+ friend class Node;
+ friend class BulkLoader;
+ }; // Index
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.cc.svn-base
new file mode 100644
index 000000000..5781734d5
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.cc.svn-base
@@ -0,0 +1,138 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::RTree;
+
+Leaf::~Leaf()
+{
+}
+
+Leaf::Leaf(SpatialIndex::RTree::RTree* pTree, id_type id): Node(pTree, id, 0, pTree->m_leafCapacity)
+{
+}
+
+NodePtr Leaf::chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer)
+{
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ return NodePtr(this, &(m_pTree->m_leafPool));
+}
+
+NodePtr Leaf::findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ if (m_pIdentifier[cChild] == id && mbr == *(m_ptrMBR[cChild])) return NodePtr(this, &(m_pTree->m_leafPool));
+ }
+
+ return NodePtr();
+}
+
+void Leaf::split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_leafPool.acquire();
+ pRight = m_pTree->m_leafPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g1[cIndex]] = 0;
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g2[cIndex]] = 0;
+ }
+}
+
+void Leaf::deleteData(id_type id, std::stack<id_type>& pathBuffer)
+{
+ uint32_t child;
+
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == id) break;
+ }
+
+ deleteEntry(child);
+ m_pTree->writeNode(this);
+
+ std::stack<NodePtr> toReinsert;
+ NodePtr ptrThis(this, &(m_pTree->m_leafPool));
+ condenseTree(toReinsert, pathBuffer, ptrThis);
+ ptrThis.relinquish();
+
+ // re-insert eliminated nodes.
+ while (! toReinsert.empty())
+ {
+ NodePtr n = toReinsert.top(); toReinsert.pop();
+ m_pTree->deleteNode(n.get());
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ // keep this in the for loop. The tree height might change after insertions.
+ byte* overflowTable = new byte[m_pTree->m_stats.m_u32TreeHeight];
+ bzero(overflowTable, m_pTree->m_stats.m_u32TreeHeight);
+ m_pTree->insertData_impl(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild], n->m_level, overflowTable);
+ n->m_pData[cChild] = 0;
+ delete[] overflowTable;
+ }
+ if (n.get() == this) n.relinquish();
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.h.svn-base
new file mode 100644
index 000000000..2705e4c1d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Leaf.h.svn-base
@@ -0,0 +1,47 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class Leaf : public Node
+ {
+ public:
+ virtual ~Leaf();
+
+ protected:
+ Leaf(RTree* pTree, id_type id);
+
+ virtual NodePtr chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ virtual void deleteData(id_type id, std::stack<id_type>& pathBuffer);
+
+ friend class RTree;
+ friend class BulkLoader;
+ }; // Leaf
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..e1bcd6272
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = librtree.la
+INCLUDES = -I../../include
+librtree_la_SOURCES = BulkLoader.cc Index.cc Leaf.cc Node.cc RTree.cc Statistics.cc BulkLoader.h Index.h Leaf.h Node.h PointerPoolNode.h RTree.h Statistics.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.cc.svn-base
new file mode 100644
index 000000000..09ecfe943
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.cc.svn-base
@@ -0,0 +1,1074 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Node.h"
+#include "Index.h"
+
+using namespace SpatialIndex::RTree;
+
+//
+// Tools::IObject interface
+//
+Tools::IObject* Node::clone()
+{
+ throw Tools::NotSupportedException("IObject::clone should never be called.");
+}
+
+//
+// Tools::ISerializable interface
+//
+uint32_t Node::getByteArraySize()
+{
+ return
+ (sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ (m_children * (m_pTree->m_dimension * sizeof(double) * 2 + sizeof(id_type) + sizeof(uint32_t))) +
+ m_totalDataLength +
+ (2 * m_pTree->m_dimension * sizeof(double)));
+}
+
+void Node::loadFromByteArray(const byte* ptr)
+{
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ // skip the node type information, it is not needed.
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_level, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_children, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ m_ptrMBR[u32Child] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[u32Child]) = m_pTree->m_infiniteRegion;
+
+ memcpy(m_ptrMBR[u32Child]->m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[u32Child]->m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(&(m_pIdentifier[u32Child]), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(&(m_pDataLength[u32Child]), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[u32Child] > 0)
+ {
+ m_totalDataLength += m_pDataLength[u32Child];
+ m_pData[u32Child] = new byte[m_pDataLength[u32Child]];
+ memcpy(m_pData[u32Child], ptr, m_pDataLength[u32Child]);
+ ptr += m_pDataLength[u32Child];
+ }
+ else
+ {
+ m_pData[u32Child] = 0;
+ }
+
+ //m_nodeMBR.combineRegion(*(m_ptrMBR[u32Child]));
+ }
+
+ memcpy(m_nodeMBR.m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+void Node::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ uint32_t nodeType;
+
+ if (m_level == 0) nodeType = PersistentLeaf;
+ else nodeType = PersistentIndex;
+
+ memcpy(ptr, &nodeType, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_level, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_children, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ memcpy(ptr, m_ptrMBR[u32Child]->m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[u32Child]->m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, &(m_pIdentifier[u32Child]), sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(ptr, &(m_pDataLength[u32Child]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[u32Child] > 0)
+ {
+ memcpy(ptr, m_pData[u32Child], m_pDataLength[u32Child]);
+ ptr += m_pDataLength[u32Child];
+ }
+ }
+
+ // store the node MBR for efficiency. This increases the node size a little bit.
+ memcpy(ptr, m_nodeMBR.m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pHigh, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+
+ assert(len == (ptr - *data) + m_pTree->m_dimension * sizeof(double));
+}
+
+//
+// SpatialIndex::IEntry interface
+//
+SpatialIndex::id_type Node::getIdentifier() const
+{
+ return m_identifier;
+}
+
+void Node::getShape(IShape** out) const
+{
+ *out = new Region(m_nodeMBR);
+}
+
+//
+// SpatialIndex::INode interface
+//
+uint32_t Node::getChildrenCount() const
+{
+ return m_children;
+}
+
+SpatialIndex::id_type Node::getChildIdentifier(uint32_t index) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pIdentifier[index];
+}
+
+void Node::getChildShape(uint32_t index, IShape** out) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ *out = new Region(*(m_ptrMBR[index]));
+}
+
+void Node::getChildData(uint32_t index, uint32_t& length, byte** data) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+ if (m_pData[index] == NULL)
+ {
+ length = 0;
+ data = NULL;
+ }
+ else
+ {
+ length = m_pDataLength[index];
+ *data = m_pData[index];
+ }
+}
+
+uint32_t Node::getLevel() const
+{
+ return m_level;
+}
+
+bool Node::isLeaf() const
+{
+ return (m_level == 0);
+}
+
+bool Node::isIndex() const
+{
+ return (m_level != 0);
+}
+
+//
+// Internal
+//
+
+Node::Node() :
+ m_pTree(0),
+ m_level(0),
+ m_identifier(-1),
+ m_children(0),
+ m_capacity(0),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+}
+
+Node::Node(SpatialIndex::RTree::RTree* pTree, id_type id, uint32_t level, uint32_t capacity) :
+ m_pTree(pTree),
+ m_level(level),
+ m_identifier(id),
+ m_children(0),
+ m_capacity(capacity),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+ m_nodeMBR.makeInfinite(m_pTree->m_dimension);
+
+ try
+ {
+ m_pDataLength = new uint32_t[m_capacity + 1];
+ m_pData = new byte*[m_capacity + 1];
+ m_ptrMBR = new RegionPtr[m_capacity + 1];
+ m_pIdentifier = new id_type[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+ throw;
+ }
+}
+
+Node::~Node()
+{
+ if (m_pData != 0)
+ {
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ if (m_pData[u32Child] != 0) delete[] m_pData[u32Child];
+ }
+
+ delete[] m_pData;
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+}
+
+Node& Node::operator=(const Node& n)
+{
+ throw Tools::IllegalStateException("operator =: This should never be called.");
+}
+
+void Node::insertEntry(uint32_t dataLength, byte* pData, Region& mbr, id_type id)
+{
+ assert(m_children < m_capacity);
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ m_totalDataLength += dataLength;
+ ++m_children;
+
+ m_nodeMBR.combineRegion(mbr);
+}
+
+void Node::deleteEntry(uint32_t index)
+{
+ assert(index >= 0 && index < m_children);
+
+ // cache it, since I might need it for "touches" later.
+ RegionPtr ptrR = m_ptrMBR[index];
+
+ m_totalDataLength -= m_pDataLength[index];
+ if (m_pData[index] != 0) delete[] m_pData[index];
+
+ if (m_children > 1 && index != m_children - 1)
+ {
+ m_pDataLength[index] = m_pDataLength[m_children - 1];
+ m_pData[index] = m_pData[m_children - 1];
+ m_ptrMBR[index] = m_ptrMBR[m_children - 1];
+ m_pIdentifier[index] = m_pIdentifier[m_children - 1];
+ }
+
+ --m_children;
+
+ // WARNING: index has now changed. Do not use it below here.
+
+ if (m_children == 0)
+ {
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ else if (m_pTree->m_bTightMBRs && m_nodeMBR.touchesRegion(*ptrR))
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[u32Child]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[u32Child]->m_pHigh[cDim]);
+ }
+ }
+ }
+}
+
+bool Node::insertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ if (m_children < m_capacity)
+ {
+ bool adjusted = false;
+
+ // this has to happen before insertEntry modifies m_nodeMBR.
+ bool b = m_nodeMBR.containsRegion(mbr);
+
+ insertEntry(dataLength, pData, mbr, id);
+ m_pTree->writeNode(this);
+
+ if ((! b) && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ adjusted = true;
+ }
+
+ return adjusted;
+ }
+ else if (m_pTree->m_treeVariant == RV_RSTAR && (! pathBuffer.empty()) && overflowTable[m_level] == 0)
+ {
+ overflowTable[m_level] = 1;
+
+ std::vector<uint32_t> vReinsert, vKeep;
+ reinsertData(dataLength, pData, mbr, id, vReinsert, vKeep);
+
+ uint32_t lReinsert = static_cast<uint32_t>(vReinsert.size());
+ uint32_t lKeep = static_cast<uint32_t>(vKeep.size());
+
+ byte** reinsertdata = 0;
+ RegionPtr* reinsertmbr = 0;
+ id_type* reinsertid = 0;
+ uint32_t* reinsertlen = 0;
+ byte** keepdata = 0;
+ RegionPtr* keepmbr = 0;
+ id_type* keepid = 0;
+ uint32_t* keeplen = 0;
+
+ try
+ {
+ reinsertdata = new byte*[lReinsert];
+ reinsertmbr = new RegionPtr[lReinsert];
+ reinsertid = new id_type[lReinsert];
+ reinsertlen = new uint32_t[lReinsert];
+
+ keepdata = new byte*[m_capacity + 1];
+ keepmbr = new RegionPtr[m_capacity + 1];
+ keepid = new id_type[m_capacity + 1];
+ keeplen = new uint32_t[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+ delete[] keepdata;
+ delete[] keepmbr;
+ delete[] keepid;
+ delete[] keeplen;
+ throw;
+ }
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ reinsertlen[cIndex] = m_pDataLength[vReinsert[cIndex]];
+ reinsertdata[cIndex] = m_pData[vReinsert[cIndex]];
+ reinsertmbr[cIndex] = m_ptrMBR[vReinsert[cIndex]];
+ reinsertid[cIndex] = m_pIdentifier[vReinsert[cIndex]];
+ }
+
+ for (cIndex = 0; cIndex < lKeep; ++cIndex)
+ {
+ keeplen[cIndex] = m_pDataLength[vKeep[cIndex]];
+ keepdata[cIndex] = m_pData[vKeep[cIndex]];
+ keepmbr[cIndex] = m_ptrMBR[vKeep[cIndex]];
+ keepid[cIndex] = m_pIdentifier[vKeep[cIndex]];
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+
+ m_pDataLength = keeplen;
+ m_pData = keepdata;
+ m_ptrMBR = keepmbr;
+ m_pIdentifier = keepid;
+ m_children = lKeep;
+ m_totalDataLength = 0;
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child) m_totalDataLength += m_pDataLength[u32Child];
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[u32Child]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[u32Child]->m_pHigh[cDim]);
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ // Divertion from R*-Tree algorithm here. First adjust
+ // the path to the root, then start reinserts, to avoid complicated handling
+ // of changes to the same node from multiple insertions.
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ m_pTree->insertData_impl(
+ reinsertlen[cIndex], reinsertdata[cIndex],
+ *(reinsertmbr[cIndex]), reinsertid[cIndex],
+ m_level, overflowTable);
+ }
+
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+
+ return true;
+ }
+ else
+ {
+ NodePtr n;
+ NodePtr nn;
+ split(dataLength, pData, mbr, id, n, nn);
+
+ if (pathBuffer.empty())
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ NodePtr ptrR = m_pTree->m_indexPool.acquire();
+ if (ptrR.get() == 0)
+ {
+ ptrR = NodePtr(new Index(m_pTree, m_pTree->m_rootID, m_level + 1), &(m_pTree->m_indexPool));
+ }
+ else
+ {
+ //ptrR->m_pTree = m_pTree;
+ ptrR->m_identifier = m_pTree->m_rootID;
+ ptrR->m_level = m_level + 1;
+ ptrR->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+
+ ptrR->insertEntry(0, 0, n->m_nodeMBR, n->m_identifier);
+ ptrR->insertEntry(0, 0, nn->m_nodeMBR, nn->m_identifier);
+
+ m_pTree->writeNode(ptrR.get());
+
+ m_pTree->m_stats.m_nodesInLevel[m_level] = 2;
+ m_pTree->m_stats.m_nodesInLevel.push_back(1);
+ m_pTree->m_stats.m_u32TreeHeight = m_level + 2;
+ }
+ else
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = m_identifier;
+ nn->m_identifier = -1;
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(n.get(), nn.get(), pathBuffer, overflowTable);
+ }
+
+ return true;
+ }
+}
+
+void Node::reinsertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep)
+{
+ ReinsertEntry** v = new ReinsertEntry*[m_capacity + 1];
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ PointPtr nc = m_pTree->m_pointPool.acquire();
+ m_nodeMBR.getCenter(*nc);
+ PointPtr c = m_pTree->m_pointPool.acquire();
+
+ for (uint32_t u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ try
+ {
+ v[u32Child] = new ReinsertEntry(u32Child, 0.0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < u32Child; ++i) delete v[i];
+ delete[] v;
+ throw;
+ }
+
+ m_ptrMBR[u32Child]->getCenter(*c);
+
+ // calculate relative distance of every entry from the node MBR (ignore square root.)
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ double d = nc->m_pCoords[cDim] - c->m_pCoords[cDim];
+ v[u32Child]->m_dist += d * d;
+ }
+ }
+
+ // sort by increasing order of distances.
+ ::qsort(v, m_capacity + 1, sizeof(ReinsertEntry*), ReinsertEntry::compareReinsertEntry);
+
+ uint32_t cReinsert = static_cast<uint32_t>(std::floor((m_capacity + 1) * m_pTree->m_reinsertFactor));
+
+ uint32_t cCount;
+
+ for (cCount = 0; cCount < cReinsert; ++cCount)
+ {
+ reinsert.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ for (cCount = cReinsert; cCount < m_capacity + 1; ++cCount)
+ {
+ keep.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ delete[] v;
+}
+
+void Node::rtreeSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ uint32_t u32Child;
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ // use this mask array for marking visited entries.
+ byte* mask = new byte[m_capacity + 1];
+ bzero(mask, m_capacity + 1);
+
+ // insert new data in the node for easier manipulation. Data arrays are always
+ // by one larger than node capacity.
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+ // m_totalDataLength does not need to be increased here.
+
+ // initialize each group with the seed entries.
+ uint32_t seed1, seed2;
+ pickSeeds(seed1, seed2);
+
+ group1.push_back(seed1);
+ group2.push_back(seed2);
+
+ mask[seed1] = 1;
+ mask[seed2] = 1;
+
+ // find MBR of each group.
+ RegionPtr mbr1 = m_pTree->m_regionPool.acquire();
+ *mbr1 = *(m_ptrMBR[seed1]);
+ RegionPtr mbr2 = m_pTree->m_regionPool.acquire();
+ *mbr2 = *(m_ptrMBR[seed2]);
+
+ // count how many entries are left unchecked (exclude the seeds here.)
+ uint32_t cRemaining = m_capacity + 1 - 2;
+
+ while (cRemaining > 0)
+ {
+ if (minimumLoad - group1.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group1 to comply with minimun load requirement.
+ for (u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ if (mask[u32Child] == 0)
+ {
+ group1.push_back(u32Child);
+ mask[u32Child] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else if (minimumLoad - group2.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group2 to comply with minimun load requirement.
+ for (u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ if (mask[u32Child] == 0)
+ {
+ group2.push_back(u32Child);
+ mask[u32Child] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else
+ {
+ // For all remaining entries compute the difference of the cost of grouping an
+ // entry in either group. When done, choose the entry that yielded the maximum
+ // difference. In case of linear split, select any entry (e.g. the first one.)
+ uint32_t sel;
+ double md1 = 0.0, md2 = 0.0;
+ double m = -std::numeric_limits<double>::max();
+ double d1, d2, d;
+ double a1 = mbr1->getArea();
+ double a2 = mbr2->getArea();
+
+ RegionPtr a = m_pTree->m_regionPool.acquire();
+ RegionPtr b = m_pTree->m_regionPool.acquire();
+
+ for (u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ if (mask[u32Child] == 0)
+ {
+ mbr1->getCombinedRegion(*a, *(m_ptrMBR[u32Child]));
+ d1 = a->getArea() - a1;
+ mbr2->getCombinedRegion(*b, *(m_ptrMBR[u32Child]));
+ d2 = b->getArea() - a2;
+ d = std::abs(d1 - d2);
+
+ if (d > m)
+ {
+ m = d;
+ md1 = d1; md2 = d2;
+ sel = u32Child;
+ if (m_pTree->m_treeVariant== RV_LINEAR || m_pTree->m_treeVariant == RV_RSTAR) break;
+ }
+ }
+ }
+
+ // determine the group where we should add the new entry.
+ int32_t group = -1;
+
+ if (md1 < md2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (md2 < md1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (a1 < a2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (a2 < a1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (group1.size() < group2.size())
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (group2.size() < group1.size())
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ mask[sel] = 1;
+ --cRemaining;
+ if (group == 1)
+ {
+ mbr1->combineRegion(*(m_ptrMBR[sel]));
+ }
+ else
+ {
+ mbr2->combineRegion(*(m_ptrMBR[sel]));
+ }
+ }
+ }
+
+ delete[] mask;
+}
+
+void Node::rstarSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ RstarSplitEntry** dataLow = 0;
+ RstarSplitEntry** dataHigh = 0;
+
+ try
+ {
+ dataLow = new RstarSplitEntry*[m_capacity + 1];
+ dataHigh = new RstarSplitEntry*[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] dataLow;
+ throw;
+ }
+
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+ // m_totalDataLength does not need to be increased here.
+
+ uint32_t nodeSPF = static_cast<uint32_t>(
+ std::floor((m_capacity + 1) * m_pTree->m_splitDistributionFactor));
+ uint32_t splitDistribution = (m_capacity + 1) - (2 * nodeSPF) + 2;
+
+ uint32_t u32Child = 0, cDim, cIndex;
+
+ for (u32Child = 0; u32Child <= m_capacity; ++u32Child)
+ {
+ try
+ {
+ dataLow[u32Child] = new RstarSplitEntry(m_ptrMBR[u32Child].get(), u32Child, 0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < u32Child; ++i) delete dataLow[i];
+ delete[] dataLow;
+ delete[] dataHigh;
+ throw;
+ }
+
+ dataHigh[u32Child] = dataLow[u32Child];
+ }
+
+ double minimumMargin = std::numeric_limits<double>::max();
+ uint32_t splitAxis = std::numeric_limits<uint32_t>::max();
+ uint32_t sortOrder = std::numeric_limits<uint32_t>::max();
+
+ // chooseSplitAxis.
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareLow);
+ ::qsort(dataHigh, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareHigh);
+
+ // calculate sum of margins and overlap for all distributions.
+ double marginl = 0.0;
+ double marginh = 0.0;
+
+ Region bbl1, bbl2, bbh1, bbh2;
+
+ for (u32Child = 1; u32Child <= splitDistribution; ++u32Child)
+ {
+ uint32_t l = nodeSPF - 1 + u32Child;
+
+ bbl1 = *(dataLow[0]->m_pRegion);
+ bbh1 = *(dataHigh[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bbl1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh1.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ bbl2 = *(dataLow[l]->m_pRegion);
+ bbh2 = *(dataHigh[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bbl2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh2.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ marginl += bbl1.getMargin() + bbl2.getMargin();
+ marginh += bbh1.getMargin() + bbh2.getMargin();
+ } // for (u32Child)
+
+ double margin = std::min(marginl, marginh);
+
+ // keep minimum margin as split axis.
+ if (margin < minimumMargin)
+ {
+ minimumMargin = margin;
+ splitAxis = cDim;
+ sortOrder = (marginl < marginh) ? 0 : 1;
+ }
+
+ // increase the dimension according to which the data entries should be sorted.
+ for (u32Child = 0; u32Child <= m_capacity; ++u32Child)
+ {
+ dataLow[u32Child]->m_sortDim = cDim + 1;
+ }
+ } // for (cDim)
+
+ for (u32Child = 0; u32Child <= m_capacity; ++u32Child)
+ {
+ dataLow[u32Child]->m_sortDim = splitAxis;
+ }
+
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), (sortOrder == 0) ? RstarSplitEntry::compareLow : RstarSplitEntry::compareHigh);
+
+ double ma = std::numeric_limits<double>::max();
+ double mo = std::numeric_limits<double>::max();
+ uint32_t splitPoint = std::numeric_limits<uint32_t>::max();
+
+ Region bb1, bb2;
+
+ for (u32Child = 1; u32Child <= splitDistribution; ++u32Child)
+ {
+ uint32_t l = nodeSPF - 1 + u32Child;
+
+ bb1 = *(dataLow[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bb1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ bb2 = *(dataLow[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bb2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ double o = bb1.getIntersectingArea(bb2);
+
+ if (o < mo)
+ {
+ splitPoint = u32Child;
+ mo = o;
+ ma = bb1.getArea() + bb2.getArea();
+ }
+ else if (o == mo)
+ {
+ double a = bb1.getArea() + bb2.getArea();
+
+ if (a < ma)
+ {
+ splitPoint = u32Child;
+ ma = a;
+ }
+ }
+ } // for (u32Child)
+
+ uint32_t l1 = nodeSPF - 1 + splitPoint;
+
+ for (cIndex = 0; cIndex < l1; ++cIndex)
+ {
+ group1.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ for (cIndex = l1; cIndex <= m_capacity; ++cIndex)
+ {
+ group2.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ delete[] dataLow;
+ delete[] dataHigh;
+}
+
+void Node::pickSeeds(uint32_t& index1, uint32_t& index2)
+{
+ double separation = -std::numeric_limits<double>::max();
+ double inefficiency = -std::numeric_limits<double>::max();
+ uint32_t cDim, u32Child, cIndex;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_RSTAR:
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ double leastLower = m_ptrMBR[0]->m_pLow[cDim];
+ double greatestUpper = m_ptrMBR[0]->m_pHigh[cDim];
+ uint32_t greatestLower = 0;
+ uint32_t leastUpper = 0;
+ double width;
+
+ for (u32Child = 1; u32Child <= m_capacity; ++u32Child)
+ {
+ if (m_ptrMBR[u32Child]->m_pLow[cDim] > m_ptrMBR[greatestLower]->m_pLow[cDim]) greatestLower = u32Child;
+ if (m_ptrMBR[u32Child]->m_pHigh[cDim] < m_ptrMBR[leastUpper]->m_pHigh[cDim]) leastUpper = u32Child;
+
+ leastLower = std::min(m_ptrMBR[u32Child]->m_pLow[cDim], leastLower);
+ greatestUpper = std::max(m_ptrMBR[u32Child]->m_pHigh[cDim], greatestUpper);
+ }
+
+ width = greatestUpper - leastLower;
+ if (width <= 0) width = 1;
+
+ double f = (m_ptrMBR[greatestLower]->m_pLow[cDim] - m_ptrMBR[leastUpper]->m_pHigh[cDim]) / width;
+
+ if (f > separation)
+ {
+ index1 = leastUpper;
+ index2 = greatestLower;
+ separation = f;
+ }
+ } // for (cDim)
+
+ if (index1 == index2)
+ {
+ if (index2 == 0) ++index2;
+ else --index2;
+ }
+
+ break;
+ case RV_QUADRATIC:
+ // for each pair of Regions (account for overflow Region too!)
+ for (u32Child = 0; u32Child < m_capacity; ++u32Child)
+ {
+ double a = m_ptrMBR[u32Child]->getArea();
+
+ for (cIndex = u32Child + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ // get the combined MBR of those two entries.
+ Region r;
+ m_ptrMBR[u32Child]->getCombinedRegion(r, *(m_ptrMBR[cIndex]));
+
+ // find the inefficiency of grouping these entries together.
+ double d = r.getArea() - a - m_ptrMBR[cIndex]->getArea();
+
+ if (d > inefficiency)
+ {
+ inefficiency = d;
+ index1 = u32Child;
+ index2 = cIndex;
+ }
+ } // for (cIndex)
+ } // for (u32Child)
+
+ break;
+ default:
+ throw Tools::NotSupportedException("Node::pickSeeds: Tree variant not supported.");
+ }
+}
+
+void Node::condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis)
+{
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ if (pathBuffer.empty())
+ {
+ // eliminate root if it has only one child.
+ if (m_level != 0 && m_children == 1)
+ {
+ NodePtr ptrN = m_pTree->readNode(m_pIdentifier[0]);
+ m_pTree->deleteNode(ptrN.get());
+ ptrN->m_identifier = m_pTree->m_rootID;
+ m_pTree->writeNode(ptrN.get());
+
+ m_pTree->m_stats.m_nodesInLevel.pop_back();
+ m_pTree->m_stats.m_u32TreeHeight -= 1;
+ // HACK: pending deleteNode for deleted child will decrease nodesInLevel, later on.
+ m_pTree->m_stats.m_nodesInLevel[m_pTree->m_stats.m_u32TreeHeight - 1] = 2;
+ }
+ }
+ else
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrParent = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrParent.get());
+
+ // find the entry in the parent, that points to this node.
+ uint32_t child;
+
+ for (child = 0; child != p->m_children; ++child)
+ {
+ if (p->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ if (m_children < minimumLoad)
+ {
+ // used space less than the minimum
+ // 1. eliminate node entry from the parent. deleteEntry will fix the parent's MBR.
+ p->deleteEntry(child);
+ // 2. add this node to the stack in order to reinsert its entries.
+ toReinsert.push(ptrThis);
+ }
+ else
+ {
+ // adjust the entry in 'p' to contain the new bounding region of this node.
+ *(p->m_ptrMBR[child]) = m_nodeMBR;
+
+ // global recalculation necessary since the MBR can only shrink in size,
+ // due to data removal.
+ if (m_pTree->m_bTightMBRs)
+ {
+ for (uint32_t cDim = 0; cDim < p->m_nodeMBR.m_dimension; ++cDim)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t u32Child = 0; u32Child < p->m_children; ++u32Child)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::min(p->m_nodeMBR.m_pLow[cDim], p->m_ptrMBR[u32Child]->m_pLow[cDim]);
+ p->m_nodeMBR.m_pHigh[cDim] = std::max(p->m_nodeMBR.m_pHigh[cDim], p->m_ptrMBR[u32Child]->m_pHigh[cDim]);
+ }
+ }
+ }
+ }
+
+ // write parent node back to storage.
+ m_pTree->writeNode(p);
+
+ p->condenseTree(toReinsert, pathBuffer, ptrParent);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.h.svn-base
new file mode 100644
index 000000000..89e55945d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Node.h.svn-base
@@ -0,0 +1,188 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class RTree;
+ class Leaf;
+ class Index;
+ class Node;
+
+ typedef Tools::PoolPointer<Node> NodePtr;
+
+ class Node : public SpatialIndex::INode
+ {
+ public:
+ virtual ~Node();
+
+ //
+ // Tools::IObject interface
+ //
+ virtual Tools::IObject* clone();
+
+ //
+ // Tools::ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // SpatialIndex::IEntry interface
+ //
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+
+ //
+ // SpatialIndex::INode interface
+ //
+ virtual uint32_t getChildrenCount() const;
+ virtual id_type getChildIdentifier(uint32_t index) const;
+ virtual void getChildShape(uint32_t index, IShape** out) const;
+ virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
+ virtual uint32_t getLevel() const;
+ virtual bool isIndex() const;
+ virtual bool isLeaf() const;
+
+ private:
+ Node();
+ Node(RTree* pTree, id_type id, uint32_t level, uint32_t capacity);
+
+ virtual Node& operator=(const Node&);
+
+ virtual void insertEntry(uint32_t dataLength, byte* pData, Region& mbr, id_type id);
+ virtual void deleteEntry(uint32_t index);
+
+ virtual bool insertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable);
+ virtual void reinsertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep);
+
+ virtual void rtreeSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
+ virtual void rstarSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
+
+ virtual void pickSeeds(uint32_t& index1, uint32_t& index2);
+
+ virtual void condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis);
+
+ virtual NodePtr chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
+
+ virtual void split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& left, NodePtr& right) = 0;
+
+ RTree* m_pTree;
+ // Parent of all nodes.
+
+ uint32_t m_level;
+ // The level of the node in the tree.
+ // Leaves are always at level 0.
+
+ id_type m_identifier;
+ // The unique ID of this node.
+
+ uint32_t m_children;
+ // The number of children pointed by this node.
+
+ uint32_t m_capacity;
+ // Specifies the node capacity.
+
+ Region m_nodeMBR;
+ // The minimum bounding region enclosing all data contained in the node.
+
+ byte** m_pData;
+ // The data stored in the node.
+
+ RegionPtr* m_ptrMBR;
+ // The corresponding data MBRs.
+
+ id_type* m_pIdentifier;
+ // The corresponding data identifiers.
+
+ uint32_t* m_pDataLength;
+
+ uint32_t m_totalDataLength;
+
+ class RstarSplitEntry
+ {
+ public:
+ Region* m_pRegion;
+ uint32_t m_index;
+ uint32_t m_sortDim;
+
+ RstarSplitEntry(Region* pr, uint32_t index, uint32_t dimension) :
+ m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
+
+ static int compareLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ assert(pe1->m_sortDim == pe2->m_sortDim);
+
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ assert(pe1->m_sortDim == pe2->m_sortDim);
+
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+ }; // RstarSplitEntry
+
+ class ReinsertEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_dist;
+
+ ReinsertEntry(uint32_t index, double dist) : m_index(index), m_dist(dist) {}
+
+ static int compareReinsertEntry(const void* pv1, const void* pv2)
+ {
+ ReinsertEntry* pe1 = * (ReinsertEntry**) pv1;
+ ReinsertEntry* pe2 = * (ReinsertEntry**) pv2;
+
+ if (pe1->m_dist < pe2->m_dist) return -1;
+ if (pe1->m_dist > pe2->m_dist) return 1;
+ return 0;
+ }
+ }; // ReinsertEntry
+
+ // Needed to access protected members without having to cast from Node.
+ // It is more efficient than using member functions to access protected members.
+ friend class RTree;
+ friend class Leaf;
+ friend class Index;
+ friend class Tools::PointerPool<Node>;
+ friend class BulkLoader;
+ }; // Node
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/PointerPoolNode.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/PointerPoolNode.h.svn-base
new file mode 100644
index 000000000..e6977a0c9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/PointerPoolNode.h.svn-base
@@ -0,0 +1,138 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#ifndef __spatialindex_rtree_pointer_pool_node_h
+#define __spatialindex_rtree_pointer_pool_node_h
+
+#include "Node.h"
+
+namespace Tools
+{
+ template<> class PointerPool<RTree::Node>
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ RTree::Node* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<RTree::Node> acquire()
+ {
+ if (! m_pool.empty())
+ {
+ RTree::Node* p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ ++m_hits;
+ #endif
+
+ return PoolPointer<RTree::Node>(p, this);
+ }
+ #ifndef NDEBUG
+ else
+ {
+ // fixme: well sort of...
+ ++m_pointerCount;
+ ++m_misses;
+ }
+ #endif
+
+ return PoolPointer<RTree::Node>();
+ }
+
+ void release(RTree::Node* p)
+ {
+ if (p != 0)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ if (p->m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ // there is no need to set the pointer to zero, after deleting it,
+ // since it will be redeleted only if it is actually initialized again,
+ // a fact that will be depicted by variable m_children.
+ if (p->m_pData[cChild] != 0) delete[] p->m_pData[cChild];
+ }
+ }
+
+ p->m_level = 0;
+ p->m_identifier = -1;
+ p->m_children = 0;
+ p->m_totalDataLength = 0;
+
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ protected:
+ uint32_t m_capacity;
+ std::stack<RTree::Node*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
+#endif /* __spatialindex_rtree_pointer_pool_node_h */
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.cc.svn-base
new file mode 100644
index 000000000..dd5f23c45
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.cc.svn-base
@@ -0,0 +1,1551 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "BulkLoader.h"
+#include "RTree.h"
+
+using namespace SpatialIndex::RTree;
+
+SpatialIndex::RTree::Data::Data(uint32_t len, byte* pData, Region& r, id_type id)
+ : m_id(id), m_region(r), m_pData(0), m_dataLength(len)
+{
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, pData, m_dataLength);
+ }
+}
+
+SpatialIndex::RTree::Data::~Data()
+{
+ delete[] m_pData;
+}
+
+SpatialIndex::RTree::Data* SpatialIndex::RTree::Data::clone()
+{
+ return new Data(m_dataLength, m_pData, m_region, m_id);
+}
+
+id_type SpatialIndex::RTree::Data::getIdentifier() const
+{
+ return m_id;
+}
+
+void SpatialIndex::RTree::Data::getShape(IShape** out) const
+{
+ *out = new Region(m_region);
+}
+
+void SpatialIndex::RTree::Data::getData(uint32_t& len, byte** data) const
+{
+ len = m_dataLength;
+ *data = 0;
+
+ if (m_dataLength > 0)
+ {
+ *data = new byte[m_dataLength];
+ memcpy(*data, m_pData, m_dataLength);
+ }
+}
+
+uint32_t SpatialIndex::RTree::Data::getByteArraySize()
+{
+ return
+ sizeof(id_type) +
+ sizeof(uint32_t) +
+ m_dataLength +
+ m_region.getByteArraySize();
+}
+
+void SpatialIndex::RTree::Data::loadFromByteArray(const byte* ptr)
+{
+ memcpy(&m_id, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ delete[] m_pData;
+ m_pData = 0;
+
+ memcpy(&m_dataLength, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, ptr, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ m_region.loadFromByteArray(ptr);
+}
+
+void SpatialIndex::RTree::Data::storeToByteArray(byte** data, uint32_t& len)
+{
+ // it is thread safe this way.
+ uint32_t regionsize;
+ byte* regiondata = 0;
+ m_region.storeToByteArray(&regiondata, regionsize);
+
+ len = sizeof(id_type) + sizeof(uint32_t) + m_dataLength + regionsize;
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_id, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_dataLength, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ memcpy(ptr, m_pData, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ memcpy(ptr, regiondata, regionsize);
+ delete[] regiondata;
+ // ptr += regionsize;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::returnRTree(SpatialIndex::IStorageManager& sm, Tools::PropertySet& ps)
+{
+ SpatialIndex::ISpatialIndex* si = new SpatialIndex::RTree::RTree(sm, ps);
+ return si;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::createNewRTree(
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ RTreeVariant rv,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = fillFactor;
+ ps.setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = indexCapacity;
+ ps.setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = leafCapacity;
+ ps.setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = dimension;
+ ps.setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = rv;
+ ps.setProperty("TreeVariant", var);
+
+ ISpatialIndex* ret = returnRTree(sm, ps);
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var = ps.getProperty("IndexIdentifier");
+ indexIdentifier = var.m_val.llVal;
+
+ return ret;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ SpatialIndex::RTree::RTreeVariant rv,
+ id_type& indexIdentifier)
+{
+ SpatialIndex::ISpatialIndex* tree = createNewRTree(sm, fillFactor, indexCapacity, leafCapacity, dimension, rv, indexIdentifier);
+
+ uint32_t bindex = static_cast<uint32_t>(std::floor(static_cast<double>(indexCapacity * fillFactor)));
+ uint32_t bleaf = static_cast<uint32_t>(std::floor(static_cast<double>(leafCapacity * fillFactor)));
+
+ SpatialIndex::RTree::BulkLoader bl;
+
+ switch (m)
+ {
+ case BLM_STR:
+ bl.bulkLoadUsingSTR(static_cast<RTree*>(tree), stream, bindex, bleaf, 10000, 100);
+ break;
+ default:
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Unknown bulk load method.");
+ break;
+ }
+
+ return tree;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ SpatialIndex::IStorageManager& sm,
+ Tools::PropertySet& ps,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ RTreeVariant rv;
+ double fillFactor;
+ uint32_t indexCapacity, leafCapacity, dimension, pageSize, numberOfPages;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != RV_LINEAR &&
+ var.m_val.lVal != RV_QUADRATIC &&
+ var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type");
+
+ rv = static_cast<RTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property FillFactor was not of type Tools::VT_DOUBLE");
+
+ if (var.m_val.dblVal <= 0.0)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property FillFactor was less than 0.0");
+
+ if (((rv == RV_LINEAR || rv == RV_QUADRATIC) && var.m_val.dblVal > 0.5))
+ throw Tools::IllegalArgumentException( "createAndBulkLoadNewRTree: Property FillFactor must be in range (0.0, 0.5) for LINEAR or QUADRATIC index types");
+ if ( var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property FillFactor must be in range (0.0, 1.0) for RSTAR index type");
+ fillFactor = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property IndexCapacity must be Tools::VT_ULONG and >= 4");
+
+ indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property LeafCapacity must be Tools::VT_ULONG and >= 4");
+
+ leafCapacity = var.m_val.ulVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property Dimension must be greater than 1");
+
+ dimension = var.m_val.ulVal;
+ }
+
+ // page size
+ var = ps.getProperty("ExternalSortBufferPageSize");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferPageSize must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferPageSize must be greater than 1");
+
+ pageSize = var.m_val.ulVal;
+ }
+
+ // number of pages
+ var = ps.getProperty("ExternalSortBufferTotalPages");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferTotalPages must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferTotalPages must be greater than 1");
+
+ numberOfPages = var.m_val.ulVal;
+ }
+
+ SpatialIndex::ISpatialIndex* tree = createNewRTree(sm, fillFactor, indexCapacity, leafCapacity, dimension, rv, indexIdentifier);
+
+ uint32_t bindex = static_cast<uint32_t>(std::floor(static_cast<double>(indexCapacity * fillFactor)));
+ uint32_t bleaf = static_cast<uint32_t>(std::floor(static_cast<double>(leafCapacity * fillFactor)));
+
+ SpatialIndex::RTree::BulkLoader bl;
+
+ switch (m)
+ {
+ case BLM_STR:
+ bl.bulkLoadUsingSTR(static_cast<RTree*>(tree), stream, bindex, bleaf, pageSize, numberOfPages);
+ break;
+ default:
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Unknown bulk load method.");
+ break;
+ }
+
+ return tree;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::loadRTree(IStorageManager& sm, id_type indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = indexIdentifier;
+ ps.setProperty("IndexIdentifier", var);
+
+ return returnRTree(sm, ps);
+}
+
+SpatialIndex::RTree::RTree::RTree(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_pStorageManager(&sm),
+ m_rootID(StorageManager::NewPage),
+ m_headerID(StorageManager::NewPage),
+ m_treeVariant(RV_RSTAR),
+ m_fillFactor(0.7),
+ m_indexCapacity(100),
+ m_leafCapacity(100),
+ m_nearMinimumOverlapFactor(32),
+ m_splitDistributionFactor(0.4),
+ m_reinsertFactor(0.3),
+ m_dimension(2),
+ m_bTightMBRs(true),
+ m_pointPool(500),
+ m_regionPool(1000),
+ m_indexPool(100),
+ m_leafPool(100)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+
+ Tools::Variant var = ps.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType == Tools::VT_LONGLONG) m_headerID = var.m_val.llVal;
+ else if (var.m_varType == Tools::VT_LONG) m_headerID = var.m_val.lVal;
+ // for backward compatibility only.
+ else throw Tools::IllegalArgumentException("RTree: Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ initOld(ps);
+ }
+ else
+ {
+ initNew(ps);
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = m_headerID;
+ ps.setProperty("IndexIdentifier", var);
+ }
+}
+
+SpatialIndex::RTree::RTree::~RTree()
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_destroy(&m_rwLock);
+#endif
+
+ storeHeader();
+}
+
+//
+// ISpatialIndex interface
+//
+
+void SpatialIndex::RTree::RTree::insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("insertData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ // convert the shape into a Region (R-Trees index regions only; i.e., approximations of the shapes).
+ RegionPtr mbr = m_regionPool.acquire();
+ shape.getMBR(*mbr);
+
+ byte* buffer = 0;
+
+ if (len > 0)
+ {
+ buffer = new byte[len];
+ memcpy(buffer, pData, len);
+ }
+
+ insertData_impl(len, buffer, *mbr, id);
+ // the buffer is stored in the tree. Do not delete here.
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+bool SpatialIndex::RTree::RTree::deleteData(const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("deleteData: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("deleteData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ RegionPtr mbr = m_regionPool.acquire();
+ shape.getMBR(*mbr);
+ bool ret = deleteData_impl(*mbr, id);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ return ret;
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::containsWhatQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("containsWhatQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(ContainmentQuery, query, v);
+}
+
+void SpatialIndex::RTree::RTree::intersectsWithQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("intersectsWithQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(IntersectionQuery, query, v);
+}
+
+void SpatialIndex::RTree::RTree::pointLocationQuery(const Point& query, IVisitor& v)
+{
+ if (query.m_dimension != m_dimension) throw Tools::IllegalArgumentException("pointLocationQuery: Shape has the wrong number of dimensions.");
+ Region r(query, query);
+ rangeQuery(IntersectionQuery, r, v);
+}
+
+void SpatialIndex::RTree::RTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("nearestNeighborQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::priority_queue<NNEntry*, std::vector<NNEntry*>, NNEntry::ascending> queue;
+
+ queue.push(new NNEntry(m_rootID, 0, 0.0));
+
+ uint32_t count = 0;
+ double knearest = 0.0;
+
+ while (! queue.empty())
+ {
+ NNEntry* pFirst = queue.top();
+
+ // report all nearest neighbors with equal greatest distances.
+ // (neighbors can be more than k, if many happen to have the same greatest distance).
+ if (count >= k && pFirst->m_minDist > knearest) break;
+
+ queue.pop();
+
+ if (pFirst->m_pEntry == 0)
+ {
+ // n is a leaf or an index.
+ NodePtr n = readNode(pFirst->m_id);
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (n->m_level == 0)
+ {
+ Data* e = new Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ // we need to compare the query with the actual data entry here, so we call the
+ // appropriate getMinimumDistance method of NearestNeighborComparator.
+ queue.push(new NNEntry(n->m_pIdentifier[cChild], e, nnc.getMinimumDistance(query, *e)));
+ }
+ else
+ {
+ queue.push(new NNEntry(n->m_pIdentifier[cChild], 0, nnc.getMinimumDistance(query, *(n->m_ptrMBR[cChild]))));
+ }
+ }
+ }
+ else
+ {
+ v.visitData(*(static_cast<IData*>(pFirst->m_pEntry)));
+ ++(m_stats.m_u64QueryResults);
+ ++count;
+ knearest = pFirst->m_minDist;
+ delete pFirst->m_pEntry;
+ }
+
+ delete pFirst;
+ }
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+ if (e->m_pEntry != 0) delete e->m_pEntry;
+ delete e;
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+ NNComparator nnc;
+ nearestNeighborQuery(k, query, v, nnc);
+}
+
+
+void SpatialIndex::RTree::RTree::selfJoinQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension)
+ throw Tools::IllegalArgumentException("selfJoinQuery: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("selfJoinQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ RegionPtr mbr = m_regionPool.acquire();
+ query.getMBR(*mbr);
+ selfJoinQuery(m_rootID, m_rootID, *mbr, v);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::queryStrategy(IQueryStrategy& qs)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");
+#endif
+
+ id_type next = m_rootID;
+ bool hasNext = true;
+
+ try
+ {
+ while (hasNext)
+ {
+ NodePtr n = readNode(next);
+ qs.getNextEntry(*n, next, hasNext);
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::getIndexProperties(Tools::PropertySet& out) const
+{
+ Tools::Variant var;
+
+ // dimension
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_dimension;
+ out.setProperty("Dimension", var);
+
+ // index capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexCapacity;
+ out.setProperty("IndexCapacity", var);
+
+ // leaf capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafCapacity;
+ out.setProperty("LeafCapacity", var);
+
+ // R-tree variant
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = m_treeVariant;
+ out.setProperty("TreeVariant", var);
+
+ // fill factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_fillFactor;
+ out.setProperty("FillFactor", var);
+
+ // near minimum overlap factor
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_nearMinimumOverlapFactor;
+ out.setProperty("NearMinimumOverlapFactor", var);
+
+ // split distribution factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_splitDistributionFactor;
+ out.setProperty("SplitDistributionFactor", var);
+
+ // reinsert factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_reinsertFactor;
+ out.setProperty("ReinsertFactor", var);
+
+ // tight MBRs
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = m_bTightMBRs;
+ out.setProperty("EnsureTightMBRs", var);
+
+ // index pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexPool.getCapacity();
+ out.setProperty("IndexPoolCapacity", var);
+
+ // leaf pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafPool.getCapacity();
+ out.setProperty("LeafPoolCapacity", var);
+
+ // region pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_regionPool.getCapacity();
+ out.setProperty("RegionPoolCapacity", var);
+
+ // point pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_pointPool.getCapacity();
+ out.setProperty("PointPoolCapacity", var);
+}
+
+void SpatialIndex::RTree::RTree::addCommand(ICommand* pCommand, CommandType ct)
+{
+ switch (ct)
+ {
+ case CT_NODEREAD:
+ m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEWRITE:
+ m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEDELETE:
+ m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ }
+}
+
+bool SpatialIndex::RTree::RTree::isIndexValid()
+{
+ bool ret = true;
+ std::stack<ValidateEntry> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_level != m_stats.m_u32TreeHeight - 1)
+ {
+ std::cerr << "Invalid tree height." << std::endl;
+ return false;
+ }
+
+ std::map<uint32_t, uint32_t> nodesInLevel;
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(root->m_level, 1));
+
+ ValidateEntry e(root->m_nodeMBR, root);
+ st.push(e);
+
+ while (! st.empty())
+ {
+ e = st.top(); st.pop();
+
+ Region tmpRegion;
+ tmpRegion = m_infiniteRegion;
+
+ for (uint32_t cDim = 0; cDim < tmpRegion.m_dimension; ++cDim)
+ {
+ tmpRegion.m_pLow[cDim] = std::numeric_limits<double>::max();
+ tmpRegion.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]);
+ tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+
+ if (! (tmpRegion == e.m_pNode->m_nodeMBR))
+ {
+ std::cerr << "Invalid parent information." << std::endl;
+ ret = false;
+ }
+ else if (! (tmpRegion == e.m_parentMBR))
+ {
+ std::cerr << "Error in parent." << std::endl;
+ ret = false;
+ }
+
+ if (e.m_pNode->m_level != 0)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
+ ValidateEntry tmpEntry(*(e.m_pNode->m_ptrMBR[cChild]), ptrN);
+
+ std::map<uint32_t, uint32_t>::iterator itNodes = nodesInLevel.find(tmpEntry.m_pNode->m_level);
+
+ if (itNodes == nodesInLevel.end())
+ {
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(tmpEntry.m_pNode->m_level, 1l));
+ }
+ else
+ {
+ nodesInLevel[tmpEntry.m_pNode->m_level] = nodesInLevel[tmpEntry.m_pNode->m_level] + 1;
+ }
+
+ st.push(tmpEntry);
+ }
+ }
+ }
+
+ uint32_t nodes = 0;
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_u32TreeHeight; ++cLevel)
+ {
+ if (nodesInLevel[cLevel] != m_stats.m_nodesInLevel[cLevel])
+ {
+ std::cerr << "Invalid nodesInLevel information." << std::endl;
+ ret = false;
+ }
+
+ nodes += m_stats.m_nodesInLevel[cLevel];
+ }
+
+ if (nodes != m_stats.m_u32Nodes)
+ {
+ std::cerr << "Invalid number of nodes information." << std::endl;
+ ret = false;
+ }
+
+ return ret;
+}
+
+void SpatialIndex::RTree::RTree::getStatistics(IStatistics** out) const
+{
+ *out = new Statistics(m_stats);
+}
+
+void SpatialIndex::RTree::RTree::initNew(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != RV_LINEAR &&
+ var.m_val.lVal != RV_QUADRATIC &&
+ var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type");
+
+ m_treeVariant = static_cast<RTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor was not of type Tools::VT_DOUBLE");
+
+ if (var.m_val.dblVal <= 0.0)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor was less than 0.0");
+
+ if (((m_treeVariant == RV_LINEAR || m_treeVariant == RV_QUADRATIC) && var.m_val.dblVal > 0.5))
+ throw Tools::IllegalArgumentException( "initNew: Property FillFactor must be in range "
+ "(0.0, 0.5) for LINEAR or QUADRATIC index types");
+ if ( var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException( "initNew: Property FillFactor must be in range "
+ "(0.0, 1.0) for RSTAR index type");
+ m_fillFactor = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_leafCapacity = var.m_val.ulVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1");
+
+ m_dimension = var.m_val.ulVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL)
+ throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+
+ m_stats.m_u32TreeHeight = 1;
+ m_stats.m_nodesInLevel.push_back(0);
+
+ Leaf root(this, -1);
+ m_rootID = writeNode(&root);
+
+ storeHeader();
+}
+
+void SpatialIndex::RTree::RTree::initOld(Tools::PropertySet& ps)
+{
+ loadHeader();
+
+ // only some of the properties may be changed.
+ // the rest are just ignored.
+
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != RV_LINEAR &&
+ var.m_val.lVal != RV_QUADRATIC &&
+ var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type");
+
+ m_treeVariant = static_cast<RTreeVariant>(var.m_val.lVal);
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+}
+
+void SpatialIndex::RTree::RTree::storeHeader()
+{
+ const uint32_t headerSize =
+ sizeof(id_type) + // m_rootID
+ sizeof(RTreeVariant) + // m_treeVariant
+ sizeof(double) + // m_fillFactor
+ sizeof(uint32_t) + // m_indexCapacity
+ sizeof(uint32_t) + // m_leafCapacity
+ sizeof(uint32_t) + // m_nearMinimumOverlapFactor
+ sizeof(double) + // m_splitDistributionFactor
+ sizeof(double) + // m_reinsertFactor
+ sizeof(uint32_t) + // m_dimension
+ sizeof(char) + // m_bTightMBRs
+ sizeof(uint32_t) + // m_stats.m_nodes
+ sizeof(uint64_t) + // m_stats.m_data
+ sizeof(uint32_t) + // m_stats.m_treeHeight
+ m_stats.m_u32TreeHeight * sizeof(uint32_t); // m_stats.m_nodesInLevel
+
+ byte* header = new byte[headerSize];
+ byte* ptr = header;
+
+ memcpy(ptr, &m_rootID, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_treeVariant, sizeof(RTreeVariant));
+ ptr += sizeof(RTreeVariant);
+ memcpy(ptr, &m_fillFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_indexCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_leafCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_splitDistributionFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_reinsertFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c = (char) m_bTightMBRs;
+ memcpy(ptr, &c, sizeof(char));
+ ptr += sizeof(char);
+ memcpy(ptr, &(m_stats.m_u32Nodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u64Data), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(ptr, &(m_stats.m_u32TreeHeight), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_u32TreeHeight; ++cLevel)
+ {
+ memcpy(ptr, &(m_stats.m_nodesInLevel[cLevel]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
+
+ delete[] header;
+}
+
+void SpatialIndex::RTree::RTree::loadHeader()
+{
+ uint32_t headerSize;
+ byte* header = 0;
+ m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
+
+ byte* ptr = header;
+
+ memcpy(&m_rootID, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&m_treeVariant, ptr, sizeof(RTreeVariant));
+ ptr += sizeof(RTreeVariant);
+ memcpy(&m_fillFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_indexCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_leafCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_splitDistributionFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_reinsertFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c;
+ memcpy(&c, ptr, sizeof(char));
+ m_bTightMBRs = (c != 0);
+ ptr += sizeof(char);
+ memcpy(&(m_stats.m_u32Nodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u64Data), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(&(m_stats.m_u32TreeHeight), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_u32TreeHeight; ++cLevel)
+ {
+ uint32_t cNodes;
+ memcpy(&cNodes, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ m_stats.m_nodesInLevel.push_back(cNodes);
+ }
+
+ delete[] header;
+}
+
+void SpatialIndex::RTree::RTree::insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id)
+{
+ assert(mbr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ byte* overflowTable = 0;
+
+ try
+ {
+ NodePtr root = readNode(m_rootID);
+
+ overflowTable = new byte[root->m_level];
+ bzero(overflowTable, root->m_level);
+
+ NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mbr, id, pathBuffer, overflowTable);
+
+ delete[] overflowTable;
+ ++(m_stats.m_u64Data);
+ }
+ catch (...)
+ {
+ delete[] overflowTable;
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id, uint32_t level, byte* overflowTable)
+{
+ assert(mbr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_rootID);
+ NodePtr n = root->chooseSubtree(mbr, level, pathBuffer);
+
+ assert(n->m_level == level);
+
+ if (n.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ n->insertData(dataLength, pData, mbr, id, pathBuffer, overflowTable);
+}
+
+bool SpatialIndex::RTree::RTree::deleteData_impl(const Region& mbr, id_type id)
+{
+ assert(mbr.m_dimension == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_rootID);
+ NodePtr l = root->findLeaf(mbr, id, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+
+ if (l.get() != 0)
+ {
+ Leaf* pL = static_cast<Leaf*>(l.get());
+ pL->deleteData(id, pathBuffer);
+ --(m_stats.m_u64Data);
+ return true;
+ }
+
+ return false;
+}
+
+SpatialIndex::id_type SpatialIndex::RTree::RTree::writeNode(Node* n)
+{
+ byte* buffer;
+ uint32_t dataLength;
+ n->storeToByteArray(&buffer, dataLength);
+
+ id_type page;
+ if (n->m_identifier < 0) page = StorageManager::NewPage;
+ else page = n->m_identifier;
+
+ try
+ {
+ m_pStorageManager->storeByteArray(page, dataLength, buffer);
+ delete[] buffer;
+ }
+ catch (InvalidPageException& e)
+ {
+ delete[] buffer;
+ std::cerr << e.what() << std::endl;
+ throw;
+ }
+
+ if (n->m_identifier < 0)
+ {
+ n->m_identifier = page;
+ ++(m_stats.m_u32Nodes);
+
+#ifndef NDEBUG
+ try
+ {
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel.at(n->m_level) + 1;
+ }
+ catch(...)
+ {
+ throw Tools::IllegalStateException("writeNode: writing past the end of m_nodesInLevel.");
+ }
+#else
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] + 1;
+#endif
+ }
+
+ ++(m_stats.m_u64Writes);
+
+ for (size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
+ {
+ m_writeNodeCommands[cIndex]->execute(*n);
+ }
+
+ return page;
+}
+
+SpatialIndex::RTree::NodePtr SpatialIndex::RTree::RTree::readNode(id_type page)
+{
+ uint32_t dataLength;
+ byte* buffer;
+
+ try
+ {
+ m_pStorageManager->loadByteArray(page, dataLength, &buffer);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ throw;
+ }
+
+ try
+ {
+ uint32_t nodeType;
+ memcpy(&nodeType, buffer, sizeof(uint32_t));
+
+ NodePtr n;
+
+ if (nodeType == PersistentIndex) n = m_indexPool.acquire();
+ else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();
+ else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");
+
+ if (n.get() == 0)
+ {
+ if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);
+ else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);
+ }
+
+ //n->m_pTree = this;
+ n->m_identifier = page;
+ n->loadFromByteArray(buffer);
+
+ ++(m_stats.m_u64Reads);
+
+ for (size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
+ {
+ m_readNodeCommands[cIndex]->execute(*n);
+ }
+
+ delete[] buffer;
+ return n;
+ }
+ catch (...)
+ {
+ delete[] buffer;
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::deleteNode(Node* n)
+{
+ try
+ {
+ m_pStorageManager->deleteByteArray(n->m_identifier);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ throw;
+ }
+
+ --(m_stats.m_u32Nodes);
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] - 1;
+
+ for (size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
+ {
+ m_deleteNodeCommands[cIndex]->execute(*n);
+ }
+}
+
+void SpatialIndex::RTree::RTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::stack<NodePtr> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_children > 0 && query.intersectsShape(root->m_nodeMBR)) st.push(root);
+
+ while (! st.empty())
+ {
+ NodePtr n = st.top(); st.pop();
+
+ if (n->m_level == 0)
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ bool b;
+ if (type == ContainmentQuery) b = query.containsShape(*(n->m_ptrMBR[cChild]));
+ else b = query.intersectsShape(*(n->m_ptrMBR[cChild]));
+
+ if (b)
+ {
+ Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ v.visitData(data);
+ ++(m_stats.m_u64QueryResults);
+ }
+ }
+ }
+ else
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (query.intersectsShape(*(n->m_ptrMBR[cChild]))) st.push(readNode(n->m_pIdentifier[cChild]));
+ }
+ }
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::selfJoinQuery(id_type id1, id_type id2, const Region& r, IVisitor& vis)
+{
+ NodePtr n1 = readNode(id1);
+ NodePtr n2 = readNode(id2);
+ vis.visitNode(*n1);
+ vis.visitNode(*n2);
+
+ for (uint32_t cChild1 = 0; cChild1 < n1->m_children; ++cChild1)
+ {
+ if (r.intersectsRegion(*(n1->m_ptrMBR[cChild1])))
+ {
+ for (uint32_t cChild2 = 0; cChild2 < n2->m_children; ++cChild2)
+ {
+ if (
+ r.intersectsRegion(*(n2->m_ptrMBR[cChild2])) &&
+ n1->m_ptrMBR[cChild1]->intersectsRegion(*(n2->m_ptrMBR[cChild2])))
+ {
+ if (n1->m_level == 0)
+ {
+ if (n1->m_pIdentifier[cChild1] != n2->m_pIdentifier[cChild2])
+ {
+ assert(n2->m_level == 0);
+
+ std::vector<const IData*> v;
+ Data e1(n1->m_pDataLength[cChild1], n1->m_pData[cChild1], *(n1->m_ptrMBR[cChild1]), n1->m_pIdentifier[cChild1]);
+ Data e2(n2->m_pDataLength[cChild2], n2->m_pData[cChild2], *(n2->m_ptrMBR[cChild2]), n2->m_pIdentifier[cChild2]);
+ v.push_back(&e1);
+ v.push_back(&e2);
+ vis.visitData(v);
+ }
+ }
+ else
+ {
+ Region rr = r.getIntersectingRegion(n1->m_ptrMBR[cChild1]->getIntersectingRegion(*(n2->m_ptrMBR[cChild2])));
+ selfJoinQuery(n1->m_pIdentifier[cChild1], n2->m_pIdentifier[cChild2], rr, vis);
+ }
+ }
+ }
+ }
+ }
+}
+
+std::ostream& SpatialIndex::RTree::operator<<(std::ostream& os, const RTree& t)
+{
+ os << "Dimension: " << t.m_dimension << std::endl
+ << "Fill factor: " << t.m_fillFactor << std::endl
+ << "Index capacity: " << t.m_indexCapacity << std::endl
+ << "Leaf capacity: " << t.m_leafCapacity << std::endl
+ << "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << std::endl;
+
+ if (t.m_treeVariant == RV_RSTAR)
+ {
+ os << "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
+ << "Reinsert factor: " << t.m_reinsertFactor << std::endl
+ << "Split distribution factor: " << t.m_splitDistributionFactor << std::endl;
+ }
+
+ if (t.m_stats.getNumberOfNodesInLevel(0) > 0)
+ os << "Utilization: " << 100 * t.m_stats.getNumberOfData() / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << std::endl
+ << t.m_stats;
+
+ #ifndef NDEBUG
+ os << "Leaf pool hits: " << t.m_leafPool.m_hits << std::endl
+ << "Leaf pool misses: " << t.m_leafPool.m_misses << std::endl
+ << "Index pool hits: " << t.m_indexPool.m_hits << std::endl
+ << "Index pool misses: " << t.m_indexPool.m_misses << std::endl
+ << "Region pool hits: " << t.m_regionPool.m_hits << std::endl
+ << "Region pool misses: " << t.m_regionPool.m_misses << std::endl
+ << "Point pool hits: " << t.m_pointPool.m_hits << std::endl
+ << "Point pool misses: " << t.m_pointPool.m_misses << std::endl;
+ #endif
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.h.svn-base
new file mode 100644
index 000000000..cb4e00452
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/RTree.h.svn-base
@@ -0,0 +1,201 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Statistics.h"
+#include "Node.h"
+#include "PointerPoolNode.h"
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class RTree : public ISpatialIndex
+ {
+ //class NNEntry;
+
+ public:
+ RTree(IStorageManager&, Tools::PropertySet&);
+ // String Value Description
+ // ----------------------------------------------
+ // IndexIndentifier VT_LONG If specified an existing index will be openened from the supplied
+ // storage manager with the given index id. Behaviour is unspecified
+ // if the index id or the storage manager are incorrect.
+ // Dimension VT_ULONG Dimensionality of the data that will be inserted.
+ // IndexCapacity VT_ULONG The index node capacity. Default is 100.
+ // LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+ // FillFactor VT_DOUBLE The fill factor. Default is 70%
+ // TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+ // NearMinimumOverlapFactor VT_ULONG Default is 32.
+ // SplitDistributionFactor VT_DOUBLE Default is 0.4
+ // ReinsertFactor VT_DOUBLE Default is 0.3
+ // EnsureTightMBRs VT_BOOL Default is true
+ // IndexPoolCapacity VT_LONG Default is 100
+ // LeafPoolCapacity VT_LONG Default is 100
+ // RegionPoolCapacity VT_LONG Default is 1000
+ // PointPoolCapacity VT_LONG Default is 500
+
+ virtual ~RTree();
+
+
+
+ //
+ // ISpatialIndex interface
+ //
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier);
+ virtual bool deleteData(const IShape& shape, id_type id);
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v);
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v);
+ virtual void pointLocationQuery(const Point& query, IVisitor& v);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator&);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v);
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v);
+ virtual void queryStrategy(IQueryStrategy& qs);
+ virtual void getIndexProperties(Tools::PropertySet& out) const;
+ virtual void addCommand(ICommand* pCommand, CommandType ct);
+ virtual bool isIndexValid();
+ virtual void getStatistics(IStatistics** out) const;
+
+ private:
+ void initNew(Tools::PropertySet&);
+ void initOld(Tools::PropertySet& ps);
+ void storeHeader();
+ void loadHeader();
+
+ void insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id);
+ void insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id, uint32_t level, byte* overflowTable);
+ bool deleteData_impl(const Region& mbr, id_type id);
+
+ id_type writeNode(Node*);
+ NodePtr readNode(id_type page);
+ void deleteNode(Node*);
+
+ void rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v);
+ void selfJoinQuery(id_type id1, id_type id2, const Region& r, IVisitor& vis);
+
+ IStorageManager* m_pStorageManager;
+
+ id_type m_rootID, m_headerID;
+
+ RTreeVariant m_treeVariant;
+
+ double m_fillFactor;
+
+ uint32_t m_indexCapacity;
+
+ uint32_t m_leafCapacity;
+
+ uint32_t m_nearMinimumOverlapFactor;
+ // The R*-Tree 'p' constant, for calculating nearly minimum overlap cost.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.1]
+
+ double m_splitDistributionFactor;
+ // The R*-Tree 'm' constant, for calculating spliting distributions.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.2]
+
+ double m_reinsertFactor;
+ // The R*-Tree 'p' constant, for removing entries at reinserts.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.3]
+
+ uint32_t m_dimension;
+
+ Region m_infiniteRegion;
+
+ Statistics m_stats;
+
+ bool m_bTightMBRs;
+
+ Tools::PointerPool<Point> m_pointPool;
+ Tools::PointerPool<Region> m_regionPool;
+ Tools::PointerPool<Node> m_indexPool;
+ Tools::PointerPool<Node> m_leafPool;
+
+ std::vector<Tools::SmartPointer<ICommand> > m_writeNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_readNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_deleteNodeCommands;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+
+
+
+
+ class NNEntry
+ {
+ public:
+ id_type m_id;
+ IEntry* m_pEntry;
+ double m_minDist;
+
+ NNEntry(id_type id, IEntry* e, double f) : m_id(id), m_pEntry(e), m_minDist(f) {}
+ ~NNEntry() {}
+
+ struct ascending : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_minDist > __y->m_minDist; }
+ };
+ }; // NNEntry
+
+ class NNComparator : public INearestNeighborComparator
+ {
+ public:
+ double getMinimumDistance(const IShape& query, const IShape& entry)
+ {
+ return query.getMinimumDistance(entry);
+ }
+
+ double getMinimumDistance(const IShape& query, const IData& data)
+ {
+ IShape* pS;
+ data.getShape(&pS);
+ double ret = query.getMinimumDistance(*pS);
+ delete pS;
+ return ret;
+ }
+ }; // NNComparator
+
+ class ValidateEntry
+ {
+ public:
+ ValidateEntry(Region& r, NodePtr& pNode) : m_parentMBR(r), m_pNode(pNode) {}
+
+ Region m_parentMBR;
+ NodePtr m_pNode;
+ }; // ValidateEntry
+
+ friend class Node;
+ friend class Leaf;
+ friend class Index;
+ friend class BulkLoader;
+
+ friend std::ostream& operator<<(std::ostream& os, const RTree& t);
+ }; // RTree
+
+ std::ostream& operator<<(std::ostream& os, const RTree& t);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.cc.svn-base
new file mode 100644
index 000000000..d79e5097d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.cc.svn-base
@@ -0,0 +1,172 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+
+#include "Statistics.h"
+
+using namespace SpatialIndex::RTree;
+
+Statistics::Statistics()
+{
+ reset();
+}
+
+Statistics::Statistics(const Statistics& s)
+{
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u32TreeHeight = s.m_u32TreeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+}
+
+Statistics::~Statistics()
+{
+}
+
+Statistics& Statistics::operator=(const Statistics& s)
+{
+ if (this != &s)
+ {
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u32TreeHeight = s.m_u32TreeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+ }
+
+ return *this;
+}
+
+uint64_t Statistics::getReads() const
+{
+ return m_u64Reads;
+}
+
+uint64_t Statistics::getWrites() const
+{
+ return m_u64Writes;
+}
+
+uint32_t Statistics::getNumberOfNodes() const
+{
+ return m_u32Nodes;
+}
+
+uint64_t Statistics::getNumberOfData() const
+{
+ return m_u64Data;
+}
+
+uint64_t Statistics::getSplits() const
+{
+ return m_u64Splits;
+}
+
+uint64_t Statistics::getHits() const
+{
+ return m_u64Hits;
+}
+
+uint64_t Statistics::getMisses() const
+{
+ return m_u64Misses;
+}
+
+uint64_t Statistics::getAdjustments() const
+{
+ return m_u64Adjustments;
+}
+
+uint64_t Statistics::getQueryResults() const
+{
+ return m_u64QueryResults;
+}
+
+uint32_t Statistics::getTreeHeight() const
+{
+ return m_u32TreeHeight;
+}
+
+uint32_t Statistics::getNumberOfNodesInLevel(uint32_t l) const
+{
+ uint32_t u32Nodes;
+ try
+ {
+ u32Nodes = m_nodesInLevel.at(l);
+ }
+ catch (...)
+ {
+ throw Tools::IndexOutOfBoundsException(l);
+ }
+
+ return u32Nodes;
+}
+
+void Statistics::reset()
+{
+ m_u64Reads = 0;
+ m_u64Writes = 0;
+ m_u64Splits = 0;
+ m_u64Hits = 0;
+ m_u64Misses = 0;
+ m_u32Nodes = 0;
+ m_u64Adjustments = 0;
+ m_u64QueryResults = 0;
+ m_u64Data = 0;
+ m_u32TreeHeight = 0;
+ m_nodesInLevel.clear();
+}
+
+std::ostream& SpatialIndex::RTree::operator<<(std::ostream& os, const Statistics& s)
+{
+ os << "Reads: " << s.m_u64Reads << std::endl
+ << "Writes: " << s.m_u64Writes << std::endl
+ << "Hits: " << s.m_u64Hits << std::endl
+ << "Misses: " << s.m_u64Misses << std::endl
+ << "Tree height: " << s.m_u32TreeHeight << std::endl
+ << "Number of data: " << s.m_u64Data << std::endl
+ << "Number of nodes: " << s.m_u32Nodes << std::endl;
+
+ for (uint32_t u32Level = 0; u32Level < s.m_u32TreeHeight; ++u32Level)
+ {
+ os << "Level " << u32Level << " pages: " << s.m_nodesInLevel[u32Level] << std::endl;
+ }
+
+ os << "Splits: " << s.m_u64Splits << std::endl
+ << "Adjustments: " << s.m_u64Adjustments << std::endl
+ << "Query results: " << s.m_u64QueryResults << std::endl;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.h.svn-base
new file mode 100644
index 000000000..389726d88
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/.svn/text-base/Statistics.h.svn-base
@@ -0,0 +1,93 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class RTree;
+ class Node;
+ class Leaf;
+ class Index;
+
+ class Statistics : public SpatialIndex::IStatistics
+ {
+ public:
+ Statistics();
+ Statistics(const Statistics&);
+ virtual ~Statistics();
+ Statistics& operator=(const Statistics&);
+
+ //
+ // IStatistics interface
+ //
+ virtual uint64_t getReads() const;
+ virtual uint64_t getWrites() const;
+ virtual uint32_t getNumberOfNodes() const;
+ virtual uint64_t getNumberOfData() const;
+
+ virtual uint64_t getSplits() const;
+ virtual uint64_t getHits() const;
+ virtual uint64_t getMisses() const;
+ virtual uint64_t getAdjustments() const;
+ virtual uint64_t getQueryResults() const;
+ virtual uint32_t getTreeHeight() const;
+ virtual uint32_t getNumberOfNodesInLevel(uint32_t l) const;
+
+ private:
+ void reset();
+
+ uint64_t m_u64Reads;
+
+ uint64_t m_u64Writes;
+
+ uint64_t m_u64Splits;
+
+ uint64_t m_u64Hits;
+
+ uint64_t m_u64Misses;
+
+ uint32_t m_u32Nodes;
+
+ uint64_t m_u64Adjustments;
+
+ uint64_t m_u64QueryResults;
+
+ uint64_t m_u64Data;
+
+ uint32_t m_u32TreeHeight;
+
+ std::vector<uint32_t> m_nodesInLevel;
+
+ friend class RTree;
+ friend class Node;
+ friend class Index;
+ friend class Leaf;
+ friend class BulkLoader;
+
+ friend std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }; // Statistics
+
+ std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.cc b/sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.cc
new file mode 100644
index 000000000..5fb14963d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.cc
@@ -0,0 +1,458 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <stdio.h>
+#include <cmath>
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "BulkLoader.h"
+
+using namespace SpatialIndex::RTree;
+
+//
+// ExternalSorter::Record
+//
+ExternalSorter::Record::Record()
+: m_pData(0)
+{
+}
+
+ExternalSorter::Record::Record(const Region& r, id_type id, uint32_t len, byte* pData, uint32_t s)
+: m_r(r), m_id(id), m_len(len), m_pData(pData), m_s(s)
+{
+}
+
+ExternalSorter::Record::~Record()
+{
+ delete[] m_pData;
+}
+
+bool ExternalSorter::Record::operator<(const Record& r) const
+{
+ if (m_s != r.m_s)
+ throw Tools::IllegalStateException("ExternalSorter::Record::operator<: Incompatible sorting dimensions.");
+
+ if (m_r.m_pHigh[m_s] + m_r.m_pLow[m_s] < r.m_r.m_pHigh[m_s] + r.m_r.m_pLow[m_s])
+ return true;
+ else
+ return false;
+}
+
+void ExternalSorter::Record::storeToFile(Tools::TemporaryFile& f)
+{
+ f.write(static_cast<uint64_t>(m_id));
+ f.write(m_r.m_dimension);
+ f.write(m_s);
+
+ for (uint32_t i = 0; i < m_r.m_dimension; ++i)
+ {
+ f.write(m_r.m_pLow[i]);
+ f.write(m_r.m_pHigh[i]);
+ }
+
+ f.write(m_len);
+ if (m_len > 0) f.write(m_len, m_pData);
+}
+
+void ExternalSorter::Record::loadFromFile(Tools::TemporaryFile& f)
+{
+ m_id = static_cast<id_type>(f.readUInt64());
+ uint32_t dim = f.readUInt32();
+ m_s = f.readUInt32();
+
+ if (dim != m_r.m_dimension)
+ {
+ delete[] m_r.m_pLow;
+ delete[] m_r.m_pHigh;
+ m_r.m_dimension = dim;
+ m_r.m_pLow = new double[dim];
+ m_r.m_pHigh = new double[dim];
+ }
+
+ for (uint32_t i = 0; i < m_r.m_dimension; ++i)
+ {
+ m_r.m_pLow[i] = f.readDouble();
+ m_r.m_pHigh[i] = f.readDouble();
+ }
+
+ m_len = f.readUInt32();
+ delete[] m_pData; m_pData = 0;
+ if (m_len > 0) f.readBytes(m_len, &m_pData);
+}
+
+//
+// ExternalSorter
+//
+ExternalSorter::ExternalSorter(uint32_t u32PageSize, uint32_t u32BufferPages)
+: m_bInsertionPhase(true), m_u32PageSize(u32PageSize),
+ m_u32BufferPages(u32BufferPages), m_u64TotalEntries(0), m_stI(0)
+{
+}
+
+ExternalSorter::~ExternalSorter()
+{
+ for (m_stI = 0; m_stI < m_buffer.size(); ++m_stI) delete m_buffer[m_stI];
+}
+
+void ExternalSorter::insert(Record* r)
+{
+ if (m_bInsertionPhase == false)
+ throw Tools::IllegalStateException("ExternalSorter::insert: Input has already been sorted.");
+
+ m_buffer.push_back(r);
+ ++m_u64TotalEntries;
+
+ // this will create the initial, sorted buckets before the
+ // external merge sort.
+ if (m_buffer.size() >= m_u32PageSize * m_u32BufferPages)
+ {
+ std::sort(m_buffer.begin(), m_buffer.end(), Record::SortAscending());
+ Tools::TemporaryFile* tf = new Tools::TemporaryFile();
+ for (size_t j = 0; j < m_buffer.size(); ++j)
+ {
+ m_buffer[j]->storeToFile(*tf);
+ delete m_buffer[j];
+ }
+ m_buffer.clear();
+ tf->rewindForReading();
+ m_runs.push_back(Tools::SmartPointer<Tools::TemporaryFile>(tf));
+ }
+}
+
+void ExternalSorter::sort()
+{
+ if (m_bInsertionPhase == false)
+ throw Tools::IllegalStateException("ExternalSorter::sort: Input has already been sorted.");
+
+ if (m_runs.empty())
+ {
+ // The data fits in main memory. No need to store to disk.
+ std::sort(m_buffer.begin(), m_buffer.end(), Record::SortAscending());
+ m_bInsertionPhase = false;
+ return;
+ }
+
+ if (m_buffer.size() > 0)
+ {
+ // Whatever remained in the buffer (if not filled) needs to be stored
+ // as the final bucket.
+ std::sort(m_buffer.begin(), m_buffer.end(), Record::SortAscending());
+ Tools::TemporaryFile* tf = new Tools::TemporaryFile();
+ for (size_t j = 0; j < m_buffer.size(); ++j)
+ {
+ m_buffer[j]->storeToFile(*tf);
+ delete m_buffer[j];
+ }
+ m_buffer.clear();
+ tf->rewindForReading();
+ m_runs.push_back(Tools::SmartPointer<Tools::TemporaryFile>(tf));
+ }
+
+ if (m_runs.size() == 1)
+ {
+ m_sortedFile = m_runs.front();
+ }
+ else
+ {
+ Record* r;
+
+ while (m_runs.size() > 1)
+ {
+ Tools::SmartPointer<Tools::TemporaryFile> tf(new Tools::TemporaryFile());
+ std::vector<Tools::SmartPointer<Tools::TemporaryFile> > buckets;
+ std::vector<std::queue<Record*> > buffers;
+ std::priority_queue<PQEntry, std::vector<PQEntry>, PQEntry::SortAscending> pq;
+
+ // initialize buffers and priority queue.
+ std::list<Tools::SmartPointer<Tools::TemporaryFile> >::iterator it = m_runs.begin();
+ for (uint32_t i = 0; i < (std::min)(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages); ++i)
+ {
+ buckets.push_back(*it);
+ buffers.push_back(std::queue<Record*>());
+
+ r = new Record();
+ r->loadFromFile(**it);
+ // a run cannot be empty initially, so this should never fail.
+ pq.push(PQEntry(r, i));
+
+ for (uint32_t j = 0; j < m_u32PageSize - 1; ++j)
+ {
+ // fill the buffer with the rest of the page of records.
+ try
+ {
+ r = new Record();
+ r->loadFromFile(**it);
+ buffers.back().push(r);
+ }
+ catch (Tools::EndOfStreamException)
+ {
+ delete r;
+ break;
+ }
+ }
+ ++it;
+ }
+
+ // exhaust buckets, buffers, and priority queue.
+ while (! pq.empty())
+ {
+ PQEntry e = pq.top(); pq.pop();
+ e.m_r->storeToFile(*tf);
+ delete e.m_r;
+
+ if (! buckets[e.m_u32Index]->eof() && buffers[e.m_u32Index].empty())
+ {
+ for (uint32_t j = 0; j < m_u32PageSize; ++j)
+ {
+ try
+ {
+ r = new Record();
+ r->loadFromFile(*buckets[e.m_u32Index]);
+ buffers[e.m_u32Index].push(r);
+ }
+ catch (Tools::EndOfStreamException)
+ {
+ delete r;
+ break;
+ }
+ }
+ }
+
+ if (! buffers[e.m_u32Index].empty())
+ {
+ e.m_r = buffers[e.m_u32Index].front();
+ buffers[e.m_u32Index].pop();
+ pq.push(e);
+ }
+ }
+
+ tf->rewindForReading();
+
+ // check if another pass is needed.
+ uint32_t u32Count = std::min(static_cast<uint32_t>(m_runs.size()), m_u32BufferPages);
+ for (uint32_t i = 0; i < u32Count; ++i)
+ {
+ m_runs.pop_front();
+ }
+
+ if (m_runs.size() == 0)
+ {
+ m_sortedFile = tf;
+ break;
+ }
+ else
+ {
+ m_runs.push_back(tf);
+ }
+ }
+ }
+
+ m_bInsertionPhase = false;
+}
+
+ExternalSorter::Record* ExternalSorter::getNextRecord()
+{
+ if (m_bInsertionPhase == true)
+ throw Tools::IllegalStateException("ExternalSorter::getNextRecord: Input has not been sorted yet.");
+
+ Record* ret;
+
+ if (m_sortedFile.get() == 0)
+ {
+ if (m_stI < m_buffer.size())
+ {
+ ret = m_buffer[m_stI];
+ m_buffer[m_stI] = 0;
+ ++m_stI;
+ }
+ else
+ throw Tools::EndOfStreamException("");
+ }
+ else
+ {
+ ret = new Record();
+ ret->loadFromFile(*m_sortedFile);
+ }
+
+ return ret;
+}
+
+inline uint64_t ExternalSorter::getTotalEntries() const
+{
+ return m_u64TotalEntries;
+}
+
+//
+// BulkLoader
+//
+void BulkLoader::bulkLoadUsingSTR(
+ SpatialIndex::RTree::RTree* pTree,
+ IDataStream& stream,
+ uint32_t bindex,
+ uint32_t bleaf,
+ uint32_t pageSize,
+ uint32_t numberOfPages
+) {
+ if (! stream.hasNext())
+ throw Tools::IllegalArgumentException(
+ "RTree::BulkLoader::bulkLoadUsingSTR: Empty data stream given."
+ );
+
+ NodePtr n = pTree->readNode(pTree->m_rootID);
+ pTree->deleteNode(n.get());
+
+ #ifndef NDEBUG
+ std::cerr << "RTree::BulkLoader: Sorting data." << std::endl;
+ #endif
+
+ Tools::SmartPointer<ExternalSorter> es = Tools::SmartPointer<ExternalSorter>(new ExternalSorter(pageSize, numberOfPages));
+
+ while (stream.hasNext())
+ {
+ Data* d = reinterpret_cast<Data*>(stream.getNext());
+ if (d == 0)
+ throw Tools::IllegalArgumentException(
+ "bulkLoadUsingSTR: RTree bulk load expects SpatialIndex::RTree::Data entries."
+ );
+
+ es->insert(new ExternalSorter::Record(d->m_region, d->m_id, d->m_dataLength, d->m_pData, 0));
+ d->m_pData = 0;
+ delete d;
+ }
+ es->sort();
+
+ pTree->m_stats.m_u64Data = es->getTotalEntries();
+
+ // create index levels.
+ uint32_t level = 0;
+
+ while (true)
+ {
+ #ifndef NDEBUG
+ std::cerr << "RTree::BulkLoader: Building level " << level << std::endl;
+ #endif
+
+ pTree->m_stats.m_nodesInLevel.push_back(0);
+
+ Tools::SmartPointer<ExternalSorter> es2 = Tools::SmartPointer<ExternalSorter>(new ExternalSorter(pageSize, numberOfPages));
+ createLevel(pTree, es, 0, bleaf, bindex, level++, es2, pageSize, numberOfPages);
+ es = es2;
+
+ if (es->getTotalEntries() == 1) break;
+ es->sort();
+ }
+
+ pTree->m_stats.m_u32TreeHeight = level;
+ pTree->storeHeader();
+}
+
+void BulkLoader::createLevel(
+ SpatialIndex::RTree::RTree* pTree,
+ Tools::SmartPointer<ExternalSorter> es,
+ uint32_t dimension,
+ uint32_t bleaf,
+ uint32_t bindex,
+ uint32_t level,
+ Tools::SmartPointer<ExternalSorter> es2,
+ uint32_t pageSize,
+ uint32_t numberOfPages
+) {
+ uint64_t b = (level == 0) ? bleaf : bindex;
+ uint64_t P = static_cast<uint64_t>(std::ceil(static_cast<double>(es->getTotalEntries()) / static_cast<double>(b)));
+ uint64_t S = static_cast<uint64_t>(std::ceil(std::sqrt(static_cast<double>(P))));
+
+ if (S == 1 || dimension == pTree->m_dimension - 1 || S * b == es->getTotalEntries())
+ {
+ std::vector<ExternalSorter::Record*> node;
+ ExternalSorter::Record* r;
+
+ while (true)
+ {
+ try { r = es->getNextRecord(); } catch (Tools::EndOfStreamException) { break; }
+ node.push_back(r);
+
+ if (node.size() == b)
+ {
+ Node* n = createNode(pTree, node, level);
+ node.clear();
+ pTree->writeNode(n);
+ es2->insert(new ExternalSorter::Record(n->m_nodeMBR, n->m_identifier, 0, 0, 0));
+ pTree->m_rootID = n->m_identifier;
+ // special case when the root has exactly bindex entries.
+ delete n;
+ }
+ }
+
+ if (! node.empty())
+ {
+ Node* n = createNode(pTree, node, level);
+ pTree->writeNode(n);
+ es2->insert(new ExternalSorter::Record(n->m_nodeMBR, n->m_identifier, 0, 0, 0));
+ pTree->m_rootID = n->m_identifier;
+ delete n;
+ }
+ }
+ else
+ {
+ bool bMore = true;
+
+ while (bMore)
+ {
+ ExternalSorter::Record* pR;
+ Tools::SmartPointer<ExternalSorter> es3 = Tools::SmartPointer<ExternalSorter>(new ExternalSorter(pageSize, numberOfPages));
+
+ for (uint64_t i = 0; i < S * b; ++i)
+ {
+ try { pR = es->getNextRecord(); }
+ catch (Tools::EndOfStreamException) { bMore = false; break; }
+ pR->m_s = dimension + 1;
+ es3->insert(pR);
+ }
+ es3->sort();
+ createLevel(pTree, es3, dimension + 1, bleaf, bindex, level, es2, pageSize, numberOfPages);
+ }
+ }
+}
+
+Node* BulkLoader::createNode(SpatialIndex::RTree::RTree* pTree, std::vector<ExternalSorter::Record*>& e, uint32_t level)
+{
+ Node* n;
+
+ if (level == 0) n = new Leaf(pTree, -1);
+ else n = new Index(pTree, -1, level);
+
+ for (size_t cChild = 0; cChild < e.size(); ++cChild)
+ {
+ n->insertEntry(e[cChild]->m_len, e[cChild]->m_pData, e[cChild]->m_r, e[cChild]->m_id);
+ e[cChild]->m_pData = 0;
+ delete e[cChild];
+ }
+
+ return n;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.h
new file mode 100644
index 000000000..17d8f71fb
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/BulkLoader.h
@@ -0,0 +1,131 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class ExternalSorter
+ {
+ public:
+ class Record
+ {
+ public:
+ Record();
+ Record(const Region& r, id_type id, uint32_t len, byte* pData, uint32_t s);
+ ~Record();
+
+ bool operator<(const Record& r) const;
+
+ void storeToFile(Tools::TemporaryFile& f);
+ void loadFromFile(Tools::TemporaryFile& f);
+
+ struct SortAscending : public std::binary_function<Record* const, Record* const, bool>
+ {
+ bool operator()(Record* const r1, Record* const r2)
+ {
+ if (*r1 < *r2) return true;
+ else return false;
+ }
+ };
+
+ public:
+ Region m_r;
+ id_type m_id;
+ byte* m_pData;
+ uint32_t m_len;
+ uint32_t m_s;
+ };
+
+ public:
+ ExternalSorter(uint32_t u32PageSize, uint32_t u32BufferPages);
+ virtual ~ExternalSorter();
+
+ void insert(Record* r);
+ void sort();
+ Record* getNextRecord();
+ uint64_t getTotalEntries() const;
+
+ private:
+ class PQEntry
+ {
+ public:
+ PQEntry(Record* r, uint32_t u32Index) : m_r(r), m_u32Index(u32Index) {}
+
+ struct SortAscending : public std::binary_function<const PQEntry&, const PQEntry&, bool>
+ {
+ bool operator()(const PQEntry& e1, const PQEntry& e2)
+ {
+ if (*(e1.m_r) < *(e2.m_r)) return true;
+ else return false;
+ }
+ };
+
+ Record* m_r;
+ uint32_t m_u32Index;
+ };
+
+ private:
+ bool m_bInsertionPhase;
+ uint32_t m_u32PageSize;
+ uint32_t m_u32BufferPages;
+ Tools::SmartPointer<Tools::TemporaryFile> m_sortedFile;
+ std::list<Tools::SmartPointer<Tools::TemporaryFile> > m_runs;
+ std::vector<Record*> m_buffer;
+ uint64_t m_u64TotalEntries;
+ uint32_t m_stI;
+ };
+
+ class BulkLoader
+ {
+ public:
+ void bulkLoadUsingSTR(
+ RTree* pTree,
+ IDataStream& stream,
+ uint32_t bindex,
+ uint32_t bleaf,
+ uint32_t pageSize, // The number of node entries per page.
+ uint32_t numberOfPages // The total number of pages to use.
+ );
+
+ protected:
+ void createLevel(
+ RTree* pTree,
+ Tools::SmartPointer<ExternalSorter> es,
+ uint32_t dimension,
+ uint32_t indexSize,
+ uint32_t leafSize,
+ uint32_t level,
+ Tools::SmartPointer<ExternalSorter> es2,
+ uint32_t pageSize,
+ uint32_t numberOfPages
+ );
+
+ Node* createNode(
+ RTree* pTree,
+ std::vector<ExternalSorter::Record*>& e,
+ uint32_t level
+ );
+ };
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Index.cc b/sci-libs/libspatialindex/svn/trunk/src/rtree/Index.cc
new file mode 100644
index 000000000..9a3209683
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Index.cc
@@ -0,0 +1,372 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+
+using namespace SpatialIndex::RTree;
+
+Index::~Index()
+{
+}
+
+Index::Index(SpatialIndex::RTree::RTree* pTree, id_type id, uint32_t level) : Node(pTree, id, level, pTree->m_indexCapacity)
+{
+}
+
+NodePtr Index::chooseSubtree(const Region& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
+{
+ if (m_level == insertionLevel) return NodePtr(this, &(m_pTree->m_indexPool));
+
+ pathBuffer.push(m_identifier);
+
+ uint32_t child = 0;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ child = findLeastEnlargement(mbr);
+ break;
+ case RV_RSTAR:
+ if (m_level == 1)
+ {
+ // if this node points to leaves...
+ child = findLeastOverlap(mbr);
+ }
+ else
+ {
+ child = findLeastEnlargement(mbr);
+ }
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::chooseSubtree: Tree variant not supported.");
+ }
+ assert(child != std::numeric_limits<uint32_t>::max());
+
+ NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
+ NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
+ assert(n.unique());
+ if (ret.get() == n.get()) n.relinquish();
+
+ return ret;
+}
+
+NodePtr Index::findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->containsRegion(mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findLeaf(mbr, id, pathBuffer);
+ if (n.get() == l.get()) n.relinquish();
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
+
+void Index::split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& ptrLeft, NodePtr& ptrRight)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::split: Tree variant not supported.");
+ }
+
+ ptrLeft = m_pTree->m_indexPool.acquire();
+ ptrRight = m_pTree->m_indexPool.acquire();
+
+ if (ptrLeft.get() == 0) ptrLeft = NodePtr(new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
+ if (ptrRight.get() == 0) ptrRight = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+
+ ptrLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ ptrRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ ptrLeft->insertEntry(0, 0, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ ptrRight->insertEntry(0, 0, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ }
+}
+
+uint32_t Index::findLeastEnlargement(const Region& r) const
+{
+ double area = std::numeric_limits<double>::max();
+ uint32_t best = std::numeric_limits<uint32_t>::max();
+
+ RegionPtr t = m_pTree->m_regionPool.acquire();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_ptrMBR[cChild]->getCombinedRegion(*t, r);
+
+ double a = m_ptrMBR[cChild]->getArea();
+ double enl = t->getArea() - a;
+
+ if (enl < area)
+ {
+ area = enl;
+ best = cChild;
+ }
+ else if (enl == area)
+ {
+ // this will rarely happen, so compute best area on the fly only
+ // when necessary.
+ if (a < m_ptrMBR[best]->getArea()) best = cChild;
+ }
+ }
+
+ return best;
+}
+
+uint32_t Index::findLeastOverlap(const Region& r) const
+{
+ OverlapEntry** entries = new OverlapEntry*[m_children];
+
+ double leastOverlap = std::numeric_limits<double>::max();
+ double me = std::numeric_limits<double>::max();
+ OverlapEntry* best = 0;
+
+ // find combined region and enlargement of every entry and store it.
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ try
+ {
+ entries[cChild] = new OverlapEntry();
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete entries[i];
+ delete[] entries;
+ throw;
+ }
+
+ entries[cChild]->m_index = cChild;
+ entries[cChild]->m_original = m_ptrMBR[cChild];
+ entries[cChild]->m_combined = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->getCombinedRegion(*(entries[cChild]->m_combined), r);
+ entries[cChild]->m_oa = entries[cChild]->m_original->getArea();
+ entries[cChild]->m_ca = entries[cChild]->m_combined->getArea();
+ entries[cChild]->m_enlargement = entries[cChild]->m_ca - entries[cChild]->m_oa;
+
+ if (entries[cChild]->m_enlargement < me)
+ {
+ me = entries[cChild]->m_enlargement;
+ best = entries[cChild];
+ }
+ else if (entries[cChild]->m_enlargement == me && entries[cChild]->m_oa < best->m_oa)
+ {
+ best = entries[cChild];
+ }
+ }
+
+ if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
+ {
+ uint32_t cIterations;
+
+ if (m_children > m_pTree->m_nearMinimumOverlapFactor)
+ {
+ // sort entries in increasing order of enlargement.
+ ::qsort(entries, m_children,
+ sizeof(OverlapEntry*),
+ OverlapEntry::compareEntries);
+ assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
+
+ cIterations = m_pTree->m_nearMinimumOverlapFactor;
+ }
+ else
+ {
+ cIterations = m_children;
+ }
+
+ // calculate overlap of most important original entries (near minimum overlap cost).
+ for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
+ {
+ double dif = 0.0;
+ OverlapEntry* e = entries[cIndex];
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (e->m_index != cChild)
+ {
+ double f = e->m_combined->getIntersectingArea(*(m_ptrMBR[cChild]));
+ if (f != 0.0) dif += f - e->m_original->getIntersectingArea(*(m_ptrMBR[cChild]));
+ }
+ } // for (cChild)
+
+ if (dif < leastOverlap)
+ {
+ leastOverlap = dif;
+ best = entries[cIndex];
+ }
+ else if (dif == leastOverlap)
+ {
+ if (e->m_enlargement == best->m_enlargement)
+ {
+ // keep the one with least area.
+ if (e->m_original->getArea() < best->m_original->getArea()) best = entries[cIndex];
+ }
+ else
+ {
+ // keep the one with least enlargement.
+ if (e->m_enlargement < best->m_enlargement) best = entries[cIndex];
+ }
+ }
+ } // for (cIndex)
+ }
+
+ uint32_t ret = best->m_index;
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ delete entries[cChild];
+ }
+ delete[] entries;
+
+ return ret;
+}
+
+void Index::adjustTree(Node* n, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ bool bContained = m_nodeMBR.containsRegion(n->m_nodeMBR);
+ bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
+
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+
+ if (bRecompute)
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ if (bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
+
+void Index::adjustTree(Node* n1, Node* n2, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ ++(m_pTree->m_stats.m_u64Adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n1->m_identifier) break;
+ }
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ bool bContained = m_nodeMBR.containsRegion(n1->m_nodeMBR);
+ bool bTouches = m_nodeMBR.touchesRegion(*(m_ptrMBR[child]));
+ bool bRecompute = (! bContained || (bTouches && m_pTree->m_bTightMBRs));
+
+ *(m_ptrMBR[child]) = n1->m_nodeMBR;
+
+ if (bRecompute)
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+ }
+
+ // No write necessary here. insertData will write the node if needed.
+ //m_pTree->writeNode(this);
+
+ bool bAdjusted = insertData(0, 0, n2->m_nodeMBR, n2->m_identifier, pathBuffer, overflowTable);
+
+ // if n2 is contained in the node and there was no split or reinsert,
+ // we need to adjust only if recalculation took place.
+ // In all other cases insertData above took care of adjustment.
+ if ((! bAdjusted) && bRecompute && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Index.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/Index.h
new file mode 100644
index 000000000..ce0510dff
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Index.h
@@ -0,0 +1,73 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class Index : public Node
+ {
+ public:
+ virtual ~Index();
+
+ protected:
+ Index(RTree* pTree, id_type id, uint32_t level);
+
+ virtual NodePtr chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ uint32_t findLeastEnlargement(const Region&) const;
+ uint32_t findLeastOverlap(const Region&) const;
+
+ void adjustTree(Node*, std::stack<id_type>&);
+ void adjustTree(Node*, Node*, std::stack<id_type>&, byte* overflowTable);
+
+ class OverlapEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_enlargement;
+ RegionPtr m_original;
+ RegionPtr m_combined;
+ double m_oa;
+ double m_ca;
+
+ static int compareEntries(const void* pv1, const void* pv2)
+ {
+ OverlapEntry* pe1 = * (OverlapEntry**) pv1;
+ OverlapEntry* pe2 = * (OverlapEntry**) pv2;
+
+ if (pe1->m_enlargement < pe2->m_enlargement) return -1;
+ if (pe1->m_enlargement > pe2->m_enlargement) return 1;
+ return 0;
+ }
+ }; // OverlapEntry
+
+ friend class RTree;
+ friend class Node;
+ friend class BulkLoader;
+ }; // Index
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.cc b/sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.cc
new file mode 100644
index 000000000..5781734d5
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.cc
@@ -0,0 +1,138 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::RTree;
+
+Leaf::~Leaf()
+{
+}
+
+Leaf::Leaf(SpatialIndex::RTree::RTree* pTree, id_type id): Node(pTree, id, 0, pTree->m_leafCapacity)
+{
+}
+
+NodePtr Leaf::chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer)
+{
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ return NodePtr(this, &(m_pTree->m_leafPool));
+}
+
+NodePtr Leaf::findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ if (m_pIdentifier[cChild] == id && mbr == *(m_ptrMBR[cChild])) return NodePtr(this, &(m_pTree->m_leafPool));
+ }
+
+ return NodePtr();
+}
+
+void Leaf::split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
+{
+ ++(m_pTree->m_stats.m_u64Splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_QUADRATIC:
+ rtreeSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ case RV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_leafPool.acquire();
+ pRight = m_pTree->m_leafPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g1[cIndex]] = 0;
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g2[cIndex]] = 0;
+ }
+}
+
+void Leaf::deleteData(id_type id, std::stack<id_type>& pathBuffer)
+{
+ uint32_t child;
+
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == id) break;
+ }
+
+ deleteEntry(child);
+ m_pTree->writeNode(this);
+
+ std::stack<NodePtr> toReinsert;
+ NodePtr ptrThis(this, &(m_pTree->m_leafPool));
+ condenseTree(toReinsert, pathBuffer, ptrThis);
+ ptrThis.relinquish();
+
+ // re-insert eliminated nodes.
+ while (! toReinsert.empty())
+ {
+ NodePtr n = toReinsert.top(); toReinsert.pop();
+ m_pTree->deleteNode(n.get());
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ // keep this in the for loop. The tree height might change after insertions.
+ byte* overflowTable = new byte[m_pTree->m_stats.m_u32TreeHeight];
+ bzero(overflowTable, m_pTree->m_stats.m_u32TreeHeight);
+ m_pTree->insertData_impl(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild], n->m_level, overflowTable);
+ n->m_pData[cChild] = 0;
+ delete[] overflowTable;
+ }
+ if (n.get() == this) n.relinquish();
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.h
new file mode 100644
index 000000000..2705e4c1d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Leaf.h
@@ -0,0 +1,47 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class Leaf : public Node
+ {
+ public:
+ virtual ~Leaf();
+
+ protected:
+ Leaf(RTree* pTree, id_type id);
+
+ virtual NodePtr chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ virtual void deleteData(id_type id, std::stack<id_type>& pathBuffer);
+
+ friend class RTree;
+ friend class BulkLoader;
+ }; // Leaf
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/rtree/Makefile.am
new file mode 100644
index 000000000..e1bcd6272
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Makefile.am
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = librtree.la
+INCLUDES = -I../../include
+librtree_la_SOURCES = BulkLoader.cc Index.cc Leaf.cc Node.cc RTree.cc Statistics.cc BulkLoader.h Index.h Leaf.h Node.h PointerPoolNode.h RTree.h Statistics.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Node.cc b/sci-libs/libspatialindex/svn/trunk/src/rtree/Node.cc
new file mode 100644
index 000000000..09ecfe943
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Node.cc
@@ -0,0 +1,1074 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RTree.h"
+#include "Node.h"
+#include "Index.h"
+
+using namespace SpatialIndex::RTree;
+
+//
+// Tools::IObject interface
+//
+Tools::IObject* Node::clone()
+{
+ throw Tools::NotSupportedException("IObject::clone should never be called.");
+}
+
+//
+// Tools::ISerializable interface
+//
+uint32_t Node::getByteArraySize()
+{
+ return
+ (sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ (m_children * (m_pTree->m_dimension * sizeof(double) * 2 + sizeof(id_type) + sizeof(uint32_t))) +
+ m_totalDataLength +
+ (2 * m_pTree->m_dimension * sizeof(double)));
+}
+
+void Node::loadFromByteArray(const byte* ptr)
+{
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ // skip the node type information, it is not needed.
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_level, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_children, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ m_ptrMBR[u32Child] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[u32Child]) = m_pTree->m_infiniteRegion;
+
+ memcpy(m_ptrMBR[u32Child]->m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[u32Child]->m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(&(m_pIdentifier[u32Child]), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(&(m_pDataLength[u32Child]), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[u32Child] > 0)
+ {
+ m_totalDataLength += m_pDataLength[u32Child];
+ m_pData[u32Child] = new byte[m_pDataLength[u32Child]];
+ memcpy(m_pData[u32Child], ptr, m_pDataLength[u32Child]);
+ ptr += m_pDataLength[u32Child];
+ }
+ else
+ {
+ m_pData[u32Child] = 0;
+ }
+
+ //m_nodeMBR.combineRegion(*(m_ptrMBR[u32Child]));
+ }
+
+ memcpy(m_nodeMBR.m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+void Node::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ uint32_t nodeType;
+
+ if (m_level == 0) nodeType = PersistentLeaf;
+ else nodeType = PersistentIndex;
+
+ memcpy(ptr, &nodeType, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_level, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_children, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ memcpy(ptr, m_ptrMBR[u32Child]->m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[u32Child]->m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, &(m_pIdentifier[u32Child]), sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(ptr, &(m_pDataLength[u32Child]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[u32Child] > 0)
+ {
+ memcpy(ptr, m_pData[u32Child], m_pDataLength[u32Child]);
+ ptr += m_pDataLength[u32Child];
+ }
+ }
+
+ // store the node MBR for efficiency. This increases the node size a little bit.
+ memcpy(ptr, m_nodeMBR.m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pHigh, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+
+ assert(len == (ptr - *data) + m_pTree->m_dimension * sizeof(double));
+}
+
+//
+// SpatialIndex::IEntry interface
+//
+SpatialIndex::id_type Node::getIdentifier() const
+{
+ return m_identifier;
+}
+
+void Node::getShape(IShape** out) const
+{
+ *out = new Region(m_nodeMBR);
+}
+
+//
+// SpatialIndex::INode interface
+//
+uint32_t Node::getChildrenCount() const
+{
+ return m_children;
+}
+
+SpatialIndex::id_type Node::getChildIdentifier(uint32_t index) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pIdentifier[index];
+}
+
+void Node::getChildShape(uint32_t index, IShape** out) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ *out = new Region(*(m_ptrMBR[index]));
+}
+
+void Node::getChildData(uint32_t index, uint32_t& length, byte** data) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+ if (m_pData[index] == NULL)
+ {
+ length = 0;
+ data = NULL;
+ }
+ else
+ {
+ length = m_pDataLength[index];
+ *data = m_pData[index];
+ }
+}
+
+uint32_t Node::getLevel() const
+{
+ return m_level;
+}
+
+bool Node::isLeaf() const
+{
+ return (m_level == 0);
+}
+
+bool Node::isIndex() const
+{
+ return (m_level != 0);
+}
+
+//
+// Internal
+//
+
+Node::Node() :
+ m_pTree(0),
+ m_level(0),
+ m_identifier(-1),
+ m_children(0),
+ m_capacity(0),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+}
+
+Node::Node(SpatialIndex::RTree::RTree* pTree, id_type id, uint32_t level, uint32_t capacity) :
+ m_pTree(pTree),
+ m_level(level),
+ m_identifier(id),
+ m_children(0),
+ m_capacity(capacity),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+ m_nodeMBR.makeInfinite(m_pTree->m_dimension);
+
+ try
+ {
+ m_pDataLength = new uint32_t[m_capacity + 1];
+ m_pData = new byte*[m_capacity + 1];
+ m_ptrMBR = new RegionPtr[m_capacity + 1];
+ m_pIdentifier = new id_type[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+ throw;
+ }
+}
+
+Node::~Node()
+{
+ if (m_pData != 0)
+ {
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ if (m_pData[u32Child] != 0) delete[] m_pData[u32Child];
+ }
+
+ delete[] m_pData;
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+}
+
+Node& Node::operator=(const Node& n)
+{
+ throw Tools::IllegalStateException("operator =: This should never be called.");
+}
+
+void Node::insertEntry(uint32_t dataLength, byte* pData, Region& mbr, id_type id)
+{
+ assert(m_children < m_capacity);
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ m_totalDataLength += dataLength;
+ ++m_children;
+
+ m_nodeMBR.combineRegion(mbr);
+}
+
+void Node::deleteEntry(uint32_t index)
+{
+ assert(index >= 0 && index < m_children);
+
+ // cache it, since I might need it for "touches" later.
+ RegionPtr ptrR = m_ptrMBR[index];
+
+ m_totalDataLength -= m_pDataLength[index];
+ if (m_pData[index] != 0) delete[] m_pData[index];
+
+ if (m_children > 1 && index != m_children - 1)
+ {
+ m_pDataLength[index] = m_pDataLength[m_children - 1];
+ m_pData[index] = m_pData[m_children - 1];
+ m_ptrMBR[index] = m_ptrMBR[m_children - 1];
+ m_pIdentifier[index] = m_pIdentifier[m_children - 1];
+ }
+
+ --m_children;
+
+ // WARNING: index has now changed. Do not use it below here.
+
+ if (m_children == 0)
+ {
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ else if (m_pTree->m_bTightMBRs && m_nodeMBR.touchesRegion(*ptrR))
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[u32Child]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[u32Child]->m_pHigh[cDim]);
+ }
+ }
+ }
+}
+
+bool Node::insertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ if (m_children < m_capacity)
+ {
+ bool adjusted = false;
+
+ // this has to happen before insertEntry modifies m_nodeMBR.
+ bool b = m_nodeMBR.containsRegion(mbr);
+
+ insertEntry(dataLength, pData, mbr, id);
+ m_pTree->writeNode(this);
+
+ if ((! b) && (! pathBuffer.empty()))
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ adjusted = true;
+ }
+
+ return adjusted;
+ }
+ else if (m_pTree->m_treeVariant == RV_RSTAR && (! pathBuffer.empty()) && overflowTable[m_level] == 0)
+ {
+ overflowTable[m_level] = 1;
+
+ std::vector<uint32_t> vReinsert, vKeep;
+ reinsertData(dataLength, pData, mbr, id, vReinsert, vKeep);
+
+ uint32_t lReinsert = static_cast<uint32_t>(vReinsert.size());
+ uint32_t lKeep = static_cast<uint32_t>(vKeep.size());
+
+ byte** reinsertdata = 0;
+ RegionPtr* reinsertmbr = 0;
+ id_type* reinsertid = 0;
+ uint32_t* reinsertlen = 0;
+ byte** keepdata = 0;
+ RegionPtr* keepmbr = 0;
+ id_type* keepid = 0;
+ uint32_t* keeplen = 0;
+
+ try
+ {
+ reinsertdata = new byte*[lReinsert];
+ reinsertmbr = new RegionPtr[lReinsert];
+ reinsertid = new id_type[lReinsert];
+ reinsertlen = new uint32_t[lReinsert];
+
+ keepdata = new byte*[m_capacity + 1];
+ keepmbr = new RegionPtr[m_capacity + 1];
+ keepid = new id_type[m_capacity + 1];
+ keeplen = new uint32_t[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+ delete[] keepdata;
+ delete[] keepmbr;
+ delete[] keepid;
+ delete[] keeplen;
+ throw;
+ }
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ reinsertlen[cIndex] = m_pDataLength[vReinsert[cIndex]];
+ reinsertdata[cIndex] = m_pData[vReinsert[cIndex]];
+ reinsertmbr[cIndex] = m_ptrMBR[vReinsert[cIndex]];
+ reinsertid[cIndex] = m_pIdentifier[vReinsert[cIndex]];
+ }
+
+ for (cIndex = 0; cIndex < lKeep; ++cIndex)
+ {
+ keeplen[cIndex] = m_pDataLength[vKeep[cIndex]];
+ keepdata[cIndex] = m_pData[vKeep[cIndex]];
+ keepmbr[cIndex] = m_ptrMBR[vKeep[cIndex]];
+ keepid[cIndex] = m_pIdentifier[vKeep[cIndex]];
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+
+ m_pDataLength = keeplen;
+ m_pData = keepdata;
+ m_ptrMBR = keepmbr;
+ m_pIdentifier = keepid;
+ m_children = lKeep;
+ m_totalDataLength = 0;
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child) m_totalDataLength += m_pDataLength[u32Child];
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t u32Child = 0; u32Child < m_children; ++u32Child)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[u32Child]->m_pLow[cDim]);
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[u32Child]->m_pHigh[cDim]);
+ }
+ }
+
+ m_pTree->writeNode(this);
+
+ // Divertion from R*-Tree algorithm here. First adjust
+ // the path to the root, then start reinserts, to avoid complicated handling
+ // of changes to the same node from multiple insertions.
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ m_pTree->insertData_impl(
+ reinsertlen[cIndex], reinsertdata[cIndex],
+ *(reinsertmbr[cIndex]), reinsertid[cIndex],
+ m_level, overflowTable);
+ }
+
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+
+ return true;
+ }
+ else
+ {
+ NodePtr n;
+ NodePtr nn;
+ split(dataLength, pData, mbr, id, n, nn);
+
+ if (pathBuffer.empty())
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ NodePtr ptrR = m_pTree->m_indexPool.acquire();
+ if (ptrR.get() == 0)
+ {
+ ptrR = NodePtr(new Index(m_pTree, m_pTree->m_rootID, m_level + 1), &(m_pTree->m_indexPool));
+ }
+ else
+ {
+ //ptrR->m_pTree = m_pTree;
+ ptrR->m_identifier = m_pTree->m_rootID;
+ ptrR->m_level = m_level + 1;
+ ptrR->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+
+ ptrR->insertEntry(0, 0, n->m_nodeMBR, n->m_identifier);
+ ptrR->insertEntry(0, 0, nn->m_nodeMBR, nn->m_identifier);
+
+ m_pTree->writeNode(ptrR.get());
+
+ m_pTree->m_stats.m_nodesInLevel[m_level] = 2;
+ m_pTree->m_stats.m_nodesInLevel.push_back(1);
+ m_pTree->m_stats.m_u32TreeHeight = m_level + 2;
+ }
+ else
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = m_identifier;
+ nn->m_identifier = -1;
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(n.get(), nn.get(), pathBuffer, overflowTable);
+ }
+
+ return true;
+ }
+}
+
+void Node::reinsertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep)
+{
+ ReinsertEntry** v = new ReinsertEntry*[m_capacity + 1];
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ PointPtr nc = m_pTree->m_pointPool.acquire();
+ m_nodeMBR.getCenter(*nc);
+ PointPtr c = m_pTree->m_pointPool.acquire();
+
+ for (uint32_t u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ try
+ {
+ v[u32Child] = new ReinsertEntry(u32Child, 0.0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < u32Child; ++i) delete v[i];
+ delete[] v;
+ throw;
+ }
+
+ m_ptrMBR[u32Child]->getCenter(*c);
+
+ // calculate relative distance of every entry from the node MBR (ignore square root.)
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ double d = nc->m_pCoords[cDim] - c->m_pCoords[cDim];
+ v[u32Child]->m_dist += d * d;
+ }
+ }
+
+ // sort by increasing order of distances.
+ ::qsort(v, m_capacity + 1, sizeof(ReinsertEntry*), ReinsertEntry::compareReinsertEntry);
+
+ uint32_t cReinsert = static_cast<uint32_t>(std::floor((m_capacity + 1) * m_pTree->m_reinsertFactor));
+
+ uint32_t cCount;
+
+ for (cCount = 0; cCount < cReinsert; ++cCount)
+ {
+ reinsert.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ for (cCount = cReinsert; cCount < m_capacity + 1; ++cCount)
+ {
+ keep.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ delete[] v;
+}
+
+void Node::rtreeSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ uint32_t u32Child;
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ // use this mask array for marking visited entries.
+ byte* mask = new byte[m_capacity + 1];
+ bzero(mask, m_capacity + 1);
+
+ // insert new data in the node for easier manipulation. Data arrays are always
+ // by one larger than node capacity.
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+ // m_totalDataLength does not need to be increased here.
+
+ // initialize each group with the seed entries.
+ uint32_t seed1, seed2;
+ pickSeeds(seed1, seed2);
+
+ group1.push_back(seed1);
+ group2.push_back(seed2);
+
+ mask[seed1] = 1;
+ mask[seed2] = 1;
+
+ // find MBR of each group.
+ RegionPtr mbr1 = m_pTree->m_regionPool.acquire();
+ *mbr1 = *(m_ptrMBR[seed1]);
+ RegionPtr mbr2 = m_pTree->m_regionPool.acquire();
+ *mbr2 = *(m_ptrMBR[seed2]);
+
+ // count how many entries are left unchecked (exclude the seeds here.)
+ uint32_t cRemaining = m_capacity + 1 - 2;
+
+ while (cRemaining > 0)
+ {
+ if (minimumLoad - group1.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group1 to comply with minimun load requirement.
+ for (u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ if (mask[u32Child] == 0)
+ {
+ group1.push_back(u32Child);
+ mask[u32Child] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else if (minimumLoad - group2.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group2 to comply with minimun load requirement.
+ for (u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ if (mask[u32Child] == 0)
+ {
+ group2.push_back(u32Child);
+ mask[u32Child] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else
+ {
+ // For all remaining entries compute the difference of the cost of grouping an
+ // entry in either group. When done, choose the entry that yielded the maximum
+ // difference. In case of linear split, select any entry (e.g. the first one.)
+ uint32_t sel;
+ double md1 = 0.0, md2 = 0.0;
+ double m = -std::numeric_limits<double>::max();
+ double d1, d2, d;
+ double a1 = mbr1->getArea();
+ double a2 = mbr2->getArea();
+
+ RegionPtr a = m_pTree->m_regionPool.acquire();
+ RegionPtr b = m_pTree->m_regionPool.acquire();
+
+ for (u32Child = 0; u32Child < m_capacity + 1; ++u32Child)
+ {
+ if (mask[u32Child] == 0)
+ {
+ mbr1->getCombinedRegion(*a, *(m_ptrMBR[u32Child]));
+ d1 = a->getArea() - a1;
+ mbr2->getCombinedRegion(*b, *(m_ptrMBR[u32Child]));
+ d2 = b->getArea() - a2;
+ d = std::abs(d1 - d2);
+
+ if (d > m)
+ {
+ m = d;
+ md1 = d1; md2 = d2;
+ sel = u32Child;
+ if (m_pTree->m_treeVariant== RV_LINEAR || m_pTree->m_treeVariant == RV_RSTAR) break;
+ }
+ }
+ }
+
+ // determine the group where we should add the new entry.
+ int32_t group = -1;
+
+ if (md1 < md2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (md2 < md1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (a1 < a2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (a2 < a1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (group1.size() < group2.size())
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (group2.size() < group1.size())
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ mask[sel] = 1;
+ --cRemaining;
+ if (group == 1)
+ {
+ mbr1->combineRegion(*(m_ptrMBR[sel]));
+ }
+ else
+ {
+ mbr2->combineRegion(*(m_ptrMBR[sel]));
+ }
+ }
+ }
+
+ delete[] mask;
+}
+
+void Node::rstarSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ RstarSplitEntry** dataLow = 0;
+ RstarSplitEntry** dataHigh = 0;
+
+ try
+ {
+ dataLow = new RstarSplitEntry*[m_capacity + 1];
+ dataHigh = new RstarSplitEntry*[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] dataLow;
+ throw;
+ }
+
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+ // m_totalDataLength does not need to be increased here.
+
+ uint32_t nodeSPF = static_cast<uint32_t>(
+ std::floor((m_capacity + 1) * m_pTree->m_splitDistributionFactor));
+ uint32_t splitDistribution = (m_capacity + 1) - (2 * nodeSPF) + 2;
+
+ uint32_t u32Child = 0, cDim, cIndex;
+
+ for (u32Child = 0; u32Child <= m_capacity; ++u32Child)
+ {
+ try
+ {
+ dataLow[u32Child] = new RstarSplitEntry(m_ptrMBR[u32Child].get(), u32Child, 0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < u32Child; ++i) delete dataLow[i];
+ delete[] dataLow;
+ delete[] dataHigh;
+ throw;
+ }
+
+ dataHigh[u32Child] = dataLow[u32Child];
+ }
+
+ double minimumMargin = std::numeric_limits<double>::max();
+ uint32_t splitAxis = std::numeric_limits<uint32_t>::max();
+ uint32_t sortOrder = std::numeric_limits<uint32_t>::max();
+
+ // chooseSplitAxis.
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareLow);
+ ::qsort(dataHigh, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareHigh);
+
+ // calculate sum of margins and overlap for all distributions.
+ double marginl = 0.0;
+ double marginh = 0.0;
+
+ Region bbl1, bbl2, bbh1, bbh2;
+
+ for (u32Child = 1; u32Child <= splitDistribution; ++u32Child)
+ {
+ uint32_t l = nodeSPF - 1 + u32Child;
+
+ bbl1 = *(dataLow[0]->m_pRegion);
+ bbh1 = *(dataHigh[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bbl1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh1.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ bbl2 = *(dataLow[l]->m_pRegion);
+ bbh2 = *(dataHigh[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bbl2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ bbh2.combineRegion(*(dataHigh[cIndex]->m_pRegion));
+ }
+
+ marginl += bbl1.getMargin() + bbl2.getMargin();
+ marginh += bbh1.getMargin() + bbh2.getMargin();
+ } // for (u32Child)
+
+ double margin = std::min(marginl, marginh);
+
+ // keep minimum margin as split axis.
+ if (margin < minimumMargin)
+ {
+ minimumMargin = margin;
+ splitAxis = cDim;
+ sortOrder = (marginl < marginh) ? 0 : 1;
+ }
+
+ // increase the dimension according to which the data entries should be sorted.
+ for (u32Child = 0; u32Child <= m_capacity; ++u32Child)
+ {
+ dataLow[u32Child]->m_sortDim = cDim + 1;
+ }
+ } // for (cDim)
+
+ for (u32Child = 0; u32Child <= m_capacity; ++u32Child)
+ {
+ dataLow[u32Child]->m_sortDim = splitAxis;
+ }
+
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), (sortOrder == 0) ? RstarSplitEntry::compareLow : RstarSplitEntry::compareHigh);
+
+ double ma = std::numeric_limits<double>::max();
+ double mo = std::numeric_limits<double>::max();
+ uint32_t splitPoint = std::numeric_limits<uint32_t>::max();
+
+ Region bb1, bb2;
+
+ for (u32Child = 1; u32Child <= splitDistribution; ++u32Child)
+ {
+ uint32_t l = nodeSPF - 1 + u32Child;
+
+ bb1 = *(dataLow[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bb1.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ bb2 = *(dataLow[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bb2.combineRegion(*(dataLow[cIndex]->m_pRegion));
+ }
+
+ double o = bb1.getIntersectingArea(bb2);
+
+ if (o < mo)
+ {
+ splitPoint = u32Child;
+ mo = o;
+ ma = bb1.getArea() + bb2.getArea();
+ }
+ else if (o == mo)
+ {
+ double a = bb1.getArea() + bb2.getArea();
+
+ if (a < ma)
+ {
+ splitPoint = u32Child;
+ ma = a;
+ }
+ }
+ } // for (u32Child)
+
+ uint32_t l1 = nodeSPF - 1 + splitPoint;
+
+ for (cIndex = 0; cIndex < l1; ++cIndex)
+ {
+ group1.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ for (cIndex = l1; cIndex <= m_capacity; ++cIndex)
+ {
+ group2.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ delete[] dataLow;
+ delete[] dataHigh;
+}
+
+void Node::pickSeeds(uint32_t& index1, uint32_t& index2)
+{
+ double separation = -std::numeric_limits<double>::max();
+ double inefficiency = -std::numeric_limits<double>::max();
+ uint32_t cDim, u32Child, cIndex;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_RSTAR:
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ double leastLower = m_ptrMBR[0]->m_pLow[cDim];
+ double greatestUpper = m_ptrMBR[0]->m_pHigh[cDim];
+ uint32_t greatestLower = 0;
+ uint32_t leastUpper = 0;
+ double width;
+
+ for (u32Child = 1; u32Child <= m_capacity; ++u32Child)
+ {
+ if (m_ptrMBR[u32Child]->m_pLow[cDim] > m_ptrMBR[greatestLower]->m_pLow[cDim]) greatestLower = u32Child;
+ if (m_ptrMBR[u32Child]->m_pHigh[cDim] < m_ptrMBR[leastUpper]->m_pHigh[cDim]) leastUpper = u32Child;
+
+ leastLower = std::min(m_ptrMBR[u32Child]->m_pLow[cDim], leastLower);
+ greatestUpper = std::max(m_ptrMBR[u32Child]->m_pHigh[cDim], greatestUpper);
+ }
+
+ width = greatestUpper - leastLower;
+ if (width <= 0) width = 1;
+
+ double f = (m_ptrMBR[greatestLower]->m_pLow[cDim] - m_ptrMBR[leastUpper]->m_pHigh[cDim]) / width;
+
+ if (f > separation)
+ {
+ index1 = leastUpper;
+ index2 = greatestLower;
+ separation = f;
+ }
+ } // for (cDim)
+
+ if (index1 == index2)
+ {
+ if (index2 == 0) ++index2;
+ else --index2;
+ }
+
+ break;
+ case RV_QUADRATIC:
+ // for each pair of Regions (account for overflow Region too!)
+ for (u32Child = 0; u32Child < m_capacity; ++u32Child)
+ {
+ double a = m_ptrMBR[u32Child]->getArea();
+
+ for (cIndex = u32Child + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ // get the combined MBR of those two entries.
+ Region r;
+ m_ptrMBR[u32Child]->getCombinedRegion(r, *(m_ptrMBR[cIndex]));
+
+ // find the inefficiency of grouping these entries together.
+ double d = r.getArea() - a - m_ptrMBR[cIndex]->getArea();
+
+ if (d > inefficiency)
+ {
+ inefficiency = d;
+ index1 = u32Child;
+ index2 = cIndex;
+ }
+ } // for (cIndex)
+ } // for (u32Child)
+
+ break;
+ default:
+ throw Tools::NotSupportedException("Node::pickSeeds: Tree variant not supported.");
+ }
+}
+
+void Node::condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis)
+{
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ if (pathBuffer.empty())
+ {
+ // eliminate root if it has only one child.
+ if (m_level != 0 && m_children == 1)
+ {
+ NodePtr ptrN = m_pTree->readNode(m_pIdentifier[0]);
+ m_pTree->deleteNode(ptrN.get());
+ ptrN->m_identifier = m_pTree->m_rootID;
+ m_pTree->writeNode(ptrN.get());
+
+ m_pTree->m_stats.m_nodesInLevel.pop_back();
+ m_pTree->m_stats.m_u32TreeHeight -= 1;
+ // HACK: pending deleteNode for deleted child will decrease nodesInLevel, later on.
+ m_pTree->m_stats.m_nodesInLevel[m_pTree->m_stats.m_u32TreeHeight - 1] = 2;
+ }
+ }
+ else
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrParent = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrParent.get());
+
+ // find the entry in the parent, that points to this node.
+ uint32_t child;
+
+ for (child = 0; child != p->m_children; ++child)
+ {
+ if (p->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ if (m_children < minimumLoad)
+ {
+ // used space less than the minimum
+ // 1. eliminate node entry from the parent. deleteEntry will fix the parent's MBR.
+ p->deleteEntry(child);
+ // 2. add this node to the stack in order to reinsert its entries.
+ toReinsert.push(ptrThis);
+ }
+ else
+ {
+ // adjust the entry in 'p' to contain the new bounding region of this node.
+ *(p->m_ptrMBR[child]) = m_nodeMBR;
+
+ // global recalculation necessary since the MBR can only shrink in size,
+ // due to data removal.
+ if (m_pTree->m_bTightMBRs)
+ {
+ for (uint32_t cDim = 0; cDim < p->m_nodeMBR.m_dimension; ++cDim)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t u32Child = 0; u32Child < p->m_children; ++u32Child)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::min(p->m_nodeMBR.m_pLow[cDim], p->m_ptrMBR[u32Child]->m_pLow[cDim]);
+ p->m_nodeMBR.m_pHigh[cDim] = std::max(p->m_nodeMBR.m_pHigh[cDim], p->m_ptrMBR[u32Child]->m_pHigh[cDim]);
+ }
+ }
+ }
+ }
+
+ // write parent node back to storage.
+ m_pTree->writeNode(p);
+
+ p->condenseTree(toReinsert, pathBuffer, ptrParent);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Node.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/Node.h
new file mode 100644
index 000000000..89e55945d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Node.h
@@ -0,0 +1,188 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class RTree;
+ class Leaf;
+ class Index;
+ class Node;
+
+ typedef Tools::PoolPointer<Node> NodePtr;
+
+ class Node : public SpatialIndex::INode
+ {
+ public:
+ virtual ~Node();
+
+ //
+ // Tools::IObject interface
+ //
+ virtual Tools::IObject* clone();
+
+ //
+ // Tools::ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // SpatialIndex::IEntry interface
+ //
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+
+ //
+ // SpatialIndex::INode interface
+ //
+ virtual uint32_t getChildrenCount() const;
+ virtual id_type getChildIdentifier(uint32_t index) const;
+ virtual void getChildShape(uint32_t index, IShape** out) const;
+ virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
+ virtual uint32_t getLevel() const;
+ virtual bool isIndex() const;
+ virtual bool isLeaf() const;
+
+ private:
+ Node();
+ Node(RTree* pTree, id_type id, uint32_t level, uint32_t capacity);
+
+ virtual Node& operator=(const Node&);
+
+ virtual void insertEntry(uint32_t dataLength, byte* pData, Region& mbr, id_type id);
+ virtual void deleteEntry(uint32_t index);
+
+ virtual bool insertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable);
+ virtual void reinsertData(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep);
+
+ virtual void rtreeSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
+ virtual void rstarSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
+
+ virtual void pickSeeds(uint32_t& index1, uint32_t& index2);
+
+ virtual void condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis);
+
+ virtual NodePtr chooseSubtree(const Region& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findLeaf(const Region& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
+
+ virtual void split(uint32_t dataLength, byte* pData, Region& mbr, id_type id, NodePtr& left, NodePtr& right) = 0;
+
+ RTree* m_pTree;
+ // Parent of all nodes.
+
+ uint32_t m_level;
+ // The level of the node in the tree.
+ // Leaves are always at level 0.
+
+ id_type m_identifier;
+ // The unique ID of this node.
+
+ uint32_t m_children;
+ // The number of children pointed by this node.
+
+ uint32_t m_capacity;
+ // Specifies the node capacity.
+
+ Region m_nodeMBR;
+ // The minimum bounding region enclosing all data contained in the node.
+
+ byte** m_pData;
+ // The data stored in the node.
+
+ RegionPtr* m_ptrMBR;
+ // The corresponding data MBRs.
+
+ id_type* m_pIdentifier;
+ // The corresponding data identifiers.
+
+ uint32_t* m_pDataLength;
+
+ uint32_t m_totalDataLength;
+
+ class RstarSplitEntry
+ {
+ public:
+ Region* m_pRegion;
+ uint32_t m_index;
+ uint32_t m_sortDim;
+
+ RstarSplitEntry(Region* pr, uint32_t index, uint32_t dimension) :
+ m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
+
+ static int compareLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ assert(pe1->m_sortDim == pe2->m_sortDim);
+
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ assert(pe1->m_sortDim == pe2->m_sortDim);
+
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe2->m_sortDim]) return 1;
+ return 0;
+ }
+ }; // RstarSplitEntry
+
+ class ReinsertEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_dist;
+
+ ReinsertEntry(uint32_t index, double dist) : m_index(index), m_dist(dist) {}
+
+ static int compareReinsertEntry(const void* pv1, const void* pv2)
+ {
+ ReinsertEntry* pe1 = * (ReinsertEntry**) pv1;
+ ReinsertEntry* pe2 = * (ReinsertEntry**) pv2;
+
+ if (pe1->m_dist < pe2->m_dist) return -1;
+ if (pe1->m_dist > pe2->m_dist) return 1;
+ return 0;
+ }
+ }; // ReinsertEntry
+
+ // Needed to access protected members without having to cast from Node.
+ // It is more efficient than using member functions to access protected members.
+ friend class RTree;
+ friend class Leaf;
+ friend class Index;
+ friend class Tools::PointerPool<Node>;
+ friend class BulkLoader;
+ }; // Node
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/PointerPoolNode.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/PointerPoolNode.h
new file mode 100644
index 000000000..e6977a0c9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/PointerPoolNode.h
@@ -0,0 +1,138 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#ifndef __spatialindex_rtree_pointer_pool_node_h
+#define __spatialindex_rtree_pointer_pool_node_h
+
+#include "Node.h"
+
+namespace Tools
+{
+ template<> class PointerPool<RTree::Node>
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ RTree::Node* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<RTree::Node> acquire()
+ {
+ if (! m_pool.empty())
+ {
+ RTree::Node* p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ ++m_hits;
+ #endif
+
+ return PoolPointer<RTree::Node>(p, this);
+ }
+ #ifndef NDEBUG
+ else
+ {
+ // fixme: well sort of...
+ ++m_pointerCount;
+ ++m_misses;
+ }
+ #endif
+
+ return PoolPointer<RTree::Node>();
+ }
+
+ void release(RTree::Node* p)
+ {
+ if (p != 0)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ if (p->m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ // there is no need to set the pointer to zero, after deleting it,
+ // since it will be redeleted only if it is actually initialized again,
+ // a fact that will be depicted by variable m_children.
+ if (p->m_pData[cChild] != 0) delete[] p->m_pData[cChild];
+ }
+ }
+
+ p->m_level = 0;
+ p->m_identifier = -1;
+ p->m_children = 0;
+ p->m_totalDataLength = 0;
+
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ protected:
+ uint32_t m_capacity;
+ std::stack<RTree::Node*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
+#endif /* __spatialindex_rtree_pointer_pool_node_h */
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.cc b/sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.cc
new file mode 100644
index 000000000..dd5f23c45
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.cc
@@ -0,0 +1,1551 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "BulkLoader.h"
+#include "RTree.h"
+
+using namespace SpatialIndex::RTree;
+
+SpatialIndex::RTree::Data::Data(uint32_t len, byte* pData, Region& r, id_type id)
+ : m_id(id), m_region(r), m_pData(0), m_dataLength(len)
+{
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, pData, m_dataLength);
+ }
+}
+
+SpatialIndex::RTree::Data::~Data()
+{
+ delete[] m_pData;
+}
+
+SpatialIndex::RTree::Data* SpatialIndex::RTree::Data::clone()
+{
+ return new Data(m_dataLength, m_pData, m_region, m_id);
+}
+
+id_type SpatialIndex::RTree::Data::getIdentifier() const
+{
+ return m_id;
+}
+
+void SpatialIndex::RTree::Data::getShape(IShape** out) const
+{
+ *out = new Region(m_region);
+}
+
+void SpatialIndex::RTree::Data::getData(uint32_t& len, byte** data) const
+{
+ len = m_dataLength;
+ *data = 0;
+
+ if (m_dataLength > 0)
+ {
+ *data = new byte[m_dataLength];
+ memcpy(*data, m_pData, m_dataLength);
+ }
+}
+
+uint32_t SpatialIndex::RTree::Data::getByteArraySize()
+{
+ return
+ sizeof(id_type) +
+ sizeof(uint32_t) +
+ m_dataLength +
+ m_region.getByteArraySize();
+}
+
+void SpatialIndex::RTree::Data::loadFromByteArray(const byte* ptr)
+{
+ memcpy(&m_id, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ delete[] m_pData;
+ m_pData = 0;
+
+ memcpy(&m_dataLength, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, ptr, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ m_region.loadFromByteArray(ptr);
+}
+
+void SpatialIndex::RTree::Data::storeToByteArray(byte** data, uint32_t& len)
+{
+ // it is thread safe this way.
+ uint32_t regionsize;
+ byte* regiondata = 0;
+ m_region.storeToByteArray(&regiondata, regionsize);
+
+ len = sizeof(id_type) + sizeof(uint32_t) + m_dataLength + regionsize;
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_id, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_dataLength, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ memcpy(ptr, m_pData, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ memcpy(ptr, regiondata, regionsize);
+ delete[] regiondata;
+ // ptr += regionsize;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::returnRTree(SpatialIndex::IStorageManager& sm, Tools::PropertySet& ps)
+{
+ SpatialIndex::ISpatialIndex* si = new SpatialIndex::RTree::RTree(sm, ps);
+ return si;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::createNewRTree(
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ RTreeVariant rv,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = fillFactor;
+ ps.setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = indexCapacity;
+ ps.setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = leafCapacity;
+ ps.setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = dimension;
+ ps.setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = rv;
+ ps.setProperty("TreeVariant", var);
+
+ ISpatialIndex* ret = returnRTree(sm, ps);
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var = ps.getProperty("IndexIdentifier");
+ indexIdentifier = var.m_val.llVal;
+
+ return ret;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ SpatialIndex::RTree::RTreeVariant rv,
+ id_type& indexIdentifier)
+{
+ SpatialIndex::ISpatialIndex* tree = createNewRTree(sm, fillFactor, indexCapacity, leafCapacity, dimension, rv, indexIdentifier);
+
+ uint32_t bindex = static_cast<uint32_t>(std::floor(static_cast<double>(indexCapacity * fillFactor)));
+ uint32_t bleaf = static_cast<uint32_t>(std::floor(static_cast<double>(leafCapacity * fillFactor)));
+
+ SpatialIndex::RTree::BulkLoader bl;
+
+ switch (m)
+ {
+ case BLM_STR:
+ bl.bulkLoadUsingSTR(static_cast<RTree*>(tree), stream, bindex, bleaf, 10000, 100);
+ break;
+ default:
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Unknown bulk load method.");
+ break;
+ }
+
+ return tree;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::createAndBulkLoadNewRTree(
+ BulkLoadMethod m,
+ IDataStream& stream,
+ SpatialIndex::IStorageManager& sm,
+ Tools::PropertySet& ps,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ RTreeVariant rv;
+ double fillFactor;
+ uint32_t indexCapacity, leafCapacity, dimension, pageSize, numberOfPages;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != RV_LINEAR &&
+ var.m_val.lVal != RV_QUADRATIC &&
+ var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type");
+
+ rv = static_cast<RTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property FillFactor was not of type Tools::VT_DOUBLE");
+
+ if (var.m_val.dblVal <= 0.0)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property FillFactor was less than 0.0");
+
+ if (((rv == RV_LINEAR || rv == RV_QUADRATIC) && var.m_val.dblVal > 0.5))
+ throw Tools::IllegalArgumentException( "createAndBulkLoadNewRTree: Property FillFactor must be in range (0.0, 0.5) for LINEAR or QUADRATIC index types");
+ if ( var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property FillFactor must be in range (0.0, 1.0) for RSTAR index type");
+ fillFactor = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property IndexCapacity must be Tools::VT_ULONG and >= 4");
+
+ indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property LeafCapacity must be Tools::VT_ULONG and >= 4");
+
+ leafCapacity = var.m_val.ulVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property Dimension must be greater than 1");
+
+ dimension = var.m_val.ulVal;
+ }
+
+ // page size
+ var = ps.getProperty("ExternalSortBufferPageSize");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferPageSize must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferPageSize must be greater than 1");
+
+ pageSize = var.m_val.ulVal;
+ }
+
+ // number of pages
+ var = ps.getProperty("ExternalSortBufferTotalPages");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferTotalPages must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Property ExternalSortBufferTotalPages must be greater than 1");
+
+ numberOfPages = var.m_val.ulVal;
+ }
+
+ SpatialIndex::ISpatialIndex* tree = createNewRTree(sm, fillFactor, indexCapacity, leafCapacity, dimension, rv, indexIdentifier);
+
+ uint32_t bindex = static_cast<uint32_t>(std::floor(static_cast<double>(indexCapacity * fillFactor)));
+ uint32_t bleaf = static_cast<uint32_t>(std::floor(static_cast<double>(leafCapacity * fillFactor)));
+
+ SpatialIndex::RTree::BulkLoader bl;
+
+ switch (m)
+ {
+ case BLM_STR:
+ bl.bulkLoadUsingSTR(static_cast<RTree*>(tree), stream, bindex, bleaf, pageSize, numberOfPages);
+ break;
+ default:
+ throw Tools::IllegalArgumentException("createAndBulkLoadNewRTree: Unknown bulk load method.");
+ break;
+ }
+
+ return tree;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::RTree::loadRTree(IStorageManager& sm, id_type indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = indexIdentifier;
+ ps.setProperty("IndexIdentifier", var);
+
+ return returnRTree(sm, ps);
+}
+
+SpatialIndex::RTree::RTree::RTree(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_pStorageManager(&sm),
+ m_rootID(StorageManager::NewPage),
+ m_headerID(StorageManager::NewPage),
+ m_treeVariant(RV_RSTAR),
+ m_fillFactor(0.7),
+ m_indexCapacity(100),
+ m_leafCapacity(100),
+ m_nearMinimumOverlapFactor(32),
+ m_splitDistributionFactor(0.4),
+ m_reinsertFactor(0.3),
+ m_dimension(2),
+ m_bTightMBRs(true),
+ m_pointPool(500),
+ m_regionPool(1000),
+ m_indexPool(100),
+ m_leafPool(100)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+
+ Tools::Variant var = ps.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType == Tools::VT_LONGLONG) m_headerID = var.m_val.llVal;
+ else if (var.m_varType == Tools::VT_LONG) m_headerID = var.m_val.lVal;
+ // for backward compatibility only.
+ else throw Tools::IllegalArgumentException("RTree: Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ initOld(ps);
+ }
+ else
+ {
+ initNew(ps);
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = m_headerID;
+ ps.setProperty("IndexIdentifier", var);
+ }
+}
+
+SpatialIndex::RTree::RTree::~RTree()
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_destroy(&m_rwLock);
+#endif
+
+ storeHeader();
+}
+
+//
+// ISpatialIndex interface
+//
+
+void SpatialIndex::RTree::RTree::insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("insertData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ // convert the shape into a Region (R-Trees index regions only; i.e., approximations of the shapes).
+ RegionPtr mbr = m_regionPool.acquire();
+ shape.getMBR(*mbr);
+
+ byte* buffer = 0;
+
+ if (len > 0)
+ {
+ buffer = new byte[len];
+ memcpy(buffer, pData, len);
+ }
+
+ insertData_impl(len, buffer, *mbr, id);
+ // the buffer is stored in the tree. Do not delete here.
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+bool SpatialIndex::RTree::RTree::deleteData(const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("deleteData: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("deleteData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ RegionPtr mbr = m_regionPool.acquire();
+ shape.getMBR(*mbr);
+ bool ret = deleteData_impl(*mbr, id);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ return ret;
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::containsWhatQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("containsWhatQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(ContainmentQuery, query, v);
+}
+
+void SpatialIndex::RTree::RTree::intersectsWithQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("intersectsWithQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(IntersectionQuery, query, v);
+}
+
+void SpatialIndex::RTree::RTree::pointLocationQuery(const Point& query, IVisitor& v)
+{
+ if (query.m_dimension != m_dimension) throw Tools::IllegalArgumentException("pointLocationQuery: Shape has the wrong number of dimensions.");
+ Region r(query, query);
+ rangeQuery(IntersectionQuery, r, v);
+}
+
+void SpatialIndex::RTree::RTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("nearestNeighborQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::priority_queue<NNEntry*, std::vector<NNEntry*>, NNEntry::ascending> queue;
+
+ queue.push(new NNEntry(m_rootID, 0, 0.0));
+
+ uint32_t count = 0;
+ double knearest = 0.0;
+
+ while (! queue.empty())
+ {
+ NNEntry* pFirst = queue.top();
+
+ // report all nearest neighbors with equal greatest distances.
+ // (neighbors can be more than k, if many happen to have the same greatest distance).
+ if (count >= k && pFirst->m_minDist > knearest) break;
+
+ queue.pop();
+
+ if (pFirst->m_pEntry == 0)
+ {
+ // n is a leaf or an index.
+ NodePtr n = readNode(pFirst->m_id);
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (n->m_level == 0)
+ {
+ Data* e = new Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ // we need to compare the query with the actual data entry here, so we call the
+ // appropriate getMinimumDistance method of NearestNeighborComparator.
+ queue.push(new NNEntry(n->m_pIdentifier[cChild], e, nnc.getMinimumDistance(query, *e)));
+ }
+ else
+ {
+ queue.push(new NNEntry(n->m_pIdentifier[cChild], 0, nnc.getMinimumDistance(query, *(n->m_ptrMBR[cChild]))));
+ }
+ }
+ }
+ else
+ {
+ v.visitData(*(static_cast<IData*>(pFirst->m_pEntry)));
+ ++(m_stats.m_u64QueryResults);
+ ++count;
+ knearest = pFirst->m_minDist;
+ delete pFirst->m_pEntry;
+ }
+
+ delete pFirst;
+ }
+
+ while (! queue.empty())
+ {
+ NNEntry* e = queue.top(); queue.pop();
+ if (e->m_pEntry != 0) delete e->m_pEntry;
+ delete e;
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+ NNComparator nnc;
+ nearestNeighborQuery(k, query, v, nnc);
+}
+
+
+void SpatialIndex::RTree::RTree::selfJoinQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension)
+ throw Tools::IllegalArgumentException("selfJoinQuery: Shape has the wrong number of dimensions.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("selfJoinQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ RegionPtr mbr = m_regionPool.acquire();
+ query.getMBR(*mbr);
+ selfJoinQuery(m_rootID, m_rootID, *mbr, v);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::queryStrategy(IQueryStrategy& qs)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");
+#endif
+
+ id_type next = m_rootID;
+ bool hasNext = true;
+
+ try
+ {
+ while (hasNext)
+ {
+ NodePtr n = readNode(next);
+ qs.getNextEntry(*n, next, hasNext);
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::getIndexProperties(Tools::PropertySet& out) const
+{
+ Tools::Variant var;
+
+ // dimension
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_dimension;
+ out.setProperty("Dimension", var);
+
+ // index capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexCapacity;
+ out.setProperty("IndexCapacity", var);
+
+ // leaf capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafCapacity;
+ out.setProperty("LeafCapacity", var);
+
+ // R-tree variant
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = m_treeVariant;
+ out.setProperty("TreeVariant", var);
+
+ // fill factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_fillFactor;
+ out.setProperty("FillFactor", var);
+
+ // near minimum overlap factor
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_nearMinimumOverlapFactor;
+ out.setProperty("NearMinimumOverlapFactor", var);
+
+ // split distribution factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_splitDistributionFactor;
+ out.setProperty("SplitDistributionFactor", var);
+
+ // reinsert factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_reinsertFactor;
+ out.setProperty("ReinsertFactor", var);
+
+ // tight MBRs
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = m_bTightMBRs;
+ out.setProperty("EnsureTightMBRs", var);
+
+ // index pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexPool.getCapacity();
+ out.setProperty("IndexPoolCapacity", var);
+
+ // leaf pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafPool.getCapacity();
+ out.setProperty("LeafPoolCapacity", var);
+
+ // region pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_regionPool.getCapacity();
+ out.setProperty("RegionPoolCapacity", var);
+
+ // point pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_pointPool.getCapacity();
+ out.setProperty("PointPoolCapacity", var);
+}
+
+void SpatialIndex::RTree::RTree::addCommand(ICommand* pCommand, CommandType ct)
+{
+ switch (ct)
+ {
+ case CT_NODEREAD:
+ m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEWRITE:
+ m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEDELETE:
+ m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ }
+}
+
+bool SpatialIndex::RTree::RTree::isIndexValid()
+{
+ bool ret = true;
+ std::stack<ValidateEntry> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_level != m_stats.m_u32TreeHeight - 1)
+ {
+ std::cerr << "Invalid tree height." << std::endl;
+ return false;
+ }
+
+ std::map<uint32_t, uint32_t> nodesInLevel;
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(root->m_level, 1));
+
+ ValidateEntry e(root->m_nodeMBR, root);
+ st.push(e);
+
+ while (! st.empty())
+ {
+ e = st.top(); st.pop();
+
+ Region tmpRegion;
+ tmpRegion = m_infiniteRegion;
+
+ for (uint32_t cDim = 0; cDim < tmpRegion.m_dimension; ++cDim)
+ {
+ tmpRegion.m_pLow[cDim] = std::numeric_limits<double>::max();
+ tmpRegion.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pLow[cDim]);
+ tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pHigh[cDim]);
+ }
+ }
+
+ if (! (tmpRegion == e.m_pNode->m_nodeMBR))
+ {
+ std::cerr << "Invalid parent information." << std::endl;
+ ret = false;
+ }
+ else if (! (tmpRegion == e.m_parentMBR))
+ {
+ std::cerr << "Error in parent." << std::endl;
+ ret = false;
+ }
+
+ if (e.m_pNode->m_level != 0)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
+ ValidateEntry tmpEntry(*(e.m_pNode->m_ptrMBR[cChild]), ptrN);
+
+ std::map<uint32_t, uint32_t>::iterator itNodes = nodesInLevel.find(tmpEntry.m_pNode->m_level);
+
+ if (itNodes == nodesInLevel.end())
+ {
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(tmpEntry.m_pNode->m_level, 1l));
+ }
+ else
+ {
+ nodesInLevel[tmpEntry.m_pNode->m_level] = nodesInLevel[tmpEntry.m_pNode->m_level] + 1;
+ }
+
+ st.push(tmpEntry);
+ }
+ }
+ }
+
+ uint32_t nodes = 0;
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_u32TreeHeight; ++cLevel)
+ {
+ if (nodesInLevel[cLevel] != m_stats.m_nodesInLevel[cLevel])
+ {
+ std::cerr << "Invalid nodesInLevel information." << std::endl;
+ ret = false;
+ }
+
+ nodes += m_stats.m_nodesInLevel[cLevel];
+ }
+
+ if (nodes != m_stats.m_u32Nodes)
+ {
+ std::cerr << "Invalid number of nodes information." << std::endl;
+ ret = false;
+ }
+
+ return ret;
+}
+
+void SpatialIndex::RTree::RTree::getStatistics(IStatistics** out) const
+{
+ *out = new Statistics(m_stats);
+}
+
+void SpatialIndex::RTree::RTree::initNew(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != RV_LINEAR &&
+ var.m_val.lVal != RV_QUADRATIC &&
+ var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type");
+
+ m_treeVariant = static_cast<RTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor was not of type Tools::VT_DOUBLE");
+
+ if (var.m_val.dblVal <= 0.0)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor was less than 0.0");
+
+ if (((m_treeVariant == RV_LINEAR || m_treeVariant == RV_QUADRATIC) && var.m_val.dblVal > 0.5))
+ throw Tools::IllegalArgumentException( "initNew: Property FillFactor must be in range "
+ "(0.0, 0.5) for LINEAR or QUADRATIC index types");
+ if ( var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException( "initNew: Property FillFactor must be in range "
+ "(0.0, 1.0) for RSTAR index type");
+ m_fillFactor = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_leafCapacity = var.m_val.ulVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1");
+
+ m_dimension = var.m_val.ulVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL)
+ throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+
+ m_stats.m_u32TreeHeight = 1;
+ m_stats.m_nodesInLevel.push_back(0);
+
+ Leaf root(this, -1);
+ m_rootID = writeNode(&root);
+
+ storeHeader();
+}
+
+void SpatialIndex::RTree::RTree::initOld(Tools::PropertySet& ps)
+{
+ loadHeader();
+
+ // only some of the properties may be changed.
+ // the rest are just ignored.
+
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != RV_LINEAR &&
+ var.m_val.lVal != RV_QUADRATIC &&
+ var.m_val.lVal != RV_RSTAR))
+ throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of RTreeVariant type");
+
+ m_treeVariant = static_cast<RTreeVariant>(var.m_val.lVal);
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+}
+
+void SpatialIndex::RTree::RTree::storeHeader()
+{
+ const uint32_t headerSize =
+ sizeof(id_type) + // m_rootID
+ sizeof(RTreeVariant) + // m_treeVariant
+ sizeof(double) + // m_fillFactor
+ sizeof(uint32_t) + // m_indexCapacity
+ sizeof(uint32_t) + // m_leafCapacity
+ sizeof(uint32_t) + // m_nearMinimumOverlapFactor
+ sizeof(double) + // m_splitDistributionFactor
+ sizeof(double) + // m_reinsertFactor
+ sizeof(uint32_t) + // m_dimension
+ sizeof(char) + // m_bTightMBRs
+ sizeof(uint32_t) + // m_stats.m_nodes
+ sizeof(uint64_t) + // m_stats.m_data
+ sizeof(uint32_t) + // m_stats.m_treeHeight
+ m_stats.m_u32TreeHeight * sizeof(uint32_t); // m_stats.m_nodesInLevel
+
+ byte* header = new byte[headerSize];
+ byte* ptr = header;
+
+ memcpy(ptr, &m_rootID, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_treeVariant, sizeof(RTreeVariant));
+ ptr += sizeof(RTreeVariant);
+ memcpy(ptr, &m_fillFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_indexCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_leafCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_splitDistributionFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_reinsertFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c = (char) m_bTightMBRs;
+ memcpy(ptr, &c, sizeof(char));
+ ptr += sizeof(char);
+ memcpy(ptr, &(m_stats.m_u32Nodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_u64Data), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(ptr, &(m_stats.m_u32TreeHeight), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_u32TreeHeight; ++cLevel)
+ {
+ memcpy(ptr, &(m_stats.m_nodesInLevel[cLevel]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
+
+ delete[] header;
+}
+
+void SpatialIndex::RTree::RTree::loadHeader()
+{
+ uint32_t headerSize;
+ byte* header = 0;
+ m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
+
+ byte* ptr = header;
+
+ memcpy(&m_rootID, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&m_treeVariant, ptr, sizeof(RTreeVariant));
+ ptr += sizeof(RTreeVariant);
+ memcpy(&m_fillFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_indexCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_leafCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_splitDistributionFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_reinsertFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c;
+ memcpy(&c, ptr, sizeof(char));
+ m_bTightMBRs = (c != 0);
+ ptr += sizeof(char);
+ memcpy(&(m_stats.m_u32Nodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_u64Data), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(&(m_stats.m_u32TreeHeight), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_u32TreeHeight; ++cLevel)
+ {
+ uint32_t cNodes;
+ memcpy(&cNodes, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ m_stats.m_nodesInLevel.push_back(cNodes);
+ }
+
+ delete[] header;
+}
+
+void SpatialIndex::RTree::RTree::insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id)
+{
+ assert(mbr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ byte* overflowTable = 0;
+
+ try
+ {
+ NodePtr root = readNode(m_rootID);
+
+ overflowTable = new byte[root->m_level];
+ bzero(overflowTable, root->m_level);
+
+ NodePtr l = root->chooseSubtree(mbr, 0, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mbr, id, pathBuffer, overflowTable);
+
+ delete[] overflowTable;
+ ++(m_stats.m_u64Data);
+ }
+ catch (...)
+ {
+ delete[] overflowTable;
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id, uint32_t level, byte* overflowTable)
+{
+ assert(mbr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_rootID);
+ NodePtr n = root->chooseSubtree(mbr, level, pathBuffer);
+
+ assert(n->m_level == level);
+
+ if (n.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ n->insertData(dataLength, pData, mbr, id, pathBuffer, overflowTable);
+}
+
+bool SpatialIndex::RTree::RTree::deleteData_impl(const Region& mbr, id_type id)
+{
+ assert(mbr.m_dimension == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_rootID);
+ NodePtr l = root->findLeaf(mbr, id, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+
+ if (l.get() != 0)
+ {
+ Leaf* pL = static_cast<Leaf*>(l.get());
+ pL->deleteData(id, pathBuffer);
+ --(m_stats.m_u64Data);
+ return true;
+ }
+
+ return false;
+}
+
+SpatialIndex::id_type SpatialIndex::RTree::RTree::writeNode(Node* n)
+{
+ byte* buffer;
+ uint32_t dataLength;
+ n->storeToByteArray(&buffer, dataLength);
+
+ id_type page;
+ if (n->m_identifier < 0) page = StorageManager::NewPage;
+ else page = n->m_identifier;
+
+ try
+ {
+ m_pStorageManager->storeByteArray(page, dataLength, buffer);
+ delete[] buffer;
+ }
+ catch (InvalidPageException& e)
+ {
+ delete[] buffer;
+ std::cerr << e.what() << std::endl;
+ throw;
+ }
+
+ if (n->m_identifier < 0)
+ {
+ n->m_identifier = page;
+ ++(m_stats.m_u32Nodes);
+
+#ifndef NDEBUG
+ try
+ {
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel.at(n->m_level) + 1;
+ }
+ catch(...)
+ {
+ throw Tools::IllegalStateException("writeNode: writing past the end of m_nodesInLevel.");
+ }
+#else
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] + 1;
+#endif
+ }
+
+ ++(m_stats.m_u64Writes);
+
+ for (size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
+ {
+ m_writeNodeCommands[cIndex]->execute(*n);
+ }
+
+ return page;
+}
+
+SpatialIndex::RTree::NodePtr SpatialIndex::RTree::RTree::readNode(id_type page)
+{
+ uint32_t dataLength;
+ byte* buffer;
+
+ try
+ {
+ m_pStorageManager->loadByteArray(page, dataLength, &buffer);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ throw;
+ }
+
+ try
+ {
+ uint32_t nodeType;
+ memcpy(&nodeType, buffer, sizeof(uint32_t));
+
+ NodePtr n;
+
+ if (nodeType == PersistentIndex) n = m_indexPool.acquire();
+ else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();
+ else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");
+
+ if (n.get() == 0)
+ {
+ if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);
+ else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);
+ }
+
+ //n->m_pTree = this;
+ n->m_identifier = page;
+ n->loadFromByteArray(buffer);
+
+ ++(m_stats.m_u64Reads);
+
+ for (size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
+ {
+ m_readNodeCommands[cIndex]->execute(*n);
+ }
+
+ delete[] buffer;
+ return n;
+ }
+ catch (...)
+ {
+ delete[] buffer;
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::deleteNode(Node* n)
+{
+ try
+ {
+ m_pStorageManager->deleteByteArray(n->m_identifier);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ throw;
+ }
+
+ --(m_stats.m_u32Nodes);
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] - 1;
+
+ for (size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
+ {
+ m_deleteNodeCommands[cIndex]->execute(*n);
+ }
+}
+
+void SpatialIndex::RTree::RTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::stack<NodePtr> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_children > 0 && query.intersectsShape(root->m_nodeMBR)) st.push(root);
+
+ while (! st.empty())
+ {
+ NodePtr n = st.top(); st.pop();
+
+ if (n->m_level == 0)
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ bool b;
+ if (type == ContainmentQuery) b = query.containsShape(*(n->m_ptrMBR[cChild]));
+ else b = query.intersectsShape(*(n->m_ptrMBR[cChild]));
+
+ if (b)
+ {
+ Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ v.visitData(data);
+ ++(m_stats.m_u64QueryResults);
+ }
+ }
+ }
+ else
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (query.intersectsShape(*(n->m_ptrMBR[cChild]))) st.push(readNode(n->m_pIdentifier[cChild]));
+ }
+ }
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::RTree::RTree::selfJoinQuery(id_type id1, id_type id2, const Region& r, IVisitor& vis)
+{
+ NodePtr n1 = readNode(id1);
+ NodePtr n2 = readNode(id2);
+ vis.visitNode(*n1);
+ vis.visitNode(*n2);
+
+ for (uint32_t cChild1 = 0; cChild1 < n1->m_children; ++cChild1)
+ {
+ if (r.intersectsRegion(*(n1->m_ptrMBR[cChild1])))
+ {
+ for (uint32_t cChild2 = 0; cChild2 < n2->m_children; ++cChild2)
+ {
+ if (
+ r.intersectsRegion(*(n2->m_ptrMBR[cChild2])) &&
+ n1->m_ptrMBR[cChild1]->intersectsRegion(*(n2->m_ptrMBR[cChild2])))
+ {
+ if (n1->m_level == 0)
+ {
+ if (n1->m_pIdentifier[cChild1] != n2->m_pIdentifier[cChild2])
+ {
+ assert(n2->m_level == 0);
+
+ std::vector<const IData*> v;
+ Data e1(n1->m_pDataLength[cChild1], n1->m_pData[cChild1], *(n1->m_ptrMBR[cChild1]), n1->m_pIdentifier[cChild1]);
+ Data e2(n2->m_pDataLength[cChild2], n2->m_pData[cChild2], *(n2->m_ptrMBR[cChild2]), n2->m_pIdentifier[cChild2]);
+ v.push_back(&e1);
+ v.push_back(&e2);
+ vis.visitData(v);
+ }
+ }
+ else
+ {
+ Region rr = r.getIntersectingRegion(n1->m_ptrMBR[cChild1]->getIntersectingRegion(*(n2->m_ptrMBR[cChild2])));
+ selfJoinQuery(n1->m_pIdentifier[cChild1], n2->m_pIdentifier[cChild2], rr, vis);
+ }
+ }
+ }
+ }
+ }
+}
+
+std::ostream& SpatialIndex::RTree::operator<<(std::ostream& os, const RTree& t)
+{
+ os << "Dimension: " << t.m_dimension << std::endl
+ << "Fill factor: " << t.m_fillFactor << std::endl
+ << "Index capacity: " << t.m_indexCapacity << std::endl
+ << "Leaf capacity: " << t.m_leafCapacity << std::endl
+ << "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << std::endl;
+
+ if (t.m_treeVariant == RV_RSTAR)
+ {
+ os << "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
+ << "Reinsert factor: " << t.m_reinsertFactor << std::endl
+ << "Split distribution factor: " << t.m_splitDistributionFactor << std::endl;
+ }
+
+ if (t.m_stats.getNumberOfNodesInLevel(0) > 0)
+ os << "Utilization: " << 100 * t.m_stats.getNumberOfData() / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << std::endl
+ << t.m_stats;
+
+ #ifndef NDEBUG
+ os << "Leaf pool hits: " << t.m_leafPool.m_hits << std::endl
+ << "Leaf pool misses: " << t.m_leafPool.m_misses << std::endl
+ << "Index pool hits: " << t.m_indexPool.m_hits << std::endl
+ << "Index pool misses: " << t.m_indexPool.m_misses << std::endl
+ << "Region pool hits: " << t.m_regionPool.m_hits << std::endl
+ << "Region pool misses: " << t.m_regionPool.m_misses << std::endl
+ << "Point pool hits: " << t.m_pointPool.m_hits << std::endl
+ << "Point pool misses: " << t.m_pointPool.m_misses << std::endl;
+ #endif
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.h
new file mode 100644
index 000000000..cb4e00452
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/RTree.h
@@ -0,0 +1,201 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Statistics.h"
+#include "Node.h"
+#include "PointerPoolNode.h"
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class RTree : public ISpatialIndex
+ {
+ //class NNEntry;
+
+ public:
+ RTree(IStorageManager&, Tools::PropertySet&);
+ // String Value Description
+ // ----------------------------------------------
+ // IndexIndentifier VT_LONG If specified an existing index will be openened from the supplied
+ // storage manager with the given index id. Behaviour is unspecified
+ // if the index id or the storage manager are incorrect.
+ // Dimension VT_ULONG Dimensionality of the data that will be inserted.
+ // IndexCapacity VT_ULONG The index node capacity. Default is 100.
+ // LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+ // FillFactor VT_DOUBLE The fill factor. Default is 70%
+ // TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+ // NearMinimumOverlapFactor VT_ULONG Default is 32.
+ // SplitDistributionFactor VT_DOUBLE Default is 0.4
+ // ReinsertFactor VT_DOUBLE Default is 0.3
+ // EnsureTightMBRs VT_BOOL Default is true
+ // IndexPoolCapacity VT_LONG Default is 100
+ // LeafPoolCapacity VT_LONG Default is 100
+ // RegionPoolCapacity VT_LONG Default is 1000
+ // PointPoolCapacity VT_LONG Default is 500
+
+ virtual ~RTree();
+
+
+
+ //
+ // ISpatialIndex interface
+ //
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier);
+ virtual bool deleteData(const IShape& shape, id_type id);
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v);
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v);
+ virtual void pointLocationQuery(const Point& query, IVisitor& v);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator&);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v);
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v);
+ virtual void queryStrategy(IQueryStrategy& qs);
+ virtual void getIndexProperties(Tools::PropertySet& out) const;
+ virtual void addCommand(ICommand* pCommand, CommandType ct);
+ virtual bool isIndexValid();
+ virtual void getStatistics(IStatistics** out) const;
+
+ private:
+ void initNew(Tools::PropertySet&);
+ void initOld(Tools::PropertySet& ps);
+ void storeHeader();
+ void loadHeader();
+
+ void insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id);
+ void insertData_impl(uint32_t dataLength, byte* pData, Region& mbr, id_type id, uint32_t level, byte* overflowTable);
+ bool deleteData_impl(const Region& mbr, id_type id);
+
+ id_type writeNode(Node*);
+ NodePtr readNode(id_type page);
+ void deleteNode(Node*);
+
+ void rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v);
+ void selfJoinQuery(id_type id1, id_type id2, const Region& r, IVisitor& vis);
+
+ IStorageManager* m_pStorageManager;
+
+ id_type m_rootID, m_headerID;
+
+ RTreeVariant m_treeVariant;
+
+ double m_fillFactor;
+
+ uint32_t m_indexCapacity;
+
+ uint32_t m_leafCapacity;
+
+ uint32_t m_nearMinimumOverlapFactor;
+ // The R*-Tree 'p' constant, for calculating nearly minimum overlap cost.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.1]
+
+ double m_splitDistributionFactor;
+ // The R*-Tree 'm' constant, for calculating spliting distributions.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.2]
+
+ double m_reinsertFactor;
+ // The R*-Tree 'p' constant, for removing entries at reinserts.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.3]
+
+ uint32_t m_dimension;
+
+ Region m_infiniteRegion;
+
+ Statistics m_stats;
+
+ bool m_bTightMBRs;
+
+ Tools::PointerPool<Point> m_pointPool;
+ Tools::PointerPool<Region> m_regionPool;
+ Tools::PointerPool<Node> m_indexPool;
+ Tools::PointerPool<Node> m_leafPool;
+
+ std::vector<Tools::SmartPointer<ICommand> > m_writeNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_readNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_deleteNodeCommands;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+
+
+
+
+ class NNEntry
+ {
+ public:
+ id_type m_id;
+ IEntry* m_pEntry;
+ double m_minDist;
+
+ NNEntry(id_type id, IEntry* e, double f) : m_id(id), m_pEntry(e), m_minDist(f) {}
+ ~NNEntry() {}
+
+ struct ascending : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_minDist > __y->m_minDist; }
+ };
+ }; // NNEntry
+
+ class NNComparator : public INearestNeighborComparator
+ {
+ public:
+ double getMinimumDistance(const IShape& query, const IShape& entry)
+ {
+ return query.getMinimumDistance(entry);
+ }
+
+ double getMinimumDistance(const IShape& query, const IData& data)
+ {
+ IShape* pS;
+ data.getShape(&pS);
+ double ret = query.getMinimumDistance(*pS);
+ delete pS;
+ return ret;
+ }
+ }; // NNComparator
+
+ class ValidateEntry
+ {
+ public:
+ ValidateEntry(Region& r, NodePtr& pNode) : m_parentMBR(r), m_pNode(pNode) {}
+
+ Region m_parentMBR;
+ NodePtr m_pNode;
+ }; // ValidateEntry
+
+ friend class Node;
+ friend class Leaf;
+ friend class Index;
+ friend class BulkLoader;
+
+ friend std::ostream& operator<<(std::ostream& os, const RTree& t);
+ }; // RTree
+
+ std::ostream& operator<<(std::ostream& os, const RTree& t);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.cc b/sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.cc
new file mode 100644
index 000000000..d79e5097d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.cc
@@ -0,0 +1,172 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+
+#include "Statistics.h"
+
+using namespace SpatialIndex::RTree;
+
+Statistics::Statistics()
+{
+ reset();
+}
+
+Statistics::Statistics(const Statistics& s)
+{
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u32TreeHeight = s.m_u32TreeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+}
+
+Statistics::~Statistics()
+{
+}
+
+Statistics& Statistics::operator=(const Statistics& s)
+{
+ if (this != &s)
+ {
+ m_u64Reads = s.m_u64Reads;
+ m_u64Writes = s.m_u64Writes;
+ m_u64Splits = s.m_u64Splits;
+ m_u64Hits = s.m_u64Hits;
+ m_u64Misses = s.m_u64Misses;
+ m_u32Nodes = s.m_u32Nodes;
+ m_u64Adjustments = s.m_u64Adjustments;
+ m_u64QueryResults = s.m_u64QueryResults;
+ m_u64Data = s.m_u64Data;
+ m_u32TreeHeight = s.m_u32TreeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+ }
+
+ return *this;
+}
+
+uint64_t Statistics::getReads() const
+{
+ return m_u64Reads;
+}
+
+uint64_t Statistics::getWrites() const
+{
+ return m_u64Writes;
+}
+
+uint32_t Statistics::getNumberOfNodes() const
+{
+ return m_u32Nodes;
+}
+
+uint64_t Statistics::getNumberOfData() const
+{
+ return m_u64Data;
+}
+
+uint64_t Statistics::getSplits() const
+{
+ return m_u64Splits;
+}
+
+uint64_t Statistics::getHits() const
+{
+ return m_u64Hits;
+}
+
+uint64_t Statistics::getMisses() const
+{
+ return m_u64Misses;
+}
+
+uint64_t Statistics::getAdjustments() const
+{
+ return m_u64Adjustments;
+}
+
+uint64_t Statistics::getQueryResults() const
+{
+ return m_u64QueryResults;
+}
+
+uint32_t Statistics::getTreeHeight() const
+{
+ return m_u32TreeHeight;
+}
+
+uint32_t Statistics::getNumberOfNodesInLevel(uint32_t l) const
+{
+ uint32_t u32Nodes;
+ try
+ {
+ u32Nodes = m_nodesInLevel.at(l);
+ }
+ catch (...)
+ {
+ throw Tools::IndexOutOfBoundsException(l);
+ }
+
+ return u32Nodes;
+}
+
+void Statistics::reset()
+{
+ m_u64Reads = 0;
+ m_u64Writes = 0;
+ m_u64Splits = 0;
+ m_u64Hits = 0;
+ m_u64Misses = 0;
+ m_u32Nodes = 0;
+ m_u64Adjustments = 0;
+ m_u64QueryResults = 0;
+ m_u64Data = 0;
+ m_u32TreeHeight = 0;
+ m_nodesInLevel.clear();
+}
+
+std::ostream& SpatialIndex::RTree::operator<<(std::ostream& os, const Statistics& s)
+{
+ os << "Reads: " << s.m_u64Reads << std::endl
+ << "Writes: " << s.m_u64Writes << std::endl
+ << "Hits: " << s.m_u64Hits << std::endl
+ << "Misses: " << s.m_u64Misses << std::endl
+ << "Tree height: " << s.m_u32TreeHeight << std::endl
+ << "Number of data: " << s.m_u64Data << std::endl
+ << "Number of nodes: " << s.m_u32Nodes << std::endl;
+
+ for (uint32_t u32Level = 0; u32Level < s.m_u32TreeHeight; ++u32Level)
+ {
+ os << "Level " << u32Level << " pages: " << s.m_nodesInLevel[u32Level] << std::endl;
+ }
+
+ os << "Splits: " << s.m_u64Splits << std::endl
+ << "Adjustments: " << s.m_u64Adjustments << std::endl
+ << "Query results: " << s.m_u64QueryResults << std::endl;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.h b/sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.h
new file mode 100644
index 000000000..389726d88
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/rtree/Statistics.h
@@ -0,0 +1,93 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace RTree
+ {
+ class RTree;
+ class Node;
+ class Leaf;
+ class Index;
+
+ class Statistics : public SpatialIndex::IStatistics
+ {
+ public:
+ Statistics();
+ Statistics(const Statistics&);
+ virtual ~Statistics();
+ Statistics& operator=(const Statistics&);
+
+ //
+ // IStatistics interface
+ //
+ virtual uint64_t getReads() const;
+ virtual uint64_t getWrites() const;
+ virtual uint32_t getNumberOfNodes() const;
+ virtual uint64_t getNumberOfData() const;
+
+ virtual uint64_t getSplits() const;
+ virtual uint64_t getHits() const;
+ virtual uint64_t getMisses() const;
+ virtual uint64_t getAdjustments() const;
+ virtual uint64_t getQueryResults() const;
+ virtual uint32_t getTreeHeight() const;
+ virtual uint32_t getNumberOfNodesInLevel(uint32_t l) const;
+
+ private:
+ void reset();
+
+ uint64_t m_u64Reads;
+
+ uint64_t m_u64Writes;
+
+ uint64_t m_u64Splits;
+
+ uint64_t m_u64Hits;
+
+ uint64_t m_u64Misses;
+
+ uint32_t m_u32Nodes;
+
+ uint64_t m_u64Adjustments;
+
+ uint64_t m_u64QueryResults;
+
+ uint64_t m_u64Data;
+
+ uint32_t m_u32TreeHeight;
+
+ std::vector<uint32_t> m_nodesInLevel;
+
+ friend class RTree;
+ friend class Node;
+ friend class Index;
+ friend class Leaf;
+ friend class BulkLoader;
+
+ friend std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }; // Statistics
+
+ std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/all-wcprops
new file mode 100644
index 000000000..bacdee811
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/all-wcprops
@@ -0,0 +1,65 @@
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/spatialindex/!svn/ver/202/spatialindex/trunk/src/spatialindex
+END
+TimeRegion.cc
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/spatialindex/TimeRegion.cc
+END
+MovingRegion.cc
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/spatialindex/!svn/ver/179/spatialindex/trunk/src/spatialindex/MovingRegion.cc
+END
+Region.cc
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/spatialindex/!svn/ver/202/spatialindex/trunk/src/spatialindex/Region.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/spatialindex/!svn/ver/45/spatialindex/trunk/src/spatialindex/Makefile.am
+END
+SpatialIndexImpl.cc
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/spatialindex/!svn/ver/99/spatialindex/trunk/src/spatialindex/SpatialIndexImpl.cc
+END
+TimePoint.cc
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/spatialindex/TimePoint.cc
+END
+MovingPoint.cc
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/spatialindex/MovingPoint.cc
+END
+Point.cc
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/spatialindex/Point.cc
+END
+SpatialIndexImpl.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/spatialindex/!svn/ver/99/spatialindex/trunk/src/spatialindex/SpatialIndexImpl.h
+END
+LineSegment.cc
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/spatialindex/LineSegment.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/dir-prop-base
new file mode 100644
index 000000000..ea9b95e8a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/dir-prop-base
@@ -0,0 +1,9 @@
+K 10
+svn:ignore
+V 33
+Makefile.in
+.libs
+.deps
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/entries
new file mode 100644
index 000000000..927718e38
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/entries
@@ -0,0 +1,368 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/spatialindex
+http://svn.gispython.org/spatialindex
+
+
+
+2011-03-01T14:50:59.673579Z
+202
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+TimeRegion.cc
+file
+
+
+
+
+2011-08-01T00:42:34.661911Z
+62277830274cb167e9ec0398084b2dbc
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11360
+
+MovingRegion.cc
+file
+
+
+
+
+2011-08-01T00:42:34.661911Z
+5a2ae3cdefaabc9ae84bd5511ec35219
+2010-03-30T20:18:40.573111Z
+179
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+40320
+
+Region.cc
+file
+
+
+
+
+2011-08-01T00:42:34.674138Z
+b09532912891826f971cbf77c37de29a
+2011-03-01T14:50:59.673579Z
+202
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13432
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.674138Z
+0399288962ff138cc73334b8e3b8ce9c
+2008-01-17T23:34:01.575758Z
+45
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+290
+
+SpatialIndexImpl.cc
+file
+
+
+
+
+2011-08-01T00:42:34.674138Z
+2f757bb99d300514fbaf8fed62aae461
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2638
+
+TimePoint.cc
+file
+
+
+
+
+2011-08-01T00:42:34.674138Z
+caaaa671695b7e2812711c81405eae55
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7136
+
+MovingPoint.cc
+file
+
+
+
+
+2011-08-01T00:42:34.717146Z
+d4d894f9e6b1c8643d1136f7c9d96d56
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8000
+
+Point.cc
+file
+
+
+
+
+2011-08-01T00:42:34.717146Z
+231b1432a5696b1b7292c803a53eee9c
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5720
+
+SpatialIndexImpl.h
+file
+
+
+
+
+2011-08-01T00:42:34.717146Z
+067fba191ef05d4c1f218c1626912fb0
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1127
+
+LineSegment.cc
+file
+
+
+
+
+2011-08-01T00:42:34.717146Z
+7d9e92b721a313b8d30fee5d86467b93
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11337
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/LineSegment.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/LineSegment.cc.svn-base
new file mode 100644
index 000000000..1653f15da
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/LineSegment.cc.svn-base
@@ -0,0 +1,388 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+LineSegment::LineSegment()
+ : m_dimension(0), m_pStartPoint(0), m_pEndPoint(0)
+{
+}
+
+LineSegment::LineSegment(const double* pStartPoint, const double* pEndPoint, uint32_t dimension)
+ : m_dimension(dimension)
+{
+ // no need to initialize arrays to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ memcpy(m_pStartPoint, pStartPoint, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, pEndPoint, m_dimension * sizeof(double));
+}
+
+LineSegment::LineSegment(const Point& startPoint, const Point& endPoint)
+ : m_dimension(startPoint.m_dimension)
+{
+ if (startPoint.m_dimension != endPoint.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "LineSegment::LineSegment: Points have different dimensionalities."
+ );
+
+ // no need to initialize arrays to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ memcpy(m_pStartPoint, startPoint.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, endPoint.m_pCoords, m_dimension * sizeof(double));
+}
+
+LineSegment::LineSegment(const LineSegment& l)
+ : m_dimension(l.m_dimension)
+{
+ // no need to initialize arrays to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ memcpy(m_pStartPoint, l.m_pStartPoint, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, l.m_pEndPoint, m_dimension * sizeof(double));
+}
+
+LineSegment::~LineSegment()
+{
+ delete[] m_pStartPoint;
+ delete[] m_pEndPoint;
+}
+
+LineSegment& LineSegment::operator=(const LineSegment& l)
+{
+ if (this != &l)
+ {
+ makeDimension(l.m_dimension);
+ memcpy(m_pStartPoint, l.m_pStartPoint, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, l.m_pEndPoint, m_dimension * sizeof(double));
+ }
+
+ return *this;
+}
+
+bool LineSegment::operator==(const LineSegment& l) const
+{
+ if (m_dimension != l.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "LineSegment::operator==: LineSegments have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pStartPoint[i] < l.m_pStartPoint[i] - std::numeric_limits<double>::epsilon() ||
+ m_pStartPoint[i] > l.m_pStartPoint[i] + std::numeric_limits<double>::epsilon()) return false;
+
+ if (
+ m_pEndPoint[i] < l.m_pEndPoint[i] - std::numeric_limits<double>::epsilon() ||
+ m_pEndPoint[i] > l.m_pEndPoint[i] + std::numeric_limits<double>::epsilon()) return false;
+ }
+
+ return true;
+}
+
+//
+// IObject interface
+//
+LineSegment* LineSegment::clone()
+{
+ return new LineSegment(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t LineSegment::getByteArraySize()
+{
+ return (sizeof(uint32_t) + m_dimension * sizeof(double) * 2);
+}
+
+void LineSegment::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ makeDimension(dimension);
+ memcpy(m_pStartPoint, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pEndPoint, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void LineSegment::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, m_pStartPoint, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pEndPoint, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IShape interface
+//
+bool LineSegment::intersectsShape(const IShape& s) const
+{
+ throw Tools::IllegalStateException(
+ "LineSegment::intersectsShape: Not implemented yet!"
+ );
+}
+
+bool LineSegment::containsShape(const IShape& s) const
+{
+ return false;
+}
+
+bool LineSegment::touchesShape(const IShape& s) const
+{
+ throw Tools::IllegalStateException(
+ "LineSegment::touchesShape: Not implemented yet!"
+ );
+}
+
+void LineSegment::getCenter(Point& out) const
+{
+ double* coords = new double[m_dimension];
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ coords[cDim] =
+ (std::abs(m_pStartPoint[cDim] - m_pEndPoint[cDim]) / 2.0) +
+ std::min(m_pStartPoint[cDim], m_pEndPoint[cDim]);
+ }
+
+ out = Point(coords, m_dimension);
+ delete[] coords;
+}
+
+uint32_t LineSegment::getDimension() const
+{
+ return m_dimension;
+}
+
+void LineSegment::getMBR(Region& out) const
+{
+ double* low = new double[m_dimension];
+ double* high = new double[m_dimension];
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ low[cDim] = std::min(m_pStartPoint[cDim], m_pEndPoint[cDim]);
+ high[cDim] = std::max(m_pStartPoint[cDim], m_pEndPoint[cDim]);
+ }
+
+ out = Region(low, high, m_dimension);
+ delete[] low;
+ delete[] high;
+}
+
+double LineSegment::getArea() const
+{
+ return 0.0;
+}
+
+double LineSegment::getMinimumDistance(const IShape& s) const
+{
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0)
+ {
+ return getMinimumDistance(*ppt);
+ }
+
+/*
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->getMinimumDistance(*this);
+ }
+*/
+
+ throw Tools::IllegalStateException(
+ "LineSegment::getMinimumDistance: Not implemented yet!"
+ );
+}
+
+double LineSegment::getMinimumDistance(const Point& p) const
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getMinimumDistance: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getMinimumDistance: Distance for high dimensional spaces not supported!"
+ );
+
+ if (m_pEndPoint[0] >= m_pStartPoint[0] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[0] <= m_pStartPoint[0] + std::numeric_limits<double>::epsilon()) return std::abs(p.m_pCoords[0] - m_pStartPoint[0]);
+
+ if (m_pEndPoint[1] >= m_pStartPoint[1] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[1] <= m_pStartPoint[1] + std::numeric_limits<double>::epsilon()) return std::abs(p.m_pCoords[1] - m_pStartPoint[1]);
+
+ double x1 = m_pStartPoint[0];
+ double x2 = m_pEndPoint[0];
+ double x0 = p.m_pCoords[0];
+ double y1 = m_pStartPoint[1];
+ double y2 = m_pEndPoint[1];
+ double y0 = p.m_pCoords[1];
+
+ return std::abs((x2 - x1) * (y1 - y0) - (x1 - x0) * (y2 - y1)) / (std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
+}
+
+// assuming moving from start to end, positive distance is from right hand side.
+double LineSegment::getRelativeMinimumDistance(const Point& p) const
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMinimumDistance: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMinimumDistance: Distance for high dimensional spaces not supported!"
+ );
+
+ if (m_pEndPoint[0] >= m_pStartPoint[0] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[0] <= m_pStartPoint[0] + std::numeric_limits<double>::epsilon())
+ {
+ if (m_pStartPoint[1] < m_pEndPoint[1]) return m_pStartPoint[0] - p.m_pCoords[0];
+ if (m_pStartPoint[1] >= m_pEndPoint[1]) return p.m_pCoords[0] - m_pStartPoint[0];
+ }
+
+ if (m_pEndPoint[1] >= m_pStartPoint[1] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[1] <= m_pStartPoint[1] + std::numeric_limits<double>::epsilon())
+ {
+ if (m_pStartPoint[0] < m_pEndPoint[0]) return p.m_pCoords[1] - m_pStartPoint[1];
+ if (m_pStartPoint[0] >= m_pEndPoint[0]) return m_pStartPoint[1] - p.m_pCoords[1];
+ }
+
+ double x1 = m_pStartPoint[0];
+ double x2 = m_pEndPoint[0];
+ double x0 = p.m_pCoords[0];
+ double y1 = m_pStartPoint[1];
+ double y2 = m_pEndPoint[1];
+ double y0 = p.m_pCoords[1];
+
+ return ((x1 - x0) * (y2 - y1) - (x2 - x1) * (y1 - y0)) / (std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
+}
+
+double LineSegment::getRelativeMaximumDistance(const Region& r) const
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMaximumDistance: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMaximumDistance: Distance for high dimensional spaces not supported!"
+ );
+
+ // clockwise.
+ double d1 = getRelativeMinimumDistance(Point(r.m_pLow, 2));
+
+ double coords[2];
+ coords[0] = r.m_pLow[0];
+ coords[1] = r.m_pHigh[1];
+ double d2 = getRelativeMinimumDistance(Point(coords, 2));
+
+ double d3 = getRelativeMinimumDistance(Point(r.m_pHigh, 2));
+
+ coords[0] = r.m_pHigh[0];
+ coords[1] = r.m_pLow[1];
+ double d4 = getRelativeMinimumDistance(Point(coords, 2));
+
+ return std::max(d1, std::max(d2, std::max(d3, d4)));
+}
+
+double LineSegment::getAngleOfPerpendicularRay()
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getAngleOfPerpendicularRay: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getAngleOfPerpendicularRay: Distance for high dimensional spaces not supported!"
+ );
+
+ if (m_pStartPoint[0] >= m_pEndPoint[0] - std::numeric_limits<double>::epsilon() &&
+ m_pStartPoint[0] <= m_pEndPoint[0] + std::numeric_limits<double>::epsilon()) return 0.0;
+
+ if (m_pStartPoint[1] >= m_pEndPoint[1] - std::numeric_limits<double>::epsilon() &&
+ m_pStartPoint[1] <= m_pEndPoint[1] + std::numeric_limits<double>::epsilon()) return M_PI_2;
+
+ return std::atan(-(m_pStartPoint[0] - m_pEndPoint[0]) / (m_pStartPoint[1] - m_pEndPoint[1]));
+}
+
+void LineSegment::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pStartPoint[cIndex] = std::numeric_limits<double>::max();
+ m_pEndPoint[cIndex] = std::numeric_limits<double>::max();
+ }
+}
+
+void LineSegment::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pStartPoint;
+ delete[] m_pEndPoint;
+
+ // remember that this is not a constructor. The object will be destructed normally if
+ // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
+ m_pStartPoint = 0;
+ m_pEndPoint = 0;
+
+ m_dimension = dimension;
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, const LineSegment& l)
+{
+ for (uint32_t cDim = 0; cDim < l.m_dimension; ++cDim)
+ {
+ os << l.m_pStartPoint[cDim] << ", " << l.m_pEndPoint[cDim] << " ";
+ }
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..6a0adc928
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = liblibrary.la
+INCLUDES = -I../../include
+liblibrary_la_SOURCES = Point.cc Region.cc LineSegment.cc MovingPoint.cc MovingRegion.cc TimePoint.cc TimeRegion.cc SpatialIndexImpl.cc SpatialIndexImpl.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingPoint.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingPoint.cc.svn-base
new file mode 100644
index 000000000..d3a33cb59
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingPoint.cc.svn-base
@@ -0,0 +1,299 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+MovingPoint::MovingPoint()
+{
+}
+
+MovingPoint::MovingPoint(const double* pCoords, const double* pVCoords, const IInterval& ti, uint32_t dimension)
+{
+ initialize(pCoords, pVCoords, ti.getLowerBound(), ti.getUpperBound(), dimension);
+}
+
+MovingPoint::MovingPoint(const double* pCoords, const double* pVCoords, double tStart, double tEnd, uint32_t dimension)
+{
+ initialize(pCoords, pVCoords, tStart, tEnd, dimension);
+}
+
+MovingPoint::MovingPoint(const Point& p, const Point& vp, const IInterval& ti)
+{
+ if (p.m_dimension != vp.m_dimension) throw Tools::IllegalArgumentException("MovingPoint: Points have different number of dimensions.");
+
+ initialize(p.m_pCoords, vp.m_pCoords, ti.getLowerBound(), ti.getUpperBound(), p.m_dimension);
+}
+
+MovingPoint::MovingPoint(const Point& p, const Point& vp, double tStart, double tEnd)
+{
+ if (p.m_dimension != vp.m_dimension) throw Tools::IllegalArgumentException("MovingPoint: Points have different number of dimensions.");
+
+ initialize(p.m_pCoords, vp.m_pCoords, tStart, tEnd, p.m_dimension);
+}
+
+MovingPoint::MovingPoint(const MovingPoint& p)
+{
+ m_startTime = p.m_startTime;
+ m_endTime = p.m_endTime;
+ m_pCoords = 0;
+
+ m_dimension = p.m_dimension;
+
+ try
+ {
+ m_pCoords = new double[m_dimension];
+ m_pVCoords = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pCoords;
+ throw;
+ }
+
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVCoords, p.m_pVCoords, m_dimension * sizeof(double));
+}
+
+MovingPoint::~MovingPoint()
+{
+ delete[] m_pVCoords;
+}
+
+void MovingPoint::initialize(
+ const double* pCoords, const double* pVCoords,
+ double tStart, double tEnd, uint32_t dimension)
+{
+ m_dimension = dimension;
+ m_startTime = tStart;
+ m_endTime = tEnd;
+ m_pCoords = 0;
+
+ if (m_endTime <= m_startTime) throw Tools::IllegalArgumentException("MovingPoint: Cannot support degenerate time intervals.");
+
+ try
+ {
+ m_pCoords = new double[m_dimension];
+ m_pVCoords = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pCoords;
+ throw;
+ }
+
+ // first store the point coordinates, than the point velocities.
+ memcpy(m_pCoords, pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVCoords, pVCoords, m_dimension * sizeof(double));
+}
+
+MovingPoint& MovingPoint::operator=(const MovingPoint& p)
+{
+ if (this != &p)
+ {
+ makeDimension(p.m_dimension);
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVCoords, p.m_pVCoords, m_dimension * sizeof(double));
+
+ m_startTime = p.m_startTime;
+ m_endTime = p.m_endTime;
+ }
+
+ return *this;
+}
+
+bool MovingPoint::operator==(const MovingPoint& p) const
+{
+ if (
+ m_startTime < p.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > p.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < p.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > p.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t cDim = 0; cDim < 2 * m_dimension; ++cDim)
+ {
+ if (
+ m_pCoords[cDim] < p.m_pCoords[cDim] - std::numeric_limits<double>::epsilon() ||
+ m_pCoords[cDim] > p.m_pCoords[cDim] + std::numeric_limits<double>::epsilon() ||
+ m_pVCoords[cDim] < p.m_pVCoords[cDim] - std::numeric_limits<double>::epsilon() ||
+ m_pVCoords[cDim] > p.m_pVCoords[cDim] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+
+ return true;
+}
+
+double MovingPoint::getCoord(uint32_t d, double t) const
+{
+ if (d < 0 && d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ if (t >= m_endTime) return m_pCoords[d] + m_pVCoords[d] * (m_endTime - m_startTime);
+ else if (t <= m_startTime) return m_pCoords[d] + m_pVCoords[d] * m_startTime;
+ else return m_pCoords[d] + m_pVCoords[d] * (t - m_startTime);
+}
+
+double MovingPoint::getProjectedCoord(uint32_t d, double t) const
+{
+ if (d < 0 && d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pCoords[d] + m_pVCoords[d] * (t - m_startTime);
+}
+
+double MovingPoint::getVCoord(uint32_t d) const
+{
+ if (d < 0 && d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pVCoords[d];
+}
+
+void MovingPoint::getPointAtTime(double t, Point& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ out.m_pCoords[cDim] = getCoord(cDim, t);
+ }
+}
+
+//
+// IObject interface
+//
+MovingPoint* MovingPoint::clone()
+{
+ return new MovingPoint(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t MovingPoint::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + 2 * m_dimension * sizeof(double));
+}
+
+void MovingPoint::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pVCoords, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void MovingPoint::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pVCoords, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IEvolvingShape interface
+//
+void MovingPoint::getVMBR(Region& out) const
+{
+ out.makeDimension(m_dimension);
+ memcpy(out.m_pLow, m_pVCoords, m_dimension * sizeof(double));
+ memcpy(out.m_pHigh, m_pVCoords, m_dimension * sizeof(double));
+}
+
+void MovingPoint::getMBRAtTime(double t, Region& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ out.m_pLow[cDim] = getCoord(cDim, t);
+ out.m_pHigh[cDim] = getCoord(cDim, t);
+ }
+}
+
+void MovingPoint::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pCoords[cIndex] = std::numeric_limits<double>::max();
+ m_pVCoords[cIndex] = -std::numeric_limits<double>::max();
+ }
+
+ m_startTime = std::numeric_limits<double>::max();
+ m_endTime = -std::numeric_limits<double>::max();
+}
+
+void MovingPoint::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pCoords;
+ delete[] m_pVCoords;
+ m_pCoords = 0; m_pVCoords = 0;
+
+ m_dimension = dimension;
+ m_pCoords = new double[m_dimension];
+ m_pVCoords = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const MovingPoint& pt)
+{
+ uint32_t i;
+
+ os << "Coords: ";
+ for (i = 0; i < pt.m_dimension; ++i)
+ {
+ os << pt.m_pCoords[i] << " ";
+ }
+
+ os << "VCoords: ";
+ for (i = 0; i < pt.m_dimension; ++i)
+ {
+ os << pt.m_pVCoords[i] << " ";
+ }
+
+ os << ", Start: " << pt.m_startTime << ", End: " << pt.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingRegion.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingRegion.cc.svn-base
new file mode 100644
index 000000000..8f54e4a37
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/MovingRegion.cc.svn-base
@@ -0,0 +1,1231 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+/*
+ * Does not support degenerate time intervals or shrinking regions.
+*/
+
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+MovingRegion::MovingRegion()
+ : TimeRegion(), m_pVLow(0), m_pVHigh(0)
+{
+}
+
+MovingRegion::MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ const IInterval& ivT, uint32_t dimension)
+{
+ initialize(pLow, pHigh, pVLow, pVHigh, ivT.getLowerBound(), ivT.getUpperBound(), dimension);
+}
+
+MovingRegion::MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension)
+{
+ initialize(pLow, pHigh, pVLow, pVHigh, tStart, tEnd, dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ const IInterval& ivT)
+{
+ if (low.m_dimension != high.m_dimension || low.m_dimension != vlow.m_dimension || vlow.m_dimension != vhigh.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(
+ low.m_pCoords, high.m_pCoords, vlow.m_pCoords, vhigh.m_pCoords,
+ ivT.getLowerBound(), ivT.getUpperBound(), low.m_dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ double tStart, double tEnd)
+{
+ if (low.m_dimension != high.m_dimension || low.m_dimension != vlow.m_dimension || vlow.m_dimension != vhigh.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(
+ low.m_pCoords, high.m_pCoords, vlow.m_pCoords, vhigh.m_pCoords,
+ tStart, tEnd, low.m_dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Region& mbr, const Region& vbr, const IInterval& ivT)
+{
+ if (mbr.m_dimension != vbr.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(mbr.m_pLow, mbr.m_pHigh, vbr.m_pLow, vbr.m_pHigh, ivT.getLowerBound(), ivT.getUpperBound(), mbr.m_dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Region& mbr, const Region& vbr, double tStart, double tEnd)
+{
+ if (mbr.m_dimension != vbr.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(mbr.m_pLow, mbr.m_pHigh, vbr.m_pLow, vbr.m_pHigh, tStart, tEnd, mbr.m_dimension);
+}
+
+MovingRegion::MovingRegion(const MovingPoint& low, const MovingPoint& high)
+{
+ m_startTime = low.m_startTime;
+ m_endTime = high.m_endTime;;
+ m_dimension = low.m_dimension;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ if (m_endTime <= m_startTime) throw Tools::IllegalArgumentException("MovingRegion: Cannot support degenerate time intervals.");
+
+ if (low.m_dimension != high.m_dimension) throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ throw;
+ }
+
+ memcpy(m_pLow, low.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pHigh, high.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVLow, low.m_pVCoords, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, high.m_pVCoords, m_dimension * sizeof(double));
+}
+
+MovingRegion::MovingRegion(const MovingRegion& r)
+{
+ m_startTime = r.m_startTime;
+ m_endTime = r.m_endTime;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ m_dimension = r.m_dimension;
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ throw;
+ }
+
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+ memcpy(m_pVLow, r.m_pVLow, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, r.m_pVHigh, m_dimension * sizeof(double));
+}
+
+void MovingRegion::initialize(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension)
+{
+ m_startTime = tStart;
+ m_endTime = tEnd;
+ m_dimension = dimension;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ if (m_endTime <= m_startTime) throw Tools::IllegalArgumentException("MovingRegion: Cannot support degenerate time intervals.");
+
+#ifndef NDEBUG
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (pLow[cDim] > pHigh[cDim]) throw Tools::IllegalArgumentException("MovingRegion: Low point has larger coordinates than High point.");
+ }
+#endif
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ throw;
+ }
+
+ // first store the point coordinates, than the point velocities.
+ memcpy(m_pLow, pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, pHigh, m_dimension * sizeof(double));
+ memcpy(m_pVLow, pVLow, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, pVHigh, m_dimension * sizeof(double));
+}
+
+MovingRegion::~MovingRegion()
+{
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+}
+
+MovingRegion& MovingRegion::operator=(const MovingRegion& r)
+{
+ if(this != &r)
+ {
+ makeDimension(r.m_dimension);
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+ memcpy(m_pVLow, r.m_pVLow, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, r.m_pVHigh, m_dimension * sizeof(double));
+
+ m_startTime = r.m_startTime;
+ m_endTime = r.m_endTime;
+
+ assert(m_startTime < m_endTime);
+ }
+
+ return *this;
+}
+
+bool MovingRegion::operator==(const MovingRegion& r) const
+{
+ if (m_startTime < r.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > r.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < r.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > r.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon() ||
+ m_pVLow[i] < r.m_pVLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pVLow[i] > r.m_pVLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pVHigh[i] < r.m_pVHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pVHigh[i] > r.m_pVHigh[i] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+ return true;
+}
+
+bool MovingRegion::isShrinking() const
+{
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (m_pVHigh[cDim] < m_pVLow[cDim]) return true;
+ }
+ return false;
+}
+
+// assumes that the region is not moving before and after start and end time.
+double MovingRegion::getLow(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ if (t > m_endTime) return m_pLow[d] + m_pVLow[d] * (m_endTime - m_startTime);
+ else if (t < m_startTime) return m_pLow[d];
+ else return m_pLow[d] + m_pVLow[d] * (t - m_startTime);
+}
+
+// assumes that the region is not moving before and after start and end time.
+double MovingRegion::getHigh(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ if (t > m_endTime) return m_pHigh[d] + m_pVHigh[d] * (m_endTime - m_startTime);
+ else if (t < m_startTime) return m_pHigh[d];
+ else return m_pHigh[d] + m_pVHigh[d] * (t - m_startTime);
+}
+
+// assuming that the region kept moving.
+double MovingRegion::getExtrapolatedLow(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pLow[d] + m_pVLow[d] * (t - m_startTime);
+}
+
+// assuming that the region kept moving.
+double MovingRegion::getExtrapolatedHigh(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pHigh[d] + m_pVHigh[d] * (t - m_startTime);
+}
+
+double MovingRegion::getVLow(uint32_t d) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pVLow[d];
+}
+
+double MovingRegion::getVHigh(uint32_t d) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pVHigh[d];
+}
+
+bool MovingRegion::intersectsRegionInTime(const MovingRegion& r) const
+{
+ Tools::Interval ivOut;
+ return intersectsRegionInTime(r, ivOut);
+}
+
+bool MovingRegion::intersectsRegionInTime(const MovingRegion& r, IInterval& ivOut) const
+{
+ return intersectsRegionInTime(r, r, ivOut);
+}
+
+// if tmin, tmax are infinity then this will not work correctly (everything will always intersect).
+// does not work for shrinking regions.
+// does not work with degenerate time-intervals.
+//
+// WARNING: this will return true even if one region completely contains the other, since
+// their areas do intersect in that case!
+//
+// there are various cases here:
+// 1. one region contains the other.
+// 2. one boundary of one region is always contained indide the other region, while the other
+// boundary is not (so no boundaries will ever intersect).
+// 3. either the upper or lower boundary of one region intersects a boundary of the other.
+bool MovingRegion::intersectsRegionInTime(const IInterval& ivPeriod, const MovingRegion& r, IInterval& ivOut) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("intersectsRegionInTime: MovingRegions have different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(r.m_startTime < r.m_endTime);
+ assert(ivPeriod.getLowerBound() < ivPeriod.getUpperBound());
+ assert(isShrinking() == false && r.isShrinking() == false);
+
+ // this is needed, since we are assuming below that the two regions have some point of intersection
+ // inside itPeriod.
+ if (containsRegionInTime(ivPeriod, r) || r.containsRegionInTime(ivPeriod, *this))
+ {
+ ivOut = ivPeriod;
+ return true;
+ }
+
+ double tmin = std::max(m_startTime, r.m_startTime);
+ double tmax = std::min(m_endTime, r.m_endTime);
+
+ // the regions do not intersect in time.
+ if (tmax <= tmin) return false;
+
+ tmin = std::max(tmin, ivPeriod.getLowerBound());
+ tmax = std::min(tmax, ivPeriod.getUpperBound());
+
+ // the regions intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return false;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ // I use projected low and high because they are faster and it does not matter.
+ // The are also necessary for calculating the intersection point with reference time instant 0.0.
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= r.m_startTime && tmax <= r.m_endTime);
+
+ // completely above or bellow in i-th dimension
+ if (
+ (r.getExtrapolatedLow(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) &&
+ r.getExtrapolatedLow(cDim, tmax) >= getExtrapolatedHigh(cDim, tmax)) ||
+ (r.getExtrapolatedHigh(cDim, tmin) < getExtrapolatedLow(cDim, tmin) &&
+ r.getExtrapolatedHigh(cDim, tmax) <= getExtrapolatedLow(cDim, tmax)))
+ return false;
+
+ // otherwise they intersect inside this interval for sure. Care needs to be taken since
+ // intersection does not necessarily mean that two line segments intersect. It could be
+ // that one line segment is completely above/below another, in which case there is no intersection
+ // point inside tmin, tmax, even though the two region areas do intersect.
+
+ if (r.getExtrapolatedLow(cDim, tmin) > getExtrapolatedHigh(cDim, tmin)) // r above *this at tmin
+ {
+ tmin = (getExtrapolatedHigh(cDim, 0.0) - r.getExtrapolatedLow(cDim, 0.0)) / (r.getVLow(cDim) - getVHigh(cDim));
+ }
+ else if (r.getExtrapolatedHigh(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) // r below *this at tmin
+ {
+ tmin = (getExtrapolatedLow(cDim, 0.0) - r.getExtrapolatedHigh(cDim, 0.0)) / (r.getVHigh(cDim) - getVLow(cDim));
+ }
+ // else they do not intersect and the boundary might be completely contained in this region.
+
+ if (r.getExtrapolatedLow(cDim, tmax) > getExtrapolatedHigh(cDim, tmax)) // r above *this at tmax
+ {
+ tmax = (getExtrapolatedHigh(cDim, 0.0) - r.getExtrapolatedLow(cDim, 0.0)) / (r.getVLow(cDim) - getVHigh(cDim));
+ }
+ else if (r.getExtrapolatedHigh(cDim, tmax) < getExtrapolatedLow(cDim, tmax)) // r below *this at tmax
+ {
+ tmax = (getExtrapolatedLow(cDim, 0.0) - r.getExtrapolatedHigh(cDim, 0.0)) / (r.getVHigh(cDim) - getVLow(cDim));
+ }
+ // else they do not intersect and the boundary might be completely contained in this region.
+
+ assert(tmin <= tmax);
+ }
+
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= r.m_startTime && tmax <= r.m_endTime);
+
+ ivOut.setBounds(tmin, tmax);
+
+ return true;
+}
+
+bool MovingRegion::containsRegionInTime(const MovingRegion& r) const
+{
+ return containsRegionInTime(r, r);
+}
+
+// does not work for shrinking regions.
+// works fine for infinite bounds (both tmin and tmax).
+// does not work with degenerate time-intervals.
+//
+// finds if during the intersecting time-interval of r and ivPeriod, r is completely contained in *this.
+bool MovingRegion::containsRegionInTime(const IInterval& ivPeriod, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("containsRegionInTime: MovingRegions have different number of dimensions.");
+
+ assert(isShrinking() == false && r.isShrinking() == false);
+
+ double tmin = std::max(ivPeriod.getLowerBound(), r.m_startTime);
+ double tmax = std::min(ivPeriod.getUpperBound(), r.m_endTime);
+
+ // it should be contained in time.
+ // it does not make sense if this region is not defined for any part ot [tmin, tmax].
+ if (tmax <= tmin || tmin < m_startTime || tmax > m_endTime) return false;
+
+ double intersectionTime;
+
+ // no need to take projected coordinates here, since tmin and tmax are always contained in
+ // the regions intersecting time-intervals.
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= r.m_startTime && tmax <= r.m_endTime);
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ // it should be contained at start time.
+ if (r.getExtrapolatedHigh(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) ||
+ r.getExtrapolatedLow(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) return false;
+
+ // this will take care of infinite bounds.
+ if (r.m_pVHigh[cDim] != m_pVHigh[cDim])
+ {
+ intersectionTime = (getExtrapolatedHigh(cDim, 0.0) - r.getExtrapolatedHigh(cDim, 0.0)) / (r.m_pVHigh[cDim] - m_pVHigh[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && r.m_pVHigh[cDim] > m_pVHigh[cDim]) return false;
+ }
+
+ if (r.m_pVLow[cDim] != m_pVLow[cDim])
+ {
+ intersectionTime = (getExtrapolatedLow(cDim, 0.0) - r.getExtrapolatedLow(cDim, 0.0)) / (r.m_pVLow[cDim] - m_pVLow[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && r.m_pVLow[cDim] < m_pVLow[cDim]) return false;
+ }
+ }
+
+ return true;
+}
+
+bool MovingRegion::containsRegionAfterTime(double t, const MovingRegion& r) const
+{
+ Tools::Interval ivT(t, r.m_endTime);
+ return containsRegionInTime(ivT, r);
+}
+
+// Returns the area swept by the rectangle in time, in d-dimensional space (without
+// including the temporal dimension, that is).
+// This is what Saltenis calls Margin (which is different than what Beckmann proposes,
+// where he computes only the wireframe -- instead of the surface/volume/etc. -- of the MBR in any dimension).
+double MovingRegion::getProjectedSurfaceAreaInTime() const
+{
+ return getProjectedSurfaceAreaInTime(*this);
+}
+
+double MovingRegion::getProjectedSurfaceAreaInTime(const IInterval& ivI) const
+{
+ double tmin = std::max(ivI.getLowerBound(), m_startTime);
+ double tmax = std::min(ivI.getUpperBound(), m_endTime);
+
+ assert(tmin > -std::numeric_limits<double>::max());
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin <= tmax);
+
+ if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
+ tmin <= tmax + std::numeric_limits<double>::epsilon())
+ return 0.0;
+
+ double dx1, dx2, dx3;
+ double dv1, dv2, dv3;
+ double H = tmax - tmin;
+
+ if (m_dimension == 3)
+ {
+ dx3 = getExtrapolatedHigh(2, tmin) - getExtrapolatedLow(2, tmin);
+ dv3 = getVHigh(2) - getVLow(2);
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return
+ H * (dx1 + dx2 + dx3 + dx1*dx2 + dx1*dx3 + dx2*dx3) +
+ H*H * (dv1 + dv2 + dv3 + dx1*dv2 + dv1*dx2 + dx1*dv3 +
+ dv1*dx3 + dx2*dv3 + dv2*dx3) / 2.0 +
+ H*H*H * (dv1*dv2 + dv1*dv3 + dv2*dv3) / 3.0;
+ }
+ else if (m_dimension == 2)
+ {
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return H * (dx1 + dx2) + H * H * (dv1 + dv2) / 2.0;
+ }
+ else if (m_dimension == 1)
+ {
+ // marioh: why not use the increase of the length of the interval here?
+ return 0.0;
+ }
+ else
+ {
+ throw Tools::IllegalStateException("getProjectedSurfaceAreaInTime: unsupported dimensionality.");
+ }
+}
+
+double MovingRegion::getCenterDistanceInTime(const MovingRegion& r) const
+{
+
+ return getCenterDistanceInTime(r, r);
+}
+
+double MovingRegion::getCenterDistanceInTime(const IInterval& ivI, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("getCenterDistanceInTime: MovingRegions have different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(r.m_startTime < r.m_endTime);
+ assert(ivI.getLowerBound() < ivI.getUpperBound());
+
+ double tmin = std::max(m_startTime, r.m_startTime);
+ double tmax = std::min(m_endTime, r.m_endTime);
+
+ // the regions do not intersect in time.
+ if (tmax <= tmin) return 0.0;
+
+ tmin = std::max(tmin, ivI.getLowerBound());
+ tmax = std::min(tmax, ivI.getUpperBound());
+
+ // the regions intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return 0.0;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
+ tmin <= tmax + std::numeric_limits<double>::epsilon())
+ return 0.0;
+
+ double H = tmax - tmin;
+
+ double* dx = new double[m_dimension];
+ double* dv = new double[m_dimension];
+ double a = 0.0, b = 0.0, c = 0.0, f = 0.0, l = 0.0, m = 0.0, n = 0.0;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ dx[cDim] =
+ (r.getExtrapolatedLow(cDim, tmin) + r.getExtrapolatedHigh(cDim, tmin)) / 2.0 -
+ (getExtrapolatedLow(cDim, tmin) + getExtrapolatedHigh(cDim, tmin)) / 2.0;
+ dv[cDim] =
+ (r.getVLow(cDim) + r.getVHigh(cDim)) / 2.0 -
+ (getVLow(cDim) + getVHigh(cDim)) / 2.0;
+ }
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ a += dv[cDim] * dv[cDim];
+ b += 2.0 * dx[cDim] * dv[cDim];
+ c += dx[cDim] * dx[cDim];
+ }
+
+ if (a == 0.0 && c == 0.0) return 0.0;
+ if (a == 0.0) return H * std::sqrt(c);
+ if (c == 0.0) return H * H * std::sqrt(a) / 2.0;
+
+ f = std::sqrt(a * H * H + b * H + c);
+ l = 2.0 * a * H + b;
+ m = 4.0 * a * c - b * b;
+ n = 2.0 * std::sqrt(a);
+
+ delete[] dx;
+ delete[] dv;
+
+ return (l * f + log(l / n + f) * m / n - b * std::sqrt(c) - std::log(b / n + std::sqrt(c)) * m / n) / (4.0 * a);
+}
+
+// does not work with degenerate time-intervals.
+bool MovingRegion::intersectsRegionAtTime(double t, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("intersectsRegionAtTime: MovingRegions have different number of dimensions.");
+
+ // do they contain the time instant?
+ if (! (m_startTime <= t && t < m_endTime && r.m_startTime <= t && t < r.m_endTime)) return false;
+
+ // do they intersect at that time instant?
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (getExtrapolatedLow(i, t) > r.getExtrapolatedHigh(i, t) || getExtrapolatedHigh(i, t) < r.getExtrapolatedLow(i, t)) return false;
+ }
+ return true;
+}
+
+// does not work with degenerate time-intervals.
+bool MovingRegion::containsRegionAtTime(double t, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("containsRegionAtTime: MovingRegions have different number of dimensions.");
+
+ // do they contain the time instant?
+ if (! (m_startTime <= t && t < m_endTime && r.m_startTime <= t && t < r.m_endTime)) return false;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (getExtrapolatedLow(cDim, t) > r.getExtrapolatedLow(cDim, t) || getExtrapolatedHigh(cDim, t) < getExtrapolatedHigh(cDim, t)) return false;
+ }
+ return true;
+}
+
+bool MovingRegion::intersectsPointInTime(const MovingPoint& p) const
+{
+ Tools::Interval ivOut;
+ return intersectsPointInTime(p, ivOut);
+}
+
+bool MovingRegion::intersectsPointInTime(const MovingPoint& p, IInterval& ivOut) const
+{
+ return intersectsPointInTime(p, p, ivOut);
+}
+
+// if tmin, tmax are infinity then this will not work correctly (everything will always intersect).
+// does not work for shrinking regions.
+// does not work with degenerate time-intervals.
+// FIXME: don't know what happens if tmin is negative infinity.
+//
+// WARNING: This will return true even if the region completely contains the point, since
+// in that case the point trajectory intersects the region area!
+bool MovingRegion::intersectsPointInTime(const IInterval& ivPeriod, const MovingPoint& p, IInterval& ivOut) const
+{
+ if (m_dimension != p.m_dimension) throw Tools::IllegalArgumentException("intersectsPointInTime: MovingPoint has different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(p.m_startTime < p.m_endTime);
+ assert(ivPeriod.getLowerBound() < ivPeriod.getUpperBound());
+ assert(isShrinking() == false);
+
+ if (containsPointInTime(ivPeriod, p))
+ {
+ ivOut = ivPeriod;
+ return true;
+ }
+
+ double tmin = std::max(m_startTime, p.m_startTime);
+ double tmax = std::min(m_endTime, p.m_endTime);
+
+ // the shapes do not intersect in time.
+ if (tmax <= tmin) return false;
+
+ tmin = std::max(tmin, ivPeriod.getLowerBound());
+ tmax = std::min(tmax, ivPeriod.getUpperBound());
+
+ // the shapes intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return false;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= p.m_startTime && tmax <= p.m_endTime);
+
+ // completely above or bellow in i-th dimension
+ if ((p.getProjectedCoord(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) &&
+ p.getProjectedCoord(cDim, tmax) >= getExtrapolatedHigh(cDim, tmax)) ||
+ (p.getProjectedCoord(cDim, tmin) < getExtrapolatedLow(cDim, tmin) &&
+ p.getProjectedCoord(cDim, tmax) <= getExtrapolatedLow(cDim, tmax)))
+ return false;
+
+ // otherwise they intersect inside this interval for sure, since we know that the point is not contained,
+ // so there is no need to check for 0 divisors, negative values, etc...
+
+ // adjust tmin
+ if (p.getProjectedCoord(cDim, tmin) > getExtrapolatedHigh(cDim, tmin)) // p above *this at tmin
+ {
+ tmin = (getExtrapolatedHigh(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVHigh(cDim));
+ }
+ else if (p.getProjectedCoord(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) // p below *this at tmin
+ {
+ tmin = (getExtrapolatedLow(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVLow(cDim));
+ }
+
+ // adjust tmax
+ if (p.getProjectedCoord(cDim, tmax) > getExtrapolatedHigh(cDim, tmax)) // p above *this at tmax
+ {
+ tmax = (getExtrapolatedHigh(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVHigh(cDim));
+ }
+ else if (p.getProjectedCoord(cDim, tmax) < getExtrapolatedLow(cDim, tmax)) // p below *this at tmax
+ {
+ tmax = (getExtrapolatedLow(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVLow(cDim));
+ }
+
+ if (tmin > tmax) return false;
+ }
+
+ ivOut.setBounds(tmin, tmax);
+
+ return true;
+}
+
+bool MovingRegion::containsPointInTime(const MovingPoint& p) const
+{
+ return containsPointInTime(p, p);
+}
+
+// does not work for shrinking regions.
+// works fine for infinite bounds (both tmin and tmax).
+// does not work with degenerate time-intervals.
+//
+// finds if during the intersecting time-interval of p and ivPeriod, p is completely contained in *this.
+bool MovingRegion::containsPointInTime(const IInterval& ivPeriod, const MovingPoint& p) const
+{
+ if (m_dimension != p.m_dimension) throw Tools::IllegalArgumentException("containsPointInTime: MovingPoint has different number of dimensions.");
+
+ assert(isShrinking() == false);
+
+ double tmin = std::max(ivPeriod.getLowerBound(), p.m_startTime);
+ double tmax = std::min(ivPeriod.getUpperBound(), p.m_endTime);
+
+ // it should be contained in time.
+ if (tmax <= tmin || tmin < m_startTime || tmax > m_endTime) return false;
+
+ double intersectionTime;
+
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= p.m_startTime && tmax <= p.m_endTime);
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ // it should be contained at start time.
+ if (p.getProjectedCoord(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) ||
+ p.getProjectedCoord(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) return false;
+
+ if (p.m_pVCoords[cDim] != m_pVHigh[cDim])
+ {
+ intersectionTime = (getExtrapolatedHigh(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.m_pVCoords[cDim] - m_pVHigh[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && p.m_pVCoords[cDim] > m_pVHigh[cDim]) return false;
+ }
+
+ if (p.m_pVCoords[cDim] != m_pVLow[cDim])
+ {
+ intersectionTime = (getExtrapolatedLow(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.m_pVCoords[cDim] - m_pVLow[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && p.m_pVCoords[cDim] < m_pVLow[cDim]) return false;
+ }
+ }
+
+ return true;
+}
+
+void MovingRegion::combineRegionInTime(const MovingRegion& r)
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("combineRegionInTime: MovingRegions have different number of dimensions.");
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(getExtrapolatedLow(cDim, m_startTime), r.getExtrapolatedLow(cDim, m_startTime));
+ m_pHigh[cDim] = std::max(getExtrapolatedHigh(cDim, m_startTime), r.getExtrapolatedHigh(cDim, m_startTime));
+ m_pVLow[cDim] = std::min(m_pVLow[cDim], r.m_pVLow[cDim]);
+ m_pVHigh[cDim] = std::max(m_pVHigh[cDim], r.m_pVHigh[cDim]);
+ }
+
+ // m_startTime should be modified at the end, since it affects the
+ // calculation of extrapolated coordinates.
+ m_startTime = std::min(m_startTime, r.m_startTime);
+ m_endTime = std::max(m_endTime, r.m_endTime);
+}
+
+void MovingRegion::getCombinedRegionInTime(MovingRegion& out, const MovingRegion& in) const
+{
+ if (m_dimension != in.m_dimension) throw Tools::IllegalArgumentException("getCombinedProjectedRegionInTime: MovingRegions have different number of dimensions.");
+
+ out = *this;
+ out.combineRegionInTime(in);
+}
+
+void MovingRegion::combineRegionAfterTime(double t, const MovingRegion& r)
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("combineRegionInTime: MovingRegions have different number of dimensions.");
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(getExtrapolatedLow(cDim, t), r.getExtrapolatedLow(cDim, t));
+ m_pHigh[cDim] = std::max(getExtrapolatedHigh(cDim, t), r.getExtrapolatedHigh(cDim, t));
+ m_pVLow[cDim] = std::min(m_pVLow[cDim], r.m_pVLow[cDim]);
+ m_pVHigh[cDim] = std::max(m_pVHigh[cDim], r.m_pVHigh[cDim]);
+ }
+
+ // m_startTime should be modified at the end, since it affects the
+ // calculation of extrapolated coordinates.
+ m_startTime = t;
+ m_endTime = std::max(m_endTime, r.m_endTime);
+ if (t >= m_endTime) m_endTime = std::numeric_limits<double>::max();
+}
+
+void MovingRegion::getCombinedRegionAfterTime(double t, MovingRegion& out, const MovingRegion& in) const
+{
+ if (m_dimension != in.m_dimension) throw Tools::IllegalArgumentException("getCombinedProjectedRegionInTime: MovingRegions have different number of dimensions.");
+
+ out = *this;
+ out.combineRegionAfterTime(t, in);
+}
+
+double MovingRegion::getIntersectingAreaInTime(const MovingRegion& r) const
+{
+ return getIntersectingAreaInTime(r, r);
+}
+
+double MovingRegion::getIntersectingAreaInTime(const IInterval& ivI, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("getIntersectingAreaInTime: MovingRegions have different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(r.m_startTime < r.m_endTime);
+ assert(ivI.getLowerBound() < ivI.getUpperBound());
+ assert(isShrinking() == false && r.isShrinking() == false);
+
+ double tmin = std::max(m_startTime, r.m_startTime);
+ double tmax = std::min(m_endTime, r.m_endTime);
+
+ // the regions do not intersect in time.
+ if (tmax <= tmin) return 0.0;
+
+ tmin = std::max(tmin, ivI.getLowerBound());
+ tmax = std::min(tmax, ivI.getUpperBound());
+
+ // the regions intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return 0.0;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ Tools::Interval ivIn(tmin, tmax);
+ Tools::Interval ivOut(ivIn);
+
+ if (! intersectsRegionInTime(ivIn, r, ivOut)) return 0.0;
+
+ ivIn = ivOut;
+ tmin = ivIn.getLowerBound();
+ tmax = ivIn.getUpperBound();
+ assert(tmin <= tmax);
+
+ assert(tmin >= ivI.getLowerBound() && tmax <= ivI.getUpperBound());
+
+ if (containsRegionInTime(ivIn, r))
+ {
+ return r.getAreaInTime(ivIn);
+ }
+ else if (r.containsRegionInTime(ivIn, *this))
+ {
+ return getAreaInTime(ivIn);
+ }
+
+ MovingRegion x = *this;
+ CrossPoint c;
+ std::priority_queue<CrossPoint, std::vector<CrossPoint>, CrossPoint::ascending> pq;
+
+ // find points of intersection in all dimensions.
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (getLow(i, tmin) > r.getLow(i, tmin))
+ {
+ x.m_pLow[i] = m_pLow[i];
+ x.m_pVLow[i] = m_pVLow[i];
+
+ if (getLow(i, tmax) < r.getLow(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 0;
+ c.m_t = (getExtrapolatedLow(i, 0.0) - r.getExtrapolatedLow(i, 0.0)) / (r.getVLow(i) - getVLow(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = &r;
+ pq.push(c);
+ }
+ }
+ else
+ {
+ x.m_pLow[i] = r.m_pLow[i];
+ x.m_pVLow[i] = r.m_pVLow[i];
+
+ if (r.getLow(i, tmax) < getLow(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 0;
+ c.m_t = (getExtrapolatedLow(i, 0.0) - r.getExtrapolatedLow(i, 0.0)) / (r.getVLow(i) - getVLow(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = this;
+ pq.push(c);
+ }
+ }
+
+ if (getHigh(i, tmin) < r.getHigh(i, tmin))
+ {
+ x.m_pHigh[i] = m_pHigh[i];
+ x.m_pVHigh[i] = m_pVHigh[i];
+
+ if (getHigh(i, tmax) > r.getHigh(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 1;
+ c.m_t = (getExtrapolatedHigh(i, 0.0) - r.getExtrapolatedHigh(i, 0.0)) / (r.getVHigh(i) - getVHigh(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = &r;
+ pq.push(c);
+ }
+ }
+ else
+ {
+ x.m_pHigh[i] = r.m_pHigh[i];
+ x.m_pVHigh[i] = r.m_pVHigh[i];
+
+ if (r.getHigh(i, tmax) > getHigh(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 1;
+ c.m_t = (getExtrapolatedHigh(i, 0.0) - r.getExtrapolatedHigh(i, 0.0)) / (r.getVHigh(i) - getVHigh(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = this;
+ pq.push(c);
+ }
+ }
+ }
+
+ // add up the total area of the intersecting pieces.
+ double area = 0.0;
+#ifndef NDEBUG
+ double _t = -std::numeric_limits<double>::max();
+#endif
+
+ while (! pq.empty())
+ {
+ c = pq.top(); pq.pop();
+#ifndef NDEBUG
+ assert(_t <= c.m_t);
+ _t = c.m_t;
+#endif
+
+ // needed in case two consecutive points have the same intersection time.
+ if (c.m_t > tmin) area += x.getAreaInTime(Tools::Interval(tmin, c.m_t));
+
+ if (c.m_boundary == 0)
+ {
+ x.m_pLow[c.m_dimension] = c.m_to->m_pLow[c.m_dimension];
+ x.m_pVLow[c.m_dimension] = c.m_to->m_pVLow[c.m_dimension];
+ }
+ else
+ {
+ x.m_pHigh[c.m_dimension] = c.m_to->m_pHigh[c.m_dimension];
+ x.m_pVHigh[c.m_dimension] = c.m_to->m_pVHigh[c.m_dimension];
+ }
+
+ tmin = c.m_t;
+ }
+
+ // ... and the last piece
+ if (tmax > tmin) area += x.getAreaInTime(Tools::Interval(tmin, tmax));
+
+ return area;
+}
+
+//
+// IObject interface
+//
+MovingRegion* MovingRegion::clone()
+{
+ return new MovingRegion(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t MovingRegion::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + 4 * m_dimension * sizeof(double));
+}
+
+void MovingRegion::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pVLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pVHigh, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void MovingRegion::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, m_pLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pVLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pVHigh, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IEvolvingShape interface
+//
+void MovingRegion::getVMBR(Region& out) const
+{
+ out.makeDimension(m_dimension);
+ memcpy(out.m_pLow, m_pVLow, m_dimension * sizeof(double));
+ memcpy(out.m_pHigh, m_pVHigh, m_dimension * sizeof(double));
+}
+
+void MovingRegion::getMBRAtTime(double t, Region& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ out.m_pLow[cDim] = getLow(cDim, t);
+ out.m_pHigh[cDim] = getHigh(cDim, t);
+ }
+}
+
+//
+// ITimeShape interface
+//
+double MovingRegion::getAreaInTime() const
+{
+ return getAreaInTime(*this);
+}
+
+// this computes the area/volume/etc. swept by the Region in time.
+double MovingRegion::getAreaInTime(const IInterval& ivI) const
+{
+ double tmin = std::max(ivI.getLowerBound(), m_startTime);
+ double tmax = std::min(ivI.getUpperBound(), m_endTime);
+
+ assert(tmin > -std::numeric_limits<double>::max());
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin <= tmax);
+
+ if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
+ tmin <= tmax + std::numeric_limits<double>::epsilon())
+ return 0.0;
+
+ double dx1, dx2, dx3;
+ double dv1, dv2, dv3;
+ double H = tmax - tmin;
+
+ if (m_dimension == 3)
+ {
+ dx3 = getExtrapolatedHigh(2, tmin) - getExtrapolatedLow(2, tmin);
+ dv3 = getVHigh(2) - getVLow(2);
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return
+ H * dx1 * dx2 * dx3 + H * H * (dx1 * dx2 * dv3 + (dx1 * dv2 + dv1 * dx2) * dx3) / 2.0 +
+ H * H * H * ((dx1 * dv2 + dv1 * dx2) * dv3 + dv1 * dv2 * dx3) / 3.0 + H * H * H * H * dv1 * dv2 * dv3 / 4.0;
+ }
+ else if (m_dimension == 2)
+ {
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return H * dx1 * dx2 + H * H * (dx1 * dv2 + dv1 * dx2) / 2.0 + H * H * H * dv1 * dv2 / 3.0;
+ }
+ else if (m_dimension == 1)
+ {
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return H * dx1 + H * H * dv1 / 2.0;
+ }
+ else
+ {
+ throw Tools::NotSupportedException("getAreaInTime: unsupported dimensionality.");
+ }
+}
+
+double MovingRegion::getIntersectingAreaInTime(const ITimeShape& r) const
+{
+ return getIntersectingAreaInTime(r, r);
+}
+
+double MovingRegion::getIntersectingAreaInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ const MovingRegion* pr = dynamic_cast<const MovingRegion*>(&in);
+ if (pr != 0) return getIntersectingAreaInTime(*pr);
+
+ throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
+}
+
+void MovingRegion::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pLow[cIndex] = std::numeric_limits<double>::max();
+ m_pHigh[cIndex] = -std::numeric_limits<double>::max();
+ m_pVLow[cIndex] = std::numeric_limits<double>::max();
+ m_pVHigh[cIndex] = -std::numeric_limits<double>::max();
+ }
+
+ m_startTime = -std::numeric_limits<double>::max();
+ m_endTime = std::numeric_limits<double>::max();
+}
+
+void MovingRegion::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ m_dimension = dimension;
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const MovingRegion& r)
+{
+ uint32_t i;
+
+ os << "Low: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pLow[i] << " ";
+ }
+
+ os << ", High: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pHigh[i] << " ";
+ }
+
+ os << "VLow: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pVLow[i] << " ";
+ }
+
+ os << ", VHigh: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pVHigh[i] << " ";
+ }
+
+ os << ", Start: " << r.m_startTime << ", End: " << r.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Point.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Point.cc.svn-base
new file mode 100644
index 000000000..8c36c1123
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Point.cc.svn-base
@@ -0,0 +1,262 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+Point::Point()
+ : m_dimension(0), m_pCoords(0)
+{
+}
+
+Point::Point(const double* pCoords, uint32_t dimension)
+ : m_dimension(dimension)
+{
+ // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pCoords = new double[m_dimension];
+ memcpy(m_pCoords, pCoords, m_dimension * sizeof(double));
+}
+
+Point::Point(const Point& p)
+ : m_dimension(p.m_dimension)
+{
+ // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pCoords = new double[m_dimension];
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+}
+
+Point::~Point()
+{
+ delete[] m_pCoords;
+}
+
+Point& Point::operator=(const Point& p)
+{
+ if (this != &p)
+ {
+ makeDimension(p.m_dimension);
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ }
+
+ return *this;
+}
+
+bool Point::operator==(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Point::operator==: Points have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pCoords[i] < p.m_pCoords[i] - std::numeric_limits<double>::epsilon() ||
+ m_pCoords[i] > p.m_pCoords[i] + std::numeric_limits<double>::epsilon()) return false;
+ }
+
+ return true;
+}
+
+//
+// IObject interface
+//
+Point* Point::clone()
+{
+ return new Point(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t Point::getByteArraySize()
+{
+ return (sizeof(uint32_t) + m_dimension * sizeof(double));
+}
+
+void Point::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ makeDimension(dimension);
+ memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void Point::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IShape interface
+//
+bool Point::intersectsShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->containsPoint(*this);
+ }
+
+ throw Tools::IllegalStateException(
+ "Point::intersectsShape: Not implemented yet!"
+ );
+}
+
+bool Point::containsShape(const IShape& s) const
+{
+ return false;
+}
+
+bool Point::touchesShape(const IShape& s) const
+{
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0)
+ {
+ if (*this == *ppt) return true;
+ return false;
+ }
+
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->touchesPoint(*this);
+ }
+
+ throw Tools::IllegalStateException(
+ "Point::touchesShape: Not implemented yet!"
+ );
+}
+
+void Point::getCenter(Point& out) const
+{
+ out = *this;
+}
+
+uint32_t Point::getDimension() const
+{
+ return m_dimension;
+}
+
+void Point::getMBR(Region& out) const
+{
+ out = Region(m_pCoords, m_pCoords, m_dimension);
+}
+
+double Point::getArea() const
+{
+ return 0.0;
+}
+
+double Point::getMinimumDistance(const IShape& s) const
+{
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0)
+ {
+ return getMinimumDistance(*ppt);
+ }
+
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->getMinimumDistance(*this);
+ }
+
+ throw Tools::IllegalStateException(
+ "Point::getMinimumDistance: Not implemented yet!"
+ );
+}
+
+double Point::getMinimumDistance(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Point::getMinimumDistance: Shapes have different number of dimensions."
+ );
+
+ double ret = 0.0;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ ret += std::pow(m_pCoords[cDim] - p.m_pCoords[cDim], 2.0);
+ }
+
+ return std::sqrt(ret);
+}
+
+double Point::getCoordinate(uint32_t index) const
+{
+ if (index < 0 || index >= m_dimension)
+ throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pCoords[index];
+}
+
+void Point::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pCoords[cIndex] = std::numeric_limits<double>::max();
+ }
+}
+
+void Point::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pCoords;
+
+ // remember that this is not a constructor. The object will be destructed normally if
+ // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
+ m_pCoords = 0;
+
+ m_dimension = dimension;
+ m_pCoords = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const Point& pt)
+{
+ for (uint32_t cDim = 0; cDim < pt.m_dimension; ++cDim)
+ {
+ os << pt.m_pCoords[cDim] << " ";
+ }
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Region.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Region.cc.svn-base
new file mode 100644
index 000000000..8db029831
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/Region.cc.svn-base
@@ -0,0 +1,554 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../../include/SpatialIndex.h"
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+using namespace SpatialIndex;
+
+Region::Region()
+ : m_dimension(0), m_pLow(0), m_pHigh(0)
+{
+}
+
+Region::Region(const double* pLow, const double* pHigh, uint32_t dimension)
+{
+ initialize(pLow, pHigh, dimension);
+}
+
+Region::Region(const Point& low, const Point& high)
+{
+ if (low.m_dimension != high.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::Region: arguments have different number of dimensions."
+ );
+
+ initialize(low.m_pCoords, high.m_pCoords, low.m_dimension);
+}
+
+Region::Region(const Region& r)
+{
+ initialize(r.m_pLow, r.m_pHigh, r.m_dimension);
+}
+
+void Region::initialize(const double* pLow, const double* pHigh, uint32_t dimension)
+{
+ m_pLow = 0;
+ m_dimension = dimension;
+
+#ifndef NDEBUG
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if ((pLow[cDim] > pHigh[cDim]))
+ {
+ // check for infinitive region
+ if (!(pLow[cDim] == std::numeric_limits<double>::max() ||
+ pHigh[cDim] == -std::numeric_limits<double>::max() ))
+ throw Tools::IllegalArgumentException(
+ "Region::initialize: Low point has larger coordinates than High point."
+ " Neither point is infinity."
+ );
+ }
+ }
+#endif
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ throw;
+ }
+
+ memcpy(m_pLow, pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, pHigh, m_dimension * sizeof(double));
+}
+
+Region::~Region()
+{
+ delete[] m_pLow;
+ delete[] m_pHigh;
+}
+
+Region& Region::operator=(const Region& r)
+{
+ if(this != &r)
+ {
+ makeDimension(r.m_dimension);
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+ }
+
+ return *this;
+}
+
+bool Region::operator==(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::operator==: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+ return true;
+}
+
+//
+// IObject interface
+//
+Region* Region::clone()
+{
+ return new Region(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t Region::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * m_dimension * sizeof(double));
+}
+
+void Region::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ makeDimension(dimension);
+ memcpy(m_pLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void Region::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, m_pLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IShape interface
+//
+bool Region::intersectsShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return intersectsRegion(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return containsPoint(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::intersectsShape: Not implemented yet!"
+ );
+}
+
+bool Region::containsShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return containsRegion(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return containsPoint(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::containsShape: Not implemented yet!"
+ );
+}
+
+bool Region::touchesShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return touchesRegion(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return touchesPoint(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::touchesShape: Not implemented yet!"
+ );
+}
+
+void Region::getCenter(Point& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ out.m_pCoords[i] = (m_pLow[i] + m_pHigh[i]) / 2.0;
+ }
+}
+
+uint32_t Region::getDimension() const
+{
+ return m_dimension;
+}
+
+void Region::getMBR(Region& out) const
+{
+ out = *this;
+}
+
+double Region::getArea() const
+{
+ double area = 1.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ area *= m_pHigh[i] - m_pLow[i];
+ }
+
+ return area;
+}
+
+double Region::getMinimumDistance(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return getMinimumDistance(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return getMinimumDistance(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::getMinimumDistance: Not implemented yet!"
+ );
+}
+
+bool Region::intersectsRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::intersectsRegion: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (m_pLow[i] > r.m_pHigh[i] || m_pHigh[i] < r.m_pLow[i]) return false;
+ }
+ return true;
+}
+
+bool Region::containsRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::containsRegion: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (m_pLow[i] > r.m_pLow[i] || m_pHigh[i] < r.m_pHigh[i]) return false;
+ }
+ return true;
+}
+
+bool Region::touchesRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::touchesRegion: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ (m_pLow[i] >= r.m_pLow[i] + std::numeric_limits<double>::epsilon() &&
+ m_pLow[i] <= r.m_pLow[i] - std::numeric_limits<double>::epsilon()) ||
+ (m_pHigh[i] >= r.m_pHigh[i] + std::numeric_limits<double>::epsilon() &&
+ m_pHigh[i] <= r.m_pHigh[i] - std::numeric_limits<double>::epsilon()))
+ return false;
+ }
+ return true;
+}
+
+double Region::getMinimumDistance(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getMinimumDistance: Regions have different number of dimensions."
+ );
+
+ double ret = 0.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ double x = 0.0;
+
+ if (r.m_pHigh[i] < m_pLow[i])
+ {
+ x = std::abs(r.m_pHigh[i] - m_pLow[i]);
+ }
+ else if (m_pHigh[i] < r.m_pLow[i])
+ {
+ x = std::abs(r.m_pLow[i] - m_pHigh[i]);
+ }
+
+ ret += x * x;
+ }
+
+ return std::sqrt(ret);
+}
+
+bool Region::containsPoint(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::containsPoint: Point has different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (m_pLow[i] > p.getCoordinate(i) || m_pHigh[i] < p.getCoordinate(i)) return false;
+ }
+ return true;
+}
+
+bool Region::touchesPoint(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::touchesPoint: Point has different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ (m_pLow[i] >= p.getCoordinate(i) - std::numeric_limits<double>::epsilon() &&
+ m_pLow[i] <= p.getCoordinate(i) + std::numeric_limits<double>::epsilon()) ||
+ (m_pHigh[i] >= p.getCoordinate(i) - std::numeric_limits<double>::epsilon() &&
+ m_pHigh[i] <= p.getCoordinate(i) + std::numeric_limits<double>::epsilon()))
+ return true;
+ }
+ return false;
+}
+
+double Region::getMinimumDistance(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getMinimumDistance: Point has different number of dimensions."
+ );
+
+ double ret = 0.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (p.getCoordinate(i) < m_pLow[i])
+ {
+ ret += std::pow(m_pLow[i] - p.getCoordinate(i), 2.0);
+ }
+ else if (p.getCoordinate(i) > m_pHigh[i])
+ {
+ ret += std::pow(p.getCoordinate(i) - m_pHigh[i], 2.0);
+ }
+ }
+
+ return std::sqrt(ret);
+}
+
+Region Region::getIntersectingRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getIntersectingRegion: Regions have different number of dimensions."
+ );
+
+ Region ret;
+ ret.makeInfinite(m_dimension);
+
+ // check for intersection.
+ // marioh: avoid function call since this is called billions of times.
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (m_pLow[cDim] > r.m_pHigh[cDim] || m_pHigh[cDim] < r.m_pLow[cDim]) return ret;
+ }
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ ret.m_pLow[cDim] = std::max(m_pLow[cDim], r.m_pLow[cDim]);
+ ret.m_pHigh[cDim] = std::min(m_pHigh[cDim], r.m_pHigh[cDim]);
+ }
+
+ return ret;
+}
+
+double Region::getIntersectingArea(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getIntersectingArea: Regions have different number of dimensions."
+ );
+
+ double ret = 1.0;
+ double f1, f2;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (m_pLow[cDim] > r.m_pHigh[cDim] || m_pHigh[cDim] < r.m_pLow[cDim]) return 0.0;
+
+ f1 = std::max(m_pLow[cDim], r.m_pLow[cDim]);
+ f2 = std::min(m_pHigh[cDim], r.m_pHigh[cDim]);
+ ret *= f2 - f1;
+ }
+
+ return ret;
+}
+
+/*
+ * Returns the margin of a region. It is calcuated as the sum of 2^(d-1) * width, in each dimension.
+ * It is actually the sum of all edges, no matter what the dimensionality is.
+*/
+double Region::getMargin() const
+{
+ double mul = std::pow(2.0, static_cast<double>(m_dimension) - 1.0);
+ double margin = 0.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ margin += (m_pHigh[i] - m_pLow[i]) * mul;
+ }
+
+ return margin;
+}
+
+void Region::combineRegion(const Region& r)
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::combineRegion: Region has different number of dimensions."
+ );
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(m_pLow[cDim], r.m_pLow[cDim]);
+ m_pHigh[cDim] = std::max(m_pHigh[cDim], r.m_pHigh[cDim]);
+ }
+}
+
+void Region::combinePoint(const Point& p)
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::combinePoint: Point has different number of dimensions."
+ );
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(m_pLow[cDim], p.m_pCoords[cDim]);
+ m_pHigh[cDim] = std::max(m_pHigh[cDim], p.m_pCoords[cDim]);
+ }
+}
+
+void Region::getCombinedRegion(Region& out, const Region& in) const
+{
+ if (m_dimension != in.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getCombinedRegion: Regions have different number of dimensions."
+ );
+
+ out = *this;
+ out.combineRegion(in);
+}
+
+double Region::getLow(uint32_t index) const
+{
+ if (index < 0 || index >= m_dimension)
+ throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pLow[index];
+}
+
+double Region::getHigh(uint32_t index) const
+{
+ if (index < 0 || index >= m_dimension)
+ throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pHigh[index];
+}
+
+void Region::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pLow[cIndex] = std::numeric_limits<double>::max();
+ m_pHigh[cIndex] = -std::numeric_limits<double>::max();
+ }
+}
+
+void Region::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+
+ // remember that this is not a constructor. The object will be destructed normally if
+ // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
+ m_pLow = 0; m_pHigh = 0;
+
+ m_dimension = dimension;
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const Region& r)
+{
+ uint32_t i;
+
+ os << "Low: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pLow[i] << " ";
+ }
+
+ os << ", High: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pHigh[i] << " ";
+ }
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.cc.svn-base
new file mode 100644
index 000000000..9d2bd11aa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.cc.svn-base
@@ -0,0 +1,93 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "SpatialIndexImpl.h"
+
+#include "../rtree/RTree.h"
+#include "../mvrtree/MVRTree.h"
+#include "../tprtree/TPRTree.h"
+
+SpatialIndex::InvalidPageException::InvalidPageException(id_type id)
+{
+ std::ostringstream s;
+ s << "Unknown page id " << id;
+ m_error = s.str();
+}
+
+std::string SpatialIndex::InvalidPageException::what()
+{
+ return "InvalidPageException: " + m_error;
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const ISpatialIndex& i)
+{
+ const SpatialIndex::RTree::RTree* pRTree = dynamic_cast<const SpatialIndex::RTree::RTree*>(&i);
+ if (pRTree != 0)
+ {
+ os << *pRTree;
+ return os;
+ }
+
+ const SpatialIndex::MVRTree::MVRTree* pMVRTree = dynamic_cast<const SpatialIndex::MVRTree::MVRTree*>(&i);
+ if (pMVRTree != 0)
+ {
+ os << *pMVRTree;
+ return os;
+ }
+
+ const SpatialIndex::TPRTree::TPRTree* pTPRTree = dynamic_cast<const SpatialIndex::TPRTree::TPRTree*>(&i);
+ if (pTPRTree != 0)
+ {
+ os << *pTPRTree;
+ return os;
+ }
+
+ std::cerr << "ISpatialIndex operator<<: Not implemented yet for this index type." << std::endl;
+ return os;
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const IStatistics& s)
+{
+ const SpatialIndex::RTree::Statistics* pRTreeStats = dynamic_cast<const SpatialIndex::RTree::Statistics*>(&s);
+ if (pRTreeStats != 0)
+ {
+ os << *pRTreeStats;
+ return os;
+ }
+
+ const SpatialIndex::MVRTree::Statistics* pMVRTreeStats = dynamic_cast<const SpatialIndex::MVRTree::Statistics*>(&s);
+ if (pMVRTreeStats != 0)
+ {
+ os << * pMVRTreeStats;
+ return os;
+ }
+
+ const SpatialIndex::TPRTree::Statistics* pTPRTreeStats = dynamic_cast<const SpatialIndex::TPRTree::Statistics*>(&s);
+ if (pTPRTreeStats != 0)
+ {
+ os << * pTPRTreeStats;
+ return os;
+ }
+
+ std::cerr << "IStatistics operator<<: Not implemented yet for this index type." << std::endl;
+ return os;
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.h.svn-base
new file mode 100644
index 000000000..5a24bbc6e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/SpatialIndexImpl.h.svn-base
@@ -0,0 +1,32 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+typedef Tools::PoolPointer<Region> RegionPtr;
+typedef Tools::PoolPointer<Point> PointPtr;
+typedef Tools::PoolPointer<TimeRegion> TimeRegionPtr;
+typedef Tools::PoolPointer<MovingRegion> MovingRegionPtr;
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimePoint.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimePoint.cc.svn-base
new file mode 100644
index 000000000..d860a0168
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimePoint.cc.svn-base
@@ -0,0 +1,297 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+TimePoint::TimePoint()
+ : Point(), m_startTime(-std::numeric_limits<double>::max()), m_endTime(std::numeric_limits<double>::max())
+{
+}
+
+TimePoint::TimePoint(const double* pCoords, const IInterval& ti, uint32_t dimension)
+ : Point(pCoords, dimension), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimePoint::TimePoint(const double* pCoords, double tStart, double tEnd, uint32_t dimension)
+ : Point(pCoords, dimension), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimePoint::TimePoint(const Point& p, const IInterval& ti)
+ : Point(p), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimePoint::TimePoint(const Point& p, double tStart, double tEnd)
+ : Point(p), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimePoint::TimePoint(const TimePoint& p)
+ : m_startTime(p.m_startTime), m_endTime(p.m_endTime)
+{
+ m_dimension = p.m_dimension;
+
+ m_pCoords = new double[m_dimension];
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+}
+
+TimePoint::~TimePoint()
+{
+}
+
+TimePoint& TimePoint::operator=(const TimePoint& p)
+{
+ if (this != &p)
+ {
+ makeDimension(p.m_dimension);
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ m_startTime = p.m_startTime;
+ m_endTime = p.m_endTime;
+ }
+
+ return *this;
+}
+
+bool TimePoint::operator==(const TimePoint& p) const
+{
+ if (
+ m_startTime < p.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > p.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < p.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > p.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (
+ m_pCoords[cDim] < p.m_pCoords[cDim] - std::numeric_limits<double>::epsilon() ||
+ m_pCoords[cDim] > p.m_pCoords[cDim] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+
+ return true;
+}
+
+//
+// IObject interface
+//
+TimePoint* TimePoint::clone()
+{
+ return new TimePoint(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t TimePoint::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + m_dimension * sizeof(double));
+}
+
+void TimePoint::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void TimePoint::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// ITimeShape interface
+//
+bool TimePoint::intersectsShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return pr->containsPointInTime(*this);
+
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimePoint::intersectsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimePoint::containsShapeInTime(const ITimeShape& in) const
+{
+ return false;
+}
+
+bool TimePoint::containsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ return false;
+}
+
+bool TimePoint::touchesShapeInTime(const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+bool TimePoint::touchesShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+double TimePoint::getAreaInTime() const
+{
+ return 0.0;
+}
+
+double TimePoint::getAreaInTime(const IInterval& ivI) const
+{
+ return 0.0;
+}
+
+double TimePoint::getIntersectingAreaInTime(const ITimeShape& r) const
+{
+ return 0.0;
+}
+
+double TimePoint::getIntersectingAreaInTime(const IInterval& ivI, const ITimeShape& r) const
+{
+ return 0.0;
+}
+
+//
+// IInterval interface
+//
+Tools::IInterval& TimePoint::operator=(const Tools::IInterval& i)
+{
+ if (this != &i)
+ {
+ m_startTime = i.getLowerBound();
+ m_endTime = i.getUpperBound();
+ }
+
+ return *this;
+}
+
+double TimePoint::getLowerBound() const
+{
+ return m_startTime;
+}
+
+double TimePoint::getUpperBound() const
+{
+ return m_endTime;
+}
+
+void TimePoint::setBounds(double l, double h)
+{
+ assert(l <= h);
+
+ m_startTime = l;
+ m_endTime = h;
+}
+
+bool TimePoint::intersectsInterval(const IInterval& ti) const
+{
+ return intersectsInterval(ti.getIntervalType(), ti.getLowerBound(), ti.getUpperBound());
+}
+
+bool TimePoint::intersectsInterval(Tools::IntervalType t, const double start, const double end) const
+{
+ //if (m_startTime != start &&
+ // (m_startTime >= end || m_endTime <= start)) return false;
+ if (m_startTime >= end || m_endTime <= start) return false;
+
+ return true;
+}
+
+bool TimePoint::containsInterval(const IInterval& ti) const
+{
+ if (m_startTime <= ti.getLowerBound() && m_endTime >= ti.getUpperBound()) return true;
+ return false;
+}
+
+Tools::IntervalType TimePoint::getIntervalType() const
+{
+ return Tools::IT_RIGHTOPEN;
+}
+
+void TimePoint::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pCoords[cIndex] = std::numeric_limits<double>::max();
+ }
+
+ m_startTime = std::numeric_limits<double>::max();
+ m_endTime = -std::numeric_limits<double>::max();
+}
+
+void TimePoint::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ m_dimension = dimension;
+
+ delete[] m_pCoords;
+ m_pCoords = 0;
+
+ m_pCoords = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const TimePoint& pt)
+{
+ uint32_t i;
+
+ for (i = 0; i < pt.m_dimension; ++i)
+ {
+ os << pt.m_pCoords[i] << " ";
+ }
+
+ os << ", Start: " << pt.m_startTime << ", End: " << pt.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimeRegion.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimeRegion.cc.svn-base
new file mode 100644
index 000000000..00d575223
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/.svn/text-base/TimeRegion.cc.svn-base
@@ -0,0 +1,419 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../../include/SpatialIndex.h"
+
+#include <cstring>
+#include <limits>
+
+using namespace SpatialIndex;
+
+TimeRegion::TimeRegion()
+ : Region(), m_startTime(-std::numeric_limits<double>::max()), m_endTime(std::numeric_limits<double>::max())
+{
+}
+
+TimeRegion::TimeRegion(const double* pLow, const double* pHigh, const IInterval& ti, uint32_t dimension)
+ : Region(pLow, pHigh, dimension), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimeRegion::TimeRegion(const double* pLow, const double* pHigh, double tStart, double tEnd, uint32_t dimension)
+ : Region(pLow, pHigh, dimension), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimeRegion::TimeRegion(const Point& low, const Point& high, const IInterval& ti)
+ : Region(low, high), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimeRegion::TimeRegion(const Point& low, const Point& high, double tStart, double tEnd)
+ : Region(low, high), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimeRegion::TimeRegion(const Region& r, const IInterval& ti)
+ : Region(r), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimeRegion::TimeRegion(const Region& r, double tStart, double tEnd)
+ : Region(r), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimeRegion::TimeRegion(const TimePoint& low, const TimePoint& high)
+ : Region((Point&) low, (Point&) high), m_startTime(low.m_startTime), m_endTime(high.m_endTime)
+{
+}
+
+TimeRegion::TimeRegion(const TimeRegion& r)
+ : m_startTime(r.m_startTime), m_endTime(r.m_endTime)
+{
+ m_dimension = r.m_dimension;
+ m_pLow = 0;
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ throw;
+ }
+
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+}
+
+TimeRegion::~TimeRegion()
+{
+}
+
+TimeRegion& TimeRegion::operator=(const TimeRegion& r)
+{
+ if(this != &r)
+ {
+ makeDimension(r.m_dimension);
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+
+ m_startTime = r.m_startTime;
+ m_endTime = r.m_endTime;
+ }
+
+ return *this;
+}
+
+bool TimeRegion::operator==(const TimeRegion& r) const
+{
+ if (m_startTime < r.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > r.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < r.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > r.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+ return true;
+}
+
+bool TimeRegion::intersectsRegionInTime(const TimeRegion& r) const
+{
+ // they should just intersect in time.
+ // check if they intersect in time first.
+ // the first check is needed for the following case:
+ // m_endTime == m_startTime == r.m_startTime.
+ // For open ended intervals this should be considered as an intersection
+ // (takes care of degenarate intervals)
+ //if (m_startTime != r.m_startTime &&
+ // (m_startTime >= r.m_endTime || m_endTime <= r.m_startTime))
+ if (! intersectsInterval(r)) return false;
+ return Region::intersectsRegion(r);
+}
+
+bool TimeRegion::containsRegionInTime(const TimeRegion& r) const
+{
+ // it should be contained in time.
+ if (! containsInterval(r)) return false;
+ return Region::containsRegion(r);
+}
+
+bool TimeRegion::touchesRegionInTime(const TimeRegion& r) const
+{
+ // they should just intersect in time.
+ //if (m_startTime != r.m_startTime &&
+ // (m_startTime >= r.m_endTime || m_endTime <= r.m_startTime))
+ if (!intersectsInterval(r)) return false;
+ return Region::touchesRegion(r);
+}
+
+bool TimeRegion::containsPointInTime(const TimePoint& p) const
+{
+ // it should be contained in time.
+ //if (p.m_startTime < m_startTime || p.m_endTime > m_endTime) return false;
+ if (containsInterval(p)) return false;
+ return Region::containsPoint(p);
+}
+
+bool TimeRegion::touchesPointInTime(const TimePoint& p) const
+{
+ // they should just intersect in time.
+ //if (m_startTime != p.m_startTime &&
+ // (m_startTime >= p.m_endTime || m_endTime <= p.m_startTime))
+ if (intersectsInterval(p)) return false;
+ return Region::touchesPoint(p);
+}
+
+void TimeRegion::combineRegionInTime(const TimeRegion& r)
+{
+ Region::combineRegion(r);
+
+ m_startTime = std::min(m_startTime, r.m_startTime);
+ m_endTime = std::max(m_endTime, r.m_endTime);
+}
+
+void TimeRegion::getCombinedRegionInTime(TimeRegion& out, const TimeRegion& in) const
+{
+ Region::getCombinedRegion(out, in);
+
+ out.m_startTime = std::min(m_startTime, in.m_startTime);
+ out.m_endTime = std::max(m_endTime, in.m_endTime);
+}
+
+//
+// IObject interface
+//
+TimeRegion* TimeRegion::clone()
+{
+ return new TimeRegion(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t TimeRegion::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + 2 * m_dimension * sizeof(double));
+}
+
+void TimeRegion::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void TimeRegion::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, m_pLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// ITimeShape interface
+//
+bool TimeRegion::intersectsShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return intersectsRegionInTime(*pr);
+
+ const TimePoint* ppt = dynamic_cast<const TimePoint*>(&in);
+ if (ppt != 0) return containsPointInTime(*ppt);
+
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::intersectsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::containsShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return containsRegionInTime(*pr);
+
+ const TimePoint* ppt = dynamic_cast<const TimePoint*>(&in);
+ if (ppt != 0) return containsPointInTime(*ppt);
+
+ throw Tools::IllegalStateException("containsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::containsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("containsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::touchesShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return touchesRegionInTime(*pr);
+
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::touchesShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+double TimeRegion::getAreaInTime() const
+{
+ throw Tools::IllegalStateException("getAreaInTime: Not implemented yet!");
+}
+
+double TimeRegion::getAreaInTime(const IInterval& ivI) const
+{
+ throw Tools::IllegalStateException("getAreaInTime: Not implemented yet!");
+}
+
+double TimeRegion::getIntersectingAreaInTime(const ITimeShape& r) const
+{
+ throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
+}
+
+double TimeRegion::getIntersectingAreaInTime(const IInterval& ivI, const ITimeShape& r) const
+{
+ throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
+}
+
+//
+// IInterval interface
+//
+Tools::IInterval& TimeRegion::operator=(const Tools::IInterval& i)
+{
+ if (this != &i)
+ {
+ m_startTime = i.getLowerBound();
+ m_endTime = i.getUpperBound();
+ }
+
+ return *this;
+}
+
+double TimeRegion::getLowerBound() const
+{
+ return m_startTime;
+}
+
+double TimeRegion::getUpperBound() const
+{
+ return m_endTime;
+}
+
+void TimeRegion::setBounds(double l, double h)
+{
+ assert(m_startTime <= m_endTime);
+
+ m_startTime = l;
+ m_endTime = h;
+}
+
+bool TimeRegion::intersectsInterval(const IInterval& ti) const
+{
+ return intersectsInterval(ti.getIntervalType(), ti.getLowerBound(), ti.getUpperBound());
+}
+
+bool TimeRegion::intersectsInterval(Tools::IntervalType t, const double start, const double end) const
+{
+ //if (m_startTime != start &&
+ // (m_startTime >= end || m_endTime <= start)) return false;
+ // this will not work for degenarate intervals.
+ if (m_startTime >= end || m_endTime <= start) return false;
+
+ return true;
+}
+
+bool TimeRegion::containsInterval(const IInterval& ti) const
+{
+ if (m_startTime <= ti.getLowerBound() && m_endTime >= ti.getUpperBound()) return true;
+ return false;
+}
+
+Tools::IntervalType TimeRegion::getIntervalType() const
+{
+ return Tools::IT_RIGHTOPEN;
+}
+
+void TimeRegion::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pLow[cIndex] = std::numeric_limits<double>::max();
+ m_pHigh[cIndex] = -std::numeric_limits<double>::max();
+ }
+
+ m_startTime = std::numeric_limits<double>::max();
+ m_endTime = -std::numeric_limits<double>::max();
+}
+
+void TimeRegion::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ m_dimension = dimension;
+
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ m_pLow = 0; m_pHigh = 0;
+
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const TimeRegion& r)
+{
+ uint32_t i;
+
+ os << "Low: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pLow[i] << " ";
+ }
+
+ os << ", High: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pHigh[i] << " ";
+ }
+
+ os << ", Start: " << r.m_startTime << ", End: " << r.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/LineSegment.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/LineSegment.cc
new file mode 100644
index 000000000..1653f15da
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/LineSegment.cc
@@ -0,0 +1,388 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+LineSegment::LineSegment()
+ : m_dimension(0), m_pStartPoint(0), m_pEndPoint(0)
+{
+}
+
+LineSegment::LineSegment(const double* pStartPoint, const double* pEndPoint, uint32_t dimension)
+ : m_dimension(dimension)
+{
+ // no need to initialize arrays to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ memcpy(m_pStartPoint, pStartPoint, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, pEndPoint, m_dimension * sizeof(double));
+}
+
+LineSegment::LineSegment(const Point& startPoint, const Point& endPoint)
+ : m_dimension(startPoint.m_dimension)
+{
+ if (startPoint.m_dimension != endPoint.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "LineSegment::LineSegment: Points have different dimensionalities."
+ );
+
+ // no need to initialize arrays to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ memcpy(m_pStartPoint, startPoint.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, endPoint.m_pCoords, m_dimension * sizeof(double));
+}
+
+LineSegment::LineSegment(const LineSegment& l)
+ : m_dimension(l.m_dimension)
+{
+ // no need to initialize arrays to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ memcpy(m_pStartPoint, l.m_pStartPoint, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, l.m_pEndPoint, m_dimension * sizeof(double));
+}
+
+LineSegment::~LineSegment()
+{
+ delete[] m_pStartPoint;
+ delete[] m_pEndPoint;
+}
+
+LineSegment& LineSegment::operator=(const LineSegment& l)
+{
+ if (this != &l)
+ {
+ makeDimension(l.m_dimension);
+ memcpy(m_pStartPoint, l.m_pStartPoint, m_dimension * sizeof(double));
+ memcpy(m_pEndPoint, l.m_pEndPoint, m_dimension * sizeof(double));
+ }
+
+ return *this;
+}
+
+bool LineSegment::operator==(const LineSegment& l) const
+{
+ if (m_dimension != l.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "LineSegment::operator==: LineSegments have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pStartPoint[i] < l.m_pStartPoint[i] - std::numeric_limits<double>::epsilon() ||
+ m_pStartPoint[i] > l.m_pStartPoint[i] + std::numeric_limits<double>::epsilon()) return false;
+
+ if (
+ m_pEndPoint[i] < l.m_pEndPoint[i] - std::numeric_limits<double>::epsilon() ||
+ m_pEndPoint[i] > l.m_pEndPoint[i] + std::numeric_limits<double>::epsilon()) return false;
+ }
+
+ return true;
+}
+
+//
+// IObject interface
+//
+LineSegment* LineSegment::clone()
+{
+ return new LineSegment(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t LineSegment::getByteArraySize()
+{
+ return (sizeof(uint32_t) + m_dimension * sizeof(double) * 2);
+}
+
+void LineSegment::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ makeDimension(dimension);
+ memcpy(m_pStartPoint, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pEndPoint, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void LineSegment::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, m_pStartPoint, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pEndPoint, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IShape interface
+//
+bool LineSegment::intersectsShape(const IShape& s) const
+{
+ throw Tools::IllegalStateException(
+ "LineSegment::intersectsShape: Not implemented yet!"
+ );
+}
+
+bool LineSegment::containsShape(const IShape& s) const
+{
+ return false;
+}
+
+bool LineSegment::touchesShape(const IShape& s) const
+{
+ throw Tools::IllegalStateException(
+ "LineSegment::touchesShape: Not implemented yet!"
+ );
+}
+
+void LineSegment::getCenter(Point& out) const
+{
+ double* coords = new double[m_dimension];
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ coords[cDim] =
+ (std::abs(m_pStartPoint[cDim] - m_pEndPoint[cDim]) / 2.0) +
+ std::min(m_pStartPoint[cDim], m_pEndPoint[cDim]);
+ }
+
+ out = Point(coords, m_dimension);
+ delete[] coords;
+}
+
+uint32_t LineSegment::getDimension() const
+{
+ return m_dimension;
+}
+
+void LineSegment::getMBR(Region& out) const
+{
+ double* low = new double[m_dimension];
+ double* high = new double[m_dimension];
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ low[cDim] = std::min(m_pStartPoint[cDim], m_pEndPoint[cDim]);
+ high[cDim] = std::max(m_pStartPoint[cDim], m_pEndPoint[cDim]);
+ }
+
+ out = Region(low, high, m_dimension);
+ delete[] low;
+ delete[] high;
+}
+
+double LineSegment::getArea() const
+{
+ return 0.0;
+}
+
+double LineSegment::getMinimumDistance(const IShape& s) const
+{
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0)
+ {
+ return getMinimumDistance(*ppt);
+ }
+
+/*
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->getMinimumDistance(*this);
+ }
+*/
+
+ throw Tools::IllegalStateException(
+ "LineSegment::getMinimumDistance: Not implemented yet!"
+ );
+}
+
+double LineSegment::getMinimumDistance(const Point& p) const
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getMinimumDistance: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getMinimumDistance: Distance for high dimensional spaces not supported!"
+ );
+
+ if (m_pEndPoint[0] >= m_pStartPoint[0] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[0] <= m_pStartPoint[0] + std::numeric_limits<double>::epsilon()) return std::abs(p.m_pCoords[0] - m_pStartPoint[0]);
+
+ if (m_pEndPoint[1] >= m_pStartPoint[1] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[1] <= m_pStartPoint[1] + std::numeric_limits<double>::epsilon()) return std::abs(p.m_pCoords[1] - m_pStartPoint[1]);
+
+ double x1 = m_pStartPoint[0];
+ double x2 = m_pEndPoint[0];
+ double x0 = p.m_pCoords[0];
+ double y1 = m_pStartPoint[1];
+ double y2 = m_pEndPoint[1];
+ double y0 = p.m_pCoords[1];
+
+ return std::abs((x2 - x1) * (y1 - y0) - (x1 - x0) * (y2 - y1)) / (std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
+}
+
+// assuming moving from start to end, positive distance is from right hand side.
+double LineSegment::getRelativeMinimumDistance(const Point& p) const
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMinimumDistance: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMinimumDistance: Distance for high dimensional spaces not supported!"
+ );
+
+ if (m_pEndPoint[0] >= m_pStartPoint[0] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[0] <= m_pStartPoint[0] + std::numeric_limits<double>::epsilon())
+ {
+ if (m_pStartPoint[1] < m_pEndPoint[1]) return m_pStartPoint[0] - p.m_pCoords[0];
+ if (m_pStartPoint[1] >= m_pEndPoint[1]) return p.m_pCoords[0] - m_pStartPoint[0];
+ }
+
+ if (m_pEndPoint[1] >= m_pStartPoint[1] - std::numeric_limits<double>::epsilon() &&
+ m_pEndPoint[1] <= m_pStartPoint[1] + std::numeric_limits<double>::epsilon())
+ {
+ if (m_pStartPoint[0] < m_pEndPoint[0]) return p.m_pCoords[1] - m_pStartPoint[1];
+ if (m_pStartPoint[0] >= m_pEndPoint[0]) return m_pStartPoint[1] - p.m_pCoords[1];
+ }
+
+ double x1 = m_pStartPoint[0];
+ double x2 = m_pEndPoint[0];
+ double x0 = p.m_pCoords[0];
+ double y1 = m_pStartPoint[1];
+ double y2 = m_pEndPoint[1];
+ double y0 = p.m_pCoords[1];
+
+ return ((x1 - x0) * (y2 - y1) - (x2 - x1) * (y1 - y0)) / (std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
+}
+
+double LineSegment::getRelativeMaximumDistance(const Region& r) const
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMaximumDistance: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getRelativeMaximumDistance: Distance for high dimensional spaces not supported!"
+ );
+
+ // clockwise.
+ double d1 = getRelativeMinimumDistance(Point(r.m_pLow, 2));
+
+ double coords[2];
+ coords[0] = r.m_pLow[0];
+ coords[1] = r.m_pHigh[1];
+ double d2 = getRelativeMinimumDistance(Point(coords, 2));
+
+ double d3 = getRelativeMinimumDistance(Point(r.m_pHigh, 2));
+
+ coords[0] = r.m_pHigh[0];
+ coords[1] = r.m_pLow[1];
+ double d4 = getRelativeMinimumDistance(Point(coords, 2));
+
+ return std::max(d1, std::max(d2, std::max(d3, d4)));
+}
+
+double LineSegment::getAngleOfPerpendicularRay()
+{
+ if (m_dimension == 1)
+ throw Tools::NotSupportedException(
+ "LineSegment::getAngleOfPerpendicularRay: Use an Interval instead."
+ );
+
+ if (m_dimension != 2)
+ throw Tools::NotSupportedException(
+ "LineSegment::getAngleOfPerpendicularRay: Distance for high dimensional spaces not supported!"
+ );
+
+ if (m_pStartPoint[0] >= m_pEndPoint[0] - std::numeric_limits<double>::epsilon() &&
+ m_pStartPoint[0] <= m_pEndPoint[0] + std::numeric_limits<double>::epsilon()) return 0.0;
+
+ if (m_pStartPoint[1] >= m_pEndPoint[1] - std::numeric_limits<double>::epsilon() &&
+ m_pStartPoint[1] <= m_pEndPoint[1] + std::numeric_limits<double>::epsilon()) return M_PI_2;
+
+ return std::atan(-(m_pStartPoint[0] - m_pEndPoint[0]) / (m_pStartPoint[1] - m_pEndPoint[1]));
+}
+
+void LineSegment::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pStartPoint[cIndex] = std::numeric_limits<double>::max();
+ m_pEndPoint[cIndex] = std::numeric_limits<double>::max();
+ }
+}
+
+void LineSegment::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pStartPoint;
+ delete[] m_pEndPoint;
+
+ // remember that this is not a constructor. The object will be destructed normally if
+ // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
+ m_pStartPoint = 0;
+ m_pEndPoint = 0;
+
+ m_dimension = dimension;
+ m_pStartPoint = new double[m_dimension];
+ m_pEndPoint = new double[m_dimension];
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, const LineSegment& l)
+{
+ for (uint32_t cDim = 0; cDim < l.m_dimension; ++cDim)
+ {
+ os << l.m_pStartPoint[cDim] << ", " << l.m_pEndPoint[cDim] << " ";
+ }
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Makefile.am
new file mode 100644
index 000000000..6a0adc928
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Makefile.am
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = liblibrary.la
+INCLUDES = -I../../include
+liblibrary_la_SOURCES = Point.cc Region.cc LineSegment.cc MovingPoint.cc MovingRegion.cc TimePoint.cc TimeRegion.cc SpatialIndexImpl.cc SpatialIndexImpl.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingPoint.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingPoint.cc
new file mode 100644
index 000000000..d3a33cb59
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingPoint.cc
@@ -0,0 +1,299 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+MovingPoint::MovingPoint()
+{
+}
+
+MovingPoint::MovingPoint(const double* pCoords, const double* pVCoords, const IInterval& ti, uint32_t dimension)
+{
+ initialize(pCoords, pVCoords, ti.getLowerBound(), ti.getUpperBound(), dimension);
+}
+
+MovingPoint::MovingPoint(const double* pCoords, const double* pVCoords, double tStart, double tEnd, uint32_t dimension)
+{
+ initialize(pCoords, pVCoords, tStart, tEnd, dimension);
+}
+
+MovingPoint::MovingPoint(const Point& p, const Point& vp, const IInterval& ti)
+{
+ if (p.m_dimension != vp.m_dimension) throw Tools::IllegalArgumentException("MovingPoint: Points have different number of dimensions.");
+
+ initialize(p.m_pCoords, vp.m_pCoords, ti.getLowerBound(), ti.getUpperBound(), p.m_dimension);
+}
+
+MovingPoint::MovingPoint(const Point& p, const Point& vp, double tStart, double tEnd)
+{
+ if (p.m_dimension != vp.m_dimension) throw Tools::IllegalArgumentException("MovingPoint: Points have different number of dimensions.");
+
+ initialize(p.m_pCoords, vp.m_pCoords, tStart, tEnd, p.m_dimension);
+}
+
+MovingPoint::MovingPoint(const MovingPoint& p)
+{
+ m_startTime = p.m_startTime;
+ m_endTime = p.m_endTime;
+ m_pCoords = 0;
+
+ m_dimension = p.m_dimension;
+
+ try
+ {
+ m_pCoords = new double[m_dimension];
+ m_pVCoords = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pCoords;
+ throw;
+ }
+
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVCoords, p.m_pVCoords, m_dimension * sizeof(double));
+}
+
+MovingPoint::~MovingPoint()
+{
+ delete[] m_pVCoords;
+}
+
+void MovingPoint::initialize(
+ const double* pCoords, const double* pVCoords,
+ double tStart, double tEnd, uint32_t dimension)
+{
+ m_dimension = dimension;
+ m_startTime = tStart;
+ m_endTime = tEnd;
+ m_pCoords = 0;
+
+ if (m_endTime <= m_startTime) throw Tools::IllegalArgumentException("MovingPoint: Cannot support degenerate time intervals.");
+
+ try
+ {
+ m_pCoords = new double[m_dimension];
+ m_pVCoords = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pCoords;
+ throw;
+ }
+
+ // first store the point coordinates, than the point velocities.
+ memcpy(m_pCoords, pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVCoords, pVCoords, m_dimension * sizeof(double));
+}
+
+MovingPoint& MovingPoint::operator=(const MovingPoint& p)
+{
+ if (this != &p)
+ {
+ makeDimension(p.m_dimension);
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVCoords, p.m_pVCoords, m_dimension * sizeof(double));
+
+ m_startTime = p.m_startTime;
+ m_endTime = p.m_endTime;
+ }
+
+ return *this;
+}
+
+bool MovingPoint::operator==(const MovingPoint& p) const
+{
+ if (
+ m_startTime < p.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > p.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < p.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > p.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t cDim = 0; cDim < 2 * m_dimension; ++cDim)
+ {
+ if (
+ m_pCoords[cDim] < p.m_pCoords[cDim] - std::numeric_limits<double>::epsilon() ||
+ m_pCoords[cDim] > p.m_pCoords[cDim] + std::numeric_limits<double>::epsilon() ||
+ m_pVCoords[cDim] < p.m_pVCoords[cDim] - std::numeric_limits<double>::epsilon() ||
+ m_pVCoords[cDim] > p.m_pVCoords[cDim] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+
+ return true;
+}
+
+double MovingPoint::getCoord(uint32_t d, double t) const
+{
+ if (d < 0 && d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ if (t >= m_endTime) return m_pCoords[d] + m_pVCoords[d] * (m_endTime - m_startTime);
+ else if (t <= m_startTime) return m_pCoords[d] + m_pVCoords[d] * m_startTime;
+ else return m_pCoords[d] + m_pVCoords[d] * (t - m_startTime);
+}
+
+double MovingPoint::getProjectedCoord(uint32_t d, double t) const
+{
+ if (d < 0 && d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pCoords[d] + m_pVCoords[d] * (t - m_startTime);
+}
+
+double MovingPoint::getVCoord(uint32_t d) const
+{
+ if (d < 0 && d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pVCoords[d];
+}
+
+void MovingPoint::getPointAtTime(double t, Point& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ out.m_pCoords[cDim] = getCoord(cDim, t);
+ }
+}
+
+//
+// IObject interface
+//
+MovingPoint* MovingPoint::clone()
+{
+ return new MovingPoint(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t MovingPoint::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + 2 * m_dimension * sizeof(double));
+}
+
+void MovingPoint::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pVCoords, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void MovingPoint::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pVCoords, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IEvolvingShape interface
+//
+void MovingPoint::getVMBR(Region& out) const
+{
+ out.makeDimension(m_dimension);
+ memcpy(out.m_pLow, m_pVCoords, m_dimension * sizeof(double));
+ memcpy(out.m_pHigh, m_pVCoords, m_dimension * sizeof(double));
+}
+
+void MovingPoint::getMBRAtTime(double t, Region& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ out.m_pLow[cDim] = getCoord(cDim, t);
+ out.m_pHigh[cDim] = getCoord(cDim, t);
+ }
+}
+
+void MovingPoint::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pCoords[cIndex] = std::numeric_limits<double>::max();
+ m_pVCoords[cIndex] = -std::numeric_limits<double>::max();
+ }
+
+ m_startTime = std::numeric_limits<double>::max();
+ m_endTime = -std::numeric_limits<double>::max();
+}
+
+void MovingPoint::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pCoords;
+ delete[] m_pVCoords;
+ m_pCoords = 0; m_pVCoords = 0;
+
+ m_dimension = dimension;
+ m_pCoords = new double[m_dimension];
+ m_pVCoords = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const MovingPoint& pt)
+{
+ uint32_t i;
+
+ os << "Coords: ";
+ for (i = 0; i < pt.m_dimension; ++i)
+ {
+ os << pt.m_pCoords[i] << " ";
+ }
+
+ os << "VCoords: ";
+ for (i = 0; i < pt.m_dimension; ++i)
+ {
+ os << pt.m_pVCoords[i] << " ";
+ }
+
+ os << ", Start: " << pt.m_startTime << ", End: " << pt.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingRegion.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingRegion.cc
new file mode 100644
index 000000000..8f54e4a37
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/MovingRegion.cc
@@ -0,0 +1,1231 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+/*
+ * Does not support degenerate time intervals or shrinking regions.
+*/
+
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+MovingRegion::MovingRegion()
+ : TimeRegion(), m_pVLow(0), m_pVHigh(0)
+{
+}
+
+MovingRegion::MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ const IInterval& ivT, uint32_t dimension)
+{
+ initialize(pLow, pHigh, pVLow, pVHigh, ivT.getLowerBound(), ivT.getUpperBound(), dimension);
+}
+
+MovingRegion::MovingRegion(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension)
+{
+ initialize(pLow, pHigh, pVLow, pVHigh, tStart, tEnd, dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ const IInterval& ivT)
+{
+ if (low.m_dimension != high.m_dimension || low.m_dimension != vlow.m_dimension || vlow.m_dimension != vhigh.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(
+ low.m_pCoords, high.m_pCoords, vlow.m_pCoords, vhigh.m_pCoords,
+ ivT.getLowerBound(), ivT.getUpperBound(), low.m_dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Point& low, const Point& high,
+ const Point& vlow, const Point& vhigh,
+ double tStart, double tEnd)
+{
+ if (low.m_dimension != high.m_dimension || low.m_dimension != vlow.m_dimension || vlow.m_dimension != vhigh.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(
+ low.m_pCoords, high.m_pCoords, vlow.m_pCoords, vhigh.m_pCoords,
+ tStart, tEnd, low.m_dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Region& mbr, const Region& vbr, const IInterval& ivT)
+{
+ if (mbr.m_dimension != vbr.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(mbr.m_pLow, mbr.m_pHigh, vbr.m_pLow, vbr.m_pHigh, ivT.getLowerBound(), ivT.getUpperBound(), mbr.m_dimension);
+}
+
+MovingRegion::MovingRegion(
+ const Region& mbr, const Region& vbr, double tStart, double tEnd)
+{
+ if (mbr.m_dimension != vbr.m_dimension)
+ throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ initialize(mbr.m_pLow, mbr.m_pHigh, vbr.m_pLow, vbr.m_pHigh, tStart, tEnd, mbr.m_dimension);
+}
+
+MovingRegion::MovingRegion(const MovingPoint& low, const MovingPoint& high)
+{
+ m_startTime = low.m_startTime;
+ m_endTime = high.m_endTime;;
+ m_dimension = low.m_dimension;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ if (m_endTime <= m_startTime) throw Tools::IllegalArgumentException("MovingRegion: Cannot support degenerate time intervals.");
+
+ if (low.m_dimension != high.m_dimension) throw Tools::IllegalArgumentException("MovingRegion: arguments have different number of dimensions.");
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ throw;
+ }
+
+ memcpy(m_pLow, low.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pHigh, high.m_pCoords, m_dimension * sizeof(double));
+ memcpy(m_pVLow, low.m_pVCoords, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, high.m_pVCoords, m_dimension * sizeof(double));
+}
+
+MovingRegion::MovingRegion(const MovingRegion& r)
+{
+ m_startTime = r.m_startTime;
+ m_endTime = r.m_endTime;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ m_dimension = r.m_dimension;
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ throw;
+ }
+
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+ memcpy(m_pVLow, r.m_pVLow, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, r.m_pVHigh, m_dimension * sizeof(double));
+}
+
+void MovingRegion::initialize(
+ const double* pLow, const double* pHigh,
+ const double* pVLow, const double* pVHigh,
+ double tStart, double tEnd, uint32_t dimension)
+{
+ m_startTime = tStart;
+ m_endTime = tEnd;
+ m_dimension = dimension;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ if (m_endTime <= m_startTime) throw Tools::IllegalArgumentException("MovingRegion: Cannot support degenerate time intervals.");
+
+#ifndef NDEBUG
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (pLow[cDim] > pHigh[cDim]) throw Tools::IllegalArgumentException("MovingRegion: Low point has larger coordinates than High point.");
+ }
+#endif
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ throw;
+ }
+
+ // first store the point coordinates, than the point velocities.
+ memcpy(m_pLow, pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, pHigh, m_dimension * sizeof(double));
+ memcpy(m_pVLow, pVLow, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, pVHigh, m_dimension * sizeof(double));
+}
+
+MovingRegion::~MovingRegion()
+{
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+}
+
+MovingRegion& MovingRegion::operator=(const MovingRegion& r)
+{
+ if(this != &r)
+ {
+ makeDimension(r.m_dimension);
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+ memcpy(m_pVLow, r.m_pVLow, m_dimension * sizeof(double));
+ memcpy(m_pVHigh, r.m_pVHigh, m_dimension * sizeof(double));
+
+ m_startTime = r.m_startTime;
+ m_endTime = r.m_endTime;
+
+ assert(m_startTime < m_endTime);
+ }
+
+ return *this;
+}
+
+bool MovingRegion::operator==(const MovingRegion& r) const
+{
+ if (m_startTime < r.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > r.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < r.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > r.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon() ||
+ m_pVLow[i] < r.m_pVLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pVLow[i] > r.m_pVLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pVHigh[i] < r.m_pVHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pVHigh[i] > r.m_pVHigh[i] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+ return true;
+}
+
+bool MovingRegion::isShrinking() const
+{
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (m_pVHigh[cDim] < m_pVLow[cDim]) return true;
+ }
+ return false;
+}
+
+// assumes that the region is not moving before and after start and end time.
+double MovingRegion::getLow(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ if (t > m_endTime) return m_pLow[d] + m_pVLow[d] * (m_endTime - m_startTime);
+ else if (t < m_startTime) return m_pLow[d];
+ else return m_pLow[d] + m_pVLow[d] * (t - m_startTime);
+}
+
+// assumes that the region is not moving before and after start and end time.
+double MovingRegion::getHigh(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ if (t > m_endTime) return m_pHigh[d] + m_pVHigh[d] * (m_endTime - m_startTime);
+ else if (t < m_startTime) return m_pHigh[d];
+ else return m_pHigh[d] + m_pVHigh[d] * (t - m_startTime);
+}
+
+// assuming that the region kept moving.
+double MovingRegion::getExtrapolatedLow(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pLow[d] + m_pVLow[d] * (t - m_startTime);
+}
+
+// assuming that the region kept moving.
+double MovingRegion::getExtrapolatedHigh(uint32_t d, double t) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pHigh[d] + m_pVHigh[d] * (t - m_startTime);
+}
+
+double MovingRegion::getVLow(uint32_t d) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pVLow[d];
+}
+
+double MovingRegion::getVHigh(uint32_t d) const
+{
+ if (d < 0 || d >= m_dimension) throw Tools::IndexOutOfBoundsException(d);
+
+ return m_pVHigh[d];
+}
+
+bool MovingRegion::intersectsRegionInTime(const MovingRegion& r) const
+{
+ Tools::Interval ivOut;
+ return intersectsRegionInTime(r, ivOut);
+}
+
+bool MovingRegion::intersectsRegionInTime(const MovingRegion& r, IInterval& ivOut) const
+{
+ return intersectsRegionInTime(r, r, ivOut);
+}
+
+// if tmin, tmax are infinity then this will not work correctly (everything will always intersect).
+// does not work for shrinking regions.
+// does not work with degenerate time-intervals.
+//
+// WARNING: this will return true even if one region completely contains the other, since
+// their areas do intersect in that case!
+//
+// there are various cases here:
+// 1. one region contains the other.
+// 2. one boundary of one region is always contained indide the other region, while the other
+// boundary is not (so no boundaries will ever intersect).
+// 3. either the upper or lower boundary of one region intersects a boundary of the other.
+bool MovingRegion::intersectsRegionInTime(const IInterval& ivPeriod, const MovingRegion& r, IInterval& ivOut) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("intersectsRegionInTime: MovingRegions have different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(r.m_startTime < r.m_endTime);
+ assert(ivPeriod.getLowerBound() < ivPeriod.getUpperBound());
+ assert(isShrinking() == false && r.isShrinking() == false);
+
+ // this is needed, since we are assuming below that the two regions have some point of intersection
+ // inside itPeriod.
+ if (containsRegionInTime(ivPeriod, r) || r.containsRegionInTime(ivPeriod, *this))
+ {
+ ivOut = ivPeriod;
+ return true;
+ }
+
+ double tmin = std::max(m_startTime, r.m_startTime);
+ double tmax = std::min(m_endTime, r.m_endTime);
+
+ // the regions do not intersect in time.
+ if (tmax <= tmin) return false;
+
+ tmin = std::max(tmin, ivPeriod.getLowerBound());
+ tmax = std::min(tmax, ivPeriod.getUpperBound());
+
+ // the regions intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return false;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ // I use projected low and high because they are faster and it does not matter.
+ // The are also necessary for calculating the intersection point with reference time instant 0.0.
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= r.m_startTime && tmax <= r.m_endTime);
+
+ // completely above or bellow in i-th dimension
+ if (
+ (r.getExtrapolatedLow(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) &&
+ r.getExtrapolatedLow(cDim, tmax) >= getExtrapolatedHigh(cDim, tmax)) ||
+ (r.getExtrapolatedHigh(cDim, tmin) < getExtrapolatedLow(cDim, tmin) &&
+ r.getExtrapolatedHigh(cDim, tmax) <= getExtrapolatedLow(cDim, tmax)))
+ return false;
+
+ // otherwise they intersect inside this interval for sure. Care needs to be taken since
+ // intersection does not necessarily mean that two line segments intersect. It could be
+ // that one line segment is completely above/below another, in which case there is no intersection
+ // point inside tmin, tmax, even though the two region areas do intersect.
+
+ if (r.getExtrapolatedLow(cDim, tmin) > getExtrapolatedHigh(cDim, tmin)) // r above *this at tmin
+ {
+ tmin = (getExtrapolatedHigh(cDim, 0.0) - r.getExtrapolatedLow(cDim, 0.0)) / (r.getVLow(cDim) - getVHigh(cDim));
+ }
+ else if (r.getExtrapolatedHigh(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) // r below *this at tmin
+ {
+ tmin = (getExtrapolatedLow(cDim, 0.0) - r.getExtrapolatedHigh(cDim, 0.0)) / (r.getVHigh(cDim) - getVLow(cDim));
+ }
+ // else they do not intersect and the boundary might be completely contained in this region.
+
+ if (r.getExtrapolatedLow(cDim, tmax) > getExtrapolatedHigh(cDim, tmax)) // r above *this at tmax
+ {
+ tmax = (getExtrapolatedHigh(cDim, 0.0) - r.getExtrapolatedLow(cDim, 0.0)) / (r.getVLow(cDim) - getVHigh(cDim));
+ }
+ else if (r.getExtrapolatedHigh(cDim, tmax) < getExtrapolatedLow(cDim, tmax)) // r below *this at tmax
+ {
+ tmax = (getExtrapolatedLow(cDim, 0.0) - r.getExtrapolatedHigh(cDim, 0.0)) / (r.getVHigh(cDim) - getVLow(cDim));
+ }
+ // else they do not intersect and the boundary might be completely contained in this region.
+
+ assert(tmin <= tmax);
+ }
+
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= r.m_startTime && tmax <= r.m_endTime);
+
+ ivOut.setBounds(tmin, tmax);
+
+ return true;
+}
+
+bool MovingRegion::containsRegionInTime(const MovingRegion& r) const
+{
+ return containsRegionInTime(r, r);
+}
+
+// does not work for shrinking regions.
+// works fine for infinite bounds (both tmin and tmax).
+// does not work with degenerate time-intervals.
+//
+// finds if during the intersecting time-interval of r and ivPeriod, r is completely contained in *this.
+bool MovingRegion::containsRegionInTime(const IInterval& ivPeriod, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("containsRegionInTime: MovingRegions have different number of dimensions.");
+
+ assert(isShrinking() == false && r.isShrinking() == false);
+
+ double tmin = std::max(ivPeriod.getLowerBound(), r.m_startTime);
+ double tmax = std::min(ivPeriod.getUpperBound(), r.m_endTime);
+
+ // it should be contained in time.
+ // it does not make sense if this region is not defined for any part ot [tmin, tmax].
+ if (tmax <= tmin || tmin < m_startTime || tmax > m_endTime) return false;
+
+ double intersectionTime;
+
+ // no need to take projected coordinates here, since tmin and tmax are always contained in
+ // the regions intersecting time-intervals.
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= r.m_startTime && tmax <= r.m_endTime);
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ // it should be contained at start time.
+ if (r.getExtrapolatedHigh(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) ||
+ r.getExtrapolatedLow(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) return false;
+
+ // this will take care of infinite bounds.
+ if (r.m_pVHigh[cDim] != m_pVHigh[cDim])
+ {
+ intersectionTime = (getExtrapolatedHigh(cDim, 0.0) - r.getExtrapolatedHigh(cDim, 0.0)) / (r.m_pVHigh[cDim] - m_pVHigh[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && r.m_pVHigh[cDim] > m_pVHigh[cDim]) return false;
+ }
+
+ if (r.m_pVLow[cDim] != m_pVLow[cDim])
+ {
+ intersectionTime = (getExtrapolatedLow(cDim, 0.0) - r.getExtrapolatedLow(cDim, 0.0)) / (r.m_pVLow[cDim] - m_pVLow[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && r.m_pVLow[cDim] < m_pVLow[cDim]) return false;
+ }
+ }
+
+ return true;
+}
+
+bool MovingRegion::containsRegionAfterTime(double t, const MovingRegion& r) const
+{
+ Tools::Interval ivT(t, r.m_endTime);
+ return containsRegionInTime(ivT, r);
+}
+
+// Returns the area swept by the rectangle in time, in d-dimensional space (without
+// including the temporal dimension, that is).
+// This is what Saltenis calls Margin (which is different than what Beckmann proposes,
+// where he computes only the wireframe -- instead of the surface/volume/etc. -- of the MBR in any dimension).
+double MovingRegion::getProjectedSurfaceAreaInTime() const
+{
+ return getProjectedSurfaceAreaInTime(*this);
+}
+
+double MovingRegion::getProjectedSurfaceAreaInTime(const IInterval& ivI) const
+{
+ double tmin = std::max(ivI.getLowerBound(), m_startTime);
+ double tmax = std::min(ivI.getUpperBound(), m_endTime);
+
+ assert(tmin > -std::numeric_limits<double>::max());
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin <= tmax);
+
+ if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
+ tmin <= tmax + std::numeric_limits<double>::epsilon())
+ return 0.0;
+
+ double dx1, dx2, dx3;
+ double dv1, dv2, dv3;
+ double H = tmax - tmin;
+
+ if (m_dimension == 3)
+ {
+ dx3 = getExtrapolatedHigh(2, tmin) - getExtrapolatedLow(2, tmin);
+ dv3 = getVHigh(2) - getVLow(2);
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return
+ H * (dx1 + dx2 + dx3 + dx1*dx2 + dx1*dx3 + dx2*dx3) +
+ H*H * (dv1 + dv2 + dv3 + dx1*dv2 + dv1*dx2 + dx1*dv3 +
+ dv1*dx3 + dx2*dv3 + dv2*dx3) / 2.0 +
+ H*H*H * (dv1*dv2 + dv1*dv3 + dv2*dv3) / 3.0;
+ }
+ else if (m_dimension == 2)
+ {
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return H * (dx1 + dx2) + H * H * (dv1 + dv2) / 2.0;
+ }
+ else if (m_dimension == 1)
+ {
+ // marioh: why not use the increase of the length of the interval here?
+ return 0.0;
+ }
+ else
+ {
+ throw Tools::IllegalStateException("getProjectedSurfaceAreaInTime: unsupported dimensionality.");
+ }
+}
+
+double MovingRegion::getCenterDistanceInTime(const MovingRegion& r) const
+{
+
+ return getCenterDistanceInTime(r, r);
+}
+
+double MovingRegion::getCenterDistanceInTime(const IInterval& ivI, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("getCenterDistanceInTime: MovingRegions have different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(r.m_startTime < r.m_endTime);
+ assert(ivI.getLowerBound() < ivI.getUpperBound());
+
+ double tmin = std::max(m_startTime, r.m_startTime);
+ double tmax = std::min(m_endTime, r.m_endTime);
+
+ // the regions do not intersect in time.
+ if (tmax <= tmin) return 0.0;
+
+ tmin = std::max(tmin, ivI.getLowerBound());
+ tmax = std::min(tmax, ivI.getUpperBound());
+
+ // the regions intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return 0.0;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
+ tmin <= tmax + std::numeric_limits<double>::epsilon())
+ return 0.0;
+
+ double H = tmax - tmin;
+
+ double* dx = new double[m_dimension];
+ double* dv = new double[m_dimension];
+ double a = 0.0, b = 0.0, c = 0.0, f = 0.0, l = 0.0, m = 0.0, n = 0.0;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ dx[cDim] =
+ (r.getExtrapolatedLow(cDim, tmin) + r.getExtrapolatedHigh(cDim, tmin)) / 2.0 -
+ (getExtrapolatedLow(cDim, tmin) + getExtrapolatedHigh(cDim, tmin)) / 2.0;
+ dv[cDim] =
+ (r.getVLow(cDim) + r.getVHigh(cDim)) / 2.0 -
+ (getVLow(cDim) + getVHigh(cDim)) / 2.0;
+ }
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ a += dv[cDim] * dv[cDim];
+ b += 2.0 * dx[cDim] * dv[cDim];
+ c += dx[cDim] * dx[cDim];
+ }
+
+ if (a == 0.0 && c == 0.0) return 0.0;
+ if (a == 0.0) return H * std::sqrt(c);
+ if (c == 0.0) return H * H * std::sqrt(a) / 2.0;
+
+ f = std::sqrt(a * H * H + b * H + c);
+ l = 2.0 * a * H + b;
+ m = 4.0 * a * c - b * b;
+ n = 2.0 * std::sqrt(a);
+
+ delete[] dx;
+ delete[] dv;
+
+ return (l * f + log(l / n + f) * m / n - b * std::sqrt(c) - std::log(b / n + std::sqrt(c)) * m / n) / (4.0 * a);
+}
+
+// does not work with degenerate time-intervals.
+bool MovingRegion::intersectsRegionAtTime(double t, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("intersectsRegionAtTime: MovingRegions have different number of dimensions.");
+
+ // do they contain the time instant?
+ if (! (m_startTime <= t && t < m_endTime && r.m_startTime <= t && t < r.m_endTime)) return false;
+
+ // do they intersect at that time instant?
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (getExtrapolatedLow(i, t) > r.getExtrapolatedHigh(i, t) || getExtrapolatedHigh(i, t) < r.getExtrapolatedLow(i, t)) return false;
+ }
+ return true;
+}
+
+// does not work with degenerate time-intervals.
+bool MovingRegion::containsRegionAtTime(double t, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("containsRegionAtTime: MovingRegions have different number of dimensions.");
+
+ // do they contain the time instant?
+ if (! (m_startTime <= t && t < m_endTime && r.m_startTime <= t && t < r.m_endTime)) return false;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (getExtrapolatedLow(cDim, t) > r.getExtrapolatedLow(cDim, t) || getExtrapolatedHigh(cDim, t) < getExtrapolatedHigh(cDim, t)) return false;
+ }
+ return true;
+}
+
+bool MovingRegion::intersectsPointInTime(const MovingPoint& p) const
+{
+ Tools::Interval ivOut;
+ return intersectsPointInTime(p, ivOut);
+}
+
+bool MovingRegion::intersectsPointInTime(const MovingPoint& p, IInterval& ivOut) const
+{
+ return intersectsPointInTime(p, p, ivOut);
+}
+
+// if tmin, tmax are infinity then this will not work correctly (everything will always intersect).
+// does not work for shrinking regions.
+// does not work with degenerate time-intervals.
+// FIXME: don't know what happens if tmin is negative infinity.
+//
+// WARNING: This will return true even if the region completely contains the point, since
+// in that case the point trajectory intersects the region area!
+bool MovingRegion::intersectsPointInTime(const IInterval& ivPeriod, const MovingPoint& p, IInterval& ivOut) const
+{
+ if (m_dimension != p.m_dimension) throw Tools::IllegalArgumentException("intersectsPointInTime: MovingPoint has different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(p.m_startTime < p.m_endTime);
+ assert(ivPeriod.getLowerBound() < ivPeriod.getUpperBound());
+ assert(isShrinking() == false);
+
+ if (containsPointInTime(ivPeriod, p))
+ {
+ ivOut = ivPeriod;
+ return true;
+ }
+
+ double tmin = std::max(m_startTime, p.m_startTime);
+ double tmax = std::min(m_endTime, p.m_endTime);
+
+ // the shapes do not intersect in time.
+ if (tmax <= tmin) return false;
+
+ tmin = std::max(tmin, ivPeriod.getLowerBound());
+ tmax = std::min(tmax, ivPeriod.getUpperBound());
+
+ // the shapes intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return false;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= p.m_startTime && tmax <= p.m_endTime);
+
+ // completely above or bellow in i-th dimension
+ if ((p.getProjectedCoord(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) &&
+ p.getProjectedCoord(cDim, tmax) >= getExtrapolatedHigh(cDim, tmax)) ||
+ (p.getProjectedCoord(cDim, tmin) < getExtrapolatedLow(cDim, tmin) &&
+ p.getProjectedCoord(cDim, tmax) <= getExtrapolatedLow(cDim, tmax)))
+ return false;
+
+ // otherwise they intersect inside this interval for sure, since we know that the point is not contained,
+ // so there is no need to check for 0 divisors, negative values, etc...
+
+ // adjust tmin
+ if (p.getProjectedCoord(cDim, tmin) > getExtrapolatedHigh(cDim, tmin)) // p above *this at tmin
+ {
+ tmin = (getExtrapolatedHigh(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVHigh(cDim));
+ }
+ else if (p.getProjectedCoord(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) // p below *this at tmin
+ {
+ tmin = (getExtrapolatedLow(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVLow(cDim));
+ }
+
+ // adjust tmax
+ if (p.getProjectedCoord(cDim, tmax) > getExtrapolatedHigh(cDim, tmax)) // p above *this at tmax
+ {
+ tmax = (getExtrapolatedHigh(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVHigh(cDim));
+ }
+ else if (p.getProjectedCoord(cDim, tmax) < getExtrapolatedLow(cDim, tmax)) // p below *this at tmax
+ {
+ tmax = (getExtrapolatedLow(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.getVCoord(cDim) - getVLow(cDim));
+ }
+
+ if (tmin > tmax) return false;
+ }
+
+ ivOut.setBounds(tmin, tmax);
+
+ return true;
+}
+
+bool MovingRegion::containsPointInTime(const MovingPoint& p) const
+{
+ return containsPointInTime(p, p);
+}
+
+// does not work for shrinking regions.
+// works fine for infinite bounds (both tmin and tmax).
+// does not work with degenerate time-intervals.
+//
+// finds if during the intersecting time-interval of p and ivPeriod, p is completely contained in *this.
+bool MovingRegion::containsPointInTime(const IInterval& ivPeriod, const MovingPoint& p) const
+{
+ if (m_dimension != p.m_dimension) throw Tools::IllegalArgumentException("containsPointInTime: MovingPoint has different number of dimensions.");
+
+ assert(isShrinking() == false);
+
+ double tmin = std::max(ivPeriod.getLowerBound(), p.m_startTime);
+ double tmax = std::min(ivPeriod.getUpperBound(), p.m_endTime);
+
+ // it should be contained in time.
+ if (tmax <= tmin || tmin < m_startTime || tmax > m_endTime) return false;
+
+ double intersectionTime;
+
+ assert(
+ tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
+ tmin >= m_startTime && tmax <= m_endTime &&
+ tmin >= p.m_startTime && tmax <= p.m_endTime);
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ // it should be contained at start time.
+ if (p.getProjectedCoord(cDim, tmin) > getExtrapolatedHigh(cDim, tmin) ||
+ p.getProjectedCoord(cDim, tmin) < getExtrapolatedLow(cDim, tmin)) return false;
+
+ if (p.m_pVCoords[cDim] != m_pVHigh[cDim])
+ {
+ intersectionTime = (getExtrapolatedHigh(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.m_pVCoords[cDim] - m_pVHigh[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && p.m_pVCoords[cDim] > m_pVHigh[cDim]) return false;
+ }
+
+ if (p.m_pVCoords[cDim] != m_pVLow[cDim])
+ {
+ intersectionTime = (getExtrapolatedLow(cDim, 0.0) - p.getProjectedCoord(cDim, 0.0)) / (p.m_pVCoords[cDim] - m_pVLow[cDim]);
+ // if they intersect during this time-interval, then it is not contained.
+ if (tmin < intersectionTime && intersectionTime < tmax) return false;
+ if (tmin == intersectionTime && p.m_pVCoords[cDim] < m_pVLow[cDim]) return false;
+ }
+ }
+
+ return true;
+}
+
+void MovingRegion::combineRegionInTime(const MovingRegion& r)
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("combineRegionInTime: MovingRegions have different number of dimensions.");
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(getExtrapolatedLow(cDim, m_startTime), r.getExtrapolatedLow(cDim, m_startTime));
+ m_pHigh[cDim] = std::max(getExtrapolatedHigh(cDim, m_startTime), r.getExtrapolatedHigh(cDim, m_startTime));
+ m_pVLow[cDim] = std::min(m_pVLow[cDim], r.m_pVLow[cDim]);
+ m_pVHigh[cDim] = std::max(m_pVHigh[cDim], r.m_pVHigh[cDim]);
+ }
+
+ // m_startTime should be modified at the end, since it affects the
+ // calculation of extrapolated coordinates.
+ m_startTime = std::min(m_startTime, r.m_startTime);
+ m_endTime = std::max(m_endTime, r.m_endTime);
+}
+
+void MovingRegion::getCombinedRegionInTime(MovingRegion& out, const MovingRegion& in) const
+{
+ if (m_dimension != in.m_dimension) throw Tools::IllegalArgumentException("getCombinedProjectedRegionInTime: MovingRegions have different number of dimensions.");
+
+ out = *this;
+ out.combineRegionInTime(in);
+}
+
+void MovingRegion::combineRegionAfterTime(double t, const MovingRegion& r)
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("combineRegionInTime: MovingRegions have different number of dimensions.");
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(getExtrapolatedLow(cDim, t), r.getExtrapolatedLow(cDim, t));
+ m_pHigh[cDim] = std::max(getExtrapolatedHigh(cDim, t), r.getExtrapolatedHigh(cDim, t));
+ m_pVLow[cDim] = std::min(m_pVLow[cDim], r.m_pVLow[cDim]);
+ m_pVHigh[cDim] = std::max(m_pVHigh[cDim], r.m_pVHigh[cDim]);
+ }
+
+ // m_startTime should be modified at the end, since it affects the
+ // calculation of extrapolated coordinates.
+ m_startTime = t;
+ m_endTime = std::max(m_endTime, r.m_endTime);
+ if (t >= m_endTime) m_endTime = std::numeric_limits<double>::max();
+}
+
+void MovingRegion::getCombinedRegionAfterTime(double t, MovingRegion& out, const MovingRegion& in) const
+{
+ if (m_dimension != in.m_dimension) throw Tools::IllegalArgumentException("getCombinedProjectedRegionInTime: MovingRegions have different number of dimensions.");
+
+ out = *this;
+ out.combineRegionAfterTime(t, in);
+}
+
+double MovingRegion::getIntersectingAreaInTime(const MovingRegion& r) const
+{
+ return getIntersectingAreaInTime(r, r);
+}
+
+double MovingRegion::getIntersectingAreaInTime(const IInterval& ivI, const MovingRegion& r) const
+{
+ if (m_dimension != r.m_dimension) throw Tools::IllegalArgumentException("getIntersectingAreaInTime: MovingRegions have different number of dimensions.");
+
+ assert(m_startTime < m_endTime);
+ assert(r.m_startTime < r.m_endTime);
+ assert(ivI.getLowerBound() < ivI.getUpperBound());
+ assert(isShrinking() == false && r.isShrinking() == false);
+
+ double tmin = std::max(m_startTime, r.m_startTime);
+ double tmax = std::min(m_endTime, r.m_endTime);
+
+ // the regions do not intersect in time.
+ if (tmax <= tmin) return 0.0;
+
+ tmin = std::max(tmin, ivI.getLowerBound());
+ tmax = std::min(tmax, ivI.getUpperBound());
+
+ // the regions intersecting interval does not intersect with the given time period.
+ if (tmax <= tmin) return 0.0;
+
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin > -std::numeric_limits<double>::max());
+
+ Tools::Interval ivIn(tmin, tmax);
+ Tools::Interval ivOut(ivIn);
+
+ if (! intersectsRegionInTime(ivIn, r, ivOut)) return 0.0;
+
+ ivIn = ivOut;
+ tmin = ivIn.getLowerBound();
+ tmax = ivIn.getUpperBound();
+ assert(tmin <= tmax);
+
+ assert(tmin >= ivI.getLowerBound() && tmax <= ivI.getUpperBound());
+
+ if (containsRegionInTime(ivIn, r))
+ {
+ return r.getAreaInTime(ivIn);
+ }
+ else if (r.containsRegionInTime(ivIn, *this))
+ {
+ return getAreaInTime(ivIn);
+ }
+
+ MovingRegion x = *this;
+ CrossPoint c;
+ std::priority_queue<CrossPoint, std::vector<CrossPoint>, CrossPoint::ascending> pq;
+
+ // find points of intersection in all dimensions.
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (getLow(i, tmin) > r.getLow(i, tmin))
+ {
+ x.m_pLow[i] = m_pLow[i];
+ x.m_pVLow[i] = m_pVLow[i];
+
+ if (getLow(i, tmax) < r.getLow(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 0;
+ c.m_t = (getExtrapolatedLow(i, 0.0) - r.getExtrapolatedLow(i, 0.0)) / (r.getVLow(i) - getVLow(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = &r;
+ pq.push(c);
+ }
+ }
+ else
+ {
+ x.m_pLow[i] = r.m_pLow[i];
+ x.m_pVLow[i] = r.m_pVLow[i];
+
+ if (r.getLow(i, tmax) < getLow(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 0;
+ c.m_t = (getExtrapolatedLow(i, 0.0) - r.getExtrapolatedLow(i, 0.0)) / (r.getVLow(i) - getVLow(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = this;
+ pq.push(c);
+ }
+ }
+
+ if (getHigh(i, tmin) < r.getHigh(i, tmin))
+ {
+ x.m_pHigh[i] = m_pHigh[i];
+ x.m_pVHigh[i] = m_pVHigh[i];
+
+ if (getHigh(i, tmax) > r.getHigh(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 1;
+ c.m_t = (getExtrapolatedHigh(i, 0.0) - r.getExtrapolatedHigh(i, 0.0)) / (r.getVHigh(i) - getVHigh(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = &r;
+ pq.push(c);
+ }
+ }
+ else
+ {
+ x.m_pHigh[i] = r.m_pHigh[i];
+ x.m_pVHigh[i] = r.m_pVHigh[i];
+
+ if (r.getHigh(i, tmax) > getHigh(i, tmax))
+ {
+ c.m_dimension = i;
+ c.m_boundary = 1;
+ c.m_t = (getExtrapolatedHigh(i, 0.0) - r.getExtrapolatedHigh(i, 0.0)) / (r.getVHigh(i) - getVHigh(i));
+ assert(c.m_t >= tmin && c.m_t <= tmax);
+ c.m_to = this;
+ pq.push(c);
+ }
+ }
+ }
+
+ // add up the total area of the intersecting pieces.
+ double area = 0.0;
+#ifndef NDEBUG
+ double _t = -std::numeric_limits<double>::max();
+#endif
+
+ while (! pq.empty())
+ {
+ c = pq.top(); pq.pop();
+#ifndef NDEBUG
+ assert(_t <= c.m_t);
+ _t = c.m_t;
+#endif
+
+ // needed in case two consecutive points have the same intersection time.
+ if (c.m_t > tmin) area += x.getAreaInTime(Tools::Interval(tmin, c.m_t));
+
+ if (c.m_boundary == 0)
+ {
+ x.m_pLow[c.m_dimension] = c.m_to->m_pLow[c.m_dimension];
+ x.m_pVLow[c.m_dimension] = c.m_to->m_pVLow[c.m_dimension];
+ }
+ else
+ {
+ x.m_pHigh[c.m_dimension] = c.m_to->m_pHigh[c.m_dimension];
+ x.m_pVHigh[c.m_dimension] = c.m_to->m_pVHigh[c.m_dimension];
+ }
+
+ tmin = c.m_t;
+ }
+
+ // ... and the last piece
+ if (tmax > tmin) area += x.getAreaInTime(Tools::Interval(tmin, tmax));
+
+ return area;
+}
+
+//
+// IObject interface
+//
+MovingRegion* MovingRegion::clone()
+{
+ return new MovingRegion(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t MovingRegion::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + 4 * m_dimension * sizeof(double));
+}
+
+void MovingRegion::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pVLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pVHigh, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void MovingRegion::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, m_pLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pVLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pVHigh, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IEvolvingShape interface
+//
+void MovingRegion::getVMBR(Region& out) const
+{
+ out.makeDimension(m_dimension);
+ memcpy(out.m_pLow, m_pVLow, m_dimension * sizeof(double));
+ memcpy(out.m_pHigh, m_pVHigh, m_dimension * sizeof(double));
+}
+
+void MovingRegion::getMBRAtTime(double t, Region& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ out.m_pLow[cDim] = getLow(cDim, t);
+ out.m_pHigh[cDim] = getHigh(cDim, t);
+ }
+}
+
+//
+// ITimeShape interface
+//
+double MovingRegion::getAreaInTime() const
+{
+ return getAreaInTime(*this);
+}
+
+// this computes the area/volume/etc. swept by the Region in time.
+double MovingRegion::getAreaInTime(const IInterval& ivI) const
+{
+ double tmin = std::max(ivI.getLowerBound(), m_startTime);
+ double tmax = std::min(ivI.getUpperBound(), m_endTime);
+
+ assert(tmin > -std::numeric_limits<double>::max());
+ assert(tmax < std::numeric_limits<double>::max());
+ assert(tmin <= tmax);
+
+ if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
+ tmin <= tmax + std::numeric_limits<double>::epsilon())
+ return 0.0;
+
+ double dx1, dx2, dx3;
+ double dv1, dv2, dv3;
+ double H = tmax - tmin;
+
+ if (m_dimension == 3)
+ {
+ dx3 = getExtrapolatedHigh(2, tmin) - getExtrapolatedLow(2, tmin);
+ dv3 = getVHigh(2) - getVLow(2);
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return
+ H * dx1 * dx2 * dx3 + H * H * (dx1 * dx2 * dv3 + (dx1 * dv2 + dv1 * dx2) * dx3) / 2.0 +
+ H * H * H * ((dx1 * dv2 + dv1 * dx2) * dv3 + dv1 * dv2 * dx3) / 3.0 + H * H * H * H * dv1 * dv2 * dv3 / 4.0;
+ }
+ else if (m_dimension == 2)
+ {
+ dx2 = getExtrapolatedHigh(1, tmin) - getExtrapolatedLow(1, tmin);
+ dv2 = getVHigh(1) - getVLow(1);
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return H * dx1 * dx2 + H * H * (dx1 * dv2 + dv1 * dx2) / 2.0 + H * H * H * dv1 * dv2 / 3.0;
+ }
+ else if (m_dimension == 1)
+ {
+ dx1 = getExtrapolatedHigh(0, tmin) - getExtrapolatedLow(0, tmin);
+ dv1 = getVHigh(0) - getVLow(0);
+ return H * dx1 + H * H * dv1 / 2.0;
+ }
+ else
+ {
+ throw Tools::NotSupportedException("getAreaInTime: unsupported dimensionality.");
+ }
+}
+
+double MovingRegion::getIntersectingAreaInTime(const ITimeShape& r) const
+{
+ return getIntersectingAreaInTime(r, r);
+}
+
+double MovingRegion::getIntersectingAreaInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ const MovingRegion* pr = dynamic_cast<const MovingRegion*>(&in);
+ if (pr != 0) return getIntersectingAreaInTime(*pr);
+
+ throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
+}
+
+void MovingRegion::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pLow[cIndex] = std::numeric_limits<double>::max();
+ m_pHigh[cIndex] = -std::numeric_limits<double>::max();
+ m_pVLow[cIndex] = std::numeric_limits<double>::max();
+ m_pVHigh[cIndex] = -std::numeric_limits<double>::max();
+ }
+
+ m_startTime = -std::numeric_limits<double>::max();
+ m_endTime = std::numeric_limits<double>::max();
+}
+
+void MovingRegion::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ delete[] m_pVLow;
+ delete[] m_pVHigh;
+ m_pLow = 0; m_pHigh = 0;
+ m_pVLow = 0; m_pVHigh = 0;
+
+ m_dimension = dimension;
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ m_pVLow = new double[m_dimension];
+ m_pVHigh = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const MovingRegion& r)
+{
+ uint32_t i;
+
+ os << "Low: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pLow[i] << " ";
+ }
+
+ os << ", High: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pHigh[i] << " ";
+ }
+
+ os << "VLow: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pVLow[i] << " ";
+ }
+
+ os << ", VHigh: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pVHigh[i] << " ";
+ }
+
+ os << ", Start: " << r.m_startTime << ", End: " << r.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Point.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Point.cc
new file mode 100644
index 000000000..8c36c1123
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Point.cc
@@ -0,0 +1,262 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+Point::Point()
+ : m_dimension(0), m_pCoords(0)
+{
+}
+
+Point::Point(const double* pCoords, uint32_t dimension)
+ : m_dimension(dimension)
+{
+ // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pCoords = new double[m_dimension];
+ memcpy(m_pCoords, pCoords, m_dimension * sizeof(double));
+}
+
+Point::Point(const Point& p)
+ : m_dimension(p.m_dimension)
+{
+ // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
+
+ m_pCoords = new double[m_dimension];
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+}
+
+Point::~Point()
+{
+ delete[] m_pCoords;
+}
+
+Point& Point::operator=(const Point& p)
+{
+ if (this != &p)
+ {
+ makeDimension(p.m_dimension);
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ }
+
+ return *this;
+}
+
+bool Point::operator==(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Point::operator==: Points have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pCoords[i] < p.m_pCoords[i] - std::numeric_limits<double>::epsilon() ||
+ m_pCoords[i] > p.m_pCoords[i] + std::numeric_limits<double>::epsilon()) return false;
+ }
+
+ return true;
+}
+
+//
+// IObject interface
+//
+Point* Point::clone()
+{
+ return new Point(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t Point::getByteArraySize()
+{
+ return (sizeof(uint32_t) + m_dimension * sizeof(double));
+}
+
+void Point::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ makeDimension(dimension);
+ memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void Point::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IShape interface
+//
+bool Point::intersectsShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->containsPoint(*this);
+ }
+
+ throw Tools::IllegalStateException(
+ "Point::intersectsShape: Not implemented yet!"
+ );
+}
+
+bool Point::containsShape(const IShape& s) const
+{
+ return false;
+}
+
+bool Point::touchesShape(const IShape& s) const
+{
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0)
+ {
+ if (*this == *ppt) return true;
+ return false;
+ }
+
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->touchesPoint(*this);
+ }
+
+ throw Tools::IllegalStateException(
+ "Point::touchesShape: Not implemented yet!"
+ );
+}
+
+void Point::getCenter(Point& out) const
+{
+ out = *this;
+}
+
+uint32_t Point::getDimension() const
+{
+ return m_dimension;
+}
+
+void Point::getMBR(Region& out) const
+{
+ out = Region(m_pCoords, m_pCoords, m_dimension);
+}
+
+double Point::getArea() const
+{
+ return 0.0;
+}
+
+double Point::getMinimumDistance(const IShape& s) const
+{
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0)
+ {
+ return getMinimumDistance(*ppt);
+ }
+
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0)
+ {
+ return pr->getMinimumDistance(*this);
+ }
+
+ throw Tools::IllegalStateException(
+ "Point::getMinimumDistance: Not implemented yet!"
+ );
+}
+
+double Point::getMinimumDistance(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Point::getMinimumDistance: Shapes have different number of dimensions."
+ );
+
+ double ret = 0.0;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ ret += std::pow(m_pCoords[cDim] - p.m_pCoords[cDim], 2.0);
+ }
+
+ return std::sqrt(ret);
+}
+
+double Point::getCoordinate(uint32_t index) const
+{
+ if (index < 0 || index >= m_dimension)
+ throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pCoords[index];
+}
+
+void Point::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pCoords[cIndex] = std::numeric_limits<double>::max();
+ }
+}
+
+void Point::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pCoords;
+
+ // remember that this is not a constructor. The object will be destructed normally if
+ // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
+ m_pCoords = 0;
+
+ m_dimension = dimension;
+ m_pCoords = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const Point& pt)
+{
+ for (uint32_t cDim = 0; cDim < pt.m_dimension; ++cDim)
+ {
+ os << pt.m_pCoords[cDim] << " ";
+ }
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Region.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Region.cc
new file mode 100644
index 000000000..8db029831
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/Region.cc
@@ -0,0 +1,554 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../../include/SpatialIndex.h"
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+using namespace SpatialIndex;
+
+Region::Region()
+ : m_dimension(0), m_pLow(0), m_pHigh(0)
+{
+}
+
+Region::Region(const double* pLow, const double* pHigh, uint32_t dimension)
+{
+ initialize(pLow, pHigh, dimension);
+}
+
+Region::Region(const Point& low, const Point& high)
+{
+ if (low.m_dimension != high.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::Region: arguments have different number of dimensions."
+ );
+
+ initialize(low.m_pCoords, high.m_pCoords, low.m_dimension);
+}
+
+Region::Region(const Region& r)
+{
+ initialize(r.m_pLow, r.m_pHigh, r.m_dimension);
+}
+
+void Region::initialize(const double* pLow, const double* pHigh, uint32_t dimension)
+{
+ m_pLow = 0;
+ m_dimension = dimension;
+
+#ifndef NDEBUG
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if ((pLow[cDim] > pHigh[cDim]))
+ {
+ // check for infinitive region
+ if (!(pLow[cDim] == std::numeric_limits<double>::max() ||
+ pHigh[cDim] == -std::numeric_limits<double>::max() ))
+ throw Tools::IllegalArgumentException(
+ "Region::initialize: Low point has larger coordinates than High point."
+ " Neither point is infinity."
+ );
+ }
+ }
+#endif
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ throw;
+ }
+
+ memcpy(m_pLow, pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, pHigh, m_dimension * sizeof(double));
+}
+
+Region::~Region()
+{
+ delete[] m_pLow;
+ delete[] m_pHigh;
+}
+
+Region& Region::operator=(const Region& r)
+{
+ if(this != &r)
+ {
+ makeDimension(r.m_dimension);
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+ }
+
+ return *this;
+}
+
+bool Region::operator==(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::operator==: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+ return true;
+}
+
+//
+// IObject interface
+//
+Region* Region::clone()
+{
+ return new Region(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t Region::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * m_dimension * sizeof(double));
+}
+
+void Region::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ makeDimension(dimension);
+ memcpy(m_pLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void Region::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, m_pLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// IShape interface
+//
+bool Region::intersectsShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return intersectsRegion(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return containsPoint(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::intersectsShape: Not implemented yet!"
+ );
+}
+
+bool Region::containsShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return containsRegion(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return containsPoint(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::containsShape: Not implemented yet!"
+ );
+}
+
+bool Region::touchesShape(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return touchesRegion(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return touchesPoint(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::touchesShape: Not implemented yet!"
+ );
+}
+
+void Region::getCenter(Point& out) const
+{
+ out.makeDimension(m_dimension);
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ out.m_pCoords[i] = (m_pLow[i] + m_pHigh[i]) / 2.0;
+ }
+}
+
+uint32_t Region::getDimension() const
+{
+ return m_dimension;
+}
+
+void Region::getMBR(Region& out) const
+{
+ out = *this;
+}
+
+double Region::getArea() const
+{
+ double area = 1.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ area *= m_pHigh[i] - m_pLow[i];
+ }
+
+ return area;
+}
+
+double Region::getMinimumDistance(const IShape& s) const
+{
+ const Region* pr = dynamic_cast<const Region*>(&s);
+ if (pr != 0) return getMinimumDistance(*pr);
+
+ const Point* ppt = dynamic_cast<const Point*>(&s);
+ if (ppt != 0) return getMinimumDistance(*ppt);
+
+ throw Tools::IllegalStateException(
+ "Region::getMinimumDistance: Not implemented yet!"
+ );
+}
+
+bool Region::intersectsRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::intersectsRegion: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (m_pLow[i] > r.m_pHigh[i] || m_pHigh[i] < r.m_pLow[i]) return false;
+ }
+ return true;
+}
+
+bool Region::containsRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::containsRegion: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (m_pLow[i] > r.m_pLow[i] || m_pHigh[i] < r.m_pHigh[i]) return false;
+ }
+ return true;
+}
+
+bool Region::touchesRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::touchesRegion: Regions have different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ (m_pLow[i] >= r.m_pLow[i] + std::numeric_limits<double>::epsilon() &&
+ m_pLow[i] <= r.m_pLow[i] - std::numeric_limits<double>::epsilon()) ||
+ (m_pHigh[i] >= r.m_pHigh[i] + std::numeric_limits<double>::epsilon() &&
+ m_pHigh[i] <= r.m_pHigh[i] - std::numeric_limits<double>::epsilon()))
+ return false;
+ }
+ return true;
+}
+
+double Region::getMinimumDistance(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getMinimumDistance: Regions have different number of dimensions."
+ );
+
+ double ret = 0.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ double x = 0.0;
+
+ if (r.m_pHigh[i] < m_pLow[i])
+ {
+ x = std::abs(r.m_pHigh[i] - m_pLow[i]);
+ }
+ else if (m_pHigh[i] < r.m_pLow[i])
+ {
+ x = std::abs(r.m_pLow[i] - m_pHigh[i]);
+ }
+
+ ret += x * x;
+ }
+
+ return std::sqrt(ret);
+}
+
+bool Region::containsPoint(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::containsPoint: Point has different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (m_pLow[i] > p.getCoordinate(i) || m_pHigh[i] < p.getCoordinate(i)) return false;
+ }
+ return true;
+}
+
+bool Region::touchesPoint(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::touchesPoint: Point has different number of dimensions."
+ );
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ (m_pLow[i] >= p.getCoordinate(i) - std::numeric_limits<double>::epsilon() &&
+ m_pLow[i] <= p.getCoordinate(i) + std::numeric_limits<double>::epsilon()) ||
+ (m_pHigh[i] >= p.getCoordinate(i) - std::numeric_limits<double>::epsilon() &&
+ m_pHigh[i] <= p.getCoordinate(i) + std::numeric_limits<double>::epsilon()))
+ return true;
+ }
+ return false;
+}
+
+double Region::getMinimumDistance(const Point& p) const
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getMinimumDistance: Point has different number of dimensions."
+ );
+
+ double ret = 0.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (p.getCoordinate(i) < m_pLow[i])
+ {
+ ret += std::pow(m_pLow[i] - p.getCoordinate(i), 2.0);
+ }
+ else if (p.getCoordinate(i) > m_pHigh[i])
+ {
+ ret += std::pow(p.getCoordinate(i) - m_pHigh[i], 2.0);
+ }
+ }
+
+ return std::sqrt(ret);
+}
+
+Region Region::getIntersectingRegion(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getIntersectingRegion: Regions have different number of dimensions."
+ );
+
+ Region ret;
+ ret.makeInfinite(m_dimension);
+
+ // check for intersection.
+ // marioh: avoid function call since this is called billions of times.
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (m_pLow[cDim] > r.m_pHigh[cDim] || m_pHigh[cDim] < r.m_pLow[cDim]) return ret;
+ }
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ ret.m_pLow[cDim] = std::max(m_pLow[cDim], r.m_pLow[cDim]);
+ ret.m_pHigh[cDim] = std::min(m_pHigh[cDim], r.m_pHigh[cDim]);
+ }
+
+ return ret;
+}
+
+double Region::getIntersectingArea(const Region& r) const
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getIntersectingArea: Regions have different number of dimensions."
+ );
+
+ double ret = 1.0;
+ double f1, f2;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (m_pLow[cDim] > r.m_pHigh[cDim] || m_pHigh[cDim] < r.m_pLow[cDim]) return 0.0;
+
+ f1 = std::max(m_pLow[cDim], r.m_pLow[cDim]);
+ f2 = std::min(m_pHigh[cDim], r.m_pHigh[cDim]);
+ ret *= f2 - f1;
+ }
+
+ return ret;
+}
+
+/*
+ * Returns the margin of a region. It is calcuated as the sum of 2^(d-1) * width, in each dimension.
+ * It is actually the sum of all edges, no matter what the dimensionality is.
+*/
+double Region::getMargin() const
+{
+ double mul = std::pow(2.0, static_cast<double>(m_dimension) - 1.0);
+ double margin = 0.0;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ margin += (m_pHigh[i] - m_pLow[i]) * mul;
+ }
+
+ return margin;
+}
+
+void Region::combineRegion(const Region& r)
+{
+ if (m_dimension != r.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::combineRegion: Region has different number of dimensions."
+ );
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(m_pLow[cDim], r.m_pLow[cDim]);
+ m_pHigh[cDim] = std::max(m_pHigh[cDim], r.m_pHigh[cDim]);
+ }
+}
+
+void Region::combinePoint(const Point& p)
+{
+ if (m_dimension != p.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::combinePoint: Point has different number of dimensions."
+ );
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ m_pLow[cDim] = std::min(m_pLow[cDim], p.m_pCoords[cDim]);
+ m_pHigh[cDim] = std::max(m_pHigh[cDim], p.m_pCoords[cDim]);
+ }
+}
+
+void Region::getCombinedRegion(Region& out, const Region& in) const
+{
+ if (m_dimension != in.m_dimension)
+ throw Tools::IllegalArgumentException(
+ "Region::getCombinedRegion: Regions have different number of dimensions."
+ );
+
+ out = *this;
+ out.combineRegion(in);
+}
+
+double Region::getLow(uint32_t index) const
+{
+ if (index < 0 || index >= m_dimension)
+ throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pLow[index];
+}
+
+double Region::getHigh(uint32_t index) const
+{
+ if (index < 0 || index >= m_dimension)
+ throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pHigh[index];
+}
+
+void Region::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pLow[cIndex] = std::numeric_limits<double>::max();
+ m_pHigh[cIndex] = -std::numeric_limits<double>::max();
+ }
+}
+
+void Region::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ delete[] m_pLow;
+ delete[] m_pHigh;
+
+ // remember that this is not a constructor. The object will be destructed normally if
+ // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
+ m_pLow = 0; m_pHigh = 0;
+
+ m_dimension = dimension;
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const Region& r)
+{
+ uint32_t i;
+
+ os << "Low: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pLow[i] << " ";
+ }
+
+ os << ", High: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pHigh[i] << " ";
+ }
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.cc
new file mode 100644
index 000000000..9d2bd11aa
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.cc
@@ -0,0 +1,93 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "SpatialIndexImpl.h"
+
+#include "../rtree/RTree.h"
+#include "../mvrtree/MVRTree.h"
+#include "../tprtree/TPRTree.h"
+
+SpatialIndex::InvalidPageException::InvalidPageException(id_type id)
+{
+ std::ostringstream s;
+ s << "Unknown page id " << id;
+ m_error = s.str();
+}
+
+std::string SpatialIndex::InvalidPageException::what()
+{
+ return "InvalidPageException: " + m_error;
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const ISpatialIndex& i)
+{
+ const SpatialIndex::RTree::RTree* pRTree = dynamic_cast<const SpatialIndex::RTree::RTree*>(&i);
+ if (pRTree != 0)
+ {
+ os << *pRTree;
+ return os;
+ }
+
+ const SpatialIndex::MVRTree::MVRTree* pMVRTree = dynamic_cast<const SpatialIndex::MVRTree::MVRTree*>(&i);
+ if (pMVRTree != 0)
+ {
+ os << *pMVRTree;
+ return os;
+ }
+
+ const SpatialIndex::TPRTree::TPRTree* pTPRTree = dynamic_cast<const SpatialIndex::TPRTree::TPRTree*>(&i);
+ if (pTPRTree != 0)
+ {
+ os << *pTPRTree;
+ return os;
+ }
+
+ std::cerr << "ISpatialIndex operator<<: Not implemented yet for this index type." << std::endl;
+ return os;
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const IStatistics& s)
+{
+ const SpatialIndex::RTree::Statistics* pRTreeStats = dynamic_cast<const SpatialIndex::RTree::Statistics*>(&s);
+ if (pRTreeStats != 0)
+ {
+ os << *pRTreeStats;
+ return os;
+ }
+
+ const SpatialIndex::MVRTree::Statistics* pMVRTreeStats = dynamic_cast<const SpatialIndex::MVRTree::Statistics*>(&s);
+ if (pMVRTreeStats != 0)
+ {
+ os << * pMVRTreeStats;
+ return os;
+ }
+
+ const SpatialIndex::TPRTree::Statistics* pTPRTreeStats = dynamic_cast<const SpatialIndex::TPRTree::Statistics*>(&s);
+ if (pTPRTreeStats != 0)
+ {
+ os << * pTPRTreeStats;
+ return os;
+ }
+
+ std::cerr << "IStatistics operator<<: Not implemented yet for this index type." << std::endl;
+ return os;
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.h b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.h
new file mode 100644
index 000000000..5a24bbc6e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/SpatialIndexImpl.h
@@ -0,0 +1,32 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+typedef Tools::PoolPointer<Region> RegionPtr;
+typedef Tools::PoolPointer<Point> PointPtr;
+typedef Tools::PoolPointer<TimeRegion> TimeRegionPtr;
+typedef Tools::PoolPointer<MovingRegion> MovingRegionPtr;
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimePoint.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimePoint.cc
new file mode 100644
index 000000000..d860a0168
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimePoint.cc
@@ -0,0 +1,297 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <limits>
+
+#include "../../include/SpatialIndex.h"
+
+using namespace SpatialIndex;
+
+TimePoint::TimePoint()
+ : Point(), m_startTime(-std::numeric_limits<double>::max()), m_endTime(std::numeric_limits<double>::max())
+{
+}
+
+TimePoint::TimePoint(const double* pCoords, const IInterval& ti, uint32_t dimension)
+ : Point(pCoords, dimension), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimePoint::TimePoint(const double* pCoords, double tStart, double tEnd, uint32_t dimension)
+ : Point(pCoords, dimension), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimePoint::TimePoint(const Point& p, const IInterval& ti)
+ : Point(p), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimePoint::TimePoint(const Point& p, double tStart, double tEnd)
+ : Point(p), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimePoint::TimePoint(const TimePoint& p)
+ : m_startTime(p.m_startTime), m_endTime(p.m_endTime)
+{
+ m_dimension = p.m_dimension;
+
+ m_pCoords = new double[m_dimension];
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+}
+
+TimePoint::~TimePoint()
+{
+}
+
+TimePoint& TimePoint::operator=(const TimePoint& p)
+{
+ if (this != &p)
+ {
+ makeDimension(p.m_dimension);
+ memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
+ m_startTime = p.m_startTime;
+ m_endTime = p.m_endTime;
+ }
+
+ return *this;
+}
+
+bool TimePoint::operator==(const TimePoint& p) const
+{
+ if (
+ m_startTime < p.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > p.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < p.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > p.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
+ {
+ if (
+ m_pCoords[cDim] < p.m_pCoords[cDim] - std::numeric_limits<double>::epsilon() ||
+ m_pCoords[cDim] > p.m_pCoords[cDim] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+
+ return true;
+}
+
+//
+// IObject interface
+//
+TimePoint* TimePoint::clone()
+{
+ return new TimePoint(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t TimePoint::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + m_dimension * sizeof(double));
+}
+
+void TimePoint::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void TimePoint::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// ITimeShape interface
+//
+bool TimePoint::intersectsShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return pr->containsPointInTime(*this);
+
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimePoint::intersectsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimePoint::containsShapeInTime(const ITimeShape& in) const
+{
+ return false;
+}
+
+bool TimePoint::containsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ return false;
+}
+
+bool TimePoint::touchesShapeInTime(const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+bool TimePoint::touchesShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+double TimePoint::getAreaInTime() const
+{
+ return 0.0;
+}
+
+double TimePoint::getAreaInTime(const IInterval& ivI) const
+{
+ return 0.0;
+}
+
+double TimePoint::getIntersectingAreaInTime(const ITimeShape& r) const
+{
+ return 0.0;
+}
+
+double TimePoint::getIntersectingAreaInTime(const IInterval& ivI, const ITimeShape& r) const
+{
+ return 0.0;
+}
+
+//
+// IInterval interface
+//
+Tools::IInterval& TimePoint::operator=(const Tools::IInterval& i)
+{
+ if (this != &i)
+ {
+ m_startTime = i.getLowerBound();
+ m_endTime = i.getUpperBound();
+ }
+
+ return *this;
+}
+
+double TimePoint::getLowerBound() const
+{
+ return m_startTime;
+}
+
+double TimePoint::getUpperBound() const
+{
+ return m_endTime;
+}
+
+void TimePoint::setBounds(double l, double h)
+{
+ assert(l <= h);
+
+ m_startTime = l;
+ m_endTime = h;
+}
+
+bool TimePoint::intersectsInterval(const IInterval& ti) const
+{
+ return intersectsInterval(ti.getIntervalType(), ti.getLowerBound(), ti.getUpperBound());
+}
+
+bool TimePoint::intersectsInterval(Tools::IntervalType t, const double start, const double end) const
+{
+ //if (m_startTime != start &&
+ // (m_startTime >= end || m_endTime <= start)) return false;
+ if (m_startTime >= end || m_endTime <= start) return false;
+
+ return true;
+}
+
+bool TimePoint::containsInterval(const IInterval& ti) const
+{
+ if (m_startTime <= ti.getLowerBound() && m_endTime >= ti.getUpperBound()) return true;
+ return false;
+}
+
+Tools::IntervalType TimePoint::getIntervalType() const
+{
+ return Tools::IT_RIGHTOPEN;
+}
+
+void TimePoint::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pCoords[cIndex] = std::numeric_limits<double>::max();
+ }
+
+ m_startTime = std::numeric_limits<double>::max();
+ m_endTime = -std::numeric_limits<double>::max();
+}
+
+void TimePoint::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ m_dimension = dimension;
+
+ delete[] m_pCoords;
+ m_pCoords = 0;
+
+ m_pCoords = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const TimePoint& pt)
+{
+ uint32_t i;
+
+ for (i = 0; i < pt.m_dimension; ++i)
+ {
+ os << pt.m_pCoords[i] << " ";
+ }
+
+ os << ", Start: " << pt.m_startTime << ", End: " << pt.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimeRegion.cc b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimeRegion.cc
new file mode 100644
index 000000000..00d575223
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/spatialindex/TimeRegion.cc
@@ -0,0 +1,419 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../../include/SpatialIndex.h"
+
+#include <cstring>
+#include <limits>
+
+using namespace SpatialIndex;
+
+TimeRegion::TimeRegion()
+ : Region(), m_startTime(-std::numeric_limits<double>::max()), m_endTime(std::numeric_limits<double>::max())
+{
+}
+
+TimeRegion::TimeRegion(const double* pLow, const double* pHigh, const IInterval& ti, uint32_t dimension)
+ : Region(pLow, pHigh, dimension), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimeRegion::TimeRegion(const double* pLow, const double* pHigh, double tStart, double tEnd, uint32_t dimension)
+ : Region(pLow, pHigh, dimension), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimeRegion::TimeRegion(const Point& low, const Point& high, const IInterval& ti)
+ : Region(low, high), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimeRegion::TimeRegion(const Point& low, const Point& high, double tStart, double tEnd)
+ : Region(low, high), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimeRegion::TimeRegion(const Region& r, const IInterval& ti)
+ : Region(r), m_startTime(ti.getLowerBound()), m_endTime(ti.getUpperBound())
+{
+}
+
+TimeRegion::TimeRegion(const Region& r, double tStart, double tEnd)
+ : Region(r), m_startTime(tStart), m_endTime(tEnd)
+{
+}
+
+TimeRegion::TimeRegion(const TimePoint& low, const TimePoint& high)
+ : Region((Point&) low, (Point&) high), m_startTime(low.m_startTime), m_endTime(high.m_endTime)
+{
+}
+
+TimeRegion::TimeRegion(const TimeRegion& r)
+ : m_startTime(r.m_startTime), m_endTime(r.m_endTime)
+{
+ m_dimension = r.m_dimension;
+ m_pLow = 0;
+
+ try
+ {
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+ catch (...)
+ {
+ delete[] m_pLow;
+ throw;
+ }
+
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+}
+
+TimeRegion::~TimeRegion()
+{
+}
+
+TimeRegion& TimeRegion::operator=(const TimeRegion& r)
+{
+ if(this != &r)
+ {
+ makeDimension(r.m_dimension);
+ memcpy(m_pLow, r.m_pLow, m_dimension * sizeof(double));
+ memcpy(m_pHigh, r.m_pHigh, m_dimension * sizeof(double));
+
+ m_startTime = r.m_startTime;
+ m_endTime = r.m_endTime;
+ }
+
+ return *this;
+}
+
+bool TimeRegion::operator==(const TimeRegion& r) const
+{
+ if (m_startTime < r.m_startTime - std::numeric_limits<double>::epsilon() ||
+ m_startTime > r.m_startTime + std::numeric_limits<double>::epsilon() ||
+ m_endTime < r.m_endTime - std::numeric_limits<double>::epsilon() ||
+ m_endTime > r.m_endTime + std::numeric_limits<double>::epsilon())
+ return false;
+
+ for (uint32_t i = 0; i < m_dimension; ++i)
+ {
+ if (
+ m_pLow[i] < r.m_pLow[i] - std::numeric_limits<double>::epsilon() ||
+ m_pLow[i] > r.m_pLow[i] + std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] < r.m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
+ m_pHigh[i] > r.m_pHigh[i] + std::numeric_limits<double>::epsilon())
+ return false;
+ }
+ return true;
+}
+
+bool TimeRegion::intersectsRegionInTime(const TimeRegion& r) const
+{
+ // they should just intersect in time.
+ // check if they intersect in time first.
+ // the first check is needed for the following case:
+ // m_endTime == m_startTime == r.m_startTime.
+ // For open ended intervals this should be considered as an intersection
+ // (takes care of degenarate intervals)
+ //if (m_startTime != r.m_startTime &&
+ // (m_startTime >= r.m_endTime || m_endTime <= r.m_startTime))
+ if (! intersectsInterval(r)) return false;
+ return Region::intersectsRegion(r);
+}
+
+bool TimeRegion::containsRegionInTime(const TimeRegion& r) const
+{
+ // it should be contained in time.
+ if (! containsInterval(r)) return false;
+ return Region::containsRegion(r);
+}
+
+bool TimeRegion::touchesRegionInTime(const TimeRegion& r) const
+{
+ // they should just intersect in time.
+ //if (m_startTime != r.m_startTime &&
+ // (m_startTime >= r.m_endTime || m_endTime <= r.m_startTime))
+ if (!intersectsInterval(r)) return false;
+ return Region::touchesRegion(r);
+}
+
+bool TimeRegion::containsPointInTime(const TimePoint& p) const
+{
+ // it should be contained in time.
+ //if (p.m_startTime < m_startTime || p.m_endTime > m_endTime) return false;
+ if (containsInterval(p)) return false;
+ return Region::containsPoint(p);
+}
+
+bool TimeRegion::touchesPointInTime(const TimePoint& p) const
+{
+ // they should just intersect in time.
+ //if (m_startTime != p.m_startTime &&
+ // (m_startTime >= p.m_endTime || m_endTime <= p.m_startTime))
+ if (intersectsInterval(p)) return false;
+ return Region::touchesPoint(p);
+}
+
+void TimeRegion::combineRegionInTime(const TimeRegion& r)
+{
+ Region::combineRegion(r);
+
+ m_startTime = std::min(m_startTime, r.m_startTime);
+ m_endTime = std::max(m_endTime, r.m_endTime);
+}
+
+void TimeRegion::getCombinedRegionInTime(TimeRegion& out, const TimeRegion& in) const
+{
+ Region::getCombinedRegion(out, in);
+
+ out.m_startTime = std::min(m_startTime, in.m_startTime);
+ out.m_endTime = std::max(m_endTime, in.m_endTime);
+}
+
+//
+// IObject interface
+//
+TimeRegion* TimeRegion::clone()
+{
+ return new TimeRegion(*this);
+}
+
+//
+// ISerializable interface
+//
+uint32_t TimeRegion::getByteArraySize()
+{
+ return (sizeof(uint32_t) + 2 * sizeof(double) + 2 * m_dimension * sizeof(double));
+}
+
+void TimeRegion::loadFromByteArray(const byte* ptr)
+{
+ uint32_t dimension;
+
+ memcpy(&dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_startTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_endTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+
+ makeDimension(dimension);
+ memcpy(m_pLow, ptr, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(m_pHigh, ptr, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+void TimeRegion::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_startTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_endTime, sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, m_pLow, m_dimension * sizeof(double));
+ ptr += m_dimension * sizeof(double);
+ memcpy(ptr, m_pHigh, m_dimension * sizeof(double));
+ //ptr += m_dimension * sizeof(double);
+}
+
+//
+// ITimeShape interface
+//
+bool TimeRegion::intersectsShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return intersectsRegionInTime(*pr);
+
+ const TimePoint* ppt = dynamic_cast<const TimePoint*>(&in);
+ if (ppt != 0) return containsPointInTime(*ppt);
+
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::intersectsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("intersectsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::containsShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return containsRegionInTime(*pr);
+
+ const TimePoint* ppt = dynamic_cast<const TimePoint*>(&in);
+ if (ppt != 0) return containsPointInTime(*ppt);
+
+ throw Tools::IllegalStateException("containsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::containsShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("containsShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::touchesShapeInTime(const ITimeShape& in) const
+{
+ const TimeRegion* pr = dynamic_cast<const TimeRegion*>(&in);
+ if (pr != 0) return touchesRegionInTime(*pr);
+
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+bool TimeRegion::touchesShapeInTime(const IInterval& ivI, const ITimeShape& in) const
+{
+ throw Tools::IllegalStateException("touchesShapeInTime: Not implemented yet!");
+}
+
+double TimeRegion::getAreaInTime() const
+{
+ throw Tools::IllegalStateException("getAreaInTime: Not implemented yet!");
+}
+
+double TimeRegion::getAreaInTime(const IInterval& ivI) const
+{
+ throw Tools::IllegalStateException("getAreaInTime: Not implemented yet!");
+}
+
+double TimeRegion::getIntersectingAreaInTime(const ITimeShape& r) const
+{
+ throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
+}
+
+double TimeRegion::getIntersectingAreaInTime(const IInterval& ivI, const ITimeShape& r) const
+{
+ throw Tools::IllegalStateException("getIntersectingAreaInTime: Not implemented yet!");
+}
+
+//
+// IInterval interface
+//
+Tools::IInterval& TimeRegion::operator=(const Tools::IInterval& i)
+{
+ if (this != &i)
+ {
+ m_startTime = i.getLowerBound();
+ m_endTime = i.getUpperBound();
+ }
+
+ return *this;
+}
+
+double TimeRegion::getLowerBound() const
+{
+ return m_startTime;
+}
+
+double TimeRegion::getUpperBound() const
+{
+ return m_endTime;
+}
+
+void TimeRegion::setBounds(double l, double h)
+{
+ assert(m_startTime <= m_endTime);
+
+ m_startTime = l;
+ m_endTime = h;
+}
+
+bool TimeRegion::intersectsInterval(const IInterval& ti) const
+{
+ return intersectsInterval(ti.getIntervalType(), ti.getLowerBound(), ti.getUpperBound());
+}
+
+bool TimeRegion::intersectsInterval(Tools::IntervalType t, const double start, const double end) const
+{
+ //if (m_startTime != start &&
+ // (m_startTime >= end || m_endTime <= start)) return false;
+ // this will not work for degenarate intervals.
+ if (m_startTime >= end || m_endTime <= start) return false;
+
+ return true;
+}
+
+bool TimeRegion::containsInterval(const IInterval& ti) const
+{
+ if (m_startTime <= ti.getLowerBound() && m_endTime >= ti.getUpperBound()) return true;
+ return false;
+}
+
+Tools::IntervalType TimeRegion::getIntervalType() const
+{
+ return Tools::IT_RIGHTOPEN;
+}
+
+void TimeRegion::makeInfinite(uint32_t dimension)
+{
+ makeDimension(dimension);
+ for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
+ {
+ m_pLow[cIndex] = std::numeric_limits<double>::max();
+ m_pHigh[cIndex] = -std::numeric_limits<double>::max();
+ }
+
+ m_startTime = std::numeric_limits<double>::max();
+ m_endTime = -std::numeric_limits<double>::max();
+}
+
+void TimeRegion::makeDimension(uint32_t dimension)
+{
+ if (m_dimension != dimension)
+ {
+ m_dimension = dimension;
+
+ delete[] m_pLow;
+ delete[] m_pHigh;
+ m_pLow = 0; m_pHigh = 0;
+
+ m_pLow = new double[m_dimension];
+ m_pHigh = new double[m_dimension];
+ }
+}
+
+std::ostream& SpatialIndex::operator<<(std::ostream& os, const TimeRegion& r)
+{
+ uint32_t i;
+
+ os << "Low: ";
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pLow[i] << " ";
+ }
+
+ os << ", High: ";
+
+ for (i = 0; i < r.m_dimension; ++i)
+ {
+ os << r.m_pHigh[i] << " ";
+ }
+
+ os << ", Start: " << r.m_startTime << ", End: " << r.m_endTime;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/all-wcprops
new file mode 100644
index 000000000..4741ee8b7
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/all-wcprops
@@ -0,0 +1,59 @@
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/158/spatialindex/trunk/src/storagemanager
+END
+Buffer.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/storagemanager/Buffer.h
+END
+DiskStorageManager.h
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/storagemanager/DiskStorageManager.h
+END
+RandomEvictionsBuffer.cc
+K 25
+svn:wc:ra_dav:version-url
+V 89
+/spatialindex/!svn/ver/158/spatialindex/trunk/src/storagemanager/RandomEvictionsBuffer.cc
+END
+RandomEvictionsBuffer.h
+K 25
+svn:wc:ra_dav:version-url
+V 87
+/spatialindex/!svn/ver/99/spatialindex/trunk/src/storagemanager/RandomEvictionsBuffer.h
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/spatialindex/!svn/ver/45/spatialindex/trunk/src/storagemanager/Makefile.am
+END
+MemoryStorageManager.cc
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/storagemanager/MemoryStorageManager.cc
+END
+Buffer.cc
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/storagemanager/Buffer.cc
+END
+DiskStorageManager.cc
+K 25
+svn:wc:ra_dav:version-url
+V 86
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/storagemanager/DiskStorageManager.cc
+END
+MemoryStorageManager.h
+K 25
+svn:wc:ra_dav:version-url
+V 87
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/storagemanager/MemoryStorageManager.h
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/dir-prop-base
new file mode 100644
index 000000000..60357233a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/dir-prop-base
@@ -0,0 +1,10 @@
+K 10
+svn:ignore
+V 34
+Makefile.in
+.libs
+.deps
+Makefile
+
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/entries
new file mode 100644
index 000000000..3cb6f0abc
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/entries
@@ -0,0 +1,334 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/storagemanager
+http://svn.gispython.org/spatialindex
+
+
+
+2009-10-30T17:09:14.837776Z
+158
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Buffer.h
+file
+
+
+
+
+2011-08-01T00:42:34.385378Z
+94f2d7e7c44093c7c05f5300ece746c2
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2228
+
+DiskStorageManager.h
+file
+
+
+
+
+2011-08-01T00:42:34.385378Z
+9bd3718b4137b193929124050414f022
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1703
+
+RandomEvictionsBuffer.cc
+file
+
+
+
+
+2011-08-01T00:42:34.385378Z
+18366c036c6b03381b91f110885ff78d
+2009-10-30T17:09:14.837776Z
+158
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2719
+
+RandomEvictionsBuffer.h
+file
+
+
+
+
+2011-08-01T00:42:34.385378Z
+5189e602bc4b650a48215ed1f2ea0a2c
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1269
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.385378Z
+d5ec09ef9b0b39266f73187e1d98f5ae
+2008-01-17T23:34:01.575758Z
+45
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+332
+
+MemoryStorageManager.cc
+file
+
+
+
+
+2011-08-01T00:42:34.409261Z
+3b94af6eadf797555dc5bbfff0aa716a
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2856
+
+Buffer.cc
+file
+
+
+
+
+2011-08-01T00:42:34.409261Z
+ea93f0fe41f1d4a84899dbecafec54d8
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3648
+
+DiskStorageManager.cc
+file
+
+
+
+
+2011-08-01T00:42:34.409261Z
+79d50b6e39a2b68c61da0777d95bd992
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+15691
+
+MemoryStorageManager.h
+file
+
+
+
+
+2011-08-01T00:42:34.409261Z
+2696238537d4e8ef56d99755d86ff3e5
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1708
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.cc.svn-base
new file mode 100644
index 000000000..f605cd0f8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.cc.svn-base
@@ -0,0 +1,142 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Buffer.h"
+
+Buffer::Buffer(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_capacity(10),
+ m_bWriteThrough(false),
+ m_pStorageManager(&sm),
+ m_u64Hits(0)
+{
+ Tools::Variant var = ps.getProperty("Capacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("Property Capacity must be Tools::VT_ULONG");
+ m_capacity = var.m_val.ulVal;
+ }
+
+ var = ps.getProperty("WriteThrough");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("Property WriteThrough must be Tools::VT_BOOL");
+ m_bWriteThrough = var.m_val.blVal;
+ }
+}
+
+Buffer::~Buffer()
+{
+ for (std::map<id_type, Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); ++it)
+ {
+ if ((*it).second->m_bDirty)
+ {
+ id_type page = (*it).first;
+ m_pStorageManager->storeByteArray(page, (*it).second->m_length, (*it).second->m_pData);
+ }
+ delete (*it).second;
+ }
+}
+
+void Buffer::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ std::map<id_type, Entry*>::iterator it = m_buffer.find(page);
+
+ if (it != m_buffer.end())
+ {
+ ++m_u64Hits;
+ len = (*it).second->m_length;
+ *data = new byte[len];
+ memcpy(*data, (*it).second->m_pData, len);
+ }
+ else
+ {
+ m_pStorageManager->loadByteArray(page, len, data);
+ addEntry(page, new Entry(len, static_cast<const byte*>(*data)));
+ }
+}
+
+void Buffer::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ if (page == NewPage)
+ {
+ m_pStorageManager->storeByteArray(page, len, data);
+ assert(m_buffer.find(page) == m_buffer.end());
+ addEntry(page, new Entry(len, data));
+ }
+ else
+ {
+ if (m_bWriteThrough)
+ {
+ m_pStorageManager->storeByteArray(page, len, data);
+ }
+
+ Entry* e = new Entry(len, data);
+ if (m_bWriteThrough == false) e->m_bDirty = true;
+
+ std::map<id_type, Entry*>::iterator it = m_buffer.find(page);
+ if (it != m_buffer.end())
+ {
+ delete (*it).second;
+ (*it).second = e;
+ if (m_bWriteThrough == false) ++m_u64Hits;
+ }
+ else
+ {
+ addEntry(page, e);
+ }
+ }
+}
+
+void Buffer::deleteByteArray(const id_type page)
+{
+ std::map<id_type, Entry*>::iterator it = m_buffer.find(page);
+ if (it != m_buffer.end())
+ {
+ delete (*it).second;
+ m_buffer.erase(it);
+ }
+
+ m_pStorageManager->deleteByteArray(page);
+}
+
+void Buffer::clear()
+{
+ for (std::map<id_type, Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); ++it)
+ {
+ if ((*it).second->m_bDirty)
+ {
+ id_type page = (*it).first;
+ m_pStorageManager->storeByteArray(page, ((*it).second)->m_length, static_cast<const byte*>(((*it).second)->m_pData));
+ }
+
+ delete (*it).second;
+ }
+
+ m_buffer.clear();
+ m_u64Hits = 0;
+}
+
+uint64_t Buffer::getHits()
+{
+ return m_u64Hits;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.h.svn-base
new file mode 100644
index 000000000..450e38a5b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Buffer.h.svn-base
@@ -0,0 +1,78 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include <cstring>
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class Buffer : public IBuffer
+ {
+ public:
+ Buffer(IStorageManager& sm, Tools::PropertySet& ps);
+ // String Value Description
+ // ----------------------------------------------
+ // Capacity VT_ULONG Buffer maximum capacity.
+ // WriteThrough VT_BOOL Enable or disable write through policy.
+
+ virtual ~Buffer();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ virtual void clear();
+ virtual uint64_t getHits();
+
+ protected:
+ class Entry
+ {
+ public:
+ Entry(uint32_t l, const byte* const d) : m_pData(0), m_length(l), m_bDirty(false)
+ {
+ m_pData = new byte[m_length];
+ memcpy(m_pData, d, m_length);
+ }
+
+ ~Entry() { delete[] m_pData; }
+
+ byte* m_pData;
+ uint32_t m_length;
+ bool m_bDirty;
+ }; // Entry
+
+ virtual void addEntry(id_type page, Entry* pEntry) = 0;
+ virtual void removeEntry() = 0;
+
+ uint32_t m_capacity;
+ bool m_bWriteThrough;
+ IStorageManager* m_pStorageManager;
+ std::map<id_type, Entry*> m_buffer;
+ uint64_t m_u64Hits;
+ }; // Buffer
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.cc.svn-base
new file mode 100644
index 000000000..ecf1c9139
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.cc.svn-base
@@ -0,0 +1,501 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <fstream>
+#include <cstring>
+
+// For checking if a file exists - hobu
+#include <sys/stat.h>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "DiskStorageManager.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+bool CheckFilesExists(Tools::PropertySet& ps)
+{
+ bool bExists = false;
+
+ std::string filename("");
+ std::string idx("idx");
+ std::string dat("dat");
+
+ Tools::Variant idx_name;
+ Tools::Variant dat_name;
+ Tools::Variant fn;
+
+ idx_name = ps.getProperty("FileNameIdx");
+ dat_name = ps.getProperty("FileNameDat");
+ fn = ps.getProperty("FileName");
+
+ if (idx_name.m_varType != Tools::VT_EMPTY) dat = std::string(idx_name.m_val.pcVal);
+ if (dat_name.m_varType != Tools::VT_EMPTY) idx = std::string(dat_name.m_val.pcVal);
+ if (fn.m_varType != Tools::VT_EMPTY) filename = std::string(fn.m_val.pcVal);
+
+ struct stat stats;
+
+ std::ostringstream os;
+ int ret;
+ os << filename <<"."<<dat;
+ std::string data_name = os.str();
+ ret = stat(data_name.c_str(), &stats);
+
+ if (ret == 0) bExists = true;
+
+ os.str("");
+ os << filename <<"."<<idx;
+ std::string index_name = os.str();
+ ret = stat(index_name.c_str(), &stats);
+
+ if ((ret == 0) && (bExists == true)) bExists = true;
+
+ return bExists;
+}
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::returnDiskStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new DiskStorageManager(ps);
+ return sm;
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::createNewDiskStorageManager(std::string& baseName, uint32_t pageSize)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = true;
+ ps.setProperty("Overwrite", var);
+ // overwrite the file if it exists.
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>(baseName.c_str());
+ ps.setProperty("FileName", var);
+ // .idx and .dat extensions will be added.
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = pageSize;
+ ps.setProperty("PageSize", var);
+ // specify the page size. Since the index may also contain user defined data
+ // there is no way to know how big a single node may become. The storage manager
+ // will use multiple pages per node if needed. Off course this will slow down performance.
+
+ return returnDiskStorageManager(ps);
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::loadDiskStorageManager(std::string& baseName)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>(baseName.c_str());
+ ps.setProperty("FileName", var);
+ // .idx and .dat extensions will be added.
+
+ return returnDiskStorageManager(ps);
+}
+
+DiskStorageManager::DiskStorageManager(Tools::PropertySet& ps) : m_pageSize(0), m_nextPage(-1), m_buffer(0)
+{
+ Tools::Variant var;
+
+ // Open/Create flag.
+ bool bOverwrite = false;
+ var = ps.getProperty("Overwrite");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL)
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property Overwrite must be Tools::VT_BOOL");
+ bOverwrite = var.m_val.blVal;
+ }
+
+ // storage filename.
+ var = ps.getProperty("FileName");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR)
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property FileName must be Tools::VT_PCHAR");
+
+ std::string idx("idx");
+ std::string dat("dat");
+
+ Tools::Variant idx_name = ps.getProperty("FileNameIdx");
+ if (idx_name.m_varType != Tools::VT_EMPTY) idx = std::string(idx_name.m_val.pcVal);
+
+ Tools::Variant dat_name = ps.getProperty("FileNameDat");
+ if (dat_name.m_varType != Tools::VT_EMPTY) dat = std::string(dat_name.m_val.pcVal);
+
+ std::string sIndexFile = std::string(var.m_val.pcVal) + "." + idx;
+ std::string sDataFile = std::string(var.m_val.pcVal) + "." + dat;
+
+ // check if file exists.
+ bool bFileExists = CheckFilesExists(ps);
+
+ // check if file can be read/written.
+ if (bFileExists == true && bOverwrite == false)
+ {
+ m_indexFile.open(sIndexFile.c_str(), std::ios::in | std::ios::out | std::ios::binary);
+ m_dataFile.open(sDataFile.c_str(), std::ios::in | std::ios::out | std::ios::binary);
+
+ if (m_indexFile.fail() || m_dataFile.fail())
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Index/Data file cannot be read/writen.");
+ }
+ else
+ {
+ m_indexFile.open(sIndexFile.c_str(), std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
+ m_dataFile.open(sDataFile.c_str(), std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
+
+ if (m_indexFile.fail() || m_dataFile.fail())
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Index/Data file cannot be created.");
+
+ }
+ }
+ else
+ {
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property FileName was not specified.");
+ }
+
+ // find page size.
+ if (bOverwrite == true)
+ {
+ var = ps.getProperty("PageSize");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property PageSize must be Tools::VT_ULONG");
+ m_pageSize = var.m_val.ulVal;
+ m_nextPage = 0;
+ }
+ else
+ {
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: A new storage manager is created and property PageSize was not specified.");
+ }
+ }
+ else
+ {
+ m_indexFile.read(reinterpret_cast<char*>(&m_pageSize), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Failed reading pageSize.");
+
+ m_indexFile.read(reinterpret_cast<char*>(&m_nextPage), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Failed reading nextPage.");
+ }
+
+ // create buffer.
+ m_buffer = new byte[m_pageSize];
+ bzero(m_buffer, m_pageSize);
+
+ if (bOverwrite == false)
+ {
+ uint32_t count;
+ id_type page, id;
+
+ // load empty pages in memory.
+ m_indexFile.read(reinterpret_cast<char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cCount = 0; cCount < count; ++cCount)
+ {
+ m_indexFile.read(reinterpret_cast<char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ m_emptyPages.push(page);
+ }
+
+ // load index table in memory.
+ m_indexFile.read(reinterpret_cast<char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cCount = 0; cCount < count; ++cCount)
+ {
+ Entry* e = new Entry();
+
+ m_indexFile.read(reinterpret_cast<char*>(&id), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ m_indexFile.read(reinterpret_cast<char*>(&(e->m_length)), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ uint32_t count2;
+ m_indexFile.read(reinterpret_cast<char*>(&count2), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cCount2 = 0; cCount2 < count2; ++cCount2)
+ {
+ m_indexFile.read(reinterpret_cast<char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ e->m_pages.push_back(page);
+ }
+ m_pageIndex.insert(std::pair<id_type, Entry* >(id, e));
+ }
+ }
+}
+
+DiskStorageManager::~DiskStorageManager()
+{
+ flush();
+ m_indexFile.close();
+ m_dataFile.close();
+ if (m_buffer != 0) delete[] m_buffer;
+
+ std::map<id_type, Entry*>::iterator it;
+ for (it = m_pageIndex.begin(); it != m_pageIndex.end(); ++it) delete (*it).second;
+}
+
+void DiskStorageManager::flush()
+{
+ m_indexFile.seekp(0, std::ios_base::beg);
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ m_indexFile.write(reinterpret_cast<const char*>(&m_pageSize), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ m_indexFile.write(reinterpret_cast<const char*>(&m_nextPage), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ uint32_t count = static_cast<uint32_t>(m_emptyPages.size());
+ id_type page, id;
+
+ m_indexFile.write(reinterpret_cast<const char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ while (! m_emptyPages.empty())
+ {
+ page = m_emptyPages.top(); m_emptyPages.pop();
+ m_indexFile.write(reinterpret_cast<const char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ }
+
+ count = static_cast<uint32_t>(m_pageIndex.size());
+
+ m_indexFile.write(reinterpret_cast<const char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ std::map<id_type, Entry*>::iterator it;
+
+ for (it = m_pageIndex.begin(); it != m_pageIndex.end(); ++it)
+ {
+ id = (*it).first;
+ m_indexFile.write(reinterpret_cast<const char*>(&id), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ uint32_t length = (*it).second->m_length;
+ m_indexFile.write(reinterpret_cast<const char*>(&length), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ count = static_cast<uint32_t>((*it).second->m_pages.size());
+ m_indexFile.write(reinterpret_cast<const char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cIndex = 0; cIndex < count; ++cIndex)
+ {
+ page = (*it).second->m_pages[cIndex];
+ m_indexFile.write(reinterpret_cast<const char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ }
+ }
+
+ m_indexFile.flush();
+ m_dataFile.flush();
+}
+
+void DiskStorageManager::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ std::map<id_type, Entry*>::iterator it = m_pageIndex.find(page);
+
+ if (it == m_pageIndex.end())
+ throw InvalidPageException(page);
+
+ std::vector<id_type>& pages = (*it).second->m_pages;
+ uint32_t cNext = 0;
+ uint32_t cTotal = static_cast<uint32_t>(pages.size());
+
+ len = (*it).second->m_length;
+ *data = new byte[len];
+
+ byte* ptr = *data;
+ uint32_t cLen;
+ uint32_t cRem = len;
+
+ do
+ {
+ m_dataFile.seekg(pages[cNext] * m_pageSize, std::ios_base::beg);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ m_dataFile.read(reinterpret_cast<char*>(m_buffer), m_pageSize);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ cLen = (cRem > m_pageSize) ? m_pageSize : cRem;
+ memcpy(ptr, m_buffer, cLen);
+
+ ptr += cLen;
+ cRem -= cLen;
+ ++cNext;
+ }
+ while (cNext < cTotal);
+}
+
+void DiskStorageManager::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ if (page == NewPage)
+ {
+ Entry* e = new Entry();
+ e->m_length = len;
+
+ const byte* ptr = data;
+ id_type cPage;
+ uint32_t cRem = len;
+ uint32_t cLen;
+
+ while (cRem > 0)
+ {
+ if (! m_emptyPages.empty())
+ {
+ cPage = m_emptyPages.top(); m_emptyPages.pop();
+ }
+ else
+ {
+ cPage = m_nextPage;
+ ++m_nextPage;
+ }
+
+ cLen = (cRem > m_pageSize) ? m_pageSize : cRem;
+ memcpy(m_buffer, ptr, cLen);
+
+ m_dataFile.seekp(cPage * m_pageSize, std::ios_base::beg);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ m_dataFile.write(reinterpret_cast<const char*>(m_buffer), m_pageSize);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ ptr += cLen;
+ cRem -= cLen;
+ e->m_pages.push_back(cPage);
+ }
+
+ page = e->m_pages[0];
+ m_pageIndex.insert(std::pair<id_type, Entry*>(page, e));
+ }
+ else
+ {
+ // find the entry.
+ std::map<id_type, Entry*>::iterator it = m_pageIndex.find(page);
+
+ // check if it exists.
+ if (it == m_pageIndex.end())
+ throw InvalidPageException(page);
+
+ Entry* oldEntry = (*it).second;
+
+ m_pageIndex.erase(it);
+
+ Entry* e = new Entry();
+ e->m_length = len;
+
+ const byte* ptr = data;
+ id_type cPage;
+ uint32_t cRem = len;
+ uint32_t cLen, cNext = 0;
+
+ while (cRem > 0)
+ {
+ if (cNext < oldEntry->m_pages.size())
+ {
+ cPage = oldEntry->m_pages[cNext];
+ ++cNext;
+ }
+ else if (! m_emptyPages.empty())
+ {
+ cPage = m_emptyPages.top(); m_emptyPages.pop();
+ }
+ else
+ {
+ cPage = m_nextPage;
+ ++m_nextPage;
+ }
+
+ cLen = (cRem > m_pageSize) ? m_pageSize : cRem;
+ memcpy(m_buffer, ptr, cLen);
+
+ m_dataFile.seekp(cPage * m_pageSize, std::ios_base::beg);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ m_dataFile.write(reinterpret_cast<const char*>(m_buffer), m_pageSize);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ ptr += cLen;
+ cRem -= cLen;
+ e->m_pages.push_back(cPage);
+ }
+
+ while (cNext < oldEntry->m_pages.size())
+ {
+ m_emptyPages.push(oldEntry->m_pages[cNext]);
+ ++cNext;
+ }
+
+ m_pageIndex.insert(std::pair<id_type, Entry*>(page, e));
+ delete oldEntry;
+ }
+}
+
+void DiskStorageManager::deleteByteArray(const id_type page)
+{
+ std::map<id_type, Entry*>::iterator it = m_pageIndex.find(page);
+
+ if (it == m_pageIndex.end())
+ throw InvalidPageException(page);
+
+ for (uint32_t cIndex = 0; cIndex < (*it).second->m_pages.size(); ++cIndex)
+ {
+ m_emptyPages.push((*it).second->m_pages[cIndex]);
+ }
+
+ delete (*it).second;
+ m_pageIndex.erase(it);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.h.svn-base
new file mode 100644
index 000000000..178eb684e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/DiskStorageManager.h.svn-base
@@ -0,0 +1,58 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class DiskStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ DiskStorageManager(Tools::PropertySet&);
+ virtual ~DiskStorageManager();
+
+ void flush();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ private:
+ class Entry
+ {
+ public:
+ uint32_t m_length;
+ std::vector<id_type> m_pages;
+ };
+
+ std::fstream m_dataFile;
+ std::fstream m_indexFile;
+ uint32_t m_pageSize;
+ id_type m_nextPage;
+ std::priority_queue<id_type, std::vector<id_type>, std::greater<id_type> > m_emptyPages;
+ std::map<id_type, Entry*> m_pageIndex;
+
+ byte* m_buffer;
+ }; // DiskStorageManager
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..430ab3dac
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libstoragemanager.la
+INCLUDES = -I../../include
+libstoragemanager_la_SOURCES = Buffer.h Buffer.cc DiskStorageManager.cc MemoryStorageManager.cc RandomEvictionsBuffer.cc DiskStorageManager.h MemoryStorageManager.h RandomEvictionsBuffer.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.cc.svn-base
new file mode 100644
index 000000000..24ef0e04b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.cc.svn-base
@@ -0,0 +1,126 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <stdexcept>
+#include <cstring>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MemoryStorageManager.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::returnMemoryStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new MemoryStorageManager(ps);
+ return sm;
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::createNewMemoryStorageManager()
+{
+ Tools::PropertySet ps;
+ return returnMemoryStorageManager(ps);
+}
+
+MemoryStorageManager::MemoryStorageManager(Tools::PropertySet& ps)
+{
+}
+
+MemoryStorageManager::~MemoryStorageManager()
+{
+ for (std::vector<Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); ++it) delete *it;
+}
+
+void MemoryStorageManager::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ Entry* e;
+ try
+ {
+ e = m_buffer.at(page);
+ if (e == 0) throw InvalidPageException(page);
+ }
+ catch (std::out_of_range)
+ {
+ throw InvalidPageException(page);
+ }
+
+ len = e->m_length;
+ *data = new byte[len];
+
+ memcpy(*data, e->m_pData, len);
+}
+
+void MemoryStorageManager::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ if (page == NewPage)
+ {
+ Entry* e = new Entry(len, data);
+
+ if (m_emptyPages.empty())
+ {
+ m_buffer.push_back(e);
+ page = m_buffer.size() - 1;
+ }
+ else
+ {
+ page = m_emptyPages.top(); m_emptyPages.pop();
+ m_buffer[page] = e;
+ }
+ }
+ else
+ {
+ Entry* e_old;
+ try
+ {
+ e_old = m_buffer.at(page);
+ if (e_old == 0) throw InvalidPageException(page);
+ }
+ catch (std::out_of_range)
+ {
+ throw InvalidPageException(page);
+ }
+
+ Entry* e = new Entry(len, data);
+
+ delete e_old;
+ m_buffer[page] = e;
+ }
+}
+
+void MemoryStorageManager::deleteByteArray(const id_type page)
+{
+ Entry* e;
+ try
+ {
+ e = m_buffer.at(page);
+ if (e == 0) throw InvalidPageException(page);
+ }
+ catch (std::out_of_range)
+ {
+ throw InvalidPageException(page);
+ }
+
+ m_buffer[page] = 0;
+ m_emptyPages.push(page);
+
+ delete e;
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.h.svn-base
new file mode 100644
index 000000000..61a224d80
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/MemoryStorageManager.h.svn-base
@@ -0,0 +1,61 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include <cstring>
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class MemoryStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ MemoryStorageManager(Tools::PropertySet&);
+
+ virtual ~MemoryStorageManager();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ private:
+ class Entry
+ {
+ public:
+ byte* m_pData;
+ uint32_t m_length;
+
+ Entry(uint32_t l, const byte* const d) : m_pData(0), m_length(l)
+ {
+ m_pData = new byte[m_length];
+ memcpy(m_pData, d, m_length);
+ }
+
+ ~Entry() { delete[] m_pData; }
+ }; // Entry
+
+ std::vector<Entry*> m_buffer;
+ std::stack<id_type> m_emptyPages;
+ }; // MemoryStorageManager
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.cc.svn-base
new file mode 100644
index 000000000..e0e22d296
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.cc.svn-base
@@ -0,0 +1,94 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <time.h>
+#include <stdlib.h>
+#include <cmath>
+#include "../../include/tools/rand48.h"
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RandomEvictionsBuffer.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+IBuffer* SpatialIndex::StorageManager::returnRandomEvictionsBuffer(IStorageManager& sm, Tools::PropertySet& ps)
+{
+ IBuffer* b = new RandomEvictionsBuffer(sm, ps);
+ return b;
+}
+
+IBuffer* SpatialIndex::StorageManager::createNewRandomEvictionsBuffer(IStorageManager& sm, uint32_t capacity, bool bWriteThrough)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = capacity;
+ ps.setProperty("Capacity", var);
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = bWriteThrough;
+ ps.setProperty("WriteThrough", var);
+
+ return returnRandomEvictionsBuffer(sm, ps);
+}
+
+RandomEvictionsBuffer::RandomEvictionsBuffer(IStorageManager& sm, Tools::PropertySet& ps) : Buffer(sm, ps)
+{
+ srand48(static_cast<uint32_t>(time(0)));
+}
+
+RandomEvictionsBuffer::~RandomEvictionsBuffer()
+{
+}
+
+void RandomEvictionsBuffer::addEntry(id_type page, Entry* e)
+{
+ assert(m_buffer.size() <= m_capacity);
+
+ if (m_buffer.size() == m_capacity) removeEntry();
+ assert(m_buffer.find(page) == m_buffer.end());
+ m_buffer.insert(std::pair<id_type, Entry*>(page, e));
+}
+
+void RandomEvictionsBuffer::removeEntry()
+{
+ if (m_buffer.size() == 0) return;
+
+ double random;
+
+ random = drand48();
+
+ uint32_t entry = static_cast<uint32_t>(floor(((double) m_buffer.size()) * random));
+
+ std::map<id_type, Entry*>::iterator it = m_buffer.begin();
+ for (uint32_t cIndex = 0; cIndex < entry; cIndex++) ++it;
+
+ if ((*it).second->m_bDirty)
+ {
+ id_type page = (*it).first;
+ m_pStorageManager->storeByteArray(page, ((*it).second)->m_length, (const byte *) ((*it).second)->m_pData);
+ }
+
+ delete (*it).second;
+ m_buffer.erase(it);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.h.svn-base
new file mode 100644
index 000000000..64f26681c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/.svn/text-base/RandomEvictionsBuffer.h.svn-base
@@ -0,0 +1,42 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Buffer.h"
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class RandomEvictionsBuffer : public Buffer
+ {
+ public:
+ RandomEvictionsBuffer(IStorageManager&, Tools::PropertySet& ps);
+ // see Buffer.h for available properties.
+
+ virtual ~RandomEvictionsBuffer();
+
+ virtual void addEntry(id_type page, Buffer::Entry* pEntry);
+ virtual void removeEntry();
+ }; // RandomEvictionsBuffer
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.cc b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.cc
new file mode 100644
index 000000000..f605cd0f8
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.cc
@@ -0,0 +1,142 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Buffer.h"
+
+Buffer::Buffer(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_capacity(10),
+ m_bWriteThrough(false),
+ m_pStorageManager(&sm),
+ m_u64Hits(0)
+{
+ Tools::Variant var = ps.getProperty("Capacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("Property Capacity must be Tools::VT_ULONG");
+ m_capacity = var.m_val.ulVal;
+ }
+
+ var = ps.getProperty("WriteThrough");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("Property WriteThrough must be Tools::VT_BOOL");
+ m_bWriteThrough = var.m_val.blVal;
+ }
+}
+
+Buffer::~Buffer()
+{
+ for (std::map<id_type, Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); ++it)
+ {
+ if ((*it).second->m_bDirty)
+ {
+ id_type page = (*it).first;
+ m_pStorageManager->storeByteArray(page, (*it).second->m_length, (*it).second->m_pData);
+ }
+ delete (*it).second;
+ }
+}
+
+void Buffer::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ std::map<id_type, Entry*>::iterator it = m_buffer.find(page);
+
+ if (it != m_buffer.end())
+ {
+ ++m_u64Hits;
+ len = (*it).second->m_length;
+ *data = new byte[len];
+ memcpy(*data, (*it).second->m_pData, len);
+ }
+ else
+ {
+ m_pStorageManager->loadByteArray(page, len, data);
+ addEntry(page, new Entry(len, static_cast<const byte*>(*data)));
+ }
+}
+
+void Buffer::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ if (page == NewPage)
+ {
+ m_pStorageManager->storeByteArray(page, len, data);
+ assert(m_buffer.find(page) == m_buffer.end());
+ addEntry(page, new Entry(len, data));
+ }
+ else
+ {
+ if (m_bWriteThrough)
+ {
+ m_pStorageManager->storeByteArray(page, len, data);
+ }
+
+ Entry* e = new Entry(len, data);
+ if (m_bWriteThrough == false) e->m_bDirty = true;
+
+ std::map<id_type, Entry*>::iterator it = m_buffer.find(page);
+ if (it != m_buffer.end())
+ {
+ delete (*it).second;
+ (*it).second = e;
+ if (m_bWriteThrough == false) ++m_u64Hits;
+ }
+ else
+ {
+ addEntry(page, e);
+ }
+ }
+}
+
+void Buffer::deleteByteArray(const id_type page)
+{
+ std::map<id_type, Entry*>::iterator it = m_buffer.find(page);
+ if (it != m_buffer.end())
+ {
+ delete (*it).second;
+ m_buffer.erase(it);
+ }
+
+ m_pStorageManager->deleteByteArray(page);
+}
+
+void Buffer::clear()
+{
+ for (std::map<id_type, Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); ++it)
+ {
+ if ((*it).second->m_bDirty)
+ {
+ id_type page = (*it).first;
+ m_pStorageManager->storeByteArray(page, ((*it).second)->m_length, static_cast<const byte*>(((*it).second)->m_pData));
+ }
+
+ delete (*it).second;
+ }
+
+ m_buffer.clear();
+ m_u64Hits = 0;
+}
+
+uint64_t Buffer::getHits()
+{
+ return m_u64Hits;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.h b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.h
new file mode 100644
index 000000000..450e38a5b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Buffer.h
@@ -0,0 +1,78 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include <cstring>
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class Buffer : public IBuffer
+ {
+ public:
+ Buffer(IStorageManager& sm, Tools::PropertySet& ps);
+ // String Value Description
+ // ----------------------------------------------
+ // Capacity VT_ULONG Buffer maximum capacity.
+ // WriteThrough VT_BOOL Enable or disable write through policy.
+
+ virtual ~Buffer();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ virtual void clear();
+ virtual uint64_t getHits();
+
+ protected:
+ class Entry
+ {
+ public:
+ Entry(uint32_t l, const byte* const d) : m_pData(0), m_length(l), m_bDirty(false)
+ {
+ m_pData = new byte[m_length];
+ memcpy(m_pData, d, m_length);
+ }
+
+ ~Entry() { delete[] m_pData; }
+
+ byte* m_pData;
+ uint32_t m_length;
+ bool m_bDirty;
+ }; // Entry
+
+ virtual void addEntry(id_type page, Entry* pEntry) = 0;
+ virtual void removeEntry() = 0;
+
+ uint32_t m_capacity;
+ bool m_bWriteThrough;
+ IStorageManager* m_pStorageManager;
+ std::map<id_type, Entry*> m_buffer;
+ uint64_t m_u64Hits;
+ }; // Buffer
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.cc b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.cc
new file mode 100644
index 000000000..ecf1c9139
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.cc
@@ -0,0 +1,501 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <fstream>
+#include <cstring>
+
+// For checking if a file exists - hobu
+#include <sys/stat.h>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "DiskStorageManager.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+bool CheckFilesExists(Tools::PropertySet& ps)
+{
+ bool bExists = false;
+
+ std::string filename("");
+ std::string idx("idx");
+ std::string dat("dat");
+
+ Tools::Variant idx_name;
+ Tools::Variant dat_name;
+ Tools::Variant fn;
+
+ idx_name = ps.getProperty("FileNameIdx");
+ dat_name = ps.getProperty("FileNameDat");
+ fn = ps.getProperty("FileName");
+
+ if (idx_name.m_varType != Tools::VT_EMPTY) dat = std::string(idx_name.m_val.pcVal);
+ if (dat_name.m_varType != Tools::VT_EMPTY) idx = std::string(dat_name.m_val.pcVal);
+ if (fn.m_varType != Tools::VT_EMPTY) filename = std::string(fn.m_val.pcVal);
+
+ struct stat stats;
+
+ std::ostringstream os;
+ int ret;
+ os << filename <<"."<<dat;
+ std::string data_name = os.str();
+ ret = stat(data_name.c_str(), &stats);
+
+ if (ret == 0) bExists = true;
+
+ os.str("");
+ os << filename <<"."<<idx;
+ std::string index_name = os.str();
+ ret = stat(index_name.c_str(), &stats);
+
+ if ((ret == 0) && (bExists == true)) bExists = true;
+
+ return bExists;
+}
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::returnDiskStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new DiskStorageManager(ps);
+ return sm;
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::createNewDiskStorageManager(std::string& baseName, uint32_t pageSize)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = true;
+ ps.setProperty("Overwrite", var);
+ // overwrite the file if it exists.
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>(baseName.c_str());
+ ps.setProperty("FileName", var);
+ // .idx and .dat extensions will be added.
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = pageSize;
+ ps.setProperty("PageSize", var);
+ // specify the page size. Since the index may also contain user defined data
+ // there is no way to know how big a single node may become. The storage manager
+ // will use multiple pages per node if needed. Off course this will slow down performance.
+
+ return returnDiskStorageManager(ps);
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::loadDiskStorageManager(std::string& baseName)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_PCHAR;
+ var.m_val.pcVal = const_cast<char*>(baseName.c_str());
+ ps.setProperty("FileName", var);
+ // .idx and .dat extensions will be added.
+
+ return returnDiskStorageManager(ps);
+}
+
+DiskStorageManager::DiskStorageManager(Tools::PropertySet& ps) : m_pageSize(0), m_nextPage(-1), m_buffer(0)
+{
+ Tools::Variant var;
+
+ // Open/Create flag.
+ bool bOverwrite = false;
+ var = ps.getProperty("Overwrite");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL)
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property Overwrite must be Tools::VT_BOOL");
+ bOverwrite = var.m_val.blVal;
+ }
+
+ // storage filename.
+ var = ps.getProperty("FileName");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_PCHAR)
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property FileName must be Tools::VT_PCHAR");
+
+ std::string idx("idx");
+ std::string dat("dat");
+
+ Tools::Variant idx_name = ps.getProperty("FileNameIdx");
+ if (idx_name.m_varType != Tools::VT_EMPTY) idx = std::string(idx_name.m_val.pcVal);
+
+ Tools::Variant dat_name = ps.getProperty("FileNameDat");
+ if (dat_name.m_varType != Tools::VT_EMPTY) dat = std::string(dat_name.m_val.pcVal);
+
+ std::string sIndexFile = std::string(var.m_val.pcVal) + "." + idx;
+ std::string sDataFile = std::string(var.m_val.pcVal) + "." + dat;
+
+ // check if file exists.
+ bool bFileExists = CheckFilesExists(ps);
+
+ // check if file can be read/written.
+ if (bFileExists == true && bOverwrite == false)
+ {
+ m_indexFile.open(sIndexFile.c_str(), std::ios::in | std::ios::out | std::ios::binary);
+ m_dataFile.open(sDataFile.c_str(), std::ios::in | std::ios::out | std::ios::binary);
+
+ if (m_indexFile.fail() || m_dataFile.fail())
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Index/Data file cannot be read/writen.");
+ }
+ else
+ {
+ m_indexFile.open(sIndexFile.c_str(), std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
+ m_dataFile.open(sDataFile.c_str(), std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
+
+ if (m_indexFile.fail() || m_dataFile.fail())
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Index/Data file cannot be created.");
+
+ }
+ }
+ else
+ {
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property FileName was not specified.");
+ }
+
+ // find page size.
+ if (bOverwrite == true)
+ {
+ var = ps.getProperty("PageSize");
+
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: Property PageSize must be Tools::VT_ULONG");
+ m_pageSize = var.m_val.ulVal;
+ m_nextPage = 0;
+ }
+ else
+ {
+ throw Tools::IllegalArgumentException("SpatialIndex::DiskStorageManager: A new storage manager is created and property PageSize was not specified.");
+ }
+ }
+ else
+ {
+ m_indexFile.read(reinterpret_cast<char*>(&m_pageSize), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Failed reading pageSize.");
+
+ m_indexFile.read(reinterpret_cast<char*>(&m_nextPage), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Failed reading nextPage.");
+ }
+
+ // create buffer.
+ m_buffer = new byte[m_pageSize];
+ bzero(m_buffer, m_pageSize);
+
+ if (bOverwrite == false)
+ {
+ uint32_t count;
+ id_type page, id;
+
+ // load empty pages in memory.
+ m_indexFile.read(reinterpret_cast<char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cCount = 0; cCount < count; ++cCount)
+ {
+ m_indexFile.read(reinterpret_cast<char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ m_emptyPages.push(page);
+ }
+
+ // load index table in memory.
+ m_indexFile.read(reinterpret_cast<char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cCount = 0; cCount < count; ++cCount)
+ {
+ Entry* e = new Entry();
+
+ m_indexFile.read(reinterpret_cast<char*>(&id), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ m_indexFile.read(reinterpret_cast<char*>(&(e->m_length)), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ uint32_t count2;
+ m_indexFile.read(reinterpret_cast<char*>(&count2), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cCount2 = 0; cCount2 < count2; ++cCount2)
+ {
+ m_indexFile.read(reinterpret_cast<char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ e->m_pages.push_back(page);
+ }
+ m_pageIndex.insert(std::pair<id_type, Entry* >(id, e));
+ }
+ }
+}
+
+DiskStorageManager::~DiskStorageManager()
+{
+ flush();
+ m_indexFile.close();
+ m_dataFile.close();
+ if (m_buffer != 0) delete[] m_buffer;
+
+ std::map<id_type, Entry*>::iterator it;
+ for (it = m_pageIndex.begin(); it != m_pageIndex.end(); ++it) delete (*it).second;
+}
+
+void DiskStorageManager::flush()
+{
+ m_indexFile.seekp(0, std::ios_base::beg);
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ m_indexFile.write(reinterpret_cast<const char*>(&m_pageSize), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ m_indexFile.write(reinterpret_cast<const char*>(&m_nextPage), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ uint32_t count = static_cast<uint32_t>(m_emptyPages.size());
+ id_type page, id;
+
+ m_indexFile.write(reinterpret_cast<const char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ while (! m_emptyPages.empty())
+ {
+ page = m_emptyPages.top(); m_emptyPages.pop();
+ m_indexFile.write(reinterpret_cast<const char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ }
+
+ count = static_cast<uint32_t>(m_pageIndex.size());
+
+ m_indexFile.write(reinterpret_cast<const char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ std::map<id_type, Entry*>::iterator it;
+
+ for (it = m_pageIndex.begin(); it != m_pageIndex.end(); ++it)
+ {
+ id = (*it).first;
+ m_indexFile.write(reinterpret_cast<const char*>(&id), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ uint32_t length = (*it).second->m_length;
+ m_indexFile.write(reinterpret_cast<const char*>(&length), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ count = static_cast<uint32_t>((*it).second->m_pages.size());
+ m_indexFile.write(reinterpret_cast<const char*>(&count), sizeof(uint32_t));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+
+ for (uint32_t cIndex = 0; cIndex < count; ++cIndex)
+ {
+ page = (*it).second->m_pages[cIndex];
+ m_indexFile.write(reinterpret_cast<const char*>(&page), sizeof(id_type));
+ if (m_indexFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted storage manager index file.");
+ }
+ }
+
+ m_indexFile.flush();
+ m_dataFile.flush();
+}
+
+void DiskStorageManager::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ std::map<id_type, Entry*>::iterator it = m_pageIndex.find(page);
+
+ if (it == m_pageIndex.end())
+ throw InvalidPageException(page);
+
+ std::vector<id_type>& pages = (*it).second->m_pages;
+ uint32_t cNext = 0;
+ uint32_t cTotal = static_cast<uint32_t>(pages.size());
+
+ len = (*it).second->m_length;
+ *data = new byte[len];
+
+ byte* ptr = *data;
+ uint32_t cLen;
+ uint32_t cRem = len;
+
+ do
+ {
+ m_dataFile.seekg(pages[cNext] * m_pageSize, std::ios_base::beg);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ m_dataFile.read(reinterpret_cast<char*>(m_buffer), m_pageSize);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ cLen = (cRem > m_pageSize) ? m_pageSize : cRem;
+ memcpy(ptr, m_buffer, cLen);
+
+ ptr += cLen;
+ cRem -= cLen;
+ ++cNext;
+ }
+ while (cNext < cTotal);
+}
+
+void DiskStorageManager::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ if (page == NewPage)
+ {
+ Entry* e = new Entry();
+ e->m_length = len;
+
+ const byte* ptr = data;
+ id_type cPage;
+ uint32_t cRem = len;
+ uint32_t cLen;
+
+ while (cRem > 0)
+ {
+ if (! m_emptyPages.empty())
+ {
+ cPage = m_emptyPages.top(); m_emptyPages.pop();
+ }
+ else
+ {
+ cPage = m_nextPage;
+ ++m_nextPage;
+ }
+
+ cLen = (cRem > m_pageSize) ? m_pageSize : cRem;
+ memcpy(m_buffer, ptr, cLen);
+
+ m_dataFile.seekp(cPage * m_pageSize, std::ios_base::beg);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ m_dataFile.write(reinterpret_cast<const char*>(m_buffer), m_pageSize);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ ptr += cLen;
+ cRem -= cLen;
+ e->m_pages.push_back(cPage);
+ }
+
+ page = e->m_pages[0];
+ m_pageIndex.insert(std::pair<id_type, Entry*>(page, e));
+ }
+ else
+ {
+ // find the entry.
+ std::map<id_type, Entry*>::iterator it = m_pageIndex.find(page);
+
+ // check if it exists.
+ if (it == m_pageIndex.end())
+ throw InvalidPageException(page);
+
+ Entry* oldEntry = (*it).second;
+
+ m_pageIndex.erase(it);
+
+ Entry* e = new Entry();
+ e->m_length = len;
+
+ const byte* ptr = data;
+ id_type cPage;
+ uint32_t cRem = len;
+ uint32_t cLen, cNext = 0;
+
+ while (cRem > 0)
+ {
+ if (cNext < oldEntry->m_pages.size())
+ {
+ cPage = oldEntry->m_pages[cNext];
+ ++cNext;
+ }
+ else if (! m_emptyPages.empty())
+ {
+ cPage = m_emptyPages.top(); m_emptyPages.pop();
+ }
+ else
+ {
+ cPage = m_nextPage;
+ ++m_nextPage;
+ }
+
+ cLen = (cRem > m_pageSize) ? m_pageSize : cRem;
+ memcpy(m_buffer, ptr, cLen);
+
+ m_dataFile.seekp(cPage * m_pageSize, std::ios_base::beg);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ m_dataFile.write(reinterpret_cast<const char*>(m_buffer), m_pageSize);
+ if (m_dataFile.fail())
+ throw Tools::IllegalStateException("SpatialIndex::DiskStorageManager: Corrupted data file.");
+
+ ptr += cLen;
+ cRem -= cLen;
+ e->m_pages.push_back(cPage);
+ }
+
+ while (cNext < oldEntry->m_pages.size())
+ {
+ m_emptyPages.push(oldEntry->m_pages[cNext]);
+ ++cNext;
+ }
+
+ m_pageIndex.insert(std::pair<id_type, Entry*>(page, e));
+ delete oldEntry;
+ }
+}
+
+void DiskStorageManager::deleteByteArray(const id_type page)
+{
+ std::map<id_type, Entry*>::iterator it = m_pageIndex.find(page);
+
+ if (it == m_pageIndex.end())
+ throw InvalidPageException(page);
+
+ for (uint32_t cIndex = 0; cIndex < (*it).second->m_pages.size(); ++cIndex)
+ {
+ m_emptyPages.push((*it).second->m_pages[cIndex]);
+ }
+
+ delete (*it).second;
+ m_pageIndex.erase(it);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.h b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.h
new file mode 100644
index 000000000..178eb684e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/DiskStorageManager.h
@@ -0,0 +1,58 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class DiskStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ DiskStorageManager(Tools::PropertySet&);
+ virtual ~DiskStorageManager();
+
+ void flush();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ private:
+ class Entry
+ {
+ public:
+ uint32_t m_length;
+ std::vector<id_type> m_pages;
+ };
+
+ std::fstream m_dataFile;
+ std::fstream m_indexFile;
+ uint32_t m_pageSize;
+ id_type m_nextPage;
+ std::priority_queue<id_type, std::vector<id_type>, std::greater<id_type> > m_emptyPages;
+ std::map<id_type, Entry*> m_pageIndex;
+
+ byte* m_buffer;
+ }; // DiskStorageManager
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Makefile.am
new file mode 100644
index 000000000..430ab3dac
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/Makefile.am
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libstoragemanager.la
+INCLUDES = -I../../include
+libstoragemanager_la_SOURCES = Buffer.h Buffer.cc DiskStorageManager.cc MemoryStorageManager.cc RandomEvictionsBuffer.cc DiskStorageManager.h MemoryStorageManager.h RandomEvictionsBuffer.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.cc b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.cc
new file mode 100644
index 000000000..24ef0e04b
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.cc
@@ -0,0 +1,126 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <stdexcept>
+#include <cstring>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "MemoryStorageManager.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::returnMemoryStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new MemoryStorageManager(ps);
+ return sm;
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::createNewMemoryStorageManager()
+{
+ Tools::PropertySet ps;
+ return returnMemoryStorageManager(ps);
+}
+
+MemoryStorageManager::MemoryStorageManager(Tools::PropertySet& ps)
+{
+}
+
+MemoryStorageManager::~MemoryStorageManager()
+{
+ for (std::vector<Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); ++it) delete *it;
+}
+
+void MemoryStorageManager::loadByteArray(const id_type page, uint32_t& len, byte** data)
+{
+ Entry* e;
+ try
+ {
+ e = m_buffer.at(page);
+ if (e == 0) throw InvalidPageException(page);
+ }
+ catch (std::out_of_range)
+ {
+ throw InvalidPageException(page);
+ }
+
+ len = e->m_length;
+ *data = new byte[len];
+
+ memcpy(*data, e->m_pData, len);
+}
+
+void MemoryStorageManager::storeByteArray(id_type& page, const uint32_t len, const byte* const data)
+{
+ if (page == NewPage)
+ {
+ Entry* e = new Entry(len, data);
+
+ if (m_emptyPages.empty())
+ {
+ m_buffer.push_back(e);
+ page = m_buffer.size() - 1;
+ }
+ else
+ {
+ page = m_emptyPages.top(); m_emptyPages.pop();
+ m_buffer[page] = e;
+ }
+ }
+ else
+ {
+ Entry* e_old;
+ try
+ {
+ e_old = m_buffer.at(page);
+ if (e_old == 0) throw InvalidPageException(page);
+ }
+ catch (std::out_of_range)
+ {
+ throw InvalidPageException(page);
+ }
+
+ Entry* e = new Entry(len, data);
+
+ delete e_old;
+ m_buffer[page] = e;
+ }
+}
+
+void MemoryStorageManager::deleteByteArray(const id_type page)
+{
+ Entry* e;
+ try
+ {
+ e = m_buffer.at(page);
+ if (e == 0) throw InvalidPageException(page);
+ }
+ catch (std::out_of_range)
+ {
+ throw InvalidPageException(page);
+ }
+
+ m_buffer[page] = 0;
+ m_emptyPages.push(page);
+
+ delete e;
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.h b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.h
new file mode 100644
index 000000000..61a224d80
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/MemoryStorageManager.h
@@ -0,0 +1,61 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include <cstring>
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class MemoryStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ MemoryStorageManager(Tools::PropertySet&);
+
+ virtual ~MemoryStorageManager();
+
+ virtual void loadByteArray(const id_type page, uint32_t& len, byte** data);
+ virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data);
+ virtual void deleteByteArray(const id_type page);
+
+ private:
+ class Entry
+ {
+ public:
+ byte* m_pData;
+ uint32_t m_length;
+
+ Entry(uint32_t l, const byte* const d) : m_pData(0), m_length(l)
+ {
+ m_pData = new byte[m_length];
+ memcpy(m_pData, d, m_length);
+ }
+
+ ~Entry() { delete[] m_pData; }
+ }; // Entry
+
+ std::vector<Entry*> m_buffer;
+ std::stack<id_type> m_emptyPages;
+ }; // MemoryStorageManager
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.cc b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.cc
new file mode 100644
index 000000000..e0e22d296
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.cc
@@ -0,0 +1,94 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <time.h>
+#include <stdlib.h>
+#include <cmath>
+#include "../../include/tools/rand48.h"
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "RandomEvictionsBuffer.h"
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+IBuffer* SpatialIndex::StorageManager::returnRandomEvictionsBuffer(IStorageManager& sm, Tools::PropertySet& ps)
+{
+ IBuffer* b = new RandomEvictionsBuffer(sm, ps);
+ return b;
+}
+
+IBuffer* SpatialIndex::StorageManager::createNewRandomEvictionsBuffer(IStorageManager& sm, uint32_t capacity, bool bWriteThrough)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = capacity;
+ ps.setProperty("Capacity", var);
+
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = bWriteThrough;
+ ps.setProperty("WriteThrough", var);
+
+ return returnRandomEvictionsBuffer(sm, ps);
+}
+
+RandomEvictionsBuffer::RandomEvictionsBuffer(IStorageManager& sm, Tools::PropertySet& ps) : Buffer(sm, ps)
+{
+ srand48(static_cast<uint32_t>(time(0)));
+}
+
+RandomEvictionsBuffer::~RandomEvictionsBuffer()
+{
+}
+
+void RandomEvictionsBuffer::addEntry(id_type page, Entry* e)
+{
+ assert(m_buffer.size() <= m_capacity);
+
+ if (m_buffer.size() == m_capacity) removeEntry();
+ assert(m_buffer.find(page) == m_buffer.end());
+ m_buffer.insert(std::pair<id_type, Entry*>(page, e));
+}
+
+void RandomEvictionsBuffer::removeEntry()
+{
+ if (m_buffer.size() == 0) return;
+
+ double random;
+
+ random = drand48();
+
+ uint32_t entry = static_cast<uint32_t>(floor(((double) m_buffer.size()) * random));
+
+ std::map<id_type, Entry*>::iterator it = m_buffer.begin();
+ for (uint32_t cIndex = 0; cIndex < entry; cIndex++) ++it;
+
+ if ((*it).second->m_bDirty)
+ {
+ id_type page = (*it).first;
+ m_pStorageManager->storeByteArray(page, ((*it).second)->m_length, (const byte *) ((*it).second)->m_pData);
+ }
+
+ delete (*it).second;
+ m_buffer.erase(it);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.h b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.h
new file mode 100644
index 000000000..64f26681c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/storagemanager/RandomEvictionsBuffer.h
@@ -0,0 +1,42 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Buffer.h"
+
+namespace SpatialIndex
+{
+ namespace StorageManager
+ {
+ class RandomEvictionsBuffer : public Buffer
+ {
+ public:
+ RandomEvictionsBuffer(IStorageManager&, Tools::PropertySet& ps);
+ // see Buffer.h for available properties.
+
+ virtual ~RandomEvictionsBuffer();
+
+ virtual void addEntry(id_type page, Buffer::Entry* pEntry);
+ virtual void removeEntry();
+ }; // RandomEvictionsBuffer
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/all-wcprops
new file mode 100644
index 000000000..e62a9d87c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/spatialindex/!svn/ver/192/spatialindex/trunk/src/tools
+END
+Tools.cc
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/192/spatialindex/trunk/src/tools/Tools.cc
+END
+rand48.cc
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/69/spatialindex/trunk/src/tools/rand48.cc
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/99/spatialindex/trunk/src/tools/Makefile.am
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/dir-prop-base
new file mode 100644
index 000000000..981994deb
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/dir-prop-base
@@ -0,0 +1,11 @@
+K 10
+svn:ignore
+V 48
+Makefile.in
+geometry
+tools
+.libs
+.deps
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/entries
new file mode 100644
index 000000000..ff93e5df5
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/tools
+http://svn.gispython.org/spatialindex
+
+
+
+2010-10-14T13:18:23.380119Z
+192
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Tools.cc
+file
+
+
+
+
+2011-08-01T00:42:34.413114Z
+f618b02d67eb86196340c030c7d844ca
+2010-10-14T13:18:23.380119Z
+192
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+32390
+
+rand48.cc
+file
+
+
+
+
+2011-08-01T00:42:34.413114Z
+8d4eb03c1b578802bf3484c9ca4ce755
+2008-02-26T16:15:43.620812Z
+69
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3560
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.413114Z
+edc8140c6fff84fb52c4f6d9f3932bdc
+2009-07-18T22:19:07.374702Z
+99
+mhadji
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+183
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/prop-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/prop-base/Makefile.am.svn-base
new file mode 100644
index 000000000..869ac71cf
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/prop-base/Makefile.am.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..eae038194
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libtools.la
+INCLUDES = -I../../../include/tools
+libtools_la_SOURCES = Tools.cc rand48.cc
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Tools.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Tools.cc.svn-base
new file mode 100644
index 000000000..a8f4a970e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/Tools.cc.svn-base
@@ -0,0 +1,1365 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <time.h>
+#include <limits>
+#include "../../include/tools/Tools.h"
+#include "../../include/tools/rand48.h"
+
+#include <cstring>
+
+Tools::IndexOutOfBoundsException::IndexOutOfBoundsException(size_t i)
+{
+ std::ostringstream s;
+ s << "Invalid index " << i;
+ m_error = s.str();
+}
+
+std::string Tools::IndexOutOfBoundsException::what()
+{
+ return "IndexOutOfBoundsException: " + m_error;
+}
+
+Tools::IllegalArgumentException::IllegalArgumentException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::IllegalArgumentException::what()
+{
+ return "IllegalArgumentException: " + m_error;
+}
+
+Tools::IllegalStateException::IllegalStateException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::IllegalStateException::what()
+{
+ return "IllegalStateException: " + m_error;
+}
+
+Tools::EndOfStreamException::EndOfStreamException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::EndOfStreamException::what()
+{
+ return "EndOfStreamException: " + m_error;
+}
+
+Tools::ResourceLockedException::ResourceLockedException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::ResourceLockedException::what()
+{
+ return "ResourceLockedException: " + m_error;
+}
+
+Tools::NotSupportedException::NotSupportedException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::NotSupportedException::what()
+{
+ return "NotSupportedException: " + m_error;
+}
+
+Tools::Variant::Variant() : m_varType(VT_EMPTY)
+{
+}
+
+Tools::PropertySet::PropertySet(const byte* data)
+{
+#ifdef HAVE_PTHREAD_H
+ // pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+ loadFromByteArray(data);
+}
+
+Tools::PropertySet::~PropertySet()
+{
+#ifdef HAVE_PTHREAD_H
+ // pthread_rwlock_destroy(&m_rwLock);
+#endif
+}
+
+Tools::PropertySet::PropertySet()
+{
+#ifdef HAVE_PTHREAD_H
+ // pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+}
+void Tools::PropertySet::loadFromByteArray(const byte* ptr)
+{
+ m_propertySet.clear();
+
+ uint32_t numberOfProperties;
+ memcpy(&numberOfProperties, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ Variant v;
+
+ for (uint32_t cIndex = 0; cIndex < numberOfProperties; ++cIndex)
+ {
+ std::string s(reinterpret_cast<const char*>(ptr));
+ ptr += s.size() + 1;
+ memcpy(&(v.m_varType), ptr, sizeof(VariantType));
+ ptr += sizeof(VariantType);
+
+ switch (v.m_varType)
+ {
+ case VT_SHORT:
+ int16_t s;
+ memcpy(&s, ptr, sizeof(int16_t));
+ ptr += sizeof(int16_t);
+ v.m_val.iVal = s;
+ break;
+ case VT_LONG:
+ int32_t l;
+ memcpy(&l, ptr, sizeof(int32_t));
+ ptr += sizeof(int32_t);
+ v.m_val.lVal = l;
+ break;
+ case VT_LONGLONG:
+ int64_t ll;
+ memcpy(&ll, ptr, sizeof(int64_t));
+ ptr += sizeof(int64_t);
+ v.m_val.llVal = ll;
+ break;
+ case VT_BYTE:
+ byte b;
+ memcpy(&b, ptr, sizeof(byte));
+ ptr += sizeof(byte);
+ v.m_val.bVal = b;
+ break;
+ case VT_FLOAT:
+ float f;
+ memcpy(&f, ptr, sizeof(float));
+ ptr += sizeof(float);
+ v.m_val.fltVal = f;
+ break;
+ case VT_DOUBLE:
+ double d;
+ memcpy(&d, ptr, sizeof(double));
+ ptr += sizeof(double);
+ v.m_val.dblVal = d;
+ break;
+ case VT_CHAR:
+ char c;
+ memcpy(&c, ptr, sizeof(char));
+ ptr += sizeof(char);
+ v.m_val.cVal = c;
+ break;
+ case VT_USHORT:
+ uint16_t us;
+ memcpy(&us, ptr, sizeof(uint16_t));
+ ptr += sizeof(uint16_t);
+ v.m_val.uiVal = us;
+ break;
+ case VT_ULONG:
+ uint32_t ul;
+ memcpy(&ul, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ v.m_val.ulVal = ul;
+ break;
+ case VT_ULONGLONG:
+ uint64_t ull;
+ memcpy(&ull, ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ v.m_val.ullVal = ull;
+ break;
+ case VT_BOOL:
+ byte bl;
+ memcpy(&bl, ptr, sizeof(byte));
+ ptr += sizeof(byte);
+ v.m_val.blVal = (bl != 0);
+ break;
+ default:
+ throw IllegalStateException(
+ "Tools::PropertySet::PropertySet: Deserialization problem."
+ );
+ }
+
+ m_propertySet.insert(std::pair<std::string, Variant>(s, v));
+ }
+}
+
+uint32_t Tools::PropertySet::getByteArraySize()
+{
+ uint32_t size = sizeof(uint32_t);
+ std::map<std::string, Variant>::iterator it;
+
+ for (it = m_propertySet.begin(); it != m_propertySet.end(); ++it)
+ {
+ switch ((*it).second.m_varType)
+ {
+ case VT_SHORT:
+ size += sizeof(int16_t);
+ break;
+ case VT_LONG:
+ size += sizeof(int32_t);
+ break;
+ case VT_LONGLONG:
+ size += sizeof(int64_t);
+ break;
+ case VT_BYTE:
+ size += sizeof(byte);
+ break;
+ case VT_FLOAT:
+ size += sizeof(float);
+ break;
+ case VT_DOUBLE:
+ size += sizeof(double);
+ break;
+ case VT_CHAR:
+ size += sizeof(char);
+ break;
+ case VT_USHORT:
+ size += sizeof(uint16_t);
+ break;
+ case VT_ULONG:
+ size += sizeof(uint32_t);
+ break;
+ case VT_ULONGLONG:
+ size += sizeof(uint64_t);
+ break;
+ case VT_BOOL:
+ size += sizeof(byte);
+ break;
+ default:
+ throw NotSupportedException(
+ "Tools::PropertySet::getSize: Unknown type."
+ );
+ }
+ size += static_cast<uint32_t>((*it).first.size()) + 1 + sizeof(VariantType);
+ }
+
+ return size;
+}
+
+void Tools::PropertySet::storeToByteArray(byte** data, uint32_t& length)
+{
+ length = getByteArraySize();
+ *data = new byte[length];
+ byte* ptr = *data;
+
+ uint32_t numberOfProperties = static_cast<uint32_t>(m_propertySet.size());
+ memcpy(ptr, &numberOfProperties, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ std::map<std::string, Variant>::iterator it;
+
+ for (it = m_propertySet.begin(); it != m_propertySet.end(); ++it)
+ {
+ size_t strSize = (*it).first.size();
+ memcpy(ptr, (*it).first.c_str(), strSize);
+ ptr += strSize;
+ *ptr = 0;
+ ++ptr;
+
+ memcpy(ptr, &((*it).second.m_varType), sizeof(VariantType));
+ ptr += sizeof(VariantType);
+
+ switch ((*it).second.m_varType)
+ {
+ case VT_SHORT:
+ memcpy(ptr, &((*it).second.m_val.iVal), sizeof(int16_t));
+ ptr += sizeof(int16_t);
+ break;
+ case VT_LONG:
+ memcpy(ptr, &((*it).second.m_val.lVal), sizeof(int32_t));
+ ptr += sizeof(int32_t);
+ break;
+ case VT_LONGLONG:
+ memcpy(ptr, &((*it).second.m_val.llVal), sizeof(int64_t));
+ ptr += sizeof(int64_t);
+ break;
+ case VT_BYTE:
+ memcpy(ptr, &((*it).second.m_val.bVal), sizeof(byte));
+ ptr += sizeof(byte);
+ break;
+ case VT_FLOAT:
+ memcpy(ptr, &((*it).second.m_val.fltVal), sizeof(float));
+ ptr += sizeof(float);
+ break;
+ case VT_DOUBLE:
+ memcpy(ptr, &((*it).second.m_val.dblVal), sizeof(double));
+ ptr += sizeof(double);
+ break;
+ case VT_CHAR:
+ memcpy(ptr, &((*it).second.m_val.cVal), sizeof(char));
+ ptr += sizeof(char);
+ break;
+ case VT_USHORT:
+ memcpy(ptr, &((*it).second.m_val.uiVal), sizeof(uint16_t));
+ ptr += sizeof(uint16_t);
+ break;
+ case VT_ULONG:
+ memcpy(ptr, &((*it).second.m_val.ulVal), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ break;
+ case VT_ULONGLONG:
+ memcpy(ptr, &((*it).second.m_val.ullVal), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ break;
+ case VT_BOOL:
+ byte bl;
+ bl = (*it).second.m_val.blVal;
+ memcpy(ptr, &bl, sizeof(byte));
+ ptr += sizeof(byte);
+ break;
+ default:
+ throw NotSupportedException(
+ "Tools::PropertySet::getData: Cannot serialize a variant of this type."
+ );
+ }
+ }
+
+ assert(ptr == (*data) + length);
+}
+
+Tools::Variant Tools::PropertySet::getProperty(std::string property)
+{
+// #ifdef HAVE_PTHREAD_H
+// Tools::ExclusiveLock lock(&m_rwLock);
+// #else
+// if (m_rwLock == false) m_rwLock = true;
+// else throw Tools::IllegalStateException("getProperty: cannot acquire an shared lock");
+// #endif
+
+ try
+ {
+ std::map<std::string, Variant>::iterator it = m_propertySet.find(property);
+
+ if (it != m_propertySet.end()) return (*it).second;
+ else return Variant();
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void Tools::PropertySet::setProperty(std::string property, Variant& v)
+{
+#ifdef HAVE_PTHREAD_H
+ // Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::EndOfStreamException("setProperty: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ std::pair<std::map<std::string, Variant>::iterator, bool> ret;
+ std::map<std::string, Variant>::iterator it;
+
+ ret = m_propertySet.insert(std::pair<std::string, Variant>(property, v));
+
+ // If we weren't able to insert because it is already in the map
+ // update our existing value
+ if (ret.second == false) ret.first->second = v;
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void Tools::PropertySet::removeProperty(std::string property)
+{
+#ifdef HAVE_PTHREAD_H
+ // Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::EndOfStreamException("setProperty: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ std::map<std::string, Variant>::iterator it = m_propertySet.find(property);
+ if (it != m_propertySet.end()) m_propertySet.erase(it);
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+Tools::Interval::Interval() : m_type(IT_RIGHTOPEN), m_low(0.0), m_high(0.0)
+{
+}
+
+Tools::Interval::Interval(IntervalType t, double l, double h) : m_type(t), m_low(l), m_high(h)
+{
+ assert(l < h);
+}
+
+Tools::Interval::Interval(double l, double h) : m_type(IT_RIGHTOPEN), m_low(l), m_high(h)
+{
+ assert(l < h);
+}
+
+Tools::Interval::Interval(const Interval& iv)
+{
+ m_low = iv.m_low;
+ m_high = iv.m_high;
+ m_type = iv.m_type;
+}
+
+Tools::IInterval& Tools::Interval::operator=(const Tools::IInterval& iv)
+{
+ if (this != &iv)
+ {
+ m_low = iv.getLowerBound();
+ m_high = iv.getUpperBound();
+ m_type = iv.getIntervalType();
+ }
+
+ return *this;
+}
+
+bool Tools::Interval::operator==(const Interval& iv) const
+{
+ if (
+ m_type == iv.m_type &&
+ m_low >= iv.m_low - std::numeric_limits<double>::epsilon() &&
+ m_low <= iv.m_low + std::numeric_limits<double>::epsilon() &&
+ m_high >= iv.m_high - std::numeric_limits<double>::epsilon() &&
+ m_high <= iv.m_high + std::numeric_limits<double>::epsilon())
+ return true;
+
+ return false;
+}
+
+bool Tools::Interval::operator!=(const Interval& iv) const
+{
+ return ! (*this == iv);
+}
+
+double Tools::Interval::getLowerBound() const
+{
+ return m_low;
+}
+
+double Tools::Interval::getUpperBound() const
+{
+ return m_high;
+}
+
+void Tools::Interval::setBounds(double l, double h)
+{
+ assert(l <= h);
+
+ m_low = l;
+ m_high = h;
+}
+
+bool Tools::Interval::intersectsInterval(const IInterval& i) const
+{
+ return intersectsInterval(i.getIntervalType(), i.getLowerBound(), i.getUpperBound());
+}
+
+bool Tools::Interval::intersectsInterval(IntervalType type, const double low, const double high) const
+{
+ if (m_high < m_low)
+ throw IllegalStateException(
+ "Tools::Interval::intersectsInterval: high boundary is smaller than low boundary."
+ );
+
+ if (m_low > high || m_high < low) return false;
+ if ((m_low > low && m_low < high) || (m_high > low && m_high < high)) return true;
+
+ switch (m_type)
+ {
+ case IT_CLOSED:
+ if (m_low == high)
+ {
+ if (type == IT_CLOSED || type == IT_LEFTOPEN) return true;
+ else return false;
+ }
+ else if (m_high == low)
+ {
+ if (type == IT_CLOSED || type == IT_RIGHTOPEN) return true;
+ else return false;
+ }
+ break;
+ case IT_OPEN:
+ if (m_low == high || m_high == low) return false;
+ break;
+ case IT_RIGHTOPEN:
+ if (m_low == high)
+ {
+ if (type == IT_CLOSED || type == IT_LEFTOPEN) return true;
+ else return false;
+ }
+ else if (m_high == low)
+ {
+ return false;
+ }
+ break;
+ case IT_LEFTOPEN:
+ if (m_low == high)
+ {
+ return false;
+ }
+ else if (m_high == low)
+ {
+ if (type == IT_CLOSED || type == IT_RIGHTOPEN) return true;
+ else return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+bool Tools::Interval::containsInterval(const IInterval& i) const
+{
+ if (m_high < m_low)
+ throw IllegalStateException(
+ "Tools::Interval::containsInterval: high boundary is smaller than low boundary."
+ );
+
+ double low = i.getLowerBound();
+ double high = i.getUpperBound();
+ IntervalType type = i.getIntervalType();
+
+ if (m_low < low && m_high > high) return true;
+ if (m_low > low || m_high < high) return false;
+
+ switch (m_type)
+ {
+ case IT_CLOSED:
+ break;
+ case IT_OPEN:
+ if ((m_low == low && m_high == high && type != IT_OPEN) ||
+ (m_low == low && (type == IT_CLOSED || type == IT_RIGHTOPEN)) ||
+ (m_high == high && ( type == IT_CLOSED || type == IT_LEFTOPEN)))
+ return false;
+ break;
+ case IT_RIGHTOPEN:
+ if (m_high == high && (type == IT_CLOSED || type == IT_LEFTOPEN))
+ return false;
+ break;
+ case IT_LEFTOPEN:
+ if (m_low == low && (type == IT_CLOSED || type == IT_RIGHTOPEN))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+Tools::IntervalType Tools::Interval::getIntervalType() const
+{
+ return m_type;
+}
+
+Tools::Random::Random()
+{
+ m_pBuffer = 0;
+ initDrand(static_cast<uint32_t>(time(0)), 0xD31A);
+}
+
+Tools::Random::Random(uint32_t seed, uint16_t xsubi0)
+{
+ m_pBuffer = 0;
+ initDrand(seed, xsubi0);
+}
+
+Tools::Random::~Random()
+{
+ delete[] m_pBuffer;
+}
+
+void Tools::Random::initDrand(uint32_t seed, uint16_t xsubi0)
+{
+ m_pBuffer = new uint16_t[3];
+ m_pBuffer[0] = static_cast<uint16_t>(xsubi0);
+ uint32_t mask = 0xFFFF;
+ m_pBuffer[1] = static_cast<uint16_t>(seed & mask);
+ mask = mask << 16;
+ m_pBuffer[2] = static_cast<uint16_t>((seed & mask) >> 16);
+
+#ifdef BUILD_OS_CYGWIN
+ srand48(*(reinterpret_cast<uint32_t*>(m_pBuffer)));
+ // BUG: There is a bug in cygwin gcc 3.4.4. srand48 needs to be called
+ // even if we are using the functions that take the seed as a parameter.
+ // This does not affect random number generation, which still happens
+ // using the seed provided as a parameter and not the one provided to srand48 :-S
+#endif
+}
+
+int32_t Tools::Random::nextUniformLong()
+{
+ return jrand48(m_pBuffer);
+}
+
+uint32_t Tools::Random::nextUniformUnsignedLong()
+{
+ return static_cast<uint32_t>(nextUniformLong());
+}
+
+int32_t Tools::Random::nextUniformLong(int32_t low, int32_t high)
+{
+ return low + static_cast<int32_t>((high - low) * nextUniformDouble());
+}
+
+uint32_t Tools::Random::nextUniformUnsignedLong(uint32_t low, uint32_t high)
+{
+ return low + static_cast<uint32_t>((high - low) * nextUniformDouble());
+}
+
+int64_t Tools::Random::nextUniformLongLong()
+{
+ return static_cast<int64_t>(nextUniformUnsignedLongLong());
+}
+
+uint64_t Tools::Random::nextUniformUnsignedLongLong()
+{
+ uint64_t lh = static_cast<uint64_t>(nextUniformLong());
+ uint64_t ll = static_cast<uint64_t>(nextUniformLong());
+ uint64_t ret = (lh << 32) | ll;
+ return ret;
+}
+
+int64_t Tools::Random::nextUniformLongLong(int64_t low, int64_t high)
+{
+ return low + static_cast<int64_t>((high - low) * nextUniformDouble());
+}
+
+uint64_t Tools::Random::nextUniformUnsignedLongLong(uint64_t low, uint64_t high)
+{
+ return low + static_cast<uint64_t>((high - low) * nextUniformDouble());
+}
+
+int16_t Tools::Random::nextUniformShort()
+{
+ return static_cast<int16_t>(nextUniformUnsignedShort());
+}
+
+uint16_t Tools::Random::nextUniformUnsignedShort()
+{
+ return nextUniformUnsignedLong() >> 16;
+ // retain the high order bits.
+}
+
+double Tools::Random::nextUniformDouble()
+{
+ uint16_t* xsubi = reinterpret_cast<uint16_t*>(m_pBuffer);
+ return erand48(xsubi);
+}
+
+double Tools::Random::nextUniformDouble(double low, double high)
+{
+ return (high - low) * nextUniformDouble() + low;
+}
+
+bool Tools::Random::flipCoin()
+{
+ if (nextUniformDouble() < 0.5) return true;
+ return false;
+}
+
+#if HAVE_PTHREAD_H
+Tools::SharedLock::SharedLock(pthread_rwlock_t* pLock)
+ : m_pLock(pLock)
+{
+ pthread_rwlock_rdlock(m_pLock);
+}
+
+Tools::SharedLock::~SharedLock()
+{
+ pthread_rwlock_unlock(m_pLock);
+}
+
+Tools::ExclusiveLock::ExclusiveLock(pthread_rwlock_t* pLock)
+ : m_pLock(pLock)
+{
+ pthread_rwlock_wrlock(m_pLock);
+}
+
+Tools::ExclusiveLock::~ExclusiveLock()
+{
+ pthread_rwlock_unlock(m_pLock);
+}
+#endif
+
+std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p)
+{
+ std::map<std::string, Variant>::const_iterator it;
+
+ for (it = p.m_propertySet.begin(); it != p.m_propertySet.end(); ++it)
+ {
+ if (it != p.m_propertySet.begin()) os << ", ";
+
+ switch ((*it).second.m_varType)
+ {
+ case VT_LONG:
+ os << (*it).first << ": " << (*it).second.m_val.lVal;
+ break;
+ case VT_LONGLONG:
+ os << (*it).first << ": " << (*it).second.m_val.llVal;
+ break;
+ case VT_BYTE:
+ os << (*it).first << ": " << (*it).second.m_val.bVal;
+ break;
+ case VT_SHORT:
+ os << (*it).first << ": " << (*it).second.m_val.iVal;
+ break;
+ case VT_FLOAT:
+ os << (*it).first << ": " << (*it).second.m_val.fltVal;
+ break;
+ case VT_DOUBLE:
+ os << (*it).first << ": " << (*it).second.m_val.dblVal;
+ break;
+ case VT_CHAR:
+ os << (*it).first << ": " << (*it).second.m_val.cVal;
+ break;
+ case VT_USHORT:
+ os << (*it).first << ": " << (*it).second.m_val.uiVal;
+ break;
+ case VT_ULONG:
+ os << (*it).first << ": " << (*it).second.m_val.ulVal;
+ break;
+ case VT_ULONGLONG:
+ os << (*it).first << ": " << (*it).second.m_val.ullVal;
+ break;
+ case VT_BOOL:
+ os << (*it).first << ": " << (*it).second.m_val.blVal;
+ break;
+ case VT_PCHAR:
+ os << (*it).first << ": " << (*it).second.m_val.pcVal;
+ break;
+ case VT_PVOID:
+ os << (*it).first << ": ?";
+ break;
+ case VT_EMPTY:
+ os << (*it).first << ": empty";
+ break;
+ default:
+ os << (*it).first << ": unknown";
+ }
+ }
+
+ return os;
+}
+
+std::ostream& Tools::operator<<(std::ostream& os, const Tools::Interval& iv)
+{
+ os << iv.m_type << " " << iv.m_low << " " << iv.m_high;
+ return os;
+}
+
+//
+// BufferedFile
+//
+Tools::BufferedFile::BufferedFile(uint32_t u32BufferSize)
+: m_buffer(new char[u32BufferSize]), m_u32BufferSize(u32BufferSize), m_bEOF(true)
+{
+}
+
+Tools::BufferedFile::~BufferedFile()
+{
+ m_file.close();
+ delete[] m_buffer;
+}
+
+void Tools::BufferedFile::close()
+{
+ m_file.close();
+}
+
+bool Tools::BufferedFile::eof()
+{
+ return m_bEOF;
+}
+
+//
+// BufferedFileReader
+//
+Tools::BufferedFileReader::BufferedFileReader()
+{
+}
+
+Tools::BufferedFileReader::BufferedFileReader(const std::string& sFileName, uint32_t u32BufferSize)
+: BufferedFile(u32BufferSize)
+{
+ open(sFileName);
+}
+
+void Tools::BufferedFileReader::open(const std::string& sFileName)
+{
+ m_bEOF = false;
+ m_file.close(); m_file.clear();
+
+
+ m_file.open(sFileName.c_str(), std::ios_base::in | std::ios_base::binary);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileReader::BufferedFileReader: Cannot open file.");
+
+ m_file.rdbuf()->pubsetbuf(m_buffer, m_u32BufferSize);
+}
+
+Tools::BufferedFileReader::~BufferedFileReader()
+{
+}
+
+void Tools::BufferedFileReader::rewind()
+{
+ m_file.clear();
+ m_file.seekg(0, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileReader::rewind: seek failed.");
+
+ m_bEOF = false;
+}
+
+void Tools::BufferedFileReader::seek(std::fstream::off_type offset)
+{
+ m_bEOF = false;
+ m_file.clear();
+ m_file.seekg(offset, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileReader::seek: seek failed.");
+}
+
+uint8_t Tools::BufferedFileReader::readUInt8()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint8_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint8_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+uint16_t Tools::BufferedFileReader::readUInt16()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint16_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint16_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+uint32_t Tools::BufferedFileReader::readUInt32()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint32_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint32_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+uint64_t Tools::BufferedFileReader::readUInt64()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint64_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint64_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+float Tools::BufferedFileReader::readFloat()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ float ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(float));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+double Tools::BufferedFileReader::readDouble()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ double ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(double));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+bool Tools::BufferedFileReader::readBoolean()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ bool ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(bool));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+std::string Tools::BufferedFileReader::readString()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint32_t len;
+ m_file.read(reinterpret_cast<char*>(&len), sizeof(uint32_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+
+ std::string::value_type* buf = new std::string::value_type[len];
+ m_file.read(reinterpret_cast<char*>(buf), len * sizeof(std::string::value_type));
+ if (! m_file.good())
+ {
+ delete[] buf;
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+
+ std::string ret(buf, len);
+ delete[] buf;
+
+ return ret;
+}
+
+void Tools::BufferedFileReader::readBytes(uint32_t u32Len, byte** pData)
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ *pData = new byte[u32Len];
+ m_file.read(reinterpret_cast<char*>(*pData), u32Len);
+ if (! m_file.good())
+ {
+ delete[] *pData;
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+}
+
+//
+// BufferedFileWriter
+//
+Tools::BufferedFileWriter::BufferedFileWriter()
+{
+ open("");
+}
+
+Tools::BufferedFileWriter::BufferedFileWriter(const std::string& sFileName, FileMode mode, uint32_t u32BufferSize)
+: BufferedFile(u32BufferSize)
+{
+ open(sFileName, mode);
+}
+
+Tools::BufferedFileWriter::~BufferedFileWriter()
+{
+ m_file.flush();
+}
+
+void Tools::BufferedFileWriter::open(const std::string& sFileName, FileMode mode)
+{
+ m_bEOF = false;
+ m_file.close(); m_file.clear();
+
+ if (mode == CREATE)
+ {
+ m_file.open(sFileName.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::open: Cannot open file.");
+ }
+ else if (mode == APPEND)
+ {
+ // Idiotic fstream::open truncates an existing file anyway, if it is only opened
+ // for output (no ios_base::in flag)!! On the other hand, if a file does not exist
+ // and the ios_base::in flag is specified, then the open fails!!
+
+ m_file.open(sFileName.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ if (! m_file.good())
+ {
+ m_file.clear();
+ m_file.open(sFileName.c_str(), std::ios_base::out | std::ios_base::binary);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::open: Cannot open file.");
+ }
+ else
+ {
+ m_file.seekp(0, std::ios_base::end);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::open: Cannot open file.");
+ }
+ }
+ else
+ throw Tools::IllegalArgumentException("Tools::BufferedFileWriter::open: Unknown mode.");
+}
+
+void Tools::BufferedFileWriter::rewind()
+{
+ m_bEOF = false;
+ m_file.clear();
+ m_file.seekp(0, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::rewind: seek failed.");
+}
+
+void Tools::BufferedFileWriter::seek(std::fstream::off_type offset)
+{
+ m_bEOF = false;
+ m_file.clear();
+ m_file.seekp(offset, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::seek: seek failed.");
+}
+
+void Tools::BufferedFileWriter::write(uint8_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint8_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint16_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint16_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint32_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint32_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint64_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint64_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(float i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(float));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(double i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(double));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(bool b)
+{
+ m_file.write(reinterpret_cast<const char*>(&b), sizeof(bool));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(const std::string& s)
+{
+ uint32_t len = static_cast<uint32_t>(s.size());
+ m_file.write(reinterpret_cast<const char*>(&len), sizeof(uint32_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+ m_file.write(reinterpret_cast<const char*>(s.c_str()), len * sizeof(std::string::value_type));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint32_t u32Len, byte* pData)
+{
+ m_file.write(reinterpret_cast<const char*>(pData), u32Len);
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+//
+// TemporaryFile
+//
+Tools::TemporaryFile::TemporaryFile()
+{
+
+#ifdef _MSC_VER
+
+#ifndef L_tmpnam_s
+// MSVC 2003 doesn't have tmpnam_s, so we'll have to use the old functions
+
+ char* tmpName = NULL;
+ tmpName = tmpnam( NULL );
+
+ if (tmpName == NULL)
+ throw std::ios_base::failure("Tools::TemporaryFile: Cannot create temporary file name.");
+
+#else
+ char tmpName[L_tmpnam_s];
+ errno_t err = tmpnam_s(tmpName, L_tmpnam_s);
+ if (err)
+ throw std::ios_base::failure("Tools::TemporaryFile: Cannot create temporary file name.");
+
+#endif
+ if (tmpName[0] == '\\')
+ m_sFile = std::string(tmpName + 1);
+ else
+ m_sFile = std::string(tmpName);
+
+#else
+ char tmpName[7] = "XXXXXX";
+ if (mktemp(tmpName) == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile: Cannot create temporary file name.");
+ m_sFile = tmpName;
+#endif
+
+ m_pFile = new Tools::BufferedFileWriter(m_sFile, Tools::CREATE);
+}
+
+Tools::TemporaryFile::~TemporaryFile()
+{
+ delete m_pFile;
+
+#ifdef _MSC_VER
+ _unlink(m_sFile.c_str());
+#else
+ std::remove(m_sFile.c_str());
+#endif
+}
+
+void Tools::TemporaryFile::rewindForReading()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br != 0)
+ m_pFile->rewind();
+ else
+ {
+ delete m_pFile;
+ m_pFile = new Tools::BufferedFileReader(m_sFile);
+ }
+}
+
+void Tools::TemporaryFile::rewindForWriting()
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw != 0)
+ m_pFile->rewind();
+ else
+ {
+ delete m_pFile;
+ m_pFile = new Tools::BufferedFileWriter(m_sFile);
+ }
+}
+
+bool Tools::TemporaryFile::eof()
+{
+ return m_pFile->eof();
+}
+
+std::string Tools::TemporaryFile::getFileName() const
+{
+ return m_sFile;
+}
+
+uint8_t Tools::TemporaryFile::readUInt8()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt8: file not open for reading.");
+
+ return br->readUInt8();
+}
+
+uint16_t Tools::TemporaryFile::readUInt16()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt16: file not open for reading.");
+
+ return br->readUInt16();
+}
+
+uint32_t Tools::TemporaryFile::readUInt32()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt32: file not open for reading.");
+
+ return br->readUInt32();
+}
+
+uint64_t Tools::TemporaryFile::readUInt64()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt64: file not open for reading.");
+
+ return br->readUInt64();
+}
+
+float Tools::TemporaryFile::readFloat()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readFloat: file not open for reading.");
+
+ return br->readFloat();
+}
+
+double Tools::TemporaryFile::readDouble()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readDouble: file not open for reading.");
+
+ return br->readDouble();
+}
+
+std::string Tools::TemporaryFile::readString()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readString: file not open for reading.");
+
+ return br->readString();
+}
+
+void Tools::TemporaryFile::readBytes(uint32_t u32Len, byte** pData)
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readString: file not open for reading.");
+
+ return br->readBytes(u32Len, pData);
+}
+
+void Tools::TemporaryFile::write(uint8_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(uint16_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(uint32_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(uint64_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(float i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(double i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(const std::string& s)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(s);
+}
+
+void Tools::TemporaryFile::write(uint32_t u32Len, byte* pData)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(u32Len, pData);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/rand48.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/rand48.cc.svn-base
new file mode 100644
index 000000000..cc406019d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/.svn/text-base/rand48.cc.svn-base
@@ -0,0 +1,145 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include <math.h>
+#include <stdlib.h>
+
+#define RAND48_SEED_0 (0x330e)
+#define RAND48_SEED_1 (0xabcd)
+#define RAND48_SEED_2 (0x1234)
+#define RAND48_MULT_0 (0xe66d)
+#define RAND48_MULT_1 (0xdeec)
+#define RAND48_MULT_2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+
+ /* Internal function to compute next state of the generator. */
+static void _dorand48(unsigned short[3]);
+
+/* Unfortunately, 3 __globals, which the exported functions must access */
+unsigned short __rand48_Seed[3] = {
+ RAND48_SEED_0,
+ RAND48_SEED_1,
+ RAND48_SEED_2
+};
+unsigned short __rand48_Mult[3] = {
+ RAND48_MULT_0,
+ RAND48_MULT_1,
+ RAND48_MULT_2
+};
+unsigned short __rand48_Add = RAND48_ADD;
+
+/* Internal function to compute next state of the generator. */
+ static void
+_dorand48(unsigned short xseed[3])
+{
+ unsigned long accu;
+ unsigned short temp[2];
+
+ accu = (unsigned long) __rand48_Mult[0] * (unsigned long) xseed[0] +
+ (unsigned long) __rand48_Add;
+ temp[0] = (unsigned short) accu; /* lower 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += (unsigned long) __rand48_Mult[0] * (unsigned long) xseed[1] +
+ (unsigned long) __rand48_Mult[1] * (unsigned long) xseed[0];
+ temp[1] = (unsigned short) accu; /* middle 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += __rand48_Mult[0] * xseed[2] + __rand48_Mult[1] * xseed[1] +
+ __rand48_Mult[2] * xseed[0];
+ xseed[0] = temp[0];
+ xseed[1] = temp[1];
+ xseed[2] = (unsigned short) accu;
+}
+
+ extern void
+srand48(long seed)
+{
+ __rand48_Seed[0] = RAND48_SEED_0;
+ __rand48_Seed[1] = (unsigned short) seed;
+ __rand48_Seed[2] = (unsigned short) (seed >> 16);
+ __rand48_Mult[0] = RAND48_MULT_0;
+ __rand48_Mult[1] = RAND48_MULT_1;
+ __rand48_Mult[2] = RAND48_MULT_2;
+ __rand48_Add = RAND48_ADD;
+}
+
+ extern unsigned short *
+seed48(unsigned short xseed[3])
+{
+ static unsigned short sseed[3];
+
+ sseed[0] = __rand48_Seed[0];
+ sseed[1] = __rand48_Seed[1];
+ sseed[2] = __rand48_Seed[2];
+ __rand48_Seed[0] = xseed[0];
+ __rand48_Seed[1] = xseed[1];
+ __rand48_Seed[2] = xseed[2];
+ __rand48_Mult[0] = RAND48_MULT_0;
+ __rand48_Mult[1] = RAND48_MULT_1;
+ __rand48_Mult[2] = RAND48_MULT_2;
+ __rand48_Add = RAND48_ADD;
+ return sseed;
+}
+
+ extern long
+nrand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
+}
+ extern long
+mrand48(void)
+{
+ _dorand48(__rand48_Seed);
+ return ((long) __rand48_Seed[2] << 16) + (long) __rand48_Seed[1];
+}
+
+ extern long
+lrand48(void)
+{
+ _dorand48(__rand48_Seed);
+ return ((long) __rand48_Seed[2] << 15) + ((long) __rand48_Seed[1] >> 1);
+}
+
+ extern void
+lcong48(unsigned short p[7])
+{
+ __rand48_Seed[0] = p[0];
+ __rand48_Seed[1] = p[1];
+ __rand48_Seed[2] = p[2];
+ __rand48_Mult[0] = p[3];
+ __rand48_Mult[1] = p[4];
+ __rand48_Mult[2] = p[5];
+ __rand48_Add = p[6];
+}
+ extern long
+jrand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ((long) xseed[2] << 16) + (long) xseed[1];
+}
+
+ extern double
+erand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ldexp((double) xseed[0], -48) +
+ ldexp((double) xseed[1], -32) +
+ ldexp((double) xseed[2], -16);
+}
+
+ extern double
+drand48(void)
+{
+ return erand48(__rand48_Seed);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/tools/Makefile.am
new file mode 100755
index 000000000..eae038194
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/Makefile.am
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libtools.la
+INCLUDES = -I../../../include/tools
+libtools_la_SOURCES = Tools.cc rand48.cc
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/Tools.cc b/sci-libs/libspatialindex/svn/trunk/src/tools/Tools.cc
new file mode 100644
index 000000000..a8f4a970e
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/Tools.cc
@@ -0,0 +1,1365 @@
+// Spatial Index Library
+//
+// Copyright (C) 2004 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <time.h>
+#include <limits>
+#include "../../include/tools/Tools.h"
+#include "../../include/tools/rand48.h"
+
+#include <cstring>
+
+Tools::IndexOutOfBoundsException::IndexOutOfBoundsException(size_t i)
+{
+ std::ostringstream s;
+ s << "Invalid index " << i;
+ m_error = s.str();
+}
+
+std::string Tools::IndexOutOfBoundsException::what()
+{
+ return "IndexOutOfBoundsException: " + m_error;
+}
+
+Tools::IllegalArgumentException::IllegalArgumentException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::IllegalArgumentException::what()
+{
+ return "IllegalArgumentException: " + m_error;
+}
+
+Tools::IllegalStateException::IllegalStateException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::IllegalStateException::what()
+{
+ return "IllegalStateException: " + m_error;
+}
+
+Tools::EndOfStreamException::EndOfStreamException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::EndOfStreamException::what()
+{
+ return "EndOfStreamException: " + m_error;
+}
+
+Tools::ResourceLockedException::ResourceLockedException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::ResourceLockedException::what()
+{
+ return "ResourceLockedException: " + m_error;
+}
+
+Tools::NotSupportedException::NotSupportedException(std::string s) : m_error(s)
+{
+}
+
+std::string Tools::NotSupportedException::what()
+{
+ return "NotSupportedException: " + m_error;
+}
+
+Tools::Variant::Variant() : m_varType(VT_EMPTY)
+{
+}
+
+Tools::PropertySet::PropertySet(const byte* data)
+{
+#ifdef HAVE_PTHREAD_H
+ // pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+ loadFromByteArray(data);
+}
+
+Tools::PropertySet::~PropertySet()
+{
+#ifdef HAVE_PTHREAD_H
+ // pthread_rwlock_destroy(&m_rwLock);
+#endif
+}
+
+Tools::PropertySet::PropertySet()
+{
+#ifdef HAVE_PTHREAD_H
+ // pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+}
+void Tools::PropertySet::loadFromByteArray(const byte* ptr)
+{
+ m_propertySet.clear();
+
+ uint32_t numberOfProperties;
+ memcpy(&numberOfProperties, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ Variant v;
+
+ for (uint32_t cIndex = 0; cIndex < numberOfProperties; ++cIndex)
+ {
+ std::string s(reinterpret_cast<const char*>(ptr));
+ ptr += s.size() + 1;
+ memcpy(&(v.m_varType), ptr, sizeof(VariantType));
+ ptr += sizeof(VariantType);
+
+ switch (v.m_varType)
+ {
+ case VT_SHORT:
+ int16_t s;
+ memcpy(&s, ptr, sizeof(int16_t));
+ ptr += sizeof(int16_t);
+ v.m_val.iVal = s;
+ break;
+ case VT_LONG:
+ int32_t l;
+ memcpy(&l, ptr, sizeof(int32_t));
+ ptr += sizeof(int32_t);
+ v.m_val.lVal = l;
+ break;
+ case VT_LONGLONG:
+ int64_t ll;
+ memcpy(&ll, ptr, sizeof(int64_t));
+ ptr += sizeof(int64_t);
+ v.m_val.llVal = ll;
+ break;
+ case VT_BYTE:
+ byte b;
+ memcpy(&b, ptr, sizeof(byte));
+ ptr += sizeof(byte);
+ v.m_val.bVal = b;
+ break;
+ case VT_FLOAT:
+ float f;
+ memcpy(&f, ptr, sizeof(float));
+ ptr += sizeof(float);
+ v.m_val.fltVal = f;
+ break;
+ case VT_DOUBLE:
+ double d;
+ memcpy(&d, ptr, sizeof(double));
+ ptr += sizeof(double);
+ v.m_val.dblVal = d;
+ break;
+ case VT_CHAR:
+ char c;
+ memcpy(&c, ptr, sizeof(char));
+ ptr += sizeof(char);
+ v.m_val.cVal = c;
+ break;
+ case VT_USHORT:
+ uint16_t us;
+ memcpy(&us, ptr, sizeof(uint16_t));
+ ptr += sizeof(uint16_t);
+ v.m_val.uiVal = us;
+ break;
+ case VT_ULONG:
+ uint32_t ul;
+ memcpy(&ul, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ v.m_val.ulVal = ul;
+ break;
+ case VT_ULONGLONG:
+ uint64_t ull;
+ memcpy(&ull, ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ v.m_val.ullVal = ull;
+ break;
+ case VT_BOOL:
+ byte bl;
+ memcpy(&bl, ptr, sizeof(byte));
+ ptr += sizeof(byte);
+ v.m_val.blVal = (bl != 0);
+ break;
+ default:
+ throw IllegalStateException(
+ "Tools::PropertySet::PropertySet: Deserialization problem."
+ );
+ }
+
+ m_propertySet.insert(std::pair<std::string, Variant>(s, v));
+ }
+}
+
+uint32_t Tools::PropertySet::getByteArraySize()
+{
+ uint32_t size = sizeof(uint32_t);
+ std::map<std::string, Variant>::iterator it;
+
+ for (it = m_propertySet.begin(); it != m_propertySet.end(); ++it)
+ {
+ switch ((*it).second.m_varType)
+ {
+ case VT_SHORT:
+ size += sizeof(int16_t);
+ break;
+ case VT_LONG:
+ size += sizeof(int32_t);
+ break;
+ case VT_LONGLONG:
+ size += sizeof(int64_t);
+ break;
+ case VT_BYTE:
+ size += sizeof(byte);
+ break;
+ case VT_FLOAT:
+ size += sizeof(float);
+ break;
+ case VT_DOUBLE:
+ size += sizeof(double);
+ break;
+ case VT_CHAR:
+ size += sizeof(char);
+ break;
+ case VT_USHORT:
+ size += sizeof(uint16_t);
+ break;
+ case VT_ULONG:
+ size += sizeof(uint32_t);
+ break;
+ case VT_ULONGLONG:
+ size += sizeof(uint64_t);
+ break;
+ case VT_BOOL:
+ size += sizeof(byte);
+ break;
+ default:
+ throw NotSupportedException(
+ "Tools::PropertySet::getSize: Unknown type."
+ );
+ }
+ size += static_cast<uint32_t>((*it).first.size()) + 1 + sizeof(VariantType);
+ }
+
+ return size;
+}
+
+void Tools::PropertySet::storeToByteArray(byte** data, uint32_t& length)
+{
+ length = getByteArraySize();
+ *data = new byte[length];
+ byte* ptr = *data;
+
+ uint32_t numberOfProperties = static_cast<uint32_t>(m_propertySet.size());
+ memcpy(ptr, &numberOfProperties, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ std::map<std::string, Variant>::iterator it;
+
+ for (it = m_propertySet.begin(); it != m_propertySet.end(); ++it)
+ {
+ size_t strSize = (*it).first.size();
+ memcpy(ptr, (*it).first.c_str(), strSize);
+ ptr += strSize;
+ *ptr = 0;
+ ++ptr;
+
+ memcpy(ptr, &((*it).second.m_varType), sizeof(VariantType));
+ ptr += sizeof(VariantType);
+
+ switch ((*it).second.m_varType)
+ {
+ case VT_SHORT:
+ memcpy(ptr, &((*it).second.m_val.iVal), sizeof(int16_t));
+ ptr += sizeof(int16_t);
+ break;
+ case VT_LONG:
+ memcpy(ptr, &((*it).second.m_val.lVal), sizeof(int32_t));
+ ptr += sizeof(int32_t);
+ break;
+ case VT_LONGLONG:
+ memcpy(ptr, &((*it).second.m_val.llVal), sizeof(int64_t));
+ ptr += sizeof(int64_t);
+ break;
+ case VT_BYTE:
+ memcpy(ptr, &((*it).second.m_val.bVal), sizeof(byte));
+ ptr += sizeof(byte);
+ break;
+ case VT_FLOAT:
+ memcpy(ptr, &((*it).second.m_val.fltVal), sizeof(float));
+ ptr += sizeof(float);
+ break;
+ case VT_DOUBLE:
+ memcpy(ptr, &((*it).second.m_val.dblVal), sizeof(double));
+ ptr += sizeof(double);
+ break;
+ case VT_CHAR:
+ memcpy(ptr, &((*it).second.m_val.cVal), sizeof(char));
+ ptr += sizeof(char);
+ break;
+ case VT_USHORT:
+ memcpy(ptr, &((*it).second.m_val.uiVal), sizeof(uint16_t));
+ ptr += sizeof(uint16_t);
+ break;
+ case VT_ULONG:
+ memcpy(ptr, &((*it).second.m_val.ulVal), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ break;
+ case VT_ULONGLONG:
+ memcpy(ptr, &((*it).second.m_val.ullVal), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ break;
+ case VT_BOOL:
+ byte bl;
+ bl = (*it).second.m_val.blVal;
+ memcpy(ptr, &bl, sizeof(byte));
+ ptr += sizeof(byte);
+ break;
+ default:
+ throw NotSupportedException(
+ "Tools::PropertySet::getData: Cannot serialize a variant of this type."
+ );
+ }
+ }
+
+ assert(ptr == (*data) + length);
+}
+
+Tools::Variant Tools::PropertySet::getProperty(std::string property)
+{
+// #ifdef HAVE_PTHREAD_H
+// Tools::ExclusiveLock lock(&m_rwLock);
+// #else
+// if (m_rwLock == false) m_rwLock = true;
+// else throw Tools::IllegalStateException("getProperty: cannot acquire an shared lock");
+// #endif
+
+ try
+ {
+ std::map<std::string, Variant>::iterator it = m_propertySet.find(property);
+
+ if (it != m_propertySet.end()) return (*it).second;
+ else return Variant();
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void Tools::PropertySet::setProperty(std::string property, Variant& v)
+{
+#ifdef HAVE_PTHREAD_H
+ // Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::EndOfStreamException("setProperty: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ std::pair<std::map<std::string, Variant>::iterator, bool> ret;
+ std::map<std::string, Variant>::iterator it;
+
+ ret = m_propertySet.insert(std::pair<std::string, Variant>(property, v));
+
+ // If we weren't able to insert because it is already in the map
+ // update our existing value
+ if (ret.second == false) ret.first->second = v;
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void Tools::PropertySet::removeProperty(std::string property)
+{
+#ifdef HAVE_PTHREAD_H
+ // Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::EndOfStreamException("setProperty: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ std::map<std::string, Variant>::iterator it = m_propertySet.find(property);
+ if (it != m_propertySet.end()) m_propertySet.erase(it);
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+Tools::Interval::Interval() : m_type(IT_RIGHTOPEN), m_low(0.0), m_high(0.0)
+{
+}
+
+Tools::Interval::Interval(IntervalType t, double l, double h) : m_type(t), m_low(l), m_high(h)
+{
+ assert(l < h);
+}
+
+Tools::Interval::Interval(double l, double h) : m_type(IT_RIGHTOPEN), m_low(l), m_high(h)
+{
+ assert(l < h);
+}
+
+Tools::Interval::Interval(const Interval& iv)
+{
+ m_low = iv.m_low;
+ m_high = iv.m_high;
+ m_type = iv.m_type;
+}
+
+Tools::IInterval& Tools::Interval::operator=(const Tools::IInterval& iv)
+{
+ if (this != &iv)
+ {
+ m_low = iv.getLowerBound();
+ m_high = iv.getUpperBound();
+ m_type = iv.getIntervalType();
+ }
+
+ return *this;
+}
+
+bool Tools::Interval::operator==(const Interval& iv) const
+{
+ if (
+ m_type == iv.m_type &&
+ m_low >= iv.m_low - std::numeric_limits<double>::epsilon() &&
+ m_low <= iv.m_low + std::numeric_limits<double>::epsilon() &&
+ m_high >= iv.m_high - std::numeric_limits<double>::epsilon() &&
+ m_high <= iv.m_high + std::numeric_limits<double>::epsilon())
+ return true;
+
+ return false;
+}
+
+bool Tools::Interval::operator!=(const Interval& iv) const
+{
+ return ! (*this == iv);
+}
+
+double Tools::Interval::getLowerBound() const
+{
+ return m_low;
+}
+
+double Tools::Interval::getUpperBound() const
+{
+ return m_high;
+}
+
+void Tools::Interval::setBounds(double l, double h)
+{
+ assert(l <= h);
+
+ m_low = l;
+ m_high = h;
+}
+
+bool Tools::Interval::intersectsInterval(const IInterval& i) const
+{
+ return intersectsInterval(i.getIntervalType(), i.getLowerBound(), i.getUpperBound());
+}
+
+bool Tools::Interval::intersectsInterval(IntervalType type, const double low, const double high) const
+{
+ if (m_high < m_low)
+ throw IllegalStateException(
+ "Tools::Interval::intersectsInterval: high boundary is smaller than low boundary."
+ );
+
+ if (m_low > high || m_high < low) return false;
+ if ((m_low > low && m_low < high) || (m_high > low && m_high < high)) return true;
+
+ switch (m_type)
+ {
+ case IT_CLOSED:
+ if (m_low == high)
+ {
+ if (type == IT_CLOSED || type == IT_LEFTOPEN) return true;
+ else return false;
+ }
+ else if (m_high == low)
+ {
+ if (type == IT_CLOSED || type == IT_RIGHTOPEN) return true;
+ else return false;
+ }
+ break;
+ case IT_OPEN:
+ if (m_low == high || m_high == low) return false;
+ break;
+ case IT_RIGHTOPEN:
+ if (m_low == high)
+ {
+ if (type == IT_CLOSED || type == IT_LEFTOPEN) return true;
+ else return false;
+ }
+ else if (m_high == low)
+ {
+ return false;
+ }
+ break;
+ case IT_LEFTOPEN:
+ if (m_low == high)
+ {
+ return false;
+ }
+ else if (m_high == low)
+ {
+ if (type == IT_CLOSED || type == IT_RIGHTOPEN) return true;
+ else return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+bool Tools::Interval::containsInterval(const IInterval& i) const
+{
+ if (m_high < m_low)
+ throw IllegalStateException(
+ "Tools::Interval::containsInterval: high boundary is smaller than low boundary."
+ );
+
+ double low = i.getLowerBound();
+ double high = i.getUpperBound();
+ IntervalType type = i.getIntervalType();
+
+ if (m_low < low && m_high > high) return true;
+ if (m_low > low || m_high < high) return false;
+
+ switch (m_type)
+ {
+ case IT_CLOSED:
+ break;
+ case IT_OPEN:
+ if ((m_low == low && m_high == high && type != IT_OPEN) ||
+ (m_low == low && (type == IT_CLOSED || type == IT_RIGHTOPEN)) ||
+ (m_high == high && ( type == IT_CLOSED || type == IT_LEFTOPEN)))
+ return false;
+ break;
+ case IT_RIGHTOPEN:
+ if (m_high == high && (type == IT_CLOSED || type == IT_LEFTOPEN))
+ return false;
+ break;
+ case IT_LEFTOPEN:
+ if (m_low == low && (type == IT_CLOSED || type == IT_RIGHTOPEN))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+Tools::IntervalType Tools::Interval::getIntervalType() const
+{
+ return m_type;
+}
+
+Tools::Random::Random()
+{
+ m_pBuffer = 0;
+ initDrand(static_cast<uint32_t>(time(0)), 0xD31A);
+}
+
+Tools::Random::Random(uint32_t seed, uint16_t xsubi0)
+{
+ m_pBuffer = 0;
+ initDrand(seed, xsubi0);
+}
+
+Tools::Random::~Random()
+{
+ delete[] m_pBuffer;
+}
+
+void Tools::Random::initDrand(uint32_t seed, uint16_t xsubi0)
+{
+ m_pBuffer = new uint16_t[3];
+ m_pBuffer[0] = static_cast<uint16_t>(xsubi0);
+ uint32_t mask = 0xFFFF;
+ m_pBuffer[1] = static_cast<uint16_t>(seed & mask);
+ mask = mask << 16;
+ m_pBuffer[2] = static_cast<uint16_t>((seed & mask) >> 16);
+
+#ifdef BUILD_OS_CYGWIN
+ srand48(*(reinterpret_cast<uint32_t*>(m_pBuffer)));
+ // BUG: There is a bug in cygwin gcc 3.4.4. srand48 needs to be called
+ // even if we are using the functions that take the seed as a parameter.
+ // This does not affect random number generation, which still happens
+ // using the seed provided as a parameter and not the one provided to srand48 :-S
+#endif
+}
+
+int32_t Tools::Random::nextUniformLong()
+{
+ return jrand48(m_pBuffer);
+}
+
+uint32_t Tools::Random::nextUniformUnsignedLong()
+{
+ return static_cast<uint32_t>(nextUniformLong());
+}
+
+int32_t Tools::Random::nextUniformLong(int32_t low, int32_t high)
+{
+ return low + static_cast<int32_t>((high - low) * nextUniformDouble());
+}
+
+uint32_t Tools::Random::nextUniformUnsignedLong(uint32_t low, uint32_t high)
+{
+ return low + static_cast<uint32_t>((high - low) * nextUniformDouble());
+}
+
+int64_t Tools::Random::nextUniformLongLong()
+{
+ return static_cast<int64_t>(nextUniformUnsignedLongLong());
+}
+
+uint64_t Tools::Random::nextUniformUnsignedLongLong()
+{
+ uint64_t lh = static_cast<uint64_t>(nextUniformLong());
+ uint64_t ll = static_cast<uint64_t>(nextUniformLong());
+ uint64_t ret = (lh << 32) | ll;
+ return ret;
+}
+
+int64_t Tools::Random::nextUniformLongLong(int64_t low, int64_t high)
+{
+ return low + static_cast<int64_t>((high - low) * nextUniformDouble());
+}
+
+uint64_t Tools::Random::nextUniformUnsignedLongLong(uint64_t low, uint64_t high)
+{
+ return low + static_cast<uint64_t>((high - low) * nextUniformDouble());
+}
+
+int16_t Tools::Random::nextUniformShort()
+{
+ return static_cast<int16_t>(nextUniformUnsignedShort());
+}
+
+uint16_t Tools::Random::nextUniformUnsignedShort()
+{
+ return nextUniformUnsignedLong() >> 16;
+ // retain the high order bits.
+}
+
+double Tools::Random::nextUniformDouble()
+{
+ uint16_t* xsubi = reinterpret_cast<uint16_t*>(m_pBuffer);
+ return erand48(xsubi);
+}
+
+double Tools::Random::nextUniformDouble(double low, double high)
+{
+ return (high - low) * nextUniformDouble() + low;
+}
+
+bool Tools::Random::flipCoin()
+{
+ if (nextUniformDouble() < 0.5) return true;
+ return false;
+}
+
+#if HAVE_PTHREAD_H
+Tools::SharedLock::SharedLock(pthread_rwlock_t* pLock)
+ : m_pLock(pLock)
+{
+ pthread_rwlock_rdlock(m_pLock);
+}
+
+Tools::SharedLock::~SharedLock()
+{
+ pthread_rwlock_unlock(m_pLock);
+}
+
+Tools::ExclusiveLock::ExclusiveLock(pthread_rwlock_t* pLock)
+ : m_pLock(pLock)
+{
+ pthread_rwlock_wrlock(m_pLock);
+}
+
+Tools::ExclusiveLock::~ExclusiveLock()
+{
+ pthread_rwlock_unlock(m_pLock);
+}
+#endif
+
+std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p)
+{
+ std::map<std::string, Variant>::const_iterator it;
+
+ for (it = p.m_propertySet.begin(); it != p.m_propertySet.end(); ++it)
+ {
+ if (it != p.m_propertySet.begin()) os << ", ";
+
+ switch ((*it).second.m_varType)
+ {
+ case VT_LONG:
+ os << (*it).first << ": " << (*it).second.m_val.lVal;
+ break;
+ case VT_LONGLONG:
+ os << (*it).first << ": " << (*it).second.m_val.llVal;
+ break;
+ case VT_BYTE:
+ os << (*it).first << ": " << (*it).second.m_val.bVal;
+ break;
+ case VT_SHORT:
+ os << (*it).first << ": " << (*it).second.m_val.iVal;
+ break;
+ case VT_FLOAT:
+ os << (*it).first << ": " << (*it).second.m_val.fltVal;
+ break;
+ case VT_DOUBLE:
+ os << (*it).first << ": " << (*it).second.m_val.dblVal;
+ break;
+ case VT_CHAR:
+ os << (*it).first << ": " << (*it).second.m_val.cVal;
+ break;
+ case VT_USHORT:
+ os << (*it).first << ": " << (*it).second.m_val.uiVal;
+ break;
+ case VT_ULONG:
+ os << (*it).first << ": " << (*it).second.m_val.ulVal;
+ break;
+ case VT_ULONGLONG:
+ os << (*it).first << ": " << (*it).second.m_val.ullVal;
+ break;
+ case VT_BOOL:
+ os << (*it).first << ": " << (*it).second.m_val.blVal;
+ break;
+ case VT_PCHAR:
+ os << (*it).first << ": " << (*it).second.m_val.pcVal;
+ break;
+ case VT_PVOID:
+ os << (*it).first << ": ?";
+ break;
+ case VT_EMPTY:
+ os << (*it).first << ": empty";
+ break;
+ default:
+ os << (*it).first << ": unknown";
+ }
+ }
+
+ return os;
+}
+
+std::ostream& Tools::operator<<(std::ostream& os, const Tools::Interval& iv)
+{
+ os << iv.m_type << " " << iv.m_low << " " << iv.m_high;
+ return os;
+}
+
+//
+// BufferedFile
+//
+Tools::BufferedFile::BufferedFile(uint32_t u32BufferSize)
+: m_buffer(new char[u32BufferSize]), m_u32BufferSize(u32BufferSize), m_bEOF(true)
+{
+}
+
+Tools::BufferedFile::~BufferedFile()
+{
+ m_file.close();
+ delete[] m_buffer;
+}
+
+void Tools::BufferedFile::close()
+{
+ m_file.close();
+}
+
+bool Tools::BufferedFile::eof()
+{
+ return m_bEOF;
+}
+
+//
+// BufferedFileReader
+//
+Tools::BufferedFileReader::BufferedFileReader()
+{
+}
+
+Tools::BufferedFileReader::BufferedFileReader(const std::string& sFileName, uint32_t u32BufferSize)
+: BufferedFile(u32BufferSize)
+{
+ open(sFileName);
+}
+
+void Tools::BufferedFileReader::open(const std::string& sFileName)
+{
+ m_bEOF = false;
+ m_file.close(); m_file.clear();
+
+
+ m_file.open(sFileName.c_str(), std::ios_base::in | std::ios_base::binary);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileReader::BufferedFileReader: Cannot open file.");
+
+ m_file.rdbuf()->pubsetbuf(m_buffer, m_u32BufferSize);
+}
+
+Tools::BufferedFileReader::~BufferedFileReader()
+{
+}
+
+void Tools::BufferedFileReader::rewind()
+{
+ m_file.clear();
+ m_file.seekg(0, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileReader::rewind: seek failed.");
+
+ m_bEOF = false;
+}
+
+void Tools::BufferedFileReader::seek(std::fstream::off_type offset)
+{
+ m_bEOF = false;
+ m_file.clear();
+ m_file.seekg(offset, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileReader::seek: seek failed.");
+}
+
+uint8_t Tools::BufferedFileReader::readUInt8()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint8_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint8_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+uint16_t Tools::BufferedFileReader::readUInt16()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint16_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint16_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+uint32_t Tools::BufferedFileReader::readUInt32()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint32_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint32_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+uint64_t Tools::BufferedFileReader::readUInt64()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint64_t ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(uint64_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+float Tools::BufferedFileReader::readFloat()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ float ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(float));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+double Tools::BufferedFileReader::readDouble()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ double ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(double));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+bool Tools::BufferedFileReader::readBoolean()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ bool ret;
+ m_file.read(reinterpret_cast<char*>(&ret), sizeof(bool));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+ return ret;
+}
+
+std::string Tools::BufferedFileReader::readString()
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ uint32_t len;
+ m_file.read(reinterpret_cast<char*>(&len), sizeof(uint32_t));
+ if (! m_file.good())
+ {
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+
+ std::string::value_type* buf = new std::string::value_type[len];
+ m_file.read(reinterpret_cast<char*>(buf), len * sizeof(std::string::value_type));
+ if (! m_file.good())
+ {
+ delete[] buf;
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+
+ std::string ret(buf, len);
+ delete[] buf;
+
+ return ret;
+}
+
+void Tools::BufferedFileReader::readBytes(uint32_t u32Len, byte** pData)
+{
+ if (m_bEOF) throw Tools::EndOfStreamException("");
+
+ *pData = new byte[u32Len];
+ m_file.read(reinterpret_cast<char*>(*pData), u32Len);
+ if (! m_file.good())
+ {
+ delete[] *pData;
+ m_bEOF = true;
+ throw Tools::EndOfStreamException("");
+ }
+}
+
+//
+// BufferedFileWriter
+//
+Tools::BufferedFileWriter::BufferedFileWriter()
+{
+ open("");
+}
+
+Tools::BufferedFileWriter::BufferedFileWriter(const std::string& sFileName, FileMode mode, uint32_t u32BufferSize)
+: BufferedFile(u32BufferSize)
+{
+ open(sFileName, mode);
+}
+
+Tools::BufferedFileWriter::~BufferedFileWriter()
+{
+ m_file.flush();
+}
+
+void Tools::BufferedFileWriter::open(const std::string& sFileName, FileMode mode)
+{
+ m_bEOF = false;
+ m_file.close(); m_file.clear();
+
+ if (mode == CREATE)
+ {
+ m_file.open(sFileName.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::open: Cannot open file.");
+ }
+ else if (mode == APPEND)
+ {
+ // Idiotic fstream::open truncates an existing file anyway, if it is only opened
+ // for output (no ios_base::in flag)!! On the other hand, if a file does not exist
+ // and the ios_base::in flag is specified, then the open fails!!
+
+ m_file.open(sFileName.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ if (! m_file.good())
+ {
+ m_file.clear();
+ m_file.open(sFileName.c_str(), std::ios_base::out | std::ios_base::binary);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::open: Cannot open file.");
+ }
+ else
+ {
+ m_file.seekp(0, std::ios_base::end);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::open: Cannot open file.");
+ }
+ }
+ else
+ throw Tools::IllegalArgumentException("Tools::BufferedFileWriter::open: Unknown mode.");
+}
+
+void Tools::BufferedFileWriter::rewind()
+{
+ m_bEOF = false;
+ m_file.clear();
+ m_file.seekp(0, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::rewind: seek failed.");
+}
+
+void Tools::BufferedFileWriter::seek(std::fstream::off_type offset)
+{
+ m_bEOF = false;
+ m_file.clear();
+ m_file.seekp(offset, std::ios_base::beg);
+ if (! m_file.good())
+ throw std::ios_base::failure("Tools::BufferedFileWriter::seek: seek failed.");
+}
+
+void Tools::BufferedFileWriter::write(uint8_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint8_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint16_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint16_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint32_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint32_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint64_t i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(uint64_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(float i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(float));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(double i)
+{
+ m_file.write(reinterpret_cast<const char*>(&i), sizeof(double));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(bool b)
+{
+ m_file.write(reinterpret_cast<const char*>(&b), sizeof(bool));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(const std::string& s)
+{
+ uint32_t len = static_cast<uint32_t>(s.size());
+ m_file.write(reinterpret_cast<const char*>(&len), sizeof(uint32_t));
+ if (! m_file.good()) throw std::ios_base::failure("");
+ m_file.write(reinterpret_cast<const char*>(s.c_str()), len * sizeof(std::string::value_type));
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+void Tools::BufferedFileWriter::write(uint32_t u32Len, byte* pData)
+{
+ m_file.write(reinterpret_cast<const char*>(pData), u32Len);
+ if (! m_file.good()) throw std::ios_base::failure("");
+}
+
+//
+// TemporaryFile
+//
+Tools::TemporaryFile::TemporaryFile()
+{
+
+#ifdef _MSC_VER
+
+#ifndef L_tmpnam_s
+// MSVC 2003 doesn't have tmpnam_s, so we'll have to use the old functions
+
+ char* tmpName = NULL;
+ tmpName = tmpnam( NULL );
+
+ if (tmpName == NULL)
+ throw std::ios_base::failure("Tools::TemporaryFile: Cannot create temporary file name.");
+
+#else
+ char tmpName[L_tmpnam_s];
+ errno_t err = tmpnam_s(tmpName, L_tmpnam_s);
+ if (err)
+ throw std::ios_base::failure("Tools::TemporaryFile: Cannot create temporary file name.");
+
+#endif
+ if (tmpName[0] == '\\')
+ m_sFile = std::string(tmpName + 1);
+ else
+ m_sFile = std::string(tmpName);
+
+#else
+ char tmpName[7] = "XXXXXX";
+ if (mktemp(tmpName) == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile: Cannot create temporary file name.");
+ m_sFile = tmpName;
+#endif
+
+ m_pFile = new Tools::BufferedFileWriter(m_sFile, Tools::CREATE);
+}
+
+Tools::TemporaryFile::~TemporaryFile()
+{
+ delete m_pFile;
+
+#ifdef _MSC_VER
+ _unlink(m_sFile.c_str());
+#else
+ std::remove(m_sFile.c_str());
+#endif
+}
+
+void Tools::TemporaryFile::rewindForReading()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br != 0)
+ m_pFile->rewind();
+ else
+ {
+ delete m_pFile;
+ m_pFile = new Tools::BufferedFileReader(m_sFile);
+ }
+}
+
+void Tools::TemporaryFile::rewindForWriting()
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw != 0)
+ m_pFile->rewind();
+ else
+ {
+ delete m_pFile;
+ m_pFile = new Tools::BufferedFileWriter(m_sFile);
+ }
+}
+
+bool Tools::TemporaryFile::eof()
+{
+ return m_pFile->eof();
+}
+
+std::string Tools::TemporaryFile::getFileName() const
+{
+ return m_sFile;
+}
+
+uint8_t Tools::TemporaryFile::readUInt8()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt8: file not open for reading.");
+
+ return br->readUInt8();
+}
+
+uint16_t Tools::TemporaryFile::readUInt16()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt16: file not open for reading.");
+
+ return br->readUInt16();
+}
+
+uint32_t Tools::TemporaryFile::readUInt32()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt32: file not open for reading.");
+
+ return br->readUInt32();
+}
+
+uint64_t Tools::TemporaryFile::readUInt64()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readUInt64: file not open for reading.");
+
+ return br->readUInt64();
+}
+
+float Tools::TemporaryFile::readFloat()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readFloat: file not open for reading.");
+
+ return br->readFloat();
+}
+
+double Tools::TemporaryFile::readDouble()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readDouble: file not open for reading.");
+
+ return br->readDouble();
+}
+
+std::string Tools::TemporaryFile::readString()
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readString: file not open for reading.");
+
+ return br->readString();
+}
+
+void Tools::TemporaryFile::readBytes(uint32_t u32Len, byte** pData)
+{
+ Tools::BufferedFileReader* br = dynamic_cast<Tools::BufferedFileReader*>(m_pFile);
+ if (br == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::readString: file not open for reading.");
+
+ return br->readBytes(u32Len, pData);
+}
+
+void Tools::TemporaryFile::write(uint8_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(uint16_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(uint32_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(uint64_t i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(float i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(double i)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(i);
+}
+
+void Tools::TemporaryFile::write(const std::string& s)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(s);
+}
+
+void Tools::TemporaryFile::write(uint32_t u32Len, byte* pData)
+{
+ Tools::BufferedFileWriter* bw = dynamic_cast<Tools::BufferedFileWriter*>(m_pFile);
+ if (bw == 0)
+ throw std::ios_base::failure("Tools::TemporaryFile::write: file not open for writing.");
+
+ return bw->write(u32Len, pData);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tools/rand48.cc b/sci-libs/libspatialindex/svn/trunk/src/tools/rand48.cc
new file mode 100644
index 000000000..cc406019d
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tools/rand48.cc
@@ -0,0 +1,145 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include <math.h>
+#include <stdlib.h>
+
+#define RAND48_SEED_0 (0x330e)
+#define RAND48_SEED_1 (0xabcd)
+#define RAND48_SEED_2 (0x1234)
+#define RAND48_MULT_0 (0xe66d)
+#define RAND48_MULT_1 (0xdeec)
+#define RAND48_MULT_2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+
+ /* Internal function to compute next state of the generator. */
+static void _dorand48(unsigned short[3]);
+
+/* Unfortunately, 3 __globals, which the exported functions must access */
+unsigned short __rand48_Seed[3] = {
+ RAND48_SEED_0,
+ RAND48_SEED_1,
+ RAND48_SEED_2
+};
+unsigned short __rand48_Mult[3] = {
+ RAND48_MULT_0,
+ RAND48_MULT_1,
+ RAND48_MULT_2
+};
+unsigned short __rand48_Add = RAND48_ADD;
+
+/* Internal function to compute next state of the generator. */
+ static void
+_dorand48(unsigned short xseed[3])
+{
+ unsigned long accu;
+ unsigned short temp[2];
+
+ accu = (unsigned long) __rand48_Mult[0] * (unsigned long) xseed[0] +
+ (unsigned long) __rand48_Add;
+ temp[0] = (unsigned short) accu; /* lower 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += (unsigned long) __rand48_Mult[0] * (unsigned long) xseed[1] +
+ (unsigned long) __rand48_Mult[1] * (unsigned long) xseed[0];
+ temp[1] = (unsigned short) accu; /* middle 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += __rand48_Mult[0] * xseed[2] + __rand48_Mult[1] * xseed[1] +
+ __rand48_Mult[2] * xseed[0];
+ xseed[0] = temp[0];
+ xseed[1] = temp[1];
+ xseed[2] = (unsigned short) accu;
+}
+
+ extern void
+srand48(long seed)
+{
+ __rand48_Seed[0] = RAND48_SEED_0;
+ __rand48_Seed[1] = (unsigned short) seed;
+ __rand48_Seed[2] = (unsigned short) (seed >> 16);
+ __rand48_Mult[0] = RAND48_MULT_0;
+ __rand48_Mult[1] = RAND48_MULT_1;
+ __rand48_Mult[2] = RAND48_MULT_2;
+ __rand48_Add = RAND48_ADD;
+}
+
+ extern unsigned short *
+seed48(unsigned short xseed[3])
+{
+ static unsigned short sseed[3];
+
+ sseed[0] = __rand48_Seed[0];
+ sseed[1] = __rand48_Seed[1];
+ sseed[2] = __rand48_Seed[2];
+ __rand48_Seed[0] = xseed[0];
+ __rand48_Seed[1] = xseed[1];
+ __rand48_Seed[2] = xseed[2];
+ __rand48_Mult[0] = RAND48_MULT_0;
+ __rand48_Mult[1] = RAND48_MULT_1;
+ __rand48_Mult[2] = RAND48_MULT_2;
+ __rand48_Add = RAND48_ADD;
+ return sseed;
+}
+
+ extern long
+nrand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
+}
+ extern long
+mrand48(void)
+{
+ _dorand48(__rand48_Seed);
+ return ((long) __rand48_Seed[2] << 16) + (long) __rand48_Seed[1];
+}
+
+ extern long
+lrand48(void)
+{
+ _dorand48(__rand48_Seed);
+ return ((long) __rand48_Seed[2] << 15) + ((long) __rand48_Seed[1] >> 1);
+}
+
+ extern void
+lcong48(unsigned short p[7])
+{
+ __rand48_Seed[0] = p[0];
+ __rand48_Seed[1] = p[1];
+ __rand48_Seed[2] = p[2];
+ __rand48_Mult[0] = p[3];
+ __rand48_Mult[1] = p[4];
+ __rand48_Mult[2] = p[5];
+ __rand48_Add = p[6];
+}
+ extern long
+jrand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ((long) xseed[2] << 16) + (long) xseed[1];
+}
+
+ extern double
+erand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ldexp((double) xseed[0], -48) +
+ ldexp((double) xseed[1], -32) +
+ ldexp((double) xseed[2], -16);
+}
+
+ extern double
+drand48(void)
+{
+ return erand48(__rand48_Seed);
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/all-wcprops b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/all-wcprops
new file mode 100644
index 000000000..d0b7228b9
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/all-wcprops
@@ -0,0 +1,77 @@
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/tprtree
+END
+Statistics.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/Statistics.h
+END
+PointerPoolNode.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/PointerPoolNode.h
+END
+Makefile.am
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/45/spatialindex/trunk/src/tprtree/Makefile.am
+END
+Node.cc
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/tprtree/Node.cc
+END
+TPRTree.cc
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/tprtree/TPRTree.cc
+END
+Index.cc
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/spatialindex/!svn/ver/159/spatialindex/trunk/src/tprtree/Index.cc
+END
+Leaf.cc
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/Leaf.cc
+END
+Node.h
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/Node.h
+END
+TPRTree.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/spatialindex/!svn/ver/133/spatialindex/trunk/src/tprtree/TPRTree.h
+END
+Index.h
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/Index.h
+END
+Leaf.h
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/Leaf.h
+END
+Statistics.cc
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/spatialindex/!svn/ver/130/spatialindex/trunk/src/tprtree/Statistics.cc
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/dir-prop-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/dir-prop-base
new file mode 100644
index 000000000..ea9b95e8a
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/dir-prop-base
@@ -0,0 +1,9 @@
+K 10
+svn:ignore
+V 33
+Makefile.in
+.libs
+.deps
+Makefile
+
+END
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/entries b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/entries
new file mode 100644
index 000000000..370b2ac09
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/entries
@@ -0,0 +1,436 @@
+10
+
+dir
+203
+http://svn.gispython.org/spatialindex/spatialindex/trunk/src/tprtree
+http://svn.gispython.org/spatialindex
+
+
+
+2009-11-02T20:08:16.754818Z
+159
+hobu
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+619784c2-a736-0410-9738-aa60efc94a9c
+
+Statistics.h
+file
+
+
+
+
+2011-08-01T00:42:34.734138Z
+a9369e45f996375d76e118a00d438f6c
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2269
+
+PointerPoolNode.h
+file
+
+
+
+
+2011-08-01T00:42:34.734138Z
+a97ebd375163a3bee8d1cf56222f0671
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2676
+
+Makefile.am
+file
+
+
+
+
+2011-08-01T00:42:34.734138Z
+3289458f71d69c2203543185e34a605d
+2008-01-17T23:34:01.575758Z
+45
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+274
+
+Node.cc
+file
+
+
+
+
+2011-08-01T00:42:34.734138Z
+27dfacbf070d76b0c85114c65f0c76eb
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+36860
+
+TPRTree.cc
+file
+
+
+
+
+2011-08-01T00:42:34.734138Z
+39fc26a49ea18f3271482e1ba30f9bb1
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+38446
+
+Index.cc
+file
+
+
+
+
+2011-08-01T00:42:34.734138Z
+b3f77c3ed0dce9c492b40f850c1eeb20
+2009-11-02T20:08:16.754818Z
+159
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+12394
+
+Leaf.cc
+file
+
+
+
+
+2011-08-01T00:42:34.737159Z
+28860ef91f5b5b1a1f10b2da9b0bd24c
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4193
+
+Node.h
+file
+
+
+
+
+2011-08-01T00:42:34.741160Z
+deb8036556b5969f5f10470683e6b5c6
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6487
+
+TPRTree.h
+file
+
+
+
+
+2011-08-01T00:42:34.741160Z
+d812837a69ec25ea163a6b254386a211
+2009-08-14T15:19:40.553411Z
+133
+hobu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6862
+
+Index.h
+file
+
+
+
+
+2011-08-01T00:42:34.741160Z
+1a71065318767017c849ceb14b3acbb3
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2216
+
+Leaf.h
+file
+
+
+
+
+2011-08-01T00:42:34.741160Z
+f548d3c8d8ff0a8245013b1380d7921c
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1483
+
+Statistics.cc
+file
+
+
+
+
+2011-08-01T00:42:34.741160Z
+e93804de428f2bffd1e5a1672cd36a52
+2009-08-13T15:24:35.589450Z
+130
+mhadji
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3591
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.cc.svn-base
new file mode 100644
index 000000000..574414812
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.cc.svn-base
@@ -0,0 +1,400 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "TPRTree.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+
+using namespace SpatialIndex::TPRTree;
+
+Index::~Index()
+{
+}
+
+Index::Index(SpatialIndex::TPRTree::TPRTree* pTree, id_type id, uint32_t level) : Node(pTree, id, level, pTree->m_indexCapacity)
+{
+}
+
+NodePtr Index::chooseSubtree(const MovingRegion& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
+{
+ if (m_level == insertionLevel) return NodePtr(this, &(m_pTree->m_indexPool));
+
+ pathBuffer.push(m_identifier);
+
+ uint32_t child = 0;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case TPRV_RSTAR:
+ if (m_level == 1)
+ {
+ // if this node points to leaves...
+ child = findLeastOverlap(mbr);
+ }
+ else
+ {
+ child = findLeastEnlargement(mbr);
+ }
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::chooseSubtree: Tree variant not supported.");
+ }
+ assert(child != std::numeric_limits<uint32_t>::max());
+
+ NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
+ NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
+ assert(n.unique());
+ if (ret.get() == n.get()) n.relinquish();
+
+ return ret;
+}
+
+NodePtr Index::findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->containsRegionAfterTime(m_pTree->m_currentTime, mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findLeaf(mbr, id, pathBuffer);
+ if (n.get() == l.get()) n.relinquish();
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
+
+void Index::split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
+{
+ ++(m_pTree->m_stats.m_splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case TPRV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_indexPool.acquire();
+ pRight = m_pTree->m_indexPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(0, 0, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(0, 0, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ }
+}
+
+uint32_t Index::findLeastEnlargement(const MovingRegion& r) const
+{
+ double area = std::numeric_limits<double>::max();
+ uint32_t best = std::numeric_limits<uint32_t>::max();
+
+ MovingRegionPtr t = m_pTree->m_regionPool.acquire();
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // I need the combined region from current time up to infinity here.
+ m_ptrMBR[cChild]->getCombinedRegionAfterTime(ivT.getLowerBound(), *t, r);
+
+ double a = m_ptrMBR[cChild]->getAreaInTime(ivT);
+ double b = t->getAreaInTime(ivT);
+ double enl = b - a;
+
+ if (enl < area)
+ {
+ area = enl;
+ best = cChild;
+ }
+ else if (enl == area)
+ {
+ // this will rarely happen, so compute best area on the fly only
+ // when necessary.
+ if (a < m_ptrMBR[best]->getAreaInTime(ivT)) best = cChild;
+ }
+ }
+
+ return best;
+}
+
+uint32_t Index::findLeastOverlap(const MovingRegion& r) const
+{
+ OverlapEntry** entries = new OverlapEntry*[m_children];
+
+ double leastOverlap = std::numeric_limits<double>::max();
+ double me = std::numeric_limits<double>::max();
+ OverlapEntry* best = 0;
+
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ // find combined region and enlargement of every entry and store it.
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ try
+ {
+ entries[cChild] = new OverlapEntry();
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete entries[i];
+ delete[] entries;
+ throw;
+ }
+
+ entries[cChild]->m_index = cChild;
+ entries[cChild]->m_original = m_ptrMBR[cChild];
+ entries[cChild]->m_combined = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->getCombinedRegionAfterTime(m_pTree->m_currentTime, *(entries[cChild]->m_combined), r);
+ entries[cChild]->m_oa = entries[cChild]->m_original->getAreaInTime(ivT);
+ entries[cChild]->m_ca = entries[cChild]->m_combined->getAreaInTime(ivT);
+ entries[cChild]->m_enlargement = entries[cChild]->m_ca - entries[cChild]->m_oa;
+
+ if (entries[cChild]->m_enlargement < me)
+ {
+ me = entries[cChild]->m_enlargement;
+ best = entries[cChild];
+ }
+ else if (entries[cChild]->m_enlargement == me && entries[cChild]->m_oa < best->m_oa)
+ {
+ best = entries[cChild];
+ }
+ }
+
+ if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
+ {
+ uint32_t cIterations;
+
+ if (m_children > m_pTree->m_nearMinimumOverlapFactor)
+ {
+ // sort entries in increasing order of enlargement.
+ ::qsort(entries, m_children,
+ sizeof(OverlapEntry*),
+ OverlapEntry::compareEntries);
+ assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
+
+ cIterations = m_pTree->m_nearMinimumOverlapFactor;
+ }
+ else
+ {
+ cIterations = m_children;
+ }
+
+ // calculate overlap of most important original entries (near minimum overlap cost).
+ for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
+ {
+ double dif = 0.0;
+ OverlapEntry* e = entries[cIndex];
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (e->m_index != cChild)
+ {
+ double f = e->m_combined->getIntersectingAreaInTime(ivT, *(m_ptrMBR[cChild]));
+ if (f != 0.0) dif += f - e->m_original->getIntersectingAreaInTime(ivT, *(m_ptrMBR[cChild]));
+ }
+ } // for (cChild)
+
+ if (dif < leastOverlap)
+ {
+ leastOverlap = dif;
+ best = entries[cIndex];
+ }
+ else if (dif == leastOverlap)
+ {
+ if (e->m_enlargement == best->m_enlargement)
+ {
+ // keep the one with least area.
+ if (e->m_original->getAreaInTime(ivT) < best->m_original->getAreaInTime(ivT)) best = entries[cIndex];
+ }
+ else
+ {
+ // keep the one with least enlargement.
+ if (e->m_enlargement < best->m_enlargement) best = entries[cIndex];
+ }
+ }
+ } // for (cIndex)
+ }
+
+ uint32_t ret = best->m_index;
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ delete entries[cChild];
+ }
+ delete[] entries;
+
+ return ret;
+}
+
+void Index::adjustTree(Node* n, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+ assert(child < m_children);
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ //Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+ //bool bContained = m_nodeMBR.containsRegionInTime(ivT, n->m_nodeMBR);
+
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+
+ //if (! bContained)
+ //{
+ // update the MBR at the current time anyway, to make tighter.
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+ //}
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, *(m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ m_pTree->writeNode(this);
+
+ if (/*! bContained && */ ! pathBuffer.empty())
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
+
+void Index::adjustTree(Node* n1, Node* n2, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ ++(m_pTree->m_stats.m_adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n1->m_identifier) break;
+ }
+ assert(child < m_children);
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ //Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+ //bool bContained = m_nodeMBR.containsRegionInTime(ivT, n1->m_nodeMBR);
+
+ *(m_ptrMBR[child]) = n1->m_nodeMBR;
+
+ //if (! bContaied)
+ //{
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+ //}
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, *(m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ // No write necessary here. insertData will write the node if needed.
+ //m_pTree->writeNode(this);
+
+ bool bAdjusted = insertData(0, 0, n2->m_nodeMBR, n2->m_identifier, pathBuffer, overflowTable);
+
+ // if n2 is contained in the node and there was no split or reinsert,
+ // we need to adjust only if recalculation took place.
+ // In all other cases insertData above took care of adjustment.
+ if (! bAdjusted && ! pathBuffer.empty())
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.h.svn-base
new file mode 100644
index 000000000..68ca1f51f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Index.h.svn-base
@@ -0,0 +1,73 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class Index : public Node
+ {
+ public:
+ virtual ~Index();
+
+ private:
+ Index(TPRTree* pTree, id_type id, uint32_t level);
+
+ virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ uint32_t findLeastEnlargement(const MovingRegion&) const;
+ uint32_t findLeastOverlap(const MovingRegion&) const;
+
+ void adjustTree(Node*, std::stack<id_type>&);
+ void adjustTree(Node*, Node*, std::stack<id_type>&, byte* overflowTable);
+
+ class OverlapEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_enlargement;
+ MovingRegionPtr m_original;
+ MovingRegionPtr m_combined;
+ double m_oa;
+ double m_ca;
+
+ static int compareEntries(const void* pv1, const void* pv2)
+ {
+ OverlapEntry* pe1 = * (OverlapEntry**) pv1;
+ OverlapEntry* pe2 = * (OverlapEntry**) pv2;
+
+ if (pe1->m_enlargement < pe2->m_enlargement) return -1;
+ if (pe1->m_enlargement > pe2->m_enlargement) return 1;
+ return 0;
+ }
+ }; // OverlapEntry
+
+ friend class TPRTree;
+ friend class Node;
+ friend class BulkLoader;
+ }; // Index
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.cc.svn-base
new file mode 100644
index 000000000..a9db9df2c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.cc.svn-base
@@ -0,0 +1,135 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "TPRTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::TPRTree;
+
+Leaf::~Leaf()
+{
+}
+
+Leaf::Leaf(SpatialIndex::TPRTree::TPRTree* pTree, id_type id)
+ : Node(pTree, id, 0, pTree->m_leafCapacity)
+{
+}
+
+NodePtr Leaf::chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer)
+{
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ return NodePtr(this, &(m_pTree->m_leafPool));
+}
+
+NodePtr Leaf::findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ if (m_pIdentifier[cChild] == id /*&& mbr == *(m_ptrMBR[cChild])*/) return NodePtr(this, &(m_pTree->m_leafPool));
+ }
+
+ return NodePtr();
+}
+
+void Leaf::split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
+{
+ ++(m_pTree->m_stats.m_splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case TPRV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_leafPool.acquire();
+ pRight = m_pTree->m_leafPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g1[cIndex]] = 0;
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g2[cIndex]] = 0;
+ }
+}
+
+void Leaf::deleteData(id_type id, std::stack<id_type>& pathBuffer)
+{
+ uint32_t child;
+
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == id) break;
+ }
+
+ deleteEntry(child);
+ m_pTree->writeNode(this);
+
+ std::stack<NodePtr> toReinsert;
+ NodePtr ptrThis(this, &(m_pTree->m_leafPool));
+ condenseTree(toReinsert, pathBuffer, ptrThis);
+ ptrThis.relinquish();
+
+ // re-insert eliminated nodes.
+ while (! toReinsert.empty())
+ {
+ NodePtr n = toReinsert.top(); toReinsert.pop();
+ m_pTree->deleteNode(n.get());
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ // keep this in the for loop. The tree height might change after insertions.
+ byte* overflowTable = new byte[m_pTree->m_stats.m_treeHeight];
+ bzero(overflowTable, m_pTree->m_stats.m_treeHeight);
+ m_pTree->insertData_impl(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild], n->m_level, overflowTable);
+ n->m_pData[cChild] = 0;
+ delete[] overflowTable;
+ }
+ if (n.get() == this) n.relinquish();
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.h.svn-base
new file mode 100644
index 000000000..01a0bd53c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Leaf.h.svn-base
@@ -0,0 +1,47 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class Leaf : public Node
+ {
+ public:
+ virtual ~Leaf();
+
+ private:
+ Leaf(TPRTree* pTree, id_type id);
+
+ virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ virtual void deleteData(id_type id, std::stack<id_type>& pathBuffer);
+
+ friend class TPRTree;
+ friend class BulkLoader;
+ }; // Leaf
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Makefile.am.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Makefile.am.svn-base
new file mode 100644
index 000000000..6f6a87aa2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Makefile.am.svn-base
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libtprtree.la
+INCLUDES = -I../../include
+libtprtree_la_SOURCES = Index.cc Leaf.cc Node.cc TPRTree.cc Statistics.cc Leaf.h Index.h Node.h PointerPoolNode.h Statistics.h TPRTree.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.cc.svn-base
new file mode 100644
index 000000000..1c14b99c2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.cc.svn-base
@@ -0,0 +1,1253 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "TPRTree.h"
+#include "Node.h"
+#include "Index.h"
+
+using namespace SpatialIndex::TPRTree;
+
+//
+// Tools::IObject interface
+//
+Tools::IObject* Node::clone()
+{
+ throw Tools::NotSupportedException("IObject::clone should never be called.");
+}
+
+//
+// Tools::ISerializable interface
+//
+uint32_t Node::getByteArraySize()
+{
+ return
+ (sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(double) +
+ (m_children * (4 * m_pTree->m_dimension * sizeof(double) + sizeof(double) + sizeof(id_type) + sizeof(uint32_t))) +
+ m_totalDataLength +
+ (4 * m_pTree->m_dimension * sizeof(double)));
+}
+
+void Node::loadFromByteArray(const byte* ptr)
+{
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ // skip the node type information, it is not needed.
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_level, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_children, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&(m_nodeMBR.m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ //memcpy(&(m_nodeMBR.m_endTime), ptr, sizeof(double));
+ //ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_ptrMBR[cChild] = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->makeDimension(m_pTree->m_dimension);
+
+ memcpy(m_ptrMBR[cChild]->m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pVLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pVHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(&(m_ptrMBR[cChild]->m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ m_ptrMBR[cChild]->m_endTime = std::numeric_limits<double>::max();
+
+ memcpy(&(m_pIdentifier[cChild]), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(&(m_pDataLength[cChild]), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ m_totalDataLength += m_pDataLength[cChild];
+ m_pData[cChild] = new byte[m_pDataLength[cChild]];
+ memcpy(m_pData[cChild], ptr, m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ else
+ {
+ m_pData[cChild] = 0;
+ }
+
+ //m_nodeMBR.combineRegion(*(m_ptrMBR[cChild]));
+ }
+
+ memcpy(m_nodeMBR.m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pVLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pVHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+void Node::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ uint32_t nodeType;
+
+ if (m_level == 0) nodeType = PersistentLeaf;
+ else nodeType = PersistentIndex;
+
+ memcpy(ptr, &nodeType, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_level, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_children, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &(m_nodeMBR.m_startTime), sizeof(double));
+ ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ memcpy(ptr, m_ptrMBR[cChild]->m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pVLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pVHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, &(m_ptrMBR[cChild]->m_startTime), sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, &(m_pIdentifier[cChild]), sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(ptr, &(m_pDataLength[cChild]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ memcpy(ptr, m_pData[cChild], m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ }
+
+ // store the node MBR for efficiency. This increases the node size a little bit.
+ memcpy(ptr, m_nodeMBR.m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pVLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pVHigh, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+
+ assert(len == (ptr - *data) + m_pTree->m_dimension * sizeof(double));
+}
+
+//
+// SpatialIndex::IEntry interface
+//
+id_type Node::getIdentifier() const
+{
+ return m_identifier;
+}
+
+void Node::getShape(IShape** out) const
+{
+ *out = new MovingRegion(m_nodeMBR);
+}
+
+//
+// SpatialIndex::INode interface
+//
+uint32_t Node::getChildrenCount() const
+{
+ return m_children;
+}
+
+id_type Node::getChildIdentifier(uint32_t index) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pIdentifier[index];
+}
+
+void Node::getChildShape(uint32_t index, IShape** out) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ *out = new MovingRegion(*(m_ptrMBR[index]));
+}
+
+void Node::getChildData(uint32_t index, uint32_t& length, byte** data) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+ if (m_pData[index] == NULL)
+ {
+ length = 0;
+ data = NULL;
+ }
+ else
+ {
+ length = m_pDataLength[index];
+ *data = m_pData[index];
+ }
+}
+
+uint32_t Node::getLevel() const
+{
+ return m_level;
+}
+
+bool Node::isLeaf() const
+{
+ return (m_level == 0);
+}
+
+bool Node::isIndex() const
+{
+ return (m_level != 0);
+}
+
+//
+// Internal
+//
+
+Node::Node() :
+ m_pTree(0),
+ m_level(0),
+ m_identifier(-1),
+ m_children(0),
+ m_capacity(0),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+}
+
+Node::Node(SpatialIndex::TPRTree::TPRTree* pTree, id_type id, uint32_t level, uint32_t capacity) :
+ m_pTree(pTree),
+ m_level(level),
+ m_identifier(id),
+ m_children(0),
+ m_capacity(capacity),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+ m_nodeMBR.makeInfinite(m_pTree->m_dimension);
+
+ try
+ {
+ m_pDataLength = new uint32_t[m_capacity + 1];
+ m_pData = new byte*[m_capacity + 1];
+ m_ptrMBR = new MovingRegionPtr[m_capacity + 1];
+ m_pIdentifier = new id_type[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+ throw;
+ }
+}
+
+Node::~Node()
+{
+ if (m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_pData[cChild] != 0) delete[] m_pData[cChild];
+ }
+
+ delete[] m_pData;
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+}
+
+Node& Node::operator=(const Node& n)
+{
+ throw Tools::IllegalStateException("Node::operator =: This should never be called.");
+}
+
+bool Node::insertEntry(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id)
+{
+ assert(m_children < m_capacity);
+
+ bool bAdjusted = false;
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ m_totalDataLength += dataLength;
+ ++m_children;
+
+ if (m_nodeMBR.m_startTime != m_pTree->m_currentTime)
+ {
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ bAdjusted = true;
+ }
+ else if (
+ //m_nodeMBR.m_pLow[0] != std::numeric_limits<double>::max() &&
+ ! m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, mbr))
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ double l = m_nodeMBR.getExtrapolatedLow(cDim, m_pTree->m_currentTime);
+ double rl = mbr.getExtrapolatedLow(cDim, m_pTree->m_currentTime);
+ if (rl <= l)
+ {
+ m_nodeMBR.m_pLow[cDim] = rl - 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ double h = m_nodeMBR.getExtrapolatedHigh(cDim, m_pTree->m_currentTime);
+ double rh = mbr.getExtrapolatedHigh(cDim, m_pTree->m_currentTime);
+ if (rh >= h)
+ {
+ m_nodeMBR.m_pHigh[cDim] = rh + 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], mbr.m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], mbr.m_pVHigh[cDim]);
+ }
+
+ bAdjusted = true;
+ }
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_nodeMBR.m_startTime, *(m_ptrMBR[cChild])));
+ }
+#endif
+
+ return true;
+}
+
+void Node::deleteEntry(uint32_t index)
+{
+ assert(index >= 0 && index < m_children);
+
+ // cache it, since I might need it for "touches" later.
+ MovingRegionPtr ptrR = m_ptrMBR[index];
+
+ m_totalDataLength -= m_pDataLength[index];
+ if (m_pData[index] != 0) delete[] m_pData[index];
+
+ if (m_children > 1 && index != m_children - 1)
+ {
+ m_pDataLength[index] = m_pDataLength[m_children - 1];
+ m_pData[index] = m_pData[m_children - 1];
+ m_ptrMBR[index] = m_ptrMBR[m_children - 1];
+ m_pIdentifier[index] = m_pIdentifier[m_children - 1];
+ }
+
+ --m_children;
+
+ // WARNING: index has now changed. Do not use it below here.
+
+ if (m_children == 0)
+ {
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ else //if (m_pTree->m_bTightMBRs && m_nodeMBR.touchesRegion(*ptrR))
+ {
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, *(m_ptrMBR[cChild])) == true);
+ }
+#endif
+ }
+}
+
+bool Node::insertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ if (m_children < m_capacity)
+ {
+ bool bNeedToAdjust = insertEntry(dataLength, pData, mbr, id);
+ m_pTree->writeNode(this);
+
+ if (bNeedToAdjust && ! pathBuffer.empty())
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+
+ return bNeedToAdjust;
+ }
+ else if (false && m_pTree->m_treeVariant == TPRV_RSTAR && ! pathBuffer.empty() && overflowTable[m_level] == 0)
+ {
+ overflowTable[m_level] = 1;
+
+ std::vector<uint32_t> vReinsert, vKeep;
+ reinsertData(dataLength, pData, mbr, id, vReinsert, vKeep);
+
+ uint32_t lReinsert = static_cast<uint32_t>(vReinsert.size());
+ uint32_t lKeep = static_cast<uint32_t>(vKeep.size());
+
+ byte** reinsertdata = 0;
+ MovingRegionPtr* reinsertmbr = 0;
+ id_type* reinsertid = 0;
+ uint32_t* reinsertlen = 0;
+ byte** keepdata = 0;
+ MovingRegionPtr* keepmbr = 0;
+ id_type* keepid = 0;
+ uint32_t* keeplen = 0;
+
+ try
+ {
+ reinsertdata = new byte*[lReinsert];
+ reinsertmbr = new MovingRegionPtr[lReinsert];
+ reinsertid = new id_type[lReinsert];
+ reinsertlen = new uint32_t[lReinsert];
+
+ keepdata = new byte*[m_capacity + 1];
+ keepmbr = new MovingRegionPtr[m_capacity + 1];
+ keepid = new id_type[m_capacity + 1];
+ keeplen = new uint32_t[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+ delete[] keepdata;
+ delete[] keepmbr;
+ delete[] keepid;
+ delete[] keeplen;
+ throw;
+ }
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ reinsertlen[cIndex] = m_pDataLength[vReinsert[cIndex]];
+ reinsertdata[cIndex] = m_pData[vReinsert[cIndex]];
+ reinsertmbr[cIndex] = m_ptrMBR[vReinsert[cIndex]];
+ reinsertid[cIndex] = m_pIdentifier[vReinsert[cIndex]];
+ }
+
+ for (cIndex = 0; cIndex < lKeep; ++cIndex)
+ {
+ keeplen[cIndex] = m_pDataLength[vKeep[cIndex]];
+ keepdata[cIndex] = m_pData[vKeep[cIndex]];
+ keepmbr[cIndex] = m_ptrMBR[vKeep[cIndex]];
+ keepid[cIndex] = m_pIdentifier[vKeep[cIndex]];
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+
+ m_pDataLength = keeplen;
+ m_pData = keepdata;
+ m_ptrMBR = keepmbr;
+ m_pIdentifier = keepid;
+ m_children = lKeep;
+ m_totalDataLength = 0;
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild) m_totalDataLength += m_pDataLength[cChild];
+
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_nodeMBR.m_startTime, *(m_ptrMBR[cChild])));
+ }
+#endif
+
+ m_pTree->writeNode(this);
+
+ // Divertion from R*-Tree algorithm here. First adjust
+ // the path to the root, then start reinserts, to avoid complicated handling
+ // of changes to the same node from multiple insertions.
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ m_pTree->insertData_impl(
+ reinsertlen[cIndex], reinsertdata[cIndex],
+ *(reinsertmbr[cIndex]), reinsertid[cIndex],
+ m_level, overflowTable);
+ }
+
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+
+ return true;
+ }
+ else
+ {
+ NodePtr n;
+ NodePtr nn;
+ split(dataLength, pData, mbr, id, n, nn);
+
+ if (pathBuffer.empty())
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ assert(n->m_nodeMBR.containsRegionAfterTime(n->m_nodeMBR.m_startTime, *(n->m_ptrMBR[cChild])) == true);
+ }
+ for (uint32_t cChild = 0; cChild < nn->m_children; ++cChild)
+ {
+ assert(nn->m_nodeMBR.containsRegionAfterTime(nn->m_nodeMBR.m_startTime, *(nn->m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ NodePtr ptrR = m_pTree->m_indexPool.acquire();
+ if (ptrR.get() == 0)
+ {
+ ptrR = NodePtr(new Index(m_pTree, m_pTree->m_rootID, m_level + 1), &(m_pTree->m_indexPool));
+ }
+ else
+ {
+ //ptrR->m_pTree = m_pTree;
+ ptrR->m_identifier = m_pTree->m_rootID;
+ ptrR->m_level = m_level + 1;
+ ptrR->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+
+ ptrR->insertEntry(0, 0, n->m_nodeMBR, n->m_identifier);
+ ptrR->insertEntry(0, 0, nn->m_nodeMBR, nn->m_identifier);
+
+ m_pTree->writeNode(ptrR.get());
+
+ m_pTree->m_stats.m_nodesInLevel[m_level] = 2;
+ m_pTree->m_stats.m_nodesInLevel.push_back(1);
+ m_pTree->m_stats.m_treeHeight = m_level + 2;
+ }
+ else
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = m_identifier;
+ nn->m_identifier = -1;
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ assert(n->m_nodeMBR.containsRegionAfterTime(n->m_nodeMBR.m_startTime, *(n->m_ptrMBR[cChild])) == true);
+ }
+ for (uint32_t cChild = 0; cChild < nn->m_children; ++cChild)
+ {
+ assert(nn->m_nodeMBR.containsRegionAfterTime(nn->m_nodeMBR.m_startTime, *(nn->m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(n.get(), nn.get(), pathBuffer, overflowTable);
+ }
+
+ return true;
+ }
+}
+
+void Node::reinsertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep)
+{
+ ReinsertEntry** v = new ReinsertEntry*[m_capacity + 1];
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ for (uint32_t cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ try
+ {
+ v[cChild] = new ReinsertEntry(cChild, 0.0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete v[i];
+ delete[] v;
+ throw;
+ }
+
+ v[cChild]->m_dist = m_nodeMBR.getCenterDistanceInTime(ivT, *(m_ptrMBR[cChild]));
+ }
+
+ // sort by increasing order of distances.
+ ::qsort(v, m_capacity + 1, sizeof(ReinsertEntry*), ReinsertEntry::compareReinsertEntry);
+
+ uint32_t cReinsert = static_cast<uint32_t>(std::floor((m_capacity + 1) * m_pTree->m_reinsertFactor));
+
+ uint32_t cCount;
+
+ for (cCount = 0; cCount < cReinsert; ++cCount)
+ {
+ reinsert.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ for (cCount = cReinsert; cCount < m_capacity + 1; ++cCount)
+ {
+ keep.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ delete[] v;
+}
+
+/*
+void Node::rtreeSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ uint32_t cChild;
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ // use this mask array for marking visited entries.
+ byte* mask = new byte[m_capacity + 1];
+ bzero(mask, m_capacity + 1);
+
+ // insert new data in the node for easier manipulation. Data arrays are always
+ // by one larger than node capacity.
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+
+ // initialize each group with the seed entries.
+ uint32_t seed1, seed2;
+ pickSeeds(seed1, seed2);
+
+ group1.push_back(seed1);
+ group2.push_back(seed2);
+
+ mask[seed1] = 1;
+ mask[seed2] = 1;
+
+ // find MBR of each group.
+ RegionPtr mbr1 = m_pTree->m_regionPool.acquire();
+ *mbr1 = *(m_ptrMBR[seed1]);
+ RegionPtr mbr2 = m_pTree->m_regionPool.acquire();
+ *mbr2 = *(m_ptrMBR[seed2]);
+
+ // count how many entries are left unchecked (exclude the seeds here.)
+ uint32_t cRemaining = m_capacity + 1 - 2;
+
+ while (cRemaining > 0)
+ {
+ if (minimumLoad - group1.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group1 to comply with minimun load requirement.
+ for (cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group1.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else if (minimumLoad - group2.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group2 to comply with minimun load requirement.
+ for (cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group2.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else
+ {
+ // For all remaining entries compute the difference of the cost of grouping an
+ // entry in either group. When done, choose the entry that yielded the maximum
+ // difference. In case of linear split, select any entry (e.g. the first one.)
+ uint32_t sel;
+ double md1 = 0.0, md2 = 0.0;
+ double m = -std::numeric_limits<double>::max();
+ double d1, d2, d;
+ double a1 = mbr1->getArea();
+ double a2 = mbr2->getArea();
+
+ RegionPtr a = m_pTree->m_regionPool.acquire();
+ RegionPtr b = m_pTree->m_regionPool.acquire();
+
+ for (cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ mbr1->getCombinedRegion(*a, *(m_ptrMBR[cChild]));
+ d1 = a->getArea() - a1;
+ mbr2->getCombinedRegion(*b, *(m_ptrMBR[cChild]));
+ d2 = b->getArea() - a2;
+ d = std::abs(d1 - d2);
+
+ if (d > m)
+ {
+ m = d;
+ md1 = d1; md2 = d2;
+ sel = cChild;
+ if (m_pTree->m_treeVariant== RV_LINEAR || m_pTree->m_treeVariant == RV_RSTAR) break;
+ }
+ }
+ }
+
+ // determine the group where we should add the new entry.
+ int32_t group = -1;
+
+ if (md1 < md2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (md2 < md1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (a1 < a2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (a2 < a1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (group1.size() < group2.size())
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (group2.size() < group1.size())
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ mask[sel] = 1;
+ --cRemaining;
+ if (group == 1)
+ {
+ mbr1->combineRegion(*(m_ptrMBR[sel]));
+ }
+ else
+ {
+ mbr2->combineRegion(*(m_ptrMBR[sel]));
+ }
+ }
+ }
+
+ delete[] mask;
+}
+*/
+
+void Node::rstarSplit(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ RstarSplitEntry** dataLow = 0;
+ RstarSplitEntry** dataHigh = 0;
+ RstarSplitEntry** dataVLow = 0;
+ RstarSplitEntry** dataVHigh = 0;
+
+ try
+ {
+ dataLow = new RstarSplitEntry*[m_capacity + 1];
+ dataHigh = new RstarSplitEntry*[m_capacity + 1];
+ dataVLow = new RstarSplitEntry*[m_capacity + 1];
+ dataVHigh = new RstarSplitEntry*[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] dataLow;
+ delete[] dataHigh;
+ delete[] dataVLow;
+ delete[] dataVHigh;
+ throw;
+ }
+
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+
+ uint32_t nodeSPF = static_cast<uint32_t>(std::floor((m_capacity + 1) * m_pTree->m_splitDistributionFactor));
+ uint32_t splitDistribution = (m_capacity + 1) - (2 * nodeSPF) + 2;
+
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ uint32_t cChild = 0, cDim, cIndex;
+
+ for (cChild = 0; cChild <= m_capacity; ++cChild)
+ {
+ try
+ {
+ dataLow[cChild] = new RstarSplitEntry(m_ptrMBR[cChild].get(), cChild, 0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete dataLow[i];
+ delete[] dataLow;
+ delete[] dataHigh;
+ throw;
+ }
+
+ dataHigh[cChild] = dataLow[cChild];
+ dataVLow[cChild] = dataLow[cChild];
+ dataVHigh[cChild] = dataLow[cChild];
+ }
+
+ double minimumMargin = std::numeric_limits<double>::max();
+ uint32_t splitAxis = std::numeric_limits<uint32_t>::max();
+ uint32_t sortOrder = std::numeric_limits<uint32_t>::max();
+
+ // chooseSplitAxis.
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareLow);
+ ::qsort(dataHigh, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareHigh);
+ ::qsort(dataVLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVLow);
+ ::qsort(dataVHigh, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVHigh);
+
+ // calculate sum of margins and overlap for all distributions.
+ double marginl = 0.0;
+ double marginh = 0.0;
+ double marginvl = 0.0;
+ double marginvh = 0.0;
+
+ MovingRegion bbl1, bbl2, bbh1, bbh2;
+ MovingRegion bbvl1, bbvl2, bbvh1, bbvh2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bbl1 = *(dataLow[0]->m_pRegion);
+ bbh1 = *(dataHigh[0]->m_pRegion);
+ bbvl1 = *(dataVLow[0]->m_pRegion);
+ bbvh1 = *(dataVHigh[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bbl1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ bbh1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataHigh[cIndex]->m_pRegion));
+ bbvl1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVLow[cIndex]->m_pRegion));
+ bbvh1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVHigh[cIndex]->m_pRegion));
+ }
+
+ bbl2 = *(dataLow[l]->m_pRegion);
+ bbh2 = *(dataHigh[l]->m_pRegion);
+ bbvl2 = *(dataVLow[l]->m_pRegion);
+ bbvh2 = *(dataVHigh[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bbl2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ bbh2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataHigh[cIndex]->m_pRegion));
+ bbvl2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVLow[cIndex]->m_pRegion));
+ bbvh2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVHigh[cIndex]->m_pRegion));
+ }
+
+ marginl += bbl1.getProjectedSurfaceAreaInTime(ivT) + bbl2.getProjectedSurfaceAreaInTime(ivT);
+ marginh += bbh1.getProjectedSurfaceAreaInTime(ivT) + bbh2.getProjectedSurfaceAreaInTime(ivT);
+ marginvl += bbvl1.getProjectedSurfaceAreaInTime(ivT) + bbvl2.getProjectedSurfaceAreaInTime(ivT);
+ marginvh += bbvh1.getProjectedSurfaceAreaInTime(ivT) + bbvh2.getProjectedSurfaceAreaInTime(ivT);
+ } // for (cChild)
+
+ double margin = std::min(std::min(marginl, marginh), std::min(marginvl, marginvh));
+
+ // keep minimum margin as split axis.
+ if (margin < minimumMargin)
+ {
+ minimumMargin = margin;
+ splitAxis = cDim;
+ if (marginl < marginh && marginl < marginvl && marginl < marginvh) sortOrder = 0;
+ else if (marginh < marginl && marginh < marginvl && marginh < marginvh) sortOrder = 1;
+ else if (marginvl < marginl && marginvl < marginh && marginvl < marginvh) sortOrder = 2;
+ else if (marginvh < marginl && marginvh < marginh && marginvh < marginvl) sortOrder = 3;
+ }
+
+ // increase the dimension according to which the data entries should be sorted.
+ for (cChild = 0; cChild <= m_capacity; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = cDim + 1;
+ }
+ } // for (cDim)
+
+ for (cChild = 0; cChild <= m_capacity; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = splitAxis;
+ }
+
+ if (sortOrder == 0)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareLow);
+ else if (sortOrder == 1)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareHigh);
+ else if (sortOrder == 2)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVLow);
+ else if (sortOrder == 3)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVHigh);
+
+ double ma = std::numeric_limits<double>::max();
+ double mo = std::numeric_limits<double>::max();
+ uint32_t splitPoint = std::numeric_limits<uint32_t>::max();
+
+ MovingRegion bb1, bb2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bb1 = *(dataLow[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bb1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ }
+
+ bb2 = *(dataLow[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bb2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ }
+
+ double o = bb1.getIntersectingAreaInTime(ivT, bb2);
+
+ if (o < mo)
+ {
+ splitPoint = cChild;
+ mo = o;
+ ma = bb1.getAreaInTime(ivT) + bb2.getAreaInTime(ivT);
+ }
+ else if (o == mo)
+ {
+ double a = bb1.getAreaInTime(ivT) + bb2.getAreaInTime(ivT);
+
+ if (a < ma)
+ {
+ splitPoint = cChild;
+ ma = a;
+ }
+ }
+ } // for (cChild)
+
+ uint32_t l1 = nodeSPF - 1 + splitPoint;
+
+ for (cIndex = 0; cIndex < l1; ++cIndex)
+ {
+ group1.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ for (cIndex = l1; cIndex <= m_capacity; ++cIndex)
+ {
+ group2.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ delete[] dataLow;
+ delete[] dataHigh;
+ delete[] dataVLow;
+ delete[] dataVHigh;
+}
+
+/*
+void Node::pickSeeds(uint32_t& index1, uint32_t& index2)
+{
+ double separation = -std::numeric_limits<double>::max();
+ double inefficiency = -std::numeric_limits<double>::max();
+ uint32_t cDim, cChild, cIndex;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_RSTAR:
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ double leastLower = m_ptrMBR[0]->m_pLow[cDim];
+ double greatestUpper = m_ptrMBR[0]->m_pHigh[cDim];
+ uint32_t greatestLower = 0;
+ uint32_t leastUpper = 0;
+ double width;
+
+ for (cChild = 1; cChild <= m_capacity; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->m_pLow[cDim] > m_ptrMBR[greatestLower]->m_pLow[cDim]) greatestLower = cChild;
+ if (m_ptrMBR[cChild]->m_pHigh[cDim] < m_ptrMBR[leastUpper]->m_pHigh[cDim]) leastUpper = cChild;
+
+ leastLower = std::min(m_ptrMBR[cChild]->m_pLow[cDim], leastLower);
+ greatestUpper = std::max(m_ptrMBR[cChild]->m_pHigh[cDim], greatestUpper);
+ }
+
+ width = greatestUpper - leastLower;
+ if (width <= 0) width = 1;
+
+ double f = (m_ptrMBR[greatestLower]->m_pLow[cDim] - m_ptrMBR[leastUpper]->m_pHigh[cDim]) / width;
+
+ if (f > separation)
+ {
+ index1 = leastUpper;
+ index2 = greatestLower;
+ separation = f;
+ }
+ } // for (cDim)
+
+ if (index1 == index2)
+ {
+ if (index2 == 0) ++index2;
+ else --index2;
+ }
+
+ break;
+ case RV_QUADRATIC:
+ // for each pair of Regions (account for overflow Region too!)
+ for (cChild = 0; cChild < m_capacity; ++cChild)
+ {
+ double a = m_ptrMBR[cChild]->getArea();
+
+ for (cIndex = cChild + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ // get the combined MBR of those two entries.
+ Region r;
+ m_ptrMBR[cChild]->getCombinedRegion(r, *(m_ptrMBR[cIndex]));
+
+ // find the inefficiency of grouping these entries together.
+ double d = r.getArea() - a - m_ptrMBR[cIndex]->getArea();
+
+ if (d > inefficiency)
+ {
+ inefficiency = d;
+ index1 = cChild;
+ index2 = cIndex;
+ }
+ } // for (cIndex)
+ } // for (cChild)
+
+ break;
+ default:
+ throw Tools::NotSupportedException("Node::pickSeeds: Tree variant not supported.");
+ }
+}
+*/
+
+void Node::condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis)
+{
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ if (pathBuffer.empty())
+ {
+ // eliminate root if it has only one child.
+ if (m_level != 0 && m_children == 1)
+ {
+ NodePtr ptrN = m_pTree->readNode(m_pIdentifier[0]);
+ m_pTree->deleteNode(ptrN.get());
+ ptrN->m_identifier = m_pTree->m_rootID;
+ m_pTree->writeNode(ptrN.get());
+
+ m_pTree->m_stats.m_nodesInLevel.pop_back();
+ m_pTree->m_stats.m_treeHeight -= 1;
+ // HACK: pending deleteNode for deleted child will decrease nodesInLevel, later on.
+ m_pTree->m_stats.m_nodesInLevel[m_pTree->m_stats.m_treeHeight - 1] = 2;
+ }
+ }
+ else
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrParent = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrParent.get());
+
+ // find the entry in the parent, that points to this node.
+ uint32_t child;
+
+ for (child = 0; child != p->m_children; ++child)
+ {
+ if (p->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ if (m_children < minimumLoad)
+ {
+ // used space less than the minimum
+ // 1. eliminate node entry from the parent. deleteEntry will fix the parent's MBR.
+ p->deleteEntry(child);
+ // 2. add this node to the stack in order to reinsert its entries.
+ toReinsert.push(ptrThis);
+ }
+ else
+ {
+ // adjust the entry in 'p' to contain the new bounding region of this node.
+ *(p->m_ptrMBR[child]) = m_nodeMBR;
+
+ // global recalculation necessary since the MBR can only shrink in size,
+ // due to data removal.
+ //if (m_pTree->m_bTightMBRs)
+ //{
+
+ p->m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < p->m_nodeMBR.m_dimension; ++cDim)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::min(p->m_nodeMBR.m_pLow[cDim], p->m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_pTree->m_currentTime));
+ p->m_nodeMBR.m_pHigh[cDim] = std::max(p->m_nodeMBR.m_pHigh[cDim], p->m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_pTree->m_currentTime));
+ p->m_nodeMBR.m_pVLow[cDim] = std::min(p->m_nodeMBR.m_pVLow[cDim], p->m_ptrMBR[cChild]->m_pVLow[cDim]);
+ p->m_nodeMBR.m_pVHigh[cDim] = std::max(p->m_nodeMBR.m_pVHigh[cDim], p->m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ p->m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ p->m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+ //}
+ }
+
+ // write parent node back to storage.
+ m_pTree->writeNode(p);
+
+ p->condenseTree(toReinsert, pathBuffer, ptrParent);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.h.svn-base
new file mode 100644
index 000000000..6cf5d98a0
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Node.h.svn-base
@@ -0,0 +1,200 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class TPRTree;
+ class Leaf;
+ class Index;
+ class Node;
+
+ typedef Tools::PoolPointer<Node> NodePtr;
+
+ class Node : public SpatialIndex::INode
+ {
+ public:
+ virtual ~Node();
+
+ //
+ // Tools::IObject interface
+ //
+ virtual Tools::IObject* clone();
+
+ //
+ // Tools::ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // SpatialIndex::IEntry interface
+ //
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+
+ //
+ // SpatialIndex::INode interface
+ //
+ virtual uint32_t getChildrenCount() const;
+ virtual id_type getChildIdentifier(uint32_t index) const;
+ virtual void getChildShape(uint32_t index, IShape** out) const;
+ virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
+ virtual uint32_t getLevel() const;
+ virtual bool isIndex() const;
+ virtual bool isLeaf() const;
+
+ private:
+ Node();
+ Node(TPRTree* pTree, id_type id, uint32_t level, uint32_t capacity);
+
+ virtual Node& operator=(const Node&);
+
+ virtual bool insertEntry(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id);
+ virtual void deleteEntry(uint32_t index);
+
+ virtual bool insertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable);
+ virtual void reinsertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep);
+
+ virtual void rstarSplit(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
+
+ virtual void condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis);
+
+ virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
+
+ virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right) = 0;
+
+ TPRTree* m_pTree;
+ // Parent of all nodes.
+
+ uint32_t m_level;
+ // The level of the node in the tree.
+ // Leaves are always at level 0.
+
+ id_type m_identifier;
+ // The unique ID of this node.
+
+ uint32_t m_children;
+ // The number of children pointed by this node.
+
+ uint32_t m_capacity;
+ // Specifies the node capacity.
+
+ MovingRegion m_nodeMBR;
+ // The minimum bounding region enclosing all data contained in the node.
+
+ byte** m_pData;
+ // The data stored in the node.
+
+ MovingRegionPtr* m_ptrMBR;
+ // The corresponding data MBRs.
+
+ id_type* m_pIdentifier;
+ // The corresponding data identifiers.
+
+ uint32_t* m_pDataLength;
+
+ uint32_t m_totalDataLength;
+
+ class RstarSplitEntry
+ {
+ public:
+ MovingRegion* m_pRegion;
+ uint32_t m_index;
+ uint32_t m_sortDim;
+
+ RstarSplitEntry(MovingRegion* pr, uint32_t index, uint32_t dimension)
+ : m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
+
+ static int compareLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareVLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pVLow[pe1->m_sortDim] < pe2->m_pRegion->m_pVLow[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pVLow[pe1->m_sortDim] > pe2->m_pRegion->m_pVLow[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareVHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pVHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pVHigh[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pVHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pVHigh[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+ }; // RstarSplitEntry
+
+ class ReinsertEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_dist;
+
+ ReinsertEntry(uint32_t index, double dist) : m_index(index), m_dist(dist) {}
+
+ static int compareReinsertEntry(const void* pv1, const void* pv2)
+ {
+ ReinsertEntry* pe1 = * (ReinsertEntry**) pv1;
+ ReinsertEntry* pe2 = * (ReinsertEntry**) pv2;
+
+ if (pe1->m_dist < pe2->m_dist) return -1;
+ if (pe1->m_dist > pe2->m_dist) return 1;
+ return 0;
+ }
+ }; // ReinsertEntry
+
+ // Needed to access protected members without having to cast from Node.
+ // It is more efficient than using member functions to access protected members.
+ friend class TPRTree;
+ friend class Leaf;
+ friend class Index;
+ friend class Tools::PointerPool<Node>;
+ }; // Node
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/PointerPoolNode.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/PointerPoolNode.h.svn-base
new file mode 100644
index 000000000..8c026fbe3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/PointerPoolNode.h.svn-base
@@ -0,0 +1,133 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Node.h"
+
+namespace Tools
+{
+ template<> class PointerPool<TPRTree::Node>
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ TPRTree::Node* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<TPRTree::Node> acquire()
+ {
+ if (! m_pool.empty())
+ {
+ TPRTree::Node* p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ ++m_hits;
+ #endif
+
+ return PoolPointer<TPRTree::Node>(p, this);
+ }
+ #ifndef NDEBUG
+ else
+ {
+ // fixme: well sort of...
+ ++m_pointerCount;
+ ++m_misses;
+ }
+ #endif
+
+ return PoolPointer<TPRTree::Node>();
+ }
+
+ void release(TPRTree::Node* p)
+ {
+ if (p != 0)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ if (p->m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ if (p->m_pData[cChild] != 0) delete[] p->m_pData[cChild];
+ }
+ }
+
+ p->m_level = 0;
+ p->m_identifier = -1;
+ p->m_children = 0;
+ p->m_totalDataLength = 0;
+
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ protected:
+ uint32_t m_capacity;
+ std::stack<TPRTree::Node*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.cc.svn-base
new file mode 100644
index 000000000..d2031d4db
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.cc.svn-base
@@ -0,0 +1,171 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Statistics.h"
+
+using namespace SpatialIndex::TPRTree;
+
+Statistics::Statistics()
+{
+ reset();
+}
+
+Statistics::Statistics(const Statistics& s)
+{
+ m_reads = s.m_reads;
+ m_writes = s.m_writes;
+ m_splits = s.m_splits;
+ m_hits = s.m_hits;
+ m_misses = s.m_misses;
+ m_nodes = s.m_nodes;
+ m_adjustments = s.m_adjustments;
+ m_queryResults = s.m_queryResults;
+ m_data = s.m_data;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+}
+
+Statistics::~Statistics()
+{
+}
+
+Statistics& Statistics::operator=(const Statistics& s)
+{
+ if (this != &s)
+ {
+ m_reads = s.m_reads;
+ m_writes = s.m_writes;
+ m_splits = s.m_splits;
+ m_hits = s.m_hits;
+ m_misses = s.m_misses;
+ m_nodes = s.m_nodes;
+ m_adjustments = s.m_adjustments;
+ m_queryResults = s.m_queryResults;
+ m_data = s.m_data;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+ }
+
+ return *this;
+}
+
+uint64_t Statistics::getReads() const
+{
+ return m_reads;
+}
+
+uint64_t Statistics::getWrites() const
+{
+ return m_writes;
+}
+
+uint32_t Statistics::getNumberOfNodes() const
+{
+ return m_nodes;
+}
+
+uint64_t Statistics::getNumberOfData() const
+{
+ return m_data;
+}
+
+uint64_t Statistics::getSplits() const
+{
+ return m_splits;
+}
+
+uint64_t Statistics::getHits() const
+{
+ return m_hits;
+}
+
+uint64_t Statistics::getMisses() const
+{
+ return m_misses;
+}
+
+uint64_t Statistics::getAdjustments() const
+{
+ return m_adjustments;
+}
+
+uint64_t Statistics::getQueryResults() const
+{
+ return m_queryResults;
+}
+
+uint32_t Statistics::getTreeHeight() const
+{
+ return m_treeHeight;
+}
+
+uint32_t Statistics::getNumberOfNodesInLevel(uint32_t l) const
+{
+ uint32_t cNodes;
+ try
+ {
+ cNodes = m_nodesInLevel.at(l);
+ }
+ catch (...)
+ {
+ throw Tools::IndexOutOfBoundsException(l);
+ }
+
+ return cNodes;
+}
+
+void Statistics::reset()
+{
+ m_reads = 0;
+ m_writes = 0;
+ m_splits = 0;
+ m_hits = 0;
+ m_misses = 0;
+ m_nodes = 0;
+ m_adjustments = 0;
+ m_queryResults = 0;
+ m_data = 0;
+ m_treeHeight = 0;
+ m_nodesInLevel.clear();
+}
+
+std::ostream& SpatialIndex::TPRTree::operator<<(std::ostream& os, const Statistics& s)
+{
+ os << "Reads: " << s.m_reads << std::endl
+ << "Writes: " << s.m_writes << std::endl
+ << "Hits: " << s.m_hits << std::endl
+ << "Misses: " << s.m_misses << std::endl
+ << "Tree height: " << s.m_treeHeight << std::endl
+ << "Number of data: " << s.m_data << std::endl
+ << "Number of nodes: " << s.m_nodes << std::endl;
+
+ for (uint32_t cLevel = 0; cLevel < s.m_treeHeight; ++cLevel)
+ {
+ os << "Level " << cLevel << " pages: " << s.m_nodesInLevel[cLevel] << std::endl;
+ }
+
+ os << "Splits: " << s.m_splits << std::endl
+ << "Adjustments: " << s.m_adjustments << std::endl
+ << "Query results: " << s.m_queryResults << std::endl;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.h.svn-base
new file mode 100644
index 000000000..44b707c30
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/Statistics.h.svn-base
@@ -0,0 +1,93 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class TPRTree;
+ class Node;
+ class Leaf;
+ class Index;
+
+ class Statistics : public SpatialIndex::IStatistics
+ {
+ public:
+ Statistics();
+ Statistics(const Statistics&);
+ virtual ~Statistics();
+ Statistics& operator=(const Statistics&);
+
+ //
+ // IStatistics interface
+ //
+ virtual uint64_t getReads() const;
+ virtual uint64_t getWrites() const;
+ virtual uint32_t getNumberOfNodes() const;
+ virtual uint64_t getNumberOfData() const;
+
+ virtual uint64_t getSplits() const;
+ virtual uint64_t getHits() const;
+ virtual uint64_t getMisses() const;
+ virtual uint64_t getAdjustments() const;
+ virtual uint64_t getQueryResults() const;
+ virtual uint32_t getTreeHeight() const;
+ virtual uint32_t getNumberOfNodesInLevel(uint32_t l) const;
+
+ private:
+ void reset();
+
+ uint64_t m_reads;
+
+ uint64_t m_writes;
+
+ uint64_t m_splits;
+
+ uint64_t m_hits;
+
+ uint64_t m_misses;
+
+ uint32_t m_nodes;
+
+ uint64_t m_adjustments;
+
+ uint64_t m_queryResults;
+
+ uint64_t m_data;
+
+ uint32_t m_treeHeight;
+
+ std::vector<uint32_t> m_nodesInLevel;
+
+ friend class TPRTree;
+ friend class Node;
+ friend class Index;
+ friend class Leaf;
+ friend class BulkLoader;
+
+ friend std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }; // Statistics
+
+ std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.cc.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.cc.svn-base
new file mode 100644
index 000000000..16b8f9c54
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.cc.svn-base
@@ -0,0 +1,1352 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "TPRTree.h"
+
+#include <cstring>
+
+using namespace SpatialIndex::TPRTree;
+
+SpatialIndex::TPRTree::Data::Data(uint32_t len, byte* pData, MovingRegion& r, id_type id)
+ : m_id(id), m_region(r), m_pData(0), m_dataLength(len)
+{
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, pData, m_dataLength);
+ }
+}
+
+SpatialIndex::TPRTree::Data::~Data()
+{
+ delete[] m_pData;
+}
+
+SpatialIndex::TPRTree::Data* SpatialIndex::TPRTree::Data::clone()
+{
+ return new Data(m_dataLength, m_pData, m_region, m_id);
+}
+
+SpatialIndex::id_type SpatialIndex::TPRTree::Data::getIdentifier() const
+{
+ return m_id;
+}
+
+void SpatialIndex::TPRTree::Data::getShape(IShape** out) const
+{
+ *out = new MovingRegion(m_region);
+}
+
+void SpatialIndex::TPRTree::Data::getData(uint32_t& len, byte** data) const
+{
+ len = m_dataLength;
+ *data = 0;
+
+ if (m_dataLength > 0)
+ {
+ *data = new byte[m_dataLength];
+ memcpy(*data, m_pData, m_dataLength);
+ }
+}
+
+uint32_t SpatialIndex::TPRTree::Data::getByteArraySize()
+{
+ return
+ sizeof(id_type) +
+ sizeof(uint32_t) +
+ m_dataLength +
+ m_region.getByteArraySize();
+}
+
+void SpatialIndex::TPRTree::Data::loadFromByteArray(const byte* ptr)
+{
+ memcpy(&m_id, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ delete[] m_pData;
+ m_pData = 0;
+
+ memcpy(&m_dataLength, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, ptr, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ m_region.loadFromByteArray(ptr);
+}
+
+void SpatialIndex::TPRTree::Data::storeToByteArray(byte** data, uint32_t& len)
+{
+ // it is thread safe this way.
+ uint32_t regionsize;
+ byte* regiondata = 0;
+ m_region.storeToByteArray(&regiondata, regionsize);
+
+ len = sizeof(id_type) + sizeof(uint32_t) + m_dataLength + regionsize;
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_id, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_dataLength, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ memcpy(ptr, m_pData, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ memcpy(ptr, regiondata, regionsize);
+ delete[] regiondata;
+ // ptr += regionsize;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::TPRTree::returnTPRTree(SpatialIndex::IStorageManager& sm, Tools::PropertySet& ps)
+{
+ SpatialIndex::ISpatialIndex* si = new SpatialIndex::TPRTree::TPRTree(sm, ps);
+ return si;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::TPRTree::createNewTPRTree(
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ TPRTreeVariant rv,
+ double horizon,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = fillFactor;
+ ps.setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = horizon;
+ ps.setProperty("Horizon", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = indexCapacity;
+ ps.setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = leafCapacity;
+ ps.setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = dimension;
+ ps.setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = rv;
+ ps.setProperty("TreeVariant", var);
+
+ ISpatialIndex* ret = returnTPRTree(sm, ps);
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var = ps.getProperty("IndexIdentifier");
+ indexIdentifier = var.m_val.llVal;
+
+ return ret;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::TPRTree::loadTPRTree(IStorageManager& sm, id_type indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = indexIdentifier;
+ ps.setProperty("IndexIdentifier", var);
+
+ return returnTPRTree(sm, ps);
+}
+
+SpatialIndex::TPRTree::TPRTree::TPRTree(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_pStorageManager(&sm),
+ m_rootID(StorageManager::NewPage),
+ m_headerID(StorageManager::NewPage),
+ m_treeVariant(TPRV_RSTAR),
+ m_fillFactor(0.7),
+ m_indexCapacity(100),
+ m_leafCapacity(100),
+ m_nearMinimumOverlapFactor(32),
+ m_splitDistributionFactor(0.4),
+ m_reinsertFactor(0.3),
+ m_dimension(2),
+ m_bTightMBRs(true),
+ m_currentTime(0.0),
+ m_horizon(20.0),
+ m_pointPool(500),
+ m_regionPool(1000),
+ m_indexPool(100),
+ m_leafPool(100)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+
+ Tools::Variant var = ps.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType == Tools::VT_LONGLONG) m_headerID = var.m_val.llVal;
+ else if (var.m_varType == Tools::VT_LONG) m_headerID = var.m_val.lVal;
+ // for backward compatibility only.
+ else throw Tools::IllegalArgumentException("TPRTree: Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ initOld(ps);
+ }
+ else
+ {
+ initNew(ps);
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = m_headerID;
+ ps.setProperty("IndexIdentifier", var);
+ }
+}
+
+SpatialIndex::TPRTree::TPRTree::~TPRTree()
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_destroy(&m_rwLock);
+#endif
+
+ storeHeader();
+}
+
+//
+// ISpatialIndex interface
+//
+
+void SpatialIndex::TPRTree::TPRTree::insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+ const IEvolvingShape* es = dynamic_cast<const IEvolvingShape*>(&shape);
+ if (es == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IEvolvingShape interface.");
+ const Tools::IInterval *pivI = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (pivI == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IInterval interface.");
+
+ if (pivI->getLowerBound() < m_currentTime) throw Tools::IllegalArgumentException("insertData: Shape start time is older than tree current time.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("insertData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ Region mbr;
+ shape.getMBR(mbr);
+ Region vbr;
+ es->getVMBR(vbr);
+ assert(mbr.m_dimension == vbr.m_dimension);
+
+ MovingRegionPtr mr = m_regionPool.acquire();
+ mr->makeDimension(mbr.m_dimension);
+
+ memcpy(mr->m_pLow, mbr.m_pLow, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pHigh, mbr.m_pHigh, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVLow, vbr.m_pLow, vbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVHigh, vbr.m_pHigh, vbr.m_dimension * sizeof(double));
+ mr->m_startTime = pivI->getLowerBound();
+ mr->m_endTime = std::numeric_limits<double>::max();
+
+ byte* buffer = 0;
+
+ if (len > 0)
+ {
+ buffer = new byte[len];
+ memcpy(buffer, pData, len);
+ }
+
+ m_currentTime = mr->m_startTime;
+ insertData_impl(len, buffer, *mr, id);
+ // the buffer is stored in the tree. Do not delete here.
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+// shape.m_startTime should be the time when the object was inserted initially.
+// shape.m_endTime should be the time of the deletion (current time).
+bool SpatialIndex::TPRTree::TPRTree::deleteData(const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+ const IEvolvingShape* es = dynamic_cast<const IEvolvingShape*>(&shape);
+ if (es == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IEvolvingShape interface.");
+ const Tools::IInterval *pivI = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (pivI == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IInterval interface.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("deleteData cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ Region mbr;
+ shape.getMBR(mbr);
+ Region vbr;
+ es->getVMBR(vbr);
+ assert(mbr.m_dimension == vbr.m_dimension);
+
+ MovingRegionPtr mr = m_regionPool.acquire();
+ mr->makeDimension(mbr.m_dimension);
+
+ memcpy(mr->m_pLow, mbr.m_pLow, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pHigh, mbr.m_pHigh, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVLow, vbr.m_pLow, vbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVHigh, vbr.m_pHigh, vbr.m_dimension * sizeof(double));
+ mr->m_startTime = pivI->getLowerBound();
+ mr->m_endTime = std::numeric_limits<double>::max();
+
+ m_currentTime = pivI->getUpperBound();
+ bool ret = deleteData_impl(*mr, id);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ return ret;
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::containsWhatQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("containsWhatQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(ContainmentQuery, query, v);
+}
+
+void SpatialIndex::TPRTree::TPRTree::intersectsWithQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("intersectsWithQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(IntersectionQuery, query, v);
+}
+
+void SpatialIndex::TPRTree::TPRTree::pointLocationQuery(const Point& query, IVisitor& v)
+{
+ if (query.m_dimension != m_dimension) throw Tools::IllegalArgumentException("pointLocationQuery: Shape has the wrong number of dimensions.");
+ Region r(query, query);
+ rangeQuery(IntersectionQuery, r, v);
+}
+
+void SpatialIndex::TPRTree::TPRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc)
+{
+ throw Tools::IllegalStateException("nearestNeighborQuery: not impelmented yet.");
+}
+
+void SpatialIndex::TPRTree::TPRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+ NNComparator nnc;
+ nearestNeighborQuery(k, query, v, nnc);
+}
+
+void SpatialIndex::TPRTree::TPRTree::selfJoinQuery(const IShape& query, IVisitor& v)
+{
+ throw Tools::IllegalStateException("selfJoinQuery: not impelmented yet.");
+}
+
+void SpatialIndex::TPRTree::TPRTree::queryStrategy(IQueryStrategy& qs)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");
+#endif
+
+ id_type next = m_rootID;
+ bool hasNext = true;
+
+ try
+ {
+ while (hasNext)
+ {
+ NodePtr n = readNode(next);
+ qs.getNextEntry(*n, next, hasNext);
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::getIndexProperties(Tools::PropertySet& out) const
+{
+ Tools::Variant var;
+
+ // dimension
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_dimension;
+ out.setProperty("Dimension", var);
+
+ // index capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexCapacity;
+ out.setProperty("IndexCapacity", var);
+
+ // leaf capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafCapacity;
+ out.setProperty("LeafCapacity", var);
+
+ // Tree variant
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = m_treeVariant;
+ out.setProperty("TreeVariant", var);
+
+ // fill factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_fillFactor;
+ out.setProperty("FillFactor", var);
+
+ // horizon
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_horizon;
+ out.setProperty("Horizon", var);
+
+ // near minimum overlap factor
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_nearMinimumOverlapFactor;
+ out.setProperty("NearMinimumOverlapFactor", var);
+
+ // split distribution factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_splitDistributionFactor;
+ out.setProperty("SplitDistributionFactor", var);
+
+ // reinsert factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_reinsertFactor;
+ out.setProperty("ReinsertFactor", var);
+
+ // tight MBRs
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = m_bTightMBRs;
+ out.setProperty("EnsureTightMBRs", var);
+
+ // index pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexPool.getCapacity();
+ out.setProperty("IndexPoolCapacity", var);
+
+ // leaf pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafPool.getCapacity();
+ out.setProperty("LeafPoolCapacity", var);
+
+ // region pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_regionPool.getCapacity();
+ out.setProperty("RegionPoolCapacity", var);
+
+ // point pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_pointPool.getCapacity();
+ out.setProperty("PointPoolCapacity", var);
+}
+
+void SpatialIndex::TPRTree::TPRTree::addCommand(ICommand* pCommand, CommandType ct)
+{
+ switch (ct)
+ {
+ case CT_NODEREAD:
+ m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEWRITE:
+ m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEDELETE:
+ m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ }
+}
+
+bool SpatialIndex::TPRTree::TPRTree::isIndexValid()
+{
+ bool ret = true;
+
+ std::stack<ValidateEntry> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_level != m_stats.m_treeHeight - 1)
+ {
+ std::cerr << "Invalid tree height." << std::endl;
+ return false;
+ }
+
+ std::map<uint32_t, uint32_t> nodesInLevel;
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(root->m_level, 1));
+
+ ValidateEntry e(root->m_nodeMBR, root);
+ st.push(e);
+
+ while (! st.empty())
+ {
+ e = st.top(); st.pop();
+
+ MovingRegion tmpRegion;
+ tmpRegion = m_infiniteRegion;
+
+ // I have to rely on the parent information here, since none of the node's
+ // children might have a reference time equal to their parents (e.g., after
+ // a split).
+ tmpRegion.m_startTime = e.m_parentMBR.m_startTime;
+
+ for (uint32_t cDim = 0; cDim < tmpRegion.m_dimension; ++cDim)
+ {
+ tmpRegion.m_pLow[cDim] = std::numeric_limits<double>::max();
+ tmpRegion.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ tmpRegion.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ tmpRegion.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->getExtrapolatedLow(cDim, tmpRegion.m_startTime));
+ tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, tmpRegion.m_startTime));
+ tmpRegion.m_pVLow[cDim] = std::min(tmpRegion.m_pVLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pVLow[cDim]);
+ tmpRegion.m_pVHigh[cDim] = std::max(tmpRegion.m_pVHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ tmpRegion.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ tmpRegion.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ if (! (tmpRegion == e.m_pNode->m_nodeMBR))
+ {
+ std::cerr << "Invalid parent information." << std::endl;
+ ret = false;
+ }
+ if (! (tmpRegion == e.m_parentMBR))
+ {
+ std::cerr << "Error in parent." << std::endl;
+ ret = false;
+ }
+
+ if (e.m_pNode->m_level != 0)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
+ ValidateEntry tmpEntry(*(e.m_pNode->m_ptrMBR[cChild]), ptrN);
+
+ std::map<uint32_t, uint32_t>::iterator itNodes = nodesInLevel.find(tmpEntry.m_pNode->m_level);
+
+ if (itNodes == nodesInLevel.end())
+ {
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(tmpEntry.m_pNode->m_level, 1l));
+ }
+ else
+ {
+ nodesInLevel[tmpEntry.m_pNode->m_level] = nodesInLevel[tmpEntry.m_pNode->m_level] + 1;
+ }
+
+ st.push(tmpEntry);
+ }
+ }
+ }
+
+ uint32_t nodes = 0;
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_treeHeight; ++cLevel)
+ {
+ if (nodesInLevel[cLevel] != m_stats.m_nodesInLevel[cLevel])
+ {
+ std::cerr << "Invalid nodesInLevel information." << std::endl;
+ ret = false;
+ }
+
+ nodes += m_stats.m_nodesInLevel[cLevel];
+ }
+
+ if (nodes != m_stats.m_nodes)
+ {
+ std::cerr << "Invalid number of nodes information." << std::endl;
+ ret = false;
+ }
+
+ return ret;
+}
+
+void SpatialIndex::TPRTree::TPRTree::getStatistics(IStatistics** out) const
+{
+ *out = new Statistics(m_stats);
+}
+
+void SpatialIndex::TPRTree::TPRTree::initNew(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != TPRV_RSTAR))
+ throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of TPRTreeVariant type");
+
+ m_treeVariant = static_cast<TPRTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor must be Tools::VT_DOUBLE and in (0.0, 1.0) for RSTAR");
+
+ m_fillFactor = var.m_val.dblVal;
+ }
+
+ // horizon
+ var = ps.getProperty("Horizon");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal == std::numeric_limits<double>::max())
+ throw Tools::IllegalArgumentException("initNew: Property Horizon must be Tools::VT_DOUBLE and a positive constant");
+
+ m_horizon = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_leafCapacity = var.m_val.ulVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1");
+
+ m_dimension = var.m_val.ulVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL)
+ throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+
+ m_stats.m_treeHeight = 1;
+ m_stats.m_nodesInLevel.push_back(0);
+
+ Leaf root(this, -1);
+ m_rootID = writeNode(&root);
+
+ storeHeader();
+}
+
+void SpatialIndex::TPRTree::TPRTree::initOld(Tools::PropertySet& ps)
+{
+ loadHeader();
+
+ // only some of the properties may be changed.
+ // the rest are just ignored.
+
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != TPRV_RSTAR))
+ throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of TPRTreeVariant type");
+
+ m_treeVariant = static_cast<TPRTreeVariant>(var.m_val.lVal);
+ }
+
+ // horizon
+ var = ps.getProperty("Horizon");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal == std::numeric_limits<double>::max())
+ throw Tools::IllegalArgumentException("initOld: Property Horizon must be Tools::VT_DOUBLE and a positive constant");
+
+ m_horizon = var.m_val.dblVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+}
+
+void SpatialIndex::TPRTree::TPRTree::storeHeader()
+{
+ const uint32_t headerSize =
+ sizeof(id_type) + // m_rootID
+ sizeof(TPRTreeVariant) + // m_treeVariant
+ sizeof(double) + // m_fillFactor
+ sizeof(uint32_t) + // m_indexCapacity
+ sizeof(uint32_t) + // m_leafCapacity
+ sizeof(uint32_t) + // m_nearMinimumOverlapFactor
+ sizeof(double) + // m_splitDistributionFactor
+ sizeof(double) + // m_reinsertFactor
+ sizeof(uint32_t) + // m_dimension
+ sizeof(char) + // m_bTightMBRs
+ sizeof(uint32_t) + // m_stats.m_nodes
+ sizeof(uint64_t) + // m_stats.m_data
+ sizeof(double) + // m_currentTime
+ sizeof(double) + // m_horizon
+ sizeof(uint32_t) + // m_stats.m_treeHeight
+ m_stats.m_treeHeight * sizeof(uint32_t);// m_stats.m_nodesInLevel
+
+ byte* header = new byte[headerSize];
+ byte* ptr = header;
+
+ memcpy(ptr, &m_rootID, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_treeVariant, sizeof(TPRTreeVariant));
+ ptr += sizeof(TPRTreeVariant);
+ memcpy(ptr, &m_fillFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_indexCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_leafCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_splitDistributionFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_reinsertFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c = (char) m_bTightMBRs;
+ memcpy(ptr, &c, sizeof(char));
+ ptr += sizeof(char);
+ memcpy(ptr, &(m_stats.m_nodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_data), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(ptr, &m_currentTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_horizon, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(m_stats.m_treeHeight), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_treeHeight; ++cLevel)
+ {
+ memcpy(ptr, &(m_stats.m_nodesInLevel[cLevel]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
+
+ delete[] header;
+}
+
+void SpatialIndex::TPRTree::TPRTree::loadHeader()
+{
+ uint32_t headerSize;
+ byte* header = 0;
+ m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
+
+ byte* ptr = header;
+
+ memcpy(&m_rootID, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&m_treeVariant, ptr, sizeof(TPRTreeVariant));
+ ptr += sizeof(TPRTreeVariant);
+ memcpy(&m_fillFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_indexCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_leafCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_splitDistributionFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_reinsertFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c;
+ memcpy(&c, ptr, sizeof(char));
+ m_bTightMBRs = (c != 0);
+ ptr += sizeof(char);
+ memcpy(&(m_stats.m_nodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_data), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(&m_currentTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_horizon, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(m_stats.m_treeHeight), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_treeHeight; ++cLevel)
+ {
+ uint32_t cNodes;
+ memcpy(&cNodes, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ m_stats.m_nodesInLevel.push_back(cNodes);
+ }
+
+ delete[] header;
+}
+
+void SpatialIndex::TPRTree::TPRTree::insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mr, id_type id)
+{
+ assert(mr.getDimension() == m_dimension);
+ assert(m_currentTime <= mr.m_startTime);
+
+ std::stack<id_type> pathBuffer;
+ byte* overflowTable = 0;
+
+ try
+ {
+ NodePtr root = readNode(m_rootID);
+
+ overflowTable = new byte[root->m_level];
+ bzero(overflowTable, root->m_level);
+
+ NodePtr l = root->chooseSubtree(mr, 0, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mr, id, pathBuffer, overflowTable);
+
+ delete[] overflowTable;
+ ++(m_stats.m_data);
+ }
+ catch (...)
+ {
+ delete[] overflowTable;
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mr, id_type id, uint32_t level, byte* overflowTable)
+{
+ assert(mr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_rootID);
+ NodePtr n = root->chooseSubtree(mr, level, pathBuffer);
+
+ assert(n->m_level == level);
+
+ if (n.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ n->insertData(dataLength, pData, mr, id, pathBuffer, overflowTable);
+}
+
+bool SpatialIndex::TPRTree::TPRTree::deleteData_impl(const MovingRegion& mr, id_type id)
+{
+ assert(mr.m_dimension == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+
+ NodePtr root = readNode(m_rootID);
+ NodePtr l = root->findLeaf(mr, id, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+
+ if (l.get() != 0)
+ {
+ Leaf* pL = static_cast<Leaf*>(l.get());
+ pL->deleteData(id, pathBuffer);
+ --(m_stats.m_data);
+ return true;
+ }
+
+ return false;
+}
+
+id_type SpatialIndex::TPRTree::TPRTree::writeNode(Node* n)
+{
+ byte* buffer;
+ uint32_t dataLength;
+ n->storeToByteArray(&buffer, dataLength);
+
+ id_type page;
+ if (n->m_identifier < 0) page = StorageManager::NewPage;
+ else page = n->m_identifier;
+
+ try
+ {
+ m_pStorageManager->storeByteArray(page, dataLength, buffer);
+ delete[] buffer;
+ }
+ catch (InvalidPageException& e)
+ {
+ delete[] buffer;
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("writeNode: failed with Tools::InvalidPageException");
+ }
+
+ if (n->m_identifier < 0)
+ {
+ n->m_identifier = page;
+ ++(m_stats.m_nodes);
+
+#ifndef NDEBUG
+ try
+ {
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel.at(n->m_level) + 1;
+ }
+ catch(...)
+ {
+ throw Tools::IllegalStateException("writeNode: writing past the end of m_nodesInLevel.");
+ }
+#else
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] + 1;
+#endif
+ }
+
+ ++(m_stats.m_writes);
+
+ for (size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
+ {
+ m_writeNodeCommands[cIndex]->execute(*n);
+ }
+
+ return page;
+}
+
+SpatialIndex::TPRTree::NodePtr SpatialIndex::TPRTree::TPRTree::readNode(id_type id)
+{
+ uint32_t dataLength;
+ byte* buffer;
+
+ try
+ {
+ m_pStorageManager->loadByteArray(id, dataLength, &buffer);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("readNode: failed with Tools::InvalidPageException");
+ }
+
+ try
+ {
+ uint32_t nodeType;
+ memcpy(&nodeType, buffer, sizeof(uint32_t));
+
+ NodePtr n;
+
+ if (nodeType == PersistentIndex) n = m_indexPool.acquire();
+ else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();
+ else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");
+
+ if (n.get() == 0)
+ {
+ if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);
+ else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);
+ }
+
+ //n->m_pTree = this;
+ n->m_identifier = id;
+ n->loadFromByteArray(buffer);
+
+ ++(m_stats.m_reads);
+
+ for (size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
+ {
+ m_readNodeCommands[cIndex]->execute(*n);
+ }
+
+ delete[] buffer;
+ return n;
+ }
+ catch (...)
+ {
+ delete[] buffer;
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::deleteNode(Node* n)
+{
+ try
+ {
+ m_pStorageManager->deleteByteArray(n->m_identifier);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("deleteNode: failed with Tools::InvalidPageException");
+ }
+
+ --(m_stats.m_nodes);
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] - 1;
+
+ for (size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
+ {
+ m_deleteNodeCommands[cIndex]->execute(*n);
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v)
+{
+ const MovingRegion* mr = dynamic_cast<const MovingRegion*>(&query);
+ if (mr == 0) throw Tools::IllegalArgumentException("rangeQuery: Shape has to be a moving region.");
+ if (mr->m_startTime < m_currentTime || mr->m_endTime >= m_currentTime + m_horizon)
+ throw Tools::IllegalArgumentException("rangeQuery: Query time interval does not intersect current horizon.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::stack<NodePtr> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_children > 0 && mr->intersectsRegionInTime(root->m_nodeMBR)) st.push(root);
+
+ while (! st.empty())
+ {
+ NodePtr n = st.top(); st.pop();
+
+ if (n->m_level == 0)
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ bool b;
+ if (type == ContainmentQuery) b = mr->containsRegionInTime(*(n->m_ptrMBR[cChild]));
+ else b = mr->intersectsRegionInTime(*(n->m_ptrMBR[cChild]));
+
+ if (b)
+ {
+ Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ v.visitData(data);
+ ++(m_stats.m_queryResults);
+ }
+ }
+ }
+ else
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (mr->intersectsRegionInTime(*(n->m_ptrMBR[cChild]))) st.push(readNode(n->m_pIdentifier[cChild]));
+ }
+ }
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+std::ostream& SpatialIndex::TPRTree::operator<<(std::ostream& os, const TPRTree& t)
+{
+ os << "Dimension: " << t.m_dimension << std::endl
+ << "Fill factor: " << t.m_fillFactor << std::endl
+ << "Horizon: " << t.m_horizon << std::endl
+ << "Index capacity: " << t.m_indexCapacity << std::endl
+ << "Leaf capacity: " << t.m_leafCapacity << std::endl
+ << "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << std::endl;
+
+ if (t.m_treeVariant == TPRV_RSTAR)
+ {
+ os << "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
+ << "Reinsert factor: " << t.m_reinsertFactor << std::endl
+ << "Split distribution factor: " << t.m_splitDistributionFactor << std::endl;
+ }
+
+ if (t.m_stats.getNumberOfNodesInLevel(0) > 0)
+ os << "Utilization: " << 100 * t.m_stats.getNumberOfData() / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << std::endl
+ << t.m_stats;
+
+ #ifndef NDEBUG
+ os << "Leaf pool hits: " << t.m_leafPool.m_hits << std::endl
+ << "Leaf pool misses: " << t.m_leafPool.m_misses << std::endl
+ << "Index pool hits: " << t.m_indexPool.m_hits << std::endl
+ << "Index pool misses: " << t.m_indexPool.m_misses << std::endl
+ << "Region pool hits: " << t.m_regionPool.m_hits << std::endl
+ << "Region pool misses: " << t.m_regionPool.m_misses << std::endl
+ << "Point pool hits: " << t.m_pointPool.m_hits << std::endl
+ << "Point pool misses: " << t.m_pointPool.m_misses << std::endl;
+ #endif
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.h.svn-base b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.h.svn-base
new file mode 100644
index 000000000..2c28727cd
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/.svn/text-base/TPRTree.h.svn-base
@@ -0,0 +1,199 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Statistics.h"
+#include "Node.h"
+#include "PointerPoolNode.h"
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class TPRTree : public ISpatialIndex
+ {
+ class NNEntry;
+
+ public:
+ TPRTree(IStorageManager&, Tools::PropertySet&);
+ // String Value Description
+ // ----------------------------------------------
+ // IndexIndentifier VT_LONG If specified an existing index will be openened from the supplied
+ // storage manager with the given index id. Behaviour is unspecified
+ // if the index id or the storage manager are incorrect.
+ // Dimension VT_ULONG Dimensionality of the data that will be inserted.
+ // IndexCapacity VT_ULONG The index node capacity. Default is 100.
+ // LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+ // FillFactor VT_DOUBLE The fill factor. Default is 70%
+ // Horizon VT_DOUBLE Horizon. Default is 20.0.
+ // TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+ // NearMinimumOverlapFactor VT_ULONG Default is 32.
+ // SplitDistributionFactor VT_DOUBLE Default is 0.4
+ // ReinsertFactor VT_DOUBLE Default is 0.3
+ // EnsureTightMBRs VT_BOOL Default is true
+ // IndexPoolCapacity VT_LONG Default is 100
+ // LeafPoolCapacity VT_LONG Default is 100
+ // RegionPoolCapacity VT_LONG Default is 1000
+ // PointPoolCapacity VT_LONG Default is 500
+
+ virtual ~TPRTree();
+
+ //
+ // ISpatialIndex interface
+ //
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier);
+ virtual bool deleteData(const IShape& shape, id_type id);
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v);
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v);
+ virtual void pointLocationQuery(const Point& query, IVisitor& v);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator&);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v);
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v);
+ virtual void queryStrategy(IQueryStrategy& qs);
+ virtual void getIndexProperties(Tools::PropertySet& out) const;
+ virtual void addCommand(ICommand* pCommand, CommandType ct);
+ virtual bool isIndexValid();
+ virtual void getStatistics(IStatistics** out) const;
+
+ private:
+ void initNew(Tools::PropertySet&);
+ void initOld(Tools::PropertySet& ps);
+ void storeHeader();
+ void loadHeader();
+
+ void insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id);
+ void insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, uint32_t level, byte* overflowTable);
+ bool deleteData_impl(const MovingRegion& mbr, id_type id);
+
+ id_type writeNode(Node*);
+ NodePtr readNode(id_type id);
+ void deleteNode(Node*);
+
+ void rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v);
+
+ IStorageManager* m_pStorageManager;
+
+ id_type m_rootID, m_headerID;
+
+ TPRTreeVariant m_treeVariant;
+
+ double m_fillFactor;
+
+ uint32_t m_indexCapacity;
+
+ uint32_t m_leafCapacity;
+
+ uint32_t m_nearMinimumOverlapFactor;
+ // The R*-Tree 'p' constant, for calculating nearly minimum overlap cost.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.1]
+
+ double m_splitDistributionFactor;
+ // The R*-Tree 'm' constant, for calculating spliting distributions.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.2]
+
+ double m_reinsertFactor;
+ // The R*-Tree 'p' constant, for removing entries at reinserts.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.3]
+
+ uint32_t m_dimension;
+
+ MovingRegion m_infiniteRegion;
+
+ Statistics m_stats;
+
+ bool m_bTightMBRs;
+
+ double m_currentTime;
+
+ double m_horizon;
+
+ Tools::PointerPool<Point> m_pointPool;
+ Tools::PointerPool<MovingRegion> m_regionPool;
+ Tools::PointerPool<Node> m_indexPool;
+ Tools::PointerPool<Node> m_leafPool;
+
+ std::vector<Tools::SmartPointer<ICommand> > m_writeNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_readNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_deleteNodeCommands;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+
+ class NNEntry
+ {
+ public:
+ id_type m_id;
+ IEntry* m_pEntry;
+ double m_minDist;
+
+ NNEntry(id_type id, IEntry* e, double f) : m_id(id), m_pEntry(e), m_minDist(f) {}
+ ~NNEntry() {}
+
+ struct ascending : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_minDist > __y->m_minDist; }
+ };
+ }; // NNEntry
+
+ class NNComparator : public INearestNeighborComparator
+ {
+ public:
+ double getMinimumDistance(const IShape& query, const IShape& entry)
+ {
+ return query.getMinimumDistance(entry);
+ }
+
+ double getMinimumDistance(const IShape& query, const IData& data)
+ {
+ IShape* pS;
+ data.getShape(&pS);
+ double ret = query.getMinimumDistance(*pS);
+ delete pS;
+ return ret;
+ }
+ }; // NNComparator
+
+ class ValidateEntry
+ {
+ public:
+ ValidateEntry(MovingRegion& r, NodePtr& pNode) : m_parentMBR(r), m_pNode(pNode) {}
+
+ MovingRegion m_parentMBR;
+ NodePtr m_pNode;
+ }; // ValidateEntry
+
+ friend class Node;
+ friend class Leaf;
+ friend class Index;
+
+ friend std::ostream& operator<<(std::ostream& os, const TPRTree& t);
+ }; // TPRTree
+
+ std::ostream& operator<<(std::ostream& os, const TPRTree& t);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.cc b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.cc
new file mode 100644
index 000000000..574414812
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.cc
@@ -0,0 +1,400 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "TPRTree.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+
+using namespace SpatialIndex::TPRTree;
+
+Index::~Index()
+{
+}
+
+Index::Index(SpatialIndex::TPRTree::TPRTree* pTree, id_type id, uint32_t level) : Node(pTree, id, level, pTree->m_indexCapacity)
+{
+}
+
+NodePtr Index::chooseSubtree(const MovingRegion& mbr, uint32_t insertionLevel, std::stack<id_type>& pathBuffer)
+{
+ if (m_level == insertionLevel) return NodePtr(this, &(m_pTree->m_indexPool));
+
+ pathBuffer.push(m_identifier);
+
+ uint32_t child = 0;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case TPRV_RSTAR:
+ if (m_level == 1)
+ {
+ // if this node points to leaves...
+ child = findLeastOverlap(mbr);
+ }
+ else
+ {
+ child = findLeastEnlargement(mbr);
+ }
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::chooseSubtree: Tree variant not supported.");
+ }
+ assert(child != std::numeric_limits<uint32_t>::max());
+
+ NodePtr n = m_pTree->readNode(m_pIdentifier[child]);
+ NodePtr ret = n->chooseSubtree(mbr, insertionLevel, pathBuffer);
+ assert(n.unique());
+ if (ret.get() == n.get()) n.relinquish();
+
+ return ret;
+}
+
+NodePtr Index::findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ pathBuffer.push(m_identifier);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->containsRegionAfterTime(m_pTree->m_currentTime, mbr))
+ {
+ NodePtr n = m_pTree->readNode(m_pIdentifier[cChild]);
+ NodePtr l = n->findLeaf(mbr, id, pathBuffer);
+ if (n.get() == l.get()) n.relinquish();
+ if (l.get() != 0) return l;
+ }
+ }
+
+ pathBuffer.pop();
+
+ return NodePtr();
+}
+
+void Index::split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
+{
+ ++(m_pTree->m_stats.m_splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case TPRV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Index::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_indexPool.acquire();
+ pRight = m_pTree->m_indexPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Index(m_pTree, m_identifier, m_level), &(m_pTree->m_indexPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Index(m_pTree, -1, m_level), &(m_pTree->m_indexPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(0, 0, *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(0, 0, *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ }
+}
+
+uint32_t Index::findLeastEnlargement(const MovingRegion& r) const
+{
+ double area = std::numeric_limits<double>::max();
+ uint32_t best = std::numeric_limits<uint32_t>::max();
+
+ MovingRegionPtr t = m_pTree->m_regionPool.acquire();
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // I need the combined region from current time up to infinity here.
+ m_ptrMBR[cChild]->getCombinedRegionAfterTime(ivT.getLowerBound(), *t, r);
+
+ double a = m_ptrMBR[cChild]->getAreaInTime(ivT);
+ double b = t->getAreaInTime(ivT);
+ double enl = b - a;
+
+ if (enl < area)
+ {
+ area = enl;
+ best = cChild;
+ }
+ else if (enl == area)
+ {
+ // this will rarely happen, so compute best area on the fly only
+ // when necessary.
+ if (a < m_ptrMBR[best]->getAreaInTime(ivT)) best = cChild;
+ }
+ }
+
+ return best;
+}
+
+uint32_t Index::findLeastOverlap(const MovingRegion& r) const
+{
+ OverlapEntry** entries = new OverlapEntry*[m_children];
+
+ double leastOverlap = std::numeric_limits<double>::max();
+ double me = std::numeric_limits<double>::max();
+ OverlapEntry* best = 0;
+
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ // find combined region and enlargement of every entry and store it.
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ try
+ {
+ entries[cChild] = new OverlapEntry();
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete entries[i];
+ delete[] entries;
+ throw;
+ }
+
+ entries[cChild]->m_index = cChild;
+ entries[cChild]->m_original = m_ptrMBR[cChild];
+ entries[cChild]->m_combined = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->getCombinedRegionAfterTime(m_pTree->m_currentTime, *(entries[cChild]->m_combined), r);
+ entries[cChild]->m_oa = entries[cChild]->m_original->getAreaInTime(ivT);
+ entries[cChild]->m_ca = entries[cChild]->m_combined->getAreaInTime(ivT);
+ entries[cChild]->m_enlargement = entries[cChild]->m_ca - entries[cChild]->m_oa;
+
+ if (entries[cChild]->m_enlargement < me)
+ {
+ me = entries[cChild]->m_enlargement;
+ best = entries[cChild];
+ }
+ else if (entries[cChild]->m_enlargement == me && entries[cChild]->m_oa < best->m_oa)
+ {
+ best = entries[cChild];
+ }
+ }
+
+ if (me < -std::numeric_limits<double>::epsilon() || me > std::numeric_limits<double>::epsilon())
+ {
+ uint32_t cIterations;
+
+ if (m_children > m_pTree->m_nearMinimumOverlapFactor)
+ {
+ // sort entries in increasing order of enlargement.
+ ::qsort(entries, m_children,
+ sizeof(OverlapEntry*),
+ OverlapEntry::compareEntries);
+ assert(entries[0]->m_enlargement <= entries[m_children - 1]->m_enlargement);
+
+ cIterations = m_pTree->m_nearMinimumOverlapFactor;
+ }
+ else
+ {
+ cIterations = m_children;
+ }
+
+ // calculate overlap of most important original entries (near minimum overlap cost).
+ for (uint32_t cIndex = 0; cIndex < cIterations; ++cIndex)
+ {
+ double dif = 0.0;
+ OverlapEntry* e = entries[cIndex];
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (e->m_index != cChild)
+ {
+ double f = e->m_combined->getIntersectingAreaInTime(ivT, *(m_ptrMBR[cChild]));
+ if (f != 0.0) dif += f - e->m_original->getIntersectingAreaInTime(ivT, *(m_ptrMBR[cChild]));
+ }
+ } // for (cChild)
+
+ if (dif < leastOverlap)
+ {
+ leastOverlap = dif;
+ best = entries[cIndex];
+ }
+ else if (dif == leastOverlap)
+ {
+ if (e->m_enlargement == best->m_enlargement)
+ {
+ // keep the one with least area.
+ if (e->m_original->getAreaInTime(ivT) < best->m_original->getAreaInTime(ivT)) best = entries[cIndex];
+ }
+ else
+ {
+ // keep the one with least enlargement.
+ if (e->m_enlargement < best->m_enlargement) best = entries[cIndex];
+ }
+ }
+ } // for (cIndex)
+ }
+
+ uint32_t ret = best->m_index;
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ delete entries[cChild];
+ }
+ delete[] entries;
+
+ return ret;
+}
+
+void Index::adjustTree(Node* n, std::stack<id_type>& pathBuffer)
+{
+ ++(m_pTree->m_stats.m_adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n->m_identifier) break;
+ }
+ assert(child < m_children);
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ //Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+ //bool bContained = m_nodeMBR.containsRegionInTime(ivT, n->m_nodeMBR);
+
+ *(m_ptrMBR[child]) = n->m_nodeMBR;
+
+ //if (! bContained)
+ //{
+ // update the MBR at the current time anyway, to make tighter.
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+ //}
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, *(m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ m_pTree->writeNode(this);
+
+ if (/*! bContained && */ ! pathBuffer.empty())
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
+
+void Index::adjustTree(Node* n1, Node* n2, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ ++(m_pTree->m_stats.m_adjustments);
+
+ // find entry pointing to old node;
+ uint32_t child;
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == n1->m_identifier) break;
+ }
+ assert(child < m_children);
+
+ // MBR needs recalculation if either:
+ // 1. the NEW child MBR is not contained.
+ // 2. the OLD child MBR is touching.
+ //Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+ //bool bContained = m_nodeMBR.containsRegionInTime(ivT, n1->m_nodeMBR);
+
+ *(m_ptrMBR[child]) = n1->m_nodeMBR;
+
+ //if (! bContaied)
+ //{
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+ //}
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, *(m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ // No write necessary here. insertData will write the node if needed.
+ //m_pTree->writeNode(this);
+
+ bool bAdjusted = insertData(0, 0, n2->m_nodeMBR, n2->m_identifier, pathBuffer, overflowTable);
+
+ // if n2 is contained in the node and there was no split or reinsert,
+ // we need to adjust only if recalculation took place.
+ // In all other cases insertData above took care of adjustment.
+ if (! bAdjusted && ! pathBuffer.empty())
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.h b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.h
new file mode 100644
index 000000000..68ca1f51f
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Index.h
@@ -0,0 +1,73 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class Index : public Node
+ {
+ public:
+ virtual ~Index();
+
+ private:
+ Index(TPRTree* pTree, id_type id, uint32_t level);
+
+ virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ uint32_t findLeastEnlargement(const MovingRegion&) const;
+ uint32_t findLeastOverlap(const MovingRegion&) const;
+
+ void adjustTree(Node*, std::stack<id_type>&);
+ void adjustTree(Node*, Node*, std::stack<id_type>&, byte* overflowTable);
+
+ class OverlapEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_enlargement;
+ MovingRegionPtr m_original;
+ MovingRegionPtr m_combined;
+ double m_oa;
+ double m_ca;
+
+ static int compareEntries(const void* pv1, const void* pv2)
+ {
+ OverlapEntry* pe1 = * (OverlapEntry**) pv1;
+ OverlapEntry* pe2 = * (OverlapEntry**) pv2;
+
+ if (pe1->m_enlargement < pe2->m_enlargement) return -1;
+ if (pe1->m_enlargement > pe2->m_enlargement) return 1;
+ return 0;
+ }
+ }; // OverlapEntry
+
+ friend class TPRTree;
+ friend class Node;
+ friend class BulkLoader;
+ }; // Index
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.cc b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.cc
new file mode 100644
index 000000000..a9db9df2c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.cc
@@ -0,0 +1,135 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "TPRTree.h"
+#include "Node.h"
+#include "Index.h"
+#include "Leaf.h"
+
+using namespace SpatialIndex::TPRTree;
+
+Leaf::~Leaf()
+{
+}
+
+Leaf::Leaf(SpatialIndex::TPRTree::TPRTree* pTree, id_type id)
+ : Node(pTree, id, 0, pTree->m_leafCapacity)
+{
+}
+
+NodePtr Leaf::chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer)
+{
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ return NodePtr(this, &(m_pTree->m_leafPool));
+}
+
+NodePtr Leaf::findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer)
+{
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ // should make sure to relinquish other PoolPointer lists that might be pointing to the
+ // same leaf.
+ if (m_pIdentifier[cChild] == id /*&& mbr == *(m_ptrMBR[cChild])*/) return NodePtr(this, &(m_pTree->m_leafPool));
+ }
+
+ return NodePtr();
+}
+
+void Leaf::split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& pLeft, NodePtr& pRight)
+{
+ ++(m_pTree->m_stats.m_splits);
+
+ std::vector<uint32_t> g1, g2;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case TPRV_RSTAR:
+ rstarSplit(dataLength, pData, mbr, id, g1, g2);
+ break;
+ default:
+ throw Tools::NotSupportedException("Leaf::split: Tree variant not supported.");
+ }
+
+ pLeft = m_pTree->m_leafPool.acquire();
+ pRight = m_pTree->m_leafPool.acquire();
+
+ if (pLeft.get() == 0) pLeft = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+ if (pRight.get() == 0) pRight = NodePtr(new Leaf(m_pTree, -1), &(m_pTree->m_leafPool));
+
+ pLeft->m_nodeMBR = m_pTree->m_infiniteRegion;
+ pRight->m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < g1.size(); ++cIndex)
+ {
+ pLeft->insertEntry(m_pDataLength[g1[cIndex]], m_pData[g1[cIndex]], *(m_ptrMBR[g1[cIndex]]), m_pIdentifier[g1[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g1[cIndex]] = 0;
+ }
+
+ for (cIndex = 0; cIndex < g2.size(); ++cIndex)
+ {
+ pRight->insertEntry(m_pDataLength[g2[cIndex]], m_pData[g2[cIndex]], *(m_ptrMBR[g2[cIndex]]), m_pIdentifier[g2[cIndex]]);
+ // we don't want to delete the data array from this node's destructor!
+ m_pData[g2[cIndex]] = 0;
+ }
+}
+
+void Leaf::deleteData(id_type id, std::stack<id_type>& pathBuffer)
+{
+ uint32_t child;
+
+ for (child = 0; child < m_children; ++child)
+ {
+ if (m_pIdentifier[child] == id) break;
+ }
+
+ deleteEntry(child);
+ m_pTree->writeNode(this);
+
+ std::stack<NodePtr> toReinsert;
+ NodePtr ptrThis(this, &(m_pTree->m_leafPool));
+ condenseTree(toReinsert, pathBuffer, ptrThis);
+ ptrThis.relinquish();
+
+ // re-insert eliminated nodes.
+ while (! toReinsert.empty())
+ {
+ NodePtr n = toReinsert.top(); toReinsert.pop();
+ m_pTree->deleteNode(n.get());
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ // keep this in the for loop. The tree height might change after insertions.
+ byte* overflowTable = new byte[m_pTree->m_stats.m_treeHeight];
+ bzero(overflowTable, m_pTree->m_stats.m_treeHeight);
+ m_pTree->insertData_impl(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild], n->m_level, overflowTable);
+ n->m_pData[cChild] = 0;
+ delete[] overflowTable;
+ }
+ if (n.get() == this) n.relinquish();
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.h b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.h
new file mode 100644
index 000000000..01a0bd53c
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Leaf.h
@@ -0,0 +1,47 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class Leaf : public Node
+ {
+ public:
+ virtual ~Leaf();
+
+ private:
+ Leaf(TPRTree* pTree, id_type id);
+
+ virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer);
+ virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer);
+
+ virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right);
+
+ virtual void deleteData(id_type id, std::stack<id_type>& pathBuffer);
+
+ friend class TPRTree;
+ friend class BulkLoader;
+ }; // Leaf
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Makefile.am b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Makefile.am
new file mode 100644
index 000000000..6f6a87aa2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Makefile.am
@@ -0,0 +1,4 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libtprtree.la
+INCLUDES = -I../../include
+libtprtree_la_SOURCES = Index.cc Leaf.cc Node.cc TPRTree.cc Statistics.cc Leaf.h Index.h Node.h PointerPoolNode.h Statistics.h TPRTree.h
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.cc b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.cc
new file mode 100644
index 000000000..1c14b99c2
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.cc
@@ -0,0 +1,1253 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <cstring>
+#include <cmath>
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "TPRTree.h"
+#include "Node.h"
+#include "Index.h"
+
+using namespace SpatialIndex::TPRTree;
+
+//
+// Tools::IObject interface
+//
+Tools::IObject* Node::clone()
+{
+ throw Tools::NotSupportedException("IObject::clone should never be called.");
+}
+
+//
+// Tools::ISerializable interface
+//
+uint32_t Node::getByteArraySize()
+{
+ return
+ (sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(uint32_t) +
+ sizeof(double) +
+ (m_children * (4 * m_pTree->m_dimension * sizeof(double) + sizeof(double) + sizeof(id_type) + sizeof(uint32_t))) +
+ m_totalDataLength +
+ (4 * m_pTree->m_dimension * sizeof(double)));
+}
+
+void Node::loadFromByteArray(const byte* ptr)
+{
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+
+ // skip the node type information, it is not needed.
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_level, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&m_children, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(&(m_nodeMBR.m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ m_nodeMBR.m_endTime = std::numeric_limits<double>::max();
+ //memcpy(&(m_nodeMBR.m_endTime), ptr, sizeof(double));
+ //ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_ptrMBR[cChild] = m_pTree->m_regionPool.acquire();
+ m_ptrMBR[cChild]->makeDimension(m_pTree->m_dimension);
+
+ memcpy(m_ptrMBR[cChild]->m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pVLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_ptrMBR[cChild]->m_pVHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(&(m_ptrMBR[cChild]->m_startTime), ptr, sizeof(double));
+ ptr += sizeof(double);
+ m_ptrMBR[cChild]->m_endTime = std::numeric_limits<double>::max();
+
+ memcpy(&(m_pIdentifier[cChild]), ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(&(m_pDataLength[cChild]), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ m_totalDataLength += m_pDataLength[cChild];
+ m_pData[cChild] = new byte[m_pDataLength[cChild]];
+ memcpy(m_pData[cChild], ptr, m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ else
+ {
+ m_pData[cChild] = 0;
+ }
+
+ //m_nodeMBR.combineRegion(*(m_ptrMBR[cChild]));
+ }
+
+ memcpy(m_nodeMBR.m_pLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pVLow, ptr, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(m_nodeMBR.m_pVHigh, ptr, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+}
+
+void Node::storeToByteArray(byte** data, uint32_t& len)
+{
+ len = getByteArraySize();
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ uint32_t nodeType;
+
+ if (m_level == 0) nodeType = PersistentLeaf;
+ else nodeType = PersistentIndex;
+
+ memcpy(ptr, &nodeType, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_level, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &m_children, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ memcpy(ptr, &(m_nodeMBR.m_startTime), sizeof(double));
+ ptr += sizeof(double);
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ memcpy(ptr, m_ptrMBR[cChild]->m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pVLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_ptrMBR[cChild]->m_pVHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, &(m_ptrMBR[cChild]->m_startTime), sizeof(double));
+ ptr += sizeof(double);
+
+ memcpy(ptr, &(m_pIdentifier[cChild]), sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ memcpy(ptr, &(m_pDataLength[cChild]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_pDataLength[cChild] > 0)
+ {
+ memcpy(ptr, m_pData[cChild], m_pDataLength[cChild]);
+ ptr += m_pDataLength[cChild];
+ }
+ }
+
+ // store the node MBR for efficiency. This increases the node size a little bit.
+ memcpy(ptr, m_nodeMBR.m_pLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pHigh, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pVLow, m_pTree->m_dimension * sizeof(double));
+ ptr += m_pTree->m_dimension * sizeof(double);
+ memcpy(ptr, m_nodeMBR.m_pVHigh, m_pTree->m_dimension * sizeof(double));
+ //ptr += m_pTree->m_dimension * sizeof(double);
+
+ assert(len == (ptr - *data) + m_pTree->m_dimension * sizeof(double));
+}
+
+//
+// SpatialIndex::IEntry interface
+//
+id_type Node::getIdentifier() const
+{
+ return m_identifier;
+}
+
+void Node::getShape(IShape** out) const
+{
+ *out = new MovingRegion(m_nodeMBR);
+}
+
+//
+// SpatialIndex::INode interface
+//
+uint32_t Node::getChildrenCount() const
+{
+ return m_children;
+}
+
+id_type Node::getChildIdentifier(uint32_t index) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ return m_pIdentifier[index];
+}
+
+void Node::getChildShape(uint32_t index, IShape** out) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+
+ *out = new MovingRegion(*(m_ptrMBR[index]));
+}
+
+void Node::getChildData(uint32_t index, uint32_t& length, byte** data) const
+{
+ if (index < 0 || index >= m_children) throw Tools::IndexOutOfBoundsException(index);
+ if (m_pData[index] == NULL)
+ {
+ length = 0;
+ data = NULL;
+ }
+ else
+ {
+ length = m_pDataLength[index];
+ *data = m_pData[index];
+ }
+}
+
+uint32_t Node::getLevel() const
+{
+ return m_level;
+}
+
+bool Node::isLeaf() const
+{
+ return (m_level == 0);
+}
+
+bool Node::isIndex() const
+{
+ return (m_level != 0);
+}
+
+//
+// Internal
+//
+
+Node::Node() :
+ m_pTree(0),
+ m_level(0),
+ m_identifier(-1),
+ m_children(0),
+ m_capacity(0),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+}
+
+Node::Node(SpatialIndex::TPRTree::TPRTree* pTree, id_type id, uint32_t level, uint32_t capacity) :
+ m_pTree(pTree),
+ m_level(level),
+ m_identifier(id),
+ m_children(0),
+ m_capacity(capacity),
+ m_pData(0),
+ m_ptrMBR(0),
+ m_pIdentifier(0),
+ m_pDataLength(0),
+ m_totalDataLength(0)
+{
+ m_nodeMBR.makeInfinite(m_pTree->m_dimension);
+
+ try
+ {
+ m_pDataLength = new uint32_t[m_capacity + 1];
+ m_pData = new byte*[m_capacity + 1];
+ m_ptrMBR = new MovingRegionPtr[m_capacity + 1];
+ m_pIdentifier = new id_type[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+ throw;
+ }
+}
+
+Node::~Node()
+{
+ if (m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ if (m_pData[cChild] != 0) delete[] m_pData[cChild];
+ }
+
+ delete[] m_pData;
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+}
+
+Node& Node::operator=(const Node& n)
+{
+ throw Tools::IllegalStateException("Node::operator =: This should never be called.");
+}
+
+bool Node::insertEntry(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id)
+{
+ assert(m_children < m_capacity);
+
+ bool bAdjusted = false;
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ m_totalDataLength += dataLength;
+ ++m_children;
+
+ if (m_nodeMBR.m_startTime != m_pTree->m_currentTime)
+ {
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ bAdjusted = true;
+ }
+ else if (
+ //m_nodeMBR.m_pLow[0] != std::numeric_limits<double>::max() &&
+ ! m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, mbr))
+ {
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ double l = m_nodeMBR.getExtrapolatedLow(cDim, m_pTree->m_currentTime);
+ double rl = mbr.getExtrapolatedLow(cDim, m_pTree->m_currentTime);
+ if (rl <= l)
+ {
+ m_nodeMBR.m_pLow[cDim] = rl - 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ double h = m_nodeMBR.getExtrapolatedHigh(cDim, m_pTree->m_currentTime);
+ double rh = mbr.getExtrapolatedHigh(cDim, m_pTree->m_currentTime);
+ if (rh >= h)
+ {
+ m_nodeMBR.m_pHigh[cDim] = rh + 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], mbr.m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], mbr.m_pVHigh[cDim]);
+ }
+
+ bAdjusted = true;
+ }
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_nodeMBR.m_startTime, *(m_ptrMBR[cChild])));
+ }
+#endif
+
+ return true;
+}
+
+void Node::deleteEntry(uint32_t index)
+{
+ assert(index >= 0 && index < m_children);
+
+ // cache it, since I might need it for "touches" later.
+ MovingRegionPtr ptrR = m_ptrMBR[index];
+
+ m_totalDataLength -= m_pDataLength[index];
+ if (m_pData[index] != 0) delete[] m_pData[index];
+
+ if (m_children > 1 && index != m_children - 1)
+ {
+ m_pDataLength[index] = m_pDataLength[m_children - 1];
+ m_pData[index] = m_pData[m_children - 1];
+ m_ptrMBR[index] = m_ptrMBR[m_children - 1];
+ m_pIdentifier[index] = m_pIdentifier[m_children - 1];
+ }
+
+ --m_children;
+
+ // WARNING: index has now changed. Do not use it below here.
+
+ if (m_children == 0)
+ {
+ m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+ else //if (m_pTree->m_bTightMBRs && m_nodeMBR.touchesRegion(*ptrR))
+ {
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_pTree->m_currentTime, *(m_ptrMBR[cChild])) == true);
+ }
+#endif
+ }
+}
+
+bool Node::insertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable)
+{
+ if (m_children < m_capacity)
+ {
+ bool bNeedToAdjust = insertEntry(dataLength, pData, mbr, id);
+ m_pTree->writeNode(this);
+
+ if (bNeedToAdjust && ! pathBuffer.empty())
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+ }
+
+ return bNeedToAdjust;
+ }
+ else if (false && m_pTree->m_treeVariant == TPRV_RSTAR && ! pathBuffer.empty() && overflowTable[m_level] == 0)
+ {
+ overflowTable[m_level] = 1;
+
+ std::vector<uint32_t> vReinsert, vKeep;
+ reinsertData(dataLength, pData, mbr, id, vReinsert, vKeep);
+
+ uint32_t lReinsert = static_cast<uint32_t>(vReinsert.size());
+ uint32_t lKeep = static_cast<uint32_t>(vKeep.size());
+
+ byte** reinsertdata = 0;
+ MovingRegionPtr* reinsertmbr = 0;
+ id_type* reinsertid = 0;
+ uint32_t* reinsertlen = 0;
+ byte** keepdata = 0;
+ MovingRegionPtr* keepmbr = 0;
+ id_type* keepid = 0;
+ uint32_t* keeplen = 0;
+
+ try
+ {
+ reinsertdata = new byte*[lReinsert];
+ reinsertmbr = new MovingRegionPtr[lReinsert];
+ reinsertid = new id_type[lReinsert];
+ reinsertlen = new uint32_t[lReinsert];
+
+ keepdata = new byte*[m_capacity + 1];
+ keepmbr = new MovingRegionPtr[m_capacity + 1];
+ keepid = new id_type[m_capacity + 1];
+ keeplen = new uint32_t[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+ delete[] keepdata;
+ delete[] keepmbr;
+ delete[] keepid;
+ delete[] keeplen;
+ throw;
+ }
+
+ uint32_t cIndex;
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ reinsertlen[cIndex] = m_pDataLength[vReinsert[cIndex]];
+ reinsertdata[cIndex] = m_pData[vReinsert[cIndex]];
+ reinsertmbr[cIndex] = m_ptrMBR[vReinsert[cIndex]];
+ reinsertid[cIndex] = m_pIdentifier[vReinsert[cIndex]];
+ }
+
+ for (cIndex = 0; cIndex < lKeep; ++cIndex)
+ {
+ keeplen[cIndex] = m_pDataLength[vKeep[cIndex]];
+ keepdata[cIndex] = m_pData[vKeep[cIndex]];
+ keepmbr[cIndex] = m_ptrMBR[vKeep[cIndex]];
+ keepid[cIndex] = m_pIdentifier[vKeep[cIndex]];
+ }
+
+ delete[] m_pDataLength;
+ delete[] m_pData;
+ delete[] m_ptrMBR;
+ delete[] m_pIdentifier;
+
+ m_pDataLength = keeplen;
+ m_pData = keepdata;
+ m_ptrMBR = keepmbr;
+ m_pIdentifier = keepid;
+ m_children = lKeep;
+ m_totalDataLength = 0;
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild) m_totalDataLength += m_pDataLength[cChild];
+
+ m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < m_nodeMBR.m_dimension; ++cDim)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ m_nodeMBR.m_pLow[cDim] = std::min(m_nodeMBR.m_pLow[cDim], m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pHigh[cDim] = std::max(m_nodeMBR.m_pHigh[cDim], m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_nodeMBR.m_startTime));
+ m_nodeMBR.m_pVLow[cDim] = std::min(m_nodeMBR.m_pVLow[cDim], m_ptrMBR[cChild]->m_pVLow[cDim]);
+ m_nodeMBR.m_pVHigh[cDim] = std::max(m_nodeMBR.m_pVHigh[cDim], m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < m_children; ++cChild)
+ {
+ assert(m_nodeMBR.containsRegionAfterTime(m_nodeMBR.m_startTime, *(m_ptrMBR[cChild])));
+ }
+#endif
+
+ m_pTree->writeNode(this);
+
+ // Divertion from R*-Tree algorithm here. First adjust
+ // the path to the root, then start reinserts, to avoid complicated handling
+ // of changes to the same node from multiple insertions.
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(this, pathBuffer);
+
+ for (cIndex = 0; cIndex < lReinsert; ++cIndex)
+ {
+ m_pTree->insertData_impl(
+ reinsertlen[cIndex], reinsertdata[cIndex],
+ *(reinsertmbr[cIndex]), reinsertid[cIndex],
+ m_level, overflowTable);
+ }
+
+ delete[] reinsertdata;
+ delete[] reinsertmbr;
+ delete[] reinsertid;
+ delete[] reinsertlen;
+
+ return true;
+ }
+ else
+ {
+ NodePtr n;
+ NodePtr nn;
+ split(dataLength, pData, mbr, id, n, nn);
+
+ if (pathBuffer.empty())
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = -1;
+ nn->m_identifier = -1;
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ assert(n->m_nodeMBR.containsRegionAfterTime(n->m_nodeMBR.m_startTime, *(n->m_ptrMBR[cChild])) == true);
+ }
+ for (uint32_t cChild = 0; cChild < nn->m_children; ++cChild)
+ {
+ assert(nn->m_nodeMBR.containsRegionAfterTime(nn->m_nodeMBR.m_startTime, *(nn->m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ NodePtr ptrR = m_pTree->m_indexPool.acquire();
+ if (ptrR.get() == 0)
+ {
+ ptrR = NodePtr(new Index(m_pTree, m_pTree->m_rootID, m_level + 1), &(m_pTree->m_indexPool));
+ }
+ else
+ {
+ //ptrR->m_pTree = m_pTree;
+ ptrR->m_identifier = m_pTree->m_rootID;
+ ptrR->m_level = m_level + 1;
+ ptrR->m_nodeMBR = m_pTree->m_infiniteRegion;
+ }
+
+ ptrR->insertEntry(0, 0, n->m_nodeMBR, n->m_identifier);
+ ptrR->insertEntry(0, 0, nn->m_nodeMBR, nn->m_identifier);
+
+ m_pTree->writeNode(ptrR.get());
+
+ m_pTree->m_stats.m_nodesInLevel[m_level] = 2;
+ m_pTree->m_stats.m_nodesInLevel.push_back(1);
+ m_pTree->m_stats.m_treeHeight = m_level + 2;
+ }
+ else
+ {
+ n->m_level = m_level;
+ nn->m_level = m_level;
+ n->m_identifier = m_identifier;
+ nn->m_identifier = -1;
+
+#ifndef NDEBUG
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ assert(n->m_nodeMBR.containsRegionAfterTime(n->m_nodeMBR.m_startTime, *(n->m_ptrMBR[cChild])) == true);
+ }
+ for (uint32_t cChild = 0; cChild < nn->m_children; ++cChild)
+ {
+ assert(nn->m_nodeMBR.containsRegionAfterTime(nn->m_nodeMBR.m_startTime, *(nn->m_ptrMBR[cChild])) == true);
+ }
+#endif
+
+ m_pTree->writeNode(n.get());
+ m_pTree->writeNode(nn.get());
+
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrN = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrN.get());
+ p->adjustTree(n.get(), nn.get(), pathBuffer, overflowTable);
+ }
+
+ return true;
+ }
+}
+
+void Node::reinsertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep)
+{
+ ReinsertEntry** v = new ReinsertEntry*[m_capacity + 1];
+
+ m_pDataLength[m_children] = dataLength;
+ m_pData[m_children] = pData;
+ m_ptrMBR[m_children] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_children]) = mbr;
+ m_pIdentifier[m_children] = id;
+
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ for (uint32_t cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ try
+ {
+ v[cChild] = new ReinsertEntry(cChild, 0.0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete v[i];
+ delete[] v;
+ throw;
+ }
+
+ v[cChild]->m_dist = m_nodeMBR.getCenterDistanceInTime(ivT, *(m_ptrMBR[cChild]));
+ }
+
+ // sort by increasing order of distances.
+ ::qsort(v, m_capacity + 1, sizeof(ReinsertEntry*), ReinsertEntry::compareReinsertEntry);
+
+ uint32_t cReinsert = static_cast<uint32_t>(std::floor((m_capacity + 1) * m_pTree->m_reinsertFactor));
+
+ uint32_t cCount;
+
+ for (cCount = 0; cCount < cReinsert; ++cCount)
+ {
+ reinsert.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ for (cCount = cReinsert; cCount < m_capacity + 1; ++cCount)
+ {
+ keep.push_back(v[cCount]->m_index);
+ delete v[cCount];
+ }
+
+ delete[] v;
+}
+
+/*
+void Node::rtreeSplit(uint32_t dataLength, byte* pData, Region& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ uint32_t cChild;
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ // use this mask array for marking visited entries.
+ byte* mask = new byte[m_capacity + 1];
+ bzero(mask, m_capacity + 1);
+
+ // insert new data in the node for easier manipulation. Data arrays are always
+ // by one larger than node capacity.
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+
+ // initialize each group with the seed entries.
+ uint32_t seed1, seed2;
+ pickSeeds(seed1, seed2);
+
+ group1.push_back(seed1);
+ group2.push_back(seed2);
+
+ mask[seed1] = 1;
+ mask[seed2] = 1;
+
+ // find MBR of each group.
+ RegionPtr mbr1 = m_pTree->m_regionPool.acquire();
+ *mbr1 = *(m_ptrMBR[seed1]);
+ RegionPtr mbr2 = m_pTree->m_regionPool.acquire();
+ *mbr2 = *(m_ptrMBR[seed2]);
+
+ // count how many entries are left unchecked (exclude the seeds here.)
+ uint32_t cRemaining = m_capacity + 1 - 2;
+
+ while (cRemaining > 0)
+ {
+ if (minimumLoad - group1.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group1 to comply with minimun load requirement.
+ for (cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group1.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else if (minimumLoad - group2.size() == cRemaining)
+ {
+ // all remaining entries must be assigned to group2 to comply with minimun load requirement.
+ for (cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ group2.push_back(cChild);
+ mask[cChild] = 1;
+ --cRemaining;
+ }
+ }
+ }
+ else
+ {
+ // For all remaining entries compute the difference of the cost of grouping an
+ // entry in either group. When done, choose the entry that yielded the maximum
+ // difference. In case of linear split, select any entry (e.g. the first one.)
+ uint32_t sel;
+ double md1 = 0.0, md2 = 0.0;
+ double m = -std::numeric_limits<double>::max();
+ double d1, d2, d;
+ double a1 = mbr1->getArea();
+ double a2 = mbr2->getArea();
+
+ RegionPtr a = m_pTree->m_regionPool.acquire();
+ RegionPtr b = m_pTree->m_regionPool.acquire();
+
+ for (cChild = 0; cChild < m_capacity + 1; ++cChild)
+ {
+ if (mask[cChild] == 0)
+ {
+ mbr1->getCombinedRegion(*a, *(m_ptrMBR[cChild]));
+ d1 = a->getArea() - a1;
+ mbr2->getCombinedRegion(*b, *(m_ptrMBR[cChild]));
+ d2 = b->getArea() - a2;
+ d = std::abs(d1 - d2);
+
+ if (d > m)
+ {
+ m = d;
+ md1 = d1; md2 = d2;
+ sel = cChild;
+ if (m_pTree->m_treeVariant== RV_LINEAR || m_pTree->m_treeVariant == RV_RSTAR) break;
+ }
+ }
+ }
+
+ // determine the group where we should add the new entry.
+ int32_t group = -1;
+
+ if (md1 < md2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (md2 < md1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (a1 < a2)
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (a2 < a1)
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else if (group1.size() < group2.size())
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ else if (group2.size() < group1.size())
+ {
+ group2.push_back(sel);
+ group = 2;
+ }
+ else
+ {
+ group1.push_back(sel);
+ group = 1;
+ }
+ mask[sel] = 1;
+ --cRemaining;
+ if (group == 1)
+ {
+ mbr1->combineRegion(*(m_ptrMBR[sel]));
+ }
+ else
+ {
+ mbr2->combineRegion(*(m_ptrMBR[sel]));
+ }
+ }
+ }
+
+ delete[] mask;
+}
+*/
+
+void Node::rstarSplit(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2)
+{
+ RstarSplitEntry** dataLow = 0;
+ RstarSplitEntry** dataHigh = 0;
+ RstarSplitEntry** dataVLow = 0;
+ RstarSplitEntry** dataVHigh = 0;
+
+ try
+ {
+ dataLow = new RstarSplitEntry*[m_capacity + 1];
+ dataHigh = new RstarSplitEntry*[m_capacity + 1];
+ dataVLow = new RstarSplitEntry*[m_capacity + 1];
+ dataVHigh = new RstarSplitEntry*[m_capacity + 1];
+ }
+ catch (...)
+ {
+ delete[] dataLow;
+ delete[] dataHigh;
+ delete[] dataVLow;
+ delete[] dataVHigh;
+ throw;
+ }
+
+ m_pDataLength[m_capacity] = dataLength;
+ m_pData[m_capacity] = pData;
+ m_ptrMBR[m_capacity] = m_pTree->m_regionPool.acquire();
+ *(m_ptrMBR[m_capacity]) = mbr;
+ m_pIdentifier[m_capacity] = id;
+
+ uint32_t nodeSPF = static_cast<uint32_t>(std::floor((m_capacity + 1) * m_pTree->m_splitDistributionFactor));
+ uint32_t splitDistribution = (m_capacity + 1) - (2 * nodeSPF) + 2;
+
+ Tools::Interval ivT(m_pTree->m_currentTime, m_pTree->m_currentTime + m_pTree->m_horizon);
+
+ uint32_t cChild = 0, cDim, cIndex;
+
+ for (cChild = 0; cChild <= m_capacity; ++cChild)
+ {
+ try
+ {
+ dataLow[cChild] = new RstarSplitEntry(m_ptrMBR[cChild].get(), cChild, 0);
+ }
+ catch (...)
+ {
+ for (uint32_t i = 0; i < cChild; ++i) delete dataLow[i];
+ delete[] dataLow;
+ delete[] dataHigh;
+ throw;
+ }
+
+ dataHigh[cChild] = dataLow[cChild];
+ dataVLow[cChild] = dataLow[cChild];
+ dataVHigh[cChild] = dataLow[cChild];
+ }
+
+ double minimumMargin = std::numeric_limits<double>::max();
+ uint32_t splitAxis = std::numeric_limits<uint32_t>::max();
+ uint32_t sortOrder = std::numeric_limits<uint32_t>::max();
+
+ // chooseSplitAxis.
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareLow);
+ ::qsort(dataHigh, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareHigh);
+ ::qsort(dataVLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVLow);
+ ::qsort(dataVHigh, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVHigh);
+
+ // calculate sum of margins and overlap for all distributions.
+ double marginl = 0.0;
+ double marginh = 0.0;
+ double marginvl = 0.0;
+ double marginvh = 0.0;
+
+ MovingRegion bbl1, bbl2, bbh1, bbh2;
+ MovingRegion bbvl1, bbvl2, bbvh1, bbvh2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bbl1 = *(dataLow[0]->m_pRegion);
+ bbh1 = *(dataHigh[0]->m_pRegion);
+ bbvl1 = *(dataVLow[0]->m_pRegion);
+ bbvh1 = *(dataVHigh[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bbl1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ bbh1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataHigh[cIndex]->m_pRegion));
+ bbvl1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVLow[cIndex]->m_pRegion));
+ bbvh1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVHigh[cIndex]->m_pRegion));
+ }
+
+ bbl2 = *(dataLow[l]->m_pRegion);
+ bbh2 = *(dataHigh[l]->m_pRegion);
+ bbvl2 = *(dataVLow[l]->m_pRegion);
+ bbvh2 = *(dataVHigh[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bbl2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ bbh2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataHigh[cIndex]->m_pRegion));
+ bbvl2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVLow[cIndex]->m_pRegion));
+ bbvh2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataVHigh[cIndex]->m_pRegion));
+ }
+
+ marginl += bbl1.getProjectedSurfaceAreaInTime(ivT) + bbl2.getProjectedSurfaceAreaInTime(ivT);
+ marginh += bbh1.getProjectedSurfaceAreaInTime(ivT) + bbh2.getProjectedSurfaceAreaInTime(ivT);
+ marginvl += bbvl1.getProjectedSurfaceAreaInTime(ivT) + bbvl2.getProjectedSurfaceAreaInTime(ivT);
+ marginvh += bbvh1.getProjectedSurfaceAreaInTime(ivT) + bbvh2.getProjectedSurfaceAreaInTime(ivT);
+ } // for (cChild)
+
+ double margin = std::min(std::min(marginl, marginh), std::min(marginvl, marginvh));
+
+ // keep minimum margin as split axis.
+ if (margin < minimumMargin)
+ {
+ minimumMargin = margin;
+ splitAxis = cDim;
+ if (marginl < marginh && marginl < marginvl && marginl < marginvh) sortOrder = 0;
+ else if (marginh < marginl && marginh < marginvl && marginh < marginvh) sortOrder = 1;
+ else if (marginvl < marginl && marginvl < marginh && marginvl < marginvh) sortOrder = 2;
+ else if (marginvh < marginl && marginvh < marginh && marginvh < marginvl) sortOrder = 3;
+ }
+
+ // increase the dimension according to which the data entries should be sorted.
+ for (cChild = 0; cChild <= m_capacity; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = cDim + 1;
+ }
+ } // for (cDim)
+
+ for (cChild = 0; cChild <= m_capacity; ++cChild)
+ {
+ dataLow[cChild]->m_sortDim = splitAxis;
+ }
+
+ if (sortOrder == 0)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareLow);
+ else if (sortOrder == 1)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareHigh);
+ else if (sortOrder == 2)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVLow);
+ else if (sortOrder == 3)
+ ::qsort(dataLow, m_capacity + 1, sizeof(RstarSplitEntry*), RstarSplitEntry::compareVHigh);
+
+ double ma = std::numeric_limits<double>::max();
+ double mo = std::numeric_limits<double>::max();
+ uint32_t splitPoint = std::numeric_limits<uint32_t>::max();
+
+ MovingRegion bb1, bb2;
+
+ for (cChild = 1; cChild <= splitDistribution; ++cChild)
+ {
+ uint32_t l = nodeSPF - 1 + cChild;
+
+ bb1 = *(dataLow[0]->m_pRegion);
+
+ for (cIndex = 1; cIndex < l; ++cIndex)
+ {
+ bb1.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ }
+
+ bb2 = *(dataLow[l]->m_pRegion);
+
+ for (cIndex = l + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ bb2.combineRegionAfterTime(m_pTree->m_currentTime, *(dataLow[cIndex]->m_pRegion));
+ }
+
+ double o = bb1.getIntersectingAreaInTime(ivT, bb2);
+
+ if (o < mo)
+ {
+ splitPoint = cChild;
+ mo = o;
+ ma = bb1.getAreaInTime(ivT) + bb2.getAreaInTime(ivT);
+ }
+ else if (o == mo)
+ {
+ double a = bb1.getAreaInTime(ivT) + bb2.getAreaInTime(ivT);
+
+ if (a < ma)
+ {
+ splitPoint = cChild;
+ ma = a;
+ }
+ }
+ } // for (cChild)
+
+ uint32_t l1 = nodeSPF - 1 + splitPoint;
+
+ for (cIndex = 0; cIndex < l1; ++cIndex)
+ {
+ group1.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ for (cIndex = l1; cIndex <= m_capacity; ++cIndex)
+ {
+ group2.push_back(dataLow[cIndex]->m_index);
+ delete dataLow[cIndex];
+ }
+
+ delete[] dataLow;
+ delete[] dataHigh;
+ delete[] dataVLow;
+ delete[] dataVHigh;
+}
+
+/*
+void Node::pickSeeds(uint32_t& index1, uint32_t& index2)
+{
+ double separation = -std::numeric_limits<double>::max();
+ double inefficiency = -std::numeric_limits<double>::max();
+ uint32_t cDim, cChild, cIndex;
+
+ switch (m_pTree->m_treeVariant)
+ {
+ case RV_LINEAR:
+ case RV_RSTAR:
+ for (cDim = 0; cDim < m_pTree->m_dimension; ++cDim)
+ {
+ double leastLower = m_ptrMBR[0]->m_pLow[cDim];
+ double greatestUpper = m_ptrMBR[0]->m_pHigh[cDim];
+ uint32_t greatestLower = 0;
+ uint32_t leastUpper = 0;
+ double width;
+
+ for (cChild = 1; cChild <= m_capacity; ++cChild)
+ {
+ if (m_ptrMBR[cChild]->m_pLow[cDim] > m_ptrMBR[greatestLower]->m_pLow[cDim]) greatestLower = cChild;
+ if (m_ptrMBR[cChild]->m_pHigh[cDim] < m_ptrMBR[leastUpper]->m_pHigh[cDim]) leastUpper = cChild;
+
+ leastLower = std::min(m_ptrMBR[cChild]->m_pLow[cDim], leastLower);
+ greatestUpper = std::max(m_ptrMBR[cChild]->m_pHigh[cDim], greatestUpper);
+ }
+
+ width = greatestUpper - leastLower;
+ if (width <= 0) width = 1;
+
+ double f = (m_ptrMBR[greatestLower]->m_pLow[cDim] - m_ptrMBR[leastUpper]->m_pHigh[cDim]) / width;
+
+ if (f > separation)
+ {
+ index1 = leastUpper;
+ index2 = greatestLower;
+ separation = f;
+ }
+ } // for (cDim)
+
+ if (index1 == index2)
+ {
+ if (index2 == 0) ++index2;
+ else --index2;
+ }
+
+ break;
+ case RV_QUADRATIC:
+ // for each pair of Regions (account for overflow Region too!)
+ for (cChild = 0; cChild < m_capacity; ++cChild)
+ {
+ double a = m_ptrMBR[cChild]->getArea();
+
+ for (cIndex = cChild + 1; cIndex <= m_capacity; ++cIndex)
+ {
+ // get the combined MBR of those two entries.
+ Region r;
+ m_ptrMBR[cChild]->getCombinedRegion(r, *(m_ptrMBR[cIndex]));
+
+ // find the inefficiency of grouping these entries together.
+ double d = r.getArea() - a - m_ptrMBR[cIndex]->getArea();
+
+ if (d > inefficiency)
+ {
+ inefficiency = d;
+ index1 = cChild;
+ index2 = cIndex;
+ }
+ } // for (cIndex)
+ } // for (cChild)
+
+ break;
+ default:
+ throw Tools::NotSupportedException("Node::pickSeeds: Tree variant not supported.");
+ }
+}
+*/
+
+void Node::condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis)
+{
+ uint32_t minimumLoad = static_cast<uint32_t>(std::floor(m_capacity * m_pTree->m_fillFactor));
+
+ if (pathBuffer.empty())
+ {
+ // eliminate root if it has only one child.
+ if (m_level != 0 && m_children == 1)
+ {
+ NodePtr ptrN = m_pTree->readNode(m_pIdentifier[0]);
+ m_pTree->deleteNode(ptrN.get());
+ ptrN->m_identifier = m_pTree->m_rootID;
+ m_pTree->writeNode(ptrN.get());
+
+ m_pTree->m_stats.m_nodesInLevel.pop_back();
+ m_pTree->m_stats.m_treeHeight -= 1;
+ // HACK: pending deleteNode for deleted child will decrease nodesInLevel, later on.
+ m_pTree->m_stats.m_nodesInLevel[m_pTree->m_stats.m_treeHeight - 1] = 2;
+ }
+ }
+ else
+ {
+ id_type cParent = pathBuffer.top(); pathBuffer.pop();
+ NodePtr ptrParent = m_pTree->readNode(cParent);
+ Index* p = static_cast<Index*>(ptrParent.get());
+
+ // find the entry in the parent, that points to this node.
+ uint32_t child;
+
+ for (child = 0; child != p->m_children; ++child)
+ {
+ if (p->m_pIdentifier[child] == m_identifier) break;
+ }
+
+ if (m_children < minimumLoad)
+ {
+ // used space less than the minimum
+ // 1. eliminate node entry from the parent. deleteEntry will fix the parent's MBR.
+ p->deleteEntry(child);
+ // 2. add this node to the stack in order to reinsert its entries.
+ toReinsert.push(ptrThis);
+ }
+ else
+ {
+ // adjust the entry in 'p' to contain the new bounding region of this node.
+ *(p->m_ptrMBR[child]) = m_nodeMBR;
+
+ // global recalculation necessary since the MBR can only shrink in size,
+ // due to data removal.
+ //if (m_pTree->m_bTightMBRs)
+ //{
+
+ p->m_nodeMBR.m_startTime = m_pTree->m_currentTime;
+
+ for (uint32_t cDim = 0; cDim < p->m_nodeMBR.m_dimension; ++cDim)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ p->m_nodeMBR.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ p->m_nodeMBR.m_pLow[cDim] = std::min(p->m_nodeMBR.m_pLow[cDim], p->m_ptrMBR[cChild]->getExtrapolatedLow(cDim, m_pTree->m_currentTime));
+ p->m_nodeMBR.m_pHigh[cDim] = std::max(p->m_nodeMBR.m_pHigh[cDim], p->m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, m_pTree->m_currentTime));
+ p->m_nodeMBR.m_pVLow[cDim] = std::min(p->m_nodeMBR.m_pVLow[cDim], p->m_ptrMBR[cChild]->m_pVLow[cDim]);
+ p->m_nodeMBR.m_pVHigh[cDim] = std::max(p->m_nodeMBR.m_pVHigh[cDim], p->m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ p->m_nodeMBR.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ p->m_nodeMBR.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+ //}
+ }
+
+ // write parent node back to storage.
+ m_pTree->writeNode(p);
+
+ p->condenseTree(toReinsert, pathBuffer, ptrParent);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.h b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.h
new file mode 100644
index 000000000..6cf5d98a0
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Node.h
@@ -0,0 +1,200 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class TPRTree;
+ class Leaf;
+ class Index;
+ class Node;
+
+ typedef Tools::PoolPointer<Node> NodePtr;
+
+ class Node : public SpatialIndex::INode
+ {
+ public:
+ virtual ~Node();
+
+ //
+ // Tools::IObject interface
+ //
+ virtual Tools::IObject* clone();
+
+ //
+ // Tools::ISerializable interface
+ //
+ virtual uint32_t getByteArraySize();
+ virtual void loadFromByteArray(const byte* data);
+ virtual void storeToByteArray(byte** data, uint32_t& len);
+
+ //
+ // SpatialIndex::IEntry interface
+ //
+ virtual id_type getIdentifier() const;
+ virtual void getShape(IShape** out) const;
+
+ //
+ // SpatialIndex::INode interface
+ //
+ virtual uint32_t getChildrenCount() const;
+ virtual id_type getChildIdentifier(uint32_t index) const;
+ virtual void getChildShape(uint32_t index, IShape** out) const;
+ virtual void getChildData(uint32_t index, uint32_t& length, byte** data) const;
+ virtual uint32_t getLevel() const;
+ virtual bool isIndex() const;
+ virtual bool isLeaf() const;
+
+ private:
+ Node();
+ Node(TPRTree* pTree, id_type id, uint32_t level, uint32_t capacity);
+
+ virtual Node& operator=(const Node&);
+
+ virtual bool insertEntry(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id);
+ virtual void deleteEntry(uint32_t index);
+
+ virtual bool insertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer, byte* overflowTable);
+ virtual void reinsertData(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& reinsert, std::vector<uint32_t>& keep);
+
+ virtual void rstarSplit(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, std::vector<uint32_t>& group1, std::vector<uint32_t>& group2);
+
+ virtual void condenseTree(std::stack<NodePtr>& toReinsert, std::stack<id_type>& pathBuffer, NodePtr& ptrThis);
+
+ virtual NodePtr chooseSubtree(const MovingRegion& mbr, uint32_t level, std::stack<id_type>& pathBuffer) = 0;
+ virtual NodePtr findLeaf(const MovingRegion& mbr, id_type id, std::stack<id_type>& pathBuffer) = 0;
+
+ virtual void split(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, NodePtr& left, NodePtr& right) = 0;
+
+ TPRTree* m_pTree;
+ // Parent of all nodes.
+
+ uint32_t m_level;
+ // The level of the node in the tree.
+ // Leaves are always at level 0.
+
+ id_type m_identifier;
+ // The unique ID of this node.
+
+ uint32_t m_children;
+ // The number of children pointed by this node.
+
+ uint32_t m_capacity;
+ // Specifies the node capacity.
+
+ MovingRegion m_nodeMBR;
+ // The minimum bounding region enclosing all data contained in the node.
+
+ byte** m_pData;
+ // The data stored in the node.
+
+ MovingRegionPtr* m_ptrMBR;
+ // The corresponding data MBRs.
+
+ id_type* m_pIdentifier;
+ // The corresponding data identifiers.
+
+ uint32_t* m_pDataLength;
+
+ uint32_t m_totalDataLength;
+
+ class RstarSplitEntry
+ {
+ public:
+ MovingRegion* m_pRegion;
+ uint32_t m_index;
+ uint32_t m_sortDim;
+
+ RstarSplitEntry(MovingRegion* pr, uint32_t index, uint32_t dimension)
+ : m_pRegion(pr), m_index(index), m_sortDim(dimension) {}
+
+ static int compareLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] < pe2->m_pRegion->m_pLow[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pLow[pe1->m_sortDim] > pe2->m_pRegion->m_pLow[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pHigh[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pHigh[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareVLow(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pVLow[pe1->m_sortDim] < pe2->m_pRegion->m_pVLow[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pVLow[pe1->m_sortDim] > pe2->m_pRegion->m_pVLow[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+
+ static int compareVHigh(const void* pv1, const void* pv2)
+ {
+ RstarSplitEntry* pe1 = * (RstarSplitEntry**) pv1;
+ RstarSplitEntry* pe2 = * (RstarSplitEntry**) pv2;
+
+ if (pe1->m_pRegion->m_pVHigh[pe1->m_sortDim] < pe2->m_pRegion->m_pVHigh[pe1->m_sortDim]) return -1;
+ if (pe1->m_pRegion->m_pVHigh[pe1->m_sortDim] > pe2->m_pRegion->m_pVHigh[pe1->m_sortDim]) return 1;
+ return 0;
+ }
+ }; // RstarSplitEntry
+
+ class ReinsertEntry
+ {
+ public:
+ uint32_t m_index;
+ double m_dist;
+
+ ReinsertEntry(uint32_t index, double dist) : m_index(index), m_dist(dist) {}
+
+ static int compareReinsertEntry(const void* pv1, const void* pv2)
+ {
+ ReinsertEntry* pe1 = * (ReinsertEntry**) pv1;
+ ReinsertEntry* pe2 = * (ReinsertEntry**) pv2;
+
+ if (pe1->m_dist < pe2->m_dist) return -1;
+ if (pe1->m_dist > pe2->m_dist) return 1;
+ return 0;
+ }
+ }; // ReinsertEntry
+
+ // Needed to access protected members without having to cast from Node.
+ // It is more efficient than using member functions to access protected members.
+ friend class TPRTree;
+ friend class Leaf;
+ friend class Index;
+ friend class Tools::PointerPool<Node>;
+ }; // Node
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/PointerPoolNode.h b/sci-libs/libspatialindex/svn/trunk/src/tprtree/PointerPoolNode.h
new file mode 100644
index 000000000..8c026fbe3
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/PointerPoolNode.h
@@ -0,0 +1,133 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Node.h"
+
+namespace Tools
+{
+ template<> class PointerPool<TPRTree::Node>
+ {
+ public:
+ explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
+ {
+ #ifndef NDEBUG
+ m_hits = 0;
+ m_misses = 0;
+ m_pointerCount = 0;
+ #endif
+ }
+
+ ~PointerPool()
+ {
+ assert(m_pool.size() <= m_capacity);
+
+ while (! m_pool.empty())
+ {
+ TPRTree::Node* x = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete x;
+ }
+
+ #ifndef NDEBUG
+ std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
+ #endif
+ }
+
+ PoolPointer<TPRTree::Node> acquire()
+ {
+ if (! m_pool.empty())
+ {
+ TPRTree::Node* p = m_pool.top(); m_pool.pop();
+ #ifndef NDEBUG
+ ++m_hits;
+ #endif
+
+ return PoolPointer<TPRTree::Node>(p, this);
+ }
+ #ifndef NDEBUG
+ else
+ {
+ // fixme: well sort of...
+ ++m_pointerCount;
+ ++m_misses;
+ }
+ #endif
+
+ return PoolPointer<TPRTree::Node>();
+ }
+
+ void release(TPRTree::Node* p)
+ {
+ if (p != 0)
+ {
+ if (m_pool.size() < m_capacity)
+ {
+ if (p->m_pData != 0)
+ {
+ for (uint32_t cChild = 0; cChild < p->m_children; ++cChild)
+ {
+ if (p->m_pData[cChild] != 0) delete[] p->m_pData[cChild];
+ }
+ }
+
+ p->m_level = 0;
+ p->m_identifier = -1;
+ p->m_children = 0;
+ p->m_totalDataLength = 0;
+
+ m_pool.push(p);
+ }
+ else
+ {
+ #ifndef NDEBUG
+ --m_pointerCount;
+ #endif
+ delete p;
+ }
+
+ assert(m_pool.size() <= m_capacity);
+ }
+ }
+
+ uint32_t getCapacity() const { return m_capacity; }
+ void setCapacity(uint32_t c)
+ {
+ assert (c >= 0);
+ m_capacity = c;
+ }
+
+ protected:
+ uint32_t m_capacity;
+ std::stack<TPRTree::Node*> m_pool;
+
+ #ifndef NDEBUG
+ public:
+ uint64_t m_hits;
+ uint64_t m_misses;
+ uint64_t m_pointerCount;
+ #endif
+ };
+}
+
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.cc b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.cc
new file mode 100644
index 000000000..d2031d4db
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.cc
@@ -0,0 +1,171 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Statistics.h"
+
+using namespace SpatialIndex::TPRTree;
+
+Statistics::Statistics()
+{
+ reset();
+}
+
+Statistics::Statistics(const Statistics& s)
+{
+ m_reads = s.m_reads;
+ m_writes = s.m_writes;
+ m_splits = s.m_splits;
+ m_hits = s.m_hits;
+ m_misses = s.m_misses;
+ m_nodes = s.m_nodes;
+ m_adjustments = s.m_adjustments;
+ m_queryResults = s.m_queryResults;
+ m_data = s.m_data;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+}
+
+Statistics::~Statistics()
+{
+}
+
+Statistics& Statistics::operator=(const Statistics& s)
+{
+ if (this != &s)
+ {
+ m_reads = s.m_reads;
+ m_writes = s.m_writes;
+ m_splits = s.m_splits;
+ m_hits = s.m_hits;
+ m_misses = s.m_misses;
+ m_nodes = s.m_nodes;
+ m_adjustments = s.m_adjustments;
+ m_queryResults = s.m_queryResults;
+ m_data = s.m_data;
+ m_treeHeight = s.m_treeHeight;
+ m_nodesInLevel = s.m_nodesInLevel;
+ }
+
+ return *this;
+}
+
+uint64_t Statistics::getReads() const
+{
+ return m_reads;
+}
+
+uint64_t Statistics::getWrites() const
+{
+ return m_writes;
+}
+
+uint32_t Statistics::getNumberOfNodes() const
+{
+ return m_nodes;
+}
+
+uint64_t Statistics::getNumberOfData() const
+{
+ return m_data;
+}
+
+uint64_t Statistics::getSplits() const
+{
+ return m_splits;
+}
+
+uint64_t Statistics::getHits() const
+{
+ return m_hits;
+}
+
+uint64_t Statistics::getMisses() const
+{
+ return m_misses;
+}
+
+uint64_t Statistics::getAdjustments() const
+{
+ return m_adjustments;
+}
+
+uint64_t Statistics::getQueryResults() const
+{
+ return m_queryResults;
+}
+
+uint32_t Statistics::getTreeHeight() const
+{
+ return m_treeHeight;
+}
+
+uint32_t Statistics::getNumberOfNodesInLevel(uint32_t l) const
+{
+ uint32_t cNodes;
+ try
+ {
+ cNodes = m_nodesInLevel.at(l);
+ }
+ catch (...)
+ {
+ throw Tools::IndexOutOfBoundsException(l);
+ }
+
+ return cNodes;
+}
+
+void Statistics::reset()
+{
+ m_reads = 0;
+ m_writes = 0;
+ m_splits = 0;
+ m_hits = 0;
+ m_misses = 0;
+ m_nodes = 0;
+ m_adjustments = 0;
+ m_queryResults = 0;
+ m_data = 0;
+ m_treeHeight = 0;
+ m_nodesInLevel.clear();
+}
+
+std::ostream& SpatialIndex::TPRTree::operator<<(std::ostream& os, const Statistics& s)
+{
+ os << "Reads: " << s.m_reads << std::endl
+ << "Writes: " << s.m_writes << std::endl
+ << "Hits: " << s.m_hits << std::endl
+ << "Misses: " << s.m_misses << std::endl
+ << "Tree height: " << s.m_treeHeight << std::endl
+ << "Number of data: " << s.m_data << std::endl
+ << "Number of nodes: " << s.m_nodes << std::endl;
+
+ for (uint32_t cLevel = 0; cLevel < s.m_treeHeight; ++cLevel)
+ {
+ os << "Level " << cLevel << " pages: " << s.m_nodesInLevel[cLevel] << std::endl;
+ }
+
+ os << "Splits: " << s.m_splits << std::endl
+ << "Adjustments: " << s.m_adjustments << std::endl
+ << "Query results: " << s.m_queryResults << std::endl;
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.h b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.h
new file mode 100644
index 000000000..44b707c30
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/Statistics.h
@@ -0,0 +1,93 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class TPRTree;
+ class Node;
+ class Leaf;
+ class Index;
+
+ class Statistics : public SpatialIndex::IStatistics
+ {
+ public:
+ Statistics();
+ Statistics(const Statistics&);
+ virtual ~Statistics();
+ Statistics& operator=(const Statistics&);
+
+ //
+ // IStatistics interface
+ //
+ virtual uint64_t getReads() const;
+ virtual uint64_t getWrites() const;
+ virtual uint32_t getNumberOfNodes() const;
+ virtual uint64_t getNumberOfData() const;
+
+ virtual uint64_t getSplits() const;
+ virtual uint64_t getHits() const;
+ virtual uint64_t getMisses() const;
+ virtual uint64_t getAdjustments() const;
+ virtual uint64_t getQueryResults() const;
+ virtual uint32_t getTreeHeight() const;
+ virtual uint32_t getNumberOfNodesInLevel(uint32_t l) const;
+
+ private:
+ void reset();
+
+ uint64_t m_reads;
+
+ uint64_t m_writes;
+
+ uint64_t m_splits;
+
+ uint64_t m_hits;
+
+ uint64_t m_misses;
+
+ uint32_t m_nodes;
+
+ uint64_t m_adjustments;
+
+ uint64_t m_queryResults;
+
+ uint64_t m_data;
+
+ uint32_t m_treeHeight;
+
+ std::vector<uint32_t> m_nodesInLevel;
+
+ friend class TPRTree;
+ friend class Node;
+ friend class Index;
+ friend class Leaf;
+ friend class BulkLoader;
+
+ friend std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }; // Statistics
+
+ std::ostream& operator<<(std::ostream& os, const Statistics& s);
+ }
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.cc b/sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.cc
new file mode 100644
index 000000000..16b8f9c54
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.cc
@@ -0,0 +1,1352 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#include <limits>
+
+#include "../spatialindex/SpatialIndexImpl.h"
+#include "Node.h"
+#include "Leaf.h"
+#include "Index.h"
+#include "TPRTree.h"
+
+#include <cstring>
+
+using namespace SpatialIndex::TPRTree;
+
+SpatialIndex::TPRTree::Data::Data(uint32_t len, byte* pData, MovingRegion& r, id_type id)
+ : m_id(id), m_region(r), m_pData(0), m_dataLength(len)
+{
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, pData, m_dataLength);
+ }
+}
+
+SpatialIndex::TPRTree::Data::~Data()
+{
+ delete[] m_pData;
+}
+
+SpatialIndex::TPRTree::Data* SpatialIndex::TPRTree::Data::clone()
+{
+ return new Data(m_dataLength, m_pData, m_region, m_id);
+}
+
+SpatialIndex::id_type SpatialIndex::TPRTree::Data::getIdentifier() const
+{
+ return m_id;
+}
+
+void SpatialIndex::TPRTree::Data::getShape(IShape** out) const
+{
+ *out = new MovingRegion(m_region);
+}
+
+void SpatialIndex::TPRTree::Data::getData(uint32_t& len, byte** data) const
+{
+ len = m_dataLength;
+ *data = 0;
+
+ if (m_dataLength > 0)
+ {
+ *data = new byte[m_dataLength];
+ memcpy(*data, m_pData, m_dataLength);
+ }
+}
+
+uint32_t SpatialIndex::TPRTree::Data::getByteArraySize()
+{
+ return
+ sizeof(id_type) +
+ sizeof(uint32_t) +
+ m_dataLength +
+ m_region.getByteArraySize();
+}
+
+void SpatialIndex::TPRTree::Data::loadFromByteArray(const byte* ptr)
+{
+ memcpy(&m_id, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+
+ delete[] m_pData;
+ m_pData = 0;
+
+ memcpy(&m_dataLength, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ m_pData = new byte[m_dataLength];
+ memcpy(m_pData, ptr, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ m_region.loadFromByteArray(ptr);
+}
+
+void SpatialIndex::TPRTree::Data::storeToByteArray(byte** data, uint32_t& len)
+{
+ // it is thread safe this way.
+ uint32_t regionsize;
+ byte* regiondata = 0;
+ m_region.storeToByteArray(&regiondata, regionsize);
+
+ len = sizeof(id_type) + sizeof(uint32_t) + m_dataLength + regionsize;
+
+ *data = new byte[len];
+ byte* ptr = *data;
+
+ memcpy(ptr, &m_id, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_dataLength, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ if (m_dataLength > 0)
+ {
+ memcpy(ptr, m_pData, m_dataLength);
+ ptr += m_dataLength;
+ }
+
+ memcpy(ptr, regiondata, regionsize);
+ delete[] regiondata;
+ // ptr += regionsize;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::TPRTree::returnTPRTree(SpatialIndex::IStorageManager& sm, Tools::PropertySet& ps)
+{
+ SpatialIndex::ISpatialIndex* si = new SpatialIndex::TPRTree::TPRTree(sm, ps);
+ return si;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::TPRTree::createNewTPRTree(
+ SpatialIndex::IStorageManager& sm,
+ double fillFactor,
+ uint32_t indexCapacity,
+ uint32_t leafCapacity,
+ uint32_t dimension,
+ TPRTreeVariant rv,
+ double horizon,
+ id_type& indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = fillFactor;
+ ps.setProperty("FillFactor", var);
+
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = horizon;
+ ps.setProperty("Horizon", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = indexCapacity;
+ ps.setProperty("IndexCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = leafCapacity;
+ ps.setProperty("LeafCapacity", var);
+
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = dimension;
+ ps.setProperty("Dimension", var);
+
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = rv;
+ ps.setProperty("TreeVariant", var);
+
+ ISpatialIndex* ret = returnTPRTree(sm, ps);
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var = ps.getProperty("IndexIdentifier");
+ indexIdentifier = var.m_val.llVal;
+
+ return ret;
+}
+
+SpatialIndex::ISpatialIndex* SpatialIndex::TPRTree::loadTPRTree(IStorageManager& sm, id_type indexIdentifier)
+{
+ Tools::Variant var;
+ Tools::PropertySet ps;
+
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = indexIdentifier;
+ ps.setProperty("IndexIdentifier", var);
+
+ return returnTPRTree(sm, ps);
+}
+
+SpatialIndex::TPRTree::TPRTree::TPRTree(IStorageManager& sm, Tools::PropertySet& ps) :
+ m_pStorageManager(&sm),
+ m_rootID(StorageManager::NewPage),
+ m_headerID(StorageManager::NewPage),
+ m_treeVariant(TPRV_RSTAR),
+ m_fillFactor(0.7),
+ m_indexCapacity(100),
+ m_leafCapacity(100),
+ m_nearMinimumOverlapFactor(32),
+ m_splitDistributionFactor(0.4),
+ m_reinsertFactor(0.3),
+ m_dimension(2),
+ m_bTightMBRs(true),
+ m_currentTime(0.0),
+ m_horizon(20.0),
+ m_pointPool(500),
+ m_regionPool(1000),
+ m_indexPool(100),
+ m_leafPool(100)
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_init(&m_rwLock, NULL);
+#else
+ m_rwLock = false;
+#endif
+
+ Tools::Variant var = ps.getProperty("IndexIdentifier");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType == Tools::VT_LONGLONG) m_headerID = var.m_val.llVal;
+ else if (var.m_varType == Tools::VT_LONG) m_headerID = var.m_val.lVal;
+ // for backward compatibility only.
+ else throw Tools::IllegalArgumentException("TPRTree: Property IndexIdentifier must be Tools::VT_LONGLONG");
+
+ initOld(ps);
+ }
+ else
+ {
+ initNew(ps);
+ var.m_varType = Tools::VT_LONGLONG;
+ var.m_val.llVal = m_headerID;
+ ps.setProperty("IndexIdentifier", var);
+ }
+}
+
+SpatialIndex::TPRTree::TPRTree::~TPRTree()
+{
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_destroy(&m_rwLock);
+#endif
+
+ storeHeader();
+}
+
+//
+// ISpatialIndex interface
+//
+
+void SpatialIndex::TPRTree::TPRTree::insertData(uint32_t len, const byte* pData, const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+ const IEvolvingShape* es = dynamic_cast<const IEvolvingShape*>(&shape);
+ if (es == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IEvolvingShape interface.");
+ const Tools::IInterval *pivI = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (pivI == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IInterval interface.");
+
+ if (pivI->getLowerBound() < m_currentTime) throw Tools::IllegalArgumentException("insertData: Shape start time is older than tree current time.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("insertData: cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ Region mbr;
+ shape.getMBR(mbr);
+ Region vbr;
+ es->getVMBR(vbr);
+ assert(mbr.m_dimension == vbr.m_dimension);
+
+ MovingRegionPtr mr = m_regionPool.acquire();
+ mr->makeDimension(mbr.m_dimension);
+
+ memcpy(mr->m_pLow, mbr.m_pLow, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pHigh, mbr.m_pHigh, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVLow, vbr.m_pLow, vbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVHigh, vbr.m_pHigh, vbr.m_dimension * sizeof(double));
+ mr->m_startTime = pivI->getLowerBound();
+ mr->m_endTime = std::numeric_limits<double>::max();
+
+ byte* buffer = 0;
+
+ if (len > 0)
+ {
+ buffer = new byte[len];
+ memcpy(buffer, pData, len);
+ }
+
+ m_currentTime = mr->m_startTime;
+ insertData_impl(len, buffer, *mr, id);
+ // the buffer is stored in the tree. Do not delete here.
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+// shape.m_startTime should be the time when the object was inserted initially.
+// shape.m_endTime should be the time of the deletion (current time).
+bool SpatialIndex::TPRTree::TPRTree::deleteData(const IShape& shape, id_type id)
+{
+ if (shape.getDimension() != m_dimension) throw Tools::IllegalArgumentException("insertData: Shape has the wrong number of dimensions.");
+ const IEvolvingShape* es = dynamic_cast<const IEvolvingShape*>(&shape);
+ if (es == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IEvolvingShape interface.");
+ const Tools::IInterval *pivI = dynamic_cast<const Tools::IInterval*>(&shape);
+ if (pivI == 0) throw Tools::IllegalArgumentException("insertData: Shape does not support the Tools::IInterval interface.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::ExclusiveLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("deleteData cannot acquire an exclusive lock");
+#endif
+
+ try
+ {
+ Region mbr;
+ shape.getMBR(mbr);
+ Region vbr;
+ es->getVMBR(vbr);
+ assert(mbr.m_dimension == vbr.m_dimension);
+
+ MovingRegionPtr mr = m_regionPool.acquire();
+ mr->makeDimension(mbr.m_dimension);
+
+ memcpy(mr->m_pLow, mbr.m_pLow, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pHigh, mbr.m_pHigh, mbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVLow, vbr.m_pLow, vbr.m_dimension * sizeof(double));
+ memcpy(mr->m_pVHigh, vbr.m_pHigh, vbr.m_dimension * sizeof(double));
+ mr->m_startTime = pivI->getLowerBound();
+ mr->m_endTime = std::numeric_limits<double>::max();
+
+ m_currentTime = pivI->getUpperBound();
+ bool ret = deleteData_impl(*mr, id);
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+
+ return ret;
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::containsWhatQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("containsWhatQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(ContainmentQuery, query, v);
+}
+
+void SpatialIndex::TPRTree::TPRTree::intersectsWithQuery(const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("intersectsWithQuery: Shape has the wrong number of dimensions.");
+ rangeQuery(IntersectionQuery, query, v);
+}
+
+void SpatialIndex::TPRTree::TPRTree::pointLocationQuery(const Point& query, IVisitor& v)
+{
+ if (query.m_dimension != m_dimension) throw Tools::IllegalArgumentException("pointLocationQuery: Shape has the wrong number of dimensions.");
+ Region r(query, query);
+ rangeQuery(IntersectionQuery, r, v);
+}
+
+void SpatialIndex::TPRTree::TPRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc)
+{
+ throw Tools::IllegalStateException("nearestNeighborQuery: not impelmented yet.");
+}
+
+void SpatialIndex::TPRTree::TPRTree::nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v)
+{
+ if (query.getDimension() != m_dimension) throw Tools::IllegalArgumentException("nearestNeighborQuery: Shape has the wrong number of dimensions.");
+ NNComparator nnc;
+ nearestNeighborQuery(k, query, v, nnc);
+}
+
+void SpatialIndex::TPRTree::TPRTree::selfJoinQuery(const IShape& query, IVisitor& v)
+{
+ throw Tools::IllegalStateException("selfJoinQuery: not impelmented yet.");
+}
+
+void SpatialIndex::TPRTree::TPRTree::queryStrategy(IQueryStrategy& qs)
+{
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("queryStrategy: cannot acquire a shared lock");
+#endif
+
+ id_type next = m_rootID;
+ bool hasNext = true;
+
+ try
+ {
+ while (hasNext)
+ {
+ NodePtr n = readNode(next);
+ qs.getNextEntry(*n, next, hasNext);
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::getIndexProperties(Tools::PropertySet& out) const
+{
+ Tools::Variant var;
+
+ // dimension
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_dimension;
+ out.setProperty("Dimension", var);
+
+ // index capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexCapacity;
+ out.setProperty("IndexCapacity", var);
+
+ // leaf capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafCapacity;
+ out.setProperty("LeafCapacity", var);
+
+ // Tree variant
+ var.m_varType = Tools::VT_LONG;
+ var.m_val.lVal = m_treeVariant;
+ out.setProperty("TreeVariant", var);
+
+ // fill factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_fillFactor;
+ out.setProperty("FillFactor", var);
+
+ // horizon
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_horizon;
+ out.setProperty("Horizon", var);
+
+ // near minimum overlap factor
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_nearMinimumOverlapFactor;
+ out.setProperty("NearMinimumOverlapFactor", var);
+
+ // split distribution factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_splitDistributionFactor;
+ out.setProperty("SplitDistributionFactor", var);
+
+ // reinsert factor
+ var.m_varType = Tools::VT_DOUBLE;
+ var.m_val.dblVal = m_reinsertFactor;
+ out.setProperty("ReinsertFactor", var);
+
+ // tight MBRs
+ var.m_varType = Tools::VT_BOOL;
+ var.m_val.blVal = m_bTightMBRs;
+ out.setProperty("EnsureTightMBRs", var);
+
+ // index pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_indexPool.getCapacity();
+ out.setProperty("IndexPoolCapacity", var);
+
+ // leaf pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_leafPool.getCapacity();
+ out.setProperty("LeafPoolCapacity", var);
+
+ // region pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_regionPool.getCapacity();
+ out.setProperty("RegionPoolCapacity", var);
+
+ // point pool capacity
+ var.m_varType = Tools::VT_ULONG;
+ var.m_val.ulVal = m_pointPool.getCapacity();
+ out.setProperty("PointPoolCapacity", var);
+}
+
+void SpatialIndex::TPRTree::TPRTree::addCommand(ICommand* pCommand, CommandType ct)
+{
+ switch (ct)
+ {
+ case CT_NODEREAD:
+ m_readNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEWRITE:
+ m_writeNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ case CT_NODEDELETE:
+ m_deleteNodeCommands.push_back(Tools::SmartPointer<ICommand>(pCommand));
+ break;
+ }
+}
+
+bool SpatialIndex::TPRTree::TPRTree::isIndexValid()
+{
+ bool ret = true;
+
+ std::stack<ValidateEntry> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_level != m_stats.m_treeHeight - 1)
+ {
+ std::cerr << "Invalid tree height." << std::endl;
+ return false;
+ }
+
+ std::map<uint32_t, uint32_t> nodesInLevel;
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(root->m_level, 1));
+
+ ValidateEntry e(root->m_nodeMBR, root);
+ st.push(e);
+
+ while (! st.empty())
+ {
+ e = st.top(); st.pop();
+
+ MovingRegion tmpRegion;
+ tmpRegion = m_infiniteRegion;
+
+ // I have to rely on the parent information here, since none of the node's
+ // children might have a reference time equal to their parents (e.g., after
+ // a split).
+ tmpRegion.m_startTime = e.m_parentMBR.m_startTime;
+
+ for (uint32_t cDim = 0; cDim < tmpRegion.m_dimension; ++cDim)
+ {
+ tmpRegion.m_pLow[cDim] = std::numeric_limits<double>::max();
+ tmpRegion.m_pHigh[cDim] = -std::numeric_limits<double>::max();
+ tmpRegion.m_pVLow[cDim] = std::numeric_limits<double>::max();
+ tmpRegion.m_pVHigh[cDim] = -std::numeric_limits<double>::max();
+
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ tmpRegion.m_pLow[cDim] = std::min(tmpRegion.m_pLow[cDim], e.m_pNode->m_ptrMBR[cChild]->getExtrapolatedLow(cDim, tmpRegion.m_startTime));
+ tmpRegion.m_pHigh[cDim] = std::max(tmpRegion.m_pHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->getExtrapolatedHigh(cDim, tmpRegion.m_startTime));
+ tmpRegion.m_pVLow[cDim] = std::min(tmpRegion.m_pVLow[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pVLow[cDim]);
+ tmpRegion.m_pVHigh[cDim] = std::max(tmpRegion.m_pVHigh[cDim], e.m_pNode->m_ptrMBR[cChild]->m_pVHigh[cDim]);
+ }
+ tmpRegion.m_pLow[cDim] -= 2.0 * std::numeric_limits<double>::epsilon();
+ tmpRegion.m_pHigh[cDim] += 2.0 * std::numeric_limits<double>::epsilon();
+ }
+
+ if (! (tmpRegion == e.m_pNode->m_nodeMBR))
+ {
+ std::cerr << "Invalid parent information." << std::endl;
+ ret = false;
+ }
+ if (! (tmpRegion == e.m_parentMBR))
+ {
+ std::cerr << "Error in parent." << std::endl;
+ ret = false;
+ }
+
+ if (e.m_pNode->m_level != 0)
+ {
+ for (uint32_t cChild = 0; cChild < e.m_pNode->m_children; ++cChild)
+ {
+ NodePtr ptrN = readNode(e.m_pNode->m_pIdentifier[cChild]);
+ ValidateEntry tmpEntry(*(e.m_pNode->m_ptrMBR[cChild]), ptrN);
+
+ std::map<uint32_t, uint32_t>::iterator itNodes = nodesInLevel.find(tmpEntry.m_pNode->m_level);
+
+ if (itNodes == nodesInLevel.end())
+ {
+ nodesInLevel.insert(std::pair<uint32_t, uint32_t>(tmpEntry.m_pNode->m_level, 1l));
+ }
+ else
+ {
+ nodesInLevel[tmpEntry.m_pNode->m_level] = nodesInLevel[tmpEntry.m_pNode->m_level] + 1;
+ }
+
+ st.push(tmpEntry);
+ }
+ }
+ }
+
+ uint32_t nodes = 0;
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_treeHeight; ++cLevel)
+ {
+ if (nodesInLevel[cLevel] != m_stats.m_nodesInLevel[cLevel])
+ {
+ std::cerr << "Invalid nodesInLevel information." << std::endl;
+ ret = false;
+ }
+
+ nodes += m_stats.m_nodesInLevel[cLevel];
+ }
+
+ if (nodes != m_stats.m_nodes)
+ {
+ std::cerr << "Invalid number of nodes information." << std::endl;
+ ret = false;
+ }
+
+ return ret;
+}
+
+void SpatialIndex::TPRTree::TPRTree::getStatistics(IStatistics** out) const
+{
+ *out = new Statistics(m_stats);
+}
+
+void SpatialIndex::TPRTree::TPRTree::initNew(Tools::PropertySet& ps)
+{
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != TPRV_RSTAR))
+ throw Tools::IllegalArgumentException("initNew: Property TreeVariant must be Tools::VT_LONG and of TPRTreeVariant type");
+
+ m_treeVariant = static_cast<TPRTreeVariant>(var.m_val.lVal);
+ }
+
+ // fill factor
+ // it cannot be larger than 50%, since linear and quadratic split algorithms
+ // require assigning to both nodes the same number of entries.
+ var = ps.getProperty("FillFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property FillFactor must be Tools::VT_DOUBLE and in (0.0, 1.0) for RSTAR");
+
+ m_fillFactor = var.m_val.dblVal;
+ }
+
+ // horizon
+ var = ps.getProperty("Horizon");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal == std::numeric_limits<double>::max())
+ throw Tools::IllegalArgumentException("initNew: Property Horizon must be Tools::VT_DOUBLE and a positive constant");
+
+ m_horizon = var.m_val.dblVal;
+ }
+
+ // index capacity
+ var = ps.getProperty("IndexCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property IndexCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_indexCapacity = var.m_val.ulVal;
+ }
+
+ // leaf capacity
+ var = ps.getProperty("LeafCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG || var.m_val.ulVal < 4)
+ throw Tools::IllegalArgumentException("initNew: Property LeafCapacity must be Tools::VT_ULONG and >= 4");
+
+ m_leafCapacity = var.m_val.ulVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initNew: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initNew: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // dimension
+ var = ps.getProperty("Dimension");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be Tools::VT_ULONG");
+ if (var.m_val.ulVal <= 1)
+ throw Tools::IllegalArgumentException("initNew: Property Dimension must be greater than 1");
+
+ m_dimension = var.m_val.ulVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL)
+ throw Tools::IllegalArgumentException("initNew: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG)
+ throw Tools::IllegalArgumentException("initNew: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+
+ m_stats.m_treeHeight = 1;
+ m_stats.m_nodesInLevel.push_back(0);
+
+ Leaf root(this, -1);
+ m_rootID = writeNode(&root);
+
+ storeHeader();
+}
+
+void SpatialIndex::TPRTree::TPRTree::initOld(Tools::PropertySet& ps)
+{
+ loadHeader();
+
+ // only some of the properties may be changed.
+ // the rest are just ignored.
+
+ Tools::Variant var;
+
+ // tree variant
+ var = ps.getProperty("TreeVariant");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_LONG ||
+ (var.m_val.lVal != TPRV_RSTAR))
+ throw Tools::IllegalArgumentException("initOld: Property TreeVariant must be Tools::VT_LONG and of TPRTreeVariant type");
+
+ m_treeVariant = static_cast<TPRTreeVariant>(var.m_val.lVal);
+ }
+
+ // horizon
+ var = ps.getProperty("Horizon");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_DOUBLE ||
+ var.m_val.dblVal <= 0.0 ||
+ var.m_val.dblVal == std::numeric_limits<double>::max())
+ throw Tools::IllegalArgumentException("initOld: Property Horizon must be Tools::VT_DOUBLE and a positive constant");
+
+ m_horizon = var.m_val.dblVal;
+ }
+
+ // near minimum overlap factor
+ var = ps.getProperty("NearMinimumOverlapFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (
+ var.m_varType != Tools::VT_ULONG ||
+ var.m_val.ulVal < 1 ||
+ var.m_val.ulVal > m_indexCapacity ||
+ var.m_val.ulVal > m_leafCapacity)
+ throw Tools::IllegalArgumentException("initOld: Property NearMinimumOverlapFactor must be Tools::VT_ULONG and less than both index and leaf capacities");
+
+ m_nearMinimumOverlapFactor = var.m_val.ulVal;
+ }
+
+ // split distribution factor
+ var = ps.getProperty("SplitDistributionFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property SplitDistributionFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_splitDistributionFactor = var.m_val.dblVal;
+ }
+
+ // reinsert factor
+ var = ps.getProperty("ReinsertFactor");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_DOUBLE || var.m_val.dblVal <= 0.0 || var.m_val.dblVal >= 1.0)
+ throw Tools::IllegalArgumentException("initOld: Property ReinsertFactor must be Tools::VT_DOUBLE and in (0.0, 1.0)");
+
+ m_reinsertFactor = var.m_val.dblVal;
+ }
+
+ // tight MBRs
+ var = ps.getProperty("EnsureTightMBRs");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_BOOL) throw Tools::IllegalArgumentException("initOld: Property EnsureTightMBRs must be Tools::VT_BOOL");
+
+ m_bTightMBRs = var.m_val.blVal;
+ }
+
+ // index pool capacity
+ var = ps.getProperty("IndexPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property IndexPoolCapacity must be Tools::VT_ULONG");
+
+ m_indexPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // leaf pool capacity
+ var = ps.getProperty("LeafPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property LeafPoolCapacity must be Tools::VT_ULONG");
+
+ m_leafPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // region pool capacity
+ var = ps.getProperty("RegionPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property RegionPoolCapacity must be Tools::VT_ULONG");
+
+ m_regionPool.setCapacity(var.m_val.ulVal);
+ }
+
+ // point pool capacity
+ var = ps.getProperty("PointPoolCapacity");
+ if (var.m_varType != Tools::VT_EMPTY)
+ {
+ if (var.m_varType != Tools::VT_ULONG) throw Tools::IllegalArgumentException("initOld: Property PointPoolCapacity must be Tools::VT_ULONG");
+
+ m_pointPool.setCapacity(var.m_val.ulVal);
+ }
+
+ m_infiniteRegion.makeInfinite(m_dimension);
+}
+
+void SpatialIndex::TPRTree::TPRTree::storeHeader()
+{
+ const uint32_t headerSize =
+ sizeof(id_type) + // m_rootID
+ sizeof(TPRTreeVariant) + // m_treeVariant
+ sizeof(double) + // m_fillFactor
+ sizeof(uint32_t) + // m_indexCapacity
+ sizeof(uint32_t) + // m_leafCapacity
+ sizeof(uint32_t) + // m_nearMinimumOverlapFactor
+ sizeof(double) + // m_splitDistributionFactor
+ sizeof(double) + // m_reinsertFactor
+ sizeof(uint32_t) + // m_dimension
+ sizeof(char) + // m_bTightMBRs
+ sizeof(uint32_t) + // m_stats.m_nodes
+ sizeof(uint64_t) + // m_stats.m_data
+ sizeof(double) + // m_currentTime
+ sizeof(double) + // m_horizon
+ sizeof(uint32_t) + // m_stats.m_treeHeight
+ m_stats.m_treeHeight * sizeof(uint32_t);// m_stats.m_nodesInLevel
+
+ byte* header = new byte[headerSize];
+ byte* ptr = header;
+
+ memcpy(ptr, &m_rootID, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(ptr, &m_treeVariant, sizeof(TPRTreeVariant));
+ ptr += sizeof(TPRTreeVariant);
+ memcpy(ptr, &m_fillFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_indexCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_leafCapacity, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_nearMinimumOverlapFactor, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &m_splitDistributionFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_reinsertFactor, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_dimension, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c = (char) m_bTightMBRs;
+ memcpy(ptr, &c, sizeof(char));
+ ptr += sizeof(char);
+ memcpy(ptr, &(m_stats.m_nodes), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(ptr, &(m_stats.m_data), sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(ptr, &m_currentTime, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &m_horizon, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(ptr, &(m_stats.m_treeHeight), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_treeHeight; ++cLevel)
+ {
+ memcpy(ptr, &(m_stats.m_nodesInLevel[cLevel]), sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ }
+
+ m_pStorageManager->storeByteArray(m_headerID, headerSize, header);
+
+ delete[] header;
+}
+
+void SpatialIndex::TPRTree::TPRTree::loadHeader()
+{
+ uint32_t headerSize;
+ byte* header = 0;
+ m_pStorageManager->loadByteArray(m_headerID, headerSize, &header);
+
+ byte* ptr = header;
+
+ memcpy(&m_rootID, ptr, sizeof(id_type));
+ ptr += sizeof(id_type);
+ memcpy(&m_treeVariant, ptr, sizeof(TPRTreeVariant));
+ ptr += sizeof(TPRTreeVariant);
+ memcpy(&m_fillFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_indexCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_leafCapacity, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_nearMinimumOverlapFactor, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&m_splitDistributionFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_reinsertFactor, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_dimension, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ char c;
+ memcpy(&c, ptr, sizeof(char));
+ m_bTightMBRs = (c != 0);
+ ptr += sizeof(char);
+ memcpy(&(m_stats.m_nodes), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ memcpy(&(m_stats.m_data), ptr, sizeof(uint64_t));
+ ptr += sizeof(uint64_t);
+ memcpy(&m_currentTime, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&m_horizon, ptr, sizeof(double));
+ ptr += sizeof(double);
+ memcpy(&(m_stats.m_treeHeight), ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+
+ for (uint32_t cLevel = 0; cLevel < m_stats.m_treeHeight; ++cLevel)
+ {
+ uint32_t cNodes;
+ memcpy(&cNodes, ptr, sizeof(uint32_t));
+ ptr += sizeof(uint32_t);
+ m_stats.m_nodesInLevel.push_back(cNodes);
+ }
+
+ delete[] header;
+}
+
+void SpatialIndex::TPRTree::TPRTree::insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mr, id_type id)
+{
+ assert(mr.getDimension() == m_dimension);
+ assert(m_currentTime <= mr.m_startTime);
+
+ std::stack<id_type> pathBuffer;
+ byte* overflowTable = 0;
+
+ try
+ {
+ NodePtr root = readNode(m_rootID);
+
+ overflowTable = new byte[root->m_level];
+ bzero(overflowTable, root->m_level);
+
+ NodePtr l = root->chooseSubtree(mr, 0, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ l->insertData(dataLength, pData, mr, id, pathBuffer, overflowTable);
+
+ delete[] overflowTable;
+ ++(m_stats.m_data);
+ }
+ catch (...)
+ {
+ delete[] overflowTable;
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mr, id_type id, uint32_t level, byte* overflowTable)
+{
+ assert(mr.getDimension() == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+ NodePtr root = readNode(m_rootID);
+ NodePtr n = root->chooseSubtree(mr, level, pathBuffer);
+
+ assert(n->m_level == level);
+
+ if (n.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+ n->insertData(dataLength, pData, mr, id, pathBuffer, overflowTable);
+}
+
+bool SpatialIndex::TPRTree::TPRTree::deleteData_impl(const MovingRegion& mr, id_type id)
+{
+ assert(mr.m_dimension == m_dimension);
+
+ std::stack<id_type> pathBuffer;
+
+ NodePtr root = readNode(m_rootID);
+ NodePtr l = root->findLeaf(mr, id, pathBuffer);
+ if (l.get() == root.get())
+ {
+ assert(root.unique());
+ root.relinquish();
+ }
+
+ if (l.get() != 0)
+ {
+ Leaf* pL = static_cast<Leaf*>(l.get());
+ pL->deleteData(id, pathBuffer);
+ --(m_stats.m_data);
+ return true;
+ }
+
+ return false;
+}
+
+id_type SpatialIndex::TPRTree::TPRTree::writeNode(Node* n)
+{
+ byte* buffer;
+ uint32_t dataLength;
+ n->storeToByteArray(&buffer, dataLength);
+
+ id_type page;
+ if (n->m_identifier < 0) page = StorageManager::NewPage;
+ else page = n->m_identifier;
+
+ try
+ {
+ m_pStorageManager->storeByteArray(page, dataLength, buffer);
+ delete[] buffer;
+ }
+ catch (InvalidPageException& e)
+ {
+ delete[] buffer;
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("writeNode: failed with Tools::InvalidPageException");
+ }
+
+ if (n->m_identifier < 0)
+ {
+ n->m_identifier = page;
+ ++(m_stats.m_nodes);
+
+#ifndef NDEBUG
+ try
+ {
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel.at(n->m_level) + 1;
+ }
+ catch(...)
+ {
+ throw Tools::IllegalStateException("writeNode: writing past the end of m_nodesInLevel.");
+ }
+#else
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] + 1;
+#endif
+ }
+
+ ++(m_stats.m_writes);
+
+ for (size_t cIndex = 0; cIndex < m_writeNodeCommands.size(); ++cIndex)
+ {
+ m_writeNodeCommands[cIndex]->execute(*n);
+ }
+
+ return page;
+}
+
+SpatialIndex::TPRTree::NodePtr SpatialIndex::TPRTree::TPRTree::readNode(id_type id)
+{
+ uint32_t dataLength;
+ byte* buffer;
+
+ try
+ {
+ m_pStorageManager->loadByteArray(id, dataLength, &buffer);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("readNode: failed with Tools::InvalidPageException");
+ }
+
+ try
+ {
+ uint32_t nodeType;
+ memcpy(&nodeType, buffer, sizeof(uint32_t));
+
+ NodePtr n;
+
+ if (nodeType == PersistentIndex) n = m_indexPool.acquire();
+ else if (nodeType == PersistentLeaf) n = m_leafPool.acquire();
+ else throw Tools::IllegalStateException("readNode: failed reading the correct node type information");
+
+ if (n.get() == 0)
+ {
+ if (nodeType == PersistentIndex) n = NodePtr(new Index(this, -1, 0), &m_indexPool);
+ else if (nodeType == PersistentLeaf) n = NodePtr(new Leaf(this, -1), &m_leafPool);
+ }
+
+ //n->m_pTree = this;
+ n->m_identifier = id;
+ n->loadFromByteArray(buffer);
+
+ ++(m_stats.m_reads);
+
+ for (size_t cIndex = 0; cIndex < m_readNodeCommands.size(); ++cIndex)
+ {
+ m_readNodeCommands[cIndex]->execute(*n);
+ }
+
+ delete[] buffer;
+ return n;
+ }
+ catch (...)
+ {
+ delete[] buffer;
+ throw;
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::deleteNode(Node* n)
+{
+ try
+ {
+ m_pStorageManager->deleteByteArray(n->m_identifier);
+ }
+ catch (InvalidPageException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ //std::cerr << *this << std::endl;
+ throw Tools::IllegalStateException("deleteNode: failed with Tools::InvalidPageException");
+ }
+
+ --(m_stats.m_nodes);
+ m_stats.m_nodesInLevel[n->m_level] = m_stats.m_nodesInLevel[n->m_level] - 1;
+
+ for (size_t cIndex = 0; cIndex < m_deleteNodeCommands.size(); ++cIndex)
+ {
+ m_deleteNodeCommands[cIndex]->execute(*n);
+ }
+}
+
+void SpatialIndex::TPRTree::TPRTree::rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v)
+{
+ const MovingRegion* mr = dynamic_cast<const MovingRegion*>(&query);
+ if (mr == 0) throw Tools::IllegalArgumentException("rangeQuery: Shape has to be a moving region.");
+ if (mr->m_startTime < m_currentTime || mr->m_endTime >= m_currentTime + m_horizon)
+ throw Tools::IllegalArgumentException("rangeQuery: Query time interval does not intersect current horizon.");
+
+#ifdef HAVE_PTHREAD_H
+ Tools::SharedLock lock(&m_rwLock);
+#else
+ if (m_rwLock == false) m_rwLock = true;
+ else throw Tools::ResourceLockedException("rangeQuery: cannot acquire a shared lock");
+#endif
+
+ try
+ {
+ std::stack<NodePtr> st;
+ NodePtr root = readNode(m_rootID);
+
+ if (root->m_children > 0 && mr->intersectsRegionInTime(root->m_nodeMBR)) st.push(root);
+
+ while (! st.empty())
+ {
+ NodePtr n = st.top(); st.pop();
+
+ if (n->m_level == 0)
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ bool b;
+ if (type == ContainmentQuery) b = mr->containsRegionInTime(*(n->m_ptrMBR[cChild]));
+ else b = mr->intersectsRegionInTime(*(n->m_ptrMBR[cChild]));
+
+ if (b)
+ {
+ Data data = Data(n->m_pDataLength[cChild], n->m_pData[cChild], *(n->m_ptrMBR[cChild]), n->m_pIdentifier[cChild]);
+ v.visitData(data);
+ ++(m_stats.m_queryResults);
+ }
+ }
+ }
+ else
+ {
+ v.visitNode(*n);
+
+ for (uint32_t cChild = 0; cChild < n->m_children; ++cChild)
+ {
+ if (mr->intersectsRegionInTime(*(n->m_ptrMBR[cChild]))) st.push(readNode(n->m_pIdentifier[cChild]));
+ }
+ }
+ }
+
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ }
+ catch (...)
+ {
+#ifndef HAVE_PTHREAD_H
+ m_rwLock = false;
+#endif
+ throw;
+ }
+}
+
+std::ostream& SpatialIndex::TPRTree::operator<<(std::ostream& os, const TPRTree& t)
+{
+ os << "Dimension: " << t.m_dimension << std::endl
+ << "Fill factor: " << t.m_fillFactor << std::endl
+ << "Horizon: " << t.m_horizon << std::endl
+ << "Index capacity: " << t.m_indexCapacity << std::endl
+ << "Leaf capacity: " << t.m_leafCapacity << std::endl
+ << "Tight MBRs: " << ((t.m_bTightMBRs) ? "enabled" : "disabled") << std::endl;
+
+ if (t.m_treeVariant == TPRV_RSTAR)
+ {
+ os << "Near minimum overlap factor: " << t.m_nearMinimumOverlapFactor << std::endl
+ << "Reinsert factor: " << t.m_reinsertFactor << std::endl
+ << "Split distribution factor: " << t.m_splitDistributionFactor << std::endl;
+ }
+
+ if (t.m_stats.getNumberOfNodesInLevel(0) > 0)
+ os << "Utilization: " << 100 * t.m_stats.getNumberOfData() / (t.m_stats.getNumberOfNodesInLevel(0) * t.m_leafCapacity) << "%" << std::endl
+ << t.m_stats;
+
+ #ifndef NDEBUG
+ os << "Leaf pool hits: " << t.m_leafPool.m_hits << std::endl
+ << "Leaf pool misses: " << t.m_leafPool.m_misses << std::endl
+ << "Index pool hits: " << t.m_indexPool.m_hits << std::endl
+ << "Index pool misses: " << t.m_indexPool.m_misses << std::endl
+ << "Region pool hits: " << t.m_regionPool.m_hits << std::endl
+ << "Region pool misses: " << t.m_regionPool.m_misses << std::endl
+ << "Point pool hits: " << t.m_pointPool.m_hits << std::endl
+ << "Point pool misses: " << t.m_pointPool.m_misses << std::endl;
+ #endif
+
+ return os;
+}
diff --git a/sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.h b/sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.h
new file mode 100644
index 000000000..2c28727cd
--- /dev/null
+++ b/sci-libs/libspatialindex/svn/trunk/src/tprtree/TPRTree.h
@@ -0,0 +1,199 @@
+// Spatial Index Library
+//
+// Copyright (C) 2002 Navel Ltd.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Email:
+// mhadji@gmail.com
+
+#pragma once
+
+#include "Statistics.h"
+#include "Node.h"
+#include "PointerPoolNode.h"
+
+namespace SpatialIndex
+{
+ namespace TPRTree
+ {
+ class TPRTree : public ISpatialIndex
+ {
+ class NNEntry;
+
+ public:
+ TPRTree(IStorageManager&, Tools::PropertySet&);
+ // String Value Description
+ // ----------------------------------------------
+ // IndexIndentifier VT_LONG If specified an existing index will be openened from the supplied
+ // storage manager with the given index id. Behaviour is unspecified
+ // if the index id or the storage manager are incorrect.
+ // Dimension VT_ULONG Dimensionality of the data that will be inserted.
+ // IndexCapacity VT_ULONG The index node capacity. Default is 100.
+ // LeafCapactiy VT_ULONG The leaf node capacity. Default is 100.
+ // FillFactor VT_DOUBLE The fill factor. Default is 70%
+ // Horizon VT_DOUBLE Horizon. Default is 20.0.
+ // TreeVariant VT_LONG Can be one of Linear, Quadratic or Rstar. Default is Rstar
+ // NearMinimumOverlapFactor VT_ULONG Default is 32.
+ // SplitDistributionFactor VT_DOUBLE Default is 0.4
+ // ReinsertFactor VT_DOUBLE Default is 0.3
+ // EnsureTightMBRs VT_BOOL Default is true
+ // IndexPoolCapacity VT_LONG Default is 100
+ // LeafPoolCapacity VT_LONG Default is 100
+ // RegionPoolCapacity VT_LONG Default is 1000
+ // PointPoolCapacity VT_LONG Default is 500
+
+ virtual ~TPRTree();
+
+ //
+ // ISpatialIndex interface
+ //
+ virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier);
+ virtual bool deleteData(const IShape& shape, id_type id);
+ virtual void containsWhatQuery(const IShape& query, IVisitor& v);
+ virtual void intersectsWithQuery(const IShape& query, IVisitor& v);
+ virtual void pointLocationQuery(const Point& query, IVisitor& v);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator&);
+ virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v);
+ virtual void selfJoinQuery(const IShape& s, IVisitor& v);
+ virtual void queryStrategy(IQueryStrategy& qs);
+ virtual void getIndexProperties(Tools::PropertySet& out) const;
+ virtual void addCommand(ICommand* pCommand, CommandType ct);
+ virtual bool isIndexValid();
+ virtual void getStatistics(IStatistics** out) const;
+
+ private:
+ void initNew(Tools::PropertySet&);
+ void initOld(Tools::PropertySet& ps);
+ void storeHeader();
+ void loadHeader();
+
+ void insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id);
+ void insertData_impl(uint32_t dataLength, byte* pData, MovingRegion& mbr, id_type id, uint32_t level, byte* overflowTable);
+ bool deleteData_impl(const MovingRegion& mbr, id_type id);
+
+ id_type writeNode(Node*);
+ NodePtr readNode(id_type id);
+ void deleteNode(Node*);
+
+ void rangeQuery(RangeQueryType type, const IShape& query, IVisitor& v);
+
+ IStorageManager* m_pStorageManager;
+
+ id_type m_rootID, m_headerID;
+
+ TPRTreeVariant m_treeVariant;
+
+ double m_fillFactor;
+
+ uint32_t m_indexCapacity;
+
+ uint32_t m_leafCapacity;
+
+ uint32_t m_nearMinimumOverlapFactor;
+ // The R*-Tree 'p' constant, for calculating nearly minimum overlap cost.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.1]
+
+ double m_splitDistributionFactor;
+ // The R*-Tree 'm' constant, for calculating spliting distributions.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.2]
+
+ double m_reinsertFactor;
+ // The R*-Tree 'p' constant, for removing entries at reinserts.
+ // [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and Robust Access Method
+ // for Points and Rectangles', Section 4.3]
+
+ uint32_t m_dimension;
+
+ MovingRegion m_infiniteRegion;
+
+ Statistics m_stats;
+
+ bool m_bTightMBRs;
+
+ double m_currentTime;
+
+ double m_horizon;
+
+ Tools::PointerPool<Point> m_pointPool;
+ Tools::PointerPool<MovingRegion> m_regionPool;
+ Tools::PointerPool<Node> m_indexPool;
+ Tools::PointerPool<Node> m_leafPool;
+
+ std::vector<Tools::SmartPointer<ICommand> > m_writeNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_readNodeCommands;
+ std::vector<Tools::SmartPointer<ICommand> > m_deleteNodeCommands;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_rwlock_t m_rwLock;
+#else
+ bool m_rwLock;
+#endif
+
+ class NNEntry
+ {
+ public:
+ id_type m_id;
+ IEntry* m_pEntry;
+ double m_minDist;
+
+ NNEntry(id_type id, IEntry* e, double f) : m_id(id), m_pEntry(e), m_minDist(f) {}
+ ~NNEntry() {}
+
+ struct ascending : public std::binary_function<NNEntry*, NNEntry*, bool>
+ {
+ bool operator()(const NNEntry* __x, const NNEntry* __y) const { return __x->m_minDist > __y->m_minDist; }
+ };
+ }; // NNEntry
+
+ class NNComparator : public INearestNeighborComparator
+ {
+ public:
+ double getMinimumDistance(const IShape& query, const IShape& entry)
+ {
+ return query.getMinimumDistance(entry);
+ }
+
+ double getMinimumDistance(const IShape& query, const IData& data)
+ {
+ IShape* pS;
+ data.getShape(&pS);
+ double ret = query.getMinimumDistance(*pS);
+ delete pS;
+ return ret;
+ }
+ }; // NNComparator
+
+ class ValidateEntry
+ {
+ public:
+ ValidateEntry(MovingRegion& r, NodePtr& pNode) : m_parentMBR(r), m_pNode(pNode) {}
+
+ MovingRegion m_parentMBR;
+ NodePtr m_pNode;
+ }; // ValidateEntry
+
+ friend class Node;
+ friend class Leaf;
+ friend class Index;
+
+ friend std::ostream& operator<<(std::ostream& os, const TPRTree& t);
+ }; // TPRTree
+
+ std::ostream& operator<<(std::ostream& os, const TPRTree& t);
+ }
+}