API Google Maps рисуем полилинию и сохраняем ее в базе данных MySQL – продолжение

Автор: | 23.05.2010

В этой заметке я продолжаю тему начатую в предыдущей записи «API Google Maps рисуем полилинию и сохраняем ее в базе данных MySQL» и здесь я рассмотрю, как сохранить нарисованную линию в базе данных, а затем вывести на карту.

В начале,  необходимо будет создать таблицу в базе данных MySQL, куда мы будем производить сохранение наших полилиний.

Сделать это можно с помощью следующего запроса:

CREATE TABLE IF NOT EXISTS `usersline` (
`id_line` int(20) NOT NULL AUTO_INCREMENT,
`colour` varchar(10) NOT NULL,
`width` int(10) NOT NULL,
`users` varchar(255) NOT NULL,
`coordinats` text NOT NULL,
PRIMARY KEY (`id_line`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

Мы создаем таблицу usersline, с помощью утилиты phpMyAdmin,  которая будем иметь следующую структуру:

id_line – здесь хранится порядковый номер записи в таблице, происходит его автоматическое увеличение на единицу при добавлении новой записи;

colour – служит для хранения цвета полилинии, например, красный — #ff0000;

width – этот параметр отвечает за толщину полилинии;

users – параметр для хранения имени пользователя , добавившего полилинию – в нашем примере не используется, но если вы захотите учитывать пользователей – это поле вам понадобиться;

coordinats – хранятся координаты вершин полилинии в виде текстовой строки, пары значений разделяются между собой точкой с запятой.

Еще одно замечание, в базе данных MySQL реализована поддержка пространственных расширений, чтобы позволяет хранить и анализировать  географические свойства, но для нашего примера мы будем использовать обычное текстовое поле для хранения координат.

После того, как мы создали таблицу для хранения данных необходимо написать два файла – один для соединения с нашей базой данных config.php, а другой для записи координат вершин полилинии в нашу таблицу — upload.php.

Код файла config.php:

<?php
 
$sdb_name = "localhost";
$user_name = "root";
$user_password = "";
$db_name = "gmapsbd";
 
// соединение с сервером базы данных
if(!$link = mysql_connect($sdb_name, $user_name, $user_password))
{
  echo "<br>Не могу соединиться с сервером базы данных<br>";
  exit();
}
 
// выбираем базу данных
if(!mysql_select_db($db_name, $link))
{
  echo "<br>Не могу выбрать базу данных<br>";
  exit();
}
 
mysql_query('SET NAMES utf8');
 
?>

Тут понятно все без пояснений.

Код файла upload.php:

<?php
 
include("config.php");
 
$points = trim($_POST['points']);
 
$str_exp = explode("),(", $points);
 
$str_exp[0] = substr($str_exp[0], 1);
 
$str_exp[count($str_exp)-1] = substr($str_exp[count($str_exp)-1], 0, -1);
 
$points_line = implode(";", $str_exp);
 
$result = mysql_query ("INSERT INTO usersline VALUES (0, '#FF0000', 2, ' ', '$points_line')");
 
?>

Здесь мы через метод POST получаем данные о координатах вершин полилинии и с помощью различных функций для работы со строками преобразуем их в строку вида:

56.294157195782795, 43.905487060546875;56.29768165036526, 43.92316818237305;56.30168198872378, 43.937931060791016

После этого записываем наши данные в таблицу usersline, дополнительно добавляя цвет для нашей полилинии и толщину.

Теперь нам необходимо изменить код файла для рисования полилинии, чтобы координаты ее вершин передать в скрипт upload.php.

Для этого необходимо изменить функцию showPoints в файле gmap-polyline.html и после строк

document.getElementById("route").innerHTML += points[n]+'<br>’;
}

Добавить новый фрагмент кода:

GDownloadUrl("upload.php", function(data, responseCode) {
if (responseCode == 200 && data.length <= 1) {
document.getElementById("message").innerHTML = "Location added.";
}
},
"points="+points);

Здесь для передачи данных используется функция GDownloadUrl, которая может передавать параметры не только методом GET, но и POST

Смотрите ее описание в документации по адресу http://code.google.com/intl/ru/apis/maps/documentation/javascript/v2/reference.html#GDownloadUrl

Посмотреть пример в действии

Полный код файла  gmap-polyline.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"> 
  <head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
 
<title>API Google Maps рисуем полилинии</title> 
 
<style type="text/css"> 
 
v:* { /* Only for IE */
	behavior:url(#default#VML);
}
 
body { height: 600px; }
 
#map { position: absolute;
	top: 50px;
	left: 15px;
	width: 550px;
	height: 400px;
}
 
#descr { position: absolute;
	left: 580px;
	top: 50px;
	margin-right: 40px;
}
 
.tooltip {
	text-align: center;
	opacity: .70;
	-moz-opacity:.70;
	filter:Alpha(opacity=70);
	white-space: nowrap;
	margin: 0;
	padding: 2px 0.5ex;
	border: 1px solid #000;
	font-weight: bold;
	font-size: 9pt;
	font-family: Verdana;
	background-color: #fff;
}
 
</style> 
 
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAACHCJdlgAEGcD_flKUFEmVhQlAYd20Yeej0MiKNuYPUGBnCwDThQlwUCPtCqtX3RC7LUKE-JYan3T4g"
            type="text/javascript"></script> 
 
</head> 
 
<body onload="buildMap()" onunload="GUnload()"> 
 
<div id="map"></div> 
 
<div id="descr">Нажмите на карту, чтобы установить маркеры в узлах полилинии.<br> 
Чтобы удалить существующий маркер, нажмите на маркер снова.
<p><a href="#" onclick="showPoints()">Сохранить линию</a></p> 
<div id="route"><p><strong>Координаты вершин полилинии:</strong></p></div> 
</div> 
 
<div id="message"></div>
 
<p><a href="/?p=557" title="API Google Maps рисуем полилинию и сохраняем ее в базе данных MySQL" target="_blank">Вернуться к тексту заметки</a></p> 
 
<script type="text/javascript"> 
//<![CDATA[
 
// Глобальные переменные
var mapdiv = document.getElementById("map");
var map;
var polylines = new Array();
var count = 0;
var points = new Array();
var markers = new Array();
var icon_url ="http://labs.google.com/ridefinder/images/";
var tooltip;
 
 
function addIcon(icon) { // Определяем значки для маркеров
 
 icon.shadow= icon_url + "mm_20_shadow.png";
 icon.iconSize = new GSize(12, 20);
 icon.shadowSize = new GSize(22, 20);
 icon.iconAnchor = new GPoint(6, 20);
 icon.infoWindowAnchor = new GPoint(5, 1);
}
 
 
function showTooltip(marker) { // показываем подсказки (tooltip)
 
 tooltip.innerHTML = marker.tooltip;
 tooltip.style.display = "block";
 
 // Tooltip transparency specially for IE
 if(typeof(tooltip.style.filter) == "string") {
 tooltip.style.filter = "alpha(opacity:70)";
 }
 
 var currtype = map.getCurrentMapType().getProjection();
 var point= currtype.fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
 var offset= currtype.fromLatLngToPixel(marker.getLatLng(),map.getZoom());
 var anchor = marker.getIcon().iconAnchor;
 var width = marker.getIcon().iconSize.width + 6;
// var height = tooltip.clientHeight +18;
 var height = 10;
 var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y - height)); 
 pos.apply(tooltip);
}
 
 
function buildMap() {
 
 map = new GMap2((mapdiv), {draggableCursor:"auto", draggingCursor:"move"});
 
 // Добавляем слушатель события для белых маркеров
 GEvent.bind(map, "click", this, this.leftClick);
 
 // Добавляем div элемент для toolips
 tooltip = document.createElement("div");
 tooltip.className="tooltip";
 map.getPane(G_MAP_MARKER_PANE).appendChild(tooltip);
 
 // Определяем карту и добавляем элементы управления
 map.setCenter(new GLatLng(56.2980387, 43.9123535), 13);
 map.addControl(new GLargeMapControl()); 
 map.addControl(new GMapTypeControl()); 
 map.disableDoubleClickZoom();
} 
 
function leftClick(overlay, point) {
 
 if(point) {
 
  // Иконка для белого маркера
  var icon = new GIcon();
  icon.image = icon_url +"mm_20_white.png";
  addIcon(icon);
 
  count++;
  var w_marker = new GMarker(point, icon);
  map.addOverlay(w_marker);
  w_marker.content = count;
  markers.push(w_marker);
  points.push(point);
 
  w_marker.tooltip = "Точка "+ count;
 
  GEvent.addListener(w_marker, "mouseover", function() {
   showTooltip(w_marker);
  });
 
  GEvent.addListener(w_marker, "mouseout", function() {
   tooltip.style.display = "none";
 });
 
 if(markers.length > 1) {
 
  // Рисуем красную полилинию
  var poly = new GPolyline(points, "#ff0000", 2, 1);
  map.addOverlay(poly);
  polylines.push(poly);
 }
 
  // Слушаем событие удаление маркера
  GEvent.addListener(w_marker, "click", function() {
 
  tooltip.style.display = "none";
  // Удаляем все полилинии, прежде чем делать более короткий путь
  for(var m= 0; m < polylines.length; m++) {
   map.removeOverlay(polylines[m]);
  }
  polylines.length = 0;
  // Удаляем маркер
  for(var n = 0; n < markers.length; n++) {
 
   if(markers[n] == w_marker) {
    map.removeOverlay(markers[n]);
    break;
   }
  }
  // Уменьшаем массив маркеров и точек и настраиваем счетчик
  markers.splice(n, 1); points.splice(n, 1);
  if(markers.length == 0) {
    count = 0;
  }
   else {
    count = markers[markers.length-1].content;
  }
 
  // Рисуем короткий путь
  var newpoly = new GPolyline(points, "#ff0000", 2, 1);
  map.addOverlay(newpoly);
  polylines.push(newpoly);
  });
 }
}
 
//Выводим координаты маркеров при клике на ссылку Сохранить линию
function showPoints() {	
for (var n = 0 ; n < points.length ; n++ ) {
document.getElementById("route").innerHTML += points[n]+'<br>';
}
 
 GDownloadUrl("upload.php", function(data, responseCode) {
        if (responseCode == 200 && data.length <= 1) {         
          document.getElementById("message").innerHTML = "Location added.";
        }
      },
 
        "points="+points);
 
 
}
 
//]]>
</script> 
 
</body> 
</html>

После того как,  мы передали данные о нашей полилинии в таблицу usersline, необходимо вывести их на карту.

Для этого нам нужно сформировать XML-файл с данными полилиний и отобразить на карте.

Формировать xml-файл мы будем при помощи скрипта viv-xml.php

Его код:

<?php
 
include("config.php");
 
echo '<markers>', "n";
 
$result = mysql_query("SELECT * FROM usersline");
if(mysql_num_rows($result)>0)
            {
			while ($mar = mysql_fetch_array($result))
            {
			echo '<line colour="', $mar['colour'], '" width="', $mar['width'], '" html="Полилиния-', $mar['id_line'], '"> ', "n";
			$str_exp1 = explode(";", $mar['coordinats']);
 
			for($i=0; $i<count($str_exp1); $i++)
			{
			$str_exp2 = explode(",", $str_exp1[$i]);
			echo '<point lat="', $str_exp2[0], '" lng="', $str_exp2[1], '" />', "n";
			}
 
			echo '</line>', "n";
			}
 
			}
 
			else
{
echo "<p>Линий не обнаружено!</p>";
}
 
echo '</markers>';
 
?><?php
 
include("config.php");
 
echo '<markers>', "n";
 
$result = mysql_query("SELECT * FROM usersline");
if(mysql_num_rows($result)>0)
            {
			while ($mar = mysql_fetch_array($result))
            {
			echo '<line colour="', $mar['colour'], '" width="', $mar['width'], '" html="Полилиния-', $mar['id_line'], '"> ', "n";
			$str_exp1 = explode(";", $mar['coordinats']);
 
			for($i=0; $i<count($str_exp1); $i++)
			{
			$str_exp2 = explode(",", $str_exp1[$i]);
			echo '<point lat="', $str_exp2[0], '" lng="', $str_exp2[1], '" />', "n";
			}
 
			echo '</line>', "n";
			}
 
			}
 
			else
{
echo "<p>Линий не обнаружено!</p>";
}
 
echo '</markers>';
 
?>

Здесь мы делаем выборку данных из базы и на их основе формируем xml-фай, используя оператор echo.

Если выполнить данный скрипт в браузере и посмотреть исходный код страницы мы увидим примерно следующее:

<markers>
<line colour="#FF0000" width="4" html="Полилиния-1">
<point lat="56.294157195782795" lng=" 43.905487060546875" />
<point lat="56.29768165036526" lng=" 43.92316818237305" />
<point lat="56.30168198872378" lng=" 43.937931060791016" />
</line>
<line colour="#008800" width="4" html="Полилиния-2">
<point lat="56.32186778153616" lng=" 43.980159759521484" />
<point lat="56.31349006825793" lng=" 43.990631103515625" />
<point lat="56.315870287350684" lng=" 44.0031623840332" />
<point lat="56.315679875282434" lng=" 44.01775360107422" />
<point lat="56.30987185111504" lng=" 44.02376174926758" />
<point lat="56.30653897945073" lng=" 44.039039611816406" />
<point lat="56.31168100253115" lng=" 44.047279357910156" />
</line>
</markers>

За вывод информации на карту будет отвечать файл viv-xml-polyline.html

