Uso de PHP y MySQL para generar KML

https://developers.google.com/kml/articles/phpmysqlkml?hl=es-ES

Este tutorial está destinado a desarrolladores familiarizados con PHP y MySQL y que deseen aprender a generar KML a partir de una base de datos MySQL. Para este tutorial, deberás crear dos secuencias de comandos que generen archivos KML de forma dinámica a partir de una base de datos de ubicaciones en Seattle. La primera secuencia de comandos genera una recopilación de puntos con dos tipos de ubicaciones, restaurantes y bares, delineadas con iconos distintivos. Cuando el usuario hace clic en un marcador, una viñeta muestra el nombre y la información de la dirección. La segunda secuencia de comandos crea una línea que conecta todos los restaurantes. En el tutorial también se explica cómo crear un mapa de Google Maps que muestre los archivos KML y un archivo NetworkLink que dirija al archivo KML y permita al usuario abrirlo en Google Earth.

Este tutorial está basado en el artículo Uso de PHP/MySQL con Google Maps de Pamela Fox, que indica cómo exportar los datos desde una tabla MySQL a Google Maps mediante PHP. Si ya has leído el artículo de Pamela, puedes omitir los dos primeros pasos de este tutorial. El resto de tutorial es considerablemente distinto, puesto que trata sobre KML.

El tutorial se divide en los siguientes pasos:

  1. Crear la tabla
  2. Completar la tabla
  3. Utilizar PHP para generar archivos KML
  4. Visualizar tus archivos KML
  5. Más información

Imagen de Google Earth

Paso 1: crear la tabla

Al crear la tabla MySQL, presta especial atención a los atributos lat y lng. Con las funciones actuales de zoom de Google Maps, sólo necesitas seis dígitos de precisión después de la coma decimal. Para mantener al mínimo el espacio de almacenamiento necesario para nuestra tabla, puedes especificar que los atributos lat y lng sean valores “float” con un tamaño de (10,6). De esta forma, los campos podrán almacenar seis dígitos después de la coma decimal más un máximo de cuatro dígitos anteriores a la coma decimal como, por ejemplo, -123,456789 grados. En la tabla también deberías incluir un atributo id que sirva de clave principal y un atributo type que distinga entre restaurantes y bares.

Nota: este tutorial utiliza datos de la ubicación que ya contienen la información sobre la latitud y la longitud necesaria para establecer los marcadores correspondientes. Si estás intentando emplear tus propios datos que aún no contienen esa información, utiliza un servicio de codificación geográfica por lotes para convertir las direcciones en latitudes y longitudes. Algunos sitios cometen el error de codificar geográficamente las direcciones cada vez que se carga una página y eso hace que la página se cargue más despacio y que se repitan las codificaciones geográficas de forma innecesaria. Cuando sea posible, se recomienda predefinir siempre la información de la latitud y la longitud. Este enlace contiene una amplia lista de codificadores geográficos: http://groups.google.com/group/Google-Maps-API/web/resources-non-google-geocoders.

Para generar la información de la tabla, puedes utilizar la interfaz phpMyAdmin o los comandos SQL. A continuación se indica cómo crear la tabla mediante la interfaz phpMyAdmin.

Esta es la instrucción SQL correspondiente que crea la tabla. phpsqlajax_createtable.sql:

