3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

モバイルファクトリーAdvent Calendar 2017

Day 16

go-staticmapsの地図にアイコンとして任意の画像を表示したい

Last updated at Posted at 2017-12-16

この記事は、モバイルファクトリー Advent Calendar 2017 16日目の記事です。

10日目の記事で、go-staticmmapsというライブラリの紹介をさせていただきました。
https://github.com/flopp/go-staticmaps

実は最近このライブラリに出したp-r(小さな変更)がマージされて浮かれています。
ということで今回はせっかくなので、前回の記事の続編として、ライブラリをよくするために、さらにこんなの考えてみたよ!という内容で書こうと思います。

地図にアイコンとして任意の画像を表示したい

今現在、go-staticmapsはある一点を示すものとしてマーカーを用意しています。
しかし、このマーカーはサイズと色は変えられますが、形は変えられません。
せっかくなのですから、例えば会社の場所を示す地図には会社のロゴとか、なにかのキャラクターに関連する場所にそのキャラクターの顔を表示したり、そういう使い方をしたいものです。

そこで、アイコンとして任意の画像を表示できるようにライブラリを拡張してみました。

いまのマーカーの実装

いまのマーカーがどのように実装されているかを見てみます。
https://github.com/flopp/go-staticmaps/blob/master/marker.go#L125-L149

gc.DrawArc(x, y-m.Size, radius, (90.0+60.0)*math.Pi/180.0, (360.0+90.0-60.0)*math.Pi/180.0)
gc.LineTo(x, y)
gc.ClosePath()
gc.SetColor(m.Color)
gc.FillPreserve()
gc.SetRGB(0, 0, 0)	
gc.Stroke()

すごいですね、2D図形を描画できるライブラリでマーカーを描いてます。
ということで、画像を表示させる仕組みはなさそうなので、新しく作りましょう。

icon.goの実装

Iconという新しい機能を実装してみました。
これを使うと、こんな感じで指定した場所に画像を表示することができます。
もちろん、既存のものと組み合わせて、マーカーやパスを一緒に表示することもできます。
my-map.png

使い方

使い方を説明します。

package main

import (
  "path/to/tsukumaru/go-staticmaps" //cloneしてきたパス
  "github.com/fogleman/gg"
  "github.com/golang/geo/s2"
)

func main() {
  ctx := sm.NewContext()

  spot := s2.LatLngFromDegrees(35.6259434, 139.7251859)
  icon := sm.NewIcon(spot, "tsukumaru.jpeg", 30 ) //座標、画像のパス、サイズ
  icon.SetOffset(0, 0) //オフセット
  ctx.AddIcon(icon)

  // 画像として出力
  img, _ := ctx.Render()
  gg.SavePNG("my-map.png", img)
}

いままでのMarkerやPathと同じような雰囲気で使うことができます。

"path/to/tsukumaru/go-staticmaps"

いま現在は add_iconブランチに変更が置いてあるので、使ってみたい場合はtsukumaru/go-staticmapsをcloneしてブランチを変更してください。

NewIcon関数

この関数には画像を表示したい座標、画像のパス、サイズを指定します。
サイズは幅も高さも指定した数値で初期化されますが、それぞれ変更したい場合はSetWidthSetHeight関数を使います。

SetOffset関数

この関数ではOffsetを指定します。
デフォルトでは指定した点を中心として画像が表示されるようになっているので、少し上にあげたいなどの場合にお使いください。

実装

実装の中身としては、そこまで難しいことはしておらず、以下がほぼすべてです。
https://github.com/tsukumaru/go-staticmaps/blob/add_icon/icon.go#L75-L81

img = resize.Resize(i.Width, i.Height, img, resize.Lanczos3) //画像のリサイズ

//指定された場所を中心として画像が表示されるように
x, y := trans.ll2p(i.Position)
ix := int(x) - int(i.Width/2) 
iy := int(y) - int(i.Height/2)

//オフセットつきで画像を描画
gc.DrawImageAnchored(img, ix, iy, i.Offset[0], i.Offset[1])

画像のリサイズには以下のライブラリを使い、指定したサイズにリサイズしています。補完関数の指定はなんとなくで指定してます...
https://github.com/nfnt/resize

trans.ll2pという関数は、内部で定義されている関数で、LatLng型から内部の座標に変換してくれます。
https://github.com/flopp/go-staticmaps/blob/master/context.go#L292-L308

画像の描画は、fogleman/ggの中にDrawImageAnchoredというオフセットを考慮して描画してくれるちょうどいい関数があったので、それを使っています。
https://github.com/fogleman/gg/blob/master/context.go#L575-L591

画像の合成とか必要なのかなーとか思ってましたが、単に画像を描画するだけで済んだのでよかったです。

まとめ

go-staticmapsで地図画像に任意の画像を表示させるために、Iconという新しい機能を実装してみました。既存の機能と同様に使うことができます。
しかしまだコマンドラインに対応してなかったり、まだまだ改善できるところはあるので、改善していってまたp-r出せればと思っています!

明日は @tenmihi さんです。楽しみですね!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?