Leaflet Javascript AlmostOver でポリラインのイベント

Leaflet Javascriptで、GeoJSONから読み込んだポリラインに対してイベントをつける必要があり、
mouseover, mouseoutのイベントが発火しにくいので、調べてましたところ AlmostOver のプラグインで解決しました。

< コード例 >

HTML


<!-- Leaflet almostover -->
<script type="text/javascript" src="Script/js/leaflet.almostover.js"></script>

Javascript


        // almost over //
        lmap.almostOver.addLayer(DrawLine.amlinejson);

        // @@ 線をクリックした時 @@ //
        lmap.on('almost:click', function (e) {
         
         if (DrawLine.thickLines) {
         lmap.removeLayer(DrawLine.thickLines)
         }
         // if (RailLines.stationsjson) {
         //   lmap.removeLayer(RailLines.stationsjson)
         // }
         
         
         //console.log("--- e.target")
         //console.log(e.target)
         
         const layer = e.layer
         const pp = layer.feature.properties
         
         // 線を太くする //
         const tgtjson = new getComlineJSON(datas, pp.NAME)
         //console.log(tgtjson)
         
         DrawLine.thickLines = L.geoJson(tgtjson, {
         
         // スタイル //
         style: {color: "#00FFFF", weight: 7}
         
         }).addTo(lmap)
         
         //const comline = pp.NM_COM + " " + pp.NM_LINE
         //$("#raillinespn").text(comline)
         
         // リクエスト引数リスト名 //
         //const listnm = "国交 " + pp.NM_COM + " " + pp.NM_LINE
         //alert(listnm)
         
         // 駅簡略化マーカー描画 //
         //const rl = new RailLines()
         //rl.getStationsMarker(listnm)
         
         });

< 画面例 >

マウスが乗った線を太くする

国土交通省 国土数値情報

飛行機のライブ地図で空港の境界線もわかれば面白いので、探してましたところ、国土交通省・国土数値情報・空港データでできることがわかり使ってみました。

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-C28-v2_4.html

< コード例 >

直接GeoJSONを読み込むわけではなく、データベースに問い合わせて対象リストのGeoJSONを生成するAPIを使ってますので、長くなるので省略

< 画面例 >

Leaflet JavaScript OpenRailwayMap

Leafletの地図に鉄道線路、駅を表示する必要があり、探しましたところベースレイヤーでOpenRailwayMapというのが見つかり使ってみました。

 

< コード例 >

レイヤー選択にOpenRailwayMapを加える


{
        label: '鉄道路線図',
        url: 'http://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png',
        attr: {
          minZoom: 2,
          maxZoom: 19,
          tileSize: 256,
          attribution: '<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>, Style: <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA 2.0</a> <a href="http://www.openrailwaymap.org/">OpenRailwayMap</a> and OpenStreetMap'
        },
        ldtp: "L"
      },

OpenStreetMapを重ねる必要があります。


   let baseMaps = {};
    let curkey = "";
    let objlayer;
    $.each(leyers, function (j, itm) {
      curkey = itm["label"];
      objlayer = L.tileLayer(itm["url"], itm["attr"]);
      baseMaps[curkey] = objlayer;
    });

    // layersコントロールにbaseMapsオブジェクトを設定して地図に追加
    // コントロール内にプロパティ名が表示される

    L.control.layers(baseMaps).addTo(lmap);
   
    let tgtbase = baseMaps[layerkey];
    tgtbase.addTo(lmap);

    //baseMaps["OpenRailwayMap"].addTo(lmap)

    // 鉄道地図の場合、OpenStreetmapも重ねる必要あるので //
    if (layerkey.includes("OpenRailwayMap")) {
      const addmap = layerkey.includes("satellite") ? "Google satellite" : "Open street map"
      const osbase = baseMaps[addmap]
      try {
        osbase.addTo(lmap);
      }
      catch (e) {
      }

    }
    else {
      $("#legend").hide()
    }

< 画面例 >

Leaflet JavaScript マウスオーバーでポリラインを強調

鉄道路線図が入った地図で、ポリラインのセグメントにマウスが乗った時、その線を強調させてみました。

