استفاده از PHP و MySQL برای ایجاد KML

مانو مارکس، تیم گوگل ژئو
ژوئن ۲۰۰۷

این آموزش برای توسعه‌دهندگانی در نظر گرفته شده است که با PHP و MySQL آشنا هستند و می‌خواهند یاد بگیرند که چگونه KML را از پایگاه داده MySQL تولید کنند. برای این آموزش، شما دو اسکریپت ایجاد خواهید کرد که به صورت پویا KML را از پایگاه داده‌ای از مکان‌ها در سیاتل تولید می‌کنند. اسکریپت اول مجموعه‌ای از نقاط را ایجاد می‌کند که دو نوع مکان - رستوران‌ها و بارها - با نمادهای متمایز مشخص شده‌اند. وقتی کاربر روی یک نشانگر کلیک می‌کند، یک بالن اطلاعات نام و آدرس را نمایش می‌دهد. اسکریپت دوم خطی ایجاد می‌کند که تمام رستوران‌ها را به هم متصل می‌کند. این آموزش همچنین نحوه ایجاد یک نقشه گوگل که فایل‌های KML را نمایش می‌دهد و یک فایل NetworkLink که به فایل KML اشاره می‌کند و کاربر را قادر می‌سازد آن را در Google Earth باز کند، نشان می‌دهد.

این آموزش بر اساس مقاله «استفاده از PHP/MySQL با نقشه‌های گوگل» نوشته پاملا فاکس است که نحوه خروجی گرفتن از جدول MySQL به نقشه‌های گوگل با استفاده از PHP را نشان می‌دهد. اگر مقاله پاملا را خوانده‌اید، می‌توانید از دو مرحله اول این آموزش صرف نظر کنید. بقیه آموزش به طور قابل توجهی متفاوت است زیرا با KML سروکار دارد.

آموزش به مراحل زیر تقسیم می‌شود:

  1. ایجاد جدول
  2. پر کردن جدول
  3. استفاده از PHP برای خروجی KML
  4. نمایش فایل‌های KML شما
  5. از اینجا به کجا برویم؟

تصویر گوگل ارث

مرحله ۱: ایجاد جدول

هنگام ایجاد جدول MySQL، باید به ویژگی‌های lat و lng توجه ویژه‌ای داشته باشید. با قابلیت‌های بزرگنمایی فعلی نقشه‌های گوگل، فقط به ۶ رقم دقت بعد از اعشار نیاز دارید. برای اینکه فضای ذخیره‌سازی مورد نیاز جدول ما حداقل باشد، می‌توانید مشخص کنید که ویژگی‌های lat و lng اعشاری با اندازه (۱۰،۶) باشند. این به فیلدها اجازه می‌دهد ۶ رقم بعد از اعشار، به علاوه حداکثر ۴ رقم قبل از اعشار، مثلاً -۱۲۳.۴۵۶۷۸۹ درجه را ذخیره کنند. جدول شما همچنین باید یک ویژگی id برای استفاده به عنوان کلید اصلی و یک ویژگی type برای تمایز بین رستوران‌ها و بارها داشته باشد.

توجه: این آموزش از داده‌های مکانی استفاده می‌کند که از قبل اطلاعات طول و عرض جغرافیایی مورد نیاز برای ترسیم نشانگرهای مربوطه را دارند. اگر می‌خواهید از داده‌های خودتان که هنوز این اطلاعات را ندارند استفاده کنید، از یک سرویس کدگذاری جغرافیایی دسته‌ای برای تبدیل آدرس‌ها به عرض/طول جغرافیایی استفاده کنید. برخی از سایت‌ها اشتباه کدگذاری جغرافیایی آدرس‌ها را هر بار که صفحه بارگذاری می‌شود، مرتکب می‌شوند، اما انجام این کار منجر به بارگذاری کندتر صفحه و تکرار غیرضروری کدهای جغرافیایی می‌شود. همیشه بهتر است در صورت امکان، اطلاعات طول و عرض جغرافیایی را به صورت کد ثابت (hard code) وارد کنید.

شما می‌توانید داده‌های جدول را به یکی از دو روش زیر ایجاد کنید - یا با استفاده از رابط 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 ;


مرحله ۲: پر کردن جدول

پس از ایجاد جدول، زمان آن رسیده است که آن را با داده‌ها پر کنید. داده‌های نمونه برای 10 مکان در سیاتل در زیر ارائه شده است. در phpMyAdmin، می‌توانید از تب IMPORT برای وارد کردن فرمت‌های مختلف فایل، از جمله CSV (مقادیر جدا شده با کاما) استفاده کنید. مایکروسافت اکسل و صفحات گسترده گوگل هر دو به فرمت 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');


مرحله ۳: استفاده از 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 برای ایجاد یک فایل نشانگر ساده استفاده می‌کرد که بعداً با استفاده از جاوا اسکریپت تجزیه می‌شد. برای این آموزش، شما می‌خواهید KML تولید کنید. به جای استفاده از جاوا اسکریپت، می‌توانید استایل Placemark را مستقیماً در KML مشخص کنید. این آموزش کدی را نشان می‌دهد که هم از کتابخانه‌های DOM یکپارچه PHP 5 و هم از افزونه dom_xml PHP 4 استفاده می‌کند.

