MULTISOUP

MULTISOUP

MULTISOUP

マルティスープ
Staff Blog

Introduction example

2018.04.26

Googleマップでマーカーの回転

マーカーの回転

みなさん、こんにちは。

Google マップでマーカーを描画するとき、回転したいなと思うことはありませんか?

例えば、車の走行履歴を地図上に表示するときは、走行している方向に対して車のアイコンを描画したいですよね。

 

Googleマップなら、その位簡単にできるでしょう! と思う方が多いはずです。実際に自分もそう思っていました。しかし、色々と試してみると自分が思っていること(車のアイコンを回転しながら描画)は簡単にできそうにありませんでした。

 

そこで、色々と調査した結果を今回は書きたいと思います。

 

 

1.予め回転したアイコンを用意しておく

こちらは、あまりオススメしませんが、予め回転したアイコン画像を用意しておき角度によって目的のアイコンを指定する方法です。

 

 

2.サーバサイトでアイコンを回転する

例えば、サーバサイドのプログラム(PHPやPython)を使用し、元となる画像を回転し、レスポンスを返す方法です。

phpの例
<?php
    header("Content-type: image/png");
    $source = imagecreatefrompng($_REQUEST["icon"]);
    $rotate = imagerotate($source, $_REQUEST["angle"], 0);
    imagepng($rotate);
    imagedestroy($source);
?>

icon オプションの url に作成した php を指定し、パラメータとしてアイコン名と角度を指定します。

var marker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(35.7, 139.7),
    icon: {
        url: 'getIcon.php?icon=car.png&angle=30',
        scaledSize: new google.maps.Size(30, 30)
    }
});

 

 

3.シンボルを使って回転する

こちらは、標準の機能です。アイコン画像を使用するのではなく、シンボルという形式のマーカーであれば回転する機能があります。icon オプションに path を指定すると ratation が使用できます。

var marker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(35.7, 139.7),
    icon: {
        path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
        scale: 6,
        rotation: 30,
        fillColor: '#ff0000',
        fillOpacity: 0.7,
        strokeColor: '#ff0000',
        strokeWeight: 2 
    }
});

 

シンボルアイコンについては、以下のブログにも記載しているので、参考にしてください。

Googleマップに色々なマーカーを描画する方法

 

 

シンボルマーカを使ったサンプルです。ルート検索を実行後、ルート上をマーカーを回転しながら描画しています。

マーカーの回転

 

 

4.クライアントサイドでアイコンを回転する

こちらは、以下のサイトを参考にしました。HTML5のキャンバスを利用し、クライアントサイドでアイコンを回転して指定する方法です。

https://code.i-harness.com/en/q/67c4e5

 

RotateIcon というオブジェクトを定義します。

var RotateIcon = function(options){
    this.options = options || {};
    this.rImg = options.img || new Image();
    this.rImg.src = this.rImg.src || this.options.url;
    this.options.width = this.options.width || this.rImg.width;
    this.options.height = this.options.height || this.rImg.height;
    canvas = document.createElement("canvas");
    canvas.width = this.options.width;
    canvas.height = this.options.height;
    this.context = canvas.getContext("2d");
    this.canvas = canvas;
};
RotateIcon.makeIcon = function(url) {
    return new RotateIcon({url: url});
};
RotateIcon.prototype.setRotation = function(options){
    var canvas = this.context,
        angle = options.deg ? options.deg * Math.PI / 180 : options.rad,
        centerX = this.options.width/2,
        centerY = this.options.height/2;
    canvas.clearRect(0, 0, this.options.width, this.options.height);
    canvas.save();
    canvas.translate(centerX, centerY);
    canvas.rotate(angle);
    canvas.translate(-centerX, -centerY);
    canvas.drawImage(this.rImg, 0, 0);
    canvas.restore();
    return this;
};
RotateIcon.prototype.getUrl = function(){
    return this.canvas.toDataURL('image/png');
};

 

マーカー生成時に、icon オプションの url に「RotateIcon.makeIcon(“car.png”).setRotation({deg: 30}).getUrl()」のように指定します。

var marker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(35.7, 139.7),
    icon: {
        url: RotateIcon.makeIcon("car.png").setRotation({deg: 30}).getUrl(),
        scaledSize: new google.maps.Size(30, 30)
    }
});

 

アイコン画像を回転するサンプルです。シンボルマーカーと同様、ルート検索を実行後、ルート上をアイコン画像を回転しながら描画しています。

シンボルマーカーの回転

 

 

上記2つのサンプルでは、ルート検索実行後に、全てのノード(ポイント)を配列に保持し、ノード間の距離や角度を計算しながら次の点を求めています。このような計算を、Googleマップでは、ジオメトリライブラリを使用することで、簡単に行えます。

var p1 = new google.maps.LatLng(35.7, 139.7);
var p2 = new google.maps.LatLng(35.8, 139.8);
// p1 と p2 の距離
var distance = google.maps.geometry.spherical.computeLength([p1, p2]);
// p1 と p2の角度
var angle = google.maps.geometry.spherical.computeHeading(p1, p2);
// 次の点を求める(p1 から 距離100m、角度20度の位置)
var p3 = google.maps.geometry.spherical.computeOffset(p1, 100, 20);

 

なお、ジオメトリライブラリを使用するときは、「libraries=geometry」というパラメータを付ける必要があるので気をつけてください。

<script https://maps.google.com/maps/api/js?v=3&libraries=geometry&key={API_KEY}"></script>

ジオメトリライブラリについては、以下のブログも参考にしてください。

ジオメトリライブラリを使って距離や面積を算出する

 

 

いかがでしたか?

マーカーを回転する方法はいくつかありますが、クライアントサイド(JavaScript側)で行う方が良いと思いますので、3 か 4 をオススメします。

是非、お試しください。

 

 

地図や位置情報を用いたシステムのご提案・開発ならマルティスープへ

マルティスープは、創業以来のGISとモバイル開発の実績と技術力で、営業支援システムやリサーチ・公共インフラ・工事・警備業界の現場を支援するシステム開発など、地図や位置情報を使った業務システムの導入のご提案や開発をいたします。

現場をつなぐコミュニケーションが屋内外業務のパフォーマンスを最大限に。マルティスープのiField(アイ・フィールド)®シリーズは、屋内外業務の現場の実力を減少させるコミュニケーション障壁を除き、使い慣れたスマートデバイスを使って 現場の実力をリアルに伝えるサービス。

位置・空間情報のエキスパート集団として一緒に働きませんか?

マルティスープは地図情報をはじめとする位置・空間情報技術のエキスパート集団です。当社で日々研究している地図や位置情報といった技術は、災害支援など貢献度の高いシステムとして使用されることもあれば、スマートフォンアプリのゲームとして使われることもあり、その利用用途・価値は、今後もますます広がっていっています。
私たちの企業理念は、「創る喜び、使う喜び」です。
今後の開発体制をより強化するために、新卒・中途問わず、当社の未来を共に創っていただける新メンバーを募集します!

【関連記事】こんな記事も読まれています

2017.03.17

時差計算ができるGoogle Maps Time Zone API の利用方法を・・・

みなさん、こんにちは。

 

Google Maps API で最後まで紹介できていなかった「続きを読む

2017.03.22

Google マップで「竹島」と表示する方法は?

みなさん、こんにちは。

Google Maps JavaScript API は、みなさんご存知のとおり多言語に対応した地図です。そのため、l・・・

続きを読む

2018.04.20

Google マップでルート検索のレンダリングをカスタマイズ

みなさん、こんにちは!

Google Maps JavaScript API でルート検索を行い、その結果を地図上にレンダリングするとき、・・・

続きを読む

 - Google Maps JavaScript API, スタッフ日記