" 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;}
}