All checks were successful
Build, Push and Run Container / build (push) Successful in 27s
71 lines
2.9 KiB
C#
71 lines
2.9 KiB
C#
using System.Diagnostics;
|
|
using Microsoft.Extensions.Options;
|
|
using NetTopologySuite.Features;
|
|
using NetTopologySuite.Geometries;
|
|
using NetTopologySuite.IO;
|
|
using SzakatsA.Result;
|
|
|
|
namespace ProofOfConcept.Services;
|
|
|
|
public class ZoneDeterminatorService
|
|
{
|
|
private readonly ILogger<ZoneDeterminatorService> logger;
|
|
private ZoneDeterminatorServiceConfiguration configuration;
|
|
|
|
private FeatureCollection parkingZones;
|
|
private bool initialized;
|
|
|
|
public ZoneDeterminatorService(ILogger<ZoneDeterminatorService> logger, IOptions<ZoneDeterminatorServiceConfiguration> options)
|
|
{
|
|
this.logger = logger;
|
|
this.configuration = options.Value;
|
|
|
|
this.parkingZones = new FeatureCollection();
|
|
this.initialized = false;
|
|
}
|
|
|
|
public async Task<Result<string>> DetermineZoneCodeAsync(double latitude, double longitude, CancellationToken cancellationToken = default(CancellationToken))
|
|
{
|
|
this.logger.LogTrace("Determinating parking zone code for coordinates: {Latitude}, {Longitude}...", latitude, longitude);
|
|
|
|
if (!this.initialized)
|
|
await InitializeAsync(cancellationToken);
|
|
|
|
Point point = new Point(longitude, latitude);
|
|
IFeature? zone = this.parkingZones.FirstOrDefault(f => f.Geometry.Contains(point));
|
|
|
|
if (zone is null)
|
|
return Result.Success(String.Empty);
|
|
else if (!zone.Attributes.Exists("zoneid"))
|
|
return Result.Fail(new MissingFieldException("Zone ID not found for parking zone"));
|
|
else if (zone.Attributes["zoneid"] is null)
|
|
return Result.Fail(new NullReferenceException("Zone ID null for parking zone"));
|
|
else if (zone.Attributes["zoneid"].ToString() is null)
|
|
return Result.Fail(new InvalidCastException($"Zone ID is of type {zone.Attributes["zoneID"].GetType().FullName}"));
|
|
else
|
|
return Result.Success(zone.Attributes["zoneid"].ToString()!);
|
|
}
|
|
|
|
public async Task InitializeAsync(CancellationToken cancellationToken = default(CancellationToken))
|
|
{
|
|
this.logger.LogTrace("Initializing...");
|
|
Stopwatch sw = Stopwatch.StartNew();
|
|
|
|
this.logger.LogTrace("Reading file...");
|
|
string geojson = await File.ReadAllTextAsync(this.configuration.ZoneFilePath, cancellationToken);
|
|
this.logger.LogTrace("File read in {Elapsed} ms", sw.ElapsedMilliseconds);
|
|
|
|
this.logger.LogTrace("Parsing geojson...");
|
|
GeoJsonReader reader = new GeoJsonReader();
|
|
this.parkingZones = reader.Read<FeatureCollection>(geojson);
|
|
this.logger.LogTrace("Geojson parsed in {Elapsed} ms: {FeatureCount} features", sw.ElapsedMilliseconds, this.parkingZones.Count);
|
|
|
|
this.initialized = true;
|
|
this.logger.LogInformation("Initialized");
|
|
}
|
|
}
|
|
|
|
public class ZoneDeterminatorServiceConfiguration
|
|
{
|
|
public string ZoneFilePath { get; set; } = "Resources/zones.geojson";
|
|
} |