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); }