" con la url //de googlemaps. Si se ha definido una apikey se incluye private $_isAutoApikey = true; //Indica si se va a incluir la libreria jquery desde google. //Si dispones de una copia local se puede desactivar. private $_useGoogleJquery = true; //FOR JS //Estos son parametros de configuración para el archivo: js_google_map_3.js private $_arMarkers = "[]"; //Las chinchetas private $_useMakersNumbers = true; //Si las chinchetas mostrarán números. private $_sMapType = "'roadmap'"; //El tipo de mapa. //Elemento div donde se mostrará el mapa generado. private $_sIdDivContainer = "'map_canvas'"; //El zoom private $_iZoom = 6; //Punto inicial de muestreo. Cuando se crea el mapa debe mostrar algún punto //he escogido las coord. de la Puerta del Sol (Madrid) private $_fLatitude = 40.41694; private $_fLongitude = -3.70361; //Indica si ha de pintarse lineas entre las chinchetas (Markers). private $_drawLines = false; //Configuración del tamaño del mapa y su unidad. private $_iWidth = 800; private $_iHeight = 600; private $_sUnitWH = "px"; //FOR PHP //Parametros para hacer peticiones de latitud y longitud de una dirección //Url para enviar peticiones por get. Devolvera un objeto xml private $_sUrlAskAddress = "http://maps.googleapis.com/maps/api/geocode/xml"; //Indica si se ha de acotar la busqueda de una dirección. //Evita que te encuentre una dirección equivalente en otro país. private $_doNarrowSearch = true; //Coordenadas de acotación de España. Peninsula y Canarias. private $_arNarrowLat = array("min"=>24.654534254781115,"max"=>45.18786629495072); private $_arNarrowLong = array("min"=>-19.80908203125, "max"=>4.3828125); //TODO: Direcciones a geolocalizar. Lo dejaré para otra versión. private $_arAddresses = array(); //Indica si se ha de esperar x microsegundos a que responda la url de petición private $_useDelay = true; private $_iDelayTime = 250; //Indicadores del estado de la petición de geolocalización. private $_is_error = false; private $_message = ""; /** * Formato del array de marcadores: $arMarkers[]=array ( "title"=>"un titulo ", Lo que se mostrara al pasar el raton "content"=>"Un contenido", El texto dentro del popup de dialogo "latitude"=>"36.643271085342", "longitude"=>"-4.578660819468" ); * @param array $arMarkers Array anidado tipo tabla filas x columnas * @param array $arAddresses TODO próxima entrega ;0) */ public function __construct($arMarkers=array(),$arAddresses=array(),$sApikey="") { $this->_arMarkers = $arMarkers; $this->_arAddresses = $arAddresses; if(!empty($sApikey)) $this->_sApikey = $sApikey; } //Pasa al objeto javascript los datos configurados en esta clase y despues //ejecuta load_map(), función javascript que dibuja el mapa con los datos //de configuración. public function draw_map() { if($this->_useGoogleJquery) $this->show_google_jquery_tag(); if($this->_isAutoApikey) $this->show_apikey_tag(); ?> get_js_as_array_table(); } /* * Devuelve un string js con el formato de un array generado desde * $this_arMarkers */ private function get_js_as_array_table() { $arTable = $this->_arMarkers; $arItems = array(); $sJsArray = "["; foreach($arTable as $i=>$arRow) $arItems[] = $this->get_as_js_array_row($arRow); if(!empty($arItems)) $sJsArray .= implode(",", $arItems); $sJsArray .= "]"; return $sJsArray; } /** * Se le pasa un array de tipo columnas y lo convierte en array js * @param array $arRow tipo array("nombre_columna"=>"valor",..,) * @return string Cadena de texto en formato array */ private function get_as_js_array_row($arRow=array()) { $arItems = array(); $sJsArray = "["; foreach($arRow as $key=>$sFieldValue) { switch($key) { case "content": case "title": $arItems[] = $this->get_as_js_string($sFieldValue); break; case "number": case "latitude": case "longitude": case "zindex": $arItems[] = $sFieldValue; break; } } if(!empty($arItems)) $sJsArray .= implode(",", $arItems); $sJsArray .= "]\n"; return $sJsArray; //['sTitle', fLat, fLong, iZindex, sContent, iIconNumber] } /** * Se utiliza para generar un array de substrings * @param string $sValue * @return string algo como '1'. Asi js lo entenderá como un string. */ private function get_as_js_string($sValue) { return "'$sValue'"; } /** * * @param array $arPoint1 array("latitude"=>valor,"longitude"=>valor) * @param array $arPoint2 array("latitude"=>valor,"longitude"=>valor) * @return float distancia redondeada a dos decimales. */ public function distance_calculation(array $arPoint1, array $arPoint2) { $fX1 = $arPoint1["latitude"]; $fY1 = $arPoint1["longitude"]; $fX2 = $arPoint2["latitude"]; $fY2 = $arPoint2["longitude"]; if(is_numeric($fX1)&&is_numeric($fY1)&&is_numeric($fX2)&&is_numeric($fY2)) $fX1 = sqrt(pow(($fX1 - $fX2),2) + pow(($fY1-$fY2),2)); $fX1 = round($fX1, 2); return (float)$fX1; } /* * Dependiendo de los datos de las chinchetas se va calculando las distancias * ojo, NO EL RECORRIDO. */ public function sum_distance() { $arPoint1 = array("latitude"=>0,"longitude"=>0); $arPoint2 = array("latitude"=>0,"longitude"=>0); $iNumMarkers =count($this->_arMarkers); $fDistance = 0; for($i=0; $i<$iNumMarkers-1; $i++) { $arPoint1["latitude"] = $this->_arMarkers[$i]["latitude"]; $arPoint1["longitude"] = $this->_arMarkers[$i]["longitude"]; $arPoint2["latitude"] = $this->_arMarkers[$i+1]["latitude"]; $arPoint2["longitude"] = $this->_arMarkers[$i+1]["longitude"]; $fDistance += $this->distance_calculation($arPoint1, $arPoint2); } return (float)$fDistance; } //GETTERS public function get_markers(){return $this->_arMarkers;} public function is_makers_with_numbers() { if($this->_useMakersNumbers) echo "true"; else echo "false"; } public function do_draw_lines() { if($this->_drawLines) echo "true"; else echo "false"; } /** * Segun un array con datos de una dirección se recupera su latitud y longitud * @param array $arAddress array("pais"=>"España","direccion"=>"Conde de Peñalver 32", "zona"=>"Madrid", "cp"=>"28006"); */ public function get_latlong_from_address(array $arAddress) { $arLl = array("latitude"=>"","longitude"=>""); if(!empty($arAddress)) { $sGmapAskAddress = $this->_sUrlAskAddress; //Une con comas el array $sAddrForUrl = join(", ",$arAddress); //codifica el string en utf $sAddrForUrl = utf8_encode($sAddrForUrl); //codifica el string en formato url $sAddrForUrl = urldecode($sAddrForUrl); //sustituye espacios por el caracter + $sAddrForUrl = str_replace(" ", "+", $sAddrForUrl); $sGmapAskAddress = $sGmapAskAddress."?address=".$sAddrForUrl."&sensor=false"; //bug($sGmapAskAddress); $oXml = simplexml_load_file($sGmapAskAddress); //bug($oXml); die; //Dependiendo de cuanto esté ocupado el servidor de google puede tardar mas ó menos. //Para asegurarnos que se cree correctamente el objeto xml con los detalles de la dirección pedida //forzamos a que el archivo espere unos instantes if($this->_useDelay) usleep($this->_iDelayTime);//microsegundos if($oXml!=false) { //bug($oXml); $sXmlStatus = $oXml->status; //status ok. Se ha localizado la dirección if(strcmp($sXmlStatus,"OK") == 0) { $fLatitude = $oXml->result->geometry->location->lat;//v3 $fLongitude = $oXml->result->geometry->location->lng;//v3 $fLatitude = (float) $fLatitude; $fLongitude = (float) $fLongitude; //bug($fLatitude,"latitud"); bug($fLongitude,"longitud"); if($this->_doNarrowSearch) { if($this->is_in_range_latlong($fLatitude, $fLongitude)) { $arLl["latitude"]=$fLatitude; $arLl["longitude"]=$fLongitude; $this->_message = "Dirección encontrada"; } //fuera de rango else { //bug("fuera de rango"); $this->set_message_error("Dirección fuera de rango: Lat:$fLatitude, Long:$fLongitude"); } } //No se usa acotación else { $arLl["latitude"]=$fLatitude; $arLl["longitude"]=$fLongitude; $this->_message = "Dirección encontrada"; } } //status de xml fallido else { $this->set_message_error("La dirección $sAddrForUrl no se pudo geolocalizar. Estado=$sXmlStatus"); } } //error en simplexml_load_file else { $this->set_message_error("No se ha podido crear xml desde: $sGmapAskAddress"); } } return $arLl; } /** * Determina si las coordenadas obtenidas de una dirección está dentro de los limites * de acotación * @param float $fLatitude * @param float $fLongitude * @return boolean */ private function is_in_range_latlong($fLatitude=0.0,$fLongitude=0.0) { //bug($this->_arNarrowLat,"lat"); bug($fLatitude,"lat"); bug($this->_arNarrowLong,"long"); bug($fLongitude,"long"); //bug($this->comapre_float($fLatitude,"<",$this->_arNarrowLat["max"]),"lat < latmax?"); //bug($this->comapre_float($this->_arNarrowLat["min"],"<",$fLatitude),"latmin > latitude?"); //bug($this->comapre_float($fLongitude,"<",$this->_arNarrowLong["max"]),"long < longmax?"); //bug($this->comapre_float($this->_arNarrowLong["min"],"<",$fLongitude),"longmin > longitude?"); $isInRange = ( $this->comapre_float($fLatitude,"<",$this->_arNarrowLat["max"]) && $this->comapre_float($this->_arNarrowLat["min"],"<",$fLatitude) && $this->comapre_float($fLongitude,"<",$this->_arNarrowLong["max"]) && $this->comapre_float($this->_arNarrowLong["min"],"<",$fLongitude) ); return $isInRange; } /** * Función para comparar números en coma flotante (eaf) * La comparación de números en coma flotante no es tribial. No se puede * utilizar por ejemplo: $float1>$float2... es decir, los operadores comunes. * Esta función pasa los numeros a binarios con una precision marcada * @param float $float1 * @param char $cOperator =, <, >, <=, >= != * @param float $float2 * @param integer $iPrecision * @return boolean o "operator error"; */ private function comapre_float($float1,$cOperator="=",$float2,$iPrecision=10) { //Siempre la comparación se hace de float1 con respecto a float1 // si el resultado es: 0 son igulaes, -1 f1 menor, 1 f1 mayor switch (trim($cOperator)) { case "=": return bccomp($float1, $float2, $iPrecision)==0; break; case "<": return bccomp($float1, $float2, $iPrecision)==-1; break; case ">": return bccomp($float1, $float2, $iPrecision)==1; break; case "!=": return !(compare_float($float1,"=",$float2, $iPrecision)); break; case ">=": return compare_float($float1,">",$float2, $iPrecision) ||compare_float($float1,"=",$float2, $iPrecision); break; case "<=": return compare_float($float1,"<",$float2, $iPrecision) ||compare_float($float1,"=",$float2, $iPrecision); break; default: return "operator error"; break; } } // public function get_google_jquery() { $sTagJquery = "\n"; return $sTagJquery; } public function show_google_jquery_tag(){echo $this->get_google_jquery();} public function get_apikey_tag() { $sApiUrl = ""; //bug($this->_sApikey); if(!empty($this->_sApikey)) $sApiUrl = "\n"; else $sApiUrl = "\n"; return $sApiUrl; } public function show_apikey_tag(){echo $this->get_apikey_tag();} private function get_maptype(){echo $this->_sMapType;} private function get_div_container(){echo $this->_sIdDivContainer;} private function get_zoom(){echo $this->_iZoom;} private function get_latitude(){ echo $this->_fLatitude; } private function get_longitude(){ echo $this->_fLongitude; } private function get_height(){echo $this->_iHeight;} private function get_width(){echo $this->_iWidth;} private function get_size_unit(){echo "'$this->_sUnitWH'";} private function get_message(){return $this->_message;} public function get_apikey(){ return $this->_sApikey;} //SETTERS public function set_markers($arMarkers=array()){ $this->_arMarkers = $arMarkers; } public function set_markers_numbers_off($isOn=false){$this->_useMakersNumbers = $isOn;} public function set_maptype($sValue){$this->_sMapType = strtolower("'$sValue'");} public function set_div_container($sValue){ $this->_sIdDivContainer = "'$sValue'"; } public function set_zoom($iZoom){ $this->_iZoom = $iZoom; } public function set_latitude($fLatitude){ $this->_fLatitude = $fLatitude; } public function set_longitude($fLongitude){ $this->_fLongitude = $fLongitude; } public function draw_lines($isOn=true){ $this->_drawLines = $isOn; } public function set_size_container($iWidth=800,$iHeight=600) { if(!empty($iHeight))$this->_iHeight = $iHeight; if(!empty($iWidth)) $this->_iWidth = $iWidth; } public function set_size_unit($sType="pt"){ $this->_sUnitWH = $sType; } public function add_address(array $arAddress){ $this->_arAddresses[] = $arAddress; } private function set_message_error($sMessage,$isError=true) { $this->_is_error = $isError; $this->_message = $sMessage; } /** * Solo influye para recuperar latitud y longitud de direcciones. * No en el pintado de marcadores * @param boolean $isOn */ public function no_narrow($isOn=false){ $this->_doNarrowSearch = $isOn; } public function set_delay_time($iMicroSeconds){$this->_iDelayTime = $iMicroSeconds;} public function no_dalay($isOn=false){ $this->_useDelay = $isOn; } public function set_apikey($sApikey){$this->_sApikey = $sApikey;} public function no_auto_apikey($isOn=false){$this->_isAutoApikey = $isOn;} public function no_google_jquery($isOn=false){$this->_useGoogleJquery = $isOn;} }