Search code examples
angularionic-frameworkopenlayersionic4

Generating a OpenLayers map as a Component in Ionic


Ionic v4 & OpenLayers v5.3

I'm trying to generate a OL map as a component, but the only thing that is loaded is the icons. It seems that the styles and the JS configuration is not loading correctly, but I can't figure out why. I was able to generate the map injecting the functions inside the main page configuration file (home.page.ts), but the quality of the map is low and blurry.

While trying to fix this I found some people suggesting to load the map as Component, so here I am. The last time I used Ionic he had just switched to version 3, so I'm a little rusty and might be missing something.

The open-layers.component.ts code:

import { Component, OnInit, ElementRef, ViewChild, Renderer } from '@angular/core';
import { Map } from 'ol';
import { OSM } from 'ol/source.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';

@Component({
  selector: 'app-open-layers',
  templateUrl: './open-layers.component.html',
  styleUrls: ['./open-layers.component.scss'],
})

export class OpenLayersComponent implements OnInit {
    @ViewChild('mapRef') mapRef: ElementRef;

    constructor() {}

    ngOnInit() {

        console.log('Hello');

        var map = new Map({
            layers: [
                new TileLayer({ 
                    source: new OSM()
                })],
            target: document.getElementById('map'), 
            view: new View({
              center: [0, 0],
              zoom: 3
            })
        });
    }
}

Inside open-layers.component.html:

<div #mapRef id="map" class="map"></div>

home.page.html:

<ion-header>
  <ion-toolbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <app-open-layers></app-open-layers>
</ion-content>

Solution

  • I was able to generate the map as a component thanks to the robinyo links. What I needed to change was:

    Define map variable as the OL Map class in the beggining of the code and load the map inside ngOnInit(). This also loads the styles buttons that don’t load in previous example. I still need to update the size of the map to show him though. The blurry screen in mobile appear to be a device thing, if I try to open the OL online example page it is also blurry.

    openlayers.component.ts

    import { Component, OnInit, Renderer, ViewChild } from '@angular/core';
    import { NavController, Platform } from '@ionic/angular';
    import { Map } from 'ol';
    import { OSM, Vector as VectorSource } from 'ol/source.js';
    import View from 'ol/View.js';
    import TileLayer from 'ol/layer/Tile.js';
    
    @Component({
      selector: 'app-openlayers',
      templateUrl: './openlayers.component.html',
      styleUrls: ['./openlayers.component.scss'],
    })
    
    export class OpenlayersComponent implements OnInit {
    
        map: Map;
    
        constructor() { }
    
        ngOnInit() {
            this.map = new Map({
              layers: [
                new TileLayer({ 
                    source: new OSM()
                })],
              target: document.getElementById('map'),
              view: new View({
                center: [0, 0],
                zoom: 3
              })
            });
    
            setTimeout(() => {
              this.map.updateSize();
            }, 500);
        }
    }
    

    home.page.html

    <ion-header>
        <ion-toolbar>
            <ion-title>
                Ionic Blank
            </ion-title>
        </ion-toolbar>
        <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css">
        <style>html, body { margin: 0; }</style>
    </ion-header>
    
    <ion-content>
        <app-openlayers></app-openlayers>
    </ion-content>
    

    openlayers.component.html

    <div id="map" class="map"></div>