Первое и самое важное, что вам нужно знать о сервисе Google Maps - это круто! Google предоставляет чрезвычайно быстрый, надежный и настраиваемый инструмент freemium. Более того, пока вы не достигнете лимита в 2500 запросов в день, это будет совершенно бесплатно, поэтому подходит для большинства стартапов.

Моя карьера веб-разработчика только началась, когда я столкнулся с необходимостью интегрировать интерактивную карту в приложение. Это были дни, когда я часто забывала, что «под солнцем нет ничего нового». Так что время от времени я изобретал велосипед заново.

То же самое произошло с добавлением Google Maps - я начал с изучения руководств, вместо того, чтобы искать какое-то готовое решение. Должен сказать, мне это нисколько не жаль. Я выяснил, что с интеграцией с Google Maps API нет никаких сложностей.

Я хочу поделиться своим опытом интеграции Google Maps в Ruby on Rails.

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

Прежде чем перейти к самой интеграции с Google Maps, стоит упомянуть геокодирование.

Согласно руководствам Google Maps, геокодирование - это процесс преобразования адресов (например, «1600 Amphitheatre Parkway, Mountain View, CA») в географические координаты (например, широту 37,423021 и долготу -122,083739).

Эти координаты можно использовать для размещения маркеров или расположения карты.

Для Rails есть прекрасная жемчужина - Геокодер, которая может обрабатывать все задачи, связанные с геокодированием. Настроить довольно просто. Что вам нужно сделать, так это добавить два поля - latitude: float и longitude: float - в таблицу, содержащую адреса, указать в модели:

geocoded_by :address
after_validation :geocode

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

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

Статические карты

Google предоставляет карты двух типов - статические и динамические.

Может показаться, что у статических карт вообще нет области применения, так как динамические намного функциональнее и привлекательнее. Однако есть два преимущества использования статических Google Maps:

  • во-первых, их гораздо проще интегрировать;
  • во-вторых, что наиболее важно, их можно легко добавить в любой сгенерированный статический документ, например, в PDF-файл.

Статический API довольно прост - HTTP-запрос к Google Maps API возвращает сплошное изображение. Выполнено. С полученным изображением можно делать что угодно. Конечно, вы не должны обрезать информацию об авторских правах Google или делать что-либо в этом роде.

В следующем примере вы видите место, знакомое большинству наших сотрудников - офис Anadea в Днепре:

Вот то же место, но с большим увеличением:

И снова то же самое место, но на этот раз в виде панорамного вида (сделанного соответствующей службой Google Maps под названием Street View):

Список доступных параметров можно найти здесь.

Очевидно, что первая итерация интеграции статической карты Google Map включает в себя просто написание одного метода для одного помощника, например:

def google_map(center)
  "https://maps.googleapis.com/maps/api/staticmap?center=#{center}&size=300x300&zoom=17"
end

где в качестве параметра центра вы можете передать адрес улицы или пару координат.

Затем из представления к нему можно получить доступ, позвонив:

image_tag google_map(center: location.address)

or

image_tag google_map(center: [ location.latitude, location.longitude ].join(','))

Понятно, что в реальных приложениях параметры не должны быть своего рода «магическими числами». Они могут быть либо явно переданы вспомогательному методу, либо сохранены в файле настроек.

На этом все, что касается интеграции статических карт.

Встроенные карты

Google Maps Embed API очень похож на статический API.

С помощью одного HTTP-запроса вы можете легко добавить интерактивную карту в свое приложение. Его можно встроить, добавив iframe и указав URL-адрес Google Maps Embed API в качестве атрибута srcattribute:

<iframe width="300" height="300" frameborder="0" style="border:0"
 src="https://www.google.com/maps/embed/v1/place?key=YOUR_API_KEY&q=ADDRESS_OR_COORDINATES"
 allowfullscreen>
</iframe>

Это позволяет очень быстро и легко получить базовую функциональность Google Maps.

Конечно, в реальном приложении этот код нужно переместить во вспомогательный, немного доработать и улучшить, но интеграция по-прежнему остается очень простой.

Более подробную информацию о Google Embed API можно найти здесь.

Динамические карты (JS)

Все еще легко!

Первое, что вам нужно сделать, это добавить скрипты Google Maps с тегом ‹script›:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY async defer></script>

Во-вторых, вам нужно добавить на страницу div с определенным идентификатором (например, картой). Скрипты JS будут использовать этот идентификатор, чтобы определить, где должна быть нарисована карта.

В-третьих, вы можете начать изучать руководство Google Maps и добавлять новые возможности на свою интерактивную карту.

Пример: предположим, что в нашем приложении есть несколько вкладок, и каждая вкладка содержит карту той же области, но с другим набором маркеров. При нажатии на любой маркер карта должна быть отцентрирована на нем и увеличена.

Ниже вы можете найти код CoffeeScript для реализации необходимой функциональности.

