首页 > 解决方案 > 在 Angularjs 中加入谷歌地图

问题描述

所以我目前一直在尝试让谷歌地图 API 加载到我的网站上。我正在将 javascript 添加到我的代码中以实现功能,但您可以忽略其中的大部分内容。问题似乎出在下面的几行中<!--map--><!--current location-->因为它说需要在模块中验证 app-map 并且找不到管道“lat”和“lon”。如果您发现问题,请告诉我。

<!DOCTYPE html>
<body ng-app="app" ng-controller="appCtrl">
<h3>Google Maps</h3>

    <!-- search/go to current location -->
    <div class="text-right">
        <div class="input-append text-right">
            <input type="text" ng-model="search"/>
            <button class="btn" type="button" ng-click="geoCode()" ng-disabled="search.length == 0" title="search" >
              &nbsp;<i class="icon-search"></i>Where is this place?
            </button>
            <button class="btn" type="button" ng-click="gotoCurrentLocation()" title="current location">
              &nbsp;<i class="icon-home"></i>Where am I now?
            </button>
        </div>
    </div>

    <!-- map -->
     <app-map style="height:400px;margin:12px;box-shadow:0 3px 25px black;"
        center="loc"
        markers="cities"
    > 
    </app-map> 

    <!-- current location -->
     <div class="text-info text-right">
        {{loc.lat | lat:0}}, {{loc.lon | lon:0}}
    </div>

    <!-- list of airports -->
    <div class="container-fluid">
        <div class="span3 btn" 
            ng-repeat="a in cities"
            ng-click="gotoLocation(a.lat, a.lon)">
            <b>{{a.place}}</b>: {{a.desc}}
        </div>
    </div>
    <script>
    var app = angular.module("app", []);

    app.controller("appCtrl", function ($scope) {

        // current location
        $scope.loc = { lat: 23, lon: 79 };
        $scope.gotoCurrentLocation = function () {
            if ("geolocation" in navigator) {
                navigator.geolocation.getCurrentPosition(function (position) {
                    var c = position.coords;
                    $scope.gotoLocation(c.latitude, c.longitude);
                });
                return true;
            }
            return false;
        };
        $scope.gotoLocation = function (lat, lon) {
            if ($scope.lat != lat || $scope.lon != lon) {
                $scope.loc = { lat: lat, lon: lon };
                if (!$scope.$$phase) $scope.$apply("loc");
            }
        };

        // geo-coding
        $scope.search = "";
        $scope.geoCode = function () {
            if ($scope.search && $scope.search.length > 0) {
                if (!this.geocoder) this.geocoder = new google.maps.Geocoder();
                this.geocoder.geocode({ 'address': $scope.search }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        var loc = results[0].geometry.location;
                        $scope.search = results[0].formatted_address;
                        $scope.gotoLocation(loc.lat(), loc.lng());
                    } else {
                        alert("Sorry, this search produced no results.");
                    }
                });
            }
        };

    $scope.cities = [
                {
                    place : 'India',
                    desc : 'A country of culture and tradition!',
                    lat : 23.200000,
                    lon : 79.225487
                },
                {
                    place : 'New Delhi',
                    desc : 'Capital of India...',
                    lat : 28.500000,
                    lon : 77.250000
                },
                {
                    place : 'Kolkata',
                    desc : 'City of Joy...',
                    lat : 22.500000,
                    lon : 88.400000
                },
                {
                    place : 'Mumbai',
                    desc : 'Commercial city!',
                    lat : 19.000000,
                    lon : 72.90000
                },
                {
                    place : 'Bangalore',
                    desc : 'Silicon Valley of India...',
                    lat : 12.9667,
                    lon : 77.5667
                }
            ];    
    });

    // formats a number as a latitude (e.g. 40.46... => "40°27'44"N")
    app.filter('lat', function () {
        return function (input, decimals) {
            if (!decimals) decimals = 0;
            input = input * 1;
            var ns = input > 0 ? "N" : "S";
            input = Math.abs(input);
            var deg = Math.floor(input);
            var min = Math.floor((input - deg) * 60);
            var sec = ((input - deg - min / 60) * 3600).toFixed(decimals);
            return deg + "°" + min + "'" + sec + '"' + ns;
        }
    });

    // formats a number as a longitude (e.g. -80.02... => "80°1'24"W")
    app.filter('lon', function () {
        return function (input, decimals) {
            if (!decimals) decimals = 0;
            input = input * 1;
            var ew = input > 0 ? "E" : "W";
            input = Math.abs(input);
            var deg = Math.floor(input);
            var min = Math.floor((input - deg) * 60);
            var sec = ((input - deg - min / 60) * 3600).toFixed(decimals);
            return deg + "°" + min + "'" + sec + '"' + ew;
        }
    });

    // - Documentation: https://developers.google.com/maps/documentation/
    app.directive("appMap", function () {
        return {
            restrict: "E",
            replace: true,
            template: "<div></div>",
            scope: {
                center: "=",        // Center point on the map (e.g. <code>{ latitude: 10, longitude: 10 }</code>).
                markers: "=",       // Array of map markers (e.g. <code>[{ lat: 10, lon: 10, name: "hello" }]</code>).
                width: "@",         // Map width in pixels.
                height: "@",        // Map height in pixels.
                zoom: "@",          // Zoom level (one is totally zoomed out, 25 is very much zoomed in).
                mapTypeId: "@",     // Type of tile to show on the map (roadmap, satellite, hybrid, terrain).
                panControl: "@",    // Whether to show a pan control on the map.
                zoomControl: "@",   // Whether to show a zoom control on the map.
                scaleControl: "@"   // Whether to show scale control on the map.
            },
            link: function (scope, element, attrs) {
                var toResize, toCenter;
                var map;
                var currentMarkers;

                // listen to changes in scope variables and update the control
                var arr = ["width", "height", "markers", "mapTypeId", "panControl", "zoomControl", "scaleControl"];
                for (var i = 0, cnt = arr.length; i < arr.length; i++) {
                    scope.$watch(arr[i], function () {
                        cnt--;
                        if (cnt <= 0) {
                            updateControl();
                        }
                    });
                }

                // update zoom and center without re-creating the map
                scope.$watch("zoom", function () {
                    if (map && scope.zoom)
                        map.setZoom(scope.zoom * 1);
                });
                scope.$watch("center", function () {
                    if (map && scope.center)
                        map.setCenter(getLocation(scope.center));
                });

                // update the control
                function updateControl() {

                    // update size
                    if (scope.width) element.width(scope.width);
                    if (scope.height) element.height(scope.height);

                    // get map options
                    var options =
                    {
                        center: new google.maps.LatLng(23, 79),
                        zoom: 6,
                        mapTypeId: "roadmap"
                    };
                    if (scope.center) options.center = getLocation(scope.center);
                    if (scope.zoom) options.zoom = scope.zoom * 1;
                    if (scope.mapTypeId) options.mapTypeId = scope.mapTypeId;
                    if (scope.panControl) options.panControl = scope.panControl;
                    if (scope.zoomControl) options.zoomControl = scope.zoomControl;
                    if (scope.scaleControl) options.scaleControl = scope.scaleControl;

                    // create the map
                    map = new google.maps.Map(element[0], options);

                    // update markers
                    updateMarkers();

                    // listen to changes in the center property and update the scope
                    google.mapTypeIds.event.addListener(map, 'center_changed', function () {

                        // do not update while the user pans or zooms
                        if (toCenter) clearTimeout(toCenter);
                        toCenter = setTimeout(function () {
                            if (scope.center) {

                                // check if the center has really changed
                                if (map.center.lat() != scope.center.lat ||
                                    map.center.lng() != scope.center.lon) {

                                    // update the scope and apply the change
                                    scope.center = { lat: map.center.lat(), lon: map.center.lng() };
                                    if (!scope.$$phase) scope.$apply("center");
                                }
                            }
                        }, 500);
                    });
                }

                // update map markers to match scope marker collection
                function updateMarkers() {
                    if (map && scope.markers) {

                        // clear old markers
                        if (currentMarkers != null) {
                            for (var i = 0; i < currentMarkers.length; i++) {
                                currentMarkers[i] = m.setMap(null);
                            }
                        }

                        // create new markers
                        currentMarkers = [];
                        var markers = scope.markers;
                        if (angular.isString(markers)) markers = scope.$eval(scope.markers);
                        for (var i = 0; i < markers.length; i++) {
                            var m = markers[i];
                            var loc = new google.maps.LatLng(m.lat, m.lon);
                            var mm = new google.maps.Marker({ position: loc, map: map, title: m.name });
                            currentMarkers.push(mm);
                        }
                    }
                }

                // convert current location to Google maps location
                function getLocation(loc) {
                    if (loc == null) return new google.maps.LatLng(23, 79);
                    if (angular.isString(loc)) loc = scope.$eval(loc);
                    return new google.maps.LatLng(loc.lat, loc.lon);
                }
            }
        };
    });

    </script>
<script
    src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script
    src="http://maps.googleapis.com/maps/api/js?sensor=false&language=en"></script>
</body>

标签: javascriptangularjsgoogle-maps

解决方案


这是工作版本减去现在 Google Maps API 运行所需的API 密钥。地图现在在您的中心位置放置一个标记。

<!DOCTYPE html>
<html>
<body ng-app="app" ng-controller="appCtrl">
<h3>Google Maps</h3>

    <!-- search/go to current location -->
    <div class="text-right">
        <div class="input-append text-right">
            <input type="text" ng-model="search"/>
            <button class="btn" type="button" ng-click="geoCode()" ng-disabled="search.length == 0" title="search" >
              &nbsp;<i class="icon-search"></i>Where is this place?
            </button>
            <button class="btn" type="button" ng-click="gotoCurrentLocation()" title="current location">
              &nbsp;<i class="icon-home"></i>Where am I now?
            </button>
        </div>
    </div>

    <!-- map -->
    <div id="app-map" style="height:400px;margin:12px;box-shadow:0 3px 25px black;"
        center="loc"
        markers="cities"
    > 
    </div> -->

    <!-- current location -->
<!--     <div class="text-info text-right">
        {{loc.lat | lat:0}}, {{loc.lon | lon:0}}
    </div> -->

    <!-- list of airports -->
    <div class="container-fluid">
        <div class="span3 btn" 
            ng-repeat="a in cities"
            ng-click="gotoLocation(a.lat, a.lon)">
            <b>{{a.place}}</b>: {{a.desc}}
        </div>
    </div>
    
    
    <script
    src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>


    <script>
            var latitude = 41.8781;
    var longitude = -87.6298;
    
    function updateMarker(lat,lng) {
        var map = getMap(lat,lng);
        addMarker({lat:lat,lng:lng},map);
    }        
    function getMap(lat,lon) {
        var location = {lat:lat,lng:lon};
        return new google.maps.Map(document.getElementById('app-map'), { zoom: 6, center: location });;
        
    }
