#!/usr/bin/python
# -*- coding: utf-8 -*-
# 必要なライブラリ
import pandas as pd
pd.set_option('display.max_columns', 99999)
pd.set_option('display.max_rows', 500)
import pandas as pd
from pandas import Series, DataFrame
import datetime
from datetime import timedelta
import worldmesh
from geojson import Polygon, LineString,Feature, FeatureCollection, dump

import cgi
import sqlite3
import sys
import json

import pyproj
import math

# アーチ作成関数
import pyproj
grs80 = pyproj.Geod(ellps='GRS80')
def arch_points(df):
    # 重なると見づらいので方向別で始点終点をずらす ※ 125mメッシュ単位の移動を想定したズレになっています。1kmメッシュ単位の移動の場合もう少しズレを大きくする必要があります。
    # エリア間の移動の場合、エリア間の平均的な距離からズレを決めてもいいかもしれません。
    # 左側通行の原則
    # イメージ
    # ↗↙
    # ↖↘
    # ↑↓
    # →
    # ←
    lat_space = 0.0001802
    lng_space = 0.0002190
    # 移動の縦横の関係性を見るために緯度経度の差を出す
    df['lat_diff'] = df['destination_area_lat'] - df['origin_area_lat']
    df['lng_diff'] = df['destination_area_lng'] - df['origin_area_lng']
    # 緯度が同じ&経度差がマイナス　→　西へ向かう　→　始点・終点を南にずらす（左側通行の原則。以下同様）
    df.loc[(df['lat_diff']==0)&(df['lng_diff']<0 ), 'origin_area_lat']      = df['origin_area_lat']      - lat_space 
    df.loc[(df['lat_diff']==0)&(df['lng_diff']<0 ), 'destination_area_lat'] = df['destination_area_lat'] - lat_space 
    # 緯度が同じ&経度差がプラス　→　東へ向かう　→　始点・終点を北にずらす
    df.loc[(df['lat_diff']==0)&(df['lng_diff']>0 ), 'origin_area_lat']      = df['origin_area_lat']      + lat_space
    df.loc[(df['lat_diff']==0)&(df['lng_diff']>0 ), 'destination_area_lat'] = df['destination_area_lat']  + lat_space
    # 緯度差がマイナス&経度が同じ　→　南へ向かう　→　始点・終点を東へずらす
    df.loc[(df['lat_diff']< 0)&(df['lng_diff']==0), 'origin_area_lng']      = df['origin_area_lng']      + lng_space
    df.loc[(df['lat_diff']< 0)&(df['lng_diff']==0), 'destination_area_lng'] = df['destination_area_lng'] + lng_space
    # 緯度差がプラス&経度が同じ　→　北へ向かう　→　始点・終点を西へずらす
    df.loc[(df['lat_diff']> 0)&(df['lng_diff']==0), 'origin_area_lng']      = df['origin_area_lng']      - lng_space
    df.loc[(df['lat_diff']> 0)&(df['lng_diff']==0), 'destination_area_lng'] = df['destination_area_lng'] - lng_space
    # 南西へ向かう　→　始点を南へ、終点を東へずらす
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']<0 ), 'origin_area_lat']      = df['origin_area_lat']      - lat_space
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']<0 ), 'destination_area_lat'] = df['destination_area_lat']
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']<0 ), 'origin_area_lng']      = df['origin_area_lng']
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']<0 ), 'destination_area_lng'] = df['destination_area_lng'] + lng_space
    # 北西へ向かう　→　始点を西へ、終点を南へずらす
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']<0 ), 'origin_area_lat']      = df['origin_area_lat']
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']<0 ), 'destination_area_lat'] = df['destination_area_lat'] - lat_space
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']<0 ), 'origin_area_lng']      = df['origin_area_lng']      - lng_space
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']<0 ), 'destination_area_lng'] = df['destination_area_lng']
    # 北東へ向かう　→　始点を北へ、終点を西へずらす
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']>0 ), 'origin_area_lat']      = df['origin_area_lat']      + lat_space
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']>0 ), 'destination_area_lat'] = df['destination_area_lat']
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']>0 ), 'origin_area_lng']      = df['origin_area_lng']
    df.loc[(df['lat_diff']>0 )&(df['lng_diff']>0 ), 'destination_area_lng'] = df['destination_area_lng'] - lng_space
    # 南東へ向かう　→　始点を東へ、終点を北へずらす
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']>0 ), 'origin_area_lat']      = df['origin_area_lat']
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']>0 ), 'destination_area_lat'] = df['destination_area_lat'] + lat_space
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']>0 ), 'origin_area_lng']      = df['origin_area_lng']      + lng_space
    df.loc[(df['lat_diff']<0 )&(df['lng_diff']>0 ), 'destination_area_lng'] = df['destination_area_lng']
    df.drop(columns=(['lat_diff', 'lng_diff']), inplace=True)
    # アーチにする
    # もともとがアニメーションにするコードだったこと等から冗長さを指摘する警告が出ます。。
    # 3次元で表現するので、高さ情報が必要になります。ここでは、ベースを0としていますが、もともと標高情報を持った3Dマップを使う場合は、ベースをその土地の標高を考慮した高さにしないといけないです。
    arch_resolution = 100
    for i in range(len(df)):
        df.loc[i, 'dist'] = grs80.inv(df.loc[i, 'origin_area_lng'], df.loc[i, 'origin_area_lat'], df.loc[i, 'destination_area_lng'], df.loc[i, 'destination_area_lat'])[2]
    for i in range(arch_resolution+1):
        df[f'origin_area_lat_{i}'] = df['origin_area_lat'] + (df['destination_area_lat'] - df['origin_area_lat'])/arch_resolution*i
        df[f'origin_area_lng_{i}'] = df['origin_area_lng'] + (df['destination_area_lng'] - df['origin_area_lng'])/arch_resolution*i
        df[f'altitude_{i}']   = round(abs((df['dist']/2)**2 - (df['dist']/2-df['dist']*i/arch_resolution)**2)**0.5, 2)
    # df.drop(columns=['latitude', 'longitude', 'next_latitude', 'next_longitude', 'dist'], inplace=True)
    # アーチ本体部分
    df['arch_points'] = ''
    for i in range(arch_resolution+1):
        df['arch_points'] = df['arch_points'] + df[f'origin_area_lng_{i}'].astype(str) + ',' + df[f'origin_area_lat_{i}'].astype(str) + ',' + df[f'altitude_{i}'].astype(str) + ','
        df.drop(columns=[f'origin_area_lat_{i}', f'origin_area_lng_{i}', f'altitude_{i}'], inplace=True)
    df['arch_points'] = df['arch_points'].str[:-1]
    df.drop(columns='dist', inplace=True)
    return df



