Skip to content

Instantly share code, notes, and snippets.

@tai-sho
Last active July 11, 2017 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tai-sho/b886a823f02682a457a99e97a7e8be73 to your computer and use it in GitHub Desktop.
Save tai-sho/b886a823f02682a457a99e97a7e8be73 to your computer and use it in GitHub Desktop.
GoogleMapを扱うjs
/**
* Map表示を行う
* @class Map
*/
;var Map = (function(window, $) {
/**
* コンストラクタ
* @class Map
*/
function Map(target, coords, options) {
if(!('google' in window && 'maps' in window.google)) {
throw new Error('GoogleMapAPI was not found.');
}
this.engine = google.maps;
// 地図オプション
options = $.extend({
center: null, zoom: 13
}, options);
// マップ情報を取得
if(coords) {
options['center'] = new this.engine.LatLng(coords.lat, coords.lng);
}
// マップ初期化処理
this.entity = new this.engine.Map(target, options);
// マーカー、情報ウィンドウを保持する配列
this.markers = new this.engine.MVCArray();
this.infoWindows = new this.engine.MVCArray();
this.mapElement = target;
// GoogleMapによって出力されるspanタグの監視・削除
this.removeGmapSpan();
}
/**
* MapEngine
* @var google.maps
*/
Map.prototype.engine = null;
/**
* GoogleMapObject
* @var this.engine.Map
*/
Map.prototype.entity = null;
/**
* マーカーを格納する配列
* @var this.engine.MVCArray
*/
Map.prototype.markers = null;
/**
* 情報ウィンドウを格納する配列
*/
Map.prototype.infoWindows = null;
/**
* 現在選択されている情報ウィンドウ
* @var {google.map.infoWindow}
*/
Map.prototype.currentInfoWindow = null;
/**
* 地図の高さ調整を行います。
* @param {integer} [height] 高さ。未指定の場合はウィンドウの高さを指定。
*/
Map.prototype.setHeight = function(height) {
height = height || window.innerHeight;
// 高さを設定
this.mapElement.style.height = height + 'px';
this.engine.event.trigger(this.entity, 'resize');
}
/**
* 指定された緯度経度の位置に地図の中心点を移動します。
* @param {float} lat 緯度
* @param {float} lng 経度
*/
Map.prototype.setCenter = function(lat, lng) {
this.entity.panTo(new this.engine.LatLng(lat, lng));
};
/**
* マーカーを地図にセットします。
* セットされたマーカーはmarkersプロパティで管理します。
* @param {float} lat 緯度
* @param {float} lng 経度
* @param {object} options this.engine.Markerに引き渡す設定値
* @returns {this.engine.Marker} セットしたMarkerのオブジェクト
*/
Map.prototype.setMarker = function(lat, lng, options) {
var latlng = new this.engine.LatLng(lat,lng);
var markerOptions = {
position: latlng,
map: this.entity
};
if(options) {
markerOptions = $.extend(markerOptions, options);
}
var marker = new this.engine.Marker(markerOptions);
this.markers.push(marker);
return marker;
};
/**
* マーカーを全て削除します。
*/
Map.prototype.destroyMarker= function() {
this.markers.forEach(function (marker, idx) {
marker.setMap(null);
});
this.markers.clear();
};
/**
* マーカーに情報ウィンドウをセットします。
* @param {google.map.Marker} marker マーカーオブジェクト
* @param {string} html 情報ウィンドウにセットするhtml
* @returns {google.map.InfoWindow} セットしたInfoWindowのオブジェクト
*/
Map.prototype.setInfoWindow = function(marker, html) {
var infoWindow = new this.engine.InfoWindow({content: html});
var _this = this;
marker.addListener('click', function () {
if(_this.currentInfoWindow) {
_this.currentInfoWindow.close();
_this.engine.event.trigger(_this.currentInfoWindow, 'closeclick');
}
infoWindow.open(this.entity, marker);
_this.currentInfoWindow = infoWindow;
});
this.infoWindows.push(infoWindow);
return infoWindow;
};
/**
* 情報ウィンドウを全て削除します。
*/
Map.prototype.destroyInfoWindow= function() {
this.infoWindows.forEach(function (infoWindow, idx) {
infoWindow.close();
});
this.currentInfoWindow = null;
this.infoWindows.clear();
};
/**
* 2点間の距離を計算します
*/
Map.prototype.calcDistance = function(lat_1, lng_1, lat_2, lng_2) {
// 測地系定数
// GRS80 ( 世界測地系 ) <- 現在の日本での標準
var RX = 6378137.000000; // 赤道半径
var RY = 6356752.314140; // 極半径
// ベッセル楕円体 ( 旧日本測地系 ) <- 以前の日本での標準
//var RX = 6377397.155000 // 赤道半径
//var RY = 6356079.000000 // 極半径
// WGS84 ( GPS ) <- Google はこの測地系
//var RX = 6378137.000000 // 赤道半径
//var RY = 6356752.314245 // 極半径
// 2点の経度の差を計算 ( ラジアン )
var a_x = lng_1 * Math.PI / 180 - lng_2 * Math.PI / 180;
// 2点の緯度の差を計算 ( ラジアン )
var a_y = lat_1 * Math.PI / 180 - lat_2 * Math.PI / 180;
// 2点の緯度の平均を計算
var p = (lat_1 * Math.PI / 180 + lat_2 * Math.PI / 180) / 2;
// 離心率を計算
var e = Math.sqrt((RX * RX - RY * RY) / (RX * RX));
// 子午線・卯酉線曲率半径の分母Wを計算
var w = Math.sqrt(1 - e * e * Math.sin(p) * Math.sin(p));
// 子午線曲率半径を計算
var m = RX * (1 - e * e) / (w * w * w);
// 卯酉線曲率半径を計算
var n = RX / w;
// 距離を計算
var d = Math.pow(a_y * m, 2) + Math.pow(a_x * n * Math.cos(p), 2);
d = Math.round(Math.sqrt(d)) / 1000;
return d;
};
/**
* マーカーのBOUNCEアニメーションを切り替えます。
* @param {google.maps.Marker} marker
* @param {boolean} doBounce
*/
Map.prototype.toggleMarkerBounce = function(marker, doBounce) {
doBounce = (typeof doBounce === 'undefined') ? (marker.getAnimation() === null) : doBounce;
if(doBounce) {
marker.setAnimation(this.engine.Animation.BOUNCE);
} else {
marker.setAnimation(null);
}
};
/**
* GoogleMapが出力するspanタグを監視・除去します。
*/
Map.prototype.removeGmapSpan = function() {
var clearDamnSpan = setInterval(function () {
$('body').children('span').each(function () {
var $this = $(this);
var text = $this.text().toLowerCase();
// spanに挿入される文字列
if(text === 'besbewy' || text === 'besbswy') {
$this.hide();
clearInterval(clearDamnSpan);
}
});
}, 500);
setTimeout(function () {
clearInterval(clearDamnSpan);
}, 50000);
}
return Map;
}) (window, jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment