mqttGeo / csv2geojs.py /
3a5b1d8 3 years ago
1 contributor
202 lines | 7.296kb
#!/usr/bin/python3
import time
import json
import paho.mqtt.client as mqtt

circleOpacity=0.2
useLeafletLocal=1
MAPBOXTOKEN="pk.eyJ1IjoieWFuaWtjYXdpZHJvbmUiLCJhIjoiY2p4dmlheGtzMDN0dTNoa2R2b2sxZndkNSJ9.Tfd-xcohTT4x7nEe5_6Rxg"

# Leaflet
# https://unpkg.com/leaflet@1.7.1/dist/leaflet.js
# https://unpkg.com/leaflet@1.7.1/dist/leaflet.css

def networkSurveyColor(rssi):
    color="#888"
    if float(rssi) < -105:
        color="#f00"
    elif float(rssi) < -95:
        color="#ff6600"
    elif float(rssi) < -85:
        color="#ffa500"
    elif float(rssi) < -80:
        color="#ffab40"
    else:
        color="#15ab00"
    return color

def networkSurveyAddLeaflet():
    global useLeafletLocal
    leaflet=""
    leafletCssPath="leaflet.css"
    leafletJsPath="leaflet.js"
    if useLeafletLocal is 0:
        leafletCssPath="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
        leafletJsPath="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
    leaflet+="  <link rel=\"stylesheet\" href=\""+leafletCssPath+"\"\n"
    leaflet+="    integrity=\"sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==\"\n"
    leaflet+="    crossorigin=\"\"/>\n"
    leaflet+="  <script src=\""+leafletJsPath+"\"\n"
    leaflet+="    integrity=\"sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==\"\n"
    leaflet+="    crossorigin=\"\"></script>\n"
    return leaflet

def networkSurveySetMapboxApiToken():
    global MAPBOXTOKEN
    return MAPBOXTOKEN


def networkSurvey(filename, subId):
    global circleOpacity
    start_time = time.time()
    htmlOutput="<!DOCTYPE html>\n"
    htmlOutput+="<html>\n"
    htmlOutput+="<head>\n"
    htmlOutput+="  <title>networkSurvey</title>\n"
    htmlOutput+="  <meta charset=\"utf-8\" />\n"
    htmlOutput+="  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
    htmlOutput+="  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"

    htmlOutput+=networkSurveyAddLeaflet()

    htmlOutput+="<style>\n"
    htmlOutput+="html {\n"
    htmlOutput+="    font-family: \"Lucida Sans\", sans-serif; text-align: center;\n"
    htmlOutput+="}\n"
    htmlOutput+="#deveui { font-size: 1.1em; }\n"
    htmlOutput+="#fcnt { font-size: 1.4em; }\n"
    htmlOutput+="#time { font-size: 1.1em; }\n"
    htmlOutput+="#position { display: inline-block; font-size: 1.1em; }\n"
    htmlOutput+="button {\n"
    htmlOutput+="  position: relative;\n"
    htmlOutput+="  width: 200px;\n"
    htmlOutput+="  height: 24px;\n"
    htmlOutput+="  margin: 8px auto;\n"
    htmlOutput+="  padding: 0;\n"
    htmlOutput+="  font-size: 16px;\n"
    htmlOutput+="  text-align: center;\n"
    htmlOutput+="  color: white;\n"
    htmlOutput+="  border: none;\n"
    htmlOutput+="  outline: none;\n"
    htmlOutput+="  cursor: pointer;\n"
    htmlOutput+="  overflow: hidden;\n"
    htmlOutput+="  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);\n"
    htmlOutput+="  transition: transform 0.4s ease-in-out;\n"
    htmlOutput+="}\n"
    htmlOutput+=".btn-green {\n"
    htmlOutput+="  background: #1abc9c;\n"
    htmlOutput+="  border-bottom: 2px solid #12ab8d;\n"
    htmlOutput+="  box-shadow: inset 0 -2px #12ab8d;\n"
    htmlOutput+="}\n"
    htmlOutput+="</style>\n"
    htmlOutput+="</head>\n"
    htmlOutput+="<body>\n"
    htmlOutput+="  <div id=\"mapid\" style=\"width: 95%; max-width: 400px; height: 400px; margin: auto\"></div>\n"
    htmlOutput+="\n"
    htmlOutput+="<script>\n"

    latMin=90
    lonMin=180
    latMax=-90
    lonMax=-180
    pointList=""
    count = 0
    countRaw = 0
    lastLine=""
    with open(filename, "rt") as fin:
        lines=fin.readlines()
        for line in lines:
            lastLine=line
            part=line.split(',')
            countRaw += 1
            if subId == part[0]:
                if part[5] is not "0" and part[6] is not "0":
                    count += 1
                    color=networkSurveyColor(part[9])
                    jsLine="  L.circle(["+part[5]+","+part[6]+"],{color: '"+color+"', fillcolor: '"+color+"', fillOpacity: "+str(circleOpacity)+", radius:XXXX}).addTo(mymap);\n"
                    if float(part[5]) > latMax:
                        latMax=float(part[5])
                    if float(part[5]) < latMin:
                        latMin=float(part[5])
                    if float(part[6]) > lonMax:
                        lonMax=float(part[6])
                    if float(part[6]) < lonMin:
                        lonMin=float(part[6])
                    pointList+=jsLine
        fin.close()

    # Adapt Zoom to Max(DeltaLat, DeltaLon)
    latDelta=latMax-latMin
    lonDelta=lonMax-lonMin
    posDelta=latDelta
    zoomValue=13
    if lonDelta > latDelta:
        posDelta = lonDelta
    if posDelta < 0.00075:
        zoomValue=19
    elif posDelta < 0.0015:
        zoomValue=18
    elif posDelta < 0.003:
        zoomValue=17
    elif posDelta < 0.006:
        zoomValue=16
    elif posDelta < 0.012:
        zoomValue=15
    #print(str(posDelta)+" : "+str(zoomValue))


    # Adapt Radius to number of circles
    radiusValue=5
    if count < 50:
        radiusValue=1
    elif count < 100:
        radiusValue=10
    elif count < 500:
        radiusValue=5
    elif count < 1000:
        radiusValue=2
    elif count < 2000:
        radiusValue=1
    pointList=pointList.replace("XXXX",str(radiusValue))



    #print(str(posDelta))
    latMid=(latMin+latMax)/2
    lonMid=(lonMin+lonMax)/2
    htmlOutput+="  var mymap = L.map('mapid').setView(["+str(latMid)+", "+str(lonMid)+"], "+str(zoomValue)+");\n"
    htmlOutput+="\n"
    htmlOutput+="        L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token="+networkSurveySetMapboxApiToken()+"', {\n"
    htmlOutput+="                maxZoom: 20,\n"
    htmlOutput+="                attribution: 'Map data &copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors, ' +\n"
    htmlOutput+="                        'Imagery © <a href=\"https://www.mapbox.com/\">Mapbox</a>',\n"
    htmlOutput+="                id: 'mapbox/streets-v11',\n"
    htmlOutput+="                tileSize: 512,\n"
    htmlOutput+="                zoomOffset: -1\n"
    htmlOutput+="        }).addTo(mymap);\n"
    htmlOutput+="\n"
    htmlOutput+= pointList
    htmlOutput+="</script>\n"

    deltaTime = float(int(100*(time.time() - start_time)))/100
    htmlOutput+="<p>Took: "+str(deltaTime)+" seconds</p>\n"

    if countRaw != 0:
        #print(lastLine)
        part=lastLine.split(',')
        lastOutput="<p>\n"
        lastOutput+="<div id=\"deveui\">"+part[1]+"</div>\n"
        lastOutput+="<div id=\"fcnt\">"+part[4]+"</div>\n"
        lastOutput+="<div id=\"time\">"+part[2]+"</div>\n"
        lastOutput+="<div id=\"position\">"+part[5]+" "+part[6]+" "+part[7]+"</div>\n"
        lastOutput+="<div id=\"reload\"><button class=\"btn-green\" onClick=\"window.location.reload();\">Reload</div>\n"
        lastOutput+="</p>\n"
        htmlOutput+=lastOutput

    htmlOutput+="</body>\n"
    htmlOutput+="</html>\n"

    filenameSurvey="networkSurvey-"+str(subId)+".html"
    with open(filenameSurvey,"w") as f:
        f.write(htmlOutput+"\n")
        f.close()