geo_hash.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "geo_hash.h"
  2. void geo_list::find_near(std::vector<uint64_t>&ret,int x,int y,unsigned h,uint32_t dist2,unsigned mask,uint64_t card_no)
  3. {
  4. for(auto it=geo2card.lower_bound(h);it!=geo2card.end();++it)
  5. {
  6. if((it->first&mask)!=h)
  7. break;
  8. auto pos=ghash::decode(it->first);
  9. int xi=std::get<0>(pos);
  10. int yi=std::get<1>(pos);
  11. unsigned sn = (xi-x)*(xi-x)+(yi-y)*(yi-y);
  12. if(sn > dist2)
  13. continue;
  14. if (card_no==it->second)
  15. continue;
  16. //std::stringstream ss;
  17. //ss<<"-----LemonHash---findnear---cardid"<<card_no<<"x:"<<x<<"y:"<<y<<"dist2:"<<dist2<<" cardid:"<<it->second<<"x:"<<xi<<"y:"<<yi<<"sn"<<sn;
  18. //debug_print_syslog(0,"%s",ss.str().c_str());
  19. ret.push_back(it->second);
  20. }
  21. }
  22. std::vector<uint64_t> geo_list::find_near(int x,int y,int dist,uint64_t card_no)
  23. {
  24. int t=1;
  25. while(t<dist) t<<=1;
  26. int x0=x&~(t-1) , y0=y&~(t-1);
  27. std::vector<uint64_t> r;
  28. const int dist2=dist*dist;
  29. unsigned mask=~(t*t-1);
  30. find_near(r,x,y,ghash::encode(x0-t,y0-t),dist2,mask,card_no);
  31. find_near(r,x,y,ghash::encode(x0,y0-t),dist2,mask,card_no);
  32. find_near(r,x,y,ghash::encode(x0+t,y0-t),dist2,mask,card_no);
  33. find_near(r,x,y,ghash::encode(x0-t,y0),dist2,mask,card_no);
  34. find_near(r,x,y,ghash::encode(x0,y0),dist2,mask,card_no);
  35. find_near(r,x,y,ghash::encode(x0+t,y0),dist2,mask,card_no);
  36. find_near(r,x,y,ghash::encode(x0-t,y0+t),dist2,mask,card_no);
  37. find_near(r,x,y,ghash::encode(x0,y0+t),dist2,mask,card_no);
  38. find_near(r,x,y,ghash::encode(x0+t,y0+t),dist2,mask,card_no);
  39. return std::move(r);
  40. }
  41. //std::vector<std::string> find_near(const char*card_no,int dist)
  42. std::vector<uint64_t> geo_list::find_near(uint64_t card_no,int dist)
  43. {
  44. std::vector<uint64_t> r;
  45. auto it=card2geo.find(card_no);
  46. if(it==card2geo.end())
  47. return std::move(r);
  48. auto h=ghash::decode(it->second);
  49. return find_near(std::get<0>(h),std::get<1>(h),dist,card_no);
  50. }
  51. //void update(int x,int y,const char*card_no)
  52. void geo_list::update(int x,int y,uint64_t card_no)
  53. {
  54. //std::stringstream ss;
  55. unsigned h=ghash::encode(x,y);
  56. //ss<<"-----LemonHash--update--"<<card_no<<"x:"<<x<<"y:"<<y<<"h:"<<h;
  57. //debug_print_syslog(0,"%s",ss.str().c_str());
  58. auto it=card2geo.find(card_no);
  59. if(it==card2geo.end())
  60. {
  61. card2geo.insert(std::make_pair(card_no,h));
  62. geo2card.insert(std::make_pair(h,card_no));
  63. }
  64. else
  65. {
  66. it->second=h;
  67. for(auto it1=geo2card.begin();it1!=geo2card.end();++it1)
  68. {
  69. if(it1->second==card_no)
  70. {
  71. geo2card.erase(it1);
  72. break;
  73. }
  74. }
  75. geo2card.insert(std::make_pair(h,card_no));
  76. }
  77. }