public void ValidOutputNoStitch()
        {
            var options = ValidOptions();

            using var state = new FileState();

            options.SourcePath = Path.Combine(state.CreateTempDirectory(), "*.jpg");
            options.OutputPath = state.CreateTempDirectory();

            VerifyNoFailure(options);
        }
        public void ValidOutputStitchAndBatch()
        {
            var options = ValidOptions();

            using var state         = new FileState();
            options.Timestamp       = DateTime.Now;
            options.IntervalMinutes = 30;

            options.SourcePath = Path.Combine(state.CreateTempDirectory(), "*.jpg");
            options.OutputPath = state.CreateTempDirectory();

            VerifyNoFailure(options);
        }
        public void OutputIsFileIfLongitudeSpecified()
        {
            var options = ValidOptions();

            options.Longitude = 147;
            options.Timestamp = DateTime.Now;

            using var state = new FileState();

            options.SourcePath = Path.Combine(state.CreateTempDirectory(), "*.jpg");
            options.OutputPath = Path.Combine(state.CreateTempDirectory(), "out.jpg");

            VerifyNoFailure(options);
        }
示例#4
0
        public async Task EquirectangularMultiple()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();

            var returnCode = await Bootstrapper.Main(
                "reproject",
                "-s", rootDirectory,
                "-vo", outputDirectory);

            VerifySuccessfulExecution(returnCode);

            Directory.Exists(outputDirectory).Should().BeTrue("output directory should have been created");
            Directory.GetFiles(outputDirectory).Should().HaveCount(8);

            foreach (var outputFile in Directory.GetFiles(outputDirectory))
            {
                var outputImage = await Image.LoadAsync(outputFile);

                outputImage.Width.Should().BeGreaterThan(0);
                outputImage.Height.Should().BeGreaterThan(0);
            }
        }
        public void OutputNotDirectoryIfLongitudeSpecified()
        {
            var options = ValidOptions();

            options.Longitude = 147;

            using var state = new FileState();

            options.SourcePath = Path.Combine(state.CreateTempDirectory(), "*.jpg");
            options.OutputPath = state.CreateTempDirectory();

            VerifyFailure(
                options,
                nameof(GeostationaryOptions.OutputPath),
                "If multiple source files are specified with a target latitude reprojection, the output cannot be a directory.");
        }
示例#6
0
        public async Task GeostationaryMultiple()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();

            var returnCode = await Bootstrapper.Main(
                "-s", rootDirectory,
                "-o", outputDirectory,
                "-q");

            VerifySuccessfulExecution(returnCode);

            Directory.Exists(outputDirectory).Should().BeTrue("output directory should have been created");
            Directory.GetFiles(outputDirectory).Should().HaveCount(8);

            foreach (var outputFile in Directory.GetFiles(outputDirectory))
            {
                var outputImage = await Image.LoadAsync(outputFile);

                outputImage.Width.Should().Be(Constants.Satellite.ImageSize.FourKm);
                outputImage.Height.Should().Be(Constants.Satellite.ImageSize.FourKm);
            }
        }
示例#7
0
        public async Task Quiet()
        {
            using var fileState = new FileState();
            const string sourceFile = "GOES17_FD_CH13_20200830T033031Z.jpg";

            var rootDirectory = await CreateSingleSimpleImageAsync(fileState, sourceFile);

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var writer = new StringWriter();

            Console.SetOut(writer);

            var returnCode = await Bootstrapper.Main(
                "reproject",
                "-s", Path.Combine(rootDirectory, sourceFile),
                "-o", outputFile,
                "-aq");

            VerifySuccessfulExecution(returnCode);

            File.Exists(outputFile).Should().BeTrue("output file should have been created");
            var outputImage = await Image.LoadAsync(outputFile);

            outputImage.Width.Should().Be(1918);
            outputImage.Height.Should().Be(1916);

            writer.ToString().Should().BeEmpty("no output should be written in quiet mode");
        }
示例#8
0
        public async Task EquirectangularTimestampStitch()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();

            var returnCode = await Bootstrapper.Main(
                "reproject",
                "-s", rootDirectory,
                "-o", outputDirectory,
                "-a",
                "-I", "60",
                "-d", "60",
                "-v",
                "-T", "2020-08-30T03:00:20",
                "-e", "2020-08-31T03:00:20"
                );

            VerifySuccessfulExecution(returnCode);

            Directory.Exists(outputDirectory).Should().BeTrue("output directory should have been created");
            var outputFiles = Directory.GetFiles(outputDirectory);

            outputFiles.Length.Should().Be(3);
        }
