XRX/地圖導航
外觀
< XRX
您希望在您的 XRX 應用程式中新增地圖導航功能。
雖然地圖控制元件沒有在原始 XForms 規範中定義,但可以透過使用一些 JavaScript 來新增它們。
我們將使用三個框架。
- XSLTForms - 用於啟用模型、控制元件和繫結
- JQuery - JQuery UI,JQuery 佈局 - 用於使用者介面。這包括控制元件來進行北、南、東、西方向的平移
- OpenLayers - 用於地圖導航、平移和縮放功能
XForms 模型將包含以下內容
- 一個包含搜尋查詢的預設例項,其中包含最小和最大經度和緯度(預設值)。
- 一個用於儲存查詢響應的位置(響應)。
- 一個定位例項(定位)
- 一些繫結語句
- 一個提交,用於從 openmap 資料庫獲取新的地圖資料
此示例具有一個簡單的地圖使用者介面控制元件,允許向北/南/東/西平移以及縮放和縮小。
此使用者介面使用一個與 XForms 輸入使用者介面控制元件關聯的 JQuery 物件。
以下內容儲存在 XForms 模型中
請注意,以下名稱空間在此示例中使用
xmlns:geo="http://schematronic.ru/geo"
xmlns:param="http://schematronic.ru/param"
xmlns:ev="http://www.w3.org/2001/xml-events"
<xf:model>
<!-- this holds the parameters for the outbound search query. -->
<xf:instance id="default" xmlns="http://schematronic.ru/geo">
<geo:search>
<param:query/>
<!-- variables for the min and max longitude and latitude -->
<param:min-lon/>
<param:min-lat/>
<param:max-lon/>
<param:max-lat/>
</geo:search>
</xf:instance>
<!-- this holds the search results -->
<xf:instance xmlns="" id="response">
<response/>
</xf:instance>
<xf:instance id="locate">
<eval>
javascript:g.locate(<lon></lon>, <lat></lat>, "<icon></icon>")
</eval>
</xf:instance>
<!-- These binds associate an id with a variable in the search form and a calculation -->
<xf:bind id="query" nodeset="instance('default')/param:query"/>
<xf:bind id="min-lon" nodeset="instance('default')/param:min-lon" calculate="min-lon()"/>
<xf:bind id="min-lat" nodeset="instance('default')/param:min-lat" calculate="min-lat()"/>
<xf:bind id="max-lon" nodeset="instance('default')/param:max-lon" calculate="max-lon()"/>
<xf:bind id="max-lat" nodeset="instance('default')/param:max-lat" calculate="max-lat()"/>
<!-- These binds associate an ID with
<xf:bind id="lon" nodeset="instance('locate')/lon"/>
<xf:bind id="lat" nodeset="instance('locate')/lat"/>
<xf:bind id="icon" nodeset="instance('locate')/icon"/>
<!-- When the user selects any of the navigation controls, the following does a POST to the server. -->
<!-- Note that the response to the search is places in the "response instance -->
<xf:submission id="do-search" method="post" ref="instance('default')" replace="instance" instance="response" resource="/gate">
<xf:load
ev:event="xforms-submit-done"
resource="javascript:showResult()"/>
</xf:submission>
</xf:model>
Javascript 庫將來自 openstreemap.org 網站。我們還將使用一些 JQuery 使用者介面控制元件。
以下是您需要新增的靜態 JavaScript 檔案。
<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript" src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script type="text/javascript" src="/share/geo.js"></script>
<script type="text/javascript" src="/share/jquery.js"></script>
<script type="text/javascript" src="/share/jquery-ui.js"></script>
<script type="text/javascript" src="/share/jquery-layout.js"></script>
除了以上內容外,還必須使用以下 JavaScript 資料。
<script type="text/javascript">
var g;
function map(){
var lat = 51.30505;
var lon = 37.85331;
var zoom = 12;
g = geo("map", lon, lat, zoom);
}
var isDebug = false;
var layout;
function showResult (){
layout.open("west");
}
jQuery(function (){
jQuery("#search input").addClass("ui-state-default ui-corner-left");
jQuery("#search button").addClass("ui-button ui-state-default ui-corner-right");
layout = jQuery("body").layout({
north : {
resizable : false,
slidable : false,
closable : false,
spacing_open : 0,
spacing_closed : 0,
size : 40
},
south : {
size : 100,
resizable : true,
slidable : true,
closable : true,
initHidden : !isDebug
},
west : {
size : 300,
minSize : 200,
maxSize : 400,
resizable : true,
slidable : true,
closable : true,
initHidden : true
}
});
map();
if (isDebug) jQuery("#console").show();
})
</script>
<body>
<div id="header" class="ui-layout-north ui-widget-header">
<span id="logo">
<a href="/">
<img src="/site/stkurier/images/logo/logo.png" alt="logo" />
</a>
</span>
<span id="search">
<xf:input xmlns:xf="http://www.w3.org/2002/xforms" bind="query">
<xf:send submission="do-search" ev:event="xforms-value-changed"/>
</xf:input>
<xf:submit submission="do-search">
<xf:label>
<img alt="search" src="/share/icons/fugue-icons/icons/magnifier-medium-left.png" />
</xf:label>
</xf:submit>
</span>
</div>
<div class="ui-layout-west">
<div id="result">
<ol>
<xf:repeat xmlns:xf="http://www.w3.org/2002/xforms" id="place_list" nodeset="instance('response')//*:place">
<li>
<xf:trigger appearance="minimal">
<xf:action xmlns:ev="http://www.w3.org/2001/xml-events" ev:event="DOMActivate">
<xf:setvalue bind="lon" value="instance('response')//*:place[index('place_list')]/@lon"></xf:setvalue>
<xf:setvalue bind="lat" value="instance('response')//*:place[index('place_list')]/@lat"></xf:setvalue>
<xf:setvalue bind="icon" value="instance('response')//*:place[index('place_list')]/@icon"></xf:setvalue>
<xf:load>
<xf:resource value="instance('locate')"></xf:resource>
</xf:load>
</xf:action>
<xf:label>
<xf:output ref="@icon" mediatype="image/*" if="@icon"></xf:output>
<xf:output ref="@display_name"></xf:output>
</xf:label>
</xf:trigger>
</li>
</xf:repeat>
</ol>
</div>
</div>
<div class="ui-layout-center">
<div id="map"></div>
</div>
<div div="#debug" class="ui-layout-south">
<div id="console"></div>
</div>
</body>
以下是伺服器端 XQuery 程式碼的示例。
geo:search($query, $min-lon, $min-lat, $max-lon, $max-lat)
將在伺服器端針對例項進行評估
<geo:search>
<param:query/>
<param:min-lon/>
<param:min-lat/>
<param:max-lon/>
<param:max-lat/>
</geo:search>
module namespace geo = "http://schematronic.ru/geo";
import module namespace http = "http://exist-db.org/xquery/httpclient";
import module namespace request = "http://exist-db.org/xquery/request";
declare variable $geo:search-service-uri := "http://nominatim.openstreetmap.org/search";
declare function geo:search($query as xs:string,
$min-lon as xs:float, $min-lat as xs:float,
$max-lon as xs:float, $max-lat as xs:float) {
let $view-box := string-join(($min-lon, $min-lat, $max-lon, $max-lat), ",")
let $lon := ($min-lon + $max-lon) div 2
let $lat := ($min-lat + $max-lat) div 2
let $uri := escape-uri(xs:anyURI(concat(
$geo:search-service-uri,
"?format=xml",
"&viewbox=", $view-box,
"&addressdetails=1&limit=100",
"&polygon=0",
"&q=", $query
)), false())
let $response := http:get($uri, false(), ())
let $results := $response//searchresults
return
element {name($results)} {
$response/@*,
for $i in $results/place
order by ($lon - $i/@lon) * ($lon - $i/@lon) + ($lat - $i/@lat) * ($lat - $i/@lat)
return $i
}
};
declare function geo:search($query as xs:string, $view-box as xs:float*) {
geo:search($query, $view-box[1], $view-box[2], $view-box[3], $view-box[4])
};
declare function geo:search($query as xs:string) {
geo:search($query, -180, -90, 180, 90)
};
所有工作均由 Evgeny Gazdovsky 完成。文稿由 Dan McCreary 完成。