Организация добавления и вывода данных на карту Google Maps, используя Fusion Tables

После публикации заметки «Организация добавления и вывода данных на
карту Google Maps по категориям, используя PHP и MySQL
»
мне задали вопрос, как это же можно сделать используя сервис Fusion
Tables
?

В этой заметке я расскажу как это реализовать .

На своем блоге я уже писал о том как можно использовать Fusion
Tables для отображения данных на картах Google
(http://webmap-blog.ru/google-maps/ispolzuem-fusion-tables-dlya-otobrazheniya-dannyx-na-kartax-google
и
http://webmap-blog.ru/google-maps/ispolzuem-fusion-tables-dlya-otobrazheniya-dannyx-na-kartax-google-prodolzhenie
). Это для тех, кто еще не знаком с данным сервисом.

Для решения нашей задачи мы будем использовать Google Fusion Tables
API
  и небольшую
php-библиотеку для удобства взаимодействия с этим API на языке PHP​

Загрузить код библиотеки  fusiontableslib.php можно здесь
или с моего блога.

Для работы библиотеки должно быть активно расширение php — CURL.

На первом этапе мы должны создать таблицу usersmarkerstable, в
которую пользователи будут добавлять свои метки.

Для этого мы заходим на главную страницу сервиса Google Fusion
Tables по адресу http://www.google.com/fusiontables/Home и в выпадающем
меню New table в левой части страницы выбираем пункт New empty table.

Открывается новая страница с новой таблицей New Table и начальной
структурой столбцов: Text, Number, Location, Date

Изменим название колонок и их тип как нам необходимо.

В меню Edit выберем пункт Modify columns – для изменения колонок.

Для колонки Text вводим новое название name
Для колонки Number – название address и тип text
Колонку Location переименуем в lat
Для колонки Date — название type, тип text

Нажимаем кнопку Save для сохранения изменений

Добавим еще одну колонку lng, выбрав в меню Edit пункт Add columns,
тип колонки location.

И еще для коллонки lat в свойствах отметим галочкой Two column
location и выберем для Latitude: колонку lat, а для Longitude: — lng.

Теперь изменим название нашей таблицы с New Table на
usersmarkerstable.

Для этого мы выбираем в меню Edit пункт Modify table info.

В открывшемся окне заменяем название таблицы на usersmarkerstable и
нажимаем кнопку Save для сохранения внесенных изменений.

Запоминаем идентификатор созданной таблицы из адресной строки, у
моей таблицы dsrcid=406275

Можно добавить одну строку с данными в таблицу для того, чтобы
настроить отображение данных их таблицы Fusion Tables на Google Maps.

Для этого в меню Edit выберем пункт Add row.

Заполняем поля в открывшемся окне как показано на рисунке

Сохраняем изменения.

Отобразим наши данные на карте Google, для этого выберем в меню
Vizualize пункт Map.

Настроим шаблон для отображения информации в балуне, перейдя по
ссылке Configure info window.

Выбираем тип шаблона Custom и вводим следующий код:

<strong>Наименование:</strong> {name}<br />
<strong>Адрес:</strong> {address}

Щелкнув мышью по маркеру мы увидим следующее:

Теперь организуем вывод полученной карты с использованием API Google
Maps v3 и предварительно изменив параметры ее видимости.

 
<html> 
  <head> 
    <title>Добавление меток пользователями, с использованием Google Maps API v3 и Fusion Tables API</title> 
    <link rel="stylesheet" href="common.css"> 
    <link rel="stylesheet" href="dialog.css"> 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
	<script src="jquery.min.js" type="text/javascript"></script>
    <style> 
    body {
      font-family: sans-serif;
      font-size: small;
    }
 
    #map {
      width: 800px;
      height: 600px;
      border: 1px solid black;
      margin-bottom: 10px;
    }
    </style> 
  <script> 
  var map, layer;
 
    var marker;
    var infowindow;
 
 $(document).ready(function(){
 
    map = new google.maps.Map(document.getElementById('map'), {
      center: new google.maps.LatLng(56.316537,43.998779),
      zoom: 14,
      mapTypeId: 'roadmap'
    });
 
 
    layer = new google.maps.FusionTablesLayer(406275, {
    query: "SELECT lat, lng from 406275 WHERE type ='cafe'"}
  );
  layer.setMap(map);  
 
   });  
 
 
function updateMap() { layer.setQuery("select lat, lng from 406275 where type = 'bar'"); }
function updateMap1() {layer.setQuery("select lat, lng from 406275 where type = 'cafe'"); }
function updateMap2() {layer.setQuery("select lat, lng from 406275 where type = 'restaurant'"); }
function updateMap3() {layer.setQuery("select lat, lng from 406275"); }
 
</script> 
 
<body> 
<table> 
<tr><td style="vertical-align:top;"> 
<div id="map"></div> 
<div id="message"></div>
</td>
 
<td style="vertical-align:top;">
 
<a href="#" onclick="updateMap()">Бары</a><br />
<a href="#" onclick="updateMap1()">Кафе</a><br />
<a href="#" onclick="updateMap2()">Рестораны</a><br />
<a href="#" onclick="updateMap3()">Все</a><br />
 
</td>	
</tr>	
</table>
 
</body> 
</html>

Загружаем страницу в браузере и наблюдаем:

В коде организована возможность вывода меток из таблицы по
категориям.

Следующим этапом будет организация добавления данных пользователей.

По щелчку мышкой по карте будет появляться маркер, а по щелчку по
маркеру открываться балун с формой для ввода параметров метки.

После ввода параметров метки и нажатие кнопки Сохранить, данные
будут передаваться скрипту phpsqlinfo_addrow.php, он будет выполнять
запись данных с использованием Fusion Tables API в нашу таблицу
usersmarkerstable. В случае успеха php-скрипт отправляем сообщение на
страницу с картой с идентификатором добавленной строки.

Если обновить страницу, то мы увидим добавленную метку (иногда из-за
кэширования браузера метка не видна, тогда стоит очистить кэш и
перезагрузить страницу).

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

Окончательный код файла index.html

 
<html> 
  <head> 
    <title>Добавление меток пользователями, с использованием Google Maps API v3 и Fusion Tables API</title> 
    <link rel="stylesheet" href="common.css"> 
    <link rel="stylesheet" href="dialog.css"> 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
	<script src="jquery.min.js" type="text/javascript"></script>
    <style> 
    body {
      font-family: sans-serif;
      font-size: small;
    }
 
    #map {
      width: 800px;
      height: 600px;
      border: 1px solid black;
      margin-bottom: 10px;
    }
    </style> 
  <script> 
  var map, layer;
 
    var marker;
    var infowindow;
 
 $(document).ready(function(){
 
    map = new google.maps.Map(document.getElementById('map'), {
      center: new google.maps.LatLng(56.316537,43.998779),
      zoom: 14,
      mapTypeId: 'roadmap'
    });
 
 
    layer = new google.maps.FusionTablesLayer(406275, {
    query: "SELECT lat, lng from 406275 WHERE type ='cafe'"}
  );
  layer.setMap(map);  
 
<!-- Добавление меток -->	
      var html = "<table>" +
                 "<tr><td>Наименование:</td> <td><input type='text' id='name'/> </td> </tr>" +
                 "<tr><td>Адрес:</td> <td><input type='text' id='address'/></td> </tr>" +
                 "<tr><td>Тип:</td> <td><select id='type'>" +
                 "<option value='bar' SELECTED>bar</option>" +
                 "<option value='cafe' SELECTED>cafe</option>" +
                 "<option value='restaurant'>restaurant</option>" +
                 "</select> </td></tr>" +
                 "<tr><td></td><td><input type='button' value='Сохранить' onclick='saveData()'/></td></tr>";
    infowindow = new google.maps.InfoWindow({
     content: html
    });
 
    google.maps.event.addListener(map, "click", function(event) {
        marker = new google.maps.Marker({
          position: event.latLng,
          map: map
        });
        google.maps.event.addListener(marker, "click", function() {
          infowindow.open(map, marker);
        });
    });
   });
 
  function saveData() {
      var name = escape(document.getElementById("name").value);
      var address = escape(document.getElementById("address").value);
      var type = document.getElementById("type").value;
      var latlng = marker.getPosition();
 
	$.get("phpsqlinfo_addrow.php", {name: name, address:address, type:type, lat: latlng.lat(), lng:latlng.lng()}, function(data){
	infowindow.close();
	$('#message').html('Данные добавлены! RowID: '+data);
	});
 
    }    
 
function updateMap() { layer.setQuery("select lat, lng from 406275 where type = 'bar'"); }
function updateMap1() {layer.setQuery("select lat, lng from 406275 where type = 'cafe'"); }
function updateMap2() {layer.setQuery("select lat, lng from 406275 where type = 'restaurant'"); }
function updateMap3() {layer.setQuery("select lat, lng from 406275"); }
 
</script> 
 
<body> 
<table> 
<tr><td style="vertical-align:top;"> 
<div id="map"></div> 
<div id="message"></div>
</td>
 
<td style="vertical-align:top;">
 
<a href="#" onclick="updateMap()">Бары</a><br />
<a href="#" onclick="updateMap1()">Кафе</a><br />
<a href="#" onclick="updateMap2()">Рестораны</a><br />
<a href="#" onclick="updateMap3()">Все</a><br />
 
</td>	
</tr>	
</table>
 
</body> 
</html>

В начале мы подключаем файл с библиотекой jQuery строкой:

<script src=»jquery.min.js»
type=»text/javascript»></script>

Определяем основные параметры нашей карты и подгружаем слой из
таблицы usersmarkerstable с метками кафе.

После задается содержимое для балуна – форма ввода параметров метки.

Затем идет обработка события клика по карте, мы открываем балун
строкой infowindow.open(map, marker);

Функция saveData вызывается при нажатии на кнопку Сохранить и
значения из формы методом GET передаются скрипту phpsqlinfo_addrow.php

Затем принимаются данные data из скрипта и выводиться сообщенние
«Данные добавлены!»
Теперь рассмотрим код файла phpsqlinfo_addrow.php

 
<?php
include("fusiontableslib.php");
 
function utf8_urldecode($str) {
    $str = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\1;",urldecode($str));
    return html_entity_decode($str,null,'UTF-8');
  }
 
header('Content-Type: text/html; charset=utf-8');
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
 
// Gets data from URL parameters
$name = utf8_urldecode($_GET['name']);
$address = utf8_urldecode($_GET['address']);
$lat = $_GET['lat'];
$lng = $_GET['lng'];
$type = $_GET['type'];
 
$token = GoogleClientLogin("login", "password", "fusiontables");
 
$ft = new FusionTable($token);
 
$output = $ft->query("INSERT INTO 406275 (name, address, lat, lng, type) VALUES ('$name', '$address', '$lat', '$lng', '$type')");
 
$result = $output[0]['rowid'];
 
echo $result;
 
}
 
?>

В начале мы подключаем файл с библиотекой fusiontableslib.php

После идет вспомогательная функция для декодирования названия и
адреса на русском языке из адресной строки utf8_urldecode.

Далее мы принимаем переданные параметры, причем проверяем как послан
запрос.

Следущая строка $token = GoogleClientLogin(«login», «password»,
«fusiontables»);

передает параметры для авторизации пользователя на сайте Google:

login — логин для авторизации, для всех сервисов Google логином
является адрес электронной почты вида xxxxx@gmail.com, здесь вы должны
вводить в качестве логина левую часть до знака @.

password — ваш пароль для сервисов Google;

fusiontables — название подключаемого сервиса.

Строка $ft = new FusionTable($token); определяет указатель для
подключения.

Строка $output = $ft->query(«INSERT INTO 406275 (name, address,
lat, lng, type) VALUES (‘$name’, ‘$address’, ‘$lat’, ‘$lng’,
‘$type’)»); вставляет введенные данные в таблицу с идентификатором
406275 (usersmarkerstable).

Если вставка прошла успешно, то в переменную $result передается
значение идентификатора добавленой строки.

О других SQL-командах для работы с Google Fusion Tables API можно
узнать здесь.

  • Гость: вот спасибо... теперь попробую заточить код на благие дела...
  • Гость: +1, спасибо. Пойду ломать мозг =)
  • Гость: А всё ли верно написано о процессе создания таблицы? Ибо у меня такое чувство что - нет и пропущена какая то часть. Когда пытаюсь повторить "подвиг" получается совсем наоборот: строки не хотят объединяться и после строка add row выглядит совсем иначе. Один ли я такой везунчик?
  • Гость: Написано правильно, я проверил все еще раз. Нужно все делать внимательно без ошибок. И объединять ни строки, ни столбцы здесь не надо. Немного позже запишу небольшое видео по созданию таблиц в Fusion Tables
  • Гость: спасибо, что вняли нашим просьбам, пойду пробовать что-то сделать по вашему мануалу :)
  • Гость: подскажите, пожалуйста, возможно ли сделать так: при загрузке страницы отображается просто карта (России, к примеру), а при нажатии на ссылку будут подгружаться на карту данные из разных таблиц (например, театры, но расположенные в разных городах, а анкорами ссылок будут названия городов)?
  • Гость: Отдельно карту России показать нельзя, можно настроить область отображения, чтобы была максимально видна карта всей России. А по выборкам все возможно, к таблицам в Fusion Tables можно осуществлять SQL запросы
  • Гость: вы меня немного не поняли (я неточно выразился) я имею в виду как сделать так, чтобы карта при загрузке страницы отобразилась без маркеров, а маркеры подгружались лишь при выполнении SQL запроса. И еще такой вопрос: SQL запросы можно делать к разным таблицам?
  • Гость: Я видимо не так выразился, не теми словами. Вот это вот действие вызывает затруднение: И еще для коллонки lat в свойствах отметим галочкой Two column location и выберем для Latitude: колонку lat, а для Longitude: – lng. Фт отвечает - проблема в определении и делает вид что ничего не происходило и колонка под названием - ing пропадает. Буду ждать видео, надеюсь там будет показан ответ на мои "страдания". =)
  • Гость: Видео бы...
  • Гость: здесь кодировка не та http://webmap-blog.ru/files/fusion/index.html
  • Гость: Проверю, спасибо
  • Гость: Добрый и занятой дядя Админ, добавь пожалуйста видео с уроком по этому материалу.
  • Гость: Подскажите пожалуйста, а можно ли, используя функционал таблицы, отдельные строчки в ней делать невидимыми. К примеру, на карту наносятся клиенты, которые оплатили эту услугу. Затем, по каким-то причинам, они не проплатили - значит их нужно выключить. Удалять не хочется, потому что через время они проплатят и опять появятся на карте.
  • Гость: И еще, в карте изготовленной данным способом отсутствует кнопка "Земля". А, к примеру, на картах сделанных через простой механизм создания "Моя карта" эта кнопка есть. Её можно как-то добавить?
  • Гость: И еще один маленький вопросик: Вот на страничке клиента, на нашем сайте http://www.nashasvadba.zp.ua/soms/main.php?fr=uldthlmkleharflmr7rarclwgnldhjulftaohlmugorldjej93 внизу есть карта месторасположения. Можно ли сделать одну метку на карте (т.е. метку клиента) развернутой. Ну, чтобы она сразу привлекала к себе внимание. Заранее благодарен!
  • Гость: Ф-у-уххх!!! Получилось!!! http://www.nashasvadba.zp.ua/soms/main.php?fr=uldthlmklehanhtldlbjudhfgclmlbganhtldlbjeje# спасибо большое автору блога
  • Гость: FusionTable позволяет в отдельной колонке хранить имена меток.На карте отображаются пользовательские метки, исходя из соответствия имени и "привязанного" набора. Набор имеющихся в распоряжении меток явно слабоват. Хотелось бы иметь возможность самому хранить свой файл метки в колонке (ссылку на него), с условием, что будет отображаться моя иконка метки. Сначала думалось, что пропишу в какой-нибудь колонке часть KML с тегом и атрибутами , но сервис "не переваривает" такой код. Что делать? Или это в принципе невозможно реализовать с помощью fusiontables??? Спасибо.
  • Гость: Здравствуйте, у меня в файле phpsqlinfo_addrow.php ошибка. Пишет Данные добавлены! RowID: Fatal error: Cannot use string offset as an array in Z:homepoputkauzwwwphpsqlinfo_addrow.php on line 25 В чем может быть проблема?
  • Гость: Ошибка возникает "Невозможно использовать строки смещения в виде массива", надо смотреть значение переменной $output[0]['rowid']. Передается не одно значение, а массив значений. Его можно посмотреть так, print_r($output[0]['rowid']);
  • Гость: Теперь пишет Данные добавлены! RowID: Fatal error: Cannot use string offset as an array in /srv/www/vhosts/poputka.uz/httpdocs/phpsqlinfo_addrow.php on line 25
  • Гость: Я правильно написал строку? $result = print_r($output[0]['rowid']);
  • Гость: Нет, оператор print_r выводит данные в виде ключ=>значение, его нельзя присваивать какой-либо переменой. Правильно print_r($output[0]['rowid']);, а строку ниже echo $result; нужно удалить.
  • Гость: Здравствуйте, все равно пишет Данные добавлены! RowID: Fatal error: Cannot use string offset as an array in /srv/www/vhosts/poputka.uz/httpdocs/phpsqlinfo_addrow.php on line 25
  • Гость: Когда запускаешь ваш пример такая же ошибка выходит Fatal error: Cannot use string offset as an array in /home/k/katalogbiz/webmap/public_html/files/fusion/phpsqlinfo_addrow.php on line 25 Я так понят что раньше на других браузерах всё работало нормально?
  • Гость: Надо разобраться в чем дело
  • Гость: Здравствуйте, очень жду решения проблемы
  • Гость: Не понимаю почему у автора при добавлении есть пункт "location" в Create new row, хотя его же в lat переименовали. У меня при добавлении добавляюца в разные строки кординаты почему то.
  • Гость: Марат, я нашел, как можно сделать свою иконку на каждое поле
  • Гость: Здравствуйте! очень интересная статья и полезный сервис! Но никак не могу решить проблему с CURL... Скачал дополнительный пакет для denwer, раскоментировал curl, phpinfo() показывает что curl = enabled Но после того как я пытаюсь добавить в свою таблицу данные спустя 40-50 сек. выдает ошибку: Данные добавлены! RowID: Fatal error: Maximum execution time of 30 seconds exceeded in V:hometest2wwwfusiontableslib.php on line 21, а точнее: $response = curl_exec($c); В файле phpsqlinfo_addrow.php логин, пароль и id таблицы указаны, сервис "fusiontables"
  • Гость: Проблема с cURL может возникать из-за установленного прокси - и решается через добавление строчки: сurl_setopt($c, CURLOPT_PROXY, 'ваш_прокси:порт'); в файле fusiontableslib.php (в двух местах) Марат, ваша проблема появляется из-за того что запрос не может подключиться Вашей к таблице. В файле phpsqlinfo_addrow.php проверьте логин и пароль, id вашей таблицы, и самое важное соответствие полей - чтобы ПОЛЯ ТАБЛИЦЫ начинались с МАЛЕНЬКОЙ БУКВЫ "name" "address" "type" - у меня такая ошибка появлялась из-за этого. admin, Спасибо за статью!