From c354661a104041ad491d12b8a610e0adee0435e2 Mon Sep 17 00:00:00 2001 From: Oleksandr Bezdieniezhnykh Date: Sat, 25 Oct 2025 21:29:33 +0300 Subject: [PATCH] initial commit add get post requests structure - simple get --- .gitignore | 9 ++ SatelliteProvider.sln | 16 ++ SatelliteProvider/Program.cs | 140 ++++++++++++++++++ .../Properties/launchSettings.json | 41 +++++ SatelliteProvider/SatelliteProvider.csproj | 14 ++ SatelliteProvider/SatelliteProvider.http | 6 + .../appsettings.Development.json | 8 + SatelliteProvider/appsettings.json | 9 ++ global.json | 7 + 9 files changed, 250 insertions(+) create mode 100644 .gitignore create mode 100644 SatelliteProvider.sln create mode 100644 SatelliteProvider/Program.cs create mode 100644 SatelliteProvider/Properties/launchSettings.json create mode 100644 SatelliteProvider/SatelliteProvider.csproj create mode 100644 SatelliteProvider/SatelliteProvider.http create mode 100644 SatelliteProvider/appsettings.Development.json create mode 100644 SatelliteProvider/appsettings.json create mode 100644 global.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a187b8a --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.idea +bin +obj +.vs +*.DotSettings* +*.user +log* +Content/ +.env \ No newline at end of file diff --git a/SatelliteProvider.sln b/SatelliteProvider.sln new file mode 100644 index 0000000..e25f723 --- /dev/null +++ b/SatelliteProvider.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SatelliteProvider", "SatelliteProvider\SatelliteProvider.csproj", "{35C6FC8B-92D8-4D8D-BE36-D6B181715019}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {35C6FC8B-92D8-4D8D-BE36-D6B181715019}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35C6FC8B-92D8-4D8D-BE36-D6B181715019}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35C6FC8B-92D8-4D8D-BE36-D6B181715019}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35C6FC8B-92D8-4D8D-BE36-D6B181715019}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/SatelliteProvider/Program.cs b/SatelliteProvider/Program.cs new file mode 100644 index 0000000..5095f12 --- /dev/null +++ b/SatelliteProvider/Program.cs @@ -0,0 +1,140 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new OpenApiInfo { Title = "Satellite Provider API", Version = "v1" }); + + c.MapType(() => new OpenApiSchema + { + Type = "object", + Properties = new Dictionary + { + ["timestamp"] = new() { Type = "string", Format = "date-time", Description = "Image capture timestamp" }, + ["image"] = new() { Type = "string", Format = "binary", Description = "Image file to upload" }, + ["lat"] = new() { Type = "number", Format = "double", Description = "Latitude coordinate where image was captured" }, + ["lon"] = new() { Type = "number", Format = "double", Description = "Longitude coordinate where image was captured" }, + ["height"] = new() { Type = "number", Format = "double", Description = "Height/altitude in meters where image was captured" }, + ["focalLength"] = new() { Type = "number", Format = "double", Description = "Camera focal length in millimeters" }, + ["sensorWidth"] = new() { Type = "number", Format = "double", Description = "Camera sensor width in millimeters" }, + ["sensorHeight"] = new() { Type = "number", Format = "double", Description = "Camera sensor height in millimeters" } + }, + Required = new HashSet { "timestamp", "image", "lat", "lon", "height", "focalLength", "sensorWidth", "sensorHeight" } + }); + + c.OperationFilter(); +}); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.MapGet("/api/satellite/tiles/latlon", GetSatelliteTilesByLatLon) + .WithOpenApi(op => new(op) { Summary = "Get satellite tiles by latitude and longitude coordinates" }); + +app.MapGet("/api/satellite/tiles/mgrs", GetSatelliteTilesByMgrs) + .WithOpenApi(op => new(op) { Summary = "Get satellite tiles by MGRS coordinates" }); + +app.MapPost("/api/satellite/upload", UploadImage) + .Accepts("multipart/form-data") + .WithOpenApi(op => new(op) { Summary = "Upload image with metadata and save to /maps folder" }) + .DisableAntiforgery(); + +app.Run(); + +IResult GetSatelliteTilesByLatLon(double lat, double lon, double squareSideMeters) +{ + return Results.Ok(new GetSatelliteTilesResponse()); +} + +IResult GetSatelliteTilesByMgrs(string mgrs, double squareSideMeters) +{ + return Results.Ok(new GetSatelliteTilesResponse()); +} + +IResult UploadImage([FromForm] UploadImageRequest request) +{ + return Results.Ok(new SaveResult { Success = false }); +} + +public record GetSatelliteTilesResponse +{ + public List Tiles { get; set; } = new(); +} + +public record SatelliteTile +{ + public string TileId { get; set; } = string.Empty; + public byte[] ImageData { get; set; } = Array.Empty(); + public double Lat { get; set; } + public double Lon { get; set; } + public int ZoomLevel { get; set; } +} + +public record UploadImageRequest +{ + [Required] + public DateTime Timestamp { get; set; } + + [Required] + public IFormFile? Image { get; set; } + + [Required] + public double Lat { get; set; } + + [Required] + public double Lon { get; set; } + + [Required] + public double Height { get; set; } + + [Required] + public double FocalLength { get; set; } + + [Required] + public double SensorWidth { get; set; } + + [Required] + public double SensorHeight { get; set; } +} + +public record SaveResult +{ + public bool Success { get; set; } + public string? Exception { get; set; } +} + +public class ParameterDescriptionFilter : IOperationFilter +{ + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (operation.Parameters == null) return; + + var parameterDescriptions = new Dictionary + { + ["lat"] = "Latitude coordinate where image was captured", + ["lon"] = "Longitude coordinate where image was captured", + ["mgrs"] = "MGRS coordinate string", + ["squareSideMeters"] = "Square side size in meters" + }; + + foreach (var parameter in operation.Parameters) + { + if (parameterDescriptions.TryGetValue(parameter.Name, out var description)) + { + parameter.Description = description; + } + } + } +} diff --git a/SatelliteProvider/Properties/launchSettings.json b/SatelliteProvider/Properties/launchSettings.json new file mode 100644 index 0000000..6a4cbbf --- /dev/null +++ b/SatelliteProvider/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:34324", + "sslPort": 44311 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5162", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7112;http://localhost:5162", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SatelliteProvider/SatelliteProvider.csproj b/SatelliteProvider/SatelliteProvider.csproj new file mode 100644 index 0000000..e006786 --- /dev/null +++ b/SatelliteProvider/SatelliteProvider.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/SatelliteProvider/SatelliteProvider.http b/SatelliteProvider/SatelliteProvider.http new file mode 100644 index 0000000..7d778eb --- /dev/null +++ b/SatelliteProvider/SatelliteProvider.http @@ -0,0 +1,6 @@ +@SatelliteProvider_HostAddress = http://localhost:5063 + +GET {{SatelliteProvider_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/SatelliteProvider/appsettings.Development.json b/SatelliteProvider/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/SatelliteProvider/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/SatelliteProvider/appsettings.json b/SatelliteProvider/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/SatelliteProvider/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/global.json b/global.json new file mode 100644 index 0000000..2ddda36 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMinor", + "allowPrerelease": false + } +} \ No newline at end of file