Главная > инструменты, исследования, картинки, разработка > Краткое руководство по добавлению собственных карт на Google Maps.

Краткое руководство по добавлению собственных карт на Google Maps.

Добавить собственную карту не так сложно, как может показаться :)
Итак приступим…

Земля в Google Maps разворачивается в проекцию Меркатора – т.е. представляет собой развёрнутый на плоскость цилиндр, что даёт нам прямоугольник, который разбивается на маленькие квадратики (tiles) с размерами 256×256пикселей.

Пример кусочка карты от Google:
http://mt1.google.com/mt?v=ap.88&hl=ru&x=285&y=162&z=9&s=G
mt

здесь можно видеть следующие значения
x=285 y=162 zoom=9

т.е. нам нужно хранить свою картинку по кусочкам вида:
tile_285_162_9.jpg
(или, разумеется, аналогичным образом хранить изображения в БД)
tile_285_162_9

Чтобы описать кусочек карты нужно знать три числа:
1 – его номер по вертикали (числа растут сверху вниз (т.е. с севера на юг)) ( в примере — 285)
2 – его номер по горизонтали (числа растут слева направо (с запада на восток)) (162)
3 – его уровень увеличения ( zoom) (9)

Таким образом, карту можно представить в виде стопки слоёв, каждый из которых состоит из маленьких квадратиков. (Очевидно, что число квадратиков становится больше при увеличении уровня приближения.)

Итак, у нас есть изображение, которое мы хотим наложить на карту или показать вместо карты.
Во-первых, нужно узнать те самые три числа, которые дают нам местоположение нужного кусочка карты.
В самом простом случае можно загрузить нужный нам участок карты и посмотреть информацию о полученных изображениях (в FireFox: Инструменты->Информация о странице — > Мультимедиа) или же можно воспользоваться online-сервисом [6].
Там нужно ввести координаты и уровень увеличения интересующего нас места на карте и он покажет нужные нам числа, но самое интересное — через данный сервис можно загрузить свою картинку и он её нам разрежет на необходимое количество кусочков и даст им нужные имена в формате:

Tile_18250_10410_15.jpg

К сожалению, данный сервис вываливается с ошибкой при попытке разрезать большие картинки. В таком случае — придётся резать картинку самостоятельно.

! Следует учесть, что картинку придётся подгонять под те самые квадратики карты !

Можно воспользоваться Photoshop-ом, я же использую для этих целей Gimp.
Чтобы в нём разрезать картинку нужно по вертикали и горизонтали картинки (уже подогнанной под карту, т.е. уже обрезанной или смещённой нужным образом) через каждые 256 пикселей вывести направляющие (Изображение->Направляющие->Новая направляющая)
Далее выполняем преобразование гильотина (Изображение->Преобразование->Гильотина)
!процедура крайне требовательная к оперативной памяти!
После этого у нас появится много кусочков изображения, которые сохраняются с именами вида:
p4.jpg – исходное изображение
p4-00-00.jpg
p4-01-00.jpg

p4-01-07.jpg
..
p4-09-00.jpg

и т.д.
Нумерация идёт так же как и на карте – первый номер – столбец, второй – строка.

Чтобы переименовать (или лучше сказать – перенумеровать) получившиеся картинки я написал небольшой скрипт на питоне:

  1. #
  2. # For copy files from def-00-00.jpg to tile\tile_18243_10406_15
  3. #
  4. import os
  5. # for copy
  6. import shutil
  7. srcfile="p4-01-01.JPG"
  8. dstfile=""
  9. #-----------------------------------------
  10. #
  11. # begin here :)
  12. #
  13. print "Start..."
  14. path = srcfile
  15. tilex=281
  16. tiley_beg=160
  17. tiley=tiley_beg
  18. zoom='9'
  19. for i in range(1,10):
  20. for j in range(1,8):
  21. if i<= 9:
  22. x='0'+str(i)
  23. else:
  24. x=str(i)
  25. if j<= 9:
  26. y='0'+str(j)
  27. else:
  28. y=str(j)
  29. srcpath='p4-'+x+'-'+y+'.jpg'
  30. if os.path.exists(srcpath):
  31. print srcpath, ' exists'
  32. shutil.copy(srcpath,'tile\\tile_'+str(tilex)+'_'+str(tiley)+'_'+zoom+'.jpg')
  33. else:
  34. print 'Cant find', srcpath
  35. tiley+=1
  36. tilex+=1
  37. tiley=tiley_beg
  38. print "Done."

