Svinjica
Svinjica

Reputation: 2519

OpenLayers 3 - Geometry Collection Empty

I have question regarding writing geometry using Ol_3.

When I use ol.interaction.Draw I've noticed some strange behavior when writing Features. Using mentioned interaction I want to add vector (point, linestring, polygon, etc.) but on the first try (or click) I get GEOMETRYCOLLECTION EMPTY but when I use that same command for the second time I get desired result Can someone explain that behavior and how can one avoid it?

Is it possible to get geometry on first try/click ?

Example snippet below:

var vector = new ol.layer.Vector({
    source: new ol.source.Vector(),
    style: new ol.style.Style({
            image: new ol.style.Circle({
                radius: 12,
                fill: new ol.style.Fill()
            })
        })
});

var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        vector
    ],
    target: 'map',
    view: new ol.View({
        center: [-11000000, 4600000],
        zoom: 4
    })
});

map.on('pointermove', function(e) {
    if (e.dragging) return;
    var
        pixel = map.getEventPixel(e.originalEvent),
        hit = map.hasFeatureAtPixel(pixel);
    map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});

var button = $('#pan').button('toggle');
var interaction;
var features = undefined;;
$('div.btn-group button').on('click', function(event) {
    var id = event.target.id;
    var features;
    var selectedFeatures = undefined;
    button.button('toggle');
    button = $('#' + id).button('toggle');
    map.removeInteraction(interaction);

    switch (id) {
        case "select":
            document.getElementById("export").innerHTML="";
            interaction = new ol.interaction.Select();
            map.addInteraction(interaction);
            features = interaction.getFeatures();

            dragBoxInteraction = new ol.interaction.DragBox({
                condition: ol.events.condition.platformModifierKeyOnly,
                style: new ol.style.Style({
                    stroke: new ol.style.Stroke({
                        color: [12, 25, 25, 4]
                    })
                })
            });
            dragBoxInteraction.on('boxend', function(event) {
                selectedFeatures = interaction.getFeatures();
                selectedFeatures.clear();
                var extent = dragBoxInteraction.getGeometry().getExtent();
                vector.getSource().forEachFeatureIntersectingExtent(extent, function(feature) {
                    selectedFeatures.push(feature);
                });
            });
            map.addInteraction(dragBoxInteraction);

            break;
        case "point":
            interaction = new ol.interaction.Draw({
                type: 'Point',
                source: vector.getSource()
            });
            vector.getSource().on('addfeature', function(e) {
                var source = e.target;
                var writer = new ol.format.WKT();

                if (vector.getSource().getState() === 'ready') {
                    //https://gis.stackexchange.com/questions/179907/openlayers-3-geojson-save-and-load
                    var wkt = writer.writeFeatures(vector.getSource().getFeatures());
                    document.getElementById("export").innerHTML = wkt;
                }
            });
            map.addInteraction(interaction);
            break;


        default:
            break;
    }
    var snap = new ol.interaction.Snap({
        source: vector.getSource()
    });
    map.addInteraction(snap);
});
<!DOCTYPE html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.3.2/ol.css" type="text/css">
</head>

<body>
    <div class="container">
        <div id="map" class="map"></div>
        <br>
 
            <pre>
            <div id="export"></div>
            </pre>
        <!-- <button type="button" class="btn btn-outline-danger" id="js-remove">Izbriši</button> -->
        <div class="btn-group btn-group-sm" id="bar" role="group" aria-label="Draw">
            <button id="pan" type="button" class="btn btn-primary">Pan</button>
            <button id="select" type="button" class="btn btn-default active">Select</button>
            <button id="point" value="pointless" type="button" class="btn btn-success">Point</button>
        </div>
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.3.2/ol.js" type="text/javascript"></script>
        <script src="script.js" type="text/javascript"></script>
        <!-- <script src="functions_draw.js" type="text/javascript"></script> -->
</body>

</html>

UPDATE

I edited snippet according to JGH answer, hope it helps :)

Upvotes: 1

Views: 1330

Answers (1)

JGH
JGH

Reputation: 17836

The drawend event is fired before the feature is actually added to its source. It is (not obviously) documented here, under the finishDrawing() definition.

So, to get your code working, you can listen to events on the layer source instead of on the interaction.

Try replacing the line

interaction.on('drawend', function(e) {

by

vector.getSource().on('addfeature', function(e){

Upvotes: 1

Related Questions