1

I am creating a small Open Layers Addon library with some common style and interaction to use it across some applications.

So I create this library in Typescript, and I use webpack to bundle It.

Today, my library is a single class as follow :

import Map from 'ol/Map';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Feature from 'ol/Feature';
import GeometryType from 'ol/geom/GeometryType';
import {OlFeaturesStyles} from './Styles';
import {Draw} from 'ol/interaction'


export class OpenLayersAddOn {
  private map: Map;

  private drawingFeaturesVector: VectorLayer;
  private drawingInteraction: Draw;
  private drawingFeaturesSource: VectorSource;

  constructor(map: Map) {
    this.map = map;

    // const foo = new VectorSource();

    this.drawingFeaturesVector = new VectorLayer({
      source: new VectorSource({features: []})
    });
    this.map.addLayer(this.drawingFeaturesVector);
    this.drawingFeaturesSource = this.drawingFeaturesVector.getSource();

    this.drawingInteraction = new Draw({
      source: this.drawingFeaturesSource,
      type: GeometryType.LINE_STRING
    });
    this.map.addInteraction(this.drawingInteraction);
  }
}

I use this library in an Angular component (in another project) as follow :

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import Map from 'ol/Map';
import TileLayer from 'ol/layer/Tile';
import {OSM} from 'ol/source';
import View from 'ol/View';
import {IxOpenLayersAddOn} from 'ix-openlayers-add-on';
import GeometryType from 'ol/geom/GeometryType';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  private addOn: IxOpenLayersAddOn;
  private map: Map;
  @ViewChild('map', { static: true }) private mapContainer: ElementRef;

  ngAfterViewInit() {

    this.map = new Map({
      layers: [ new TileLayer({source: new OSM()}) ],
      view: new View({
        center: [0, 0],
        zoom: 2
      })
    });
    this.map.setTarget(this.mapContainer.nativeElement);
    this.addOn = new IxOpenLayersAddOn(this.map);
  }
}

When I launch my application, I can see my OpenLayer Map, and the "Line String" drawing interaction is installed. When I start drawing a polyline, I can see the classic "blue polyline" drawing, but when I go out of the interaction (by double clicking), my polyline is not drawn on the map.

Now, if I create an useless VectorSource before creating my layer (by uncommenting the const foo = new VectorSource(); in the constructor of my addon) : I can see my lines on map when drawing...

So my question is : Why should I add the useless vector layer to be able to show my drawing.

I don't think that it can be an OpenLayers's bug (If I try the same code in a plain old script in an HTML file, everythings is fine).

I think it can be somewhere in my bundling process (this is my first webpack library)

Here is the webpack.config.js of the add-on project :

const path = require('path');
module.exports = {
    mode: 'development',
    watch: true,
    entry: {
        lib: './index.ts',
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle-[name].js',
        library: 'ixOpenLayersAddOnLib',
        libraryTarget: 'umd',
        umdNamedDefine: true
    },
    plugins: [],
    devtool: 'inline-source-map',
    module: {
        rules: [
            {
                test: /\.ts?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ],
    },
    resolve: {
        extensions: [ '.ts', '.js' ]
    },
    externals: [
        function(context, request, callback) {
            console.log('Checking : ' + request);
            if (/^ol.*$/.test(request)) {
                return callback(null, 'umd ' + request);
            }
            callback();
        }
    ],
    }
};

I checked, and my bundle-lib.js is quite small, I can read in it

/*!**********************************!*\
  !*** ./src/OpenLayersAddOn.ts ***!
  \**********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst Vector_1 = __webpack_require__ ...");

With the whole transpiled version of my OpenLayersAddOn.ts.

And for the OpenLayers import, they are just declared as this (because I don't want openlayer be part of my bundle) :

eval("module.exports = __WEBPACK_EXTERNAL_MODULE_ol_geom_GeometryType__;\n\n//# sourceURL=webpack://OpenLayersAddOnLib/external_%22ol/geom/GeometryType%22?");

I have also check that the Openlayer version I use to build my library and my applications are the same (5.3.3).

Does some one have an Idea ?

Adrien BARRAL
  • 3,474
  • 1
  • 25
  • 37
  • If you want to see your features after you have finished drawing them the Draw interaction needs a layer source to store them in and a layer to display it. – Mike Sep 26 '19 at 16:03
  • @Mike : I am agree, but my interaction have them. The interaction's source is the vector layer (drawingFeaturesSource), and the layer to display them is "drawingFeatureVector". Like in the official sample here : https://openlayers.org/en/latest/examples/draw-features.html – Adrien BARRAL Sep 26 '19 at 16:16

0 Answers0