【发布时间】:2021-02-04 14:08:09
【问题描述】:
我正在尝试从 OpenStreetMap 计算节点所在的给定图块,以便我可以手动将节点直接添加到 current_nodes 表中。如果我想在纬度 X 和经度 Y 添加一个新节点,我可以在插入 current_nodes 表之前计算所需的“平铺”值。
我正在尝试将当前的 PostgreSQL 函数转换为 C#,但它没有给出预期的输出。我不确定我是否正确转换了它,或者我是否遗漏了什么。
//maptile_for_point(scaled_lat bigint, scaled_lon bigint, zoom integer)
DECLARE
lat CONSTANT DOUBLE PRECISION := scaled_lat / 10000000.0;
lon CONSTANT DOUBLE PRECISION := scaled_lon / 10000000.0;
zscale CONSTANT DOUBLE PRECISION := 2.0 ^ zoom;
pi CONSTANT DOUBLE PRECISION := 3.141592653589793;
r_per_d CONSTANT DOUBLE PRECISION := pi / 180.0;
x int4;
y int4;
BEGIN
-- straight port of the C code. see db/functions/maptile.c
x := floor((lon + 180.0) * zscale / 360.0);
y := floor((1.0 - ln(tan(lat * r_per_d) + 1.0 / cos(lat * r_per_d)) / pi) * zscale / 2.0);
RETURN (x << zoom) | y;
END;
到目前为止,我有:
public const double pi = 3.141592653589793;
public const double r_per_d = pi / 180.0;
public static long GetTile(double scaled_lat, double scaled_lon, int zoom)
{
double lat = scaled_lat / 10000000.0;
double lon = scaled_lon / 10000000.0;
return GetTile(lat, lon, zoom);
}
public static long GetTile(long lat, long lon, int zoom)
{
double zscale = Math.Pow(2.0, zoom);
long x = (long)Math.Floor((lon + 180.0) * zscale / 360.0);
long y = (long)Math.Floor((1.0 - Math.Log(Math.Tan(lat * r_per_d) + 1.0 / Math.Cos(lat * r_per_d)) / pi) * zscale / 2.0);
return (x << zoom) | y;
}
我调用了该函数,但循环了可能的缩放值,但没有一个与预期的输出匹配。
使用表中已有的数据(526868344,-18000386),它应该返回 2062343892。
for (int i = 0; i < int.MaxValue; i++)
{
var r1 = NodeTileHelper.GetTile(526868344, -18000386, i);
if (r1 == 2062343892)
{
;
}
}
【问题讨论】:
-
有趣的事实:也无需声明自己的Pi:您能分享一些示例输入、预期输出和实际输出吗?
-
您是否比较了您使用的每个数学函数的结果?
-
您好,感谢您的回复。我在底部添加了输入和输出。 (526868344, -18000386) 应该返回 2062343892。我将添加文本以使其更清晰。
-
返回值在 c# 中没有多大意义:return (x
-
我没有发现差异; dotnetfiddle.net/4U8y62 vs dbfiddle.uk/… 虽然我确实将 GetTile 拆分为两部分;无法弄清楚您为什么这样做 - 您使用的缩放值是多少?
标签: c# postgresql openstreetmap .net-core-3.1