หลีกเลี่ยงการ จำกัด รหัสภูมิศาสตร์ของ Google Maps หรือไม่


32

ฉันกำลังสร้างแผนที่ google แบบกำหนดเองที่มีตัวทำเครื่องหมาย 125 จุดผ่านทางเซนติเมตร เมื่อโหลดแผนที่ฉันได้รับข้อความนี้:

รหัสภูมิศาสตร์ไม่สำเร็จด้วยเหตุผลดังต่อไปนี้: OVER_QUERY_LIMIT

ฉันค่อนข้างแน่ใจว่ามันเป็นวิธีที่ฉันใช้ระบุตำแหน่งทางภูมิศาสตร์

ฉันจะหลีกเลี่ยงคำเตือนเหล่านี้และมีวิธีที่มีประสิทธิภาพมากขึ้นในการเข้ารหัสผลลัพธ์หรือไม่

ปรับปรุง: นี่คือความพยายามของฉันที่คำตอบของเคซี่ย์ฉันเพิ่งได้รับหน้าว่างในขณะนี้

<script type="text/javascript"> 
(function() { 

window.onload = function() { 
 var mc;
// Creating an object literal containing the properties we want to pass to the map 
var options = { 
zoom: 10, 
center: new google.maps.LatLng(52.40, -3.61), 
mapTypeId: google.maps.MapTypeId.ROADMAP 
}; 

// Creating the map 
var map = new google.maps.Map(document.getElementById('map'), options); 

// Creating a LatLngBounds object 
var bounds = new google.maps.LatLngBounds(); 

// Creating an array that will contain the addresses 
var places = []; 

// Creating a variable that will hold the InfoWindow object 
var infowindow; 
mc = new MarkerClusterer(map);
<?php
$pages = get_pages(array('child_of' => $post->ID, 'sort_column' => 'menu_order'));
$popup_content = array();
foreach($pages as $post)
    {
    setup_postdata($post);
    $fields = get_fields(); 
    $popup_content[] = '<p>'.$fields->company_name.'</p><img src="'.$fields->company_logo.'" /><br /><br /><a href="'.get_page_link($post->ID).'">View profile</a>';
    $comma = ", ";
    $full_address = "{$fields->address_line_1}{$comma}{$fields->address_line_2}{$comma}{$fields->address_line_3}{$comma}{$fields->post_code}";
    $address[] = $full_address;
    }
wp_reset_query();
echo 'var popup_content = ' . json_encode($popup_content) . ';';
echo 'var address = ' . json_encode($address) . ';';
?>

var geocoder = new google.maps.Geocoder(); 

var markers = [];

// Adding a LatLng object for each city  
for (var i = 0; i < address.length; i++) { 
    (function(i) { 
        geocoder.geocode( {'address': address[i]}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                places[i] = results[0].geometry.location;

                // Adding the markers 
                var marker = new google.maps.Marker({position: places[i], map: map});
                markers.push(marker);
                mc.addMarker(marker);

                // Creating the event listener. It now has access to the values of i and marker as they were during its creation
                google.maps.event.addListener(marker, 'click', function() {
                    // Check to see if we already have an InfoWindow
                    if (!infowindow) {
                        infowindow = new google.maps.InfoWindow();
                    }

                    // Setting the content of the InfoWindow
                    infowindow.setContent(popup_content[i]);

                    // Tying the InfoWindow to the marker 
                    infowindow.open(map, marker);
                });

                // Extending the bounds object with each LatLng 
                bounds.extend(places[i]); 

                // Adjusting the map to new bounding box 
                map.fitBounds(bounds) 
            } else { 
            alert("Geocode was not successful for the following reason: " + status); 
            }

        });

    })(i);

} 
var markerCluster = new MarkerClusterer(map, markers); 
} 
})
(); 
</script> 

มันไม่สำคัญว่าโซลูชันจะเป็นอะไรตราบใดที่เครื่องหมายถูกโหลดขึ้นมาทันทีและไม่ได้ละเมิดข้อกำหนดและเงื่อนไขใด ๆ


คุณไม่ได้บอกว่าทำไมหรือบ่อยครั้งที่คุณทำการค้นหาเหล่านี้ คุณไม่ได้พยายามที่จะเข้ารหัสจุดเดียวกันทุกหน้าเรนเดอร์ใช่ไหม? หากเป็นกรณีนี้คุณควรใช้ api เพื่อค้นหาเซิร์ฟเวอร์เหล่านี้เพียงครั้งเดียวเมื่อมีการเพิ่มตำแหน่งลงในฐานข้อมูลเป็นครั้งแรก
ปีเตอร์