CREATE TABLE 'markers' (
 'id' INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 'name' VARCHAR( 60 ) NOT NULL ,
 'address' VARCHAR( 80 ) NOT NULL ,
 'lat' FLOAT( 10, 6 ) NOT NULL ,
 'lng' FLOAT( 10, 6 ) NOT NULL ,
 'type' VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;

Paso 2: completar la tabla

Una vez creada la tabla, hay que completarla con información. A continuación se proporciona la información de ejemplo de diez ubicaciones de Seattle. Puedes utilizar la pestaña IMPORT, en phpMyAdmin, para importar distintos formatos de archivo, incluidos los archivos CSV (valores separados por coma). Tanto Microsoft Excel como las hojas de cálculo de Google Docs te permiten exportar al formato CSV para poder transferir los datos de una forma sencilla desde las hojas de cálculo a las tablas MySQL mediante la exportación/importación de archivos CSV.

A continuación se muestran los datos de ejemplo en formato CSV. phpsqlajax_data.csv:

Pan Africa Market,'1521 1st Ave, Seattle, WA',47.608941,-122.340145,restaurant
Buddha Thai & Bar,'2222 2nd Ave, Seattle, WA',47.613591,-122.344394,bar
The Melting Pot,'14 Mercer St, Seattle, WA',47.624562,-122.356442,restaurant
Ipanema Grill,'1225 1st Ave, Seattle, WA',47.606366,-122.337656,restaurant
Sake House,'2230 1st Ave, Seattle, WA',47.612825,-122.34567,bar
Crab Pot,'1301 Alaskan Way, Seattle, WA',47.605961,-122.34036,restaurant
Mama's Mexican Kitchen,'2234 2nd Ave, Seattle, WA',47.613975,-122.345467,bar
Wingdome,'1416 E Olive Way, Seattle, WA',47.617215,-122.326584,bar
Piroshky Piroshky,'1908 Pike pl, Seattle, WA',47.610127,-122.342838,restaurant

A continuación se muestra una captura de pantalla de las opciones de importación utilizadas para transformar esos datos en formato CSV en datos de tabla:

Estas son las instrucciones SQL correspondientes. phpsqlajax_data.sql:

INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Pan Africa Market', '1521 1st Ave, Seattle, WA', '47.608941', '-122.340145', 'restaurant');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Buddha Thai & Bar', '2222 2nd Ave, Seattle, WA', '47.613591', '-122.344394', 'bar');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('The Melting Pot', '14 Mercer St, Seattle, WA', '47.624562', '-122.356442', 'restaurant');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Ipanema Grill', '1225 1st Ave, Seattle, WA', '47.606366', '-122.337656', 'restaurant');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Sake House', '2230 1st Ave, Seattle, WA', '47.612825', '-122.34567', 'bar');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Crab Pot', '1301 Alaskan Way, Seattle, WA', '47.605961', '-122.34036', 'restaurant');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Mama\'s Mexican Kitchen', '2234 2nd Ave, Seattle, WA', '47.613975', '-122.345467', 'bar');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Wingdome', '1416 E Olive Way, Seattle, WA', '47.617215', '-122.326584', 'bar');
INSERT INTO 'markers' ('name', 'address', 'lat', 'lng', 'type') VALUES ('Piroshky Piroshky', '1908 Pike pl, Seattle, WA', '47.610127', '-122.342838', 'restaurant');

Paso 3: utilizar PHP para generar archivos KML

En este punto, deberías tener una tabla llamada “marcadores” que incluya datos de ejemplo. Ahora tienes que escribir algunas instrucciones PHP para exportar los datos de la tabla a formato KML. Si no has escrito nunca PHP para conectar con una base de datos MySQL, puedes visitar php.net e informarte sobre mysql_connect, mysql_select_db, my_sql_query y mysql_error.

Deberías colocar tu información sobre la conexión a la base de datos en un archivo independiente. Suele ser una buena idea siempre que utilices PHP para acceder a una base de datos, ya que guarda tu información confidencial en un archivo que no te sentirás tentado a compartir. En el foro de las API de Google Maps, hemos tenido conocimiento de que algunos usuarios habían publicado de forma accidental su información de conexión a la base de datos cuando sólo intentaban depurar su código. El archivo debería aparecer así, pero completado con tu propia información de la base de datos. phpsqlajax_dbinfo.php:

<?
 $username = 'username';
 $password = 'password';
 $database = 'database';
 $server = 'server'
?>

Uso de las funciones DOM de PHP5 para generar KML

