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

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

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

Этот учебник основан на статье Использование 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). Это позволит полям хранить 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 вы можете указать стиль метки непосредственно в KML. В этом руководстве будет показан код, который использует как интегрированные библиотеки DOM PHP 5, так и расширение dom_xml PHP 4.

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

Как только вы решили, что можете продолжать работу с DOM, начните с создания разных меток для каждой строки в таблице маркеров. В PHP инициализируйте новый XML-документ и создайте родительский узел «kml». Добавьте пространство имен KML в качестве атрибута. После создания базовой структуры элемента KML <document> создайте два стиля — один для ресторанов и один для баров, — которые впоследствии будут использоваться в Placemarks через элемент <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 для вывода KML

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

  1. Подключитесь к базе данных и выполните запрос SELECT * (выбрать все) в таблице маркеров.
  2. Создайте массив строк, составляющих базовую структуру документа KML.
  3. Затем выполните итерацию по результатам запроса, добавляя элемент в массив для каждой строки таблицы (каждого местоположения).
  4. Создайте элемент Placemark для этой строки, передав столбец name через функцию 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>

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

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

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

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

Для просмотра того же файла в 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 Карт

Шаг 5: Куда идти дальше

Итак, теперь, когда у вас есть эта база данных, что вы с ней делаете? Что ж, самое замечательное в базах данных то, что вы можете добавлять к ним данные. Отличительной особенностью KML, предоставляемого из базы данных, является то, что вы можете обновлять свой контент. Сложите их вместе, и вы получите много силы.

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

Вернуться к вершине