Google Maps API: создание указателя магазинов

Сегодня я пытаюсь сделать локатор магазинов, используя api карт Google. Локатор магазинов должен быть настроен следующим образом: две области, одна с картой, содержащей все магазины в данной области (измеряется в выбираемом радиусе от центральной точки), и одна область со списком всех магазинов на карту, их информацию и, конечно же, ссылку на их веб-сайт. Когда человек щелкает по названию магазина в списке магазинов, он сосредотачивается на магазине на карте и открывает информационное окно над маркером магазина.

У меня есть переменная javascript, к которой я приложил все усилия, чтобы назначить некоторые данные json из сценария php (который выбирает эти данные на лету из базы данных)

locations = [{"siteurl":"http:\/\/localhost.localdomain\/5","address":"260 Test St","city":"Brooklyn","state":"New York","zip_code":"11206"},{"siteurl":"http:\/\/localhost.localdomain\/4","address":"3709 Testing St.","city":"Austin","state":"Texas","zip_code":"78705"}]; 

Теперь я знаю, что мне нужно запустить 5 различных функций, перечисленных ниже с их очевидным использованием:

  1. geocoder.getLocations: используется для преобразования адресных данных (из объекта json) в объект данных широты и долготы.
  2. addElementToList: используется для добавления адресной информации в список магазинов и привязки функции centerOnStore к onclick
  3. centerOnStore при щелчке по элементу списка магазинов в области списка этот функциональный центр обращается к магазину, который был нажат в области карты. Эта функция также открывает информационное окно над магазином по центру.
  4. placeMarker функция для размещения маркера на карте, вызываемая, когда геокодер возвращает объекты широты и долготы.
  5. eventListener это каким-то образом связано с щелчком по элементу списка и дополнительно центрирует карту на рассматриваемом магазине

Что ж, похоже, я не в своей лиге. Я только сейчас изучаю закрытие javascript и думаю, что это может быть необходимо, но я не совсем понимаю их. Мне нужно найти способ привести все эти функции в рабочий порядок, передавая информацию друг другу взад и вперед, и создать локатор магазинов.

.


Вот что у меня есть, но с этим что-то не так.

    var map = null;
    var geocoder = null;
    var locations = null;
    var center_on = null;
    var zoom_level = null;
    var markerList = [];

    function initialize()
    {
            if(GBrowserIsCompatible())
            {
                    // Assign vars
                    map = new GMap2(document.getElementById("map_canvas"));
                    geocoder = new GClientGeocoder();
                    locations = <?php echo(json_encode($my_vars['locations'])); ?>;
                    center_on = "<?php echo($my_vars['center_on']); ?>";
                    zoom_level = <?php echo($my_vars['zoom_level']); ?>;
                    var currentLocation = 0;

                    geocoder.getLatLng(center_on, function(myPoint)
                    {
                            map.setCenter(myPoint, zoom_level);
                    });
                    map.setUIToDefault();


                    var list = document.getElementById('center_list');

                    for(var i = 0; i < locations.length; i++)
                    {
                            var address = locations[i]['address'] + ', ' + locations[i]['city'] + ' ' + locations[i]['state'] + ', ' + locations[i]['zip_code'];
                            geocoder.getLocations(address, addAddressToMap);
                    }

            }




            function addAddressToMap(response) {

                    if (!response || response.Status.code != 200) {
                            currentLocation++;
                    } else {
                    var place = response.Placemark[0];
                    var point = new GLatLng(place.Point.coordinates[1],
                            place.Point.coordinates[0]);
                    marker = new GMarker(point);
                    GEvent.addListener(marker, 'click', function(){
                            this.openInfoWindowHtml("<strong>" + place.address + "</strong><br /><a href='" + locations[currentLocation]['siteurl'] + "'>" + locations[currentLocation]['siteurl'] + "</a>");
                    });
                    map.setCenter(point, 13);
                    markerList.push(marker);
                    map.addOverlay(marker);
                    li = document.createElement('li');

                    li.innerHTML = "<strong>" + place.address + "</strong>";
                    li.setAttribute('onclick', 'center_on_center(' + place.Point.coordinates[1] + ',' + place.Point.coordinates[0] + ')');
                    li.setAttribute('id', 'center_');
                    li.style.fontSize = '1.4em';
                    document.getElementById('center_list').appendChild(li);
                    // alert(currentLocation) here says 0,0,0,0
                    currentLocation++;
                    // alert(currentLocation) here says 1,2,3,4
                    }
            }
    }

Прошу прощения за стену кода. Я больше не могу думать. Я понятия не имел, что это будет так сложно. Совершенно без понятия.

если я предупреждаю currentLocation в строке до того, как увеличиваю его, это всегда 0. но если я предупреждаю об этом в строке после того, как увеличиваю его, это «1,2,3,4» и т. д. Это идет вразрез со всем, что я знаю о компьютерах.


person Joseph Carrington    schedule 28.08.2009    source источник
comment
Немного не связано, но вы действительно должны хранить геокоды в базе данных после того, как они были получены один раз, так как это должно ускорить работу вашего приложения.   -  person wheresrhys    schedule 30.08.2009
comment
Для этого мне нужно было бы добавить ловушку в админку wordpress MU для запуска асинхронного xml-запроса javascript и убедиться, что этот запрос завершен ДО того, как пользователь отправил форму.   -  person Joseph Carrington    schedule 30.08.2009
comment
Вероятно, вам будет лучше использовать геокодер HTTP для хранения местоположений в вашей базе данных. code.google.com/apis/maps/documentation/geocoding/index. html   -  person Chris B    schedule 30.08.2009


Ответы (4)


Забудьте на мгновение о закрытии. Вы можете погрузиться в них, когда получите работающее приложение. Я думаю, что ваша цель на данный момент должна состоять в том, чтобы просто получить то, что выполняет то, что вы хотите.

Мне кажется, что единственное, что вам не хватает, - это идея функции обратного вызова . Например, addElementToList будет передан в качестве аргумента обратного вызова geocoder.getLocaitons < / а>. Это работает так: когда getLocations () завершает свою работу, он вызывает addElementToList и передает результат getLocations () в качестве аргумента addElementToList. Затем код для addElementToList добавит местоположение вашего магазина на карту в качестве маркера и добавит новый элемент в ваш html-список с именем или адресом магазина или чем-то еще.

Взгляните на это сообщение в блоге, чтобы увидеть простой пример использования обратного вызова: Знакомство с геокодированием Google Сервис.

Последняя часть, сосредоточенная на конкретном магазине, может быть выполнена (как вы предложили) с помощью прослушивателей событий. Вы можете настроить прослушиватель для щелчков по маркерам, а также для щелчков по вашему списку. Когда вы добавляете маркер, вы также можете добавить на него прослушиватель событий < / а>. Было бы неплохо, если бы вы могли установить одного слушателя для всех маркеров на карте, но я недостаточно знаком с API Google, чтобы знать, возможно ли это.

person Derek Swingley    schedule 29.08.2009

Каков ваш источник этой информации? placeMarker определенно не звонит. Справочник по API Карт Google (вместе с примерами!) Доступен по адресу http://code.google.com/apis/maps/documentation/reference.html

person Rushyo    schedule 28.08.2009
comment
некоторые функции являются одними из моих собственных предположений, placeMarker - это просто более простой способ сказать function placeMarker(response) { if (!response || response.Status.code != 200) { } else { place = response.Placemark[0]; point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]); marker = new GMarker(point); map.addOverlay(marker); } - person Joseph Carrington; 29.08.2009

Основываясь на вашем комментарии к ответу @ Rushyo, похоже, вы достаточно знаете о Javascript и Google Maps API, чтобы создавать эти функции. Я немного запутался в том, что вы ищете.

Однако я бы посоветовал вам в первую очередь добавить координаты широты и долготы в свою базу данных. Вам не нужно геокодировать адреса каждый раз при загрузке карты.

Обновление. В ответ на ваш комментарий ниже приведен код, на который вы указали, а также функцию addAddressToMap(), вызываемую геокодером. Он создает маркер для каждого адреса и добавляет его в массив markerList. Затем вы сможете получить доступ к маркерам в этом массиве позже, поскольку мы инициализировали его за пределами функции addAddressToMap().

for(var i = 0; i < locations.length; i++) { 
    var address = locations[i]['address'] + ', ' + locations[i]['city'] + ' ' + locations[i]['state'] + ', ' + locations[i]['zip_code'];
    geocoder.getLocations(address, addAddressToMap); 
}

var markerList = new array();

function addAddressToMap(response) {
    if (!response || response.Status.code != 200) {
        alert("\"" + address + "\" not found");
  } else {
      place = response.Placemark[0];
      point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
      marker = new GMarker(point);
      markerList.push(marker);
      map.addOverlay(marker);
  }
}

Обновление 2: в ответ на код, который вы разместили в своем вопросе выше, вы, вероятно, получаете случайные числа в currentLocation из-за асинхронного характера геокодера. Помните, что ваша функция getLocations() будет отправлять запросы для каждого местоположения в массиве до того, как получит какие-либо ответы.

person Chris B    schedule 28.08.2009
comment
Думаю, я просто надеялся на какой-то план, в который я мог бы вписать детали. Я могу более или менее создавать функции, но не могу заставить их работать друг с другом. Я знаю, что это функции, которые обычно включены во все локаторы магазинов, которые я видел, но я просто не знаю, как они должны происходить по отношению друг к другу. Я не могу понять, как передавать данные туда и обратно между функциями javascript, это не работает, как в php, это язык, с которым мне гораздо удобнее. - person Joseph Carrington; 29.08.2009
comment
По сути, я только что наткнулся на стену моего познания и не могу придумать, как решить эту проблему. И, конечно, функциональность должна была появиться несколько дней назад. - person Joseph Carrington; 29.08.2009
comment
Например, `for (var i = 0; i‹ location.length; i ++) {var address = locations [i] ['address'] + ',' + locations [i] ['city'] + '' + location [я] ['состояние'] + ',' + местоположения [я] ['zip_code']; geocoder.getLocations (адрес, addAddressToMap); } `Итак, у меня есть функция, которая принимает адрес и превращает его в объект latLng, а затем помещает маркер под этим latLng, но как мне снова ссылаться на этот объект? Есть некоторая базовая часть javascript, которую я не понимаю - person Joseph Carrington; 29.08.2009
comment
Итак, есть ли способ вернуть latLng геокодера и использовать его для другой функции без того, чтобы эта функция была обратным вызовом геокодера? Мне нужно вставить URL-адрес магазина в адрес infoWindow, но нет возможности передать дату функции обратного вызова геокодера. - person Joseph Carrington; 30.08.2009

Я создаю новый ответ, так как мой другой ответ становится беспорядочным.

Чтобы получить правильное закрытие, вам нужно создать отдельную функцию для выполнения запроса геокодера. Следующий код позволит вам назначить желаемый текст infoWindow для каждого маркера.

for(var i = 0; i < locations.length; i++) {
    var address = locations[i]['address'] + ', ' + locations[i]['city'] + ' ' + locations[i]['state'] + ', ' + locations[i]['zip_code'];
    var text = locations[i]['address']; // or whatever you want the text to be
    getLocation(address, text);
}

...

function getLocation(address, text) {
    geocoder.getLocations(address, function(response) {
        var place = response.Placemark[0];
        var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
        marker = new GMarker(point);
        marker.bindInfoWindowHtml(text); // note that if you want to use GEvent.addListener() instead - you'll need to create another function to get proper closure
        map.addOverlay(marker);
    });
}

Дополнительные сведения о закрытии в картах Google см. В следующих вопросах:

person Chris B    schedule 30.08.2009