Aquí comienza lo nuevo. En el artículo anterior, Pamela Fox presentaba el código PHP 4 que utilizaba la extensión dom_xml para crear un archivo de marcadores sencillos que posteriormente se analizaba con JavaScript. En este tutorial vas a generar KML. Puedes especificar el estilo de la marca de posición directamente en KML, en lugar de hacerlo con JavaScript. Este tutorial mostrará código que utiliza bibliotecas con DOM integrado de PHP 5 y la extensión dom_xml de PHP 4.

 

En primer lugar, comprueba tu configuración o intenta inicializar un documento de DOM (DOMDocument()) para determinar si el PHP de tu servidor tiene la función DOM activada. Si tienes acceso al DOM, puedes utilizarlo para crear nodos XML, añadir nodos secundarios y generar un documento XML. Esto también funciona con KML, puesto que KML es un lenguaje de marcado XML. Si no dispones de DOM en tu servidor, intenta utilizar los métodos dom_xml o echo, que se describen a continuación.

Una vez que hayas determinado que puedes continuar con DOM, comienza creando varias marcas de posición para cada fila de la tabla de marcadores. Inicializa un nuevo documento en PHP y crea el nodo principal “kml”. Añade el espacio de nombre KML como un atributo. Después de crear la estructura básica de un elemento <document> de KML, crea los dos estilos, uno para los restaurantes y otro para los bares, a los que posteriormente harán referencia las marcas de posición mediante el elemento <styleUrl>.

A continuación, conéctate a la base de datos, ejecuta una consulta SELECT * (seleccionar todo) en la tabla de marcadores y repite el proceso con los resultados. Crea un nuevo elemento <Placemark> para cada fila de la tabla (cada ubicación). Extrae la información de la fila y utilízala para crear los elementos secundarios de los elementos <Placemark>, <name>, <description>, <styleUrl> y <Point>. Asigna al elemento <styleUrl> un valor en función del valor de la columna type correspondiente a esa fila. A continuación, incluye en el elemento <Point> y un elemento secundario <coordinates> y combina los valores de las columnas lng y lat como su valor.

El siguiente archivo PHP crea un archivo KML con los encabezados HTML adecuados. Asigna el valor de la columna name al elemento <name> y el valor de la dirección al elemento <description>. Una vez generado el archivo KML desde esta secuencia de comandos, recomendamos que verifiques los resultados con un editor de textos o un navegador. phpsql_genkml.php:

<?php
require('phpsqlajax_dbinfo.php');

// Opens a connection to a MySQL server.

$connection = mysql_connect ($server, $username, $password);

if (!$connection) 
{
  die('Not connected : ' . mysql_error());
}
// Sets the active MySQL database.
$db_selected = mysql_select_db($database, $connection);

if (!$db_selected) 
{
  die('Can\'t use db : ' . mysql_error());
}

// Selects all the rows in the markers table.
$query = 'SELECT * FROM markers WHERE 1';
$result = mysql_query($query);

if (!$result) 
{
  die('Invalid query: ' . mysql_error());
}

// Creates the Document.
$dom = new DOMDocument('1.0', 'UTF-8');

// Creates the root KML element and appends it to the root document.
$node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml');
$parNode = $dom->appendChild($node);

// Creates a KML Document element and append it to the KML element.
$dnode = $dom->createElement('Document');
$docNode = $parNode->appendChild($dnode);

// Creates the two Style elements, one for restaurant and one for bar, and append the elements to the Document element.
$restStyleNode = $dom->createElement('Style');
$restStyleNode->setAttribute('id', 'restaurantStyle');
$restIconstyleNode = $dom->createElement('IconStyle');
$restIconstyleNode->setAttribute('id', 'restaurantIcon');
$restIconNode = $dom->createElement('Icon');
$restHref = $dom->createElement('href', 'http://maps.google.com/mapfiles/kml/pal2/icon63.png');
$restIconNode->appendChild($restHref);
$restIconstyleNode->appendChild($restIconNode);
$restStyleNode->appendChild($restIconstyleNode);
$docNode->appendChild($restStyleNode);

