[TYPO3-mvc] Re: Re: How would you realize a radius search

Philipp philippwrann at gmx.at
Tue Feb 26 19:22:58 CET 2013


Finally i wrote the 2 pass algorythm, its just better for modular repository architectures.

First step:
	/**
	 * Get Constraints for georelative queries
	 * 
	 * @param \Vendor\RegionalObject\Domain\Model\GeoCoordsInterface $regionalObject the center point of the rectangle
	 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query The queryobject
	 * @return array holding the constraints
	 */
	public function getCoordsConstraints(\Vendor\RegionalObject\Domain\Model\GeoCoordsInterface $regionalObject, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query) {
		
		$radius = $this->defaultRadius;
		$earthRadius = \Vendor\RegionalObject\Service\GeneralRegionalObjectService::$earthRadius;
		
		$lowestLat =  (double) $regionalObject->getLatitude() - rad2deg($radius/$earthRadius);
		$highestLat = (double) $regionalObject->getLatitude() + rad2deg($radius/$earthRadius);
		$lowestLng =  (double) $regionalObject->getLongitude() - rad2deg($radius/$earthRadius);
		$highestLng = (double) $regionalObject->getLongitude()+ rad2deg($radius/$earthRadius);
		
		return array(
			$query->greaterThanOrEqual('latitude',$lowestLat),
			$query->lessThanOrEqual('latitude',$highestLat),
			$query->greaterThanOrEqual('longitude',$lowestLng),
			$query->lessThanOrEqual('longitude',$highestLng)
		);
	
###########

second step: add distance
/**
	 * Add the calculated Distance to one object
	 * @param \Vendor\RegionalObject\Domain\Model\GeoCoordsInterface $object
	 * @param \Vendor\RegionalObject\Domain\Model\GeoCoordsInterface $center
	 * @return void
	 */
	public function addDistance(\Vendor\RegionalObject\Domain\Model\GeoCoordsInterface $object, \Vendor\RegionalObject\Domain\Model\GeoCoordsInterface $center) {
		
		$lat1 = (double) $object->getLatitude();
		$lng1 = (double) $object->getLongitude();
		$lat2 = (double) $center->getLatitude();
		$lng2 = (double) $center->getLongitude();
		
		$distance = \Vendor\RegionalObject\Service\GeneralRegionalObjectService::calculateDistance($lat1, $lng1, $lat2, $lng2);
		$object->setDistance($distance);
	}

##########
there i have this formular:

	
	/**
	 * Calculates the great-circle distance between two points, with the Vincenty formula.
	 * @param float $latitudeFrom Latitude of start point in [deg decimal]
	 * @param float $longitudeFrom Longitude of start point in [deg decimal]
	 * @param float $latitudeTo Latitude of target point in [deg decimal]
	 * @param float $longitudeTo Longitude of target point in [deg decimal]
	 * @param float $earthRadius Mean earth radius in [m]
	 * @return float Distance between points in (same as earthRadius)
	 */
	public static function calculateDistance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo)
	{
	  // convert from degrees to radians
	  $latFrom = deg2rad($latitudeFrom);
	  $lonFrom = deg2rad($longitudeFrom);
	  $latTo = deg2rad($latitudeTo);
	  $lonTo = deg2rad($longitudeTo);

	  $lonDelta = $lonTo - $lonFrom;
	  $a = pow(cos($latTo) * sin($lonDelta), 2) + pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2);
	  $b = sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta);

	  $angle = atan2(sqrt($a), $b);
	  return $angle * self::$earthRadius;
	}


##########
The Interface just makes sure of get/set methods for Lat, Lng and distance.


More information about the TYPO3-project-typo3v4mvc mailing list