Hi,

* Yes, you can have several coordinate filters at once, although they will
all have the same "distance" value, which is admittedly a weakness.
* Yes, you can also use kilometers, by specifying a distance of "5 km", etc.
(or "5 kilometers", or "5 kilometres"). It defaults to miles mostly because
it was written by an American, but I think it's a reasonable default...
* The patch file is attached.

-Yaron


2009/4/30 Denny Vrandečić <[email protected]>

> That's a great addition. Just a few questions:
> * what happens with several coordinates? (both, in the ask, as well as
> in the page)
> * can I put another unit in "distance"? why does it assume miles?
> * where's the code for reviewing?
>
> cheers,
> denny
>
> Yaron Koren wrote:
> > Hi,
> >
> > Thomas Fellows has written some code to enable #ask queries to return
> > pages within a certain distance of a set of coordinates. I've tried it
> > out, and it works great; you can see it in action here:
> >
> > http://discoursedb.org/wiki/Proximity_query
> >
> > (You can view the page source to see what the syntax looks like - the
> > '::~' comparator is used.)
> >
> > My question is: are there any objections to adding this in to SMW?
> >
> > -Yaron
> >
> >
> > ------------------------------------------------------------------------
> >
> >
> ------------------------------------------------------------------------------
> > Register Now & Save for Velocity, the Web Performance & Operations
> > Conference from O'Reilly Media. Velocity features a full day of
> > expert-led, hands-on workshops and two days of sessions from industry
> > leaders in dedicated Performance & Operations tracks. Use code vel09scf
> > and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
> >
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > Semediawiki-devel mailing list
> > [email protected]
> > https://lists.sourceforge.net/lists/listinfo/semediawiki-devel
>
Index: includes/storage/SMW_Query.php
===================================================================
--- includes/storage/SMW_Query.php	(revision 49775)
+++ includes/storage/SMW_Query.php	(working copy)
@@ -44,6 +44,7 @@
 	protected $m_inline; // query used inline? (required for finding right default parameters)
 	protected $m_concept; // query used in concept? (required for finding right default parameters)
 	protected $m_extraprintouts = array(); // SMWPrintoutRequest objects supplied outside querystring
+	protected $m_distance = 5; // Default 5 miles 
 
 	/**
 	 * Constructor.
@@ -117,6 +118,15 @@
 		return $this->m_offset;
 	}
 
+	public function setDistance($distance) {
+		$this->m_distance = $distance;
+		return $this->m_distance;
+	}
+
+	public function getDistance() {
+		return $this->m_distance;
+	}
+
 	/**
 	 * Set an offset for the returned query results. No offset beyond the maximal query
 	 * limit will be set, and the current query limit might be reduced in order to ensure
Index: includes/storage/SMW_SQLStore2_Queries.php
===================================================================
--- includes/storage/SMW_SQLStore2_Queries.php	(revision 49775)
+++ includes/storage/SMW_SQLStore2_Queries.php	(working copy)
@@ -153,6 +153,7 @@
 		$this->m_hierarchies = array();
 		$this->m_querylog = array();
 		$this->m_errors = array();
+		$this->m_distance = $query->getDistance();
 		SMWSQLStore2Query::$qnum = 0;
 		$this->m_sortkeys = $query->sortkeys;
 		// manually make final root query (to retrieve namespace,title):
@@ -577,7 +578,12 @@
                                        if ($dv->getTypeID() == '_str') {
                                                $comp = ' LIKE ';
                                                $value =  str_replace(array('%', '_', '*', '?'), array('\%', '\_', '%', '_'), $value);
-                                       } else { // LIKE only supported for strings
+                                       } elseif ($dv->getTypeID() == '_geo') {
+                                               $comp = '<=';
+                                               $geoarray = explode(",", $value);
+                                               $field = "ROUND(((ACOS( SIN($geoarray[0] * PI()/180 ) * SIN(SUBSTRING_INDEX($field, ',',1) * PI()/180 ) + COS($geoarray[0] * PI()/180 ) * COS(SUBSTRING_INDEX($field, ',',1) * PI()/180 ) * COS(($geoarray[1] - SUBSTRING_INDEX($field, ',',-1)) * PI()/180))*180/PI())*60*1.1515),6)";
+                                               $value = $this->m_distance;
+                                       } else { // LIKE only supported for strings and coordinates
                                                $comp = '=';
                                        }
                                break;
Index: includes/SMW_QueryProcessor.php
===================================================================
--- includes/SMW_QueryProcessor.php     (revision 50072)
+++ includes/SMW_QueryProcessor.php     (working copy)
@@ -113,6 +113,23 @@
                        $orders = Array();
                }
                reset($orders);
+               // get distance to search for location-based queries
+               if ( (array_key_exists('distance', $params)) && (is_numeric(trim($params['distance']) + 0)) ) {
+                       $distance = trim($params['distance']);
+                       $dist_components = explode(' ', $distance);
+                       $dist_num = $dist_components[0]; //str_replace(",", "", $dist2[0]);
+                       if (is_numeric($dist_num)) {
+                               // if the unit isn't kilometers, or there is
+                               // no unit, assume it's in miles
+                               if (count($dist_components) > 1) {
+                                       if ( in_array($dist_components[1], array('km', 'kms', 'kilometer', 'kilometers', 'kilometre', 'kilometres') ) ) {
+                                               $dist_num *= .621371192;
+                                       }
+                               }
+                               $query->setDistance($dist_num);
+                       }
+               }
+
                if ( array_key_exists('sort', $params) ) {
                        $query->sort = true;
                        $query->sortkeys = Array();
------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
Semediawiki-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/semediawiki-devel

Reply via email to