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

Мано Маркс, команда Google Geo
Июнь 2007 г.

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

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

Учебное пособие состоит из следующих шагов:

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

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

Шаг 1: Создание таблицы

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

Примечание: В этом руководстве используются данные о местоположении, которые уже содержат информацию о широте и долготе, необходимую для отображения соответствующих маркеров. Если вы пытаетесь использовать собственные данные, которые еще не содержат этой информации, воспользуйтесь сервисом пакетного геокодирования для преобразования адресов в широту/долготу. Некоторые сайты допускают ошибку, геокодируя адреса каждый раз при загрузке страницы, но это приводит к замедлению загрузки страниц и ненужным повторным геокодированиям. Всегда лучше, если информация о широте/долготе задана жестко в коде, если это возможно.

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

Вот соответствующий 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 вы можете использовать вкладку «ИМПОРТ» для импорта файлов различных форматов, включая CSV (значения, разделенные запятыми). 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

Вот скриншот параметров импорта, использованных для преобразования этого CSV-файла в табличные данные:

Вот соответствующие 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 для доступа к базе данных, поскольку это позволяет хранить конфиденциальную информацию в файле, которым вы не захотите делиться. На форуме Maps API у нас иногда случались случаи, когда люди случайно публиковали информацию о подключении к базе данных, просто пытаясь отладить свой код. Файл должен выглядеть примерно так, но с заполненной информацией о вашей базе данных: phpsqlajax_dbinfo.php :

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

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

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

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

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

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

Приведённый ниже PHP-файл создаёт KML-файл с соответствующими HTML-заголовками. Он присваивает значение столбца name элементу <name> , а значение столбца address — элементу <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;
?
>

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

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

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

  1. Подключитесь к базе данных и выполните запрос SELECT * (выбрать все) к таблице markers.
  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 &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>

Выстраивая линию

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

Вот пример PHP-скрипта, который создает <linestring> между всеми ресторанами в порядке их id на высоте 100 метров с эффектом выдавливания. Хотя это не отобразится на Google Maps, в Google Earth этот скрипт создает стену высотой 100 метров, проходящую через все местоположения ресторанов в Google Earth в порядке их внесения в базу данных. 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 Earth. Лучший способ сделать это — создать файл 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.kml с помощью Google Earth. Вы увидите следующее:

Отображение NetworkLink в Google Earth

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

Вернуться наверх