GIS
foss4g
Cesium
japanmesh
CesiumDay 2

Cesiumの地図上のマウスイベント処理で、ひたすら3次メッシュを表示する

More than 1 year has passed since last update.

目的

基本的な操作である、マウス操作によるイベント処理について実装します。

最終成果物の外観

fig1.png

マウスカーソル付近に、緯度経度とメッシュコードが表示されます。
クリックすると、コンソールログに緯度経度とメッシュコードが出力されます。

公開先

 http://jsdo.it/tkama/QHvx

エラー表示がなされる場合が在りますが、実行ボタンを押下して頂ければ動作します。。。

地図上にマウスイベントリスナーの設置

Cesiumのチュートリアルにマウスやキーボードのイベントリスナーの設置についての記載があります。
Custom Camera mouse/keyboard events

サンプルコードも公開されています。
https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Picking.html&label=Showcases

マウスの移動イベント発生時の座標取得

マウスカーソルの位置を取得し、地球上にカーソルがあるか、ある場合はその緯度経度を取得する処理です。

/*
* マウス移動のイベントリスナーを設置
*/
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(
    function(movement) {
        var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
        //マウスが地球上にあることを判定
        if (cartesian) {
            //位置情報を管理するオブジェクトcartographicを取得
            var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            //緯度経度を小数点5桁で取得
            var lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
            var lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);


        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE
);

左クリックのイベント発生時の座標取得

チュートリアルにあるように、イベントをMOUSE_MOVEからLEFT_DOWNにイベント種別を切り替える事で実現可能であると思いましたが、エラーが出てしまい座標の取得が出来ませんでした。

下記のサイトに、Canvasに対してクリックイベントのリスナーを設置する方法で動きました。
http://www.phpmind.com/blog/2015/11/cesiumjs-how-to-get-longitude-and-latitude-on-click/

/*
 * Click event 
 */
viewer.canvas.addEventListener('click',
    function(e) {
        var mousePosition = new Cesium.Cartesian2(e.clientX, e.clientY);
        var ellipsoid = viewer.scene.globe.ellipsoid;
        var cartesian = viewer.camera.pickEllipsoid(mousePosition, ellipsoid);
        if (cartesian) {
            //位置情報を管理するオブジェクトcartographicを取得
            var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            //緯度経度を小数点5桁で取得
            var lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
            var lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);

        }
    }, false
);

緯度経度から3次メッシュを計算する関数

メッシュコードの基本的な仕様を元に、変換関数を作成しました。

/**
 *  3次メッシュを算出する関数
 * @param  <Number>  lon (required) 経度 122度以上154度未満
 * @param  <Number>  lat (required) 緯度 20度以上46度未満
 * @return <Number>
 **/
function lonlat2jmesh(lon, lat) {

    if (lat >= 20 && lat < 46 && lon >= 122 && lon < 154) {

        var p = Math.floor(lat * 60 / 40);
        var a = (lat * 60) % 40;
        var q = Math.floor(a / 5);
        var b = a % 5;
        var r = Math.floor(b * 60 / 30);

        var u = Math.floor(lon - 100);
        var f = lon - 100 - u;
        var v = Math.floor((f * 3600) / (7 * 60 + 30));
        var g = (f * 3600) % (7 * 60 + 30);
        var w = Math.floor(g / 45);

        var jmesh = p + "" + u + "" + q + "" + v + "" + r + "" + w;
        return jmesh;
    } else {
        return null;
    }
}

マウスの移動、左クリックのイベント発生時に、緯度経度を取得し、3次メッシュの値を求めることで、目的を達成することが出来ました。