четверг, 26 декабря 2013 г.

Google Maps API. Маркеры, кластеры и геокодирование

Добавление маркера на карту

Обычный маркер добавить очень просто. Достаточно коротенького кода:
var marker = new google.maps.Marker({    
 position: new google.maps.LatLng('56', '37'),
 map: map
});

и маркер будет установлен. Однако это будет пустой и стандартный маркер.
Сделаем его более уникальным, заменив изображение маркера:
var image = new google.maps.MarkerImage('marker_image.png',
 new google.maps.Size(32, 37),
 new google.maps.Point(0,0),
 new google.maps.Point(16, 35)
);

var marker = new google.maps.Marker({
 position: new google.maps.LatLng('56', '37'),
 map: map,
 title: 'Marker Title',
 icon: image
});

marker_image.png - замените на свое изображение маркера
Size - размер изображения
Point - смещение изображения (чтобы якорь маркера был в нужной точке)

Изображение маркера изменили, теперь нужно установить на маркер балун (всплывающее окошко при клике на маркер).

Создаем балун:
var infowindow = new google.maps.InfoWindow({
 content: 'Marker content'
});


Создаем событие, которое откроет балун на карте при клике на наш маркер:
google.maps.event.addListener(marker, 'click', function() {
 infowindow.open(map, this);
});


Вам могут пригодиться эти функции балунов:
infowindow.setContent('Marker content');
infowindow.close();

setContent - изменяет наполнение балуна не изменяя его статус (открыт\закрыт).
close - закрывает балун.




Кластеризация маркеров

К сожалению, в картах гугла нет встроенной кластеризации. Однако есть несколько сторонних функций.
Одну из них можно скачать здесь

Выглядит это так:
Без кластеризации:


С кластеризацией:


Подключаем этот скрипт к странице и делаем изменения в коде карты:
var markers = []; 
var marker = new google.maps.Marker({    
    position: new google.maps.LatLng('56', '37')
});
markers.push(marker);
markerClusterer = new MarkerClusterer(map, markers, 
{ 
    maxZoom: 13,
    gridSize: 50,
    styles: null 
});

maxZoom – максимальный зум, при котором маркеры будут группироваться в кластеры
gridSize – размер ячеек сетки. Чем меньше значение, тем меньше сетка группировки
styles – дополнительные стили

Обратите внимание - из функции создания маркера была удалена строка map: map. Это очень важно, т.к. теперь маркеры не будут добавляться на карту напрямую, они будут добавляться в кластер, а кластер уже будет добавлен на карту.

Функция очистки кластера может быть полезна:
markerClusterer.clearMarkers();




Геокодирование

Геокодирование бывает двух видов:
1) Поиск адреса по координатам
2) Поиск координат по адресу

Поиска по адресу:
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': 'Адрес','partialmatch': true}, function (results, status) {
 if (status == 'OK' && results.length > 0) {
  var location = results[0].geometry.location;
 }else{
  // Адрес не найден
 }
});

Массив results может содержать не одну запись, если похожий адрес был найден в нескольких разных точках. Но обычно самый точный из них идет первым (results[0]).
В переменную location были записаны координаты в виде объекта. Для их использования не нужно создавать координату через google.maps.LatLng, она уже готова, просто используйте эту переменную.

partialmatch - искать ли адреса с частичным совпадением

Поиска по координатам:
var geocoder = new google.maps.Geocoder();
geocoder.geocode({latLng:location}, function (results, status) {
 if (status == 'OK' && results.length > 0) {
  var address = results[0].formatted_address;
 }else{
  // Адрес не найден
 }
});

Переменная address будет содержать адрес в текстовом виде.


Пример с установкой маркеров и получение их адреса с помощью геокодера. Для установки маркера - кликните на карту.



среда, 25 декабря 2013 г.

Google Maps API. Элементы управления и свой интерфейс карты

В этой статье будут описаны все настройки интерфейса карты и примеры установки в карту своих элементов интерфейса

Пример функции загрузки карты с расширенными настройками:
function initialize() {
 var Options = {
  center: new google.maps.LatLng(56, 37),
  zoom: 8,
  disableDefaultUI: false,
  scrollwheel: true,
  zoomControl: true,
  zoomControlOptions: {
   style: google.maps.ZoomControlStyle.LARGE,
   position: google.maps.ControlPosition.TOP_LEFT
  },
  panControl: true,
  mapTypeControl: true,
  scaleControl: true,
  streetViewControl: true,
  overviewMapControl: true,
  mapTypeId: google.maps.MapTypeId.ROADMAP
 };
 var map = new google.maps.Map(document.getElementById("map-canvas"), Options);
}


