Show HN:一个简单的服务器,用于将经纬度匹配到 TimeZone
Navigation Menu
LittleGreenViper / **LGV_TZ_Lookup ** Public
Server for Matching Long/Lat to Timezone
License
LittleGreenViper/LGV_TZ_Lookup
A Server for Matching Long/Lat to Timezone
Overview
本项目是一个相当简单的 PHP 项目,旨在接受 Timezone Boundary Builder Project 的 GeoJSON 输出,并提供一个简单的 API,用于将经度/纬度位置与时区进行匹配。
传入经度/纬度,并返回一个字符串,其中包含覆盖该点的时区的 标准 TZ 时区指示符。
What Problem Does This Solve?
不幸的是,时区并非简单的“我在这个经度,所以一定是这个时间”。它们是政治构建。
以下是我们不能只进行简单的经度匹配的原因:
Image Source: Wikimedia Commons
我们通过使用 这个伟大项目 的渲染结果来解决这个问题,该项目致力于构建一个“活文档”的世界所有时区地图,作为 shapefile(一种可以在数字地图上投影多边形的文件),并在这些形状内定位地理点。
How This Works
我们提供了一个非常基本的 PHP 服务器,该服务器从大型 shapefile 中的数据构建一个简单的数据库(由时区边界构建器生成的 GeoJSON 变体。它可以在 任何项目版本 中找到)。 该数据库是故意“哑”的,目的是使项目尽可能灵活,并且查找快速简便。
每个时区都在 GeoJSON 多边形(或 multipolygon)中描述。
注意:我们对文件做出了_巨大_的假设。 我们假设多边形是非常基本的“闭合”多边形,并且 multipolygon 只是简单多边形的聚合(而不是构成“孔”等)。
我们构建了一个多边形数据库(分解 multipolygon),我们称之为“domain rect”。 这是一个包围整个多边形的矩形,而不管多边形的形状如何。
“domain rect”用于快速“分流”查找。 它的顶点在数据库中被索引,因此比较非常快速。 我们可以快速找到可能包含我们位置的时区,并忽略其余时区。
在某些情况下,domain rect“分流”可能只返回一个结果,所以我们一次就得到了它。 在其他情况下,我们可以使用未索引的多边形数据,对该位置进行简单的 "Winding Number" 查找,并找出哪个多边形实际拥有它。 我们返回第一个。
从使用角度来看,您只需通过简单的 HTTP GET 发送一个经度/纬度对,您将收到一个“原始”字符串响应,其中包含适用于该位置的时区的 TZ 名称。
http
[s
]://
< YOUR SERVER URL TO THE src DIRECTORY>[/index.php
]?ll=
,
https://tz.example.com?ll=-73.123,44.456
经度/纬度作为以逗号分隔的浮点数对发送,表示经度和纬度的度数。
Dependencies
这是一个服务器项目,专为您的经典 "LAMP" 托管而设计,因此您需要有一个标准的 PHP/MySQL 主机。
本项目使用 streaming JSON parser,以便解析 此文件(在编写本文时是当前版本),它是 一个 GeoJSON 文件,其中包含计算出的时区,并由 这个项目 创建。
否则,它是一个非常基本的 PHP 项目(在编写本文时,已针对 PHP 8.2 进行了测试)。
初始版本是为 MySQL 构建的(已针对 MySQL 5.7 进行了测试),但使用 PHP PDO,并且具有 一个非常简单的数据库模式,因此可以相对轻松地扩展到其他数据库。
除了到 streaming JSON parser 的 Composer 链接外,没有其他依赖项。
Batteries Not Included
嗯……这并不_完全_正确。 您需要从 Timezone Boundary Builder Project releases 下载 GeoJSON 文件。 这是一个大文件,可能会随着时区更改而更新。 您可以使用任一文件(无论是否包含海洋),但该项目针对海洋变体进行测试。
Implementation
Initial Installation
一旦您拥有可用的服务器,请将 src
子目录 的内容安装到您选择的位置,该位置可通过 HTTP 访问。 您应该有一个指向 src
目录 中 index.php
文件 的 URI。
Database Setup
您将需要设置一个 MySQL 数据库,其中包含一个具有基本完整权限的用户。
Config File
服务器的一项要求是配置文件。 它通常应放置在 HTTP 可访问目录树之外,您需要修改 index.php
文件中的这行代码:
define("__CONFIG_FILE_", __DIR__.'/../../../../TZInfo/config.php');
以指向配置文件。
配置文件的内容如下所示:
<?php
$g_dbName = "<DATABASE NAME>";
$g_dbUserName = "<DATABASE USERNAME>";
$g_dbPassword = "<DATABASE USER PASSWORD>";
$g_dbType = "<DATABASE TYPE>";
$g_dbHost = "<DATABASE HOST>";
$g_dbPort = "<DATABASE PORT>";
$g_server_secret = "<SERVER SECRET>";
每个字符串都更改为与配置匹配。 这是一个例子:
<?php
$g_dbName = "HostingHash_TZDB";
$g_dbUserName = "tzUser";
$g_dbPassword = "swordfish";
$g_dbType = "mysql";
$g_dbHost = "127.0.0.1";
$g_dbPort = "3306";
$g_server_secret = "Shh-Dont-Tell-Anyone";
如果您不希望“任何人”访问服务器,则 $g_server_secret
非常重要。 如果将其设置为字符串,则对服务器的每次调用(包括命令行)都需要将 secret=<SERVER SECRET>
查询参数添加到常规查询中,如下所示:
HTTP Request:
https://tz.example.com/index.php?secret=Shh-Dont-Tell-Anyone&ll=-73.123,44.456
Command Line:
?> php
< PATH TO THE src DIRECTORY>/index.php secret=Shh-Dont-Tell-Anyone load
Composer
目录就位后,您需要更新 composer,以引入依赖项。
$> cd <YOUR src DIRECTORY>
$> composer update
这会设置一个 vendor
子目录。 之后忽略它即可。 服务器知道在哪里获取它。
注意:加载和设置仅需要依赖项。 后续查询不需要它。
The Data File
您需要从 Boundary Builder Project Releases Directory 获取 GeoJSON 数据文件。 获取最新版本,并查找名为 timezones.geojson.zip
或 timezones-with-oceans.geojson.zip
的文件。
它们是非常大的文件。
将文件解压缩到 src
目录中。
注意:我们已将项目最初设置为
combined-with-oceans.json
文件。 如果您想改为使用combined.json
文件,则应编辑index.php
文件,该行的代码如下所示:
$stream = fopen("$path/combined-with-oceans.json", 'r');
因此,它看起来像这样:
$stream = fopen("$path/combined.json", 'r');
注意:如果您这样做,某些测试将无法通过!
The Initial Load and Database Setup
您不需要“预热”数据库。 服务器将负责创建表。
但是,初始加载只能通过命令行完成,因此您需要 SSH 进入服务器,并从那里运行加载。 您可以使用上面指示的语法:
$> php <YOUR src DIRECTORY>/index.php secret=<SERVER SECRET> load
这可能需要一段时间。
成功后,脚本会发出一个简单的 1
。 如果出现问题,它会发出 0
。
完成后。 服务器已准备就绪。 您甚至可以删除 JSON 文件和 vendor 目录(如果需要),但它们需要返回才能加载。
您不需要经常运行 load
,因此它不应位于 cron
作业或任何作业中。
从那时起的所有交互都是通过 HTTP 完成的。
Testing
我们有一组可以运行的简单测试。 它们发送已知的坐标,并确保服务器返回正确的响应。
您可以像这样运行测试:
https://tz.example.com
[/index.php
]?
[secret=
&
]test
您将获得一个简单的 HTML 页面,其中列出了每个测试。 如果测试通过,则标题将为绿色。 如果失败,标题将为红色,并且页面顶部将显示指向失败的链接列表。
一切都应该是绿色的(除非您换掉了 JSON 文件,在这种情况下,您需要查找失败并验证测试)。
License
这是一个 MIT-Licensed 项目。