r108052 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r108051‎ | r108052 | r108053 >
Date:17:01, 4 January 2012
Author:maxsem
Status:resolved (Comments)
Tags:
Comment:
API module to search pages by coordinate
Modified paths:
  • /trunk/extensions/GeoData/ApiQueryGeoSearch.php (added) (history)

Diff [purge]

Index: trunk/extensions/GeoData/ApiQueryGeoSearch.php
@@ -0,0 +1,170 @@
 2+<?php
 3+
 4+class ApiQueryGeoSearch extends ApiQueryGeneratorBase {
 5+ const MIN_RADIUS = 10;
 6+
 7+ public function __construct( $query, $moduleName ) {
 8+ parent::__construct( $query, $moduleName, 'gs' );
 9+ }
 10+
 11+ public function execute() {
 12+ $this->run();
 13+ }
 14+
 15+ public function getCacheMode( $params ) {
 16+ return 'public';
 17+ }
 18+
 19+ public function executeGenerator( $resultPageSet ) {
 20+ $this->run( $resultPageSet );
 21+ }
 22+
 23+ /**
 24+ * @param $resultPageSet ApiPageSet
 25+ * @return
 26+ */
 27+ private function run( $resultPageSet = null ) {
 28+ global $wgMaxGeoSearchRadius;
 29+
 30+ $params = $this->extractRequestParams();
 31+ $exclude = false;
 32+
 33+ $this->requireOnlyOneParameter( $params, 'coord', 'page' );
 34+ if ( isset( $params['coord'] ) ) {
 35+ $arr = explode( '|', $params['coord'] );
 36+ if ( count( $arr ) != 2 || !GeoData::validateCoord( $arr[0], $arr[1] ) ) {
 37+ $this->dieUsage( 'Invalid coordinate provided', '_invalid-coord' );
 38+ }
 39+ $lat = $arr[0];
 40+ $lon = $arr[1];
 41+ } elseif ( isset( $params['page'] ) ) {
 42+ $t = Title::newFromText( $params['page'] );
 43+ if ( !$t || !$t->canExist() ) {
 44+ $this->dieUsage( "Invalid page title `{$params['page']}' provided", '_invalid-page' );
 45+ }
 46+ if ( !$t->exists() ) {
 47+ $this->dieUsage( "Page `{$params['page']}' does not exist", '_nonexistent-page' );
 48+ }
 49+ $coord = GeoData::getPageCoordinates( $t );
 50+ if ( !$coord ) {
 51+ $this->dieUsage( 'Page coordinates unknown', '_no-coordinates' );
 52+ }
 53+ $lat = $coord->lat;
 54+ $lon = $coord->lon;
 55+ $exclude = $t->getArticleID();
 56+ }
 57+ $lat = floatval( $lat );
 58+ $lon = floatval( $lon );
 59+ $radius = intval( $params['radius'] );
 60+ $rect = GeoMath::rectAround( $lat, $lon, $radius );
 61+
 62+ $dbr = wfGetDB( DB_SLAVE );
 63+ $this->addTables( array( 'geo_tags', 'page' ) );
 64+ $this->addFields( array( 'page_namespace', 'page_title', 'gt_lat', 'gt_lon',
 65+ "{$dbr->tablePrefix()}gd_distance( {$lat}, {$lon}, gt_lat, gt_lon ) AS dist" )
 66+ );
 67+ $this->addWhereRange( 'gt_lat', 'newer', $rect["minLat"], $rect["maxLat"], false );
 68+ $this->addWhereRange( 'gt_lon', 'newer', $rect["minLon"], $rect["maxLon"], false );
 69+ //$this->addWhere( 'dist < ' . intval( $radius ) ); hasta be in HAVING, not WHERE
 70+ $this->addWhere( 'gt_page_id = page_id' );
 71+ if ( $exclude ) {
 72+ $this->addWhere( "gt_page_id <> {$exclude}" );
 73+ }
 74+ if ( isset( $params['maxdim'] ) ) {
 75+ $this->addWhere( 'gt_dim < ' . intval( $params['maxdim'] ) );
 76+ }
 77+ $this->addOption( 'ORDER BY', 'dist' );
 78+
 79+ $limit = $params['limit'];
 80+ $this->addOption( 'LIMIT', $limit );
 81+
 82+ $res = $this->select( __METHOD__ );
 83+
 84+ $count = 0;
 85+ $result = $this->getResult();
 86+ foreach ( $res as $row ) {
 87+ if ( is_null( $resultPageSet ) ) {
 88+ $title = Title::newFromRow( $row );
 89+ $vals = array(
 90+ 'pageid' => intval( $row->page_id ),
 91+ 'ns' => intval( $title->getNamespace() ),
 92+ 'title' => $title->getPrefixedText(),
 93+ 'dist' => $row->dist,
 94+ );
 95+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
 96+ if ( !$fit ) {
 97+ break;
 98+ }
 99+ } else {
 100+ $resultPageSet->processDbRow( $row );
 101+ }
 102+ }
 103+ }
 104+
 105+ public function getAllowedParams() {
 106+ global $wgMaxGeoSearchRadius;
 107+ return array (
 108+ 'coord' => array(
 109+ ApiBase::PARAM_TYPE => 'string',
 110+ ),
 111+ 'page' => array(
 112+ ApiBase::PARAM_TYPE => 'string',
 113+ ),
 114+ 'radius' => array(
 115+ ApiBase::PARAM_TYPE => 'integer',
 116+ ApiBase::PARAM_REQUIRED => true,
 117+ ApiBase::PARAM_MIN => self::MIN_RADIUS,
 118+ ApiBase::PARAM_MAX => $wgMaxGeoSearchRadius,
 119+ ApiBase::PARAM_RANGE_ENFORCE => true,
 120+ ),
 121+ 'maxdim' => array(
 122+ ApiBase::PARAM_TYPE => 'integer',
 123+ ),
 124+ 'limit' => array(
 125+ ApiBase::PARAM_DFLT => 10,
 126+ ApiBase::PARAM_TYPE => 'limit',
 127+ ApiBase::PARAM_MIN => 1,
 128+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 129+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 130+ ),
 131+ );
 132+ }
 133+
 134+ public function getParamDescription() {
 135+ return array(
 136+ 'coord' => 'Coordinate around which to search: two floating-point values separated by pipe (|)',
 137+ 'page' => 'Page around which to search',
 138+ 'radius' => 'Search radius in meters',
 139+ 'maxdim' => 'Restrict search to onjects no larger than this, in meters',
 140+ 'limit' => 'Maximum number of pages to return',
 141+ );
 142+ }
 143+
 144+ public function getDescription() {
 145+ return 'Returns pages around the given point';
 146+ }
 147+
 148+ public function getPossibleErrors() {
 149+ return array_merge( parent::getPossibleErrors(), array(
 150+ ) );//@todo:
 151+ }
 152+
 153+ public function getExamples() {
 154+ global $wgVersion;
 155+ if ( version_compare( $wgVersion, '1.19alpha', '>=' ) ) {
 156+ return array(
 157+ "api.php?action=query&list=geosearch&gsccord=37.786971|-122.399677" =>
 158+ "Search around the point with coordinates 37° 47′ 13.1″ N, 122° 23′ 58.84″ W",
 159+ );
 160+ } else {
 161+ return array(
 162+ "Search around the point with coordinates 37° 47′ 13.1″ N, 122° 23′ 58.84″ W",
 163+ " api.php?action=query&list=geosearch&gsccord=37.786971|-122.399677"
 164+ );
 165+ }
 166+ }
 167+
 168+ public function getVersion() {
 169+ return __CLASS__ . ': $Id: ApiQueryGeoSearch.php 106945 2011-12-21 15:00:59Z maxsem $';
 170+ }
 171+}
Property changes on: trunk/extensions/GeoData/ApiQueryGeoSearch.php
___________________________________________________________________
Added: svn:eol-style
1172 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r108054Follow-up r108052: fixed undefined property warnings, keywordsmaxsem17:19, 4 January 2012

Comments

#Comment by Reedy (talk | contribs)   17:03, 4 January 2012

svn:keywords Id

#Comment by Reedy (talk | contribs)   17:15, 6 January 2012

$wgMaxGeoSearchRadius at the top is unused, as is $count

#Comment by MaxSem (talk | contribs)   17:30, 6 January 2012

Status & tagging log