【问题标题】:Postgresql function to C#Postgresql 函数到 C#
【发布时间】: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


【解决方案1】:

看起来问题可能在于方法重载的定义方式。

以下代码 sn-p 将调用 GetTile(long, long, int) 重载,因此它可能无法解释其他方法中存在的缩放。

NodeTileHelper.GetTile(526868344, -18000386, i);

此外,由于变量声明,缩放方法中的以下代码递归调用自身。为了考虑不同的方法,您需要将latlon 转换为long 类型。

double lat, lon;
// ...
return GetTile(lat, lon, zoom);

鉴于最初的存储过程定义,我认为将其合并为一种方法而不是使用重载会更有意义。或者,我认为为方法使用不同的名称比简单地使用参数类型之间的差异(例如,longdouble)更清楚。

【讨论】:

    猜你喜欢
    • 2013-11-27
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 2017-09-29
    • 1970-01-01
    • 2015-10-30
    相关资源
    最近更新 更多