$barStyleNode = $dom->createElement('Style');
$barStyleNode->setAttribute('id', 'barStyle');
$barIconstyleNode = $dom->createElement('IconStyle');
$barIconstyleNode->setAttribute('id', 'barIcon');
$barIconNode = $dom->createElement('Icon');
$barHref = $dom->createElement('href', 'http://maps.google.com/mapfiles/kml/pal2/icon27.png');
$barIconNode->appendChild($barHref);
$barIconstyleNode->appendChild($barIconNode);
$barStyleNode->appendChild($barIconstyleNode);
$docNode->appendChild($barStyleNode);

// Iterates through the MySQL results, creating one Placemark for each row.
while ($row = @mysql_fetch_assoc($result))
{
  // Creates a Placemark and append it to the Document.

  $node = $dom->createElement('Placemark');
  $placeNode = $docNode->appendChild($node);

  // Creates an id attribute and assign it the value of id column.
  $placeNode->setAttribute('id', 'placemark' . $row['id']);

  // Create name, and description elements and assigns them the values of the name and address columns from the results.
  $nameNode = $dom->createElement('name',htmlentities($row['name']));
  $placeNode->appendChild($nameNode);
  $descNode = $dom->createElement('description', $row['address']);
  $placeNode->appendChild($descNode);
  $styleUrl = $dom->createElement('styleUrl', '#' . $row['type'] . 'Style');
  $placeNode->appendChild($styleUrl);

  // Creates a Point element.
  $pointNode = $dom->createElement('Point');
  $placeNode->appendChild($pointNode);

  // Creates a coordinates element and gives it the value of the lng and lat columns from the results.
  $coorStr = $row['lng'] . ','  . $row['lat'];
  $coorNode = $dom->createElement('coordinates', $coorStr);
  $pointNode->appendChild($coorNode);
}

$kmlOutput = $dom->saveXML();
header('Content-type: application/vnd.google-earth.kml+xml');
echo $kmlOutput;
?>

Uso de la función “dom_xml” de PHP 4 para generar archivos KML

Las funciones dom_xml de PHP 4 son muy parecidas a las del DOM de PHP 5. phpsql_genkml2.php:

<?php
require('phpsqlajax_dbinfo.php');

// Opens a connection to a MySQL server.
$connection=mysql_connect ($server, $username, $password);
if (!$connection) 
{
  die('Not connected : ' . mysql_error());
}
// Sets the active MySQL database.
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) 
{
  die ('Can\'t use db : ' . mysql_error());
}

// Selects all the rows in the markers table.
$query = 'SELECT * FROM markers WHERE 1';
$result = mysql_query($query);
if (!$result) 
{
  die('Invalid query: ' . mysql_error());
}

// Creates the Document.
$dom = new domxml_new_doc('1.0');

// Creates the root KML element and appends it to the root document.
$node = $dom->create_element_ns('http://earth.google.com/kml/2.1', 'kml');
$parNode = $dom->append_child($node);

// Creates a KML Document element and append it to the KML element.
$dnode = $dom->create_element('Document');
$docNode = $parNode->append_child($dnode);
 
//Creates the two Style elements, one for restaurant and one for bar, and append the elements to the Document element.
$restStyleNode = $dom->create_element('Style');
$restStyleNode->set_attribute('id', 'restaurantStyle');
$restIconstyleNode = $dom->create_element('IconStyle');
$restIconstyleNode->set_attribute('id', 'restaurantIcon');
$restIconNode = $dom->create_element('Icon');
$restHref = $dom->create_element('href', 'http://maps.google.com/mapfiles/kml/pal2/icon63.png');
$restIconNode->append_child($restHref);
$restIconstyleNode->append_child($restIconNode);
$restStyleNode->append_child($restIconstyleNode);
$docNode->append_child($restStyleNode);
$barStyleNode = $dom->create_element('Style');
$barStyleNode->set_attribute('id', 'barStyle');
$barIconstyleNode = $dom->create_element('IconStyle');
$barIconstyleNode->set_attribute('id', 'barIcon');
$barIconNode = $dom->create_element('Icon');
$barHref = $dom->create_element('href', 'http://maps.google.com/mapfiles/kml/pal2/icon27.png');
$barIconNode->append_child($barHref);
$barIconstyleNode->append_child($barIconNode);
$barStyleNode->append_child($barIconstyleNode);
$docNode->append_child($barStyleNode);

