OS-sw ver.: CCBot/2.0 (https://commoncrawl.org/faq/)
Login date: 21 Sep 18 - 14:48:17
IP Address: 54.166.141.69Cursore

Registrati

---------------------------------------------------------------------------------
Compatibilità software
---------------------------------------------------------------------------------



Ho testato il sistema di tracciamento solo sul mio cellulare, che è un Jolla Sailfish 2.0.2.48, ma fondamentalmente sul cell gira solo uno script sh. Più che altro la compatibilità software è da vedersi sull'app di terze parti gpscon installato dal repository non ufficiale Jolla.

---------------------------------------------------------------------------------
Prerequisiti
---------------------------------------------------------------------------------



- Un cellulare sailfish (Jolla) (?)o un sistema operativo *x con accesso root e modificabile (?)
- gpscon installato su cellulare sailfish
- wget installato su cellulare sailfish
- registrazione utente google con API key (Console API)
- Un host remoto/sito con:
    - Un db mysql
    - php installato
- nei settings del telefono impostare il GPS su "High accurancy position"

---------------------------------------------------------------------------------
Configurazione telefono
---------------------------------------------------------------------------------



Per prima cosa da shell andiamo a creare gliscript che effettueranno il rilevamento e l'invio delle coordinate.
(Per comodità io piazzo i miei script sotto la directory /opt/scripts/)


touch /opt/scripts/gpscon.sh
chmod +x /opt/scripts/gpscon.sh
touch /opt/scripts/gpscon_gen.sh
chmod +x /opt/scripts/gpscon_gen.sh

touch /opt/scripts/find_phone.sh
chmod +x /opt/scripts/find_phone.sh


di seguito gpscon.sh che sfruttando gpscon darà in output il file /tmp/gpscon.txt contenente le coordinate gps in questo formato:

Latitude: 46.5837; Longitude: 11.5155; Altitude: nan
Latitude: 46.3837; Longitude: 11.3155; Altitude: 150
Latitude: 46.3837; Longitude: 11.3155; Altitude: 200


lo script gpscon.sh in primis salva (se esiste) un precente gpscon.txt rinominandolo, esegue con utente nemo (systectl sotto jolla ha problemi con esecuzione senza shell interattiva quindi ho sfruttato su - nemo -c '/usr/bin/gpscon --posm=onlysat --sat runs=10' > /tmp/gpscon_temp.txt &) il comando gpscon che rimane attivo per 10 output di coordinate redirette in gpscon_temp.txt.  Il file conterrà:

Using 6750255 of 24 satellites
Using 0 of 24 satellites
Using 0 of 24 satellites
Using 0 of 24 satellites
Using 0 of 24 satellites
Using 0 of 24 satellites
Latitude: 46.5837; Longitude: 11.5155; Altitude: nan
Using 3 of 24 satellites
Using 3 of 24 satellites
Latitude: 46.3837; Longitude: 11.3155; Altitude: 150
Using 4 of 24 satellites
Using 4 of 24 satellites
Latitude: 46.3837; Longitude: 11.3155; Altitude: 200

Allora, la prima riga di solito è un output "sporco", con 0 satelliti collegati la coordinata risulta molto approssimativa, poi come si vede quando il gps si connette a più di 2 satelliti le coordinate sono precise.
Quindi lo script killerà il gpscon se ancora attivo dopo 100 secondi, poi nella variabile valido, lancio un altro script (inserendo il comando ho visto che con sysctl si blocca..) che esegue questo comando:
gpscon_gen.sh

#!/bin/bash
grep "Using" /tmp/gpscon_temp.txt | awk -F ' ' '$2 > 2 && $2 < 1000' |  wc -l

Il grep manda in output le righe che conengono la parola "Using" cioè quelle riferite ai satelliti connessi. "| awk -F ' ' '$2 >= 2 && $2 < 1000'" separa ogni riga in vare variabili con carattere delimitatore lo spazio. Prende la variabile 2 di ogni riga, cioè quella che contiene il numero di satelliti connessi, a questo punto il | wc -l mi restituisce il numero di righe filtrate. Nell'esempio di /tmp/gpscon_temp.txt il numero sarà 4.

Se il numero di satelliti trovati è superiore a un tot allora vado a creare il file gpscon.txt contenente solo le coordinate. Infine rimuovo il file gpscon_temp.txt.
gpscon.sh


#!/bin/bash
data=$(date +%s)
mv /tmp/gpscon.txt /tmp/gpscon_$data.txt
su - nemo -c '/usr/bin/gpscon --posm=onlysat --sat runs=10' > /tmp/gpscon_temp.txt &
sleep 100
kill -9 $(pidof gpscon)
valido=$(/opt/scripts/gpscon_gen.sh)
if [ $valido -gt 4 ]
 then
   sed '/Last login/d;/Using/d' /tmp/gpscon_temp.txt > /tmp/gpscon.txt
fi
rm /tmp/gpscon_temp.txt


Il find_phone.sh non farà altro che rilevare se siamo su una rete wifi ed in tal caso invierà le coordinate presenti nell'array coord_wifi con wget, nel caso in cui non fossimo connessi ad una rete wifi nota, avvia il servizio systemctl gpscon.service per rilevare e inviare sempre con wget le coordinate gps.
find_phone.sh

#!/bin/bash
coord_wifi=(
'casa,46.9293,12.1345'
'lavoro,42.1345,22.3333'
)
username=USERNAMEPERAGGIORNARE
password=PASSWORD
data=$(date +%s)
wifi=$(iw dev wlan0 link | grep SSID: | tr -d 'SSID: '  | xargs)
trovato=0
for coordinata in "${coord_wifi[@]}"
do
  ssid=$(echo $coordinata | cut -f1 -d ',')
  lat=$(echo $coordinata | cut -f2 -d ',')
  lon=$(echo $coordinata | cut -f3 -d ',')
  if [ "$ssid" == "$wifi" ]
  then
    echo "username=${username}&password=${password}&data=${data}&lat=${lat}&lon=${lon}"
    wget --tries=5 --no-check-certificate -qO- --post-data "username=${username}&password=${password}&data=${data}&lat=${lat}&lon=${lon}" https://www.m0220.it/findphone/aggiorna.php >/dev/null
    trovato=1
  fi
done
if [ "$wifi" == "" ] || [ $trovato -eq 0 ]
then
  systemctl start gpscon.service
  if [ -f /tmp/gpscon.txt ] && [ $(wc -l </tmp/gpscon.txt) -gt 8 ]
    then
      lat=$(tail -n 1 /tmp/gpscon.txt | tr -d ';' | cut -d ' ' -f 2)
      lon=$(tail -n 1 /tmp/gpscon.txt | tr -d ';' | cut -d ' ' -f 4)
      echo "username=${username}&password=${password}&data=${data}&lat=${lat}&lon=${lon}"
      wget --tries=5 --no-check-certificate -qO- --post-data "username=${username}&password=${password}&data=${data}&lat=${lat}&lon=${lon}" https://www.m0220.it/findphone/aggiorna.php >/dev/null
  fi
fi


Per far ciclare find_phone.sh in modo che esegua un check ogni tot minuti fare riferimento a questa guida: link articolo.
Praticamente non ho fatto altro che creare 2 servizi find_phone.service e gpscond.service un terzo di timer find_phone.timer che cicla il servizio find_phone.service ogni X minuti.

---------------------------------------------------------------------------------
Parte remota - DB
---------------------------------------------------------------------------------



Ora che abbiamo configurato la parte telefono andiamo a configurare la parte remota.
In primis il db. In mysql avrò le seguenti tabelle:

findphone
    #     Campo          Tipo     Collation             Attributi         Null   Predefinito Extra        
    1     id             int(11)                                          No     Nessuno     AUTO_INCREMENT
    2     data           int(11)                                          No     Nessuno     
    3     data1          int(11)                                          No     Nessuno    
    4     lat            text     latin1_swedish_ci                       No     Nessuno     
    5     lon            text     latin1_swedish_ci                       No     Nessuno     
    6     descrizione    text     latin1_swedish_ci                       Sì     NULL         
    7     dist_A_B       int(10)                        UNSIGNED          Sì     NULL        
findphone_users
    #     Campo         Tipo            Collation         Attributi     Null     Predefinito Extra        
    1     id            int(11)                                         No       Nessuno     AUTO_INCREMENT
    2     username      varchar(20)     latin1_swedish_ci               No       Nessuno
    3     password      varchar(60)     latin1_swedish_ci               No       Nessuno
    4     rw            tinyint(1)                                      No       Nessuno



---------------------------------------------------------------------------------
Parte remota - PHP - Connessione DB
---------------------------------------------------------------------------------



Creiamo la directory findphone o JGPStracker o con un nome a piacere e ci creiamo i seguenti files.
Configuriamo i file di connessione al db
db_con.php

<?php
$con = mysql_connect("X.X.X.X","USERNAMEDB","PASSWORDDB");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
mysql_select_db("NOMEDB", $con);
?>

---------------------------------------------------------------------------------
Parte remota - PHP - Registrazione utente
---------------------------------------------------------------------------------


Ora registriamo un primo utente modificando lo script php con le credenziali che più ci piacciono tramite
register_user.php

<?php
include('db_con.php');
ini_set ( 'display_errors', 'On' );
session_start();
$username = 'USERNAMEPERAGGIORNARE';
$password = 'PASSWORD';
$rw = 1; //livello di accesso
// $hash is what you would store in your database
$hash = password_hash($password, PASSWORD_DEFAULT);
mysql_query ("INSERT INTO findphone_users (username, password, rw) VALUES ('".$username."' , '".$hash."' , '".$rw."')");
?>

In particolare il livello di accesso l'ho impostato seguendo il seguente criterio:
0 visualizzo solo pagina demo
1 inserisco solo coordinate
2 visualizzo tutti i percorsi ma non cancello e non inserisco
3 visualizzo tutti i percorsi cancello inserisco

---------------------------------------------------------------------------------
Parte remota - PHP - Ricezione coordinate
---------------------------------------------------------------------------------


Entriamo ora nella parte più interessante, cioè nella memorizzazione delle coordinate. Ci serve un api key di google per ricavare le info di distanza fra 2 punti e la descrizione di un punto gps. Nelle parte centrale verifico se è un punto significativamente distante dal precedente (+-0,0004) e se si trova in quel range lo scarto. NB la security viene eseguita dallo stesso script in quanto è esterno alla parte di visualizzazione del sito.
aggiorna.php
<html>
<head>
<title>M0220.it - Phone tracking system</title>
<link href="/style.css" rel="stylesheet" type="text/css">
</head>
<body>

<?php
//setto l'api key, mi servirà per reperire info di distanza
$api_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
include('db_con.php');
ini_set ( 'display_errors', 'On' );
$error='';
//controllo se ci sono errori di connessione db
if (empty($_POST['username']) || empty($_POST['password'])) {
  $error = "<div align='center'><br><br><br><br>Errore, username o password non validi<br><a href='javascript:history.go(-1)'>Torna indietro</a></div>";
}
else
{
$username=$_POST['username'];
$password=$_POST['password'];
$username = stripslashes($username);
$password = stripslashes($password);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
$sql = ("SELECT * FROM findphone_users WHERE username = '".$username."' LIMIT 1");
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$hash = $row['password'];
$checked = password_verify($password, $hash);
  if (($checked) && (($row['rw'] == 1))||($row['rw'] == 3)) {
    $descrizione='';
    //se non sono presenti la longitudine e la latitudine nei valori postati esco
    if (empty($_POST['lat']) || empty($_POST['lon'])) {
      $error = "Latitudine o longitudine non presenti";
      }
    else
      {
      //seleziono l ultimo record gps inserito
      $sql = "SELECT * FROM findphone ORDER BY id DESC LIMIT 1";
      $result = mysql_query($sql);
      $row = mysql_fetch_array($result);
      //se il valore di latitudine e longitudine sono diversi dall'ultimo record inserito
/*      if (($_POST['lat'] != $row['lat']) || ($_POST['lon'] != $row['lon'])) {
        //ottengo da google la distanza fra l'ultimo record gps e quello che devo inserire*/
        $geocode=file_get_contents("https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$row['lat'].",".$row['lon']."&destinations=".$_POST['lat'].",".$_POST['lon']."&key=".$api_key);
        $output= json_decode($geocode);
        //se ok allora metto la distanza nella var dist_A_B
        if($output->status == 'OK'){
       $dist_A_B = $output->rows[0]->elements[0]->distance->value;
          }
        //rilevo il nome della via/città/nazione del record gps che devo inserire e lo metto nella var descrizione
        $geocode=file_get_contents("https://maps.googleapis.com/maps/api/geocode/json?latlng=".$_POST['lat'].",".$_POST['lon']."&key=".$api_key);
        $output= json_decode($geocode);
        if($output->status == 'OK') {
      $descrizione = $output->results[0]->formatted_address;
          }  
        //inserisco nel db i valori rilevati, se sono esterni a -0,0004+0,0004 di latitudine o longitudine, inserisco un nuovo record, altrimenti aggiorno il precedente
        if (($_POST['lat'] >= $row['lat']+0.0007) || ($_POST['lat'] <= $row['lat']-0.0007) || ($_POST['lon'] >= $row['lon']+0.0007) || ($_POST['lon'] <= $row['lon']-0.0007)) {
          echo "INSERT INTO findphone (data, data1, lat, lon, descrizione, dist_A_B) VALUES (".$_POST['data']." ,".$_POST['data']." , ".$_POST['lat']." , ".$_POST['lon']." , '".$descrizione."' , '".$dist_A_B."')";
          mysql_query("INSERT INTO findphone (data, data1, lat, lon, descrizione, dist_A_B) VALUES (".$_POST['data']." , ".$_POST['data']." , ".$_POST['lat']." , ".$_POST['lon']." , '".$descrizione."' , '".$dist_A_B."')");
          }
        else {
          echo "UPDATE findphone SET data=".$_POST['data']." , lat=".$_POST['lat']." , lon=".$_POST['lon']." , descrizione='".$descrizione."' WHERE ID=".$row['id']."";
          mysql_query("UPDATE findphone SET data=".$_POST['data']." , lat=".$_POST['lat']." , lon=".$_POST['lon']." , descrizione='".$descrizione."' WHERE ID=".$row['id']."");
          }
  /*      }*/
      }
    }
  else {
    $error = "Errore, username o password non validi";
  }
}
mysql_close($con);
echo $error;
?>

</body>
</html>

---------------------------------------------------------------------------------
Parte remota - PHP - Connessione in visualizzazione
---------------------------------------------------------------------------------


Premesso di aver creato l'utente per visualizzare il sito (vedi PHP registrazione utente, nb dare come rw 2 o 3).
Di seguito l'index php per quanto riguarda il form di input:
index.php


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
   <HEAD>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <TITLE>M0220.it - JGPStracker</TITLE>
      <link href="/style.css" rel="stylesheet" type="text/css">
   </HEAD>
   <BODY>
<?php
include('login.php'); // Includes Login Script
?>
<form action="index.php" method="post">
<table class="center_table">
<tr>
  <td>
     <label>USERNAME:</label>
  </td>
  <td>
     <input id="name" name="username" type="text">
  </td>
</tr>
<tr>
  <td>
    <label>PASSWORD:</label>
  </td>
  <td>
     <input id="password" name="password" type="password">
  </td>
</tr>
<tr>
  <td>
    <a href="https://validator.w3.org/check?uri=referer"><img
      src="https://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Strict" height="31" width="88"></a>
  </td>
  <td>
     <input name="submit" type="submit" value="LOGIN">
     <span><?php echo $error; ?></span>
  </td>
</tr>
<tr>
   <td>
   </td>
   <td>
      demo:demo per entrare in modalità demo.
   </td>
</tr>
</table>
</form>
</body>
</html>
Poi il login script per il controllo dell'utente e password e il settaggio delle variabili di sessione
login.php
<?php
include('db_con.php');
ini_set ( 'display_errors', 'On' );
session_start(); // Starting Session
$error=''; // Variable To Store Error Message


define( '_JEXEC', 1 );
define( 'DS', DIRECTORY_SEPARATOR );
define('JPATH_BASE', "../" );

require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );

$mainframe =& JFactory::getApplication('site');
$mainframe->initialise();

$session =& JFactory::getSession();
$user = $session->get( 'user' );

echo $user[0];

if (isset($_POST['submit'])) {
if (empty($_POST['username']) || empty($_POST['password'])) {
$error = "Username or Password is invalid";
}
else
{
// Define $username and $password
$username=$_POST['username'];
$password=$_POST['password'];
// To protect MySQL injection for Security purpose
$username = stripslashes($username);
$password = stripslashes($password);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
// Establishing Connection with Server by passing server_name, user_id and password as a parameter
// Selecting Database
// SQL query to fetch information of registerd users and finds user match.
$sql = ("SELECT * FROM findphone_users WHERE username = '".$username."' LIMIT 1");
//echo $sql;
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$hash = $row['password'];
//$query = mysql_query("select * from users", $connection);
$checked = password_verify($password, $hash);
if ($checked) {
// $_SESSION['rw'] 0 visualizzo solo pagina demo
// $_SESSION['rw'] 1 inserisco solo coordinate
// $_SESSION['rw'] 2 visualizzo tutti i percorsi ma non cancello e non inserisco
// $_SESSION['rw'] 3 visualizzo tutti i percorsi cancello inserisco

  $_SESSION['login_user']=$username; // Initializing Session
  $_SESSION['rw']=$row['rw'];
  if ($row['rw'] == 0) {
    header("location: findphone_demo.php");
  }
  else {
    header("location: findphone.php"); // Redirecting To Other Page
  }
}
else
  {
    $error = "Username or Password is invalid";
  }
mysql_close($con); // Closing Connection
}
}
?>

Lo script php per la sessione
session.php
<?php
include('db_con.php');
session_start();// Starting Session
// Storing Session
$user_check=$_SESSION['login_user'];
// SQL Query To Fetch Complete Information Of User
$ses_sql=mysql_query("select * from findphone_users where username='$user_check'", $con);
$row = mysql_fetch_assoc($ses_sql);
$login_session =$row['username'];
$userid_session =$row['id'];
if(!isset($login_session)){
mysql_close($con); // Closing Connection
header('Location: index.php'); // Redirecting To Home Page
}
?>

Un eventuale menu utente
menu.php
Utente:<b><i>
<?php
include('session.php');
echo $login_session;
?>
</i></b>   <a href="/logout.php">Log Out</a><br><br>
<table>
<tr>
<td colspan="3" align="center">MENU UTENTE</td>
</tr>
</table>
<link href="/style.css" rel="stylesheet" type="text/css">

Lo script di logout
logout.php
<?php
session_start();
if(session_destroy()) // Destroying All Sessions
{
header("Location: index.php"); // Redirecting To Home Page
}
?>


---------------------------------------------------------------------------------
Parte remota - PHP - Visualizzazione principale
---------------------------------------------------------------------------------


Passata la parte di login ora passiamo alla visualizzazione principale, della mappa, dei punti e del calcolo del persorso.
Questo è lo script principale, in particolare è diviso in 2 parti fondamentali, quella della mappa (java) e quello del percorso html.
findphone.php

<html>
<head>
<title>M0220.it - Phone tracking system</title>
<?php
include('menu.php');
if ($_SESSION['rw'] <= 1) {
  die("<div align='center'><br><br><br><br>Non hai i permessi<br><a href='javascript:history.go(-1)'>Torna indietro</a></div>");
}
include('db_con.php');
ini_set ( 'display_errors', 'On' );
$error='';    
//parte cancellazione record se settata la var del_id
if (isset($_GET['del_id'])){
  $sql = "DELETE FROM findphone WHERE id=".$_GET['del_id'];
  mysql_query($sql);
}
//setto il numero di markers massimi da mostrare
$num_punti = 99999;
//setto l'intervallo di tempo da mostrare, se non ho inviato nessun intervallo lo setto fra la mezzanotte di oggi e domani, e cerco tutti i record gps
if ($_POST){
  $_SESSION['timestamp1'] = strtotime($_POST['giorno']."-".$_POST['mese']."-".$_POST['anno']."00:00:00");
  $_SESSION['timestamp2'] = strtotime($_POST['giorno']."-".$_POST['mese']."-".$_POST['anno']."23:59:00");
}
//se non ho eseguito post e se non ho effettuato cancellazioni prendo data odierna, se ho effettuato cancellazioni non modifico le var globali
else if (!isset($_GET['del_id'])){
  $_SESSION['timestamp1'] = strtotime('today midnight');
  $_SESSION['timestamp2'] = strtotime('tomorrow');
}
$sql = "SELECT * FROM findphone WHERE data1 >=".$_SESSION['timestamp1']." AND data1 <".$_SESSION['timestamp2']." ORDER BY id DESC LIMIT ".$num_punti;
$result = mysql_query($sql);
//inizializzo le variabili
$percorso = "";
$pointer_percorso = "";
$i = 0;
$num_rows = mysql_num_rows($result);
//seleziono anche l'ultimo record gps del giorno precedente (-86400)
$periodo = 86400;
$sql2 = "SELECT * FROM findphone WHERE data1 >=".($_SESSION['timestamp1']-$periodo)." AND data1 <".($_SESSION['timestamp2']-$periodo)." ORDER BY id DESC LIMIT 1";
$result2 = mysql_query($sql2);
$row2 = mysql_fetch_array($result2);
$num_rows2 = mysql_num_rows($result2);
//se non trovo un ultimo record nello spazio temporale, prendo l'ultimo inserito in assoluto
if ($num_rows2 == 0){
  $sql2 = "SELECT * FROM findphone WHERE data1 <".($_SESSION['timestamp1']-$periodo)." ORDER BY id DESC LIMIT 1";
  $result2 = mysql_query($sql2);
  $row2 = mysql_fetch_array($result2);
  $num_rows2 = mysql_num_rows($result2);
  echo $num_rows2;
}
//imposto il pointer sui valori dell'ultimo record del giorno precedente (in caso non ci fossero record sarebbe lui il pointer, l'unico sulla mappa)
$pointer = "{lat: ".$row2['lat'].", lng: ".$row2['lon'];
//ciclo tutti i record gps del giorno selezionato
while($row = mysql_fetch_array($result)) {
  //se la variabile i è 0 allora significa che sono sul record gps ultimo cronologicamente di oggi e allora lo setto come pointer, sovrascrivendo quello del gg precedente
  if ($i == 0) {
    $pointer = "{lat: ".$row['lat'].", lng: ".$row['lon'];
    $i++;
  }
  //vado a ritroso costruendo i pointer del percorso e il percorso (dal piu giovane al piu vecchio)
  $pointer_percorso = $pointer_percorso.'[ "'.date("d-m-Y H:i:s", ($row['data'])).'", '.$row['lat'].', '.$row['lon'].', "'.date("d-m-Y H:i:s", ($row['data1'])).'", "'.$row['descrizione'].'" ],';
  $percorso = $percorso."{lat: ".$row['lat'].", lng: ".$row['lon']."},";
}
//aggiungo come ultimo pointer del percorso e nel percorso l'ultimo record del giorno precedente, solo se ci sono record gps della data selezionata
if (($num_rows != 0) && ($num_rows2 != 0)) {  
  $pointer_percorso = $pointer_percorso.'[ "'.date("d-m-Y H:i:s", ($row2['data'])).'", '.$row2['lat'].', '.$row2['lon'].', "'.date("d-m-Y H:i:s", ($row2['data1'])).'", "'.$row2['descrizione'].'" ]';
  $percorso = $percorso."{lat: ".$row2['lat'].", lng: ".$row2['lon']."}";
}

 
//passo tutto quello che ho crostruito a java per disegnarne la mappa
echo ('    
<style>
  #map {
    width: 100%;
    height: 300px;
  }
</style>
<br>
<div id="map"></div>
<script>
  function initMap() {
    //inizializzo le variabili myLatLng marker attuale, coordinate_polilinea e locations gli altri markers
    var markers, i;
    var myLatLng = '.$pointer.'};
    var coordinate_polilinea = ['.$percorso.'];
    var locations = ['.$pointer_percorso.'];
    var infowindow = new google.maps.InfoWindow();
    var map = new google.maps.Map(document.getElementById("map"), {zoom: 12,center: myLatLng});
    if ('.$num_rows.' > 0) {
      var marker = new google.maps.Marker({position: myLatLng,icon: "arrow.png",map: map});
    }
    else {
      var marker = new google.maps.Marker({
          position: myLatLng,
          icon: "https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=0|CCCCCC|777777",map: map}
          );
    }
    //variabili per disegnare le frecce e il colore della polilinea
    var iconsetngs = {path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW};
    var percorso_polilinea = new google.maps.Polyline({path: coordinate_polilinea,geodesic: true,strokeColor: "#777777",strokeOpacity: 1.0,strokeWeight: 1, icons: [{icon:iconsetngs, repeat :"50px"}] });
    
    //aggiungo le info quando clicco sul marker attuale, la data in questo caso
    marker.addListener("click", function() {
      infowindow.setContent(locations[0][4]+"<br />Aggiornato->"+locations[0][0]+"<br />Inserito--->"+locations[0][3]);
      infowindow.open(map, marker);
    });

    //disegno i markers se sono arrivato al marker 0, lo disegno in un altro modo
    percorso_polilinea.setMap(map);
    for (i = 1; i < locations.length; i++) {  
      var numero = '.$num_rows.' - i;
      if (numero <= 0) {
        markers = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        labelInBackground: true,
        icon: "https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + numero + "|CCCCCC|777777",map: map}
        );  
      }
      else {
        markers = new google.maps.Marker({
          position: new google.maps.LatLng(locations[i][1], locations[i][2]),
          labelInBackground: true,
          icon: "https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + numero + "|000000|FFFFFF",map: map}
        );
      }
      //aggiungo la possibilità di cliccarci su e vedere le info, la data nel nostro caso
      google.maps.event.addListener(markers, "click", (function(markers, i) {
        return function() {
          infowindow.setContent(locations[i][4]+"<br />Aggiornato->"+locations[i][0]+"<br />Inserito--->"+locations[i][3]);
          infowindow.open(map, markers);
        }
      })(markers, i));
    }

    //funzione per il calcolo approssimativo della route da un marker ad un altro
    function calculateAndDisplayRoute(directionsService, directionsDisplay, puntoA, puntoB) {
      directionsService.route({
      origin: puntoA,
      destination: puntoB,
      travelMode: "DRIVING"
      },
      function(response, status) {
        if (status === "OK") {
          directionsDisplay.setDirections(response);
        } else {
            window.alert("Directions request failed due to " + status);
        }
      });
    }
    
    //disegno il possibile percorso, attenzione google da errore oltre i 10 percorsi, quindi disegno solo gli ultimi 10 o inferiori         

    i = locations.length-1;
    if (locations.length >11) {
      i = 10;
    }
    for (i; i >= 0; i--) {
      var puntoA = locations[i][1]+","+locations[i][2];
      var puntoB = locations[i-1][1]+","+locations[i-1][2];
      var directionsService = new google.maps.DirectionsService;
      var directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers: true, preserveViewport: true});
      directionsDisplay.setMap(map)
      calculateAndDisplayRoute(directionsService, directionsDisplay, puntoA, puntoB);
    }
  }
</script>
<script async defer
   src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDmi2XDMLMc_2VNm2qjJ4_ZCZAdAT4HjA4&callback=initMap">
</script>');

//incorporo il calendario con menu a tendina
include('calendario.php');
//reinizializzo le query e le variabili per generare la cronistoria in html
$num_rows = mysql_num_rows($result);
if ($num_rows >0 ) {
  mysql_data_seek($result, 0);
  $row = mysql_fetch_array($result);
}
if ($num_rows2 >0 ) {
  mysql_data_seek($result2, 0);
  $row2 = mysql_fetch_array($result2);
}
//inizio a creare la tabella html
echo '<table width="100%" align="center"><tr><td>Marker GPS<br>------------------<br>';
//inizializzazione variabili
$numero = 0;
$tot_km_gg = 0;
//se non ci sono record gps nella query della data selezionata, mostro solo l'ultimo record di ieri che diventa marker attuale
if ($num_rows == 0) {
  //icona 0 grigia
  echo '<img style="float: left;" src="https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=0|CCCCCC|777777">';
  echo date("d-m-Y H:i:s", ($row2['data']));
  echo ( ' - <a target="_blank" href="https://www.google.com/maps/place/'.$row2['lat'].','.$row2['lon'].'">Mappa</a><br>');
  echo "<i>Inserito:".date("d-m-Y H:i:s", ($row2['data1'])).'</i><br>';
  //mostro i km del marker di ieri a 0
  echo ($row2['descrizione']."<br><b>0km</b>");
}
else {
  echo '<img style="float: left;" src="/arrow.png">';
  //altrimenti setto il numero da mostrare sui marker al numero di record trovati -1 perchè mostrerò il primo dell'elenco come marker attuale
  $numero = $num_rows -1;
  //visualizzo l'ultimo marker cronologico (marker attuale)
  echo date("d-m-Y H:i:s", ($row['data']));
  echo ( ' - <a target="_blank" href="https://www.google.com/maps/place/'.$row['lat'].','.$row['lon'].'">Mappa</a><br>');
  echo "<i>Inserito:".date("d-m-Y H:i:s", ($row['data1'])).'</i><br>';
  echo ($row['descrizione']."<br><b>".($row['dist_A_B']/1000)."km</b>  <a href='findphone.php?del_id=".$row['id']."'><img src='x.png'></a>");
  //calcolo anche il totale km
  $tot_km_gg = $tot_km_gg + ($row['dist_A_B']/1000);  
  //leggo e mostro come marker normali tutti i record dal più giovane al più vecchio
  while($row = mysql_fetch_array($result)) {
    echo '<p><img style="float: left;" src="https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld='.$numero.'|000000|FFFFFF">';
    echo date("d-m-Y H:i:s", ($row['data']));
    echo ( ' - <a target="_blank" href="https://www.google.com/maps/place/'.$row['lat'].','.$row['lon'].'">Mappa</a><br>');
    echo "<i>Inserito:".date("d-m-Y H:i:s", ($row['data1'])).'</i><br>';
    echo ($row['descrizione']."<br><b>".($row['dist_A_B']/1000)."km</b>  <a href='findphone.php?del_id=".$row['id']."'><img src='x.png'></a></p>");
    //calcolo anche il totale km
    $tot_km_gg = $tot_km_gg + ($row['dist_A_B']/1000);
    //decremento il numero da mostrare sul marker
    $numero = $numero -1;
  }
  //finito di ciclare mostro il marker di ieri (marker 0)
  echo '<p><img style="float: left;" src="https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld='.$numero.'|CCCCCC|777777">';
  echo date("d-m-Y H:i:s", ($row2['data']));
  echo ( ' - <a target="_blank" href="https://www.google.com/maps/place/'.$row2['lat'].','.$row2['lon'].'">Mappa</a><br>');
  echo "<i>Inserito:".date("d-m-Y H:i:s", ($row2['data1'])).'</i><br>';
  echo ($row2['descrizione']."<br><b>0km</b></p>");
}
echo '</td><td valign="top">';
//mostro nella colonna 2 della tabella i km totali
echo 'Totale km percorsi<br>------------------<br><b>'.$tot_km_gg.'km</b></td></tr></table>';
?>
</body>
</html>

