Angular JS-使用地理位置对集合进行排序

Angular JS - sorting a collection using geolocation

本文关键字:集合 排序 地理位置 JS- Angular      更新时间:2023-09-26

我正在呈现一个包含坐标数据(经度、纬度)的商店位置集合。我想使用用户的地理位置对结果进行排序——特别是按最近的商店位置排序。就上下文而言,该应用程序旨在让人们更容易找到一家苹果商店(在加拿大),里面有他们想要的iPhone:

http://www.applestoreinventory.com

我正在使用angularjs地理定位包装器(https://github.com/arunisrael/angularjs-geolocation)以获取访问者的lat/lng,但我不知道如何使用用户的地理位置(一旦获取)以及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中构建它,有什么想法吗?

我认为AngularJS没有太大区别。我举了一个例子。它使用谷歌放置API进行搜索。地图是必需的(地图=新google.maps.Map),因为没有它,地方API就无法工作。如果您的地理位置被禁用,它将无法工作。它使用谷歌地图几何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>