Ejemplo n.º 1
0
        private static bool IsLinesIntersected(ProfileSurfacePoint firstStartPoint, ProfileSurfacePoint firstEndPoint,
                                               ProfileSurfacePoint secondStartPoint, ProfileSurfacePoint secondEndPoint)
        {
            const double epsilon = 1e-10;

            var firstLineVectorDiff  = PointsDiff(firstEndPoint, firstStartPoint);
            var secondLineVectorDiff = PointsDiff(secondEndPoint, secondStartPoint);
            var startPointsDiff      = PointsDiff(secondStartPoint, firstStartPoint);

            var diffCross = VectorCross(firstLineVectorDiff, secondLineVectorDiff);
            var startPointsCrossToFirst = VectorCross(startPointsDiff, firstLineVectorDiff);

            if (Math.Abs(diffCross) < epsilon && Math.Abs(startPointsCrossToFirst) < epsilon)
            {
                var firstLineProduct  = PointsProduct(startPointsDiff, firstLineVectorDiff);
                var secondLineProduct = PointsProduct(PointsDiff(firstStartPoint, secondStartPoint), secondLineVectorDiff);

                if ((firstLineProduct >= 0 && firstLineProduct <= VectorCross(firstLineVectorDiff, firstLineVectorDiff)) ||
                    (secondLineProduct >= 0 && secondLineProduct <= VectorCross(secondLineVectorDiff, secondLineVectorDiff)))
                {
                    return(true);
                }

                return(false);
            }
            var t = VectorCross(startPointsDiff, secondLineVectorDiff) / diffCross;
            var u = startPointsCrossToFirst / diffCross;

            if (!(Math.Abs(diffCross) < epsilon) && (0 <= t && t <= 1) && (0 <= u && u <= 1))
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 2
0
        private static double CalcVectorLength(ProfileSurfacePoint leftPoint, ProfileSurfacePoint rightPoint)
        {
            var x = rightPoint.Distance - leftPoint.Distance;
            var y = rightPoint.Z - leftPoint.Z;

            return(Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)));
        }
Ejemplo n.º 3
0
        private double CalcAngleOfDeviation(ProfileSurfacePoint leftPoint,
                                            ProfileSurfacePoint rightPoint)
        {
            var angle = Math.Atan(Math.Abs(rightPoint.Z - leftPoint.Z) / (rightPoint.Distance - leftPoint.Distance)) * (180 / Math.PI);

            return((rightPoint.Z < leftPoint.Z) ? angle * (-1) : angle);
        }
Ejemplo n.º 4
0
        private static double CalcAngleOfDeviation(ProfileSurfacePoint leftPoint, ProfileSurfacePoint rightPoint)
        {
            var angle = Math.Atan(Math.Abs(rightPoint.Z - leftPoint.Z) / (rightPoint.Distance - leftPoint.Distance));

            angle = RadiansToDegrees(angle);

            return((rightPoint.Z < leftPoint.Z) ? angle * (-1) : angle);
        }
Ejemplo n.º 5
0
        internal static IPoint GetObserverPoint(double observerHeight, ProfileSurfacePoint firstPoint)
        {
            IPoint geoPoint = new Point()
            {
                X = firstPoint.X, Y = firstPoint.Y, Z = firstPoint.Z, SpatialReference = EsriTools.Wgs84Spatialreference
            };

            return(EsriTools.GetObserverPoint(geoPoint, observerHeight, ArcMap.Document.FocusMap.SpatialReference));
        }
Ejemplo n.º 6
0
        private static double CalcAngleOfVisibility(double observerHeight, ProfileSurfacePoint leftPoint,
                                                    ProfileSurfacePoint rightPoint, double firstPointDistance)
        {
            var sightLineKoef   = (rightPoint.Z - observerHeight) / (rightPoint.Distance - firstPointDistance);
            var surfaceLineKoef = (rightPoint.Z - leftPoint.Z) / (rightPoint.Distance - leftPoint.Distance);

            var result = (surfaceLineKoef - sightLineKoef) / (1 + surfaceLineKoef * sightLineKoef);

            return(Math.Atan(result));
        }
