如何使用 AngularJS 和 PHP 为任何地点生成简短而唯一的数字地址

介绍

邮件地址通常很长,有时很难记住。有许多情况下,更短的地址是可取的。例如,能够发送一个短的地址,只有几个字符可以确保更快的救护车服务。Pieter Geelen和Harold Goddijn在2001年开发了Mapcode系统(http://www.mapcode.com/),以便为世界上任何物理地址轻松创建一个短形地址。

在本教程中,您将开发一个Web应用程序,该应用程序使用Google地图API生成您选择的任何地址的短数字地址。您将通过从GitHub克隆该应用程序的基本代码,然后添加代码,使其完全功能。

前提条件

为了完成本教程,您将需要以下内容:

步骤1:获取 Google API 密钥

在本教程中,您将使用JavaScript创建对Google地图的界面。Google分配API密钥,使开发人员能够在Google地图上使用JavaScript API,您需要获取并添加到您的Web应用程序的代码中。

要获取自己的 API 密钥,请前往 Google 的 获取 API 密钥页面

如果您尚未登录到 Google 帐户,将被要求这样做,然后,窗口将要求您为项目提供一个名称,这可能是您想要的任何东西:

请注意,Google 作为免费试用的一部分提供 API 密钥,但需要您设置并启用计费以获取它们。

输入此信息后,您的 API 密钥将出现在屏幕上. 复制并将其存储到您可以轻松获取的位置,因为您需要稍后将其添加到您的项目代码中。

获取 API 密钥后,您可以通过创建 MySQL 数据库开始构建应用程序的基础。

第2步:创建数据库

本教程中描述的Web应用程序接受用户的地址,并为其生成地图代码,以及指定位置的纬度和长度. 您将将这些数据存储在MySQL数据库中,以便您可以在稍后通过输入相应的数字地址来获取。

首先,打开MySQL壳并使用您的密码进行身份验证:

1mysql -u root -p

在提示中,使用以下命令创建名为digitaladdress的数据库:

1CREATE DATABASE IF NOT EXISTS `digitaladdress`;

接下来,选择此新数据库,以便在其中创建表:

1USE `digitaladdress`;

在选择数字地址数据库后,创建一个名为位置的表格,以存储您的应用程序将从这些数据中创建的物理地址、长度、纬度和地图代码。

 1CREATE TABLE `locations` (
 2  `digitaladdress` varchar(50) DEFAULT NULL,
 3  `state` varchar(30) DEFAULT NULL,
 4  `zip` varchar(30) DEFAULT NULL,
 5  `street` varchar(30) DEFAULT NULL,
 6  `town` varchar(30) DEFAULT NULL,
 7  `house` varchar(30) DEFAULT NULL,
 8  `latitude` varchar(30) DEFAULT NULL,
 9  `longitude` varchar(30) DEFAULT NULL,
10  KEY `digitaladdress` (`digitaladdress`)
11);

本表有八栏: " 数字地址 " 、 " 状态 " 、 " zip " 、 " 街道 " 、 " 城镇 " 、 " 住宅 " 、 " 纬度 " 和 " 纬度 " 。 第一栏 " 数字地址 " 采用 " KEY " 命令。 MySQL中的索引功能类似于他们在百科全书或其他参考作品中的工作方式. 每当您或您的应用程序发布包含 WHERE 语句的查询时, MySQL 都会逐行读取每个列的每个条目,随着您的表格累积了越来越多的条目,这可能会成为一个极其耗费资源的过程。 这样的一列索引从一列中取出数据,将其按字母顺序保存在一个单独的位置上,这意味着MySQL将不必通过表格中的每一行查看. 它只需要在索引中找到所寻找的数据,然后跳到表格中相应的行.

添加此表后,请退出 MySQL 提示:

1exit

有了您的数据库和表设置,以及您的 Google 地图 API 键,您已经准备好创建该项目。

步骤3 - 创建项目

正如介绍中提到的,我们将从GitHub克隆这个项目的基本代码,然后添加一些额外的代码来使应用程序功能性。 为此,而不是通过创建每个文件并自己添加所有代码的过程,我们将加快应用程序运行的过程,这也将使我们能够专注于添加和理解允许应用程序与Google地图和Mapcode API进行通信的代码。

您可以在 这个 GitHub 项目页面找到完整项目的骨骼代码。 使用下面的 git 命令将项目克隆到您的服务器:

1git clone https://github.com/do-community/digiaddress.git

这将在您的主目录中创建一个名为digiaddress的新文件夹. 将此目录移动到您的服务器的 Web 根. 如果您遵循了在前提条件中链接的 LAMP 堆栈教程,这将是 /var/www/html 目录:

1sudo mv digiaddress/ /var/www/html/

该项目包含几个PHP和JS文件,您将在本教程中稍后添加一些代码。 要查看目录结构,请先安装使用apt包:

1sudo apt install tree

然后运行命令以作为参数提供的digiaddress目录:

1tree /var/www/html/digiaddress/
 1[secondary_label Output]
 2digiaddress/
 3├── README.md
 4├── db.php
 5├── fetchaddress.php
 6├── findaddress.php
 7├── generateDigitalAddress.php
 8├── geoimplement.php
 9├── index.php
10└── js
11    ├── createDigitialAddressApp.js
12    └── findAddressApp.js

您可以从这个输出中看到,该项目由六个PHP文件和两个JavaScript文件组成,这些文件共同创造了应用程序的两个主要功能:从物理地址创建地图代码,并解码地图代码以获取原始物理地址。

「index.php」 *「geoimplement.php」 *「generateDigitialAddress.php」 *「db.php」 *「createDigitialAddressApp.js」

‘index.php'文件包含应用程序用户界面(UI)的代码,它由用户可以输入物理地址的表格组成. index.php ' 文件称执行 ' 。 php ' 文件,用户随时提交表格。 地理执行. php给Google地图API打个电话,并将地址传给它。 Google服务器随后用包含指定地址信息,包括其纬度和经度的JSON响应. 然后将此信息传递给基因DigitalAddress.php文件,该文件称地图编码API,以获得按其纬度和经度指定的特定位置的地图编码。 由此产生的地图编码以及纬度、经度和物理地址,随后被存储在您在第2步中创建的数据库中。 ‘create DigitalAddressApp.js'文件进行一些操作,控制应用程序中看到的UX元素,包括在Google Maps接口上设置标记和边界矩.

剩下的三个文件允许应用程序的第二个功能 - 即从给定的地图代码中获取物理地址:

  • findaddress.php
  • fetchaddress.php
  • findAddressApp.js

findaddese.php'文件定义了应用程序UI,它不同于index.php'中的定义。 应用程序接受之前生成的地图码作为输入并显示存储在数据库中的相应物理地址. 当用户提交此表时,请查找地址。 php发出一个fetchaddress.php的电话,然后从数据库取回相应的地图编码。 findAddressApp.js'文件载有在Google Maps接口上设置标记和边界矩的助手代码.

测试安装,访问您的浏览器中的http://your_server_ip/digiaddress,确保更改your_server_ip,以反映您的服务器的IP地址。

注意: 如果您不知道您的服务器的 IP 地址,您可以运行以下弯曲命令. 此命令将打印icanhazip.com的页面内容,该网站显示访问该机器的 IP 地址:

1curl http://icanhazip.com

美元

一旦在那里,你会看到这个标题在你的浏览器窗口的顶部:

1Generate Digital Address

这确认您正确下载了项目文件,因此,让我们继续开发应用程序的主要功能:生成地图代码。

步骤4 — 开发应用程序的UI

虽然应用程序界面的锅炉代码包含在您在上一步下载的文件中,但您仍然需要对其中一些文件进行一些更改和添加,以使应用程序功能和吸引用户。

使用您喜爱的编辑器打开index.php文件,在这里,我们将使用nano:

1nano /var/www/html/digiaddress/index.php

寻找以下代码行:

1[label /var/www/html/digiaddress/index.php]
2. . .
3<script async defer src="https://maps.googleapis.com/maps/api/js?key=<YOUR KEY>"></script>
4. . .

用您在步骤 1 中获取的 Google API 密钥代替<Your KEY>,添加 API 密钥后,该行应该看起来像这样:

1[label /var/www/html/digiaddress/index.php]
2. . .
3<script async defer src="https://maps.googleapis.com/maps/api/js?key=ExampleAPIKeyH2vITfv1eIHbfka9ym634Esw7u"></script>
4. . .

接下来,在index.php文件中找到以下评论:

1[label /var/www/html/digiaddress/index.php]
2. . .
3            <!-- add form code here -->
4. . .

我们将在本评论下方添加几十行代码,这将创建一个表单,用户可以输入应用程序将使用的物理位置的地址来生成地图代码。

 1[label /var/www/html/digiaddress/index.php]
 2. . .
 3            <!-- add form code here -->
 4
 5            <div class="form-border spacing-top">
 6                <div class="card-header" style="background:#cc0001; color:#ffff">
 7                    <h5>Enter Address</h5>
 8                </div>
 9                <div class="extra-padding">
10. . .

下面,添加以下HTML代码,创建一个包含五个文本字段(以及相应的标签)的表格,用户将输入他们的信息:

 1[label /var/www/html/digiaddress/index.php]
 2                . . .
 3                <form>
 4                        <div class="form-group input-group-sm">
 5                            <label for="state">State</label>
 6                            <input type="text" class="form-control rounded-0 textbox-border" id="state"
 7                                   placeholder="" ng-model="address.state"/>
 8                        </div>
 9                        <div class="form-group input-group-sm">
10                            <label for="zip" class="animated-label">Zip</label>
11                            <input type="text" class="form-control rounded-0 textbox-depth textbox-border"
12                                   id="zip" ng-model="address.zip" disabled="disabled"/>
13                        </div>
14                        <div class="form-group input-group-sm">
15                            <label for="town">Town</label>
16                            <input type="text" class="form-control rounded-0 textbox-border"
17                                   id="town" ng-model="address.town" disabled="disabled"/>
18                        </div>
19                        <div class="form-group input-group-sm">
20                            <label for="street">Street</label>
21                            <input type="text" class="form-control rounded-0 textbox-border" id="street"
22                                   placeholder="" ng-model="address.street" disabled="disabled"/>
23                        </div>
24                        <div class="form-group input-group-sm">
25                            <label for="house">House</label>
26                            <input type="text" class="form-control rounded-0 textbox-border" id="house"
27                                   placeholder="" ng-model="address.house" disabled="disabled"/>
28                        </div>
29                 . . .

在表单代码下方,添加下列行,创建两个隐藏的控件,这些控件通过表单中提交的任何地址的纬度和长度信息:

1[label /var/www/html/digiaddress/index.php]
2                            . . .
3                            <div class="form-group input-group-sm">
4                                <input type="hidden" ng-model="address.lat"/>
5                            </div>
6                            <div class="form-group input-group-sm">
7                                <input type="hidden" ng-model="address.long"/>
8                            </div>
9                            . . .

最后,通过添加以下代码来关闭本节,创建一个 Generate 按钮,允许用户提交表单:

1[label /var/www/html/digiaddress/index.php]
2                            . . .
3                            <button type="submit" disabled="disabled" class="btn btn-color btn-block rounded-0" id="generate"
4                                    style="color:#ffff;background-color: #cc0001;">Generate
5                            </button>
6                    </form>
7                </div>
8            </div>
9        . . .

添加这些元素后,该文件的此部分应匹配:

 1[label /var/www/html/digiaddress/index.php]
 2. . .
 3            <!-- add form code here -->
 4
 5            <div class="form-border spacing-top">
 6                <div class="card-header" style="background:#cc0001; color:#ffff">
 7                    <h5>Enter Address</h5>
 8                </div>
 9                <div class="extra-padding">
10                    <form>    
11                            <div class="form-group input-group-sm">
12                                <label for="state">State</label>
13                                <input type="text" class="form-control rounded-0 textbox-border" id="state"
14                                       placeholder="" ng-model="address.state"/>
15                            </div>
16                            <div class="form-group input-group-sm">
17                                <label for="zip" class="animated-label">Zip</label>
18                                <input type="text" class="form-control rounded-0 textbox-depth textbox-border"
19                                       id="zip" ng-model="address.zip" disabled="disabled"/>
20                            </div>
21                            <div class="form-group input-group-sm">
22                                <label for="town">Town</label>
23                                <input type="text" class="form-control rounded-0 textbox-border "
24                                       id="town" ng-model="address.town" disabled="disabled"/>
25                            </div>
26                            <div class="form-group input-group-sm">
27                                <label for="street">Street</label>
28                                <input type="text" class="form-control rounded-0 textbox-border" id="street"
29                                       placeholder="" ng-model="address.street" disabled="disabled"/>
30                            </div>
31                            <div class="form-group input-group-sm">
32                                <label for="house">House</label>
33                                <input type="text" class="form-control rounded-0 textbox-border" id="house"
34                                       placeholder="" ng-model="address.house" disabled="disabled"/>
35                            </div>
36
37                            <div class="form-group input-group-sm">
38                                <input type="hidden" ng-model="address.lat"/>
39                            </div>
40                            <div class="form-group input-group-sm">
41                                <input type="hidden" ng-model="address.long"/>
42                            </div>
43                            <button type="submit" disabled="disabled" class="btn btn-color btn-block rounded-0" id="generate"
44                                    style="color:#ffff;background-color: #cc0001;">Generate
45                            </button>
46                    </form>
47                </div>
48            </div>
49            <br>
50        </div>
51
52        <!-- add google map control -->
53                    . . .

保存文件,按CTRL+O,然后按ENTER,然后再次访问浏览器中的应用程序:

1http://your_server_ip/digiaddress

您将看到新添加的表单字段和 ** 生成** 按钮,应用程序应该是这样的:

在此时,如果您将地址信息输入表单并尝试点击生成按钮,则不会发生任何事,我们将稍后添加地图代码生成功能,但让我们首先专注于通过添加用户可以互动的地图来使此页面更具视觉吸引力。

第5步:添加Google地图控制

当地图通过Google地图JavaScript API在网站上显示时,它们包含用户界面功能,允许访问者与他们看到的地图进行互动.这些功能被称为 controls. 我们将继续编辑index.php文件,将Google地图控制器添加到该应用程序中,完成后,用户将能够在输入表单旁查看地图,拖动它以查看不同的位置,缩放并切换谷歌的地图,卫星和街头视图。

在 index.php 文件中找到以下评论:

1[label /var/www/html/digiaddress/index.php]
2. . .
3<!-- add google map control -->
4. . .

添加此评论下方的以下突出代码:

 1[label /var/www/html/digiaddress/index.php]
 2. . .
 3        <!-- add google map control -->
 4
 5        <div class="col-sm-8 map-align" ng-init="initMap()">
 6            <div id="map" class="extra-padding" style="height: 100%;
 7            margin-bottom: 15px;"></div>
 8            <label id="geocoordinates" ng-show="latlng" ng-model="lt"></label><br/>
 9            <label id="geoaddress" ng-show="address" ng-model="padd"></label>
10            </div>
11        </div>
12. . .

保存文件,然后再次访问您的浏览器中的应用程序. 您将看到以下内容:

正如您所看到的,我们已经成功地添加了一个地图到应用程序中。您可以将地图拖动到不同的位置,缩放到不同的位置,并在地图,卫星和街头视图之间切换。 回顾您刚刚添加的代码,请注意,我们还添加了两个标签控制,将显示在表单上输入的地理坐标和物理地址:

1[label /var/www/html/digiaddress/index.php]
2            . . .
3            <label id="geocoordinates" ng-show="latlng" ng-model="lt"></label><br/>
4            <label id="geoaddress" ng-show="address" ng-model="padd"></label>
5            . . .

在浏览器中再次访问应用程序,并在第一个字段中输入状态的名称。当您将文本标记移动到下一个字段时,纬度和长度标签不会出现,地图上显示的位置也不会改变以反映您输入的信息。

步骤6 - 添加事件听众

将交互式元素添加到应用程序中可以帮助保持用户的参与,我们将通过使用 event listeners 来实现该应用程序中的几个交互式行为。

一个 event 是任何在网页上发生的任何行动. 事件可以是由用户或浏览器自己完成的。

  • 点击 HTML 按钮 * 更改输入字段的内容 * 将焦点从一个页面元素改变到另一个页面元素

在 AngularJS 中,事件聆听器是指示程序在发生特定事件时采取特定行动的指令。

1ng-event_type=expression

在这个步骤中,我们将添加一个事件倾听器,帮助用户在提交表单时将输入的信息处理成映射码. 我们还将增加几个活动听众,使应用程序更具互动性。 具体来说,我们将利用这些收听器来改变应用程序地图中显示的位置,放置一个标记,并在用户将信息输入到表格时将位置周围画出一个矩形. 我们把这些活动的听众添加到index.php中,所以如果你关闭了文件,就再打开文件:

1nano /var/www/html/digiaddress/index.php

滚到我们添加的第一批代码,并找到以<form>开始的块。

 1[label /var/www/html/digiaddress/index.php]
 2                . . .
 3                    <form>
 4                            <div class="form-group input-group-sm">
 5                                <label for="state">State</label>
 6                                <input type="text" class="form-control rounded-0 textbox-border" id="state"
 7                                       placeholder="" ng-model="address.state"/>
 8                            </div>
 9                            <div class="form-group input-group-sm">
10                                <label for="zip" class="animated-label">Zip</label>
11                                <input type="text" class="form-control rounded-0 textbox-depth textbox-border"
12                                       id="zip" ng-model="address.zip" disabled="disabled"/>
13                            </div>
14                            <div class="form-group input-group-sm">
15                                <label for="town">Town</label>
16                                <input type="text" class="form-control rounded-0 textbox-border"
17                                       id="town" ng-model="address.town" disabled="disabled"/>
18                            </div>
19                            <div class="form-group input-group-sm">
20                                <label for="street">Street</label>
21                                <input type="text" class="form-control rounded-0 textbox-border" id="street"
22                                       placeholder="" ng-model="address.street" disabled="disabled"/>
23                            </div>
24                            <div class="form-group input-group-sm">
25                                <label for="house">House</label>
26                                <input type="text" class="form-control rounded-0 textbox-border" id="house"
27                                       placeholder="" ng-model="address.house" disabled="disabled"/>
28                            </div>
29                    </form>
30. . .

首先,将以下突出事件倾听器添加到打开的<form>标签中。该代码告诉应用程序每次用户通过表单提交信息时,请呼叫processForm函数。processFormcreateDigitalAddressApp.js文件中定义,并作为一个辅助函数,将用户提交的信息发送到相应文件中,然后将其处理成地图代码。

1[label /var/www/html/digiaddress/index.php]
2                . . .
3                    <form ng-submit="processForm()" class="custom-form">
4                            <div class="form-group input-group-sm">
5                                <label for="state">State</label>
6                                <input type="text" class="form-control rounded-0 textbox-border" id="state"
7                                       placeholder="" ng-model="address.state"
8                            </div>
9                . . .

接下来,继续编辑这一块,增加几个 " blur " 活动听众。 当某一页面元素失去焦点时,会发生blur'事件。 在表格'块'输入'标记上添加以下突出线。 这些行告诉应用程序,当用户的焦点从我们在步骤4中创建的各自形式字段移出时,可以调用"geocodeAddress"功能. 请注意,你还必须删除关闭每个 " 输入 " 标记的鞭子和比标记( " /> " )大。 如果不这样做,应用程序将无法正确登记 " blur " 事件:

 1[label /var/www/html/digiaddress/index.php]
 2                . . .
 3                <form ng-submit="processForm()" class="custom-form">
 4                            <div class="form-group input-group-sm">
 5                                <label for="state">State</label>
 6                                <input type="text" class="form-control rounded-0 textbox-border" id="state"
 7                                       placeholder="" ng-model="address.state"
 8                                       ng-blur="geocodeAddress(address,'state')" required=""/>
 9                            </div>
10                            <div class="form-group input-group-sm">
11                                <label for="zip" class="animated-label">Zip</label>
12                                <input type="text" class="form-control rounded-0 textbox-depth textbox-border"
13                                       id="zip" ng-model="address.zip" disabled="disabled"
14                                       ng-blur="geocodeAddress(address,'zip')" required=""/>
15                            </div>
16                            <div class="form-group input-group-sm">
17                                <label for="town">Town</label>
18                                <input type="text" class="form-control rounded-0 textbox-border"
19                                       id="town" ng-model="address.town" disabled="disabled"
20                                       ng-blur="geocodeAddress(address,'town')" required=""/>
21                            </div>
22                            <div class="form-group input-group-sm">
23                                <label for="street">Street</label>
24                                <input type="text" class="form-control rounded-0 textbox-border" id="street"
25                                       placeholder="" ng-model="address.street" disabled="disabled"
26                                       ng-blur="geocodeAddress(address,'street')" required=""/>
27                            </div>
28                            <div class="form-group input-group-sm">
29                                <label for="house">House</label>
30                                <input type="text" class="form-control rounded-0 textbox-border" id="house"
31                                       placeholder="" ng-model="address.house" disabled="disabled"
32                                       ng-blur="geocodeAddress(address,'house')" required=""/>
33                            </div>
34. . .

这些新行中的第一行 - ng-blur="geocodeAddress(地址,'state')" required=""/> - 翻译为当用户的焦点从状态字段中移动时,请拨打geocodeAddress`函数。

processForm函数一样,geocodeAddresscreateDigitalAddressApp.js文件中被声明,但该文件中尚无定义该函数的代码,我们将完成此函数,以便在这些混淆事件发生后将标记放到应用地图上并绘制一个直角,以反映输入表单中的信息。

保存并关闭index.php文件(按CTRL+X,Y,然后ENTER),然后打开CreateDigitalAddressApp.js文件:

1nano /var/www/html/digiaddress/js/createDigitalAddressApp.js

在此檔案中,找到下列行:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2. . .
3$scope.geocodeAddress = function (address, field) {
4. . .

这个行是我们声明地理代码地址函数的地方。下面几行,我们声明一个名为fullAddress的变量,该变量构建了一个可人读的邮件地址,从用户输入到应用程序的表单字段的信息中。

 1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
 2. . .
 3var fullAddress = "";
 4
 5    if (address ['house']) {
 6        angular.element(document.getElementById('generate'))[0].disabled = false;
 7            fullAddress = address ['house'] + ",";
 8                }
 9    if (address ['town']) {
10        angular.element(document.getElementById('street'))[0].disabled = false;
11            fullAddress = fullAddress + address ['town'] + ",";
12    }
13    if (address ['street']) {
14        angular.element(document.getElementById('house'))[0].disabled = false;
15            fullAddress = fullAddress + address ['street'] + ",";
16    }
17    if (address ['state']) {
18        angular.element(document.getElementById('zip'))[0].disabled = false;
19            fullAddress = fullAddress + address ['state'] + " ";
20    }
21    if (address ['zip']) {
22        angular.element(document.getElementById('town'))[0].disabled = false;
23            fullAddress = fullAddress + address ['zip'];
24    }
25. . .

这些行后面是以下评论:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2. . .
3// add code for locating the address on Google maps
4. . .

在此评论下方,添加以下行,检查fullAddress是否是其他值,而不是null:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2                . . .
3                if (fullAddress !== "") {
4                . . .

此代码将输入表单中的信息提交到 geoimplement.php 文件中,如果 `fullAddress' 不是 null,则使用 HTTP POST 方法:

 1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
 2                    . . .
 3                    $http({
 4                        method: 'POST',
 5                        url: 'geoimplement.php',
 6                        data: {address: fullAddress},
 7                        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
 8
 9                    }).then(function successCallback(results) {
10                    . . .

接下来,添加以下行,检查 PHP 调用是否成功返回:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2                        . . .
3                        if (results.data !== "false") {
4                        . . .

如果 PHP 调用成功返回,我们将能够处理结果,添加以下行,通过调用删除Rectangle函数,在CreateDigitalAddressApp.js文件的顶部定义删除之前可能在地图上绘制的任何边界直角:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2                            . . .
3                            removeRectangle();
4                            . . .

删除Rectangle();行下方,添加以下四行,以创建地图控制上指向新位置的标记:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2                            . . .
3                            new google.maps.Marker({
4                                map: locationMap,
5                                position: results.data.geometry.location
6                            });
7                            . . .

然后添加以下代码,从结果中获取纬度和长度信息,并用我们在步骤 5 中创建的 index.php 文件中的两个 HTML 标签显示它:

 1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
 2                            . . .
 3                            lat = results.data.geometry.location.lat;
 4                            lng = results.data.geometry.location.lng;
 5
 6                            $scope.address.lat = lat;
 7                            $scope.address.lng = lng;
 8
 9                            geoCoordLabel = angular.element(document.querySelector('#geocoordinates'));
10                            geoCoordLabel.html("Geo Coordinate: " + lat + "," + lng);
11
12                            geoAddressLabel = angular.element(document.querySelector('#geoaddress'));
13                            geoAddressLabel.html("Geo Address: " + fullAddress);
14
15                            $scope.latlng = true;
16                            . . .

最后,在这些行下面添加以下内容. 此代码创建了一个视图端口,在地图上标记一个新的边界直角:

 1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
 2                            . . .
 3                            if (results.data.geometry.viewport) {
 4
 5                                rectangle = new google.maps.Rectangle({
 6                                    strokeColor: '#FF0000',
 7                                    strokeOpacity: 0.8,
 8                                    strokeWeight: 0.5,
 9                                    fillColor: '#FF0000',
10                                    fillOpacity: 0.35,
11                                    map: locationMap,
12                                    bounds: {
13                                        north: results.data.geometry.viewport.northeast.lat,
14                                        south: results.data.geometry.viewport.southwest.lat,
15                                        east: results.data.geometry.viewport.northeast.lng,
16                                        west: results.data.geometry.viewport.southwest.lng
17                                    }
18                                });
19
20                                var googleBounds = new google.maps.LatLngBounds(results.data.geometry.viewport.southwest, results.data.geometry.viewport.northeast);
21
22                                locationMap.setCenter(new google.maps.LatLng(lat, lng));
23                                locationMap.fitBounds(googleBounds);
24                            }
25                        } else {
26                            errorLabel = angular.element(document.querySelector('#lt'));
27                            errorLabel.html("Place not found.");
28                            $scope.latlng = true;
29                            removeRectangle();
30                        }
31
32                    }, function errorCallback(results) {
33                       console.log(results);
34                    });
35                }
36                . . .

