mapbox で地図を見ている時に、基準となる長さを表示しておきたかったのですが、調べた限りではそういったコントロールはありませんでした。
Mapboxでは自分でカスタムコントロールが作れるようなので、簡易的な距離表示コントロールを作ってみました。
GoogleMapsの距離表示は動的に長さや基準が変わりますが、
今回は手を抜いて
- コントロールは右下に常に同じサイズで表示
- ズーム変更でコントロールの長さに応じた距離を表示
という仕様にしました。
コントロールの引数として長さや距離の単位を渡すには、コンストラクタに当たる部分で
function DistanceGaugeControl(_options) { this._options=_options; } // _options={ width:200, units:'kilometers' }
のようにすれば良いようです。
まずはコントロールを下記のように定義し、
function DistanceGaugeControl(_options) { this._options=_options; }
DistanceGaugeControl.prototype.onAdd = function(_map) {
this._map = _map;
this._width = (this._options?.width??200);
this._units = (this._options?.units??'kilometers');
this._gaugeArea = document.createElement('button');
this._gaugeArea.style="position: relative; width: "+this._width+"px; background: #eee; font-size: 12px;";
this._gaugeArea.innerText = '?km';
this._container = document.createElement('div');
this._container.className = 'mapboxgl-ctrl';
this._container.appendChild(this._gaugeArea);
//this._map.addEventListener('mousemove', ()=>{ this._gaugeButton.innerText="moved"; });
this._map.on('zoom', (e) => { this.calcDist(); });
this.calcDist();
return this._container;
};
DistanceGaugeControl.prototype.onRemove = function () {
this._container.parentNode.removeChild(this._container);
this._map = undefined;
};
DistanceGaugeControl.prototype.calcDist = function(){
const coordinate0 = new mapboxgl.Point(0, 0);
const coordinate1 = new mapboxgl.Point(this._width, 0);
const lngLat0 = map.unproject(coordinate0);
const lngLat1 = map.unproject(coordinate1);
//const distkm = turf.distance(turf.point([lngLat0.lng,lngLat0.lat]), turf.point([lngLat1.lng,lngLat1.lat]), {units: this._units});
const distkm = lngLat0.distanceTo(lngLat1)*0.001;
this._gaugeArea.innerText= distkm.toFixed(1)+((this._units=='kilometers')?"km":"ml");
}
定義したコントロールを
var kmControl = map.addControl(new DistanceGaugeControl({ width:200, units:'kilometers' }),'bottom-right'); // miles or kilometers
のようにmap.addControlに渡せば表示されます。
'bottom-right'
を 'bottom-left'
にすると、
ちゃんとmapboxのロゴを避けて左下に表示されます。賢い!