Skip to content

Commit dd49e58

Browse files
committed
Implemented Trajectory Functions methods with tests
1 parent 1002cca commit dd49e58

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using System.Linq;
2+
3+
using LinqToDB;
4+
using NUnit.Framework;
5+
6+
namespace LinqToDBPostGisNetTopologySuite.Tests
7+
{
8+
[TestFixture]
9+
class TrajectoryFunctionsTests : TestsBase
10+
{
11+
[SetUp]
12+
public void Setup()
13+
{
14+
using (var db = new PostGisTestDataConnection(TestDatabaseConnectionString))
15+
{
16+
db.TestGeometries.Delete();
17+
}
18+
}
19+
20+
[Test]
21+
public void TestSTIsValidTrajectory()
22+
{
23+
using (var db = new PostGisTestDataConnection(TestDatabaseConnectionString))
24+
{
25+
db.TestGeometries
26+
.Value(g => g.Id, 1)
27+
.Value(p => p.Geometry, () =>
28+
GeometryConstructors.STMakeLine(
29+
GeometryConstructors.STMakePointM(0, 0, 1),
30+
GeometryConstructors.STMakePointM(0, 1, 2)))
31+
.Insert();
32+
33+
db.TestGeometries
34+
.Value(g => g.Id, 2)
35+
.Value(p => p.Geometry, () =>
36+
GeometryConstructors.STMakeLine(
37+
GeometryConstructors.STMakePointM(0, 0, 1),
38+
GeometryConstructors.STMakePointM(0, 1, 0)))
39+
.Insert();
40+
41+
db.TestGeometries.Value(g => g.Id, 3).Value(p => p.Geometry, () => null).Insert();
42+
43+
Assert.IsTrue(db.TestGeometries.Where(g => g.Id == 1).Select(g => g.Geometry.STIsValidTrajectory()).Single());
44+
Assert.IsFalse(db.TestGeometries.Where(g => g.Id == 2).Select(g => g.Geometry.STIsValidTrajectory()).Single());
45+
Assert.IsNull(db.TestGeometries.Where(g => g.Id == 3).Select(g => g.Geometry.STIsValidTrajectory()).Single());
46+
}
47+
}
48+
49+
[Test]
50+
public void TestSTClosestPointOfApproach()
51+
{
52+
using (var db = new PostGisTestDataConnection(TestDatabaseConnectionString))
53+
{
54+
const string wkt1 = "LINESTRING ZM (0 0 0 1432623600,10 0 5 1432627200)";
55+
db.TestGeometries.Value(g => g.Id, 1).Value(p => p.Geometry, () => GeometryInput.STGeomFromText(wkt1)).Insert();
56+
57+
const string wkt2 = "LINESTRING ZM (0 2 10 1432623600,12 1 2 1432627200)";
58+
db.TestGeometries.Value(g => g.Id, 2).Value(p => p.Geometry, () => GeometryInput.STGeomFromText(wkt2)).Insert();
59+
60+
db.TestGeometries.Value(g => g.Id, 3).Value(p => p.Geometry, () => null).Insert();
61+
62+
Assert.AreEqual(1432626331.03448,
63+
db.TestGeometries.Where(g => g.Id == 1)
64+
.Select(g => g.Geometry.STClosestPointOfApproach(db.TestGeometries.Where(g2 => g2.Id == 2).Single().Geometry))
65+
.Single(),
66+
1.0E-3);
67+
68+
Assert.IsNull(db.TestGeometries.Where(g => g.Id == 3).Select(g => g.Geometry.STClosestPointOfApproach(null)).Single());
69+
}
70+
}
71+
72+
[Test]
73+
public void TestSTDistanceCPA()
74+
{
75+
using (var db = new PostGisTestDataConnection(TestDatabaseConnectionString))
76+
{
77+
const string wkt1 = "LINESTRING ZM (0 0 0 1432623600,10 0 5 1432627200)";
78+
db.TestGeometries.Value(g => g.Id, 1).Value(p => p.Geometry, () => GeometryInput.STGeomFromText(wkt1)).Insert();
79+
80+
const string wkt2 = "LINESTRING ZM (0 2 10 1432623600,12 1 2 1432627200)";
81+
db.TestGeometries.Value(g => g.Id, 2).Value(p => p.Geometry, () => GeometryInput.STGeomFromText(wkt2)).Insert();
82+
83+
db.TestGeometries.Value(g => g.Id, 3).Value(p => p.Geometry, () => null).Insert();
84+
85+
Assert.AreEqual(1.96521473776207,
86+
db.TestGeometries.Where(g => g.Id == 1)
87+
.Select(g => g.Geometry.STDistanceCPA(db.TestGeometries.Where(g2 => g2.Id == 2).Single().Geometry))
88+
.Single(),
89+
1.0E-8);
90+
91+
Assert.IsNull(db.TestGeometries.Where(g => g.Id == 3).Select(g => g.Geometry.STDistanceCPA(null)).Single());
92+
}
93+
}
94+
95+
[Test]
96+
public void TestSTCPAWithin()
97+
{
98+
using (var db = new PostGisTestDataConnection(TestDatabaseConnectionString))
99+
{
100+
const string wkt1 = "LINESTRING ZM (0 0 0 1432623600,10 0 5 1432627200)";
101+
db.TestGeometries.Value(g => g.Id, 1).Value(p => p.Geometry, () => GeometryInput.STGeomFromText(wkt1)).Insert();
102+
103+
const string wkt2 = "LINESTRING ZM (0 2 10 1432623600,12 1 2 1432627200)";
104+
db.TestGeometries.Value(g => g.Id, 2).Value(p => p.Geometry, () => GeometryInput.STGeomFromText(wkt2)).Insert();
105+
106+
db.TestGeometries.Value(g => g.Id, 3).Value(p => p.Geometry, () => null).Insert();
107+
108+
Assert.IsTrue(db.TestGeometries.Where(g => g.Id == 1)
109+
.Select(g => g.Geometry.STCPAWithin(db.TestGeometries.Where(g2 => g2.Id == 2).Single().Geometry, 2))
110+
.Single());
111+
112+
Assert.IsNull(db.TestGeometries.Where(g => g.Id == 3).Select(g => g.Geometry.STCPAWithin(null, 2)).Single());
113+
}
114+
}
115+
}
116+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
3+
using LinqToDB;
4+
5+
using NTSG = NetTopologySuite.Geometries.Geometry;
6+
7+
namespace LinqToDBPostGisNetTopologySuite
8+
{
9+
/// <summary>
10+
/// Trajectory Functions
11+
/// </summary>
12+
/// <remarks>
13+
/// 8.18. Trajectory Functions https://postgis.net/docs/manual-3.0/reference.html#Temporal
14+
/// </remarks>
15+
public static class TrajectoryFunctions
16+
{
17+
/// <summary>
18+
/// Tests if input geometry represents valid trajectory - LINESTRING with measures (M values), which increase from each vertex to the next.
19+
/// </summary>
20+
/// <remarks>
21+
/// See https://postgis.net/docs/manual-3.0/ST_IsValidTrajectory.html
22+
/// </remarks>
23+
/// <param name="geometry">Input geometry</param>
24+
/// <returns>True if input geometry is a valid trajectory</returns>
25+
[Sql.Function("ST_IsValidTrajectory", ServerSideOnly = true)]
26+
public static bool? STIsValidTrajectory(this NTSG geometry)
27+
{
28+
throw new InvalidOperationException();
29+
}
30+
31+
/// <summary>
32+
/// Returns the smallest measure at which points interpolated along the given trajectories are at the smallest distance.
33+
/// </summary>
34+
/// <remarks>
35+
/// See https://postgis.net/docs/manual-3.0/ST_ClosestPointOfApproach.html
36+
/// </remarks>
37+
/// <param name="track1">Input geometry for trajectory 1</param>
38+
/// <param name="track2">Input geometry for trajectory 2</param>
39+
/// <returns>Smallest measure at the smallest distance</returns>
40+
[Sql.Function("ST_ClosestPointOfApproach", ServerSideOnly = true)]
41+
public static double? STClosestPointOfApproach(this NTSG track1, NTSG track2)
42+
{
43+
throw new InvalidOperationException();
44+
}
45+
46+
/// <summary>
47+
/// Returns the minimum distance two input geometries have ever been each other.
48+
/// </summary>
49+
/// <remarks>
50+
/// See https://postgis.net/docs/manual-3.0/ST_DistanceCPA.html
51+
/// </remarks>
52+
/// <param name="track1">Input geometry for trajectory 1</param>
53+
/// <param name="track2">Input geometry for trajectory 2</param>
54+
/// <returns>Minimum distance</returns>
55+
[Sql.Function("ST_DistanceCPA", ServerSideOnly = true)]
56+
public static double? STDistanceCPA(this NTSG track1, NTSG track2)
57+
{
58+
throw new InvalidOperationException();
59+
}
60+
61+
/// <summary>
62+
/// Checks whether two input geometries have ever been within given maximum distance.
63+
/// </summary>
64+
/// <remarks>
65+
/// See https://postgis.net/docs/manual-3.0/ST_CPAWithin.html
66+
/// </remarks>
67+
/// <param name="track1">Input geometry for trajectory 1</param>
68+
/// <param name="track2">Input geometry for trajectory 2</param>
69+
/// <param name="maxDistance">Maximum distance</param>
70+
/// <returns>True, if two input geometries have ever been within given maximum distance</returns>
71+
[Sql.Function("ST_CPAWithin", ServerSideOnly = true)]
72+
public static bool? STCPAWithin(this NTSG track1, NTSG track2, double maxDistance)
73+
{
74+
throw new InvalidOperationException();
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)