添加此内容后,该文件的此部分将看起来如下:

 1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
 2                . . .
 3                // add code for locating the address on Google maps
 4                if (fullAddress !== "") {
 5                    $http({
 6                        method: 'POST',
 7                        url: 'geoimplement.php',
 8                        data: {address: fullAddress},
 9                        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
10
11                    }).then(function successCallback(results) {
12
13                        if (results.data !== "false") {
14                            removeRectangle();
15
16                            new google.maps.Marker({
17                                map: locationMap,
18                                position: results.data.geometry.location
19                            });
20
21                            lat = results.data.geometry.location.lat;
22                            lng = results.data.geometry.location.lng;
23
24                            $scope.address.lat = lat;
25                            $scope.address.lng = lng;
26
27                            geoCoordLabel = angular.element(document.querySelector('#geocoordinates'));
28                            geoCoordLabel.html("Geo Coordinate: " + lat + "," + lng);
29
30                            geoAddressLabel = angular.element(document.querySelector('#geoaddress'));
31                            geoAddressLabel.html("Geo Address: " + fullAddress);
32
33                            $scope.latlng = true;
34
35                            if (results.data.geometry.viewport) {
36
37                                rectangle = new google.maps.Rectangle({
38                                    strokeColor: '#FF0000',
39                                    strokeOpacity: 0.8,
40                                    strokeWeight: 0.5,
41                                    fillColor: '#FF0000',
42                                    fillOpacity: 0.35,
43                                    map: locationMap,
44                                    bounds: {
45                                        north: results.data.geometry.viewport.northeast.lat,
46                                        south: results.data.geometry.viewport.southwest.lat,
47                                        east: results.data.geometry.viewport.northeast.lng,
48                                        west: results.data.geometry.viewport.southwest.lng
49                                    }
50                                });
51
52                                var googleBounds = new google.maps.LatLngBounds(results.data.geometry.viewport.southwest, results.data.geometry.viewport.northeast);
53
54                                locationMap.setCenter(new google.maps.LatLng(lat, lng));
55                                locationMap.fitBounds(googleBounds);
56                            }
57                        } else {
58                            errorLabel = angular.element(document.querySelector('#lt'));
59                            errorLabel.html("Place not found.");
60                            $scope.latlng = true;
61                            removeRectangle();
62                        }
63
64                    }, function errorCallback(results) {
65                       console.log(results);
66                    });
67                }
68                . . .