All'interno del mio findphone.php richiamo anche un calendario da script php, di seguito lo stesso:
calendario.php

<div align="center">
<form action="findphone.php" method="POST">
<?php
if (!$_POST){
  $date=date("d-m-Y", $_SESSION['timestamp1']);}
else {
  $date=$_POST['giorno']."-".$_POST['mese']."-".$_POST['anno'];
}
$date_split= explode('-', $date);
?>

<select name="giorno">
<?php for($i=1;$i<32;$i++){?>
        <option value="<?php
           echo $i.'"';
           if ($date_split[0] == $i)
             {
             echo ' selected = "selected"';
             }

        echo '>'.$i?></option>
<?php } ?>     
</select>
<select name="mese">
<?php for($i=1;$i<13;$i++){?>
        <option value="<?php
           echo $i.'"';
           if ($date_split[1] == $i)
             {
             echo ' selected = "selected"';
             }

        echo '>'.$i?></option>
<?php } ?>     
</select>
<select name="anno">
<?php for($i=2016;$i<=date("Y");$i++){?>
        <option value="<?php
           echo $i.'"';
           if ($date_split[2] == $i)
             {
             echo ' selected = "selected"';
             }

        echo '>'.$i?></option>
<?php } ?>     
</select>
<input type="submit" value="Invia">
</form>
</div>


---------------------------------------------------------------------------------
Parte remota - PHP - Il resto
---------------------------------------------------------------------------------



Per la serie varie ed evetuali, ho piazzato un php per lo user demo:
findphone_demo.php
Copiandolo da findphone.php modificando semplicemente l'intervallo di date mettendolo fisso.
Un paio di png una per il puntatore e una per la x con la quale elimino un record:
arrow.png
x.png
Volendo anche un file di stile:
style.css
@font-face {
  font-family: 'anonregular';
  src: url('/m0220/templates/m0220/css/anonregular.ttf');
}

* {
    font-family: anonregular, courier new;
    font-size:11px;
#    background:#fff
  }

body {
    background-image:url(sfondo.jpg);
    margin:0;
    padding:0
}

#main {
width:960px;
margin:50px auto;
#font-family:raleway
}
.styled-select select {
   background: transparent;
   width: 220px;
#   padding: 5px;
   font-size:11px;
   line-height: 1;
   border: 0;
   border-radius: 0;
   height: 11px;
   -webkit-appearance: none;
   }
.styled-select {
   width: 200px;
   height: 11px;
   overflow: hidden;
   background: url(down_arrow.png) no-repeat right #fff;
   border: 1px solid #fff;
   }
green   {
color:green;
}
yellow   {
color:olive;
}
red   {
color:red;
}
img {
vertical-align: middle;
}
span {
font-size:11px;
color:red
}
h2 {
background-color:#FEFFED;
text-align:center;
border-radius:10px 10px 0 0;
margin:-10px -40px;
padding:15px
}
hr {
border:0;
border-bottom:1px solid #ccc;
margin:10px -40px;
margin-bottom:30px
}
#login {
width:70px;
height:40px;
border:2px solid #ccc;
border-radius:5px;
margin-bottom:15px
}
input[type=text],input[type=password] {
width:300px;
height:25px;
border:1px solid #000;
font-size:11px;
}
input[type=submit] {
width:70px;
height:20px;
background-color:#000;
color:#FFF;
border:1px solid #000;
font-size:11px;
cursor:pointer;
#border-radius:5px;
}
#profile {
padding:50px;
border:1px dashed grey;
font-size:20px;
background-color:#DCE6F7
}
#logout {
float:right;
padding:5px;
border:dashed 1px gray
}
a {
color:#1072cc;
font-size:11px;
cursor:pointer;
}
.testo_dx {
text-align: right;
}
td, th {
   border-left-style: dashed;
   border-left-color: black;
   border-left-width: 1px;
}
tr.border_bottom td {
  border-bottom:1pt dashed black;
}
tr.border_top td {
  border-top:1pt dashed black;
}
table {
   border: 1px solid black;
#    background-image:url(sfondo.jpg);

}
table.center_table
{
margin-left: auto;
margin-right: auto;
text-align: left;
}

Uh! finita questa fatica godiamoci il nostro tracker ovunque in giro per il mondo!

Ultimi articoli

Prev Next

Contatti

25-07-2018 Click:31

Visualizza i contatti e i riferimenti degli admin del sito.

Windows - Script batch - Check se servizio running e in caso riavvio

27-03-2018 Click:107

Di seguito un paio di scripta batch per windows che se lanci...

Windows - Script batch - Backup di cartelle/files con robocopy

27-03-2018 Click:103

Nell'esempio successivo, creeremo uno script per l'esecuzion...

Visite totali35205
Questo sito web usa i cookies per gestire alcune funzionalità, quali navigazione, autenticazione, commenti, etc. Utilizzando il nostro sito web, accetti l'utilizzo dei cookies.