I inherited this code of an openlayers map, but I am not able to remove all markers to reset the map and redraw.
I added the resetMap
function at the end of the file:
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, map, 'MY CENTER');
this.addDistrict(lat, lon, 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,
text: label,
font: '13px Lato',
scale: 1.3,
textAlign: 'center',
textBaseline: 'middle',
fill: new ol.style.Fill({
color: 'black'
}),
stroke: new ol.style.Stroke({
color: '#FEFEFE',
width: 2
})
})
});
}
addMarker(lat, lng, map, label, nodeid) {
const point = new ol.geom.Point(
ol.proj.transform(
[parseFloat(lng), parseFloat(lat)],
'EPSG:4326',
'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, lon, map) {
if (this.vectorMyPositionLayer) {
map.removeLayer(this.vectorMyPositionLayer);
}
const point = new ol.geom.Point(
ol.proj.transform(
[parseFloat(lon), parseFloat(lat)],
'EPSG:4326',
'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,
font: '13px Lato',
scale: 1.3,
textAlign: 'center',
textBaseline: 'middle',
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:4326', 'EPSG:3857');
const dettaglio = new ol.View({
minZoom: 6,
maxZoom: 24,
zoom: 17,
center: location,
duration: 200
});
map.setView(dettaglio);
}
resetCenter(lat, lon, map) {
const location = ol.proj.transform([lon, lat], 'EPSG:4326', 'EPSG:3857');
const dettaglio = new ol.View({
minZoom: 6,
maxZoom: 24,
zoom: 17,
center: location,
duration: 200
});
map.setView(dettaglio);
}
addDistrict(lat: number, lon: 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,156,1)',
width: 0
}),
fill: new ol.style.Fill({
color: 'rgba(0,0,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,
stroke: new ol.style.Stroke({
color: '#fff',
width: 2
}),
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();
}
}
}
This is the code to add markers (I call initMap
before that):
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);
When I get new markers from the web (for example 0 records, so I expect to not have any markers on the map), the map is redrawn but the markers remain.
I solved.
The problem was I was adding new layer of markers without deleting old one.
This is the new version of addCluster
function, where first of all I name the cluster, and I remove it (if exists) before adding new one:
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,
stroke: new ol.style.Stroke({
color: '#fff',
width: 2
}),
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);
}