Python 時刻形式経緯度十進変換関数クラス

航空や気象で扱われてる時刻形式の経緯度を地図で扱うために、十進値に変換する関数を作ってクラスにしてみました。

< コード例 >

クラス


'''
時刻形式経緯度十進変換クラス
'''
class DigitLL:

  '''
  コンストラクタ
  txt : 時刻経緯度
  endchr : N or S or E or W
  '''
  def __init__(self, txt, endchr):
    self.txt = txt
    self.endchr = endchr

  '''
  十進変換
  '''
  def digitLLFromTimeLL(self):

      numInt = int(self.txt)
      # 整数部
      hourPartVal = int(numInt / 10000)
      # 分
      minutePartVal = int(numInt / 100) % 100
      # 秒
      secondPartVal = numInt % 100

      minuteVal = minutePartVal / 60
      secondVal = secondPartVal / 3600
      resval = hourPartVal + minuteVal + secondVa
      
      # 南半球、西半球の場合 #
      if (self.endchr == "S" or self.endchr == "W
          resval = resval * -1

      # debug
      # print(str(hourPartVal) + ":" + str(minute

      return resval

呼び出し
ダウンロードしたExcelのファイルのセルの値を読み込んで変換する場面で使ってます。


'''
Waypointエクセルファイル読込
使用
wp_euro_procedure.pyから使う

filename : エクセルファイル名
effdate_end : effective expired date
'''
def readExcel(filename, effdate_end):

    wb = openpyxl.load_workbook(filename)
    sheet = wb["FRA Points"]

    # 書き込み用タプルリスト追加 #

    tpllist = []

    # 行数を調べる #
    rowmax = getDataRowMax(sheet)

    # identcol = "C" + str(i + 2)

    ## ++ 辞書値リスト追加走査 ++ ##
    for i in range(rowmax):

        ident = sheet["C" + str(i + 2)].value
        type = sheet["A" + str(i + 2)].value
        latcval = sheet["D" + str(i + 2)].value
        loncval = sheet["E" + str(i + 2)].value
        name = sheet["F" + str(i + 2)].value
        #if type == None:
        #    type = "FIX"
            
        type = "FIX" if type == None else type     

        latendchr = latcval[0:1]
        lonendchr = loncval[0:1]
        latvalpart  = latcval[1:]
        lonvalpart = loncval[1:]

        #lat = digitLLFromTimeLL(latvalpart, latendchr)
        #lon = digitLLFromTimeLL(lonvalpart, lonendchr)
        
        # クラスを使う #
        dll_lat = dll.DigitLL(latvalpart, latendchr)
        dll_lon = dll.DigitLL(lonvalpart, lonendchr)
        
        lat = dll_lat.digitLLFromTimeLL()
        lon = dll_lon.digitLLFromTimeLL()
        
        
        # debug
        print(ident)
        print(latcval + " => " + str(lat))
        print(loncval + " => " + str(lon))
        print("-------------------------------------------")

        tpl = {"type": "", "ident": "", "name": "", "lat": -500, "lon": -500}

        if lat != 0 and lon != 0:
            tpl["type"] = type
            tpl["ident"] = ident
            tpl["name"] = name
            tpl["lat"] = lat
            tpl["lon"] = lon
            tpllist.append(tpl)

< エクセルファイル例 >

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

航空情報 2023年 6月号 [雑誌]
価格:1,425円(税込、送料無料) (2023/5/21時点)

Javascript 時刻形式経緯度十進変換関数

気象や航空関係のデータの経緯度の形式が時刻なものを、Leafletの地図で扱う場合のデータ検証用として、
地名入力してジオコーダーを使って移動させるような処理を、入力値を時刻経緯度で行うために作ってみました。

< コード例 >


/**
 * 時刻経緯度十進変換
 * 
 * @param txt 入力文字列 ex. 353220.86N
 *                            1394906.93E
 */
const getDecLocationFromTimeLocation = (txt) => {

  let res = ""

  const pos_comma = txt.indexOf(".")

  const txt_int_part = txt.slice(0, pos_comma)

  let txt_dec_part = txt.slice(pos_comma + 1)
  txt_dec_part = txt_dec_part.replace("N", "").replace("S", "").replace("W", "").replace("E", "")

  let txt_int = ""
  let txt_min = ""

  //alert(txt_int_part + "\n" + txt_int_part.length)

  // 整数部分、分の切り取り //
  switch (txt_int_part.length) {
    // 整数1桁 //
    case 5:
      txt_int = txt_int_part.slice(0, 1)
      txt_min = txt_int_part.slice(1, 3)
      break
      // 整数2桁 //  
    case 6:
      txt_int = txt_int_part.slice(0, 2)
      txt_min = txt_int_part.slice(2, 4)
      break;
      // 整数3桁 //  
    case 7:
      txt_int = txt_int_part.slice(0, 3)
      txt_min = txt_int_part.slice(3, 5)
      break
  }

  // 秒は常に右2文字
  const txt_sec = txt_int_part.slice(-2)

  //alert (txt_int + ":" + txt_min + ":" + txt_sec + "." + txt_dec_part)


  res = Number(txt_int) +
          Number(txt_min / 60) +
          Number(txt_sec / 3600) +
          Number(txt_dec_part / 360000)

  // 南半球の場合 //
  if (txt.slice(-1) === "S" || txt.slice(-1) === "W") {
    res = res * -1
  }

  return res
}
           

作ってから気づいたのですが、整数部分の分秒の変換は、Pythonでの例ですが、


numInt = int(self.txt)
# 整数部
hourPartVal = int(numInt / 10000)
# 分
minutePartVal = int(numInt / 100) % 100
# 秒
secondPartVal = numInt % 100
minuteVal = minutePartVal / 60
secondVal = secondPartVal / 3600
resval = hourPartVal + minuteVal + secondVal

のようにすれば簡潔になります。

< 利用例 >

AiP JAPANに載っている FIXのWaypoint EPSON がどこにあるか調べる

千葉県にあることがわかる

MySQL 時刻形式経緯度十進変換関数

ページスクレープしたテキストをデータベースに登録する為、seleniumやsoupを使えば、とったテキストが整ってる場合は、自分のプログラムに関数を入れ処理出来ますが、コピペしてエクセルに貼り付けてSQLにしないと出来ないような整理されてないソースだったので、MySQLのUDFで作ってみました。

CREATE DEFINER=`root`@`localhost` FUNCTION `fc_decLL_from_timeLL`(
	`srctxt` VARCHAR(20)
)
RETURNS double
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '時刻経緯度十進変換関数'
BEGIN

DECLARE resLL DOUBLE DEFAULT 0;      -- decimaled return value 

DECLARE pos_comma TINYINT;           -- chart index of .
DECLARE txt_int_part VARCHAR(7);     -- always 7char or 6char
DECLARE txt_dec_part VARCHAR(2);     -- decimal part text
DECLARE chr_nesw CHAR(1);            -- north or east or south or west 

DECLARE txt_int VARCHAR(3);          -- 2 char or 3 char
DECLARE txt_min CHAR(2);             -- always 2 char
DECLARE txt_sec CHAR(2);             -- always 2 char


SET pos_comma = INSTR(srctxt, '.');
SET txt_int_part = LEFT(srctxt, pos_comma - 1);

SET txt_dec_part = SUBSTR(srctxt, pos_comma + 1, pos_comma + 4);
SET txt_dec_part = TRIM('N' FROM txt_dec_part);
SET txt_dec_part = TRIM('S' FROM txt_dec_part);
SET txt_dec_part = TRIM('W' FROM txt_dec_part);
SET txt_dec_part = TRIM('E' FROM txt_dec_part);

-- 整数部分、分の切り取り
IF LENGTH(txt_int_part) = 5 THEN
  SET txt_int = LEFT(txt_int_part, 1);
  SET txt_min = MID(txt_int_part, 2, 2);
ELSEIF LENGTH(txt_int_part) = 6 THEN
  SET txt_int = LEFT(txt_int_part, 2);
  SET txt_min = MID(txt_int_part, 3, 2);
ELSEIF LENGTH(txt_int_part) = 7 THEN
  SET txt_int = LEFT(txt_int_part, 3);
  SET txt_min = MID(txt_int_part, 4, 2);
END IF;

-- 秒は常に右2文字
SET txt_sec = RIGHT(txt_int_part, 2);

SET chr_nesw = RIGHT(srctxt, 1);

SET resLL = CAST(txt_int AS UNSIGNED) + 
            CAST(txt_min AS UNSIGNED) / 60 +
            CAST(txt_sec AS UNSIGNED) / 3600 +
            CAST(txt_dec_part AS UNSIGNED) / 360000;

-- 南半球、西半球の場合            
IF (chr_nesw = 'S' OR chr_nesw = 'W') THEN
  SET resLL = resLL * -1;
END IF;            
 
-- debug
-- INSERT INTO tst (fld0, fld1) VALUES(txt_int_part, txt_dec_part);
-- INSERT INTO tst (fld0, fld1, fld2) VALUES(txt_int, txt_min, txt_sec);

  
RETURN resLL;  
  
END

< テキストソース例 >

< Excel貼付例 >

坂本龍一・遊び創作

遊びは結果を求めませんし、プロセス。僕が音楽を作るのもそんなプロセスが面白いから。子供の砂遊びみたいに、何を作ろうとイメージするのではなく、いじっているうちに形になっていく。それが創作であり、僕にとって創作こそ遊びだと思います。

Python tqdmでプログレス表示

ここで教えて頂きました。

< コード例 >


pos = 0
for icao in tqdm(ICAOS):
  url = BASE_URL.replace("##ICAO##", icao[0])
  driver.get(url)
  time.sleep(5)
  pos += 1
  if pos <= 4:
    continue

< 画面例 >

  
 62%|███████████████████████████████████████████████████████████████████████████████████████████████████████████▋                                                                   | 184/299 [38:59<23:30, 12.26s/it]E55P:64257
{}

CSSでLeafletの画像マーカーの色を変える

Leafletでマーカーに画像ファイルを使ってる場合、同じ形のマーカーで動的に色を変えたい場合、以前は色を違えた別の画像ファイルを用意して、アイコンのURLをセットする方法を行ってましたが、色数が多くなったり中間色を使う場合、別のファイルを用意するのも大変なので何とかならないかと調べてましたところ、
CSSのhue-rotateで色相環の回転位置を使って同じ画像ファイルで色を変えることがわかり試してみました。

ここで教えていただきました。

 

 

 

 

 

< 使った画像 >

黄色


< コード例 >

CSS


  /* 色相環回転色 */
  .acmarker_aqua {
    filter: hue-rotate(150deg);   /* 黄色から150度 */
  }
  .acmarker_orange {
    filter: hue-rotate(-45deg);   /* 黄色から-45度 */
  }
  .acmarker_aquamarine {
    filter: hue-rotate(120deg);   /* 黄色から120度 */
  }
  
  .acmarker_red {
    filter: hue-rotate(-90deg);   /* 黄色から-90度 */
  }
  .acmarker_fuchsia {
    filter: hue-rotate(-135deg);  /* 黄色から-135度 */ 
  }
  .acmarker_yellow {
    filter: hue-rotate(0deg);   
  }
  .acmarker_lightgreen {
    filter: hue-rotate(45deg);   /* 黄色から-45度 */ 
  }
  .acmarker_blue {
    filter: hue-rotate(150deg);  /* 黄色から-150度 */ 
  }
  
  .acmarker_blue_red {
    filter: hue-rotate(150deg);   /* 青から150度 */ 
  }
  
  .acmarker_blue_green {
    filter: hue-rotate(250deg);   /* 青から250度 */ 
  }

javaScript


      // 色相環回転色適用CSSクラス //
      let markerClass = isAquaChange ? "acmarker_aqua" : ""

      if (!isByAltMarker) {
        markerClass = isOrangeChange ? "acmarker_orange" : markerClass
        markerClass = isAquaMarineChange ? "acmarker_aquamarine" : markerClass
        markerClass = isPinkChange ? "acmarker_red" : markerClass
        markerClass = isRedChange ? "acmarker_blue_red" : markerClass
        markerClass = isGreenChange ? "acmarker_blue_green" : markerClass
      }

      // 高度別マーカーの場合 //
      if (isByAltMarker) {

        // 色名ディレクトリ、クラス名取得 //
        const altclass = new Altitude()
        const map = altclass.getIconColorDirClassName(lineitm.altidx)

        const coldir = map["dir"]
        const iconfnm = ICON_URL_OTHEROPE.split("/")[3]
        ICON_URL_OTHEROPE = `Img/apbytype/${coldir}/${iconfnm}`
        markerClass = map["class"]

        // Img/acbytype/yellow/ac_787.png
      }

      // 対象オペレータ飛行中 //
      const acicon = L.icon({
        iconUrl: ICON_URL,
        iconRetinaUrl: ICON_URL,
        iconSize: [szInt, szInt],
        iconAnchor: [szIntHalf, szInt],
        popupAnchor: [0, ppAnchorY],

        className: markerClass
      })
      // 他オペレータ飛行中 //
      const acicon_other = L.icon({
        iconUrl: ICON_URL_OTHEROPE,
        iconRetinaUrl: ICON_URL,
        iconSize: [szInt, szInt],
        iconAnchor: [szIntHalf, szInt],
        popupAnchor: [0, ppAnchorY],

        className: markerClass
      })

JavaScript 画像ディレクトリ、クラス名関数


  /**
   * 高度レベル別飛行機マーカーディレクトリ名クラス名
   * @param {type} level 高度レベル
   * @returns {Altitude.getIconColorDirClassName.map}
   */
  getIconColorDirClassName(level) {

    let map = {"dir": "white", "class": ""}


    if (level === 0) {
      map = {"dir": "blue", "class": "acmarker_blue_green"}
    }
    else if (level === 1) {
      map = {"dir": "blue", "class": "acmarker_blue_red"}
    }
    else if (level === 2) {
      map = {"dir": "fuchsia", "class": ""}  // Fucisia
    }
    else if (level === 3) {
      map = {"dir": "yellow", "class": ""}    // Yellow
    }
    else if (level === 4) {
      map = {"dir": "lightgreen", "class": ""}     // LightGreen
    }
    else if (level === 5) {
      map = {"dir": "blue", "class": ""}     // Blue
    }
    else if (level === 6) {
      map = {"dir": "yellow", "class": "acmarker_aqua"}    // Aqua
    }
    else if (level === 7) {
      map = {"dir": "white", "class": ""}     // white
    }

    return map
  }

< 画面例 >

3AFB Aviaton

飛行機の高度でアイコンの色を変えています。

画像ファイルにない色を使う。