### P1,2,3画面左　日別量の算出
def daily_sum(df, grouping_list):
    # 定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(grouping_list, as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby(['yyyymmdd'], as_index=False)['cnt'].sum()
    return df

### P1,2,3画面左　時間帯別量の算出
def hour_mean(df, grouping_list):
    # 指定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(grouping_list, as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby(['hour'], as_index=False)['cnt'].sum()
    # 日平均にする
    df['cnt'] = df['cnt'] / nod
    return df

# P1,3画面右　曜日別分析　年月日別合計量の算出
def holiday_daily_sum(df, grouping_list):
    # 指定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(grouping_list, as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby(['yyyymmdd', 'holiday'], as_index=False)['cnt'].sum()
    return df

# P1,3画面右　曜日別分析　曜日平均量の算出
def holiday_mean(df):
    df = df.groupby(['holiday'], as_index=False)['cnt'].sum()
    # 日平均にする
    df.loc[df['holiday']=='平日', 'cnt'] = df['cnt'] / nod_week
    df.loc[df['holiday']=='休日', 'cnt'] = df['cnt'] / nod_holi
    return df

# P1,3画面右　曜日別分析　時間帯別平均量算の出用
def holiday_hour_mean(df, grouping_list):
    # 指定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(grouping_list, as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby(['holiday', 'hour'], as_index=False)['cnt'].sum()
    # 日平均にする
    df.loc[df['holiday']=='平日', 'cnt'] = df['cnt'] / nod_week
    df.loc[df['holiday']=='休日', 'cnt'] = df['cnt'] / nod_holi
    return df

