Angular JS - 使用地理位置对集合进行排序
Posted
技术标签:
【中文标题】Angular JS - 使用地理位置对集合进行排序【英文标题】:Angular JS - sorting a collection using geolocation 【发布时间】:2014-10-04 04:17:17 【问题描述】:我正在呈现包含坐标数据(经度、纬度)的商店位置集合。我想使用用户的地理位置对结果进行排序——特别是按最近的商店位置排序。就上下文而言,该应用程序旨在让人们更容易使用他们想要的 iPhone 找到 Apple Store(加拿大):
http://www.applestoreinventory.com
我正在使用 angularjs-geolocation 包装器 (https://github.com/arunisrael/angularjs-geolocation) 来获取访问者的纬度/经度,但我不确定如何使用用户的地理位置(一旦获取)以及 Angular 的 orderBy 指令来动态地使用收藏。 (我想按壁橱的距离进行排序,这是我习惯用 javascript 计算的东西。)这可能是一个简单的问题,但是对于 Angular 来说是新手,我仍在努力了解自己的方位。到目前为止,这是控制器:
angular.module('InventoryApp')
.controller('searchController', ['$scope', 'searchService', 'geolocation', function(scope, searchService, geolocation)
scope.model_ids = model_ids;
scope.store_ids = store_ids;
scope.address = '';
scope.find = '';
scope.position = null;
scope.refreshLocation = function ()
geolocation.getLocation().then(function(data)
scope.coords = lat:parseFloat(data.coords.latitude.toFixed(6)), lng:parseFloat(data.coords.longitude.toFixed(6)) ;
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(scope.coords.lat, scope.coords.lng);
geocoder.geocode( 'latLng': latlng , function (results, status)
if (status == google.maps.GeocoderStatus.OK)
if (results[0])
scope.address = results[0].formatted_address;
else
scope.address = 'Address not found';
else
scope.address = 'Geocoder failed due to: ' + status;
scope.$digest();
);
);
;
scope.search = function ()
searchService.update().success(function (stores)
scope.stores = stores;
);
;
scope.refreshLocation();
scope.search();
])
.factory('searchService', ['$http', function(http)
return
update: function ()
return http.get('/inventory');
])
那么,关于如何在 Angular JS 中构建它有什么想法吗?
【问题讨论】:
您可以计算到每个商店的距离并按距离排序。 是的,这就是我的想法。我知道如何计算距离,但在 Angular 控制器的上下文中,如何做到这一点?在 Backbone 中,这很简单——我只需为邻近度创建一个计算属性,然后对其进行排序。在 Angular JS 中,我只是不知道如何处理它。 【参考方案1】:我认为 AngularJS 没有太大的不同。我做了一个例子。它使用 Google Places API 进行搜索。需要地图(map = new google.maps.Map),因为没有它,places API 就无法工作。如果您的地理位置被禁用,它将不起作用。它使用 Google 地图几何 API 以米为单位计算距离,并使用 orderBy 过滤器对商店进行排序。
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script src="https://raw.githubusercontent.com/arunisrael/angularjs-geolocation/master/dist/angularjs-geolocation.min.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=false&v=3&libraries=geometry,places"></script>
<style>
.check-yes
background-color: green;
</style>
</head>
<body ng-app="plunker">
<div id="map-canvas"></div>
<div ng-controller="searchController">
Search for: <input type="text" ng-model="searchText"> <button ng-click="search()">Search</button>
<ul>
<li ng-repeat="store in stores | orderBy:'distance'">
store.name (store.distance metres)
</li>
</ul>
</div>
<script>
var app = angular.module('plunker', ['geolocation']);
app.controller('searchController', ['$scope', 'searchService', 'geolocation', function(scope, searchService, geolocation)
scope.address = '';
scope.find = '';
scope.position = null;
scope.stores = [];
scope.searchText = '';
scope.refreshLocation = function ()
geolocation.getLocation().then(function(data)
scope.coords = lat:parseFloat(data.coords.latitude.toFixed(6)), lng:parseFloat(data.coords.longitude.toFixed(6)) ;
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(scope.coords.lat, scope.coords.lng);
scope.position = latlng;
scope.search();
geocoder.geocode( 'latLng': latlng , function (results, status)
if (status == google.maps.GeocoderStatus.OK)
if (results[0])
scope.address = results[0].formatted_address;
else
scope.address = 'Address not found';
else
scope.address = 'Geocoder failed due to: ' + status;
scope.$digest();
);
);
;
scope.search = function ()
if (!scope.position)
alert('Please share your location to search');
searchService.update(setStores, scope.position, scope.searchText);
;
var setStores = function (stores)
scope.stores = stores;
calculateDistance();
scope.$apply();
var calculateDistance = function ()
for (var id in scope.stores)
var store = scope.stores[id];
var storeLocation = new google.maps.LatLng(store.geometry.location.lat(), store.geometry.location.lng());
var distance = google.maps.geometry.spherical.computeDistanceBetween(scope.position, storeLocation);
store.distance = parseInt(distance);
scope.refreshLocation();
]).factory('searchService', ['$http', function(http)
return
update: function (callback, position, text)
var url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json';
var params =
location: position,
radius: 2500,
types: ['store']
;
if (text)
params['name'] = text;
map = new google.maps.Map(document.getElementById('map-canvas'),
center: position,
zoom: 15
);
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(params, callback);
]);
</script>
</body>
</html>
【讨论】:
以上是关于Angular JS - 使用地理位置对集合进行排序的主要内容,如果未能解决你的问题,请参考以下文章
JAVA-初步认识-常用对象API(集合框架-Map集合-存储自定义对象)