// Iterates through the MySQL results, creating one Placemark for each row.
while ($row = @mysql_fetch_assoc($result))
{
  // Creates a Placemark and append it to the Document.
  $node = $dom->create_element('Placemark');
  $placeNode = $docNode->append_child($node);
  // Creates an id attribute and assign it the value of id column.
  $placeNode->set_attribute('id', 'placemark' . $row['id']);

  // Create name, and description elements and assigns them the values of the name and address columns from the results.
  $nameNode = $dom->create_element('name',htmlentities($row['name']));
  $placeNode->append_child($nameNode);
  $descNode = $dom->  create_element('description', $row['address']);
  $placeNode->append_child($descNode);
  $styleUrl = $dom->create_element('styleUrl', '#' . $row['type'] . 'Style');
  $placeNode->append_child($styleUrl);
 // Creates a Point element.
  $pointNode = $dom->create_element('Point');
  $placeNode->append_child($pointNode);
   
  // Creates a coordinates element and gives it the value of the lng and lat columns from the results.
  $coorStr = $row['lng'] . ','  . $row['lat'];
  $coorNode = $dom->create_element('coordinates', $coorStr);
  $pointNode->append_child($coorNode);
}

$kmlOutput = $dom->dump_mem(TRUE, 'UTF-8');
header('Content-type: application/vnd.google-earth.kml+xml');
echo $kmlOutput;
?>

Como puedes ver, la mayoría de las diferencias se resuelven cambiando las funciones con palabras concatenadas en mayúsculas (“camel case”) (createElement) a minúsculas con un guión bajo (“_”) para separar las palabras del nombre de la función. La excepción de esta regla es el elemento domxml_new_doc, que PHP 5 reemplaza con DOMDocument. Asimismo, con el elemento dom_xml, se establece la codificación al volcar el archivo en la memoria y no cuando se crea.

Uso de la función “echo” de PHP para generar archivos KML

Si no tienes acceso a las funciones DOM de PHP, puedes generar simplemente el archivo KML con la función echo.

  1. Conéctate a la base de datos y ejecuta la consulta SELECT * (seleccionar todo) en la tabla de marcadores.
  2. Crea un conjunto de cadenas que compongan la estructura básica del documento KML.
  3. A continuación, repite el proceso con los resultados de la consulta y añade un elemento al conjunto por cada fila de la tabla (cada una de las ubicaciones).
  4. Crea el elemento de marca de posición (Placemark) de la fila, pasando la columna de nombre a través de la función htmlentities por si contuviera alguna entidad especial.
  5. Completa la secuencia de comandos compilando el conjunto en una gran cadena y aplicando el método “echo” a los encabezados primero y a la cadena KML después.

A continuación se muestra el archivo PHP que lleva a cabo todo el procedimiento. phpsql_genkml3.php:

<?php
require('phpsqlajax_dbinfo.php');

 // Opens a connection to a MySQL server.
$connection = mysql_connect ($server, $username, $password);
if (!$connection) 
{
  die('Not connected : ' . mysql_error());
}

// Sets the active MySQL database.
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) 
{
  die ('Can\'t use db : ' . mysql_error());
}

 // Selects all the rows in the markers table.
 $query = 'SELECT * FROM markers WHERE 1';
 $result = mysql_query($query);
 if (!$result) 
 {
  die('Invalid query: ' . mysql_error());
 }

