我使用REST接口的新技術來提供新的地理編碼加載項。其核心是對相應REST接口的調用 MapQuest ,一家提供大量路由服務和應用程序的公司。
MapQuest的服務之一是路由。對於提供的每對地址,MapQuest會發回每個位置的緯度和經度,以及國家和州等行政信息。它還提供了兩個點之間所有航路點的位置,以及從第一個地址到第二個地址的更改方向的位置。還提供摘要信息,例如總距離和估計的行駛時間。如果僅使用兩個地址調用該函數,則它將返回它們之間的路徑和/或距離。如果提供地址列表,則將為每對連續的列表元素計算路由。然後將在元素1和元素2之間,在元素2和元素3之間給出連接,依此類推。n個位置的列表將產生n-1條路線。
由於數據表是收集信息的常用方式 JMP ,分析開始於用戶通過用戶對話框將角色分配給數據表的列。的地理編碼2020插件以相同的方式工作。用戶完成對話框後,程序將從數據表中收集相關數據,將其轉換為REST API所需的結構,然後將其發送到MapQuest。因此,該程序的大致結構是:1)完成用戶對話框,2)收集數據,3)為接口準備數據,4)發送接口請求,5)解釋結果,6)編寫JMP數據表。第三步,數據準備,定義為一個函數,可以作為 MapQuest_route.jsl 在JSL食譜中。您可以將其嵌入自己的地理應用程序中,或使用它來獲取有關如何為REST調用構造數據的想法。
基準功能
您或您程序的任何用戶都需要 API密鑰來自MapQuest。
JMP數據以數據表列的形式出現,而REST接口最有可能使用JSON結構。結果,需要具有在兩種格式之間轉換的功能。JSL還具有用於數據收集的結構,可以是列表或關聯數組。此功能的目的是封裝所有非本機JSL命令。典型的JSL變量以字符,數字或列表格式提供了必要的數據。調用返回的數據也包含在JSL列表中。因此,將此功能嵌入JSL腳本不需要JSL標準以外的任何其他知識。
介面
使用如下語句調用JSL函數:
結果= function();
如果函數需要或接受參數,則將其列在括號中。可以使用大括號或完整參數列表調用此函數GC_route。用括號括起來的調用將調用一個參數定義窗口,其中包含輸入和輸出的輪廓,如以下各節所示:

函數調用中的參數始終是位置參數。使用參數調用該函數時,需要提供所有必填參數,但它們可以為空。
在我的關於我的地理編碼插件的博客文章 ,我使用了家鄉周圍的一些當地旅遊景點作為如何使用外接程序的示例。讓我們來看看其中兩個,看看這個接口是如何工作的:

|
Alte Freiheit 24a,42103 Wuppertal,德國
|
伍珀塔勒Schwebebahn鐵路(Wuppertaler Schwebebahn)是一條長達13公里的懸索鐵路,這是世界上最古老的懸掛汽車的高架電氣鐵路,於1901年啟用。
|

|
Schloßplatz2,42659索林根,德國
|
城堡城堡(Schloss Burg),始建於十二世紀日世紀。
|
首先,您需要MapQuest的訪問密鑰,假設它是1234ABCD。另外,假設:
- 每個地址只是一個文本字符串。
- 您提供了一對地址字符串;不涉及數據表。
- 您想乘汽車旅行。
- 您只對距離和旅行時間感興趣。
- 您想要以英里為單位的距離。
使用此接口的一種方法是直接獲取地址字符串。在這種情況下,格式指示符(位置2)必須為1或更大。然後,函數調用如下所示:
routes = GC_route ("1234ABCD", "", 1, "fastest", "m", {"Alte Freiheit 24a, 42103 Wuppertal, Deutschland",<BR /> "Schloßplatz 2, 42659 Solingen, Deutschland"}, {}, {}, {}, {}, {}, {});
如果地址不是在一個字符串中,而是在單獨的元素中,則格式指示符必須為0(零),這意味著您的調用將類似於:
routes = GC_route ("1234ABCD", "", 0, "fastest", "m", {}, {"Deutschland", "Deutschland"}, {},
{"Wuppertal", "Solingen"}, {42103, 42659}, {"Alte Freiheit 24a", "Schloßplatz 2"}, {})
當然,您不需要將值作為參數放入;您還可以提供一個變量,例如帶有國家名稱列表的列表變量。

