Skip to content

Commit 600da68

Browse files
author
Tule Splestule
committed
Přidána podpora TimeLimitExceeded a vylepšený rendering
Přidána vlastnost TimeLimitExceeded do TrailStats a její zpracování v logice i výstupech. Doplněny lokalizované řetězce pro stav časového limitu. Vylepšeno vykreslování trasy psa: po překročení limitu je trasa šedá, waypointy mají lepší logiku barev a popisků. Změněny barvy některých typů tras. Odstraněny nepoužívané lokalizace. Přidán volitelný fontScale do PngRendereru a upraven výpočet velikosti písma. Refaktoring a drobné úpravy pro lepší čitelnost.
1 parent f37df98 commit 600da68

15 files changed

Lines changed: 99 additions & 167 deletions

K9TrailsAnalyzer/GpxManager.vb

Lines changed: 15 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -776,103 +776,6 @@ Public Class GPXRecord
776776
Private _First_Contact As TrackGeoPoint = Nothing
777777
Private _LastWithinTimeLimit As TrackGeoPoint = Nothing
778778

779-
780-
'Public ReadOnly Property WptNodes As TrackAsTrkPts
781-
' Get
782-
' If _wptNodes IsNot Nothing Then Return _wptNodes
783-
' If Me.Reader Is Nothing Then
784-
' Throw New InvalidOperationException("Reader nebyl nastaven.")
785-
' End If
786-
787-
788-
' ' --- TADY PŘIDÁME VIRTUÁLNÍ START ---
789-
' If _First_Contact IsNot Nothing Then
790-
' Dim wptNodeList As XmlNodeList = Me.Reader.SelectNodes("wpt") 'když není žádný, vrátí prázdný list
791-
792-
' Dim combinedNodes As List(Of XmlNode) = wptNodeList.Cast(Of XmlNode)().ToList()
793-
' Dim i As Integer
794-
' For i = combinedNodes.Count - 1 To 0 Step -1 'projdeme list pozpátku, protože budeme odstraňovat uzly
795-
' ' Najdi uzel <name> uvnitř <wpt> s použitím namespace
796-
' Dim nameNode As XmlNode = TrackConverter.SelectSingleChildNode("name", combinedNodes(i))
797-
' If nameNode IsNot Nothing AndAlso nameNode.InnerText = "First Contact" Then
798-
' ' vymaže dříve definovaný first contact
799-
' combinedNodes.Remove(combinedNodes(i))
800-
' End If
801-
' Next
802-
803-
804-
' ' Vytvoříme uzel
805-
' Dim startNode As XmlElement = Me.Reader.CreateElement("wpt")
806-
' startNode.SetAttribute("lat", _First_Contact.Location.Lat.ToString(System.Globalization.CultureInfo.InvariantCulture))
807-
' startNode.SetAttribute("lon", _First_Contact.Location.Lon.ToString(System.Globalization.CultureInfo.InvariantCulture))
808-
809-
' ' Přidáme čas, aby fungovalo řazení
810-
' ' Nejdříve převedeme na UniversalTime a pak teprve formátujeme
811-
' TrackConverter.CreateAndAddElement(startNode, "time", _First_Contact.Time.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"), False)
812-
' TrackConverter.CreateAndAddElement(startNode, "name", "First Contact", False) ' Identifikátor
813-
814-
' combinedNodes.Add(startNode)
815-
816-
' ' 1. Převedeme XmlNodeList na IEnumerable(Of XmlNode) pomocí .Cast(Of XmlNode)
817-
' ' 2. Seřadíme uzly pomocí .OrderBy()
818-
' ' Seřazení (teď už i s tím naším startem)
819-
' Dim sortedWptNodeList As List(Of XmlNode) = combinedNodes.
820-
' OrderBy(Function(node)
821-
' Dim timenode As XmlNode = TrackConverter.SelectSingleChildNode("time", node)
822-
' Return If(timenode Is Nothing, DateTime.MinValue, DateTime.Parse(timenode.InnerText))
823-
' End Function).ToList()
824-
' Dim parentNode As XmlNode
825-
' If wptNodeList.Count > 0 Then
826-
' parentNode = wptNodeList(0)?.ParentNode
827-
' For Each wptNode As XmlNode In wptNodeList
828-
' parentNode.RemoveChild(wptNode) 'odstraní uzel z původního umístění
829-
' Next
830-
' End If
831-
' ' 4. Přidání Seřazených Uzlů Zpět
832-
' ' Přidáme seřazené uzly na konec rodičovského uzlu v novém pořadí.
833-
' i = 1
834-
' ' Dim newName As String = My.Resources.Resource1.article
835-
' ' Pokud je to náš START, pojmenujeme ho
836-
' For Each wptNode In sortedWptNodeList
837-
' ' Najdi uzel <name> uvnitř <wpt> s použitím namespace
838-
' Dim nameNode As XmlNode = TrackConverter.SelectSingleChildNode("name", wptNode)
839-
' If nameNode IsNot Nothing AndAlso nameNode.InnerText = "First Contact" Then
840-
' ' Pokud je to místo kde se pes přiblíží na 5 m k trase, pojmenujeme ho "First Contact"
841-
' nameNode.InnerText = "First Contact"
842-
' Else
843-
844-
' Dim newNamei As String = $"{i}"
845-
' i += 1
846-
847-
' If nameNode IsNot Nothing Then
848-
' ' Přepiš hodnotu <name> na newname
849-
' nameNode.InnerText = $"{newNamei}"
850-
' Else
851-
' TrackConverter.CreateAndAddElement(wptNode, "name", newNamei, False)
852-
' End If
853-
' End If
854-
' If wptNode.ParentNode Is Nothing Then
855-
' ' Toto je ten náš nový uzel - vložíme ho taky, aby byl vidět v mapě/UI
856-
' Me.Tracks(0).TrkNode.ParentNode.InsertBefore(wptNode, Me.Tracks(0).TrkNode)
857-
' Else
858-
' parentNode.InsertBefore(wptNode, Me.Tracks(0).TrkNode)
859-
' End If
860-
' ' ... (konec tvého cyklu For Each wptNode In sortedWptNodeList)
861-
' Next
862-
' End If
863-
' ' TADY JE TO KOUZLO:
864-
' ' Protože jsi všechny uzly (včetně "First Contact") vložil do dokumentu,
865-
' ' prostě se znovu zeptej dokumentu na všechny "wpt" uzly.
866-
' ' Výsledkem bude nový, čerstvý XmlNodeList, který obsahuje vše a v novém pořadí.
867-
868-
' Dim finalNodeList As XmlNodeList = Me.Reader.SelectNodes("wpt") '
869-
870-
' _wptNodes = New TrackAsTrkPts(TrackType.Article, finalNodeList)
871-
' Return _wptNodes
872-
873-
' End Get
874-
'End Property
875-
876779
Public ReadOnly Property WptNodes As TrackAsTrkPts
877780
Get
878781
If _wptNodes IsNot Nothing Then Return _wptNodes
@@ -1816,6 +1719,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
18161719
Dim txtDogReading = Localizer.GetString("DogReading", kvp.Key)
18171720
Dim txtTrailPickup = Localizer.GetString("TrailPickup", kvp.Key)
18181721
Dim txtTimeLimit = Localizer.GetString("TimeLimit", kvp.Key)
1722+
Dim txtTimeLimitExceeded = If(Me.TrailStats.TimeLimitExceeded, Localizer.GetString("TimeLimitExceeded", kvp.Key), Localizer.GetString("TimeLimitMet", kvp.Key))
18191723
Dim pointsTotal As Integer = Me.TrailStats.PointsInMTCompetition.RunnerFoundPoints + Me.TrailStats.PointsInMTCompetition.DogSpeedPoints + Me.TrailStats.PointsInMTCompetition.DogAccuracyPoints + Me.TrailStats.PointsInMTCompetition.DogReadingPoints + Me.TrailStats.PointsInMTCompetition.TrailPickupPoints
18201724
Dim pointsMax As Integer = Me.ActiveCategoryInfo.PointsForFindMax + Me.ActiveCategoryInfo.PointsPerTempoMax + Me.ActiveCategoryInfo.PointsForAccuracyMax + Me.ActiveCategoryInfo.PointsForDogReadingMax + Me.ActiveCategoryInfo.PointsForTrailPickupMax
18211725
Dim performancePoints As String = $"🏆{txtTotal}: {pointsTotal} {txtpoints} ({txtof} {pointsMax}){vbCrLf}
@@ -1824,7 +1728,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
18241728
🎯{txtAccuracy}: {Me.TrailStats.PointsInMTCompetition.DogAccuracyPoints} {txtpoints} ({txtof} {Me.ActiveCategoryInfo.PointsForAccuracyMax}){vbCrLf}
18251729
🚀{txtSpeed}: {Me.TrailStats.PointsInMTCompetition.DogSpeedPoints} {txtpoints} ({txtof} {Me.ActiveCategoryInfo.PointsPerTempoMax}){vbCrLf}
18261730
🔀{txtTrailPickup}: {Me.TrailStats.PointsInMTCompetition.TrailPickupPoints} {txtpoints} ({txtof} {Me.ActiveCategoryInfo.PointsForTrailPickupMax}){vbCrLf}
1827-
{txtTimeLimit}: {Me.ActiveCategoryInfo.TimeLimitMinutesPerKm} min/km
1731+
{txtTimeLimit}: {Me.ActiveCategoryInfo.TimeLimitMinutesPerKm} min/km ({txtTimeLimitExceeded})
18281732
"
18291733

