Navigation Menu

LittleGreenViper / **LGV_TZ_Lookup ** Public

Server for Matching Long/Lat to Timezone

License

MIT license 16 stars 0 forks

LittleGreenViper/LGV_TZ_Lookup

A Server for Matching Long/Lat to Timezone

Overview

本项目是一个相当简单的 PHP 项目,旨在接受 Timezone Boundary Builder Project 的 GeoJSON 输出,并提供一个简单的 API,用于将经度/纬度位置与时区进行匹配。

传入经度/纬度,并返回一个字符串,其中包含覆盖该点的时区的 标准 TZ 时区指示符

这是此项目的 GitHub 仓库

What Problem Does This Solve?

不幸的是,时区并非简单的“我在这个经度,所以一定是这个时间”。它们是政治构建。

以下是我们不能只进行简单的经度匹配的原因:

Time Zones Of the World 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 parserComposer 链接外,没有其他依赖项。

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.ziptimezones-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 项目。