2

我目前正在使用具有以下版本的 asymmetrik 的 ngx-leaflet 和 ngx-leaflet-markercluster :

"@asymmetrik/ngx-leaflet": "^5.0.2",
"@asymmetrik/ngx-leaflet-markercluster": "^2.1.1"

在开发过程中一切都很好。但是,当我为生产 ( ng serve --prod) 构建 angular 项目时,我无法看到集群标记,并且在 Chrome 的控制台中出现以下错误:

ERROR TypeError: a.markerClusterGroup is not a function
    at t.ngOnInit (main-es2015.94505399b2d83c23de95.js:1)
    at main-es2015.94505399b2d83c23de95.js:1
    at main-es2015.94505399b2d83c23de95.js:1
    at Kb (main-es2015.94505399b2d83c23de95.js:1)
    at xw (main-es2015.94505399b2d83c23de95.js:1)
    at Object.updateDirectives (14-es2015.a3c30690716486447af1.js:1)
    at Object.updateDirectives (main-es2015.94505399b2d83c23de95.js:1)
    at Xb (main-es2015.94505399b2d83c23de95.js:1)
    at rw (main-es2015.94505399b2d83c23de95.js:1)
    at nw (main-es2015.94505399b2d83c23de95.js:1)

我在我的组件中导入“leaflet”和“leaflet.markercluster”。下面是map.component.ts代码:

import { Component, Input, SimpleChanges } from '@angular/core';
import { tileLayer, latLng, control, marker, divIcon, LatLngBounds, MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet';

import { NgElement, WithProperties } from '@angular/elements';

import * as L from 'leaflet';
import 'leaflet.markercluster';
...

@Component({
    selector: 'map',
    styleUrls: ['./map.component.scss'],
    templateUrl: './map.component.html'
})
export class MapComponent {

    layers = [];
    markerClusterGroup: L.MarkerClusterGroup;
    markerClusterData: any[] = [];
    maxBounds: L.LatLngBounds;
    map: L.Map;

    options = {
        layers: [
            tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18 }),
        ],
        zoom: 2,
        zoomControl: false,
        maxZoom: 18
    };

    markerClusterOptions: L.MarkerClusterGroupOptions = {
        showCoverageOnHover: true,
        animate: true,
        chunkedLoading: true,
        zoomToBoundsOnClick: true,
        spiderfyOnMaxZoom: true,
        chunkDelay: 500,
        animateAddingMarkers: true,
        chunkInterval: 7,
        iconCreateFunction: function (cluster) {
            var markers = cluster.getAllChildMarkers();
            var icon = divIcon({
                iconSize: [35, 35],
                iconAnchor: [10, 10],
                popupAnchor: [10, 0],
                shadowSize: [0, 0],
                html: '<div>' + cluster.getChildCount() + '</div>'
            });

            if (markers.find(x => x.options.alt == enum.A)) {
                icon.options.className = 'cluster cluster-critical';
            } else if (markers.find(x => x.options.alt == enum.B)) {
                icon.options.className = 'cluster cluster-warning';
            } else {
                icon.options.className = 'cluster cluster-normal';
            }

            return icon;
        }
    };

    ngOnChanges(changes: SimpleChanges): void {
        this.fixMap();
    }

    mapReady(map: L.Map) {
        this.map = map;
        map.addControl(control.zoom({ position: 'bottomright' }));
        this.fixMap();
    }

    fixMap() {
        if (this.map) {
            this.setBounds();
            this.map.fitBounds(this.maxBounds);
            this.initMarkers();
            setTimeout(() => {
                this.map.invalidateSize();
            }, 0);
        }
    }

    markerClusterReady(group: L.MarkerClusterGroup) {
        this.markerClusterGroup = group;
        this.markerClusterGroup.addLayers(this.markerClusterData);
    }

    initMarkers() {
        this.markerClusterData = [];
        this.objectList.forEach(x => {
            var location = latLng(x.location.latitude, x.location.longitude);
            var system = marker(location, {
                icon: divIcon({
                    iconSize: [30, 30],
                    iconAnchor: [10, 10],
                    popupAnchor: [10, 0],
                    shadowSize: [0, 0],
                    className: this.getMarkerStyle(x),
                }),
                title: x.serialNumber,
                alt: x.objectStatusSummary.status
            });

            system.bindPopup(fl => this.createPopupComponent(x), {
                className: 'popup',
                closeButton: false
            }).on('click', (data) => {
                this.focusOnMarker(x);
            });

            this.markerClusterData.push(system);
        });
    }

    focusOnMarker(object: Object) {
        var bounds = new L.LatLngBounds([[object.objectLocation.latitude, object.objectLocation.longitude]]);
        this.map.fitBounds(bounds, {
            animate: true,
            duration: 1,
            easeLinearity: 1,
            maxZoom: this.map.getZoom(),
            noMoveStart: true
        });
    }

    setBounds() {
        var latLngArray: any[] = [];
        if (this.objectList && this.objectList.length > 0) {
            this.objectList.forEach(x => {
                latLngArray.push({
                    lat: x.objectLocation.latitude,
                    lng: x.objectLocation.longitude,
                });
            });
        }
        else {
            latLngArray.push({
                lat: 0,
                lng: 0
            });
        }
        this.maxBounds = new L.LatLngBounds(latLngArray);
    }

    getMarkerStyle(object: object) {
        return 'marker marker-' + this.businessHelper.getClassByStatus(<objectHealthStatusEnum>object.objectStatusSummary.status) + ' marker-' + object.serialNumber;
    }

    resetZoom() {
        this.map.fitBounds(this.maxBounds, {
            animate: true,
            duration: 1,
            easeLinearity: 1,
            noMoveStart: true
        });
    }

    public createPopupComponent(object) {
        const popupEl: NgElement & WithProperties<MapPopupComponent> = document.createElement('popup-element') as any;
        popupEl.addEventListener('closed', () => document.body.removeChild(popupEl));
        popupEl.object = object;
        document.body.appendChild(popupEl);
        return popupEl;
    }
}

这是map.component.html代码:

<div class="map-wrapper">
    <div 
        leaflet 
        [leafletOptions]="options" 
        (leafletMapReady)="mapReady($event)"

        [leafletMarkerCluster]="markerClusterData"
        [leafletMarkerClusterOptions]="markerClusterOptions"
        (leafletMarkerClusterReady)="markerClusterReady($event)"
    ></div>
</div>

您可以在此处找到主要代码。

有任何想法吗?

4

2 回答 2

1

我遇到了同样的问题并找到了解决方案。问题是从定义中导入了不同的传单作为“L”。确保首先导入传单,然后是其他包,例如:

import * as L from 'leaflet';
import { Map, MapOptions, MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet';
import 'leaflet.markercluster';

另一种猜测是生产时间与开发时间不同。您的电话是initMarkers通过ngOnChanges,但这可能为时过早。地图或集群可能尚未初始化。尝试initMarkers拨打markerClusterReadymapReady

于 2019-12-13T10:15:09.673 回答
0

不要通过html导入leaflet,安装包并导入你需要的模块

于 2019-11-25T15:29:10.660 回答