简体   繁体   English

Postgresql 函数到 C#

[英]Postgresql function to C#

I'm trying to calculate the given tile a node is in from OpenStreetMap so that I can manually add nodes directly into the current_nodes table.我正在尝试从 OpenStreetMap 计算节点所在的给定图块,以便我可以手动将节点直接添加到 current_nodes 表中。 If I want to add a new node at latitude X and longitude Y, I can then calculate the 'tile' value that's needed before inserting into the current_nodes table.如果我想在纬度 X 和经度 Y 添加一个新节点,则可以在插入 current_nodes 表之前计算所需的“tile”值。

I'm trying to convert the current PostgreSQL function into C# but it's not giving the output expected.我正在尝试将当前的 PostgreSQL 函数转换为 C#,但它没有给出预期的输出。 I'm not sure I've converted it correctly or if I'm missing something.我不确定我是否正确转换了它,或者我是否遗漏了什么。

//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;

So far I have:到目前为止,我有:

 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;
 }

I call the function but loop through possible zoom values but none of them are matching the expected output.我调用该函数但循环遍历可能的缩放值,但没有一个与预期的输出匹配。

Using data that's already in the table (526868344, -18000386) it should return 2062343892.使用表中已有的数据 (526868344, -18000386) 应返回 2062343892。

for (int i = 0; i < int.MaxValue; i++)
{
    var r1 = NodeTileHelper.GetTile(526868344, -18000386, i);
    if (r1 == 2062343892)
    {
        ;
    }
}

It looks like the problem might be how the method overloads are defined.看起来问题可能在于方法重载是如何定义的。

The following snippet of code is going to call the GetTile(long, long, int) overload, so it may not account for the scaling that is present in the other method.以下代码片段将调用GetTile(long, long, int)重载,因此它可能不考虑其他方法中存在的缩放。

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

In addition the following code in the scaling method recursively calls itself, because of the variable declarations.此外,由于变量声明,缩放方法中的以下代码递归调用自身。 In order to account for the different method, you will need to convert lat and lon to long types.为了说明不同的方法,您需要将latlon转换为long类型。

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

Given the original stored procedure definition, I think it would make more sense to consolidate this into one method instead of using overloads.鉴于原始存储过程定义,我认为将其合并为一种方法而不是使用重载会更有意义。 Alternately, I think using different names for the methods would make it clearer than simply using the difference between parameter types (eg,. long vs. double ).或者,我认为为方法使用不同的名称会比简单地使用参数类型之间的差异(例如, longdouble )更清晰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM