123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 |
- <template>
- <view class="container-box">
- <view :id="mapId" class="container"></view>
- <!-- info window弹框窗体 -->
- <component :is="componentView" ref="componentViewRef" />
- <slot></slot>
- </view>
- </template>
- <script>
- import Vue from 'vue'
- import AMapLoader from '@amap/amap-jsapi-loader';
- import { createPulseLinkLayer, createMarkerCluster, createMoveAlong, createMarker, createPolylineShow } from "./controller/createApi";
- import { uniqueId,isEmpty } from 'lodash'
- import {getMaxMinBounds,listCrudChange} from '@/utils/gdtq.js'
- /**地图展示相关组件*/
- import vehicleInfo from './components/vehicleInfo.vue';//聚合车辆弹框
- import pastRoute from './components/pastRoute.vue'; //轨迹弹框
- //组件映射
- const componentsMapDefault = {
- markerCluster: vehicleInfo,
- moveAnimation: pastRoute,
- }
- export default {
- components: {
- },
- props: {
- //外部重置默认弹窗组件
- componentsMapProps: {
- type: Object,
- default: () => {}
- },
- mapConfig: {
- type: Object,
- default: () => { }
- },
- pointsData: {
- type: Array,
- default: () => []
- },
- pointsDataConfig: {
- type: Object,
- default: () => { }
- },
- toolMapKey: { //markerCluster moveAnimation(轨迹回放)
- type: String,
- default: 'markerCluster'
- },
- isCreateInfoWindow: {
- type: Boolean,
- default: true
- },
- infoWindowConfig: {
- type: Object,
- default: () => {
- return {
- isCustom: true
- }
- }
- },
- //城市定位
- enableCityPositon: {
- type: Boolean,
- default: true
- }
- },
- watch: {
- pointsData: function(pointsData, prevPointsData) {
- /**对比改变后的数据做业务处理*/
- // console.log('watch地图数据', pointsData, prevPointsData)
- if (this.map === null) return;
- this.createProjects(this.toolMapKey, { points: this.pointsData, prePoints: prevPointsData })
- }
- },
-
- data() {
- return {
- map: null,
- mapId: uniqueId('gaode_map_'),
-
- /* 聚合相关 */
- cluster: undefined, //点聚合实例
-
- /* 轨迹相关 */
- createMoveAlongFn: null,//轨迹回放响应式实例对象
- allmarkerPro: undefined,
- isMoveAlongWindow: undefined,
-
- /* 弹窗相关*/
- createInfoWindow: undefined,
- componentView: undefined,
-
- satelliteLayer: '', //卫星图
-
- trafficLayer: '', //实时路况
-
- isMoveAlongWindow: false,
- }
- },
-
-
- mounted() {
- let that = this;
- //组件映射
- this.componentsMap = Object.assign(componentsMapDefault,this.componentsMapProps)
-
- /* 窗体相关 */
- this.createInfoWindow = function createInfoWindowFn() {
- let infoWindow;
- let cluster2;
-
- function add(data) {
- let { cluster, clusterData, lnglat, offset, componentsMapKey } = data
- if (clusterData) {
- cluster2 = clusterData.length > 0 ? clusterData : [cluster.p]
- }
-
- that.componentView = that.componentsMap[componentsMapKey]
-
- that.$nextTick(() => {
- console.log(that.$refs.componentViewRef,'that.that.$refs.componentViewRef')
- that.$refs.componentViewRef.callBack(data, closeWindow)
-
- if (clusterData?.length > 1) return;
- infoWindow = new AMap.InfoWindow({
- ...that.infoWindowConfig,
- content: that.$refs.componentViewRef.$el,
- offset: offset
- });
- that.map.on('click', function () {
- infoWindow.close();
- });
- setTimeout(() => {
- infoWindow.open(that.map, [lnglat.lng, lnglat.lat]);
- infoWindow.setOffset(new AMap.Pixel(0, -23));
- }, 0);
- })
-
- }
-
- function setPosition(data) {
- infoWindow.setPosition(data);
- }
-
- function closeWindow() {
- if (infoWindow) {
- infoWindow.close();
- }
- }
-
- function getItem() {
- return cluster2
- }
-
- function getinfoWindow() {
- return infoWindow
- }
-
- return {
- add: add,
- setPosition: setPosition,
- closeWindow: closeWindow,
- getItem: getItem,
- getinfoWindow: getinfoWindow,
- };
- }()
-
-
- this.initMap()
- },
-
- methods: {
-
- initMap() {
- AMapLoader.load({
- key: "08d130e013f96dcf4329cf7bac274c8e", // 申请好的Web端开发者Key,首次调用 load 时必填
- version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
- plugins: [
- 'AMap.MarkerCluster', 'AMap.Polyline', 'AMap.MoveAnimation', 'AMap.CircleEditor',
- 'AMap.Driving', 'AMap.AutoComplete', 'AMap.Scale','AMap.MouseTool', 'AMap.Geolocation','AMap.CitySearch',
- ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
- Loca: { // 是否加载 Loca, 缺省不加载
- "version": '2.0.0' // Loca 版本,缺省 1.3.2
- },
- }).then((AMap) => {
- console.log('AMap Load','data')
- this.map = new AMap.Map(this.mapId, { //设置地图容器id
- viewMode: "3D", //是否为3D地图模式
- zoom: 3, //初始化地图级别
- center: [105.602725, 37.076636], //初始化地图中心点位置
- ...this.mapConfig
- });
- this.createProjects(this.toolMapKey, { points: this.pointsData, pointsDataConfig: this.pointsDataConfig })
-
- this.map.addControl(new AMap.Scale());
-
- if(this.enableCityPositon) {
- this.citySearch()
- }
-
-
- this.$emit('onload', this.map)
- }).catch(e => {
- console.log(e);
- })
- },
- createProjects(key, data, callBack) {
- if (!key) return
- const toolMapFn = {
- pulseLinkLayer: () => {//飞线
- createPulseLinkLayer(this.map, data, callBack);
- },
- markerCluster: () => {//创建聚合点
- if (!this.cluster) {
- this.cluster = createMarkerCluster(this.map, data, (e) => {
- const { clusterData, lnglat } = e
- if (clusterData.length > 1) {
-
- let {southWest,northEast} = getMaxMinBounds(clusterData.map((e) => [e.item.lng,e.item.lat]))
- let bounds = new AMap.Bounds(southWest, northEast)
-
- this.map.setBounds(bounds,true,[80, 80, 40, 40])
- }
-
- // console.log(e, 'eeeee')
- if (clusterData?.length > 1) return;
- this.$emit('handleMarkerClick',e)
- // this.createInfoWindow.closeWindow()
- // this.createInfoWindow.add({ ...e, offset: [0, -14], componentsMapKey: 'markerCluster' })//创建窗体
- });
- } else {
- let { points, prePoints } = data
- this.cluster.setData(points)
-
- /*移动窗体 */
- /* let activeItem = this.createInfoWindow.getItem()
-
- if (activeItem) {
-
- let filterItem = points.filter((item) => {
- return item.item.id == activeItem[0].item.id
- })
- if (!isEmpty(filterItem)) {
- this.createInfoWindow.setPosition([filterItem[0].item.lng, filterItem[0].item.lat])
- } else {
- this.createInfoWindow.closeWindow()
- }
-
- } */
-
-
- let newPoint = points.map(e => e.item)
- let oldPoint = prePoints.map(e => e.item)
- let {adds,deletes} = listCrudChange(newPoint,oldPoint)
-
- console.log(adds,'addsaddsadds')
- if( adds.length>=2) {
- let {southWest,northEast} = getMaxMinBounds(adds.map((e) => [e.lng,e.lat]))
- let bounds = new AMap.Bounds(southWest, northEast)
- this.$nextTick(() => {
- this.map.setBounds(bounds,true,[80, 80,40, 40])
- })
-
- console.log(bounds,'boundsbounds',this.map)
- } else if (adds.length == 1) {
- let item = adds[0]
- this.map.setZoomAndCenter(18, [item.lng,item.lat], true);
- }
-
-
- }
-
- },
- moveAnimation: () => {//创建轨迹回放
- let index = 0;
- if (this.createInfoWindow.getinfoWindow()) {
- this.createInfoWindow.closeWindow();
- }
- this.createMoveAlongFn = createMoveAlong(this.map, data, (key, e) => {
- if (key === 'moving') {
- index = e.index
- this.$emit('moving', e)
- /* if (this.createInfoWindow.getinfoWindow()) {
- if (this.isMoveAlongWindow) {
- this.createInfoWindow.setPosition([e.target.getPosition().lng, e.target.getPosition().lat])
- if (this.$refs.componentViewRef) {
- this.$refs.componentViewRef.callBack(e, this.createInfoWindow.closeWindow)
- }
- }
-
- } */
- this.$emit('handleMarkerClick',e, key)
- }
- if (key === 'moveTo') {
- /* if (this.createInfoWindow.getinfoWindow()) {
- if (this.isMoveAlongWindow) {
- this.createInfoWindow.setPosition(e.lnglat)
- if (this.$refs.componentViewRef) {
- this.$refs.componentViewRef.callBack(e, this.createInfoWindow.closeWindow)
- }
- }
- } */
- this.$emit('handleMarkerClick',e, key)
- }
- if (key === 'click') {
- if(e.resetIdx>index){
- e.index = e.resetIdx
- }else{
- e.index = index
- }
-
- this.$emit('handleMarkerClick',e, key)
- /* this.isMoveAlongWindow = true
- if (!this.isCreateInfoWindow) return;
- this.createInfoWindow.add({ index, lnglat: e.target.getPosition(), offset: [0, -23], componentsMapKey: 'moveAnimation' })//创建窗体 */
- }
- })
- },
- createMarker: () => { //创建标注点
- this.allmarkerPro = createMarker(this.map, data, (key, e) => { //返回目前地图上所有Mark实例
- if (this.createInfoWindow.getinfoWindow()) {
- this.createInfoWindow.closeWindow();
- }
- console.log('创建标注点', e)
- let lng = Number(e.lng02)
- let lat = Number(e.lat02)
- this.isMoveAlongWindow = false
-
- if (e.hiddenInfoWindow) return
- this.createInfoWindow.add({ lnglat: { lng, lat }, offset: [0, 0], componentsMapKey: e.type, info: e })//创建窗体
- })
- },
- removeAllMarkers: () => {//删除所有创建的标注点
- if (this.allmarkerPro) {
- this.allmarkerPro.removeAllMarkers()
- }
- },
- createPolyline: () => {//创建展示路线
- createPolylineShow(this.map, data)
- }
- }
- toolMapFn[key]();
- },
- citySearch() {
- //实例化城市查询类
- let that = this;
- var citysearch = new AMap.CitySearch();
-
- //自动获取用户IP,返回当前城市
- citysearch.getLocalCity(function(status, result) {
- if (status === 'complete' && result.info === 'OK') {
- if (result && result.city && result.bounds) {
- var citybounds = result.bounds;
- //地图显示当前城市
- that.map.setBounds(citybounds,true);
- }
- } else {
-
- }
- });
- },
- setisMoveAlongWindow(e) {
- isMoveAlongWindow = e
- },
-
- /**创建路线 */
- createPolyline(data, option) {
-
- let polyline
- polyline = new AMap.Polyline({
- map: this.map,
- path: data,
- showDir: true,
- strokeStyle: "solid",
- strokeColor: "#027AFF", //线颜色
- strokeWeight: 6, //线宽
- strokeOpacity: 1,
- ...option,
- });
-
- return polyline
- },
- /**移除覆盖物 */
- removeOverlays(Overlays) {
- this.map.remove(Overlays)
- },
- /**创建围栏 */
- createPolygon(data, option) {
-
- let Polygon
- Polygon = new AMap.Polygon({
- map: this.map,
- path: data,
- strokeStyle: "solid",
- fillColor: '#00b0ff',
- strokeColor: '#80d8ff',
- strokeWeight: 2, //轮廓线宽度
- ...option,
- });
-
- return Polygon
- },
-
- /**创建圆 */
- createCircle(center, option) {
-
- let Circle
- Circle = new AMap.Circle({
- center: center,
- radius: 50, //半径
- borderWeight: 3,
- strokeColor: "#FF33FF",
- strokeOpacity: 1,
- strokeWeight: 6,
- strokeOpacity: 0.2,
- fillOpacity: 0.4,
- fillColor: '#1791fc',
- ...option,
- });
- this.map.add(Circle)
-
- return Circle
- },
- /**批量创建标记点 */
- batchCreateMarkers(data, option) {
-
- let Markers = []
- data.forEach(item => {
- Markers.push(
- new AMap.Marker({
- position: item.position,
- content: item.content,
- offset: item.offset,
- title: item.title,
- ...option
- })
- )
- });
-
- this.map.add(Markers)
-
- return Markers
- },
-
- // 坐标集合适配
- setBoundsPolygon(bounds,immediately){
- let polygon = new AMap.Polygon({
- path: bounds,
- });
- let mybounds = polygon.getBounds();
- this.map.setBounds(mybounds,immediately);
- },
- /**视觉适配 */
- setFitView(...args) {
- this.map.setFitView(...args);
- },
-
- /**设置中心点 */
- setCenter(...args) {
- this.map.setCenter(...args);
- },
- /**地图缩放至指定级别并以指定点为地图显示中心点 */
- setZoomAndCenter(...args) {
- this.map.setZoomAndCenter(...args);
- },
-
- /* 设置卫星图 */
- setStelliteLayer(isShow = true) {
- if (isShow) {
- if (!this.satelliteLayer) {
- this.satelliteLayer = new AMap.TileLayer.Satellite();
- this.satelliteLayer.setMap(this.map);
- } else {
- this.satelliteLayer.show();
- }
- } else {
- if (this.satelliteLayer) this.satelliteLayer.hide();
- }
-
- },
-
- }
- }
- </script>
- <style scoped lang="scss">
- // 地图
- ::v-deep {
- .amap-logo {
- display: none !important;
- }
- .amap-copyright {
- display: none !important;
- }
- }
- .container-box {
- width: 100%;
- height: 100%;
- position: relative;
- .showspeed-box {
- border-radius: 6px;
- overflow: hidden;
- position: absolute;
- right: 12px;
- top: 11px;
- height: 33px;
- color: #fff;
- display: flex;
- align-items: center;
- text-align: center;
- height: 33px;
- line-height: 33px;
- font-size: 12px;
- .flex-al {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .checkbox {
- width: 84px;
- background: linear-gradient(180deg, #3296FF 0%, #027AFF 100%);
- border-radius: 6px 0px 0px 6px;
- :deep(.el-checkbox__label) {
- color: #fff;
- }
- :deep(.el-checkbox) {
- height: 33px;
- line-height: 33px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
- .speed-60 {
- width: 30px;
- background: #16B92A;
- }
- .speed-80 {
- width: 45px;
- background: #0000FE;
- }
- .speed-100 {
- width: 53px;
- background: #F98202;
- }
- .speed-m100 {
- width: 71px;
- background: #FE0100;
- border-radius: 0px 6px 6px 0px;
- }
- }
- .mapToolBox {
- position: absolute;
- display: flex;
- max-width: 500px;
- overflow: auto;
- top: 10px;
- left: 30px;
- }
- }
- .container {
- padding: 0px;
- margin: 0px;
- width: 100%;
- height: 100%;
- }
- </style>
|