Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilization of the main scenarios #81

Merged
merged 22 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using Inc.TeamAssistant.Appraiser.Domain;
using Inc.TeamAssistant.Primitives.FeatureProperties;
using Inc.TeamAssistant.Primitives.Languages;

namespace Inc.TeamAssistant.Appraiser.Application.Services;

internal sealed class AppraiserSettingSectionProvider : ISettingSectionProvider
{
private readonly IReadOnlyDictionary<StoryType, string> _storyType = new Dictionary<StoryType, string>
private readonly IReadOnlyDictionary<StoryType, MessageId> _storyType = new Dictionary<StoryType, MessageId>
{
[StoryType.Fibonacci] = "Constructor_FormSectionSetSettingsFibonacciDescription",
[StoryType.TShirt] = "Constructor_FormSectionSetSettingsTShirtDescription",
[StoryType.PowerOfTwo] = "Constructor_FormSectionSetSettingsPowerOfTwoDescription"
[StoryType.Fibonacci] = new("Constructor_FormSectionSetSettingsFibonacciDescription"),
[StoryType.TShirt] = new("Constructor_FormSectionSetSettingsTShirtDescription"),
[StoryType.PowerOfTwo] = new("Constructor_FormSectionSetSettingsPowerOfTwoDescription")
};

public string FeatureName => "Appraiser";
Expand All @@ -19,12 +20,12 @@ public IReadOnlyCollection<SettingSection> GetSections()
return
[
new SettingSection(
"Constructor_FormSectionSetSettingsAppraiserHeader",
"Constructor_FormSectionSetSettingsAppraiserHelp",
new("Constructor_FormSectionSetSettingsAppraiserHeader"),
new("Constructor_FormSectionSetSettingsAppraiserHelp"),
[
new(
AppraiserProperties.StoryTypeKey,
"Constructor_FormSectionSetSettingsStoryTypeFieldLabel",
new("Constructor_FormSectionSetSettingsStoryTypeFieldLabel"),
GetValuesForStoryType().ToArray())
])
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ public Estimation GetValue(int value)
if (Estimations.TryGetValue(value, out var estimation))
return estimation;

throw new ArgumentOutOfRangeException(
nameof(value),
value,
$"Value is not valid for {nameof(FibonacciEstimationStrategy)}.");
throw new ArgumentOutOfRangeException(nameof(value), value, "State out of range.");
}

public int GetWeight(Story story)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ public Estimation GetValue(int value)
if (Estimations.TryGetValue(value, out var estimation))
return estimation;

throw new ArgumentOutOfRangeException(
nameof(value),
value,
$"Value is not valid for {nameof(FibonacciEstimationStrategy)}.");
throw new ArgumentOutOfRangeException(nameof(value), value, "State out of range.");
}

public int GetWeight(Story story)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ public Estimation GetValue(int value)
if (Estimations.TryGetValue(value, out var estimation))
return estimation;

throw new ArgumentOutOfRangeException(
nameof(value),
value,
$"Value is not valid for {nameof(TShirtEstimationStrategy)}.");
throw new ArgumentOutOfRangeException(nameof(value), value, "State out of range.");
}

public int GetWeight(Story story)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public static IEstimationStrategy Create(StoryType storyType)
{
return Strategies.TryGetValue(storyType, out var strategy)
? strategy
: throw new ArgumentOutOfRangeException(nameof(storyType),
storyType,
$"StoryType is not valid for {nameof(EstimationStrategyFactory)}.");
: throw new ArgumentOutOfRangeException(nameof(storyType), storyType, "State out of range.");
}
}
54 changes: 0 additions & 54 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeoJsonParser.cs

This file was deleted.

31 changes: 31 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeoParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Text.Json;
using Inc.TeamAssistant.CheckIn.Application.Contracts;
using Inc.TeamAssistant.CheckIn.Geo.Models;

namespace Inc.TeamAssistant.CheckIn.Geo;

internal sealed class GeoParser
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
{
PropertyNameCaseInsensitive = true,
TypeInfoResolver = new GeometryResolver()
};

public IEnumerable<Region> Parse(IEnumerable<string> json)
{
ArgumentNullException.ThrowIfNull(json);

foreach (var line in json)
{
var item = JsonSerializer.Deserialize<GeoItem>(line, JsonSerializerOptions);

if (item is not null)
yield return new Region(
item.Properties.Name,
item.Id,
item.Properties.Type == "country" ? RegionType.Country : RegionType.Ocean,
item.Geometry.GetCoordinates().ToArray());
}
}
}
64 changes: 24 additions & 40 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeoService.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
using GeoTimeZone;
using Inc.TeamAssistant.CheckIn.Application.Contracts;
using Inc.TeamAssistant.CheckIn.Geo.Models;

namespace Inc.TeamAssistant.CheckIn.Geo;

internal sealed class GeoService : IGeoService
{
private readonly GeoJsonParser _geoJsonParser;
private readonly Region[] _regions;

public GeoService(RegionLoader regionLoader, GeoJsonParser geoJsonParser)
public GeoService(RegionLoader regionLoader, GeoParser geoParser)
{
_geoJsonParser = geoJsonParser;
_regions = ParseInput(regionLoader.LoadFile()).ToArray();
ArgumentNullException.ThrowIfNull(regionLoader);
ArgumentNullException.ThrowIfNull(geoParser);

_regions = geoParser.Parse(regionLoader.LoadFile()).ToArray();
}

public Region? FindCountry(double lat, double lng, params RegionType[] types)
{
var coords = new[] { (float)lng, (float)lat };
var subset = types.Any()
ArgumentNullException.ThrowIfNull(types);

var point = new Point((float)lng, (float)lat);
var items = types.Any()
? _regions.Where(x => types.Any(y => y == x.Type))
: _regions;

foreach (var country in subset)
{
if (InPolygon(coords, country.Polygon))
{
return country;
}
}
foreach (var item in items)
if (InPolygon(point, item.Polygon))
return item;

return null;
}
Expand All @@ -38,37 +38,21 @@ public TimeZoneInfo GetTimeZone(double lat, double lng)
return TimeZoneInfo.FindSystemTimeZoneById(timeZoneId.Result);
}

private bool InPolygon(float[] point, float[][] polygon)
private bool InPolygon(Point point, float[][] polygon)
{
var polygonLength = polygon.Length;
var c = false;
ArgumentNullException.ThrowIfNull(point);
ArgumentNullException.ThrowIfNull(polygon);

var result = false;
var i = 0;
var j = 0;
for (i = 0, j = polygonLength - 1; i < polygonLength; j = i++)
{
if (polygon[i][1] > point[1] != (polygon[j][1] > point[1]) &&
point[0] < (polygon[j][0] - polygon[i][0]) * (point[1] - polygon[i][1]) /

for (i = 0, j = polygon.Length - 1; i < polygon.Length; j = i++)
if (polygon[i][1] > point.Lat != polygon[j][1] > point.Lat &&
point.Lng < (polygon[j][0] - polygon[i][0]) * (point.Lat - polygon[i][1]) /
(polygon[j][1] - polygon[i][1]) + polygon[i][0])
{
c = !c;
}
}
result = !result;

return c;
}

private IEnumerable<Region> ParseInput(IEnumerable<string> geojson)
{
foreach (var line in geojson)
{
foreach (var polygon in _geoJsonParser.Convert(line))
{
yield return new Region(
polygon.Properties["name"],
polygon.Id,
polygon.Properties["type"] == "country" ? RegionType.Country : RegionType.Ocean,
polygon.Geometry);
}
}
return result;
}
}
34 changes: 34 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/GeometryResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Inc.TeamAssistant.CheckIn.Geo.Models;

namespace Inc.TeamAssistant.CheckIn.Geo;

internal sealed class GeometryResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
ArgumentNullException.ThrowIfNull(type);
ArgumentNullException.ThrowIfNull(options);

var jsonTypeInfo = base.GetTypeInfo(type, options);

if (jsonTypeInfo.Type == typeof(IGeometry))
{
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
{
TypeDiscriminatorPropertyName = "type",
IgnoreUnrecognizedTypeDiscriminators = false,
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization,
DerivedTypes =
{
new JsonDerivedType(typeof(PolygonGeometry), "Polygon"),
new JsonDerivedType(typeof(MultiPolygonGeometry), "MultiPolygon"),
}
};
}

return jsonTypeInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<ProjectReference Include="..\Inc.TeamAssistant.CheckIn.Application\Inc.TeamAssistant.CheckIn.Application.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="GeoTimeZone" Version="5.3.0" />
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/GeoItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record GeoItem(
string Id,
GeoProperties Properties,
IGeometry Geometry);
3 changes: 3 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/GeoProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record GeoProperties(string Type, string Name);
6 changes: 6 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/IGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal interface IGeometry
{
IEnumerable<float[]> GetCoordinates();
}
12 changes: 12 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/MultiPolygonGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record MultiPolygonGeometry(float[][][][] Coordinates)
: IGeometry
{
public IEnumerable<float[]> GetCoordinates()
{
foreach (var coordinate in Coordinates)
foreach (var item in coordinate[0])
yield return [item[0], item[1]];
}
}
3 changes: 3 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/Point.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record Point(float Lng, float Lat);
11 changes: 11 additions & 0 deletions src/Inc.TeamAssistant.CheckIn.Geo/Models/PolygonGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Inc.TeamAssistant.CheckIn.Geo.Models;

internal sealed record PolygonGeometry(float[][][] Coordinates)
: IGeometry
{
public IEnumerable<float[]> GetCoordinates()
{
foreach (var item in Coordinates[0])
yield return [item[0], item[1]];
}
}
8 changes: 0 additions & 8 deletions src/Inc.TeamAssistant.CheckIn.Geo/ParsedGeoJson.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static IServiceCollection AddCheckInGeo(this IServiceCollection services,

services
.AddSingleton(sp => ActivatorUtilities.CreateInstance<RegionLoader>(sp, webRootPath))
.AddSingleton<GeoJsonParser>()
.AddSingleton<GeoParser>()
.AddSingleton<IGeoService, GeoService>();

return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ public static IReadOnlyCollection<WidgetDto> Convert(
ArgumentNullException.ThrowIfNull(features);

return settings.Widgets
.Select(w => new WidgetDto(w.Type, w.Position, CanEnabled(w), w.IsEnabled))
.Select(w => new WidgetDto(
w.Type,
w.Feature,
w.Position,
CanEnabled(w), w.IsEnabled))
.ToArray();

bool CanEnabled(DashboardWidget widget) =>
Expand Down
Loading