Инструмент для определения координат с использованием API Google Maps

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

Исходный код для начала мы возьмем из примеров в документации API Google Maps по адресу http://code.google.com/intl/ru-RU/apis/maps/documentation/examples/index.html

А именно пример Tile Detector — http://code.google.com/intl/ru/apis/maps/documentation/javascript/v2/examples/tile-detector.htmll

Код примера:

<!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>Google Maps JavaScript API Example: Tile Detector</title> 
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
            type="text/javascript"></script> 
    <script type="text/javascript">	
    function initialize() {
      if (GBrowserIsCompatible()) {
 
        var map = new GMap2(document.getElementById("map_canvas"));
        map.setCenter(new GLatLng(37.88, -122.442626), 10);
        map.setUIToDefault();
 
        GEvent.addListener(map,"click", function(overlay,latlng) {
          if (overlay) {
            // ignore if we click on the info window
            return;
          }
          var tileCoordinate = new GPoint();
          var tilePoint = new GPoint();
          var currentProjection = G_NORMAL_MAP.getProjection();
          tilePoint = currentProjection.fromLatLngToPixel(latlng, map.getZoom());
          tileCoordinate.x = Math.floor(tilePoint.x / 256);
          tileCoordinate.y = Math.floor(tilePoint.y / 256);
          var myHtml = "Latitude: " + latlng.lat() + "<br/>Longitude: " + latlng.lng() + 
            "<br/>The Tile Coordinate is:<br/> x: " + tileCoordinate.x + 
            "<br/> y: " + tileCoordinate.y + "<br/> at zoom level " + map.getZoom();	
          map.openInfoWindow(latlng, myHtml);
        });
      }
    }
    </script> 
  </head> 
  <body onload="initialize()" onunload="GUnload()"> 
    <div id="map_canvas" style="width: 500px; height: 300px"></div> 
  </body> 
</html>

Теперь давайте немного изменим его.

Первое, поменяем координаты центра карты, для своего примера я беру координаты в Нижнем Новгороде 56.317957, 43.944416 и уровень масштаба 14.

Для нашей задачи нужны только значения широты и долготы, поэтому ненужные строчки я удалю (при желании Вы можете их оставить).

Это строки после функции GEvent.addListener:

var tileCoordinate = new GPoint();
var tilePoint = new GPoint();
var currentProjection = G_NORMAL_MAP.getProjection();
tilePoint = currentProjection.fromLatLngToPixel(latlng, map.getZoom());
tileCoordinate.x = Math.floor(tilePoint.x / 256);
tileCoordinate.y = Math.floor(tilePoint.y / 256);

И еще две строки

"<br/>The Tile Coordinate is:<br/> x: " + tileCoordinate.x +
"<br/> y: " + tileCoordinate.y + "<br/> at zoom level " + map.getZoom();    

 А в строке var myHtml = "Latitude: " + latlng.lat() + "<br/>Longitude: " + latlng.lng() + последний плюс заменяем на точку с запятой

var myHtml = "Latitude: " + latlng.lat() + "<br/>Longitude: " + latlng.lng() ;

Можно еще заменить слова Latitude и Longitude на Широту и Долготу соответственно.

Теперь нам надо подгрузить свою карту.

Делается это аналогично тому,  как описано в заметке: «Используем свою карту вместе с компонентом SOBI2 для Joomla».

В начале,  размещаем функцию CustomGetTileUrl для подгрузки тайлов.

После строки  map.setUIToDefault(); создается объект GCopyrightCollection и он прикрепляется к слою фрагментов, чтобы задать разрешение на использование изображений.

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

Задаем параметры для нашего слоя

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

Главное нужно не забыть удалить строку map.setCenter(new GLatLng(56.317957, 43.944416), 14); перед строкой map.setUIToDefault();

Привожу полный код, который у нас получился:

<!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>Пример кода для определения координат по своей карте c Google Maps JavaScript API</title> 
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAACHCJdlgAEGcD_flKUFEmVhT2yXp_ZAY8_ufC3CFXhHIE1NvwkxTeukKcKHF3ezmjTB0q6gzSBmoIUQ"
            type="text/javascript"></script> 
    <script type="text/javascript">	
 
 function CustomGetTileUrl(a,b)
    {
        if ( b == 11 && a.x >= 1272 && a.x <= 1275 && a.y >= 633 && a.y <= 635 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 12 && a.x >= 2545 && a.x <= 2550 && a.y >= 1266 && a.y <= 1271 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 13 && a.x >= 5090 && a.x <= 5100 && a.y >= 2533 && a.y <= 2543 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 14 && a.x >= 10180 && a.x <= 10200 && a.y >= 5067 && a.y <= 5087 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 15 && a.x >= 20361 && a.x <= 20400 && a.y >= 10135 && a.y <= 10174 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 16 && a.x >= 40723 && a.x <= 40801 && a.y >= 20270 && a.y <= 20348 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 17 && a.x >= 81446 && a.x <= 81603 && a.y >= 40540 && a.y <= 40697 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        else if ( b == 18 && a.x >= 162893 && a.x <= 163206 && a.y >= 81080 && a.y <= 81394 )
        {
            return "http://www.map.cek.ru//nnmaps//Z" + b + "/" + a.y + "/" + a.x + ".jpg"; // replace that with a "real" URL
        }
        return G_NORMAL_MAP.getTileLayers()[0].getTileUrl(a,b);
    }  
 
    function initialize() {
      if (GBrowserIsCompatible()) {
 
        var map = new GMap2(document.getElementById("map_canvas"));
        map.setUIToDefault();
 
        // Создаем copyright collection
            var copyCollection = new GCopyrightCollection('nn-map');
            var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(56.1700230, 43.6816406), new GLatLng(56.4260545, 44.1430664)), 0, "Created by Ugolnikov Sergey");
            copyCollection.addCopyright(copyright);
 
            //Определяем слой нашей карты
            var tilelayers = new Array();
            tilelayers[0] = G_NORMAL_MAP.getTileLayers()[0];
            tilelayers[1] = new GTileLayer(copyCollection, 11, 18 );
            tilelayers[1].getTileUrl = CustomGetTileUrl
            tilelayers[1].getOpacity = function () {return 1.00;};//of the non transparent part
            tilelayers[1].isPng = function() {return false;}; 
 
            // Устанавливаем параметры для нашего слоя карты
            var GMapTypeOptions = new Object();
            GMapTypeOptions.minResolution = 11;
            GMapTypeOptions.maxResolution = 18;
            GMapTypeOptions.errorMessage = "Данные карты не доступны";
 
            //Создаем пользовательский слой
            var custommap = new GMapType(tilelayers, new GMercatorProjection(22), "nn-map", GMapTypeOptions);
            custommap.getTextColor = function() {return "#000000";};
            map.addMapType(custommap);
            map.setCenter( new GLatLng(56.317957, 43.944416), 14, custommap );
 
 
        GEvent.addListener(map,"click", function(overlay,latlng) {
          if (overlay) {
            // ignore if we click on the info window
            return;
          }
 
          var myHtml = "Координата широты: " + latlng.lat() + "<br/>Координата долготы: " + latlng.lng() ;
          map.openInfoWindow(latlng, myHtml);
        });
      }
    }
    </script> 
  </head> 
  <body onload="initialize()" onunload="GUnload()"> 
    <div id="map_canvas" style="width: 800px; height: 600px"></div> 
  </body> 
