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

Автор: | 29.01.2011

После публикации заметки «Организация добавления и вывода данных на
карту 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 можно
узнать здесь.

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

  1. Тёмка

    А всё ли верно написано о процессе создания таблицы?
    Ибо у меня такое чувство что — нет и пропущена какая то часть.
    Когда пытаюсь повторить «подвиг» получается совсем наоборот:
    строки не хотят объединяться и после строка add row выглядит совсем иначе.
    Один ли я такой везунчик?

    1. admin Автор записи

      Написано правильно, я проверил все еще раз. Нужно все делать внимательно без ошибок. И объединять ни строки, ни столбцы здесь не надо.
      Немного позже запишу небольшое видео по созданию таблиц в Fusion Tables

  2. shramik84

    спасибо, что вняли нашим просьбам, пойду пробовать что-то сделать по вашему мануалу 🙂

  3. shramik84

    подскажите, пожалуйста, возможно ли сделать так: при загрузке страницы отображается просто карта (России, к примеру), а при нажатии на ссылку будут подгружаться на карту данные из разных таблиц (например, театры, но расположенные в разных городах, а анкорами ссылок будут названия городов)?

    1. admin Автор записи

      Отдельно карту России показать нельзя, можно настроить область отображения, чтобы была максимально видна карта всей России.
      А по выборкам все возможно, к таблицам в Fusion Tables можно осуществлять SQL запросы

  4. shramik84

    вы меня немного не поняли (я неточно выразился)
    я имею в виду как сделать так, чтобы карта при загрузке страницы отобразилась без маркеров, а маркеры подгружались лишь при выполнении SQL запроса. И еще такой вопрос: SQL запросы можно делать к разным таблицам?

  5. Тёмка

    Я видимо не так выразился, не теми словами.
    Вот это вот действие вызывает затруднение:
    И еще для коллонки lat в свойствах отметим галочкой Two column
    location и выберем для Latitude: колонку lat, а для Longitude: – lng.
    Фт отвечает — проблема в определении и делает вид что ничего не происходило и колонка под названием — ing пропадает.
    Буду ждать видео, надеюсь там будет показан ответ на мои «страдания». =)

  6. Тёмка

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

  7. Руслан

    Подскажите пожалуйста, а можно ли, используя функционал таблицы, отдельные строчки в ней делать невидимыми. К примеру, на карту наносятся клиенты, которые оплатили эту услугу. Затем, по каким-то причинам, они не проплатили — значит их нужно выключить. Удалять не хочется, потому что через время они проплатят и опять появятся на карте.

  8. Руслан

    И еще, в карте изготовленной данным способом отсутствует кнопка «Земля». А, к примеру, на картах сделанных через простой механизм создания «Моя карта» эта кнопка есть. Её можно как-то добавить?

  9. Руслан

    И еще один маленький вопросик: Вот на страничке клиента, на нашем сайте http://www.nashasvadba.zp.ua/soms/main.php?fr=uldthlmkleharflmr7rarclwgnldhjulftaohlmugorldjej93 внизу есть карта месторасположения. Можно ли сделать одну метку на карте (т.е. метку клиента) развернутой. Ну, чтобы она сразу привлекала к себе внимание.

    Заранее благодарен!

  10. Вова

    FusionTable позволяет в отдельной колонке хранить имена меток.На карте отображаются пользовательские метки, исходя из соответствия имени и «привязанного» набора. Набор имеющихся в распоряжении меток явно слабоват.
    Хотелось бы иметь возможность самому хранить свой файл метки в колонке (ссылку на него), с условием, что будет отображаться моя иконка метки.
    Сначала думалось, что пропишу в какой-нибудь колонке часть KML с тегом и атрибутами , но сервис «не переваривает» такой код. Что делать? Или это в принципе невозможно реализовать с помощью fusiontables???
    Спасибо.

  11. Марат

    Здравствуйте, у меня в файле phpsqlinfo_addrow.php ошибка.
    Пишет Данные добавлены! RowID:
    Fatal error: Cannot use string offset as an array in Z:homepoputkauzwwwphpsqlinfo_addrow.php on line 25
    В чем может быть проблема?

    1. admin Автор записи

      Ошибка возникает «Невозможно использовать строки смещения в виде массива», надо смотреть значение переменной $output[0][‘rowid’].
      Передается не одно значение, а массив значений. Его можно посмотреть так, print_r($output[0][‘rowid’]);

  12. Марат

    Теперь пишет
    Данные добавлены! RowID:
    Fatal error: Cannot use string offset as an array in /srv/www/vhosts/poputka.uz/httpdocs/phpsqlinfo_addrow.php on line 25

  13. Марат

    Я правильно написал строку?
    $result = print_r($output[0][‘rowid’]);

    1. admin Автор записи

      Нет, оператор print_r выводит данные в виде ключ=>значение, его нельзя присваивать какой-либо переменой.
      Правильно print_r($output[0][‘rowid’]);, а строку ниже echo $result; нужно удалить.

  14. Марат

    Здравствуйте, все равно пишет
    Данные добавлены! RowID:
    Fatal error: Cannot use string offset as an array in /srv/www/vhosts/poputka.uz/httpdocs/phpsqlinfo_addrow.php on line 25

  15. Марат

    Когда запускаешь ваш пример такая же ошибка выходит
    Fatal error: Cannot use string offset as an array in /home/k/katalogbiz/webmap/public_html/files/fusion/phpsqlinfo_addrow.php on line 25
    Я так понят что раньше на других браузерах всё работало нормально?

  16. ILYA

    Не понимаю почему у автора при добавлении есть пункт «location» в Create new row, хотя его же в lat переименовали.

    У меня при добавлении добавляюца в разные строки кординаты почему то.

  17. Иван

    Здравствуйте! очень интересная статья и полезный сервис!
    Но никак не могу решить проблему с 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»

  18. Иван

    Проблема с cURL может возникать из-за установленного прокси — и решается через добавление строчки:
    сurl_setopt($c, CURLOPT_PROXY, ‘ваш_прокси:порт’);
    в файле fusiontableslib.php (в двух местах)

    Марат, ваша проблема появляется из-за того что запрос не может подключиться Вашей к таблице.
    В файле phpsqlinfo_addrow.php проверьте логин и пароль, id вашей таблицы, и самое важное соответствие полей — чтобы ПОЛЯ ТАБЛИЦЫ начинались с МАЛЕНЬКОЙ БУКВЫ «name» «address» «type» — у меня такая ошибка появлялась из-за этого.

    admin, Спасибо за статью!

Добавить комментарий

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