geo_hash.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. ret.push_back(it->second);
  17. }
  18. }
  19. std::vector<uint64_t> geo_list::find_near(int x,int y,int dist,uint64_t card_no)
  20. {
  21. int t=1;
  22. while(t<dist) t<<=1;
  23. int x0=x&~(t-1) , y0=y&~(t-1);
  24. std::vector<uint64_t> r;
  25. const int dist2=dist*dist;
  26. unsigned mask=~(t*t-1);
  27. find_near(r, x, y, ghash::encode(x0-t,y0-t), dist2, mask, card_no);
  28. find_near(r, x, y, ghash::encode(x0,y0-t), dist2, mask, card_no);
  29. find_near(r, x, y, ghash::encode(x0+t,y0-t), dist2, mask, card_no);
  30. find_near(r, x, y, ghash::encode(x0-t,y0), dist2, mask, card_no);
  31. find_near(r, x, y, ghash::encode(x0,y0), dist2, mask, card_no);
  32. find_near(r, x, y, ghash::encode(x0+t,y0), dist2, mask, card_no);
  33. find_near(r, x, y, ghash::encode(x0-t,y0+t), dist2, mask, card_no);
  34. find_near(r, x, y, ghash::encode(x0,y0+t), dist2, mask, card_no);
  35. find_near(r, x, y, ghash::encode(x0+t,y0+t), dist2, mask, card_no);
  36. return std::move(r);
  37. }
  38. std::vector<uint64_t> geo_list::find_near(uint64_t card_no,int dist)
  39. {
  40. std::vector<uint64_t> r;
  41. auto it=card2geo.find(card_no);
  42. if(it==card2geo.end())
  43. return std::move(r);
  44. auto h=ghash::decode(it->second);
  45. return find_near(std::get<0>(h),std::get<1>(h),dist,card_no);
  46. }
  47. void geo_list::update(int x,int y,uint64_t card_no)
  48. {
  49. unsigned h=ghash::encode(x,y);
  50. auto it=card2geo.find(card_no);
  51. if(it==card2geo.end())
  52. {
  53. card2geo.insert(std::make_pair(card_no,h));
  54. geo2card.insert(std::make_pair(h,card_no));
  55. }
  56. else
  57. {
  58. it->second=h;
  59. for(auto it1=geo2card.begin();it1!=geo2card.end();++it1)
  60. {
  61. if(it1->second==card_no)
  62. {
  63. geo2card.erase(it1);
  64. break;
  65. }
  66. }
  67. geo2card.insert(std::make_pair(h,card_no));
  68. }
  69. }