/** * Returns true if the parameter value contains atleast 1 comma * meaning that there are atleast two enpoints on which to draw a line. * * @param string $value * @param Parameter $parameter * @param array $parameters * * @since 0.4 * * @return boolean */ protected function doValidation($value, Parameter $parameter, array $parameters) { //fetch locations $value = explode($this->metaDataSeparator, $value); $value = $value[0]; //need atleast two points to create a line $valid = strpos($value, ':') != false; if (!$valid) { return $valid; } //setup geocode deps $canGeoCode = MapsGeocoders::canGeocode(); if ($canGeoCode) { $geoService = $parameter->hasDependency('geoservice') ? $parameters['geoservice']->getValue() : ''; $mappingService = $parameter->hasDependency('mappingservice') ? $parameters['mappingservice']->getValue() : false; } //strip away line parameters and check for valid locations $parts = explode(':', $value); foreach ($parts as $part) { $toIndex = strpos($part, $this->metaDataSeparator); if ($toIndex != false) { $part = substr($part, 0, $toIndex); } if ($canGeoCode) { $valid = MapsGeocoders::isLocation($part, $geoService, $mappingService); } else { $valid = MapsCoordinateParser::areCoordinates($part); } if (!$valid) { break; } } return $valid; }
/** * @see ItemParameterManipulation::doManipulation * * @since 0.7.5 */ public function doManipulation(&$value, Parameter $parameter, array &$parameters) { global $egMapsDefaultGeoService; static $validatedDefault = false; if (!MapsGeocoders::canGeocode()) { throw new MWException('There are no geocoders registered, so no geocoding can happen.'); } // Get rid of any aliases. $value = $this->getMainIndentifier($value); // Override the defaulting. if ($parameter->wasSetToDefault() && is_string($this->mappingServiceParam) && array_key_exists($this->mappingServiceParam, $parameters)) { $value = self::resolveOverrides($value, $parameters[$this->mappingServiceParam]->getValue()); } if ($value === '' || !array_key_exists($value, MapsGeocoders::$registeredGeocoders)) { if (!$validatedDefault) { if (!array_key_exists($egMapsDefaultGeoService, MapsGeocoders::$registeredGeocoders)) { $geoServices = array_keys(MapsGeocoders::$registeredGeocoders); $egMapsDefaultGeoService = array_shift($geoServices); if (is_null($egMapsDefaultGeoService)) { throw new MWException('Tried to geocode while there are no geocoders available at ' . __METHOD__); } } } if (array_key_exists($egMapsDefaultGeoService, MapsGeocoders::$registeredGeocoders)) { $value = $egMapsDefaultGeoService; } else { throw new MWException('Attempt to use the default geocoder while it does not exist.'); } } }
/** * Registeres the geocoder. * * No LSB in pre-5.3 PHP *sigh*. * This is to be refactored as soon as php >=5.3 becomes acceptable. * * @since 1.0 */ public static function register() { global $egMapsGeoNamesUser; if ($egMapsGeoNamesUser !== '') { MapsGeocoders::registerGeocoder('geonames', __CLASS__); } return true; }
/** * @see ItemParameterCriterion::validate */ protected function doValidation($value, Parameter $parameter, array $parameters) { if ($this->metaDataSeparator !== false) { $parts = explode($this->metaDataSeparator, $value); $value = $parts[0]; } if (MapsGeocoders::canGeocode()) { $geoService = $parameter->hasDependency('geoservice') ? $parameters['geoservice']->getValue() : ''; $mappingService = $parameter->hasDependency('mappingservice') ? $parameters['mappingservice']->getValue() : false; return MapsGeocoders::isLocation($value, $geoService, $mappingService); } else { return MapsCoordinateParser::areCoordinates($value); } }
public function getAllowedParams() { return array('locations' => array(ApiBase::PARAM_TYPE => 'string', ApiBase::PARAM_REQUIRED => true, ApiBase::PARAM_ISMULTI => true), 'service' => array(ApiBase::PARAM_TYPE => MapsGeocoders::getAvailableGeocoders()), 'props' => array(ApiBase::PARAM_ISMULTI => true, ApiBase::PARAM_TYPE => array('lat', 'lon', 'alt'), ApiBase::PARAM_DFLT => 'lat|lon')); }
/** * Initiate the geocoding functionality. * * @since 1.0.3 * * @return boolean Indicates if init happened */ public static function init() { static $initiated = false; if ($initiated) { return false; } $initiated = true; // Register the geocoders. wfRunHooks('GeocoderFirstCallInit'); // Determine if there are any geocoders. self::$canGeocode = count(self::$registeredGeocoders) > 0; return true; }
/** * Sets the location to an address. * * @since 0.7.1 * * @param string $address * @param boolean $asActualLocation When set to false, the location is not changed, only the address string is. * * @return boolean Success indicator */ public function setAddress($address, $asActualLocation = true) { if ($asActualLocation) { $this->setCoordinates(MapsGeocoders::geocode($address)); } $this->address = $address; return $this->isValid; }
/** * Renders and returns the output. * @see ParserHook::render * * @since 0.7 * * @param array $parameters * * @return string */ public function render(array $parameters) { if (MapsGeocoders::canGeocode()) { $geovalues = MapsGeocoders::attemptToGeocodeToString($parameters['location'], $parameters['geoservice'], $parameters['mappingservice'], $parameters['allowcoordinates'], $parameters['format'], $parameters['directional']); $output = $geovalues ? $geovalues : ''; } else { $output = htmlspecialchars(wfMsg('maps-geocoder-not-available')); } return $output; }
/** * Registeres the geocoder. * * No LSB in pre-5.3 PHP *sigh*. * This is to be refactored as soon as php >=5.3 becomes acceptable. * * @since 0.7 */ public static function register() { MapsGeocoders::registerGeocoder('google', __CLASS__); return true; }
/** * Renders and returns the output. * @see ParserHook::render * * @since 0.7 * * @param array $parameters * * @return string */ public function render(array $parameters) { $canGeocode = MapsGeocoders::canGeocode(); if ($canGeocode) { $location = MapsGeocoders::attemptToGeocode($parameters['location'], $parameters['geoservice'], $parameters['mappingservice']); } else { $location = MapsCoordinateParser::parseCoordinates($parameters['location']); } // TODO if ($location) { $destination = MapsGeoFunctions::findDestination($location, $parameters['bearing'], MapsDistanceParser::parseDistance($parameters['distance'])); $output = MapsCoordinateParser::formatCoordinates($destination, $parameters['format'], $parameters['directional']); } else { // The location should be valid when this method gets called. throw new MWException('Attempt to find a destination from an invalid location'); } return $output; }
public function __construct(&$results, SMWPrintRequest $printRequest, SRFFiltered &$queryPrinter) { global $wgParser; parent::__construct($results, $printRequest, $queryPrinter); if (!defined('Maps_VERSION') || version_compare(Maps_VERSION, '1.0', '<')) { throw new FatalError('You need to have the <a href="http://www.mediawiki.org/wiki/Extension:Maps">Maps</a> extension version 1.0 or higher installed in order to use the distance filter.<br />'); } MapsGeocoders::init(); $params = $this->getActualParameters(); if (array_key_exists('distance filter origin', $params)) { $origin = MapsGeocoders::attemptToGeocode($wgParser->recursiveTagParse($params['distance filter origin'])); } else { $origin = array('lat' => '0', 'lon' => '0'); } if (array_key_exists('distance filter unit', $params)) { $this->mUnit = MapsDistanceParser::getValidUnit($wgParser->recursiveTagParse($params['distance filter unit'])); } else { $this->mUnit = MapsDistanceParser::getValidUnit(); } // Is the real position stored in a property? if (array_key_exists('distance filter property', $params)) { $property = trim($wgParser->recursiveTagParse($params['distance filter property'])); $locations = array(); } else { $property = null; $locations = null; } $targetLabel = $printRequest->getLabel(); foreach ($this->getQueryResults() as $id => $filteredItem) { $row = $filteredItem->getValue(); // $filteredItem is of class SRF_Filtered_Item // $row is an array of SMWResultArray foreach ($row as $field) { // $field is an SMWResultArray $label = $field->getPrintRequest()->getLabel(); if ($label === $targetLabel) { $field->reset(); $dataValue = $field->getNextDataValue(); // only use first value if ($dataValue !== false) { $posText = $dataValue->getShortText(SMW_OUTPUT_WIKI, false); if ($property === null) { // position is directly given $pos = MapsGeocoders::attemptToGeocode($posText); } else { // position is given in a property of a page // if we used this page before, just look up the coordinates if (array_key_exists($posText, $locations)) { $pos = $locations[$posText]; } else { // query the position's page for the coordinates or address $posText = SMWQueryProcessor::getResultFromFunctionParams(array($posText, '?' . $property), SMW_OUTPUT_WIKI, SMWQueryProcessor::INLINE_QUERY, true); // if ($posText !== '') { // geocode $pos = MapsGeocoders::attemptToGeocode($posText); } else { $pos = array('lat' => '0', 'lon' => '0'); } // store coordinates in case we need them again $locations[$posText] = $pos; } } if (is_array($pos)) { $distance = round(MapsGeoFunctions::calculateDistance($origin, $pos) / MapsDistanceParser::getUnitRatio($this->mUnit)); if ($distance > $this->mMaxDistance) { $this->mMaxDistance = $distance; } } else { $distance = -1; } } else { $distance = -1; // no location given } $filteredItem->setData('distance-filter', $distance); break; } } } if (array_key_exists('distance filter max distance', $params) && is_numeric($maxDist = trim($wgParser->recursiveTagParse($params['distance filter max distance'])))) { // this assignation ^^^ is ugly, but intentional $this->mMaxDistance = $maxDist; } else { if ($this->mMaxDistance > 1) { $base = pow(10, floor(log10($this->mMaxDistance))); $this->mMaxDistance = ceil($this->mMaxDistance / $base) * $base; } } }
/** * Renders and returns the output. * @see ParserHook::render * * @since 0.7 * * @param array $parameters * * @return string */ public function render(array $parameters) { if (MapsGeocoders::canGeocode()) { $start = MapsGeocoders::attemptToGeocode($parameters['location1'], $parameters['geoservice'], $parameters['mappingservice']); $end = MapsGeocoders::attemptToGeocode($parameters['location2'], $parameters['geoservice'], $parameters['mappingservice']); } else { $start = MapsCoordinateParser::parseCoordinates($parameters['location1']); $end = MapsCoordinateParser::parseCoordinates($parameters['location2']); } if ($start && $end) { $output = MapsDistanceParser::formatDistance(MapsGeoFunctions::calculateDistance($start, $end), $parameters['unit'], $parameters['decimals']); } else { // The locations should be valid when this method gets called. throw new Exception('Attempt to find the distance between locations of at least one is invalid'); } return $output; }
/** * Registeres the geocoder. * * No LSB in pre-5.3 PHP *sigh*. * This is to be refactored as soon as php >=5.3 becomes acceptable. * * @since 0.7 */ public static function register() { global $egMapsGeoNamesUser; MapsGeocoders::registerGeocoder($egMapsGeoNamesUser === '' ? 'geonames' : 'geonamesold', __CLASS__); return true; }
/** * Translates the coordinates field to the centre field and makes sure it's set to it's default when invalid. * * @since 1.0 * * @param array &$params */ protected function setCentre(array &$params) { // If it's false, the coordinate was invalid, or geocoding failed. Either way, the default's should be used. if ($params['coordinates'] === false) { global $egMapsDefaultMapCentre; $centre = MapsGeocoders::attemptToGeocode($egMapsDefaultMapCentre, $params['geoservice'], $this->service->getName()); if ($centre === false) { throw new Exception('Failed to parse the default centre for the map. Please check the value of $egMapsDefaultMapCentre.'); } else { $params['centre'] = $centre; } } else { $params['centre'] = $params['coordinates']; } unset($params['coordinates']); }