Angular-leaflet加载JSON marker无法显示问题排查
问题根因
标记无法渲染和12000条数据量无直接关系,核心是代码存在3个错误:
- 字段匹配错误:JSON文件中经纬度字段为大写开头的
Latitude、Longitude,代码中写为全小写的latitude、longtitude(同时存在单词拼写错误),读取到的经纬度值均为undefined - 坐标顺序错误:Leaflet的
L.marker接收坐标的格式为[纬度, 经度],代码中写反为[经度, 纬度] - 地图重复初始化:
ngOnInit和ngAfterViewInit生命周期中重复调用initMap(),会生成多个地图实例,标记被挂载到未渲染的无效实例上
修正后代码
map.service.ts 修复
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import * as L from 'leaflet'; @Injectable({ providedIn: 'root', }) export class MarkerService { baseUrl: string = 'http://localhost:3000/PLNT20' constructor(private http: HttpClient) {} makesMarkers(map: L.Map): void { this.http.get(this.baseUrl).subscribe((res : any) => { for(const c of res){ // 修正字段名大小写、拼写错误 const lat = c.Latitude; const lng = c.Longitude; // 修正坐标顺序 const marker = L.marker([lat, lng]).addTo(map); // 弹窗按需开启即可 marker.bindPopup(`<center> <p> <strong>${c.PlantID} | ${c.PlantName}</strong> </p> <p>运营方:${c.UtilityName}</p> </center>`) } }); } }
map.component.ts 修复
import { Component, AfterViewInit } from '@angular/core'; import * as L from 'leaflet'; import { MarkerService } from 'src/app/map.service'; @Component({ selector: 'app-map', templateUrl: './map.component.html', styleUrls: ['./map.component.scss'] }) export class MapComponent implements AfterViewInit { private map!: L.Map; private initMap(): void { // 初始化时开启canvas渲染,适配大数据量场景 this.map = L.map('map', { preferCanvas: true }).setView([40,-100],5) const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' }); tiles.addTo(this.map); } constructor(private markerService : MarkerService) { } // 仅在DOM加载完成后初始化一次地图,再加载标记 ngAfterViewInit():void{ this.initMap(); this.markerService.makesMarkers(this.map); } }
12000点位性能优化
代码错误修复后,直接渲染12000个原生DOM标记会出现页面卡顿、交互掉帧问题,可按需选择优化方案:
- 若需要点位点击、弹窗等完整交互:引入点聚合能力,将同一视野下相邻点位合并为聚合标记,缩放至对应层级后再展示具体点位,可将同时渲染的DOM数量降低90%以上
- 若仅需要展示点位分布、无复杂交互:上述代码中已经开启
preferCanvas: true配置,会将点位绘制在Canvas层而非生成独立DOM,渲染性能可提升10倍以上
内容的提问来源于stack exchange,提问作者Ayman Sharaf
相关产品推荐
相关产品推荐

