Ionic 2 Beta and Open Layers 3 not loading map

2019-07-03 08:26发布

问题:

I have try to create a test project for use Open Layers 3 with the new ionic 2 but it isn't work

This is my layout:

<ion-navbar *navbar>
  <button menuToggle>
    <ion-icon name="menu"></ion-icon>
  </button>
  <ion-title>Mappa</ion-title>
</ion-navbar>


<ion-content padding class="map-page">

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

</ion-content>

And this is my controller:

import {Page} from 'ionic-angular';


@Page({
  templateUrl: 'build/pages/map/map-page.html'
})
export class MapPage {


    constructor(){

        this.test = ["uno", "due", "tre"];



        // var layer = ga.layer.create('ch.swisstopo.pixelkarte-farbe');

     //    var map = new ga.Map({
        //     target: 'map',
        //     layers: [layer],
        //     view: new ol.View({
        //       resolution: 500,
        //       center: [670000, 160000]
        //     })
        //   });

     //    this.map = map;


     console.log(this.map);

      var projection = ol.proj.get('EPSG:3857');

      var map = new ol.Map({
            target: this.map,
            layers: [
              new ol.layer.Tile({
                source: new ol.source.OSM()
              })
            ],
            view: new ol.View({
              center: ol.proj.transform([8.92471, 46.07257], 'EPSG:4326', 'EPSG:3857'),
              zoom: 14
            })
          });

    }

}

I have also imported this library on my application:

<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
  <title>Ionic</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">


  <script src="http://openlayers.org/en/v3.14.2/build/ol.js"></script>



  <link ios-href="build/css/app.ios.css" rel="stylesheet">
  <link md-href="build/css/app.md.css" rel="stylesheet">
  <link wp-href="build/css/app.wp.css" rel="stylesheet">  
</head>
<body>

  <ion-app></ion-app>

  <script src="cordova.js"></script>
  <script src="build/js/app.bundle.js"></script>


</body>
</html>

In a old project with ionic 1 this code is working. Any suggestion?

THX.

回答1:

Inspired from @Thierry Templier answer i post the full solution about this:

Import headers on index.html

<script src="http://openlayers.org/en/v3.14.2/build/ol.js"></script>

Create a new custom component manually or via CLI this is my case:

import {Component, Input, ViewChild, Renderer, Query, QueryList, ElementRef} from 'angular2/core';
import {IONIC_DIRECTIVES} from 'ionic-angular';

declare var ol: any;

@Component({
  selector: 'map-component',
  templateUrl: 'build/components/map-component/map-component.html',
  directives: [IONIC_DIRECTIVES] // makes all Ionic directives available to your component
})




export class MapComponent {

  @ViewChild('map') map;


  constructor(public renderer: Renderer) {


   }

ngAfterViewInit() {
    console.log(this.map);

     var projection = ol.proj.get('EPSG:3857');


     var map = new ol.Map({
            target: "map",
            layers: [
              new ol.layer.Tile({
                source: new ol.source.OSM() 
              })
            ],
            view: new ol.View({
              center: ol.proj.transform([8.92471, 46.07257], 'EPSG:4326', 'EPSG:3857'),
              zoom: 10
            })
          });





 }
}

Remember to declare this for use OpenLayer library:

declare var ol: any;

Then create the template for your custom component or implement that directly in the @Component statement and use #something for use it with @ViewChild:

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

At the end now you can use your custom component in a page, remember to import it in your pages!

import {Page, NavController} from 'ionic-angular';
import {Query, QueryList, Component, ElementRef} from 'angular2/core';
import {MapComponent} from './../../components/map-component/map-component';


/*
  Generated class for the MapPagePage page.

  See http://ionicframework.com/docs/v2/components/#navigation for more info on
  Ionic pages and navigation.
*/
@Page({
  templateUrl: 'build/pages/map-page/map-page.html',
  directives: [MapComponent]
})

and the page template file:

<ion-navbar *navbar>
  <button menuToggle>
    <ion-icon name="menu"></ion-icon>
  </button>
  <ion-title>Map Page</ion-title>
</ion-navbar>

<ion-content padding class="map-page">

  <map-component></map-component>

</ion-content>

That's it.



回答2:

You need first to reference the DOM element for your map from the template. You could try this code:

<ion-navbar *navbar>
  <button menuToggle>
    <ion-icon name="menu"></ion-icon>
  </button>
  <ion-title>Mappa</ion-title>
</ion-navbar>

<ion-content padding class="map-page">

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

</ion-content>

And leverage @Query into your component:

@Component({
  (...)
})
class MapComponent {
  constructor(@Query('map') elList: QueryList<ElementRef>) {
    this.map = elList.first;

    (...)

    var projection = ol.proj.get('EPSG:3857');

    var map = new ol.Map({
        target: this.map.nativeElement,
        (...)
    });

    (...)
  }
}


回答3:

Hi simple solution just use settimeout !

setTimeout(() => {

            var map = new ol.Map({
                layers: [
                    new ol.layer.Tile({
                        source: new ol.source.OSM()
                    })
                ],
                target: 'openlayers',
                controls: ol.control.defaults({
                    attributionOptions: ({
                        collapsible: false
                    })
                }),
                view: new ol.View({
                    center: [0, 0],
                    zoom: 2
                })
            });

        }, 500);