繼上次搭建完框架獲得了個粗糙的demo之後,基本的圖形組件試了個遍沒什麼阻力。我天真地覺得我離真理的距離簡直就只有一步之遙了。
想着我還有些模擬的地理數據沒有作可視化,數據信息的內容放在名爲location的屬性之下,具體格式如:javascript
{ "location": { "lat":12.345, "lon":56.789 }, "temperature": 49.966, "more-props": "value" }
一個很天然而然想法萌生了---用地圖來展現相關信息。但!萬萬那沒想到,一進地圖的坑,卡了10天都沒出坑。(部分緣由是聖誕節讓我懶惰[寫不出來就讓聖誕節背鍋哈哈哈哈],沒有作功課)。
關於基於地圖的信息可視化,Power BI上的Map工具給我留下了用戶友好簡單易用的好印象。只要使用直接的經緯度數據對就能在地圖上對位置定位並展現。邏輯慣性讓我想固然了,天真地覺得全部的地圖插件都同樣」單純」。
首先,在Grafana的標準可視化工具中是不包括地圖相關的工具的, 但在插件庫中官方發佈了一款名爲Worldmap Panel基於地圖可視化的工具,符合個人需求看起來效果也不錯。前端
在簡單地下載安裝了這個插件後,我發現事情並無想象簡單。該工具和個人可視化框架最大的衝突是:
Worldmap Panel並不支持經過經緯度數據對 e.g. (latitude, longtitude)在地圖上定位與可視化, 其支持的數據格式有且僅有兩種:Country/State Code或geohash。 java
如下從官方文檔中摘出的這句話很好地的解釋了這兩種數據類型。 node
There are currently two ways to connect data with points on a map. Either by matching a tag or series name to a country code/state code (e.g. SE for Sweden, TX for Texas) or by using geohashes to map against geographic coordinates。
Grafana和InfluxDB的文檔大概是我有生以來看到過寫的最邏輯混亂的文檔之一了,吐槽請見上篇博客。
在這新年之際,我要邀請你們繼續欣賞出自Grafana官方WorldMap Panel的documentation。 說實話我一口氣看了三遍後居然比看第一遍時還要混亂。文檔以table data, time series data和json爲data source的介紹相關配置實在是很是地不明智之舉。以個人構架爲例:首先,使用influxdb獲得的數據照理說應該是time series data吧?畢竟人家influxdb號稱time-series數據庫,以寫入數據庫時的時間戳做爲表格的惟一索引。 然而最後使用的配置方法居然歸檔在table data下(influxdb: 我不要面子的哦);
其次"time-series data"這個稱謂也許還可以直觀地理解是以時間戳爲索引的數據(更有甚者我這樣的理解實際上是錯誤的),那麼「table data」該如何去理解呢?"time-series data"難道不是以表格的形式組織排列儲存的嗎?至於「json」就更爲模糊了,是以json爲格式的數據?仍是經過json的形式傳遞的數據? 那麼json這種格式的數據就不能同時是"time-series data"或"table data"嗎?這三種類型的數據不具有互斥性,因而可知這種分類方法是不科學的。
我我的主觀認爲正確的分類方法正如文檔開頭所說,我在本文的第一章節也引用了這句話:git
There are currently two ways to connect data with points on a map. Either by matching a tag or series name to a country code/state code (e.g. SE for Sweden, TX for Texas) or by using geohashes to map against geographic coordinates.
註解:
對於code: 可使用grafana預先定義的code, 也能夠自定義一些code並用json/jsonp方式導入;
對於geohash: 主要是爲了支持elasticsearch, 可是對於influxdb, 能夠人工添加geohash的tag,並將數據看做是表格讀取geohash tag中的內容;
「以country code和geohash爲區分,詳述在不一樣數據庫下針對這兩種數據源的配置方法」---若是用這樣的方法組織文檔,一目瞭然,結構清晰;讀者按圖索驥,效率大大提升,至少好過如今的文檔。而全文檔如此重要的一句話,居然放在一個絕不起眼的角落。恕我實在沒法理解撰寫者的意圖。github
爲了解決這個如鯁在喉的數據匹配問題,幾種可能的解決方法一番折騰後初現原形: 1. 在原始數據中人工硬是添加個country code field或geohash field;
最容易想到的方法。簡單粗暴快捷!可是考慮到這樣的方法並不能適配全部的IoT設備,且大部分的GPS產生的數據仍是經緯度。排除排除! 算法
2. 在Telegraf中添加可以對經緯度數據對作處理併產生geohash的plug-in;
惋惜我並無找到這樣能夠直接使用的plug-in。轉念想到能夠本身開發plug-in,可是對我而言時間,學習成本太。高。(Golang小白,geohash算法不瞭解)。兩個字:排除!
P.S:有興趣的朋友能夠看看telegraf的文檔,他們是歡迎各類形式的plugin PR的。暗中觀察,這樣的plug-in應該要歸在processor plug-in一類中。而目前官方只在這類中給了個printer。基本等於沒什麼卵用,就是在cmd裏打印下數據流。亟待小夥伴填坑!
ref:https://github.com/influxdata... 數據庫
3. 使用Kapacitor對流出數據庫的數據分析處理,後而送至可視化終端;
Kapacitor是influxdata四個開源核心產品之一(TICK stack, K--Kapacitor),能夠對數據進行相應的分析處理,好比使用機器學習模型處理分析數據。具體其餘功能不是特別清楚沒作仔細調研,有興趣的同窗移架這裏。
至於排除的緣由和2相似,沒有可用的腳本,開發成本過高。 npm
4. 使用node-influx和node-geohash等開源插件, 後端語言(如node.js)處理,向數據庫直接添加geohash tag並寫入值;
看起來彷佛是個物美價廉的正經解決方法。不過因爲本文討論的是實時IoT數據的可視化,可能每分鐘就會向數據庫內寫入大量的數據,若是在數據存儲後再對數據進行操做,則要頻繁地調用數據庫I/O進行讀寫操做,將已經存入的數據記錄逐條處理並寫回,增長了數據庫負擔。所以排除。
ref: https://community.influxdata.... json
5. 使用Node-Red對數據流向管理,在數據存入數據庫以前利用已有的集成塊調用接口計算geohash以減輕對數據庫的負擔。
Node-RED爲一個開源的IoT設備數據流編輯器,主要用於可視化IoT數據的流向而且對數據流向進行管理和鏈接。 它依賴於活躍的node.js社區,擁有大量可用資源和強大的社區支持。 既能有效地將數據從源頭歷經的各個技術棧以流程圖的形式表達出來,又能對數據流進行簡單管理,支持javascript對數據流的處理,所以對前端工程師十分友好。
而吸引我使用Red-Node很重要的一個緣由是:Node-RED中有一個名爲node-red-node-geohash的結點模塊,在Node-RED項目中使用npm簡單安裝後,便可將數據中的經緯度數據對直接編碼成geohash碼,反之亦然。這樣就避免了我投入大量時間成本和開發成本在geohash到經緯度的轉碼上;
其次,Node-RED對數據流向進行管理和編輯處理的強大功能,容許在流向中插入自定義的javascript功能代碼;這讓數據流向設計的靈活度大大提升了,所以也能充分利用這種靈活度將個人數據在存入數據庫以前將關於經緯度的數據轉譯成geohash,這樣一來就避免了方法4中對數據庫資源的浪費和複寫;
最後,Node-RED的可視化編輯界面能有效將數據流向以一種簡單直接的方式表達出來,是選擇使用該工具的加分點。權衡性價比以後,決定採起最後一種方案。
tips: 使用Node-RED的前提條件是保證node.js已安裝;
若是是和我同樣使用windows系統的小夥伴們, 推薦一個插件叫作chocolately, 今後Windows也擁有了軟件包管理工具,命令行安裝package不是夢!
打開 windows cmd使用chocolately安裝node.js: choco install nodejs-lts
C:\WINDOWS\system32>npm install -g --unsafe-perm node-red
用戶app路徑\npm\node_modules\node-red>npm install node-red-node-geohash
用戶app路徑\npm\node_modules\node-red>node-red
Node-RED的數據流向編輯器採用模塊拖拽的形式,用戶很容易理解和使用,所以上手不難,學習曲線平緩。
根據個人案例狀況,在Node-RED上搭建的數據流向以下
從我機器上的MQTT broker上訂閱從個人模擬器中發出的特定話題的數據後,利用geohash結點模塊處理經緯度數據,生成geohash,而後再一次利用MQTT broker發佈一個新的話題,用於傳遞通過處理的數據, 這時只要數據庫訂閱這個新話題,就能利用telegraf順利地將數據存入數據庫中。
在這個流向中除了必備的mqtt和geohash節點,我還利用了兩個function節點來自定義代碼。它們分別用於處理流入geohash結點以前的數據,和geohash結點以後的數據。
根據官方文檔中的描述,geohash節點將會直接讀取msg.payload中的lat和lon屬性,若是規定了精確度即msg.payload.precision存在,那麼會一併處理生成惟一的geohash碼。具體描述以下:
A function that encodes lat,lon to and from a geohash.
If the msg.payload is an object with properties lat or latitude and lon or longitude - it will add a geohash property to the payload.
The precision can be set by msg.payload.precision from 1 to 9.
Note: If the msg contains a .location property it will operate on that in preference to the .payload.
在第一章中,我提到過,個人地理數據是被包裹在location屬性中的,即msg.payload.location。所以geohash沒法直接獲得經緯度信息。這時就藉助了location-preprocessor的功能節點將location中的信息提取出來。注意在引用的文檔敘述中的最後一句, 若是msg中包含了location屬性,會直接處理location屬性中的lat,lon屬性,忽略payload中的信息。 藉助這一點,咱們則能夠將msg.payload.location中的信息直接放入msg.location讓其計算geohash。
location-preprocessor的代碼:
//The main purpose of this snippet is to extract the location info from msg.payload and then put it to msg.location to get the calculated geohash. var message=JSON.parse(msg.payload); if(message[0].location!==null) { msg.location={ "lat":message[0].location.lat.toString(), "lon":message[0].location.lon.toString(), "precision":"8" }; //msg.location=message; } return msg;
當獲得有效的geohash碼後,此時,只需將msg.location.geohash的值複製進入msg.payload中,此時數據中就擁有了geohash碼了。接着只需新建一個mqtt話題,將處理的數據經過mqtt broker發佈出去,則Node-RED的配置到這裏就結束了。
location-afterprocessor的代碼:
//The main purpose for this snippet is to put the geohash property into msg.payload which is then transferred by mqtt-broker via certain topic if(msg.location.geohash!==null) { var message=JSON.parse(msg.payload); message[0].geohash=msg.location.geohash; msg.payload=JSON.stringify(message); msg.topic="sensors/wrap_geohash"; } return msg;
[注意]在使用telegraf接受數據以前,要將geohash一項設置爲tag才能被Worldpanel識別和使用。同時若是使用了mqtt的新話題,要記得在配置文件中修改相關項
到這裏,運行telegraf和influxdb,數據應該安然無恙地被telegraf簡單處理後存入數據庫。這時對數據庫進行簡單的操做檢查數據是否如本身預期地被寫入了指定數據庫。
既然到這裏已經保證數據庫裏有了可用的數據,那麼接下來開始設置Worldmap Panel工具吧!
欣喜伴隨着絕望。又要開始研究文檔T.T。
瞅來瞅去,文章裏關於配置最重要的一段話就是這裏了:
An example of Table Data would using InfluxDB and then formatting the data returned from the metric query as Table.
Similar to the Elasticsearch query above, 3 fields are expected (2 of them are mandatory)
- field named metric
- geohash tag named geohash
- an optional location name (shown in the mouse over). This location name has to be specified in the Worldmap settings tab too.
我給你們用直白的話翻譯一下這段話的意思: 老子Worldmap Panel只認兩個兄弟,一個叫作metric,還有一個就是geohash!location name的這我的能夠考慮,可是無關緊要。其餘的都滾一邊去!
geohash就是個打手,Worldmap Panel說讓它去哪兒它就得去哪兒,該在那個地理位置就給定在哪裏;
metric是個師爺,在geohash的定位基礎上,每一個點要顯示的值都靠metric去提供。可是師爺這種人聰明絕頂,行走江湖容易遭人暗算,因此metric是個化名,真正名字叫什麼,主要看數據庫給什麼值了。總之在Worldmap上他就叫metric。
這樣一來咱們就能夠設置數據集按照geohash來定位,而在每一個geohash的點上須要顯示的值則由metric肯定。好比從個人需求出發,須要顯示個人每臺設備在地圖上的定位並能讓用戶看到每臺機器的當前運行的溫度狀況,那麼我就應該這樣來設置個人query。
同時,在worldmap一欄對map data options進行設置:
location data必定要選擇table,且通常table field name設置爲geohash;
到這裏應該能夠看到美膩的demo了!Worldmap panel到這裏終於可用了!
臉上笑嘻嘻,內心真是mmp啊!朋友們填坑不易,且填且珍惜哦! 也不知道本身還能堅持填坑多久,前路漫漫啊前路漫漫! 最後是否是要祝盆友們元旦快樂呢?雖然我知道看到最後的基本都是真愛,而真愛的機率和在這個現實世界同樣基本爲0。