<html>
<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<body>
<img id="unlike" width:20px height:20px src="https://image.flaticon.com/icons/svg/1142/1142213.svg" width="20px" height="20px" value="0" onclick="toggle()" />
</body>
<script>
function toggle()
{
var val = document.getElementById("unlike").getAttribute('value')
console.log(val)
if(val==0)
{
console.log("yyy")
$("#unlike").attr("src","https://image.flaticon.com/icons/svg/1142/1142131.svg")
$("#unlike").attr("value","1")
}
else
{
console.log("nnn")
$("#unlike").attr("src","https://image.flaticon.com/icons/svg/1142/1142213.svg")
$("#unlike").attr("value","0")
}
}
</script>
</html>
index.html
<!-- firebase Login-->
<script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase-database.js"></script>
add login button
// Google 登入按鈕 //
var customControl3 = L.Control.extend({
options: {
position: 'topleft'
},
onAdd: function(map) {
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
container.style.backgroundColor = 'white';
container.style.backgroundImage = "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAABgFBMVEX////qQjU0qFNChvX6vAX//v8/hfZRjvX///38//85gfOYt/j///ymwvn//f////s0qVLrQjP4uAD/vADqPS/pQjf5vQP3uADvQDXsQTjqPi375+Q0qFjoMCDqQzHnRDT7tQDqNSfoOCD3ysj+/PP6wgD87cUxfPQQoT7y9v0no0hCgv03noLy+vIkpUz/9fL1trP0pqLzl5Lxg3rtcmnwY1jtVEj1sqn5xcX739vscGHmLAz85OXxeXLvm5Lxh3/vWk/vf2/vq53xnZj81dTjOBTykIv4zMvuY1X1tbXymxn85afqTyrmPDvuaifzixb7xy74pgzsXSj20Fzxeh/63ZL/5rX60XD836D+ykToYyH++ef40aOlyPXb5vrE1/t+qPVkm/b79tnd3aBnqjlTtHfduBJUk/G2tB+a0aWArzRUqEXD5MzMtRyZsSzd8OC74MdZtnGTzaHEtiOAr/V1wYMglm8/jNQ4lKw4o1w7kL84m5g3omg/iNuCyJWw0+P/W6tqAAATN0lEQVR4nO1di3/TRrYeOx5nxgjLsi3jl+w4IcQRtZxQEpK4QLoEeluWXXZZKCzLo9wCTcnWdm5zt9xts//6PUd2ArFke/S03R8fjyYUJH867zNnRoR8wid8wu8ejBDKOE8ydvpHlBIG3/Ik4RP8YD6CMUokCf97CvgaeMvmlzMPoIKiOpEWpwP/nybp4B/NEExatFlaWlu/8vnVjc1KpVjTarWiurlx9fqVW9e2tptJTsiMKaspM/wNPnhp+9qdHVVrAataNptVlEgPigLfFWu12y2tsvH5+tIXoMNgm4TJnHMmJSfNYQxM0+Js+9r1TRBYMR+JqJERKGZryPPGUhP/sXTydKYbwG6nqNVAZopajUQK+WHsCiBOpA9/oaYtbl7ZaqIsiTxpAqPRXLpZadWyFRBdARUSflRHiLAKjyGiVpVqVS0Utds710qTJmALyimj8BPoXV/UisoIRmMAKru7DiQ5+Fw2VQ4IYjrnX31ZXMyCzo2S2XhUFrWNa02wx2kKlejyS+tVLZvPg015Y1jNoyQXP9/jZIoocrJ3XaspVfCao61OBKjjilLTdremImr00s2t3ZZHWjZEK1plvYnxUZ6kLJGgtLapKVUP3mUIQ3CxtewNNMgJx8c1ZbGoKpGhMc81Q/hVydcWb8mTTOoY36pqFfw8hYrfDMGmK5AwqFrx2gSYSZSRpAz+ZVfzXTsHAfZYXSKmYw3RHhmkx4yXvmxlK4EzhKxObV0tQTkZZgaA6Qv5g5a9p3gNDUIUIXdtrYMYQ8xXIYPZ3qzlzaQzaBSr4FbVvLa7TUKKj5CCQn1zJXgDHECldQs7PCHYIgVz2FZrIajnWeSr2u4XobQDgOANTVFHVrVBQCnki9rXYfhT3tzQImrwPnQQKkRcRbseNEPKyVJN8T+6C6JQKW6WoHYEewxIW7lMrmhZNXT5nTIsQPxfwkZHYB1IdnUxkldCt8ETVNC/aTdQfgExLKlFoFeYnAyrSgEoXg9GRZMS2budnRS3M6htXAyCIyNbrbznAt4fFDebATDk661eE2UakK36L0R+5bYpwKkQYr7yhWWFxyMYualNmlYf1Xw1my35TpDfXJw0sxPkI0Ug6Htqcyf0UmIoqkWl5PvqDZ8ighFQUaBHJf/oQbV0Y1psUA3GBsm6/+1el+jZoO8VFAb6KUG1WAEb9LtDvNeajhiI6Nmgn4tSUIWVbk+JBAOKg4xVs1MiwrwCNui7CVKyk52WXLRngz4TJOTWInYspkKI2SLaIPExDuLYx5LHQJhXoFxWsCdQydY0TVusFZWqomThSxzVqOAKmiLwBFUlCBuE6zUXi3lPHYuqqlbVSHaxld24ub62vV1qNpsy/CqV9pau3bmqtrQi1tRjGSoKpGq+r8zA5TayEW89mUIeRKfeWSv1a3L08+awVP8ZNr+6tVMzh4rGPCkz2fbbCBm/pfW6lK6R1Wo7ayWTEQU+EHv6Y4nm5fF7oCp9daeiFcdcCCXoaxxkEnyibffpdgElX9N21prjS3GcW9y7WdQiSl5V8tYJsX4u6vOqDKVUYir2tdxBySuLxRslc0xN5G6cSGu7IMiCWrHc08xF/V8dlSm/UvPQ+V1U1/qeXeiTUVzu2bsKHKsWr9OPg74bIQEddctQ0Ta3zBUcLlGxGI1terCLvQ2bKgZsENy636tqSZlvumqN4lMpVta421WwJbWmFj6IUc1jsh1AJgPq9Qd3sT4P0fwW64nEBRjh61rlQ/Do92QCaP/ykjuCakTbAbeH7NwxBM0ubXy4txkHg1mj+LLoKhfNatdADu4HChjIi5P10zCFcZD67mWwhN5r3XPMUIlUtV0fxl8Z49uVbCGgOIgAx8U3ss5FWFVbd2TufeUShxGa/1VTA4qDxFxj2mpVnI+RKNoWGIz3kReJyhBHP28FVA/iHVhy0y57GoNsZRvyBB9shhHKk2CMLezJ8CCmSxj5GizdacZd22xyX30e/7oU1IQQZd/kC4rDurC4keR+9zF5QLMzlNzNLfzxXsURw9oOYX6HLZoMapSd59KZ2J8clRVIEF2gr8+cy1IAMoSykDxKp3OZ5T8XIqLuVMmCis7ATh4TlEn8fiyTS8dyf6kUCkKaWs3uzgg7BJXopYWFdC4Xy+XSf70nVF5kK03MEqZob8QoMMoegPxi5s/lvwkZo1ZCrxBMbPYfVHq6EDtBevmbSGFM9qYqraVZEZ8Jxh+mTxnmYssLfxwtxqqi3eBBxa2AkDtlmEmDNY4JG2pxg0u+NtqDBr+UTn8QIWL5z/dGMFRqJR5Y7hEMHizkYmex/JdKXlUVa55aLUQq2pbfawkBg15MDxIEWab/mlerEYu2FpRI9rq5L2+W8MgiQlOMf7tXsKk1lMpic8ZECEpqI0OkCNWGhWC+qq1BOTHlu5LPgIGSxjJ2DGMxDBuV/NlEVdmdMQ1NMv7oQixtSxDixp/uFQYqKm1v0h/ZMfi3kJHaqmlmIQfVhnpmnS+7M1PJDMF6jOcyMVuCIMQcVhtnZKhtzxpDyl8t2NM70VSoNiKVEzeTvWpWk7MExh/bG2EfabPa6IkRPOvi9oz5GWz8PBnJEBQ1s/xNwQwbaiS7QXzuWgQPJg+xwVN383G1sbjEQ9kp5yf4pZFmeAJIcCIFNYhZ+cDB76ZHaukpRQgbSvHWrDlSxIMh4X5QWbFJ1SrNogxzYgwhMmb+vjF7ImTkacY+7baV4z/c+1E8w8zPT265PmESo9Z7MALlvTDD9Cv3+/+execDB7E5LISRx6L0APe56447O5+Iz8UDxVxiVbbOgjPyrTjB9EP38y3sWSIxFyjicyvPJctaNHz/JJcZUhyeRS4dS1/ibjvAlJxPwGcIFisvJMs6CidyLjassBhgCBRl6r62Px+wCAGJ85Y5Rsr403TMvja0qKhphu7XmsJg+NISzKjEny6IEQRceIjjBFPMMP4dG2yRUQwWgvxyC+lHbtmFxXDe2uVk5K4ow1gm/XTKGc4lrLGMkYfCDGMxTwsVYTBcWbUSdMAwvewp6w6F4fNBTwMB8oEowVz6wfQzfDGY08D3T4R1FDKa6WdouS0l94UZXph+honzgxGfUS5cV8TSj6ef4Tk24A2BsHjl5C0chsXQmjc7kOGl6Wf4sw1DYYKxhVfTz9CamBImHA5zC688TUWGwTBuYQh5qbgM07MgQ0tt4YThLGjpd4N3pb83O/zOiwwzCzPgSy0MwdMsCzO88MjTumFIWmqtf8QZpu96ITihaAFaKp6Xph9OfW0BDAch/75qi8RLaVCGuPIkiFzswfQz/JkNZCWQiTvoYtyffi09Z40WXJhhLp32tHYUTn046GkYGTOI8THDjLeQPxmG4GkeLcTEVrnB1Tzysrc6pD7NwF0p4a9Eu/q5zIWHXlaAJ8SQyhcvZAQZpmNPvBwmFk43cVAGEmXS8kJOaHUNhBi76GHXVTgdYWtiKfEnYotriPSl5FSvPc0lVm1qfIdrwIM5w1QxjM/Z7D3FpRkHMZ+43wUUwhpw/C2zY3hpwYGaPnU/eWnK0M38gQOGLy/azBnQpzkxIWaW05nMf7veKMPOJdxCkJ6ZtNlOUuREZZjJff/a9cQQe3HOJeZFDTiO4dCO4QNBO8y8SUXrDZcEcSYK5M+cArz9W1H7jePimh3DxxeE4mHmByOa0vddM+QypY4JAlYdaOkqtdMxdunCWCFC2pP5sVxORVMp3Cwf3px3UqbPV8QYJoDikDEKNmw7yQfkMrl3yC8arR/gEUJhEcQjwcSjTNzSLT25zJOxDDP/NMrILxrVu4S7nzhxzpCyt3OiDBPn7K/CwBDHEfwJNbTHsd4mQb2BweazMXk1IRgS43YrwL2rjNhv0Q8k35ejpzCOQtxvwYn8QjjZSyQscwp9hkQaYYCxTOaN/hFBFGKIW/MY+06YYTw+pHzlnH87zJkupyFIlKNnGIIlhgYqicYKxMshHhD3rg0PF5kfjTP8ohATD0JjyKXzgrECsPJsmI+XkxfxSAyLgmaA95t3A/yAYbSM532E4m0YmRcXoXVc6PQyjPQOVLDa4D8HBdjT030QfBgEIZldEa8t4sM+FCZ/dy9kLAwhjYEgYeVXNsp6I6yg/9ZB8WTp6J8yhPh20cYQM7F3GAFTFi0tY8QIZXcXiFC8al55NuqMPst0Ww6CRMqw0dB+xOgE/z47iUrMgRXiXOII06EDc7RA8AejbKejJ6bYCDwmwscFKxQWYXx+5KH0lC+foZiJ/WgWEsMIpoxu8AUGSzqQICSlI7VqYJA28+YdmFvZaoMfKOqHQROU2TncgyIa8Veej3QNjD5NY3ff3B+UyfyPYZSHs+ub4kGQzoYTJokWhihAUNLRjgEC+IN0Bgpd7PBnfjKi5eEaekqxHRxFmTHOHenoyrkxZoNNRRAgUIRaFwlGh3uZU1tsBBf2IUi/dLKLKA5KOhJ4bN79jCnAN3qvEBwrw7LeDUyGQPCZaF3Yk+Fbgas+MoX401jZfSTELqPc/7jIJCDowAhRhInzAhem4Gdy34+X3akMUynjNfH/3dmMwo9VhxvdVlYFnjR/vPDm3agIYRViCmpF38+plBi9uDrnqJuPczQCFsPlHwwz6xTlh7/pXd+1FAkKt7lPRDi0cPoYSdLRU6nxUeIsS+N9A5+6X7oq40ZeZwQhLUjMs8EJdjvAx0QdFfc0fYrlNvHtXWHcbHLPOfIy/SabgBDhr3T0qEOGYIspKDR8A3pRZwoK+cxcHMoQgWeMC1NdJ47GFCHmr/Vjv5SUcemZg6q+L8OV80x4abpdd0ixB73bJjKnHiNHEvfT/+xMQ5Gg3Z684ThyxTBqoKZK3po3kIqS5/OOCYIjPe+kpdLQHdrhx2L0dtInKMDh/zoNEyZDJ/flZF93RRB8qn4oe3OpB+W6nvrXZacEhRK2Dww5eS+SdduLsdwxj6p2+I47yvG8e9Lu4rNN6b84ogiFYTxpc1TEcIbMdDauNDUVTdWRI0k6Gw0zD+ptH9VTmOoCxc/mLos3Z8CRPnNmG2Dth7rTmNiDuYIKcsTy3NE9TX562Yw8GF/f/yYuxnh8nhHZQW7MKfhDgfp+mBRRzVKHDUfr4I1OuW6YiwVwY/iZ0vX/E5ZiYuUFGIXT3LgXFF2yRI56t4MjG5SZ46i0J9MeZ0gNqfnKJdbbON/ogPgst6r/O4FNKAERWjc6CYCBP3VNL4ppH4rhtUkSeTE8tp1xM+U0gx47CSvtzmujbnsN/VecnhLguLLqIs2Aqr3rhSHoONiTXq+XjzvtRl9ySWq+Y4f3T+bgjYPOUaquG8Py4FT0X0IEn7lZj07C/esjusHj0e/zpAy9bnSP9jvtdrvRB3zZ2T/upuqmbpqGO+Qp1X+5PLYKtm5VE8aBvfK4ANDUgaiBHfQUSrau64bQ06t/Zhb6I1gmQEddT/Tu111mbyO49qprcd3Q3/82apRmPp54JrteqJXokbvsbQQ/F/8CwsYIiisvoeBz2yaCZzO2rR84MEn69+XhehoHHaWOs4s+QPhtw3AfE30jmfp13laMcTz2ysv5b/hPDzxFRb8YQtiw8amXsSr0VnAzkKJ/DtUDUqn6L3bd4ZWXkpz00MmkqOFua0U/+eGv+mdWiol5Tj1PSzAZy4zJayoWnr9dNjnGeyaYwFlZH9a9uMTIcX3yLhUlidXGiTHif1eey76se4EnPq5PnmHZDBuJuZPwn0hYjxJyBW6+kP548raI2VVK/3U+cSJFIJj0a80LLnM8DR41ihyxSYW6CnHCH3YILiUhRXXXt/EdZtiIJ1YsJyV5ggzuZn8KbDFqRsbPzNVeyU+GHK2RdKZDUbHP9RtI0PdXkUuQ3UQNLxWxPyib9eV/Apj/QKfVLk/cpfY2ChwEMWzG8Zh5fjR5TU0ZRtvXN8l/BJlScjhxinq3QeUg3/N2YOie+qiegPuRjgKfS250dexLT4Qh5G37YRwHv18Xa5P5z09PtUMYaMWFqbLbFVRv0I9kuL9vMy0jaYZdbGAP0tD33Z+U7hDUFGN0+Ii77/wg0NdfNwgfNYfvJ/C10qHmqZCM6h1C5bAIEnMViTSOwuJY1uvHDXwPrJcjR1zhoNtflA4YOOExKXTAHIOrG1OmizHKPs6TOQU3OQYow1RKj3Zww9KE3vrCcGFSCpCjoevAD7P+yb7XJtnp1o3eura7+Y1BpPqLVPr7CernANpH/QVPX6SJAyvgP4/a4eyNEwBWa439sq771AIoR3Ujengy4zANgEwRR64OjqO+VI+GbhwdMHMW2skUUCjgB0fw8RxLsqffqZS5D7AePeq4PzolYGDC0UBJmkbpcBq+jENGevT4gPeH3KYRvWkZwtudrm4z4zScHYQ9o66D8Nq091av0BJQhzDnnXqdWmB5VBYaKcF5G73cPe5gZgahXZJ4cmbeZt5odw67ZQOJGsZHXHHVujdhU6+nusf7B+1ZenHyR+glIqzROOjsHx4ddXHiEKka5XK3e3R8uN85aHDe+5szSrF/xtNIm2LcPJhrSuKeCyA71vccUFVKklldorPEr5mZLXA6tZ7lEz7hEz5BCP8PL/iVRUE+poIAAAAASUVORK5CYII=)";
container.style.backgroundSize = "50px 50px";
container.style.width = '50px';
container.style.height = '50px';
container.onclick = function() {
console.log("Google Login")
openPopup()
}
return container;
}
});
mymap.addControl(new customControl3());
變數宣告
var UID = "" // 使用者ID
var userName = "" // 使用者名稱
var Today=new Date();
fb_login_status = 0 // 0 為還未登入
初始化 firebase
var firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "fb-login-df75e",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
Google 第三方彈出視窗
function openPopup()
{
// var provider = new firebase.auth.GoogleAuthProvider()
var provider = new firebase.auth.GoogleAuthProvider()
firebase.auth().signInWithPopup(provider).then(function(result) {
console.log('test') // 未登入 => 不會跑這裡
// This gives you a Facebook Access Token. You can use it to access the Facebook API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
console.log(user)
console.log(user.displayName) // 使用者名稱
userName = user.displayName
console.log(user.uid) // uid
UID = user.uid
console.log(typeof(user.displayName))
console.log(typeof(user.uid))
if(user.displayName!="" && user.uid!="")
{
fb_login_status = 1
console.log('Login Status:',fb_login_status)
}
// writeUserData(user.displayName,user.uid)
// ...
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
}
firebase - write
依據 uid 寫入個人最愛清單
function writeUserData(name,uid) {
console.log('name:',name)
console.log('id',uid)
loginTime = Today.getFullYear().toString() +'/'+ (Today.getMonth()+1).toString() +'/' +Today.getDate().toString()
console.log('UID',UID)
var database = firebase.database().ref("users/"+UID)
favo_list = JSON.stringify(loved)
console.log(database)
doc = {
'Name' : userName,
'LoginTime' : loginTime,
'favorite_list': name
}
database.set(doc)
}
firebase - read
如果是第一次登入 不會進行讀取
try{
database.on('value',function(data){
console.log('Check')
favorite_list = data.val().favorite_list
Object.entries(loved).forEach(([key, value]) => {
if(favorite_list.hasOwnProperty(key))
{
// match_count = match_count + 1
loved[key] = favorite_list[key]
//console.log(loved[key])
}
});
OriginList = "";
part1="";
part2="";
Data = dataX
for (var i = 0; i < Data.length; i++) {
// update
if (loved[Data[i].SubRoutes[0].SubRouteName.Zh_tw] == 0)
{
path = "https://image.flaticon.com/icons/svg/1142/1142213.svg"
valueX = 0
part1 += `
<img id="${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}" width:20px height:20px src="${path}" width="20px" height="20px" value="${valueX}" onclick="toggle('${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}')" />
<li class="card" title="路線詳情" onclick=updatemap('${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}')>
<p class="bus-way">${ Data[i].SubRoutes[0].Headsign }</p>
<p class="bus-num">${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}</p>
</li>`
}
else
{
path = "https://image.flaticon.com/icons/svg/1142/1142131.svg"
valueX = 1
part2 += `
<img id="${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}" width:20px height:20px src="${path}" width="20px" height="20px" value="${valueX}" onclick="toggle('${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}')" />
<li class="card" title="路線詳情" onclick=updatemap('${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}')>
<p class="bus-way">${ Data[i].SubRoutes[0].Headsign }</p>
<p class="bus-num">${ Data[i].SubRoutes[0].SubRouteName.Zh_tw}</p>
</li>`
}
}
OriginList = part2+part1
list.innerHTML = OriginList;
//
})
}
catch(e)
{
console.log('第一次登入')
}
運行於Google Cloud Platform
from hashlib import sha1
import hmac
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import base64
from requests import request
from pprint import pprint
import json
import smtplib
from email.mime.text import MIMEText
app_id = ''
app_key = ''
class Auth():
def __init__(self, app_id, app_key):
self.app_id = app_id
self.app_key = app_key
def get_auth_header(self):
xdate = format_date_time(mktime(datetime.now().timetuple()))
hashed = hmac.new(self.app_key.encode('utf8'), ('x-date: ' + xdate).encode('utf8'), sha1)
signature = base64.b64encode(hashed.digest()).decode()
authorization = 'hmac username="' + self.app_id + '", ' + \
'algorithm="hmac-sha1", ' + \
'headers="x-date", ' + \
'signature="' + signature + '"'
return {
'Authorization': authorization,
'x-date': format_date_time(mktime(datetime.now().timetuple())),
'Accept - Encoding': 'gzip'
}
if __name__ == '__main__':
a = Auth(app_id, app_key)
response = request('get', "https://ptx.transportdata.tw/MOTC/v2/Bus/RealTimeByFrequency/InterCity/9018?$filter=Direction%20eq%20'0'&$top=150&$format=JSON", headers= a.get_auth_header())
str = str(response.content,'utf-8')
jsonValue = json.loads(str)
listA = []
try:
#將已有的讀出來
with open('/home/turningpoint1125/record2.json' , 'r') as reader:
jf = json.loads(reader.read())
#print(jf)
for item in jsonValue:
mydict = {}
mydict['GPSTime'] = item['GPSTime']
mydict['Lat'] = item['BusPosition']['PositionLat']
mydict['Lon'] = item['BusPosition']['PositionLon']
mydict['Speed'] = item['Speed']
print(mydict)
#jf.append(mydict)
if item['PlateNumb'] in jf:
jf[item['PlateNumb']].append(mydict)
else:
jf[item['PlateNumb']] = list()
jf[item['PlateNumb']].append(mydict)
#listA.append(mydict)
with open("/home/turningpoint1125/record2.json","w+") as dump_f:
json.dump(jf,dump_f,indent=4)
except:
gmail_user = 'turningpoint1125@gmail.com'
gmail_password = 'wisdom5678' # your gmail password
msg = MIMEText('Programmer No Life')
msg['Subject'] = 'GCP運行情況'
msg['From'] = 'turningpoint1125@gmail.com'
msg['To'] = 'turningpoint1125@gmail.com'
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
server.send_message(msg)
server.quit()
print('Email sent!')
#載入收集來的資料
import json
with open('/home/turningpoint1125/record2.json','r') as load_f:
load_dict = json.load(load_f)
#print(load_dict) #測試是否載入資料成功
#計算其他需要的特徵值 - distance,time
#print(len(load_dict)) #共14台 負責跑台中
GPSTime = []
Lat = []
Lon = []
Speed = []
train_number = 0
for key in load_dict:
#print(load_dict[key]) #[{第一筆資料},{第2筆資料},...]...[]
#print(load_dict[key][0])
#input('Stop')
for item in load_dict[key]:
if len(item) == 4 :
#print(item['Lat']) #每一筆資料的距離(target)的依據 #Lat
#print(item['Lon']) #每一筆資料的距離(target)的依據 #Lon
GPSTime.append(item['GPSTime'])
Lat.append(item['Lat'])
Lon.append(item['Lon'])
Speed.append(item['Speed'])
train_number = train_number+1
#計算 label
##前備工具(1):計算點點距離
import math
def getDistance(latA, lonA, latB, lonB):
ra = 6378140 # radius of equator: meter
rb = 6356755 # radius of polar: meter
flatten = (ra - rb) / ra # Partial rate of the earth
# change angle to radians
radLatA = math.radians(latA)
radLonA = math.radians(lonA)
radLatB = math.radians(latB)
radLonB = math.radians(lonB)
pA = math.atan(rb / ra * math.tan(radLatA))
pB = math.atan(rb / ra * math.tan(radLatB))
x = math.acos(math.sin(pA) * math.sin(pB) + math.cos(pA) * math.cos(pB) * math.cos(radLonA - radLonB))
c1 = (math.sin(x) - x) * (math.sin(pA) + math.sin(pB))**2 / math.cos(x / 2)**2
c2 = (math.sin(x) + x) * (math.sin(pA) - math.sin(pB))**2 / math.sin(x / 2)**2
dr = flatten / 8 * (c1 - c2)
distance = ra * (x + dr)
return distance
##前備工具(2):載入路線經緯度資料
with open('/home/turningpoint1125/save.json' , 'r') as reader:
route = json.loads(reader.read())
##前備工具(3):載入距離對照資料
with open('/home/turningpoint1125/disTable.json' , 'r') as reader:
distoNTCU = json.loads(reader.read())
#計算離target的大略距離(先)
add_dis = []
for i in range(train_number):
min = 3000
rd = -1 # 不列入train data
for j in range(0,13):
if(float(Lat[i])!=route[j][0] and float(Lon[i])!=route[j][1]):
dis = getDistance(float(Lat[i]),float(Lon[i]),route[j][0],route[j][1])
else:
dis = 0
if dis < min :
rd = distoNTCU[j]
min = dis
add_dis.append(rd)
#print(add_dis)
#print(len(add_dis))
#計算距離TARGET 所花時間(label)(後)
from datetime import datetime
#from dateutil.parser import parse
ctime = {}
for i in range(train_number):
flag = 0
if str(add_dis[i])=="26.136332967166602":
ctime[i] = "0"
flag = 1
j = i - 1
while flag == 1 and str(add_dis[j])!="26.136332967166602":
if j==1 or str(add_dis[j])=="-1":
break
year = GPSTime[j][0:4]
year = int(year)
#print('year:',int(year))
month = GPSTime[j][5:7]
#print('month:',int(month))
month = int(month)
day = GPSTime[j][8:10]
#print('day:',int(day))
day = int(day)
hour = GPSTime[j][11:13]
#print('hour:',int(hour))
hour = int(hour)
minu = GPSTime[j][14:16]
minu = int(minu)
#print('min:',minu)
year2 = GPSTime[j+1][0:4]
year2 = int(year2)
month2 = GPSTime[j+1][5:7]
month2 = int(month2)
day2 = GPSTime[j+1][8:10]
day2 = int(day2)
hour2 = GPSTime[j+1][11:13]
hour2 = int(hour2)
min2 = GPSTime[j+1][14:16]
min2 = int(min2)
#input('stop')
if (year2-year)==0 and (month2-month)==0 and (day2-day)==0 and (hour2-hour)==0 and (min2-minu)==5:
#X = GPSTime[i][0:10]+' '+GPSTime[i][11:16]
#X = datetime.strptime(str(X),"%Y-%m-%d %H:%M")
#print(X)
#print(A)
#input('stop')
X=GPSTime[i][14:16]
X=int(X)
#a = X - A
#a=str(a)
ctime[j] = X - minu
#print(a)
#input('stop')
else:
break
j = j - 1
#print(ctime)
import time
today = time.strftime("%Y-%m-%d",time.localtime())
filename = '/home/turningpoint1125/'+today+'.csv'
#將訓練資料儲成表格.csv
import csv
with open(filename,'w',newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['GPSTime','Lat','Lon','disTO','Speed','Time'])
for i in range(train_number):
if i in ctime.keys():
writer.writerow([GPSTime[i],Lat[i],Lon[i],add_dis[i],Speed[i],ctime[i]])
print('today data saved')
import pandas as pd
from sklearn import linear_model
from sklearn import preprocessing # 標準化1
from sklearn.preprocessing import MinMaxScaler # 標準化2
scaler = MinMaxScaler() # 標準化2
import time
today = time.strftime("%Y-%m-%d",time.localtime())
filename = '/home/turningpoint1125/'+today+'.csv'
df = pd.read_csv(filename)
print('資料數量:',len(df))
#df_normalize = preprocessing.scale(df.drop(['Time','GPSTime'],axis='columns')) # 標準化1
#df_normalize = scaler.fit_transform(df.drop(['Time','GPSTime'],axis='columns')) # 標準化2
#print(df_normalize)
reg = linear_model.LinearRegression()
reg.fit(df.drop(['Time','GPSTime'],axis='columns'),df.Time)
#reg.fit(df_normalize,df.Time) # 標準化 1 2
#print('R^2:',reg.score(df_normalize,df.Time))
print('R^2:',reg.score(df.drop(['Time','GPSTime'],axis='columns'),df.Time))
print('weight:',reg.coef_ )
print('bias',reg.intercept_ )
import csv
with open('/home/turningpoint1125/daily_log.csv','a',encoding='utf8',newline='') as fd :
writer = csv.writer(fd)
writer.writerow([float(reg.coef_[0:1]),float(reg.coef_[1:2]),float(reg.coef_[2:3]),float(reg.coef_[3:4]),float(reg.intercept_ ),float(reg.score(df.drop(['Time','GPSTime'],axis='columns'),df.Time))])
import smtplib
from email.mime.text import MIMEText
gmail_user = ''
gmail_password = '' # your gmail password
LatW = str(reg.coef_[0:1])
LonW = str(reg.coef_[1:2])
DisW = str(reg.coef_[2:3])
SpeW = str(reg.coef_[3:4])
context = 'Lat: '+ LatW + '\n' + 'Lon: '+LonW+'\n'+'Dis: '+DisW+'\n'+'Speed: '+SpeW+'\n'+'Bias: '+str(reg.intercept_)+'\n'+'R^2: '+str(reg.score(df.drop(['Time','GPSTime'],axis='columns'),df.Time))+'\n'
msg = MIMEText(context)
msg['Subject'] = 'Good Night!'
msg['From'] = 'turningpoint1125@gmail.com'
msg['To'] = 'turningpoint1125@gmail.com'
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
server.send_message(msg)
server.quit()
print('Email sent!')
背景執行flask app
import flask
from flask import jsonify
app = flask.Flask(__name__)
app.config["DEBUG"] = True
# load data - daily_log.csv 最後一筆 #
import csv
with open('/home/turningpoint1125/daily_log.csv','r') as csvfile:
rows = csv.reader(csvfile)
count = 0
for row in rows:
Lat = row[0]
Lon = row[1]
Dis = row[2]
Speed = row[3]
Bias = row[4]
r2 = row[5]
count = count + 1
print(count)
import datetime
x = datetime.datetime.now()
print(x.year)
print(x.month)
print(x.day)
response = {}
response['Lat'] = Lat
response['Lon'] = Lon
response['Dis'] = Dis
response['Speed'] = Speed
response['Bias'] = Bias
response['R2'] = r2
response['date'] = str(x.year) + '/' + str(x.month) + '/' + str(x.day)
response['Start'] = 'taichung'
response['End'] = 'NTCU'
body = [response]
@app.route("/")
def estimate_waitingtime():
return jsonify(body)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=80)
YEAR-MONTH-DATE 為訓練資料
daily_log.csv 紀錄每天的訓練結果 - 四個特徵值的係數 加上一個bias
以及 決定係數 R^2
自動回報模型狀況 by Gmail
Application 可以 call 的到
$.ajax({
url: "https://bypasscors.herokuapp.com/api/?url=http://35.202.154.243/",
type: 'GET',
responseType:'text/javascript',
error: function(e)
{
console.log(e)
},
success: function(e){
console.log(e)
}
})
Solution :https://bypasscors.herokuapp.com/api/?url=
+ http網址
Deploying Simple Flask App with Google Cloud Instance