</html>

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

  • Гость: Подскажите пожалуйста как в моем случае можно убрать маркеры при клике на чекбокс,когда снимаю галочку? Вот код: if (GBrowserIsCompatible()) { map = new GMap2(document.getElementById("map_canvas")); map.setCenter(new GLatLng(48.0, 37.8), 14); geocoder = new GClientGeocoder(); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); // bind a search control to the map, suppress result list map.addControl(new google.maps.LocalSearch(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,20))); var trafficOptions = {incidents:true}; trafficInfo = new GTrafficOverlay(trafficOptions); map.addOverlay(trafficInfo); for (var k = 100; k &lt;= 183; k++) { $(&quot;#x&quot;+k).change(function () { if ($(this).attr(&quot;checked&quot;)) { GDownloadUrl(&quot;php/&quot;+this.id+&quot;.php&quot;, function(data) { var xml = GXml.parse(data); var markers = xml.documentElement.getElementsByTagName(&quot;marker&quot;); for (var i = 0; i &lt; markers.length; i++) { var name = markers[i].getAttribute(&quot;name&quot;); var address = markers[i].getAttribute(&quot;address&quot;); var telephone = markers[i].getAttribute(&quot;telephone&quot;); var email = markers[i].getAttribute(&quot;email&quot;); var links = markers[i].getAttribute(&quot;links&quot;); var images = markers[i].getAttribute(&quot;images&quot;); var type = markers[i].getAttribute(&quot;type&quot;); var point = new GLatLng(parseFloat(markers[i].getAttribute(&quot;lat&quot;)),parseFloat(markers[i].getAttribute(&quot;lng&quot;))); var marker = createMarker(point, name, address,telephone, email, links, images, type); map.addOverlay(marker); } }); function createMarker(point, name, address,telephone, email, links,images, type) { var marker = new GMarker(point, customIcons[type]); var html =&#039;<b>' + name +'</b> ' + address+''+ telephone+''+email+''+links+''; GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(html); }); //return marker; } } else { GEvent.addListener(marker, function() { this.hide(); }); } }); } }
  • Гость: Супер! Отличная штука, давно такое искал! В связи с этим у меня к Вам огромная просьба - как можно прописать в коде, чтобы при нажатии на точку карты долгота записывалась в одно поле рядом с картой, а широта - в другое поле? То есть по задумке неграмотный пользователь кликает чтобы показать где он живет, а данные вклеиваются в контактную форму и потом отправляются на сервер после нажатия кнопки "отправить". Спасибо заранее за ответ!
  • Гость: <pre lang="html"> document.getElementById(id поля формы).value = latlng.lat(); document.getElementById(id поля формы).value = latlng.lng(); </pre>
  • Гость: Админушка, спасибо за скорый ответ, да только эта штука не работает с одинарными кавычками, а двойные внутри двойных - полностью блокируют работу скрипта и карта не показывается. Я пишу это так: <a href='#' rel="nofollow">ссылка</a> так как я не спец в яваскрипте, скажите пожалуйста, как мне поместить две кнопочки в это облако, где показываются широта и долгота, чтобы при нажатии на каждую вклеивалось значение в поле? Если я прописываю <a href='#' rel="nofollow">ссылка</a> <a href='#' rel="nofollow">ссылка2</a> вне скрипта, то есть в body, то все работает , а как мне поместить внутрь скрипта (или другим способом), чтобы можно было прямо в облаке нажимать на ссылочки? Спасибо заранее! С уважением, Роман
  • Гость: Спасибо, покопался, нашел выход. Спасибо, классная статья!
  • Гость: А что такое переменная key в строке. &lt;script src=&quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA&quot; Могу ли я использовать данное значение на своем сайте?
  • Гость: Это ключ к API Google Maps v2 для моего сайта. У каждого сайта (домена) он свой. Получить его можно на странице по адресу <a href="http://code.google.com/intl/ru/apis/maps/signup.html" rel="nofollow">http://code.google.com/intl/ru/apis/maps/signup.html</a>
  • Гость: СПАСИБО!!! Давно искал!! как найти lat и lng после звонка с телефона или отправки смс, чтобы цифры приходили на имейл или кудато еще!! Скажите плз!! Ася: 609340869 Мыло: axiomgames@mail.ru