Let's write β

プログラミング中にできたことか、思ったこととか

GoogleMapのスタイルギャラリーSnazzyMapsのスタイルを適用したGoogle Static Mapの作成

GoogleMapのStaticMapを作るときに、スタイルをカスタマイズしてアプリケーションのテーマと雰囲気を合わせたいなという場合があります。 GoogleMapのスタイルはカスタマイズできるのですが、個別の項目を1からカスタマイズするよりは、 おしゃれな既存のテーマを見つけて、そこから微調整するほうがらくですよね。

そんな既存のテーマが大量にアップロードされている

snazzymaps.com

というありがたいページがあります。 このサイトはユーザーがカスタマイズしたスタイルを投稿してくれていて、ライセンスCCで公開されており、自由に使うことができます。

このサイトで、たとえば

Apple Maps-esque - Snazzy Maps - Free Styles for Google Maps

のようなスタイルページを開くとJS用のスタイルコードをJSONでダウンロードできるのですが、 このJS用のスタイルをStaticMapで利用するためには少し変換してやる必要があります。

具体的にはfeature:<featureType>|element:<elementType>|<StylersのKey Valueを:で繋いだもの>という形式に変換して それぞれ個別にstyleパラメータとして指定してやる必要があります。 また、カラーコードは#で始まる形式ではなく、0xから始める形式に変換してやる必要があります。

なので、SnazzyのページのURIを指定すると、そこからHTMLを解析してスタイルのJSONを取得して、 上記の変換をした上でStaticMapのURLを生成してくれるRubyスクリプトを書いてみました。

require 'json'
require 'open-uri'
require 'nokogiri'

SNAZZY_URL = '<Snazzy style page url>' # 'https://snazzymaps.com/style/42/apple-maps-esque'
GOOGLE_MAP_API_KEY = "<Google Map Api Key>"

if __FILE__ == $0
    baseURL = "https://maps.googleapis.com/maps/api/staticmap"
    # Default Parameters
    parameters = [
        {"size": "400x400"},
        {"scale": 2},
        {"maptype": "roadmap"},
        {"key": GOOGLE_MAP_API_KEY}
    ]

    # Retrieve Style from Snazzy
    charset = nil
    html = open(SNAZZY_URL) do |f|
      charset = f.charset
      f.read
    end
    page = Nokogiri::HTML.parse(html, nil, charset)
    styleJSONStr = page.search('pre#style-json').text
    styleJSON = JSON.parse(styleJSONStr)
    styleJSON.each do |entry|
      style = []
      featureType = entry["featureType"]
      if featureType
        style.push("feature:#{featureType}")
      end
      elementType = entry["elementType"]
      if elementType
        style.push("element:#{elementType}")
      end
      entry["stylers"].map { |styleEntry|
        k, v = styleEntry.first
        if k == "color"
          v = "0x#{v[1..-1]}"
        end
        style.push("#{k}:#{v}")
      }
      parameters.push({"style": style.join("|")})
    end

    # Markers
    src = "label:S|color:blue|渋谷駅"
    dst = "label:G|color:red|六本木一丁目駅"
    parameters.push({"markers": "#{src}"})
    parameters.push({"markers": "#{dst}"})

    # Add Polyline
    parameters.push({"path": "color:0x5BB2FFFF|weight:4|enc:omsxEystsYMo@Kw@GgACa@??EqBGo@GaAC_@Ek@KmG?iBCwAIwEUgFGwAWsFSuEGeBGmBKgBI}BAOCo@IeBG{@OwDWmGOkDGkAKeA??KkGIsC??CeABwAIsAYuCS}AKo@]{AmCcLm@{Ba@qAc@uAw@qB_@aAQc@s@iBwBiGyA}D_E}JYu@qAyCkBqE??k@wAo@yAWo@Mk@G[EUAW?[@SBODQDK"})

    # Generate QueryParameter
    queryParameter = parameters.map {|entry|
      k,v = entry.first
      "#{k}=#{v}"
    }.join("&")

    # Generate & Open URL
    url = "#{baseURL}?#{queryParameter}"
    puts url
    system "open '#{url}'"
end

このスクリプトを実行すると以下の画像のようなStaticMapへのリンクが生成されます。

f:id:Pocket7878_dev:20170725135121p:plain

無事ギャラリーのスタイルが適用されたStaticMapを取得することができました。

僕が働いているAzit.incでは一緒に働けるエンジニアを募集しています!
採用情報 — 株式会社アジット|Azit Inc.