我正在使用 vue 并安装了位于此处的 vue-mapbox 组件:https://soal.github.io/vue-mapbox/#/quickstart
我已将 js 和 css 更新到最新版本,并将其添加到 index.html 中:
<!-- Mapbox GL CSS -->
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css" rel="stylesheet" />
<!-- Mapbox GL JS -->
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js"></script>
我正在尝试利用此组件使用 center
或 bounds
或 fitBounds
到列表来设置 map 边界的默认 View Lng,Lat 坐标。那么,基本上,如何插入 lng,lat 坐标并使 map 默认将这些坐标在容器内居中?
这是我在 vue 中创建的一个名为 Map
的组件,用于使用上面列出的组件 vue-mapbox
输出 map 框:
<template>
<b-row id="map" class="d-flex justify-content-center align-items-center my-2">
<b-col cols="24" id="map-holder" v-bind:class="getMapType">
<mgl-map
id="map-obj"
:accessToken="accessToken"
:mapStyle.sync="mapStyle"
:zoom="zoom"
:center="center"
container="map-holder"
:interactive="interactive"
@load="loadMap"
ref="mapbox" />
</b-col>
</b-row>
</template>
<script>
import { MglMap } from 'vue-mapbox'
export default {
components: {
MglMap
},
data () {
return {
accessToken: 'pk.eyJ1Ijoic29sb2dob3N0IiwiYSI6ImNqb2htbmpwNjA0aG8zcWxjc3IzOGI1ejcifQ.nGL4NwbJYffJpjOiBL-Zpg',
mapStyle: 'mapbox://styles/mapbox/streets-v9', // options: basic-v9, streets-v9, bright-v9, light-v9, dark-v9, satellite-v9
zoom: 9,
map: {}, // Holds the Map...
fitBounds: [[-79, 43], [-73, 45]]
}
},
props: {
interactive: {
default: true
},
resizeMap: {
default: false
},
mapType: {
default: ''
},
center: {
type: Array,
default: function () { return [4.899, 52.372] }
}
},
computed: {
getMapType () {
let classes = 'inner-map'
if (this.mapType !== '') {
classes += ' map-' + this.mapType
}
return classes
}
},
watch: {
resizeMap (val) {
if (val) {
this.$nextTick(() => this.$refs.mapbox.resize())
}
},
fitBounds (val) {
if (this.fitBounds.length) {
this.MoveMapCoords()
}
}
},
methods: {
loadMap () {
if (this.map === null) {
this.map = event.map // store the map object in here...
}
},
MoveMapCoords () {
this.$refs.mapbox.fitBounds(this.fitBounds)
}
}
}
</script>
<style lang="scss" scoped>
@import '../../styles/custom.scss';
#map {
#map-obj {
text-align: justify;
width: 100%;
}
#map-holder {
&.map-modal {
#map-obj {
height: 340px;
}
}
&.map-large {
#map-obj {
height: 500px;
}
}
}
.mapboxgl-map {
border: 2px solid lightgray;
}
}
</style>
因此,我尝试在此处使用 fitBounds
方法来让 map 初始化以 2 Lng,Lat 坐标为中心:[[-79, 43], [-73 , 45]]
具体如何做到这一点?好吧,我想我的代码可能有点错误,所以我认为 fitBounds
应该看起来像这样:
fitBounds: () => {
return { bounds: [[-79, 43], [-73, 45]] }
}
无论如何,将 map 框的初始位置设置为以 2 个或更多坐标为中心是最困难的。有人成功做到这一点了吗?
好的,所以我最终创建了一个过滤器来向 bbox 添加空间,如下所示:
Vue.filter('addSpaceToBBoxBounds', function (value) {
if (value && value.length) {
var boxArea = []
for (var b = 0, len = value.length; b < len; b++) {
boxArea.push(b > 1 ? value[b] + 2 : value[b] - 2)
}
return boxArea
}
return value
})
目前看来这已经足够好了。不仅仅是像这样使用它:
let line = turf.lineString(this.markers)
mapOptions['bounds'] = this.$options.filters.addSpaceToBBoxBounds(turf.bbox(line))
return mapOptions
最佳答案
我创建了一些简单的函数来计算一个边界框,其中包含给定 [lng, lat]
对(标记)的最西南 Angular 和最东北 Angular 。然后,您可以使用 Mapbox GL JS map.fitBounds(bounds, options?)
函数将 map 缩放到标记集。
永远记住:
lng
(lon):经度(伦敦 = 0、伯尔尼 = 7.45、纽约 = -74)
→ 越低,越西
lat
:纬度(赤道 = 0、伯尔尼 = 46.95、开普敦 = -33.9)
→ 越低,越南
getSWCoordinates(coordinatesCollection) {
const lowestLng = Math.min(
...coordinatesCollection.map((coordinates) => coordinates[0])
);
const lowestLat = Math.min(
...coordinatesCollection.map((coordinates) => coordinates[1])
);
return [lowestLng, lowestLat];
}
getNECoordinates(coordinatesCollection) {
const highestLng = Math.max(
...coordinatesCollection.map((coordinates) => coordinates[0])
);
const highestLat = Math.max(
...coordinatesCollection.map((coordinates) => coordinates[1])
);
return [highestLng, highestLat];
}
calcBoundsFromCoordinates(coordinatesCollection) {
return [
getSWCoordinates(coordinatesCollection),
getNECoordinates(coordinatesCollection),
];
}
要使用该函数,您只需调用 calcBoundsFromCooperatives
并输入一个包含所有标记坐标的数组:
calcBoundsFromCoordinates([
[8.03287, 46.62789],
[7.53077, 46.63439],
[7.57724, 46.63914],
[7.76408, 46.55193],
[7.74324, 46.7384]
])
// returns [[7.53077, 46.55193], [8.03287, 46.7384]]
总的来说,使用 Mapbox 的 mapboxgl.LngLatBounds()
函数可能会更容易。
正如 jscastro 的回答中提到的在 Scale MapBox GL map to fit set of markers你可以像这样使用它:
const bounds = mapMarkers.reduce(function (bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(mapMarkers[0], mapMarkers[0]));
然后就打电话
map.fitBounds(bounds, {
padding: { top: 75, bottom: 30, left: 90, right: 90 },
});
关于javascript - 根据多个标记 Lng、Lat 设置 map 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53330202/