// Creates an array of strings to hold the lines of the KML file.
$kml = array('<?xml version="1.0" encoding="UTF-8"?>');
$kml[] = '<kml xmlns="http://earth.google.com/kml/2.1">';
$kml[] = ' <Document>';
$kml[] = ' <Style id="restaurantStyle">';
$kml[] = ' <IconStyle id="restuarantIcon">';
$kml[] = ' <Icon>';
$kml[] = ' <href>http://maps.google.com/mapfiles/kml/pal2/icon63.png</href>';
$kml[] = ' </Icon>';
$kml[] = ' </IconStyle>';
$kml[] = ' </Style>';
$kml[] = ' <Style id="barStyle">';
$kml[] = ' <IconStyle id="barIcon">';
$kml[] = ' <Icon>';
$kml[] = ' <href>http://maps.google.com/mapfiles/kml/pal2/icon27.png</href>';
$kml[] = ' </Icon>';
$kml[] = ' </IconStyle>';
$kml[] = ' </Style>';

// Iterates through the rows, printing a node for each row.
while ($row = @mysql_fetch_assoc($result)) 
{
  $kml[] = ' <Placemark id="placemark' . $row['id'] . '">';
  $kml[] = ' <name>' . htmlentities($row['name']) . '</name>';
  $kml[] = ' <description>' . htmlentities($row['address']) . '</description>';
  $kml[] = ' <styleUrl>#' . ($row['type']) .'Style</styleUrl>';
  $kml[] = ' <Point>';
  $kml[] = ' <coordinates>' . $row['lng'] . ','  . $row['lat'] . '</coordinates>';
  $kml[] = ' </Point>';
  $kml[] = ' </Placemark>';
 
} 

// End XML file
$kml[] = ' </Document>';
$kml[] = '</kml>';
$kmlOutput = join("\n", $kml);
header('Content-type: application/vnd.google-earth.kml+xml');
echo $kmlOutput;
?>

 

Comprobación del funcionamiento del KML generado

Ejecuta esta secuencia de comandos PHP desde el navegador para asegurarte de que genera archivos KML válidos. Si la secuencia de comandos funciona correctamente, el KML resultante será el siguiente: phpsqlkml_expectedoutput.kml:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns = "http://earth.google.com/kml/2.1">
  <Document>
    <Style id="restaurantStyle">
      <IconStyle id="restuarantIcon">
      <Icon>
        <href>http://maps.google.com/mapfiles/kml/pal2/icon63.png</href>
      </Icon>
      </IconStyle>
    </Style>
    <Style id="barStyle">
      <IconStyle id="barIcon">
      <Icon>
        <href>http://maps.google.com/mapfiles/kml/pal2/icon27.png</href>
      </Icon>
      </IconStyle>
      </Style>
    <Placemark id="placemark1">
      <name>Pan Africa Market</name>
      <description>1521 1st Ave, Seattle, WA</description>
      <styleUrl>#restaurantStyle</styleUrl>
      <Point>
        <coordinates>-122.340141,47.608940</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark2">
      <name>Buddha Thai &amp; Bar</name>
      <description>2222 2nd Ave, Seattle, WA</description>
      <styleUrl>#barStyle</styleUrl>
      <Point>
        <coordinates>-122.344391,47.613590</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark3">
      <name>The Melting Pot</name>
      <description>14 Mercer St, Seattle, WA</description>
      <styleUrl>#restaurantStyle</styleUrl>
      <Point>
        <coordinates>-122.356445,47.624561</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark4">
      <name>Ipanema Grill</name>
      <description>1225 1st Ave, Seattle, WA</description>
      <styleUrl>#restaurantStyle</styleUrl>
      <Point>
        <coordinates>-122.337654,47.606365</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark5">
      <name>Sake House</name>
      <description>2230 1st Ave, Seattle, WA</description>
      <styleUrl>#barStyle</styleUrl>
      <Point>
      <coordinates>-122.345673,47.612823</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark6">
      <name>Crab Pot</name>
      <description>1301 Alaskan Way, Seattle, WA</description>
      <styleUrl>#restaurantStyle</styleUrl>
      <Point>
        <coordinates>-122.340363,47.605961</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark7">
      <name>Mama's Mexican Kitchen</name>
      <description>2234 2nd Ave, Seattle, WA</description>
      <styleUrl>#barStyle</styleUrl>
      <Point>
        <coordinates>-122.345467,47.613976</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark8">
      <name>Wingdome</name>
      <description>1416 E Olive Way, Seattle, WA</description>
      <styleUrl>#barStyle</styleUrl>
      <Point>
        <coordinates>-122.326584,47.617214</coordinates>
      </Point>
    </Placemark>
    <Placemark id="placemark9">
      <name>Piroshky Piroshky</name>
      <description>1908 Pike pl, Seattle, WA</description>
      <styleUrl>#restaurantStyle</styleUrl>
      <Point>
        <coordinates>-122.342834,47.610126</coordinates>
      </Point>
    </Placemark>
 </Document>
