0

我很难将当前用户位置的地理坐标(纬度和经度)插入到 PHP/MySQL 生成的 xml 文件中。它要求用户的地理位置正确生成 30 英里半径内最近的 20 家企业。我目前正在使用 jQuery 驱动的商店定位器脚本来生成地图。该脚本使用静态 URL 作为 xmlLocation 可以正常工作,但是当我尝试在 URL 中使用变量时,它只会输出未定义的警报消息。我的目标是让 javascript 将用户位置的纬度和经度值放入 PHP GET 变量中,以便 XML 生成器可以生成正确的输出。它看起来像这样:

LocationGlobal = 'data/gen_default_map.php?lat=' + lat + '&lng=' + lon + '&radius=30';

并且应该输出如下内容:

数据/gen_default_map.php?lat=34.383747&lng=-82.364574&radius=30

我已经对脚本进行了修改并相应地发表了评论。您可能只需要关注代码的前 42 行,但以防万一这里是整个脚本:

/* Get the User's Current Location and place it in the URL */   
/*--------------------------------------------------*/

var LocationGlobal;

if(navigator.geolocation)
{
    navigator.geolocation.getCurrentPosition(function(position)
{
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    LocationGlobal = 'data/gen_default_map.php?lat=' + lat + '&lng=' + lon + '&radius=30';
    alert(LocationGlobal); // Sets correctly here
    return LocationGlobal;
    });
} else {
    console.log('Error getting coordinates.');  
}

alert(LocationGlobal); // Undefined here
/*--------------------------------------------------*/

