删除标记和清除源不起作用标记保留在地图上

问题描述

我继承了 openlayers 地图的这段代码,但我无法移除所有标记来重置地图并重绘。
我在文件末尾添加resetMap 函数

declare var ol: any;

export class OpenLayeRSService {

  private markers: any[] = [];
  public layers: any[] = [];
  public markerVectorLayer : any;
  public vectorSource : any ;
  private findMe: boolean;
  private lastLat: any;
  private lastLon: any;
  private vectorMyPositionLayer: any; 
  private markersClusterLayer;

  static adddistrictCenter(lat,lng,map,label) {
    const vectorLayer = new ol.layer.Vector({
      source: new ol.source.Vector({
        features: [
          new ol.Feature({
            geometry: new ol.geom.Point(
                ol.proj.transform(
                    [parseFloat(lng),parseFloat(lat)],'epsg:4326','epsg:3857'
                )
            )
          }),]
      }),minResolution: 2,maxResolution: 10,style: new ol.style.Style({
        text: new ol.style.Text({
          offsetY: 13,text: label,font: '13px Lato',scale: 1,textAlign: 'center',textBaseline: 'middle',fill: new ol.style.Fill({
            color: 'white'
          }),stroke: new ol.style.stroke({
            color: 'black',width: 3
          })
        })
      })
    });

    map.addLayer(vectorLayer);
  }

  initMap(lat: number,lon: number,target: string) {
    this.vectorSource = new ol.source.Vector({
      features: [],style: new ol.style.Style({
        image: new ol.style.Icon({
          anchor: [0.5,0.5],anchorXUnits: "fraction",anchorYUnits: "fraction",src: "https://upload.wikimedia.org/wikipedia/commons/e/ec/RedDot.svg"
        })
      })
    });

    this.markerVectorLayer = new ol.layer.Vector({
      source: this.vectorSource,minResolution: 0,maxResolution: 1.2
    });

    const map = new ol.Map({
      interactions: ol.interaction.defaults({
        doubleClickZoom: true,dragAndDrop: false,dragPan: true,keyboardPan: false,keyboardZoom: false,mouseWheelZoom: true,pointer: false,select: false,}),target: target,layers: [
        new ol.layer.Tile({
          visible: true,source: new ol.source.XYZ({
            url: 'https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',})
        }),this.markerVectorLayer,],view: new ol.View({
        maxZoom: 24,minZoom: 6,zoom: 15,center: ol.proj.fromLonLat([lon,lat])
      }),controls: [],loadTilesWhileAnimating: true
    });

    OpenLayeRSService.adddistrictCenter(lat,lon,'MY CENTER');
    this.adddistrict(lat,map);
    map.updateSize();

    return map;
  }

  styleFunction(label) {
    return new ol.style.Style({
      image: new ol.style.Circle({
        radius: 8,stroke: new ol.style.stroke({
          color: '#fff',width: 2
        }),fill: new ol.style.Fill({
          color: '#343434'
        })
      }),text: new ol.style.Text({
        offsetY: 17,scale: 1.3,fill: new ol.style.Fill({
          color: 'black'
        }),stroke: new ol.style.stroke({
          color: '#FEFEFE',width: 2
        })
      })
    });
  }

