private async Task UpdatePointsOfInterest(OsmChange changes) { var deleteTasks = new List <Task>(); var relevantTagsDictionary = _tagsHelper.GetAllTags(); foreach (var poiToRemove in changes.Delete) { var task = _elasticSearchGateway.DeleteOsmPointOfInterestById(poiToRemove.Type.ToString().ToLower() + "_" + poiToRemove.Id); deleteTasks.Add(task); } await Task.WhenAll(deleteTasks); var updateTasks = new List <Task <ICompleteOsmGeo> >(); foreach (var poiToUpdate in changes.Modify .Concat(changes.Create) .Where(o => IsRelevantPointOfInterest(o, relevantTagsDictionary))) { var task = _osmGateway.GetCompleteElement(poiToUpdate.Id.Value, poiToUpdate.Type); updateTasks.Add(task); } var allElemets = await Task.WhenAll(updateTasks); var osmNamesDictionary = allElemets.GroupBy(e => e.Tags.GetName()).ToDictionary(g => g.Key, g => g.ToList()); var features = _osmGeoJsonPreprocessorExecutor.Preprocess(osmNamesDictionary); foreach (var poiToUpdate in changes.Modify .Where(o => IsRelevantPointOfInterest(o, relevantTagsDictionary))) { var featureFromDb = await _elasticSearchGateway.GetPointOfInterestById(poiToUpdate.Type.ToString().ToLower() + "_" + poiToUpdate.Id, Sources.OSM); if (featureFromDb == null) { continue; } var featureToUpdate = features.First(f => f.GetId().Equals(featureFromDb.GetId())); foreach (var attributeKey in featureFromDb.Attributes.GetNames().Where(n => n.StartsWith(FeatureAttributes.POI_PREFIX))) { featureToUpdate.Attributes.AddOrUpdate(attributeKey, featureFromDb.Attributes[attributeKey]); } if (featureToUpdate.Geometry.OgcGeometryType == OgcGeometryType.Point && featureFromDb.Geometry.OgcGeometryType != OgcGeometryType.Point) { featureToUpdate.Geometry = featureFromDb.Geometry; } } await _elasticSearchGateway.UpdatePointsOfInterestData(features); }