18301734
kvp.Value.PerformancePointsText = performancePoints
@@ -2220,6 +2124,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
22202124
.BestCheckPointIndex = max_index
22212125
.DogName = If(.DogName, Me.ActiveCategoryInfo.Name)
22222126
.TimeLimit = preparedData.timeLimit
2127+
.TimeLimitExceeded = preparedData.TimeLimitExceeded
22232128
End With
22242129

22252130
Return True
@@ -2249,7 +2154,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
22492154
''' Pokud trasa běžce neexistuje, First Contact se nehledá a ořezání se neprovádí.
22502155
''' </remarks>
22512156
Private Function PrepareTrackData(dogTrkNode As XmlNode, runnerTrkNode As XmlNode) _
2252-
As (PurifiedDogGeoPoints As List(Of TrackGeoPoint), PurifiedRunnerGeoPoints As List(Of TrackGeoPoint), Lat0 As Double, Lon0 As Double, RunnerTotalDistance As Double, dogTotalDistance As Double, dogTotalTime As TimeSpan, RunnerFound As Boolean, timeLimit As TimeSpan)
2157+
As (PurifiedDogGeoPoints As List(Of TrackGeoPoint), PurifiedRunnerGeoPoints As List(Of TrackGeoPoint), Lat0 As Double, Lon0 As Double, RunnerTotalDistance As Double, dogTotalDistance As Double, dogTotalTime As TimeSpan, RunnerFound As Boolean, timeLimit As TimeSpan, TimeLimitExceeded As Boolean)
22532158

