Skip to content

Instantly share code, notes, and snippets.

@marucyan5821
Last active August 29, 2015 14:00
Show Gist options
  • Save marucyan5821/52c207517a1f7ba550d8 to your computer and use it in GitHub Desktop.
Save marucyan5821/52c207517a1f7ba550d8 to your computer and use it in GitHub Desktop.
Google Maps APIを用いたシンガポールの公共交通ルート案内システムの開発(現在も、改良中)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Google Maps ルート検索</title>
<style>
//マップのサイズ指定
#map_canvas {
width: 595px;
height: 500px;
float: left;
}
#container {
width: 1000px;
margin: auto;
}
#tabs {
width: 39%;
float: right;
}
.inputHintOverlay {
color: #999;
font-size: 14px;
}
</style>
<link type="text/css" href="css/excite-bike/jquery-ui-1.10.3.custom.css"rel="stylesheet" />
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDrR2yJxKS0sqi69gypoFX4ieoeuV9f0nA&sensor=false&region=SG&language=JA"></script>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script>
//Google Maps APIに必要な設定
var map;
var directionsRenderer;
var directions;
var err = google.maps.DirectionsStatus;
var directionsErr = new Array();
directionsErr[err.INVALID_REQUEST] = "指定された DirectionsRequest が無効です。";
directionsErr[err.MAX_WAYPOINTS_EXCEEDED] = "DirectionsRequest に指定された DirectionsWaypoint が多すぎます。ウェイポイントの最大許容数は 8 に出発地点と到着地点を加えた数です。";
directionsErr[err.NOT_FOUND] = "出発地点、到着地点、ウェイポイントのうち、少なくとも 1 つがジオコード化できませんでした。";
directionsErr[err.OVER_QUERY_LIMIT] = "ウェブページは、短期間にリクエストの制限回数を超えました。";
directionsErr[err.REQUEST_DENIED] = "ウェブページではルート サービスを使用できません。";
directionsErr[err.UNKNOWN_ERROR] = "サーバー エラーのため、ルート リクエストを処理できませんでした。もう一度試すと正常に処理される可能性があります。";
directionsErr[err.ZERO_RESULTS] = "出発地点と到着地点間でルートを見つけられませんでした。";
var result = google.maps.DirectionsResult;
var route = google.maps.DirectionsRoute;
//onload時の処理
function initialize() {
//Google Maps初期設定
var opts = {
zoom : 12,
center : new google.maps.LatLng(1.315154, 103.836883),
mapTypeId : google.maps.MapTypeId.TRANSIT
};
map = new google.maps.Map($("#map_canvas")[0], opts);
//Google Maps作成
//路線図レイヤー
var transitLayer = new google.maps.TransitLayer();
transitLayer.setMap(map);
//ルートレンダラ生成
directionsRenderer = new google.maps.DirectionsRenderer({
polylineOptions : {
strokeColor : '#FF0000',
strokeWeight : 6,
strokeOpacity : 1
}
});
directionsRenderer.setMap(map);
//ルートレンダラにマップを関連付け
directionsRenderer.setPanel($("#directionsPanel")[0]);
$(document).ready(function() {
$("#tabs").tabs();
$("#button").button();
$("#cost").load(data);
})
}
//検索開始
function searchRoute() {
//textboxからの値を取得
var start = $("#start").val();
var end = $("#end").val();
start = start + " station, Singapore";
end = end + " station, Singapore";
//検索設定
directions = new google.maps.DirectionsService();
//ルート生成
//ルートリクエスト
directions.route({
origin : start, //開始地点
destination : end, //終了地点
travelMode : google.maps.DirectionsTravelMode.TRANSIT, //ルートタイプ(公共交通機関)
unitSystem : google.maps.DirectionsUnitSystem.METRIC, //メートル法表示
provideRouteAlternatives : true, //複数ルートの結果を表示させる
optimizeWaypoints : true, //最適化ルートを表示
}, function(response, status) {//ルート結果コールバック関数
if (status == err.OK) {//検索結果がtrueの場合
directionsRenderer.setDirections(response);
computeTotalDistance(directionsRenderer.directions);
} else {//検索結果がfalseの場合
alert(directionsErr[status]);
}
});
}
function computeTotalDistance(result) {
//total kmの出力
var total = [];
var myroute = [];
var step = [];
var distance = [];
for ( i = 0; i < result.routes.length; i++) {
if (result.routes[i] != null) {
myroute[i] = result.routes[i];
total[i] = 0;
}
for ( j = 0; j < myroute[i].legs.length; j++) {
total[i] += myroute[i].legs[j].distance.value;
total[i] = total[i] / 1000.0;
total[i] = Math.round(total[i] * 10) / 10;
}
}
//1つのステップあたりの距離を取得
var myroutea = result.routes[0].legs[0];
for ( k = 0; k < myroutea.steps.length; k++) {
distance[k] = 0;
distance[k] = myroutea.steps[k].distance.value;
distance[k] = distance[k] / 1000.0;
distance[k] = Math.round(distance[k] * 10) / 10;
}
//totalの変数化
var $total0 = total[0];
var $total1 = total[1];
var $total2 = total[2];
var $total3 = total[3];
//各ステップの路線名を取得
//undefinedの場合は、totalから差し引く
//totalが0.0になった場合は、totalをundefinedにする。
for ( i = 0; i < myroutea.steps.length; i++) {
if (myroutea.steps[i].travel_mode == "TRANSIT") {
step[i] = myroutea.steps[i].transit.line.short_name;
} else {
step[i] = null;
$total0 = $total0 - distance[i];
}
//除外処理(セントーサ島エクスプレスでの入場の際)
if(step[i] == "SN") {
$total0 = $total0 - distance[i];
}
}
var $step0 = step[0];
var $step1 = step[1];
var $step2 = step[2];
var $step3 = step[3];
if ($total0 == 0.0) {
$total0 = undefined;
}
if ($total1 != null) {
var myrouteb = result.routes[1].legs[0];
var stepb = [];
var distanceb = [];
for ( k = 0; k < myrouteb.steps.length; k++) {
distanceb[k] = 0;
distanceb[k] = myrouteb.steps[k].distance.value;
distanceb[k] = distanceb[k] / 1000.0;
distanceb[k] = Math.round(distanceb[k] * 10) / 10;
}
for ( i = 0; i < myrouteb.steps.length; i++) {
if (myrouteb.steps[i].travel_mode == "TRANSIT") {
stepb[i] = myrouteb.steps[i].transit.line.short_name;
} else {
stepb[i] = null;
$total1 = $total1 - distanceb[i];
}
if(stepb[i] == "SN") {
$total1 = $total1 - distanceb[i];
}
}
if ($total1 == 0.0) {
$total1 = undefined;
}
var $stepb0 = stepb[0];
var $stepb1 = stepb[1];
var $stepb2 = stepb[2];
var $stepb3 = stepb[3];
}
if ($total2 != null) {
var myroutec = result.routes[2].legs[0];
var stepc = [];
var distancec = [];
for ( k = 0; k < myroutec.steps.length; k++) {
distancec[k] = 0;
distancec[k] = myroutec.steps[k].distance.value;
distancec[k] = distancec[k] / 1000.0;
distancec[k] = Math.round(distancec[k] * 10) / 10;
}
for ( i = 0; i < myroutec.steps.length; i++) {
if (myroutec.steps[i].travel_mode == "TRANSIT") {
stepc[i] = myroutec.steps[i].transit.line.short_name;
} else {
stepc[i] = null;
$total2 = $total2 - distancec[i];
}
if(stepc[i] == "SN") {
$total2 = $total2 - distancec[i];
}
}
if ($total2 == 0.0) {
$total2 = undefined;
}
var $stepc0 = stepc[0];
var $stepc1 = stepc[1];
var $stepc2 = stepc[2];
var $stepc3 = stepc[3];
}
if ($total3 != null) {
var myrouted = result.routes[3].legs[0];
var stepd = [];
var distanced = [];
for ( k = 0; k < myrouted.steps.length; k++) {
distanced[k] = 0;
distanced[k] = myrouted.steps[k].distance.value;
distanced[k] = distanced[k] / 1000.0;
distanced[k] = Math.round(distanced[k] * 10) / 10;
}
for ( i = 0; i < myrouted.steps.length; i++) {
if (myrouted.steps[i].travel_mode == "TRANSIT") {
stepd[i] = myrouted.steps[i].transit.line.short_name;
} else {
stepd[i] = null;
$total3 = $total3 - distanced[i];
}
if(stepd[i] == "SN") {
$total3 = $total3 - distanced[i];
}
}
if ($total3 == 0.0) {
$total3 = undefined;
}
var $stepd0 = stepd[0];
var $stepd1 = stepd[1];
var $stepd2 = stepd[2];
var $stepd3 = stepd[3];
}
//marina bay - bugisの運賃計算の際に、路線キロが同じための例外処理
/* for ( i = 0; i < 3; i++) {
for ( j = 1; j < 3; j++) {
if (total[i] == 3.1 && total[j] == 3.1) {
if (i == 0) {
$step0 = null;
$step1 = null;
$step2 = null;
$step3 = null;
} else if (i == 1) {
$stepb0 = null;
$stepb1 = null;
$stepb2 = null;
$stepb3 = null;
} else {
$stepc0 = null;
$stepc1 = null;
$stepc2 = null;
$stepc3 = null;
}
break;
}
}
}
*/
//AjaxでPHPにデータの送信
var data = {
step : [$step0, $step1, $step2, $step3],
total : [$total0, $total1, $total2, $total3],
stepb : [$stepb0, $stepb1, $stepb2, $stepb3],
stepc : [$stepc0, $stepc1, $stepc2, $stepc3],
stepd : [$stepd0, $stepd1, $stepd2, $stepd3],
};
$.ajaxSetup({
url : "test01.php",
global : false,
type : "POST"
});
$.ajax({
// type : "POST",
// url : "test11.php",
data : data
}).done(function(data) {
$("#cost").html(data);
$("#tabs").tabs({
active : 1
});
});
//サーチ開始処理
$(document).ready(function() {
searchRoute();
})
}
</script>
<script type="text/javascript" src="js/jquery-ui-1.10.3.custom.min.js"></script>
</head>
<body onload="initialize();">
<div id="container">
<h1>公共交通ルート案内システム シンガポール編</h1>
<p>
<div id="tabs">
<ul>
<li>
<a href="#explanation">説明</a>
</li>
<li>
<a href="#directionsPanel">ルート検索結果</a>
</li>
<li>
<a href="#costs">運賃</a>
</li>
<li>
<a href="#ez-link">EZ-Linkカード</a>
</li>
<li>
<a href="#mrt">MRTの乗り方</a>
</li>
</ul>
<div id="directionsPanel">
</div>
<div id="costs">
<span name="cost" id="cost"></span>
</div>
<div id="explanation">
ルート検索:出発駅と目的地を入力してください。検索ボタンを押すと検索結果をルート検索結果に表示します。
<br/>
<br/>
運賃表示:出発駅と目的地のルート検索結果を基に、各ルートごとの運賃を表示します。ADULTは、大人運賃、EZ-Link ADULTは、EZ-Linkカードを使用した大人運賃を指します。
なお、EZ-Linkカードについては、<u>EZ-Linkカード</u>もご覧ください。
<br/>
<br/>
セントーサ島に入島される際は、利用する交通機関により異なりますので、下記の表または、<a href="http://www.sentosa.com.sg/en/getting-to-around-sentosa/getting-to-sentosa/" target="blank">URL</a>を確認してください。
<br/>
<table border="1">
<tbody>
<tr>
<td>交通機関</td><td>入場料</td>
</tr>
<tr>
<td>セントーサ・エクスプレス</td><td>S$ 4</td>
</tr>
<tr>
<td>セントーサ・ボードウォーク</td><td>S$ 1</td>
</tr>
<tr>
<td>セントーサ・ライダー</td><td>S$ 5</td>
</tr>
</tbody>
</table>
</div>
<div id="ez-link"><img src="ezlink2.jpg">
<br/>
EZ-Linkカードは、日本でいうSuicaやPASMO,ICOCAといった交通系ICカードです。
<br/>
MRTのほか、バスでも利用でき、MRTのTicket Officeや、セブンイレブンで購入ができます。
<br/>
<br/>
購入額のうち、S$5は、カードのデポジットで、残りの額が、利用可能額となります。
<br/>
<br/>
MRTでは、カード残高が<u>S$3以下</u>であると、チャージ(Top Up)してくださいと改札機のディスプレイに表示されるので、券売機でチャージする必要があります。
<br/>
<br/>
<a href="http://www.geocities.jp/mankitsujutsu/trans_007.htm" target="blank">こちら</a>も併せてご覧ください。
</div>
<div id="mrt">
券売機にてチケットを最初に購入する際、大人運賃に加え、下記のICカードデポジットの<u>$1</u>が必要となります。
<br/>
<img src="standard2.jpg">
<br/>
このICカードは、毎回情報を書き換えて利用することができます。
<br/>
なお、このICカードは、券売機に返却すると、<u>$1</u>が返却されます。
<br/>
<br/>
MRTでは、<b><u>飲食禁止</u></b>です。飲食すると罰金が科せられます。
<br/>
また、スーパーなどで販売されている<B><u>ドリアン</u></B>は、持ち込み禁止となっております。
<br/>
</div>
</div>
テキストフィールドに出発地と目的地を入力すると、ルート検索を行います。
</p>
<p id ="form">
出発駅:
<input type="text" name="start" id="start" size="20" maxlength="150">
&nbsp;目的地:
<input type="text" name="end" id="end" size="20" maxlength="150">
&nbsp;
<input type="submit" id = "button" value="検索" onclick="searchRoute()"/>
</p>
<div id="map_canvas"></div>
</div>
</body>
</html>
<?php
include("connect.php");
//header("Content-type: application/x-javascript");
//Ajaxからデータの取得
if(isset($_POST['total'])){
$total = $_POST['total'];
}
if(isset($_POST['step'])){
$step = $_POST['step'];
}
if(isset($_POST['stepb'])){
$stepb =$_POST['stepb'];
}
if(isset($_POST['stepc'])){
$stepc =$_POST['stepc'];
}
if(isset($_POST['stepd'])){
$stepd =$_POST['stepd'];
}
error_reporting(0);
//ループ処理による運賃を実施するため、小数点以下と整数を分離
for($k=0; $k<count($total); $k++){
$total_a = floor($total[$k]);
$total_b = $total[$k] - $total_a;
//路線の判別(料金体系が異なるため)
if($k == 0){
for($i=0; $i<4; $i++){
switch($i){
case in_array("NE",array_keys($step)):
case in_array("CC",array_keys($step)):
case in_array("CE",array_keys($step)):
case in_array("DT",array_keys($step)):
$c ="1";
break;
default:
$c ="0";
}
}
}
if($k == 1){
for($i=0; $i<4; $i++){
switch($i){
case in_array("NE",array_keys($stepb)):
case in_array("CC",array_keys($stepb)):
case in_array("CE",array_keys($stepb)):
case in_array("DT",array_keys($stepb)):
$c ="1";
break;
default:
$c ="0";
}
}
}
if($k == 2){
for($i=0; $i<4; $i++){
switch($i){
case in_array("NE",array_keys($stepc)):
case in_array("CC",array_keys($stepc)):
case in_array("CE",array_keys($stepc)):
case in_array("DT",array_keys($stepc)):
$c ="1";
break;
default:
$c ="0";
}
}
}
if($k == 3){
for($i=0; $i<4; $i++){
switch($i){
case in_array("NE",array_keys($stepd)):
case in_array("CC",array_keys($stepd)):
case in_array("CE",array_keys($stepd)):
case in_array("DT",array_keys($stepd)):
break;
default:
$c ="0";
}
}
}
//路線Bによる路線キロデータの計算
if($c == "1"){
$sql = 'SELECT cash, adult FROM mrtb, kmb WHERE kmb.a = :total_cc and kmb.id = mrtb.id';
if($total_a <= 3){
if($total_a < 1){
$total_a = 0;
}else if($total_a = 3){
if($total_b >= 0.3){
$total_a= $total_a + 0.3;
}else{
$total_a = 2.1;
}
}else if($total_b >= 0.1){
$total_b= $total_a + 0.1;
}else{
$total_a = ($total_a - 1) + 0.1;
}
}else if($total_a >= 40){
if($total_a >= 41){
$total_a = 40.3;
if($total_a = 40 && $total_b <= 0.2){
$total_a = 39.3;
}else{
$total_a = 40.3;
}
}
}else if($total_b <= 0.2){
$total_a = ($total_a - 1) + 0.3;
}else{
$total_a = $total_a + 0.3;
}
}else{
//路線Aによる路線データの計算
$sql = 'SELECT cash, adult FROM mrta, kma WHERE kma.a = :total_cc and kma.id = mrta.id';
if($total_a <= 3){
if($total_a = 3){
if($total_b >= 0.3){
$total_a= 3.3;
}else{
$total_a= 0;
}
}else{
$total_a = 0;
}
}else if($total_a >= 40){
if($total_a >= 41){
$total_a = 40.3;
if($total_a = 40 && $total_b <= 0.2){
$total_a = 39.3;
}else{
$total_a = 40.3;
}
}
}else if($total_b <= 0.3){
$total_a = ($total_a - 1) + 0.3;
}else{
$total_a = $total_a + 0.3;
}
}
//計算した路線結果を格納
$total_c = strval($total_a);
$rows="";
//SQLにアクセス、結果の表示
try{
$result = $conn -> prepare($sql);
$result ->bindParam(':total_cc',$total_c);
$result -> execute();
while($r = $result -> fetch()){
$cash = $r['cash'] / 100;
$adult = $r['adult'] / 100;
$k = $k + 1;
$rows .="<tr><td>Route {$k}</td><td>S$ {$cash}</td><td>S$ {$adult}</td></tr>";
if($k == 1){
echo "<table border='1'><tbody><tr><th width='100'></th><th width='100'>CASH</th><th width='100'>EZ-LINK ADULT</th></tr>";
}
echo $rows;
if($k == max($total)){
echo "</tbody></table>";
}
$k = $k - 1;
}
}catch(Exception $e){
$conn = null;
die($e -> getMessage());
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment