GETパラメーターをhiddenで送る

日付のパラメーターがついていた場合には、それに地域パラメータを加えてリンクさせる。

if(isset($_GET['_udate00'])&&isset($_GET['_udate01'])) {
  $date1 = $_GET['_udate00'];
  $date2 = $_GET['_udate01'] . " 23:59:59";
  $continent = "?_udate00".$_GET['_udate00']."&_udate01=".$_GET['_udate01']."&selectedDimension=continent";
  $contry = "?_udate00".$_GET['_udate00']."&_udate01=".$_GET['_udate01']."&selectedDimension=contry";
  $city = "?_udate00".$_GET['_udate00']."&_udate01=".$_GET['_udate01']."&selectedDimension=city";
} else {
  $date1 = date("Y-m-d", strtotime("-10 day"));
  $date2 = date("Y-m-d H:i:s");
  $continent = "?selectedDimension=continent";
  $contry = "?selectedDimension=contry";
  $city = "?selectedDimension=city";
}
if(isset($_GET['selectedDimension'])){
  $c = $_GET['selectedDimension'];
}

datepickerのformでは、hiddenでipの地域データをsubmitさせます。

<form method="GET" name="form" action="">
<input name="_udate00" type="text" id="datepicker" value="<?php echo $date1; ?>"> ~ <input name="_udate01" type="text" id="datepicker2" value="<?php echo $date2; ?>">
<input type="hidden" name="selectedDimension" value="<?php echo $c; ?>">
<input type="submit" class="submit" value="apply">
</form>

両方ついています。

ipアドレスの地理情報を取得してmongoDBに挿入する

192.168.33.1だとgeoliteがエラーになるので、198.7.31.23にします。

$data = array("date"=>date("Y-m-d H:i:s"));
$audience = $_POST['userdata']; 
$mongo = "app.na".$audience[0][1];
$audience = array_splice($audience, 1);

$ip_addr = $audience[0][1];
if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

foreach($audience as $value){
	$data += array($value[0]=>$value[1]); 
}

require_once '../geolite/vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('../geolite/GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$data = $data + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

var_dump($data);

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($data);
$mng->executeBulkWrite($mongo, $bulk);

echo "finished!!!";

取得できています。

mongoDBにもはいってます。

-geoliteがエラーの時の為に、try catch (Exception $e) に変えると、以下の分岐条件は削除できます。

if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

ipの地理情報はmongoDBには入りません。

因みに、Chrom extensionでBetternet Unlimited Free VPN ProxyやHotspot Shieldなどを使うとIPアドレスを偽造できるようです。

次は、表示側を作ります。
flexを入れ子にしたレイアウトにします。

iphoneのカメラとEOSは何が違うのか?

プロでなければ、普通に写真撮る分にはiphoneで十分、と誰かにお聞きしたんだが、
前から気になっていた、iphoneと一眼レフでどれ位性能違うの?

iphone
6s
-live photos(シャッターを切る前後1.5秒ずつの動画も含めて記録する)
-位相差AFセンサー
-手ぶれ補正
-動画画質 4K/30p(フルHDの4倍の情報量)
-有効画素数 1200万画素

X
-1200万画素
-連写速度 約10コマ/秒
-シャッター速度 1/8000~30秒
-4Kビデオ作成
-wifi bluetooth, gps 〇
-レンズF値 広角:1.8, 望遠:2.4
-レンズカバー距離 28-57mm
-174g

Cannon
EOS630(1989年129,700円)
-シャッター1/2000~30秒
-AF方式:TTL位相差検出方式(ズレ検出)、AFモードはワンショット式 /動体予測AIサーボAF、AF検出範囲はEV1~18(ISO100)
-ファインダー:ペンタ固定アイレベル式、倍率0.8倍、視野率94%、交換スクリーン7種完備
-測光・露出制御:複合型SPC素子使用、TTL開放測光シャッタースピード優先式AE/絞り優先式AE/インテリジェントプログラムAE、定点連動マニュアル、オートブラケティング(1/2段±5段階露光可能)、9回まで予約可能の多重露出可能、測光感度分布特性=画面6分割評価測光/中央部分(画面中央約6.5%部)測光(AEロック機能付き)、露出補正±5EV(1/2ステップ)可能、測光連動範囲はEV-1~ 20(ISO100:F1.4)、フィルム使用感度域はISO6~6400、イメージセレクト=AF、AE、巻き上げ、プログラムの組み合わせ7種、カスタムファンクション=7種設定可能

