在上一篇《地图移动应用实战:Ionic ElasticSearch 搜索服务》中我们说到了,如果创建一个搜索服务,以及使用搜索接口。接着,我们来将他们显示到地图上。
效果图:
判断是否有上次记录的位置信息,如果有则将地图的中心设置为上次的位置。
将位置添加到ElasticSearch的Query中。
从ElasticSearch中获取数据,并解析Render到地图上。
OpenLayers是一个用于开发WebGIS客户端的JavaScript包。OpenLayers 支持的地图来源包括Google Maps、Yahoo、 Map、微软Virtual Earth 等,用户还可以用简单的图片地图作为背景图,与其他的图层在OpenLayers 中进行叠加,在这一方面OpenLayers提供了非常多的选择。除此之外,OpenLayers实现访问地理空间数据的方法都符合行业标准。OpenLayers 支持Open GIS 协会制定的WMS(Web Mapping Service)和WFS(Web Feature Service)等网络服务规范,可以通过远程服务的方式,将以OGC 服务形式发布的地图数据加载到基于浏览器的OpenLayers 客户端中进行显示。OpenLayers采用面向对象方式开发,并使用来自Prototype.js和Rico中的一些组件。
1.下载OpenLayer
2.添加到index.html
:
<script src="js/ol.js"></script>
新建一个MapCtrl
,需要用到ESService
和 NSService
,NSService是官方示例中的一个函数,提供了一个getRendererFromQueryString
方法。
.factory('NSService', function(){
var exampleNS = {};
exampleNS.getRendererFromQueryString = function() {
var obj = {}, queryString = location.search.slice(1),
re = /([^&=]+)=([^&]*)/g, m;
while (m = re.exec(queryString)) {
obj[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
if ('renderers' in obj) {
return obj['renderers'].split(',');
} else if ('renderer' in obj) {
return [obj['renderer']];
} else {
return undefined;
}
};
return {
"exampleNS": exampleNS
};
})
这里我们使用的是Bing地图:
var view = new ol.View({
center: map_center,
zoom: 4
});
var controls = ol.control.defaults({rotate: false});
var interactions = ol.interaction.defaults({altShiftDragRotate:false, pinchRotate:false});
var map = new ol.Map({
controls: controls,
interactions: interactions,
layers: [
new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3',
culture: 'zh-CN',
imagerySet: 'Road'
})
})
],
renderer: NSService.exampleNS.getRendererFromQueryString(),
target: 'map',
view: view
});
一个简单的地图如上如示。
ngCordova有一个插件是$cordovaGeolocation
,用于获取当前的位置。代码如下所示:
var posOptions = {timeout: 10000, enableHighAccuracy: true};
$cordovaGeolocation
.getCurrentPosition(posOptions)
.then(function (position) {
var pos = new ol.proj.transform([position.coords.longitude, position.coords.latitude], 'EPSG:4326', 'EPSG:3857');
$localstorage.set('position', [position.coords.latitude, position.coords.longitude].toString());
$localstorage.set('map_center', pos);
view.setCenter(pos);
}, function (err) {
console.log(err)
});
当获取到位置时,将位置存储到localstorage
中。
最后代码如下所示,获取解析后的结果,添加icon
ESService.search("", 0).then(function(results){
var vectorSource = new ol.source.Vector({ });
$.each(results, function(index, result){
var position = result.location.split(",");
var pos = ol.proj.transform([parseFloat(position[1]), parseFloat(position[0])], 'EPSG:4326', 'EPSG:3857');
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(pos),
name: result.title,
phone: result.phone_number,
distance: result.distance
});
vectorSource.addFeature(iconFeature);
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: 'img/icon.png'
}))
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
map.addLayer(vectorLayer);
});
在上面的代码中添加:
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: 'bottom-center',
stopEvent: false
});
map.addOverlay(popup);
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if (feature) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
$(element).popover({
'placement': 'top',
'html': true,
'content': "<h4>商品:" + feature.get('name') + "</h4>" + '' +
'<div class="button icon-left ion-ios-telephone button-calm button-outline">' +
'<a ng-href="tel: {{result.phone_number}}">' + feature.get('phone') + '</a> </div>' +
"<p class='icon-left ion-ios-navigate'> " + feature.get('distance') + "公里</p>"
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
当用户点击时,调用Bootstrap的Popover来显示信息。
围观我的Github Idea墙, 也许,你会遇到心仪的项目