Update jQuery jqgrid column with google api addres

2019-04-15 08:45发布

问题:

I am trying to get the address from the google maps api and display this address in the right column of my table when there is not already a value there. When they have a custom address defined in the code this address is shown, but when it needs to show the address from the google maps api it doesn't show up. What do I need to change to make these show up?

var oTable = $("#example").dataTable({
  "aoColumns": [{
    "sTitle": "Time"
  }, {
    "sTitle": "Lat"
  }, {
    "sTitle": "Long"
  }, {
    "sTitle": "Addr"
  }]
});
var p = [
        ["10:00:00", "78.8807865", "17.8921649", "got Address"]
];
for (var j = 0; j < 400; j++) {
p.push(["10:00:"+j, "78.4807865", "17.4921649", ""]);
}
alert(p.length);
oTable.fnAddData(p);

for (var i = 0; i < p.length; i++) {
  if (p[i][3] == "") {
    var geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(p[i][1], p[i][2]);
    function getAddr(i){

  geocoder.geocode({
    "latLng": latlng
  }, function(results, status) {
    var address;
    if (status == 'OVER_QUERY_LIMIT') {
      address = 'Loading...';
      setTimeout(function(){ getAddr(i); }, 1000);
    } else if (status == 'OK') {
      address = results[0].formatted_address;
    } else {
      address = 'Error: ' + status;
    }
    p[i][3] = address;
    oTable.fnUpdate(p[i], i);
  });

}

getAddr(i);}
}
<link href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<table id="example"></table>

UPDATED CODE

  • with this updated Code BROWSER NOT RESPONDING and BROWSER STRUCK.
  • any advice for more then calls of client side google map api avoid BROWSER NOT RESPONDING and BROWSER STRUCK(if it takes more time not a problem,need solution for without struck the browser),
  • thanks in advance.

回答1:

When the callback is called, the loop has already finished, so the loop variable i is outside of the array p.

You can use a function expression to create a scope where a copy of the variable i survives until the data arrives:

var oTable = $("#example").dataTable({
  "aoColumns": [{
    "sTitle": "Time"
  }, {
    "sTitle": "Lat"
  }, {
    "sTitle": "Long"
  }, {
    "sTitle": "Addr"
  }]
});
var p = [
  ["10:00:00", "17.4807865", "78.4921649", ""],
  ["10:00:01", "17.5807865", "78.5921649", ""],
  ["10:00:02", "17.6807865", "78.6921649", "Somthing address"],
  ["10:00:03", "17.7807865", "78.7921649", ""],
  ["10:00:04", "17.8807865", "78.8921649", "got Address"],
  ["10:00:05", "17.4807865", "78.4921649", ""],
  ["10:00:06", "17.5807865", "78.5921649", ""],
  ["10:00:07", "17.6807865", "78.6921649", "Somthing address"],
  ["10:00:08", "17.7807865", "78.7921649", ""],
  ["10:00:09", "17.8807865", "78.8921649", "got Address"],
  ["10:00:10", "17.4807865", "78.4921649", ""],
  ["10:00:11", "17.5807865", "78.5921649", ""],
  ["10:00:12", "17.6807865", "78.6921649", "Somthing address"],
  ["10:00:13", "17.7807865", "78.7921649", ""],
  ["10:00:14", "17.8807865", "78.8921649", "got Address"],
  ["10:00:15", "17.4807865", "78.4921649", ""],
  ["10:00:16", "17.5807865", "78.5921649", ""],
  ["10:00:17", "17.6807865", "78.6921649", "Somthing address"],
  ["10:00:18", "17.7807865", "78.7921649", ""],
  ["10:00:19", "17.8807865", "78.8921649", "got Address"],
  ["10:00:19", "17.8807865", "78.8921649", "got Address"],
];

oTable.fnAddData(p);
for (var i = 0; i < p.length; i++) {
  if (p[i][3] == "") {
    var geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(p[i][1], p[i][2]);
    
    (function(i){
    
      geocoder.geocode({
        "latLng": latlng
      }, function(results, status) {
        var address;
        if (status == 'OK') {
          address = results[0].formatted_address;
        } else {
          address = 'Error: ' + status;
        }
        p[i][3] = address;
        oTable.fnUpdate(p[i], i);
      });

    })(i);
    
  }
}
<link href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<table id="example"></table>

To use a timeout to circumvent the query limit, it looks like this:

    function getAddr(i){

      geocoder.geocode({
        "latLng": latlng
      }, function(results, status) {
        var address;
        if (status == 'OVER_QUERY_LIMIT') {
          address = 'Loading...';
          setTimeout(function(){ getAddr(i); }, 1500);
        } else if (status == 'OK') {
          address = results[0].formatted_address;
        } else {
          address = 'Error: ' + status;
        }
        p[i][3] = address;
        oTable.fnUpdate(p[i], i);
      });

    }

    getAddr(i);


回答2:

  • Try this Code.

    oTable.fnUpdate(p[i],i);



回答3:

Why don't you use a reverse geocode service to curate this in your datasource server-side? You're likely to be hitting query api limits for google pretty quickly, and unless you're combining this with a maps display, I'm pretty sure it violates TOS.

There are many free and paid services available. You can also download data sets and roll your own.

  • https://geoservices.tamu.edu/Services/ReverseGeocoding/