google maps over query limit
Asked Answered
T

1

0

I know that similar questions have been posted but I have not found and answer in any of them as it relates to my particular issue.

I have a javascript that uses google maps to place customer zipcodes on a map. The problem I am have is similar to what others have already posted – I get a “over query limit” error.

I have tried different setups using setTimeOut to try to send google the data within the allowable time intervals but I can’t get it to work.

Here is my action:

        function initialize() 
        {
            var rowNum      = 0 ; 
            var rowColor    = "" ;

            var latlng      = new google.maps.LatLng(27.91425, -82.842617);             

            var myOptions   = 
            {
                zoom: 7,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            map             = new google.maps.Map(document.getElementById("map_canvas"),myOptions);

            geocoder        = new google.maps.Geocoder();

            data.forEach(function(mapData,idx) 
            {       
                window.setTimeout(function() 
                { 
                    geocoder.geocode({ 'address': mapData.address}, function(results, status) 
                    {                   
                        if (status == google.maps.GeocoderStatus.OK) 
                        {
                            var marker = new google.maps.Marker({
                            map: map, 
                            position: results[0].geometry.location,
                            title: mapData.title,
                            icon: getIcon(mapData.type)
                        });

                        var contentHtml = "<div style='width:250px;height:90px'><strong>"+mapData.title+"</strong><br />"+mapData.address+"</div>";

                        var infowindow = new google.maps.InfoWindow({
                            content: contentHtml
                        });

                        google.maps.event.addListener(marker, 'click', function() 
                        {
                          infowindow.open(map,marker);
                        });

                        marker.locid = idx+1;
                        marker.infowindow = infowindow;
                        markers[markers.length] = marker;

                        if (idx%2 == 0)
                        {
                            rowColor = 'style="background-color:#00FFFF;"' ; 
                        }
                        else
                        {
                            rowColor = 'style="background-color:#FFFFFF;"' ; 
                        }

                        var sideHtml = '<div ' + rowColor + ' class="loc" data-locid="'+marker.locid+'"><b>'+mapData.title+'</b><br/>';
                             sideHtml += mapData.address + '</div>';
                             $("#locs").append(sideHtml); 

                        //Are we all done? Not 100% sure of this
                        if(markers.length == data.length) doFilter();
                    } 
                    else 
                    {
                        // alert("Geocode was not successful for the following reason: " + status);
                    }   
                }, 3000);                   
            });                             
        });

When I run my page using this action, I get back 11 markers even though I have many more than that in my JSON string. The window.setTimeout has absolutely no effect – I’m obviously doing something wrong here.

I would appreciate any help on this matter.

Thanks,

Torture answered 20/5, 2013 at 22:30 Comment(3)
How many points are you trying to display? If it is lots of points the general answer is "Don't geocode known locations every time you load your page. Geocode them off-line and use the resulting coordinates to display the markers on your page."Digestible
In my current example, I’m trying to load about 100 markers from a static JSON string. In reality, I will need to dynamically load a JSON string based on a specific search criteria according to the clients needs. The client has store data in a MySQL database. The user is first prompted on a form in order to filter the necessary data – lets say sales for a specific month. I then use a Java action to query the database which in turn returns the JSON string. The Google map is done using this string. Sales are placed on the map based on the customer’s zip code.Torture
You need to obtain a database of geographic coordinates for zipcodes. Geocoding 100 (or more) zipcodes on page load will take too long. They aren't going to move. Either that or do the geocoding on the server, and cache the geographic information in your database per the terms of use.Digestible
T
2

I found the answer to my question. I found the following code on the Web and modified it to my needs.

With it, you can load many markers without getting Over Query Limit from Google.

I have tested it with over 100 markers and it works beautifully. The page does not freeze up at all.

I am certain some of you guys can do something much more elegant and efficient but this is a good starting point.

<script type="text/javascript">
    //<![CDATA[    

// display ani gif
    loadingGMap() ; 

 // delay between geocode requests - at the time of writing, 100 miliseconds seems to work well
      var delay = 100;

    // ====== Create map objects ======
        var infowindow = new google.maps.InfoWindow();
    var latlng = new google.maps.LatLng(27.989551,-82.462235);

    var mapOptions = 
    {
        zoom: 7,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }

    var geo         = new google.maps.Geocoder(); 
    var map     = new google.maps.Map(document.getElementById("map"), mapOptions);
    var bounds  = new google.maps.LatLngBounds();

    // ====== Geocoding ======
    function getAddress(search, next) 
    {
        geo.geocode({address:search}, function (results,status)
        { 
            // If that was successful
            if (status == google.maps.GeocoderStatus.OK) 
            {
                // Lets assume that the first marker is the one we want
                var p   = results[0].geometry.location;
                var lat = p.lat();
                var lng = p.lng();

                // Output the data
                var msg = 'address="' + search + '" lat=' +lat+ ' lng=' +lng+ '(delay='+delay+'ms)<br>';
                //document.getElementById("messages").innerHTML += msg;
                // Create a marker

                createMarker(search,lat,lng);
            }
            // ====== Decode the error status ======
            else 
            {
                // === if we were sending the requests to fast, try this one again and increase the delay
                if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) 
                {
                    nextAddress--;
                    delay++;
                } 
                else 
                {
                    var reason  =   "Code "+status;
                    var msg     = 'address="' + search + '" error=' +reason+ '(delay='+delay+'ms)<br>';
                    // document.getElementById("messages").innerHTML += msg;
                }   
            }
            next();
        }
    );
}

// ======= Function to create a marker
function createMarker(add,lat,lng) 
{
    var contentString   = add;  

    if (add=='EOF') 
    {
        stopLoadingGMap() ; 
    }

    var addArray        = add.split(' ');       
    var zipcode         = addArray.pop();
    var zipcode         = add.match(/\d{5}/)[0] ;       

    var image           = 'icons/sm_02.png';        
    var marker          = new MarkerWithLabel(
    {
            position: new google.maps.LatLng(lat,lng),
        map: map,
        icon: image,
        labelContent: zipcode,
        labelAnchor: new google.maps.Point(50, 0),
         labelClass: "labels", // the CSS class for the label
         labelStyle: {opacity: 0.75},           
        zIndex: Math.round(latlng.lat()*-100000)<<5
    });

    google.maps.event.addListener(marker, 'click', function() 
    {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
    });

    bounds.extend(marker.position);
}

// ======= An array of locations that we want to Geocode ========
// use static or build dynamically
// use as many markers as you need – I’ve test with over 100
var addresses = var data = [
{‘StreetAddress1 City State Zipcode’},
    {‘StreetAddress2 City State Zipcode’},
    {‘StreetAddress3 City State Zipcode’},
    {‘StreetAddress14 City State Zipcode’},
…
    {‘EOF’},
    ];

// ======= Global variable to remind us what to do next
var nextAddress = 0;

// ======= Function to call the next Geocode operation when the reply comes back
function theNext() 
{
    if (nextAddress < addresses.length) 
    {
        setTimeout('getAddress("'+addresses[nextAddress]+'",theNext)', delay);
        nextAddress++;
         } 
    else 
    {
        // We're done. Show map bounds
        map.fitBounds(bounds);
            }
}

// ======= Call that function for the first time =======
theNext();

// This Javascript is based on code provided by the
 // Community Church Javascript Team
 // http://www.bisphamchurch.org.uk/   
 // http://econym.org.uk/gmap/

    //]]>
    </script>
Torture answered 25/5, 2013 at 21:39 Comment(1)
Please don’t spam links to your question (especially with that formatting) everywhere. Either comment (when you can) or flag (again, when you can) as a duplicate if appropriate.Dossier

© 2022 - 2024 — McMap. All rights reserved.