class GoogleMap 
  # defaults
  zoom =
    initialView: 15
    closeView: 18
  markers = []
  map = undefined
  constructor: (home) ->
    # set map center and view options
    lat = home["lat"]
    lon = home["lon"]
    myLatlng = new google.maps.LatLng(lat, lon)
    mapOptions =
      zoom: zoom.initialView
      center: myLatlng
    # create map
    map = new google.maps.Map(document.getElementById("map"), mapOptions)
  addMarker: (location, title) ->
    # create marker and add it to the array of markers
    marker = new google.maps.Marker(
      position: location,
      title: title,
      map: map
    )
    markers.push marker
    # add event listener - change zoom and center position on marker click
    google.maps.event.addListener marker, "click", ->
      map.setZoom zoom.closeView
      map.setCenter marker.getPosition()
  addMarkers: (markerList) ->
    # add all markers
    _.each markerList, (marker) =>
      position = new google.maps.LatLng marker["lat"], marker["lon"]
      title = "#{marker['full_address']}"
      @addMarker position, title
  
  drawMarkers: (map) ->
    # draw markers
    _.each markers, (marker) ->
      marker.setMap map
      # IMPORTANT: calling setMap method on marker will draw this marker, calling setMap with null parameter will erase it
  
  showMarkers: ->
    @setAllMap map
  hideMarkers: ->
    @setAllMap null
  removeListeners: ->
    _.each markers, (marker) ->
      google.maps.event.clearInstanceListeners(marker)
  deleteMarkers: ->
    @hideMarkers()
    @removeListeners()
    markers = []
app.google or= { classes: {} }
app.google.classes.GoogleMap = GoogleMap

Затем этот класс можно использовать в коде следующим образом:

$ ->
  { GoogleMap } = app.google.classes
  
  googleMap = new GoogleMap($('[data-map]:eq(0)').data('home'))
  googleMap.placeMarkers($("[data-map]:eq(0)").data("markers-list"))
  $(document).on 'click', '[data-tab]', ->
    googleMap.deleteMarkers()
    googleMap.placeMarkers($("[data-map]:eq($(@).index())").data("markers-list"))

Это уже не так просто, но все же читаемо, не так ли?

Гемы Rails и плагины JS

Естественно, один из самых острых вопросов, которые задают разработчики RoR, когда они хотят интегрировать Google Maps, - могут ли они использовать все классные функции Google Maps вообще без написания кода JavaScript.

Что ж, есть пара драгоценных камней, которые пытаются помочь вам в этом.

Первый и самый известный - жемчужина Google-Maps-for-Rails. Честно говоря, эта жемчужина сильно напоминает мне старинную народную сказку о Каменном супе. Сам камень играет роль камня, а все фрагменты кода JS, которые вам нужно добавить для настройки карты, играют роли моркови, картофеля, мяса, приправ и других ингредиентов.

Другое дело - гем GoogleMaps, который изо всех сил старается сделать все это в стиле Rails и сам добавляет все базовые JS-скрипты. Однако интеграция карт Google с этим драгоценным камнем также не лишена недостатков.

Ситуация ухудшается, когда вам нужно добавить некоторые взаимодействия с картой. Вы не можете справиться с этим без добавления JS-скриптов, и это значительно снижает ценность всех попыток нарастить такую ​​функциональность, как драгоценные камни.

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

Что касается плагинов JS - большинство из них - это просто код, скопированный / вставленный из Google Maps, иногда немного реорганизованный.

Вот список самых привлекательных плагинов:

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

Аргументом против как драгоценных камней, так и плагинов является тот факт, что вы должны строить логику приложения на основе их синтаксиса, и вам следует изучить этот синтаксис заранее. Более того, если Google изменяет API Карт Google, вам придется подождать, пока не будет выпущена обновленная версия драгоценного камня или плагина, или интегрировать карты вручную, чего вы и пытались избежать.

Обобщить

Интеграция статических и встроенных карт - это вопрос создания единого метода. Искать готовые решения совершенно бессмысленно.

Интеграция динамических карт немного сложнее, но это не должно мешать вам пытаться интегрировать их с нуля, потому что:

  • это поможет вам глубже понять их API и возможности, которые обязательно пригодятся в будущем;
  • это не займет больше времени, чем интеграция через готовые решения;
  • это избавит вас от необходимости тратить время на поиски лучшего решения;
  • это освободит вас от изучения (потенциально неудобного) синтаксиса, созданного кем-то другим;
  • это улучшит ваши навыки интерфейса пользователя;
  • и наконец, это интересно.

И да, написанный вами код можно легко использовать в новом проекте или даже стать основой для ваших собственных плагинов. Так что, кто знает, может, когда-нибудь появится статья о собственном решении под ключ!

Исходная статья: Как интегрировать Google Maps в приложение Ruby on Rails.