(function ($) {
$.fn.storeLocator = function (options) {

    var settings = $.extend({
        'mapDiv': 'map',
        'listDiv': 'list',
        'formID': 'user-location',
        'pinColor': 'fe7569',
        'startPinColor': '66bd4a',
        'pinTextColor': '000000',
        'storeLimit': 10,
        'distanceAlert': 60,
        'xmlLocation': LocationGlobal, //'data/gen_default_map.php?lat=34&lng=-82&radius=30', <--- the commented static URL works but variable doesn't
        'addressErrorMsg': 'Please enter valid address address or postcode',
        'googleDistanceMatrixDestinationLimit': 25,
        'defaultLat': 34.8483680,
        'defaultLng': -82.400440,
        'defaultLocationName': 'Greenville, South Carolina'
    }, options);

    return this.each(function () {
        var $this = $(this);

        // global array of shop objects
        var _locationset = new Array();
        var geocoder;

        // Calculate distances from passed in origin to all locations in the [_locationset] array
        // using Google Maps Distance Matrix Service https://developers.google.com/maps/documentation/javascript/reference#DistanceMatrixService
        var GeoCodeCalc = {};
        GeoCodeCalc.CalcDistanceGoogle = function (origin, callback) {
            var destCoordArr = new Array();
            var subFunctionTokens = [];

            $.each(_locationset, function (ix, loc) {
                destCoordArr.push(loc.LatLng);
            });

            for (var i = 0; i < destCoordArr.length; i = i + settings.googleDistanceMatrixDestinationLimit) { // Google Distance Matrix allows up to 25 destinations to be passed in
                var tempArr = destCoordArr.slice(i, Math.min(i + settings.googleDistanceMatrixDestinationLimit));
                subFunctionTokens.push(this.CallGoogleDistanceMatrix(i, origin, tempArr));
            }

            $.when.apply($, subFunctionTokens)
                  .then(function () {
                      callback(true);
                  });
        };

        GeoCodeCalc.CallGoogleDistanceMatrix = function (startIndex, origin, destinations) {
            var token = $.Deferred();
            var service = new google.maps.DistanceMatrixService();
            service.getDistanceMatrix(
              {
                  origins: [origin],
                  destinations: destinations,
                  travelMode: google.maps.TravelMode.DRIVING,
                  unitSystem: google.maps.UnitSystem.IMPERIAL
              }, function (response, status) {
                  if (response && response.rows.length) {
                      var results = response.rows[0].elements;
                      $.each(results, function (j, val) {
                          if (results[j].status != "ZERO_RESULTS") {
                              _locationset[startIndex + j].Distance = GoogleMapDistanceTextToNumber(results[j].distance.text);
                          }
                      });

                      token.resolve();
                  }
              });

            return token.promise();
        };

        // Converts "123.45 mi" into 123.45
        function GoogleMapDistanceTextToNumber(str) {
            return Number(str.replace(/[^0-9.]/g, ""));
        }

        // removes Google Maps URL unfriendly chars from a string
        function formatGoogleMapUrlString(str) {
            return str.replace("&", "%26").replace(" ", "+");
        }

        //Geocode function for the origin location
        geocoder = new google.maps.Geocoder();
        function GoogleGeocode() {
            this.geocode = function (address, callbackFunction) {
                geocoder.geocode({ 'address': address }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        var result = {};
                        result.latitude = results[0].geometry.location.lat();
                        result.longitude = results[0].geometry.location.lng();
                        result.formatted_address = results[0].formatted_address;
                        result.address_components = results[0].address_components;
                        callbackFunction(result);
                    } else {
                        handleError("Geocode was not successful for the following reason: " + status);
                        callbackFunction(null);
                    }
                });
            };

            this.geocodeLatLng = function (LatLng, callbackFunction) {
                geocoder.geocode({ 'location': LatLng }, function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK && results.length) {
                        callbackFunction(results[0]);
                    } else {
                        handleError("Geocode was not successful for the following reason: " + status);
                        callbackFunction(null);
                    }
                });
            };
        }

        //Process form input
        $(function () {
            $(document).on('submit', '#' + settings.formID, function (e) {
                $("#lblError").html("");
                //Stop the form submission
                e.preventDefault();
                //Get the user input and use it
                var userinput = $('form').serialize();
                userinput = userinput.replace("address=", "");
                if (userinput == "") {
                    handleError(settings.addressErrorMsg);
                }

                var g = new GoogleGeocode();
                var address = userinput;
                g.geocode(address, function (data) {
                    if (data != null) {
                        showAddress(data);
                        mapping(data.latitude, data.longitude);
                    } else {
                        //Unable to geocode
                        handleError(settings.addressErrorMsg);
                    }
                });

                //Replace spaces in user input
                userinput = formatGoogleMapUrlString(userinput);
            });
        });

        $(document).ready(function () {
            // Try HTML5 geolocation
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function (position) {
                    //map.setCenter(pos);
                    var g = new GoogleGeocode();
                    var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

                    g.geocodeLatLng(latlng, function (address) {
                        if (address) {
                            showAddress(address);
                        } else {
                            //Unable to geocode
                            handleNoGeolocation('Error: Unable to geocode address');
                        }
                    });

                    // do the mapping stuff
                    mapping(position.coords.latitude, position.coords.longitude);

                }, function () {
                    handleNoGeolocation("Tracking of location was not allowed.");
                });
            } else {
                // Browser doesn't support Geolocation
                handleNoGeolocation(false);
            }
        });

        function showAddress(address) {
            $("#lblAddress").html(address.formatted_address);
            // find a postcode and show it in the address textbox
            $.each(address.address_components, function (i, val) {
                if (val.types[0] == "postal_code") {
                    $("#address").val(val.short_name);
                    return false; // breaks the each() loop
                }
            });
        }

        function handleNoGeolocation(error) {
            if (error) {
                var content = error;
            } else {
                var content = 'Error: Your browser doesn\'t support geolocation.';
            }

            handleError(content + " Using default location.");
            mapping(settings.defaultLat, settings.defaultLng);
            $("#lblAddress").html(settings.defaultLocationName);

        }

        function handleError(error) {
            $("#lblError").html(error);
        }

        //Now all the mapping stuff
        function mapping(orig_lat, orig_lng) {
            $(function () {
                //Parse xml with jQuery
                $.ajax({
                    type: "GET",
                    url: settings.xmlLocation,
                    dataType: "xml",
                    success: function (xml) {
                        _locationset = new Array();
                        $(xml).find('Placemark').each(function (i) {
                            var shop = {
                                Name: $(this).find('name').text(),
                                //Take the lat lng from the user, geocoded above
                                LatLng: new google.maps.LatLng(
                                    $(this).find('coordinates').text().split(",")[1],
                                    $(this).find('coordinates').text().split(",")[0]),
                                Description: $(this).find('description').text(),
                                Marker: null,
                                Distance: null
                            };
                            _locationset.push(shop);
                        });

                        // Calc Distances from user's location
                        GeoCodeCalc.CalcDistanceGoogle(new google.maps.LatLng(orig_lat, orig_lng), function (success) {
                            if (!success) { //something went wrong
                                handleError("Unable to calculate distances at this time");
                            }
                            else {
                                //Sort the multi-dimensional array numerically
                                _locationset.sort(function (a, b) {
                                    return ((a.Distance < b.Distance) ? -1 : ((a.Distance > b.Distance) ? 1 : 0));
                                });

                                // take "N" closest shops
                                _locationset = _locationset.slice(0, settings.storeLimit);

                                //Check the closest marker
                                if (_locationset[0].Distance > settings.distanceAlert) {
                                    handleError("Unfortunately, our closest location is more than " + settings.distanceAlert + " miles away.");
                                }

                                //Create the map with jQuery
                                $(function () {
                                    var orig_LatLng = new google.maps.LatLng(orig_lat, orig_lng);
                                    //Google maps settings
                                    var myOptions = {
                                        center: orig_LatLng,
                                        mapTypeId: google.maps.MapTypeId.ROADMAP
                                    };

                                    var map = new google.maps.Map(document.getElementById(settings.mapDiv), myOptions);
                                    //Create one infowindow to fill later
                                    var infowindow = new google.maps.InfoWindow();

                                    //Add user location marker
                                    var marker = createUserMarker(orig_LatLng, "0", settings.startPinColor);
                                    marker.setAnimation(google.maps.Animation.DROP);
                                    var bounds = new google.maps.LatLngBounds();
                                    bounds.extend(orig_LatLng);

                                    $("#" + settings.listDiv).empty();

                                    $(_locationset).each(function (i, location) {
                                        bounds.extend(location.LatLng);
                                        letter = String.fromCharCode("A".charCodeAt(0) + i);
                                        location.Marker = createMarker(location.LatLng, letter, settings.pinColor);
                                        create_infowindow(location);
                                        listClick(letter, location);
                                    });

                                    // zoom in/out to show all markers
                                    map.fitBounds(bounds);

                                    function listClick(letter, shop) {
                                        $('<li />').html("<div class=\"list-details\">"
                                        + "<div class=\"list-label\">" + letter + "<\/div><div class=\"list-content\">"
                                        + "<div class=\"loc-name\">" + shop.Name + "<\/div> <div class=\"loc-addr\">" + shop.Description + "<\/div>"
                                        + (shop.Distance ? "<div class=\"loc-addr2\"><i>approx. " + shop.Distance + " " + ((shop.Distance == 1) ? "mile" : "miles" ) + "</i><\/div>" : "")
                                        + "<div class=\"loc-web\"><a href=\"http://maps.google.co.uk/maps?saddr="
                                        + formatGoogleMapUrlString($("#address").val()) + "+%40" + orig_lat + "," + orig_lng
                                        + "&daddr=" + formatGoogleMapUrlString(shop.Name) + "+%40" + shop.LatLng.lat() + "," + shop.LatLng.lng()
                                        + "&hl=en" + "\" target=\"_blank\">&raquo; Get directions</a><\/div><\/div><\/div>")
                                        .click(function () {
                                            create_infowindow(shop, "left");
                                        }).appendTo("#" + settings.listDiv);
                                    };

                                    //Custom marker function - aplhabetical
                                    function createMarker(point, letter, pinColor) {
                                        //Set up pin icon with the Google Charts API for all of our markers
                                        var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + letter + "|" + pinColor + "|" + settings.pinTextColor,
                                          new google.maps.Size(21, 34),
                                          new google.maps.Point(0, 0),
                                          new google.maps.Point(10, 34));
                                        var pinShadow = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_shadow",
                                          new google.maps.Size(40, 37),
                                          new google.maps.Point(0, 0),
                                          new google.maps.Point(12, 35));

                                        //Create the markers
                                        return new google.maps.Marker({
                                            position: point,
                                            map: map,
                                            icon: pinImage,
                                            shadow: pinShadow,
                                            draggable: false
                                        });
                                    };

                                    //Custom marker function - aplhabetical
                                    function createUserMarker(point, letter, pinColor) {
                                        //Set up pin icon with the Google Charts API for all of our markers
                                        var pinImage = new google.maps.MarkerImage("images/green_pin.png");

                                        //Create the markers
                                        return new google.maps.Marker({
                                            position: point,
                                            map: map,
                                            title: "Your Location",
                                            icon: pinImage,
                                            draggable: false
                                        });
                                    };

                                    //Infowindows
                                    function create_infowindow(shop, listLocation) {

                                        //Is the distance more than one mile?
                                        if (shop.Distance == 1) {
                                            var mi_s = "mile";
                                        } else {
                                            var mi_s = "miles";
                                        }

                                        var formattedAddress = "<div class=\"infoWindow\"><b>" + shop.Name + "<\/b>"
                                        + "<div>" + shop.Description + "<\/div>"
                                        + (shop.Distance ? "<div><i>" + shop.Distance + " " + mi_s + "<\/i><\/div><\/div>" : "<\/div>");

                                        //Opens the infowindow when list item is clicked
                                        if (listLocation == "left") {
                                            infowindow.setContent(formattedAddress);
                                            infowindow.open(shop.Marker.get(settings.mapDiv), shop.Marker);
                                        }
                                        //Opens the infowindow when the marker is clicked
                                        else {
                                            google.maps.event.addListener(shop.Marker, 'click', function () {
                                                infowindow.setContent(formattedAddress);
                                                infowindow.open(shop.Marker.get(settings.mapDiv), shop.Marker);
                                            })
                                        }
                                    };
                                });
                            }
                        });
                    }
                });
            });
        }

    });
};
})(jQuery);

var 设置下,我需要 xmlLocation 作为动态地理定位的 URL。似乎变量设置不正确。当我尝试调用LocationGlobal时收到未定义的错误消息。我已经对这个问题进行了推测,并且已经走到了死胡同。任何帮助是极大的赞赏。谢谢。

4

1 回答 1

0

undefined由于操作的回调性质而显示警报getCurrentLocation()。您必须LocationGlobal从操作的回调函数内部调用依赖函数getCurrentLocation()。大概喜欢,

navigator.geolocation.getCurrentPosition(function(position)
{
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    LocationGlobal = 'data/gen_default_map.php?lat=' + lat + '&lng=' + lon + '&radius=30';
    alert(LocationGlobal);
    $('#map').storeLocaor({ mapDiv: 'map', xmlLocation: LocationGlobal  }); //Just an example
});

希望这可以帮助。

于 2013-05-05T06:53:58.167 回答