function initMap() {
        console.log("MAPS RETURNED");
        var markers = [];
        var uluru = { lat: latitude, lng: longitude };
        var map = getMap(latitude,longitude);
        //var marker = new google.maps.Marker({ position: uluru, map: map });
        addMarker(uluru,map);
}
        function addMarker(location, map) {
            console.log(location);
            var marker = new google.maps.Marker({
                position: location,
                map: map
            });
            
        }
        var app = angular.module("app", []);

    app.controller("appCtrl", function ($scope) {

        // current location
        $scope.loc = { lat: 23, lon: 79 };
        $scope.gotoCurrentLocation = function () {
            if ("geolocation" in navigator) {
                navigator.geolocation.getCurrentPosition(function (position) {
                    var c = position.coords;
                    $scope.gotoLocation(c.latitude, c.longitude);
                });
                return true;
            }
            return false;
        };
        $scope.gotoLocation = function (lat, lon) {
            if ($scope.lat != lat || $scope.lon != lon) {
                $scope.loc = { lat: lat, lon: lon };
                updateMarker(lat,lon);
                if (!$scope.$$phase) $scope.$apply("loc");
            }
        };

        // geo-coding
        $scope.search = "";
        $scope.geoCode = function () {
            if ($scope.search && $scope.search.length > 0) {
                if (!this.geocoder) this.geocoder = new google.maps.Geocoder();
                this.geocoder.geocode({ 'address': $scope.search }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        var loc = results[0].geometry.location;
                        $scope.search = results[0].formatted_address;
                        
                        $scope.gotoLocation(loc.lat(), loc.lng());
                    } else {
                        alert("Sorry, this search produced no results.");
                    }
                });
            }
        };

    $scope.cities = [
                {
                    place : 'India',
                    desc : 'A country of culture and tradition!',
                    lat : 23.200000,
                    lon : 79.225487
                },
                {
                    place : 'New Delhi',
                    desc : 'Capital of India...',
                    lat : 28.500000,
                    lon : 77.250000
                },
                {
                    place : 'Kolkata',
                    desc : 'City of Joy...',
                    lat : 22.500000,
                    lon : 88.400000
                },
                {
                    place : 'Mumbai',
                    desc : 'Commercial city!',
                    lat : 19.000000,
                    lon : 72.90000
                },
                {
                    place : 'Bangalore',
                    desc : 'Silicon Valley of India...',
                    lat : 12.9667,
                    lon : 77.5667
                }
            ];    
    });

    // formats a number as a latitude (e.g. 40.46... => "40°27'44"N")
    app.filter('lat', function () {
        return function (input, decimals) {
            if (!decimals) decimals = 0;
            input = input * 1;
            var ns = input > 0 ? "N" : "S";
            input = Math.abs(input);
            var deg = Math.floor(input);
            var min = Math.floor((input - deg) * 60);
            var sec = ((input - deg - min / 60) * 3600).toFixed(decimals);
            return deg + "°" + min + "'" + sec + '"' + ns;
        }
    });

    // formats a number as a longitude (e.g. -80.02... => "80°1'24"W")
    app.filter('lon', function () {
        return function (input, decimals) {
            if (!decimals) decimals = 0;
            input = input * 1;
            var ew = input > 0 ? "E" : "W";
            input = Math.abs(input);
            var deg = Math.floor(input);
            var min = Math.floor((input - deg) * 60);
            var sec = ((input - deg - min / 60) * 3600).toFixed(decimals);
            return deg + "°" + min + "'" + sec + '"' + ew;
        }
    });

    // - Documentation: https://developers.google.com/maps/documentation/
    app.directive("appMap", function () {
        return {
            restrict: "E",
            replace: true,
            template: "<div></div>",
            scope: {
                center: "=",        // Center point on the map (e.g. <code>{ latitude: 10, longitude: 10 }</code>).
                markers: "=",       // Array of map markers (e.g. <code>[{ lat: 10, lon: 10, name: "hello" }]</code>).
                width: "@",         // Map width in pixels.
                height: "@",        // Map height in pixels.
                zoom: "@",          // Zoom level (one is totally zoomed out, 25 is very much zoomed in).
                mapTypeId: "@",     // Type of tile to show on the map (roadmap, satellite, hybrid, terrain).
                panControl: "@",    // Whether to show a pan control on the map.
                zoomControl: "@",   // Whether to show a zoom control on the map.
                scaleControl: "@"   // Whether to show scale control on the map.
            },
            link: function (scope, element, attrs) {
                var toResize, toCenter;
                var map;
                var currentMarkers;

                // listen to changes in scope variables and update the control
                var arr = ["width", "height", "markers", "mapTypeId", "panControl", "zoomControl", "scaleControl"];
                for (var i = 0, cnt = arr.length; i < arr.length; i++) {
                    scope.$watch(arr[i], function () {
                        cnt--;
                        if (cnt <= 0) {
                            updateControl();
                        }
                    });
                }

                // update zoom and center without re-creating the map
                scope.$watch("zoom", function () {
                    if (map && scope.zoom)
                        map.setZoom(scope.zoom * 1);
                });
                scope.$watch("center", function () {
                    if (map && scope.center)
                        map.setCenter(getLocation(scope.center));
                });

                // update the control
                function updateControl() {

                    // update size
                    if (scope.width) element.width(scope.width);
                    if (scope.height) element.height(scope.height);

                    // get map options
                    var options =
                    {
                        center: new google.maps.LatLng(23, 79),
                        zoom: 6,
                        mapTypeId: "roadmap"
                    };
                    if (scope.center) options.center = getLocation(scope.center);
                    if (scope.zoom) options.zoom = scope.zoom * 1;
                    if (scope.mapTypeId) options.mapTypeId = scope.mapTypeId;
                    if (scope.panControl) options.panControl = scope.panControl;
                    if (scope.zoomControl) options.zoomControl = scope.zoomControl;
                    if (scope.scaleControl) options.scaleControl = scope.scaleControl;

                    // create the map
                    map = new google.maps.Map(element[0], options);

                    // update markers
                    updateMarkers();

                    // listen to changes in the center property and update the scope
                    google.mapTypeIds.event.addListener(map, 'center_changed', function () {

                        // do not update while the user pans or zooms
                        if (toCenter) clearTimeout(toCenter);
                        toCenter = setTimeout(function () {
                            if (scope.center) {

                                // check if the center has really changed
                                if (map.center.lat() != scope.center.lat ||
                                    map.center.lng() != scope.center.lon) {

                                    // update the scope and apply the change
                                    scope.center = { lat: map.center.lat(), lon: map.center.lng() };
                                    if (!scope.$$phase) scope.$apply("center");
                                }
                            }
                        }, 500);
                    });
                }

                // update map markers to match scope marker collection
                function updateMarkers() {
                    if (map && scope.markers) {

                        // clear old markers
                        if (currentMarkers != null) {
                            for (var i = 0; i < currentMarkers.length; i++) {
                                currentMarkers[i] = m.setMap(null);
                            }
                        }

                        // create new markers
                        currentMarkers = [];
                        var markers = scope.markers;
                        if (angular.isString(markers)) markers = scope.$eval(scope.markers);
                        for (var i = 0; i < markers.length; i++) {
                            var m = markers[i];
                            var loc = new google.maps.LatLng(m.lat, m.lon);
                            var mm = new google.maps.Marker({ position: loc, map: map, title: m.name });
                            currentMarkers.push(mm);
                        }
                    }
                }

                // convert current location to Google maps location
                function getLocation(loc) {
                    if (loc == null) return new google.maps.LatLng(23, 79);
                    if (angular.isString(loc)) loc = scope.$eval(loc);
                    return new google.maps.LatLng(loc.lat, loc.lon);
                }
            }
        };
    });

    </script>
<script async defer
            src="https://maps.googleapis.com/maps/api/js?key=[need api key]&callback=initMap">
    </script>
</body>
</html>


推荐阅读