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 完成。