EOS-1D X Mark II(547,800円!?)
-CFカード(タイプI準拠、UDMAモード7対応)CFastカード(CFast 2.0対応)
-約35.9×23.9mm
-CMOSセンサー
-約2020万画素
-DCF2.0 PEG、RAW
-ピクチャースタイル:オート、スタンダード、ポートレート、風景、ディテール重視、ニュートラル、忠実設定、モノクロ、ユーザー設定1~3
-ホワイトバランス
-画像の明るさ自動補正,高輝度側・階調優先,レンズ光学補正
-ファインダー ペンタプリズム使用、アイレベル式 約0.76倍(50mmレンズ・∞・-1m-1)
-オートフォーカス 専用AFセンサーによるTTL二次結像位相差検出方式
-露出制御:約36万画素RGB+IR測光センサー使用、216分割TTL開放測光
-多重露出撮影
-シャッター 電子制御式、フォーカルプレーンシャッター 1/8000~30秒
-ドライブ関係 1枚撮影、高速連続撮影、低速連続撮影、1枚:ソフト動作、ソフト高速連続撮影、ソフト低速連続撮影、セルフタイマー:10秒、セルフタイマー:2秒 高速連続撮影
-外部ストロボ EXシリーズスピードライト E-TTL II 自動調光
-ライブビュー撮影機能
-動画撮影機能 MOV、MP4
-液晶モニター
-再生機能
-有線LAN機能
….

機能が想像以上にあるな。。1989年のEOS630ですら、まだキャッチアップでんぞ。。。

とりあえずシャッター速度は変わらんよう。
画素は2200万だからEOSは倍。1200万でも相当凄いんだろうけど。。よーわからんが。
明るさや、露出補正はなんとなく馴染みやすいが、手振れ補正のアルゴリズムが良くわかりませんね。
手振れ補正は、色々なアルゴリズムの研究が世界中であるようです。
https://library.naist.jp/mylimedio/dllimedio/showpdf2.cgi/DLPDFR008578_P1-93
光学式:カメラの動きをジャイロセンサで検出して、その動きがキャンセルされるようにレンズ、撮影素子を駆動する
電子式:画像処理
->光学式は、カメラそのもの動きを計算しているんですね。

自動運転は画像認識の技術が入っているので、当然カメラと連動した写真系のサービスつくらないと駄目ってことですね。(どれ位掘らないといけないのか、現段階では想像つきません)
呑気に「一眼レフ買って撮影会に行きたい」なんて言ってる場合ではないことは確か。

ipの大陸、国、地域を配列にpush

$audience = array("date"=>"2018-04-18 08:05:50", "ip"=>"198.7.31.23", "visit"=>"Returned User");

$ip_addr = $audience["ip"];

require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$audience = $audience + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

print_r("<pre>");
var_dump($audience);
print_r("</pre>");

きた!

cronでgunzipを実行する

crontabでgunzipと書くだけです。

20 * * * * root cd /home/vagrant/cookie/cron; gunzip GeoLite2-Country.mmdb.gz

ほお~

sudo cat /var/log/cron
Apr 26 22:20:02 localhost CROND[17108]: (root) CMD (cd /home/vagrant/cookie/cron; gunzip GeoLite2-Country.mmdb.gz)

無償版は毎月3日に更新されるそう(真偽は不明です)なので、日本との時差を考慮して、毎月5日の1時15分にwgetして、1時20分にgunzipするよう設定します。

15 1 5 * * root cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"
15 1 5 * * root cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz"
20 1 5 * * root cd /home/vagrant/cookie/cron; gunzip GeoLite2-Country.mmdb.gz
20 1 5 * * root cd /home/vagrant/cookie/cron; gunzip GeoLite2-City.mmdb.gz

geolite側はこれでOK
次はmongodbに入れる前に、phpでipから、continent, country, cityを取得して配列にpushするところをやりたいと思います。

cronでwgetを実行する

wget:ノンインタラクティブなダウンローダー

wgetがどこにあるか確認します。

/usr/bin/wget

bin:Binary codeのこと、実行可能プログラム置き場
/bin:FHSによって定められたシングルユーザを含めたどのユーザでも使えるコマンド
/usr/bin:ユーザーが一般的に使用するコマンド

続いて、crontabを編集します。

sudo vi /etc/crontab

任意のディレクトリ(ここでは/home/vagrant/cookie/cron)に、wgetでdownloadしたいとすると、まず、cdで移動する必要があります。そのため、以下のように書きます。
root cd で移動して、/usr/bin/wgetで、”http://hogehoge”をダウンロード
※ここでは、テスト用に毎時55分にwgetする

55 * * * * root cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"
/etc/rc.d/init.d/crond start

編集後、crond start
/etc/rc.d/init.d/crond start

結果
->取れてる!!!

sudo cat /var/log/cron でログも確認

Apr 26 21:55:01 localhost CROND[17001]: (root) CMD (cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz")

OK牧場!

ipから、continent, country, cityを取得

encodeしてdecodeします。

$reader = new Reader('GeoLite2-City.mmdb');
$ip_addr = '182.22.59.229';
$record = json_decode(json_encode($reader->city($ip_addr)));



echo $record->continent->names->en ."<br>";
echo $record->country->names->en ."<br>";
echo $record->city->names->en ."<br>";

首相官邸
https://www.kantei.go.jp/
202.214.216.10
Asia
Japan
Komagatani
大阪府羽曳野市駒ケ谷?

white house
https://www.whitehouse.gov/
North America
United States
Cambridge

おもろい!続けて..

ペニンシュラ
peninsula.com
North America
United States
cityがnullの場合もあるようです。
ってか、アメリカかい!

GeoIP2でipアドレスの住所判定

GeoLite2 CountryがIPアドレスから国を取得するデータベース、GeoLite2 CityがIPアドレスから地域を取得するデータベース

# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
# gunzip GeoLite2-Country.mmdb.gz
# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
# gunzip GeoLite2-City.mmdb.gz

mmdbはインメモリデータベース
gunzip:圧縮された圧縮ファイルを解凍する

composerを入れてGeoIP2 PHP APIをインストール

$ curl -sS https://getcomposer.org/installer | php
composer require geoip2/geoip2:~2.0

<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('GeoLite2-City.mmdb');
$ip_addr = '182.22.59.229';
$record = $reader->city($ip_addr);

print_r("<pre>");
var_dump($record);
print_r("</pre>");
?>

ドイツ語、英語、スペイン語、フランス語、日本語、ポルトガル語、ロシア語、中国語で出力されます。
[“record”:”GeoIp2\Record\AbstractRecord”:private]=>
array(2) {
[“geoname_id”]=>
int(1850147)
[“names”]=>
array(8) {
[“de”]=>
string(5) “Tokio”
[“en”]=>
string(5) “Tokyo”
[“es”]=>
string(5) “Tokio”
[“fr”]=>
string(5) “Tokyo”
[“ja”]=>
string(6) “東京”
[“pt-BR”]=>
string(7) “Tóquio”
[“ru”]=>
string(10) “Токио”
[“zh-CN”]=>
string(6) “东京”
}
}

1.エリア、国、都市を取得
2.wget・gunzipをcronで実行できるか確認が必要
3.クライアントリクエストからの負担を軽くするため、都市の抽出はmongoDBに入れる前にphp側で実行したい

anlyticsを設計していく2

必要項目: language, country, city, browser, operating system, service provider, operating system, service provider, screen resolution

例えば、countryをクリックすると、GetパラメーターにselectedDimensionが追加される。
&overview-dimensionSummary.selectedDimension=analytics.country/

Language – Country – City はIP情報か?
IP情報は、$_SERVER[‘REMOTE_ADDR’];で取得できるとして、それをどう紐づけるかが問題。。。

>IPアドレスの割り振りはIANAにが一元管理しており、世界レベルで階層構造(組織)があり、階層ごとにそれぞれ管理が行われています。(IPv4,IPv6)
なんだと???????

IANA(ICANN):全IPアドレスを地域レジストリや一部企業に割り当てしている
地域レジストリ:全世界を5ブロックに分け、地域レジストリを配置している。地域レジストリは、IANAより割り当てされたIPアドレスを国別レジストリに再割り当てしている。また、WHOIS情報の管理も行っている。
国別レジストリ:国や地域でレジストリが配置されている。(一部は企業もあり)地域レジストリより割り当てられたIPアドレスをプロバイダや企業に再割り当てしている。またWHOIS情報の管理も行っている。

IPv4 Address Space Registry
http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
Internet Protocol Version 6 Address Space
https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml

うお、吐き気がしてきた。。
000 IANA – Reserved(予約済み) whois.arin.net
001 APNIC アジア/太平洋圏 whois.apnic.net
002 RIPE NCC ヨーロッパ、中東、中央アジア whois.ripe.net
003 General Electric Company ゼネラル・エレトリック社(アメリカ) whois.arin.net
004 Level3 Communications Inc. レベル3コミュニケーションズ社(アメリカ) whois.arin.net
005 RIPE NCC ヨーロッパ、中東、中央アジア whois.ripe.net
006 Army Information Systems Center 軍情報システムセンター whois.arin.net
007 ARIN 北アメリカおよびサブサハラ等 whois.arin.net
008 Level3 Communications Inc. レベル3コミュニケーションズ社(アメリカ) whois.arin.net
009 IBM アイ・ビー・エム社(IBM社) whois.arin.net
010 IANA – Private Use See [RFC1918] ローカルIPアドレス whois.arin.net ….

現在のIPアドレス:106.***.***.***
->106 APNIC アジア/太平洋圏 whois.apnic.net
そうですか。。。

というか、USのdefence forceばっかりだ。。やばいな、これ。
Army Information Systems Center、DoD Intel Information Systems、DDN-RVN

あれ、そもそも、apnicって何?
https://www.apnic.net/

ip情報は$_SERVER[‘REMOTE_ADDR’]で渡しているので、上3桁を切り抜きたいが。。

dateのfrom – toをgetパラメーターで送る

パラメーターのnameはGA同様、_u.date00、_u.date01にします。

<?php
$date1 = date("Y-m-d", strtotime("-50 days"));
$date2 = date("Y-m-d");

?>
<style>
input{
	width:90px;
}
</style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/redmond/jquery-ui.css" >

<form method="GET" name="form" action="">
<input name="_u.date00" type="text" id="datepicker" value="<?php echo $date1; ?>"> ~ <input name="_u.date01" type="text" id="datepicker2" value="<?php echo $date2; ?>">
<input type="submit" class="submit">
</form>
<script>
  var dateFormat = 'yy-mm-dd';
  $(function() {
    $("#datepicker").datepicker({
    	dateFormat: dateFormat,
    	maxDate:0,
    	onClose: function(dateText, inst){
    		$('#datepicker2').datepicker('option', 'minDate', dateText);
    		$('#datepicker').val(dateText);
    	}
    });
    $("#datepicker2").datepicker({
    	dateFormat: dateFormat,
    	maxDate:0,
    	onClose: function(dateText, inst){
    		$('#datepicker').datepicker('option', 'maxDate', dateText);
    		$('#datepicker2').val(dateText);
    	}
    });
  });
</script>

送れています。

つなげると、、、

mongodbのfilterで’date’ => [ ‘$gte’ => $date1, ‘$lte’ => $date2]とすると、
date2が00:00:00で算出してしまうので、以下のように、Getパラメーター取得時は、その日の23:59:59にします。

if(isset($_GET['_udate00'])&&isset($_GET['_udate01'])) {
  $date1 = $_GET['_udate00'];
  $date2 = $_GET['_udate01'] . " 23:59:59";
} else {
  $date1 = date("Y-m-d", strtotime("-10 day"));
  $date2 = date("Y-m-d H:i:s");
}

次はarray_count_valuesでアクセスされたページのテーブル表示です。

あれ、google見ると、ページごとにPageviews、Unique Pageviews、Avg. Time on Page 、Entrances、Bounce Rateがある。。。まじかよ。。。