Организация добавления и вывода данных на карту Google Maps по категориям, используя PHP и MySQL (версия для API Google Maps v3)

На своем блоге я уже писал заметку на тему «Организация добавления и вывода данных на карту Google Maps по категориям, используя PHP и MySQL» и в ней использовалась API Google Maps версии 2.

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

С начала перечислю файлы которые мы будем использовать для данной версии без изменения.

Это файлы:

phpsqlinfo_dbinfo.php — для соединения с базой данных;
phpsqlinfo_addrow.php — для записи введенных данных о метке в таблицу markers;
upload.php — выбор информации о метках из базы данных и формирования ответа в формате JSON.

Основным файлом нашего примера будет файл phpsqlinfo_add.html.

Начнем заново формировать код данного файла, по ходу описания я буду отмечать особенности присущие для версии 3 API Google Maps.

Начнем с отображения карты с элементами управления.

Первоначальный код нашего файла phpsqlinfo_add.html

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>API Google Maps v3 добавление меток пользователями и вывод их по категориям</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
 
<script src="../jquery.min.js" type="text/javascript"></script>
 
<script type="text/javascript"> 
  function initialize() {
    var myLatlng = new google.maps.LatLng(56.32,44.004);
    var myOptions = {
      zoom: 15,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  }
</script> 
 
<style type="text/css" media="screen"> 
#map_canvas { float:left; width:600px; height:400px; border:1px solid #000;} 
ul#markerTypes { float:left; width:500px; list-style:none; padding:0; } 
ul#markerTypes li { padding:10px; } 
ul#markerTypes li label{ color: #000; } 
</style>
 
</head> 
<body onload="initialize()"> 
      <div id="map_canvas"></div>
 
 
	<ul id="markerTypes"> 
			<li><label for="viv_bars"><input id="barbox" type="checkbox" value="bar" /> Бары</label></li> 
			<li><label for="viv_cafe"><input id="cafebox" type="checkbox" value="cafe" /> Кафе</label></li> 
			<li><label for="viv_rest"><input id="restaurantbox" type="checkbox" value="restaurant" /> Рестораны</label></li>			 
		</ul>
 
    <div id="message"></div>
</body> 
</html>

Здесь есть отличие подключения API и инициализации карты от верии 2.

1. Нет ключа API для привязки к конкретному домену, здесь подключение API-карт производится строкой

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

2. Параметры карты задаются отдельным набором свойств myOptions

var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}

3. Все глобальные имена из API начинаются с google.maps. вместо G.

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

Измененный код файла phpsqlinfo_add.html

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>API Google Maps v3 добавление меток пользователями и вывод их по категориям</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
 
<script src="../jquery.min.js" type="text/javascript"></script>
 
<script type="text/javascript"> 
  function initialize() {
    var myLatlng = new google.maps.LatLng(56.32,44.004);
    var myOptions = {
      zoom: 15,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
 
     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>Бар</option>" +
                         "<option value='restaurant'>Ресторан</option>" +
                         "<option value='cafe'>Кафе</option>" +
                         "</select> </td></tr>" +
                         "<tr><td></td><td><input type='button' value='Сохранить' onclick='saveData()'/></td></tr></form>";
 
    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();
 
      var url = "phpsqlinfo_addrow.php?name=" + name + "&address=" + address +
                "&type=" + type + "&lat=" + latlng.lat() + "&lng=" + latlng.lng();
      downloadUrl(url, function(data, responseCode) {
        if (responseCode == 200 && data.length <= 1) {
          infowindow.close();
          document.getElementById("message").innerHTML = "Данные добавлены.";
        }
      });
    }
 
    function downloadUrl(url, callback) {
      var request = window.ActiveXObject ?
          new ActiveXObject('Microsoft.XMLHTTP') :
          new XMLHttpRequest;
 
      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          request.onreadystatechange = doNothing;
          callback(request.responseText, request.status);
        }
      };
 
      request.open('GET', url, true);
      request.send(null);
    }
 
    function doNothing() {}
 
</script> 
 
<style type="text/css" media="screen"> 
#map_canvas { float:left; width:600px; height:400px; border:1px solid #000;} 
ul#markerTypes { float:left; width:500px; list-style:none; padding:0; } 
ul#markerTypes li { padding:10px; } 
ul#markerTypes li label{ color: #000; } 
</style>
 
</head> 
<body onload="initialize()"> 
      <div id="map_canvas"></div> 
 
	<ul id="markerTypes"> 
			<li><label for="viv_bars"><input id="barbox" type="checkbox" value="bar" /> Бары</label></li> 
			<li><label for="viv_cafe"><input id="cafebox" type="checkbox" value="cafe" /> Кафе</label></li> 
			<li><label for="viv_rest"><input id="restaurantbox" type="checkbox" value="restaurant" /> Рестораны</label></li>			 
		</ul>
 
    <div id="message"></div>
</body> 
</html>

В переменную html мы добавляем код формы для ввода параметров метки.

И в балун добавляем нашу переменную html.

Затем мы обрабатываем события клика по карте, при этом событии на карту добавляется маркер, а при клике на маркере открывается балун с нашей формой.

После нажатия на кнопку Сохранить, введенные в форму параметры предаются в функцию saveData.

В ней методом GET данные передаются в файл phpsqlinfo_addrow.php для записи в базу данных.

