Skip to content

Update application to ol 6.5.0, geoext 4.0.0, BasiGX 3.0.0

Simon Seyock edited this page Jun 10, 2021 · 10 revisions

Here is a PR that makes an update like this: https://github.com/compassinformatics/cpsi-mapview/pull/412/files

Installation

  • Install ol 6.5.0: npm i @geoext/openlayers-legacy. The package provides ol.js and ol-debug.js. You can delete any static ol.js or ol-debug.js files that exist in your repository. Important: Only the ol.js file will work in IE 11 and similar old browsers.
  • Install @geoext/[email protected] (or higher) and [email protected] (or higher) via npm or update the git submodule.
  • Update paths in app.json (See cpsi-mapview/app.json)
  • Update paths in karma conf (See cpsi-mapview/karma-conf.common.js)

Migration

This will not include any changes related to WebGL rendering, VectorTiles, decluttering, renderModes and some other very specific changes. For more details about these check the OpenLayers release notes:

AtPixelOptions

The function forEachLayerAtPixel has changed syntax:

Old syntax:

    map.forEachLayerAtPixel(pixel, callback, callbackThis, layerFilterFn, layerFilterThis);

New syntax:

    map.forEachLayerAtPixel(pixel, callback, {
        layerFilter: layerFilterFn
    });

Removal of opt_this parameters

For the following functions the opt_this parameter has been removed and can be replaced by simply adding .bind(someThis):

  • Collection#forEach (search code base for .forEach( and check if a this parameter is used. Normally not the case)
  • forEachFeature, forEachFeatureAtPixel, forEachFeatureInExtent (search for .forEachFeature)
  • once (don't confuse with ExtJS once, even though it does not harm to use bind in ExtJS)

For on and un it is a little more complicated. Search codebase for the following regex: \.(on|un)\( and check if there are places where a method is bound and alter unbound with a this parameter. Again, check if the left side is an ol object or an extjs object. Still it cannot harm to use bind for ExtJs, but it should be less work.

If a class method is used in on and un you have to create a bound method in the constructor like this (look below for mixins):

Ext.define('SomeClass', {
  method1: function () {
    map.on('moveend', this.doSomething, this);
  },
  method2: function () {
    map.un('moveend', this.doSomething, this);
  }
});

becomes:

Ext.define('SomeClass', {
  constructor: function () {
    this.doSomething = this.doSomething.bind(this); // store a bound version of the method
    this.callParent(arguments); // call parent afterwards in case the parent constructor calls method1 or method2
  },
  method1: function () {
    map.on('moveend', this.doSomething);
  },
  method2: function () {
    map.un('moveend', this.doSomething);
  }
});

For mixins this should happen not in the constructor, but in a listener:

  // ...
  mixinConfig: {
    before: {
      constructor: 'onConstruct',
    }
  },

  onConstruct: function () {
    this.doSomething = this.doSomething.bind(this); // store a bound version of the method
  }
  // ...

Attribution

new ol.source.Vector({
  attributions: [new ol.Attribution({
    html: '© notice'
  }]
});

becomes:

new ol.source.Vector({
  attributions: '© notice' // array is optional
});

defaultDataProjection

In any ol.format class the defaultDataProjection is now called dataProjection (search for defaultDataProjection).

Removal of ol.FeatureStyleFunction

This is a little more tricky to find. There used to be two different kinds of style functions for features and layers. The functions for features used the feature as this, they are removed.

before:

feature.setStyle(function (resolution) {
  return new ol.style.Style({
    fill: new ol.style.Fill({
      color: this.get('color') // here `this` is the feature
    })
  });
});

becomes:

feature.setStyle(function (feature, resolution) {
  return new ol.style.Style({
    fill: new ol.style.Fill({
      color: feature.get('color')
    })
  });
});

Normally the feature styling is done via layer style anyways. But to find this you can search for .setStyle( and check if the left side is a feature and the parameter is a function. There is no other way for the feature style function to be set then via setStyle.

proj4

After the last proj4.defs call, proj4 needs to be registered:

ol.proj.proj4.register(proj4)

Search for proj4.defs.

logo

The map and sources no longer accept a logo option. Search for logo:.

Replacement of ol/Sphere constructor with ol/sphere functions

Examples before:

var sphere = new ol.sphere.Sphere(Sphere.DEFAULT_RADIUS);
var area = sphere.getGeodesicArea(polygon);
var distance = sphere.haversineDistance(g1, g2);

var poly = ol.geom.Polygon.circular(sphere, center, radius);

Examples after:

var area = ol.sphere.getArea(polygon);
var distance = ol.sphere.getDistance(g1, g2);

var poly = ol.geom.Polygon.circular(center, radius);

Search for new ol.sphere.Sphere and Polygon.circular.

The view extent option now applies to the whole viewport

Previously, this options only constrained the view center. This behaviour can still be obtained by specifying constrainCenterOnly in the view options.

Search for new ol.View and check for the option extent, set constrainCenterOnly to true if extent is used.

New prerender and postrender layer events replace old precompose, render and postcompose events

If you were previously registering for precompose and postcompose events, you should now register for prerender and postrender events on layers. Instead of the previous render event, you should now listen for postrender.

Search for precompose, render and postcompose but be careful as ExtJS also uses some of these events.

The OverviewMap requires a list of layers.

Layers can only be added to a single map, therefore the overview map needs to be constructed with a list of layers.

This causes a change in the GeoExt.component.OverviewMap component always needs to get passed their own layers. Check if all appearances of GeoExt.component.OverviewMap have a layers parameter.

Change of the behavior of the vector source's clear() and refresh() methods

The ol/source/Vector#clear() method no longer triggers a reload of the data from the server. If you were previously using clear() to refetch from the server, you now have to use refresh().

The ol/source/Vector#refresh() method now removes all features from the source and triggers a reload of the data from the server. If you were previously using the refresh() method to re-render a vector layer, you should instead call ol/layer/Vector#changed().

Search for clear and refresh.

Renaming of getGetFeatureInfoUrl to getFeatureInfoUrl

Just replace getGetFeatureInfoUrl by getFeatureInfoUrl

getFeaturesAtPixel

getFeaturesAtPixel now returns an empty array instead of null if no features were found. Search for getFeaturesAtPixel

GeoExt.data.store.Features needs a collection

If a features store is configured with a layer this layer needs to be an ol.layer.Vector with an ol.source.Vector with an ol.Collection. That means, if you used it like this before, it will now throw an Error:

Ext.create('GeoExt.data.store.Features', {
  layer: new ol.layer.Vector({
    source: new ol.source.Vector()
  })
});

If you change it to the following code it will work and keep the elements of the store, and the layer in sync.

Ext.create('GeoExt.data.store.Features', {
  layer: new ol.layer.Vector({
    source: new ol.source.Vector({
      features: new ol.Collection()
    })
  })
});

Search codebase for GeoExt.data.store.Features and check if the layer was created with a source with a collection.

getFeatures() returns original array

ol.source.Vector#getFeatures() now returns the original array it operates on (if any). This can cause issues if .removeFeature() is used on a loop on the array. Search for .getFeatures() and check if .removeFeature() is used in a loop. If so, change it like this:

var features = source.getFeatures();
features.forEach(function (f) {
  source.removeFeature(f);
});

becomes:

var features = source.getFeatures().slice(0); // copy array before.
features.forEach(function (f) {
  source.removeFeature(f);
});