All checks were successful
Build, Push and Run Container / build (push) Successful in 25s
Updates the default zone file path to point to the parking zones file. This change ensures the application uses the correct GeoJSON file for determining parking zones.
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/parking_zones.geojson";
|
|
} |