開発要求#
最近、組立輸送のプロジェクトを行い、その中に【ルート計画】の機能があります。ユーザーが出発点と終点を入力すると、デフォルトでナビゲーションルートが生成され、経由地を設定して地図のルートを合理的に計画する必要があり、各経由地に対して速度制限を設定する必要があります。
実現プロセス#
1. 高徳のドラッグ機能を使用して経由地を生成する#
<script type="text/javascript">
var map, route, marker;
//基本地図の読み込み
map = new AMap.Map("container", {
resizeEnable: true
});
//初期パスを描画
var path = [];
path.push([116.303843, 39.983412]);
path.push([116.321354, 39.896436]);
path.push([116.407012, 39.992093]);
map.plugin("AMap.DragRoute", function() {
route = new AMap.DragRoute(map, path, AMap.DrivingPolicy.LEAST_FEE); //ドラッグナビゲーションクラスを構築
route.search(); //ナビゲーションパスを検索し、ドラッグナビゲーションを開始
});
</script>
公式のデモは非常に強力で、数行のコードで自由にドラッグできる機能を実現しました。第一印象でこれを使うことにしました。基本機能も満たしています。
公式の実装効果は以下の通りです:
経由地のクリックで速度制限を設定しようとしたところ、公式が生成した経由地にコールバックメソッドを提供していないことに気付き、少し困りました。
経由地クリック方法の設定
// 公式のmousemoveメソッドを使用して、地図上の現在のマウス位置をリアルタイムで取得
triggerClick() {
const that = this
that.map.on('mousemove', function(ev) {
var lnglat = ev.lnglat
that.currentLngLat = lnglat // 緯度経度情報を保存
})
},
addMarkerClick() { // クリック方法を定義
const that = this
var infoWindow = new that.AMap.InfoWindow({
offset: new that.AMap.Pixel(0, -20)
})
// 地図上のマーカー点を取得
setTimeout(() => {
var dom = document.getElementById('container').getElementsByClassName('amap-marker') // 地図上のすべての経由地のDOMを取得
dom = Array.from(dom).filter((item) => {
if (item.style.display !== 'none') {
return item
}
})
dom.forEach((item, index) => { // DOMを遍歴
const img = item.getElementsByTagName('img')[0]
if (img) {
img.onclick = (e) => { // マーカークリックイベント
const list = [ // 緯度経度配列形式データ
that.currentLngLat.lng,
that.currentLngLat.lat
]
const distanceList = this.mapData.waypoints.map(item => { // 各経由地から現在の点までの距離リストを取得
const p = [item.lng, item.lat]
return that.AMap.GeometryUtil.distance(list, p)
})
const min = Math.min.apply(null, distanceList) // 現在位置に最も近い点を取得
const index = distanceList.indexOf(min) // インデックスを取得
const currentPoint = this.mapData.waypoints[index] // クリックされた経由地の緯度経度データを取得
const LngLat = new that.AMap.LngLat(currentPoint.lng, currentPoint.lat)
infoWindow.setMap(that.map)
// マーカー情報表示内容を設定
const speedLimit = currentPoint.speedLimit ? currentPoint.speedLimit + 'KM' : '未設定'
infoWindow.setContent(
'<b>警報情報 </b> <br/><br/>' +
'<b> 限速: </b> <span class="speed-input">' + speedLimit + '</span><br/><br/>' +
`<button id="closeBtn" type="button" class="el-button el-button--small" "><span>閉じる</span></button> <button id="editBtn" type="button" class="el-button el-button--primary el-button--small"><span>設定</span></button>`
)
infoWindow.open(that.map, LngLat) // ポップアップメッセージを開く
setTimeout(() => {
document.getElementById('closeBtn').onclick = () => {
infoWindow.close()
}
document.getElementById('editBtn').onclick = () => {
that.limitSet(index)
}
}, 500)
}
}
})
}, 500)
}
ここまで来ると、基本的に望んでいた効果を達成できました。
しかし、公式 API の制限により、16 個以上のネットポイントがあるとこのような状況が発生しました。
16 個以上の点があると、前の点がルート計画の範囲内にないため、これは明らかに問題です。
2. 公式のドラッグ方法を放棄し、経由地計画ルートを実現#
時間の関係で、まず最終的な完成効果を展示し、具体的な実現方法は次回に補完します。
3. ソースコード#
今日は少し時間をかけて地図のデモを整理しました。基本機能を公開しましたので、具体的なビジネスロジックは皆さんのニーズに応じて調整してください。
github ソースコードアドレス
基本インタラクション
ルート詳細表示