关键词搜索

源码搜索 ×
×

漫话Redis源码之六十

发布2022-01-09浏览603次

详情内容

geo相关的函数,直接跳过吧,无非就是position相关的转换,没啥好看的。对理解整体的作用不大。

  1. int geohashDecode(const GeoHashRange long_range, const GeoHashRange lat_range,
  2. const GeoHashBits hash, GeoHashArea *area) {
  3. if (HASHISZERO(hash) || NULL == area || RANGEISZERO(lat_range) ||
  4. RANGEISZERO(long_range)) {
  5. return 0;
  6. }
  7. area->hash = hash;
  8. uint8_t step = hash.step;
  9. uint64_t hash_sep = deinterleave64(hash.bits); /* hash = [LAT][LONG] */
  10. double lat_scale = lat_range.max - lat_range.min;
  11. double long_scale = long_range.max - long_range.min;
  12. uint32_t ilato = hash_sep; /* get lat part of deinterleaved hash */
  13. uint32_t ilono = hash_sep >> 32; /* shift over to get long part of hash */
  14. /* divide by 2**step.
  15. * Then, for 0-1 coordinate, multiply times scale and add
  16. to the min to get the absolute coordinate. */
  17. area->latitude.min =
  18. lat_range.min + (ilato * 1.0 / (1ull << step)) * lat_scale;
  19. area->latitude.max =
  20. lat_range.min + ((ilato + 1) * 1.0 / (1ull << step)) * lat_scale;
  21. area->longitude.min =
  22. long_range.min + (ilono * 1.0 / (1ull << step)) * long_scale;
  23. area->longitude.max =
  24. long_range.min + ((ilono + 1) * 1.0 / (1ull << step)) * long_scale;
  25. return 1;
  26. }
  27. int geohashDecodeType(const GeoHashBits hash, GeoHashArea *area) {
  28. GeoHashRange r[2] = {{0}};
  29. geohashGetCoordRange(&r[0], &r[1]);
  30. return geohashDecode(r[0], r[1], hash, area);
  31. }
  32. int geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area) {
  33. return geohashDecodeType(hash, area);
  34. }
  35. int geohashDecodeAreaToLongLat(const GeoHashArea *area, double *xy) {
  36. if (!xy) return 0;
  37. xy[0] = (area->longitude.min + area->longitude.max) / 2;
  38. if (xy[0] > GEO_LONG_MAX) xy[0] = GEO_LONG_MAX;
  39. if (xy[0] < GEO_LONG_MIN) xy[0] = GEO_LONG_MIN;
  40. xy[1] = (area->latitude.min + area->latitude.max) / 2;
  41. if (xy[1] > GEO_LAT_MAX) xy[1] = GEO_LAT_MAX;
  42. if (xy[1] < GEO_LAT_MIN) xy[1] = GEO_LAT_MIN;
  43. return 1;
  44. }
  45. int geohashDecodeToLongLatType(const GeoHashBits hash, double *xy) {
  46. GeoHashArea area = {{0}};
  47. if (!xy || !geohashDecodeType(hash, &area))
  48. return 0;
  49. return geohashDecodeAreaToLongLat(&area, xy);
  50. }
  51. int geohashDecodeToLongLatWGS84(const GeoHashBits hash, double *xy) {
  52. return geohashDecodeToLongLatType(hash, xy);
  53. }
  54. static void geohash_move_x(GeoHashBits *hash, int8_t d) {
  55. if (d == 0)
  56. return;
  57. uint64_t x = hash->bits & 0xaaaaaaaaaaaaaaaaULL;
  58. uint64_t y = hash->bits & 0x5555555555555555ULL;
  59. uint64_t zz = 0x5555555555555555ULL >> (64 - hash->step * 2);
  60. if (d > 0) {
  61. x = x + (zz + 1);
  62. } else {
  63. x = x | zz;
  64. x = x - (zz + 1);
  65. }
  66. x &= (0xaaaaaaaaaaaaaaaaULL >> (64 - hash->step * 2));
  67. hash->bits = (x | y);
  68. }
  69. static void geohash_move_y(GeoHashBits *hash, int8_t d) {
  70. if (d == 0)
  71. return;
  72. uint64_t x = hash->bits & 0xaaaaaaaaaaaaaaaaULL;
  73. uint64_t y = hash->bits & 0x5555555555555555ULL;
  74. uint64_t zz = 0xaaaaaaaaaaaaaaaaULL >> (64 - hash->step * 2);
  75. if (d > 0) {
  76. y = y + (zz + 1);
  77. } else {
  78. y = y | zz;
  79. y = y - (zz + 1);
  80. }
  81. y &= (0x5555555555555555ULL >> (64 - hash->step * 2));
  82. hash->bits = (x | y);
  83. }
  84. void geohashNeighbors(const GeoHashBits *hash, GeoHashNeighbors *neighbors) {
  85. neighbors->east = *hash;
  86. neighbors->west = *hash;
  87. neighbors->north = *hash;
  88. neighbors->south = *hash;
  89. neighbors->south_east = *hash;
  90. neighbors->south_west = *hash;
  91. neighbors->north_east = *hash;
  92. neighbors->north_west = *hash;
  93. geohash_move_x(&neighbors->east, 1);
  94. geohash_move_y(&neighbors->east, 0);
  95. geohash_move_x(&neighbors->west, -1);
  96. geohash_move_y(&neighbors->west, 0);
  97. geohash_move_x(&neighbors->south, 0);
  98. geohash_move_y(&neighbors->south, -1);
  99. geohash_move_x(&neighbors->north, 0);
  100. geohash_move_y(&neighbors->north, 1);
  101. geohash_move_x(&neighbors->north_west, -1);
  102. geohash_move_y(&neighbors->north_west, 1);
  103. geohash_move_x(&neighbors->north_east, 1);
  104. geohash_move_y(&neighbors->north_east, 1);
  105. geohash_move_x(&neighbors->south_east, 1);
  106. geohash_move_y(&neighbors->south_east, -1);
  107. geohash_move_x(&neighbors->south_west, -1);
  108. geohash_move_y(&neighbors->south_west, -1);
  109. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载