Если запись прошла успешно, то выводится сообщение о добавлении данных.

Последний этап это реализация вывода маркеров из базы данных по категориям.

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

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>API Google Maps v3 добавление меток пользователями и вывод их по категориям</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
 
<script src="../jquery.min.js" type="text/javascript"></script>
 
<script type="text/javascript"> 
 
var map, marker, gmarkers = [];
 
var customIcons = {
      restaurant: {
        icon: 'http://webmap-blog.ru/files/gmap/gicon/mm_20_blue.png',
        shadow: 'http://webmap-blog.ru/files/gmap/gicon/mm_20_shadow.png'
      },
      bar: {
        icon: 'http://webmap-blog.ru/files/gmap/gicon/mm_20_red.png',
        shadow: 'http://webmap-blog.ru/files/gmap/gicon/mm_20_shadow.png'
      },
	  cafe: {
        icon: 'http://webmap-blog.ru/files/gmap/gicon/mm_20_green.png',
        shadow: 'http://webmap-blog.ru/files/gmap/gicon/mm_20_shadow.png'
      }	  
    };
 
  function initialize() {
    var myLatlng = new google.maps.LatLng(56.32,44.004);
    var myOptions = {
      zoom: 15,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
 
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
 
$('#markerTypes input[type="checkbox"]').bind('click', function () {
 
var markersType = $(this).val();
 
if($(this).attr("checked")) {
 
if(!gmarkers[markersType]) {
 
gmarkers[markersType] = [];
 
$.getJSON("http://localhost/gmaps/gmaps-dob/upload.php", {markersType:markersType}, function(data){
 
setMarkers(data, markersType);				
 
});
 
}
else {
show(markersType);
}
 
}
else {
hide(markersType);
}
});	
 
     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>Бар</option>" +
                         "<option value='restaurant'>Ресторан</option>" +
                         "<option value='cafe'>Кафе</option>" +
                         "</select> </td></tr>" +
                         "<tr><td></td><td><input type='button' value='Сохранить' onclick='saveData()'/></td></tr></form>";
    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();
 
      var url = "phpsqlinfo_addrow.php?name=" + name + "&address=" + address +
                "&type=" + type + "&lat=" + latlng.lat() + "&lng=" + latlng.lng();
      downloadUrl(url, function(data, responseCode) {
        if (responseCode == 200 && data.length <= 1) {
          infowindow.close();
          document.getElementById("message").innerHTML = "Данные добавлены.";
        }
      });
    }
 
    function downloadUrl(url, callback) {
      var request = window.ActiveXObject ?
          new ActiveXObject('Microsoft.XMLHTTP') :
          new XMLHttpRequest;
 
      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          request.onreadystatechange = doNothing;
          callback(request.responseText, request.status);
        }
      };
 
      request.open('GET', url, true);
      request.send(null);
    }
 
    function doNothing() {}	
 
	function setMarkers(data, category) {
 
	var infoWindow = new google.maps.InfoWindow;	 
	var baseIcon = customIcons[category];	
 
	var marker_point = new Array();
    var html = new Array();
 
	for(var i = 0; i < data.markers.length; i++) {	
    	marker_point[i] = new google.maps.LatLng(data.markers[i].lat, data.markers[i].lon);	
	html[i] = '<strong>'+data.markers[i].mname+'</strong><br />'+data.markers[i].address;
	createMarker(marker_point[i], html[i], baseIcon, infoWindow, category);
	}
 
}
 
function createMarker(point, html, icon, infoWindow, category) {
	 var marker = new google.maps.Marker({
            map: map,
            position: point,
             icon: icon.icon,
            shadow: icon.shadow           
          });
 
  marker.mycategory = category; 
 
  google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
  gmarkers.push(marker);
  return marker;
}
 
 
function show(category) {
        for (var i=0; i<gmarkers.length; i++) {
          if (gmarkers[i].mycategory == category) {
            gmarkers[i].setVisible(true);
          }
        }
        // == check the checkbox ==
        document.getElementById(category+"box").checked = true;
      }
 
      // == hides all markers of a particular category, and ensures the checkbox is cleared ==
      function hide(category) {
        for (var i=0; i<gmarkers.length; i++) {
          if (gmarkers[i].mycategory == category) {
            gmarkers[i].setVisible(false);
          }
        }
        // == clear the checkbox ==
        document.getElementById(category+"box").checked = false;
        // == close the info window, in case its open on a marker that we just hid
        infowindow.close();
      }
 
</script> 
 
<style type="text/css" media="screen"> 
#map_canvas { float:left; width:600px; height:400px; border:1px solid #000;} 
ul#markerTypes { float:left; width:500px; list-style:none; padding:0; } 
ul#markerTypes li { padding:10px; } 
ul#markerTypes li label{ color: #000; } 
</style>
 
</head> 
<body onload="initialize()"> 
      <div id="map_canvas"></div>
 
	<ul id="markerTypes"> 
			<li><label for="viv_bars"><input id="barbox" type="checkbox" value="bar" /> Бары</label></li> 
			<li><label for="viv_cafe"><input id="cafebox" type="checkbox" value="cafe" /> Кафе</label></li> 
			<li><label for="viv_rest"><input id="restaurantbox" type="checkbox" value="restaurant" /> Рестораны</label></li>			 
		</ul>
 
    <div id="message"></div>
