XQuery/Google 地理编码
外观
< XQuery
您有一个或多个地理名称,并且想要创建这些位置的地图。
我们将使用 Google RESTful 网络服务从地名列表中返回地理数据。Google 提供了一个基于 HTTP 的 地理编码服务。这需要为 API 密钥注册一个站点,并且对使用此 API 存在限制。结果可以以 XML 或 JSON 格式返回。
以下脚本接受一个位置并返回来自服务的 xml
let $key := "apikey"
let $location := request:get-parameter("location",())
let $location := escape-uri($location,false())
let $url := concat("https://maps.googleapis.com/maps/api/geocode/xml?address=",$location,"&key=",$key)
let $response := doc($url)
return
$response
</source >
==== Examples ====
Single City Examples:
* [http://kitwallace.co.uk/xqbook/geo/googlegeocode.xq?location=Minneapolis Minneapolis] - example using a single city with no country
* [http://kitwallace.co.uk/xqbook/geo/googlegeocode.xq?location=Bristol,UK Bristol,UK] - example using a city and country
Multiple matches may be returned:
* [http://kitwallace.co.uk/xqbook/geo/googlegeocode.xq?location=Bristol Bristol]
* or a false positive: [http://kitwallace.co.uk/xqbook/geo/googlegeocode.xq?location=Santas+House Santa's House]
In the UK, this service will geocode postcodes:
* [http://kitwallace.co.uk/xqbook/geo/googlegeocode.xq?location=BS3+4EA Bristol Hackspace]
== Response as KML ==
The XML response can be reformated as a KML file. Note the addition of the relevant media-type for KML .
<syntaxhighlight lang="xml">
let $key := "my apikey"
let $location := request:get-parameter("location",())
let $location := escape-uri($location,false())
let $url := concat("https://maps.googleapis.com/maps/api/geocode/xml?address=",$location,"&key=",$key)
let $response := doc($url)/GeocodeResponse
return
if ($response/status="OK")
then
let $x := response:set-header('Content-disposition',concat('inline;filename="',$location,'.kml";'))
let $result := $response/result[1]
let $serialize := util:declare-option("exist:serialize", "method=xml media-type=application/vnd.google-earth.kml+xml indent=yes")
return
<kml>
<Folder>
<name>{$location}</name>
{for $result in $response/result
return
<Placemark>
<name>{string($result/formatted_address)}</name>
<Point>
<coordinates>{$result/geometry/location/lng/string()},{$result/geometry/location/lat/string()},0</coordinates>
</Point>
</Placemark>
}
</Folder>
</kml>
else $response
如果您有 GoogleEarth,它应该加载一个叠加层,显示多个布里斯托尔位置:布里斯托尔 KML
查看生成的 kml 的一种简单方法是使用 GoogleMaps。此脚本只需构建使用上述脚本的相关 URL,然后重定向到该 URL
let $location := request:get-parameter("location",())
let $wikiurl := escape-uri(concat("http:/kitwallace.co.uk/geocodekml.xq?location=",$location),false())
let $url := concat("http://maps.google.co.uk/maps?q=",$wikiurl)
return
response:redirect-to(xs:anyURI($url))
遗憾的是,这种方法不再适用于 GoogleMap - 请参阅 支持丢失 布里斯托尔
另一种方法是使用 GoogleMap 的 JavaScript API。请注意,要嵌入 JavaScript 需要将 { 复制,因此通常将 JavaScript 放入单独的文件中更容易。这种方法利用任何现有的 kml 叠加层,更简单,但比使用 JavaScript API 实现地图更受限制
declare option exist:serialize "method=xhtml media-type=text/html";
let $location := request:get-parameter("location",())
let $url := escape-uri(concat("http://kitwallace.co.uk/xqbook/geo/geocodekml.xq?location=",$location),false())
return
<html>
<head>
<script src="https://maps.googleapis.com/maps/api/js?v=3&key=myapikey"></script>
<script type="text/javascript">
function initialize(url) {{
var map = new google.maps.Map(document.getElementById("map_canvas"));
var kmlLayer = new google.maps.KmlLayer({{
url: url,
map:map
}});
}}
</script>
</head>
<body onload="initialize('{$url}')">
<h2>Map of {$location}</h2>
<div id="map_canvas" style="height: 80%;width: 80%; margin: 0px; padding: 0px">
</div>
</body>
</html>
* Bristol * London
[设置缩放级别似乎不起作用]
通常,位置在数据文件中定义。以下脚本读取一个本地文件(威士忌酒厂的样本)并创建一个 KML 叠加层。
let $key := "apikey"
let $locations := doc("/db/apps/xqbook/geo/whisky.xml")
let $serialize := util:declare-option("exist:serialize", "method=xml media-type=application/vnd.google-earth.kml+xml")
let $x := response:set-header('Content-disposition','inline;filename=whisky.kml')
return
<kml>
<Folder>
<name>Distilleries</name>
{for $location in $locations//Whisky
let $url := concat("https://maps.googleapis.com/maps/api/geocode/xml?address=",$location/Postcode,"&key=",$key)
let $response := doc($url)/GeocodeResponse
let $result := $response/result[1]
return
<Placemark>
<name>{$location/Brand/string()}</name>
<description>{$location/Address/string()}</description>
<Point>
<coordinates>{$result/geometry/location/lng/string()},{$result/geometry/location/lat/string()},0</coordinates>
</Point>
</Placemark>
}
</Folder>
</kml>
以及 JavaScript 的修改版本,可以使用输出创建 威士忌地图