* This source code was highlighted with Source Code Highlighter.

В скрипте нужно установить следующие параметры:
tilex – номер крайнего изображения по вертикали на карте Google
tiley_beg – номер крайнего изображения по горизонтали на карте Google
zoom – уровень увеличения на карте Google
Далее изменить граничные условия циклов по количеству ваших полученных картинок.
Не забыть внести изменения в srcpath, внеся туда своё название картинки.
После выполнения скрипта в директории tile будут ваши файлы с именами:
tile_281_160_9.jpg
tile_281_161_9.jpg

tile_289_166_9.jpg

Осталось только настроить вывод вашей карты, средствами Google Maps.

Для приведённого примера:

  1. function add_custom_map(map)
  2. {
  3. var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(57.72883324000875,16.471134185791016),new GLatLng(49.693182016907464,25.556020736694336) ),8, "Karta39");
  4. var copyrightCollection = new GCopyrightCollection('Map Data:');
  5. copyrightCollection.addCopyright(copyright);
  6. var tilelayers = [new GTileLayer(copyrightCollection , 9, 9)];
  7. tilelayers[0].getTileUrl = CustomGetTileUrl;
  8. tilelayers[0].getCopyright = function(a,b)
  9. {
  10. var c= copyrightCollection.getCopyrightNotice(a,b);
  11. if (!c)
  12. {
  13. c = G_NORMAL_MAP.getTileLayers()[0].getCopyright(a,b);
  14. }
  15. return c;
  16. }
  17. var custommap = new GMapType(tilelayers, new GMercatorProjection(10), "Custom Map", {shortName:"1645"});
  18. map.addMapType(custommap);
  19. }
  20. function CustomGetTileUrl(a,b)
  21. {
  22. if (b==9 && a.x>280 && a.x<290 && a.y>159 && a.y<167)
  23. return "tile_"+a.x+"_"+a.y+"_"+b+".jpg";
  24. else
  25. return G_NORMAL_MAP.getTileLayers()[0].getTileUrl(a,b);
  26. }

* This source code was highlighted with Source Code Highlighter.

Как видно – сначала создаётся copyright для слоя, а затем сам слой с вашей картой.
В параметр getTileUrl передаётся функция возвращающая ваши кусочки карты — CustomGetTileUrl(a,b)
, где a – точка с параметрами a.x и a.y, которые указывают местоположение картинки по вертикали и горизонтали
b – уровень приближения слоя.
Строчка return G_NORMAL_MAP.getTileLayers()[0].getTileUrl(a,b);
Возвращает родную картинку Google Maps – если эту строчку убрать, то на карте будет отображаться только ваша картинка.