</kml>

 

Trazo de una línea

Una de las ventajas de las bases de datos es su capacidad para combinar la información. Por ejemplo, la expresión natural de una serie de puntos es una línea o, en KML, una cadena de líneas (<linestring>). En realidad, resulta más sencillo que crear una serie de puntos. Crea una secuencia de comandos que genere la estructura de una sola marca de posición. Coloca el elemento <linestring> en las marcas de posición. A continuación, consulta en la base de datos todas las coordenadas, ordenadas por la ID (id) de la fila.

A continuación se muestra un ejemplo de secuencia de comandos PHP que genera una cadena de líneas (<linestring>) entre todos los restaurantes según el orden de su ID (id), a 100 metros de altitud con extrusión. Aunque en Google Maps no se muestra, esta secuencia de comandos crea un muro de 100 metros de altura que recorre las ubicaciones de todos restaurantes en Google Earth en el orden en que se introdujeron en la base de datos. phpsql_genkml_ls.php.

<?php
require('phpsqlajax_dbinfo.php');

// Opens a connection to a MySQL server
$connection = mysql_connect ($server, $username, $password);

if (!$connection) 
{
   die('Not connected : ' . mysql_error());
}

// Set the active MySQL database
$db_selected = mysql_select_db($database, $connection);

if (!$db_selected) 
{
  die ('Can\'t use db : ' . mysql_error());
}

// Select all the rows in the markers table

$query = " SELECT GROUP_CONCAT(lng, ',', lat, ',', '100' separator ' ') AS coordinates FROM markers WHERE type = 'restaurant';";

$result = mysql_query($query);
if (!$result) 
{
  die('Invalid query: ' . mysql_error());
}

// Start KML file, create parent node
$dom = new DOMDocument('1.0','UTF-8');

//Create the root KML element and append it to the Document
$node = $dom->createElementNS('http://earth.google.com/kml/2.1','kml');
$parNode = $dom->appendChild($node);

//Create a Folder element and append it to the KML element
$fnode = $dom->createElement('Folder');
$folderNode = $parNode->appendChild($fnode);

//Iterate through the MySQL results
$row = @mysql_fetch_assoc($result);

//Create a Placemark and append it to the document
$node = $dom->createElement('Placemark');
$placeNode = $folderNode->appendChild($node);

//Create an id attribute and assign it the value of id column
$placeNode->setAttribute('id','linestring1');

//Create name, description, and address elements and assign them the values of 
//the name, type, and address columns from the results

$nameNode = $dom->createElement('name','My path');
$placeNode->appendChild($nameNode);
$descNode= $dom->createElement('description', 'This is the path that I took through my favorite restaurants in Seattle');
$placeNode->appendChild($descNode);

//Create a LineString element
$lineNode = $dom->createElement('LineString');
$placeNode->appendChild($lineNode);
$exnode = $dom->createElement('extrude', '1');
$lineNode->appendChild($exnode);
$almodenode =$dom->createElement(altitudeMode,'relativeToGround');
$lineNode->appendChild($almodenode);

//Create a coordinates element and give it the value of the lng and lat columns from the results

$coorNode = $dom->createElement('coordinates',$row['coordinates']);
$lineNode->appendChild($coorNode);
$kmlOutput = $dom->saveXML();