示例#9
0
        public void LocateImages()
        {
            RenderOptions.EquirectangularRender = new EquirectangularRenderOptions(false, true, null);

            var targetTimestamp = new DateTime(2020, 08, 30, 03, 30, 00, DateTimeKind.Utc);

            RenderOptions.Tolerance = TimeSpan.FromMinutes(30);

            using var state = new FileState();
            var rootDirectory = state.CreateTempDirectory();

            RenderOptions.SourcePath = rootDirectory;

            // Create sample files
            state.CreateFile(rootDirectory, "GOES16_FD_CH13_20200830T035020Z.jpg");
            state.CreateFile(rootDirectory, "GOES16_FD_CH13_20200830T033020Z.jpg");
            state.CreateFile(rootDirectory, "GOES16_FD_CH13_20200930T033020Z.jpg");
            state.CreateFile(rootDirectory, "GOES16_FD_CH13_bogus.jpg");

            var directory = Directory.CreateDirectory(Path.Combine(rootDirectory, "GOES17"));

            state.CreateFile(directory.FullName, "GOES17_FD_CH13_20200830T033031Z.jpg");

            directory = Directory.CreateDirectory(Path.Combine(rootDirectory, "Himawari-8"));
            state.CreateFile(directory.FullName, "Himawari8_FD_IR_20200830T035100Z.jpg");
            state.CreateFile(directory.FullName, "bogus.jpg");

            // Run method under test
            var sourceFiles   = FileService.GetSourceFiles();
            var registrations = FileService.ToRegistrations(sourceFiles);

            var matchedFiles = Matcher.FilterMatchingRegistrations(registrations, targetTimestamp).Select(r => Path.GetFileName(r.Path));

            matchedFiles.Should().BeEquivalentTo("GOES16_FD_CH13_20200830T033020Z.jpg", "GOES17_FD_CH13_20200830T033031Z.jpg", "Himawari8_FD_IR_20200830T035100Z.jpg");
        }
示例#10
0
        public string[] GetSourceFilesBatch(string sourcePath)
        {
            using var state = new FileState();

            // Prepare source files
            var imageFolder = state.CreateTempDirectory();
            var outputPath  = Path.Combine(imageFolder, "output", "output.jpg");

            Directory.CreateDirectory(Path.Combine(imageFolder, "source", "first", "2020"));
            Directory.CreateDirectory(Path.Combine(imageFolder, "source", "second"));

            var files = new[]
            {
                Path.Combine(imageFolder, "source", "first", "2020", "firstImage.jpg"),
                Path.Combine(imageFolder, "source", "first", "2020", "secondImage.png"),
                Path.Combine(imageFolder, "source", "second", "thirdImage.png")
            };

            files.ForEach(path => File.WriteAllText(path, "Isn't this fun?"));

            var options = new CommandLineOptions
            {
                SourcePath = Path.Combine(imageFolder, sourcePath),
                OutputPath = outputPath
            };

            // Run method under test
            return(FileService
                   .GetSourceFiles(options)
                   .OrderBy(f => f)
                   .Select(file => Path.GetRelativePath(imageFolder, file))
                   .ToArray());
        }
示例#11
0
        private async Task <string> CreateSingleSimpleImageAsync(FileState state, string filename)
        {
            var rootDirectory = state.CreateTempDirectory();

            // Create sample files
            await CreateImage(Path.Combine(rootDirectory, filename));

            return(rootDirectory);
        }
示例#12
0
        public void MultipleSourcesIfDirectory()
        {
            using var state = new FileState();
            var directory = state.CreateTempDirectory();

            var options = EquirectangularOptions();

            options.SourcePath = directory;

            options.MultipleSources.Should().BeTrue();
        }
示例#13
0
        public void VerifyBatchFlagDirectory()
        {
            using var state = new FileState();
            var directory = state.CreateTempDirectory();

            var options = new CommandLineOptions
            {
                SourcePath = directory
            };

            options.IsBatch.Should().BeTrue("batch mode should be enabled if the source is a directory");
        }
示例#14
0
        public async Task MissingSource()
        {
            using var fileState = new FileState();

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var returnCode = await Bootstrapper.Main(
                "reproject",
                "-vo", outputFile);

            VerifyFailedExecution(returnCode);
        }
        public void ValidOutputStitchNoBatch()
        {
            var options = ValidOptions();

            using var state = new FileState();
            var outputFile = state.CreateFile("foo.jpg");

            options.Timestamp = DateTime.Now;

            options.SourcePath = Path.Combine(state.CreateTempDirectory(), "*.jpg");
            options.OutputPath = outputFile;

            VerifyNoFailure(options);
        }
        public void OutputNotFileIfMultipleSource()
        {
            var options = ValidOptions();

            using var state = new FileState();
            var outputFile = state.CreateFile("foo.jpg");

            options.SourcePath = Path.Combine(state.CreateTempDirectory(), "*.jpg");
            options.OutputPath = outputFile;

            VerifyFailure(
                options,
                nameof(GeostationaryOptions.OutputPath),
                "If multiple source files are specified, the output must be a directory.");
        }
