var VtmBusStopMap = function(options) {
var self = this;
self.markers = [];
self.map = null;
self.listeners = {
departureSelected: [],
arrivalSelected: [],
};
self.ajaxObj = null;
// デフォルト値をマージ
self.options = VtmUtil.mergeObject({
id: null,
key: VTM_EKISPERT_KEY,
hidePlaceSet: false,
enabledTreasure: false,
activeCategory: '駅、バス停',
activeType: undefined,
categories: [
// categoryオブジェクトの必須項目は
// code
// name
// englishName or englishNameHtml
// iconClass
{
code: '駅、バス停',
name: 'バス停',
englishName: 'Bus Stop',
iconClass: 'fas fa-bus-alt',
},
{
code: 'レストラン、喫茶',
name: '飲食店',
englishNameHtml: 'Restaurant
/ Cafe',
iconClass: 'fas fa-utensils',
},
{
code: 'スーパー、コンビニ',
name: '店舗',
englishNameHtml: 'Supermarket /
Convenience Store',
iconClass: 'fas fa-shopping-cart',
},
{
code: '薬局',
name: '薬局',
englishNameHtml: 'Drug
Store',
iconClass: 'fas fa-pills',
},
{
code: '病院',
name: '病院',
englishName: 'Hospital',
iconClass: 'fas fa-hospital',
},
{
code: '銀行、ATM',
name: '銀行・ATM',
englishNameHtml: 'Bank
/ ATM',
iconClass: 'fas fa-yen-sign',
},
{
code: '公共施設',
name: '公共施設',
englishNameHtml: 'Public
Facility',
iconClass: 'fas fa-university',
},
{
code: '観光スポット',
name: '観光施設',
englishNameHtml: 'Tourist
Spot',
iconClass: 'fas fa-vihara',
},
],
}, options);
var template = '';
template += '
';
template += '
';
template += '
';
template += '
';
template += '
';
template += '
';
template += ' ';
self.options.categories.forEach(function(category) {
template += ' ';
if (category.nameHtml || category.name) {
template += ' ';
}
if (category.englishNameHtml || category.englishName) {
template += ' ';
}
if (category.koreanNameHtml || category.koreanName) {
template += ' ';
}
if (category.simplified_chineseNameHtml || category.simplified_chineseName) {
template += ' ';
}
if (category.traditional_chineseNameHtml || category.traditional_chineseName) {
template += ' ';
}
if (category.thaiNameHtml || category.thaiName) {
template += ' ';
}
template += ' | ';
});
template += '
';
template += ' ';
self.options.categories.forEach(function(category) {
template += ' ';
if (category.nameHtml || category.name) {
template += ' ' + (category.nameHtml || category.name) + '';
}
if (category.englishNameHtml || category.englishName) {
template += ' ' + (category.englishNameHtml || category.englishName) + '';
}
if (category.koreanNameHtml || category.koreanName) {
template += ' ' + (category.koreanNameHtml || category.koreanName) + '';
}
if (category.simplified_chineseNameHtml || category.simplified_chineseName) {
template += ' ' + (category.simplified_chineseNameHtml || category.simplified_chineseName) + '';
}
if (category.traditional_chineseNameHtml || category.traditional_chineseName) {
template += ' ' + (category.traditional_chineseNameHtml || category.traditional_chineseName) + '';
}
if (category.thaiNameHtml || category.thaiName) {
template += ' ' + (category.thaiNameHtml || category.thaiName) + '';
}
template += ' | ';
});
template += '
';
template += '
';
template += '
';
template += '
';
template += '
';
template += '
';
template += '
';
if (self.options.enabledTreasure) {
template += '
';
template += '
';
template += '
';
template += ' ';
template += '
';
template += ' ';
template += '
';
template += '
';
template += '
';
}
template += '
';
self.vm = new Vue({
el: '#' + self.options.id,
template: template,
data: {
id: self.options.id,
locating: false, // 現在地を取得中かどうか
activeCategory: self.options.activeCategory, // 選択されているカテゴリ
activeType: self.options.activeType, // 選択されているタイプ(あれば)
iconCurrentLocation: VTM_LIB_URL + 'vtmBusStopMap/iconCurrentLocation.svg',
showTextbox: true,
},
mounted: function() {
var elm = document.getElementById(self.options.id);
var $elm = $(elm);
$elm.data("self", self);
var topLeftControls = $elm.find(".topLeftControls").get(0);
var bottomRightControls = $elm.find(".bottomRightControls").get(0);
// Google Maps初期化
var gmapOptions = {
center: self.options.center || { lat: 36.70187372130401, lng: 137.21260814190376 }, // 富山駅
zoom: 14,
fullscreenControl: false,
mapTypeControl: false,
scaleControl: true,
streetViewControl: false,
};
var gmapElm = $elm.find(".gmap").get(0);
self.map = new google.maps.Map(gmapElm, gmapOptions);
if (bottomRightControls) {
self.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(bottomRightControls);
}
if (!self.options.hidePlaceSet) {
self.map.addListener("click", function(e) {
console.log(e.latLng.lat(), e.latLng.lng());
var lat = e.latLng.lat();
var lng = e.latLng.lng();
var place = {name: "選択された地点", englishName: "Selected Place", koreanName: "선택된 장소", simplified_chineseName: "所选位置", traditional_chineseName: "所選位置", thaiName: "สถานที่ที่เลือก", code: null};
self.openInfoWindow("latlng", place, lat, lng);
});
}
self.infoWindow = new google.maps.InfoWindow({ zIndex: 9999 });
self.departureInfoWindow = new google.maps.InfoWindow({ zIndex: 9999 });
self.arrivalInfoWindow = new google.maps.InfoWindow({ zIndex: 9999 });
// 駅名入力パーツ#1初期化
var stationApp1Element = document.getElementById(self.options.id + '-stationApp');
var stationApp1 = new expGuiStation(stationApp1Element);
stationApp1.setConfigure("apiURL", "https://api-toyama.vtfm.jp/");
stationApp1.setConfigure("agent", 1);
stationApp1.setConfigure("key", VTM_EKISPERT_KEY);
stationApp1.setConfigure("placeholder", "駅・バス停・施設名を入力");
stationApp1.setConfigure("gcs", "wgs84");
stationApp1.setConfigure("addGeoPoint", true);
stationApp1.setStationSort([stationApp1.createSortObject("電車", "train"), stationApp1.createSortObject("バス", "bus"), stationApp1.createSortObject("施設", "landmark")]);
// 駅名入力パーツで入力が確定されたとき呼ばれる
stationApp1.bind("change", function () {
var point = stationApp1.getPointObject(stationApp1.getStationCode());
var geoPoint = stationApp1.getStationGeoPoint();
var lat = parseFloat(geoPoint.lati_d);
var lng = parseFloat(geoPoint.longi_d);
self.map.setCenter({ lat: lat, lng: lng });
self.map.setZoom(17);
var place = {};
if (point) {
place = {name: point.name, englishName: point.name, code: point.code};
} else {
place = {name: "選択された場所", englishName: "Selected Place", code: null};
}
self.openInfoWindow("latlng", place, lat, lng);
var url = "https://api-toyama.vtfm.jp/v1/place";
var params = {
key: self.options.key,
provider: VTM_PROVIDER,
category: self.options.activeCategory,
q: self.map.getCenter().lat() + ',' + self.map.getCenter().lng(),
};
if (self.options.activeType !== undefined && self.options.activeType != "undefined") {
params.type = self.options.activeType;
}
$.getJSON(url, params)
.then(function(res) {
if (!res || !res.resultSet || !res.resultSet.places) {
console.error("レスポンス不正", res);
return;
}
res.resultSet.places.forEach(function(place) {
var a = place.location.split(",");
if (a.length != 2) {
return;
}
if (self.markers.some(function(m) { return m.title == place.name; })) {
return;
}
var lat = parseFloat(a[0]);
var lng = parseFloat(a[1]);
var marker_options = {
position: { lat: lat, lng: lng },
map: self.map,
title: place.name,
};
if (place.markerurl !== undefined && place.markerurl != "") {
marker_options.icon = {
url: VTM_LIB_URL.replace('/lib/','') + place.markerurl,
scaledSize: new google.maps.Size(31, 49)
};
}
var marker = new google.maps.Marker(marker_options);
marker.addListener("click", function() {
self.openInfoWindow("facility", place, lat, lng, marker);
});
self.markers.push(marker);
});
})
.catch(function(err) {
console.error(err);
});
});
stationApp1.dispStation();
function setPlaceholder(languageCode) {
var languageStrToLocale = {
"ja": "japanese",
"en": "english",
"ko": "korean",
"zh-cn": "simplified_chinese",
"zh-tw": "traditional_chinese",
"th": "thai",
};
stationApp1.setConfigure("language", languageStrToLocale[languageCode]);
stationApp1.setConfigure("apiParam", "language=" + languageCode + "&provider=" + encodeURIComponent(VTM_PROVIDER));
switch(languageCode) {
case "ja":
stationApp1.setConfigure("placeholder", "駅・バス停・施設名を入力");
break;
case "en":
stationApp1.setConfigure("placeholder", "Station / Bus stop / Facility name");
break;
case "ko":
stationApp1.setConfigure("placeholder", "역 / 버스 정류장 / 시설 명");
break;
case "zh-cn":
stationApp1.setConfigure("placeholder", "车站 / 巴士站 / 设施名称");
break;
case "zh-tw":
stationApp1.setConfigure("placeholder", "車站 / 巴士站 / 設施名稱");
break;
case "th":
stationApp1.setConfigure("placeholder", "สถานี / ป้ายรถเมล์ / ชื่อสถานที่");
break;
}
}
VtmCommon.addEventListener("languageChanged", function(languageCode) {
setPlaceholder(languageCode);
});
setPlaceholder(localStorage.getItem("language") || "ja");
this.showMarkers(self.options.activeCategory, self.options.activeType);
},
methods: {
/**
* 指定されたカテゴリがアクティブか判定する。
*/
isActive: function(category, type) {
if (type == 'undefined') {
return category == this.activeCategory && this.activeType === undefined;
} else {
return category == this.activeCategory && type == this.activeType;
}
},
/**
* マーカーのデータ読み込み(全件終わるまで繰り返す)
*/
loadMarkers: function(url, params, category, type, cursor) {
var thisObj = this;
if (cursor !== undefined) {
params.cursor = cursor;
} else if (self.ajaxObj != null) {
// 別カテゴリーの差分読み込み中の場合は、その処理を停止する
self.ajaxObj.abort();
}
self.ajaxObj = $.ajax({
type: 'GET',
url: url,
data: params,
dataType: 'json'
})
.done(function(res) {
if (!res || !res.resultSet || !res.resultSet.places) {
console.error("レスポンス不正", res);
return;
}
var new_cursor = res.resultSet.cursor;
res.resultSet.places.forEach(function(place) {
var a = place.location.split(",");
if (a.length != 2) {
return;
}
if (self.markers.some(function(m) { return m.title == place.name; })) {
return;
}
var lat = parseFloat(a[0]);
var lng = parseFloat(a[1]);
var marker_options = {
position: { lat: lat, lng: lng },
map: self.map,
title: place.name,
};
if (place.markerurl !== undefined && place.markerurl != "") {
marker_options.icon = {
url: VTM_LIB_URL.replace('/lib/','') + place.markerurl,
scaledSize: new google.maps.Size(31, 49)
};
}
var marker = new google.maps.Marker(marker_options);
marker.addListener("click", function() {
self.openInfoWindow("facility", place, lat, lng, marker);
});
self.markers.push(marker);
});
self.vm.activeCategory = category;
if (type !== undefined && type != "undefined") {
self.vm.activeType = type;
} else {
self.vm.activeType = undefined;
}
if (res.resultSet.places.length > 0) {
thisObj.loadMarkers(url, params, category, type, new_cursor);
}
})
.fail(function(err) {
console.log(err);
});
},
/**
* 各カテゴリのアイコンをクリックしたとき呼ばれる。
*/
showMarkers: function(category, type) {
self.markers.forEach(function(marker) {
marker.setMap(null);
});
self.markers = [];
var url = "https://api-toyama.vtfm.jp/v1/place";
var params = {
key: self.options.key,
provider: VTM_PROVIDER,
category: category,
};
if (type !== undefined && type != "undefined") {
params.type = type;
}
this.loadMarkers(url, params, category, type, undefined);
},
/**
* Map右下の現在地を取得アイコンをクリックしたとき呼ばれる。
*/
getCurrentLocation: function() {
self.vm.locating = true;
function _getCurrentLocation(onSuccess, onFailure) {
if (!navigator.geolocation) {
onFailure("この端末では位置情報が取得できません");
return;
}
navigator.geolocation.getCurrentPosition(
// 取得成功した場合
function(position) {
onSuccess(position);
},
// 取得失敗した場合
function(error) {
var msg;
switch(error.code) {
case 1: // PERMISSION_DENIED
if (location.href.indexOf("http://") >= 0) {
msg = "位置情報の利用が許可されていません。\nお使いのブラウザでは、http://のページにおいて位置情報を利用できない可能性があります。";
} else {
msg = "位置情報の利用が許可されていません";
}
break;
case 2: // POSITION_UNAVAILABLE
msg = "現在位置が取得できませんでした";
break;
case 3: // TIMEOUT
msg = "タイムアウトになりました";
break;
default:
msg = "現在位置が取得できませんでした(エラーコード: " + error.code + ")";
break;
}
onFailure(msg);
}
);
};
_getCurrentLocation(function(position) {
self.map.setCenter({ lat: position.coords.latitude, lng: position.coords.longitude });
var place = {name: "現在地", englishName: "Selected Current Location", code: null};
self.openInfoWindow("latlng", place, position.coords.latitude, position.coords.longitude, null);
self.vm.locating = false;
}, function(err) {
self.vm.locating = false;
alert(err);
});
},
},
});
};
VtmBusStopMap.prototype = {
/**
* イベントリスナー追加
*/
addEventListener: function(eventName, func) {
var self = this;
if (!self.listeners[eventName]) {
console.error("イベント名 [" + eventName + "] はサポートされていません");
return;
}
self.listeners[eventName].push(func);
},
/**
* ポップアップを開く。
* place:
* 必須 {:name, :englishName, :code}
* オプショナル {:category, :url, :comment, :address, :imageurl}
* marker, hidePlaceSetはオプショナル。
*/
openInfoWindow: function(type, place, lat, lng, marker, hidePlaceSet) {
var self = this;
// Google Mapsの中はc-lang-*が効かなかったような気がするので、この方法で言語を切り替える
var language = localStorage.getItem("language") || "ja";
switch(language) {
case "en":
var labelDeparture = "Set as From";
var labelArrival = "Set as To";
var labelTreasure = "Show details (*japanese only)";
var labelGoHere = "Go here";
var placeName = place.englishName;
if (placeName === undefined || placeName === "") {
placeName = place.name;
}
break;
case "ko":
var labelDeparture = "출발지 지정";
var labelArrival = "도착 지정";
var labelTreasure = "자세히보기 (*일본어 만)";
var labelGoHere = "여기로 이동";
var placeName = place.koreanName;
if (placeName === undefined || placeName === "") {
placeName = place.name;
}
break;
case "zh-cn":
var labelDeparture = "指定为出发地";
var labelArrival = "指定为目的地";
var labelTreasure = "查看详情 (*仅日语)";
var labelGoHere = "去这里";
var placeName = place.simplified_chineseName;
if (placeName === undefined || placeName === "") {
placeName = place.name;
}
break;
case "zh-tw":
var labelDeparture = "指定為出發地";
var labelArrival = "指定為目的地";
var labelTreasure = "查看詳細 (*僅日語)";
var labelGoHere = "去這裡";
var placeName = place.traditional_chineseName;
if (placeName === undefined || placeName === "") {
placeName = place.name;
}
break;
case "th":
var labelDeparture = "ตั้งเป็นออกเดินทาง";
var labelArrival = "กำหนดเป็นปลายทาง";
var labelTreasure = "ดูรายละเอียด (*ภาษาญี่ปุ่นเท่านั้น)";
var labelGoHere = "ไปที่นี่";
var placeName = place.thaiName;
if (placeName === undefined || placeName === "") {
placeName = place.name;
}
break;
default:
var labelDeparture = "出発地に指定";
var labelArrival = "到着地に指定";
var labelTreasure = "詳細を表示";
var labelGoHere = "ここに行く";
var placeName = place.name;
}
var html = '';
html += '';
html += '
' + placeName + '
';
html += '
';
var $html = $(html);
$html.find("a.setDeparture").click(function() {
self.listeners["departureSelected"].forEach(function(func) {
func({
type: type,
placeName: placeName,
code: place.code,
lat: lat,
lng: lng,
});
});
self.setDepartureInfoWindow(lat, lng, placeName);
self.departureInfoWindow.open(self.map);
});
$html.find("a.setArrival").click(function() {
self.listeners["arrivalSelected"].forEach(function(func) {
func({
type: type,
placeName: placeName,
code: place.code,
lat: lat,
lng: lng,
});
});
self.setArrivalInfoWindow(lat, lng, placeName);
self.arrivalInfoWindow.open(self.map);
});
$html.find("a.showTreasure").click(function() {
$("#treasureDetail_title").html('' + placeName + '');
var treasureDetailHTML = '' + placeName + '
';
treasureDetailHTML += '' + place.address + '
';
if (place.comment !== undefined && place.comment != "") {
treasureDetailHTML += '';
}
treasureDetailHTML += '';
treasureDetailHTML += '- ここに行く
';
if (place.url !== undefined && place.url != "") {
treasureDetailHTML += '- ここをもっと調べる(特典があります)
';
}
if (place.imageurl !== undefined && place.imageurl == "/treasure/joyful.jpg") {
treasureDetailHTML += '- JOYFUL CARD 協賛施設(JOYFUL CARD とは?)
';
}
treasureDetailHTML += '
';
if (place.imageurl !== undefined && place.imageurl != "") {
treasureDetailHTML += '';
}
$("#treasureDetail").html(treasureDetailHTML);
$("#treasureDetailModal").modal('show');
});
self.infoWindow.setContent($html.get(0));
self.infoWindow.setPosition({ lat: lat, lng: lng });
self.infoWindow.open(self.map, marker);
},
openInfoWindowByContent: function(lat, lng, html) {
var self = this;
self.infoWindow.setContent(html);
self.infoWindow.setPosition({ lat: lat, lng: lng });
self.infoWindow.open(self.map);
},
/**
* ポップアップを閉じる
*/
closeInfoWindow: function() {
var self = this;
self.infoWindow.close();
},
/**
* google.maps.Mapオブジェクトを返す
*/
getMap: function(latlng) {
var self = this;
return self.map;
},
/**
* 上部の「駅・バス停・施設名を入力」のテキストボックスを非表示にする
*/
hideTextbox: function() {
var self = this;
self.vm.showTextbox = false;
},
/**
* 経路探索が実行されたとき呼ばれる
*/
onArrivalStation: function(lat, lng, placeName) {
var self = this;
lat = parseFloat(lat);
lng = parseFloat(lng);
self.map.setCenter({ lat: lat, lng: lng });
self.map.setZoom(17);
// 「到着地」ウィンドウを開く
self.setArrivalInfoWindow(lat, lng, placeName, { addGoogleMapsRouteLink: true });
self.arrivalInfoWindow.open(self.map);
self.hideTextbox();
},
setCenter: function(lat, lng, zoom) {
var self = this;
self.map.setCenter({ lat: lat, lng: lng });
},
setDepartureInfoWindow: function(lat, lng, placeName) {
var self = this;
var html = '';
html += '';
html += '
' + VtmUtil.escapeHtml(placeName) + '
';
html += '
出発地From출발지出发地出發地จุดออกเดินทาง';
html += '
';
self.departureInfoWindow.setContent(html);
self.departureInfoWindow.setPosition({ lat: lat, lng: lng });
},
setArrivalInfoWindow: function(lat, lng, placeName, options) {
var self = this;
var html = '';
html += '';
html += '
' + VtmUtil.escapeHtml(placeName) + '
';
html += '
到着地To도착 지到达地到達地จุดมาถึง';
if (options && options.addGoogleMapsRouteLink) {
// Google Mapsで現在地から到着地までの経路探索するURL
var googleMapsRouteUrl = 'https://www.google.com/maps/dir/?api=1&destination=' + lat + ',' + lng;
html += '
';
}
html += '
';
self.arrivalInfoWindow.setContent(html);
self.arrivalInfoWindow.setPosition({ lat: lat, lng: lng });
},
};