ابتدا، پیکربندی خود را بررسی کنید یا سعی کنید یک DOMDocument() را مقداردهی اولیه کنید تا مشخص شود که آیا PHP سرور شما قابلیت DOM را فعال کرده است یا خیر. اگر به DOM دسترسی دارید، می‌توانید از آن برای ایجاد گره‌های XML، افزودن گره‌های فرزند و خروجی یک سند XML استفاده کنید. از آنجایی که KML یک زبان نشانه‌گذاری XML است، این روش برای KML نیز کار می‌کند. اگر DOM روی سرور شما در دسترس نیست، از روش dom_xml یا echo که در زیر توضیح داده شده است استفاده کنید.

وقتی تشخیص دادید که می‌توانید با DOM ادامه دهید، با ایجاد placemarkهای مختلف برای هر ردیف در جدول markers شروع کنید. در PHP، یک سند XML جدید را مقداردهی اولیه کنید و گره والد "kml" را ایجاد کنید. فضای نام KML را به عنوان یک ویژگی اضافه کنید. پس از ایجاد ساختار اولیه یک عنصر <document> در KML، دو style - یکی برای رستوران‌ها و دیگری برای بارها - را بسازید که بعداً توسط 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;
?
>

همانطور که می‌بینید، بیشتر تفاوت‌ها با تبدیل توابع camel case ( createElement ) به حروف کوچک با استفاده از underscore ("_") برای جدا کردن کلمات در نام تابع حل می‌شوند. استثنای این قانون domxml_new_doc است که PHP 5 آن را با DOMDocument جایگزین می‌کند. همچنین، با استفاده از dom_xml ، کدگذاری را هنگام بارگذاری فایل در حافظه تنظیم می‌کنید، نه هنگام ایجاد فایل.

استفاده از دستور echo در PHP برای خروجی KML

اگر به توابع DOM در PHP دسترسی ندارید، می‌توانید به سادگی KML را با تابع echo نمایش دهید.

  1. به پایگاه داده متصل شوید و کوئری SELECT * (select all) را روی جدول 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> است. انجام این کار در واقع ساده‌تر از ایجاد مجموعه‌ای از نقاط است. اسکریپتی ایجاد کنید که ساختار یک Placemark واحد را ایجاد کند. یک عنصر <linestring> را در Placemarks قرار دهید. سپس از پایگاه داده برای تمام مختصات، که بر اساس id ردیف مرتب شده‌اند، پرس و جو کنید.

در اینجا یک اسکریپت PHP نمونه وجود دارد که یک <linestring> بین تمام رستوران‌ها، به ترتیب id آنها، در ارتفاع ۱۰۰ متری، با قابلیت extrusion ایجاد می‌کند. اگرچه این در نقشه‌های گوگل نمایش داده نمی‌شود، اما در Google Earth این اسکریپت یک دیوار ۱۰۰ متری ایجاد می‌کند که از میان تمام مکان‌های رستوران در 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>

مرحله ۴: نمایش فایل‌های KML شما


نمایش در گوگل ارث

اکنون می‌توانید به راحتی این داده‌ها را در 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 در گوگل ارث

برای مشاهده همان فایل در نقشه‌های گوگل، تنها کاری که باید انجام دهید این است که یک نقشه ایجاد کنید و لینک را به اسکریپت یا فایل 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);
  }
}

که نقشه‌ای مانند این تولید می‌کند:

مثال نقشه گوگل

مرحله ۵: از اینجا به کجا برویم

خب، حالا که این پایگاه داده را دارید، با آن چه کار می‌کنید؟ خب، نکته‌ی عالی در مورد پایگاه‌های داده این است که می‌توانید به آنها چیزی اضافه کنید. نکته‌ی عالی در مورد KML که از یک پایگاه داده ارائه می‌شود این است که می‌توانید محتوای خود را به‌روزرسانی کنید. اینها را کنار هم قرار دهید و قدرت زیادی به دست آورید.

و کارهای بسیار بیشتری می‌توانید در KML انجام دهید. از برخی ویژگی‌های منحصر به فرد Google Earth، مانند فایل‌های <NetworkLink> که از <viewFormat> استفاده می‌کنند، بهره ببرید. این ویژگی به <networklink> اجازه می‌دهد تا پارامترهایی را به اسکریپت شما ارسال کند. می‌توانید از این پارامترها برای تغییر داده‌های ارسالی استفاده کنید. یا از <TimeStamp> و <TimeSpan> استفاده کنید که به شما امکان می‌دهند مکان‌نماهای KML را در یک دوره زمانی متحرک‌سازی کنید. ساختارهای جدول پیچیده‌تری ایجاد کنید تا مواردی مانند <Polygons> را در جداول مرتبط ذخیره کنید. یا یک صفحه وب ایجاد کنید که به افراد دیگر اجازه می‌دهد داده‌ها را در پایگاه داده شما وارد کنند، که سپس دفعه بعد که اسکریپت فراخوانی می‌شود، رفرش می‌شود. امکانات بی‌پایان هستند.

بازگشت به بالا