  addMarker(lat,label,nodeid) {
    const point = new ol.geom.Point(
        ol.proj.transform(
            [parseFloat(lng),'epsg:3857'
        )
    );
    this.markers.push(point);
  
    const marker = new ol.Feature({
      geometry: point
    });
    marker.setStyle(this.styleFunction(label));
    
    marker.set('id',nodeid+1);

    this.vectorSource.addFeature(marker);
    return marker;
  }

  center(lat,map) {
    if (this.vectorMyPositionLayer) {
      map.removeLayer(this.vectorMyPositionLayer);
    }

    const point = new ol.geom.Point(
          ol.proj.transform(
              [parseFloat(lon),'epsg:3857'
          )
      );

      this.vectorMyPositionLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          features: [
            new ol.Feature({
              geometry: point
            }),]
        }),style: new ol.style.Style({
          image: new ol.style.Circle({
            radius: 8,stroke: new ol.style.stroke({
              color: '#fff',width: 2
            }),fill: new ol.style.Fill({
              color: '#b52218'
            })
          }),text: new ol.style.Text({
            offsetY: 17,fill: new ol.style.Fill({
              color: 'black'
            }),stroke: new ol.style.stroke({
              color: '#FEFEFE',width: 2
            })
          })
        })
      });

      map.addLayer(this.vectorMyPositionLayer);
      
      const location = ol.proj.transform([lon,lat],'epsg:3857');

      const dettaglio = new ol.View({
        minZoom: 6,maxZoom: 24,zoom: 17,center: location,duration: 200
      });
      map.setView(dettaglio);
  }

  resetCenter(lat,map) {
    const location = ol.proj.transform([lon,'epsg:3857');

    const dettaglio = new ol.View({
      minZoom: 6,duration: 200
    });
    
    map.setView(dettaglio);
  }

  adddistrict(lat: number,map) {
    const COORD_SYstem_GPS = 'epsg:4326';  // gps (long/lat) coord system..
    const COORD_SYstem_OSM = 'epsg:3857';  // SphericalMercatorCoords - google and OSM's coord system..

    // styles for the vector layers
    const styles = [
      new ol.style.Style({
        stroke: new ol.style.stroke({
          color: 'rgba(156,156,1)',width: 0
        }),fill: new ol.style.Fill({
          color: 'rgba(0,0.1)'
        })
      }),new ol.style.Style({
        image: new ol.style.Circle({
          radius: 0,fill: new ol.style.Fill({
            color: 'orange'
          })
        }),geometry: function (feature) {
          // return the coordinates of the first ring of the polygon
          const coordinates = feature.getGeometry().getCoordinates()[0];
          return new ol.geom.MultiPoint(coordinates);
        }
      })
    ];

    // Create new layer/s
    const numLayers = 1;
    const vectorSource = [];
    const vectorLayer = [];
    const layerGroup = [];
    for (let i = 0; i < numLayers; i++) {
      vectorSource[i] = new ol.source.Vector({});
      vectorLayer[i] = new ol.layer.Vector({
        source: vectorSource[i],style: styles
      });
      layerGroup[i] = new ol.layer.Group({
        layers: [vectorLayer[i]],});
      map.addLayer(layerGroup[i]);
    }

    let layerIndex = 0;

    const featureCollection = {
      'type': 'FeatureCollection','totalFeatures': 5,'features': [
        {
          'type': 'Feature','id': 'feature-001','geometry': {
            'type': 'polygon','coordinates': [[
              [...lat...,...lng...],]],},'geometry_name': 'xxx','properties': {}
        }
      ]
    };

    featureCollection.features.forEach(function (featureJson) {
      const feature = new ol.Feature({
        geometry: (new ol.geom.polygon(featureJson.geometry.coordinates)).transform(COORD_SYstem_GPS,COORD_SYstem_OSM)
      });
      // Add feature to the vector source..
      vectorSource[layerIndex].addFeature(feature);
    });
  }

  addCluster(map) {
    const features = [];
    for (let i = 0; i < this.markers.length; ++i) {
      features[i] = new ol.Feature(
          {
            geometry: this.markers[i]
          }
      );
    }

    const source = new ol.source.Vector({
      features: features
    });

    const clusterSource = new ol.source.Cluster({
      source: source
    });

    const styleCache = {};
    this.markersClusterLayer = new ol.layer.Vector({
      source: clusterSource,style: function(feature) {
        const zoom = map.getView().getZoom();
        const size = feature.get('features').length;
        let style = styleCache[size];
        if (size === 1) {
          style = new ol.style.Style({
            image: new ol.style.Circle({
              radius: 8,stroke: new ol.style.stroke({
                color: '#fff',width: 2
              }),fill: new ol.style.Fill({
                color: '#343434'
              })
            })
          });
          styleCache[size] = style;
        } else {
          style = new ol.style.Style({
            image: new ol.style.Circle({
              radius: 13,fill: new ol.style.Fill({
                color: '#343434'
              })
            }),text: new ol.style.Text({
              text: size.toString(),fill: new ol.style.Fill({
                color: '#fff',font: '14px'
              })
            })
          });
          styleCache[size] = style;
        }
        return style;
      }
    });

    map.addLayer(this.markersClusterLayer);
  }

  ///
  /// I added this function but it does not work
  ///
  resetMap() {
    this.markers = [];
    if (this.markersClusterLayer) {
      this.markersClusterLayer.getSource().clear();
    }
    if (this.vectorSource) {
      this.vectorSource.clear();
    }
    if (this.markerVectorLayer) {
      this.markerVectorLayer.getSource().clear();
    }
  }
}

这是添加标记代码(我在此之前调用 initMap):

this.olService.resetMap();

for (let i = 0; i < records.length; i++) {
    if (!records[i].latitude || !records[i].longitude) {
        continue;
    }
    const marker = this.olService.addMarker(records[i].latitude,records[i].longitude,this.map,records[i].title,i+1);
}

this.olService.addCluster(this.map);

当我从网络上获取标记时(例如 0 条记录,所以我希望地图上没有任何标记),地图会重新绘制,但标记会保留。

解决方法

我解决了。
问题是我在不删除旧标记的情况下添加了新的标记层。

这是 addCluster 函数的新版本,首先我命名集群,然后在添加新集群之前将其删除(如果存在):

addCluster(map,deleteOld : boolean = true) {
    if (deleteOld) {
      // HERE I DELETE OLD ONE BEFORE ADDING NEW ONE
      map.getLayers().getArray()
            .filter(layer => layer.get('name') === 'Markers')
            .forEach(layer => map.removeLayer(layer));
    }

    const features = [];
    for (let i = 0; i < this.markers.length; ++i) {
      features[i] = new ol.Feature(
          {
            geometry: this.markers[i]
          }
      );
    }

    const source = new ol.source.Vector({
      features: features
    });

    const clusterSource = new ol.source.Cluster({
      source: source
    });

    const styleCache = {};
    this.markersClusterLayer = new ol.layer.Vector({
      source: clusterSource,style: function(feature) {
        const zoom = map.getView().getZoom();
        const size = feature.get('features').length;
        let style = styleCache[size];
        if (size === 1) {
          style = new ol.style.Style({
            image: new ol.style.Circle({
              radius: 8,stroke: new ol.style.Stroke({
                color: '#fff',width: 2
              }),fill: new ol.style.Fill({
                color: '#343434'
              })
            })
          });
          styleCache[size] = style;
        } else {
          style = new ol.style.Style({
            image: new ol.style.Circle({
              radius: 13,fill: new ol.style.Fill({
                color: '#343434'
              })
            }),text: new ol.style.Text({
              text: size.toString(),fill: new ol.style.Fill({
                color: '#fff',font: '14px'
              })
            })
          });
          styleCache[size] = style;
        }
        return style;
      }
    });
    this.markersClusterLayer.set('name','Markers');

    map.addLayer(this.markersClusterLayer);
}