Example #1
0
        /// <summary>
        /// Construct the default reference surface name
        /// e.g. if the parent design file is bob.ttm, the offset 1.5 meters and the user units meters then the reference surface name is "bob +1.5m"
        /// </summary>
        /// <param name="prefProxy"></param>
        /// <param name="offset"></param>
        /// <param name="parentName"></param>
        /// <returns></returns>
        private async Task <string> DefaultReferenceSurfaceName(IPreferenceProxy prefProxy, double offset, string parentName)
        {
            const double imperialFeetToMetres = 0.3048;
            const double usFeetToMetres       = 0.304800609601;

            var displayOffset   = offset;
            var unitsString     = string.Empty;
            var userPreferences = await prefProxy.GetUserPreferences(UserId, Request.Headers.GetCustomHeaders());

            switch (userPreferences.Units.UnitsType())
            {
            case UnitsTypeEnum.Metric:
                displayOffset = offset;
                unitsString   = "m";
                break;

            case UnitsTypeEnum.Imperial:
                displayOffset = offset / imperialFeetToMetres;
                unitsString   = "ft";
                break;

            case UnitsTypeEnum.US:
                displayOffset = offset / usFeetToMetres;
                unitsString   = "ft";
                break;
            }
            var sign = offset > 0 ? "+" : "-";

            displayOffset = Math.Abs(displayOffset);
            return($"{parentName} {sign}{displayOffset:F3}{unitsString}");
        }
Example #2
0
        public async Task <ContractExecutionResult> CreateReferenceSurface(
            [FromQuery] Guid projectUid,
            [FromQuery] string filename,
            [FromQuery] DateTime fileCreatedUtc,
            [FromQuery] DateTime fileUpdatedUtc,
            [FromQuery] Guid parentUid,
            [FromQuery] double offset,
            [FromServices] ISchedulerProxy schedulerProxy,
            [FromServices] IPreferenceProxy prefProxy)
        {
            Logger.LogInformation($"{nameof(CreateReferenceSurface)}: projectUid {projectUid} filename: {filename} parentUid: {parentUid} offset: {offset}");

            await ValidateProjectId(projectUid.ToString());

            //Check parent design does exist
            var importedFiles = await ImportedFileRequestDatabaseHelper.GetImportedFileList(projectUid.ToString(), Logger, UserId, ProjectRepo);

            var parent = importedFiles.FirstOrDefault(i => i.ImportedFileUid == parentUid.ToString());

            if (parent == null)
            {
                ServiceExceptionHandler.ThrowServiceException(HttpStatusCode.BadRequest, 120);
            }

            //Fill in file name if not provided
            if (string.IsNullOrEmpty(filename))
            {
                filename = await DefaultReferenceSurfaceName(prefProxy, offset, Path.GetFileNameWithoutExtension(parent.Name));
            }

            //Validate parameters
            FileImportDataValidator.ValidateUpsertImportedFileRequest(projectUid, ImportedFileType.ReferenceSurface, DxfUnitsType.Meters, fileCreatedUtc,
                                                                      fileUpdatedUtc, UserEmailAddress, null, filename, parentUid, offset);

            //Check reference surface does not exist
            await ValidateFileDoesNotExist(projectUid.ToString(), filename, ImportedFileType.ReferenceSurface, null, parentUid, offset);

            var importedFileResult = await UpsertFileInternal(filename, null, projectUid, ImportedFileType.ReferenceSurface, DxfUnitsType.Meters,
                                                              fileCreatedUtc, fileUpdatedUtc, null, schedulerProxy, parentUid, offset);

            //If parent design is deactivated then deactivate reference surface
            if (!parent.IsActivated)
            {
                var filesToUpdate = new Dictionary <Guid, bool>();
                filesToUpdate.Add(new Guid(importedFileResult.ImportedFileDescriptor.ImportedFileUid), false);
                await DoActivationAndNotification(projectUid.ToString(), filesToUpdate);

                importedFiles = await ImportedFileRequestDatabaseHelper.GetImportedFileList(projectUid.ToString(), Logger, UserId, ProjectRepo);

                importedFileResult.ImportedFileDescriptor = importedFiles.SingleOrDefault(i =>
                                                                                          i.ImportedFileUid == importedFileResult.ImportedFileDescriptor.ImportedFileUid);
            }

            Logger.LogInformation(
                $"{nameof(CreateReferenceSurface)}: Completed successfully. Response: {JsonConvert.SerializeObject(importedFileResult)}");

            return(importedFileResult);
        }
