Skip to content

Commit

Permalink
Fix edge cases in tpointseq_linear_at_stbox_xyz (MobilityDB#501)
Browse files Browse the repository at this point in the history
  • Loading branch information
mschoema authored Jun 11, 2024
1 parent 453de85 commit 45c1606
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 8 deletions.
46 changes: 38 additions & 8 deletions meos/src/point/tpoint_restrict.c
Original file line number Diff line number Diff line change
Expand Up @@ -1501,22 +1501,46 @@ tpointseq_linear_at_stbox_xyz(const TSequence *seq, const STBox *box,
/* If ninsts > 0 the instant was added in the previous iteration */
if (ninsts == 0)
{
if (t1 != inst1->t)
if (t1 == inst1->t)
{
instants[ninsts++] = (TInstant *) inst1;
lower_inc &= p3_inc;
}
else if (t1 != inst2->t)
{
inter1 = tsegment_value_at_timestamptz(inst1, inst2, LINEAR, t1);
free1 = true;
instants[ninsts] = tinstant_make(inter1, inst1->temptype, t1);
tofree[nfree++] = instants[ninsts++];
lower_inc = p3_inc;
}
else
else if (t1 == inst2->t)
{
instants[ninsts++] = (TInstant *) inst1;
lower_inc &= p3_inc;
/* We have t1 == t2 == inst2->t and since found = true, we know
* that we are on an inclusive border (p3_inc == p4_inc == true).
* Thus, lower_inc is only false if we are at the last segment
* and seq->period.upper_inc is false. */
instants[ninsts++] = (TInstant *) inst2;
lower_inc = (i == seq->count - 1) ? seq->period.upper_inc : true;
}
}
if (t1 == t2)
upper_inc = lower_inc;
{
/* If we are here: p3_inc == p4_inc == true, otherwise found would be false.
* And we also know that p1 != p2, so segment has nonzero length.
* Thus, we are in 1 of 3 cases: */
if (t1 == inst1->t)
/* We are exiting the box at the start of a segment
* Start of segments are assumed inclusive except for the first one */
upper_inc = (i == 1) ? seq->period.lower_inc : true;
else if (t1 == inst2->t)
/* We are entering the box at the end of a segment
* End of segments are assumed exclusive except for the last one */
upper_inc = (i == seq->count - 1) ? seq->period.upper_inc : false;
else
/* We clip the box at one of its inclusive corners */
upper_inc = true;
}
else
{
if (t2 != inst2->t)
Expand Down Expand Up @@ -1551,15 +1575,21 @@ tpointseq_linear_at_stbox_xyz(const TSequence *seq, const STBox *box,
}
if (makeseq && ninsts > 0)
{
sequences[nseqs++] = tsequence_make((const TInstant **) instants, ninsts,
lower_inc, upper_inc, LINEAR, NORMALIZE_NO);
/* We can occasionally have ninsts == 1 and lower_inc == upper_inc == false
* These are cases where the sequence starts / ends on an inclusive border
* and we have seq->lower_inc / seq->upper_inc being false.
* Don't create a sequence, but still reset ninsts and lower_inc */
if (ninsts > 1 || lower_inc || upper_inc)
sequences[nseqs++] = tsequence_make((const TInstant **) instants, ninsts,
lower_inc, upper_inc, LINEAR, NORMALIZE_NO);
ninsts = 0;
lower_inc = true;
}
inst1 = inst2;
p1 = DatumGetGserializedP(tinstant_val(inst2));
}
if (ninsts > 0)
/* See above for explanation of condition */
if (ninsts > 0 && (ninsts > 1 || lower_inc || upper_inc))
sequences[nseqs++] = tsequence_make((const TInstant **) instants, ninsts,
lower_inc, upper_inc, LINEAR, NORMALIZE_NO);
pfree_array((void **) tofree, nfree);
Expand Down
36 changes: 36 additions & 0 deletions mobilitydb/test/point/expected/056_tpoint_spatialfuncs.test.out
Original file line number Diff line number Diff line change
Expand Up @@ -3603,6 +3603,42 @@ select astext(atStbox(tgeompoint '[Point(-2 1)@2000-01-01, Point(2 1)@2000-01-02
{[POINT(0 1)@Sat Jan 01 12:00:00 2000 PST, POINT(1 1)@Sat Jan 01 18:00:00 2000 PST]}
(1 row)

select astext(atStbox(tgeompoint '(Point(2 1)@2000-01-01, Point(3 1)@2000-01-02)', stbox 'STBOX X((0,0),(2 2))'));
astext
--------

(1 row)

select astext(atStbox(tgeompoint '(Point(3 1)@2000-01-01, Point(2 1)@2000-01-02)', stbox 'STBOX X((0,0),(2 2))'));
astext
--------

(1 row)

select astext(atStbox(tgeompoint '(Point(1 1)@2000-01-01, Point(2 1)@2000-01-02, Point(3 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
astext
--------------------------------------------------------------------------------------
{(POINT(1 1)@Sat Jan 01 00:00:00 2000 PST, POINT(2 1)@Sun Jan 02 00:00:00 2000 PST]}
(1 row)

select astext(atStbox(tgeompoint '(Point(3 1)@2000-01-01, Point(2 1)@2000-01-02, Point(1 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
astext
--------------------------------------------------------------------------------------
{[POINT(2 1)@Sun Jan 02 00:00:00 2000 PST, POINT(1 1)@Tue Jan 04 00:00:00 2000 PST)}
(1 row)

select astext(atStbox(tgeompoint '(Point(1 1)@2000-01-01, Point(1 1)@2000-01-02, Point(3 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
astext
-------------------------------------------------------------------------------------------------------------------------------
{(POINT(1 1)@Sat Jan 01 00:00:00 2000 PST, POINT(1 1)@Sun Jan 02 00:00:00 2000 PST, POINT(2 1)@Mon Jan 03 00:00:00 2000 PST]}
(1 row)

select astext(atStbox(tgeompoint '(Point(3 1)@2000-01-01, Point(3 1)@2000-01-02, Point(1 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
astext
--------------------------------------------------------------------------------------
{[POINT(2 1)@Mon Jan 03 00:00:00 2000 PST, POINT(1 1)@Tue Jan 04 00:00:00 2000 PST)}
(1 row)

/* Errors */
SELECT asText(atStbox(tgeompoint 'SRID=4326;Point(1 1)@2000-01-01', 'GEODSTBOX ZT(((1,1,1),(2,2,2)),[2000-01-01,2000-01-02])'));
ERROR: Operation on mixed planar and geodetic coordinates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,15 @@ select astext(atStbox(tgeompoint '[Point(0 2)@2000-01-01, Point(2 0)@2000-01-02]
select astext(atStbox(tgeompoint '[Point(0 0)@2000-01-01, Point(2 2)@2000-01-02]', stbox 'STBOX X((0,0),(1 1))'));
select astext(atStbox(tgeompoint '[Point(-2 1)@2000-01-01, Point(2 1)@2000-01-02]', stbox 'STBOX X((0,0),(1 1))'));

-- Edge cases with lower_inc / upper_inc = false
select astext(atStbox(tgeompoint '(Point(2 1)@2000-01-01, Point(3 1)@2000-01-02)', stbox 'STBOX X((0,0),(2 2))'));
select astext(atStbox(tgeompoint '(Point(3 1)@2000-01-01, Point(2 1)@2000-01-02)', stbox 'STBOX X((0,0),(2 2))'));
select astext(atStbox(tgeompoint '(Point(1 1)@2000-01-01, Point(2 1)@2000-01-02, Point(3 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
select astext(atStbox(tgeompoint '(Point(3 1)@2000-01-01, Point(2 1)@2000-01-02, Point(1 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
select astext(atStbox(tgeompoint '(Point(1 1)@2000-01-01, Point(1 1)@2000-01-02, Point(3 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));
select astext(atStbox(tgeompoint '(Point(3 1)@2000-01-01, Point(3 1)@2000-01-02, Point(1 1)@2000-01-04)', stbox 'STBOX X((0,0),(2 2))'));


/* Errors */
SELECT asText(atStbox(tgeompoint 'SRID=4326;Point(1 1)@2000-01-01', 'GEODSTBOX ZT(((1,1,1),(2,2,2)),[2000-01-01,2000-01-02])'));
SELECT asText(atStbox(tgeompoint 'SRID=5676;Point(1 1)@2000-01-01', 'STBOX XT(((1,1),(2,2)),[2000-01-01,2000-01-02])'));
Expand Down

0 comments on commit 45c1606

Please sign in to comment.