</body> 
</html>

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

После этого, аналогично версии для API Google Maps v2, мы используя библиотеку jQuery, добавиляем обработчик события выбора соответствующей категории (checkbox), если влажок для категории установлен в асинхронном режиме с помощью функции getJSON производиться GET запрос к файлу upload.php, в котором выполняется обращение к таблице в базе данных для выбора параметров меток для данной категории.

В файле upload.php также из полученных данных формируется ответ в формате JSON, который затем передается в функцию setMarkers для обработки.

Функция setMarkers будет иметь другой вид:

function setMarkers(data, category) {
 
	var infoWindow = new google.maps.InfoWindow;	 
	var baseIcon = customIcons[category];	
 
	var marker_point = new Array();
    var html = new Array();
 
	for(var i = 0; i < data.markers.length; i++) {	
    	marker_point[i] = new google.maps.LatLng(data.markers[i].lat, data.markers[i].lon);	
	html[i] = '<strong>'+data.markers[i].mname+'</strong><br />'+data.markers[i].address;
	createMarker(marker_point[i], html[i], baseIcon, infoWindow, category);
	}
 
}

Также изменениям подверглась функция createMarker:

function createMarker(point, html, icon, infoWindow, category) {
	 var marker = new google.maps.Marker({
            map: map,
            position: point,
             icon: icon.icon,
            shadow: icon.shadow           
          });
 
  marker.mycategory = category; 
 
  google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
  gmarkers.push(marker);
  return marker;
}

В функциях show и hide мы заменили строки gmarkers[i].show(); на gmarkers[i].setVisible(true); и gmarkers[i].hide(); на gmarkers[i].setVisible(false); соответсвенно.

И строку map.closeInfoWindow(); в функции hide на infowindow.close();

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

В измененных функциях по другому определяются параметры маркера и информационного окна (балуна).

На этом все, мы создали новую версию примера для добавления и вывода данных на карту Google Maps по категориям, используя PHP и MySQL, с использованием API Google Maps v3

Скачать архив с файлами примера

  • Гость: У меня проблема: всё делаю как в статье, всё файлы есть, да и в mysql я чувствую себя уверенно. Настраиваю запускаю, всё работает, маркер ставиться и в базу добавляет записи, выключил комп, потом включил и ничего не меняя зашёл снова и маркер после нажатия "сохранить" в базу не заноситься, как говориться 0 эмоций. Пересмотрел и перепробывал всё, не помогает, переустановил xampp и о чудо заработало, выключил браузер, снова захажу и всё на этом. Опять ничё не пашет! Вопрос: Автор что это может быть и что мне делать, он как будто с mysql не сотрудничает, но и ошибок не выдает?
  • Гость: Вы не подскажете как можно модифицировать модуль mod_sobi2gcat , универсального каталога Sobi 2, который выводит все маркеры из базы на одну карту, для его совместной работы с API Google Maps версии 3, да и возможно ли такое? Модуль состоит из двух файлов: mod_sobi2gcat.PHP get( 'showInSobi', 1 ); $showAllEntr = $params-&gt;get( 'showAllEntr' ); $inSobi = null; $catId = sobi2Config::request( $_REQUEST,'catid',0 ); $showFromSubcats = $params-&gt;get( 'showFromSubcats', 1 ); $useBubbleTemplate = $params-&gt;get( 'useTemplate', 0 ); $useCatsCustomMarker= $params-&gt;get( 'useCatsCustomMarker',0 ); $catsCustomMarker = $params-&gt;get( 'catsCustomMarker', null); $ignoreTask = $params-&gt;get( 'ignoreTask' ); $catsCenterPoints = $params-&gt;get( 'catsCenterPoints' ); $customMarker = $params-&gt;get( 'customMarker', null ); $markerShadow = $params-&gt;get( 'customMarkerShadow', null ); $ignoreTask = explode( ",",$ignoreTask ); $bubbleTemplate = str_replace( array( "n", "r", "t" ), null, $params-&gt;get( 'bubbleTemplate', "{link}" ) ); $sobiTask = sobi2Config::request( $_REQUEST,'sobi2Task',null, 2 ); $letter = sobi2Config::request( $_REQUEST, "letter", null, 2 ); $tag = sobi2Config::request( $_REQUEST, "tag", null, 2 ); $sobiTask = $sobiTask ? $sobiTask : ( $letter ? "alphaListing" : ( $tag ? "tagListing" : "category_{$catId}" ) ) ; $opt = sobi2Config::request( $_REQUEST,"option", 0, 2 ); $config =&amp; sobi2Config::getInstance(); $database =&amp; $config-&gt;getDb(); array_walk( $ignoreTask, "sobi2trim" ); if( in_array( $sobiTask , $ignoreTask ) ) { return false; } if (!file_exists( _SOBI_FE_PATH.DS.'languages'.DS.$config-&gt;sobi2Language.'.php' )) { $config-&gt;sobi2Language = 'english'; } require_once( _SOBI_FE_PATH.DS.'languages'.DS.$config-&gt;sobi2Language.'.php' ); if ( file_exists( _SOBI_FE_PATH.DS.'languages'.DS.'default.php' ) ) { include_once( _SOBI_FE_PATH.DS.'languages'.DS.'default.php' ); } if( $useBubbleTemplate &amp;&amp; !function_exists("sobiGeoCatModTempl") ) { sobi2Config::import( "sobi2.class" ); if( !function_exists( 'sobi2GeoCatModTempl' ) ) { function sobi2GeoCatModTempl( $id, $tpl, $href, $title, $sobiTagsLimit ) { $sobi = new sobi2( $id ); $config =&amp; sobi2Config::getInstance(); $database = &amp;$config-&gt;getDb(); if( !$sobi-&gt;icon &amp;&amp; $config-&gt;key( "frontpage", "default_ico" ) ) { $sobi-&gt;icon = $config-&gt;key( "frontpage", "default_ico" ); } if( $sobi-&gt;icon &amp;&amp; file_exists( _SOBI_CMSROOT.$config-&gt;imagesFolder.$sobi-&gt;icon ) ) { $ico = $config-&gt;liveSite.$config-&gt;imagesFolder.$sobi-&gt;icon; if(stristr( $ico, ".png" )) { $ico = sobi2Config::checkPNGImage( $ico, addslashes( $sobi-&gt;title ), "border-style:none;" ); } else { $alt = addslashes( $sobi-&gt;title ); $ico = ""; } } else { $ico = null; } if( !$sobi-&gt;image &amp;&amp; $config-&gt;key( "frontpage", "default_img" ) ) { $sobi-&gt;image = $config-&gt;key( "frontpage", "default_img" ); } if( $sobi-&gt;image &amp;&amp; file_exists( _SOBI_CMSROOT.$config-&gt;imagesFolder.$sobi-&gt;image ) ) { $image = $config-&gt;liveSite.$config-&gt;imagesFolder.$sobi-&gt;image; if(stristr( $image, ".png" )) { $image = sobi2Config::checkPNGImage( $image, addslashes( $sobi-&gt;title ), "border-style:none;" ); } else { $alt = addslashes( $sobi-&gt;title ); $image = ""; } } else { $image = null; } if( strstr( $tpl, "{categories}" ) ) { sobi2Config::import("includes|entry.functions"); $cats = sobiSpecFunc::getMyCategories( $sobi, true ); } else { $cats = null; } if( strstr( $tpl, "{tags}" ) ) { sobi2Config::import("includes|entry.functions"); $sobiTags = sobiSpecFunc::showTags( $sobi-&gt;metakey, $sobiTagsLimit ); } else { $sobiTags = null; } static $placeHolder = array(); $placeHolderReplacement = array(); $placeHolder[] = "{link}"; $placeHolderReplacement[] = "<a href="{$href}" rel="nofollow">{$title}</a>"; $placeHolder[] = "{title}"; $placeHolderReplacement[] = addslashes( $sobi-&gt;title ); $placeHolder[] = "{icon}"; $placeHolderReplacement[] = $ico; $placeHolder[] = "{image}"; $placeHolderReplacement[] = $image; $placeHolder[] = "{categories}"; $placeHolderReplacement[] = str_replace('\\\\\\\',"\", addslashes( $cats )); $placeHolder[] = "{id}"; $placeHolderReplacement[] = $sobi-&gt;id; $placeHolder[] = "{hits}"; $placeHolderReplacement[] = $sobi-&gt;hits; $placeHolder[] = "{publish_up}"; $placeHolderReplacement[] = $sobi-&gt;publish_up; $placeHolder[] = "{publish_down}"; $placeHolderReplacement[] = $sobi-&gt;publish_down; $placeHolder[] = "{last_update}"; $placeHolderReplacement[] = $sobi-&gt;lastUpdate; $placeHolder[] = "{tags}"; $placeHolderReplacement[] = str_replace('\\\\\\\',"\", addslashes( $sobiTags )); if( count( $sobi-&gt;customFieldsData ) ) { foreach ( $sobi-&gt;customFieldsData as $field =&gt; $data ) { if( is_array( $data ) ) { $data = implode( ",", $data ); } $tpl = str_replace('{'.$field.'}', str_replace('\\\\\\\',"\", addslashes( $data ) ), $tpl ); } } $tpl = str_replace( $placeHolder, $placeHolderReplacement, $tpl ); return $tpl; } } } if( $opt == "com_sobi2" ) { $inSobi = true; if( !$showInSobi ) { //wenn in SOBI aber nur anzeigen wenn nicht in SOBI return null; } } if($catId get( "curDisplSidList", array() ); if (empty( $curSids ) &amp;&amp; ( $showAllEntr &amp;&amp; ( $catId getGoogleMaps(); $class = $params-&gt;get('moduleclass_sfx'); $baseAddresse = $params-&gt;get('baseAddresse', 'http://maps.google.com'); $width = $params-&gt;get('width'); $height = $params-&gt;get('height'); $mapControl = $params-&gt;get('MapControl'); $mapTypeControl = $params-&gt;get('MapTypeControl'); $overviewMapControl = $params-&gt;get('OverviewMapControl',1); $doubleClickZoom = $params-&gt;get('DoubleClickZoom',1); $mapTypeOnStart = $params-&gt;get('MapTypeOnStart', 'G_NORMAL_MAP'); $centerPointLat = $params-&gt;get('centerPointLat',"0.0" ); $centerPointLong = $params-&gt;get('centerPointLong', "0.0" ); $mapsZoom = $params-&gt;get('MapsZoom', 1 ); $hybrid_label = $params-&gt;get('hybrid_label', "Labels"); if( $catId &gt; 1 ) { if( strstr( $catsCenterPoints, "n" ) ) { $catsCenterPoints = explode( "n", $catsCenterPoints ); } else { if( strstr( $catsCenterPoints, "r" ) ) { $catsCenterPoints = explode( "r", $catsCenterPoints ); } } if( is_array( $catsCenterPoints ) &amp;&amp; !empty( $catsCenterPoints ) ) { foreach ( $catsCenterPoints as $point ) { $point = trim( $point ); $point = explode( ":", $point ); if( trim( $point[0] ) == $catId ) { if( ( isset( $point[1] ) &amp;&amp; is_numeric( $point[1] ) ) &amp;&amp; isset( $point[2] ) &amp;&amp; is_numeric( $point[2] ) ) { $centerPointLat = floatval( $point[1] ); $centerPointLong = floatval( $point[2] ); if( isset( $point[3] ) &amp;&amp; is_numeric( $point[3] ) ) { $mapsZoom = intval( $point[3] ); } } break; } } } } if( $useCatsCustomMarker ) { $catsCustomMarker = strip_tags( $catsCustomMarker ); if( strstr( $catsCustomMarker, "n" ) ) { $customMarkers = explode( "n", $catsCustomMarker ); } if( strstr( $catsCustomMarker, "r" ) ) { $customMarkers = explode( "r", $catsCustomMarker ); } $catsCustomMarkers = array(); if( is_array( $customMarkers ) &amp;&amp; !empty( $customMarkers ) ) { foreach ($customMarkers as $catMarker ) { $position = explode( ":", $catMarker ); if( isset( $position[0] ) ) { $catsCustomMarkers[ $position[0] ] = array( ); if( isset( $position[1] ) ) { $catsCustomMarkers[ $position[0] ]['marker'] = strip_tags( $position[1] ); } if( isset( $position[2] ) ) { $catsCustomMarkers[ $position[0] ]['shadow'] = strip_tags( $position[2] ); } } } } } if( !( is_numeric( $centerPointLat ) ) || !( is_numeric( $centerPointLong ) ) ) { $centerPointLat = "0.0"; $centerPointLong = "0.0"; } if( $inSobi || !$showInSobi ) { if( $catId &gt; 0 ) { $cats = array(); if( $showFromSubcats ) { $config-&gt;getChildCats( $catId,$cats ); $cats = implode( ', ',$cats ); } else { $cats = $catId; } $query = "SELECT DISTINCT `itemid` FROM `#__sobi2_cat_items_relations` WHERE `catid` IN ({$cats})"; $database-&gt;setQuery($query); $sItems = $database-&gt;loadResultArray(); } else { $sItems = $curSids; } } else { return null; } if( !( empty( $sItems ) ) ) { $sItems = implode(', ',$sItems); $query = "SELECT `data_txt`, `itemid`, `fieldid` FROM `#__sobi2_fields_data` WHERE (`fieldid` = 1 OR `fieldid` = '{$config-&gt;googleMapsLatField}' OR `fieldid` = '{$config-&gt;googleMapsLongField}') AND `itemid` IN ($sItems)"; $database-&gt;setQuery($query); $dataResArr = $database-&gt;loadObjectList(); $data = array(); foreach($dataResArr as $dataRes) { if($dataRes-&gt;fieldid == $config-&gt;googleMapsLongField) { $data[$dataRes-&gt;itemid]['longitude'] = $dataRes-&gt;data_txt; } else if($dataRes-&gt;fieldid == $config-&gt;googleMapsLatField) { $data[$dataRes-&gt;itemid]['latitude'] = $dataRes-&gt;data_txt; } } $now = $config-&gt;getTimeAndDate(); $query = "SELECT `title`, `icon`, `itemid` FROM `#__sobi2_item` WHERE (`itemid` IN ($sItems) AND `published` = 1 AND (`publish_down` &gt; '{$now}' OR `publish_down` = '{$config-&gt;nullDate}') )"; $database-&gt;setQuery($query); $itemsResArr = $database-&gt;loadObjectList(); $itemsCats = array(); $sobiItems = array(); if( !( empty( $itemsResArr ) ) ) { foreach ( $itemsResArr as $itemArr ) { $sobiItem = new stdClass(); $sobiItem-&gt;id = $itemArr-&gt;itemid; $itemsCats[]=$itemArr-&gt;itemid; $sobiItem-&gt;title = $itemArr-&gt;title; $sobiItem-&gt;icon = $itemArr-&gt;icon; $sobiItem-&gt;latitude = null; $sobiItem-&gt;longitude = null; if(isset($data[$sobiItem-&gt;id]['latitude'])) { $sobiItem-&gt;latitude = $data[$sobiItem-&gt;id]['latitude']; } if(isset($data[$sobiItem-&gt;id]['longitude'])) { $sobiItem-&gt;longitude = $data[$sobiItem-&gt;id]['longitude']; } if($sobiItem-&gt;latitude &amp;&amp; $sobiItem-&gt;longitude) { if(is_numeric($sobiItem-&gt;longitude) &amp;&amp; is_numeric($sobiItem-&gt;latitude)) { $sobiItems[] = $sobiItem; } } unset($sobiItem); } if ($useCatsCustomMarker) { $itemsCats = implode( ',',$itemsCats); $catRels = array(); $query = "SELECT `catid`,itemid FROM #__sobi2_cat_items_relations WHERE itemid IN ({$itemsCats})"; $database-&gt;setQuery($query); $itemsCats = $database-&gt;loadObjectList(); if( !empty( $itemsCats ) ) { foreach ($itemsCats as $dbentry ) { $catRels[ $dbentry-&gt;itemid ] = $dbentry-&gt;catid; } } } } else { return null; } if(empty($sobiItems)) { return null; } $map_api_version = $config-&gt;key("google_maps", "google_map_apiversion", "2"); echo "n "; echo "<!-- Start of SOBI2 Geo Category Overview Module -->"; echo "n "; echo ""; ?&gt; window.onDomReady = DomReady; function DomReady(func) { if(document.addEventListener) { document.addEventListener("DOMContentLoaded", func, false); } else { document.onreadystatechange = function() { readyState(func) } } } function readyState(func) { if(document.readyState == "complete") { func(); } } &lt;?php echo &quot;nt &quot;; echo &quot;googleMapsApiKey}" type="text/javascript"&gt;"; echo "nt "; echo "nt "; echo "//id] ) ) { $itemCid = $catRels[$sobiItem-&gt;id]; } if( isset( $catsCustomMarkers[$itemCid] ) ) { $customCatMarker = isset( $catsCustomMarkers[$itemCid]['marker'] ) ? $catsCustomMarkers[$itemCid]['marker'] : null; $customCatShadow = isset( $catsCustomMarkers[$itemCid]['shadow'] ) ? $catsCustomMarkers[$itemCid]['shadow'] : null; if( $customCatMarker &amp;&amp; file_exists( _SOBI_CMSROOT.DS.$customCatMarker ) ) { list( $cmWidth, $cmHeight ) = getimagesize( _SOBI_CMSROOT.DS.$customCatMarker ); $jsImgArr .= "nttt SCustomMarkers[{$itemCid}] = new Array();"; $jsImgArr .= "nttt SCustomMarkers[{$itemCid}]['marker'] = '{$customCatMarker}';"; $jsImgArr .= "nttt SCustomMarkers[{$itemCid}]['mw'] = {$cmWidth};"; $jsImgArr .= "nttt SCustomMarkers[{$itemCid}]['mh'] = {$cmHeight};"; if( $customCatShadow &amp;&amp; file_exists( _SOBI_CMSROOT.DS.$customCatShadow ) ) { list( $csWidth, $csHeight ) = getimagesize( _SOBI_CMSROOT.DS.$customCatShadow ); $jsImgArr .= "nttt SCustomMarkers[{$itemCid}]['shadow'] = '{$customCatShadow}';"; $jsImgArr .= "nttt SCustomMarkers[{$itemCid}]['sw'] = {$csWidth};"; $jsImgArr .= "nttt SCustomMarkers[{$itemCid}]['sh'] = {$csHeight};"; } unset( $catsCustomMarkers[$itemCid] ); } //und zum JS array hinzufuegen: //aber wie macht man das?? } } $href = "index.php?option=com_sobi2&amp;sobi2Task=sobi2Details&amp;sobi2Id={$sobiItem-&gt;id}&amp;Itemid={$config-&gt;sobi2Itemid}"; $href = sobi2Config::sef($href); $title = str_replace("\\", "\",$sobiItem-&gt;title); $title = str_replace("\\", "\",$title); if( $useBubbleTemplate ) { $bubble = sobi2GeoCatModTempl($sobiItem-&gt;id, $bubbleTemplate, $href, $title, $sobiTagsLimit ); } else { $bubble = "<a href="{$href}" rel="nofollow">{$title}</a>"; } echo "ntttt "; //wo kommt $itemCid her? Das hier ist doch ausserhalb der for each schleife!! echo "SobiCatOverMap.addOverlay( createSobiMarker( new GLatLng( {$sobiItem-&gt;latitude},{$sobiItem-&gt;longitude} ), '{$bubble}', {$itemCid} ) );"; } echo "nttt "; echo "} "; echo "ntt "; echo "} "; echo "ntt "; echo "function createSobiMarker( point, html, sid ) {"; echo "nttt "; if( $customMarker &amp;&amp; file_exists( _SOBI_CMSROOT.DS.$customMarker ) ) { if( $useCatsCustomMarker ) { echo "SCustomMarkers = new Array();"; echo $jsImgArr; echo "nttt "; } list( $mWidth, $mHeight ) = getimagesize( _SOBI_CMSROOT.DS.$customMarker ); $gxpoint = $mWidth / 2; $gypoint = $mHeight / 2; echo "var icon = new GIcon();"; echo "nttt "; echo "icon.image = "{$config-&gt;liveSite}/{$customMarker}";"; echo "nttt "; echo "icon.iconSize = new GSize( {$mWidth}, {$mHeight} );"; if( $markerShadow &amp;&amp; file_exists( _SOBI_CMSROOT.DS.$markerShadow ) ) { list( $msWidth, $msHeight ) = getimagesize( _SOBI_CMSROOT.DS.$markerShadow ); echo "nttt "; echo "icon.shadowSize = new GSize( {$msWidth}, {$msHeight} );"; echo "nttt "; echo "icon.shadow = "{$config-&gt;liveSite}/{$markerShadow}";"; echo "nttt "; } echo "nttt "; echo "icon.iconAnchor = new GPoint( 5, 10 );"; echo "nttt "; echo "icon.infoWindowAnchor = new GPoint( {$gxpoint}, 5 );"; if( $useCatsCustomMarker ) { echo "nttt "; echo "if( SCustomMarkers[sid] != undefined &amp;&amp; SCustomMarkers[sid]['marker'] != undefined &amp;&amp; SCustomMarkers[sid]['marker'] != '' ) {"; echo "ntttt "; echo "icon.image = "{$config-&gt;liveSite}/" + SCustomMarkers[sid]['marker'];"; echo "ntttt "; echo "icon.iconSize = new GSize( SCustomMarkers[sid]['mw'], SCustomMarkers[sid]['mh'] );"; echo "ntttt "; echo "icon.infoWindowAnchor = new GPoint( ( SCustomMarkers[sid]['mw'] / 2 ), 5 );"; echo "ntttt "; echo "if( SCustomMarkers[sid]['shadow'] != undefined &amp;&amp; SCustomMarkers[sid]['shadow'] != '' ) {"; echo "nttttt "; echo "icon.shadow = "{$config-&gt;liveSite}/" + SCustomMarkers[sid]['shadow'];"; echo "nttttt "; echo "icon.shadowSize = new GSize( SCustomMarkers[sid]['sw'], SCustomMarkers[sid]['sh'] );"; echo "ntttt }"; echo "nttt }"; } echo "nttt "; echo "var marker = new GMarker( point, icon );"; } else { echo "var marker = new GMarker( point );"; } echo "nttt "; echo "GEvent.addListener(marker, 'click', function() {"; echo "ntttt "; echo "marker.openInfoWindowHtml(''+html+'');"; echo "nttt "; echo "});"; echo "nttt "; echo "return marker;"; echo "ntt "; echo "}"; echo "ntt "; echo "DomReady(loadSobiCatOverMap);"; echo "nt "; echo "//]]&gt;"; echo "nt "; echo ""; echo "n"; echo "nt "; echo ""; echo "n "; echo ""; echo "n "; echo "<!--End of SOBI2 Geo Category Overview Module -->"; echo "n "; } ?&gt; И файла mod_sobi2gcat.xml : <!-- $Id: mod_sobi2gcat.xml 4495 2008-10-05 09:04:44Z Sigrid Suski $ --> SOBI2 Geo Category Overview Sigrid and Radek Suski, Sigsiu.NET October 2008 (C) 2008 Sigsiu.NET - All rights reserved. Commercial Licence sobi@sigsiu.net www.Sigsiu.NET 2.2 SOBI2 Geo Category Overview Module. This module shows a Google Map with category dependent markers of the SOBI2 entries. Only SOBI2 entries with geo coordinates can be shown in the map. Please read the manual included in the ZIP file for setting up the module. mod_sobi2gcat.php mod_sobi2gcat.txt None Small Map Controls Large Map Controls 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Yes No Yes No Normal Satellite Terrain Yes No Yes No non-SOBI2 pages SOBI2 pages Yes No Yes No Yes No Заранее спасибо за Ваш ответ и простите за длинный комент.
  • Гость: предлагаю заменить конструкцию if(!gmarkers[markersType]) { gmarkers[markersType] = 1; $.getJSON("http://localhost/upload.php", {markersType:markersType}, function(data){ setMarkers(data, markersType); }); } на конструкцию вида if(!loaded_markers[markersType]) { loaded_markers[markersType] = 1; $.getJSON("http://localhost/upload.php", {markersType:markersType}, function(data){ setMarkers(data, markersType); }); } то есть добавить еще один массив для контроля параметров, загружен тип или нет. не знаю как на символьных значениях, на цифровых типах, конструкция приведенная автором спотыкается.
  • Гость: Спасибо Сергей! Я Разобрался, и всем на будущее, php страниц кодировки utf-8 должна быть без BOM (Byte Order Mark) Иначе запросы не будут работать! Для правильной конвертации используйте к примеру Notepad++ В кодировке выбираем utf-8 без BOM.
  • Гость: Как бы обьеденить это всё с http://webmap-blog.ru/google-maps/sobstvennoe-informacionnoe-okno-s-animaciej-na-google-maps-primenyaya-api-google-maps-v3-ccs3-i-jquery ? И ещё, как можно сделать, чтоб ставилась только одна метка за один раз? Щас можно сколько угодно ставить, но описание добавить только к последней!
  • Гость: И ещё как можно отметить все чекбоксы? Точнее отметить не проблема, но при этом не показываются все метки!
  • Гость: чтобы всё работало, в функцию SETMARKERS после VAR HTML = NEW ARRAY() вставте eval("var data="+data);
  • Гость: А как быть в случае, если два или более маркера, оказываются в одной точке? Например, два бара и один ресторан имеют одинаковые координаты. Можно ли сделать так, чтоб при нажатие на эту точку, маркеры расходились "веером" и предоставляли пользователю выбрать нужный?
  • Гость: Статья очень нужная, на 5+. Воспользовался. Спасибо.
  • Гость: Скажите а в кодировке win-1251 будет работать?
  • Гость: Могут возникнуть трудности с кодировками, но в принципе работать должно. Надо только будет постоянно перекодировать данные при сохранении и выводе из базы. Для этого в php-скриптах использовать строку вида $mas1['NAME'] = iconv("CP1251", "UTF-8", $mas1['NAME']); Производит преобразование кодировки символов строки $mas1['NAME'] из начальной кодировки CP1251 в конечную UTF-8. Возвращает строку в новой кодировке, или FALSE в случае ошибки.
  • Гость: Добрый день. В авторской редакции все здорово. Решил переписать под себя и наткнулся на на грабли. При выборе категорий все подгружается и маркеры появляются. А вот при снятии флажка ничего не происходит. Начал проверять функцию Hidi и Show - не передается gmarkers[i].mycategory - пустой. Подскажите как быть? может встречались с такой трудностью. Строка с категорией: Магазины
  • Гость: а как сделать ограничение по маркерам, чтобы можно было добавлять не больше 4-5 мест?
  • Гость: Здравствуйте, подскажите пожалуйста почему код не работает в браузерах chrom, exploer и др. только в opere я смог открыть.
  • Гость: У меня в chrom все работает, не отображались значки иконок, т.к. Google закрыл сайт http://labs.google.com откуда они брались. Я положил значки на свой блог и теперь они отображаются
  • Гость: А можете выложить файлы примера, а то все никак не выходит..?
  • Гость: если можно, выложите пожалуйста исходники
  • Гость: <a href="http://webmap-blog.ru/files/arhivs/phpsqlinfo_add_vcat_gmapv3.zip" title="Архив" target="_blank" rel="nofollow">Архив</a> с файлами примера
  • Гость: у меня маркеры не отображаются на карте а вот с добавление в бд все ок в чем проблеиа не подскажете?
  • Гость: Надо посмотреть скрипт вывода данных на карту upload.php. Каков формат вывода.
  • Гость: Все как у Вас в примере один в один.
  • Гость: $json = '{"markers":['."n"; //Выполняем запрос на выборку координат маркеров соответствующего типа. $query = mysql_query("SELECT * FROM markers WHERE type = '$markersType';"); if(mysql_num_rows($query)&gt;0) { while ($par = mysql_fetch_array($query)) { $json.= "n".'{'.'"mname": "'.$par['name'].'",'; $json.= '"address": "'.$par['address'].'",'; $json.= '"type": "'.$markerNameType.'",'; $json.= '"lat": "'.$par['lat'].'",'; $json.= '"lon": "'.$par['lng'].'"'; $json.= '},'; } $json = substr($json, 0,-1); echo $json; echo '], ', "n", '"mimg": "',$markerImg.'",',"n" ,'"status": "OK"', "n", '}'; } else { echo '{"status": "false"}'; }
  • Гость: Все получилось!!! Вопрос отпадает. Спасибо.
  • Гость: Скачал ваши исходники, заменил файл с настройками базы данных на свои, и все в принципе нормально, карта показывается - информация которую вводит пользователь сохраняется в БД, но когда обновляю страницу, чтоб посмотреть поставленный мной маркер, маркер не выводится на карте, в чем причина, не подскажите? Прямо как у предыдущего комментария UnoMono.
  • Гость: вопрос снят. в исходнике был неверно прописан путь до upload.php
  • Гость: Можно ли будет вывести рядом меню с названиями объектов (Пытаюсь переделать эту карту http://visit-plus.com/ru/node/1121 на V3, пока не получилось. Надеюсь ваша статая будет полезной. Но у меня из базы данных создаётся XML а из него данные поступают на карту) Спасибо за статью.
  • Гость: Вот готовый <a href="http://www.geocodezip.com/v3_MW_example_categories.html" title="Google Maps Javascript API v3 Example: Marker Categories" target="_blank" rel="nofollow">пример</a> реализации
  • Гость: Спасибо, это то что нужно. (Смотрел на этом сайте но почему-то не заметил этот пример).
  • Гость: Привет, подскажите пожалуйста, как вместо checkbox поставить button, чтобы при нажатии на кнопку выводились и прятались маркеры. Спасибо.
  • Гость: Помогите решить проблему. В БД заноситься все прекрасно. А вот с выводом меток на карту проблемы, такого плана. Выводятся метки только bar и restaurant, метки cafe никак выводится не хотят, хотя в БД они есть. В PHP новичок, сильно не пинать.
  • Гость: Подскажите пожалуйста, как вместо чекбоксов сделать радио? Визуально заменил, но при смене пункта радио, на карте отображаются метки предыдущего радио и текущего. Как сделать чтоб метки предыдущего радио скрывались?
  • Гость: А как быть с категориями, у которых value числа? они отображаются но не скрываются((
  • Гость: Помогите, никак не получается вывести метки на карту, нажымаю на чек бокс, ничего не выводится, но в БД все записывается, спасайте!!
  • Гость: Нужно проверить какой код выдает файл upload.php. Может быть ответ в формате JSON не правильно формируется.
  • Гость: Уважаемый администратор, нам нужна такая карта для туристического сайта, я буду очень благодарен если вы согласитесь сделать нам ее, разумеется за неплохое вознаграждение.
  • Гость: Напишите подробнее на почту ugolsergey@gmail.com попробую помочь.
  • Keep Lane: u menya v database dobovyayetsya no nevivodet'sya markeri( izvenite net russkoy klaviaturi)
  • Keep Lane: spasibo vse rabotaet
  • Keep Lane: vse rabotaet spasibo