//assign the KML headers. 
header('Content-type: application/vnd.google-earth.kml+xml');
echo $kmlOutput;
?>

El resultado de esa secuencia de comandos es el siguiente: phpsqlkml_expectedoutput_ls.kml:

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://earth.google.com/kml/2.1'>
  <Folder>
    <Placemark id='linestring1'>
      <name>My path</name>
      <description>This is the path that I took through my favorite restaurants in Seattle</description>
      <LineString>
        <extrude>1</extrude>
        <altitudeMode>relativeToGround</altitudeMode>
        <coordinates>-122.340141,47.608940,100 -122.356445,47.624561,100 
                     -122.337654,47.606365,100 -122.340363,47.605961,100
                     -122.342834,47.610126,100
        </coordinates>
     </LineString>
    </Placemark>
  </Folder>
</kml>

Paso 4: visualizar tus archivos KML

 

Visualización en Google Earth

A continuación puedes visualizar estos datos fácilmente en Google Earth. El mejor método es generar un archivo NetworkLink que dirija a la secuencia de comandos. Si actualizas los datos a menudo, puedes establecer la frecuencia de actualización para que coincida con la frecuencia de tus actualizaciones. A continuación se muestra un ejemplo de un archivo con el que se lleva a cabo el procedimiento: phpmysql_kmlnl.kml:

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns = 'http://earth.google.com/kml/2.1'>
  <Folder>
    <NetworkLink>
      <Link>
        <href>http://example.com/phpsql_genkml.kml</href>
        <refreshMode>onInterval</refreshMode>
        <refreshInterval>3600</refreshInterval>
      </Link>
    </NetworkLink>
    <NetworkLink>
      <Link>
        <href>http://example.com/phpsql_genkml_ls.kml</href>
        <refreshMode>onInterval</refreshMode>
        <refreshInterval>3600</refreshInterval>
      </Link>
    </NetworkLink>
  </Folder>
</kml>

Cambia el elemento <href> a la ruta de la secuencia de comandos en tu servidor. Abre el archivo phpmysql_kmlnl.php con Google Earth. Esto es lo que verás:

Visualización del NetworkLink en Google Earth

 

Para ver el mismo archivo en Google Maps, lo único que necesitas es crear un mapa y añadir el enlace a la secuencia de comandos o al archivo NetworkLink. Por ejemplo:

function load() 
{
  var map;
  var geoXml;

  if (GBrowserIsCompatible()) 
  {
    map = new GMap2(document.getElementById('map'));
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    geoXml = new GGeoXml('http://example.com/phpmysql_kmlnl.kml');
    map.addOverlay(geoXml);
    map.setCenter(new GLatLng(47.613976,-122.345467), 13);
  }
}

Que genera un mapa como el siguiente:

Ejemplo de Google Maps

Paso 5: más información

Una vez que tengas esta base de datos, ¿qué puedes hacer con ella? La gran ventaja de las bases de datos es que puedes añadirles elementos. Y lo mejor de los archivos KML que se muestran en las bases de datos es que puedes actualizar el contenido. Únelo y obtendrás una herramienta integral.

También puedes realizar otras muchas tareas en KML. Aprovecha algunas de las funciones únicas de Google Earth como, por ejemplo, los archivos <NetworkLink> que utilizan el recurso <viewFormat>. Este recurso permite que el archivo <networklink> envíe parámetros a tu secuencia de comandos. Puedes utilizar estos parámetros para modificar el contenido enviado que reciben los datos o utilizar las funciones <TimeStamp> y <TimeSpan>, que te permiten crear animaciones de las marcas de posición KML en un período de tiempo. Crea estructuras de tabla más complejas para almacenar elementos del tipo <Polygons> en tablas relacionadas. Asimismo, puedes crear una página web que permita que otra gente acceda a tu base de datos y que se actualizará la próxima vez que se ejecute la secuencia de comandos. Las posibilidades son infinitas.

Volver al principio