- GoogleMap
-
2013-09-06 - 更新:2017-10-25
GoogleMapを利用し、図形を描画して囲った部分の面積を求めることができます。
ネットで探しましたが、バージョン3で組まれたものが見当たらなかったので書いておきます。
計測にはというジオメトリライブラリのユーティリティ関数(google.maps.geometry.spherical
)を使用します。
コードはGoogleMapオブジェクト(map)は既に作成済のものとして書いています。
ついでに、距離も計測できるようにしています。
ご参考になれば幸いです。
ちなみに、某メーカーの住宅地図ソフトでの面積計測と精度は変わりませんでした。
GoogleMapAPI version 3.21
PolygonOptionsクラス
1 | var myPolygonOptions = { |
2 | clickable: false , // クリックイベントの有効/無効 |
3 | fillColor: "#ffffff" , // 塗り潰し色 |
4 | fillOpacity: 0.6, // 塗り潰しの不透明度(0.0-1.0) |
5 | map: map, // GoogleMapのインスタンス |
6 | paths: new Array(), // 座標の配列 |
7 | strokeColor: "#000000" , // 線の色 |
8 | strokeOpacity: 0.8, // 線の不透明度(0.0-1.0) |
9 | strokeWeight: 3 // 線の太さ(ピクセル) |
10 | } |
Polygonクラス
1 | // Polygon用グローバル変数 |
2 | var poly; |
3 |
4 | var myPolygon = { |
5 |
6 | make: function () |
7 | { |
8 | poly = new google.maps.Polygon(myPolygonOptions); |
9 |
10 | // マウスカーソルを矢印に設定 |
11 | myOptions.draggableCursor = "default" ; |
12 | myOptions.draggingCursor = "default" ; |
13 | map.setOptions(myOptions); |
14 |
15 | // 既にマップにクリックイベントを設定していたらクリアする |
16 | google.maps.event.clearListeners(map, "click" ); |
17 |
18 | // マップのクリックイベントに図形描画 |
19 | google.maps.event.addListener(map, "click" , function (e) |
20 | { |
21 | if (e) |
22 | { |
23 | myPolygonOptions.paths.push( new google.maps.LatLng(e.latLng.lat(), e.latLng.lng())); |
24 |
25 | poly.setPaths(myPolygonOptions.paths); |
26 | poly.setMap(map); |
27 |
28 | // 面積計測のための図形座標の配列を別途作成 |
29 | // 別に作成しないと続きを描画できない(計測するには図形を閉じないといけないため) |
30 | var thisPoly = new Array(); |
31 |
32 | for ( var i = 0; i < myPolygonOptions.paths.length; i++) |
33 | { |
34 | thisPoly.push(myPolygonOptions.paths[i]); |
35 | } |
36 |
37 |
38 | // 面積を計測するには図形が閉じている必要があるので、最後に開始点を追加 |
39 | thisPoly.push(myPolygonOptions.paths[0]); |
40 |
41 | // 面積を計測し、小数点以下2位で切り上げ |
42 | var a = google.maps.geometry.spherical.computeArea(thisPoly); |
43 | a *= 100; |
44 | a = Math.ceil(a); |
45 | a /= 100; |
46 |
47 | alert( "面積:" + a + "平米" ); |
48 |
49 | if (myPolygonOptions.paths.length > 1) |
50 | { |
51 | // 最終点から1つ前の座標 |
52 | var from = myPolygonOptions.paths[myPolygonOptions.paths.length - 2]; |
53 | // 最終点の座標 |
54 | var to = myPolygonOptions.paths[myPolygonOptions.paths.length - 1]; |
55 | // 2点間の距離を計測 |
56 | var d = google.maps.geometry.spherical.computeDistanceBetween(from, to); |
57 | // 距離を小数点以下2位で切り上げ |
58 | d *= 100; |
59 | d = Math.ceil(d); |
60 | d /= 100; |
61 |
62 | alert( "最終2点間の距離:" + d + "m" ); |
63 | } |
64 | } |
65 | }); |
66 | }, |
67 |
68 | clear: function () |
69 | { |
70 | // 描画した図形の削除 |
71 | myPolygonOptions.paths = new Array(); |
72 | poly.setPaths( new Array()); |
73 | poly.setMap(map); |
74 | } |
75 |
76 | } |
【実装例】
mapオブジェクトを作成した後で以下を実行してください
1 | myPolygon.make(); |
描画した図形を削除するときは
1 | myPolygon.clear(); |
【公式】Google Maps Javascript API V3 Reference
https://developers.google.com/maps/documentation/javascript/reference?hl=ja
こちらのドキュメントがとても参考になりました。
Google Maps JavaScript API V3
http://ryo59.com/reference/index.html
・マウスカーソルの形状について
カーソルの形状は、W3Cで定義されているものは使えるようです。
http://www.w3.org/TR/2004/CR-CSS21-20040225/ui.html
GoogleMapAPI version 3.26
バージョンが上がったからか、マウスカーソルの設定がうまく動作しないようになってたので修正。
描画した図形の削除と同時にマウスカーソルを元に戻し、クリックイベントもクリアするメソッドも追加しました。
ついでに坪数計算も入れておきました。
修正版(2017/10/25)
1 | var myPolygon = { |
2 |
3 | make: function (area_id, area_tubo_id, distance_id) |
4 | { |
5 | poly = new google.maps.Polygon(myPolygonOptions); |
6 |
7 | // マウスカーソルを矢印に設定 |
8 | myOptions.draggableCursor = "default" ; |
9 | myOptions.draggingCursor = "default" ; |
10 | map.setOptions( { draggableCursor: "default" , draggingCursor: "default" } ); |
11 |
12 | // 既にマップにクリックイベントを設定していたらクリアする |
13 | google.maps.event.clearListeners(map, "click" ); |
14 |
15 | // マップのクリックイベントに図形描画 |
16 | google.maps.event.addListener(map, "click" , function (e) |
17 | { |
18 | if (e) |
19 | { |
20 | myPolygonOptions.paths.push( new google.maps.LatLng(e.latLng.lat(), e.latLng.lng())); |
21 |
22 | poly.setPaths(myPolygonOptions.paths); |
23 | poly.setMap(map); |
24 |
25 | // 面積計測のための図形座標の配列を別途作成 |
26 | // 別に作成しないと続きを描画できない(計測するには図形を閉じないといけないため) |
27 | var thisPoly = new Array(); |
28 | for ( var i = 0; i < myPolygonOptions.paths.length; i++) |
29 | { |
30 | thisPoly.push(myPolygonOptions.paths[i]); |
31 | } |
32 |
33 | // 面積を計測するには図形が閉じている必要があるので、最後に開始点を追加 |
34 | thisPoly.push(myPolygonOptions.paths[0]); |
35 |
36 | // 面積を計測し、小数点以下2位で切り上げ |
37 | var a = google.maps.geometry.spherical.computeArea(thisPoly); |
38 | a *= 100; |
39 | a = Math.ceil(a); |
40 | a /= 100; |
41 |
42 | alert( "面積:" + a + "平米" ); |
43 |
44 | // 面積を坪数に変換し、小数点以下2位で切り上げ |
45 | var tubo = a * 0.3025; |
46 | tubo *= 100; |
47 | tubo = Math.ceil(tubo); |
48 | tubo /= 100; |
49 |
50 | alert( "面積:" + tubo + "坪" ); |
51 |
52 | if (myPolygonOptions.paths.length > 1) |
53 | { |
54 | // 最終点から1つ前の座標 |
55 | var from = myPolygonOptions.paths[myPolygonOptions.paths.length - 2]; |
56 | // 最終点の座標 |
57 | var to = myPolygonOptions.paths[myPolygonOptions.paths.length - 1]; |
58 | // 2点間の距離を計測 |
59 | var d = google.maps.geometry.spherical.computeDistanceBetween(from, to); |
60 | // 距離を小数点以下2位で切り上げ |
61 | d *= 100; |
62 | d = Math.ceil(d); |
63 | d /= 100; |
64 |
65 | alert( "最終2点間の距離:" + d + "m" ); |
66 | } |
67 | } |
68 | }); |
69 | }, |
70 |
71 | clear: function () |
72 | { |
73 | // 描画した図形の削除 |
74 | myPolygonOptions.paths = new Array(); |
75 | poly.setPaths( new Array()); |
76 | poly.setMap(map); |
77 | }, |
78 |
79 | destroy: function () |
80 | { |
81 | this .clear(); |
82 |
83 | // マウスカーソルを元に戻す |
84 | myOptions.draggableCursor = null ; |
85 | myOptions.draggingCursor = null ; |
86 | map.setOptions( { draggableCursor: null , draggingCursor: null } ); |
87 |
88 | // マップのクリックイベントをクリア |
89 | google.maps.event.clearListeners(map, "click" ); |
90 | }, |
91 |
92 | } |