Описание всех использованных выше настроек:
center - координата, которая будет использована в качестве центра карты после ее загрузки (56 - широта, 37 - долгота). Обязательная настройка.
zoom - зум над этой координатой (1 - максимальное отдаление, больше значение - сильнее увеличение. Максимальное значение зависит от точки (в городе может быть более 20, в лесу около 15). Обязательная настройка.
disableDefaultUI - будет ли отключен интерфейс карты (все последующие элементы).
scrollwheel - будет ли изменяться зум карты колесиком мыши (по-умолчанию - true).
zoomControl - будет ли выведен элемент управления масштабированием.
zoomControlOptions - настройки элемента управления масштабированием. Подобные настройки могут быть у всех элементов управления на карте. Подробнее о этих настройках - ниже.
panControl - будет ли выведен элемент управления панорамированием.
mapTypeControl - будет ли выведен элемент управления типом карты.
scaleControl - будет ли выведен элемент управления масштабом.
streetViewControl - будет ли выведен элемент управления street view.
overviewMapControl - будет ли выведен элемент управления обзорной картой.
mapTypeId - тип карты по-умолчанию (ROADMAP, SATELLITE, HYBRID, TERRAIN).

Так же можно установить дополнительные настройки для каждого элемента управления. В данном случае такие настройки есть у zoomControl. Для остальных элементов настройки нужно соответствующим образом назвать. Сами настройки у всех элементов не отличаются. Вот их описание:
style - размер элемента управления (LARGE, SMALL и DEFAULT (автоматически)).
position - расположение элемента управления (TOP_CENTER, TOP_LEFT, TOP_RIGHT, LEFT_TOP, RIGHT_TOP, LEFT_CENTER, RIGHT_CENTER, LEFT_BOTTOM, RIGHT_BOTTOM, BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT).


С настройками разобрались, теперь добавим свой элемент в интерфейс карты.
Добавьте следующий код в конце функции initialize:
var UIDiv = document.createElement('DIV');
UIDiv.index = 1;
UIDiv.style.display = 'block';
UIDiv.style.padding = '5px';
UIDiv.style.backgroundColor = 'white';
UIDiv.style.borderStyle = 'solid';
UIDiv.style.borderWidth = '1px';
UIDiv.innerHTML = document.getElementById('userUI').innerHTML;
map.controls[google.maps.ControlPosition.TOP_CENTER].push(UIDiv);


Этот код вставит весь код из контейнера с id=userUI в верхнюю центральную часть карты. Добавить в этот контейнер можно все что угодно. Это может быть обычная кнопка, или же таблица (не забудьте добавить фон, т.к. по-умолчанию фон будет прозрачным и за вашим элементом интерфейса сразу начнется карта).
Все стили к элементу можно добавить как показано в примере (UIDiv.style и далее в точности как в коде выше. Используйте обычные переменные CSS).
Как изменять расположение элемента вы уже знаете.






Google Maps API. Подключение карты.

Начинаю серию статей о гугл картах. Будут описаны все основные функции этой api. Начнем с самого простого - подключить карту к своему сайту.

Для начала нужно загрузить скрипт самой карты. Установите этот код в любое место:

Контейнер, куда будет остановлена карта:

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

Теперь функция загрузки карты:
var map;
function initialize() {
 var Options = {
  center: new google.maps.LatLng(56, 37),
  zoom: 8,
  mapTypeId: google.maps.MapTypeId.ROADMAP
 };
 map = new google.maps.Map(document.getElementById("map_canvas"), Options);
}
google.maps.event.addDomListener(window, 'load', initialize);


center - координата, которая будет использована в качестве центра карты после ее загрузки (56 - широта, 37 - долгота).
zoom - зум над этой координатой (1 - максимальное отдаление, больше значение - сильнее увеличение. Максимальное значение зависит от точки (в городе может быть более 20, в лесу около 15).
mapTypeId - тип карты по-умолчанию (ROADMAP, SATELLITE, HYBRID, TERRAIN).

И все готово. Карта будет выведена на вашем сайте.



В следующей статье вы сможете прочитать о настройках интерфейса карты и добавлении своих элементов в интерфейс.


суббота, 21 декабря 2013 г.

Функция print_r для Javascript

Функция конвертации массива в текстовую переменную, идентична одноименной в PHP.

Функция:
function print_r(arr, level) {
 var print_text = "";
 if(!level) level = 0;
 var level_padding = "";
 for(var j=0; j<level+1; j++) level_padding += "    ";
 if(typeof(arr) == 'object') {
  for(var item in arr) {
   var value = arr[item];
   if(typeof(value) == 'object') {
    print_text += level_padding + "'" + item + "' :\n";
    print_text += print_r(value,level+1);
   }
   else
    print_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
   }
  }
  else print_text = "===>"+arr+"<===("+typeof(arr)+")";
  return print_text;
}

Запуск:
print_r(array);
array - массив

Однако одной функции будет мало. В отличии от PHP функции - эта не может вывести свое значение сразу в html код. Для этого ей надо немного помочь. Далее несколько примеров, как это можно сделать.

1) Вывести в модальном окне:

alert(print_r(array));

2) Вывести в html:

document.getElementById(id).innerHTML = print_r(array);
id - id тега html когда (div, span, td и т.д.)

3) Вывести в консоли браузера:

console.info(print_r(array));

Иногда массив бывает слишком большим и javascript не справляется с его конвертированием. С этим может помочь отключение перехода на следующий уровень массива. При этом будет конвертирован только первый уровень массива, а последующие выведены как object.
Для этого замените строку:
print_text += print_r(value,level+1);
на:
print_text += value;

На этом все. Очень полезная функция для дебага массивов.

Функция round для Javascript


Функция округления числовых значений, идентичная одноименной в PHP.

Функция:
function round (value, precision, mode) {
  var m, f, isHalf, sgn;
  precision |= 0;
  m = Math.pow(10, precision);
  value *= m;
  sgn = (value > 0) | -(value < 0);
  isHalf = value % 1 === 0.5 * sgn;
  f = Math.floor(value);
  if (isHalf) {
    switch (mode) {
    case 'PHP_ROUND_HALF_DOWN':
      value = f + (sgn < 0);
      break;
    case 'PHP_ROUND_HALF_EVEN':
      value = f + (f % 2 * sgn);
      break;
    case 'PHP_ROUND_HALF_ODD':
      value = f + !(f % 2);
      break;
    default:
      value = f + (sgn > 0);
    }
  }
  return (isHalf ? value : Math.round(value)) / m;
}

Применение:
var rounded_value = round (value, precision, mode);
value - число, которое необходимо округлить
precision - точность округления, кол-во знаков после запятой (1 - до десятый, 2 - до сотых и т.д.)
mode - режим округления (режимы идентичны php: PHP_ROUND_HALF_UP (по-умолчанию), PHP_ROUND_HALF_DOWN, PHP_ROUND_HALF_EVEN или PHP_ROUND_HALF_ODD)
rounded_value - переменная с округленным числом

Работа с Cookie на Javascript


Представляю готовое решение по работе с cookie для javascript.

Запись в cookie:

function createCookie(name,value,days) {
if (days) {
  var date = new Date();
  date.setTime(date.getTime()+(days*24*60*60*1000));
  var expires = "; expires="+date.toGMTString();
 }
 else var expires = "";
 document.cookie = name+"="+value+expires+"; path=/";
}

Для запуска просто вызываем:
createCookie(name,value,days);
name - имя cookie
value - данные для сохранения в cookie
days - время жизни в днях

Чтение cookie:

function readCookie(name) {
 var nameEQ = name + "=";
 var ca = document.cookie.split(';');
 for(var i=0;i < ca.length;i++) {
  var c = ca[i];
  while (c.charAt(0)==' ') c = c.substring(1,c.length);
  if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
 }
 return null;
}

Запуск стандартный:
var value = readCookie(name);
name - имя cookie
value - данные из cookie будут заданы в эту переменную

Удаление cookie:

function eraseCookie(name) {
 createCookie(name,"",-1);
}

Запуск:
eraseCookie(name);
name - имя cookie

На этом все. Простой, но очень полезный скрипт.

Описание блога

Создан блог для вебмастеров. Возможно, тут найдут решения не только новички, но и опытные вебмастера.
Начинать буду с простого - интеграция функций одного языка в другой (в основном из PHP в Javascript). Далее по плану описание API карт (Яндекс и Google) с примерами основных функций. И, в перспективе, описание API электронных платежных систем и примеры реализации их интеграции (начиная с html формы, заканчивая отправкой средств через API).
Надеюсь это кому-нибудь пригодится.