Example #3
0
 /// <summary>
 ///
 /// Default constructor.
 /// </summary>
 public CompactionExportController(
     IConfigurationStore configStore, IFileImportProxy fileImportProxy, ICompactionSettingsManager settingsManager,
     IProductionDataRequestFactory requestFactory, IPreferenceProxy prefProxy,
     ITransferProxyFactory transferProxyFactory) :
     base(configStore, fileImportProxy, settingsManager)
 {
     this.prefProxy            = prefProxy;
     this.requestFactory       = requestFactory;
     this.transferProxyFactory = transferProxyFactory;
 }
Example #4
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 protected BaseController(IProductivity3dV2ProxyCompactionTile productivity3DProxyCompactionTile, IPreferenceProxy prefProxy, IFileImportProxy fileImportProxy,
                          IMapTileGenerator tileGenerator, IMemoryCache cache, IConfigurationStore configurationStore,
                          IBoundingBoxHelper boundingBoxHelper, ITPaaSApplicationAuthentication authn)
 {
     this.productivity3DProxyCompactionTile = productivity3DProxyCompactionTile;
     this.prefProxy         = prefProxy;
     this.fileImportProxy   = fileImportProxy;
     this.tileGenerator     = tileGenerator;
     tileCache              = cache;
     tileCacheExpiration    = GetCacheExpiration(configurationStore);
     configStore            = configurationStore;
     this.boundingBoxHelper = boundingBoxHelper;
     this.authn             = authn;
 }
Example #5
0
        /// <summary>
        /// Constructor with injection
        /// </summary>
        public NotificationController(
#if RAPTOR
            IASNodeClient raptorClient,
#endif
            ILoggerFactory logger, IConfigurationStore configStore,
            IPreferenceProxy prefProxy, IFileImportProxy fileImportProxy,
            IFilterServiceProxy filterServiceProxy, IProjectProxy projectProxy, IDataCache dataCache)
        {
#if RAPTOR
            this.raptorClient = raptorClient;
#endif
            this.logger             = logger;
            log                     = logger.CreateLogger <NotificationController>();
            this.configStore        = configStore;
            this.fileImportProxy    = fileImportProxy;
            this.filterServiceProxy = filterServiceProxy;
            this.dataCache          = dataCache;
            userPreferences         = prefProxy;
            this.projectProxy       = projectProxy;
        }
Example #6
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 public ReportTileController(IProductivity3dV2ProxyCompactionTile productivity3DProxyCompactionTile, IPreferenceProxy prefProxy, IFileImportProxy fileImportProxy,
                             IMapTileGenerator tileGenerator, IMemoryCache cache, IConfigurationStore configStore,
                             IBoundingBoxHelper boundingBoxHelper, ITPaaSApplicationAuthentication authn)
     : base(productivity3DProxyCompactionTile, prefProxy, fileImportProxy, tileGenerator, cache, configStore, boundingBoxHelper, authn)
 {
 }
Example #7
0
        public async Task <FileResult> GetMapTileDataTtm(
            [FromQuery] Guid projectUid,
            [FromQuery] Guid?filterUid,
            [FromQuery] Guid?designUid,
            [FromQuery] DisplayMode mode,
            [FromServices] IPreferenceProxy prefProxy,
            [FromServices] ITRexCompactionDataProxy tRexCompactionDataProxy,
#if RAPTOR
            [FromServices] IASNodeClient raptorClient,
#endif
            [FromServices] IProductionDataRequestFactory requestFactory)
        {
            const double SURFACE_EXPORT_TOLERANCE = 0.05;
            const byte   COORDS_ARRAY_LENGTH      = 3;

            var tins = new List <TrimbleTINModel>();

            var projectTask     = ((RaptorPrincipal)User).GetProject(projectUid);
            var projectSettings = GetProjectSettingsTargets(projectUid);
            var userPreferences = prefProxy.GetUserPreferences(GetUserId(), CustomHeaders);
            var filter          = GetCompactionFilter(projectUid, filterUid);
            var designTask      = GetAndValidateDesignDescriptor(projectUid, designUid);

            if (userPreferences == null)
            {
                throw new ServiceException(HttpStatusCode.BadRequest,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.FailedToGetResults,
                                                                       "Failed to retrieve preferences for current user"));
            }

            await Task.WhenAll(projectTask, projectSettings, userPreferences, designTask);

            var project = projectTask.Result;
            var design  = designTask.Result;

            // Get the terrain mesh
            var exportRequest = requestFactory.Create <ExportRequestHelper>(r => r
                                                                            .ProjectUid(projectUid)
                                                                            .ProjectId(project.ShortRaptorProjectId)
                                                                            .Headers(CustomHeaders)
                                                                            .ProjectSettings(projectSettings.Result)
                                                                            .Filter(filter.Result))
                                .SetUserPreferences(userPreferences.Result)
#if RAPTOR
                                .SetRaptorClient(raptorClient)
#endif
                                .SetProjectDescriptor(project)
                                .CreateExportRequest(
                null, //startUtc,
                null, //endUtc,
                CoordType.LatLon,
                ExportTypes.SurfaceExport,
                "test.zip",
                true,
                false,
                OutputTypes.VedaAllPasses,
                string.Empty,
                SURFACE_EXPORT_TOLERANCE);

            exportRequest.Validate();

            // First get the export of production data from Raptor
            // comes in a zip file
            var result = await WithServiceExceptionTryExecuteAsync(() => RequestExecutorContainerFactory.Build <CompactionExportExecutor>(LoggerFactory,
#if RAPTOR
                                                                                                                                          raptorClient,
#endif
                                                                                                                                          configStore : ConfigStore,
                                                                                                                                          trexCompactionDataProxy : tRexCompactionDataProxy,
                                                                                                                                          customHeaders : CustomHeaders,
                                                                                                                                          userId : GetUserId(),
                                                                                                                                          fileImportProxy : FileImportProxy)
                                                                   .ProcessAsync(exportRequest)) as CompactionExportResult;

            if (result != null)
            {
                var zipStream = (await transferProxyFactory.NewProxy(TransferProxyType.Temporary).Download(result.DownloadLink)).FileStream;
                // If we didn't get a valid file, then we failed to read the ttm from raptor
                if (zipStream == null)
                {
                    throw new ServiceException(HttpStatusCode.BadRequest,
                                               new ContractExecutionResult(ContractExecutionStatesEnum.FailedToGetResults,
                                                                           "Failed to retrieve data"));
                }

                using (var archive = new ZipArchive(zipStream))
                {
                    // The zip file will have exactly one file in it
                    if (archive.Entries.Count == 1)
                    {
                        try
                        {
                            var tin = new TrimbleTINModel();
                            using (var stream = archive.Entries[0].Open() as DeflateStream)
                                using (var ms = new MemoryStream())
                                {
                                    // Unzip the file, copy to memory as the TIN file needs the byte array, and stream
                                    stream.CopyTo(ms);
                                    ms.Seek(0, SeekOrigin.Begin);

                                    tin.LoadFromStream(ms, ms.GetBuffer());

                                    tins.Add(tin);
                                }
                        }
                        catch (TTMFileReadException e)
                        {
                            // Not valid, continue
                            Log.LogWarning(e, "Failed to parse ttm in zip file");
                        }
                    }
                }
            }

            // If we didn't get a valid file, then we failed to read the ttm from raptor
            if (tins.Count == 0)
            {
                throw new ServiceException(HttpStatusCode.BadRequest,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.FailedToGetResults,
                                                                       "Failed to retrieve data"));
            }

            // If we have a design request, get the ttm and add it for parsing
            if (design != null)
            {
                //TODO: This used to get the file from TCC. This code to get from s3 needs testing.
                //Leave for now as this end point is not currently supported.
                // Retrieve the stored file from AWS
                var s3FullPath    = $"{projectUid}/{design.File.FileName}";
                var transferProxy = transferProxyFactory.NewProxy(TransferProxyType.Temporary);
                var fileResult    = await transferProxy.Download(s3FullPath);

                if (fileResult?.FileStream != null)
                {
                    using (var ms = new MemoryStream())
                    {
                        fileResult.FileStream.CopyTo(ms);
                        ms.Seek(0, SeekOrigin.Begin);
                        var tin = new TrimbleTINModel();
                        tin.LoadFromStream(ms, ms.GetBuffer());
                        tins.Add(tin);
                    }
                }
            }

            // Calculating the bounding box for the model (including design if supplied)
            var minEasting     = tins.Select(t => t.Header.MinimumEasting).Min();
            var maxEasting     = tins.Select(t => t.Header.MaximumEasting).Max();
            var minNorthing    = tins.Select(t => t.Header.MinimumNorthing).Min();
            var maxNorthing    = tins.Select(t => t.Header.MaximumNorthing).Max();
            var centerEasting  = (maxEasting + minEasting) / 2.0;
            var centerNorthing = (maxNorthing + minNorthing) / 2.0;

            TwoDConversionCoordinate[] convertedCoordinates;