22542159
Dim conv As New TrackConverter()
22552160
Const PICKUP_ACTIVATION_THRESHOLD_M As Double = 5.0
@@ -2262,8 +2167,8 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
22622167
'a po vyčistění zahustíme trasu tak, aby body byly přibližně každý 2 metry, což umožní přesnější vyhodnocení checkpointů a odchylek od trasy běžce
22632168
'If dogTrkAsGeoPoints.TrackGeoPoints.Count > 30 Then ' vyhlazují se jen delší trasy
22642169
Dim purifiedTrack As TrackAsGeoPoints
2265-
purifiedTrack = TrackConverter.PurifyTrackAsGeoPoints(dogTrkAsGeoPoints, 10) ' Filtr pro maximální rychlost 10 km/h
2266-
dogTrkAsGeoPoints = purifiedTrack
2170+
purifiedTrack = TrackConverter.PurifyTrackAsGeoPoints(dogTrkAsGeoPoints, 10) ' Filtr pro maximální rychlost 10 km/h
2171+
dogTrkAsGeoPoints = purifiedTrack
22672172
'End If
22682173
dogGeoPoints = dogTrkAsGeoPoints.TrackGeoPoints
22692174
End If
@@ -2275,13 +2180,13 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
22752180
'a po vyčistění zahustíme trasu tak, aby body byly přibližně každý 2 metry, což umožní přesnější vyhodnocení checkpointů a odchylek od trasy běžce
22762181
'If runnerTrkAsGeoPoints.TrackGeoPoints.Count > 30 Then ' vyhlazují se jen delší trasy
22772182
Dim purifiedTrack As TrackAsGeoPoints
2278-
purifiedTrack = TrackConverter.PurifyTrackAsGeoPoints(runnerTrkAsGeoPoints, 10) ' Filtr pro maximální rychlost 10 km/h
2279-
runnerTrkAsGeoPoints = purifiedTrack
2183+
purifiedTrack = TrackConverter.PurifyTrackAsGeoPoints(runnerTrkAsGeoPoints, 10) ' Filtr pro maximální rychlost 10 km/h
2184+
runnerTrkAsGeoPoints = purifiedTrack
22802185
'End If
22812186
runnerGeoPoints = runnerTrkAsGeoPoints.TrackGeoPoints
22822187
End If
22832188

2284-
If dogGeoPoints Is Nothing OrElse dogGeoPoints.Count = 0 Then Return (Nothing, Nothing, 0, 0, 0, 0, TimeSpan.Zero, False, TimeSpan.Zero)
2189+
If dogGeoPoints Is Nothing OrElse dogGeoPoints.Count = 0 Then Return (Nothing, Nothing, 0, 0, 0, 0, TimeSpan.Zero, False, TimeSpan.Zero, False)
22852190

22862191
' Reference (Lat0, Lon0)
22872192
Dim lat0 As Double = If(runnerGeoPoints IsNot Nothing AndAlso runnerGeoPoints.Count > 0, runnerGeoPoints(0).Location.Lat, dogGeoPoints(0).Location.Lat)
@@ -2291,6 +2196,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
22912196
Dim finalRunnerGeoPoints As List(Of TrackGeoPoint) = Nothing
22922197
Dim runnerTotalDistance As Double = 0
22932198
Dim timeLimit As TimeSpan = TimeSpan.Zero
2199+
Dim TimeLimitExceeded = False
22942200
'vypočteme celkovou délku trasy kladeče, která bude použita pro kontrolu zda je time limit smysluplný
22952201
If runnerGeoPoints IsNot Nothing AndAlso runnerGeoPoints.Count > 1 Then
22962202
For i As Integer = 0 To runnerGeoPoints.Count - 2
@@ -2336,6 +2242,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
23362242
finalDogGeoPoints = finalDogGeoPoints.Take(i - 1).ToList()
23372243
'poslední bod trasy psa přidat jako waypoint s informací o překročení časového limitu
23382244
Me._LastWithinTimeLimit = finalDogGeoPoints.Last()
2245+
TimeLimitExceeded = True
23392246
Exit For
23402247
End If
23412248
Next i
@@ -2387,7 +2294,8 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
23872294
dogTotalDistance:=dogTotalDist,
23882295
dogTotalTime:=dogTotalTime,
23892296
RunnerFound:=RunnerFound,
2390-
timelimit:=timelimit)
2297+
timelimit:=timeLimit,
2298+
TimeLimitExceeded:=TimeLimitExceeded)
23912299
End Function
23922300

23932301

@@ -3638,6 +3546,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
36383546

36393547
' 5. Nastavení atributů pro Boolean
36403548
SetAttributeBoolean(trailStatsNode, "runnerFound", statsData.RunnerFound)
3549+
SetAttributeBoolean(trailStatsNode, "TimeLimitExceeded", statsData.TimeLimitExceeded)
36413550

36423551

36433552
' --------------------------------------------------------------------------------
@@ -3739,6 +3648,7 @@ $"(?<eu2>(\d+){Separator}(\d+){Separator}(\d+))"
37393648
.TrailPickupFactorPerCent = ParseDouble(statsNode, "TrailPickupFactorPerCent"),' --- Read TimeSpan attributes (stored as seconds) ---
37403649
.TrailAge = ParseTimeSpan(statsNode, "trailAge"),
37413650
.RunnerFound = ParseBoolean(statsNode, "runnerFound"),
3651+
.TimeLimitExceeded = ParseBoolean(statsNode, "TimeLimitExceeded"),
37423652
.RunnerTotalDistancekm = ParseDouble(statsNode, "runnerDistance"),
37433653
.DogTotalDistancekm = ParseDouble(statsNode, "dogDistance"),
37443654
.DogTotalTime = ParseTimeSpan(statsNode, "totalTime"),

K9TrailsAnalyzer/Resources/Resource1.cs.resx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,6 @@ Pro další zpracování je třeba rozhodnout, která trasa odpovídá
285285
-&gt; křížení.
286286
Pokud jsou trasy jen dvě, je to celkem jednoznačné - první je trasa kladeče, druhá je trasa psa. Ale pokud je trasa jen jedna nebo jich je více než dvě musíte to rozhodnout vy. Aplikace se to pokusí odhadnout, ale nemusí se vždy trefit 😉!</value>
287287
</data>
288-
<data name="CrossingTrail" xml:space="preserve">
289-
<value>Křížení stopy</value>
290-
</data>
291288
<data name="article" xml:space="preserve">
292289
<value>Checkpoint</value>
293290
</data>

