地图移动应用实战: Ionic OpenLayer 地图显示

2,261 阅读2分钟

在上一篇《地图移动应用实战:Ionic ElasticSearch 搜索服务》中我们说到了,如果创建一个搜索服务,以及使用搜索接口。接着,我们来将他们显示到地图上。

效果图:

查看图片

设计思路

  1. 判断是否有上次记录的位置信息,如果有则将地图的中心设置为上次的位置。

  2. 将位置添加到ElasticSearch的Query中。

  3. 从ElasticSearch中获取数据,并解析Render到地图上。

OpenLayer

> 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中的一些组件。

添加OpenLayer 3

1.下载OpenLayer

2.添加到index.html:

Ionic OpenLayer 地图显示:

创建NSService

新建一个MapCtrl,需要用到ESServiceNSService,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': "

商品:" + feature.get('name') + "

" + '' + '' + "

" + feature.get('distance') + "公里

" }); $(element).popover('show'); } else { $(element).popover('destroy'); } });

当用户点击时,调用Bootstrap的Popover来显示信息。

其他:

服务端代码: github.com/phodal/djan…

客户端代码: github.com/phodal/ioni…