2013-05-04 59 views
0

我很難將當前用戶位置的地理座標(緯度和經度)插入到PHP/MySQL生成的xml文件中。它要求用戶的地理位置正確地生成30英里範圍內的20家最近的企業。我目前使用jQuery驅動的商店定位器腳本來生成地圖。該腳本可以正常使用靜態URL作爲xmlLocation,但是當我嘗試在URL中使用變量時,它僅輸出未定義的警報消息。我的目標是讓javascript將用戶位置的緯度和經度值放入PHP GET變量中,以便XML生成器可以生成正確的輸出。它看起來像這樣:在jQuery文件中放置地理座標

LocationGlobal = '數據/ gen_default_map.php LAT =?' + LAT + '& LNG =' +經度+ '&半徑= 30';

而且應該輸出中是這樣的:?

數據/ gen_default_map.php LAT = 34.383747 & LNG = -82.364574 &半徑= 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); 

變量設置我需要xmlLocation是動態的地理定位的URL。看來這個變量沒有被正確設置。當我嘗試撥打LocationGlobal時,我收到一條未定義的錯誤消息。我在這個問題上進行了推測,並且已經用它來解決問題。任何幫助是極大的讚賞。謝謝。

回答

0

由於getCurrentLocation()操作的回調性質,警報顯示undefined。您必須從getCurrentLocation()操作的回調函數內調用LocationGlobal相關函數。可能像,

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 
}); 

希望這可以幫助。

+0

當你說getCurrentLocation()你的意思是getCurrentPosition()?另外,如果你說的是真的,我將不得不讓整個storeLocator jQuery成爲getCurrentPosition的依賴函數,反之亦然? – Artsy 2013-05-06 13:46:55

+0

是的,我的意思是'getCurrentPosition','getCurrentLocation'是一個錯字。我不知道'storeLocaor'確切地說了些什麼,但是你必須以某種方式採用'getCurrentPosition'回調的異步特性。 – shakib 2013-05-06 18:01:15