# P1,3画面右　属性別分析　年月日別合計量の算出
def attr_daily_sum(df, selected_attr, grouping_list):
    grouping_list.append(selected_attr)
    # 指定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(grouping_list, as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby(['yyyymmdd', selected_attr], as_index=False)['cnt'].sum()
    return df
    
# P1,3画面右　属性別分析　属性別平均量の算出
def attr_mean(df, selected_attr):
    df = df.groupby([selected_attr], as_index=False)['cnt'].sum()
    # 日平均にする
    df['cnt'] = df['cnt'] / nod
    return df

# P1,3画面右　属性別分析　時時間帯別平均○○量算出用関数
def attr_hour_mean(df, selected_attr, grouping_list):
    grouping_list.append(selected_attr)
    # 指定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(grouping_list, as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby([selected_attr, 'hour'], as_index=False)['cnt'].sum()
    # 日平均にする
    df['cnt'] = df['cnt'] / nod
    return df


# P3画面左　移動マップの量の算出
def od_daily_mean(df):
    # 指定したgrouping_listごとに重み別のUU数をカウント
    df = df.groupby(origin + destination + ['yyyymmdd', 'value'], as_index=False)['id'].nunique()
    # 重みとUU数を掛けて重み別の推計人数とする
    df['cnt'] = df['value'] * df['id']
    # 重み別の推計人数を足し合わせて最終的な推計人数とする
    df = df.groupby(origin + destination, as_index=False)['cnt'].sum()
    # 日平均にする
    df['cnt'] = df['cnt'] / nod
    return df

# P4画面右　OD表の算出
def od_matrix(df):
    df = df.groupby(origin + destination + ['yyyymmdd', 'value'], as_index=False)['id'].nunique()
    df['cnt'] = df['value'] * df['id']
    df = df.groupby(origin + destination, as_index=False)['cnt'].sum()[['origin_area', 'destination_area', 'cnt']]
    df['cnt'] = df['cnt'] / nod
    return df

# Webページ情報取得
data = sys.stdin.read()
params = json.loads(data)

df = pd.read_csv('testdata_4_2_custom.csv', dtype = 'object')

# 属性カラムを判断し左からattr1, attr2, .. と命名
attr_columns = df.columns.drop(['id', 'timestamp', 'area', 'area_lat', 'area_lng', 'value'])
attrs = [] # attr1, attr2, ...→この後の処理に使用 
attrs_name = [] #  csv内のもとの名前→HTML内のフィルターの題名や、属性分析の属性選択リストに使用
for i, column in enumerate(attr_columns):
    df.rename(columns={column: f'attr{i+1}'}, inplace=True)
    attrs.append(f'attr{i+1}')
    attrs_name.append(column)
# 型指定（attr情報はobjectのまま）
df['id'] = df['id'].astype(str)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['area'] = df['area'].astype(str)
df['area_lat'] = df['area_lat'].astype(float)
df['area_lng'] = df['area_lng'].astype(float)
df['value'] = df['value'].astype(float)
# 時間を持たせる
df['year'] = df['timestamp'].dt.year
df['month'] = df['timestamp'].dt.month
df['date']  = df['timestamp'].dt.day
df['hour']  = df['timestamp'].dt.hour
df['dow'] = df['timestamp'].dt.strftime("%a")
# 平日・休日を作成、祝日は考慮しない(不変でないため)
df.loc[df['dow'].isin(['Mon', 'Tue', 'Wed', 'Thu', 'Fri']), 'holiday'] = '平日'
df.loc[df['dow'].isin(['Sat', 'Sun']), 'holiday'] = '休日'
df['yyyymmdd'] = df['timestamp'].dt.date
df_all = df.copy()