保存文件,但暂时保持打开. 如果你在浏览器中再次访问应用程序,你不会看到其外观或行为有任何新的变化. 同样地,如果您要输入一个地址并点击Generate 按钮,该应用程序仍然不会生成或显示映射码. 这是因为在地图代码功能工作之前,我们仍然必须编辑一些文件。 让我们继续做这些修改, 并仔细研究这些地图代码是如何生成的.

第7步:理解地图代码生成

在仍在查看CreateDigitalAddressApp.js文件时,请绕过您在上一步中添加的代码部分,找到通过表单提交的信息的代码,并将其处理成一个独特的地图代码。 每当用户点击Generate**按钮时,index.php文件中的代码会提交表单并调用processForm函数,这是在CreateDigitalAddressApp.js中定义的:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2. . .
3$scope.processForm = function () {
4. . .

processForm然后将 HTTP POST 发送到 generateDigitalAddress.php 文件中:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2. . .
3$http({
4    method: 'POST',
5    url: 'generateDigitalAddress.php',
6    data: $scope.address,
7    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
8}).then(function (response) {
9. . .

Stichting Mapcode Foundation提供从物理地址生成地图代码的API作为一个免费的Web服务。 要了解如何调用Mapcode Web服务,请关闭‘createDigitalAddressApp.js’并打开‘generateDigitialAddress.php’文件:

1nano /var/www/html/digiaddress/generateDigitalAddress.php

在文件的顶部,你会看到以下内容:

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2<?php
3include("db.php");
4. . .

列读 include("db.php");告诉PHP include 来自 db.php 文件中的所有文本、代码和标记在 generateDigitalAddress.php 文件中。

下面的包括声明有几行,根据createDigitalAddressApp.js提交的请求获得纬度和长度信息:

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2. . .
3$data = json_decode(file_get_contents("php://input"));
4$lat = $data->lat;
5$long = $data->lng;
6. . .

generateDigitalAddress.php文件中寻找下面的评论。

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2. . .
3// call to mapcode web service
4. . .

此代码会调用Mapcode API,发送latlong作为参数。

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2. . .
3// call to mapcode web service
4$digitaldata = file_get_contents("https://api.mapcode.com/mapcode/codes/".$lat.",".$long."?include=territory,alphabet&allowLog=true&client=web");
5. . .

网页服务返回被分配给digitaldata的 JSON 数据,下面的语句解码了 JSON:

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2. . .
3$digitalAddress["status"] = json_decode($digitaldata, TRUE)['local']['territory']." ".json_decode($digitaldata, TRUE)['local']['mapcode'];
4. . .

这会返回用户指定位置的地图代码,然后将此信息存储在数据库中:

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2. . .
3$obj = new databaseConnection();
4
5$conn = $obj->dbConnect();
6
7$obj->insertLocation($conn, $digitalAddress["status"],$data->state,$data->zip,$data->street,$data->town,$data->house,$lat,$long);
8. . .

然后,最后一行回响地图代码返回呼叫函数:

1[label /var/www/html/digiaddress/generateDigitalAddress.php]
2. . .
3echo json_encode($digitalAddress);

保存并关闭此文件,然后重新打开 createDigitalAddressApp.js:

1nano /var/www/html/digiaddress/js/createDigitalAddressApp.js

当地图代码被成功检索时,在createDigitalAddressApp.js文件中的下列行将向用户显示在对话框中:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2. . .
3digiAddress = response.data.status;
4. . .
5$('#digitalAddressDialog').modal('show');
6. . .

虽然你确实添加了一个新的代码行到generateDigitalAddress.php,但你仍然不会看到任何功能变化,当你访问并与应用程序在你的浏览器中互动. 这是因为你还没有添加你的Google API密钥到geoimplement.php文件,这使得实际呼叫到Google地图API。

步骤 8 – 启用向 Google 地图 API 调用

此应用程序依赖Google地图API将物理地址翻译成相应的纬度和长度坐标,然后将其传送到Mapcode API,该API将其用于生成地图代码,因此,如果应用程序无法与Google地图API进行通信,以生成位置的纬度和长度,任何尝试生成地图代码都将失败。

回想一下第6步,在构建地址数据后,我们通过HTTP POST请求在createDigitalAddressApp.js文件中传递了结果:

1[label /var/www/html/digiaddress/js/createDigitalAddressApp.js]
2$http({
3    method: 'POST',
4    url: 'geoimplement.php',
5    data: {address: fullAddress},
6    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
7}).then(function successCallback(results) {

此代码块将用户输入的地址数据发送到geoimplement.php文件中,其中包含呼叫 Google 地图 API 的代码。

1nano /var/www/html/digiaddress/geoimplement.php

您将看到它首先解密了通过 POST 请求接收的地址:

1[label /var/www/html/digiaddress/geoimplement.php]
2. . .
3$data=json_decode(file_get_contents("php://input"));
4. . .

然后将输入数据的地址字段传输到一个地理代码函数中,该函数返回地址上的地理信息:

1[label /var/www/html/digiaddress/geoimplement.php]
2. . .
3$result = geocode($data->address);
4. . .

然后,结果响应返回呼叫器:

1[label /var/www/html/digiaddress/geoimplement.php]
2. . .
3echo json_encode($result);
4. . .

地理代码函数编码了地址,并将其传送到Google地图API,以及您的应用程序密钥:

1[label /var/www/html/digiaddress/geoimplement.php]
2. . .
3// url encode the address
4$address = urlencode($address);
5
6// google map geocode api url
7$url = "https://maps.googleapis.com/maps/api/geocode/json?address={$address}&key=<YOUR KEY>";
8. . .

在继续滚动之前,继续前进并将 API 密钥添加到// google map geocode api url评论下的行中:

1[label /var/www/html/digiaddress/geoimplement.php]
2. . .
3// google map geocode api url
4$url = "https://maps.googleapis.com/maps/api/geocode/json?address={$address}&key=ExampleAPIKeyH2vITfv1eIHbfka9ym634Esw7u";
5. . .

将呼叫发送到 Google 地图 API 后,响应将被解码并由函数返回其值:

 1[label /var/www/html/digiaddress/geoimplement.php]
 2. . .
 3// get the json response
 4$resp_json = file_get_contents($url);
 5
 6// decode the json
 7$resp = json_decode($resp_json, true);
 8
 9if ($resp['status'] == 'OK') {
10    return $resp['results'][0];
11} else {
12    return false;
13}
14. . .

保存此文件,然后再次访问您的应用程序。在状态字段中输入US-NY,然后按TAB,将输入焦点更改到下一个字段。

请注意,您在表单中输入的地理坐标和物理地址出现在地图底部,这使得应用程序感觉更具吸引力和互动性。

<$>[注] ** 注意:** 对于地方名称的缩写,Mapcode 使用 ISO 3166 标准,这意味着它可能无法像预期的那样解释一些常用的缩写。

你可以避免与美国邮政缩写混淆,以US-为先,在这个路易斯安那州的例子中,你会输入US-LA

有关Mapcode如何使用该标准的更多信息,请参阅 领土和标准代码参考页面

尽管应用程序在地图上显示位置的这种改进,但应用程序仍然没有完全功能. 在生成地图代码之前,您需要采取的最后一步是编辑 db.php 文件,以允许应用程序访问您的数据库。

第9步:添加数据库凭证和测试地图代码生成

请记住,这个应用程序存储在您在步骤 2 中创建的数据库中输入的每一个地址 - 以及其纬度,长度和地图代码 - 这是由db.php文件中的代码实现的,该文件存储了您的数据库凭证,并允许应用程序访问其中的位置表。

作为启用地图代码生成功能的最后一步,打开db.php文件进行编辑:

1nano /var/www/html/digiaddress/db.php

在这个文件的顶部,找到开始$pass的行。这个行提交您的MySQL登录凭证,以便该应用程序可以访问您的数据库。 用您的 root MySQL用户密码代替your_password:

1[label /var/www/html/digiaddress/db.php]
2. . .
3        $username = "root";
4        $pass = "your_password";
5. . .

这是您需要做的最后一次更改,以便从物理地址生成地图代码。 保存并关闭文件,然后继续在浏览器中重新更新应用程序。 输入您选择的地址,然后点击生成按钮。

在这个阶段,你已经完成了你的应用程序,你现在可以生成一个短的数字地址的任何物理位置在世界上. 自由尝试不同的地址,并注意,你输入的地址不一定是在美国。

您的最终任务是启用此应用程序的第二个功能:使用相应的地图代码从数据库中获取一个地址。

步骤10 - 获取物理地址

现在你可以从给定的物理地址生成地图代码,你的最后一步是从地图代码中获取原来的物理地址。

由于这个文件中定义的用户界面与我们在步骤 4 中提到的用户界面相当相似,我们不会太仔细研究它如何工作的所有细节。

为了启用地址检索功能,您需要将您的 Google API 密钥添加到findaddress.php文件中,因此请使用您喜爱的编辑器打开它:

1nano /var/www/html/digiaddress/findaddress.php

在檔案底部,尋找以「<script async defer src=」開始的行。

1[label /var/www/html/digiaddress/findaddress.php]
2<script async defer src="https://maps.googleapis.com/maps/api/js?key=<YOUR KEY>"></script>

用 Google API 密钥替换<YOUR KEY>像您在上一步中所做的那样,然后保存文件。

当用户提交表单时,它会触发一个提交事件,而事件收听器会调用fetchadd函数:

1[label /var/www/html/digiaddress/findaddress.php]
2. . .
3<form ng-submit="fetchadd()" class="custom-form">
4. . .

fetchadd函数将数字地址发送到fetchaddress.php并发送 POST 请求:

1[label /var/www/html/digiaddress/js/findAddressApp.js]
2. . .
3$http({
4    method : 'POST',
5    url : 'fetchaddress.php',
6    data : {digiaddress: $scope.digiaddress}
7}).then(function(response){
8. . .

如果 POST 成功,函数将返回 JSON 响应。

1[label /var/www/html/digiaddress/js/findAddressApp.js]
2. . .
3var jsonlatlng = JSON.parse(response.data.latlng);
4. . .

接下来的行将标记设置在地图上:

1[label /var/www/html/digiaddress/js/findAddressApp.js]
2. . .
3marker = new google.maps.Marker({
4    position: new google.maps.LatLng(jsonlatlng.latitude, jsonlatlng.longitude),
5        map: locationMap
6});
7. . .

以下是地理坐标和物理地址:

1[label /var/www/html/digiaddress/js/findAddressApp.js]
2. . .
3geoCoordLabel = angular.element(document.querySelector('#geocoordinates'));
4geoCoordLabel.html("Geo Coordinate: "+ jsonlatlng.latitude +","+ jsonlatlng.longitude);
5
6geoAddressLabel = angular.element(document.querySelector('#geoaddress'));
7geoAddressLabel.html("Geo Address: " + jsonlatlng.house +","+ jsonlatlng.town +","+ jsonlatlng.street +","+ jsonlatlng.state + " " + jsonlatlng.zip );
8. . .

在您的浏览器中访问此应用程序,通过下面的链接:

1http://your_server_ip/digiaddress/findaddress.php

通过输入您之前获得的地图代码来测试它,下面的图表显示了一种典型的输出:

您现在可以为世界上任何位置创建一个独特的地图代码,然后使用该地图代码获取该位置的物理地址。

结论

在本教程中,您使用了 Google 地图 API 来定位位置,并获取其长度和纬度信息. 此信息用于使用 Mapcode API 生成独特而短的数字地址。 地图代码有许多实际用例,从紧急服务到考古调查。 [The Stichting Mapcode Foundation] (http://www.mapcode.com/aboutus.html)列出了几种这种用例。

认可

感谢Dinesh Karpe(https://www.linkedin.com/in/dineshkarpe)和Sayli Patil(https://www.linkedin.com/in/ptsayli)开发整个项目代码。

Published At
Categories with 技术
comments powered by Disqus