X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_action%28%22logout%22%2C%22logout=prive%22%29%20.%20%22?a=blobdiff_plain;f=www%2Fplugins%2Fgis%2Fgis_fonctions.php;h=5df9b7d2f8963f950dc628bd27d83f766da58643;hb=c0f18416f529232b5555c6410a8765a5125ebcd3;hp=72f98c547c323d51a92db6a7c70d2bc819f99a03;hpb=50522c53acc9e61a4a7de3a1890c4ba93e2f61b4;p=lhc%2Fweb%2Fwww.git diff --git a/www/plugins/gis/gis_fonctions.php b/www/plugins/gis/gis_fonctions.php index 72f98c54..5df9b7d2 100755 --- a/www/plugins/gis/gis_fonctions.php +++ b/www/plugins/gis/gis_fonctions.php @@ -1,49 +1,51 @@ 0 and $from = sql_fetsel('lat,lon','spip_gis',"id_gis=$from")) - ) - and - // Le distant est soit un tableau soit un entier - ( - (is_array($to) and isset($to['lat']) and isset($to['lon'])) - or - ($to = intval($to) and $to > 0 and $to = sql_fetsel('lat,lon','spip_gis',"id_gis=$to")) - ) - ){ + if (((is_array($from) and isset($from['lat']) and isset($from['lon'])) // Le départ est soit un tableau soit un entier + or ($from = intval($from) and $from > 0 and $from = sql_fetsel('lat,lon', 'spip_gis', "id_gis=$from"))) + and ((is_array($to) and isset($to['lat']) and isset($to['lon'])) or ($to = intval($to) and $to > 0 and $to = sql_fetsel('lat,lon', 'spip_gis', "id_gis=$to"))) // Le distant est soit un tableau soit un entier + ) { $pi80 = M_PI / 180; $from['lat'] *= $pi80; $from['lon'] *= $pi80; @@ -85,13 +76,46 @@ function distance($from, $to, $miles=false) { return ($miles ? ($km * 0.621371192) : $km); } - + return false; } +/** + * Afficher proprement une distance + * + * @param float $distance + * Nombre indiquant une distance + * @param int $precision + * Précision des décimales du nombre final, par défaut 2 + * @param string $format_entree + * Format de distance donnée en entrée : par défaut en kilomètres, sinon en mètres avec "m" + * @return string + * Retourne une chaine composée d'un nombre arrondi et d'une unité de mesure de distance + **/ +function distance_en_metres($distance, $precision=2, $format_entree='km') { + if ($distance) { + // On passe toujours tout en kilomètres pour uniformiser + if ($format_entree == 'm') { + $distance = $distance / 1000; + } + + // Si c'est supérieur à 1, on reste en kilomètres + if ($distance > 1) { + $unite = 'km'; + } + elseif (($distance = $distance*1000) > 1) { + $unite = 'm'; + } + + $distance = number_format($distance, $precision, ',', '') . ' ' . $unite; + } + + return $distance; +} + /** * Compilation du critère {distancefrom} - * + * * Critère {distancefrom} qui permet de ne sélectionner que les objets se trouvant à une distance comparée avec un point de repère. * On doit lui passer 3 paramètres obligatoires : * - le point de repère qui est un tableau avec les clés "lat" et "lon" ou un id_gis @@ -110,13 +134,10 @@ function critere_distancefrom_dist($idb, &$boucles, $crit) { $id_table = $boucle->id_table; // articles $primary = $boucle->primary; // id_article $objet = objet_type($id_table); // article - - if ( - // Soit depuis une boucle (GIS) soit un autre objet mais avec {gis} - ($id_table == 'gis' or isset($boucle->join['gis'])) - // Il faut aussi qu'il y ait 3 critères obligatoires - and count($crit->param) == 3 - ){ + + if (($id_table == 'gis' or isset($boucle->join['gis'])) // Soit depuis une boucle (GIS) soit un autre objet mais avec {gis} + and count($crit->param) == 3 // Il faut aussi qu'il y ait 3 critères obligatoires + ) { $point_reference = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent); $operateur = calculer_liste($crit->param[1], array(), $boucles, $boucles[$idb]->id_parent); $distance = calculer_liste($crit->param[2], array(), $boucles, $boucles[$idb]->id_parent); @@ -130,7 +151,7 @@ function critere_distancefrom_dist($idb, &$boucles, $crit) { $boucle->hierarchie .= '$operateur_distance = trim('.$operateur.');'; $boucle->hierarchie .= 'if (!in_array($operateur_distance, array("=","<",">","<=",">="))){ $operateur_distance = false; }'; $boucle->hierarchie .= '$distance = '.$distance.';'; - + $boucle->select[] = '".(!$point_reference ? "\'\' as distance" : "(6371 * acos( cos( radians(".$point_reference["lat"].") ) * cos( radians( gis.lat ) ) * cos( radians( gis.lon ) - radians(".$point_reference["lon"].") ) + sin( radians(".$point_reference["lat"].") ) * sin( radians( gis.lat ) ) ) ) AS distance")."'; $boucle->having[] = '((!$point_reference or !$operateur_distance or !$distance) ? "1=1" : "distance $operateur_distance ".sql_quote($distance))'; } @@ -153,59 +174,57 @@ function critere_gis_dist($idb, &$boucles, $crit) { $id_table = $boucle->id_table; // articles $primary = $boucle->primary; // id_article $objet = objet_type($id_table); // article - + if ($id_table == 'gis') { // exclure l'élément en cours des résultats - $id_gis = calculer_argument_precedent($idb,$primary, $boucles); + $id_gis = calculer_argument_precedent($idb, $primary, $boucles); $boucle->where[]= array("'!='", "'$boucle->id_table." . "$primary'", $id_gis); - + // récupérer les paramètres du critère $op=''; $params = $crit->param; $type = array_shift($params); $type = $type[0]->texte; - if(preg_match(',^(\w+)([<>=]+)([0-9]+)$,',$type,$r)){ + if (preg_match(',^(\w+)([<>=]+)([0-9]+)$,', $type, $r)) { $type=$r[1]; $op=$r[2]; $op_val=$r[3]; } - if ($op) + if ($op) { $boucle->having[]= array("'".$op."'", "'".$type."'",$op_val); - + } + // récupérer lat/lon du point de la boucle englobante - $lat = calculer_argument_precedent($idb,'lat', $boucles); - $lon = calculer_argument_precedent($idb,'lon', $boucles); - + $lat = calculer_argument_precedent($idb, 'lat', $boucles); + $lon = calculer_argument_precedent($idb, 'lon', $boucles); + // http://www.awelty.fr/developpement-web/php/ // http://www.movable-type.co.uk/scripts/latlong-db.html // http://code.google.com/intl/fr/apis/maps/articles/geospatial.html#geospatial $select = "(6371 * acos( cos( radians(\".$lat.\") ) * cos( radians( gis.lat ) ) * cos( radians( gis.lon ) - radians(\".$lon.\") ) + sin( radians(\".$lat.\") ) * sin( radians( gis.lat ) ) ) ) AS distance"; $order = "'distance'"; - + $boucle->select[]= $select; $boucle->order[]= $order; } else { - /* Recherche d'objets SANS point */ if ($crit->not) { $boucle->from['gis_liens'] = 'spip_gis_liens'; - $boucle->from_type['gis_liens'] = "LEFT"; + $boucle->from_type['gis_liens'] = 'LEFT'; $boucle->join['gis_liens'] = array("'$id_table'","'id_objet'","'$primary'","'gis_liens.objet='.sql_quote('$objet')"); $boucle->where[] = "'gis_liens.id_gis IS NULL'"; /* Recherche d'objets AVEC point + ajout des champs GIS */ } else { - // ajouter tous les champs du point au select + // ajouter tous les champs du point au select // et les suffixer pour lever toute ambiguite avec des champs homonymes - $boucle->select[]= 'gis.titre AS titre_gis'; - $boucle->select[]= 'gis.descriptif AS descriptif_gis'; - $boucle->select[]= 'gis.adresse AS adresse_gis'; - $boucle->select[]= 'gis.pays AS pays_gis'; - $boucle->select[]= 'gis.code_pays AS code_pays_gis'; - $boucle->select[]= 'gis.region AS region_gis'; - $boucle->select[]= 'gis.departement AS departement_gis'; - $boucle->select[]= 'gis.ville AS ville_gis'; - $boucle->select[]= 'gis.code_postal AS code_postal_gis'; + if (!function_exists('objet_info')) { + include_spip('inc/filtres'); + } + $champs = objet_info('gis', 'champs_critere_gis'); + foreach ($champs as $champ) { + $boucle->select[] = $champ; + } // jointure sur spip_gis_liens/spip_gis // cf plugin notation // $boucle->join["surnom (as) table de liaison"] = array("surnom de la table a lier", "cle primaire de la table de liaison", "identifiant a lier", "type d'objet de l'identifiant"); @@ -217,7 +236,7 @@ function critere_gis_dist($idb, &$boucles, $crit) { // mais attention, si on trouve en amont un groupement portant sur un champ *de GIS*, // alors cela signifie que la personne veut faire une opération de groupement sur les points donc là on n'ajoute pas id_gis $tous_les_points = true; - foreach ($boucle->group as $champ){ + foreach ($boucle->group as $champ) { if (in_array($champ, array('ville', 'code_postal', 'pays', 'code_pays', 'region','departement'))) { $tous_les_points = false; } @@ -229,15 +248,22 @@ function critere_gis_dist($idb, &$boucles, $crit) { // permet de passer dans trouver_champ_exterieur() depuis index_tables_en_pile() // cf http://article.gmane.org/gmane.comp.web.spip.zone/6628 $boucle->jointures[] = 'gis'; - if (empty($boucle->jointures_explicites)){ + if (empty($boucle->jointures_explicites)) { $boucle->jointures_explicites = 'gis_liens gis'; - } - else{ + } else { $boucle->jointures_explicites .= ' gis_liens gis'; } } } } +function critere_gis_tout_dist($idb, &$boucles, $crit) { + $crit->op = 'gis'; + $critere_gis = charger_fonction('gis', 'critere/'); + $critere_gis($idb, $boucles, $crit); + $boucle = &$boucles[$idb]; + $boucle->from_type['gis_liens'] = 'LEFT'; + $boucle->from_type['gis'] = 'LEFT'; +} /** * Balise #DISTANCE issue du critère {gis distance` + * + * @example `#ENV{kml}|gis_param_to_array` + * + * @param string|int|array $param + * Le paramètre à transformer en tableau + * @param string $sep + * Le séparateur utilisé + * @return array +**/ +function gis_param_to_array($param, $sep = ',') { + if (is_array($param)) { + return $param; + } + // enlever les espaces et exploser + $tab = explode($sep, trim((string)$param)); + // enlever les champs vides, les espaces sur chaques champs. + return array_map('trim', array_filter($tab)); +} + /** * Transformer le tableau de kml en tableau d'urls : * si numerique c'est un id de document @@ -391,16 +446,16 @@ function gis_modele_url_json_env($env){ * @param array $kml * @return array */ -function gis_kml_to_urls($kml){ - if ($kml AND count($kml)){ - include_spip("inc/filtres_mini"); - include_spip("inc/distant"); - foreach($kml as $k=>$v){ - if (is_numeric($v)){ - $kml[$k] = url_absolue(generer_url_entite($v,"document")); +function gis_kml_to_urls($kml) { + if ($kml and count($kml)) { + include_spip('inc/filtres_mini'); + include_spip('inc/distant'); + foreach ($kml as $k => $v) { + if (is_numeric($v)) { + $kml[$k] = url_absolue(generer_url_entite($v, 'document')); + } else { + $kml[$k] = _DIR_RACINE.copie_locale($kml[$k], 'modif'); } - else - $kml[$k] = _DIR_RACINE.copie_locale($kml[$k],"modif"); } } return $kml; @@ -408,39 +463,47 @@ function gis_kml_to_urls($kml){ /** * Retourne les propriétés JSON de l'icône d'un point - * + * * @param string $img * Balise HTML `` ou chemin de l'image (qui peut être une URL distante). * @return string * Les propriétés de l'icône **/ -function gis_icon_properties($img=''){ +function gis_icon_properties($img = '') { $props = $icon = ''; - + if ($img) { - if (largeur($img) >= 44) - $icon = extraire_attribut(filtrer('image_graver',filtrer('image_recadre',filtrer('image_passe_partout',$img,32,32),32,32,'center','transparent')),'src'); - else - $icon = extraire_attribut($img,'src') ? extraire_attribut($img,'src') : $img; - } - else + if (largeur($img) >= 44) { + $icon = extraire_attribut(filtrer('image_graver', filtrer('image_recadre', filtrer('image_passe_partout', $img, 32, 32), 32, 32, 'center', 'transparent')), 'src'); + } else { + $icon = extraire_attribut($img, 'src') ? extraire_attribut($img, 'src') : $img; + } + } else { $icon = find_in_path('images/marker_defaut.png'); - + } + if ($icon) { - $props .= ",\n\"icon\": ". json_encode(url_absolue($icon)).","; + $props .= ",\n\t\t\t\"icon\": ". json_encode(url_absolue($icon)).','; list($h,$w) = taille_image($icon); - $props .= "\n\"icon_size\": ". json_encode(array($w,$h)).","; - $props .= "\n\"icon_anchor\": ". json_encode(array($w/2,$h)).","; - $props .= "\n\"popup_anchor\": ". json_encode(array(1,-round($h/1.2,2))); + $props .= "\n\t\t\t\"icon_size\": ". json_encode(array($w,$h)).','; + /** + * Si l'icone est carrée, on considère que c'est soit un point soit un carré qui pointe un lieu et non une "goutte" + * On centre donc au milieu de l'icone + */ + if ($w == $h) { + $props .= "\n\t\t\t\"icon_anchor\": ". json_encode(array($w/2, $h/2)).','; + $props .= "\n\t\t\t\"popup_anchor\": ". json_encode(array(0,0)); + } else { + $props .= "\n\t\t\t\"icon_anchor\": ". json_encode(array($w/2, $h)).','; + $props .= "\n\t\t\t\"popup_anchor\": ". json_encode(array(1, -round($h/1.2, 2))); + } } - + if ($shadow = find_in_path('images/marker_defaut_shadow.png')) { - $props .= ",\n\"shadow\": ". json_encode(url_absolue($shadow)); + $props .= ",\n\t\t\t\"shadow\": ". json_encode(url_absolue($shadow)); list($h,$w) = taille_image($shadow); - $props .= ",\n\"shadow_size\": ". json_encode(array($w,$h)); + $props .= ",\n\t\t\t\"shadow_size\": ". json_encode(array($w,$h)); } - + return $props; } - -?>