Пример #1
0
        private async Task <WGS84Fence> GetProjectBoundary(Guid projectUid)
        {
            var projectData = await((RaptorPrincipal)User).GetProject(projectUid);
            var result      = GeofenceValidation.ValidateWKT(projectData.ProjectGeofenceWKT);

            if (string.CompareOrdinal(result, GeofenceValidation.ValidationOk) != 0)
            {
                throw new ServiceException(HttpStatusCode.BadRequest,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.ValidationError,
                                                                       $"{nameof(GetProjectBoundary)}: The project has an invalid boundary ({result})."));
            }

            return(new WGS84Fence(CommonConverters.GeometryToPoints(projectData.ProjectGeofenceWKT).ToArray()));
        }
Пример #2
0
        private async Task <ProjectExtentsResult> FormatProjectExtentsResult(
            Guid projectUid, CoordinateConversionResult coordinateConversionResult)
        {
            Log.LogInformation($"{nameof(FormatProjectExtentsResult)}: {coordinateConversionResult}");
            var project = await((RaptorPrincipal)User).GetProject(projectUid);

            var returnResult = new ProjectExtentsResult
            {
                minLat = coordinateConversionResult.ConversionCoordinates[0].Y,
                minLng = coordinateConversionResult.ConversionCoordinates[0].X,
                maxLat = coordinateConversionResult.ConversionCoordinates[1].Y,
                maxLng = coordinateConversionResult.ConversionCoordinates[1].X
            };

            //In case we have rogue tag files distorting the extents, restrict to project boundary
            var projectPoints = CommonConverters.GeometryToPoints(project.ProjectGeofenceWKT).ToList();
            var projMinLat    = projectPoints.Min(p => p.Lat);
            var projMinLng    = projectPoints.Min(p => p.Lon);
            var projMaxLat    = projectPoints.Max(p => p.Lat);
            var projMaxLng    = projectPoints.Max(p => p.Lon);

            if (returnResult.minLat < projMinLat || returnResult.minLat > projMaxLat ||
                returnResult.maxLat < projMinLat || returnResult.maxLat > projMaxLat ||
                returnResult.minLng < projMinLng || returnResult.minLng > projMaxLng ||
                returnResult.maxLng < projMinLng || returnResult.maxLng > projMaxLng)
            {
                returnResult.minLat = projMinLat;
                returnResult.minLng = projMinLng;
                returnResult.maxLat = projMaxLat;
                returnResult.maxLng = projMaxLng;
            }

            //Convert to degrees to return
            returnResult.minLat = returnResult.minLat.LatRadiansToDegrees();
            returnResult.minLng = returnResult.minLng.LonRadiansToDegrees();
            returnResult.maxLat = returnResult.maxLat.LatRadiansToDegrees();
            returnResult.maxLng = returnResult.maxLng.LonRadiansToDegrees();

            Log.LogInformation("GetProjectExtents result: " + JsonConvert.SerializeObject(returnResult));
            return(returnResult);
        }