หากคุณต้องการลองคำแนะนำของ @ Peter มีเครื่องมือง่ายๆ ที่นี่ซึ่งจะเข้ารหัสจุดในสเปรดชีตของ Google สิ่งนี้จะช่วยให้คุณสามารถเขียน lat / long สำหรับเมืองต่างๆลงใน CMS ดังนั้นคุณไม่จำเป็นต้องใช้ geocoder ในเวลาทำงาน
สตีเฟ่นนำ

@ Peter จริง ๆ แล้วดูเหมือนว่าเป็นความคิดที่ดี ฉันขาดไปเล็กน้อยเพราะจะช่วยลดการใช้งาน cms ของฉัน หากลูกค้าต้องการค้นหา lat / long ต่อ บริษัท มากกว่าเพียงแค่ป้อนที่อยู่ก็ไม่เป็นมิตรกับผู้ใช้ ฉันเข้าใจถูกต้องหรือไม่
Rob

ดูคำตอบใหม่ของฉันลดลงสำหรับฟังก์ชั่น PHP
ปีเตอร์

2
@rob FWIW ฉันคิดว่า Ragi มีแนวทางที่ถูกต้อง คำตอบของ Casey ยังต้องการให้คุณใส่รหัสภูมิศาสตร์ทุกจุดทุกครั้งที่วาดแผนที่ซึ่งไม่จำเป็นสำหรับชุดข้อมูลคงที่ของคุณ
Stephen Lead

คำตอบ:


57

เช่นเดียวกับคนอื่น ๆ ฉันจะให้คำตอบที่มีรหัส แต่ผมไม่คิดว่าใครบางคนได้อธิบายให้คุณว่าคุณกำลังทำอะไรบางอย่างที่ผิดปกติพื้นฐาน

ทำไมคุณถึงกดปุ่มผิดพลาดนี้? เพราะคุณกำลังเรียกรหัสทางภูมิศาสตร์ทุกครั้งที่มีคนดูหน้าของคุณและคุณไม่ได้แคชผลลัพธ์ของคุณทุกที่ในฐานข้อมูล!

เหตุผลที่มีข้อ จำกัด คือเพื่อป้องกันการใช้ทรัพยากรของ Google ในทางที่ผิด (ไม่ว่าจะด้วยความเต็มใจหรือไม่เต็มใจ) - ซึ่งเป็นสิ่งที่คุณกำลังทำอยู่ :)

แม้ว่ารหัสภูมิศาสตร์ของ Google จะรวดเร็ว แต่ถ้าทุกคนใช้มันแบบนี้มันจะทำให้เซิร์ฟเวอร์ของพวกเขาล่ม เหตุผลที่ Google Fusion Tables มีอยู่คือการยกด้านเซิร์ฟเวอร์จำนวนมากสำหรับคุณ การเข้ารหัสทางภูมิศาสตร์และการเรียงไทล์จะทำบนเซิร์ฟเวอร์ของพวกเขา หากคุณไม่ต้องการใช้สิ่งนั้นคุณควรแคชข้อมูลเหล่านั้นบนเซิร์ฟเวอร์ของคุณ

หากยังมีคำขอน้อยกว่า 2,500 คำขอต่อวันคุณต้องดูใบอนุญาต Google Maps Premier (ชำระเงิน) ที่ให้การร้องขอ geocoding 100,000 ครั้งต่อวันสำหรับบางอย่างประมาณ 10k ต่อปี (นั่นคือมาก - ด้วยการแคชด้านเซิร์ฟเวอร์คุณควร ไม่ถึงขีด จำกัด นี้เว้นแต่คุณจะเป็นเว็บไซต์ขนาดใหญ่หรือกำลังทำการประมวลผลข้อมูลจำนวนมาก) หากไม่มีการแคชฝั่งเซิร์ฟเวอร์และใช้วิธีการปัจจุบันของคุณคุณจะสามารถดูได้ 800 ครั้งต่อวัน!

เมื่อคุณตระหนักว่าผู้ให้บริการรายอื่นคิดค่าใช้จ่าย ตามภูมิศาสตร์แล้วคุณจะเข้าใจว่าคุณควรแคชผลลัพธ์ในฐานข้อมูล ด้วยวิธีการนี้คุณจะเสียค่าใช้จ่ายประมาณ 10 เซ็นต์สหรัฐต่อการดูหน้าเว็บ!

