地図上のオブジェクトの色を変更する
マップ上に表示したポリゴンやラインなどのオブジェクトの、スタイルを変更する手法について記載します。
成果物デモ公開先: http://jsdo.it/tkama/Ov1W
オブジェクトの表示
2017年 Cesium アドベントカレンダー 5日目のソースコードを改造してみます。
・Qiita記事
https://qiita.com/takahi/items/238c604f71ca0c1302d4
・ソースコード設置先
http://jsdo.it/tkama/kQnc
変更対象のオブジェクト(Entity)の取得
Cesiumのチュートリアルのサイト Visualizing Spatial DataのManaging Entitiesの章を参考にします。
手法: idを指定してオブジェクト(CesiumではEntity)を取得する
var et = viewer.entities.getById("Entity作成時に指定した文字か数字");
予め、後で制御することを考えて、Entity作成時の戻り値を変数や配列で保持しておく手法を試しましたが、複数のEntityを生成した場合などでは上手く動作しませんでした。
Entityへのスタイル変更
entities.getByIdで取得したentityに対して、表示仕様を変更します。
表示はmaterial
のパラメータを指定する事で実現します。
entityは階層構造をもっており、entity.[オブイェクト(polygon,box,等)].material
と3階層目に当たります。
materialは色や透明度の他に、テクスチャなども貼ることが出来ます。
色の設定
色と透明度はColorを定義することで指定がかのうです。
色の指定方法は、非常にたくさんあります.
https://cesiumjs.org/Cesium/Build/Documentation/Color.html
-
RGBA指定
Cesium.Color.fromBytes(red, green, blue, alpha, result)
-
CSS表記
Cesium.Color.fromCssColorString(color, result)
-
ランダムカラー
Cesium.Color.fromRandom({alpha:1.0});
テクスチャ画像の指定
画像が公開されているURLを指定すればOKのようです。
その際にhttp:
やhttps:
など通信方式を表記する「URLスキーム」の記述は不要のようです。
例) 私のQiitaのアイコンのURI
https://qiita-image-store.s3.amazonaws.com/0/53918/profile-images/1473693208
↓
Cesiumのテクスチャとして指定する場合
' "//qiita-image-store.s3.amazonaws.com/0/53918/profile-images/1473693208" `
実装
元々水色で表示されているものを、ランダムカラーで置き換えるプログラムを記載しました。
ソースコード全体は、こちらを参照して下さい。
//Cesium地図ビューワの作成
var viewer = new Cesium.Viewer('cesiumContainer');
var entities = viewer.entities;
var ids = 0;
//100個の3次メッシュを追加
for( var i = 0 ; i< 100 ; i++ ){
viewer.entities.add(getJapan3rdmeshRectangle( 53394500 + i , 100*i , 0xccff6666 , String(53394500 + i) ));
}
//Rectangle Dynamic Color Control.
setInterval(
function( ){
if (ids == 100 ){
ids = 0 ; //処理を循環させるための処置
}else{
//更新対象のentityのidを生成
var id = 53394500 + ids++;
//idを指定してentityを取得し、そのままmaterialにランダムカラーを指定
viewer.entities.getById( id ).rectangle.material = Cesium.Color.fromRandom({alpha: 0.9});
};
}, 1000); //1000ミリ秒のスリープ
viewer.zoomTo(viewer.entities);
/**
* 3次メッシュ3D棒グラフオブジェクト作成関数
* @param <Number> meshcode3rd (required) 3次メッシュコード
* @param <Number> h (required) 高さ(単位メートル)
* @param <string> color_abgr (required) 色
* @param <string> description_text (required) オブジェクトの説明文
* @retrun <object> ans_entities rectangleオブジェクト
**/
function getJapan3rdmeshRectangle( meshcode3rd , h, color_abgr , description_text ){
var strMeshcoe = String(meshcode3rd);
var p = parseInt(strMeshcoe.slice(0,2));
var u = parseInt(strMeshcoe.slice(2,4));
var q = parseInt(strMeshcoe.slice(4,5));
var v = parseInt(strMeshcoe.slice(5,6));
var r = parseInt(strMeshcoe.slice(6,7));
var w = parseInt(strMeshcoe.slice(7,8));
var lat = p / 1.5 + q * 1 / 12 + r * 1 / 120;
var lon = u + 100 + v * 0.125 + w * 0.0125;
var ans_entities = {
id:meshcode3rd ,
description : "<p>"+description_text+"</p>",
rectangle : {
coordinates : Cesium.Rectangle.fromDegrees( lon , lat , lon+0.0125 , lat+0.008333333 ),
height : h,
extrudedHeight : 0,
material : Cesium.Color.fromRgba( color_abgr )
}
};
return ans_entities ;
}
まとめ
一度登録したオブジェクトを再度制御するためには、ライブラリであるCesiumの管理している仕様に合わせる必要があるため、結構躓くことがありました。