纬度经度的哈希/密钥创建函数?

发布于 2024-08-11 00:23:40 字数 227 浏览 1 评论 0原文

我有与纬度/经度值相关的数据块。我想根据纬度/经度值创建一个查找键/哈希值,以便它可以用作地图或类似内容的查找。

我对西和南使用负值...因此 5W、10S 在程序中表示为 -5、-10。

如果可能的话,我希望能够从键值中获取纬度/经度值。

派生值必须是某种整数值。

我正在使用 C/C++ :)

谢谢,我很乐意回答任何问题!

I have blocks of data associated with latitude/longitude values. I'd like to create a lookup key/hash value from the latitude/longitude value so it can be used as a lookup into a map or something similar.

I'm using negative values for West and South... therefore 5W, 10S is represented as -5, -10 in the program.

I'd like to be able to get the latitude/longitude values back from the key value if possible.

The derived value MUST be some sort of integer value.

I'm using C/C++ :)

Thanks, I'll be happy to answer any questions!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

自演自醉 2024-08-18 00:23:40

您并不是真正在寻找哈希(哈希通常会分散底层键,并且它们也允许碰撞)。

相反,我认为像下面这样的简单公式就可以解决问题,而且它是可逆的。

[pseudo code]
Precision = 100       // lat and long precsion, boost to 1000 if need be
LatOffset = 1000      // Anithing above 180 would do

Key = ((int)(Lat * Precision) * LatOffset) + (int)(Long * Precision)

要反转

Long = (Key Modulo (LatOffset * Precision)) Div Precision
Lat  = (Key Div (LatOffset * Precision)) Div Precision )

编辑:哎呀,我没有注意到这是在C中。事实上,使用jheddings的解决方案(或其变体(要求“散列”键是整数)。

You are not really looking for a Hash (Hashes normally scatter the underlying keys, and also they allow for colisions).

Instead a simple formula like the following would do the trick, I think, and it is reversible.

[pseudo code]
Precision = 100       // lat and long precsion, boost to 1000 if need be
LatOffset = 1000      // Anithing above 180 would do

Key = ((int)(Lat * Precision) * LatOffset) + (int)(Long * Precision)

To reverse

Long = (Key Modulo (LatOffset * Precision)) Div Precision
Lat  = (Key Div (LatOffset * Precision)) Div Precision )

Edit: Oops, I didn't notice this was in C. Indeed, use jheddings' solution (or a variation thereof (with the requirement that the "hash" key be an integer).

゛清羽墨安 2024-08-18 00:23:40

正如 mjv 指出的那样,哈希通常会混淆原始输入数据。相反,听起来您只是想组合这些值。

为了简单起见,您只需为“哈希”定义一个新类型:

typedef struct {
    float lat;
    float lon;
} latlon;

您可以将其视为 64 位数字。并这样使用它:

float lat = -5.432;
float lon = 10.3423;
latlon pair = {
    .lat = lat,
    .lon = lon,
};

As mjv pointed out, a hash will typically obfuscate the original input data. Instead, it sounds like you are just looking to combine the values.

To keep it easy, you can just define a new type for your "hash":

typedef struct {
    float lat;
    float lon;
} latlon;

You can treat this as a 64-bit number. And use it as such:

float lat = -5.432;
float lon = 10.3423;
latlon pair = {
    .lat = lat,
    .lon = lon,
};
星光不落少年眉 2024-08-18 00:23:40

您 100% 确定散列在这里合适吗?仅当您知道要查找的键的确切值时,哈希查找才有效,并且(据我所知)纬度/经度值并不总是准确已知。

例如,假设您有一条记录存储在键 (-5.432, 10.3423) 下,而其他人想知道在 (-5.0, +10.0) 的 1.0 半径内存储了哪些记录。或者也许他们想查找记录,但由于计算中的浮点舍入,他们将 (-5.431999, 10.3423001) 作为键值。在这些情况下,哈希无法帮助您。要进行这种空间/不精确查找,您可能最好使用更专业的数据结构,例如八叉树(或其二维等效结构)。

Are you 100% sure hashing is appropriate here? Hash lookups only work if you know the exact value of the key you are looking for, and (AFAIK) latitude/longitude values are not always known precisely.

For example, say you have a record stored under key (-5.432, 10.3423) and someone else wants to know what records are stored within in a 1.0 radius of (-5.0, +10.0). Or perhaps they want to look up the record, but due to floating point roundoff in their calculations, they have (-5.431999, 10.3423001) as their key value. Hashing can't help you in those cases. To do that sort of spatial/inexact lookup, you'd probably be better off with a more specialized data structure like octrees (or their two-dimensional equivalent).

青衫负雪 2024-08-18 00:23:40

您还可以使用一些位操作将其很好地编码为 64 位整数,

经度范围从 -180 到 180,因此至少需要 9 位。
纬度范围从 -90 到 +90,因此至少需要 8 位。
分钟从 0 到 60,因此需要 6 位。
同样的几秒钟。

9+12 = 21 位用于经度,20 位用于纬度。

对于亚秒精度,您可以使用 11 位定点。这使您的精度可低至 2048 秒。

因此,要存储经度或纬度,您可以使用如下结构

struct ALatLong
{
    int angle:9;
    int minutes:6;
    int seconds:6;
    int subSeconds:11;
};

struct LatAndLong
{
    ALatLong longitude;
    ALatLong lattitude;
};

You could also encode it in nicely into a 64-bit integer using some bit manipulation

longitude ranges from -180 to 180 so needs a minimum of 9 bits.
lattitude rangs from -90 to +90 so needs a minimum of 8 bits.
minutes go from 0 to 60 so require 6 bits.
same for seconds.

9+12 = 21 bits for longitude and 20 bits for lattitude.

For subsecond precision you can then use 11 bit fixed point. this gives you accuracy down to a 2048th of a second.

SO to store a longitude or lattitude you could use a struct as follows

struct ALatLong
{
    int angle:9;
    int minutes:6;
    int seconds:6;
    int subSeconds:11;
};

struct LatAndLong
{
    ALatLong longitude;
    ALatLong lattitude;
};
来世叙缘 2024-08-18 00:23:40

简单的解决方案:从纬度/经度对中创建一个散列键,然后对其进行散列。那么如果你有钥匙,根据定义你就有了坐标。哈希键相当紧凑,例如,如果每个坐标值是 32 位整数,则为 8 个字节。

非平凡的解决方案:使用 空间哈希

Trivial solution: make a hash key out of the lat/long pair, and hash that. Then if you have the key, by definition you have the coordinates. Hash keys are fairly compact, e.g. eight bytes if each coordinate value is a 32-bit integer.

Non-trivial solution: use spatial hashing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文