คำถามของคุณคือคุณสามารถแก้ไขวงเงิน จำกัด ที่ Google ให้ได้หรือไม่ แน่ใจ เพียงแค่ขอจากที่อยู่ IP ที่แตกต่างกัน Heck คุณสามารถเชื่อมต่อการโทรผ่านรหัสยืดหยุ่น amazon และจะมีการโทรใหม่ที่ได้รับจัดสรร 2,500 ครั้ง แต่แน่นอนว่านอกเหนือจากการผิดกฎหมาย (คุณหลีกเลี่ยงข้อ จำกัด ของข้อกำหนดการให้บริการของ Google Maps ได้อย่างมีประสิทธิภาพ) คุณจะต้องทำการแฮกเพื่อครอบคลุมข้อบกพร่องในการออกแบบที่คุณมีอยู่ในระบบของคุณ

ดังนั้นวิธีที่เหมาะสมสำหรับกรณีการใช้งานคืออะไร? ก่อนที่คุณจะโทรหา google geocode api ให้ส่งไปยังเซิร์ฟเวอร์ของคุณและสอบถามว่าอยู่ในแคชหรือไม่ หากไม่ใช่ให้โทรไปที่รหัสภูมิศาสตร์เก็บไว้ในแคชของคุณและส่งคืนผลลัพธ์

มีวิธีอื่น ๆ แต่คุณควรเริ่มต้นในทิศทางที่ถูกต้อง

อัปเดต:จากความคิดเห็นของคุณด้านล่างแสดงว่าคุณกำลังใช้ PHP ดังนั้นนี่คือตัวอย่างโค้ดเกี่ยวกับวิธีการทำอย่างถูกต้อง (คำแนะนำจากทีมงาน Google เอง) https://developers.google.com/maps/articles/phpsqlsearch_v3


คุณมีตัวอย่างที่ฉันสามารถส่งไปยังเซิร์ฟเวอร์ ฯลฯ ได้หรือไม่?
Rob

CMS แบ็กเอนด์ของคุณคืออะไร? (ฉันคิดว่าคุณสามารถ / รู้วิธีการเปลี่ยนแปลงและเพียงแค่ต้องการตัวอย่างง่ายๆที่แสดงวิธีการทำในภาษาที่คุณเลือกคุณไม่จำเป็นต้องมีตัวอย่างของฝั่งไคลเอ็นต์ js หรือคุณใช้ js ใด ๆ กรอบเช่น jQuery?
Ragi Yaser Burhum

นอกจากนี้คุณจะต้องให้บริบทเพิ่มเติมเกี่ยวกับวิธีที่ข้อมูลเครื่องหมายเข้าสู่ระบบของคุณตั้งแต่แรก
Ragi Yaser Burhum

1
ตกลง. php แล้ว บิตนี้จากเอกสาร Google ควรรวม mysql และ php ส่วนcode.google.com/apis/maps/articles/phpsqlgeocode.html
Ragi Yaser Burhum

1
ดู 10.1.3 (b) สำหรับรายละเอียดเกี่ยวกับประเภทแคชที่อนุญาต Developers.google.com/maps/terms#section_10_12
Paul Ramsey

14

ฉันคิดว่า Sasa นั้นถูกต้องทั้งสองมีค่า

ในแง่ของการส่งที่อยู่ทั้งหมดของคุณในครั้งเดียวตัวเลือกหนึ่งคือการส่งคำขอเป็นระยะ ในอดีตเมื่อใช้ JavaScript ฉันได้เลือกที่จะชะลอการร้องขอโดย 0.25 (ดูเหมือนว่าจะทำงาน!) วินาทีโดยใช้

setTimeout( [FUNCTION CALL] , 250 )

วิธี.

ใน. NET ฉันได้เลือก:

System.Threading.Thread.Sleep(250);

ดูเหมือนว่าจะทำงาน

แก้ไข: ลาดเททดสอบจริง ๆ แต่สิ่งนี้ควร / อาจทำงาน!

ตัวอย่าง Javascript addressArray เก็บสตริงที่อยู่ ...

for (var i = 0; i < addressArray.length; i++0 
{

setTimeout('googleGeocodingFunction(' + addressArray[i] + ')' , 250);

}

แก้ไข:

for (var i = 0; i < address.length; i++) {
    function(i) {
        setTimeout(geocoder.geocode({ 'address': address[i] }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                places[i] = results[0].geometry.location;

                var marker = new google.maps.Marker({ position: places[i], map: map });
                markers.push(marker);
                mc.addMarker(marker);
                google.maps.event.addListener(marker, 'click', function() {
                    if (!infowindow) {
                        infowindow = new google.maps.InfoWindow();
                    }

                    // Setting the content of the InfoWindow
                    infowindow.setContent(popup_content[i]);

                    // Tying the InfoWindow to the marker 
                    infowindow.open(map, marker);
                });

                // Extending the bounds object with all coordinates 
                bounds.extend(places[i]);

                // Adjusting the map to new bounding box 
                map.fitBounds(bounds)
            } else {
                alert("Geocode was not successful for the following reason: " + status);
            }
        }), 250);// End of setTimeOut Function - 250 being a quarter of a second. 
    } 
}

