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

Автор: | 14.03.2010

В этой заметке я расскажу, как сделать инструмент для определения координат для своей карты, созданной на основе 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>

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

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

  1. Игорь

    Подскажите пожалуйста как в моем случае можно убрать маркеры при клике на чекбокс,когда снимаю галочку?
    Вот код:
    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 <= 183; k++)
    {
    $("#x"+k).change(function ()
    {

    if ($(this).attr("checked"))
    {
    GDownloadUrl("php/"+this.id+".php", function(data)
    {
    var xml = GXml.parse(data);
    var markers = xml.documentElement.getElementsByTagName("marker");

    for (var i = 0; i < markers.length; i++)
    {
    var name = markers[i].getAttribute("name");
    var address = markers[i].getAttribute("address");
    var telephone = markers[i].getAttribute("telephone");
    var email = markers[i].getAttribute("email");
    var links = markers[i].getAttribute("links");
    var images = markers[i].getAttribute("images");
    var type = markers[i].getAttribute("type");
    var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),parseFloat(markers[i].getAttribute("lng")));
    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 ='‘ + name +’ ‘ + address+»+ telephone+»+email+»+links+»;
    GEvent.addListener(marker, ‘click’, function()
    {
    marker.openInfoWindowHtml(html);
    });
    //return marker;
    }

    }
    else
    {
    GEvent.addListener(marker, function()
    {
    this.hide();
    });
    }

    });
    }
    }

  2. Роман

    Супер! Отличная штука, давно такое искал!
    В связи с этим у меня к Вам огромная просьба — как можно прописать в коде, чтобы при нажатии на точку карты долгота записывалась в одно поле рядом с картой, а широта — в другое поле? То есть по задумке неграмотный пользователь кликает чтобы показать где он живет, а данные вклеиваются в контактную форму и потом отправляются на сервер после нажатия кнопки «отправить».
    Спасибо заранее за ответ!

    1. admin Автор записи
      document.getElementById(id поля формы).value = latlng.lat();
      document.getElementById(id поля формы).value = latlng.lng();
  3. Роман

    Админушка, спасибо за скорый ответ, да только эта штука не работает с одинарными кавычками, а двойные внутри двойных — полностью блокируют работу скрипта и карта не показывается.
    Я пишу это так:

    ссылка

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

    ссылка ссылка2

    вне скрипта, то есть в body, то все работает , а как мне поместить внутрь скрипта (или другим способом), чтобы можно было прямо в облаке нажимать на ссылочки?

    Спасибо заранее!

    С уважением, Роман

  4. Роман

    Спасибо, покопался, нашел выход.
    Спасибо, классная статья!

  5. Рома

    СПАСИБО!!! Давно искал!!
    как найти lat и lng после звонка с телефона или отправки смс, чтобы цифры приходили на имейл или кудато еще!! Скажите плз!!
    Ася: 609340869
    Мыло: axiomgames@mail.ru

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

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