# 移動情報用に変換
df = df_all.copy()
df.sort_values(['timestamp', 'id'], inplace=True)
df.rename(columns={'area': 'origin_area', 'area_lat': 'origin_area_lat', 'area_lng': 'origin_area_lng'}, inplace=True)
df['destination_area'] = df.groupby(['id', 'yyyymmdd'])['origin_area'].shift(1)
df['destination_area_lat'] = df.groupby(['id', 'yyyymmdd'])['origin_area_lat'].shift(1)
df['destination_area_lng'] = df.groupby(['id', 'yyyymmdd'])['origin_area_lng'].shift(1)
# メモ：originとdestinationが同じ時間帯で絞るつまり●時台に移動した人という考え方（←センサー間が遠く1時間で移動できないと集計できない）
# 　　　→　●時台にoriginを離れた人という考え方（←センサー間の距離があっても可能）
# 移動していないデータを削除
df = df[~(df['origin_area']==df['destination_area'])]
df_move = df.copy()

# フィルターを反映 ※ここでは選択された項目は例です。実装ではフィルター欄で選択された項目をリストとして入れてください。
df = df_move.copy()
'''
selected_year = [2019]
selected_month = [7]
selected_date = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
selected_hour = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
selected_dow = ['Wed', 'Thu', 'Sat']
selected_holiday = ['平日', '休日']
selected_origin_area = ['上野公園', '蔵前']
selected_destination_area = ['秋葉原', '浅草']
selected_attr1 = ['男性', '女性']
selected_attr2 = ['30', '40', '50', '60']
selected_attr3 = ['すべて']
'''
selected_year = ['']
selected_month = ['']
selected_date = ['']
selected_hour = ['']
selected_dow = ['']
selected_holiday = ['']
selected_origin_area = ['']
selected_destination_area = ['']
selected_attr1 = ['']
selected_attr2 = ['']
selected_attr3 = ['']
selected_attr4 = ['']
selected_attr5 = ['']


if len(params['year']) != 0:
    selected_year =  [int(i) for i in params['year']]
if len(params['month']) != 0:
    selected_month =  [int(i) for i in params['month']]
if len(params['date']) != 0:
    selected_date =  [int(i) for i in params['date']]
if len(params['time']) != 0:
    selected_hour =  [int(i) for i in params['time']]
if len(params['yobi']) != 0:
    selected_dow =  params['yobi']
if len(params['holyday']) != 0:
    selected_holiday = params['holyday']
if len(params['origin_area']) != 0:
    selected_origin_area = params['origin_area']
if len(params['destination_area']) != 0:
    selected_destination_area = params['destination_area']
if len(params['attr1']) != 0:
    selected_attr1 = params['attr1']
if len(params['attr2']) != 0:
    selected_attr2 = params['attr2']
if len(params['attr3']) != 0:
    selected_attr3 = params['attr3']
if len(params['attr4']) != 0:
    selected_attr4 = params['attr4']
if len(params['attr5']) != 0:
    selected_attr5 = params['attr5']

if params['attr'] is not None :
    if len(params['attr']) != 0:
        selected_attr = params['attr']
else :
    selected_attr = ""

if selected_year != ['すべて']:
    df = df[df['year'].isin(selected_year)]
if selected_month != ['すべて']:
    df = df[df['month'].isin(selected_month)]
if selected_date != ['すべて']:
    df = df[df['date'].isin(selected_date)]
if selected_hour != ['すべて']:
    df = df[df['hour'].isin(selected_hour)]
