Leafletの平面図上にキャンバスを表示するサンプルプログラムです。
Leafletにもキャンバスを使って描画する機能はありますが、Leafletを使わないで作成したキャンバスオブジェクトをLeafletの地図と重ねて表示したり、Leafletを使わずに直接キャンバスオブジェクトに描画したりするためのサンプルプログラムです。
サンプルプログラムでは、LeafletのCRS座標系を使ったCADの平面図の上に、キャンバスを重ねて表示しています。
Leafletの地図上に、キャンバスを重ねて表示することも可能です。
このサンプルでは、自作プラグインを利用しています。
このページのプラグインをダウンロードすることで、すぐに利用できます。
ただ、Leaflet Ver1.7.1で動作確認を行っています。
Leaflet本体を拡張して作成し、非公開の内部変数も参照しているため、Leafletのバージョンが変わると動作しない可能性があります。
その点だけは、ご注意ください。
自作プラグインは、LeafletのImageOverlayクラスを拡張した、CanvasOverlatクラスで、キャンバスを画像と同様に表示するためのプラグインです。
描画機能の他に、キャンバスの座標系と地図の座標系の変換機能を追加してあります。
HTML、CSSのソースは、地図にボタンを表示と同じです。
平面図の上に重ねたキャンバス上に、線や円などを表示するサンプルプログラムです。
Leafletで線や円などのベクタデータを表示と同じような表示ですが、LeafletのAPIを使わずに、キャンバス上にキャンバスのAPIを使って描画しています。
自作プラグインのAPIで、地図の座標をキャンバスの座標に変換することで、LeafletのAPIと同様の表示を行うことができます。
キャンバスに描画する場合、CanvasOverlayのgetContextメソッドで描画オブジェクトを取得し、キャンバスのmoveTo、lineToメソッドで線分を描画し、arcメソッドで円を描画しています。
詳しくは、キャンバスのAPI仕様書を見てください。
LeafletのAPIで描画する場合は、地図内であれば、すべて描画されますが、キャンバス上に描画する場合は、キャンバスの外はクリップされてしまい描画されません。
サンプルプログラムでは、クリップされる位置に、円を描画しています。
function init() { // 初期処理
・・・・・
canSize = [2000, 1245]; // 横, 縦
canRange = [[-1.399, -3.272], [5.710, 8.148]]; // 左下[y,x], 右上[y,x]
bound = L.latLngBounds(canRange); // 表示領域の設定
L.imageOverlay('img/plan01.png', bound).addTo(map); // 背景画像の表示
map.fitBounds(bound);
canLay = L.canvasOverlay(canSize, canRange);
canLay.addTo(map);
let ctx = canLay.getContext();
if (ctx != null) {
// map座標でキャンバスに線分を表示
ctx.beginPath();
ctx.strokeStyle = "#00aa00";
ctx.lineWidth = 6;
let p1 = canLay.map2can([3, 2]); // y, x の配列でも記述可能
ctx.moveTo(p1.x, p1.y);
let p2 = canLay.map2can([5, 3]); // y, x の配列でも記述可能
ctx.lineTo(p2.x, p2.y);
ctx.closePath();
ctx.stroke();
// map座標でキャンバスに円を表示
ctx.beginPath();
ctx.strokeStyle = "#aa0000";
ctx.lineWidth = 6;
let r = 1 / canLay.getScale();
ctx.arc(p2.x, p2.y, r, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.stroke();
// キャンバス全体に×を表示
ctx.beginPath();
ctx.strokeStyle = "#0000aa";
ctx.lineWidth = 6;
ctx.moveTo(0, 0); // x, y
ctx.lineTo(2000, 1245);
ctx.moveTo(0, 1245); // x, y
ctx.lineTo(2000, 0);
ctx.closePath();
ctx.stroke();
// キャンバス中心の円をmap側に重ねて表示
let p0 = canLay.can2map([1000, 623]); // x, y
L.circle(p0, 0.2, {color: '#00ddff'}).addTo(map);
}
}
キャンバスは、CanvasOverlayクラスで自動的に作成しますが、canvasオプションでLeafletを使わないで作成したキャンバスオブジェクトを渡すこともできます。
また、CanvasOverlayクラスは、ImageOverlayクラスを継承していますので、opacityや、zIndexなどのオプションも利用できます。
// キャンバスのオプション設定
// canLay = L.canvasOverlay(canSize, canRange);
let canvas = document.createElement('canvas');
canLay = L.canvasOverlay(canSize, canRange, {
canvas: canvas,
opacity: 0.9,
zIndex: 20
});
canLay.addTo(map);
サンプルプログラムでは、座標値を配列で指定していますが、地図座標はlat,lngで、キャンバス座標はx,yで指定することもできます。
LeafletのAPIは、配列形式とハッシュ形式の両方に対応しているため、座標変換APIも、どちらの形式にも対応しています。
// 地図座標の指定
// let p1 = canLay.map2can([3, 2]); // y, x を配列で記述
let p1 = canLay.map2can({lat: 3, lng: 2}); // y, x をハッシュで記述
・・・・・
// キャンバス座標の指定
// let p0 = canLay.can2map([1000, 623]); // x, y を配列で記述
let p0 = canLay.can2map({x: 1000, y: 623}); // x, y をハッシュで記述
leaflet_canvasプラグインは、ImageOverlayクラスを拡張したCanvasOverlayクラスとして作成しました。
Leafletの地図上に、画像を表示するのと同様に、キャンバスオブジェクトを表示できます。
描画機能の他に、キャンバスの座標系と地図の座標系の変換機能を追加してあります。
座標変換に必要な、キャンバスオブジェクトのサイズと、地図上の座標値を指定する必要があります。
●CanvasOverlayを作成
lay = L.canvasOverlay(size, range, options);
size: キャンバスの大きさ 横, 縦
range: キャンバスの表示位置 左下[y,x], 右上[y,x]
options: オプション
canvas: 表示するキャンバスオブジェクト(省略時は自動生成)
opacity: 透過度(0-1)
zIndex: 表示順位 z-indexの値
返却値: CanvasOverlayオブジェクト
●キャンバスの2D描画オブジェクトを取得
ctx = lay.getContext();
返却値: キャンバスの2D描画オブジェクト
●キャンバスの描画スケールを取得
scl = lay.getScale();
返却値: キャンバスの描画スケール
●地図座標系をキャンバス座標系に変換
canPos = canLay.map2can(mapPos);
mapPos: 地図上の緯度経度
返却値: キャンバスの座標値
●キャンバス座標系を地図座標系に変換
mapPos = canLay.can2map(canPos);
canPos: キャンバスの座標値
返却値: 地図上の緯度経度
CanvasOverlayクラスは、ImageOverlayクラスを拡張していますので、ImageOverlayクラスを利用することができると思いますが、すべての動作確認は行っていません。
本プラグインのカスタマイズは自由ですので、機能が足りない場合は、プログラムを修正して利用してください。
leaflet_canvasプラグインは、無料で利用することができます。 ただ、著作権は放棄していませんので、著作権表示は残しておいて下さい。 このソフトの利用は、無サポート無保証となります。 もし、サポートが必要な場合は、仕事としてお受けすることは可能ですので、ASH有限会社までご相談ください。