Package: rtreecpy
rtree.cAnR-treeimplementation in C.FeaturesSupports any number of dimensionsGeneric interface with support for variable sized itemsANSI C (C99)Supports custom allocatorsRobust, self-contained testsPretty darn good performance 🚀Example#include<stdio.h>#include<string.h>#include<math.h>#include"rtree.h"structcity{char*name;doublelat;doublelon;};structcityphx={.name="Phoenix",.lat=33.448,.lon=-112.073};structcityenn={.name="Ennis",.lat=52.843,.lon=-8.986};structcitypra={.name="Prague",.lat=50.088,.lon=-14.420};structcitytai={.name="Taipei",.lat=25.033,.lon=121.565};structcityher={.name="Hermosillo",.lat=29.102,.lon=-110.977};structcityhim={.name="Himeji",.lat=34.816,.lon=134.700};boolcity_iter(constdouble*rect,constvoid*item,void*udata){conststructcity*city=item;printf("%s\n",city->name);returntrue;}intmain(){// create a new rtree where each item is a `struct city*`.structrtree*tr=rtree_new(sizeof(structcity*),2);// load some cities into the rtree. Each set operation performs a copy of// the data that is pointed to in the second and third arguments.// The R-tree expects a rectangle, which is an array of doubles, that// has the first N values as the minimum corner of the rect, and the next// N values as the maximum corner of the rect, where N is the number of// dimensions provided to rtree_new(). For points the the min and max// values should match.rtree_insert(tr,(double[]){phx.lon,phx.lat,phx.lon,phx.lat},&phx);rtree_insert(tr,(double[]){enn.lon,enn.lat,enn.lon,enn.lat},&enn);rtree_insert(tr,(double[]){pra.lon,pra.lat,pra.lon,pra.lat},&pra);rtree_insert(tr,(double[]){tai.lon,tai.lat,tai.lon,tai.lat},&tai);rtree_insert(tr,(double[]){her.lon,her.lat,her.lon,her.lat},&her);rtree_insert(tr,(double[]){him.lon,him.lat,him.lon,him.lat},&him);printf("\n-- Northwestern cities --\n");rtree_search(tr,(double[]){-180,0,0,90},city_iter,NULL);printf("\n-- Northeastern cities --\n");rtree_search(tr,(double[]){0,0,180,90},city_iter,NULL);// deleting an item is the same insertingrtree_delete(tr,(double[]){phx.lon,phx.lat,phx.lon,phx.lat},&phx);printf("\n-- Northwestern cities --\n");rtree_search(tr,(double[]){-180,0,0,90},city_iter,NULL);rtree_free(tr);}// output:// -- northwest cities --// Phoenix// Ennis// Prague// Hermosillo//// -- northeast cities --// Taipei// Himeji//// -- northwest cities --// Ennis// Prague// HermosilloFunctionsrtree_new# allocate a new rtreertree_free# free the rtreertree_count# return number of itemsrtree_insert# insert an itemrtree_delete# delete an itemrtree_search# search the rtreeAlgorithmsThis implementation is avariantof the original paper:R-TREES. A DYNAMIC INDEX STRUCTURE FOR SPATIAL SEARCHINGTesting and benchmarksThertree.cfile also contains robust testing and benchmark code.$cc-DRTREE_TESTrtree.c&&./a.out# run tests$cc-DRTREE_TEST-O3rtree.c&&BENCH=1./a.out# run benchmarksThe following benchmarks were run on my 2019 Macbook Pro (2.4 GHz 8-Core Intel Core i9) using gcc-9. One million random (evenly distributed) rectangles are inserted, searched, and deleted.insert   1000000 ops in 0.406 secs, 406 ns/op, 2462496 op/sec
search   1000000 ops in 0.936 secs, 936 ns/op, 1068225 op/sec
delete   1000000 ops in 0.901 secs, 901 ns/op, 1109395 op/secLicensertree.c source code is available under the MIT License.