みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

obnizとGPSモジュールで地図(その3)

概要

前回の続き

Google Mapの表示

自分のページにGoogle Mapを埋め込むにはAPI Keyを取得し、使用時に設定する必要がある。 しかし、API Keyを使用しなくても実験用途には使用できる。

その際、次のように明らかに開発用途だとわかるようになっている。

f:id:mickey_happygolucky:20181209184140p:plain
API KeyなしでのGoogle Map

この時、「このページではGoogleマップが正しく読み込まれませんでした。」というダイアログが表示されるがOKをクリックする。

任意の場所を地図で表示

表示したい緯度と軽度がわかれば、次のようにするだけで地図は表示することができる。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Map Test</title>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js"></script>
</head>

<body>
<div id="sample" style="width: 700px; height: 400px"></div>
<script>
    var map;
    $(function () {
        map = new google.maps.Map($('#sample')[0], {
            center: {
                lat: 35.69496, // 緯度
                lng: 139.76746000000003 // 経度
            },
            zoom: 19
        });
    })
</script>

</body>
</html>

ぜんぶくっつけてみる

その1からここまで作ってきたサンプルを組み合わせて、 obnizに接続したGPSモジュールから取得したNMEAをGPS.jsでパースし、Google Mapで表示するプログラムを作ってみる。

obnizとGPSモジュールの接続についてはその1を参照。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Obniz GPS Google Map Sample</title>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://unpkg.com/obniz/obniz.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/infusion/GPS.js@v0.4.7/gps.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<div id="sample" style="width: 700px; height: 400px"></div>

<script>
    let gps = new GPS;
    let obniz = new Obniz('OBNIZ_ID_HERE');
    let buffer = '';
    let counter = 0;
    let map = null;

    obniz.onconnect = async function () {
        obniz.io0.output(1); //VCC
        obniz.io3.output(0); //GND

        obniz.display.print('waiting GPS...');
        const uart = obniz.getFreeUart();
        uart.start({tx: 1, rx: 2, baud: 9600});

        uart.onreceive = function (data, text) {
            buffer += text;
            if (++counter % 3 === 0) {
                const lines = buffer.split(/\n/);
                for (const s of lines) {
                    if (s.indexOf('$GPGGA') !== -1) {
                        gps.update(s);
                    }
                }
                buffer = '';
            }
        };
    };

    gps.on('data', function(parsed) {
        const lat = parsed.lat;
        const lon = parsed.lon;
        if (lat != null && lon != null) {
            update_map(lat, lon);
        }
    });

    function update_map(lat, lon) {
        if (map == null) {
            map = new google.maps.Map($('#sample')[0], {
                center: {
                    lat: lat,
                    lng: lon
                },
                zoom: 19
            });
            obniz.display.clear();
            obniz.display.print('GPS ok');
        } else {
            map.setCenter({lat: lat, lng: lon});
        }
    }

</script>

</body>
</html>

UARTで受信したデータは、必ずしも切りの良いところまで受信できているわけではないため、 3回に1回だけパースを行なうようにしている。

実行画面を載せると、住所がモロバレするので今回は載せない。

GPSモジュールが衛星に捕捉され緯度経度が取れるようになるまで数分かかるので、 実行してから気長に待つ必要がある。