[GIS] Openlayers VectorTiles Draw Interaction

draw-interactionopenlayersvector-layer

I am trying to add a the draw interaction to my openlayers 4.1.0 VectorTile layer. I have been able to add the draw interaction to a Vector layer, but not a VectorTile layer. Below is my js code:

Please note:

When cur_page = "page1" the draw interaction is working.

When cur_page = "page2" the draw interaction will draw the polygon, and on completion of drawing the polygon (either by double clicking or clicking on the first polygon point) an error will be generated and the polygon will disappear.

var defaultFeature = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: '#0000ff',
        width: 2
    })
});

var selectedFeature = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: '#ff0000',
        width: 2
    })
});

if(cur_page == "page1"){
    var latitude = -99.624;
    var longitude = 38.6855;
    var zoom = 3;
    var raster = new ol.layer.Tile({
        source: new ol.source.OSM()
    });

    var source = new ol.source.Vector({wrapX: false});

    var vector = new ol.layer.Vector({
        id: 'drawlayer',
        source: source,
        style: defaultFeature
    });
    var layers = [raster, vector];
}

if(cur_page == "page2"){
    var latitude = -97.587453;
    var longitude = 35.471398;
    var zoom = 11;
    var layer = 'test%3Alayer';
    var projection_epsg_no = '4326';

    var source = new ol.source.VectorTile({
        tilePixelRatio: 1,
        tileGrid: ol.tilegrid.createXYZ({maxZoom: 19}),
        format: new ol.format.MVT(),
        url: 'http://192.168.10.15:8080/geoserver/gwc/service/tms/1.0.0/' + layer + '@EPSG%3A'+projection_epsg_no+'@pbf/{z}/{x}/{-y}.pbf'
    });

    var layers = [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        new ol.layer.VectorTile({
            style:defaultFeature,
            source: source
        })
    ];
}

var projection = "EPSG:4326";
var latLong = ol.proj.fromLonLat([latitude, longitude]);

var map = new ol.Map({
    layers: layers,
    target: 'map',
    view: new ol.View({
        center: latLong,
        zoom: zoom
    })
});

$(document).on("click", ".map-side-panel", function() {
    var inter_type = $(this).data("interaction-type");
    var inter_descr = $(this).data("interaction-description");

    addInteraction(inter_type, inter_descr);
});

var draw;
var modify;
var selectInteraction;
var writer = new ol.format.GeoJSON();
function addInteraction(inter_type, inter_descr) {

    if(inter_type == 'Draw'){
        clearInteraction();
        draw = new ol.interaction.Draw({
            source: source,
            type: (inter_descr)
          });
          map.addInteraction(draw);
    } else if(inter_type == 'Modify'){
        ...
    } else if(inter_type == 'Source'){
        ...
    } else if(inter_type == 'Data'){
        ...
    } else{
        clearInteraction();
    }
}

function clearInteraction() {
    map.removeInteraction(draw);
    map.removeInteraction(selectInteraction);
    map.removeInteraction(modify);
}

This is the error I receiving in Chrome developer tools console:

ol-debug.js:64479 Uncaught TypeError: this.source_.addFeature is not a function
    at ol.interaction.Draw.finishDrawing (ol-debug.js:64479)
    at ol.interaction.Draw.handleUpEvent_ (ol-debug.js:64180)
    at ol.interaction.Draw.ol.interaction.Pointer.handleEvent (ol-debug.js:18743)
    at ol.interaction.Draw.handleEvent (ol-debug.js:64129)
    at ol.Map.handleMapBrowserEvent (ol-debug.js:31688)
    at ol.MapBrowserEventHandler.boundListener (ol-debug.js:6973)
    at ol.MapBrowserEventHandler.ol.events.EventTarget.dispatchEvent (ol-debug.js:7393)
    at ol.MapBrowserEventHandler.handlePointerUp_ (ol-debug.js:12691)
    at ol.pointer.PointerEventHandler.boundListener (ol-debug.js:6973)
    at ol.pointer.PointerEventHandler.ol.events.EventTarget.dispatchEvent (ol-debug.js:7393)

How do I add a draw interaction on my VectorTile layer?

Best Answer

Check the documentation: Although this source receives tiles with vector features from the server, it is not meant for feature editing.

So, you can not add a ol.interaction.Draw interaction to add features directly to your ol.source.VectorTile. That is why you get the error this.source_.addFeature is not a function.

Use a ol.layer.Vector with a GeoJSON source.

    var vectorSource = new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        loader: function (sourceExtent, resolution, projection) {
            (...)
            var features = (new ol.format.GeoJSON()).readFeatures(result.data);
            vectorSource.addFeatures(features);
            (...)
        }
    });

    var vectorJSON = new ol.layer.Vector({
        source: vectorSource 
    });
Related Question