map_hold = $map_hold; $this->holds = $holds; $this->clusters = array(); if(is_object($this->map_hold)) { $this->init(); $this->map_hold->get_coords(); } } public function init(){ global $opac_map_hold_distance; $query = "select Area(geomfromtext('".$this->map_hold->get_wkt()."')) as area"; $result = pmb_mysql_query($query); if(pmb_mysql_num_rows($result)){ $row = pmb_mysql_fetch_object($result); $this->map_area = $row->area; } $map_coords = $this->map_hold->get_coords(); /** * La fonction SQL enveloppe renvoi une emprise normalisée telle que: POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY)) * La distance mini se trouve donc entre les points 0 et 3 (le point 4 étant le point de fermeture du polygone) */ $this->map_distance = (sqrt(pow(($map_coords[0]->get_decimal_long() - $map_coords[3]->get_decimal_long()),2) + pow(($map_coords[0]->get_decimal_lat() - $map_coords[3]->get_decimal_lat()),2)))/$opac_map_hold_distance; } /** * Retourne les emprises correspondantes à la réduction * @param int hold_max Nombre maximum d'emprise présentes sur une couche de la carte * @return void */ public function get_reduction(){ global $opac_map_hold_ratio_max, $opac_map_hold_ratio_min; $this->dicho($opac_map_hold_ratio_min, $opac_map_hold_ratio_max); foreach($this->clustered_holds as $key => $hold){ $clustered = false; if(!count($this->clusters)){ $this->clusters[$key] = $hold; }else{ foreach($this->clusters as $keyC => $holdC){ if($this->shouldCluster($holdC, $hold)){ if(is_array($holdC->get_num_object())){ $num_obj = $holdC->get_num_object(); if(!in_array($hold->get_num_object(), $num_obj)){ $num_obj[] = $hold->get_num_object(); $holdC->set_num_object($num_obj); } }else{ if($holdC->get_num_object() != $hold->get_num_object()){ $holdC->set_num_object(array($holdC->get_num_object(), $hold->get_num_object())); } } $clustered = true; break; } } if(!$clustered){ $this->clusters[$key] = $hold; } } } foreach($this->clusters as $key => $hold){ $wkt = $hold->get_center(); $this->clusters[$key] = new map_hold_point("point", $hold->get_num_object()); $this->clusters[$key]->set_wkt($wkt); } uasort($this->displayed_holds, array('self', 'cmp_area')); return array_merge($this->displayed_holds, $this->clusters); } public function get_occupation_percentage($hold){ return ($hold->get_normalized_bbox_area()/$this->map_area)*100; } public function get_point_center($hold){ global $dbh; $query = "select AsText(Centroid(geomfromtext('".$hold->get_wkt()."'))) as center"; $result = pmb_mysql_query($query, $dbh); if(pmb_mysql_num_rows($result)){ $row = pmb_mysql_fetch_object($result); $hold_wkt = $row->center; return $hold_wkt; } } public function shouldCluster($cluster, $hold){ $coords_cluster = explode(" ",substr($cluster->get_center(),strpos($cluster->get_center(),"(")+1,-1)); $coords_hold = explode(" ",substr($hold->get_center(),strpos($hold->get_center(),"(")+1,-1)); $distance = sqrt(pow(($coords_cluster[0] - $coords_hold[0]),2) + pow(($coords_cluster[1] - $coords_hold[1]),2)); return ($distance <= $this->map_distance); } public function check_wkt($holds, $wkt_string){ foreach($holds as $num => $hold){ if($hold->get_wkt() == $wkt_string){ return $num; } } return false; } public function simplify_polygon($wkt){ $parts = explode(',', $wkt); $new = ""; $start = array_shift($parts); $stop = array_pop($parts); for($j=0 ; $j<=count($parts) ; $j++){ if($j % 2) $new.= ",".$parts[$j]; } if(!(count($parts) % 2)){ $new.=","; } $wkt = $start.$new.$stop; return $wkt; } public function dicho($min, $max){ global $opac_map_max_holds, $opac_map_hold_ratio_min; $params = explode(",", $opac_map_max_holds); if($params[1] == "1" && count($this->holds)>$params[0]){ $min = $max; } //print " min ".$min." max ".$max; $nb_emprise_min = $this->calc_empr($min); $nb_emprise_max = $this->calc_empr($max); if($nb_emprise_max >= $params[0]){ //Avec le seuil max, on a déjà trop d'emprise, on ne continue pas. return; } if($nb_emprise_min <= $params[0]){ $this->calc_empr($min); //On a un nombre convenable d'emprise avec le seuil min, on s'arrête return; } $mid = (($max-$min)/2)+$min; if((($max-$min)/2) <= $opac_map_hold_ratio_min){ $this->calc_empr($mid); //On s'arrête car le seuil est inférieur au seuil mini return; } $nb_emprise_seuil = $this->calc_empr($mid); if($nb_emprise_seuil < $params[0]){ return $this->dicho($min, $mid); }else if($nb_emprise_seuil == $params[0]){ return; }else{ return $this->dicho($mid, $max); } } public function calc_empr($seuil_min){ $this->displayed_holds = array(); $this->clusters = array(); $this->clustered_holds=$this->holds; return array(); } /* public function calc_empr($seuil_min){ global $opac_map_hold_ratio_max; $this->displayed_holds = array(); $this->clustered_holds = array(); $this->clusters = array(); foreach($this->holds as $key => $hold){ if($this->get_occupation_percentage($hold) > $seuil_min){//ces emprises doivent être affichées //quand il y a une seule emprise, $this->get_occupation_percentage($hold) renvoie 100 if ($this->get_occupation_percentage($hold) < $opac_map_hold_ratio_max || count($this->holds) == 1){ $existant_key = $this->check_wkt($this->displayed_holds, $hold->get_wkt()); if($existant_key != false){ if(is_array($this->displayed_holds[$existant_key]->get_num_object())){ $num_obj = $this->displayed_holds[$existant_key]->get_num_object(); $num_obj[] = $hold->get_num_object(); $this->displayed_holds[$existant_key]->set_num_object($num_obj); }else{ $this->displayed_holds[$existant_key]->set_num_object(array($this->displayed_holds[$existant_key]->get_num_object(), $hold->get_num_object())); } }else{ $this->displayed_holds[$key] = $hold; if(count($this->displayed_holds[$key]->get_wkt())>1000 && $this->displayed_holds[$key]->get_hold_type()=="POLYGON"){ $this->displayed_holds[$key]->set_wkt($this->simplify_polygon($this->displayed_holds[$key]->get_wkt())); } } }//Trop grandes non affichées }else{//celles ci doivent etre reduite a un point $this->clustered_holds[$key] = $hold; } } return count($this->displayed_holds); } */ public static function cmp_area($a, $b) { if ($a->get_normalized_bbox_area() == $b->get_normalized_bbox_area()) { return 0; } return ($a->get_normalized_bbox_area() > $b->get_normalized_bbox_area()) ? -1 : 1; } }