mirror of
https://github.com/typesense/typesense.git
synced 2025-05-20 13:42:26 +08:00
Fix packing/unpacking of lat lng.
This commit is contained in:
parent
eca0d952e9
commit
1f6b4e3cd4
@ -505,18 +505,20 @@ struct sort_by {
|
||||
class GeoPoint {
|
||||
constexpr static const double EARTH_RADIUS = 3958.75;
|
||||
constexpr static const double METER_CONVERT = 1609.00;
|
||||
constexpr static const uint64_t MASK_H32_BITS = 0xffffffffUL;
|
||||
public:
|
||||
static int64_t pack_lat_lng(double lat, double lng) {
|
||||
static uint64_t pack_lat_lng(double lat, double lng) {
|
||||
// https://stackoverflow.com/a/1220393/131050
|
||||
int32_t ilat = lat * 1000000;
|
||||
int32_t ilng = lng * 1000000;
|
||||
int64_t lat_lng = (int64_t(ilat) << 32) | ilng;
|
||||
const int32_t ilat = lat * 1000000;
|
||||
const int32_t ilng = lng * 1000000;
|
||||
// during int32_t -> uint64_t, higher order bits will be 1, so we have to mask that
|
||||
const uint64_t lat_lng = (uint64_t(ilat) << 32) | (uint64_t)(ilng & MASK_H32_BITS);
|
||||
return lat_lng;
|
||||
}
|
||||
|
||||
static void unpack_lat_lng(int64_t packed_lat_lng, S2LatLng& latlng) {
|
||||
double lat = double(packed_lat_lng >> 32) / 1000000;
|
||||
double lng = double(packed_lat_lng & 0xffffffffUL) / 1000000;
|
||||
static void unpack_lat_lng(uint64_t packed_lat_lng, S2LatLng& latlng) {
|
||||
const double lat = double(int32_t((packed_lat_lng >> 32) & MASK_H32_BITS)) / 1000000;
|
||||
const double lng = double(int32_t(packed_lat_lng & MASK_H32_BITS)) / 1000000;
|
||||
latlng = S2LatLng::FromDegrees(lat, lng);
|
||||
}
|
||||
|
||||
|
@ -726,7 +726,9 @@ Option<nlohmann::json> Collection::search(const std::string & query, const std::
|
||||
return Option<nlohmann::json>(404, error);
|
||||
}
|
||||
|
||||
int64_t lat_lng = GeoPoint::pack_lat_lng(std::stod(geo_coords[0]), std::stod(geo_coords[1]));
|
||||
double lat = std::stod(geo_coords[0]);
|
||||
double lng = std::stod(geo_coords[1]);
|
||||
int64_t lat_lng = GeoPoint::pack_lat_lng(lat, lng);
|
||||
sort_field_std.name = actual_field_name;
|
||||
sort_field_std.geopoint = lat_lng;
|
||||
}
|
||||
|
@ -104,4 +104,23 @@ TEST(IndexTest, PointInPolygon180thMeridian) {
|
||||
|
||||
ASSERT_FALSE(Index::is_point_in_polygon(poly1, point4));
|
||||
ASSERT_FALSE(Index::is_point_in_polygon(poly1, point5));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IndexTest, GeoPointPackUnpack) {
|
||||
std::vector<std::pair<double, double>> latlngs = {
|
||||
{43.677223,-79.630556},
|
||||
{-0.041935, 65.433296}, // Indian Ocean Equator
|
||||
{-66.035056, 173.187202}, // Newzealand
|
||||
{-65.015656, -158.336234}, // Southern Ocean
|
||||
{84.552144, -159.742483}, // Arctic Ocean
|
||||
{84.517046, 171.730040} // Siberian Sea
|
||||
};
|
||||
|
||||
for(auto& latlng: latlngs) {
|
||||
int64_t packed_latlng = GeoPoint::pack_lat_lng(latlng.first, latlng.second);
|
||||
S2LatLng s2LatLng;
|
||||
GeoPoint::unpack_lat_lng(packed_latlng, s2LatLng);
|
||||
ASSERT_FLOAT_EQ(latlng.first, s2LatLng.lat().degrees());
|
||||
ASSERT_FLOAT_EQ(latlng.second, s2LatLng.lng().degrees());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user