ขอบคุณสำหรับการตอบกลับ. ฉันจะนำรหัสนั้นไปใช้อย่างไร ทั้งหมดนี้เป็นเรื่องใหม่ดังนั้นต้องถือมือ คุณน่าจะสามารถดูซอร์สโค้ดของฉันได้
Rob

อันไหน คุณใช้ภาษาอะไร
CatchingMonkey

ฉันใช้จาวาสคริปต์ฉันจะตั้งช่วงเวลาได้อย่างไร
Rob

แก้ไขคำตอบของฉัน
CatchingMonkey

realsed ฉันหมายถึง setTimeout () ... ขอบคุณ Casey
CatchingMonkey

9

ดูเหมือนว่าคุณกำลังขีด จำกัด การร้องขอพร้อมกันที่กำหนดโดย Google (แม้ว่าฉันจะไม่สามารถหาการอ้างอิงถึงขีด จำกัด ที่แท้จริง) คุณจะต้องเว้นวรรคคำขอของคุณเพื่อที่คุณจะไม่ได้ส่งคำขอทั้งหมด 125 ครั้ง โปรดทราบว่ามีคำขอ Geocode 2,500 รายการต่อวัน

ปรึกษากลยุทธ์ของ Google Geocodingเอกสารสำหรับข้อมูลเพิ่มเติม

อัปเดต:ในฐานะที่เป็นโซลูชันเพิ่มเติมที่ได้รับแรงบันดาลใจจากการโพสต์โดย Mapperz คุณสามารถคิดเกี่ยวกับการสร้างตาราง Google Fusionใหม่จัดเก็บที่อยู่ของคุณและข้อมูลที่เกี่ยวข้องใด ๆ ในตารางและเข้ารหัสภูมิศาสตร์ตารางผ่านเว็บอินเตอร์เฟส มีการ จำกัด จำนวนรหัสทางภูมิศาสตร์ที่ขอให้ Fusion Table ทำ แต่ข้อ จำกัด มีขนาดค่อนข้างใหญ่ เมื่อคุณถึงขีด จำกัด คุณจะต้องส่งคำขอรหัส geocode อีกครั้งและ Fusion Tables จะไปรับตำแหน่งที่เหลือ โบนัสสำหรับวิธีนี้คือการปรับปรุงความเร็วอย่างมากเนื่องจากคุณจะต้องใส่รหัสภูมิศาสตร์เพียงครั้งเดียวด้วยวิธีการแก้ปัญหาปัจจุบันของคุณคุณจะต้องใช้รหัสทางภูมิศาสตร์ในการโหลดทุกครั้งจนถึงขีด จำกัด รายวันอย่างรวดเร็ว


ฉันเดาว่าฉันจะไปถึงขีด จำกัด ฉันยังใหม่กับสิ่งนี้ที่ฉันคิดว่าฉันต้องการตัวอย่างโค้ดเพื่อช่วย
Rob

ฉันกำลังดู Google Fusion Tables และพบปัญหาเล็กน้อย 1. คุณต้องระบุที่อยู่ทางภูมิศาสตร์ด้วยตนเอง (ผ่านทางไฟล์ -> รหัสทางภูมิศาสตร์) ในตารางสิ่งนี้สามารถทำได้โดยอัตโนมัติหรือไม่ 2. เครื่องหมายบางอันจะปรากฏที่ระดับการซูมบางระดับเท่านั้นในขณะที่ตัวอื่น ๆ จะแสดงระดับการซูม นี่คือตัวอย่าง - mediwales.com/mapping/example ในที่สุดสิ่งที่ฉันต้องการทำคือส่งออกข้อมูล Wordpress ของฉัน (เช่นที่อยู่ บริษัท ทั้งหมด) ไปยังตารางฟิวชั่นใส่รหัสทางภูมิศาสตร์โดยอัตโนมัติจากนั้นก็คว้าที่อยู่ทางภูมิศาสตร์ที่เข้ารหัสทั้งหมดแล้วพล็อตแผนที่ทันที
Rob

7

นี่คือวิธีที่ฉันเค้นคำขอรหัสทางภูมิศาสตร์ใน javascript ที่อยู่เป็นอาร์เรย์ที่มีที่อยู่แต่ละแห่งเป็นรหัสทางภูมิศาสตร์:

for (i=0;i<=addresses.length;i++) {
    setTimeout( function () {
            geocoder.geocode( { 'address': addresses[i]}, function(results, status) {

                if (status == google.maps.GeocoderStatus.OK) { 

                    //create and add marker to map based off geocode result
                    var marker = new google.maps.Marker({  
                        map: map,
                        title: results[0].formatted_address,
                        position: results[0].geometry.location
                    });

                 } //EDIT, was missing the closing bracket here
            });

    }, i * 1500);
}

นี่เป็นการเพิ่มวินาทีครึ่งหนึ่งระหว่างคำขอการเข้ารหัสทางภูมิศาสตร์


ขอบคุณสำหรับคำตอบ. ฉันได้รับหน้าว่างเมื่อพยายามที่จะรวมเข้ากับรหัสของฉัน - mediwales / การแมป
Rob

คุณใช้เครื่องมือแก้ไขข้อบกพร่องใด ๆ ที่อาจชี้ให้เห็นข้อผิดพลาดหรือไม่ หากคุณไม่ลองใช้ปลั๊กอิน FireFox firebug มันค่อนข้างมีประโยชน์ในสถานการณ์เช่นนี้
Casey

ฉันไม่ไม่ ฉันไม่มั่นใจว่าฉันใส่รหัสถูกที่แล้วฉันจะอัปเดตคำถามด้วยความพยายาม
Rob

ฉันไม่มีวงเล็บเหลี่ยมปิดในตัวอย่างโค้ดของฉัน ฉันแก้ไขคำตอบของฉันและเพิ่มด้วยความคิดเห็น อย่างไรก็ตามดูเหมือนว่านี่ไม่ใช่ปัญหาในโค้ดตัวอย่างของคุณ คุณได้รับหน้าว่างหรือแผนที่ว่างเปล่า? หน้าว่างจะระบุว่ามีข้อผิดพลาดทางไวยากรณ์ในรหัส javascript แผนที่เปล่า (ไม่มีเครื่องหมาย) จะระบุว่ารหัส geocoding มีปัญหา
Casey

1
สวัสดี ฉันมีคำตอบของคุณอีกแล้ว ความล่าช้าใช้งานได้ในขณะนี้ แต่ไม่สามารถทำเครื่องหมายให้ลงจุดได้ จากรหัสของฉันเหล่านี้เป็นบิตสำคัญที่พล็อตเครื่องหมาย - (function (i) {และ}) (i); หากไม่มีสิ่งนั้นมันก็ไม่ได้วางแผนแม้จะไม่เพิ่มความล่าช้า
Rob

5

ฉันได้พยายามหน้าในขณะนี้และมันดูเหมือนว่าจะทำงานในขณะนี้

ในขณะที่ฉันคิดว่าวิธีการตั้งเวลาที่คุณใช้อยู่นั้นถูกต้องและเท่าที่ฉันรู้เพียงวิธีเดียวที่จะทำงานโดยไม่มีการสนับสนุนฝั่งเซิร์ฟเวอร์ฉันควรแนะนำการเปลี่ยนแปลงต่อไปนี้ (ฉันใช้เสรีภาพในการเขียนฟังก์ชันทางภูมิศาสตร์ของคุณใหม่) เพื่อใช้ประโยชน์จากlocalStorage

LocalStorageเป็นเทคโนโลยีที่ค่อนข้างใหม่ที่ติดตั้งในเบราว์เซอร์ส่วนใหญ่ที่อนุญาตให้เว็บเพจเก็บข้อมูลบนไคลเอนต์ มันค่อนข้างคล้ายกับคุกกี้ แต่มีประสิทธิภาพมากกว่าและไม่ได้ส่งต่อไปยังเซิร์ฟเวอร์เสมอ (ต่างจากคุกกี้)

จุดประสงค์ของฉันคือการบันทึกที่อยู่ทางภูมิศาสตร์บนไคลเอนต์เพื่อที่ว่าหากผู้ใช้รีเฟรชหน้าเว็บไม่จำเป็นต้องเรียกใช้ฟังก์ชันทางภูมิศาสตร์ของ Google อีกครั้ง การใช้งานด้านล่างนี้เป็นข้อมูลหยาบ (เราควรเพิ่มรหัสเพื่อตรวจสอบบันทึกเก่าและอาจต้องใช้รหัสแคชที่ดีกว่าดัชนี) แต่น่าจะเพียงพอสำหรับคุณในการเริ่มต้น หวังว่ามันจะช่วย

(function() { 

window.onload = function() { 
 var mc;
// Creating an object literal containing the properties we want to pass to the map 
var options = { 
zoom: 0, maxZoom: 0, 
center: new google.maps.LatLng(52.40, -3.61), 
mapTypeId: google.maps.MapTypeId.ROADMAP 
}; 

// Creating the map 
var map = new google.maps.Map(document.getElementById('map'), options); 

// Creating a LatLngBounds object 
var bounds = new google.maps.LatLngBounds(); 

// Creating an array that will contain the addresses 
var places = []; 

// Creating a variable that will hold the InfoWindow object 
var infowindow; 
mc = new MarkerClusterer(map);
var popup_content = [..redacted..];

var geocoder = new google.maps.Geocoder(); 

var markers = [];

// Adding a LatLng object for each city 
function geocodeAddress(i) {
     // check if localStorage is available (it is now available on most modern browsers)
     // http://html5tutorial.net/tutorials/working-with-html5-localstorage.html
     // NB: this *must* be improved to handle quota limits, age/freshness, etc
     if(localStorage && localStorage['address_'+i]) {
        places[i]=JSON.parse(localStorage['address_'+i]);
        addPlace(i);
     } else {
      geocoder.geocode( {'address': address[i]}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            places[i] = results[0].geometry.location;
            if(localStorage) {
               // cache result locally on the browser, this will help reducing the number of requests
               // to the google geocoder in case the user refreshes the page
               // remember: the more he will refresh, the more he's likely to hit the limit
               // (this is one case where refreshing or closing the browser does not work)
               localStorage['address_'+i]=JSON.stringify(results[0].geometry.location);
            }

            addPlace(i);
        } else { 
            console.log("Geocoding of address "+address[i]+" failed");
        }
    })
}

function addPlace(i) {
    // Adding the markers 
    var marker = new google.maps.Marker({position: places[i], map: map});
    markers.push(marker);
    mc.addMarker(marker);

    // Creating the event listener. It now has access to the values of i and marker as they were during its creation
    google.maps.event.addListener(marker, 'click', function() {
        // Check to see if we already have an InfoWindow
        if (!infowindow) {
            infowindow = new google.maps.InfoWindow();
        }

        // Setting the content of the InfoWindow
        infowindow.setContent(popup_content[i]);

        // Tying the InfoWindow to the marker 
        infowindow.open(map, marker);
    });

    // Extending the bounds object with each LatLng 
    bounds.extend(places[i]); 

    // Adjusting the map to new bounding box 
    map.fitBounds(bounds);
}

function geocode() {
    if (geoIndex < address.length) {
        geocodeAddress(geoIndex);
        ++geoIndex;
    }
    else {
        clearInterval(geoTimer);
    }
}
var geoIndex = 0;
var geoTimer = setInterval(geocode, 600);  // 200 milliseconds (to try out)

var markerCluster = new MarkerClusterer(map, markers); 
} 
})
(); 

ขอบคุณมากแค่ให้ไปอย่างอื่น แต่จะลองทำในนาทีเดียว ฟังดูเหมือนความคิดที่ดี
Rob

เพิ่งลอง (ได้เปลี่ยนกลับเป็นก่อนหน้า) มันใช้งานได้ครั้งแรกเมื่อฉันรีเฟรชมันเพิ่งจะแสดงหน้าว่าง
Rob

ลองตอนนี้มีข้อผิดพลาดนอกจากนี้โปรดทราบว่าตัวแปร popup_content ได้รับการทำซ้ำเพื่อความกะทัดรัด
unicoletti

3

ใช้geocoders geopyฉันสามารถ geocode ที่อยู่จำนวนมากโดยไม่ต้องผูกปม (ฉันไม่แน่ใจว่าการตั้งค่าโพสต์หรือถ้าเขาสามารถรวมการพึ่งพาหลามกับโครงการของเขา)

นี่คือการทดสอบของฉัน:

from geopy import geocoders

g = geocoders.GoogleV3()  #https://geopy.readthedocs.io/en/latest/#geopy.geocoders.GoogleV3

for x in xrange(1,10000):
    print x
    a = g.geocode("AV JOAO NAVES DE AVILA " + str(x) + " UBERLANDIA MG BRASIL")
    print a

ตัวอย่างผลลัพธ์

7595 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7595 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-288, บราซิล ', (-18.9388154, -48.2220562))

7596 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7596 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-680, บราซิล ', (-18.938814, -48.2217423)

7597 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7597 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-288, บราซิล ', (-18.9388128, -48.2220381))

7598 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7598 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-680, บราซิล ', (-18.9388114, -48.2217242)

7599 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7599 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-288, บราซิล ', (-18.9388102, -48.2220201))

7600 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7600 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-680, บราซิล ', (-18.9388088, -48.2217062))

สิ่งนี้ยังคงทำงานอยู่และฉันมีผลลัพธ์ 7k

แก้ไข: ในขณะที่ฉันได้ตีจุดสิ้นสุดของถนนและ google เริ่มให้คะแนนฉันเหมือนกัน แต่ดูเหมือนว่ามันยังคงร้องขอและให้คำตอบที่ถูกต้องแก่ฉัน


Geopy ไม่ใช่เวทมนต์ข้อ จำกัด การใช้ยังคงมีอยู่
ตัวอักษร

1

ฟังก์ชั่น php นี้ (ฉันไม่รู้ว่าคุณกำลังใช้ภาษาใด แต่คุณสามารถเลือกได้ว่ากันหรือเปล่า) ใช้ google geolocator api ให้ที่อยู่มันจะส่งคืนที่อยู่ปกติและ latlong HTH

// GEOLOCATEBYADDRESS
// @arg (string)address
// @return (array) ((int)flag,(array)address,array(rawresponse))

function geolocatebyaddress($lookupaddress){

    $lookupaddress=trim("$lookupaddress New Zealand");
    $lookupaddress=urlencode($lookupaddress);

    //send off google api lookup request
    $apiurl="http://maps.google.com/maps/api/geocode/json";
    $apiurl.="?address=$lookupaddress";
    $apiurl.="&region=NZ";
    $apiurl.="&sensor=false";

    if (function_exists("curl_init")) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiurl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $json = curl_exec($ch);
        curl_close($ch);
    }
    else     $json= file_get_contents($apiurl);

    //process response
    $response= json_decode($json,true);
    $approxflag=0;
    if ($response['status']=='OK' and count($response['results'])) {

        $aa= array();
        foreach($response['results'] as $cc=>$result) {
            //set keys
            foreach(array('street_number','road','suburb','city','postcode','region','lat','long') as $t){
                $aa[$cc][$t]='';
            }
            if ($result['geometry']){
                $aa[$cc]['lat']= $result['geometry']['location']['lat'];
                $aa[$cc]['long']=$result['geometry']['location']['lng'];
         }

            if (count($result['address_components'])){
                foreach ($result['address_components'] as $acs){
                    if ($acs['types'][0]=='street_number')               $aa[$cc]['street_number']= $acs['long_name']; 
                    if ($acs['types'][0]=='route')                       $aa[$cc]['road']=      $acs['long_name']; 
                    if ($acs['types'][0]=='sublocality')                 $aa[$cc]['suburb']=   $acs['long_name']; 
                    if ($acs['types'][0]=='locality')                    $aa[$cc]['city']=    $acs['long_name']; 
                    if ($acs['types'][0]=='postal_code')                 $aa[$cc]['postcode']= $acs['long_name']; 
                    if ($acs['types'][0]=='administrative_area_level_1') $aa[$cc]['region']=   $acs['long_name']; 
                }    
            }
            //successful?
            if ($result['geometry']['location_type']=='APPROXIMATE') $approxflag++;
            if (isset($result['partial_match']))  $approxflag++;
            if (!$aa[$cc]['street_number'])         $approxflag++;
        }
        if ($approxflag) return (array(1,$aa,$response));
        else return (array(2,$aa,$response));
    }
    else return (array(0,array(),$response));
}    

ขอบคุณสำหรับคำตอบฉันจะรวมสิ่งนี้ในรหัสของฉันได้อย่างไร
Rob

ขออภัยฉันคิดว่าคุณกำลังเขียนรหัสเว็บไซต์ ฟังก์ชั่นนั้นใช้เป็นส่วนหนึ่งของสคริปต์ฝั่งเซิร์ฟเวอร์ที่อินสแตนซ์รับที่อยู่อินพุตของผู้ใช้ใช้ google geocoder api เพื่อรับ coords จากนั้นคุณสามารถใส่ coords เหล่านั้นใน db ของคุณและเมื่อคุณต้องการสร้างแผนที่เพียงแค่สอบถาม coords และสร้างแผนที่ด้วยเครื่องหมาย ด้วยวิธีนี้คุณจะไม่ใช้ geocoder สำหรับการแสดงผลหน้าเว็บทุกหน้าอย่างที่กล่าวมา (คุณลงความคิดเห็นของฉันลงหรือไม่ฉันพยายามช่วยและลงโทษฉันไม่ได้กระตุ้นฉันเหมือนกัน) นอกจากนี้ฉันยังบอกว่า api ต้องการให้คุณใช้กับ gmap
ปีเตอร์

1

เพิ่งเห็นข้อความค้นหาของคุณ คุณสามารถลองรหัสต่อไปนี้ ในการตรวจสอบสถานะ geocode ส่วนอื่นเรียกซ้ำฟังก์ชั่นเดียวกันกับช่องว่างเวลาสำหรับที่อยู่ที่หายไป

function spotPosition(address) {
        geocoder.geocode({ 'address': address }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var lat = results[0].geometry.location.lat();
                var lang = results[0].geometry.location.lng();
                setMarker(lat, lang);
            }
            else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                setTimeout(function () {
                    //Recursively calling spotPosition method for lost addresses
                    spotPosition(address);
                }, 1000);
            }
        });
    }

0

นี่คือทางออกของฉัน:

การพึ่งพา: Gmaps.js, jQuery

var Maps = function($) {
   var lost_addresses = [],
       geocode_count  = 0;

   var addMarker = function() { console.log('Marker Added!') };

   return {
     getGecodeFor: function(addresses) {
        var latlng;
        lost_addresses = [];
        for(i=0;i<addresses.length;i++) {
          GMaps.geocode({
            address: addresses[i],
            callback: function(response, status) {
              if(status == google.maps.GeocoderStatus.OK) {
                addMarker();
              } else if(status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                lost_addresses.push(addresses[i]);
              }

               geocode_count++;
               // notify listeners when the geocode is done
               if(geocode_count == addresses.length) {
                 $.event.trigger({ type: 'done:geocoder' });
               }
            }
          });
        }
     },
     processLostAddresses: function() {
       if(lost_addresses.length > 0) {
         this.getGeocodeFor(lost_addresses);
       }
     }
   };
}(jQuery);

Maps.getGeocodeFor(address);

// listen to done:geocode event and process the lost addresses after 1.5s
$(document).on('done:geocode', function() {
  setTimeout(function() {
    Maps.processLostAddresses();
  }, 1500);
});

0

คุณไม่สามารถหลีกเลี่ยงข้อ จำกัด geocode ของแผนที่ Google: คุณต้องได้รับและจัดเก็บข้อมูลLatLng

หากคุณมีหลายเมืองและคุณไม่ต้องการรับ LatLng ด้วยตนเองคุณสามารถใช้การหมดเวลาในการโทร geocoder.geocode และบันทึกข้อมูลภายในวัตถุจาวาสคริปต์แล้วใช้console.log(JSON.stringify(object, null, 4));เพื่อรับวัตถุที่พิมพ์ออกมาสวย ๆ ในคอนโซล ตัวอย่าง

            var locationsPosition = {
                    "Johannesburg - ZA": {
                        "lat": -26.2041028,
                        "lng": 28.047305100000017
                    },
                    "Chennai - IN": {
                        "lat": 13.0826802,
                        "lng": 80.27071840000008
                    }
             }

ดังนั้นตอนนี้คุณสามารถเพิ่มเครื่องหมายโดยใช้locationsPosition["Johannesburg - ZA"].latและ.lng


-1

ดูเหมือนคุณจะต้องทำหนึ่งในสองสิ่งนี้:

  1. เปลี่ยนกระบวนการของคุณเพื่อแคชผลลัพธ์หากคุณไม่ได้รับจำนวนมากที่ไม่ซ้ำกันต่อวัน หรือ
  2. อัปเกรดเป็นบริการที่ช่วยให้คุณสามารถดำเนินการต่อวัน

อย่างที่ผู้คนพูดกันมาหลายครั้งแล้ว แต่ฉันไม่มีประสบการณ์ส่วนตัวเลยดูเหมือนว่าใบอนุญาตของ Google สำหรับ 100k ต่อวันอยู่ที่ประมาณ $ 10k USD ต่อปี

หากคุณต้องการความแม่นยำในระดับเดียวกันหรือดีกว่า (และไม่ต้องจ่ายในราคานั้น) คุณสามารถลองใช้บริการของเรา สำหรับ Google ที่น้อยกว่า (เกือบ 10 เท่าของค่าใช้จ่าย) คุณสามารถได้รับวงเงินสูงกว่า 2500 มาก (ขีด จำกัด ต่ำสุดของเราคือ 25k / วัน)

แน่นอนว่าการใช้API การชำระเงิน Geocodingของเราไม่ใช่วิธีการแก้ปัญหาที่ฉันขอแนะนำให้ใช้อย่างซื่อสัตย์ 100% แม้ว่าจะเป็นการยอมรับในเชิงธุรกิจก็ตาม ฉันขอแนะนำให้เลือกใช้ตัวเลือกที่ 1 เพิ่มประสิทธิภาพการบริการของคุณให้เป็นแคช ยกเว้นว่าคุณต้องการรหัสภูมิศาสตร์มากกว่า 2500 รหัสต่อวัน

ข้อจำกัดความรับผิดชอบ : ฉันทำงานให้กับฟาร์ม Geocode (บริการที่ฉันแนะนำ)


เหตุใดจึงลงคะแนนนี้ ฉันไม่เห็นว่ามีอะไรในที่นี่ที่ไม่ถูกต้องหรือไม่ถูกต้อง
Geocode.Farm Staff
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.