public async void OnMeasurementChanged(object sender, IEventArgs <IFeatureCollection> args) { InUpdateMeasurementMode.WaitOne(MaxWaitTime); InUpdateMeasurementMode.Reset(); FeatureCollection = args.Value; IStreetSmartAPI api = sender as IStreetSmartAPI; foreach (IFeature feature in FeatureCollection.Features) { if (feature.Properties is IMeasurementProperties properties) { Measurement measurement; if (Count == 0) { measurement = new Measurement(properties, feature.Geometry, DrawPoint, api) { ObjectId = _lastObjectId, VectorLayer = _lastVectorLayer }; Add(properties.Id, measurement); measurement.Open(); if (_lastSketch) { measurement.SetSketch(); } } else { measurement = this.ElementAt(0).Value; } measurement.ObservationLines = properties.ObservationLines; if (measurement.Properties == null) { measurement.Properties = properties; } if (measurement.Geometry == null) { measurement.Geometry = feature.Geometry; } if (!measurement.UpdateMeasurement) { measurement.UpdateMeasurement = true; IGeometry geometry = feature.Geometry; StreetSmartGeometryType geometryType = geometry.Type; switch (geometryType) { case StreetSmartGeometryType.Point: await RemoveLineStringPoints(measurement); await RemovePolygonPoints(measurement); if (geometry is IPoint pointDst) { if (measurement.Count >= 1 && measurement[0].Point != null && (pointDst.X == null || pointDst.Y == null) && measurement.MeasurementId != properties.Id) { MapView mapView = MapView.Active; Geometry geometrySketch = await mapView.GetCurrentSketchAsync(); await measurement.VectorLayer.AddFeatureAsync(geometrySketch); await mapView.ClearSketchAsync(); measurement[0].Dispose(); } else { measurement.MeasurementId = properties.Id; await measurement.UpdatePointAsync(0, feature); measurement.Geometry = geometry; } } await measurement.UpdateMap(); break; case StreetSmartGeometryType.LineString: await RemovePointPoints(measurement); await RemovePolygonPoints(measurement); if (geometry is ILineString lineDst) { if (measurement.Count >= 1 && measurement[0].Point != null && lineDst.Count == 0 && measurement.MeasurementId != properties.Id) { MapView mapView = MapView.Active; Geometry geometrySketch = await mapView.GetCurrentSketchAsync(); await measurement.VectorLayer.AddFeatureAsync(geometrySketch); await mapView.ClearSketchAsync(); if (geometrySketch != null) { await QueuedTask.Run(() => { List <MapPoint> points = new List <MapPoint>(); Polyline line = PolylineBuilder.CreatePolyline(points, geometrySketch.SpatialReference); mapView.SetCurrentSketchAsync(line); }); } } else if (measurement.Geometry is ILineString lineSrc) { measurement.MeasurementId = properties.Id; for (int i = 0; i < Math.Max(lineDst.Count, lineSrc.Count); i++) { measurement.RemoveObservations(i, feature); if (lineSrc.Count > i && lineDst.Count > i) { await measurement.UpdatePointAsync(i, feature); } else if (lineSrc.Count <= i && lineDst.Count > i) { measurement.AddPoint(lineSrc.Count); await measurement.UpdatePointAsync(i, feature); } else if (lineSrc.Count > i && lineDst.Count <= i) { await measurement.RemovePoint(i); await measurement.UpdatePointAsync(Math.Min(i, lineDst.Count - 1), feature); } } measurement.Geometry = geometry; await measurement.UpdateMap(); } else { measurement.MeasurementId = properties.Id; for (int i = 0; i < lineDst.Count; i++) { measurement.AddPoint(i); await measurement.UpdatePointAsync(i, feature); } measurement.Geometry = geometry; await measurement.UpdateMap(); } } break; case StreetSmartGeometryType.Polygon: await RemovePointPoints(measurement); await RemoveLineStringPoints(measurement); if (geometry is IPolygon polyDst) { if (measurement.Count >= 1 && measurement[measurement.ElementAt(0).Key].Point != null && polyDst[0].Count == 0 && measurement.MeasurementId != properties.Id) { MapView mapView = MapView.Active; Geometry geometrySketch = await mapView.GetCurrentSketchAsync(); await measurement.VectorLayer.AddFeatureAsync(geometrySketch); await mapView.ClearSketchAsync(); if (geometrySketch != null) { await QueuedTask.Run(() => { List <MapPoint> points = new List <MapPoint>(); Polygon polygon = PolygonBuilder.CreatePolygon(points, geometrySketch.SpatialReference); mapView.SetCurrentSketchAsync(polygon); }); } } else if (measurement.Geometry is IPolygon polySrc) { measurement.MeasurementId = properties.Id; int polySrcCount = polySrc[0].Count; int pylyDstCount = polyDst[0].Count; for (int i = 0; i < Math.Max(pylyDstCount, polySrcCount); i++) { measurement.RemoveObservations(i, feature); if (polySrcCount > i && pylyDstCount > i) { await measurement.UpdatePointAsync(i, feature); } else if (polySrcCount <= i && pylyDstCount > i) { measurement.AddPoint(polySrcCount++); await measurement.UpdatePointAsync(i, feature); } else if (polySrcCount > i && pylyDstCount <= i) { await measurement.RemovePoint(i); polySrcCount--; await measurement.UpdatePointAsync(Math.Min(i, pylyDstCount - 1), feature); } } measurement.Geometry = geometry; await measurement.UpdateMap(); } else { measurement.MeasurementId = properties.Id; int pylyDstCount = polyDst[0].Count; for (int i = 0; i < pylyDstCount; i++) { measurement.AddPoint(i); await measurement.UpdatePointAsync(i, feature); } measurement.Geometry = geometry; await measurement.UpdateMap(); } } break; } measurement.UpdateMeasurement = false; } else { measurement.DoChange = true; } } } if (FeatureCollection.Type == FeatureType.Unknown) { if (Count == 1) { Measurement measurement = this.ElementAt(0).Value; measurement.Close(); await FrameworkApplication.SetCurrentToolAsync(string.Empty); } } InUpdateMeasurementMode.Set(); }