if selected_dow != ['すべて']:
    df = df[df['dow'].isin(selected_dow)]
if selected_holiday != ['すべて']:
    df = df[df['holiday'].isin(selected_holiday)]
if selected_origin_area != ['すべて']:
    df = df[df['origin_area'].isin(selected_origin_area)]
if selected_destination_area != ['すべて']:
    df = df[df['destination_area'].isin(selected_destination_area)]
if 'selected_attr1' in locals():
    if selected_attr1 != ['すべて']:
        df = df[df['attr1'].isin(selected_attr1)]
if 'selected_attr2' in locals():
    if selected_attr2 != ['すべて']:
        df = df[df['attr2'].isin(selected_attr2)]
if 'selected_attr3' in locals():
    if selected_attr3 != ['すべて']:
        df = df[df['attr3'].isin(selected_attr3)]
if 'selected_attr4' in locals():
    if selected_attr4 != ['すべて']:
        df = df[df['attr4'].isin(selected_attr4)]
if 'selected_attr5' in locals():
    if selected_attr5 != ['すべて']:
        df = df[df['attr5'].isin(selected_attr5)]

df_selected = df.copy().reset_index(drop=True)

if len(df_selected) == 0:
    result = {}
    print("Content-type: application/json")
    print("\n\n")
    print(json.dumps(result))

    print('\n')
    exit()
    
# フィルター後の日数を持っておく
nod = df_selected['yyyymmdd'].nunique()
nod_week = df_selected[df_selected['holiday']=='平日']['yyyymmdd'].nunique()
nod_holi = df_selected[df_selected['holiday']=='休日']['yyyymmdd'].nunique()
# 冗長になるのでorigin情報とdestination情報をまとめたリストを持っておく
origin = ['origin_area', 'origin_area_lat', 'origin_area_lng']
destination = ['destination_area', 'destination_area_lat', 'destination_area_lng']

####### P3,4共通の画面左側 #######

### マップ用エリア間平均移動量 df_k
df = od_daily_mean(df_selected)
df_a = arch_points(df)
### 年月日別合計移動量 df_l
df_b = daily_sum(df_selected, origin + destination + ['yyyymmdd', 'value'])
### 時間帯別平均移動量 df_m
df_c = hour_mean(df_selected, origin + destination + ['yyyymmdd', 'hour', 'value'])

####### P3右側 曜日別分析 #######

# 年月日別合計移動量 df_n
df_d = holiday_daily_sum(df_selected, origin + destination + ['yyyymmdd', 'holiday', 'value'])
# 曜日別平均移動量 df_o
df_e = holiday_mean(df_d)
# 時間帯別平均移動量 df_p
df_f = holiday_hour_mean(df_selected, origin + destination + ['yyyymmdd', 'holiday', 'hour', 'value'])

####### P3右側 属性別分析 #######
# ※ 「集計対象」で選択された属性が「attr1」の場合の例です。
for i, column in enumerate(attr_columns):
    df_selected.rename(columns={f'attr{i+1}' : column }, inplace=True)
if selected_attr != "" :
    # 年月日別合計移動量 df_q
    df_g = attr_daily_sum(df_selected, selected_attr, origin + destination + ['yyyymmdd', 'value'])
    # 属性別平均移動量 df_r
    df_h = attr_mean(df_g, selected_attr)
    # 時間帯別平均移動量 df_s
    df_i = attr_hour_mean(df_selected, selected_attr, origin + destination + ['yyyymmdd', 'hour', 'value'])

####### P4右側 OD表 #######
# OD表（人/日） df_t
df_j = od_matrix(df_selected)



geojson_data = df_a.to_dict(orient='records')

# Prepare Geojson FeatureCollection
ft_all = []

