1#!/usr/bin/python3 2# 3# Copyright (C) 2010, Nokia <ivan.frade@nokia.com> 4# Copyright (C) 2019, Sam Thursfield <sam@afuera.me.uk> 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License 8# as published by the Free Software Foundation; either version 2 9# of the License, or (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19# 02110-1301, USA. 20# 21""" 22Test the distance-calculation functions in Sparql. Only requires the Store 23""" 24import unittest as ut 25from storetest import CommonTrackerStoreTest as CommonTrackerStoreTest 26 27POINT_COORDS = [ 28 (0, 0), (1, 1), (2, 2), (3, 3), (4, 4) 29] 30 31 32class TestDistanceFunctions (CommonTrackerStoreTest): 33 """ 34 Insert some points and get the distance between them. 35 """ 36 37 def setUp(self): 38 self.counter = 0 39 for lat, log in POINT_COORDS: 40 insert = """ 41 INSERT { 42 <%s> a mlo:GeoPoint ; 43 mlo:longitude %d ; 44 mlo:latitude %d . 45 } 46 """ % ("point://test/point/" + str(self.counter), log, lat) 47 self.tracker.update(insert) 48 self.counter += 1 49 50 def tearDown(self): 51 for i in range(0, self.counter): 52 delete = """ 53 DELETE { 54 <%s> a rdfs:Resource. 55 } 56 """ % ("point://test/point/" + str (i)) 57 self.tracker.update(delete) 58 59 def get_distance_between_points(self, sum_func, id1, id2): 60 61 assert 0 <= id1 <= len(POINT_COORDS) 62 assert 0 <= id2 <= len(POINT_COORDS) 63 assert sum_func == "cartesian" or sum_func == "haversine" 64 65 query_1_to_2 = """ 66 SELECT xsd:integer(tracker:%s-distance(?lat1,?lat2,?lon1,?lon2)) 67 WHERE { 68 <point://test/point/%d> a mlo:GeoPoint ; 69 mlo:latitude ?lat1 ; 70 mlo:longitude ?lon1 . 71 72 <point://test/point/%d> a mlo:GeoPoint ; 73 mlo:latitude ?lat2 ; 74 mlo:longitude ?lon2 . 75 } 76 """ % (sum_func, id1, id2) 77 result = self.tracker.query(query_1_to_2) 78 return int(result[0][0]) 79 80 def test_distance_cartesian_symmetry(self): 81 """ 82 setUp: Insert 5 points in the pre-defined coordinates 83 1. TEST: Check cartesian distance from point A to B, and from B to A 84 (should be the same :P) 85 tearDown: Remove the test points inserted before 86 """ 87 a_to_b = self.get_distance_between_points("cartesian", 1, 2) 88 assert a_to_b == 204601 89 90 b_to_a = self.get_distance_between_points("cartesian", 2, 1) 91 assert b_to_a == 204601 92 93 assert a_to_b == b_to_a 94 95 def test_distance_haversine_symmetry(self): 96 """ 97 setUp: Insert 5 points in the pre-defined coordinates 98 1. TEST: Check cartesian distance from point A to B, and from B to A 99 (should be the same :P) 100 tearDown: Remove the test points inserted before 101 """ 102 a_to_b = self.get_distance_between_points("haversine", 1, 2) 103 assert a_to_b == 157225 104 105 b_to_a = self.get_distance_between_points("haversine", 2, 1) 106 assert b_to_a == 157225 107 108 assert a_to_b == b_to_a 109 110 def test_distance_cartesian_proportion(self): 111 d_1_to_2 = self.get_distance_between_points("cartesian", 1, 2) 112 d_2_to_3 = self.get_distance_between_points("cartesian", 2, 3) 113 d_3_to_4 = self.get_distance_between_points("cartesian", 3, 4) 114 assert d_1_to_2 > d_2_to_3 > d_3_to_4 115 116 def test_distance_haversine_proportion(self): 117 d_1_to_2 = self.get_distance_between_points("haversine", 1, 2) 118 d_2_to_3 = self.get_distance_between_points("haversine", 2, 3) 119 d_3_to_4 = self.get_distance_between_points("haversine", 3, 4) 120 assert d_1_to_2 > d_2_to_3 > d_3_to_4 121 122 def test_distance_different(self): 123 d_2_to_3h = self.get_distance_between_points("haversine", 2, 3) 124 d_2_to_3c = self.get_distance_between_points("cartesian", 2, 3) 125 assert d_2_to_3h < d_2_to_3c 126 127 128if __name__ == '__main__': 129 ut.main() 130