123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #include <stdio.h>
- #include <cstdlib>
- #include <random>
- #include <chrono>
- #include <vector>
- #include <spatialindex/capi/sidx_api.h>
- #include <spatialindex/capi/sidx_impl.h>
- #include <spatialindex/capi/sidx_config.h>
- using namespace std;
- using namespace SpatialIndex;
- struct MyPoint{
- double x;
- double y;
- double z;
- void init(double newX, double newY, double newZ) {
- x = newX;
- y = newY;
- z = newZ;
- }
- double distance(){
- return x * x + y * y + z * z ;
- }
- };
- const long long pointNum = 1000000; //节点数;
- const int knn = 100; //k近邻;
- long long queryNum = 1;
- vector<MyPoint> pointVector;
- double* generateRandomPoint() {
- std::random_device rd;
- std::mt19937_64 gen(rd());
- //范围
- std::uniform_real_distribution<double> dis(0, 10);
-
- double* coords = new double[3];
- coords[0] = dis(gen);
- coords[1] = dis(gen);
- coords[2] = dis(gen);
- //可注释
- MyPoint myPoint ;
- myPoint.init(coords[0], coords[1], coords[2]);
- pointVector.push_back(myPoint);
- //Print
- //for(int i = 0; i < 3; i++) cout<<coords[i]<<" "; printf("\n");
- return coords;
- }
- Index* createIndex()
- {
- // create a property set with default values.
- // see utility.cc for all defaults http://libspatialindex.github.io/doxygen/Utility_8cc_source.html#l00031
- Tools::PropertySet* ps = GetDefaults();
- Tools::Variant var;
- // set index type to R*-Tree
- var.m_varType = Tools::VT_ULONG;
- var.m_val.ulVal = RT_RTree;
- ps->setProperty("IndexType", var);
- // Set index to store in memory (default is disk)
- var.m_varType = Tools::VT_ULONG;
- var.m_val.ulVal = RT_Memory;
- ps->setProperty("IndexStorageType", var);
-
- var.m_varType = Tools::VT_ULONG;
- var.m_val.ulVal = 3;
- ps->setProperty("Dimension", var);
- // initialize index
- Index* idx = new Index(*ps);
- delete ps;
- // check index is ok
- if (!idx->index().isIndexValid())
- throw "Failed to create a valid index";
- else
- cout << "created index" << endl;
- return idx;
- }
- void addPoint(Index* idx, double x, double y, double z, int64_t id)
- {
- // create array with x, y, z coordinates
- //double coords[] = {x, y, z};
- double* coords = generateRandomPoint();
- // shapes can also have an object associated with them but we'll leave that for the moment.
- uint8_t* pData = 0;
- uint32_t nDataLength = 0;
- // create shape - three-dimensional
- SpatialIndex::IShape* shape = 0;
- shape = new SpatialIndex::Point(coords, 3);
- // insert into the index along with an object and an ID
- idx->index().insertData(nDataLength, pData, *shape, id);
- //Print
- //cout << "Point " << id << " inserted into the index.";
- delete shape;
- delete[] coords;
- }
- std::vector<SpatialIndex::IData*>* getNearest(Index* idx, double x, double y, double z, long long k)
- {
- double coords[] = {x, y, z};
- // get a visitor object and a point from which to search
- ObjVisitor* visitor = new ObjVisitor;
- // make the point from x, y, z coordinates
- SpatialIndex::Point* r = new SpatialIndex::Point(coords, 3);
- // get nearest maxResults shapes from the index
- idx->index().nearestNeighborQuery(k, *r, *visitor);
- // get the count of results
- int64_t nResultCount;
- nResultCount = visitor->GetResultCount();
- // get the actual results
- std::vector<SpatialIndex::IData*>& results = visitor->GetResults();
- // an empty vector that we will copy the results to
- vector<SpatialIndex::IData*>* resultsCopy = new vector<SpatialIndex::IData*>();
- // copy the items into the newly allocated vector array
- // we need to make sure to clone the actual item instead
- // of just the pointers, as the visitor will nuke them
- // upon destroy
- for (int64_t i = 0; i < nResultCount; ++i)
- {
- resultsCopy->push_back(dynamic_cast<SpatialIndex::IData*>(results[i]->clone()));
- }
- delete r;
- delete visitor;
- //Print
- //cout << "found " << nResultCount << " results." << endl;
- return resultsCopy;
- }
- int main(int argc, char* argv[])
- {
- cout<<"knn = "<< knn<<endl;
- try {
- // initialize the Index pointer
- Index* idx = createIndex();
- // add some points
- auto insertStart = std::chrono::high_resolution_clock::now();
- for(int i = 0; i < pointNum; i++) {
- addPoint(idx, 0,0,0, i);
- //Print
- //cout<<"distance:"<<pointVector[i].distance()<<endl;
- }
- auto insertEnd = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double> duration = insertEnd - insertStart;
- double insertTime = duration.count();
- cout<< "插入数据花费的时间为"<< insertTime << "秒"<<"("<<pointNum<<")"<<endl;
-
- // get the nearest two locations to the royal albert hall
- auto queryStart = std::chrono::high_resolution_clock::now();
- for(int i = 0 ; i<queryNum; i++){
- double* coords = generateRandomPoint();
- std::vector<SpatialIndex::IData*>* results = getNearest(idx, coords[0], coords[1], coords[2], knn);
- delete[] coords;
- }
- auto queryEnd = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double> duration2 = queryEnd - queryStart;
- double queryTime = duration2.count();
- cout<< "查询数据花费的时间为"<< queryTime << "秒"<<"("<<queryNum<<")"<<endl;
- /*//Print
- if(knn <= pointNum){
- for(SpatialIndex::IData* point : *results){
- int id = point->getIdentifier();
- cout<<"最近的n个点:"<<id;
- cout<<"("<<pointVector[id].x<<", "<<pointVector[id].y<<", "<<pointVector[id].z<<")"<<endl;
- }//endfor
- }//endif
- */
- }//end try
- catch (const char* ex) {
- cout << "Exception: " << ex << endl;
- }
- return 0;
- }
- //g++ xxx.cpp -o xxx -I/home/marioh/usr/include -L/home/marioh/usr/lib -lspatialindex
|