src/Services/Tools.php line 287

Open in your IDE?
  1. <?php
  2. // App/Services/Tools.php
  3. namespace App\Services;
  4. use Symfony\Component\HttpFoundation\JsonResponse;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\Response;
  7. use Symfony\Component\Form\FormEvent;
  8. use Symfony\Component\Form\FormEvents;
  9. use Symfony\Component\Form\FormError;
  10. use Symfony\Component\DependencyInjection\ContainerInterface;
  11. use App\Entity\User;
  12. use Symfony\Component\HttpFoundation\Session\Session;
  13. use Symfony\Component\HttpFoundation\RequestStack;
  14. use Geocoder\Dumper\GeoJson;
  15. use Geocoder\Provider\Provider;
  16. use Geocoder\Query\GeocodeQuery;
  17. use Geocoder\Query\ReverseQuery;
  18. use \DateTime;
  19. //Load entity
  20. use App\Entity\PositionGps;
  21. use App\Entity\Hobit;
  22. use App\Entity\HobitDate;
  23. // Import the Twig Environment
  24. use Twig\Environment;
  25. class Tools
  26. {
  27.     private $container;
  28.     private $em;
  29.     private $twig;
  30.     private $mail_no_reply;
  31.     private $acmeGeocoder;
  32.     private $geoJsonDumper;
  33.     public function __construct(ContainerInterface $container\Doctrine\ORM\EntityManagerInterface $emEnvironment $twigProvider $acmeGeocoderGeoJson $dumper) {
  34.         $this->container $container;
  35.         $this->em $em;
  36.         $this->twig $twig;
  37.         $this->acmeGeocoder $acmeGeocoder;
  38.         $this->geoJsonDumper $dumper;
  39.         //$this->mail_no_reply = $container->getParameter('mail_no_reply');
  40.     }
  41.     /**
  42.      * sub Phone number for international
  43.      *
  44.      * @param string $phone
  45.      * @return string
  46.      */
  47.     public function subPhoneInternational($phone)
  48.     {    
  49.         $fr "+33";
  50.         $phone_sub substr($phone1);
  51.         $phone_international $fr.$phone_sub;
  52.         return $phone_international;
  53.     }
  54.     /**
  55.      * Send json rest successData
  56.      *
  57.      * @param string $code, $message, $data
  58.      * @return json
  59.      */
  60.     public function successData($code$message$data$type Response::HTTP_OK)
  61.     {    
  62.         $response \FOS\RestBundle\View\View::create([
  63.             'success' => true,
  64.             'code'=> $code,
  65.             'message' => $message
  66.             'data'=> $data], 
  67.         $type);
  68.         return $response;
  69.     }
  70.     /**
  71.      * Send json rest successBoolean
  72.      *
  73.      * @param string $code, $message
  74.      * @return json
  75.      */
  76.     public function successBoolean($code$message$type Response::HTTP_OK)
  77.     {    
  78.         $response \FOS\RestBundle\View\View::create([
  79.             'success' => true,
  80.             'code'=> $code,
  81.             'message' => $message], 
  82.         $type);
  83.         return $response;
  84.     }
  85.     /**
  86.      * Send json rest errorData
  87.      *
  88.      * @param string $code, $message, $data
  89.      * @return json
  90.      */
  91.     public function errorData($code$message$data)
  92.     {    
  93.         $response \FOS\RestBundle\View\View::create([
  94.             'success' => false,
  95.             'code'=> $code,
  96.             'message' => $message,
  97.             'errors'=> $data], 
  98.         Response::HTTP_BAD_REQUEST);
  99.         return $response;
  100.     }
  101.     /**
  102.      * Send json rest errorBoolean
  103.      *
  104.      * @param string $code, $message
  105.      * @return json
  106.      */
  107.     public function errorBoolean($code$message$type Response::HTTP_BAD_REQUEST)
  108.     {    
  109.         $response \FOS\RestBundle\View\View::create([
  110.             'success' => false,
  111.             'code'=> $code,
  112.             'message' => $message], 
  113.         $type);
  114.         return $response;
  115.     }
  116.     /**
  117.      * Get form errors
  118.      *
  119.      * @param Array $form
  120.      * @return Array
  121.      */
  122.     /*public function getFormErrors($form)
  123.     {   
  124.         
  125.         $errorCollection = array();
  126.         foreach($form as $key => $child){
  127.             $errorCollection[$key] = array();
  128.             
  129.             if(strstr($key, "Date") || strstr($key, "date") && ($key != "birthDateDay" && $key != "birthDateMonth" && $key != "birthDateYear")) { 
  130.                 foreach($child as $keyDate => $childDate){
  131.                     if(count($childDate->getErrors()) > 0){
  132.                         $errorCollection[$key][$keyDate]["code"] = $childDate->getErrors()[0]->getCause()['payload']['code'];
  133.                         $errorCollection[$key][$keyDate]["message"] = $childDate->getErrors()[0]->getMessage();
  134.                     }
  135.                 }
  136.             }
  137.             else{
  138.                 if(count($child->getErrors()) > 0){
  139.                     $errorCollection[$key]['code'] = $child->getErrors()[0]->getCause()->getConstraint()->payload['code'];
  140.                     $errorCollection[$key]['message'] = $child->getErrors()[0]->getMessage();
  141.                 }
  142.             }
  143.             
  144.         }
  145.         return $errorCollection;
  146.     }*/
  147.     public function getFormErrors(\Symfony\Component\Form\Form $form) {
  148.         $errors = array();
  149.         foreach ($form->getErrors() as $key => $error) {
  150.             if (!$form->isRoot()) {
  151.                 $cause $error->getCause();
  152.                 if(array_key_exists("payload",$cause)){
  153.                     $payload $cause["payload"];
  154.                     $code $payload["code"];
  155.                 }
  156.                 else if ($cause instanceof \Symfony\Component\Validator\ConstraintViolation){
  157.                     $code $cause->getConstraint()->payload['code'];
  158.                 }
  159.                 else{
  160.                     $code=null;
  161.                 }
  162.                 $errors['code'] = $code;
  163.                 
  164.                 //$errors['code'] = $error->getCause()['payload']['code'];
  165.                 $errors['message'] = $error->getMessage();
  166.                 //$errors[] = $error->getMessage();
  167.             }
  168.         }
  169.         foreach ($form->all() as $child) {
  170.             if (!$child->isValid()) {
  171.                 $childErrors $this->container->get('app.tools')->getFormErrors($child);
  172.                 if(!empty($childErrors)){
  173.                     $errors[$child->getName()] =$childErrors;
  174.                 } 
  175.             }
  176.         }
  177.         return $errors;
  178.     }
  179.     /**
  180.      * Set message encrypt
  181.      *
  182.      * @param string $message
  183.      * @return String
  184.      */
  185.     public function encryptMessage($message)
  186.     {
  187.          $hash "secretHashValue";
  188.          $method "AES-256-CBC";
  189.          $iv_size mcrypt_get_iv_size(MCRYPT_CAST_256MCRYPT_MODE_CBC);
  190.          $iv mcrypt_create_iv($iv_sizeMCRYPT_RAND);
  191.          $encrypted openssl_encrypt($message$method$hash0$iv);
  192.          return base64_encode($iv $encrypted);
  193.     }
  194.     /**
  195.      * Get message encrypt
  196.      *
  197.      * @param string $message
  198.      * @return String
  199.      */
  200.     public function decryptMessage($message)
  201.     {
  202.          $message base64_decode($message);
  203.          $hash "secretHashValue";
  204.          $method "AES-256-CBC";
  205.          $iv_size mcrypt_get_iv_size(MCRYPT_CAST_256MCRYPT_MODE_CBC);
  206.          $iv substr($message0$iv_size);
  207.          $decrypted openssl_decrypt(substr($message$iv_size), $method$hash0$iv);
  208.          return $decrypted;
  209.     }
  210.     /**
  211.      * Add notification
  212.      *
  213.      * @param string $message
  214.      * @return Int idUser, String type, String message, String url
  215.      */
  216.     public function sendBasicEmail($user$subject$message$emailDest null)
  217.     {
  218.         //Load user
  219.         $user $this->em->getRepository(User::class)->find($user);
  220.         if(!$user){
  221.             return false;
  222.         }
  223.         if($emailDest==null){
  224.             $emailDest $user->getEmail();
  225.         }
  226.         //Create email
  227.         $bodyEmail $this->twig->render(
  228.             'Emails/basicEmail.html.twig',
  229.             array('user' => $user'message' => $message)
  230.         );
  231.         /*
  232.         //Load email
  233.         $message = \Swift_Message::newInstance()
  234.             ->setSubject($subject)
  235.             ->setFrom($this->mail_no_reply)
  236.             ->setTo($emailDest)
  237.             ->setBody($bodyEmail,'text/html');
  238.         //Send email
  239.         $this->mailer->send($message);
  240.         */
  241.         return true;
  242.     }
  243.     public function dreamHobit($debug$debugAndFlush$limitWidthHobit$limitTimeHobit$limitForCreateHobit$limitStable$maxSum$numberIntervalPrintedAndServer$userCurrent null$dateEndForce null$dateStartForce null)
  244.     {
  245.         //Load base
  246.         $em $this->container->get('doctrine.orm.entity_manager');
  247.         $positionGpsListTemp $em
  248.             ->getRepository(PositionGps::class)
  249.             ->findBy(array("sync" => 0"user" => $userCurrent"activityType" => "still"), array('datePrinted' => 'ASC''dateCreatedByServer' => 'ASC'), 50000);
  250.         $positionGpsList = [];
  251.         //Keep the good locations, no error gps 
  252.         foreach($positionGpsListTemp as $positionGpsTemp){
  253.             if($positionGpsTemp->getAccuracy() < 150){
  254.                 $positionGpsList[] = $positionGpsTemp;
  255.             }
  256.         }
  257.         $hobitsTemp = [];
  258.         $keyCount 1;
  259.         //Keep the good activity, check, return good array
  260.         $positionGpsList $this->checkAccuracyPosition($positionGpsList$limitTimeHobit$userCurrent);
  261.         foreach($positionGpsList as $positionGps){
  262.             
  263.             $lastPosition false;
  264.             $nextPositions = [];
  265.             $nextPositionsKeep = [];
  266.             $activtiesBetween = [];
  267.             $activtiesBetweenNumber 0;
  268.             $activtiesBetweenI 1;
  269.             $activtiesBetweenType = [];
  270.             $nextPositionKeepEnd false;
  271.             $nextStill null;
  272.             if(count($positionGpsList) == $keyCount){
  273.                 $lastPosition true;
  274.             }
  275.             if($lastPosition){
  276.                 //Current activity
  277.             }
  278.             else{
  279.                 //determine the next position "still" for get the center positions
  280.                 $nextStill $positionGpsList[$keyCount]; // KeyCount are +1
  281.                 //Get next positions
  282.                 $nextPositions $em
  283.                     ->getRepository(PositionGps::class)
  284.                     ->findPositionNext(0$userCurrent->getId(), 100$positionGps->getId(), $nextStill->getId(), 150200000);
  285.                 //For all next positions between current position still and nex position still get
  286.                 foreach($nextPositions as $nextPosition){
  287.                     $distanceM round($this->get_distance_m($positionGps$nextPosition), 3);
  288.                     //If end still, get activity between end stil and next still position
  289.                     if($nextPositionKeepEnd == false){
  290.                         if($distanceM $limitWidthHobit){
  291.                             $nextPositionsKeep[] = array("data" => $nextPosition"distanceM" => $distanceM"id" => $nextPosition->getId());
  292.                         }
  293.                         else{
  294.                             $nextPositionsKeep[] = array("data" => $nextPosition"distanceM" => $distanceM"id" => $nextPosition->getId());
  295.                             //End this hobit = break
  296.                             $nextPositionKeepEnd true;
  297.                         }
  298.                     }
  299.                     else{
  300.                         //Get Activity (bike, foot, car, etc...) between this hobit and next hobit.
  301.                         if(!isset($activtiesBetweenType[$activtiesBetweenNumber][$nextPosition->getActivityType()])){
  302.                             $activtiesBetweenType[$nextPosition->getActivityType()] = 1;
  303.                         }
  304.                         else{
  305.                             $activtiesBetweenType[$nextPosition->getActivityType()]++;
  306.                         }
  307.                         // If activities has history (number > 1) and current activity same with last activity
  308.                         if($activtiesBetweenI && $nextPosition->getActivityType() != $activtiesBetween[$activtiesBetweenNumber]['hobits'][$activtiesBetweenI 2]['data']->getActivityType()){
  309.                             //reset all variables
  310.                             $activtiesBetweenNumber++;
  311.                             $activtiesBetweenI 0;
  312.                             $activtiesBetweenType = [];
  313.                         }
  314.                         
  315.                         //Array for type by hobit
  316.                         $activtiesBetween[$activtiesBetweenNumber]["activtiesBetweenType"] = $activtiesBetweenType;
  317.                         //Default number is 0 (for 1 activity)
  318.                         $activtiesBetween[$activtiesBetweenNumber]['hobits'][] = 
  319.                             array(
  320.                                 "data" => $nextPosition
  321.                                 "dataGps" => array("longitude" => $nextPosition->getLongitude(), "latitude" => $nextPosition->getLatitude()), 
  322.                                 "distanceM" => $distanceM
  323.                                 "id" => $nextPosition->getId(), 
  324.                                 "activityType" => $nextPosition->getActivityType(),
  325.                             )
  326.                         ;
  327.                         $activtiesBetweenI++;
  328.                     }
  329.                     //Debug and flush if this variable is : true
  330.                     if($debugAndFlush == true){
  331.                         $nextPosition->setSync(1);
  332.                         $em->persist($nextPosition);
  333.                     }
  334.                 }
  335.             }
  336.             $nextPositionsKeepLast null;
  337.             if(count($nextPositionsKeep) > 0){
  338.                 $nextPositionsKeepLast $nextPositionsKeep[count($nextPositionsKeep) - 1]["data"];
  339.             }
  340.             if($nextPositionsKeepLast){
  341.                 $endDateTime $nextPositionsKeepLast->getDatePrinted();
  342.             }
  343.             else{
  344.                 if($lastPosition){
  345.                     $endDateTime = new \DateTime();
  346.                 }
  347.                 else{
  348.                     $endDateTime $nextStill->getDatePrinted();
  349.                 }
  350.             }
  351.             // REMOVE SMALL HOBIT (> $limitTimeHobit seconds)
  352.             if(($endDateTime->format("YmdHis") - $positionGps->getDatePrinted()->format("YmdHis")) > $limitTimeHobit){
  353.                 $hobitsTemp[] = array(
  354.                     "startDateTime" => $positionGps->getDatePrinted(),
  355.                     "endDateTime" => $endDateTime,
  356.                     "startDateTimeServer" => $positionGps->getDateCreatedByServer(),
  357.                     "id" => $positionGps->getId(),
  358.                     "activityType" => $positionGps->getActivityType(),
  359.                     "data" => $positionGps,
  360.                     "nextStillId" => ($nextStill) ? $nextStill->getId() : null,
  361.                     "positions" => $nextPositionsKeep,
  362.                 );
  363.             }
  364.             //For hobit activity between
  365.             if(count($activtiesBetween) > 0){
  366.                 foreach($activtiesBetween as $key => $activityBetween){
  367.                     if(count($activityBetween['hobits']) >= 10){
  368.                         $activtyBetweenFirst $activityBetween['hobits'][0]['data'];
  369.                         $activtyBetweenLast $activityBetween['hobits'][count($activityBetween['hobits']) - 1]['data'];
  370.                         $maxValue max($activityBetween['activtiesBetweenType']);
  371.                         $activityType array_search($maxValue$activityBetween['activtiesBetweenType']);
  372.                         $hobitsTemp[] = array(
  373.                             "startDateTime" => $activtyBetweenFirst->getDatePrinted(),
  374.                             "endDateTime" => $activtyBetweenLast->getDatePrinted(),
  375.                             "startDateTimeServer" => $activtyBetweenFirst->getDateCreatedByServer(),
  376.                             "activityType" => $activityType,
  377.                             "firstPosition" => $activityBetween['hobits'][0],
  378.                             "lastPosition" => $activityBetween['hobits'][count($activityBetween['hobits']) - 1],
  379.                             "positions" => $activityBetween['hobits'],
  380.                         );
  381.                     }
  382.                 }
  383.             }
  384.             if($debugAndFlush == true){
  385.                 //Sync all positions, but no current position
  386.                 if(!$lastPosition){
  387.                     $positionGps->setSync(1);
  388.                     $em->persist($positionGps);
  389.                 }
  390.             }
  391.             $em->flush();
  392.             $keyCount++;
  393.         }
  394.         return $hobitsTemp;
  395.     } 
  396.     //Check if positon less 100, then correct or no (for still)
  397.     public function checkAccuracyPosition($positionsGps$limitTimeHobit$userCurrent){
  398.         $positionsGpsGood = [];
  399.         $i 1;
  400.         foreach($positionsGps as $positionGps){
  401.             if(!$positionGps || ($positionGps && !$positionGps->getId()) || !$userCurrent){
  402.                 continue;
  403.             }
  404.             if($positionGps->getActivityConfidence() == 100 && !$positionGps->isIsMoving()){
  405.                 //It's perfect activity
  406.                 $positionsGpsGood[] = $positionGps;
  407.             }
  408.             else{
  409.                 if(count($positionsGps) == $i){
  410.                     //For last activity "still"
  411.                     $positionsGpsGood[] = $positionGps;
  412.                 }
  413.                 else{
  414.                     /*
  415.                     if($positionGps->getFloor() == "-1"){
  416.                         $positionsGpsGood[] = $positionGps;
  417.                         continue;
  418.                     }
  419.                     */
  420.                     //Remove speed fail (-1) // See for motionChange ?
  421.                     if($positionGps->getSpeed() != "-1"){
  422.                         //If during postion bigger than $limitTimeHobit (in second) 
  423.                         $nextOnePosition $this->em
  424.                             ->getRepository(PositionGps::class)
  425.                             ->findOnePositionNext(0$userCurrent->getId(), $positionGps->getId(), 150);
  426.                         
  427.                         if(($nextOnePosition[0]->getDatePrinted()->getTimestamp() - $positionGps->getDatePrinted()->getTimestamp()) > 600){
  428.                             $positionsGpsGood[] = $positionGps;
  429.                         }
  430.                     }
  431.                 }
  432.             }
  433.             $i++;
  434.         }
  435.         return $positionsGpsGood;
  436.     }
  437.     //LAST FUNCTION, NOT USE
  438.     public function dreamHobitLAST($debug$debugAndFlush$limitWidthHobit$limitTimeHobit$limitForCreateHobit$limitStable$maxSum$numberIntervalPrintedAndServer$userCurrent null$dateEndForce null$dateStartForce null)
  439.     {   
  440.         //Load base
  441.         $em $this->container->get('doctrine.orm.entity_manager');
  442.         $tabHobit = [];
  443.         $tabHobitTemp = [];
  444.         $t 0;
  445.         $a 0;
  446.         $i 0;
  447.         $hour null;
  448.         $hourLast null;
  449.         $isNewHobit true;
  450.         $positionGpsList = [];
  451.         $testDump false;
  452.         //remove fail date
  453.         $datetimeFail = new DateTime();
  454.         $newDateFail $datetimeFail->createFromFormat('Y-m-d H:i:s''1970-01-01 01:00:00');
  455.         $positionGpsListFails $this->container->get('doctrine.orm.entity_manager')
  456.                          ->getRepository(PositionGps::class)
  457.                          ->findBy(array("datePrinted" => $newDateFail"user" => $userCurrent"activityType" => "still"));
  458.         foreach ($positionGpsListFails as $fail) {
  459.             $fail->setSync(1);
  460.             $em->persist($fail);
  461.         }
  462.         $em->flush();
  463.         //Get all positions no sync
  464.         if($dateEndForce && $dateStartForce){
  465.             $positionGpsListTemp $this->container->get('doctrine.orm.entity_manager')
  466.                          ->getRepository(PositionGps::class)
  467.                          ->findBy(array("sync" => 0"user" => $userCurrent), array('datePrinted' => 'ASC''dateCreatedByServer' => 'ASC'), 50000);
  468.             foreach($positionGpsListTemp as $pos){
  469.                 if($pos->getDateCreatedByServer()->format("YmdHis") < $dateEndForce && $pos->getDateCreatedByServer()->format("YmdHis") > $dateStartForce){
  470.                     $positionGpsList[] = $pos;
  471.                 }
  472.             }
  473.         }
  474.         else if($dateEndForce){
  475.             $positionGpsListTemp $this->container->get('doctrine.orm.entity_manager')
  476.                          ->getRepository(PositionGps::class)
  477.                          ->findBy(array("sync" => 0"user" => $userCurrent), array('datePrinted' => 'ASC''dateCreatedByServer' => 'ASC'), 50000);
  478.             foreach($positionGpsListTemp as $pos){
  479.                 if($pos->getDateCreatedByServer()->format("YmdHis") < $dateEndForce){
  480.                     $positionGpsList[] = $pos;
  481.                 }
  482.             }
  483.         }
  484.         else if($dateStartForce){
  485.             $positionGpsListTemp $this->container->get('doctrine.orm.entity_manager')
  486.                          ->getRepository(PositionGps::class)
  487.                          ->findBy(array("sync" => 0"user" => $userCurrent), array('datePrinted' => 'ASC''dateCreatedByServer' => 'ASC'), 50000);
  488.             foreach($positionGpsListTemp as $pos){
  489.                 if($pos->getDateCreatedByServer()->format("YmdHis") > $dateStartForce){
  490.                     $positionGpsList[] = $pos;
  491.                 }
  492.             }
  493.         }
  494.         else{
  495.             $positionGpsList $this->container->get('doctrine.orm.entity_manager')
  496.                          ->getRepository(PositionGps::class)
  497.                          ->findBy(array("sync" => 0"user" => $userCurrent), array('datePrinted' => 'ASC''dateCreatedByServer' => 'ASC'), 50000);
  498.         }
  499.         
  500.         if($testDump){
  501.             var_dump("1 : ".count($positionGpsList)); 
  502.         }
  503.         if($positionGpsList){
  504.             $numberPosition count($positionGpsList);
  505.             
  506.             foreach ($positionGpsList as $keyPositionGps => $positionGps) {
  507.                 $i++;
  508.                 if(intval($positionGps->getAccuracy()) < 100){
  509.                     
  510.                     $hour $positionGps->getDatePrinted()->format("is");
  511.                     //if($hourLast != $hour || $hourLast == null){
  512.                         $hourLast $hour;
  513.                         
  514.                         if($positionGps->getSpeed() < 10){ 
  515.                         //if($positionGps->getSpeed() == 0 || $positionGps->getSpeed() == -1){
  516.                             $backgroundDuring false;
  517.                             if(($positionGps->getDateCreatedByServer()->format("YmdHis") - $positionGps->getDatePrinted()->format("YmdHis")) > $numberIntervalPrintedAndServer){
  518.                                 $backgroundDuring true;
  519.                             }
  520.                             if(count($tabHobit) == 0){
  521.                                 $tabHobit[$a]['data'] = $positionGps;
  522.                                 $tabHobit[$a]['move'] = false;
  523.                                 $tabHobit[$a]['startDateTime'] = $positionGps->getDatePrinted();
  524.                                 $tabHobit[$a]['startDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  525.                                 $tabHobit[$a]['number'] = 1;
  526.                                 $tabHobit[$a]['group'][] = $positionGps;
  527.                                 if($backgroundDuring){
  528.                                     $tabHobit[$a]['backgroundDuring'] = true;
  529.                                 
  530.                                 }
  531.                                 else{
  532.                                     $tabHobit[$a]['backgroundDuring'] = false;
  533.                                 }
  534.                             }
  535.                             else{
  536.                                 //Number between last geo and new geo
  537.                                 $numberRayon round($this->get_distance_m($tabHobit[$a]['data'], $positionGps) / 10003);
  538.                                 $asExistHobit false;
  539.                                 if($numberRayon $limitWidthHobit){
  540.                                     $asExistHobit true;
  541.                                 }
  542.                                 //For background data
  543.                                 if(!$backgroundDuring){
  544.                                     for($o 1$o <= $limitForCreateHobit$o++){
  545.                                         if($asExistHobit == false){
  546.                                             if($numberPosition != ($i $o) and $numberPosition > ($i $o)){
  547.                                                 $numberRayon round($this->get_distance_m($tabHobit[$a]['data'], $positionGpsList[$keyPositionGps $o]) / 10003);
  548.                                                 if($numberRayon $limitWidthHobit){
  549.                                                     $asExistHobit true;
  550.                                                 }
  551.                                             }
  552.                                         }
  553.                                     }
  554.                                 } 
  555.                                 
  556.                                 if($asExistHobit == true){
  557.                                     $tabHobit[$a]['number'] = $tabHobit[$a]['number'] + 1;
  558.                                     //echo "old - ".$positionGps->getDatePrinted()->format("d-m-Y H-i");
  559.                                     //echo "</br>";
  560.                                     //echo $numberRayon;
  561.                                     //echo "<br/>";
  562.                                     //It's sum on XX address number for a good data :)
  563.                                     if($tabHobit[$a]['number'] > 5){
  564.                                         if(isset($tabHobit[$a]['group'])){
  565.                                             if(count($tabHobit[$a]['group']) < $maxSum){
  566.                                                 $tabHobit[$a]['group'][] = $positionGps;
  567.                                             }
  568.                                         }
  569.                                         else{
  570.                                             $tabHobit[$a]['group'][] = $positionGps;
  571.                                         }
  572.                                     }
  573.                                     $t 0;
  574.                                 }
  575.                                 else{
  576.                                     if($isNewHobit == true){
  577.                                         if($keyPositionGps 2){
  578.                                             //Review
  579.                                             if($backgroundDuring){
  580.                                                 if(isset($tabHobit[$a]['group'])){
  581.                                                     /*
  582.                                                     $tabHobitTemp['last']['endDateTime'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDateCreatedByServer();
  583.                                                     $tabHobitTemp['last']['endDateTimeServer'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDateCreatedByServerFormat();
  584. */
  585.                                                     $tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDateCreatedByServer();
  586.                                                     $tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  587.                                                 }
  588.                                                 else{
  589.                                                     $tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDateCreatedByServer();
  590.                                                     $tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  591.                                                 }
  592.                                                 
  593.                                             }
  594.                                             else{
  595.                                                 if(isset($tabHobit[$a]['group'])){
  596.                                                     /*
  597.                                                     $tabHobitTemp['last']['endDateTime'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDatePrinted();
  598.                                                     $tabHobitTemp['last']['endDateTimeServer'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDateCreatedByServerFormat(); 
  599.                                                     */
  600.                                                     $tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDatePrinted();
  601.                                                     $tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  602.                                                 }
  603.                                                 else{
  604.                                                     $tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDatePrinted();
  605.                                                     $tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  606.                                                 }
  607.                                                 
  608.                                             }
  609.                                             
  610.                                             $tabHobitTemp['last']['id'] = $a;
  611.                                             $isNewHobit false;
  612.                                         }
  613.                                     }
  614.                                     //Let's go for a new hobit
  615.                                     $tabHobitTemp['new'][$t]['data'] = $positionGps;
  616.                                     $tabHobitTemp['new'][$t]['startDateTime'] = $positionGps->getDatePrinted();
  617.                                     
  618.                                     if($backgroundDuring){
  619.                                         $tabHobitTemp['new'][$t]['startDateTimeServer'] = $positionGps->getDatePrintedFormat();
  620.                                     
  621.                                     }
  622.                                     else{
  623.                                         $tabHobitTemp['new'][$t]['startDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  624.                                     }
  625.                                     $tabHobitTemp['new'][$t]['number'] = 1;
  626.                                     $numberRayon round($this->get_distance_m($tabHobitTemp['new'][0]['data'], $positionGps) / 10003);
  627.                                     //default : 0.020
  628.                                     if($numberRayon 0.010){
  629.                                         //echo "if : ".$numberRayon;
  630.                                         //echo "<br/>";
  631.                                         $t++;
  632.                                     }
  633.                                     else{ 
  634.                                         $t 0;
  635.                                         //echo "else : ".$numberRayon;
  636.                                         //var_dump($positionGps);
  637.                                         //echo "<br/>";
  638.                                         //die;
  639.                                         //echo "current - ".$positionGps->getDatePrinted()->format("d-m-Y H-i");
  640.                                         //echo "</br>";
  641.                                     }
  642.                                     //New hobit TEMP
  643.                                     
  644.                                     if($t $limitStable || $backgroundDuring){
  645.                                         if(isset($tabHobitTemp['last'])){
  646.                                             // Set the end date for the last hobit
  647.                                             $tabHobit[$tabHobitTemp['last']['id']]['endDateTime'] = $tabHobitTemp['last']['endDateTime'];
  648.                                             $tabHobit[$tabHobitTemp['last']['id']]['endDateTimeServer'] = $tabHobitTemp['last']['endDateTimeServer'];
  649.                                         }
  650.                                         $isNewHobit true;
  651.                                         //New hobit
  652.                                         $a++;
  653.                                         $tabHobit[$a]['number'] = 0;
  654.                                         if($backgroundDuring){
  655.                                             $tabHobit[$a]['backgroundDuring'] = true;
  656.                                         
  657.                                         }
  658.                                         else{
  659.                                             $tabHobit[$a]['backgroundDuring'] = false;
  660.                                         }
  661.                                         foreach ($tabHobitTemp['new'] as $hobitTemp) {
  662.                                             //echo "new - ".$hobitTemp['startDateTime']->format("d-m-Y H-i");
  663.                                             //echo "</br>";
  664.                                             //Let's go for a new hobit
  665.                                             $tabHobit[$a]['data'] = $hobitTemp['data'];
  666.                                             $tabHobit[$a]['startDateTime'] = $tabHobitTemp['new'][0]['startDateTime'];
  667.                                             $tabHobit[$a]['startDateTimeServer'] = $tabHobitTemp['new'][0]['startDateTimeServer'];
  668.                                             $tabHobit[$a]['number'] = $limitStable $tabHobit[$a]['number'];
  669.                                         }
  670.                                     }
  671.                                 }
  672.                             }
  673.                         }
  674.                         else{
  675.                             //For a travel
  676.                         }
  677.                     //}   
  678.                 }
  679.                 else{
  680.                     $em->persist($positionGps);
  681.                 }
  682.                 if(count($tabHobit) != 0){
  683.                     if($numberPosition == $i){
  684.                         //For the last line
  685.                         $tabHobit[$a]['endDateTime'] = $positionGps->getDatePrinted();
  686.                         $tabHobit[$a]['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
  687.                     }
  688.                 }
  689.                 if($debugAndFlush == true || $debug == false){
  690.                     $em->remove($positionGps);
  691.                 }
  692.             }
  693.             $em->flush();
  694.             //Delete logs
  695.             //$em->flush();
  696.             //Find the actualy hobits
  697.            /* $actualyHobits = $this->get('doctrine.orm.entity_manager')
  698.                          ->getRepository('HobitBundle:Hobit')
  699.                          ->findBy(Array("status" => Hobit::NOW)); */
  700.         /*
  701.             foreach ($tabHobit as $hobit) {
  702.                 $start = strtotime($hobit['startDateTime']->format("Y-m-d H:i:s"));
  703.                 $end = strtotime($hobit['endDateTime']->format("Y-m-d H:i:s"));
  704.                 $dateBetween = $end - $start;
  705.                 $history = false;
  706.                 //Just for debug with navigator html
  707.                 
  708.             
  709.                 if($dateBetween > $limitTimeHobit){
  710.                     if($hobit['number'] >= $limitForCreateHobit){
  711.                         //Set a new hobit
  712.                         $newHobit = new Hobit();
  713.                         foreach ($actualyHobits as $actualyHobit) {
  714.                             if(round($this->get_distance_m($actualyHobit, $hobit['data']) / 1000, 3) < $limitWidthHobit){
  715.                                 $history = true;
  716.                             }
  717.                         }
  718.                         if($history == true){
  719.                             //Set type hystory
  720.                             $newHobit->setStatus(Hobit::HISTORY);
  721.                         }
  722.                         else{
  723.                             //Set type now
  724.                             $newHobit->setStatus(Hobit::NOW);
  725.                         }
  726.                         $curl     = new \Ivory\HttpAdapter\CurlHttpAdapter();
  727.                         $geocoder = new \Geocoder\Provider\GoogleMaps($curl);
  728.                         $adresse = $geocoder->reverse($hobit['data']->getLatitude(), $hobit['data']->getLongitude());
  729.                         $fullAddress = $adresse->get(0)->getStreetNumber()." ".$adresse->get(0)->getStreetName().' '.$adresse->get(0)->getLocality().' '.$adresse->get(0)->getPostalCode().' '.$adresse->get(0)->getCountry()->getName();
  730.                         //Set property
  731.                         $newHobit->setName("Habitude");
  732.                         $newHobit->setAddress($fullAddress);
  733.                         $newHobit->setLatitude($hobit['data']->getLatitude());
  734.                         $newHobit->setLongitude($hobit['data']->getLongitude());
  735.                         $newHobit->setType(Hobit::LEISURE);
  736.                         $newHobit->setDateStartHobit($hobit['startDateTime']);
  737.                         $newHobit->setDateEndHobit($hobit['endDateTime']);
  738.                         $newHobit->setNumberRequest($hobit['number']);
  739.                         $em->persist($newHobit);
  740.                     }
  741.                 }
  742.                 
  743.             
  744.             }
  745.             if($debugAndFlush == true || $debug == false){
  746.                 //Add hobit
  747.                 $em->flush();
  748.             }
  749.             */
  750.         }
  751.         //var_dump($tabHobit);
  752.         //die;
  753.         //remove small hobit
  754.         /*
  755.         $cleanHobit  = [];
  756.         foreach ($tabHobit as $hobit) {
  757.             if(($hobit['endDateTime']->format("YmdHis") - $hobit['startDateTime']->format("YmdHis")) > $limitTimeHobit){
  758.                 $cleanHobit[] = $hobit;
  759.             }
  760.         }
  761.         */
  762.         //Just for debug
  763.         if($debug == true){
  764.             //return $cleanHobit;
  765.             return $tabHobit;
  766.         }
  767.         else{
  768.             return true;
  769.         }        
  770.     }
  771.     public function createHobit($hobits$limitWidthHobit$limitTimeHobit$limitForCreateHobit$maxSum$userCurrent){
  772.         /* TEST */
  773. /*
  774.         $adresse = $this->container
  775.         ->get('bazinga_geocoder.provider.acme')
  776.         ->reverseQuery(ReverseQuery::fromCoordinates("47.798791858866", "3.5298856962337"));
  777.         var_dump($adresse->get(0)->getId());
  778.         die;
  779. */
  780.         /* TEST */
  781.         //Load base
  782.         $em $this->container->get('doctrine.orm.entity_manager');
  783.         set_time_limit(0);
  784.         ini_set('max_execution_time'300);
  785.         $limitWidthHobit 0.030;
  786.         
  787.         $numberHobitCurrent 1;
  788.         $hobitPush false
  789.         $actualyHobits $this->container->get('doctrine.orm.entity_manager')
  790.                      ->getRepository(Hobit::class)
  791.                      ->findBy(Array("status" => "NOW""user" => $userCurrent));
  792.         $hobitsClean $hobits;
  793.         /*
  794.         //remove no complete hobit
  795.         foreach ($hobits as $hobit) {
  796.             if($hobit['number'] >= $limitForCreateHobit || $hobit['backgroundDuring']){
  797.                 if(isset($hobit['endDateTime'])){
  798.                     $start = strtotime($hobit['startDateTime']->format("Y-m-d H:i:s"));
  799.                     $end = strtotime($hobit['endDateTime']->format("Y-m-d H:i:s"));
  800.                     $dateBetween = $end - $start;
  801.                     if($dateBetween > $limitTimeHobit){
  802.                         $hobitsClean[] = $hobit;
  803.                     }
  804.                 }
  805.             }
  806.         }
  807.         */
  808.         $numberHobit count($hobitsClean); 
  809.         foreach($hobitsClean as $keyHobit => $hobit) {
  810.             $now false;
  811.             //if($numberHobit > 0 && $numberHobit == $numberHobitCurrent && count($actualyHobits) > 0){
  812.             //    $now = true;
  813.             //}
  814.             if($numberHobit && $keyHobit == && count($actualyHobits) > 0){
  815.                 if(round($this->get_distance_m($actualyHobits[0], $hobit['data']) / 10003) < $limitWidthHobit){
  816.                     $now true;
  817.                 }
  818.             }
  819.             $historyHobits $this->container->get('doctrine.orm.entity_manager')
  820.                      ->getRepository(Hobit::class)
  821.                      ->findBy(array("user" => $userCurrent));
  822.             $history false;
  823.             
  824.             if($hobit['activityType'] == "still"){
  825.                 $hobitTemp = [];
  826.                 if($now == false){
  827.                     foreach($historyHobits as $historyHobit) {
  828.                         if(round($this->get_distance_m($historyHobit$hobit['data']) / 10003) < $limitWidthHobit){
  829.                             $history true;
  830.                             $hobitTemp $historyHobit;
  831.                             $hobitDateLast $this->container->get('doctrine.orm.entity_manager')
  832.                                 ->getRepository(HobitDate::class)
  833.                                 ->findOneBy(Array("hobit" => $historyHobit"status" => "LAST"));
  834.                       
  835.                             if($hobitDateLast){
  836.                                 $hobitDateLast->setStatus(HobitDate::HISTORY);
  837.                                 // FOR TEST TEMP
  838.                                 
  839.                                 $em->persist($hobitDateLast);
  840.                                 $em->flush();
  841.                                 
  842.                             }
  843.                         }
  844.                     }
  845.                 }
  846.                 //Calc SUM IN XX ADDRESS
  847.             
  848.                 $totalLat 0;
  849.                 $totalLng 0;
  850.                 
  851.                 if($hobit['activityType'] == "still"){
  852.                     $totalLat $hobit['data']->getLatitude();
  853.                     $totalLng $hobit['data']->getLongitude();
  854.                 }
  855.                 $hobits[$keyHobit]['sumAddress']['latitude'] = $totalLat;
  856.                 $hobits[$keyHobit]['sumAddress']['longitude'] = $totalLng;
  857.           
  858.                 if($history == true || $now == true){
  859.                     //Set a new date hobit
  860.                     if($now == false){
  861.                         $newHobitDate = new HobitDate();
  862.                         $newHobitDate->setDateStartHobit($hobit['startDateTime']);
  863.                        // $newHobitDate->setNumberRequest($hobit['number']);
  864.                         $newHobitDate->setHobit($hobitTemp);
  865.                     }
  866.                     else{
  867.                         $newHobitDate $actualyHobits[0];
  868.                         //$newHobitDate->setNumberRequest($hobit['number'] + $actualyHobits[0]->getNumberRequest());
  869.                         $newHobitDate->setHobit($actualyHobits[0]->getHobit());
  870.                     }
  871.                     $newHobitDate->setLatitude($totalLat);
  872.                     $newHobitDate->setLongitude($totalLng);
  873.                     $newHobitDate->setDateEndHobit($hobit['endDateTime']);
  874.                     
  875.                     if($numberHobitCurrent == $numberHobit){
  876.                         if($now == false){
  877.                             if(count($actualyHobits) > 0){
  878.                                 $actualyHobits[0]->setStatus("LAST");
  879.                                 $em->persist($actualyHobits[0]);
  880.                             }
  881.                         }
  882.                         $newHobitDate->setStatus("NOW");
  883.                     }
  884.                     else{
  885.                         $newHobitDate->setStatus("LAST");
  886.                     }
  887.                     
  888.                     // FOR TEST TEMP
  889.                     
  890.                     $em->persist($newHobitDate);
  891.                     $em->flush();
  892.                     
  893.                 }
  894.                 else{
  895.                     //Set a new hobit
  896.                     $newHobit = new Hobit();
  897.                     
  898.                     //Set type now
  899.                     //$newHobit->setStatus("LAST");
  900.                     $newHobit->setParent(NULL);
  901.                     $adresse $this->acmeGeocoder
  902.                     ->reverseQuery(ReverseQuery::fromCoordinates($totalLat$totalLng));
  903.                     //var_dump($adresse);
  904.                     //die;
  905.                     $goodAddress "";
  906.                     $zoneAddress = [];
  907.                     $locationType "";
  908.                     $idPlace "";
  909.                     $addressTempTab = [];
  910.                     if($adresse->count() > 1){
  911.                         foreach ($adresse->all() as $keyAddress => $oneAddress) {
  912.                             $addressTemp $oneAddress->getStreetNumber()." ".$oneAddress->getStreetName().' '.$oneAddress->getLocality().' '.$oneAddress->getPostalCode().' '.$oneAddress->getCountry()->getName();
  913.                             if($keyAddress 3){
  914.                                 if($key array_search($addressTemp$addressTempTabtrue)){
  915.                                     if($addressTempTab[$key] == $addressTemp){
  916.                                         $goodAddress $addressTemp;
  917.                                         $locationType $oneAddress->getLocationType();
  918.                                         $idPlace $oneAddress->getId();
  919.                                         $zoneAddress['streetNumber'] = $oneAddress->getStreetNumber();
  920.                                         $zoneAddress['streetName'] = $oneAddress->getStreetName();
  921.                                         $zoneAddress['locality'] = $oneAddress->getLocality();
  922.                                         $zoneAddress['postalCode'] = $oneAddress->getPostalCode();
  923.                                         $zoneAddress['country'] = $oneAddress->getCountry()->getName();
  924.                                     }
  925.                                 }
  926.                             }
  927.                             $addressTempTab[] = $addressTemp;
  928.                         }
  929.                         if($goodAddress == ""){
  930.                             $goodAddress $adresse->get(0)->getStreetNumber()." ".$adresse->get(0)->getStreetName().' '.$adresse->get(0)->getLocality().' '.$adresse->get(0)->getPostalCode().' '.$adresse->get(0)->getCountry()->getName();
  931.                             $locationType $adresse->get(0)->getLocationType();
  932.                             $idPlace $adresse->get(0)->getId();
  933.                             $zoneAddress['streetNumber'] = $adresse->get(0)->getStreetNumber();
  934.                             $zoneAddress['streetName'] = $adresse->get(0)->getStreetName();
  935.                             $zoneAddress['locality'] = $adresse->get(0)->getLocality();
  936.                             $zoneAddress['postalCode'] = $adresse->get(0)->getPostalCode();
  937.                             $zoneAddress['country'] = $adresse->get(0)->getCountry()->getName();
  938.                         }
  939.                     }
  940.                     else{
  941.                         $goodAddress $adresse->get(0)->getStreetNumber()." ".$adresse->get(0)->getStreetName().' '.$adresse->get(0)->getLocality().' '.$adresse->get(0)->getPostalCode().' '.$adresse->get(0)->getCountry()->getName();
  942.                         $locationType $adresse->get(0)->getLocationType();
  943.                         $idPlace $adresse->get(0)->getId();
  944.                         $zoneAddress['streetNumber'] = $adresse->get(0)->getStreetNumber();
  945.                         $zoneAddress['streetName'] = $adresse->get(0)->getStreetName();
  946.                         $zoneAddress['locality'] = $adresse->get(0)->getLocality();
  947.                         $zoneAddress['postalCode'] = $adresse->get(0)->getPostalCode();
  948.                         $zoneAddress['country'] = $adresse->get(0)->getCountry()->getName();
  949.                     }
  950.                     //Set property
  951.                     $newHobit->setName("Habitude");
  952.                     $newHobit->setAddress($goodAddress);
  953.                     $newHobit->setLatitude($totalLat);
  954.                     $newHobit->setLongitude($totalLng);
  955.                     $newHobit->setLocationType($locationType);
  956.                     $newHobit->setIdPlace($idPlace);
  957.                     $newHobit->setType($hobit['activityType']);
  958.                     $newHobit->setStatus("LAST");
  959.                     $newHobit->setUser($userCurrent);
  960.                     $newHobit->setNumberStreet$zoneAddress['streetNumber'] );
  961.                     $newHobit->setStreet($zoneAddress['streetName']);
  962.                     $newHobit->setCity($zoneAddress['locality']);
  963.                     $newHobit->setCountry($zoneAddress['country']);
  964.                     $newHobit->setPostalCode($zoneAddress['postalCode']);
  965.                     //REMOVE FOR A VERSION 2, AFTER TEST
  966.                     $newHobit->setDateStartHobit($hobit['startDateTime']);
  967.                     $newHobit->setDateEndHobit($hobit['endDateTime']);
  968.                     $newHobit->setNumberRequest(count($hobit['positions']));
  969.                     //REMOVE FOR A VERSION 2, AFTER TEST
  970.                     $em->persist($newHobit);
  971.                     //Set a new date hobit
  972.                     $newHobitDate = new HobitDate();
  973.                     $newHobitDate->setLatitude($totalLat);
  974.                     $newHobitDate->setLongitude($totalLng);
  975.                     $newHobitDate->setDateStartHobit($hobit['startDateTime']);
  976.                     $newHobitDate->setDateEndHobit($hobit['endDateTime']);
  977.                     $newHobitDate->setNumberRequest(count($hobit['positions']));
  978.                     $newHobitDate->setHobit($newHobit);
  979.                     if($numberHobitCurrent == $numberHobit){
  980.                         if($now == false){
  981.                             if(count($actualyHobits) > 0){
  982.                                 $actualyHobits[0]->setStatus("LAST");
  983.                                 $em->persist($actualyHobits[0]);
  984.                             }
  985.                         }
  986.                         $newHobitDate->setStatus("NOW");
  987.                     }
  988.                     else{
  989.                         $newHobitDate->setStatus("LAST");
  990.                     }
  991.                     //FOR TEST TEMP 
  992.                     
  993.                     $em->persist($newHobitDate);
  994.                     $em->flush();
  995.                     
  996.                 }
  997.                 $numberHobitCurrent++;
  998.                 /*
  999.                 if($numberHobit > 0){
  1000.                     //Enable the position sync
  1001.                     //$startDate = $hobits[0]['startDateTime'];
  1002.                     //$endDate = $hobits[$numberHobit - 2]['endDateTime'];
  1003.                     $startDate = $hobit['startDateTime'];
  1004.                     $endDate = $hobit['endDateTime'];
  1005.                     $hobitPush = true;
  1006.                     // FOR TEST TEMP  
  1007.                     $positionsForSync = $this->container->get('doctrine.orm.entity_manager')
  1008.                                     ->getRepository(PositionGps::class)
  1009.                                     ->findPositionByTwoDate($startDate, $endDate, $userCurrent);       
  1010.                     
  1011.                     //All positions no sync this is a "transition", transport... :) It's easy.
  1012.                 }
  1013.                 */
  1014.                 $body "Hobit create <br/><br/>";
  1015.                 
  1016.             }
  1017.             else{
  1018.                 $body "Hobit NO create (limit) <br/><br/>";
  1019.             }
  1020.             
  1021.             $body.= "Date start : ".$hobit['startDateTime']->format("d-m-Y H:i");
  1022.             $body.= "<br/>Date end : ".$hobit['endDateTime']->format("d-m-Y H:i");
  1023.             /*
  1024.             $message = (new \Swift_Message('Life - dump hobit'))
  1025.                 ->setFrom('noreply@69dev.io')
  1026.                 ->setTo('grabettetristan@gmail.com')
  1027.                 ->setBody(
  1028.                     $body,
  1029.                     'text/html'
  1030.                 )
  1031.             ;
  1032.             */
  1033.             //$this->container->get('mailer')->send($message);
  1034.         }
  1035.         //For cut the "transition"
  1036.         /*
  1037.         if($numberHobit > 0 && $hobitPush == true){
  1038.             $startDate = $hobits[0]['startDateTime'];
  1039.             $endDate = $hobitsClean[count($hobitsClean) - 1]['endDateTime'];
  1040.             // FOR TEST TEMP 
  1041.             $positionsTransitionSync = $this->container->get('doctrine.orm.entity_manager')
  1042.             ->getRepository(PositionGps::class)
  1043.             ->findPositionByTwoDate($startDate, $endDate, $userCurrent);   
  1044.             
  1045.         }
  1046.         */
  1047.         return $hobitsClean;
  1048.     }
  1049.     function get_distance_m($lastHobit$newHobit) {
  1050.         $lat1 $lastHobit->getLatitude();
  1051.         $lng1 $lastHobit->getLongitude();
  1052.         $lat2 $newHobit->getLatitude();
  1053.         $lng2 $newHobit->getLongitude();
  1054.         $earth_radius 6378137;   
  1055.         $rlo1 deg2rad($lng1);
  1056.         $rla1 deg2rad($lat1);
  1057.         $rlo2 deg2rad($lng2);
  1058.         $rla2 deg2rad($lat2);
  1059.         $dlo = ($rlo2 $rlo1) / 2;
  1060.         $dla = ($rla2 $rla1) / 2;
  1061.         $a = (sin($dla) * sin($dla)) + cos($rla1) * cos($rla2) * (sin($dlo) * sin($dlo));
  1062.         $d atan2(sqrt($a), sqrt($a));
  1063.         return ($earth_radius $d);
  1064.     }
  1065. }