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

Improve calculation of location names #581

Merged
merged 1 commit into from
Jun 28, 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
24 changes: 24 additions & 0 deletions projects/GKCore/GDModel/GDMCustomDate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,29 @@ public static GDMDatePeriod GetIntersection(GDMCustomDate range1, GDMCustomDate

return CreatePeriod(greatestStart, smallestEnd);
}

public static GDMList<GDMDatePeriod> GetDifference(GDMCustomDate range1, GDMCustomDate range2)
{
GDMDate r1start, r1end, r2start, r2end, i2start, i2end;
range1.GetDateRange(out r1start, out r1end);
range2.GetDateRange(out r2start, out r2end);
range2.GetDateRange(out i2start, out i2end);

var smallestStart = r1start.IsEmpty() || !r2start.IsEmpty() && r1start.CompareTo(r2start) < 0 ? r1start : r2start;
var greatestStart = r1start.IsEmpty() || !r2start.IsEmpty() && r2start.CompareTo(r1start) > 0 ? r2start : r1start;
var smallestEnd = r1end.IsEmpty() || !r2end.IsEmpty() && r1end.CompareTo(r2end) > 0 ? r2end : r1end;
var greatestEnd = r1end.IsEmpty() || !r2end.IsEmpty() && r1end.CompareTo(r2end) > 0 ? r1end : r2end;

var result = new GDMList<GDMDatePeriod>();
result.Add(smallestStart.CompareTo(GDMDate.Decrement(greatestStart)) <= 0 || smallestStart.IsEmpty()
? CreatePeriod(smallestStart, GDMDate.Decrement(greatestStart))
: GDMDatePeriod.Empty);

result.Add(GDMDate.Increment(smallestEnd).CompareTo(greatestEnd) <= 0 || greatestEnd.IsEmpty()
? CreatePeriod(GDMDate.Increment(smallestEnd), greatestEnd)
: GDMDatePeriod.Empty);

return result;
}
}
}
36 changes: 25 additions & 11 deletions projects/GKCore/GDModel/GDMLocationRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ public GDMList<GDMLocationName> GetFullNames(GDMTree tree, ATDEnumeration atdEnu
var topLoc = tree.GetPtrValue<GDMLocationRecord>(topLevel);
if (topLoc == null) continue;

bool wasJoin = false;
var topNames = topLoc.GetFullNames(tree, atdEnum, abbreviations);
for (int i = 0; i < topNames.Count; i++) {
var topName = topNames[i];
Expand All @@ -198,36 +197,51 @@ public GDMList<GDMLocationName> GetFullNames(GDMTree tree, ATDEnumeration atdEnu
if (!interDate.IsEmpty()) {
string tnVal = (abbreviations && !string.IsNullOrEmpty(topName.Abbreviation)) ? topName.Abbreviation : topName.StringValue;
topBuffer.Add(new GDMLocationName(tnVal, interDate));
wasJoin = true;
}
}

if (!wasJoin && topNames.Count > 0) {
topBuffer.Add(new GDMLocationName(topNames[topNames.Count - 1].StringValue, topLevel.Date.Value));
}
}

// search of intersections of location names and intersections of top levels/names
for (int i = 0; i < fNames.Count; i++) {
var locName = fNames[i];
var locDate = locName.Date.Value;
string nVal = (abbreviations && !string.IsNullOrEmpty(locName.Abbreviation)) ? locName.Abbreviation : locName.StringValue;

bool wasJoin = false;
for (int j = 0; j < topBuffer.Count; j++) {
var topLocName = topBuffer[j];
var topName = topLocName.StringValue;
var topDate = topLocName.Date.Value;

var interDate = GDMCustomDate.GetIntersection(topDate, locName.Date.Value);
var interDate = GDMCustomDate.GetIntersection(topDate, locDate);
if (!interDate.IsEmpty()) {
string newName = (atdEnum == ATDEnumeration.fLtS) ? topName + ", " + nVal : nVal + ", " + topName;
// Find relative complement of topDate in locDate (locDate \ topDate)
// E.g. the periods that are in locDate, but not in topDate
//
// GetDifference returns two periods, one is that before topDate and one that is after
//
// Since both fNames and topBuffer lists are ordered we can assume that
// if before is not empty, it would mean that this location did not have a top level element within this period
// if after is not empty then we can try locating the next top level element within this period
// if after is empty then we finished processing this locName

var differences = GDMCustomDate.GetDifference(interDate, locDate);
var before = differences[0];
var after = differences[1];
if (!before.IsEmpty()) {
result.Add(new GDMLocationName(nVal, before));
}

result.Add(new GDMLocationName(newName, interDate));
wasJoin = true;
locDate = after;
if (after.IsEmpty()) {
break;
}
}
}

if (!wasJoin) {
result.Add(new GDMLocationName(nVal, locName.Date.Value));
if (!locDate.IsEmpty()) {
result.Add(new GDMLocationName(nVal, locDate));
}
}
}
Expand Down
Loading
Loading