[tracker/location] Implements SWP#MCoFr-511, Location functions for MLO



commit c35cfeb7420b42338aa20a620146a6eacc32b468
Author: Mikael Ottela <mikael ottela ixonos com>
Date:   Tue Jan 26 04:22:16 2010 +0200

    Implements SWP#MCoFr-511, Location functions for MLO
    
    Add functions needed for location querying

 src/libtracker-data/tracker-sparql-query.vala      |   30 +++++++++
 src/libtracker-db/tracker-db-manager.c             |   68 ++++++++++++++++++++
 tests/libtracker-data/functions/Makefile.am        |    4 +
 tests/libtracker-data/functions/data-3.ontology    |   25 +++++++
 tests/libtracker-data/functions/data-3.ttl         |   22 ++++++
 .../functions/functions-tracker-loc-1.out          |    4 +
 .../functions/functions-tracker-loc-1.rq           |   11 +++
 tests/libtracker-data/tracker-sparql-test.c        |    1 +
 8 files changed, 165 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 88ae9d8..68d71d5 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -1408,6 +1408,36 @@ public class Tracker.SparqlQuery : Object {
 			sql.append_printf ("\"%s_u_offsets\"", v);
 
 			return PropertyType.STRING;
+                } else if (uri == TRACKER_NS + "cartesian-distance") {
+                        sql.append ("SparqlCartesianDistance(");
+                        translate_expression (sql);
+                        sql.append (", ");
+                        expect (SparqlTokenType.COMMA);
+                        translate_expression (sql);
+                        sql.append (", ");
+                        expect (SparqlTokenType.COMMA);
+                        translate_expression (sql);
+                        sql.append (", ");
+                        expect (SparqlTokenType.COMMA);
+                        translate_expression (sql);
+                        sql.append (")");
+
+                        return PropertyType.DOUBLE;
+                } else if (uri == TRACKER_NS + "haversine-distance") {
+                        sql.append ("SparqlHaversineDistance(");
+                        translate_expression (sql);
+                        sql.append (", ");
+                        expect (SparqlTokenType.COMMA);
+                        translate_expression (sql);
+                        sql.append (", ");
+                        expect (SparqlTokenType.COMMA);
+                        translate_expression (sql);
+                        sql.append (", ");
+                        expect (SparqlTokenType.COMMA);
+                        translate_expression (sql);
+                        sql.append (")");
+
+                        return PropertyType.DOUBLE;
 		} else if (uri == TRACKER_NS + "coalesce") {
 			sql.append ("COALESCE(");
 			translate_expression_as_string (sql);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 7e1d7ce..61d5cea 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -29,6 +29,7 @@
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
+#include <math.h>
 
 #include <glib/gstdio.h>
 
@@ -345,6 +346,65 @@ function_sparql_string_from_filename (TrackerDBInterface *interface,
 	return result;
 }
 
+static GValue
+function_sparql_cartesian_distance (TrackerDBInterface *interface,
+				    gint                argc,
+				    GValue              values[])
+{
+	GValue result = { 0, };
+
+	if (argc != 4) {
+		g_critical ("Invalid argument count");
+		return result;
+	}
+
+	gdouble lat1 = g_value_get_double (&values[0])*M_PI/180;
+	gdouble lat2 = g_value_get_double (&values[1])*M_PI/180;
+	gdouble lon1 = g_value_get_double (&values[2])*M_PI/180;
+	gdouble lon2 = g_value_get_double (&values[3])*M_PI/180;
+
+	gdouble R = 6371000;
+	gdouble a = M_PI/2 - lat1;
+	gdouble b = M_PI/2 - lat2;
+	gdouble c = sqrt(a*a + b*b - 2*a*b*cos(lon2 - lon1));
+	gdouble d = R*c;
+
+	g_value_init (&result, G_TYPE_DOUBLE);
+	g_value_set_double (&result, d);
+
+	return result;
+}
+
+static GValue
+function_sparql_haversine_distance (TrackerDBInterface *interface,
+				    gint                argc,
+				    GValue              values[])
+{
+	GValue result = { 0, };
+
+	if (argc != 4) {
+		g_critical ("Invalid argument count");
+		return result;
+	}
+
+	gdouble lat1 = g_value_get_double (&values[0])*M_PI/180;
+	gdouble lat2 = g_value_get_double (&values[1])*M_PI/180;
+	gdouble lon1 = g_value_get_double (&values[2])*M_PI/180;
+	gdouble lon2 = g_value_get_double (&values[3])*M_PI/180;
+
+	gdouble R = 6371000;
+	gdouble dLat = (lat2-lat1);
+	gdouble dLon = (lon2-lon1); 
+	gdouble a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) *  sin(dLon/2) * sin(dLon/2); 
+	gdouble c = 2 * atan2(sqrt(a), sqrt(1-a)); 
+	gdouble d = R * c;
+
+	g_value_init (&result, G_TYPE_DOUBLE);
+	g_value_set_double (&result, d);
+
+	return result;
+}
+
 static void
 function_group_concat_step (TrackerDBInterface *interface,
                             void               *aggregate_context,
@@ -739,6 +799,14 @@ db_set_params (TrackerDBInterface *iface,
 		                                             function_sparql_string_from_filename,
 		                                             1);
 		tracker_db_interface_sqlite_create_function (iface,
+		                                             "SparqlCartesianDistance",
+		                                             function_sparql_cartesian_distance,
+		                                             4);
+		tracker_db_interface_sqlite_create_function (iface,
+		                                             "SparqlHaversineDistance",
+		                                             function_sparql_haversine_distance,
+		                                             4);
+		tracker_db_interface_sqlite_create_function (iface,
 		                                             "uncompress",
 		                                             function_uncompress,
 		                                             1);
diff --git a/tests/libtracker-data/functions/Makefile.am b/tests/libtracker-data/functions/Makefile.am
index e8d8fd9..89c86ac 100644
--- a/tests/libtracker-data/functions/Makefile.am
+++ b/tests/libtracker-data/functions/Makefile.am
@@ -5,12 +5,16 @@ EXTRA_DIST = 				\
 	data-1.ttl			\
 	data-2.ontology			\
 	data-2.ttl			\
+	data-3.ontology			\
+	data-3.ttl			\
 	functions-property-1.out	\
 	functions-property-1.rq		\
 	functions-tracker-1.out		\
 	functions-tracker-1.rq		\
 	functions-tracker-2.out		\
 	functions-tracker-2.rq		\
+	functions-tracker-loc-1.rq	\
+	functions-tracker-loc-1.out	\
 	functions-xpath-1.out		\
 	functions-xpath-1.rq		\
 	functions-xpath-2.out		\
diff --git a/tests/libtracker-data/functions/data-3.ontology b/tests/libtracker-data/functions/data-3.ontology
new file mode 100644
index 0000000..d1436a0
--- /dev/null
+++ b/tests/libtracker-data/functions/data-3.ontology
@@ -0,0 +1,25 @@
+ prefix example: <http://example/> .
+ prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+ prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+ prefix ns: <http://www.w3.org/2005/xpath-functions#> .
+
+example: a tracker:Namespace ;
+	tracker:prefix "example" .
+
+example:Location a rdfs:Class ;
+	rdfs:subClassOf rdfs:Resource .
+
+example:name a rdf:Property ;
+	rdfs:domain example:Location ;
+	rdfs:range xsd:string .
+
+example:latitude a rdf:Property ;
+	rdfs:domain example:Location ;
+	rdfs:range xsd:double .
+
+example:longitude a rdf:Property ;
+	rdfs:domain example:Location ;
+	rdfs:range xsd:double .
+
diff --git a/tests/libtracker-data/functions/data-3.ttl b/tests/libtracker-data/functions/data-3.ttl
new file mode 100644
index 0000000..c9d8239
--- /dev/null
+++ b/tests/libtracker-data/functions/data-3.ttl
@@ -0,0 +1,22 @@
+ prefix : <http://example/> .
+ prefix xsd:        <http://www.w3.org/2001/XMLSchema#> .
+
+:x a :Location .
+:x :name "Helsinki" .
+:x :latitude "60.170833" .
+:x :longitude "24.9375" .
+
+:y a :Location .
+:y :name "Tampere" .
+:y :latitude "61.498056" .
+:y :longitude "23.760833" .
+
+:z a :Location .
+:z :name "London" .
+:z :latitude "51.500278" .
+:z :longitude "-0.126111" .
+
+:c a :Location .
+:c :name "Tuvalu" .
+:c :latitude "-8.521111" .
+:c :longitude "179.198333" .
diff --git a/tests/libtracker-data/functions/functions-tracker-loc-1.out b/tests/libtracker-data/functions/functions-tracker-loc-1.out
new file mode 100644
index 0000000..55325b7
--- /dev/null
+++ b/tests/libtracker-data/functions/functions-tracker-loc-1.out
@@ -0,0 +1,4 @@
+"Helsinki"	"0.0"	"0.0"
+"Tampere"	"161905.358015775"	"160759.509081122"
+"London"	"1898317.54736874"	"1821325.85595572"
+"Tuvalu"	"14017010.3444867"	"13884463.8434573"
diff --git a/tests/libtracker-data/functions/functions-tracker-loc-1.rq b/tests/libtracker-data/functions/functions-tracker-loc-1.rq
new file mode 100644
index 0000000..64bc34a
--- /dev/null
+++ b/tests/libtracker-data/functions/functions-tracker-loc-1.rq
@@ -0,0 +1,11 @@
+PREFIX ex: <http://example/>
+PREFIX ns: <http://www.w3.org/2005/xpath-functions#>
+
+SELECT ?location tracker:cartesian-distance(?lat1,?lat2,?lon1,?lon2) tracker:haversine-distance(?lat1,?lat2,?lon1,?lon2)
+{ ?_x a ex:Location ;
+      ex:name ?location ;
+      ex:latitude ?lat1 ;
+      ex:longitude ?lon1 .
+ ex:x ex:latitude ?lat2 ;
+      ex:longitude ?lon2 .
+}
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index ac4cb36..615d6fa 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -66,6 +66,7 @@ const TestInfo tests[] = {
 	{ "functions/functions-property-1", "functions/data-1", FALSE },
 	{ "functions/functions-tracker-1", "functions/data-1", FALSE },
 	{ "functions/functions-tracker-2", "functions/data-2", FALSE },
+	{ "functions/functions-tracker-loc-1", "functions/data-3", FALSE },
 	{ "functions/functions-xpath-1", "functions/data-1", FALSE },
 	{ "functions/functions-xpath-2", "functions/data-1", FALSE },
 	{ "optional/q-opt-complex-1", "optional/complex-data-1", FALSE },



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]