Клуб API Карт

Помогите разобраться с onPointDragging

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

Здравствуйте,  я столкнулся с такими вопросами, при попытке использовать 

onPointDragging  

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

Принимает два аргумента: - массив всех видимых точек графической фигуры в пикселях карты, включающий в себя добавляемую/редактируемую точку; - индекс добавляемой/изменяемой точки в переданном массиве.

Возвращает откорректированную добавляемую/изменяемую точку в пикселях карты.


1. В описании очень смущает последняя строка. Я не представляю как можно использовать обработчик не определив его. Как в коде я могу воспользоваться тем что он возвращает?


На данный момент имеется такой код:

line =  new YMaps.Polyline();
line.addPoint(map.getCenter());
map.addOverlay(line);
line.startEditing();
line.setEditingOptions({
       onPointDragging: function(points,index){ }       
});


2. При использовании на фаекфоксе в консоли фаербага  появляются ошибки на каждое событие,

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


3. Каким способом лучше решать такую задачу:

Есть редактируемая Полилиния, на некоторых точках стоят метки.

При перетаскивании точки с меткой, метка перетаскивается вместе с точкой (или по окончанию перетаскивания точки метка прыгает на новое место)


Заранее благодарен.





10 комментариев
для начала, следуя инструкции
line.setEditingOptions({
       onPointDragging: function(points,index){
return points[index];
}       
});

так же указано что она возвращает точку...

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

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


есть у меня одна плохая привычка, которая как не странно часто помогает - если что-то не работает, или ты не понимаешь как это работает, ну или если это работает немного не так как хотелось бы, но предоставляется из коробки - вздохни грустно.
и сделай ручками, сам.
То есть я должен реализовать функцию вызываемую обработчиком  onPointDragging так,
чтобы она возвращала точку?

1,2 буду эксперементировать.

На счет привычки, пока мой опыт показывает, что
1. Я могу не найти нужную "коробку".
2. Моя реализация будет менее красива
3. Мой собственная реализация требует большего тестирования.



1. берем массив точек
2. создаем полигон
3. идем по массиву точек и создаем драгабл маркеры, задаем им polyline && polilineindex - два юзер свойства где будем хранить полигон и индекс точки в нем
4. при драг енд маркера меняем в polyline[polyindex] координаты на текушие от маркера
5. перерисовываем полигон

это намного проще чем кажеться

у меня есть решение для гугл карт двух годовой давности, могу показать
Я пошел немного с другой стороны: Поскольку точек в линии у меня много, а маркеров мало, то я маркеры оставил не перетаскиваемыми и редактирование оставил все на линии. Есть линия для отображения(на карте) и линия для контроля(невидимая) массив меток словарик типа {номер метки в массиве : индекс точки к которой он привязан} По событию Events.PositionChange Видимая линия сравнивается с невидимой и выдает один из четырех результатов addpoint inserpoint, index removepoint, index movepoint, index По соответствующему результату вызывается функция которая: изменяет позицию маркера/удаляет маркер если индекс совпадает пересчитывает словарик с индексами приводит в соответствие обе линии. Выглядит как то так: // define vars var marks = new YMaps.GeoObjectCollection(); var line; var lineB; var dict = {}; YMaps.jQuery( function(){ map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]); map.setCenter( new YMaps.GeoPoint(0,0),10 ); init() }) function init() { line = new YMaps.Polyline(); //visible line lineB = new YMaps.Polyline(); //invisible line (BackUp) line.addPoint(map.getCenter()); map.addOverlay(line); line.startEditing(); backUp(line,lineB); //back up line to lineB YMaps.Events.observe(line, line.Events.PositionChange, function(poly) {checkPoly()}) YMaps.Events.observe(map, map.Events.Click, function (map, mEvent){line.addPoint(mEvent.getGeoPoint());}); line.setEditingOptions({ menuManager: function (index, menuItems) { menuItems.splice(1) \\ remove start-end edit menuItems.push({ id: "addmark", title: 'метка', onClick: function (poly, pointIndex) { marks.add(new YMaps.Placemark(line.getPoint(pointIndex))) map.addOverlay(marks.get(-1)) dict[marks.length()-1] = pointIndex } }); return menuItems; } }); } // end Init function backUp(){ lineB.splicePoints(0,lineB.getNumPoints()); //clear points lineB.addPoint(line.getPoints()); //add points } // return event type add|remove|insert|dregged| function check(){ if (line.getNumPoints() - lineB.getNumPoints() == 1) { if (line.getPoint(-1).equals(lineB.getPoint(-1))) { return "inserted" } return "added" } if (line.getNumPoints() - lineB.getNumPoints() == -1) { return "removed" } else { return "dragged" } } // return index of changed point. function calcIndex(){ for (i=0; i= index){ dict[key] = dict[key]-1 } } }// end updateDictAndRemove function updateDict(index){ for (key in dict) { if(dict[key] >= index()){ dict[key] = dict[key]+1 } } } // end updateDict function onInsert(){updateDict(calcIndex()+1)} function onRemove(){ updateDictAndRemove(calcIndex()) }// end onRemove function onDrag(){ for (key in dict) { if(dict[key] == calcIndex()){ marks.get(key).setGeoPoint(line.getPoint(dict[key])); return} } }// end onDrug function checkPoly(){ switch (check()) { case "added": break; case "removed": onRemove(); break; case "inserted": onInsert(); break; case "dragged": onDrag(); break; default: alert("somthing else") } backUp() } // end checkPoly()
ускользает от меня смысл сих манипуляций
Изобретаю велосипед, для велосипеда :)
Пока получается то, что я хочу :)
Пока подчищал код, чтобы запостить сюда понял как его чуть улучшить.
(Выкинуть свитч и сделать события)







Собственно вот наглядный пример того что у меня вышло: http://route.pin-x.ru/test/
ничего не понял, но пить - стоп на сегодня
если вам интересно - только что написал очередную статейку, на этот раз какраз про редактор полигонов.
Работает аж в трех вариантах,
1 - чтобы создать новую вершину надо кликнуть рядом с тем местом где хотите чтобы она была
2 - надо "порвать" мышкой границу полигона - появиться новый маркер, при клике на который он зафисируется
3 - вариант от яндекса - в центре каждой грани висит маркер, челк на нем и он становиться реальным..

сама статья о редакторе полигонов
и сами примеры
http://www.kashey.ru/pages/maps/basic_poly_editor_test.php
http://www.kashey.ru/pages/maps/basic_poly_editor_test.php?v2
http://www.kashey.ru/pages/maps/basic_poly_editor_test.php?v3

во всех случаях - ахтунг иглишь и ахтунг гуглмапс.
но опятьже на гуглмапы сильно не завязано, все делается своими ручками
Прикольно. А главное просто. Немного API, немного геометрии. И получается интересная вещь. Спасибо.