# 開発環境 python 3.9.9 geopandas
# メッシュデータ情報を一括取得 並列処理

"""
Result_(河川番号)_(河川名).shp
●出力テーブル
ファイル名
河川名
メッシュサイズ X
メッシュサイズ Y
座標系
属性一覧
"""

import os
import glob
import geopandas as gpd
import pandas as pd
from multiprocessing import Pool
import time

CPU_THREAD = 4

def func():
    # read
    print("start...")
    start = time.time()

    # パスの入力
    folderPath = r""
    path_txt = r""
    files = sorted(glob.glob(folderPath+'\\*.shp'), reverse=False)
    str_info = ""

    # 並列
    with Pool(CPU_THREAD) as pool:
        sleeps = [pool.apply_async(info, (i, )) for i in files]
        d = [f.get() for f in sleeps]
        str_info = '\n'.join(d)

    # write
    write(path_txt, str_info)

    print(time.time() - start)
    print("finish")


def info(path_shp):
    # ファイル名の処理
    filename = os.path.splitext(os.path.basename(path_shp))[0]
    filename_s = filename.split("_")  # Result_111_○○○.shp

    print(filename_s)

    # データの取得
    data = gpd.read_file(path_shp, encoding="shift_jis", row=5)

    count_f = len(data)  # ポリゴンの数の取得

    # 四角形じゃない判定(全体)
    df = pd.DataFrame(data)
    for i, row in df.iterrows():
        if (len(list(row["geometry"].exterior.coords)) != 5):
            # print("not 四角形 全体で検索")
            return filename+":"+'not 四角形'
    # 実行
    df = pd.DataFrame(data.head(3))
    zahyou = df.iat[0, -1]
    str_data = ""

    if (zahyou.geom_type == "Polygon"):
        # type polygon
        if (len(list(zahyou.exterior.coords)) == 5):
            # 5points
            str_data = filename + ','+filename_s[1] + ',' + \
                str(round(zahyou.bounds[2]-zahyou.bounds[0], 15)) + ',' + \
                str(round(zahyou.bounds[3]-zahyou.bounds[1], 15)) + ',' + \
                str(data.crs) + ',' + \
                str("ポリゴン数⇒") + ',' + str(count_f) + ',' + \
                str("属性⇒") + ',' + \
                str(str(df.columns.tolist())
                    .replace('[', '').replace(']', '').replace("'", ''))

            return str_data
        else:
            return filename+":"+'not 四角形'

    else:
        return filename+":"+'not polygon'


def write(path_txt, str_data):
    with open(path_txt, 'w') as f:
        f.writelines(str_data)


if __name__ == "__main__":
    func()
# ArcGIS Pro
# 画像出力スクリプト

import arcpy
import pandas as pd
import openpyxl

"""
グループに入っているレイヤーから画像出力
(0):グループ名
(1):出力フォーマット
(2):解像度
(3):出力フォルダ
(4):レイアウト名
(5):マップフレーム
(6):マップ名
(7):図郭 レイヤー
(8):図郭 フィールド名
(9):excelファイルパス 設定ファイル

excelファイル構成
1列目:レイヤー名
2列目:(7):図郭 フィールド名の値一覧

"""