無論如何,結果都是相同的數據列表:
{200, "HTTP/1.1 200 OK", "", {}, {""}, {51.256414, 51.137675}, {7.148503, 7.152488}, {"close", "exact"},{"DE", "DE"},<BR />{"North Rhine-Westphalia", "North Rhine-Westphalia"}, {"Wuppertal", "Solingen"}, {"42103", "42659"},<BR /> {"Elberfeld", "Unterburg"}, {"Alte Freiheit", "Schloßplatz 2"}, {., 16.002}, {., 1600}, {}, {}, {0, 1}, [=>], }
找到兩個位置,併計算距離和行駛時間。因此,參數五是帶有空字符串的列表。最後,有一個用於空關聯數組的符號([=>])。它為空,因為參數13(詳細信息標誌)設置為零。否則,可以在此陣列中找到路由信息。
調用的參數列表中的微小更改會導致輸出中的重大更改。這就是參數13(“ detail”標誌)的更改。如果將其設置為1,則通過包含所有路由信息的數組擴展輸出:
{200, "HTTP/1.1 200 OK", "", {}, {""}, {51.20971, 51.21327}, {7.07255, 7.08376},{"exact", "exact"}, {"DE", "DE"},<BR /> {"Nordrhein-Westfalen", "Nordrhein-Westfalen"}, {"", ""}, {"42653", "42653"}, {"Solingen", "Solingen"},<BR /> {"Klosterhof 4", "Lützowstraße 347"}, {., 1.0767}, {., 965}, {}, {}, {0, 1},<BR /> ["gc#city" => {"Solingen", ., ., ., ., ., ., ., ., "Solingen"},
"gc#coordtype" => {"Point of Interest", "Waypoint", "Waypoint", "Waypoint", "Waypoint", "Waypoint", "Waypoint", "Waypoint", "Waypoint", "lPoint of Interest"},
"gc#ctrycd" => {"DE", ., ., ., ., ., ., ., ., "DE"},
"gc#dist" => {., 0.0064, 0.0499, 0.1481, 0.0853, 0.2366, 0.2993, 0.2478, 0.0032, 1.0767},<BR />"gc#district" => {"", ., ., ., ., ., ., ., ., ""},
"gc#lat" => {51.20971, 51.2099, 51.209949, 51.210171, 51.209187, 51.209667, 51.210789, 51.212135,51.213226, 51.21327},
"gc#leg" => {0, 1, 1, 1, 1, 1, 1, 1, 1},
"gc#long" => {7.07255, 7.072152, 7.072176, 7.072798, 7.074032, 7.074655, 7.077532, 7.081177, 7.084009, 7.08376},
"gc#msg" => {"", ., ., ., ., ., ., ., .},
"gc#postalc" => {"42653", ., ., ., ., ., ., ., ., "42653"},
"gc#ql" => {"exact", ., ., ., ., ., ., ., ., "exact"},
"gc#resp" => {0, ., ., ., ., ., ., ., .},
"gc#state" => {"Nordrhein-Westfalen", ., ., ., ., ., ., ., ., "Nordrhein-Westfalen"},<BR />"gc#street" => {"Klosterhof 4", "Klosterhof", ., "Gerberstraße", ., "Gräfrather Heide", .,<BR /> "Gräfrather Heide", "Lützowstraße", "Lützowstraße 347"},
"gc#time" => {., "00:00:05", "00:00:45", "00:02:13", "00:01:17", "00:03:32", "00:04:28", "00:03:42", "00:00:03", "00:16:05"},
"gc#wpidx" => {0, 1, 2, 3, 4, 5, 6, 7, 8, 0}], }
為簡單起見,此示例使用兩個彼此靠近的位置之間的路由。該路線由起點和終點之間的八個航路點組成。使用鍵“ gc#wpidx”在關聯數組的最後一個列表中枚舉它們。有些信息僅適用於開始和結束位置,這就是為什麼某些列表缺少這麼多值的原因。每個列表具有相同數量的元素,因此整個數組可以輕鬆轉換為數據表。
技術細節
該函數將一對地址或地址列表作為輸入。MapQuest發送回有關每個旅程的終點,每個位置的坐標,它們之間每個點的方向以及必須進行方向更改的位置的地理信息。對於這個簡單的任務,MapQuest提供了不同的輸入格式。地址信息可以作為一個文本字符串提供,用逗號分隔,例如“ Deutschland,Schloßplatz2,42659 Solingen”,這是我家鄉附近一座著名城堡的地址。或者,可以將地址指定為單個元素:country =“ Deutschland”,Street =“Schloßplatz2”,city =“ Solingen”,郵政編碼=“ 42659”。
我認為在大多數情況下,將查找多個地址。因此,該函數希望以列表的形式獲取地址信息,或者是具有完整地址的字符串列表,或者是具有地址元素的多個列表。每個地址,無論其格式如何,都需要提供其國家/地區。並且沒有檢查是否提供了所需的最少信息。所有其他元素都是可選的。
如果請求詳細的路由,則返回具有很多列表的數組。每個列表的第一個元素都屬於第一個位置,路徑的後續元素則屬於第二個位置,依此類推。為了區分輸入到請求中的位置和返回的路由點,gc#coordtype將原始位置命名為“興趣點”,並將其命名為“ Waypoints”之間的點。gc#leg列表將所有指向目的地的點粘合在一起。第一個位置不屬於一條腿(我的定義)。對於到達並包括第一個目的地的路線,它是一個;到第二個目的地的路線是兩個,依此類推。
如果為參數2提供了引用數據表的JSL變量,並且請求了詳細的路由,則假定位置列表與數據表中的位置列表相同。被引用的數據表的所有內容將被複製,並通過詳細的路由插入到陣列中。此信息只能鏈接到興趣點,因為所有列表的航路點均缺少值。
如果找不到路線,則會在與該路線的原點相對應的位置給出錯誤消息。如果可能,將計算後續路線。
如果您提供指向數據表的鏈接,並且該數據表包含排除的行,則必須提供排除的行的列表(
excludedrows = As List( dt << Get Excluded Rows )
);作為參數12。否則,列表將不同步。在消息列表中,這些觀察結果被標記為“已排除”。如果“排除”的觀測值比數據表中的原始觀測值更多,則這些觀測值將無法提供最少的位置信息。
我希望這段代碼可以對您的項目有所幫助,或者只是提供一些JSL應用程序的見識。我願意接受任何問題或建議,但由於它是Geocoding 2020外接程序的一部分,因此我將僅進行與其在該外接程序中的預期用途一致的更改。