LISTING PROGRAM
1.
Halaman Admin
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" itemscope itemtype="http://schema.org/Product"> <head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/> <meta itemprop="name" content="OptiMap">
<meta itemprop="description" content="Fastest roundtrip solver with ACO">
<title>SANJAYA - Ant Colony Optimazion for Google Maps API</title> <link rel="stylesheet" href="<?php echo base_url().'media/style.css'; ?>" type="text/css" media="screen">
<link rel="stylesheet" href="<?php echo base_url().'media/print.css'; ?>" type="text/css" media="print">
<link type="text/css" href="<?php echo base_url().'media/jquery-ui-1.8.16.custom.css'; ?>" rel="stylesheet" />
<script type="text/javascript" src="<?php echo base_url().'media/jquery.min.js'; ?>"></script>
<script type="text/javascript" src="<?php echo base_url().'media/jquery-ui.min.js'; ?>"></script>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript"
src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src="<?php echo base_url().'media/BpTspSolver.js'; ?>"></script>
<script type="text/javascript" src="<?php echo base_url().'media/tsp.js'; ?>"></script>
<script type="text/javascript" src="<?php echo base_url().'media/directions-export.js'; ?>"></script>
<script type="text/javascript"> </script>
<script type="text/javascript"> jQuery.noConflict();
function onBodyLoad() {
google.load("maps", "3", {callback: init, other_params:"sensor=false"});
}
function loadAtStart(lat, lng, zoom) {
var center = new google.maps.LatLng(lat, lng);
initMap(center, zoom, document.getElementById("map"));
directionsPanel = document.getElementById("my_textual_div");
tsp = new BpTspSolver(gebMap, directionsPanel); tsp.setDirectionUnits("m");
tsp.addWaypoint(new google.maps.LatLng(<?php echo "$row->lat"; ?>, <?php echo "$row->long"; ?>));
<?php }?>
google.maps.event.addListener(tsp.getGDirectionsService(), "error", function() {
alert("Request failed: " +
reasons[tsp.getGDirectionsService().getStatus().code]); });
}
function init() {
if (google.loader.ClientLocation != null) {
latLng = new
google.maps.LatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude);
loadAtStart(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude, 8);
} else {
loadAtStart(3.5855598,98.67395720000002, 14); }
}
function toggle(divId) {
var divObj = document.getElementById(divId); if (divObj.innerHTML == "") {
divObj.innerHTML = document.getElementById(divId + "_hidden").innerHTML;
document.getElementById(divId + "_hidden").innerHTML = ""; } else {
document.getElementById(divId + "_hidden").innerHTML = divObj.innerHTML;
divObj.innerHTML = ""; }
}
jQuery(function() {
jQuery( "#accordion" ).accordion({ collapsible: true,
autoHeight: false, clearStyle: true });
jQuery("input:button").button(); jQuery("#dialogProgress" ).dialog({ height: 140,
modal: true, autoOpen: false });
jQuery("#progressBar").progressbar({ value: 0 }); jQuery("#dialogTomTom" ).dialog({
height: 480, width: 640, modal: true, autoOpen: false });
jQuery("#dialogGarmin" ).dialog({ height: 480,
modal: true, autoOpen: false });
});
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script> </head>
<body onLoad="onBodyLoad()">
<h2>Ant Colony Optimization - Untuk Menentukan Jalur Terdekat</h2> <table class='mainTable'>
<tr>
<td class='left' style='vertical-align: top'> <div id="leftPanel">
<div id="accordion" style='width: 300pt'>
<h3><a href="#" class='accHeader'>Tujuan</a></h3> <div>
<form name="address" onSubmit="clickedAddAddress(); return false;">
Tambah alamat tujuan : <table>
<tr>
<td><input name="addressStr" type="text"></td>
<td><input type="button" value="Add!" onClick="clickedAddAddress()"></td>
</tr> </table> </form>
Atau <a href="#" onClick="toggle('bulkLoader'); document.listOfLocations.inputList.focus();
document.listOfLocations.inputList.select(); return false;"> Berapa Alamat or (lat, lng)</a>.
<div id="bulkLoader"></div> </div>
<h3><a href="#" class='accHeader'>Pilihan Jalur</a></h3> <div>
<form name="travelOpts">
<input id="walking" type="checkbox"/> Walking (Jalan kaki)<br>
<input id="bicycling" type="checkbox"/> Bicycling (Naik sepeda)<br>
<input id="avoidHighways" type="checkbox"/> Avoid highways (Hindari jalan raya)<br> <input id="avoidTolls" type="checkbox"/> Avoid toll roads
(Hindari jalan tol) </form>
<h3><a href="#" class='accHeader'>Export</a></h3> <div>
<div id="exportGoogle"></div> <div id="exportDataButton"></div> <div id="exportData"></div>
<div id="exportLabelButton"></div> <div id="exportLabelData"></div> <div id="exportAddrButton"></div> <div id="exportAddrData"></div> <div id="exportOrderButton"></div> <div id="exportOrderData"></div> <div id="garmin"></div>
<div id="tomtom"></div>
<div id="durations" class="pathdata"></div> <div id="durationsData"></div>
</div>
<h3><a href="#" class='accHeader'>Edit Route</a></h3> <div>
<div id="routeDrag"></div> <div id="reverseRoute"></div> </div>
<h3><a href="#" class='accHeader'>Mobile Tracking</a></h3> <div>
<input id='button3' class="calcButton" type='button' value='Lacak User' onClick='TrackMobile()'>
<input id="button1" class="calcButton" type="button" value="Hitung Perjalanan TSP" onClick="directions(0, document.forms['travelOpts'].walking.checked,
document.forms['travelOpts'].bicycling.checked, document.forms['travelOpts'].avoidHighways.checked, document.forms['travelOpts'].avoidTolls.checked)">
<input id="button2" class="calcButton" type="button" value="Hitung Perjalanan dari A - Z" onClick="directions(1, document.forms['travelOpts'].walking.checked,
document.forms['travelOpts'].bicycling.checked, document.forms['travelOpts'].avoidHighways.checked, document.forms['travelOpts'].avoidTolls.checked)"> </div>
</div>
<input id='button3' class="calcButton" type='button' value='Data Clinet' onClick="popup('<?php echo base_url() ?>adminweb/data', 'Win1', 1500, 600); return false">
<input id='button3' class="calcButton" type='button' value='Ulangi Lagi' onClick='startOver()'>
<input id='button3' class="calcButton" type='button' value='Refresh Halaman' onClick='RefreshPage()'>
<input id='button3' class="calcButton" type='button' value='Pengujian Javascript' onClick='testJS()'>
<input id='button3' class="calcButton" type='button' value='About' onClick="popup('http://www.sanjayamediatama.com/templates/default/img /index.html', 'Win1', 600, 600); return false">
<input id='button3' class="calcButton" type='button' value='Logout' onclick="window.location='<?php echo base_url() ?>adminweb/logout';"> </td>
<td class='right' style='vertical-align: top'>
<?php echo ! empty($kanan) ? $this->load->view($kanan) : ''; ?> </td>
</table>
<!-- Hidden stuff -->
<div id="bulkLoader_hidden" style="visibility: hidden;">
<form name="listOfLocations" onSubmit="clickedAddList(); return false;">
<textarea name="inputList" rows="10" cols="70">Isikan tujuan perbarisnya</textarea><br>
<input type="button" value="Tambahkan daftar Tujuan" onClick="clickedAddList()">
</form></div>
<div id="exportData_hidden" style="visibility: hidden;"></div> <div id="exportLabelData_hidden" style="visibility: hidden;"></div> <div id="exportAddrData_hidden" style="visibility: hidden;"></div> <div id="exportOrderData_hidden" style="visibility: hidden;"></div> <div id="durationsData_hidden" style="visibility: hidden;"></div> <div id="dialogProgress" title="Hitung perjalanan...">
<div id="progressBar"></div> </div>
<div id="dialogTomTom" title="Export to TomTom">
<iframe name='tomTomIFrame' style='width: 580px; height: 400px'></iframe>
</div>
<div id="dialogGarmin" title="Export to Garmin">
<iframe name='garminIFrame' style='width: 580px; height: 400px'></iframe>
</div> </body> </html>
2.
Admin Controller
<?php
class Adminweb extends CI_Controller { function __construct(){
parent::__construct();
$this->load->model('M_mobile', '', TRUE); }
function index(){
$this->load->view('loginadmin'); }
function aco(){
$this->auth->restrict_admin();
$data['mobile'] = $this->M_mobile->all_track();
$data['kanan'] = "map"; $this->load->view('adminweb',$data); }
function data(){
$data['query'] = $this->M_mobile->data_client();
$data['kanan'] = "data";
$this->load->view('adminweb',$data); }
/**
* Pindah ke halaman update */
function edit($id_client) {
$data['mobile'] = $this->M_mobile->all_track();
$client = $this->M_mobile->get_client_by_id($id_client)->row();
$data['default']['id_client'] = $client->id_client;
$data['default']['nama'] = $client->nama;
$data['default']['username'] = $client->username;
$data['default']['password'] = $client->password;
$data['default']['jenis_kelamin'] = $client->jenis_kelamin;
$data['default']['no_hp'] = $client->no_hp;
$data['default']['alamat'] = $client->alamat;
$data['default']['aktif'] = $client->aktif;
$data['default']['lat'] = $client->lat;
$data['default']['long'] = $client->long;
$data['kanan'] = "editclient"; $this->load->view('adminweb',$data); }
function proses_simpan(){
$id_client =
$this->input->post('id_client');
$password = $this->input->post('password');
if (empty($password)){ $profile = array(
'username' => $this->input->post('username'),
'nama' => $this->input->post('nama'),
'jenis_kelamin' => $this->input->post('jenis_kelamin'),
'no_hp' => $this->input->post('no_hp'),
'alamat' => $this->input->post('alamat')
); }else{
$profile = array(
'username' => $this->input->post('username'),
'password' => md5($password),
'nama' => $this->input->post('nama'),
'jenis_kelamin' => $this->input->post('jenis_kelamin'),
'no_hp' => $this->input->post('no_hp'),
'aktif' => $this->input->post('aktif'),
'alamat' =>
$this->input->post('alamat')
); }
$this->M_mobile->update_profile($id_client,$profile);
$this->session->set_flashdata('message', 'profile berhasil diupdate!'); redirect('adminweb/data');
}
/**
* Hapus data */
function hapus($id_data) {
$this->M_mobile->hapus($id_data); redirect('adminweb/data');
} /**
* Memproses login */
function proses_login() {
$username = $this->input->post('username'); $password = $this->input->post('password');
$success =
$this->auth->admin_login($username,$password); if($success) {
redirect('adminweb/aco'); }
else {
Anda salah, Atau Account anda sedang diblokir, silahkan Hubungi administrator untuk mengaktifkan kembali!!');
redirect('adminweb'); }
}
/**
* Memproses logout */
function logout() {
$this->session->sess_destroy(); redirect('adminweb', 'refresh'); }
}
3.
Halaman User
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> <head>
<!-- <script type="text/javascript" src="jquery-1.6.2.min.js"></script> -->
<script type="text/javascript" src="<?php echo base_url().'media/jquery-1.7.2.js'; ?>"></script>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style> html{
height:100%; }
body{
height:100%; }
#canvas{
height:80%; }
</style>
<title>Peta Dinamis Pertamaku</title>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCeCAhmBV1aJRpEy TpQzwZV-NS_zIfGdSE&sensor=false&language=id"></script>
<script type="text/javascript">
//Mendeklarasikan Array untuk menampung marker dan balloon yang ada sehiingga mempermudah saat memanggilnya kembali
var markers = new Array(); var infowindows = new Array();
var refreshId = setInterval(function() {
$('#tracking').fadeOut("slow").load('<?php echo base_url(); ?>index.php/tracking/proses').fadeIn("slow");
var refreshId2 = setInterval(function() {
$('#koordinat').fadeOut("slow").load('<?php echo base_url(); ?>index.php/tracking/koordinat').fadeIn("slow");
}, 1000);
var refreshId3 = setInterval(function(){
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
}, 10000);
function noLocation() {
alert("Sensor GPS tidak ditemukan"); }
function foundLocation(position) {
var lat = position.coords.latitude; var lon = position.coords.longitude;
$('#koordinat2').fadeOut("slow").html("Latitude: " + lat + "<br>Longitude: " + lon).fadeIn("slow");
var uri = "<?php echo
base_url().'index.php/tracking/simpanlokasi'; ?>"; $.ajax({
type: 'POST', async: false, dataType: "html", url: uri,
data: "lat="+lat+"&long="+lon, success: function(data) { }
}); }
/* Melakukan refresh setiap beberapa detik sekali */
var refreshId4 = setInterval(function(){updatedata();}, 12000); function updatedata(){
var lat = 0; var long = 0;
for(var i=0;i<markers.length;i++){
var uri = "<?php echo base_url().'index.php/tracking/ambildata1'; ?>";
$.ajax({
type: 'POST', async: false, dataType: "html", url: uri,
data: "id="+i,
success: function(data) { lat=data;
} });
$.ajax({
type: 'POST', async: false, dataType: "html", url: uri,
data: "id="+i,
success: function(data) { long = data;
} });
var myLatLng = new
google.maps.LatLng(lat,long);
markers[i].setPosition(myLatLng); infowindows[i].setPosition(myLatLng); }
}
function initialize(){
var myLatLng = new google.maps.LatLng(3.5674094, 98.66089480000005);
var myOptions = { zoom: 14,
center:myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP }
map = new google.maps.Map(
document.getElementById('canvas'),myOptions);
<?php foreach ($tampil->result() as $row){?> var marker= new google.maps.Marker({
position:new google.maps.LatLng(<?php echo "$row->lat"; ?>, <?php echo "$row->long"; ?>),
map:map,
title:"Saya disini <?php echo "$row->nama"; ?>"
});
marker.setIcon({ url: "http://4.bp.blogspot.com/-hNcYtcecKTs/T82Sd4ZNn7I/AAAAAAAABWc/l4P-UrOR4rg/s400/Blackberry.png", scaledSize: new google.maps.Size(30, 24) , anchor: new google.maps.Point(15, 12)});
markers.push(marker);
var infowindow= new google.maps.InfoWindow({ content:"<img
src='http://www.sanjayamediatama.com/templates/default/img/trackaco.p ng' width='100' align='left' /><?php echo ">nama <br> $row->alamat<br>HP : $row->no_hp" ?>",
size: new google.maps.Size(50,50),
position:new google.maps.LatLng(<?php echo "$row->lat"; ?>, <?php echo "$row->long"; ?>)
});
infowindow.open(map);
} </script> </head>
<div id="tracking"></div> <div id="koordinat"></div> <?php
$message = $this->session->flashdata('message');
echo $message == '' ? '' : '<p id="message" align="center">' . $message . '</p>';
?>
<body onLoad="initialize()"> <div id="canvas"></div> <div id="koordinat2"></div>
<?php echo anchor('tracking/profile', 'Edit Profile', 'title="Keluar dari Halaman"');?> | <?php echo anchor('client/logout', 'LogOut', 'title="Keluar dari Halaman"');?> </body>
</html>
4.
User Controller
<?php
class Client extends CI_Controller { function __construct(){
parent::__construct();
$this->load->model('M_mobile', '', TRUE); }
public function index() {
if($this->auth->is_logged_in() == false) {
$this->load->view('login'); }
else {
redirect('tracking'); }
}
function login(){
$this->load->view('login'); }
function daftar(){
$this->load->view('daftar'); }
function proses_daftar(){
$password = $this->input->post('password'); $username = $this->input->post('username'); if (empty($password) || empty($username)){
$this->session->set_flashdata('message', 'username atau password masih kosong!');
redirect('client/daftar'); }else{
'id_client' => $this->input->post('id_client'),
'username' => $username,
'password' => md5($password),
'nama' => $this->input->post('nama'),
'jenis_kelamin' => $this->input->post('jenis_kelamin'),
'no_hp' => $this->input->post('no_hp'),
'aktif' => $this->input->post('aktif'),
'alamat' =>
$this->input->post('alamat')
);
$this->M_mobile->tambah_client($daf);
}
$this->session->set_flashdata('message', 'data berhasil disimpan, tunggu max 2x24 jam. data akan segera diaktifkan!');
redirect('client/login');
} /**
* Memproses login */
function proses_login() {
$username = $this->input->post('username'); $password = $this->input->post('password');
$success =
$this->auth->do_login($username,$password); if($success) {
redirect('tracking'); }
else {
$this->session->set_flashdata('message', 'Maaf, username dan atau password Anda salah, Atau Account anda sedang diblokir, silahkan Hubungi administrator untuk mengaktifkan kembali!!');
redirect('client'); }
}
/**
* Memproses logout */
$this->session->sess_destroy(); redirect('client/login', 'refresh'); }
}
5.
Tracking Controller
<?php
class Tracking extends CI_Controller { function __construct(){
parent::__construct();
$this->load->model('M_mobile', '', TRUE); }
function index(){
$data['tampil'] = $this->M_mobile->get_track();
$this->load->view('track',$data); }
function profile(){
$client =
$this->M_mobile- >get_client_by_id($this->session->userdata('id_client'))->row();
$data['default']['id_client'] = $client->id_client;
$data['default']['username'] = $client->username;
$data['default']['password'] = $client->password;
$data['default']['nama'] =
$client->nama;
$data['default']['jenis_kelamin'] = $client->jenis_kelamin;
$data['default']['no_hp'] =
$client->no_hp;
$data['default']['alamat'] =
$client->alamat;
$this->load->view('profile',$data); }
function proses_simpan(){
$id_client =
$this->input->post('id_client');
$password = $this->input->post('password');
if (empty($password)){ $profile = array(
'username' => $this->input->post('username'),
'nama' => $this->input->post('nama'),
'jenis_kelamin' => $this->input->post('jenis_kelamin'),
'alamat' => $this->input->post('alamat')
); }else{
$profile = array(
'username' => $this->input->post('username'),
'password' => md5($password),
'nama' => $this->input->post('nama'),
'jenis_kelamin' => $this->input->post('jenis_kelamin'),
'no_hp' => $this->input->post('no_hp'),
'alamat' =>
$this->input->post('alamat')
); }
$this->M_mobile->update_profile($id_client,$profile);
$this->session->set_flashdata('message', 'profile berhasil diupdate!'); redirect('tracking');
}
function simpanlokasi(){
$id_client = $this->session->userdata('id_client');
$lat = $this->input->post('lat'); $long = $this->input->post('long'); $tangal = date("Y-m-d H:i:s");
$session_login = $this->session->userdata('session_id');
$latlong = array(
'id_track' => $this->input->post('id_track'),
'id_client' => $id_client,
'lat' =>
$lat,
'long' => $long,
'time' => $tangal,
'session_login' => $session_login
);
$jml =
$this->M_mobile->valid_lokasi($session_login)->num_rows(); if($jml == 0){
}
$this->M_mobile->update_lokasi($id_client,$lat,$long);
}
function ambildata1(){
$id = $this->input->post('id');
$lat = $this->M_mobile->get_LatLong($id)->row(); echo $lat->lat;
}
function ambildata2(){
$id = $this->input->post('id');
$long = $this->M_mobile->get_LatLong($id)->row(); echo $long->long;
}
function proses(){
echo "tracking location processing ..."; }
function koordinat(){
$this->load->view('koordinat'); }
}
6.
Ant Colony
(function() {
var tsp; // singleton
var gebMap; // The map DOM object
var directionsPanel; // The driving directions DOM object
var gebDirectionsResult; // The driving directions returned from GMAP API
var gebDirectionsService;
var gebGeocoder; // The geocoder for addresses
var maxTspSize = 100; // A limit on the size of the problem, mostly to save Google servers from undue load.
var maxTspBF = 0; // Max size for brute force, may seem conservative, but ma
var maxTspDynamic = 15; // Max size for brute force, may seem conservative, but many browsers have limitations on run-time.
var maxSize = 10; // Max number of waypoints in one Google driving directions request.
var maxTripSentry = 2000000000; // Approx. 63 years., this long a route should not be reached...
var avoidHighways = false; // Whether to avoid highways. False by default.
var avoidTolls = false; // Whether to avoid toll roads. False by default.
var travelMode; var distIndex;
var GEO_STATUS_MSG = new Array(); var DIR_STATUS_MSG = new Array(); var labels = new Array();
var addr = new Array(); var wpActive = new Array(); var addressRequests = 0;
var addressProcessing = false; var requestNum = 0;
var currQueueNum = 0; var wayArr;
var legsTmp; var distances; var durations; var legs; var dist; var dur; var visited; var currPath; var bestPath; var bestTrip; var nextSet; var numActive; var costForward; var costBackward; var improved = false; var chunkNode;
var okChunkNode;
var numDirectionsComputed = 0; var numDirectionsNeeded = 0; var cachedDirections = false; var requestLimitWait = 1000;
var fakeDirResult; // Object used to store travel info like travel mode etc. Needed for route renderer.
var onSolveCallback = function(){}; var onProgressCallback = null;
var originalOnFatalErrorCallback = function(tsp, errMsg) { alert("Request failed: " + errMsg); }
var onFatalErrorCallback = originalOnFatalErrorCallback; var doNotContinue = false;
var onLoadListener = null;
var onFatalErrorListener = null; var directionunits;
/* Computes a near-optimal solution to the TSP problem, * using Ant Colony Optimization and local optimization * in the form of k2-opting each candidate route.
* Run time is O(numWaves * numAnts * numActive ^ 2) for ACO * and O(numWaves * numAnts * numActive ^ 3) for rewiring? *
* if mode is 1, we start at node 0 and end at node numActive-1. */
function AntColony(mode) {
var alfa = 0.1; // Pentingnya jalan sebelumnya var beta = 2.0; // Pentingnya jangka waktu
var asymptoteFactor = 0.9; // Ketajaman dari reward sebagai solusi mendekati solusi terbaik
var pher = new Array();
var nextPher = new Array();
var prob = new Array();
var numAnts = 20; var numWaves = 20;
for (var i = 0; i < numActive; ++i) { pher[i] = new Array();
nextPher[i] = new Array(); }
for (var i = 0; i < numActive; ++i) { for (var j = 0; j < numActive; ++j) {
pher[i][j] = 1;
nextPher[i][j] = 0.0; }
}
var lastNode = 0; var startNode = 0;
var numSteps = numActive - 1; var numValidDests = numActive; if (mode == 1) {
lastNode = numActive - 1; numSteps = numActive - 2; numValidDests = numActive - 1; }
/*perhitungan ACO sesuai jumlah semut dan siklus*/ for (var wave = 0; wave < numWaves; ++wave) {
for (var ant = 0; ant < numAnts; ++ant) { var curr = startNode;
var currDist = 0;
for (var i = 0; i < numActive; ++i) { visited[i] = false;
}
currPath[0] = curr;
for (var step = 0; step < numSteps; ++step) { visited[curr] = true;
var cumProb = 0.0; /* probabiitas semut*/
for (var next = 1; next < numValidDests; ++next) {
if (!visited[next]) {
prob[next] = Math.pow(pher[curr][next], alfa) * Math.pow(dur[curr][next], 0.0 - beta);
cumProb += prob[next]; }
}
/*Mengambil bilangan random untuk menentukan kota yg akan ditempuh selanjutnya*/
var guess = Math.random() * cumProb; var nextI = -1;
for (var next = 1; next < numValidDests; ++next) {
guess -= prob[next]; if (guess < 0) {
nextI = next; break;
} } }
currDist += dur[curr][nextI]; currPath[step+1] = nextI; curr = nextI;
}
currPath[numSteps+1] = lastNode; currDist += dur[curr][lastNode]; // k2-rewire:
var lastStep = numActive; if (mode == 1) {
lastStep = numActive - 1; }
var changed = true; var i = 0;
while (changed) { changed = false;
for (; i < lastStep - 2 && !changed; ++i) { var cost =
dur[currPath[i+1]][currPath[i+2]];
var revCost =
dur[currPath[i+2]][currPath[i+1]]; var iCost = dur[currPath[i]][currPath[i+1]];
var tmp, nowCost, newCost;
for (var j = i+2; j < lastStep && !changed; ++j) {
nowCost = cost + iCost + dur[currPath[j]][currPath[j+1]];
newCost = revCost +
dur[currPath[i]][currPath[j]] + dur[currPath[i+1]][currPath[j+1]];
if (nowCost > newCost) {
currDist += newCost - nowCost; // Membalikkan ruas jalan terpisah for (var k = 0; k < Math.floor((j-i)/2); ++k) {
tmp = currPath[i+1+k];
currPath[i+1+k] = currPath[j-k]; currPath[j-k] = tmp;
}
changed = true; --i;
}
cost += dur[currPath[j]][currPath[j+1]]; revCost += dur[currPath[j+1]][currPath[j]]; }
} }
bestTrip = currDist; }
/*Local Update And Decay Pheromone*/ for (var i = 0; i <= numSteps; ++i) {
nextPher[currPath[i]][currPath[i+1]] += (bestTrip - asymptoteFactor * bestTrip) / (numAnts * (currDist - asymptoteFactor * bestTrip));
} }
/*Apply global pheromone update */ for (var i = 0; i < numActive; ++i) {
for (var j = 0; j < numActive; ++j) {
pher[i][j] = pher[i][j] * (1.0 - rho) + rho * nextPher[i][j];
nextPher[i][j] = 0.0; }
} }
}
function makeLatLng(latLng) {
return(latLng.toString().substr(1,latLng.toString().length-2)); }
function makeDirWp(latLng, address) { if (address != null && address != "")
return ({ location: address, stopover: true }); return ({ location: latLng,
stopover: true }); }
function getWayArr(curr) { var nextAbove = -1;
for (var i = curr + 1; i < waypoints.length; ++i) { if (wpActive[i]) {
if (nextAbove == -1) { nextAbove = i;
} else {
wayArr.push(makeDirWp(waypoints[i], addresses[i]));
wayArr.push(makeDirWp(waypoints[curr], addresses[curr])); }
} }
if (nextAbove != -1) {
wayArr.push(makeDirWp(waypoints[nextAbove], addresses[nextAbove]));
getWayArr(nextAbove);
wayArr.push(makeDirWp(waypoints[curr], addresses[curr])); }
}
function getDistTable(curr, currInd) { var nextAbove = -1;
var index = currInd;
for (var i = curr + 1; i < waypoints.length; ++i) { if (wpActive[i]) {
index++;
nextAbove = i; } else {
legs[currInd][index] = legsTmp[distIndex]; dist[currInd][index] = distances[distIndex]; dur[currInd][index] = durations[distIndex++]; legs[index][currInd] = legsTmp[distIndex]; dist[index][currInd] = distances[distIndex]; dur[index][currInd] = durations[distIndex++]; }
} }
if (nextAbove != -1) {
legs[currInd][currInd+1] = legsTmp[distIndex]; dist[currInd][currInd+1] = distances[distIndex]; dur[currInd][currInd+1] = durations[distIndex++]; getDistTable(nextAbove, currInd+1);
legs[currInd+1][currInd] = legsTmp[distIndex]; dist[currInd+1][currInd] = distances[distIndex]; dur[currInd+1][currInd] = durations[distIndex++]; }
}
// membuat jalur
function directions(mode) { if (cachedDirections) {
// Bypass Google directions lookup if we already have the distance and duration matrices.
// Melewati jalur pencarian arah Google jika kita sudah memiliki matriks jarak dan durasi.
doTsp(mode); }
wayArr = new Array(); numActive = 0;
numDirectionsComputed = 0;
for (var i = 0; i < waypoints.length; ++i) { if (wpActive[i]) ++numActive;
}
numDirectionsNeeded = numActive * (numActive - 1); for (var i = 0; i < waypoints.length; ++i) {
if (wpActive[i]) {
wayArr.push(makeDirWp(waypoints[i], addresses[i])); getWayArr(i);
break; } }
// Roundtrip
if (numActive > maxTspSize) {
alert("Too many locations! You have " + numActive + ", but max limit is " + maxTspSize);
} else {
legsTmp = new Array(); distances = new Array(); durations = new Array(); chunkNode = 0;
okChunkNode = 0;
if (typeof onProgressCallback == 'function') { onProgressCallback(tsp);
nextChunk(mode); }
}
function nextChunk(mode) { // alert("nextChunk"); chunkNode = okChunkNode;
if (chunkNode < wayArr.length) { var wayArrChunk = new Array();
for (var i = 0; i < maxSize && i + chunkNode < wayArr.length; ++i) {
wayArrChunk.push(wayArr[chunkNode+i]); }
var origin; var destination;
origin = wayArrChunk[0].location;
destination = wayArrChunk[wayArrChunk.length-1].location;
var wayArrChunk2 = new Array();
for (var i = 1; i < wayArrChunk.length - 1; i++) { wayArrChunk2[i-1] = wayArrChunk[i];
}
chunkNode += maxSize;
if (chunkNode < wayArr.length-1) { chunkNode--;
}
var myGebDirections = new google.maps.DirectionsService();
myGebDirections.route({ origin: origin,
destination: destination, waypoints: wayArrChunk2, avoidHighways: avoidHighways, avoidTolls: avoidTolls,
unitSystem: directionunits, travelMode: travelMode },
function(directionsResult, directionsStatus) {
if (directionsStatus == google.maps.DirectionsStatus.OK) { requestLimitWait = 1000;
//alert("Request completed!");
// Save legs, distances and durations fakeDirResult = directionsResult;
for (var i = 0; i < directionsResult.routes[0].legs.length; ++i) {
++numDirectionsComputed;
legsTmp.push(directionsResult.routes[0].legs[i]);
durations.push(directionsResult.routes[0].legs[i].duration.value);
distances.push(directionsResult.routes[0].legs[i].distance.value); }
if (typeof onProgressCallback == 'function') { onProgressCallback(tsp);
}
} else if (directionsStatus == google.maps.DirectionsStatus.OVER_QUERY_LIMIT) {
requestLimitWait *= 2;
setTimeout(function(){ nextChunk(mode) }, requestLimitWait);
} else {
var errorMsg = DIR_STATUS_MSG[directionsStatus]; var doNotContinue = true;
alert("Request failed: " + errorMsg); }
}); } else {
readyTsp(mode); }
}
function readyTsp(mode) { //alert("readyTsp");
// Get distances and durations into 2-d arrays: distIndex = 0;
legs = new Array(); dist = new Array(); dur = new Array(); numActive = 0;
for (var i = 0; i < waypoints.length; ++i) { if (wpActive[i]) {
legs.push(new Array()); dist.push(new Array()); dur.push(new Array());
addr[numActive] = addresses[i]; numActive++;
} }
for (var i = 0; i < numActive; ++i) { legs[i][i] = null;
dist[i][i] = 0; dur[i][i] = 0; }
for (var i = 0; i < waypoints.length; ++i) { if (wpActive[i]) {
getDistTable(i, 0); break;
} }
doTsp(mode); }
function doTsp(mode) { visited = new Array();
for (var i = 0; i < numActive; ++i) { visited[i] = false;
}
currPath = new Array(); bestPath = new Array(); nextSet = new Array(); bestTrip = maxTripSentry; visited[0] = true;
currPath[0] = 0;
//hanya menggunakan metode ant colony AntColony(mode);
prepareSolution(); }
// solusi akhir
function prepareSolution() { var wpIndices = new Array();
for (var i = 0; i < waypoints.length; ++i) { if (wpActive[i]) {
wpIndices.push(i); }
}
var bestPathLatLngStr = ""; var directionsResultLegs = new Array();
var directionsResultRoutes = new Array(); var directionsResultOverview = new Array();
var directionsResultBounds = new
google.maps.LatLngBounds();
for (var i = 1; i < bestPath.length; ++i) {
directionsResultLegs.push(legs[bestPath[i-1]][bestPath[i]]); }
for (var i = 0; i < bestPath.length; ++i) {
bestPathLatLngStr +=
makeLatLng(waypoints[wpIndices[bestPath[i]]]) + "\n";
directionsResultBounds.extend(waypoints[wpIndices[bestPath[i]]]);
directionsResultOverview.push(waypoints[wpIndices[bestPath[i]]]); }
directionsResultRoutes.push({ legs: directionsResultLegs,
bounds: directionsResultBounds, copyrights: "Map data ©2013 Google", overview_path: directionsResultOverview, warnings: new Array(),
});
gebDirectionsResult = fakeDirResult;
gebDirectionsResult.routes = directionsResultRoutes; if (onFatalErrorListener)
google.maps.event.removeListener(onFatalErrorListener);
onFatalErrorListener =
google.maps.event.addListener(gebDirectionsService, 'error', onFatalErrorCallback);
if (typeof onSolveCallback == 'function') { onSolveCallback(tsp);
} }
function reverseSolution() {
bestPath[i] = tmp; }
prepareSolution(); }
function reorderSolution(newOrder) {
var newBestPath = new Array(bestPath.length); for (var i = 0; i < bestPath.length; ++i) { newBestPath[i] = bestPath[newOrder[i]]; }
bestPath = newBestPath; prepareSolution(); }
function removeStop(number) {
var newBestPath = new Array(bestPath.length - 1); for (var i = 0; i < bestPath.length; ++i) {
if (i != number) {
newBestPath[i - (i > number ? 1 : 0)] = bestPath[i]; }
}
bestPath = newBestPath; prepareSolution(); }
function addWaypoint(latLng, label) { var freeInd = -1;
for (var i = 0; i < waypoints.length; ++i) { if (!wpActive[i]) {
freeInd = i; break;
} }
if (freeInd == -1) {
if (waypoints.length < maxTspSize) { waypoints.push(latLng);
labels.push(label); wpActive.push(true);
freeInd = waypoints.length-1; } else {
return(-1); }
} else {
waypoints[freeInd] = latLng; labels[freeInd] = label; wpActive[freeInd] = true; }
return(freeInd); }
function addAddress(address, label, callback) { addressProcessing = true;
gebGeocoder.geocode({ address: address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) { addressProcessing = false;
--addressRequests; ++currQueueNum;
if (results.length >= 1) {
var freeInd = addWaypoint(latLng, label); address = address.replace("'", "");
address = address.replace("\"", ""); addresses[freeInd] = address;
if (typeof callback == 'function') callback(address, latLng);
}
} else if (status ==
google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(function(){ addAddress(address, label, callback) }, 100);
} else {
--addressRequests;
alert("Failed to geocode address: " + address + ". Reason: " + GEO_STATUS_MSG[status]);
++currQueueNum;
addressProcessing = false;
if (typeof(callback) == 'function') callback(address);
} }); }
function swapWaypoints(i, j) { var tmpAddr = addresses[j]; var tmpWaypoint = waypoints[j]; var tmpActive = wpActive[j]; var tmpLabel = labels[j]; addresses[j] = addresses[i]; addresses[i] = tmpAddr; waypoints[j] = waypoints[i]; waypoints[i] = tmpWaypoint; wpActive[j] = wpActive[i]; wpActive[i] = tmpActive; labels[j] = labels[i]; labels[i] = tmpLabel; }
BpTspSolver.prototype.startOver = function() { waypoints = new Array();
addresses = new Array(); labels = new Array(); addr = new Array(); wpActive = new Array(); wayArr = new Array(); legsTmp = new Array(); distances = new Array(); durations = new Array(); legs = new Array(); dist = new Array(); dur = new Array(); visited = new Array(); currPath = new Array(); bestPath = new Array(); bestTrip = new Array(); nextSet = new Array();
travelMode = google.maps.DirectionsTravelMode.DRIVING; numActive = 0;
addressRequests = 0; addressProcessing = false; requestNum = 0;
currQueueNum = 0;
cachedDirections = false;
onSolveCallback = function(){}; onProgressCallback = null;
doNotContinue = false;
directionunits = google.maps.UnitSystem.METRIC;
GEO_STATUS_MSG[google.maps.GeocoderStatus.OK] = "Success.";
GEO_STATUS_MSG[google.maps.GeocoderStatus.INVALID_REQUEST] = "Request was invalid.";
GEO_STATUS_MSG[google.maps.GeocoderStatus.ERROR] = "There was a problem contacting the Google servers.";
GEO_STATUS_MSG[google.maps.GeocoderStatus.OVER_QUERY_LIMIT] = "The webpage has gone over the requests limit in too short a period of time.";
GEO_STATUS_MSG[google.maps.GeocoderStatus.REQUEST_DENIED] = "The webpage is not allowed to use the geocoder.";
GEO_STATUS_MSG[google.maps.GeocoderStatus.UNKNOWN_ERROR] = "A geocoding request could not be processed due to a server error. The request may succeed if you try again.";
GEO_STATUS_MSG[google.maps.GeocoderStatus.ZERO_RESULTS] = "No result was found for this GeocoderRequest.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.INVALID_REQUEST] = "The DirectionsRequest provided was invalid.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.MAX_WAYPOINTS_EXCEEDED] = "Too many DirectionsWaypoints were provided in the DirectionsRequest. The total allowed waypoints is 8, plus the origin and destination."; DIR_STATUS_MSG[google.maps.DirectionsStatus.NOT_FOUND] = "At least one of the origin, destination, or waypoints could not be geocoded.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.OK] = "The response contains a valid DirectionsResult.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.OVER_QUERY_LIMIT] = "The webpage has gone over the requests limit in too short a period of time.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.REQUEST_DENIED] = "The webpage is not allowed to use the directions service.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.UNKNOWN_ERROR] = "A directions request could not be processed due to a server error. The request may succeed if you try again.";
DIR_STATUS_MSG[google.maps.DirectionsStatus.ZERO_RESULTS] = "No route could be found between the origin and destination.";
}
/* end (edited) OptiMap code */ /* start public interface */
function BpTspSolver(map, panel, onFatalError) { if (tsp) {
alert('You can only create one BpTspSolver at a time.'); return;
}
gebMap = map; directionsPanel = panel;
gebGeocoder = new google.maps.Geocoder();
onFatalErrorCallback = onFatalError; // only for fatal errors, not geocoding errors
tsp = this; }
BpTspSolver.prototype.addAddressWithLabel = function(address, label, callback) {
++addressRequests; ++requestNum;
tsp.addAddressAgain(address, label, callback, requestNum - 1); }
BpTspSolver.prototype.addAddress = function(address, callback) { tsp.addAddressWithLabel(address, null, callback);
};
BpTspSolver.prototype.addAddressAgain = function(address, label, callback, queueNum) {
if (addressProcessing || queueNum > currQueueNum) {
setTimeout(function(){ tsp.addAddressAgain(address, label, callback, queueNum) }, 100);
return; }
addAddress(address, label, callback); };
BpTspSolver.prototype.addWaypointWithLabel = function(latLng, label, callback) {
++requestNum;
tsp.addWaypointAgain(latLng, label, callback, requestNum - 1); };
BpTspSolver.prototype.addWaypoint = function(latLng, callback) { tsp.addWaypointWithLabel(latLng, null, callback);
};
BpTspSolver.prototype.addWaypointAgain = function(latLng, label, callback, queueNum) {
if (addressProcessing || queueNum > currQueueNum) {
setTimeout(function(){ tsp.addWaypointAgain(latLng, label, callback, queueNum) }, 100);
return; }
addWaypoint(latLng, label); ++currQueueNum;
if (typeof(callback) == 'function') { callback(latLng);
} }
BpTspSolver.prototype.getWaypoints = function() { var wp = [];
for (var i = 0; i < waypoints.length; i++) { if (wpActive[i]) {
wp.push(waypoints[i]); }
}
BpTspSolver.prototype.getAddresses = function() { var addrs = [];
for (var i = 0; i < addresses.length; i++) { if (wpActive[i])
addrs.push(addresses[i]); }
return addrs; };
BpTspSolver.prototype.getLabels = function() { var labs = [];
for (var i = 0; i < labels.length; i++) { if (wpActive[i])
labs.push(labels[i]); }
return labs; };
BpTspSolver.prototype.removeWaypoint = function(latLng) { for (var i = 0; i < waypoints.length; ++i) {
if (wpActive[i] && waypoints[i].equals(latLng)) { wpActive[i] = false;
return true; }
}
return false; };
BpTspSolver.prototype.removeAddress = function(addr) { for (var i = 0; i < addresses.length; ++i) {
if (wpActive[i] && addresses[i] == addr) { wpActive[i] = false;
return true; }
}
return false; };
BpTspSolver.prototype.setAsStop = function(latLng) { var j = -1;
for (var i = waypoints.length - 1; i >= 0; --i) { if (j == -1 && wpActive[i]) {
j = i; }
if (wpActive[i] && waypoints[i].equals(latLng)) { for (var k = i; k < j; ++k) {
swapWaypoints(k, k + 1); }
break; } } }
BpTspSolver.prototype.setAsStart = function(latLng) { var j = -1;
for (var i = 0; i < waypoints.length; ++i) { if (j == -1 && wpActive[i]) {
if (wpActive[i] && waypoints[i].equals(latLng)) { for (var k = i; k > j; --k) {
swapWaypoints(k, k - 1); }
break; } } }
BpTspSolver.prototype.getGDirections = function() { return gebDirectionsResult;
};
BpTspSolver.prototype.getGDirectionsService = function() { return gebDirectionsService;
};
// Returns the order that the input locations was visited in. // getOrder()[0] is always the starting location.
// getOrder()[1] gives the first location visited, getOrder()[2] // gives the second location visited and so on.
BpTspSolver.prototype.getOrder = function() { return bestPath;
}
// Methods affecting the way driving directions are computed BpTspSolver.prototype.getAvoidHighways = function() {
return avoidHighways; }
BpTspSolver.prototype.setAvoidHighways = function(avoid) { avoidHighways = avoid;
}
BpTspSolver.prototype.getAvoidTolls = function() { return avoidTolls;
}
BpTspSolver.prototype.setAvoidTolls = function(avoid) { avoidTolls = avoid;
}
BpTspSolver.prototype.getTravelMode = function() { return travelMode;
}
BpTspSolver.prototype.setTravelMode = function(travelM) { travelMode = travelM;
}
BpTspSolver.prototype.getDurations = function() { return dur;
}
// Helper functions
BpTspSolver.prototype.getTotalDuration = function() { return gebDirections.getDuration().seconds;
}
BpTspSolver.prototype.isReady = function() { return addressRequests == 0;
};
BpTspSolver.prototype.solveRoundTrip = function(callback) { if (doNotContinue) {
alert('Cannot continue after fatal errors.'); return;
}
if (!this.isReady()) {
setTimeout(function(){ tsp.solveRoundTrip(callback) }, 20); return;
}
if (typeof callback == 'function') onSolveCallback = callback; directions(0);
};
// menghitung jarak sekali jalan
BpTspSolver.prototype.solveAtoZ = function(callback) { if (doNotContinue) {
alert('Cannot continue after fatal errors.'); return;
}
if (!this.isReady()) {
setTimeout(function(){ tsp.solveAtoZ(callback) }, 20); return;
}
if (typeof callback == 'function') onSolveCallback = callback; directions(1);
};
BpTspSolver.prototype.setDirectionUnits = function(mOrKm) { if (mOrKm == "m") {
directionunits = google.maps.UnitSystem.IMPERIAL; }
else {
directionunits = google.maps.UnitSystem.METRIC; }
}
BpTspSolver.prototype.setOnProgressCallback = function(callback) { onProgressCallback = callback;
}
BpTspSolver.prototype.getNumDirectionsComputed = function () { return numDirectionsComputed;
}
BpTspSolver.prototype.getNumDirectionsNeeded = function () { return numDirectionsNeeded;
}
reverseSolution(); }
BpTspSolver.prototype.reorderSolution = function(newOrder, callback) {
if (typeof callback == 'function') onSolveCallback = callback; reorderSolution(newOrder); }
BpTspSolver.prototype.removeStop = function(number, callback) { if (typeof callback == 'function')
onSolveCallback = callback; removeStop(number);
}
window.BpTspSolver = BpTspSolver;
})();
7.
Javascript Solver
/*
This should serve as an example on how to use the more general BpTspSolver.js
from http://code.google.com/p/google-maps-tsp-solver/ Author: Geir K. Engdahl
*/
var tsp; // The BpTspSolver object which handles the TSP computation.
var mode;
var markers = new Array(); // Need pointers to all markers to clean up.
var dirRenderer; // Need pointer to path to clean up. var base_url = "http://localhost/aco/media/iconsnew/"; /* Returns a textual representation of time in the format * "N days M hrs P min Q sec". Does not include days if * 0 days etc. Does not include seconds if time is more than * 1 hour.
*/
function formatTime(seconds) { var days;
var hours; var minutes;
days = parseInt(seconds / (24*3600)); seconds -= days * 24 * 3600;
hours = parseInt(seconds / 3600); seconds -= hours * 3600;
minutes = parseInt(seconds / 60); seconds -= minutes * 60;
var ret = ""; if (days > 0)
if (days > 0 || hours > 0) ret += hours + " jam ";
if (days > 0 || hours > 0 || minutes > 0) ret += minutes + " menit ";
if (days == 0 && hours == 0) ret += seconds + " detik"; return(ret);
}
/* Returns textual representation of distance in the format * "N km M m". Does not include km if less than 1 km. Does not * include meters if km >= 10.
*/
function formatLength(meters) {
var km = parseInt(meters / 1000); meters -= km * 1000;
var ret = ""; if (km > 0)
ret += km + " km "; if (km < 10)
ret += meters + " m"; return(ret);
}
/* Returns textual representation of distance in the format * "N.M miles".
*/
function formatLengthMiles(meters) { var sMeters = meters * 0.621371192; var miles = parseInt(sMeters / 1000);
var commaMiles = parseInt((sMeters - miles * 1000 + 50) / 100);
var ret = miles + "." + commaMiles + " miles"; return(ret);
}
/* Returns two HTML strings representing the driving directions.
* Icons match the ones shown in the map. Addresses are used * as headers where available.
* First string is suitable for use in reordering the directions.
* Second string is suitable for printed directions. */
function formatDirections(gdir, mode) { var addr = tsp.getAddresses(); var labels = tsp.getLabels(); var order = tsp.getOrder();
var retStr = "<table class='gebddir' border=0 cell-spacing=0>\n";
var dragStr = "tarik untuk merubah urutan:<br><ul class='unsortable'>";
var retArr = new Array();
for (var i = 0; i < gdir.legs.length; ++i) { var route = gdir.legs[i];
var colour = "g"; var number = i+1;
retStr += "\t<tr class='heading'><td class='heading' width=40>"
+ "<div class='centered-directions'><img src='"+base_url+"black"
+ number + ".png'></div></td>"
+ "<td class='heading'><div class='centered-directions'>";
//untuk tampilan pada menu kiri var headerStr;
if (labels[order[i]] != null && labels[order[i]] != "") {
headerStr = labels[order[i]]; } else if (addr[order[i]] != null) {
headerStr = addr[order[i]]; } else {
var prevI = (i == 0) ? gdir.legs.length - 1 : i-1;
var latLng = gdir.legs[prevI].end_location; headerStr =
gdir.legs[i].start_location.toString(); }
//menampilkan pada menu kiri
dragStr += "<li id='" + i + "' class='ui-state-" + (i ? "default" : "disabled") + "'>"
+ "<table class='dragTable'><tr><td class='left'><img src='"+base_url+"black"
+ number + ".png' /></td><td class='middle'>" + headerStr + "</td><td class='right'>"
+ (i ? "<button id='dragClose" + i + "' value='" + i + "'></button>" : "")
+ "</td></tr></table></li>"; if (i == 0) {
dragStr += "</ul><ul id='sortable'>"; }
retStr += headerStr + "</div></td></tr>\n"; for (var j = 0; j < route.steps.length; ++j) {
var classStr = "odd";
if (j % 2 == 0) classStr = "even";
retStr += "\t<tr class='text'><td class='" + classStr + "'></td>"
+ "<td class='" + classStr + "'>"
+ route.steps[j].instructions + "<div class='left-shift'>"
+ route.steps[j].distance.text + "</div></td></tr>\n";
} }
dragStr += "</ul><ul class='unsortable'>";
/*jika menggunakan pulang pergi */ if (mode == 0) {
if (labels[order[0]] != null && labels[order[0]] != "") {
headerStr = labels[order[0]]; } else if (addr[order[0]] != null) {
headerStr = addr[order[0]]; } else {
var prevI = gdir.legs.length - 1;
var latLng = gdir.legs[prevI].end_location; headerStr = latLng.toString();
}
dragStr += "<li id='" + 0 + "' class='ui-state-disabled'>"
+ "<table class='dragTable'><tr><td><img src='"+base_url+"black"
+ 1 + ".png' /></td><td>" + headerStr + "</td></tr></table></li>";
retStr += "\t<tr class='heading'><td class='heading'>"
+ "<div class='centered-directions'><img src='"+base_url+"black1.png'></div></td>"
+ "<td class='heading'>"
+ "<div class='centered-directions'>" + headerStr + "</div></td></tr>\n"; /* untuk sekali jalan */
}else if (mode == 1) { var headerStr;
if (labels[order[gdir.legs.length]] != null && labels[order[gdir.legs.length]] != "") {
headerStr = labels[order[gdir.legs.length]]; } else if (addr[order[gdir.legs.length]] == null) {
var latLng = gdir.legs[gdir.legs.length - 1].end_location;
headerStr = latLng.toString(); } else {
headerStr = addr[order[gdir.legs.length]]; }
dragStr += "<li id='" + gdir.legs.length + "' class='ui-state-disabled'>"
+ "<table class='dragTable'><tr><td><img src='"+base_url+"black"
+ (gdir.legs.length + 1) + ".png' /></td><td>" + headerStr + "</td></tr></table></li>";
retStr += "\t<tr class='heading'><td class='heading'>"
+ "<div class='centered-directions'><img src='"+base_url+"black"
+ (gdir.legs.length + 1) +
".png'></div></td>"
+ "<td class='heading'>"
+ "<div class='centered-directions'>" + headerStr + "</div></td></tr>\n"; }
retArr[1] = retStr; return(retArr); }
function createTomTomLink(gdir) { var addr = tsp.getAddresses(); var labels = tsp.getLabels(); var order = tsp.getOrder(); var addr2 = new Array(); var label2 = new Array();
for (var i = 0; i < order.length; ++i) { addr2[i] = addr[order[i]];
if (order[i] < labels.length && labels[order[i]] != null && labels[order[i]] != "")
label2[i] = labels[order[i]]; }
var itn = createTomTomItineraryItn(gdir, addr2, label2); var retStr = "<form method='GET' action='tomtom.php' target='tomTomIFrame'>\n";
retStr += "<input type='hidden' name='itn' value='" + itn + "' />\n";
retStr += "<input id='tomTomButton' class='calcButton'
type='submit' value='Send to TomTom'
onClick='jQuery(\"#dialogTomTom\").dialog(\"open\");'/>\n"; retStr += "</form>\n";
return retStr; }
function createGarminLink(gdir) { var addr = tsp.getAddresses(); var labels = tsp.getLabels(); var order = tsp.getOrder(); var addr2 = new Array(); var label2 = new Array();
for (var i = 0; i < order.length; ++i) { addr2[i] = addr[order[i]];
if (order[i] < labels.length && labels[order[i]] != null && labels[order[i]] != "")
label2[i] = labels[order[i]]; }
var gpx = createGarminGpx(gdir, addr2, label2);
var gpxWp = createGarminGpxWaypoints(gdir, addr2, label2); var retStr = "<form method='POST' action='garmin.php' target='garminIFrame'>\n";
retStr += "<input type='hidden' name='gpx' value='" + gpx + "' />\n";
retStr += "<input type='hidden' name='gpxWp' value='" + gpxWp + "' />\n";
retStr += "<input id='garminButton' class='calcButton'
type='submit' value='Send to Garmin'
onClick='jQuery(\"#dialogGarmin\").dialog(\"open\");'/>\n"; retStr += "</form>\n";
return retStr; }
function createGoogleLink(gdir) { var addr = tsp.getAddresses(); var order = tsp.getOrder();
if (i == 1) {
ret += "&daddr="; } else if (i >= 2) { ret += " to:"; }
if (addr[order[i]] != null && addr[order[i]] != "") { ret += escape(addr[order[i]]);
} else {
if (i == 0) {
ret += gdir.legs[0].start_location.toString(); } else {
ret += gdir.legs[i-1].end_location.toString(); }
} }
return ret; }
function getWindowHeight() {
if (typeof(window.innerHeight) == 'number') return window.innerHeight;
if (document.documentElement && document.documentElement.clientHeight)
return document.documentElement.clientHeight; if (document.body && document.body.clientHeight)
return document.body.clientHeight; return 800;
}
function getWindowWidth() {
if (typeof(window.innerWidth) == 'number') return window.innerWidth;
if (document.documentElement && document.documentElement.clientWidth)
return document.documentElement.clientWidth; if (document.body && document.body.clientWidth)
return document.body.clientWidth; return 1200;
}
function onProgressCallback(tsp) {
jQuery('#progressBar').progressbar('value', 100 * tsp.getNumDirectionsComputed() / tsp.getNumDirectionsNeeded());
}
function setMarkerAsStart(marker) { marker.infoWindow.close();
tsp.setAsStart(marker.getPosition()); drawMarkers(false);
}
function setMarkerAsStop(marker) { marker.infoWindow.close();
tsp.setAsStop(marker.getPosition()); drawMarkers(false);
}
marker.infoWindow.close();
tsp.removeWaypoint(marker.getPosition()); drawMarkers(false);
}
function drawMarker(latlng, addr, label, num) { var icon;
icon = new google.maps.MarkerImage(""+base_url+"red" + (num + 1) + ".png");
var marker = new google.maps.Marker({ position: latlng,
icon: icon,
title:"Mobile "+(num + 1), map: gebMap });
google.maps.event.addListener(marker, 'click', function(event) {
var addrStr = (addr == null) ? "" : addr + "<br>"; var labelStr = (label == null) ? "" : "<b>" + label + "</b><br>";
var markerInd = -1;
for (var i = 0; i < markers.length; ++i) {
if (markers[i] != null && marker.getPosition().equals(markers[i].getPosition())) {
markerInd = i; break;
} }
var infoWindow = new google.maps.InfoWindow({ content: labelStr + addrStr
+ "<a
href='javascript:setMarkerAsStart(markers[" + markerInd + "]"
+ ")'>"
+ "Set sebagai lokasi awal" + "</a><br>"
+ "<a
href='javascript:setMarkerAsStop(markers[" + markerInd + "])'>"
+ "Set sebagai lokasi akhir" + "</a><br>"
+ "<a href='javascript:removeMarker(markers[" + markerInd + "])'>"
+ "Hapus lokasi</a>",
position: marker.getPosition() }); marker.infoWindow = infoWindow;
infoWindow.open(gebMap);
// tsp.removeWaypoint(marker.getPosition()); // marker.setMap(null);
});
markers.push(marker); }
function setViewportToCover(waypoints) {
var bounds = new google.maps.LatLngBounds(); for (var i = 0; i < waypoints.length; ++i) {
bounds.extend(waypoints[i]); }
}
function initMap(center, zoom, div) { var myOptions = {
zoom: zoom, center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP };
gebMap = new google.maps.Map(div, myOptions);
google.maps.event.addListener(gebMap, "click", function(event) {
tsp.addWaypoint(event.latLng, addWaypointSuccessCallback);
}); }
function addWaypointWithLabel(latLng, label) {
tsp.addWaypointWithLabel(latLng, label, addWaypointSuccessCallbackZoom);
}
function addWaypoint(latLng) {
addWaypointWithLabel(latLng, null,
addWaypointSuccessCallbackZoom); }
function addAddressAndLabel(addr, label) {
tsp.addAddressWithLabel(addr, label,
addAddressSuccessCallbackZoom); //alert (addr);
}
function addAddress(addr) {
addAddressAndLabel(addr, null); //alert (addr);
}
function clickedAddAddress() {
addAddress(document.address.addressStr.value); }
function addAddressSuccessCallback(address, latlng) { if (latlng) {
drawMarkers(false); } else {
alert('Gagal Menemukan Lokasi : ' + address); }
}
function addAddressSuccessCallbackZoom(address, latlng) { if (latlng) {
drawMarkers(true); } else {
alert('Gagal Menemukan Lokasi: ' + address); }
}
function addWaypointSuccessCallback(latlng) { if (latlng) {
} }
function addWaypointSuccessCallbackZoom(latlng) { if (latlng) {
drawMarkers(true); }
}
function drawMarkers(updateViewport) { removeOldMarkers();
var waypoints = tsp.getWaypoints(); var addresses = tsp.getAddresses(); var labels = tsp.getLabels();
for (var i = 0; i < waypoints.length; ++i) {
drawMarker(waypoints[i], addresses[i], labels[i], i);
}
if (updateViewport) {
setViewportToCover(waypoints); }
}
function startOver() {
document.getElementById("my_textual_div").innerHTML = ""; document.getElementById("path").innerHTML = "";
var center = gebMap.getCenter(); var zoom = gebMap.getZoom(); var mapDiv = gebMap.getDiv(); initMap(center, zoom, mapDiv);
tsp.startOver(); // doesn't clearOverlays or clear the directionsPanel
}
function TrackMobile() { drawMarkers(true); }
function RefreshPage() {
javascript:location.reload(true); }
function testJS() {
alert ('javaScript berfungsi dengan baik ...'); }
function popup(url, name, width, height) {
settings=
"toolbar=yes,location=yes,directories=yes,"+ "status=no,menubar=no,scrollbars=yes,"+
"resizable=yes,width="+width+",height="+height; MyNewWindow=window.open(url,name,settings); }
function directions(m, walking, bicycling, avoidHighways, avoidTolls) {