Клуб API Карт

Выбор точки и рисование окружности, диаметр которой определяется определенным количеством ближайших к точке объектов.

Пост в архиве.

Здравствуйте.

Никогда не работал с API-картами. Владею PHP, MySQL, немного JavaScript.

Есть база объектов в MySQL с названиями объектов, их адресами и
географическими координатами (по одной ТОЛЬКО Москве порядка 5000).

Необходимо следующее.

 Указатель с крестиком всегда посередине карты .

Пользователь, выбирая свое место нахождения, крутит карту и вокруг этого указателя рисуется окружность.

Диаметр окружности определяется количеством ближайших до пользователя объектов, число которых равно десяти.

На лету в процессе прокрутки пользователем карты менять диаметр
окружности вряд ли получится. Скорее всего будут нереальные тормоза.

Поэтому я себе представляю это прибл. так:

Где то на карте (лучше за её пределами) есть кнопка "Сохранить
координаты", рядом с которой бегут и координаты во время прокрутки
карты.

Нажав на эту кнопку, пользователь подтверждает, что выбор места его нахождения завершен.

После нажатия, карта перестает быть интерактивной (не двигается больше),

указатель превращается в метку "я здесь", вокруг которой рисуется окружность, в которую попадают десять объектов.

Метки этих объектов также появляются в окружности.

При клике на эти метки, появляется балун с названием объекта и его адресом.

Карта эта рисуется таким образом, чтобы периметр окружности упирался в края карты, чтобы был виден весь диапазон.

Рядом с кнопкой "Сохранить координаты" находится кнопка типа "Отменить выбор, начать новый."

При нажатии на неё все начинается заново. Только карта подгружается с того места, где была поставлена метка.

Да и ещё..

На первоначальном этапе выводить район карты, соответствующий айпи пользователя.

Так будет удобнее. Не выводить же всем карту СНГ! - приблежать замучаешься.

Хотя пользователь с айпи Ростова-на-Дону может сидеть и в Краснодаре например.

Надо подумать ваще то))

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

Вот такая вот задачка.

Реально это все?

Если кто то поможет реализовать, готов заплатить за это деньги.

Спасибо.
20 комментариев
Описанная вами задачи вполне реализуема.

Может вместо кнопки "Сохранить координаты" лучше добавить кнопку в панель инструментов, например, "поиск объектов". Когда она активируется, то происходит превращение курсора в метку "я здесь", в противном случае карта работает в штатном режиме.

В принципе, окружность вокруг курсора можно рисовать с помощью многоугольника, а можно спрайтами сделать (тогда, конечно, побыстрее работать будет).

По поводу круга в клубе как раз было недавно обсуждение:
http://clubs.ya.ru/mapsapi/replies.xml?item_no=12774
Я вот не очень понял задачу, которую вы решаете.
Из текста мне показалось, что на самом деле задача найти 10 ближайших до пользователя объектов. Так?
Т.е. найдя 10 ближайших, потом можно определить расстояние до самого отдаленного, а это и будет радиус круга, который нужно нарисовать.

Расскажите подробнее, какую задачу в целом хотите решить?
если окружность рисовать после сохранения то
непонятно что меняется при перемещении карты
наверное эту окружность надо рисовать при окончании перемещения карты
DragEnd
А вообще я не очень понимаю зачем вам эта окружность?
с ней будет куча проблем.
у вас сайт стилизован под морской бой или подзорную трубу? :-)

Комментарий удалён
Карта не крутиться, она перемещается.

Упростите задачу до того, что при нажатии сабмит, берутся текущие координаты и отправляется результат.

Навесшивать обработчик на сабмит удобно с помощью YMaps.jQuery (документация на сайте jQuery)
А как получить координаты центра карты легко найти в документации.

PS. Лучьше использовать не форму, а ajax запросы (почитайте про них в документации к jQuery), пользователь скажет спасибо.
Вынесите объявления переменной placemark за пределы обработчика.

var placemark;
YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) {
    if (placemark) {
        map.removeOverlay(placemark);
    }

    // ставим метку
    placemark = new YMaps.Placemark(mEvent.getGeoPoint());
    map.addOverlay(placemark);
    // Отправляем координаты ты в поле coordinates формы
    YMaps.jQuery("#coordinates").attr("value", placemark.getGeoPoint());
});

Если не жалко всех оверлеев, которые были добавлены на карту, то можно поступить очень жестко - воспользоваться методом removeAllOverlays() и удалить все оверлеи с карты =)
Чтобы при перемещении карты координаты также записывались в форму, вам необходимо слушать событие Move у карты.

YMaps.Events.observe(map, [map.Events.Move, map.Events.BoundsChange], function () {
    placemark.setGeoPoint(map.getCenter()); // А этот ответ на ваш первый вопрос =)
    YMaps.jQuery("#coordinates").attr("value", map.getCenter());
});
Строка placemark.setGeoPoint(map.getCenter()); в Вашем, Саша, коде
приводит к тому, что координаты в форму не записываются(

Это не про запись в форму, а про то

Как поместить свой нарисованный графический указатель в центр карты


Для создания своего значка метки прочитайте раздел Создание пользовательского значка метки

Для записи в поле формы Вам нужна следующая строчка из Сашиного кода

YMaps.jQuery("#coordinates").attr("value", map.getCenter());
или можно
YMaps.jQuery("#coordinates").val(map.getCenter());

Здесь подразумевается что у вас id поля, в которое надо добавлять коорлдинату равно "coordinates"
рекомендую почитать документацию по jQuery
Указатель в виде крестика и есть ваша кастомная метка.
Чтобы он оставался в центре карты нужно слушать события перемещения и ставить её (метку/крестик) в центр.
Всё это есть в коде.
Что именно у Вас не получается?
Если вам нужно неактивное перекрестие, то можно добавить как слой:
http://gregof.narod.ru/crosshair.html
если вы захотите чтоб оно реагировало на действия пользователяб напрнимер в него можно кликнуть, то смотрите в сторону IControl.

Дизайн за вами, по коду видно, что это просто html.


а можно и как предлагает Лунный програмист, создать метку, которую двигать в противоположную сторону движению карты.
Пример кода можно попросить у Саши, это он писал "Определение координат".
А дайте, пожалуйста, ссылку на страничку. Так мы решим вашу задачу быстрее.
На самом деле это не так сложно, как может показаться на первый взгляд.

// Метка, отмечающая центр карты
var centerPlacemark = new YMaps.Placemark(map.getCenter(), {
    style : {
        iconStyle : {
            href : "http://api.yandex.ru/i/maps/icons/center.gif",
            size : new YMaps.Point(16, 16),
            offset : new YMaps.Point(-8, -8)
        }       }, 
    interactive : YMaps.Interactivity.NONE});
map.addOverlay(centerPlacemark);

// Перемещение метки в центр при любом сдвиге карты
YMaps.Events.observe(map, [map.Events.Move, map.Events.BoundsChange], function () {
    centerPlacemark.setGeoPoint(map.getCenter());
});

Я у метки выставил опцию interactive в значение none, потому что нам не нужно, чтобы по этой метки можно было щелкнуть.

P. S. Крестик лучше свой использовать, а то вдруг мы его у себя переименуем =)
Если center_coords - это строка, то делайте так:

var center = center_coords.splilt(",");
YMaps.jQuery("#longitude").attr("value", center[0]);
YMaps.jQuery("#latitude").attr("value", center[1]);

Если center_coords - это объект класса YMaps.GeoPoint, то так:

YMaps.jQuery("#longitude").attr("value", center.getLng());
YMaps.jQuery("#latitude").attr("value", center.getLat());

Карта начинает сходить с ума, потому что у вас возникает javascript-ошибка (где-то в коде). Скорее всего, я думаю, что можно придумать много способов, чтобы "взбесить" карту))
А дайте ссылку на страничку, пожалуйста. Я посмотрю.
Посмотрите еще раз мой комментарий и следуйте по инструкции "Если center_coords - это объект класса YMaps.GeoPoint...". Метод getCenter() возвращает именно геоточку.
При записи значения в атрибут ожидается строка, а вы передаете объект геоточку. У объекта геоточки неявным образом вызывается метод toString(), который преобразует объект в строку.

Метод toString() является стандартным методом в javascript. Его можно переопределить, что мы и сделали для геоточки. Для геоточки метод toString() вернет строку координат, разделенных запятыми.
Я сделал небольшой элемент управления. Вы можете поступить таким же образом или поместить форму в контейнер с картой и выставить ей z-index побольше, чтобы она вышла на передний план.

Но лучше все же сделать элемент управления. Вот пример.
Я вам предложил два варианта: через свой контрол (более правильный вариант) или просто div положить внутрь карты и вывести его повыше:


    моя форма

Используемые z-index'ы перечислены в статическом классе YMaps.ZIndex.
YMaps.jQuery(function () {
    var map = new YMaps.Map(YMaps.jQuery("#YMapsID"));
    map.setCenter(new YMaps.GeoPoint(37.64, 55.76), 10);
    map.addControl(new MyForm());
})

function MyForm () {
    var form = YMaps.jQuery("моя форма").css({
        position : "absolute",
        zIndex : YMaps.ZIndex.CONTROL
    });

    this.onAddToMap = function (map, positon) {
        form.appendTo(map.getContainer());
    };

    this.onRemoveFromMap = function () {
        form.remove();
    }
}


Подскажите  плиз... Задача элементарная - на клик по карте ставим метку, потом её  таскаем по карте, а в окошке отображаются координаты...

// Событие однократное "метка по нажатию кнопкой на карте"
var myEventListener = YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) {
        var placemark = new YMaps.Placemark(mEvent.getGeoPoint(),  {draggable: true});
        map.addOverlay(placemark);
        YMaps.jQuery("#point").attr("value", mEvent.getGeoPoint());
        myEventListener.cleanup();
    }, this);

Работает. создаёт метку, перетаскиваемую и отображает координаты.... но!


      YMaps.Events.observe(placemark,[placemark.Events.DragStart, placemark.Events.Drag, placemark.Events.DragEnd], function (placemark, mEvent) {
      YMaps.jQuery("#point").attr("value", mEvent.getGeoPoint());
      });

не работает ни под майонезом, ни под кетчунезом... :(