01.12.2009 12:53

Использование PHP и MySQL для создания KML

Это руководство взято с сайта http://code.google.com

Mano Marks, Google Geo Team
June 2007

Это руководство предназначено для разработчиков, знакомых с PHP и MySQL и желающих научиться создавать KML из базы данных MySQL. В этом руководстве мы напишем два сценария, динамически создающих KML из базы, содержащей данные о различных местах в Сиэтле. В первом сценарии создается набор точек для мест двух типов, ресторанов и баров, отмечаемых особыми значками. Когда пользователь нажимает маркер, появляется подсказка с названием и адресом этого места. Во втором сценарии создается линия, соединяющая все рестораны. В учебнике также показано, как создать Карту Google, отображающую файлы KML, и файл NetworkLink, указывающий на файл KML и дающий пользователю возможность открыть его в Google Планета Земля.

Это руководство основано на статье Использование PHP/MySQL с Картами Google, которую написала Памела Фокс и в которой показано, как экспортировать данные из таблицы MySQL в Карты Google с помощью PHP. Если вы читали статью Памелы, то первые два этапа в этом руководстве можно пропустить. Остальные разделы руководства значительно отличаются, поскольку в них рассматривается работа с KML.

 

Руководство разбито на следующие этапы.

  1. Создание таблицы
  2. Заполнение таблицы
  3. Использование PHP для получения KML
  4. Отображение файлов KML
  5. Дальнейшие действия

Изображение из Google Планета Земля

Этап 1. Создание таблицы

При создании таблицы MySQL важно обращать особое внимание на атрибуты lat и lng. Благодаря текущим возможностям масштабирования Карт Google вам понадобятся только 6 знаков после десятичной точки. Чтобы таблица занимала меньше места, можно указать, что атрибуты lat и lng имеют формат с плавающей точкой и размер (10,6). При этом в полях можно будет хранить 6 знаков после десятичной точки и до 4 знаков перед ней, например: -123.456789 градусов. В таблице также должен быть атрибут id, выступающий в качестве основного ключа, и атрибут type, позволяющий различать рестораны и бары.

Примечание. В этом руководстве используются данные о местах, уже содержащие сведения о широте и долготе, которые необходимы для размещения соответствующих маркеров. Если вы хотите использовать собственные данные, в которых нет этих сведений, воспользуйтесь службой пакетного геокодирования для превращения адресов в пары координат широты и долготы. На некоторых сайтах геокодирование адресов выполняется при каждой загрузке страницы, из-за чего страница загружается медленнее, а геокодирование выполняется повторно. Если это возможно, в коде всегда лучше использовать записанные сведения о широте и долготе. Хороший список геокодеров приведен по этому адресу: http://groups.google.com/group/Google-Maps-API/web/resources-non-google-geocoders

Данные для таблицы можно создать одним из двух способов: с помощью интерфейса phpMyAdmin или с помощью команд SQL.

 

А вот соответствующий SQL-запрос, создающий таблицу. 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 ;


Этап 2. Заполнение таблицы

После создания таблицу нужно заполнить данными. Ниже приведен пример данных для 10 заведений в Сиэтле. В phpMyAdmin можно использовать вкладку IMPORT для импорта файлов в различных форматах, включая CSV (comma-separated values – значения, разделенные запятыми). Microsoft Excel и таблицы Google экспортируются в формат CSV, поэтому данные можно легко переносить из электронных таблиц в таблицы MySQL путем экспорта и импорта файлов CSV.

 

Вот пример данных в формате 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


Вот соответствующий SQL-запрос. 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');

Этап 3. Использование PHP для получения KML

К этому моменту у вас должна быть таблица под названием "markers", заполненная данными из примера. Теперь нужно написать несколько PHP-запросов для экспорта табличных данных в формат KML. Если вы никогда не писали PHP-код для подключения к базе данных MySQL, посетите сайт php.net и почитайте о mysql_connect, mysql_select_db, my_sql_query и mysql_error.

Информацию о подключении к базе данных лучше поместить в отдельный файл. Это вообще хороший прием, если вы используете PHP для доступа к базе данных: конфиденциальная информация оказывается в файле, который вы никогда не опубликуете. На форуме API Карт бывало, что люди случайно публиковали информацию для подключения к своим базам данных, просто пытаясь отладить свой код. Файл должен выглядеть примерно так, но с информацией для вашей базы данных.

phpsqlajax_dbinfo.php:

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

Использование функций DOM PHP5 для получения KML

Здесь начинается новый материал. В статье Памелы Фокс (см. выше) был показан код PHP 4, использовавший расширение dom_xml для создания простого файла маркеров, который затем анализировался с помощью JavaScript. В данном руководстве нам нужно создать KML. Вместо того, чтобы заниматься JavaScript, можно определить оформление элементов Placemark прямо в KML. В этом руководстве показан код, использующий и встроенные библиотеки DOM PHP 5, и расширение dom_xml PHP 4.

 

Сперва проверьте свои настройки или попробуйте инициализировать DOMDocument(), чтобы определить, включены ли функция DOM PHP на вашем сервере. При наличии доступа вы можете использовать DOM для создания XML-узлов, присоединения дочерних узлов и вывода XML-документов. Поскольку KML является языком XML-разметки, это работает и для него. Если доступа к DOM на вашем сервере нет, попробуйте использовать один из описанных ниже методов, dom_xml или echo.

Определив возможность работы с DOM, начните создавать различные метки для каждой строки в таблице маркеров. В PHP инициализируйте новый XML-документ и создайте родительский узел "kml". Добавьте пространство имен KML в качестве атрибута. Реализовав основную структур элемента KML <document>, создайте два стиля – один для ресторанов и один для баров – позже к ним будут обращаться элементы Placemark с помощью элемента <styleUrl>.

Затем выполните подключение к базе данных, выполните запрос SELECT * (выбрать все) к таблице маркеров и последовательно обработайте результаты. Для каждой строки таблицы (каждого места) создавайте новый элемент <Placemark>. Извлеките информацию из строки и используйте для создания дочерних элементов <Placemark>, <name>, <description>, <styleUrl> и <Point>. Присвойте значение элементу <styleUrl> на основе значения столбца type в этой строке. Затем назначьте элементу <Point> дочерний элемент <coordinates>; его значением сделайте комбинацию значений в столбцах lng и lat.

В PHP-файле ниже показан KML-файл с верными HTML-заголовками. В нем значение столбца name присваивается элементу <name>, а значение адреса – элементу <description>. После создания KML из этого сценария проверьте результаты с помощью текстового редактора или браузера.

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;
?>

Использование dom_xml PHP 4 для получения KML

Функции dom_xml PHP 4 очень похожи на DOM 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;
?>

Как видите, основная разница заключается в том, что вместо изменения регистра (createElement) для разделения слов в именах функций используется подчеркивание ("_"). Исключением из этого правила является функция domxml_new_doc, которая в PHP 5 заменена функцией DOMDocument. Кроме того, при использовании dom_xml кодировка задается во время передачи файла в память, а не во время его создания.

Использование функции PHP echo для получения KML

При отсутствии доступа к функциям DOM PHP можно вывести KML просто с помощью функции echo.

  1. Подключитесь к базе данных и выполните запрос SELECT * (выбрать все) к таблице маркеров.
  2. Создайте массив строк, который послужит основной структурой KML-документа.
  3. Последовательно пройдите результаты запроса, добавляя в массив по элементу для каждой строки таблицы (т.е. каждого места).
  4. Создайте элемент Placemark для этой строки, предварительно передав столбец с названием функции htmlentities на случай, если в нем содержатся какие-либо специальные символы.
  5. Чтобы завершить сценарий, объедините массив в одну большую строку, выведите заголовки, а затем – строку KML.

Ниже показан PHP-файл, в котором выполняются все эти действия.

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;
?>


Проверка вывода KML

Вызовите этот PHP-сценарий из браузера, чтобы убедиться, что он создает действительный KML. Если сценарий работает верно, вывод KML выглядит так.

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 & 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>


Создание линии

Одно из главных преимуществ баз данных – это их способность к объединению информации. Например, естественным выражением ряда точек является линия, или <linestring> в терминах KML. На самом деле, создать ее проще, чем ряд точек. Напишите сценарий, создающий структуру, которая состоит из единственного элемента Placemark. Разместите элемент <linestring> в метках Placemark. Затем запросите из базы данных все координаты, связанные с id строки.

Вот пример PHP-сценария, создающего линию <linestring> между всем ресторанами, в порядке их id, на 100-метровой высоте, с экструзией. Этого не будет видно в Картах Google, но в Google Планета Земля этот сценарий создаст стену высотой 100 метров, проходящую через все указанные рестораны в том порядке, в котором они были добавлены в базу данных.

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;
?>

Вывод этого сценария будет выглядеть так.

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>

Этап 4. Отображение файлов KML

 

Отображение в Google Планета Земля

Теперь эти данные можно легко показать в Google Планета Земля. Чтобы сделать это, лучше всего создать файл NetworkLink, указывающий на этот сценарий. Если вы часто обновляете данные, то можете задать соответствующую частоту обновления. Вот пример файла, выполняющего это.

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>

Замените элемент <href> путем к сценарию на вашем сервере. Откройте файл phpmysql_kmlnl.php с помощью Google Планета Земля. Вы увидите следующее:

Отображение файла NetworkLink в Google Планета Земля
Чтобы просмотреть этот же файл в Картах Google, нужно просто создать карту и добавить ссылку на сценарий или файл NetworkLink. Например:

 

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

При этом будет создана такая карта:

Пример Google Maps

Этап 5. Дальнейшие действия

Итак, что же теперь делать с созданной базой данных? Что хорошо в базах данных, так это возможность добавления данных. Что хорошо в KML, созданном из базы данных, так это возможность обновления содержания. Совместите эти возможности, и получите огромную мощь динамически генерируемых файлов KML.
Кроме того, KML можно использовать еще множеством способов. Воспользуйтесь уникальными функциями Google Планета Земля, например файлами <NetworkLink>, использующими <viewFormat>. Эта функция позволяет <networklink> отправлять параметры вашему сценарию. С помощью этих параметров можно изменять то, какие данные будут возвращены. Или используйте <TimeStamp> и <TimeSpan>, которые позволяют создать анимацию меток Placemark KML за определенный временной период. Создавайте более сложные табличные структуры для хранения таких элементов, как <Polygons>, в соответствующих таблицах. Или создайте веб-страницу, позволяющую другим вносить данные в вашу базу, которая затем будет обновляться при вызове сценария. Возможности безграничны.