示例#17
0
        public void GetSourceFiles()
        {
            using var state = new FileState();

            var imageFolder = state.CreateTempDirectory();
            var sourceFile  = Path.Combine(imageFolder, "source.jpg");
            var outputPath  = Path.Combine(imageFolder, "output", "output.jpg");

            File.WriteAllText(sourceFile, "Hey!");

            RenderOptions.SourcePath = sourceFile;
            RenderOptions.OutputPath = outputPath;

            // Run method under test
            FileService.GetSourceFiles().Should().BeEquivalentTo(sourceFile);
        }
示例#18
0
        public void VerifyNoBatchFlagFile()
        {
            using var state = new FileState();
            var directory  = state.CreateTempDirectory();
            var outputPath = Path.Combine(directory, "source.jpg");

            File.WriteAllText(outputPath, "Hello!");

            // Sanity check
            File.Exists(outputPath).Should().BeTrue();

            var options = new CommandLineOptions
            {
                SourcePath = outputPath
            };

            options.IsBatch.Should().BeFalse("batch mode should not be enabled for a single file");
        }
示例#19
0
        public bool VerifyImageFormat(string filename)
        {
            using var state = new FileState();

            // Prepare source files
            var imageFolder = state.CreateTempDirectory();
            var sourcePath  = Path.Combine(imageFolder, "source.jpg");

            File.WriteAllText(sourcePath, "Hey!");

            var options = new CommandLineOptions
            {
                OutputPath = filename,
                SourcePath = sourcePath
            };

            // Run method under test
            return(OptionValidator.Validate(options));
        }
示例#20
0
        public async Task GeostationaryReprojectedTooFewSatellites()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var returnCode = await Bootstrapper.Main(
                "-s", rootDirectory,
                "-o", outputFile,
                "-l", "174",
                "-m", "10",
                "-T 2020-08-30T03:50:20",
                "-q");

            VerifySuccessfulExecution(returnCode);

            File.Exists(outputFile).Should().BeFalse("fewer than 10 satellites are present");
        }
示例#21
0
        public void OutputFolderNotCreatedForSingle()
        {
            using var state = new FileState();
            var imageFolder = state.CreateTempDirectory();
            var outputPath  = Path.Combine(imageFolder, "output", "output.jpg");

            var options = new CommandLineOptions
            {
                SourcePath = Path.Combine(imageFolder, "images/source.jpg"),
                OutputPath = outputPath
            };

            // Sanity check
            options.IsBatch.Should().BeFalse();

            // Run method under test
            FileService.PrepareOutput(options);
            Directory.Exists(outputPath).Should().BeFalse("no directory should be created for non-batch mode");
            File.Exists(outputPath).Should().BeFalse();
        }
示例#22
0
        public void OutputFolderCreatedIfBatch()
        {
            using var state = new FileState();
            var imageFolder = state.CreateTempDirectory();
            var outputPath  = Path.Combine(imageFolder, "output");

            var options = new CommandLineOptions
            {
                SourcePath = Path.Combine(imageFolder, "images/*.*"),
                OutputPath = outputPath
            };

            // Sanity check
            options.IsBatch.Should().BeTrue();
            Directory.Exists(outputPath).Should().BeFalse();

            // Run method under test
            FileService.PrepareOutput(options);
            Directory.Exists(outputPath).Should().BeTrue("output directory should be created for batch processing");
        }
示例#23
0
        public async Task GeostationarySingle()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var returnCode = await Bootstrapper.Main(
                "-s", Path.Combine(rootDirectory, "GOES16_FD_CH13_20200830T035020Z.jpg"),
                "-o", outputFile,
                "-q");

            VerifySuccessfulExecution(returnCode);

            File.Exists(outputFile).Should().BeTrue("output file should have been created");
            var outputImage = await Image.LoadAsync(outputFile);

            outputImage.Width.Should().Be(Constants.Satellite.ImageSize.FourKm);
            outputImage.Height.Should().Be(Constants.Satellite.ImageSize.FourKm);
        }
        private async Task CreateSampleImagesAsync(FileState state)
        {
            var rootDirectory = state.CreateTempDirectory();

            RenderOptions.EquirectangularRender = new EquirectangularRenderOptions(true, true, null);
            RenderOptions.SourcePath            = rootDirectory;

            // Create sample files
            await CreateImage(Path.Combine(rootDirectory, "GOES16_FD_CH13_20200830T035020Z.jpg"));
            await CreateImage(Path.Combine(rootDirectory, "GOES16_FD_CH13_20200830T033020Z.jpg"));

            var directory = Directory.CreateDirectory(Path.Combine(rootDirectory, "GOES17"));

            await CreateImage(Path.Combine(directory.FullName, "GOES17_FD_CH13_20200830T033031Z.jpg"));

            directory = Directory.CreateDirectory(Path.Combine(rootDirectory, "Himawari-8"));
            await CreateImage(Path.Combine(directory.FullName, "Himawari8_FD_IR_20200830T035100Z.jpg"));
            await CreateImage(Path.Combine(directory.FullName, "IMG_FD_023_IR105_20200830_035006.jpg"));

            await CreateImage(Path.Combine(directory.FullName, "bogus.jpg"));
        }