'''
for i, p in enumerate(geojson_data):
    arch_list = p['arch_points'].split(',')
    j = 0
    for j in range(len(arch_list)):
        if j % 3 == 0:
            lon, lat, z = float(arch_list[j]), float(arch_list[j+1]),float(arch_list[j+2])
            ft = Feature(geometry = Point((lon, lat, z,)),
                 properties = {'cnt': p['cnt']})
            ft_all.append(ft)
        else :
            continue
ft_colct = FeatureCollection(ft_all)
'''
origin_area_list = []
destination_area_list = []

for i, p in enumerate(geojson_data):
    arch_list = p['arch_points'].split(',')
    j = 0
    pointList = []
    for j in range(len(arch_list)):
        if j % 3 == 0:
            lon, lat, z = float(arch_list[j]), float(arch_list[j+1]),float(arch_list[j+2])
            pointList.append((lon, lat, z))

        else :
            continue
    #arrow_list.append( [pointList[48][0] , pointList[45][1], pointList[45][2] - 25] )
    arrow_list = []
    arrow_list.append( [pointList[48][0] , pointList[48][1], pointList[48][2] + (pointList[48][2]*0.05)] )
    arrow_list.append( pointList[51])
    #arrow_list.append( [pointList[48][0] , pointList[45][1], pointList[45][2] - 50] )

    ft = Feature(geometry = LineString(arrow_list),
                 properties = {'cnt': p['cnt']})
    ft_all.append(ft)

    arrow_list = []
    arrow_list.append( pointList[51])
    arrow_list.append( [pointList[48][0] , pointList[48][1], pointList[48][2] - (pointList[48][2]*0.05)] )

    ft = Feature(geometry = LineString(arrow_list),
                 properties = {'cnt': p['cnt']})
    ft_all.append(ft)

    ft = Feature(geometry = LineString(pointList),
                 properties = {'cnt': p['cnt']})
    ft_all.append(ft)


ft_colct = FeatureCollection(ft_all)





df_json_list = [*df_a.groupby("origin_area").groups] + [*df_a.groupby("destination_area").groups]

df_json_list = list(set(df_json_list))
ft_all_2 = []
for item in df_json_list:
    result = worldmesh.meshcode_to_latlong_grid('20' + item)
    lat0, lon0, lat1, lon1, = result['lat0'], result['long0'],  result['lat1'], result['long1']
    ft = Feature(geometry = Polygon([[(lon0, lat0),(lon0, lat1),(lon1, lat1),(lon1, lat0),(lon0, lat0)]]),
                 properties = {'area': item})
    ft_all_2.append(ft)

ft_colct_2 = FeatureCollection(ft_all_2)


with open('outfile4-2.geojson', 'w') as f:
    dump(ft_colct, f, indent=2)

with open('outfile4_2_area.geojson', 'w') as f:
    dump(ft_colct_2, f, indent=2)


data_list = []
df_meshcode_g = list(set([*df_move.groupby("origin_area").groups]) & set([*df_move.groupby("destination_area").groups]))
for item in df_meshcode_g:
    result = worldmesh.meshcode_to_latlong_grid('20' + item)
    data_list.append([item,result["long0"],result["lat0"],result["long1"],result["lat1"]])

df_geo = pd.DataFrame(data_list, columns=["area", "long0", "lat0", "long1", "lat1"])


geojson_data = df_geo.to_dict(orient='records')
# Prepare Geojson FeatureCollection
ft_all = []
for i, p in enumerate(geojson_data):
    lat0, lon0, lat1, lon1, = p['lat0'], p['long0'],  p['lat1'], p['long1']
    ft = Feature(geometry = Polygon([[(lon0, lat0),(lon0, lat1),(lon1, lat1),(lon1, lat0),(lon0, lat0)]]),
                 properties = {'area': p['area']},id= p['area'])
    ft_all.append(ft)
ft_colct = FeatureCollection(ft_all)

with open('outfile4_3_area.geojson', 'w') as f:
    dump(ft_colct, f, indent=2)

