/// <summary> /// Get the generated tile for the request. Used for geofence thumbnails. /// </summary> protected async Task <FileResult> GetGeneratedTile(GeofenceData geofence, TileOverlayType[] overlays, int width, int height, string bbox, MapType?mapType, string language, bool adjustBoundingBox) { var byteResult = await tileCache.GetOrCreateAsync <byte[]>(geofence.GeofenceUID, async entry => { entry.SlidingExpiration = tileCacheExpiration; var overlayTypes = overlays.ToList(); language = string.IsNullOrEmpty(language) ? (await GetShortCachedUserPreferences()).Language : language; var geofences = new List <GeofenceData> { geofence }; var mapParameters = tileGenerator.GetMapParameters(bbox, width, height, overlayTypes.Contains(TileOverlayType.GeofenceBoundary), adjustBoundingBox); var request = TileGenerationRequest.CreateTileGenerationRequest(null, null, null, null, null, geofences, null, null, null, null, null, null, overlayTypes, width, height, mapType, null, language, null, mapParameters, CustomHeaders, null); request.Validate(); Log.LogDebug("The tile doesn't exist in cache - generating it"); return(await WithServiceExceptionTryExecuteAsync(() => tileGenerator.GetMapData(request))); }); return(new FileStreamResult(new MemoryStream(byteResult), ContentTypeConstants.ImagePng)); }
/// <summary> /// Reduce the size of the tile to the requested size. This assumes the relevant calculations have been done to maintain the aspect ratio. /// </summary> /// <param name="request">Request parameters</param> /// <param name="overlayTile">The tile to scale</param> /// <returns>The scaled tile</returns> private byte[] ScaleTile(TileGenerationRequest request, byte[] overlayTile) { using (var tileStream = new MemoryStream(overlayTile)) using (Image <Rgba32> bitmap = Image.Load <Rgba32>(tileStream)) { log.LogDebug($"ScaleTile: requested size=({request.width},{request.height}), image size=({bitmap.Width},{bitmap.Height})"); bitmap.Mutate(ctx => ctx.Resize(request.width, request.height)); return(bitmap.BitmapToByteArray()); } }
protected override Task <TileMetadata> GenerateTiles(TileGenerationRequest request) { if (!(request is DxfTileGenerationRequest dxfRequest)) { log.LogError("Exception when converting parameters to DxfTileGenerationRequest"); throw new ServiceException(HttpStatusCode.InternalServerError, new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError, "Missing or Wrong parameters passed to DXF tile generation job")); } dxfRequest.Validate(); var dxfFileName = $"{dxfRequest.DataOceanPath}{Path.DirectorySeparatorChar}{dxfRequest.FileName}"; var dcFileName = $"{dxfRequest.DataOceanPath}{Path.DirectorySeparatorChar}{dxfRequest.DcFileName}"; return(pegasusClient.GenerateDxfTiles(dcFileName, dxfFileName, dxfRequest.DxfUnitsType, CustomHeaders(), SetJobValues)); }
public async Task CanRunGeoTiffJobSuccess(bool enableGeoTiffTileGeneration) { var request = new TileGenerationRequest { CustomerUid = Guid.NewGuid(), ProjectUid = Guid.NewGuid(), ImportedFileUid = Guid.NewGuid(), DataOceanRootFolder = "some folder", FileName = "a geotiff file", }; var obj = JObject.Parse(JsonConvert.SerializeObject(request)); var configStore = new Mock <IConfigurationStore>(); configStore.Setup(x => x.GetValueBool("SCHEDULER_ENABLE_DXF_TILE_GENERATION")) .Returns(enableGeoTiffTileGeneration); var mockPegasus = new Mock <IPegasusClient>(); mockPegasus.Setup(x => x.GenerateGeoTiffTiles( It.IsAny <string>(), It.IsAny <HeaderDictionary>(), It.IsAny <Action <IHeaderDictionary> >())) .ReturnsAsync(new TileMetadata()); var mockNotification = new Mock <INotificationHubClient>(); mockNotification.Setup(n => n.Notify(It.IsAny <ProjectFileRasterTilesGeneratedNotification>())) .Returns(Task.FromResult(default(object))); var mockTPaaSAuth = new Mock <ITPaaSApplicationAuthentication>(); mockTPaaSAuth.Setup(t => t.GetApplicationBearerToken()) .Returns("this is a dummy bearer token"); var job = new GeoTiffTileGenerationJob(configStore.Object, mockPegasus.Object, mockTPaaSAuth.Object, mockNotification.Object, loggerFactory); await job.Run(obj, null); var runTimes = enableGeoTiffTileGeneration ? Times.Once() : Times.Never(); // Verify based on the value of SCHEDULER_ENABLE_DXF_TILE_GENERATION the execution of GenerateGeoTiffTiles(). mockPegasus.Verify(x => x.GenerateGeoTiffTiles( It.IsAny <string>(), It.IsAny <HeaderDictionary>(), It.IsAny <Action <IHeaderDictionary> >()), runTimes); }
/// <summary> /// Gets a single tile with various types of data overlayed on it according to what is requested. /// </summary> /// <param name="request">The tile request</param> /// <returns>A TileResult</returns> public async Task <byte[]> GetMapData(TileGenerationRequest request) { log.LogInformation("Getting map tile"); log.LogDebug("TileGenerationRequest: " + JsonConvert.SerializeObject(request)); log.LogDebug("Awaiting tiles to be completed"); var overlays = await Task.WhenAll(request.overlays.Select(overlay => RequestTile(request, overlay))); log.LogDebug($"Tiles completed: {overlays.Count()} overlays"); var overlayTile = TileServiceUtils.OverlayTiles(request.mapParameters, overlays.ToDictionary(k => k.Item1, v => v.Item2)); log.LogDebug("Tiles overlaid"); overlayTile = ScaleTile(request, overlayTile); log.LogDebug("Tiles scaled"); return(overlayTile); }
/// <summary> /// Get the generated tile for the request. Used for raw geofence thumbnails where the boundaries have come from a DXF file. /// </summary> protected async Task <FileResult> GetGeneratedTile(List <WGSPoint> geofencePoints, TileOverlayType[] overlays, int width, int height, string bbox, MapType?mapType, string language, bool adjustBoundingBox) { var overlayTypes = overlays.ToList(); language = string.IsNullOrEmpty(language) ? (await GetShortCachedUserPreferences()).Language : language; var mapParameters = tileGenerator.GetMapParameters(bbox, width, height, overlayTypes.Contains(TileOverlayType.GeofenceBoundary), adjustBoundingBox); var request = TileGenerationRequest.CreateTileGenerationRequest(null, null, null, null, null, null, null, null, null, null, null, null, overlayTypes, width, height, mapType, null, language, null, mapParameters, CustomHeaders, geofencePoints); request.Validate(); var byteResult = await WithServiceExceptionTryExecuteAsync(() => tileGenerator.GetMapData(request)); return(new FileStreamResult(new MemoryStream(byteResult), ContentTypeConstants.ImagePng)); }
/// <summary> /// Creates a job request for generating raster tiles /// </summary> public static JobRequest CreateRequest(ImportedFileType importedFileType, string customerUid, string projectUid, string importedFileUid, string dataOceanRootFolder, string fileName, string dcFileName = null, DxfUnitsType dxfUnitsType = DxfUnitsType.Meters, DateTime?surveyedUtc = null) { TileGenerationRequest runParams; Guid jobUid; switch (importedFileType) { case ImportedFileType.GeoTiff: runParams = new TileGenerationRequest(); jobUid = GeoTiffTileGenerationJob.VSSJOB_UID; break; case ImportedFileType.Linework: runParams = new DxfTileGenerationRequest { DcFileName = dcFileName, DxfUnitsType = dxfUnitsType }; jobUid = DxfTileGenerationJob.VSSJOB_UID; break; default: throw new NotImplementedException(); } runParams.CustomerUid = Guid.Parse(customerUid); runParams.ProjectUid = Guid.Parse(projectUid); runParams.ImportedFileUid = Guid.Parse(importedFileUid); runParams.DataOceanRootFolder = dataOceanRootFolder; runParams.FileName = fileName; return(new JobRequest { JobUid = jobUid, RunParameters = runParams }); }
protected abstract Task <TileMetadata> GenerateTiles(TileGenerationRequest request);
private async Task <(TileOverlayType, byte[])> RequestTile(TileGenerationRequest request, TileOverlayType overlay) { byte[] bitmap = null; log.LogDebug($"Processing tile of type {overlay}"); switch (overlay) { case TileOverlayType.BaseMap: bitmap = mapTileService.GetMapBitmap(request.mapParameters, request.mapType.Value, request.language.Substring(0, 2)); break; case TileOverlayType.ProductionData: var bbox = $"{request.mapParameters.bbox.minLatDegrees},{request.mapParameters.bbox.minLngDegrees},{request.mapParameters.bbox.maxLatDegrees},{request.mapParameters.bbox.maxLngDegrees}"; bitmap = await productivity3DProxyCompactionTile.GetProductionDataTile(Guid.Parse(request.project.ProjectUID), request.filterUid, request.cutFillDesignUid, (ushort)request.mapParameters.mapWidth, (ushort)request.mapParameters.mapHeight, bbox, request.mode.Value, request.baseUid, request.topUid, request.volCalcType, request.customHeaders, request.ExplicitFilters); break; case TileOverlayType.ProjectBoundary: bitmap = projectTileService.GetProjectBitmap(request.mapParameters, request.project); break; case TileOverlayType.GeofenceBoundary: case TileOverlayType.Geofences: bitmap = request.geoJsonPoints != null && overlay == TileOverlayType.GeofenceBoundary ? geofenceTileService.GetGeoJsonBitmap(request.mapParameters, request.geoJsonPoints) : geofenceTileService.GetSitesBitmap(request.mapParameters, request.geofences); break; case TileOverlayType.FilterCustomBoundary: bitmap = geofenceTileService.GetFilterBoundaryBitmap(request.mapParameters, request.customFilterBoundary, FilterBoundaryType.Polygon); break; case TileOverlayType.FilterDesignBoundary: bitmap = geofenceTileService.GetFilterBoundaryBitmap(request.mapParameters, request.designFilterBoundary, FilterBoundaryType.Design); break; case TileOverlayType.FilterAlignmentBoundary: bitmap = geofenceTileService.GetFilterBoundaryBitmap(request.mapParameters, request.alignmentFilterBoundary, FilterBoundaryType.Alignment); break; case TileOverlayType.CutFillDesignBoundary: bitmap = geofenceTileService.GetFilterBoundaryBitmap(request.mapParameters, request.designBoundaryPoints, FilterBoundaryType.Design); break; case TileOverlayType.Alignments: bitmap = alignmentTileService.GetAlignmentsBitmap(request.mapParameters, request.project.ShortRaptorProjectId, request.alignmentPointsList); break; case TileOverlayType.DxfLinework: bitmap = await dxfTileService.GetDxfBitmap(request.mapParameters, request.dxfFiles); break; case TileOverlayType.LoadDumpData: var loadDumpLocations = await loadDumpProxy.GetLoadDumpLocations(request.project.ProjectUID, request.customHeaders); bitmap = loadDumpTileService.GetLoadDumpBitmap(request.mapParameters, loadDumpLocations); break; } return(overlay, bitmap); }
/// <summary> /// Get the generated tile for the request /// </summary> protected async Task <FileResult> GetGeneratedTile(Guid projectUid, Guid?filterUid, Guid?cutFillDesignUid, Guid?baseUid, Guid?topUid, VolumeCalcType?volumeCalcType, TileOverlayType[] overlays, int width, int height, string bbox, MapType?mapType, DisplayMode?mode, string language, bool adjustBoundingBox, bool explicitFilters = false) { var overlayTypes = overlays.ToList(); if (overlays.Contains(TileOverlayType.AllOverlays)) { overlayTypes = new List <TileOverlayType>((TileOverlayType[])Enum.GetValues(typeof(TileOverlayType))); overlayTypes.Remove(TileOverlayType.AllOverlays); //TODO: AllOverlays means for 3D so remove 2D overlay. Rename overlay type better to reflect this. Also may need a '2D all overlays' in future. overlayTypes.Remove(TileOverlayType.LoadDumpData); } var project = await((TilePrincipal)User).GetProject(projectUid); var dxfFiles = overlayTypes.Contains(TileOverlayType.DxfLinework) ? await GetFilesOfType(projectUid, ImportedFileType.Linework) : new List <FileData>(); var haveFilter = filterUid.HasValue || baseUid.HasValue || topUid.HasValue; var customFilterBoundary = haveFilter && overlayTypes.Contains(TileOverlayType.FilterCustomBoundary) ? (await productivity3DProxyCompactionTile.GetFilterPointsList(projectUid, filterUid, baseUid, topUid, FilterBoundaryType.Polygon, CustomHeaders)).PointsList : new List <List <WGSPoint> >(); var designFilterBoundary = haveFilter && overlayTypes.Contains(TileOverlayType.FilterDesignBoundary) ? (await productivity3DProxyCompactionTile.GetFilterPointsList(projectUid, filterUid, baseUid, topUid, FilterBoundaryType.Design, CustomHeaders)).PointsList : new List <List <WGSPoint> >(); var alignmentFilterBoundary = haveFilter && overlayTypes.Contains(TileOverlayType.FilterAlignmentBoundary) ? (await productivity3DProxyCompactionTile.GetFilterPointsList(projectUid, filterUid, baseUid, topUid, FilterBoundaryType.Alignment, CustomHeaders)).PointsList : new List <List <WGSPoint> >(); var designUid = !volumeCalcType.HasValue || volumeCalcType == VolumeCalcType.None || volumeCalcType == VolumeCalcType.GroundToGround ? cutFillDesignUid : (volumeCalcType == VolumeCalcType.DesignToGround ? baseUid : topUid); var designBoundary = designUid.HasValue && overlayTypes.Contains(TileOverlayType.CutFillDesignBoundary) ? (await productivity3DProxyCompactionTile.GetDesignBoundaryPoints(projectUid, designUid.Value, CustomHeaders)).PointsList : new List <List <WGSPoint> >(); var alignmentPoints = overlayTypes.Contains(TileOverlayType.Alignments) ? (await productivity3DProxyCompactionTile.GetAlignmentPointsList(projectUid, CustomHeaders)).PointsList : new List <List <WGSPoint> >(); language = string.IsNullOrEmpty(language) ? (await GetShortCachedUserPreferences()).Language : language; ////var geofences = overlayTypes.Contains(TileOverlayType.Geofences) //// ? await geofenceProxy.GetGeofences(GetCustomerUid, CustomHeaders) //// : new List<GeofenceData>(); var geofences = new List <GeofenceData>(); if (string.IsNullOrEmpty(bbox)) { bbox = await productivity3DProxyCompactionTile.GetBoundingBox(projectUid, overlays, filterUid, cutFillDesignUid, baseUid, topUid, volumeCalcType, CustomHeaders); } var mapParameters = tileGenerator.GetMapParameters(bbox, width, height, overlayTypes.Contains(TileOverlayType.ProjectBoundary), adjustBoundingBox); var request = TileGenerationRequest.CreateTileGenerationRequest(filterUid, baseUid, topUid, cutFillDesignUid, volumeCalcType, geofences, alignmentPoints, customFilterBoundary, designFilterBoundary, alignmentFilterBoundary, designBoundary, dxfFiles, overlayTypes, width, height, mapType, mode, language, project, mapParameters, CustomHeaders, null, explicitFilters); request.Validate(); var byteResult = await WithServiceExceptionTryExecuteAsync(() => tileGenerator.GetMapData(request)); return(new FileStreamResult(new MemoryStream(byteResult), ContentTypeConstants.ImagePng)); }