< コード例 >


    let thickLines

    // -- フィルターされたJSONのfeaturesを走査 -- //  
    const geojson = L.geoJson(json, {
      // 非強調、通常のスタイル //
      style: function (feature) {
        return {color: linecol, weight: 2.0}
      },
      onEachFeature: function (feature, layer) {

        const pp = feature.properties

        // @@ マウスが乗った時 @@ //
        layer.on('mouseover', function (e) {


          // 線を太くする //
          const tgtjson = new RailLines().getComlineJSON(json, pp.NM_COM, pp.NM_LINE)
          //console.log(tgtjson)

          thickLines = L.geoJson(tgtjson, {
            style: {color: linecol, weight: 7}
          }).addTo(lmap)

          const comline = pp.NM_COM + " " + pp.NM_LINE
          $("#raillinespn").text(comline /*+ " " + tgtjson["distKM"] + " Km"*/)


        })

        // @@ 乗ったマウスが外れた時 @@ //
        layer.on('mouseout', function (e) {
          //$("#raillinespn").text("")

          // 線を元に戻す //
          lmap.removeLayer(thickLines)

        })

      },
      pointToLayer: function (feature, latlng) {
      },
    })
    // マップに追加 //
    geojson.addTo(lmap);
    // 消去用配列に追加 //
    RailLines.lines.push(geojson)

  /**
   * 指定路線全線強調用GeoJSON取得
   * @param {type} json 全路線JSON
   * @param {type} com 会社名
   * @param {type} line 路線名
   * @returns {RailLines.getComlineJSON.raillinesAnonym$0} 連想配列
   */
  getComlineJSON(json, com, line) {

    const fts = json["features"]
    const tf = new MyTurf()

    let resfts = []
    let ttldst = 0

    fts.forEach((ft, i) => {
      const pp = ft.properties
      if (pp.NM_COM === com && pp.NM_LINE === line) {
        resfts.push(ft)


        const coords = ft.geometry.coordinates
        coords.forEach((cd, k) => {
          if (k > 0) {
            ttldst += tf.getDistanceM(cd, coords[k - 1])
          }
        })
        
      }
    })
    const distKM = Math.round(ttldst / 1000 * 100) / 100  // ???? 短い

    return {
      type: "FeatureCollection",
      features: resfts,
      distKM: distKM
    }

  }

< 画面例 >

Leaflet JavaScript マウスオーバーでマーカーを強調

< コード例 >

マウスオーバー用拡大アイコン


 // 通常サイズ用 //
  // 通常 //
        const icn = L.icon({
          iconUrl: "Img/aptower_50_" + iconcol + ".png",
          //shadowUrl: 'leaf-shadow.png',
          iconSize: [sz, sz]
        });
 
 // マウスオーバー用 //
        const icnmon = L.icon({
          iconUrl: "Img/aptower_64_yellow.png",
          //shadowUrl: 'leaf-shadow.png',
          iconSize: [38, 38]
        });

マウスが乗った時にマウスオーバー用拡大アイコンをセット
外れた時は元のサイズに戻す


// @@ マウスが乗った時 @@ //
        marker.on("mouseover", function (e) {
          // 大きい黄色のアイコンに変える //
          marker.setIcon(icnmon)
        })
        // @@ マウスが外れた時 @@ //
        marker.on("mouseout", function (e) {
          // からし色並サイズアイコンに戻す //
          marker.setIcon(icn)

        })

< 画面例 >

通常サイズ

拡大サイズ

Python 基本メモ import_moduleでクラスを動的import

Pythonで書いた1回限りの処理用の使い捨てスクリプトをスケジュールで定期的に処理する必要があって、調べてましたが、まだ初心者で、ダブルアンダースコアの変数の使い方がよくわからず、
意図した動作が出来ないので、使うスクリプトをクラスにしましたところ、うまく動きめでたく解決しました。
昔、Javaのリフレクションを使って同様のことをしてましたが、長いコードが必要だったのが、短く済みすっきりと出来ました。

< コード例 >

コマンドライン引数で指定した自作モジュールのインポート



import importlib

# クラス名引数 #
args = sys.argv
module_name = ""
if len(args) != 2:
    print("No argument unable to continue!!")
    sys.exit()
    #module_name = "MatsumotoClass" 
else:
    module_name = args[1] + "Class"

sttm = int(time.time())

## 動的モジュール読込 ##
mod = importlib.import_module(module_name)
## インスタンス化 ##
md = mod.ExecClass()

Python 基本メモ 関数内関数

Javascriptと同じく関数内関数が使えるので使ってみました。
別の関数にするまでもない短いのや、勘違いして必要なデータ取得が欠けた時とかに使ってます。

< コード例 >


    # 店舗ページから住所取得 #
    def getAddr (url) -> str: 
      soup = sp.Soup.getSoupText(URL_TOP + url)
      return soup.find_all("td")[0].text[10:]
    
    namelist = [p.text for p in soup.find_all("p", class_="title") 
                if p.text.endswith("店")]
    # 住所が別ページだったので関数内関数で取得 #
    addrlist = [getAddr(p.find("a")["href"]) for p in soup.find_all("p", class_="title") if p.text.endswith("店")]

Python 基本メモ Googleジオコーダー

クラスにしてみました。


import googlemaps

class Google:
    
    API_KEY = "???????????????????????????????????????"
  
    '''
    コンストラクタ
    '''

    def __init__(self, address):
        self.address = address
    
    # ジオコーダー実行 経緯度、郵便番号返却 #
    def getLatLonZip(self) -> dict:
        
        dict = {"lat": -500, "lon": -500, "zip": "000-0000"}
        
        gmaps = googlemaps.Client(key=Google.API_KEY)
        result = gmaps.geocode(self.address)
        #print(result[0])
        
        if len(result) > 0:
            lat = result[0]["geometry"]["location"]["lat"]
            lon = result[0]["geometry"]["location"]["lng"]
        
            dict["zip"] = ""
            addrcomps = result[0]["address_components"]
            for adc in addrcomps:
                if adc["types"][0] == "postal_code":
                     dict["zip"] = adc["long_name"]
                 
            print (lat,lon, zip)
        
            dict["lat"] = lat
            dict["lon"] = lon
        
        return dict

import


import geoclass.Google as g

呼び出し


 # 経緯度、郵便番号ジオコーダー #
 geo = g.Google(addr)
 llz = geo.getLatLonZip()