def func():
    # 読み込み
    gLayerName = arcpy.GetParameterAsText(0)
    format = arcpy.GetParameterAsText(1)
    reso = arcpy.GetParameterAsText(2)
    exportFolder = arcpy.GetParameterAsText(3) + "\\\\"
    layoutName = arcpy.GetParameterAsText(4)
    mapFrameName = arcpy.GetParameterAsText(5)
    mapName = arcpy.GetParameterAsText(6)
    lyr_zukaku = arcpy.GetParameterAsText(7)  # zukaku レイヤー
    lyr_zukaku_fn = arcpy.GetParameterAsText(8)  # zukaku フィールド名
    excel_file = arcpy.GetParameterAsText(9)  # excel

    #####################
    # マップ構成の読み込み
    project = arcpy.mp.ArcGISProject("CURRENT")
    layout = project.listLayouts(str(layoutName))[0]
    map = project.listMaps(str(mapName))[0]
    lyrs = map.listLayers()
    lyr_zukakua = map.listLayers(str(lyr_zukaku))[0]
    lyr_zukaku_fn_Type = arcpy.ListFields(lyr_zukakua, lyr_zukaku_fn)[0].type

    # グループレイヤー「export」のみレイヤーの取得
    exportLyr = []
    for lyr in lyrs:
        if lyr.isGroupLayer is False:
            if lyr.longName.split("\\")[0] == gLayerName:
                exportLyr.append(lyr)
                lyr.visible = False

    # マップフレームの取得
    mf=layout.listElements("mapframe_element", mapFrameName)[0]
    txt_elements = layout.listElements('TEXT_ELEMENT', "*txt_ele001*")

    # excelファイルの読み込み
    df = reader_excel(excel_file)

    #####################
    if format == "png":
        if exportLyr is not None:
            for lyr in exportLyr:
                lyr.visible = True
                str_fileter, filename, str_txt_ele = get_value(df, lyr.name, lyr_zukaku_fn_Type)
                if len(txt_elements) > 0:
                    txt_elements[0].text = str_txt_ele
                set_pan(
                    mf,
                    lyr_zukakua,
                    '"' + lyr_zukaku_fn + '"' + "=" +
                    str_fileter,
                )
                layout.exportToPNG(
                    exportFolder + filename + ".png", resolution=int(reso)
                )
                lyr.visible = False
                arcpy.AddMessage(lyr.name + ":" + str(mf.camera.scale))
    if format == "PDF":
        if exportLyr is not None:
            for lyr in exportLyr:
                lyr.visible = True
                str_fileter, filename, str_txt_ele = get_value(df, lyr.name, lyr_zukaku_fn_Type)
                if len(txt_elements) > 0:
                    txt_elements[0].text = str_txt_ele
                set_pan(
                    mf,
                    lyr_zukakua,
                    '"' + lyr_zukaku_fn + '"' + "=" +
                    get_str_filter(lyr_zukaku_fn_Type, df, lyr.name, 1),
                )
                layout.exportToPDF(
                    exportFolder + filename + ".pdf",
                    resolution=int(reso),
                    layers_attributes="NONE",
                )
                lyr.visible = False
                arcpy.AddMessage(lyr.name + ":" + str(mf.camera.scale))
    if format == "jpg":
        if exportLyr is not None:
            for lyr in exportLyr:
                lyr.visible = True
                str_fileter, filename, str_txt_ele = get_value(df, lyr.name, lyr_zukaku_fn_Type)
                if len(txt_elements) > 0:
                    txt_elements[0].text = str_txt_ele
                set_pan(
                    mf,
                    lyr_zukakua,
                    '"' + lyr_zukaku_fn + '"' + "=" +
                    get_str_filter(lyr_zukaku_fn_Type, df, lyr.name, 1),
                )
                layout.exportToJPEG(
                    exportFolder + filename + ".jpg", resolution=int(reso)
                )
                lyr.visible = False
                arcpy.AddMessage(lyr.name + ":" + str(mf.camera.scale))

    lyr_zukakua.definitionQuery = ""
    arcpy.AddMessage("AllFinish")


# フィルター設定
def set_pan(mf, lyr, str1):
    if str1[-4:] == "9999":
        arcpy.AddError("error fileter setting:" + lyr.name)
        exit()
    else:
        lyr.definitionQuery = str1
        ex = ex_mergin(mf.getLayerExtent(lyr, False, True), 50)
        mf.camera.setExtent(ex)
        mf.camera.scale = get_scale(mf.camera.scale)


# int:scale
def get_scale(scale):
    if scale < 2500:
        return 2500
    elif scale < 5000:
        return 5000
    elif scale < 7500:
        return 7500
    elif scale < 10000:
        return 10000
    elif scale < 15000:
        return 15000
    elif scale < 20000:
        return 20000
    elif scale < 25000:
        return 25000
    elif scale < 30000:
        return 30000
    elif scale < 40000:
        return 40000
    elif scale < 50000:
        return 50000


def ex_mergin(ex, mergin):
    ex.XMin = ex.XMin - mergin
    ex.YMin = ex.YMin - mergin
    ex.XMax = ex.XMax + mergin
    ex.YMax = ex.YMax + mergin
    return ex


def get_str_filter(fType, df, indexName, coli):
    # フィルターのクエリの構文を返す
    # 対象がString型とint型で異なるので判定している
    value = str(df.at[indexName, df.columns[coli]])
    if fType == "String":
        return "'"+str(value)+"'"
    elif fType == "Integer":
        return str(value)
    else:
        return str(value)


def get_value(df, indexName, fType):
    value = str(df.at[indexName, df.columns[1]])
    if fType == "String":
        str_fileter = "'" + str(value) + "'"
    elif fType == "Integer":
        str_fileter = str(value)
    else:
        str_fileter = str(value)

    return str_fileter, str(df.at[indexName, df.columns[2]]), str(df.at[indexName, df.columns[3]])


def reader_excel(pathCSV):
    """
    line1
    """
    wb = openpyxl.load_workbook(pathCSV, data_only=True)
    sheet = wb[wb.sheetnames[0]]
    data = list(sheet.values)
    col = []
    for dddd in data:
        col.append(dddd[0])
    return pd.DataFrame(data[1:], columns=data[0], index=col[1:])


if __name__ == "__main__":
    func()