Пример #3
0
        /// <summary>
        /// Gets the map bounding box to use for the report.
        /// </summary>
        /// <param name="project">The project for the report</param>
        /// <param name="filter">The filter for production data tiles</param>
        /// <param name="overlays">The overlay or layer types</param>
        /// <param name="baseFilter">The base filter for summary volumes</param>
        /// <param name="topFilter">The top filter for summary volumes</param>
        /// <param name="designDescriptor">The design for cut-fill & summary volumes</param>
        /// <param name="userId"></param>
        /// <param name="customHeaders"></param>
        /// <returns>A bounding box in latitude/longitude (radians)</returns>
        public async Task <MapBoundingBox> GetBoundingBox(ProjectData project, FilterResult filter,
                                                          TileOverlayType[] overlays,
                                                          FilterResult baseFilter, FilterResult topFilter, DesignDescriptor designDescriptor,
                                                          string userId, IHeaderDictionary customHeaders)
        {
            log.LogInformation($"GetBoundingBox: project {project.ProjectUID}");

            MapBoundingBox bbox = null;

            //If the filter has an area then use it as the bounding box
            var filterPoints = await GetFilterPoints(project, filter, baseFilter, topFilter, customHeaders);

            if (filterPoints.Count > 0)
            {
                log.LogDebug("GetBoundingBox: Using area filter");

                bbox = new MapBoundingBox
                {
                    minLat = filterPoints.Min(p => p.Lat),
                    minLng = filterPoints.Min(p => p.Lon),
                    maxLat = filterPoints.Max(p => p.Lat),
                    maxLng = filterPoints.Max(p => p.Lon)
                };
            }
            else
            {
                //If no spatial filter then use cut-fill/volumes design
                var boundaryPoints = GetPointsFromPolygons(await GetDesignBoundaryPolygons(project, designDescriptor, customHeaders));
                if (boundaryPoints.Count > 0)
                {
                    log.LogDebug("GetBoundingBox: Using cut-fill design boundary");
                    bbox = new MapBoundingBox
                    {
                        minLat = boundaryPoints.Min(p => p.Lat),
                        minLng = boundaryPoints.Min(p => p.Lon),
                        maxLat = boundaryPoints.Max(p => p.Lat),
                        maxLng = boundaryPoints.Max(p => p.Lon)
                    };
                }
                else
                {
                    log.LogDebug("GetBoundingBox: No spatial filter");
                    //No area filter so use production data extents as the bounding box.
                    //Only applies if doing production data tiles.
                    //Also if doing the project boundary tile we assume the user wants to see that so production data extents not applicable.
                    if (overlays.Contains(TileOverlayType.ProductionData) && !overlays.Contains(TileOverlayType.ProjectBoundary))
                    {
                        var productionDataExtents = await GetProductionDataExtents(Guid.Parse(project.ProjectUID), project.ShortRaptorProjectId, filter, userId, customHeaders);

                        if (productionDataExtents != null)
                        {
                            log.LogDebug(
                                $"GetBoundingBox: Production data extents {productionDataExtents.ConversionCoordinates[0].Y},{productionDataExtents.ConversionCoordinates[0].X},{productionDataExtents.ConversionCoordinates[1].Y},{productionDataExtents.ConversionCoordinates[1].X}");

                            bbox = new MapBoundingBox
                            {
                                minLat = productionDataExtents.ConversionCoordinates[0].Y,
                                minLng = productionDataExtents.ConversionCoordinates[0].X,
                                maxLat = productionDataExtents.ConversionCoordinates[1].Y,
                                maxLng = productionDataExtents.ConversionCoordinates[1].X
                            };
                        }
                    }

                    //Sometimes tag files way outside the project boundary are imported. These mean the data extents are
                    //invalid and and give problems. So need to check for this and use project extents in this case.

                    //Also use project boundary extents if fail to get production data extents or not doing production data tiles
                    //e.g. project thumbnails or user has requested project boundary overlay
                    var projectPoints = CommonConverters.GeometryToPoints(project.ProjectGeofenceWKT).ToList();
                    var projectMinLat = projectPoints.Min(p => p.Lat);
                    var projectMinLng = projectPoints.Min(p => p.Lon);
                    var projectMaxLat = projectPoints.Max(p => p.Lat);
                    var projectMaxLng = projectPoints.Max(p => p.Lon);
                    var assign        = bbox == null
            ? true
            : bbox.minLat <projectMinLat || bbox.minLat> projectMaxLat ||
                                        bbox.maxLat <projectMinLat || bbox.maxLat> projectMaxLat ||
                                        bbox.minLng <projectMinLng || bbox.minLng> projectMaxLng ||
                                        bbox.maxLng <projectMinLng || bbox.minLng> projectMaxLng;

                    if (assign)
                    {
                        log.LogDebug(
                            $"GetBoundingBox: Using project extents {projectMinLat},{projectMinLng},{projectMaxLat},{projectMaxLng}");

                        bbox = new MapBoundingBox
                        {
                            minLat = projectMinLat,
                            minLng = projectMinLng,
                            maxLat = projectMaxLat,
                            maxLng = projectMaxLng
                        };
                    }
                }
            }

            return(bbox);
        }