#if RAPTOR
            if (UseTRexGateway("ENABLE_TREX_GATEWAY_TILES"))
            {
#endif
            var conversionCoordinates = new []
            {
                new TwoDConversionCoordinate(minEasting, minNorthing),
                new TwoDConversionCoordinate(maxEasting, maxNorthing),
                new TwoDConversionCoordinate(centerEasting, centerNorthing)
            }
            ;

            var conversionRequest = new CoordinateConversionRequest(projectUid, TwoDCoordinateConversionType.NorthEastToLatLon, conversionCoordinates);
            var conversionResult  = await trexCompactionDataProxy.SendDataPostRequest <CoordinateConversionResult, CoordinateConversionRequest>(conversionRequest, "/coordinateconversion", CustomHeaders);

            if (conversionResult.Code != 0 || conversionResult.ConversionCoordinates.Length != COORDS_ARRAY_LENGTH)
            {
                throw new ServiceException(HttpStatusCode.BadRequest,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.FailedToGetResults,
                                                                       "Failed to retrieve long lat for boundary"));
            }

            convertedCoordinates = conversionResult.ConversionCoordinates;
#if RAPTOR
        }

        else
        {
            var points = new TWGS84FenceContainer
            {
                FencePoints = new[]
                {
                    TWGS84Point.Point(minEasting, minNorthing),
                    TWGS84Point.Point(maxEasting, maxNorthing),
                    TWGS84Point.Point(centerEasting, centerNorthing),
                }
            };

            // Convert the northing easting values to long lat values
            var res = raptorClient.GetGridCoordinates(project.LegacyProjectId, points, TCoordConversionType.ctNEEtoLLH, out var coordPointList);
            if (res != TCoordReturnCode.nercNoError)
            {
                throw new ServiceException(HttpStatusCode.BadRequest,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.FailedToGetResults,
                                                                       "Failed to retrieve long lat for boundary"));
            }

            convertedCoordinates = coordPointList.Points.Coords.Select(c => new TwoDConversionCoordinate(c.X, c.Y)).ToArray();
        }
#endif

            // The values returned from Raptor/TRex are in rads, where we need degrees for the bbox
            var minLat    = convertedCoordinates[0].Y * Coordinates.RADIANS_TO_DEGREES;
            var minLng    = convertedCoordinates[0].X * Coordinates.RADIANS_TO_DEGREES;
            var maxLat    = convertedCoordinates[1].Y * Coordinates.RADIANS_TO_DEGREES;
            var maxLng    = convertedCoordinates[1].X * Coordinates.RADIANS_TO_DEGREES;
            var centerLat = convertedCoordinates[2].Y * Coordinates.RADIANS_TO_DEGREES;
            var centerLng = convertedCoordinates[2].X * Coordinates.RADIANS_TO_DEGREES;
            var bbox      = $"{minLat},{minLng},{maxLat},{maxLng}";

            var outputStream = new MemoryStream();
            using (var zipArchive = new ZipArchive(outputStream, ZipArchiveMode.Create, true))
            {
                var textureZipEntry = zipArchive.CreateEntry("texture.png");
                using (var stream = textureZipEntry.Open())
                {
                    // Write the texture to the zip
                    var textureFileStream = await GetTexture(projectUid, designUid, projectSettings.Result, filter.Result, mode, bbox);

                    textureFileStream.FileStream.CopyTo(stream);
                }

                // Write the model to the zip
                var modelZipEntry = zipArchive.CreateEntry("model.obj");
                using (var stream = modelZipEntry.Open())
                {
                    var modelFileStream = ConvertMultipleToObj(tins, centerEasting, centerNorthing);
                    modelFileStream.FileStream.CopyTo(stream);
                }

                // Add some metadata to help with positioning of the model
                var metaDataEntry = zipArchive.CreateEntry("metadata.json");
                using (var stream = metaDataEntry.Open())
                {
                    var metaData = new
                    {
                        Minimum = new
                        {
                            Lat = minLat,
                            Lng = minLng
                        },
                        Maximum = new
                        {
                            Lat = maxLat,
                            Lng = maxLng
                        },
                        Center = new
                        {
                            Lat = centerLat,
                            Lng = centerLng
                        },
                        HasDesign = design != null
                    };
                    var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(metaData));
                    stream.Write(bytes, 0, bytes.Length);
                }
            }

            // Don't forget to seek back, or else the content length will be 0
            outputStream.Seek(0, SeekOrigin.Begin);
            return(new FileStreamResult(outputStream, ContentTypeConstants.ApplicationZip));
        }