【问题标题】:Leaflet map rendering problems in Ionic AngularIonic Angular 中的传单地图渲染问题
【发布时间】:2021-01-28 17:07:07
【问题描述】:

我在尝试使用 Angular 在 Ionic 页面上显示地图时遇到了一些问题。

虽然地图本身没有错误,但有一些渲染问题让我很恼火:

  1. 地图的图块加载最初非常缓慢
  2. setView 显示的地图坐标位于地图 div 的左上角(我可以通过放置在相同坐标上的标记看到这一点)
  3. 如果我调整窗口大小,图块会正常加载,并且标记会居中。

我希望第三个选项始终如此:我用setView 指向的坐标应该在地图的中心。

这是我的代码:

export class MyPage implements OnInit {

  public acc;

  posLatitude: number;
  posLongitude: number;
  map: L.Map;
  markerIcon = L.icon(
    {
      iconUrl:'assets/pin.svg',
      iconSize: [32, 32],
    }
  );

  constructor(
    private myService: MyService,
  ) { }

  ngOnInit() {
    this.acc = MyService.getAcc();
    this.posLongitude = this.acc["Long"];
    this.posLatitude = this.acc["Lat"];
    this.map = L.map('map').setView([this.posLatitude, this.posLongitude], 16);

    // center the map

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'jsp.com'
     }).addTo(this.map);

    L.marker([this.posLatitude, this.posLongitude], {icon : this.markerIcon}).addTo(this.map)
      .bindPopup('Accident');

    console.log(this.acc);
  }

}
<div id="map" style="height: 75%;"></div>

【问题讨论】:

标签: angular typescript ionic-framework leaflet


【解决方案1】:
export class MyPage implements OnInit {
  public acc;

  posLatitude: number;
  posLongitude: number;
  map: L.Map;
  markerIcon = L.icon(
    {
      iconUrl:'assets/pin.svg',
      iconSize: [32, 32],
    }
  );

  constructor(private myService: MyService) { }

  public ngOnInit(): void {
    this.acc = MyService.getAcc();
    this.posLongitude = this.acc["Long"];
    this.posLatitude = this.acc["Lat"];
    this.map = L.map('map');

    // center the map
    const observer = new MutationObserver(() => {
      map.invalidateSize();
      map.setView([this.posLatitude, this.posLongitude], 16);
      observer.disconnect();
    });

    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class'],
      childList: false,
      characterData: false,
    });

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'jsp.com'
     }).addTo(this.map);

    L.marker([this.posLatitude, this.posLongitude], {icon : this.markerIcon}).addTo(this.map)
      .bindPopup('Accident');
  }
}

基本上,当 Ionic 应用程序启动时,entire app is hidden 直到它“水​​合”为止。

html:not(.hydrated) body {
  display: none;
}

当一切准备好渲染时,Ionic adds the hydrated class to the HTML-element,此时整个应用程序已准备好渲染。但是此时 Leaflet 已经初始化了宽度和高度均为 0px 大小的地图,使其呈现单个瓦片。

虽然我还没有找到一种方法来监听所有内容都准备好呈现的事件,但您可以监听 HTML 元素的类更改。在上面的代码中,这是使用MutationObserver 完成的。这将在 HTML 元素上的类属性发生更改时触发回调,并且此时地图大小无效(因此传单将重新计算其大小)并将地图居中。

【讨论】:

    【解决方案2】:

    它应该适用于所有类型的离子应用。问题是由于在离子组件之前加载传单地图。所以试试下面的它应该可以工作

    ionViewDidEnter(){
       let osmMap = L.map('map');
       L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
       }).addTo(osmMap);
       osmMap.invalidateSize();
    }
    

    【讨论】:

      【解决方案3】:

      首先你需要在 global.scss 文件中添加传单的 CSS :

      @import "~leaflet/dist/leaflet.css";
      

      另一件事是在 HTML 中将高度和宽度设置为 100%:

        <div id="map" style="width: 100%; height: 100%;"> </div>
      

      如果这不能解决您的问题,请重新加载您的应用,直到它运行得很快,这种情况发生在我身上太多次了,当我刷新页面时它会解决它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 2014-09-14
        • 2014-02-02
        • 2016-12-29
        • 2022-11-15
        • 2020-08-17
        • 2016-06-04
        相关资源
        最近更新 更多