1
0
Fork 0
arangodb/UnitTests/Geo/georeg.cpp

1353 lines
40 KiB
C++

////////////////////////////////////////////////////////////////////////
/// @brief geo index
///
/// @file
///
/// DISCLAIMER
///
/// Copyright by triAGENS GmbH - All rights reserved.
///
/// The Programs (which include both the software and documentation)
/// contain proprietary information of triAGENS GmbH; they are
/// provided under a license agreement containing restrictions on use and
/// disclosure and are also protected by copyright, patent and other
/// intellectual and industrial property laws. Reverse engineering,
/// disassembly or decompilation of the Programs, except to the extent
/// required to obtain interoperability with other independently created
/// software or as specified by law, is prohibited.
///
/// The Programs are not intended for use in any nuclear, aviation, mass
/// transit, medical, or other inherently dangerous applications. It shall
/// be the licensee's responsibility to take all appropriate fail-safe,
/// backup, redundancy, and other measures to ensure the safe use of such
/// applications if the Programs are used for such purposes, and triAGENS
/// GmbH disclaims liability for any damages caused by such use of
/// the Programs.
///
/// This software is the confidential and proprietary information of
/// triAGENS GmbH. You shall not disclose such confidential and
/// proprietary information and shall use it only in accordance with the
/// terms of the license agreement you entered into with triAGENS GmbH.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author R. A. Parker
/// @author Copyright 2011, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
/* regression testing program for GeoIndex module */
/* R.A.P. 2.1 8.1.2012 */
#include <boost/test/unit_test.hpp>
#include "GeoIndex/GeoIndex.h"
#include "Basics/StringUtils.h"
using namespace arangodb::basics;
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
char ix[1000]; /* working array for (void *) data */
char iy[30];
int np[20]={14676,23724,24457,24785,24809,
25909,25051,27052,25192,28126,
25191,29291,25079,30338,24852,
31320,24565,31936,24133,31893};
int hs[20]={16278595,6622245,83009659,97313687,94638085,
86998272,72133969,99595673,76554853,116384443,
458789,67013205,44378533,97387502,97331554,
76392514,43104144,48695421,87361440,1556675} ;
int np1[10]={6761,13521,20282,27042,33803,
40563,47324,54084,60845,67605};
int hs1[10]={79121168,71376992,120173779,54504134,89075457,
50229904,41454125,104395668,14196041,106196305};
int hs2[10]={21216619,99404510,92771863,40046216,25926851,
6056147,93877377,82650316,14776130,41666384};
int np4[4]={2838,5116,5180,9869};
int hs4[4]={33972992,9770664,11661062,28398735};
int hs5[4]={79685116,67516870,19274248,35037618};
static GeoIndex * gi;
static GeoCursor * gcr;
static GeoCoordinate gcp;
static GeoCoordinate gcp1, gcp2, gcp3, gcp4;
static GeoCoordinates * list1;
static double la,lo;
static double d1;
static int i,j,r;
static void* nullp = 0;
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
static void MyFree (GeoIndex * gi) {
int x;
x=GeoIndex_INDEXVALID(gi);
BOOST_CHECK_EQUAL(x, 0);
GeoIndex_free(gi);
}
int GCCHECK (GeoCoordinates * gc, int ct, char const * bytes) {
int i,good;
for(i=0;i<1000;i++) ix[i]=0;
for(i=0;i<(int) gc->length;i++)
*((char *)gc->coordinates[i].data)=1;
for(i=0;i<25;i++)
iy[i]='A'+ix[4*i]+2*ix[4*i+1]+4*ix[4*i+2]+8*ix[4*i+3];
iy[25]=0;
good=1;
for(i=0;i<25;i++) if(bytes[i]!=iy[i]) good=0;
GeoIndex_CoordinatesFree(gc);
return good;
}
int GCMASS (GeoCoordinates * gc, int ct, int hash) {
int i,j;
for(i=0;i<1000;i++) ix[i]=0;
for(i=0;i<(int) gc->length;i++)
(*((char *)gc->coordinates[i].data))++;
j=0;
for(i=0;i<1000;i++)
{
j=j+ix[i];
j=j*7;
j=j%123456791;
}
if(hash!=j)
{
for(i=0;i<(int) gc->length;i++)
{
printf("long %14.9f",gc->coordinates[i].longitude);
printf(" lat %14.9f",gc->coordinates[i].latitude);
printf(" dat %4d",(int)((char *)gc->coordinates[i].data-ix));
printf(" dist %12.1f \n",gc->distances[i]);
}
printf("Correct hash is %d\n",j);
}
GeoIndex_CoordinatesFree(gc);
return hash == j ? 1 : 0;
}
double tolerance (double a, double b, double c) {
if (c == 0.0) {
return 0.00000001;
}
else {
if (a == 0.0) {
if (b == 0.0) {
return 0.001;
}
else {
return c / b * 100.0;
}
}
else {
return c / a * 100.0;
}
}
}
#define icheck(e, a, b) \
BOOST_TEST_CHECKPOINT(StringUtils::itoa((e))); \
BOOST_CHECK_EQUAL((long) (a), (long) (b))
#define pcheck(e, a, b) \
BOOST_TEST_CHECKPOINT(StringUtils::itoa((e))); \
BOOST_CHECK_EQUAL((a), (b))
#define dcheck(e, a, b, c) \
BOOST_TEST_CHECKPOINT(StringUtils::itoa((e))); \
BOOST_CHECK_CLOSE((a), (b), tolerance((a),(b),(c)))
#define gccheck(e, gc, ct, bytes) \
BOOST_TEST_CHECKPOINT(StringUtils::itoa((e))); \
BOOST_CHECK_EQUAL((long) (ct),(long) (gc)->length); \
BOOST_CHECK_EQUAL(GCCHECK((gc), (ct), (bytes)), 1)
#ifdef DEBUG
#define gicheck(e, gi) \
BOOST_TEST_CHECKPOINT(StringUtils::itoa((e))); \
BOOST_CHECK_EQUAL(GeoIndex_INDEXVALID((gi)), 0)
#else
#define gicheck(e, gi) /* do nothing */
#endif
#define gcmass(e, gc, ct, hash) \
BOOST_TEST_CHECKPOINT(StringUtils::itoa((e))); \
BOOST_CHECK_EQUAL((long) (ct), (long) (gc)->length); \
BOOST_CHECK_EQUAL(GCMASS((gc), (ct), (hash)), 1)
void coonum(GeoCoordinate * gc, int num)
{
double lat,lon;
int i,j;
j=num;
gc->latitude=-42.23994323;
gc->longitude=-53.40029372;
gc->data=&ix[num%997];
for(i=1;i<30;i++)
{
lat=0.0;
lon=0.0;
if( (j&1)==1 )
{
if(i==1) { lat=16.1543722; lon=12.1992384; }
if(i==2) { lat=6.14347227; lon=5.19923843; }
if(i==3) { lat=2.15237222; lon=3.19923843; }
if(i==4) { lat=1.51233226; lon=1.63122143; }
if(i==5) { lat=1.14347229; lon=1.69932121; }
if(i==6) { lat=0.93443431; lon=0.80023323; }
if(i==7) { lat=0.63443442; lon=0.79932032; }
if(i==8) { lat=0.70049323; lon=0.80076994; }
if(i==9) { lat=0.89223236; lon=0.78805238; }
if(i==10) { lat=0.85595656; lon=0.72332312; }
if(i==11) { lat=0.18823232; lon=0.21129576; }
if(i==12) { lat=0.12294854; lon=0.15543207; }
if(i==13) { lat=0.30984343; lon=0.18223745; }
if(i==14) { lat=0.19923412; lon=0.27345381; }
if(i==15) { lat=0.18223534; lon=0.15332087; }
if(i==16) { lat=0.09344343; lon=0.08002332; }
if(i==17) { lat=0.06344344; lon=0.07993203; }
if(i==18) { lat=0.07004932; lon=0.08007699; }
if(i==19) { lat=0.08922323; lon=0.07880523; }
if(i==20) { lat=0.08559565; lon=0.07233231; }
if(i==21) { lat=0.01882323; lon=0.02112957; }
if(i==22) { lat=0.01229485; lon=0.01554320; }
if(i==23) { lat=0.03098434; lon=0.01822374; }
if(i==24) { lat=0.01992341; lon=0.02734538; }
if(i==25) { lat=0.01822353; lon=0.01533208; }
if(i==26) { lat=0.00934434; lon=0.00800233; }
if(i==27) { lat=0.00634434; lon=0.00799320; }
if(i==28) { lat=0.00700493; lon=0.00800769; }
if(i==29) { lat=0.00480493; lon=0.00170769; }
}
gc->latitude+=lat;
gc->longitude+=lon;
j>>=1;
}
}
void litnum(GeoCoordinate * gc, int num)
{
coonum(gc,num);
gc->data=&ix[num%97];
return;
}
// -----------------------------------------------------------------------------
// --SECTION-- setup / tear-down
// -----------------------------------------------------------------------------
struct GeoIndexSetup {
GeoIndexSetup () {
BOOST_TEST_MESSAGE("setup GeoIndex");
}
~GeoIndexSetup () {
BOOST_TEST_MESSAGE("tear-down GeoIndex");
}
};
// -----------------------------------------------------------------------------
// --SECTION-- test suite
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief setup
////////////////////////////////////////////////////////////////////////////////
BOOST_FIXTURE_TEST_SUITE(GeoIndexTest, GeoIndexSetup)
/* 1-9 some real world distance */
/* 1 is London +51.500000 -0.166666 */
/* 2 is Honolulu +21.306111 -157.859722 */
/* 3 is Auckland -36.916667 +174.783333 */
/* 4 is Jo'burg -26.166667 +28.033333 */
/***********************************/
/* 1000-1100 first tests on cursor */
BOOST_AUTO_TEST_CASE (tst_geo1000) {
gi=GeoIndex_new();
la=41.23456789;
lo=39.87654321;
for(j=1;j<50;j++)
{
gcp.latitude = la;
gcp.longitude= lo;
gcp.data = &ix[j];
r = GeoIndex_insert(gi,&gcp);
icheck(1000,0,r);
la+=19.5396157761;
if(la>90.0) la-=180.0;
lo+=17.2329155421;
if(lo>180) lo-=360.0;
}
gcp.latitude = 0.0;
gcp.longitude= 25.5;
gcr = GeoIndex_NewCursor(gi,&gcp);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1001,list1,5, 87399654);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1002,list1,5, 97583446);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1003,list1,5, 30565728);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1004,list1,5, 77530526);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1005,list1,5, 38005425);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1006,list1,5, 106050772);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1007,list1,5, 51101201);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1008,list1,5, 83277910);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1009,list1,5, 53245966);
list1 = GeoIndex_ReadCursor(gcr,5);
gcmass(1010,list1,4, 86589238);
MyFree(gi);
}
/***************************************/
BOOST_AUTO_TEST_CASE (tst_geo1) {
gcp1.latitude = 51.5;
gcp1.longitude = -0.166666;
gcp2.latitude = 21.306111;
gcp2.longitude = -157.859722;
d1 = GeoIndex_distance(&gcp1, &gcp2);
dcheck(1,11624035.0, d1, 11000.0);
gcp3.latitude = -36.916667;
gcp3.longitude = 174.783333;
d1 = GeoIndex_distance(&gcp1, &gcp3);
dcheck(2,18332948.0, d1, 18000.0);
gcp4.latitude = -26.166667;
gcp4.longitude = +28.033333;
d1 = GeoIndex_distance(&gcp1, &gcp4);
dcheck(3,9059681.0, d1, 9000.0);
d1 = GeoIndex_distance(&gcp2, &gcp3);
dcheck(4,7076628.0, d1, 7000.0);
d1 = GeoIndex_distance(&gcp2, &gcp4);
dcheck(5,19194970.0, d1, 19000.0);
d1 = GeoIndex_distance(&gcp3, &gcp4);
dcheck(6,12177171.0, d1, 12000.0);
}
/* 10 - 19 */
/* first some easily recognizable GeoStrings */
/* mainly for debugging rather than regression */
BOOST_AUTO_TEST_CASE (tst_geo15) {
gi=GeoIndex_new();
GeoIndex_hint(gi,10); /* set it to "robust" mode */
for(i=0;i<50;i++)
{
gcp.latitude = 90.0;
gcp.longitude = 180.0;
gcp.data = ix + i;
r = GeoIndex_insert(gi,&gcp);
icheck(10,0,r);
}
gcp.latitude = 0.0;
gcp.longitude= 25.5;
gcr = GeoIndex_NewCursor(gi,&gcp);
list1 = GeoIndex_ReadCursor(gcr,1);
icheck(11,1,list1->length);
gcp.latitude = 89.9;
gcp.longitude = -180.0;
gcp.data = ix + 64;
GeoIndex_insert(gi,&gcp);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
gccheck(13,list1, 1,"AAAAAAAAAAAAAAAABAAAAAAAA");
gicheck(14,gi);
/*GeoIndex_INDEXDUMP(gi,stdout);*/
MyFree(gi);
}
BOOST_AUTO_TEST_CASE (tst_geo10) {
gi=GeoIndex_new();
GeoIndex_hint(gi,10); /* set it to "robust" mode */
for(i=0;i<50;i++)
{
gcp.latitude = 90.0;
gcp.longitude = 180.0;
gcp.data = ix + i;
r = GeoIndex_insert(gi,&gcp);
icheck(10,0,r);
}
gcp.latitude = 0.0;
gcp.longitude= 25.5;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
icheck(11,1,list1->length);
gcp.latitude = 89.9;
gcp.longitude = -180.0;
gcp.data = ix + 64;
GeoIndex_insert(gi,&gcp);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
gccheck(13,list1, 1,"AAAAAAAAAAAAAAAABAAAAAAAA");
gicheck(14,gi);
/*GeoIndex_INDEXDUMP(gi,stdout);*/
MyFree(gi);
}
/* 20 - 39 */
/* Make sure things work with an empty index */
BOOST_AUTO_TEST_CASE (tst_geo20) {
gi=GeoIndex_new();
/* do both searches with an empty index */
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
// gccheck(20,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,100000.0);
// gccheck(21,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
/* stick in Jo'burg */
gcp4.data=ix + 4;
r = GeoIndex_insert(gi,&gcp4);
icheck(22,0,r);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
gccheck(23,list1, 1,"ABAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,10000000.0);
gccheck(24,list1,1,"ABAAAAAAAAAAAAAAAAAAAAAAA");
/* then take it out again and repeat tests with empty index */
r = GeoIndex_remove(gi,&gcp4);
icheck(25,0,r);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,3);
// gccheck(26,list1, 0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,100000.0);
// gccheck(27,list1,0,"AAAAAAAAAAAAAAAAAAAAAAAAA");
BOOST_CHECK_EQUAL(nullp, list1); // no results, check against null pointer
/* try to delete from an empty index */
r = GeoIndex_remove(gi,&gcp2);
icheck(28,-1,r);
/* stick in Auckland into emptied index */
gcp3.data=ix + 3;
r = GeoIndex_insert(gi,&gcp3);
icheck(29,0,r);
gicheck(30,gi);
MyFree(gi);
}
/* */
/* 50 - 69 */
/* ========= */
/* */
/* now some tests on invalid data */
BOOST_AUTO_TEST_CASE (tst_geo50) {
gi=GeoIndex_new();
gcp.latitude = 91.2;
gcp.longitude = 40.0;
gcp.data = NULL;
i = GeoIndex_insert(gi,&gcp);
icheck(50,-3,i);
gcp.latitude = 90.000000001;
i = GeoIndex_insert(gi,&gcp);
icheck(51,-3,i);
gcp.latitude = 90.0;
i = GeoIndex_insert(gi,&gcp);
icheck(52,0,i);
gcp.latitude = 0.0;
i = GeoIndex_insert(gi,&gcp);
icheck(53,0,i);
gcp.latitude = -90.0;
i = GeoIndex_insert(gi,&gcp);
icheck(54,0,i);
gcp.latitude = -90.000000001;
i = GeoIndex_insert(gi,&gcp);
icheck(55,-3,i);
gcp.latitude = 333390.1;
i = GeoIndex_insert(gi,&gcp);
icheck(56,-3,i);
gcp.latitude = 40.2;
gcp.longitude = -333440.0;
i = GeoIndex_insert(gi,&gcp);
icheck(57,-3,i);
gcp.longitude = -181.0;
i = GeoIndex_insert(gi,&gcp);
icheck(58,-3,i);
gcp.longitude = -180.00000001;
i = GeoIndex_insert(gi,&gcp);
icheck(59,-3,i);
gcp.longitude = -180.0;
i = GeoIndex_insert(gi,&gcp);
icheck(60,0,i);
gcp.longitude = -81.0;
i = GeoIndex_insert(gi,&gcp);
icheck(61,0,i);
gcp.longitude = 0.0;
i = GeoIndex_insert(gi,&gcp);
icheck(62,0,i);
gcp.longitude = 180.0;
i = GeoIndex_insert(gi,&gcp);
icheck(63,0,i);
gcp.longitude = 180.00000001;
i = GeoIndex_insert(gi,&gcp);
icheck(64,-3,i);
gcp.latitude = 91.1;
gcp.longitude = 181.1;
i = GeoIndex_insert(gi,&gcp);
icheck(65,-3,i);
gicheck(66,gi);
MyFree(gi);
}
/* */
/* 70 - 99 */
/* ========= */
/* */
/* now some tests inserting and deleting in */
/* in some chaotic ways */
BOOST_AUTO_TEST_CASE (tst_geo70) {
gi=GeoIndex_new();
gcp.latitude = 0.0;
gcp.longitude = 40.0;
gcp.data = &ix[4];
i = GeoIndex_insert(gi,&gcp);
icheck(70,0,i);
gcp.data = &ix[5];
i = GeoIndex_remove(gi,&gcp);
icheck(71,-1,i);
gcp.longitude = 40.000001;
gcp.data = &ix[4];
i = GeoIndex_remove(gi,&gcp);
icheck(72,-1,i);
gcp.latitude = 0.0000000001;
gcp.longitude = 40.0;
i = GeoIndex_remove(gi,&gcp);
icheck(73,-1,i);
gcp.latitude = 0.0;
i = GeoIndex_remove(gi,&gcp);
icheck(74,0,i);
i = GeoIndex_remove(gi,&gcp);
icheck(75,-1,i);
for(j=1;j<=8;j++)
{
gcp.latitude = 0.0;
lo=j;
lo=lo*10;
gcp.longitude = lo;
gcp.data = &ix[j];
i = GeoIndex_insert(gi,&gcp);
icheck(76,0,i);
}
gcp.latitude = 0.0;
gcp.longitude= 25.5;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
icheck(77,1,list1->length);
dcheck(78,0.0,list1->coordinates[0].latitude,0.0);
dcheck(79,30.0,list1->coordinates[0].longitude,0.0);
pcheck(80,&ix[3],(char *)list1->coordinates[0].data);
gcp.longitude= 24.5;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
icheck(81,1,list1->length);
dcheck(82,0.0,list1->coordinates[0].latitude,0.0);
dcheck(83,20.0,list1->coordinates[0].longitude,0.0);
pcheck(84,&ix[2],(char *)list1->coordinates[0].data);
gcp.latitude = 1.0;
gcp.longitude = 40.0;
gcp.data = &ix[14];
i = GeoIndex_insert(gi,&gcp);
icheck(85,0,i);
gcp.longitude = 8000.0;
i = GeoIndex_insert(gi,&gcp);
icheck(86,-3,i);
gcp.latitude = 800.0;
gcp.longitude = 80.0;
i = GeoIndex_insert(gi,&gcp);
icheck(86,-3,i);
gcp.latitude = 800.0;
gcp.longitude = 80.0;
i = GeoIndex_remove(gi,&gcp);
icheck(87,-3,i);
gcp.latitude = 1.0;
gcp.longitude = 40.0;
gcp.data = &ix[14];
i = GeoIndex_remove(gi,&gcp);
icheck(88,0,i);
for(j=1;j<10;j++)
{
gcp.latitude = 0.0;
gcp.longitude = 40.0;
gcp.data = &ix[20+j];
i = GeoIndex_insert(gi,&gcp);
icheck(89,0,i);
}
for(j=1;j<10;j++)
{
gcp.latitude = 0.0;
gcp.longitude = 40.0;
gcp.data = &ix[20+j];
i = GeoIndex_remove(gi,&gcp);
icheck(90,0,i);
}
gcp.latitude = 0.0;
gcp.longitude= 35.5;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
icheck(91,1,list1->length);
dcheck(92,0.0,list1->coordinates[0].latitude,0.0);
dcheck(93,40.0,list1->coordinates[0].longitude,0.0);
pcheck(94,&ix[4],(char *)list1->coordinates[0].data);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,10);
gccheck(95,list1, 8,"OPBAAAAAAAAAAAAAAAAAAAAAA");
gcp.latitude = 0.0;
gcp.longitude = 20.0;
gcp.data = &ix[2];
i = GeoIndex_remove(gi,&gcp);
icheck(96,0,i);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,10);
gccheck(97,list1, 7,"KPBAAAAAAAAAAAAAAAAAAAAAA");
gicheck(98,gi);
MyFree(gi);
}
/* */
/* 100 - 199 */
/* ========= */
/* */
/* first main batch of tests */
/* insert 10 x 10 array of points near south pole */
/* then do some searches, results checked against */
/* the same run with full table scan */
BOOST_AUTO_TEST_CASE (tst_geo100) {
gi=GeoIndex_new();
la=-89.0;
for(i=0;i<10;i++)
{
gcp.latitude = la;
lo=17.0;
for(j=0;j<10;j++)
{
gcp.longitude = lo;
gcp.data = ix+(10*i+j);
r=GeoIndex_insert(gi,&gcp);
icheck(100,0,r);
lo+=1.0;
}
la+=1.0;
}
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,7);
gccheck(110,list1, 7,"AAAAAAAAAAAAAAAPHAAAAAAAA");
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,110);
gccheck(112,list1,100,"PPPPPPPPPPPPPPPPPPPPPPPPP");
gcp.latitude = -88.2;
gcp.longitude = 13.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,10);
gccheck(114,list1, 10,"AAMPPAAAAAAAAAAAAAAAAAAAA");
gcp.latitude = -83.2;
gcp.longitude = -163.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,2);
gccheck(116,list1, 2,"AADAAAAAAAAAAAAAAAAAAAAAA");
gcp.latitude = -87.2;
gcp.longitude = 13.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,1);
gccheck(118,list1, 1,"AAAAABAAAAAAAAAAAAAAAAAAA");
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,7);
gccheck(120,list1, 7,"AAAAAAAAAAAAAAAPHAAAAAAAA");
gcp.latitude = -83.7;
gcp.longitude = 19.7;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,7);
gccheck(122,list1, 7,"AAAAAAAAAAAAMPBAAAAAAAAAA");
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,50);
gccheck(124,list1, 50,"AAAAAAAAAAPPPPPPPPPPPPDAA");
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,11);
gccheck(126,list1, 11,"AAAAAAAAAAAAADAPPBAAAAAAA");
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_NearestCountPoints(gi,&gcp,4);
gccheck(128,list1, 4,"AAAAAAAAAAAAAAAOBAAAAAAAA");
gcp.latitude = -83.2;
gcp.longitude = 19.2;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,100000.0);
gccheck(150,list1,16,"AAAAAAAAAAAAMPAPPDAAAAAAA");
gicheck(151,gi);
MyFree(gi);
}
/* */
/* 200 - 299 */
/* ========= */
/* */
/* Batch of tests around the north pole, where */
/* the data is a known set of points, so that the */
/* distances can be computed manually */
BOOST_AUTO_TEST_CASE (tst_geo200) {
gi=GeoIndex_new();
for(i=1;i<=10;i++)
{
if(i==1)
{
gcp.latitude = 89.97989055;
gcp.longitude=-153.434948;
}
if(i==2)
{
gcp.latitude = 89.95978111;
gcp.longitude=-116.565051;
}
if(i==3)
{
gcp.latitude = 89.95978111;
gcp.longitude=153.434948;
}
if(i==4)
{
gcp.latitude = 89.87123674;
gcp.longitude=12.0947571;
}
if(i==5)
{
gcp.latitude = 89.85498874;
gcp.longitude=-7.1250163;
}
if(i==6)
{
gcp.latitude = 89.89746156;
gcp.longitude=-164.744881;
}
if(i==7)
{
gcp.latitude = 89.77516959;
gcp.longitude=163.739795;
}
if(i==8)
{
gcp.latitude = 89.8905928;
gcp.longitude=170.537677;
}
if(i==9)
{
gcp.latitude = 89.85498874;
gcp.longitude=-172.874983;
}
if(i==10)
{
gcp.latitude = 89.73367322;
gcp.longitude=168.310630;
}
gcp.data=&ix[i];
r = GeoIndex_insert(gi,&gcp);
icheck(201,0,r);
}
gcp1.latitude=89.95157004;
gcp1.longitude=21.8014095;
gcp2.latitude=89.86390794;
gcp2.longitude=172.405356;
gcp3.latitude=89.90961929;
gcp3.longitude=-174.289406;
d1=GeoIndex_distance(&gcp1,&gcp2);
dcheck(202,20000.0,d1,0.01); /* 20 Km */
d1=GeoIndex_distance(&gcp1,&gcp3);
dcheck(203,15297.058,d1,0.01); /* sqrt(234) Km */
d1=GeoIndex_distance(&gcp3,&gcp2);
dcheck(204,5830.952,d1,0.01); /* sqrt (34) Km */
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,1);
dcheck(205,7615.773,list1->distances[0],0.01); /* sqrt (58) Km */
gccheck(206,list1, 1,"CAAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_NearestCountPoints(gi,&gcp2,1);
dcheck(208,3000.0,list1->distances[0],0.01); /* 3 Km */
gccheck(209,list1, 1,"AABAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_NearestCountPoints(gi,&gcp3,1);
dcheck(211,2236.068,list1->distances[0],0.01); /* sqrt (5) Km */
gccheck(212,list1, 1,"AEAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,8000.0);
dcheck(214,7615.773,list1->distances[0],0.01); /* sqrt (58) Km */
gccheck(215,list1, 1,"CAAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_PointsWithinRadius(gi,&gcp2,3100.0);
dcheck(218,3000.0,list1->distances[0],0.01); /* 3 Km */
gccheck(219,list1, 1,"AABAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_PointsWithinRadius(gi,&gcp3,2400.0);
dcheck(221,2236.068,list1->distances[0],0.01); /* sqrt (5) Km */
gccheck(222,list1, 1,"AEAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,11000.0);
gccheck(224,list1, 4,"OBAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,13000.0);
gccheck(226,list1, 5,"ODAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,4);
gccheck(228,list1, 4,"OBAAAAAAAAAAAAAAAAAAAAAAA");
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,5);
if(list1->length==5)
{
for(i=0;i<5;i++)
{
j=( (char *) list1->coordinates[i].data) - ix;
if(j==1)
{
dcheck(230, 89.97989055,list1->coordinates[i].latitude,0.0);
dcheck(231,-153.434948,list1->coordinates[i].longitude,0.0);
dcheck(232,7615.773,list1->distances[i],0.01); /* S(58) */
}
if(j==2)
{
dcheck(233, 89.95978111,list1->coordinates[i].latitude,0.0);
dcheck(234,-116.565051,list1->coordinates[i].longitude,0.0);
dcheck(235,9219.544,list1->distances[i],0.01); /* S(85) */
}
if(j==3)
{
dcheck(236, 89.95978111,list1->coordinates[i].latitude,0.0);
dcheck(237,153.434948,list1->coordinates[i].longitude,0.0);
dcheck(238,9000.0,list1->distances[i],0.01); /* 9 */
}
if(j==4)
{
dcheck(239, 89.87123674,list1->coordinates[i].latitude,0.0);
dcheck(240,12.0947571,list1->coordinates[i].longitude,0.0);
dcheck(241,9055.385,list1->distances[i],0.01); /* S(82) */
}
if(j==5)
{
dcheck(242,89.85498874,list1->coordinates[i].latitude,0.0);
dcheck(243,-7.1250163,list1->coordinates[i].longitude,0.0);
dcheck(244,11704.700,list1->distances[i],0.01); /* S(137) */
}
}
}
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,13000.0);
if(list1->length==5)
{
for(i=0;i<5;i++)
{
j=( (char *) list1->coordinates[i].data) - ix;
if(j==1)
{
dcheck(250, 89.97989055,list1->coordinates[i].latitude,0.0);
dcheck(251,-153.434948,list1->coordinates[i].longitude,0.0);
dcheck(252,7615.773,list1->distances[i],0.01); /* S(58) */
}
if(j==2)
{
dcheck(253, 89.95978111,list1->coordinates[i].latitude,0.0);
dcheck(254,-116.565051,list1->coordinates[i].longitude,0.0);
dcheck(255,9219.544,list1->distances[i],0.01); /* S(85) */
}
if(j==3)
{
dcheck(256, 89.95978111,list1->coordinates[i].latitude,0.0);
dcheck(257,153.434948,list1->coordinates[i].longitude,0.0);
dcheck(258,9000.0,list1->distances[i],0.01); /* 9 */
}
if(j==4)
{
dcheck(259, 89.87123674,list1->coordinates[i].latitude,0.0);
dcheck(260,12.0947571,list1->coordinates[i].longitude,0.0);
dcheck(261,9055.385,list1->distances[i],0.01); /* S(82) */
}
if(j==5)
{
dcheck(262,89.85498874,list1->coordinates[i].latitude,0.0);
dcheck(263,-7.1250163,list1->coordinates[i].longitude,0.0);
dcheck(264,11704.700,list1->distances[i],0.01); /* S(137) */
}
}
}
gccheck(265,list1, 5,"ODAAAAAAAAAAAAAAAAAAAAAAA");
gicheck(266,gi);
MyFree(gi);
}
/* */
/* 300 - 399 */
/* ========= */
/* */
/* batch of massive tests. These are computed */
/* only by using (early versions of) this program */
/* so are more a way of checking it hasn't changed */
BOOST_AUTO_TEST_CASE (tst_geo300) {
gi=GeoIndex_new();
la=1.23456789;
lo=9.87654321;
for(i=1;i<=40000;i++)
{
gcp.latitude = la;
gcp.longitude= lo;
gcp.data = &ix[i%1000];
r = GeoIndex_insert(gi,&gcp);
icheck(300,0,r);
if(i==1322)
{
gcp.data=&ix[323];
r = GeoIndex_insert(gi,&gcp);
icheck(299,0,r);
}
la+=1.5394057761;
if(la>90.0) la-=180.0;
lo+=17.23223155421;
if(lo>180) lo-=360.0;
}
gcp1.latitude = -31.593944;
gcp1.longitude= -162.445323;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1130000.0);
gcmass(301,list1, 239, 32200456);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,54);
gcmass(303,list1,54,72071221);
gcp1.latitude = -11.423432;
gcp1.longitude= 102.612232;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,2130000.0);
gcmass(305,list1, 733, 48457753);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,91);
gcmass(307,list1,91,63984952);
gcp1.latitude = 17.593944;
gcp1.longitude= 67.812193;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,730000.0);
gcmass(309,list1, 85, 22185085);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,11);
gcmass(311,list1,11,82037911);
gcp1.latitude = 37.812212;
gcp1.longitude= 19.445323;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,7770000.0);
gcmass(313,list1, 14278, 119090367);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,1);
gcmass(315,list1,1,119956719);
gcp1.latitude = -89.100232;
gcp1.longitude= -179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,130000.0);
gcmass(317,list1, 215, 74977411);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,99);
gcmass(319,list1,99,112001146);
gcp1.latitude = 89.593944;
gcp1.longitude= 179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1130000.0);
gcmass(321,list1, 2256, 75029418);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,54);
gcmass(323,list1,54,36804959);
gcp1.latitude = 0.0;
gcp1.longitude= -179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,130000.0);
gcmass(325,list1, 2, 71248308);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,99);
gcmass(327,list1,99,112901191);
gcp1.latitude = 0.0;
gcp1.longitude= 179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1130000.0);
gcmass(329,list1, 198, 25827040);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,54);
gcmass(331,list1,54,307010);
gcp1.latitude = 40.0;
gcp1.longitude= -179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,130000.0);
gcmass(333,list1, 5, 21280562);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,99);
gcmass(335,list1,99,91097429);
gcp1.latitude = 40.0;
gcp1.longitude= 179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1130000.0);
gcmass(337,list1, 265, 24184562);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,54);
gcmass(339,list1,54,63183532);
gcp1.latitude = -40.0;
gcp1.longitude= -179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,130000.0);
gcmass(341,list1, 1, 19180182);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,99);
gcmass(343,list1,99,42678696);
gcp1.latitude = -40.0;
gcp1.longitude= 179.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1130000.0);
gcmass(345,list1, 255, 56578515);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,54);
gcmass(347,list1,54,78977277);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,754);
gcmass(349,list1,754,12017442);
gcp1.latitude = -10.0;
gcp1.longitude= 89.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1130000.0);
gcmass(351,list1, 203, 87076953);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,354);
gcmass(353,list1,354,2200966);
gcp1.latitude = -20.0;
gcp1.longitude= 79.999999;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,830000.0);
gcmass(355,list1, 116, 94145787);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,854);
gcmass(357,list1,854,55393902);
gcp1.latitude = 10.0;
gcp1.longitude= 49.0;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1830000.08);
gcmass(359,list1, 546, 36769740);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,154);
gcmass(361,list1,154,55726091);
gcp1.latitude = 55.0;
gcp1.longitude= 179.77;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,3130000.0);
gcmass(363,list1, 2934, 117773481);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,222);
gcmass(365,list1,222,26557002);
gcp1.latitude = 89.0;
gcp1.longitude= 179.9;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,930000.0);
gcmass(367,list1, 1857, 12304881);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,100);
gcmass(369,list1,100,67148848);
gcp1.latitude = -89.8;
gcp1.longitude= 0.0;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,880000.0);
gcmass(371,list1, 1756, 72919993);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,555);
gcmass(373,list1,555,49499403);
gcp1.latitude = 89.9;
gcp1.longitude= 0.0;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,3330000.0);
gcmass(375,list1, 6653, 85304684);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,101);
gcmass(377,list1,101,119146068);
gcp1.latitude = 45.0;
gcp1.longitude= 45.9;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,3330000.0);
gcmass(379,list1,2588,90353278);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,99);
gcmass(381,list1,99,26847261);
gcp1.latitude = -60.0;
gcp1.longitude= -45.00001;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,1730000.0);
gcmass(383,list1, 968, 26785900);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,2);
gcmass(385,list1,2,122455317);
gcp1.latitude = 44.999999;
gcp1.longitude= 45.0000001;
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,430000.0);
gcmass(387,list1, 45, 121133559);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,111);
gcmass(389,list1,111,15866065);
/*
if(mode==2)
{
BOOST_TEST_MESSAGE("start of 5000000 x points within radius 127 Km (3 found)");
for(i=0;i<10000;i++)
{
for(j=1;j<=500;j++)
{
coonum(&gcp1,j);
list1 = GeoIndex_PointsWithinRadius(gi,&gcp1,127000.0);
if (list1) {
// only free if pointer is valid
GeoIndex_CoordinatesFree(list1);
}
}
}
BOOST_TEST_MESSAGE("End of timing test");
}
if(mode==3)
{
BOOST_TEST_MESSAGE("start of 5000000 x points by count (2)");
for(i=0;i<10000;i++)
{
for(j=1;j<=500;j++)
{
coonum(&gcp1,j);
list1 = GeoIndex_NearestCountPoints(gi,&gcp1,2);
if (list1) {
// only free if pointer is valid
GeoIndex_CoordinatesFree(list1);
}
}
}
BOOST_TEST_MESSAGE("End of timing test");
}
*/
gicheck(390,gi);
MyFree(gi);
}
/* */
/* 400 - 499 */
/* ========= */
/* */
/* another batch of massive tests - again used as */
/* comparisons - this time between 1.1 and 2.0 */
BOOST_AUTO_TEST_CASE (tst_geo400) {
gi=GeoIndex_new();
la=41.23456789;
lo=39.87654321;
for(i=0;i<20;i++)
{
for(j=1;j<30000;j++)
{
gcp.latitude = la;
gcp.longitude= lo;
gcp.data = &ix[(7*i+j)%1000];
r = GeoIndex_insert(gi,&gcp);
icheck(400,0,r);
la+=19.5396157761;
if(la>90.0) la-=180.0;
lo+=17.2329155421;
if(lo>180) lo-=360.0;
}
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,9800000.0);
for(j=0;j<(int) list1->length;j++) /* delete before freeing list1! */
{
GeoIndex_remove(gi,list1->coordinates+j);
}
gcmass(400+5*i,list1, np[i], hs[i]);
}
MyFree(gi);
}
/* */
/* 500 - 599 */
/* ========= */
/* */
/* This set of tests aims to cluster the points in */
/* a sligtly more realistic way. */
BOOST_AUTO_TEST_CASE (tst_geo500) {
gi=GeoIndex_new();
for(i=1;i<135212;i++)
{
coonum(&gcp,i);
r = GeoIndex_insert(gi,&gcp);
icheck(501,0,r);
if( (i%2)==0)
{
coonum(&gcp,i/2);
r = GeoIndex_remove(gi,&gcp);
icheck(502,0,r);
}
if( (i%13521)==0)
{
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,9800000.0);
gcmass(505+4*(i/13521),list1,
np1[i/13521 - 1], hs1[i/13521 - 1]);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,i/1703);
gcmass(507+4*(i/13521),list1,i/1703,hs2[i/13521 - 1]);
}
}
MyFree(gi);
}
/* */
/* 600 - 649 */
/* ========= */
/* */
/* Test a very large database - too big for V1.2! */
BOOST_AUTO_TEST_CASE (tst_geo600) {
gi=GeoIndex_new();
for(i=1;i<21123212;i++)
{
coonum(&gcp,i);
r = GeoIndex_insert(gi,&gcp);
icheck(601,0,r);
if( (i%2)==0)
{
coonum(&gcp,i/2);
r = GeoIndex_remove(gi,&gcp);
icheck(602,0,r);
}
if( (i%4541672)==0)
{
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,9800.0);
gcmass(603+4*(i/4541672),list1,
np4[i/4541672 - 1], hs4[i/4541672 - 1]);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,i/1832703);
gcmass(605+4*(i/4541672),list1,i/1832703,hs5[i/4541672 - 1]);
}
}
MyFree(gi);
}
/* */
/* 650 - 699 */
/* ========= */
/* */
/* This set of tests puts in a few points, looks */
/* then puts in loads and deletes them again and */
/* looks again. Testing deletion balancing */
BOOST_AUTO_TEST_CASE (tst_geo650) {
gi=GeoIndex_new();
for(i=1;i<13;i++) /* put in points 1-12 */
{
litnum(&gcp,i);
r = GeoIndex_insert(gi,&gcp);
icheck(651,0,r);
}
litnum(&gcp,17);
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,984000.0);
gccheck(652,list1, 5,"KCKAAAAAAAAAAAAAAAAAAAAAA");
litnum(&gcp,16);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,4);
gccheck(654,list1, 4,"EBBBAAAAAAAAAAAAAAAAAAAAA");
for(i=100;i<80000;i++) /* put in points 100-80000 */
{
litnum(&gcp,i);
r = GeoIndex_insert(gi,&gcp);
icheck(655,0,r);
}
for(i=100;i<80000;i++) /* remove them again */
{
litnum(&gcp,i);
r = GeoIndex_remove(gi,&gcp);
icheck(656,0,r);
}
litnum(&gcp,17); /* see if it is all still OK */
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,984000.0);
gccheck(657,list1, 5,"KCKAAAAAAAAAAAAAAAAAAAAAA");
litnum(&gcp,16);
list1 = GeoIndex_NearestCountPoints(gi,&gcp,4);
gccheck(659,list1, 4,"EBBBAAAAAAAAAAAAAAAAAAAAA");
MyFree(gi);
}
/* */
/* 900 - 999 */
/* ========= */
/* */
/* tests that ensure old bugs have not reappeared */
/* forgot to allow for distance greater than pi.radius */
/* this went into sin(theta) to give small value, so it */
/* found that many points were not within 30000 Km */
BOOST_AUTO_TEST_CASE (tst_geo900) {
gi=GeoIndex_new();
la=41.23456789;
lo=39.87654321;
for(j=1;j<50;j++)
{
gcp.latitude = la;
gcp.longitude= lo;
gcp.data = &ix[j];
r = GeoIndex_insert(gi,&gcp);
icheck(900,0,r);
la+=19.5396157761;
if(la>90.0) la-=180.0;
lo+=17.2329155421;
if(lo>180) lo-=360.0;
}
list1 = GeoIndex_PointsWithinRadius(gi,&gcp,30000000.0);
gcmass(901,list1, 49, 94065911);
MyFree(gi);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generate tests
////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_SUITE_END ()
/* end of georeg.cpp */