• Tidak ada hasil yang ditemukan

Implementasi Mobile Tracking Menggunakan Metode Ant Colony Optimization Dan Google Maps Api

N/A
N/A
Protected

Academic year: 2019

Membagikan "Implementasi Mobile Tracking Menggunakan Metode Ant Colony Optimization Dan Google Maps Api"

Copied!
48
0
0

Teks penuh

(1)

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");

(2)

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,

(3)

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>

(4)

<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>

(5)

</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(){

(6)

$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'),

(7)

'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 {

(8)

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");

(9)

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;

} });

(10)

$.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);

(11)

} </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{

(12)

'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 */

(13)

$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'),

(14)

'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){

(15)

}

$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;

(16)

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

(17)

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) {

(18)

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]]; }

} }

(19)

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++;

(20)

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);

(21)

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);

}

(22)

} 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;

(23)

//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() {

(24)

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) {

(25)

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;

(26)

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();

(27)

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]); }

}

(28)

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]) {

(29)

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;

}

(30)

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;

}

(31)

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)

(32)

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;

(33)

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) {

(34)

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"; }

(35)

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();

(36)

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);

}

(37)

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]); }

(38)

}

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) {

(39)

} }

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) {

Referensi

Dokumen terkait

ALIRAN DAYA OPTIMAL MENGGUNAKAN ANT COLONY OPTIMIZATION (ACO) DAN MEMPERTIMBANGKAN BIAYA PEMBANGKITAN PADA SISTEM TRANSMISI 500 KV JAWA- BALI” beserta seluruh

Algoritma gabungan Ant Colony Optimization dan Tabu Search (ACOTS) dapat berjalan pada Vehicle Routing Problem with Time Windows (VRPTW).. Dibuktikan dengan hasil

Dari hasil pengujian terhadap sistem IEEE 26 bus di atas dapat ditarik suatu kesimpulan bahwa metoda Ant Colony Optimization mampu menghasilkan biaya pembangkitan yang

Implementasi metode Ant Colony Optimization (ACO) dan Simple Additive Weighting (SAW) pada layanan Telkom Trouble Ticket Online (T3-Online) menghasilkan sebuah sistem yang

Dengan ini saya menyatakan bahwa Tugas Akhir dengan judul “ IMPLEMENTASI ALGORITMA ACO (ANT COLONY OPTIMIZATION) UNTUK OPTIMASI PENCARIAN WEB CONTENT ”

HASIL DAN PEMBAHASAN Solusi Multiple Traveling Salesman Problem menggunakan Algoritma ant colony optimization dengan operasi elitism ini dikembangkan menggunakan bahasa pemrograman

Name of Figure Page Figure 3.1 Design Approach for the algorithm 11 Figure 4.1 Illustrates the interface part of ant colony optimization algorithm for traveler’s route in Thailand

Pencarian Rute Tercepat Mobil Ambulance Menggunakan Algoritma Ant Colony Optimization Angga Eka Prasetya Fakultas Industri Kreatif dan Telematika, Teknik Informatika, Universitas