Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am pretty new to OpenLayers. I have a polygon drawn on a vector layer, along with ModifyFeature and SelectFeature, I need to implement a functionality when user clicks on the polygon, a new vertex should be added to the polygon at the position where use clicked. With the new vertex the user should be able to reshape the polygon. Is there any existing feature to do this? if not how can we implement this?

function init() {
    map = new OpenLayers.Map('map');

    var wms = new OpenLayers.Layer.WMS("OpenLayers WMS",
        "http://vmap0.tiles.osgeo.org/wms/vmap0?", { layers: 'basic' });

    OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';

    var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
    renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;

    vectors = new OpenLayers.Layer.Vector("Vector Layer", {
        renderers: renderer
    });

    map.events.register("mousemove", map, function (e) {
        var position = this.events.getMousePosition(e);
        OpenLayers.Util.getElement("coords").innerHTML = position;
    });

    map.addLayers([wms, vectors]);
    map.addControl(new OpenLayers.Control.LayerSwitcher());
    map.addControl(new OpenLayers.Control.MousePosition());

    if (console && console.log) {
        function report(event) {
            if (event.type === "beforefeaturemodified")
                controls.polygon.deactivate();
            console.log(event.type, event.feature ? event.feature.id : event.components);
        }
        vectors.events.on({
            "beforefeaturemodified": report,
            "featuremodified": report,
            "afterfeaturemodified": report,
            "vertexmodified": report,
            "sketchmodified": report,
            "sketchstarted": report,
            "sketchcomplete": report
        });
    }

    controls = {
        polygon: new OpenLayers.Control.DrawFeature(vectors,
                    OpenLayers.Handler.Polygon),
        modify: new OpenLayers.Control.ModifyFeature(vectors),
    };

    var featureSelect = new OpenLayers.Control.SelectFeature(vectors,
    {
        hover: false,
        clickout: false,
        multiple: false,
        toggle: true,
        //box: true,
        eventListeners: {
            featureunhighlighted: function () {
                //Do whatever you want here.
            }
        }
        //multipleKey: "shiftKey"
    });
    map.addControl(featureSelect);
    featureSelect.activate();

    for (var key in controls) {
        map.addControl(controls[key]);
        controls[key].activate();
    }

    map.setCenter(new OpenLayers.LonLat(0, 0), 3);

    //vectors.events.register('click', vectors, function (e) {
    //    console.log(e);
    //});

    vectors.events.register('sketchcomplete', vectors, function (e) {
        controls.polygon.deactivate();
    });
}

Thanks in advance

share|improve this question
    
One year later... do you have a solution for your question? I am looking for the same thing. –  Below the Radar Aug 28 at 15:24

3 Answers 3

I did the similar work but a more complex algorithm for lines, and I think I get some inspiration from it. Your requirements are pretty much the same as what modifyFeature control can do, but you want to do it in a simpler way (from user point of view). It's possible but there's some trade off between the simplicity of manual work and that of computational work. It's actually often the case when it comes to computational geometry.

The modifyFeature control requires you to select one of the virtual vertices on edges, which implies that the new vertex will be inserted into that selected edge, so it's a deterministic process. Without this selecting process (by only clicking), you will need some extra computation to decide which edge (probably the nearest one, and the distance calculation to each edge is the extra work) to insert. For a simple polygon, the calculation is not a big problem, but the real use cases could be complex, e.g. a polygon has many edges and many of there's some cross over between edges. In such cases, it's possible when you want to insert the vertex to edge A, but end up with edge B. Moreover you will get some limitations on reshaping the polygon, following picture is a example (blue cross is where you clicked).

enter image description here

So I would suggest taking a deterministic way (maybe not exactly the same as how modifyFeature does), with less computation and you won't expect some 'special cases' (it's always about special cases). But if such special cases won't appear in your problem, then I don't see why not make users happy if it's a request from users or customers.

share|improve this answer

The feature is already there. When a feature is selected to be modified (with modifyfeature control), there is a circular sign at the middle of the edges of the polygon. Clicking on the circular sign will add a vertex to the polygon. Dragging the existing vertices will reshape the polygon.

In this example, first click on the draw polygon radio button and draw a polygon on map. Then click on modify feature radio button and select the polygon on map. You will see the blue edges become and orange circles at clickable positions.

share|improve this answer
    
Virtualvertices are quite handy at sometime, we can create more vertices by dragging virtualvertices. But I should be able to add a vertex on a segment between two vertices by a mouse click. –  krtz Aug 29 '13 at 17:42

onClick, I would check if the modify control is active. Then get mouse pointer xy, create a point if necessary and insert it directly into the array of vertices for that feature. You might need to call redraw(), refresh() or the like.

Update per comment:

var _selectFeature = new OpenLayers.Control.SelectFeature(layer,
            {
                hover: false,
                clickout: false,
                multiple: false,
                toggle: true,
                //box: true,
                eventListeners: {
                    featureunhighlighted: function(){
                      //Do whatever you want here.
                    }
                }
                //multipleKey: "shiftKey"
            }
        );
_selectFeature.activate();

share|improve this answer
    
'click' event of vector layer? when i register 'click' event on vector layer, repeated click on the selected feature unselects the modifyfeature. –  krtz Aug 29 '13 at 18:12
    
register the featureunhighlighted eventListener So when the feature is unselected. You can do whatever you want to it, then reselect it. –  CaptDragon Aug 29 '13 at 18:45
    
when I register a click event for vector, modifyfeature is not working and the feature is not getting selected. Could you please look into the above code? –  krtz Aug 29 '13 at 19:24
    
Actually I take that back...looking on the documentation there is a unselectFeature handler that is called when the feature is unselected. You can take the feature that is passed in there, add your vertice, then re-select it. –  CaptDragon Aug 29 '13 at 20:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.