K9TrailsAnalyzer/Resources/Resource1.de.resx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,6 @@ Zur weiteren Verarbeitung müssen Sie entscheiden, welcher Spur entspricht
284284
-&gt; Andere Personen kreuzen.
285285
Wenn es nur zwei Routen gibt, ist es ziemlich unkompliziert - der erste ist der Subjektweg, der zweite ist die Hundestrecke. Aber wenn es nur einen Track oder mehr als zwei gibt, müssen Sie sich entscheiden.</value>
286286
</data>
287-
<data name="CrossingTrail" xml:space="preserve">
288-
<value>Spurkreuzung</value>
289-
</data>
290-
<data name="RunnerTrail" xml:space="preserve">
291-
<value>Läufer</value>
292-
</data>
293287
<data name="article" xml:space="preserve">
294288
<value>Kontrollpunkt</value>
295289
</data>

K9TrailsAnalyzer/Resources/Resource1.pl.resx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,6 @@ Aby uzyskać dalsze przetwarzanie, musisz zdecydować, który tor odpowiada
284284
-&gt; Inne osoby przekraczające.
285285
Jeśli są tylko dwie trasy, jest to dość proste - pierwszy to szlak tematyczny, druga to droga psa. Ale jeśli jest tylko jeden utwór lub więcej niż dwa, musisz zdecydować.</value>
286286
</data>
287-
<data name="CrossingTrail" xml:space="preserve">
288-
<value>Skrzyżowanie śladów</value>
289-
</data>
290-
<data name="RunnerTrail" xml:space="preserve">
291-
<value>Biegacz</value>
292-
</data>
293287
<data name="article" xml:space="preserve">
294288
<value>Punkt kontrolny</value>
295289
</data>

K9TrailsAnalyzer/Resources/Resource1.ru.resx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,6 @@
284284
-&gt; Другие люди, пересекающие.
285285
Если есть только два маршрута, это довольно просто - первая - это тропа субъекта, вторая - это маршрут для собак. Но если есть только один трек или более двух, вы должны решить.</value>
286286
</data>
287-
<data name="CrossingTrail" xml:space="preserve">
288-
<value>Пересечение следа</value>
289-
</data>
290-
<data name="RunnerTrail" xml:space="preserve">
291-
<value>бегун</value>
292-
</data>
293287
<data name="article" xml:space="preserve">
294288
<value>Контрольная точка</value>
295289
</data>

K9TrailsAnalyzer/Resources/Resource1.uk.resx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,6 @@
284284
-&gt; Інші люди переправи.
285285
Якщо є лише два маршрути, це досить просто - перший - це предметний слід, другий - це маршрут собаки. Але якщо є лише один трек або більше двох, ви повинні вирішити.</value>
286286
</data>
287-
<data name="CrossingTrail" xml:space="preserve">
288-
<value>Перехрещення сліду</value>
289-
</data>
290-
<data name="RunnerTrail" xml:space="preserve">
291-
<value>бігун</value>
292-
</data>
293287
<data name="article" xml:space="preserve">
294288
<value>контрольна точка</value>
295289
</data>

TrackVideoExporter/Localization/Strings.Designer.vb

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

TrackVideoExporter/Localization/Strings.cs.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,10 @@
150150
<data name="TimeLimit" xml:space="preserve">
151151
<value>Časový limit</value>
152152
</data>
153+
<data name="TimeLimitExceeded" xml:space="preserve">
154+
<value>překročen</value>
155+
</data>
156+
<data name="TimeLimitMet" xml:space="preserve">
157+
<value>dodržen</value>
158+
</data>
153159
</root>

TrackVideoExporter/Localization/Strings.de.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,7 @@
150150
<data name="TimeLimit" xml:space="preserve">
151151
<value>Zeitlimit</value>
152152
</data>
153+
<data name="TimeLimitExceeded" xml:space="preserve">
154+
<value>überschritten</value>
155+
</data>
153156
</root>

TrackVideoExporter/Localization/Strings.pl.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,7 @@
150150
<data name="TimeLimit" xml:space="preserve">
151151
<value>Limit czasu</value>
152152
</data>
153+
<data name="TimeLimitExceeded" xml:space="preserve">
154+
<value>przekroczony</value>
155+
</data>
153156
</root>

0 commit comments

Comments
 (0)