Ejemplo n.º 7
0
        private List <double> FindAngles(ProfileSurfacePoint[] profileSurfacePoints)
        {
            var angles = new List <double>();
            ProfileSurfacePoint deviationPoint = profileSurfacePoints[0];

            for (var i = 0; i < profileSurfacePoints.Length - 2; i++)
            {
                if (CalcAngleOfDeviation(profileSurfacePoints[i], profileSurfacePoints[i + 1]) !=
                    CalcAngleOfDeviation(profileSurfacePoints[i + 1], profileSurfacePoints[i + 2]))
                {
                    angles.Add(CalcAngleOfDeviation(deviationPoint, profileSurfacePoints[i + 1]));
                    deviationPoint = profileSurfacePoints[i + 1];
                }
                else
                {
                    _triangle.Add(profileSurfacePoints[i + 1]);
                }
            }
            return(angles);
        }
Ejemplo n.º 8
0
        internal void AddVertexPointsToLine(List <ProfileSurface> segments, double observerHeight)
        {
            _surfaceProfileChart.AddVertexPoint(segments[0].ProfileSurfacePoints.First(), true, segments[0].LineId, observerHeight);

            for (int i = 0; i < segments.Count(); i++)
            {
                var isVisible = true;
                var points    = segments[i].ProfileSurfacePoints;

                var minHeightPoint = (points[0].Z > points.Last().Z) ? points.Last().Z : points[0].Z;
                minHeightPoint += observerHeight;

                for (int j = 0; j < points.Count() - 1; j++)
                {
                    if (points[j].Z < minHeightPoint && points[j + 1].Z < minHeightPoint)
                    {
                        continue;
                    }

                    var vertex = new ProfileSurfacePoint {
                        Z = points[0].Z + observerHeight, Distance = points[0].Distance
                    };
                    var vertexNext = new ProfileSurfacePoint {
                        Z = points.Last().Z + observerHeight, Distance = points.Last().Distance
                    };

                    if (IsLinesIntersected(vertex, vertexNext, points[j], points[j + 1]))
                    {
                        isVisible = false;
                        break;
                    }
                }

                _surfaceProfileChart.AddVertexPoint(points.Last(), isVisible, segments[i].LineId, observerHeight);
            }
        }
Ejemplo n.º 9
0
        internal void AddExtremePoint(ProfileSurfacePoint observerPoint, ProfileSurfacePoint observationPoint, int order)
        {
            profileChart.Series.Add(new Series
            {
                ChartType         = SeriesChartType.Line,
                Color             = Color.DarkGray,
                Name              = $"ExtremePointsLine{order}",
                YValuesPerPoint   = 1,
                IsVisibleInLegend = false
            });

            profileChart.Series[$"ExtremePointsLine{order}"].BorderDashStyle = ChartDashStyle.Dash;

            profileChart.Series[$"ExtremePointsLine{order}"].Points.AddXY(observerPoint.Distance, observerPoint.Z);
            profileChart.Series[$"ExtremePointsLine{order}"].Points[0].MarkerStyle = MarkerStyle.Circle;

            profileChart.Series[$"ExtremePointsLine{order}"].Points.AddXY(observationPoint.Distance, observationPoint.Z);

            if (profileChart.Series[$"{order}"].Points.Last().Color == profileChart.Series[$"{order}"].BackSecondaryColor)
            {
                profileChart.Series[$"ExtremePointsLine{order}"].Points[1].MarkerColor = Color.Red;
            }
            profileChart.Series[$"ExtremePointsLine{order}"].Points[1].MarkerStyle = MarkerStyle.Circle;
        }
Ejemplo n.º 10
0
 private static double VectorCross(ProfileSurfacePoint leftPoint, ProfileSurfacePoint rightPoint)
 {
     return(leftPoint.Distance * rightPoint.Z - leftPoint.Z * rightPoint.Distance);
 }
Ejemplo n.º 11
0
 private static double PointsProduct(ProfileSurfacePoint leftPoint, ProfileSurfacePoint rightPoint)
 {
     return(rightPoint.Distance * leftPoint.Distance + rightPoint.Z * leftPoint.Z);
 }
Ejemplo n.º 12
0
 private static ProfileSurfacePoint PointsDiff(ProfileSurfacePoint leftPoint, ProfileSurfacePoint rightPoint)
 {
     return(new ProfileSurfacePoint {
         Distance = rightPoint.Distance - leftPoint.Distance, Z = rightPoint.Z - leftPoint.Z
     });
 }
Ejemplo n.º 13
0
        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;
            }
        }