if selected_attr != "" :
    df_g.rename(columns={selected_attr : 'attr1'}, inplace=True)
    df_h.rename(columns={selected_attr : 'attr1'}, inplace=True)
    df_i.rename(columns={selected_attr : 'attr1'}, inplace=True)

df_d_m = df_d.pivot_table(values=['cnt'], index=['yyyymmdd'], columns=['holiday'], aggfunc='sum',fill_value=0)
df_d_m.columns = [cols[1] for cols in df_d_m.columns]
df_d_m = df_d_m.reset_index()
if not '平日' in df_d_m.columns:
    df_d_m['平日'] = 0
if not '休日' in df_d_m.columns:
    df_d_m['休日'] = 0

if selected_attr != "" :
    df_g_m = df_g.pivot_table(values=['cnt'], index=['yyyymmdd'], columns=['attr1'], aggfunc='sum',fill_value=0,margins=True)
    df_g_m = df_g_m.iloc[:-1]
    df_g_m.columns = [cols[1] for cols in df_g_m.columns]
    df_g_m = df_g_m.reset_index()

df_j_m = df_j.pivot_table(values=['cnt'], index=['origin_area'], columns=['destination_area'], aggfunc='sum',fill_value=0)
df_j_m.columns = [cols[1] for cols in df_j_m.columns]
df_j_m = df_j_m.reset_index()

df_j_m_2 = df_j_m.to_dict(orient='records')

html_cross1 = '<table  class="od-table"><tbody><tr><th class="od_title">O/D</th>'
for n in df_j_m.columns:
    if str(n) == 'origin_area':
        continue
    html_cross1 += '<th class="destination">' + str(n) + '</th>'
html_cross1 += '</tr>'

for df_list in df_j_m_2:
    html_cross1 += '<tr>'
    origin_area_name = ''
    for n in df_j_m.columns: 
        value = df_list[n]
        if str(n) == 'origin_area':
            html_cross1 += '<td>' + value + '</td>'
            origin_area_name = value
        elif str(n) == origin_area_name :
            html_cross1 += '<td>-</td>'
        else:    
            html_cross1 += '<td>' + "{:,.3f}".format(float(value)) + '</td>'
    html_cross1 += '</tr>'

html_cross1 += '</tbody></table>'

result = {}
df_b['yyyymmdd'] = df_b['yyyymmdd'].astype(str)
df_d_m['yyyymmdd'] = df_d_m['yyyymmdd'].astype(str)
if selected_attr != "" :
    df_g_m['yyyymmdd'] = df_g_m['yyyymmdd'].astype(str)
result['df_a'] = df_a.drop(columns='arch_points').to_dict(orient='records')
result['df_b'] = df_b.to_dict(orient='records')
result['df_c'] = df_c.to_dict(orient='records')
result['df_d'] = df_d_m.to_dict(orient='records')
result['df_e'] = df_e.to_dict(orient='records')
result['df_f'] = df_f.to_dict(orient='records')
if selected_attr != "" :
    result['df_g'] = df_g_m.to_dict(orient='records')
    result['df_h'] = df_h.sort_values('cnt', ascending=False).to_dict(orient='records')
    result['df_i'] = df_i.to_dict(orient='records')
else :
    result['df_g'] = []
    result['df_h'] = []
    result['df_i'] = []
result['df_j'] = df_j_m.to_dict(orient='records')
result['cross'] = html_cross1
result['pm'] = params
df_selected['yyyymmdd'] = df_selected['yyyymmdd'].astype(str)
df_selected2 = df_selected.drop(columns='timestamp')
result['df_selected'] = df_selected2.to_dict(orient='records')
#df_selected_map = df_selected_map.drop(columns='timestamp')
#df_selected_map['yyyymmdd'] = df_selected_map['yyyymmdd'].astype(str)
#result['df_selected'] = df_selected_map.to_dict(orient='records')
#result['ft_all'] = ft_all
print("Content-type: application/json")
print("\n\n")
print(json.dumps(result))

print('\n')