在 C# 中使用电信 V&H 坐标





5.00/5 (5投票s)
AT&T 的垂直和水平坐标可用于计算费率中心和线路中心的纬度和经度以及它们之间的距离。
引言
在 20 世纪 50 年代末,Jay Donald 为 AT&T 开发了一个二维坐标系统,以便更容易地计算通话费,通话费是根据美国和加拿大两点之间的里程计算的。他的系统被称为 Donald 椭圆投影,它在覆盖北美大陆的网格上用垂直 (V) 和水平 (H) 值表示点。网格的原点(V,H = 0,0)位于北大西洋的北部,V 和 H 值分别向下和向左增加。0 到 10,000 的值覆盖了美国大陆和加拿大的大部分地区。该系统使得在现场使用计算尺轻松计算距离成为可能,这在 20 世纪 50 年代很重要。AT&T 开始使用该系统来定义适用特定通话费率的区域(即费率中心)。在 20 世纪 80 年代,该系统也被用于表示电信硬件的位置(即线路中心)。
背景
V&H 坐标系统仍用于在现代电信参考数据库中提供费率中心和线路中心的位置。例如,iconectiv(前身为 Telcordia)发布的 LERG(本地交换路由指南)在其 LERG7 表中包含线路中心的 V&H 坐标,在其 LERG8 表中包含费率中心的 V&H 坐标。CCMI 的 QTEL Telecom Suite 提供费率中心和线路中心信息,他们的网站提供了一种免费查找此信息的方式。例如,CCMI 的 NPA-NXX 费率中心查找页面显示了田纳西州纳什维尔的一些 NPA NXX 值的以下 V&H 坐标(其中 NPA = 电话区号,NXX = 中心局(交换)代码)
NPA NXX | 费率中心 | 线路中心 | 运营商 |
---|---|---|---|
615 829 | V: 7010 H: 2710 | V: 7011 H: 2704 | WINDSTREAM NUVOX-TN |
615 865 | V: 7010 H: 2710 | V: 6986 H: 2711 | BELLSOUTH TELECOM-TN |
此示例表明,两个 NPA NXX 值都位于同一费率中心,但它们使用不同的线路中心,因为它们属于不同的运营商。
虽然 V&H 坐标系统仍在使用,但在北美电信行业之外通常不使用。它不是一个很好的文档化系统,其与其他坐标系统的数学关系很复杂。Voip-info.org 和 Peter Dana 的 坐标系统概述简要提到了 V&H 坐标系统。然而,V&H 坐标系统唯一的详细参考指南可在 iconectiv 的 垂直和水平坐标页面上购买。该页面提供了一些背景信息和地图,以及购买 Telcordia 关于 V&H 坐标的说明:未解之谜的链接。该文档是一个 190 页的 PDF,目前售价 95 美元。它深入探讨了 V&H 坐标系统背后的复杂数学、它与纬度和经度的关系,以及距离计算如何以及为什么与它一起工作。
大多数 V&H 坐标的用户不再关心该系统背后的数学;他们只关心如何使用坐标进行距离和位置计算。凭借现代计算能力和测绘技术,将 V&H 坐标转换为纬度和经度,以及反之亦然,既快速又可取。这个过程很复杂,但 Bellcore(后来成为 Telcordia)的程序员在 20 世纪 90 年代提供了算法的免费 C 实现,并在 Usenet 新闻组(如 comp.dcom.telecom.tech)上提供。一位匿名的 Bellcore 员工创建了一个用于纬度和经度到 V&H 转换的 ll_to_vh.c 模块,后来由 Tom Libert 进行了改进。然后,Lucent/Bellcore 的 G.L. Sicherman 上校采用了 ll_to_vh 代码,并结合 Erik Grimmelmann 的内部 Bellcore 备忘录的笔记,编写了用于 V&H 到纬度和经度转换的 vh2ll.c 模块。
这些 ll_to_vh 和 vh2ll 模块是所有其他公开转换实现(包括本文中的实现)的基础。该 C 代码已被移植到至少 Java(此处和此处)、Python 和 Perl/XS,但我找不到 C# 的移植版本。鉴于这段历史很有趣,并且与我的日常工作有间接关系,我决定将 C 代码移植到 C# 并“清理”它,使其看起来和行为都像现代 C# 和 .NET 代码。
Using the Code
附加的 C# 代码定义了一个 VHPoint
结构,具有以下 API
public struct VHPoint : IEquatable<VHPoint>, IFormattable
{
public VHPoint(double vertical, double horizontal)
{
this.Vertical = vertical;
this.Horizontal = horizontal;
}
public VHPoint(GeoCoordinate coordinate)
{
// Note: This is based on the work of an anonymous
// Bellcore employee with later changes by Tom Libert.
...
}
public GeoCoordinate ToGeoCoordinate()
{
// Note: This is based on an original implementation
// by Col. G. L. Sicherman at Lucent (Bell Labs).
...
}
public double GetDistanceTo(VHPoint point, DistanceAlgorithm algorithm, DistanceUnit units)
{
...
}
public static readonly VHPoint Origin;
public double Vertical { get; }
public double Horizontal { get; }
// Other methods: operator==, operator!=, GetHashCode, Equals, ToString
...
}
VHPoint
提供了一个构造函数,该构造函数接受双精度 V&H 坐标。传统上,V&H 坐标在电信数据库中以整数形式存储。但是,V&H 算法对分数坐标也能很好地工作,因此没有理由将 API 限制为整数。如果需要,调用者可以通过 VHPoint
进行整数转换。
还有一个构造函数,它接受 .NET 4 的 GeoCoordinate 类的实例,以使用纬度和经度初始化 VHPoint
。内部,这使用了 Bellcore 的 ll_to_vh.c 模块中的算法将纬度和经度转换为 V&H 坐标。ToGeoCoordinate
方法补充了该构造函数,并提供了从 V&H 坐标到纬度和经度的转换。它使用 G.L. Sicherman 上校的 vh2ll.c 模块中的算法进行转换。
我很乐意对这些转换算法提供清晰、简洁的解释,但这超出了我的能力范围。Telcordia 的文档花了 190 页来解释算法背后的数学。我没有提供解释,而是试图提供一个清晰、简洁的 C 代码到 C# 的移植。我使用了 Visual Studio 的重构工具,在我认为可以使代码更清晰时安全地重命名变量和常量。但除此之外,我们仍然依赖原始 C 代码中关于代码功能和原因的稀疏注释。
GetDistanceTo
方法提供了三种不同的算法来估计两个 VHPoint
之间的距离。它可以以米、公里、国际英里或美国测量英里的单位返回距离。支持的距离算法是
- 短距离计算 – 这是使用 V&H 坐标计算距离的最快方法。计算公式为 Sqrt(((V1 – V2)2 + (H1 – H2)2) / 10)。
- 长距离计算 – 这是使用 V&H 坐标计算费率距离的一种更长、迭代的方法。它考虑了 V&H 网格单元的大小随着距离的增加而如何逐渐增大。
GeoCoordinate
– 计算距离最慢的方法。这会将 V&H 坐标转换为纬度和经度,然后使用 GeoCoordinate 的 GetDistanceTo 方法计算距离。
距离的“短距离计算”是 V&H 坐标使用的第一个算法,其简单性是创建 V&H 坐标系统的主要驱动因素。后来,随着计算能力的提高,人们设计了迭代的“长距离计算”,以提供更准确的费率里程估计。“GeoCoordinate
”算法仅作为现代替代方案提供;它不作为估算费率里程的传统方法。每种算法都会产生略有不同的估计值。
VHPoint
代码使用 C# 6 语法,可以在 Visual Studio 2015 或更高版本中编译。使用的一些 C# 6 特定功能是只读自动属性、表达式主体成员、using static、字符串插值和 nameof 表达式。VHPoint
仅使用 readonly
字段,因此实例是不可变的且线程安全的。它还实现了 <a href="https://msdn.microsoft.com/en-us/library/ms131187.aspx">IEquatable<VHPoint></a>
以及 ==
和 !=
运算符,以便于进行相等性检查。
这是一个使用德克萨斯州奥斯汀和田纳西州纳什维尔的 VHPoint
的简单示例。它使用“短距离计算”算法估算它们之间的里程。然后,它输出 V&H 坐标、纬度和经度坐标,以及它们之间的估算里程。
var austinTx = new VHPoint(9004, 3995);
var nashvilleTn = new VHPoint(7010, 2710);
var usMilesBetweenAustinAndNashville = austinTx.GetDistanceTo
(nashvilleTn, DistanceAlgorithm.ShortVHCalculation, DistanceUnit.InternationalMile);
WriteLine($"Austin, TX: {austinTx} ({austinTx.ToGeoCoordinate()})");
WriteLine($"Nashville, TN: {nashvilleTn} ({nashvilleTn.ToGeoCoordinate()})");
WriteLine($"Miles between: {usMilesBetweenAustinAndNashville:N1}");
输出结果如下
Austin, TX: {V=9004, H=3995} (30.2693702251436, -97.7325447113926)
Nashville, TN: {V=7010, H=2710} (36.1593150338062, -86.7734248612693)
Miles between: 750.2
Google 估计从奥斯汀到纳什维尔的驾车行程约为 865 英里。然而,上面的里程估计是沿着大圆进行的,这是飞机在两个城市之间的飞行路线,因此比驾车路线短。GPS Visualizer 估计奥斯汀机场 (AUS) 和纳什维尔机场 (BNA) 之间的直线距离为 756.1 英里。尽管上面的 V&H 坐标是市中心区域而不是机场,但我们可以看到 VHPoint
的里程估计相当准确。
测试用例
附加的 Program.cs 文件运行了 VHPoint
每个操作的几个测试用例,以验证每个操作的一致性和正确性。
Test(0, 0, 50.7305, -42.8054, "VH Grid Origin", "Upper North Atlantic Ocean");
Test(2207, 11384, 64.8383, -147.7024, "Fairbanks", "Alaska");
Test(3961, 1370, 44.3134, -69.7775, "Augusta", "Maine");
Test(5623, 5794, 47.8427, -100.6696, "Butte", "North Dakota");
Test(7010, 2710, 36.1593, -86.7734, "Nashville", "Tennessee");
Test(8351, 527, 25.7746, -80.1903, "Miami", "Florida");
Test(9004, 3995, 30.2693, -97.7325, "Austin", "Texas");
Test(9476, 7620, 32.6749, -117.1077, "National City", "California");
Test(11591, 15609, 21.3142, -157.8634, "Honolulu", "Hawaii");
Test(7944, -3044, 17.7467, -64.7082, "St Croix", "Virgin Islands");
Test
过程接受一对 V&H 坐标以及纬度和经度坐标,以确保 VHPoint
代码能够正确处理与纬度和经度的相互转换。它尝试反向地理编码纬度和经度,以确保该点位于预期的城市。它还将距离估计值(针对每种算法和单位)与已知点进行比较,以确保结果一致。
EnsureLongCalc(6272, 2992, 6130, 2925, 50, "Indianapolis to Muncie (Indiana)");
EnsureLongCalc(5536, 2828, 5461, 2993, 57, "Detroit to Flint (Michigan)");
EnsureLongCalc(8285, 4651, 7947, 4373, 141, "Eldorado to Oklahoma City (Oklahoma)");
EnsureLongCalc(7235, 4599, 7110, 4369, 85, "Abilene to Topeka (Kansas)");
EnsureLongCalc(5536, 2828, 5986, 3426, 238, "Detroit, MI to Chicago, IL");
EnsureLongCalc
方法对估算费率里程的“长距离计算”算法进行了其他检查。AT&T 的几本公开州电话指南(例如,密歇根、俄克拉荷马、堪萨斯)包含该算法和详细的测试用例,因此确保该算法能够正确处理这些情况很重要。
测试程序的完整输出是
Austin, TX: {V=9004, H=3995} (30.2693702251436, -97.7325447113926)
Nashville, TN: {V=7010, H=2710} (36.1593150338062, -86.7734248612693)
Miles between: 750.2
-------------------- VH Grid Origin, Upper North Atlantic Ocean --------------------
Given V&H: {V=0, H=0}
Given Lat/Long: 50.7305, -42.8054
Address: Reverse Geocoding Request Status: ZERO_RESULTS
Calculated Lat/Long: 50.7305527204251, -42.805421995133 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=50.7305527204251,-42.805421995133
Calculated V&H: {V=0.00272955582386203, H=-0.0115524752491183} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.00 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.00 mi
Distance To Downtown Nashville, TN Using Given V&H: 2376.65 mi
Distance To TN State Capitol Using Calculated Lat/Long: 2382.62 mi
-------------------- Fairbanks, Alaska --------------------
Given V&H: {V=2207, H=11384}
Given Lat/Long: 64.8383, -147.7024
Address: 300 Slater Dr, Fairbanks, AK 99701, USA
Calculated Lat/Long: 64.8383870101231, -147.702487081487 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=64.8383870101231,-147.702487081487
Calculated V&H: {V=2207.01982176852, H=11383.9990191629} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 3135.40 mi
Distance To TN State Capitol Using Calculated Lat/Long: 3146.15 mi
-------------------- Augusta, Maine --------------------
Given V&H: {V=3961, H=1370}
Given Lat/Long: 44.3134, -69.7775
Address: 98 Perham St, Augusta, ME 04330, USA
Calculated Lat/Long: 44.3134895095705, -69.7775311987667 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=44.3134895095705,-69.7775311987667
Calculated V&H: {V=3961.01136066591, H=1369.98383929929} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 1053.19 mi
Distance To TN State Capitol Using Calculated Lat/Long: 1056.72 mi
-------------------- Butte, North Dakota --------------------
Given V&H: {V=5623, H=5794}
Given Lat/Long: 47.8427, -100.6696
Address: 2901-2973 4th Ave NW, Butte, ND 58723, USA
Calculated Lat/Long: 47.8427878988344, -100.669606900516 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=47.8427878988344,-100.669606900516
Calculated V&H: {V=5623.01691999776, H=5793.9929727455} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 1069.34 mi
Distance To TN State Capitol Using Calculated Lat/Long: 1074.24 mi
-------------------- Nashville, Tennessee --------------------
Given V&H: {V=7010, H=2710}
Given Lat/Long: 36.1593, -86.7734
Address: 222 2nd Ave S, Nashville, TN 37201, USA
Calculated Lat/Long: 36.1593150338062, -86.7734248612693 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=36.1593150338062,-86.7734248612693
Calculated V&H: {V=7010.0003079036, H=2709.99485696478} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.00 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.00 mi
Distance To Downtown Nashville, TN Using Given V&H: 0.00 mi
Distance To TN State Capitol Using Calculated Lat/Long: 0.75 mi
-------------------- Miami, Florida --------------------
Given V&H: {V=8351, H=527}
Given Lat/Long: 25.7746, -80.1903
Address: 2-50 NE 2nd Ave, Miami, FL 33132, USA
Calculated Lat/Long: 25.7746122738116, -80.1903149887716 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=25.7746122738116,-80.1903149887716
Calculated V&H: {V=8351.00039400534, H=526.996302815198} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.00 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.00 mi
Distance To Downtown Nashville, TN Using Given V&H: 810.17 mi
Distance To TN State Capitol Using Calculated Lat/Long: 817.50 mi
-------------------- Austin, Texas --------------------
Given V&H: {V=9004, H=3995}
Given Lat/Long: 30.2693, -97.7325
Address: 965-1099 N Interstate 35 Frontage Rd, Austin, TX 78702, USA
Calculated Lat/Long: 30.2693702251436, -97.7325447113926 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=30.2693702251436,-97.7325447113926
Calculated V&H: {V=9004.01056278259, H=3994.9867130089} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 750.15 mi
Distance To TN State Capitol Using Calculated Lat/Long: 752.51 mi
-------------------- National City, California --------------------
Given V&H: {V=9476, H=7620}
Given Lat/Long: 32.6749, -117.1077
Address: 835-899 Roosevelt Ave, National City, CA 91950, USA
Calculated Lat/Long: 32.6749441711387, -117.10779765405 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=32.6749441711387,-117.10779765405
Calculated V&H: {V=9476.00600927168, H=7619.98059652587} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 1737.51 mi
Distance To TN State Capitol Using Calculated Lat/Long: 1739.43 mi
-------------------- Honolulu, Hawaii --------------------
Given V&H: {V=11591, H=15609}
Given Lat/Long: 21.3142, -157.8634
Address: 361 River St, Honolulu, HI 96817, USA
Calculated Lat/Long: 21.3142669712309, -157.863494374223 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=21.3142669712309,-157.863494374223
Calculated V&H: {V=11591.0212039459, H=15608.9826801904} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 4328.63 mi
Distance To TN State Capitol Using Calculated Lat/Long: 4337.12 mi
-------------------- St Croix, Virgin Islands --------------------
Given V&H: {V=7944, H=-3044}
Given Lat/Long: 17.7467, -64.7082
Address: Christiansted Harbor Seaplane Base (SSB), Christiansted, St Croix, USVI
Calculated Lat/Long: 17.7467681163929, -64.7082328429113 (from Given V&H)
Calculated Lat/Long Map URL: http://maps.google.com/maps?q=17.7467681163929,-64.7082328429113
Calculated V&H: {V=7944.00747498826, H=-3044.01425437623} (from Given Lat/Long)
Distance From Given V&H To Calculated V&H: 0.01 mi
Distance From Given Lat/Long To Calculated Lat/Long: 0.01 mi
Distance To Downtown Nashville, TN Using Given V&H: 1843.39 mi
Distance To TN State Capitol Using Calculated Lat/Long: 1854.93 mi
关注点
V&H 网格的单位基于 1/10 英里的平方根,这就是为什么在“短距离计算”距离公式的根号内除以 10。V&H 网格是在 1959 年国际英里标准化之前创建的,因此 V&H 网格里程实际上是基于美国测量英里。一国际英里等于 0.999998 美国测量英里,因此它们仅相差百万分之 2,约等于 1/8 英寸或 3.2 毫米。对于相距 1000 英里的两点,国际英里和美国测量英里的距离相差约 10.5 英尺(3.2 米)。
V&H 网格有一个阿拉斯加变体,比标准 V&H 网格更加晦涩难懂。阿拉斯加 V&H 网格使用一个未公开记录的不同中心点。LERG8 表将阿拉斯加 V&H 坐标列为“次要”坐标。LergInfo.doc 文件称,当主叫和被叫号码“位于费率中心之间,其空气里程小于收费公司关税中指定的里程数”时,次要坐标用于对通话进行计费。LergInfo.doc 接着说,阿拉斯加的次要 V&H 坐标是使用与主要 V&H 坐标不同的算法计算的。当我向 iconectiv 询问有关阿拉斯加次要坐标的更多信息时,一位路由工程师告诉我
"我们对阿拉斯加的了解是,次要坐标是针对不同的中点计算的,这无疑是为了减少将行星绘制在二维坐标上的失真造成的误差。所有主要 V&H 和所有非阿拉斯加次要坐标都以美国本土 48 个州和南部加拿大陆地省份中部附近的一个点为中心。(该点靠近马尼托巴-明尼苏达州边境。)阿拉斯加坐标在这个系统中准确性最差,因为它们离该点最远。阿拉斯加的次要坐标,据推测是阿拉斯加服务提供商之间协议的结果,基于阿拉斯加某个地方的一个点,并且仅用于阿拉斯加内部的通话。"
因此,阿拉斯加 V&H 网格上的次要坐标将无法与 VHPoint
类型正确配合使用。“短距离计算”和“长距离计算”距离算法可能有效,如果阿拉斯加 V&H 网格单位也基于 1/10 英里的平方根的话,但我找不到任何保证这一点的文档。VHPoint
的纬度和经度转换逻辑(因此也是“GeoCoordinate
”距离算法)由于中心点不同而无效。但是,除非您在阿拉斯加的一家电话公司工作,并且正在对在阿拉斯加境内发生和终止的通话进行计费,否则这应该不会有太大限制。