4

Tried to migrate an angular-based project using openlayers away from deprecated openlayers-npm-package to recommended ol-npm-package. By debugging i realized that i had a problem with the previously still working integration of proj4.

After two days of following different approaches, trying this and that, realizing that in that special combination of libraries the problem seems to result from a lack of typings for the new ol-package.

What i now can confirm - and hope it helps others (i can't comment to SO-Answer yet) - is, that the support for proj4 is not yet existing in @types/ol:'4.6.2', but in @types/openlayers:'^4.6.12'.

So utilizing proj4 to provide different projections to openlayers using dependencies

"ol": "5.2.0",
"@types/openlayers": "4.6.12",

will work for the following code-snippet, but ol combined with @types/ol won't:

imports

import * as ol from 'openlayers';
import * as proj4x from 'proj4';
const proj4 = (proj4x as any).default;
proj4.defs([
  [ 'EPSG:25832', '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs' ],
    ...
]);

constructor

ol.proj.setProj4(proj4);
user10324080
  • 121
  • 8

2 Answers2

3

Trying to avoid @types/openlayers completely and resort to @types/ol i eventually came up with the following:

package.json

"dependencies": {
    ...
    "proj4": "2.4.4",
    ...

app/.../@types/ol/proj/proj4.d.ts (manually created another typefile below app-folder)

export namespace ol {
    namespace proj {
        function setProj4(proj4: any): void;
    }
}

importing & definitions within eg. a component

import proj from 'ol/proj';
import * as proj4x from 'proj4';
const proj4 = (proj4x as any).default;
// Two example-projections (2nd is included anyway)
proj4.defs([
    [ 'EPSG:25832', '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs' ],
    [ 'EPSG:4326',  '+proj=longlat +datum=WGS84 +no_defs' ]
]);

within constructor - finally registering proj4 with ol

proj.setProj4(proj4);
user10324080
  • 121
  • 8
1

The OpenLayers 5 does not have setProj4 method anymore but instead the register method in the ol/proj/proj4 module. So, I followed the solution by @user10324080 and also discussion here and came to following solution with Angular 6:

  1. Added the following lines to end of the CompilerOptions in the tsconfig.js file:

    "allowSyntheticDefaultImports": true, "esModuleInterop":true

  2. I created the file @types/ol/proj/proj4.d.ts and added in it:

    export function register(proj4: any): void;

  3. In the .ts file where the map was created I added:

    import { fromLonLat } from 'ol/proj.js' import {register as proj4register } from 'ol/proj/proj4' import proj4 from 'proj4'; proj4.defs([[ 'EPSG:3067', '+proj=utm +zone=35 +ellps=GRS80 +units=m +no_defs']]); // Constuctor: proj4register(proj4); // ngOnInit: var view = new View({ projection: 'EPSG:3067', center: fromLonLat([27.47, 64.88], 'EPSG:3067'), zoom: 5 });

I had installed the following versions of the libraries and of the type definitions:

"ol": "^5.2.0",
"proj4": "^2.5.0",
"@types/ol": "^4.6.2",
"@types/proj4": "^2.3.4"
Orienteerix
  • 453
  • 1
  • 9
  • 16