プラットフォームはラズパイ 4B / 4GB、OSはUbuntu 20.04.1 LTS Serverを使ってみます。
PostgreSQLは12.4がインストール済で、データベースも作成済みとします。
インストールや設定等はこの辺をご参照ください。
2つのファイルを編集してPostgreSQLに接続できるようにしておきます。
sudo nano /etc/postgresql/12/main/postgresql.conf
以下のコメントアウトを外します。
listen_addresses = ‘localhost’
sudo nano /etc/postgresql/12/main/pg_hba.conf
以下の2行をtrustに修正
1 2 3 4 5 |
#local all all peer local all all trust #host all all 127.0.0.1/32 md5 host all all 127.0.0.1/32 trust |
PostgreSQLを再起動
sudo systemctl restart postgresql
PHP 7.4.3 (cli)をインストール
1 |
sudo apt install php7.4-cli |
php.iniを修正
1 |
sudo nano /etc/php/7.4/cli/php.ini |
コメントアウトを解除
extension=pgsql
pg_xxxなどのコマンド用に以下をインストール
1 |
sudo apt install php7.4-pgsql |
接続して簡単なクエリーをテスト(テーブルからデータを10個取得)
【/home/postgresql.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?php $host = "host=127.0.0.1"; $port = "port=5432"; $dbname = "dbname=<データベース名>"; $credentials = "user=<ユーザー名> password=<パスワード>"; $db = pg_connect("$host $port $dbname $credentials"); if(!$db){ echo "Error : Unable to open database\n"; } else { echo "Opened database successfully<br>"; //テーブルから10個データを取得してみます $result = pg_query('SELECT * FROM <テーブル> limit 10'); if (!$result) { die('クエリー失敗'.pg_last_error()); }else{ print('クエリー成功<br>'); while($row = pg_fetch_row($result)){ for($i = 0;$i < count($row);$i++){ print($row[$i] ."<br>"); } } print('以上<br>'); } $close_flag = pg_close($db); if ($close_flag){ print('切断しました<br>'); } } ?> |
上記のコードではpg_query関数を使っています。シンプルですがSQLインジェクションの脆弱性があります。
不安な向きは以下のようにpg_query_params関数に変更。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?php $host = "host=127.0.0.1"; $port = "port=5432"; $dbname = "dbname=<データベース名>"; $credentials = "user=<ユーザー名> password=<パスワード>"; $db = pg_connect("$host $port $dbname $credentials"); if(!$db){ echo "Error : Unable to open database\n"; } else { echo "Opened database successfully<br>"; //テーブルから10個データを取得してみます $result = pg_query_params($db, 'SELECT * FROM <テーブル> limit $1',array(10)); if (!$result) { die('クエリー失敗'.pg_last_error()); }else{ print('クエリー成功<br>'); while($row = pg_fetch_row($result)){ for($i = 0;$i < count($row);$i++){ print($row[$i] ."<br>"); } } print('以上<br>'); } $close_flag = pg_close($db); if ($close_flag){ print('切断しました<br>'); } } ?> |
簡単にブラウズするには、phpのビルトインサーバーを起動(例えばIPアドレスは192.168.0.34でポートは8000番を使うとして、ドキュメントルートは/homeだとします)
1 |
php -S 192.168.0.34:8000 -t /home |
他PCからアクセス
http://192.168.0.34:8000/postgresql.php
WebGISみたいなもんにしたらこんな感じです。
最短経路探索をやっています。
緑の領域はpgRroutingのデータがロードされてる範囲。
ラズパイ4BでデータベースとSQLのみでやるなら、この範囲で端から端までの探索で4~5秒といった感じです。
背景地図は自前のタイルサーバーからとっています。
Leafletを使っていますがライブラリもスタイルシートもローカルに置いています。
このWebアプリはOpenStreetMapのクレジット表示以外は自前で完結しています。
中心座標と半径で範囲を指定して地物検索
ソースとかはまた次回ということで。
Appendix1
WebサーバーにApacheを使ったり、地図配信に自前のタイルサーバーを使う場合などは以下を参照
ラズパイ(Ubuntu 20.04 LTS Server)にOpenStreetMapのタイルサーバーを構築
Appendix2
経路探索したい!場合は以下を参照
ラズパイ(Ubuntu 20.04.1 LTS Server)でpgRoutingを使って経路探索
Appendix3
XMLHttpRequstでPHP(xxx.php)からデータを受け取る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function get_data(){ var param = ""; var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://<IPアドレス>/xxx.php' + param, true); xhr.responseType = 'text'; xhr.onload= function(e) { if (this.status == 200) { var res = this.responseText; //alert(res); } }; xhr.send(); } |
PHPのPostgreSQLクエリー
nameカラムとジオメトリ型カラム(geom)で緯度・経度・半径を使って地物検索
$query = "select name,ST_AsText(geom) from <テーブル> where ST_DWithin(geom, ST_GeomFromText('POINT(<経度> <緯度>)',4326), <半径>,true) order by name;";$result = pg_query($query);
Appendix4
Leafletライブラリを使って緯度・経度を取得
イベントはclickやmousemoveを使います。
スタイルシートやJavaScriptライブラリなどLeaflet一式
自前のタイルサーバーを使う場合はIPアドレスをセット
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<!DOCTYPE html> <html style="height:100%;margin:0;padding:0;"> <title>Leaflet page with OSM render server selection</title> <meta charset="utf-8"> <link rel="stylesheet" href="./css/leaflet.css" /> <script src="./js/leaflet.js"></script> <script src="./js/leaflet-hash.js"></script> <style type="text/css"> .leaflet-tile-container { pointer-events: auto; } </head> <body style="height:100%;margin:0;padding:0;"> <div id="map" style="height:100%;z-index:1;"></div> <script> //<![CDATA[ var map = L.map('map').setView([34.673791, 135.511708], 5); L.tileLayer('http://<IPアドレス>/hot/{z}/{x}/{y}.png', {maxZoom:18,maxNativeZoom:17, attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(map); var hash = L.hash(map) //]]> map.on('click', function(e) { //クリック位置経緯度取得 lat = e.latlng.lat; lng = e.latlng.lng; //経緯度表示 alert("lat: " + lat + ", lng: " + lng); } ); </script> </body> </html> |
OpenStreetMapのタイルサーバーを使う場合は以下のようになります。
1 2 3 |
L.tileLayer('https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', {maxZoom:18,maxNativeZoom:17, attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(map); |
Appendix5
国交省などから取得したShapeファイルから施設などの地物のデータベースを作成
ラズパイ(Ubuntu 20.04 LTS Server)で空間データベース(大阪編)
Appendix6
Javascriptで簡易距離計算、単位はm
1 2 3 4 5 6 7 8 9 10 11 |
function distance(lat1, lng1, lat2, lng2) { lat1 *= Math.PI / 180; lng1 *= Math.PI / 180; lat2 *= Math.PI / 180; lng2 *= Math.PI / 180; var temp = 6371 * Math.acos(Math.cos(lat1) * Math.cos(lat2) * Math.cos(lng2 - lng1) + Math.sin(lat1) * Math.sin(lat2)); temp *= 1000; return temp; } |
Appendix7
ローカルにテキストデータを保存する場合はblobを使います。
保存場所はWindowsの場合はユーザーのダウンロードディレクトリー
ChromeとFirefoxで動作確認
1 2 3 4 5 6 7 8 9 10 |
function download_data(data){ if(data != ""){ let blob = new Blob([data],{type:"text/plan"}); let link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = 'data.txt'; link.click(); } } |
Leave a Reply