diff --git a/examples/modify-features.html b/examples/modify-features.html
index 09cc4b912a..9be79fe94a 100644
--- a/examples/modify-features.html
+++ b/examples/modify-features.html
@@ -26,6 +26,10 @@
Modify features example
-
Example of using the Modify interaction. Select a feature and drag the circle that appears when the cursor gets close to the selected geometry.
+
Example of using the Modify interaction.
+
Select a feature on the Test Data layer and drag the circle that appears when the cursor gets close to the selected geometry. On the Real data (topology) layer, editing adjacent countries that are selected preserves the topology.
See the modify-features.js source to see how this is done.
modify, edit, vector
diff --git a/examples/modify-features.js b/examples/modify-features.js
index 44392f260d..7e50855670 100644
--- a/examples/modify-features.js
+++ b/examples/modify-features.js
@@ -67,7 +67,7 @@ var styleFunction = (function() {
};
})();
-var vectorSource = new ol.source.GeoJSON(
+var testDataSource = new ol.source.GeoJSON(
/** @type {olx.source.GeoJSONOptions} */ ({
object: {
'type': 'FeatureCollection',
@@ -96,7 +96,14 @@ var vectorSource = new ol.source.GeoJSON(
'type': 'Feature',
'geometry': {
'type': 'LineString',
- 'coordinates': [[4e6, -2e6], [8e6, 2e6]]
+ 'coordinates': [[4e6, -2e6], [8e6, 2e6], [9e6, 2e6]]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [[4e6, -2e6], [8e6, 2e6], [8e6, 3e6]]
}
},
{
@@ -159,9 +166,18 @@ var vectorSource = new ol.source.GeoJSON(
}
}));
+var testDataLayer = new ol.layer.Vector({
+ source: testDataSource,
+ style: styleFunction
+});
-var vectorLayer = new ol.layer.Vector({
- source: vectorSource,
+var realDataSource = new ol.source.GeoJSON({
+ projection: 'EPSG:3857',
+ url: 'data/geojson/countries.geojson'
+});
+
+var realDataLayer = new ol.layer.Vector({
+ source: realDataSource,
style: styleFunction
});
@@ -239,7 +255,7 @@ var modify = new ol.interaction.Modify({
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([select, modify]),
- layers: [raster, vectorLayer],
+ layers: [raster, testDataLayer, realDataLayer],
renderer: 'canvas',
target: 'map',
view: new ol.View2D({
@@ -247,3 +263,14 @@ var map = new ol.Map({
zoom: 2
})
});
+
+$('#layer-select').change(function() {
+ select.getFeatures().clear();
+ var index = $(this).children().index($(this).find(':selected'));
+ var layers = [testDataLayer, realDataLayer];
+ var i, ii;
+ for (i = 0, ii = layers.length; i < ii; ++i) {
+ layers[i].setVisible(index == i);
+ }
+});
+$('#layer-select').trigger('change');
diff --git a/src/ol/interaction/modifyinteraction.js b/src/ol/interaction/modifyinteraction.js
index eaef9502c3..4ce844fab7 100644
--- a/src/ol/interaction/modifyinteraction.js
+++ b/src/ol/interaction/modifyinteraction.js
@@ -49,6 +49,13 @@ ol.interaction.Modify = function(options) {
*/
this.vertexFeature_ = null;
+ /**
+ * Segments intersecting {@link this.vertexFeature_} by segment uid.
+ * @type {Object.
}
+ * @private
+ */
+ this.vertexSegments_ = null;
+
/**
* @type {boolean}
* @private
@@ -379,8 +386,7 @@ ol.interaction.Modify.prototype.handleDragStart = function(evt) {
this.dragSegments_.push([segmentDataMatch, 0]);
} else if (ol.coordinate.equals(segment[1], vertex)) {
this.dragSegments_.push([segmentDataMatch, 1]);
- } else if (
- ol.coordinate.squaredDistanceToSegment(vertex, segment) === 0) {
+ } else if (goog.getUid(segment) in this.vertexSegments_) {
insertVertices.push([segmentDataMatch, vertex]);
}
}
@@ -504,20 +510,37 @@ ol.interaction.Modify.prototype.handleMouseAtPixel_ = function(pixel, map) {
if (nodes.length > 0) {
nodes.sort(sortByDistance);
var node = nodes[0];
- var segment = node.segment; // the closest segment
- var vertex = (ol.coordinate.closestOnSegment(pixelCoordinate, segment));
+ var closestSegment = node.segment;
+ var vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
+ closestSegment));
var vertexPixel = map.getPixelFromCoordinate(vertex);
if (Math.sqrt(ol.coordinate.squaredDistance(pixel, vertexPixel)) <=
this.pixelTolerance_) {
- var pixel1 = map.getPixelFromCoordinate(segment[0]);
- var pixel2 = map.getPixelFromCoordinate(segment[1]);
+ var pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
+ var pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
var dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
if (dist <= 10) {
- vertex = squaredDist1 > squaredDist2 ? segment[1] : segment[0];
+ vertex = squaredDist1 > squaredDist2 ?
+ closestSegment[1] : closestSegment[0];
}
this.createOrUpdateVertexFeature_(vertex);
+ var vertexSegments = {};
+ vertexSegments[goog.getUid(closestSegment)] = true;
+ var segment;
+ for (var i = 1, ii = nodes.length; i < ii; ++i) {
+ segment = nodes[i].segment;
+ if ((ol.coordinate.equals(closestSegment[0], segment[0]) &&
+ ol.coordinate.equals(closestSegment[1], segment[1]) ||
+ (ol.coordinate.equals(closestSegment[0], segment[1]) &&
+ ol.coordinate.equals(closestSegment[1], segment[0])))) {
+ vertexSegments[goog.getUid(segment)] = true;
+ } else {
+ break;
+ }
+ }
+ this.vertexSegments_ = vertexSegments;
this.modifiable_ = true;
return;
}