5. Pequeño error con las direcciones inexistentes en Phoogle

El 30 de octubre de 2008 dejaba un mensaje en el Grupo Google CakePHP en Español explicando que tenía un problema porque el helper Phoogle no funcionaba cuando el usuario introducía una dirección inexistente. Pues bien, en este post propongo una solución; allá va:

Después de instalar el ayudante Phoogle empecé a hacer algunas pruebas, introduciendo direcciones vacías e inexistentes, y PHP lanzaba varios avisos. Para eliminar los de tipo Use of undefined constant Response hay que poner comillas simples en todos los Response del método addAddress.

A continación, después de este cambio, si uno vuelve a probar la clase e introduce una dirección inexistente, PHP lanza dos avisos de tipo Undefined index que corresponen a las dos líneas del método addAddress recién cambiadas.

La responsable es esta línea,

 $results = $this->xml2array(utf8_encode($addressData)); 

junto con el tratamiento que le da el método addAddress, que puedes ver aquí

 

Esta instrucción convierte el documento XML de Google en una matriz asociativa y utiliza el método xml2array de la clase assoc_array2xml -el autor de esta clase es Roger Veciana, está distribuida bajo la licencia BSD y puede obtenerse en www.phpclasses.org-.

Sucede que las etiquetas del XML que envía Google varían, dependiendo de si la dirección que introduce el usuario existe o no, y, como consecuencia de esto, también lo hacen los índices de la matriz asociativa $results.

Si la dirección no existe, el contenido de $results es este:

 

Array ( [kml] => Array ( [Response] => Array ( [name] => [Status] => Array ( => 601 [request] => geocode ) ) ) )

 

porque el documento XML es el siguiente:

  

<?xml version=”1.0″ encoding=”UTF-8″ ?>

<kml xmlns=”http://earth.google.com/kml/2.0“>

<Response>

  <name>jkfowioj23</name>

<Status>

  <code>602</code>

  <request>geocode</request>

  </Status>

  </Response>

  </kml>

 

El método addAddress falla porque intenta obtener las coordenadas geográficas a partir de unas etiquetas que el documento XML anterior no tiene. Por otra parte, si la dirección existe, el contenido de $results es este:

  

Array ( [kml] => Array ( [Response] => Array ( [name] => barcelona sagrada familia 2 [Status] => Array ( => 200 [request] => geocode ) [Placemark] => Array ( [address] => Aviny , 20, 08002, Barcelona, Spain [AddressDetails] => Array ( [Country] => Array ( [CountryNameCode] => ES [CountryName] => Spain [AdministrativeArea] => Array ( [AdministrativeAreaName] => CT [SubAdministrativeArea] => Array ( [SubAdministrativeAreaName] => Barcelona [Locality] => Array ( [LocalityName] => Barcelona [Thoroughfare] => Array ( [ThoroughfareName] => Aviny 20 [AddressLine] => Sagrada Familia ) [PostalCode] => Array ( [PostalCodeNumber] => 08002 ) ) ) ) ) ) [ExtendedData] => Array ( [LatLonBox] => Array ( [north] => 41.381122 [south] => 41.381122 [east] => 2.176690 [west] => 2.176690 ) ) [Point] => Array ( [coordinates] => 2.176690,41.381122,0 ) ) ) ) )

 

porque ahora el documento XML es este:

  

<?xml version=”1.0″ encoding=”UTF-8″ ?>

<kml xmlns=”http://earth.google.com/kml/2.0“>

<Response>

  <name>barcelona gaudi 2</name>

<Status>

  <code>200</code>

  <request>geocode</request>

  </Status>

<Placemark id=”p1“>

  <address>Avinguda de Gaudí, 2, 08025, Barcelona, España</address>

<AddressDetails Accuracy=”8 xmlns=”urn:oasis:names:tc:ciq:xsdschema:xAL:2.0“>

<Country>

  <CountryNameCode>ES</CountryNameCode>

  <CountryName>España</CountryName>

<AdministrativeArea>

  <AdministrativeAreaName>CT</AdministrativeAreaName>

<SubAdministrativeArea>

  <SubAdministrativeAreaName>Barcelona</SubAdministrativeAreaName>

<Locality>

  <LocalityName>Barcelona</LocalityName>

<Thoroughfare>

  <ThoroughfareName>Avinguda de Gaudí 2</ThoroughfareName>

  </Thoroughfare>

<PostalCode>

  <PostalCodeNumber>08025</PostalCodeNumber>

  </PostalCode>

  </Locality>

  </SubAdministrativeArea>

  </AdministrativeArea>

  </Country>

  </AddressDetails>

<Point>

  <coordinates>2.174498,41.404616,0</coordinates>

  </Point>

  </Placemark>

  </Response>

  </kml>

 

Como no se pueden recuperar las coordenadas geográficas de una dirección incorrecta a partir de un XML como el primero, mi método addAddress modificado no trata estos puntos y queda así:

    

   function addAddress($address,$htmlMessage=null){
    if (!is_string($address)){
      die("All Addresses must be passed as a string");
     }
      $apiURL = "<a href="http://maps.google.com/maps/geo?&output=xml&key=&quot;.$this->apiKey.&quot;&q">http://maps.google.com/maps/geo?&output=xml&key=".$this->apiKey."&q</a>=";
      $addressData = file_get_contents($apiURL.urlencode($address));

      $results = $this->xml2array(utf8_encode($addressData));
      if (empty($results['kml']['Response']['Placemark']['Point']['coordinates'])){
         $pointer = count($this->validPoints);
         $this->validPoints[$pointer]['lat']= '19.4343';
         $this->validPoints[$pointer]['long']= '155.5854';
         $this->validPoints[$pointer]['passedAddress'] = $address;
         $this->validPoints[$pointer]['htmlMessage'] = $htmlMessage;
        }else{
         $pointer = count($this->validPoints);
         $this->validPoints[$pointer]['lat']= $results['kml']['Response']['Placemark']['Point']['coordinates'];
         $this->validPoints[$pointer]['long']= $results['kml']['Response']['Placemark']['Point']['coordinates'];
         $this->validPoints[$pointer]['passedAddress'] = $address;
         $this->validPoints[$pointer]['htmlMessage'] = $htmlMessage;
      }

   }

 

  

Si un usuario se equivoca en el momento de escribir la dirección, o la deja en blanco, la clase entenderá que se trata de un punto correcto, y, en vez de mostrar los avisos anteriores, presentará un mapa de referencia con las coordenadas 19.4343 y 155.58.54.

 

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: