Реализовать было больно, но это возможно. Я использовал шаблон состояния для отслеживания процесса оцифровки. Я использовал EXT JS, поэтому я пытаюсь включить вещи, которые являются строго javascript. При нажатии кнопки объект оцифровки будет отслеживать, был ли я DIGITIZING или NOT_DIGITIZING или EDITING. Штат также будет отслеживать, какой тип геометрии мне нужно обрабатывать: POINT, POLYLINE, POLYGON. Кнопки были доступны для установки состояния. Я бы захватил клики по карте с помощью:
google.maps.event.addListener(map,"click",digitizer.onDigitize.createDelegate(digitizer));
google.maps.event.addListener(map,"dblclick",digitizer.endDigitize.createDelegate(digitizer));
Внутри объекта дигитайзера я отслеживал полигон и точки оцифровки. Всякий раз, когда пользователь нажимал, я отправлял latLng в событии отслеживаемому объекту.
this.digitizedGeometry.getPath().push(e.latLng);
Это будет работать как для ломаной линии, так и для многоугольника. Для этого я отслеживал только простую топологию, а не пончики или несколько геометрий.
Редактирование и удаление точек было более сложным.
Сначала я должен был отследить, выбрал ли пользователь геометрию, которая была POLYLINE или POLYGON, и поместить эту геометрию в переменную editGeometry в дигитайзере, а также включить кнопку для редактирования.
Я прокрутил путь редактирования геометрии и добавил маркеры и маркеры средней точки с разными стилями, чтобы маркеры можно было перетаскивать.
var path = this.editGeometry.getPath();
for (var i = 0; i < path.getLength(); i++) {
// Add point geometry markers
var point = path.getAt(i);
var latLng = new google.maps.LatLng(point.lat(), point.lng());
var markerOptions = {position: latLng, map: mapPanel.getMap()};
Ext.apply(markerOptions, digitizer.markerStyle);
var marker = new google.maps.Marker(markerOptions);
// Used to track the latLng associated with the marker when position changes.
marker.edit = {
path: path,
position: i,
isMidpoint: false
};
google.maps.event.addListener(marker, "dragend", digitizer.applyMarkerEdit.createDelegate(mapPanel, marker, true));
google.maps.event.addListener(marker, "rightclick", digitizer.onContextMenu.createDelegate(mapPanel, marker, true));
digitizer.editHandles.push(marker);
// determine the midpoint
var nextValue = (i+1) % path.getLength();
var otherPoint = path.getAt(nextValue);
var latLng = new google.maps.LatLng((point.lat() + otherPoint.lat()) / 2.0, (point.lng() + otherPoint.lng()) / 2.0);
var markerOptions = {position: latLng, map: mapPanel.getMap()};
Ext.apply(markerOptions, digitizer.midpointMarkerStyle);
var marker = new google.maps.Marker(markerOptions);
marker.edit = {
path: path,
position: i,
isMidpoint: true
};
google.maps.event.addListener(marker, "dragend", digitizer.applyMarkerEdit.createDelegate(mapPanel, marker, true));
digitizer.editHandles.push(marker);
}
Ключевой частью является «драгенд» и применение правки. Если бы это была действительная точка на пути, я бы переместил точку и переопределил средние точки.
marker.edit.path.setAt(marker.edit.position, e.latLng);
// Adjust midpoints
var index = handles.indexOf(marker);
var prev = (index - 2 + handles.length) % handles.length;
var mpprev = (index - 1 + handles.length) % handles.length;
var next = (index + 2) % handles.length;
var mpnext = (index + 1) % handles.length;
var prevMarker = handles[prev];
var nextMarker = handles[next];
var prevMpMarker = handles[mpprev];
var nextMpMarker = handles[mpnext];
prevMpMarker.setPosition(new google.maps.LatLng((e.latLng.lat() + prevMarker.getPosition().lat()) / 2.0, (e.latLng.lng() + prevMarker.getPosition().lng()) / 2.0));
nextMpMarker.setPosition(new google.maps.LatLng((e.latLng.lat() + nextMarker.getPosition().lat()) / 2.0, (e.latLng.lng() + nextMarker.getPosition()
Вы можете видеть, как это очень сложно. Если вам не нужны середины, первой строки в приведенном выше коде достаточно. Применение средних точек является более сложным. Вы должны добавить среднюю точку к траектории, сместить все позиции, добавить новую среднюю точку и скорректировать предыдущую среднюю точку. Если бы я хотел удалить точку, мне пришлось бы удалить эту точку, уменьшить позиции маркеров, удалить среднюю точку и перенастроить предыдущую среднюю точку.
Надеюсь, это поможет вам понять, как это сделать. Жаль, вместо 2 строк кода, 200 строк кода, но это дает вам гибкость в выполнении всего, что вы хотите, включая установку стиля маркера.