Полный вариант:

  1. <html>
  2. <head>
  3. <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
  4. <title>Google Custom Maps</title>
  5. <!-- key for karta39.ru :) -->
  6. <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAsL2VORzTwmVBxxfMiMNG7hSQWpIDMILbmlKIxypjOkZkxcl47xRnQ74rU6B3rYRRuou-6ZHLri9jUA"
  7. type="text/javascript"></script>
  8. <script type="text/javascript">
  9. //<![CDATA[
  10. function initialize()
  11. {
  12. if (GBrowserIsCompatible())
  13. {
  14. var map = new GMap2(document.getElementById("map"));
  15. var mmmap = map;
  16. //map.addControl(new GScaleControl());
  17. map.addControl(new GLargeMapControl()); // контрол перемещения и приближения
  18. map.addControl(new GMapTypeControl()); // контрол режима карты
  19. map.setCenter(new GLatLng(54.707168569101256,20.510530471801758),9);    // Kaliningrad
  20. add_custom_map(map);
  21. }
  22. // display a warning if the browser was not compatible
  23. else
  24. {
  25. alert("Sorry, the Google Maps API is not compatible with this browser");
  26. }
  27. }
  28. function add_custom_map(map)
  29. {
  30. var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(57.72883324000875,16.471134185791016),new GLatLng(49.693182016907464,25.556020736694336) ),8, "Karta39");
  31. var copyrightCollection = new GCopyrightCollection('Map Data:');
  32. copyrightCollection.addCopyright(copyright);
  33. var tilelayers = [new GTileLayer(copyrightCollection , 9, 9)];
  34. tilelayers[0].getTileUrl = CustomGetTileUrl;
  35. tilelayers[0].getCopyright = function(a,b)
  36. {
  37. var c= copyrightCollection.getCopyrightNotice(a,b);
  38. if (!c)
  39. {
  40. c = G_NORMAL_MAP.getTileLayers()[0].getCopyright(a,b);
  41. }
  42. return c;
  43. }
  44. var custommap = new GMapType(tilelayers, new GMercatorProjection(10), "Custom Map", {shortName:"1645"});
  45. map.addMapType(custommap);
  46. }
  47. function CustomGetTileUrl(a,b)
  48. {
  49. if (b==9 && a.x>280 && a.x<290 && a.y>159 && a.y<167)
  50. return "tile_"+a.x+"_"+a.y+"_"+b+".jpg";
  51. else
  52. return G_NORMAL_MAP.getTileLayers()[0].getTileUrl(a,b);
  53. }
  54. //]]>
  55. </script>
  56. </head>
  57. <body onload="initialize()" onunload="GUnload()">
  58. <div id="map" style="width: 500px; height: 300px"></div>
  59. </body>
  60. </html>

* This source code was highlighted with Source Code Highlighter.

Посмотреть пример можно здесь: http://karta39.ru/map/2/cm.html
Стандартная карта:
1
Включён режим нашей карты:
2

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

Для ознакомления с другими возможностями вывода своих карт можно почитать [3]. Там показано, как сделать так, чтобы ваш слой был полупрозрачным:

Для этого нужно добавить в add_custom_map следующий код:

  1. var paleLayer = new GTileLayer(copyrightCollection,12,12);
  2. paleLayer.getTileUrl = CustomGetTileUrl;
  3. paleLayer.getOpacity = function() {return 0.5}
  4. var tilelayers3 = [G_NORMAL_MAP.getTileLayers()[0], paleLayer];
  5. var custommap3 = new GMapType(tilelayers3, new GMercatorProjection(10), "1645 Mixture", {shortName:"1645Mx"});
  6. map.addMapType(custommap3);

* This source code was highlighted with Source Code Highlighter.

Вот, в принципе, и всё :)

Успехов!

Ссылки:
[1] http://code.google.com/intl/ru_ALL/apis/maps/documentation/reference.html
[2] http://econym.googlepages.com/index.htm — Google Maps API Tutorial
[3] http://econym.googlepages.com/custommap.htm
[4] http://int2e.com/blog/how-to-make-a-site-like-mapwowcom/
[5] http://mapki.com/wiki/Automatic_Tile_Cutter
[6] http://open.atlas.free.fr/GMapsTransparenciesImgOver.php

  1. 3 Февраль 2009 в 10:47 | #1

    Статья опубликована в Хакере :)
    http://www.xakep.ru/post/47006/default.asp

  2. 24 Февраль 2009 в 16:45 | #2

    а вот ещё очень хорошее объяснение работы gmaps :)
    http://docs.google.com/Doc?id=dcmn9ngg_16c32ccmpf

  3. 13 Май 2009 в 13:52 | #3

    а что-то на примере не видно Вашей новой карты?? или у меня что-то «заглючило»??

  4. 13 Май 2009 в 14:04 | #4

    @xoma
    только что проверил — в примере всё работает — см. кнопку «Custom Map» :)

Необходимо войти на сайт, чтобы написать комментарий.