public ProfileSession GenerateProfile( string profileSource, IEnumerable <IPolyline> profileLines, ProfileSettingsTypeEnum profileSettingsTypeEnum, int sessionId, string sessionName, double observHeight, string azimuthes) { string profileSourceName = GdbAccess.Instance.AddProfileLinesToCalculation(profileLines); var action = new ActionParam <string>() { ParamName = ActionParamNamesCore.Action, Value = ActionsEnum.bsp.ToString() }; string sdtnow = MilSpace.DataAccess.Helper.GetTemporaryNameSuffix(); var resuTable = $"{MilSpaceConfiguration.ConnectionProperty.TemporaryGDBConnection}\\StackProfile{sdtnow}"; var profileLineFeatureClass = GdbAccess.Instance.GetProfileLinesFeatureClass(profileSourceName); var prm = new List <IActionParam> { action, new ActionParam <string>() { ParamName = ActionParameters.FeatureClass, Value = profileLineFeatureClass }, new ActionParam <string>() { ParamName = ActionParameters.ProfileSource, Value = profileSource }, new ActionParam <string>() { ParamName = ActionParameters.DataWorkSpace, Value = resuTable }, new ActionParam <string>() { ParamName = ActionParameters.OutGraphName, Value = "" } }; var procc = new ActionProcessor(prm); var res = procc.Process <BoolResult>(); if (!res.Result) { if (res.Exception != null) { throw res.Exception; } //TODO: Log error throw new Exception(res.ErrorMessage); } //Take the table and import the data ISpatialReference currentSpatialreference = profileLines.First().SpatialReference; try { string tempTableName = $"StackProfile{sdtnow}"; ITable profiletable = GdbAccess.Instance.GetProfileTable(tempTableName); IFeatureClass lines = GdbAccess.Instance.GetCalcProfileFeatureClass(profileSourceName); IQueryFilter queryFilter = new QueryFilter() { WhereClause = WhereAllRecords }; ICursor featureCursor = profiletable.Search(queryFilter, true); IRow profileRow; int distanceFld = profiletable.FindField(FIRST_DIST_Field); int zFld = profiletable.FindField(FIRST_Z_Field); int idFld = profiletable.FindField(LINE_ID_Field); List <ProfileSurface> profileSurfaces = new List <ProfileSurface>(); ProfileSession session = new ProfileSession() { ProfileSurfaces = profileSurfaces.ToArray(), ProfileLines = GetProfileLines(lines).ToArray(), SessionId = sessionId, SessionName = sessionName, DefinitionType = profileSettingsTypeEnum, ObserverHeight = observHeight, SurfaceLayerName = profileSource, CreatedBy = Environment.UserName, CreatedOn = DateTime.Now, Shared = false, Azimuth = azimuthes }; Dictionary <int, List <ProfileSurfacePoint> > surface = new Dictionary <int, List <ProfileSurfacePoint> >(); int curLine = -1; IPolyline line = null; IEnumerable <IPoint> verticesCache; Dictionary <IPoint, ProfileSurfacePoint> mapProfilePointToVertex = new Dictionary <IPoint, ProfileSurfacePoint>(); Dictionary <IPoint, double> mapProfilePointToDistance = new Dictionary <IPoint, double>(); ProfileLine profileLine = null; verticesCache = new IPoint[0]; int pointsCount = 0; while ((profileRow = featureCursor.NextRow()) != null) { int lineId = Convert.ToInt32(profileRow.Value[idFld]); pointsCount++; if (!session.ProfileLines.Any(l => l.Id == lineId)) { throw new MilSpaceProfileLineNotFound(lineId, profileLineFeatureClass); } List <ProfileSurfacePoint> points; if (!surface.ContainsKey(lineId)) { points = new List <ProfileSurfacePoint>(); surface.Add(lineId, points); } else { points = surface[lineId]; } if (curLine != lineId) // data for new line { curLine = lineId; profileLine = session.ProfileLines.FirstOrDefault(l => l.Id == lineId); line = lines.GetFeature(profileLine.Id).Shape as IPolyline; verticesCache = line.Vertices(); mapProfilePointToVertex.ToList().ForEach(v => { if (!v.Value.IsEmpty) { v.Value.isVertex = true; } }); mapProfilePointToVertex = verticesCache.ToDictionary(k => k, t => new ProfileSurfacePoint()); mapProfilePointToDistance = verticesCache.ToDictionary(k => k, t => - 1.0); } //Returns the point with Origin (Taken from firstPoint) Spatial reference //var profilePointSource = EsriTools.GetPointFromAngelAndDistance(firstPoint, profileLine.Angel, (double)profileRow.Value[distanceFld]); //var profilePoint = profilePointSource.CloneWithProjecting(); // Try to define if this point is close to a vertex double distance = (double)profileRow.Value[distanceFld]; ProfileSurfacePoint newSurface = new ProfileSurfacePoint { Distance = distance, Z = (double)profileRow.Value[zFld], //X = profilePoint.X, //Y = profilePoint.Y }; IPoint point = new Point(); line.QueryPoint(esriSegmentExtension.esriNoExtension, newSurface.Distance, false, point); IProximityOperator proximity = point as IProximityOperator; foreach (var vertx in verticesCache) { var profilePoint = mapProfilePointToVertex[vertx]; if (mapProfilePointToDistance[vertx] == 0)// profilePoint.isVertex) { continue; } double localDistance = proximity.ReturnDistance(vertx); if (mapProfilePointToDistance[vertx] == -1 || mapProfilePointToDistance[vertx] > localDistance) { mapProfilePointToDistance[vertx] = localDistance; mapProfilePointToVertex[vertx] = newSurface; if (localDistance == 0) { newSurface.isVertex = true; } } } var projected = point.CloneWithProjecting(); newSurface.X = projected.X; newSurface.Y = projected.Y; points.Add(newSurface); } mapProfilePointToVertex.ToList().ForEach(v => { if (!v.Value.IsEmpty) { v.Value.isVertex = true; } }); //Delete temp table form the GDB GdbAccess.Instance.DeleteTemporarSource(tempTableName, profileSourceName); Marshal.ReleaseComObject(featureCursor); //TODO: Clean memo using Marhsaling IRow session.ProfileSurfaces = surface.Select(r => new ProfileSurface { LineId = r.Key, ProfileSurfacePoints = r.Value.ToArray() } ).ToArray(); return(session); } catch (MilSpaceCanotDeletePrifileCalcTable ex) { //TODO: Log error throw ex; } catch (MilSpaceDataException ex) { //TODO: Log error throw ex; } catch (Exception ex) { //TODO: Log error throw ex; } }