예제 #1
0
        public static IFeatureClass CreateOPFeatureClass(WizardResult calcResult, IFeatureClass observatioPointsFeatureClass,
                                                         IActiveView activeView, IRaster raster)
        {
            var calcObservPointsFeatureClass = VisibilityCalcResults.GetResultName(VisibilityCalculationResultsEnum.ObservationPoints, calcResult.TaskName);

            var observPointTemporaryFeatureClass =
                GdbAccess.Instance.GenerateTemporaryFeatureClassWithRequitedFields(observatioPointsFeatureClass.Fields, calcObservPointsFeatureClass);

            bool   isCircle;
            double maxAzimuth  = 0;
            double minAzimuth  = 360;
            double maxDistance = 0;

            calcResult.ObservationStation.Project(activeView.FocusMap.SpatialReference);

            var observationStationPolygon   = calcResult.ObservationStation as IPolygon;
            var observStationEnvelope       = observationStationPolygon.Envelope;
            var observStationEnvelopePoints = new IPoint[] { observStationEnvelope.LowerLeft, observStationEnvelope.LowerRight,
                                                             observStationEnvelope.UpperRight, observStationEnvelope.UpperLeft };

            var observerPointGeometry = new PointClass
            {
                X = calcResult.ObservationPoint.X.Value,
                Y = calcResult.ObservationPoint.Y.Value,
                SpatialReference = EsriTools.Wgs84Spatialreference
            };

            observerPointGeometry.Project(activeView.FocusMap.SpatialReference);

            observerPointGeometry.AddZCoordinate(raster);
            observerPointGeometry.ZAware = true;

            if (double.IsNaN(observerPointGeometry.Z))
            {
                throw new MilSpacePointOutOfRatserException(calcResult.ObservationPoint.Objectid, calcResult.RasterLayerName);
            }

            var minDistance = FindMinDistance(observStationEnvelopePoints, observerPointGeometry);


            // ---- Get min and max azimuths ----

            var points = EsriTools.GetPointsFromGeometries(new IGeometry[] { calcResult.ObservationStation },
                                                           observerPointGeometry.SpatialReference,
                                                           out isCircle).ToArray();

            bool isPointInside = EsriTools.IsPointOnExtent(observStationEnvelope, observerPointGeometry);

            // Set azimuth for circle polygon
            if (isCircle && !isPointInside)
            {
                for (int i = 0; i < observStationEnvelopePoints.Length; i++)
                {
                    var line = new Line()
                    {
                        FromPoint        = observerPointGeometry,
                        ToPoint          = observStationEnvelopePoints[i],
                        SpatialReference = observerPointGeometry.SpatialReference
                    };

                    if (i == 0)
                    {
                        maxDistance = line.Length;
                    }
                    else if (maxDistance < line.Length)
                    {
                        maxDistance = line.Length;
                    }

                    if (minAzimuth > line.PosAzimuth())
                    {
                        minAzimuth = line.PosAzimuth();
                    }

                    if (maxAzimuth < line.PosAzimuth())
                    {
                        maxAzimuth = line.PosAzimuth();
                    }
                }
            }
            else
            {
                EsriTools.CreateDefaultPolylinesForFun(observerPointGeometry, points, new IGeometry[] { calcResult.ObservationStation },
                                                       isCircle, isPointInside, -1, out minAzimuth, out maxAzimuth, out maxDistance).ToList();
            }
            // ---- End. Get min and max azimuths ----

            // observerPointGeometry.Project(activeView.FocusMap.SpatialReference);
            var pointCopy = observerPointGeometry.CloneWithProjecting();

            (pointCopy as PointClass).ZAware = true;

            int idObserPooint = 0;

            for (var currentHeight = calcResult.FromHeight; currentHeight <= calcResult.ToHeight; currentHeight += calcResult.Step)
            {
                double maxTiltAngle = -90;
                double minTiltAngle = 90;

                var height = currentHeight;

                // Set parameters for case if point located into the polygon
                if (isCircle && isPointInside)
                {
                    minTiltAngle = -90;
                    minDistance  = 0;
                }

                for (int i = 0; i < observStationEnvelopePoints.Length; i++)
                {
                    var currentTitleAngle = EsriTools.FindAngleByDistanceAndHeight(height, observerPointGeometry, observStationEnvelopePoints[i], raster);

                    if (minTiltAngle > currentTitleAngle)
                    {
                        minTiltAngle = currentTitleAngle;
                    }

                    if (maxTiltAngle < currentTitleAngle)
                    {
                        maxTiltAngle = currentTitleAngle;
                    }
                }

                // Create observation point copy with changing height, distance and angles values
                ObservationPoint currentObservationPoint = calcResult.ObservationPoint.ShallowCopy();
                currentObservationPoint.RelativeHeight  = currentHeight;
                currentObservationPoint.AngelMinH       = minTiltAngle;
                currentObservationPoint.AngelMaxH       = maxTiltAngle;
                currentObservationPoint.AzimuthStart    = minAzimuth;
                currentObservationPoint.AzimuthEnd      = maxAzimuth;
                currentObservationPoint.InnerRadius     = minDistance;
                currentObservationPoint.OuterRadius     = maxDistance;
                currentObservationPoint.AzimuthMainAxis = calcResult.ObservationPoint.AzimuthMainAxis;
                currentObservationPoint.Id = idObserPooint.ToString();

                GdbAccess.Instance.AddObservPoint(pointCopy, currentObservationPoint, observPointTemporaryFeatureClass);
                idObserPooint++;
            }

            return(observPointTemporaryFeatureClass);
        }