r64940 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r64939‎ | r64940 | r64941 >
Date:15:54, 11 April 2010
Author:jeroendedauw
Status:deferred
Tags:
Comment:
Changes for 0.6 - Rewrote distance query to work with the new coordinate table layout and a bounding box
Modified paths:
  • /trunk/extensions/SemanticMaps/GeoCoords/SM_GeoCoords.php (modified) (history)
  • /trunk/extensions/SemanticMaps/GeoCoords/SM_GeoCoordsValue.php (modified) (history)
  • /trunk/extensions/SemanticMaps/SemanticMaps.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMaps/GeoCoords/SM_GeoCoordsValue.php
@@ -32,11 +32,21 @@
3333 *
3434 * TODO: i18n keys still need to be moved
3535 */
36 - public static function InitGeoCoordsType() {
 36+ public static function initGeoCoordsType() {
3737 SMWDataValueFactory::registerDatatype( '_geo', __CLASS__, 'Geographic coordinate' );
3838 return true;
39 - }
 39+ }
4040
 41+ public static function initGeoCoordsTable( $propertyTables ) {
 42+ /*
 43+ $propertyTables['smw_coords'] = new SMWSQLStore2Table(
 44+ 'sm_coords',
 45+ array( 'lat' => 'f', 'lon' => 'f' )
 46+ );
 47+ */
 48+ return true;
 49+ }
 50+
4151 /**
4252 * @see SMWDataValue::parseUserValue
4353 */
Index: trunk/extensions/SemanticMaps/GeoCoords/SM_GeoCoords.php
@@ -11,57 +11,93 @@
1212 * @author Markus Krötzsch
1313 */
1414
 15+// Registration of the GoeCoords class.
 16+$wgAutoloadClasses['SMGeoCoords'] = __FILE__;
 17+
1518 // Registration of the Geographical Coordinate type.
16 -$wgAutoloadClasses['SMGeoCoordsValue'] = $smgDir . 'GeoCoords/SM_GeoCoordsValue.php';
 19+$wgAutoloadClasses['SMGeoCoordsValue'] = dirname( __FILE__ ) . '/SM_GeoCoordsValue.php';
1720
1821 // Registration of the Geographical Coordinate value description class.
19 -$wgAutoloadClasses['SMGeoCoordsValueDescription'] = $smgDir . 'GeoCoords/SM_GeoCoordsValueDescription.php';
 22+$wgAutoloadClasses['SMGeoCoordsValueDescription'] = dirname( __FILE__ ) . '/SM_GeoCoordsValueDescription.php';
2023
2124 // Hook for initializing the Geographical Coordinate type.
22 -$wgHooks['smwInitDatatypes'][] = 'SMGeoCoordsValue::InitGeoCoordsType';
 25+$wgHooks['smwInitDatatypes'][] = 'SMGeoCoordsValue::initGeoCoordsType';
2326
 27+$wgHooks['SMWPropertyTables'][] = 'SMGeoCoordsValue::initGeoCoordsTable';
 28+
2429 // Hook for initializing the Geographical Proximity query support.
25 -$wgHooks['smwGetSQLConditionForValue'][] = 'smfGetGeoProximitySQLCondition';
 30+$wgHooks['smwGetSQLConditionForValue'][] = 'SMGeoCoords::getGeoProximitySQLCondition';
