像这样存储在数据库 gps 位置的最佳数据格式是什么:
38°57'33.804"
95°15'55.739"
我无法将其转换为其他格式。
数据库:PozstgrSQL 9.4
像这样存储在数据库 gps 位置的最佳数据格式是什么:
38°57'33.804"
95°15'55.739"
我无法将其转换为其他格式。
数据库:PozstgrSQL 9.4
你检查过 PostGIS 吗?它是为这样的
存储数据的最佳方式完全取决于您要对数据执行的操作。
例如,如果您正在存储世界上城镇的 GPS 坐标并且只是想查找它们,那么您可以完全按原样存储它。在这种情况下,绝对不需要操作或比较数据。
但是,如果您想比较数据,例如查找附近的城镇,您最好将其存储在一种允许比较容易的方式中。鉴于这些值是六十进制(以 60 为底),可能最简单的方法是转换如下:
38°57'33.804" (38 degrees, 57 minutes, 33.804 seconds)
= (38 * 60 + 57) * 60 + 33) * 1000 + 804
= 140,253,804
对于最大范围-180..180
,您最终会得到一个± 324,000,000
很容易适合 32 位有符号整数的值。
My first thought would be to store the position as decimal degrees.
If that is unacceptable and you need to store DMS, you could store it either as a VARCHAR, or even "convert" it all to decimal thousandths of a second and store it as an integer, that way you keep your precision.
最好的格式是
1) 转换为十进制度数:例如 -73,123456
2) 然后乘以 1E7 (10000000)
3) 转换或四舍五入为整数
这是一个只需要 4 个字节的有符号整数,坐标粒度在几毫米的范围内。
但这也取决于您的目标是什么:以最小空间存储海量数据?看上面。
或可通过查询访问的数据:
然后我将使用 Postgres 为坐标提供的格式
这将是我的建议。它有点笨重,所以请耐心等待。您也可以在 C 中做得更好。然而,这是一种基于 SQL 的方法。如果不使用基于 C 的方法,您会失去快速轻松地将其转换为特定输出格式的能力。
CREATE TYPE degminsec AS (
deg int,
min int,
sec numeric
);
CREATE OR REPLACE FUNCTION decdeg_to_degminsec(numeric) RETURNS degminsec
LANGUAGE SQL AS $$
SELECT floor($1),
floor(($1 - floor($1)) * 60),
($1 * 60 - floor($1 * 60)) * 60;
$$;
CREATE OR REPLACE FUNCTION display(degminsec) RETURNS text
LANGUAGE SQL AS $$
SELECT $1.deg || '°' || $1.min || '''' || $1.sec || '"';
$$;
这种方法的主要缺点是您将拥有一个难以索引的类型,并且您必须在输出时对其进行转换。除了 btree 索引之外,这只是项目的开始。如果你不转换输出,而不是 38°57'33.804" 你会得到(38,57,33.804)
现在,您可能会认为这太麻烦了,但请注意,如果您继续存储十进制坐标,您仍然可以在输出时将其转换为显示格式,这可能会解决您的问题。有了上面的内容,如果你不是一次格式化很多这些,你可以:
SELECT display(decdeg_to_degminsec(mycoord)) from mytable;
但是为此目的编写另一个语法上更易于阅读的函数会更容易。
这取决于你想对数据做什么。
如果您只想存储它,我建议使用 varchar。在每一边使用 $$ 而不是单引号来转义字符串。
如果您想使用数据,您可以创建自己的用户定义数据类型 (UDT)。