示例#25
0
        public async Task EquirectangularMultipleStitch()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var returnCode = await Bootstrapper.Main(
                "reproject",
                "-s", rootDirectory,
                "-o", outputFile,
                "-T", "2020-08-30T03:50:20");

            VerifySuccessfulExecution(returnCode);

            File.Exists(outputFile).Should().BeTrue("output file should have been created");
            var outputImage = await Image.LoadAsync(outputFile);

            outputImage.Width.Should().Be(4794);
            outputImage.Height.Should().Be(2450);
        }
示例#26
0
        private async Task <string> CreateSampleImagesAsync(FileState state)
        {
            var rootDirectory = state.CreateTempDirectory();

            // Create sample files
            await CreateImage(Path.Combine(rootDirectory, "GOES16_FD_CH13_20200830T035020Z.jpg"));
            await CreateImage(Path.Combine(rootDirectory, "GOES16_FD_CH13_20200830T033020Z.jpg"));
            await CreateImage(Path.Combine(rootDirectory, "GOES16_FD_CH13_20200830T034020Z.jpg"));

            var directory = Directory.CreateDirectory(Path.Combine(rootDirectory, "GOES17"));

            await CreateImage(Path.Combine(directory.FullName, "GOES17_FD_CH13_20200830T033031Z.jpg"));
            await CreateImage(Path.Combine(directory.FullName, "GOES17_FD_CH13_20200830T044031Z.jpg"));

            directory = Directory.CreateDirectory(Path.Combine(rootDirectory, "Himawari-8"));
            await CreateImage(Path.Combine(directory.FullName, "Himawari8_FD_IR_20200830T034100Z.jpg"));
            await CreateImage(Path.Combine(directory.FullName, "Himawari8_FD_IR_20200830T045100Z.jpg"));
            await CreateImage(Path.Combine(directory.FullName, "IMG_FD_023_IR105_20200830_035006.jpg"));
            await CreateImage(Path.Combine(directory.FullName, "IMG_FD.jpg"));
            await CreateImage(Path.Combine(directory.FullName, "bogus.jpg"));

            return(rootDirectory);
        }
示例#27
0
        public async Task EquirectangularSingle()
        {
            using var fileState = new FileState();
            const string sourceFile = "GOES17_FD_CH13_20200830T033031Z.jpg";

            var rootDirectory = await CreateSingleSimpleImageAsync(fileState, sourceFile);

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var returnCode = await Bootstrapper.Main(
                "reproject",
                "-s", Path.Combine(rootDirectory, sourceFile),
                "-vo", outputFile);

            VerifySuccessfulExecution(returnCode);

            File.Exists(outputFile).Should().BeTrue("output file should have been created");
            var outputImage = await Image.LoadAsync(outputFile);

            outputImage.Width.Should().Be(2449);
            outputImage.Height.Should().Be(2450);
        }
示例#28
0
        public async Task GeostationaryReprojectedMinSatellites()
        {
            using var fileState = new FileState();
            var rootDirectory = await CreateSampleImagesAsync(fileState);

            var outputDirectory = fileState.CreateTempDirectory();
            var outputFile      = Path.Combine(outputDirectory, "out.jpg");

            var returnCode = await Bootstrapper.Main(
                "-s", rootDirectory,
                "-o", outputFile,
                "-l", "174",
                "-m", "3",
                "-T 2020-08-30T03:50:20",
                "-q");

            VerifySuccessfulExecution(returnCode);

            File.Exists(outputFile).Should().BeTrue("output file should have been created");
            var outputImage = await Image.LoadAsync(outputFile);

            outputImage.Width.Should().Be(Constants.Satellite.ImageSize.FourKm);
            outputImage.Height.Should().Be(Constants.Satellite.ImageSize.FourKm);
        }