2631
2732 define( 'SM_CMP_NEAR', 101 ); // Define the near comparator for proximity queries.
2833
29 -
30 -/**
31 - * Custom SQL query extension for matching geographic coordinates.
32 - *
33 - * TODO: Change the way coords are stored in the db from a string field to 2 float fields.
34 - * The geographic coordinate value object should provide functions to access the lat and lon data directly.
35 - *
36 - * TODO: Add support for a per-coordinate set distance parameter.
37 - */
38 -function smfGetGeoProximitySQLCondition( &$where, SMGeoCoordsValueDescription $description, $tablename, $fieldname, $dbs ) {
39 - global $smgGeoCoordDistance;
 34+final class SMGeoCoords {
4035
41 - $where = '';
42 - $dv = $description->getDatavalue();
43 -
44 - // Only execute the query when the description's type is geographical coordinates,
45 - // the description is valid, and the near comparator is used.
46 - if ( ( $dv->getTypeID() != '_geo' )
47 - || ( !$dv->isValid() )
48 - || ( $description->getComparator() != SM_CMP_NEAR )
49 - ) return true;
 36+ /**
 37+ * Custom SQL query extension for matching geographic coordinates.
 38+ *
 39+ * TODO: Change the way coords are stored in the db from a string field to 2 float fields.
 40+ * The geographic coordinate value object should provide functions to access the lat and lon data directly.
 41+ *
 42+ * TODO: Add support for a per-coordinate set distance parameter.
 43+ */
 44+ public static function getGeoProximitySQLCondition( &$whereSQL, SMGeoCoordsValueDescription $description, $tablename, $fieldname, $dbs ) {
 45+ // If the MapsGeoFunctions class is not loaded, we can not create the bounding box, so don't add any conditions.
 46+ if ( !self::geoFunctionsAreAvailable() ) {
 47+ return true;
 48+ }
5049
51 - $keys = $dv->getDBkeys();
52 - $geoarray = explode( ',', $keys[0] );
53 -
54 - if ( ( count( $geoarray ) != 2 )
55 - || ( $geoarray[0] == '' )
56 - || ( $geoarray[1] == '' )
57 - ) return true; // There is something wrong with the lat/lon pair
 50+ $dataValue = $description->getDatavalue();
5851
59 - $latitude = $dbs->addQuotes( $geoarray[0] );
60 - $longitude = $dbs->addQuotes( $geoarray[1] );
 52+ // Only execute the query when the description's type is geographical coordinates,
 53+ // the description is valid, and the near comparator is used.
 54+ if ( ( $dataValue->getTypeID() != '_geo' )
 55+ || ( !$dataValue->isValid() )
 56+ || ( $description->getComparator() != SM_CMP_NEAR )
 57+ ) return true;
 58+
 59+ $dbKeys = $dataValue->getDBkeys();
 60+
 61+ global $smgGeoCoordDistance;
 62+ $distance = $smgGeoCoordDistance; // TODO: get user provided distance
 63+
 64+ $boundingBox = self::getBoundingBox(
 65+ array(
 66+ 'lat' => $dbKeys[0],
 67+ 'lon' => $dbKeys[1]
 68+ ),
 69+ $distance
 70+ );
 71+
 72+ $north = $dbs->addQuotes( $boundingBox['north'] );
 73+ $east = $dbs->addQuotes( $boundingBox['east'] );
 74+ $south = $dbs->addQuotes( $boundingBox['south'] );
 75+ $west = $dbs->addQuotes( $boundingBox['west'] );
 76+
 77+ $whereSQL .= "{$tablename}lat < $north && {$tablename}lat > $south && {$tablename}lon < $east && {$tablename}lon > $west";
 78+
 79+ return true;
 80+ }
 81+
 82+ private static function getBoundingBox( $centerCoordinates, $circleRadius ) {
 83+ $north = MapsGeoFunctions::findDestination( $centerCoordinates, 0, $circleRadius );
 84+ $east = MapsGeoFunctions::findDestination( $centerCoordinates, 90, $circleRadius );
 85+ $south = MapsGeoFunctions::findDestination( $centerCoordinates, 180, $circleRadius );
 86+ $west = MapsGeoFunctions::findDestination( $centerCoordinates, 270, $circleRadius );
 87+
 88+ return array(
 89+ 'north' => $north['lat'],
 90+ 'east' => $east['lon'],
 91+ 'south' => $south['lat'],
 92+ 'west' => $west['lon'],
 93+ );
 94+ }
6195
62 - // Compute distances in miles:
63 - $distance = "ROUND(((ACOS( SIN({$latitude} * PI()/180 ) * SIN(SUBSTRING_INDEX({$tablename}.{$fieldname}, ',',1) * PI()/180 ) + COS({$latitude} * PI()/180 ) * COS(SUBSTRING_INDEX({$tablename}.{$fieldname}, ',',1) * PI()/180 ) * COS(({$longitude} - SUBSTRING_INDEX({$tablename}.{$fieldname}, ',',-1)) * PI()/180))*180/PI())*60*1.1515),6)";
 96+ /**
 97+ * Returns a boolean indicating if MapsGeoFunctions is available.
 98+ */
 99+ private static function geoFunctionsAreAvailable() {
 100+ global $wgAutoloadClasses;
 101+ return array_key_exists( 'MapsGeoFunctions', $wgAutoloadClasses );
 102+ }
 103+}
64104
65 - $where = "{$distance} <= " . $dbs->addQuotes( $smgGeoCoordDistance );
66 -
67 - return true;
68 -}
\ No newline at end of file
Index: trunk/extensions/SemanticMaps/SemanticMaps.php
@@ -35,7 +35,7 @@
3636
3737 // Only initialize the extension when all dependencies are present.
3838 if ( defined( 'Maps_VERSION' ) && defined( 'SMW_VERSION' ) ) {
39 - define( 'SM_VERSION', '0.6 a11' );
 39+ define( 'SM_VERSION', '0.6 a12' );
4040
4141 $smgScriptPath = ( isset( $wgExtensionAssetsPath ) && $wgExtensionAssetsPath ? $wgExtensionAssetsPath : $wgScriptPath . '/extensions' ) . '/SemanticMaps';
4242 $smgDir = dirname( __FILE__ ) . '/';

Status & tagging log