bbox = $bbox; $this->zoom = $zoom; $this->indexLongitude = array(); $this->indexLatitude = array(); $this->mailles = array(); $this->origine = Config::get('origine'); } public function __destruct() { while (count($this->indexLatitude) > 0) { array_pop($this->indexLatitude); } while (count($this->indexLongitude) > 0) { array_pop($this->indexLongitude); } while (count($this->mailles) > 0) { array_pop($this->mailles); } unset($this); } public function genererMaillesVides() { $this->recupererIndexMaillesDansBbox(); foreach ($this->indexLatitude as $indexLat => $intervalleLat) { $ligne = array(); foreach ($this->indexLongitude as $indexLng => $intervalleLng) { $ligne[] = new Maille($intervalleLat[0], $intervalleLng[0], $intervalleLat[1], $intervalleLng[1], $indexLat, $indexLng); } $this->mailles[] = $ligne; } } private function recupererIndexMaillesDansBbox() { $tableIndex = Config::get('table_index_mailles'); $requete = "SELECT axe, position, debut, fin FROM {$tableIndex} WHERE zoom={$this->zoom} AND (". "(axe='lat' AND debut<{$this->bbox['nord']} AND fin>{$this->bbox['sud']}) ". "OR (axe='lng' AND debut<{$this->bbox['est']} AND fin>{$this->bbox['ouest']})". ") ORDER BY axe, position"; $indexMailles = $this->getBdd()->recupererTous($requete); foreach ($indexMailles as $index) { if ($index['axe'] == 'lng') { $this->indexLongitude[$index['position']] = array($index['debut'], $index['fin']); } else { $this->indexLatitude[$index['position']] = array($index['debut'], $index['fin']); } } } private function getBdd() { if (is_null($this->bdd)) { $this->bdd = new Bdd(); } return $this->bdd; } public function ajouterPoints($points) { foreach ($points as $point) { $longitude = $point['longitude']; $latitude = $point['latitude']; list($indexLongitude, $indexLatitude) = $this->rechercherIndexMaille($longitude, $latitude); $this->mailles[$indexLatitude][$indexLongitude]->ajouterPoint($point); } } private function rechercherIndexMaille($longitude, $latitude) { $indexLatitude = 0; $indexLongitude = 0; while ($indexLatitude < count($this->indexLatitude) - 1 && $this->mailles[$indexLatitude][0]->getLatitudeNord() < $latitude) { $indexLatitude ++; } while ($indexLongitude < count($this->indexLongitude) - 1 && $this->mailles[$indexLatitude][$indexLongitude]->getLongitudeEst() < $longitude) { $indexLongitude ++; } return array($indexLongitude, $indexLatitude); } public function formaterPourInsertionBdd() { $mailles_resume = array(); foreach ($this->mailles as $ligne) { foreach ($ligne as $maille) { if ($maille->getNombrePoints() > 0) { $mailles_resume[] = array( 'zoom' => $this->zoom, 'sud' => $maille->getLatitudeSud(), 'ouest' => $maille->getLongitudeOuest(), 'nord' => $maille->getLatitudeNord(), 'est' => $maille->getLongitudeEst(), 'indexLat' => $maille->getIndexLatitude(), 'indexLng' => $maille->getIndexLongitude(), 'points' => $maille->getNombrePoints(), 'observations' => $maille->getNombreObservations() ); } } } return $mailles_resume; } private function formaterPourQuadtree() { $mailles_resume = array(); foreach ($this->mailles as $ligne) { foreach ($ligne as $maille) { if ($maille->getNombrePoints() > 0) { $mailles_resume[] = array( 'zoom' => $this->zoom, 'sud' => $maille->getLatitudeSud(), 'ouest' => $maille->getLongitudeOuest(), 'nord' => $maille->getLatitudeNord(), 'est' => $maille->getLongitudeEst(), 'indexLat' => $maille->getIndexLatitude(), 'indexLng' => $maille->getIndexLongitude(), 'points' => $maille->getPoints() ); } } } return $mailles_resume; } public function redecouperMailles() { $mailles = $this->formaterPourQuadtree(); $this->viderMailles(); while (count($mailles)>0) { $nouvellesMailles = $this->genererMaillesParQuadtree($mailles[count($mailles)-1]); foreach ($nouvellesMailles as $maille) { $this->ajouterMaille($maille); } array_pop($mailles); } $this->zoom += 1; } private function viderMailles() { while (count($this->indexLatitude) > 0) { array_pop($this->indexLatitude); } while (count($this->indexLongitude) > 0) { array_pop($this->indexLongitude); } while (count($this->mailles) > 0) { array_pop($this->mailles); } } private function genererMaillesParQuadtree(& $maille) { $ouest = $maille['ouest']; $est = $maille['est']; $sud = $maille['sud']; $nord = $maille['nord']; $indexLat = $maille['indexLat']; $indexLng = $maille['indexLng']; $milieuLongitude = $this->convertirFloatToString(($ouest + $est)/2); $milieuLatitude = $this->calculerMilieuLatitudes($sud, $nord); // sens des mailles : NordOuest, NordEst, SudOuest, SudEst $mailles = array(); $mailles[] = new Maille($milieuLatitude, $ouest, $nord, $milieuLongitude, $indexLat*2, $indexLng*2); $mailles[] = new Maille($milieuLatitude, $milieuLongitude, $nord, $est, $indexLat*2, $indexLng*2+1); $mailles[] = new Maille($sud, $ouest, $milieuLatitude, $milieuLongitude, $indexLat*2+1, $indexLng*2); $mailles[] = new Maille($sud, $milieuLongitude, $milieuLatitude, $est, $indexLat*2+1, $indexLng*2+1); $this->deplacerPoints($maille, $mailles); return $mailles; } private function calculerMilieuLatitudes($latitudeSud, $latitudeNord) { $ySud = log(tan((90 + $latitudeSud) * M_PI / 360.0 )) / (M_PI / 180.0) * ($this->origine/180.0); $yNord = log(tan((90 + $latitudeNord) * M_PI / 360.0 )) / (M_PI / 180.0) * ($this->origine/180.0); $yMilieu = ($ySud+$yNord) / 2; $latitude = ($yMilieu / $this->origine) * 180.0; $latitude = 180 / M_PI * (2 * atan(exp($latitude * M_PI / 180.0)) - M_PI / 2.0); return $this->convertirFloatToString($latitude); } private function deplacerPoints(& $maille, & $sousMailles) { $nombrePoints = count($maille['points']); for ($index = 0; $index < $nombrePoints; $index ++) { $position = ($maille['points'][$index]['latitude']>=$sousMailles[0]->getLatitudeSud()) ? 0 : 2; $position += ($maille['points'][$index]['longitude']<$sousMailles[$position]->getLongitudeEst()) ? 0 : 1; $sousMailles[$position]->ajouterPoint($maille['points'][$index]); } } private function ajouterMaille($maille) { $indexLat = $maille->getIndexLatitude(); $indexLng = $maille->getIndexLongitude(); if (!isset($this->indexLongitude[$indexLng])) { $this->indexLongitude[$indexLng] = array($maille->getLongitudeOuest(), $maille->getLongitudeEst()); $this->mailles[$indexLng] = array(); } if (!isset($this->indexLongitude[$indexLat])) { $this->indexLatitude[$indexLat] = array($maille->getLatitudeSud(), $maille->getLatitudeNord()); } $this->mailles[$indexLng][$indexLat] = $maille; } private function convertirFloatToString($float) { return str_replace(',', '.', strval($float)); } } ?>