Код данного файла:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>API Google Maps - вывод полилинии из XML-файла</title> 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAACHCJdlgAEGcD_flKUFEmVhQlAYd20Yeej0MiKNuYPUGBnCwDThQlwUCPtCqtX3RC7LUKE-JYan3T4g"
            type="text/javascript"></script> 
  </head> 
  <body onunload="GUnload()"> 
 
           <div id="map" style="width:800px; height: 600px"></div>       
 
    <script type="text/javascript"> 
    //<![CDATA[
 
    if (GBrowserIsCompatible()) { 
 
       // Определяем карту и добавляем элементы управления
      var map = new GMap2(document.getElementById("map"));
      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      map.setCenter(new GLatLng(56.2980387, 43.9123535), 13);
 
 
      // Читаем данные из XML-файла
 
      var request = GXmlHttp.create();
      request.open("GET", "viv-xml.php", true);
      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          var xmlDoc = GXml.parse(request.responseText);
 
          var markers = xmlDoc.documentElement.getElementsByTagName("marker");                             
 
          // ========= Обработка полилинии ===========
          var lines = xmlDoc.documentElement.getElementsByTagName("line");
          // читаем каждую линию
          for (var a = 0; a < lines.length; a++) {
            // определяем атрибуты линии - цвет и ширину
            var colour = lines[a].getAttribute("colour");
            var width  = parseFloat(lines[a].getAttribute("width"));
            // читаем каждую вершину полилинии
            var points = lines[a].getElementsByTagName("point");
            var pts = [];
            for (var i = 0; i < points.length; i++) {
               pts[i] = new GLatLng(parseFloat(points[i].getAttribute("lat")),
                                   parseFloat(points[i].getAttribute("lng")));
            }
            map.addOverlay(new GPolyline(pts,colour,width));
          }
          // ================================================           
        }
      }
      request.send(null);
 
    }
 
    // display a warning if the browser was not compatible
    else {
      alert("К сожалению, API Карт Google, не совместимые с данным браузером");    }
 
    //]]>
    </script> 
  </body> 
 
</html>

В данном файле мы обрабатываем сгенирированный скриптом viv-xml.php xml-файл и по извлеченным из него данным рисуем полилинии.

Посмотреть пример в действии.

Конечно, это только пример реализации процесса рисования полилинии и сохранения ее в базе данных MySQL с использованием API Google Maps.

Его можно развивать и усовершенствовать.

Можно использовать кодирование вершин полилинии, хранить координаты не в виде текстовой строки, а виде геометрического объекта, использовать для хранения базу данных PostgreSQL с расширением PostGIS и т.д.

При написании заметки использовалась статья Polylines from XML

API Google Maps рисуем полилинию и сохраняем ее в базе данных MySQL – продолжение: 6 комментариев

  1. Katya

    Спасибо Вам огромное за статью!!! У Вас отличный сайт! Все понятно даже для таких чайников как я!! )))

  2. sashko29

    Прошу Вас, если вы знаете как можно использовать ресурс гуглерз или гуглмапс или яндекс.карты без изображенной на них карты земли, рек, дорог, улиц, домов- напишите мне. Я хочу создать вместо земли, например футбольный мяч (если это ерз), или карту своей квартиры (для игры например) нанося на него пометки и ссылки. Если кто-то знает как это сделать напишите мне zaqwsx13531@mail.ru.

    Огромное спасибо за оперативность.

  3. Alex

    ТОВАРИЩ Admin перевелите статью на Яндекс Карты, гугл уже не торт!

  4. Artem

    Саттья интересная, реализовал себе такую штуку. Но есть вопрос. Читаю координаты с базы рисую полилинию №1, все работает как надо. Дальше выбираю линию №2, окно обновляется но на карте все еще линия №1. Если подождать пару минут и обновить, нарисует линию №2 как и надо. Не могу понять что ограничивает время изменения линий. Работает как надо но только с интервалом в 2-3 минуты.

  5. Станислав

    Достаточно интересно, но:

    1. В JS лучше массив «впихивать» не так:
    pts[i] = new GLatLng(parseFloat(points[i].getAttribute(«lat»)),
    parseFloat(points[i].getAttribute(«lng»)));
    А так:
    pts.push(new GLatLng(parseFloat(points[i].getAttribute(«lat»)),
    parseFloat(points[i].getAttribute(«lng»))));

    А сейчас самое интересное:

    Если Вы добавляли пустой массив точек в БД, то запись добавляется. Это нужно пофиксить. И если я выполню сие действие : «map.addOverlay(new GPolyline(pts,colour,width));» полилинии, разумеется я не увижу (ошибка).

    => При составлении массива (читаем п.1) необходимо заранее сделать проверку в цикле for на то, что в нем содержится какое-либо содержимое.
    Например, я сделал так:
    if((points[i].getAttribute(«lat»)).length > 10){
    pts.push(new GLatLng(parseFloat(points[i].getAttribute(«lat»)),
    parseFloat(points[i].getAttribute(«lng»))));
    }

    Тогда фишка с пустой строкой координат не помешает 🙂

  6. Volodymyr

    Как у файл upload.php передать не толко координати но ещё цвет линии и припустим ее толщину (несколько параметров)?

Добавить комментарий для Katya Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *