百度地图实现标点以及跑道画圈

前端代码

 <template>
  <Dialog title="地图" v-model="show" width="700px" top="5vh" center>
    <div id="container-wrapper">
      <baidu-map
        class="bm-view"
        :center="center"
        :zoom="18"
        :scroll-wheel-zoom="true"
        @click="handleClick"
        @mousemove="syncPolyline"
        @rightclick="newPolyline"
      >
      <bm-control v-show="mode == 0">
        <button @click.stop="toggle">{{ polyline.editing ? '停止绘制' : '开始绘制' }}</button>
        <button @click.stop="clearPaths">{{ "清空绘制" }}</button>
      </bm-control>
        <!-- 标点模式 -->
        <bm-marker v-if="mode == 1 && center" :position="center" :icon="markerIcon" />
        <bm-marker v-if="mode == 1 && clickPosition" :position="clickPosition" :icon="markerIcon" />

        <!-- 绘制模式 -->
        <bm-polyline
          v-for="(path, index) in polyline.paths"
          :key="index"
          :path="path"
          :stroke-color="'blue'"
        />
      </baidu-map>
    </div>
    <div v-if="mode === 1 && clickPosition" class="coordinates">
      当前选中坐标: 经度 {{ clickPosition.lng }},纬度 {{ clickPosition.lat }}
    </div>
    <div v-if="mode == 0 && polyline.paths.length" class="coordinates">
      当前绘制路径: {{ JSON.stringify(polyline.paths) }}
    </div>
    <template #footer>
      <el-button @click="confirmAction" type="primary">确 定</el-button>
      <el-button @click="cancelAction">取 消</el-button>
    </template>
  </Dialog>
</template>

<script setup>
import { ref ,toRef,nextTick} from "vue";

const show = ref(false);
const center = ref({ lng: 119.4196557630222, lat: 32.39979425018851 }); // 默认中心点
const clickPosition = ref(null); // 存储点击位置的经纬度
const mode = ref(1); // 模式,1为标点模式,0为绘制模式
const polyline = ref({
  editing: false,
  paths: []
}); // 绘制模式的路径

// 定义事件供父组件调用
const emit = defineEmits(["confirm"]);

// 显示地图模态框
const showModal = (params = {}) => {
  console.log(polyline.value.paths);
  
  center.value = {
    lng: params.longitude ?? center.value.lng,
    lat: params.latitude ?? center.value.lat,
  };
  if(params.footpathList!=[]){
    polyline.value.paths = [params.footpathList._value];
  }else{
    polyline.value.paths = []; // 重置路径
  }
  clickPosition.value = null; // 重置选中位置
  mode.value = params.mode ?? 1; // 设置模式
  show.value = true;
};

// 点击事件处理
const handleClick = (e) => {
  if (mode.value === 1) {
    clickPosition.value = e.point; // 标点模式
  } else if (mode.value === 0) {
    paintPolyline(e); // 绘制模式
  }
};


const toggle = (name) => {
  if(polyline.value.editing){
     // 停止绘制时清理未完成的点
     cleanIncompletePath();
  }
  polyline.value.editing = !polyline.value.editing;
};
// 同步绘制的线
const syncPolyline = (e) => {
  if (!polyline.value.editing) {
    return
  }

  if (!polyline.value.paths.length) {
    return
  }
  const path = polyline.value.paths[polyline.value.paths.length - 1]
  if (!path.length) {
    return
  }
  if (path.length === 1) {
    polyline.value.paths[polyline.value.paths.length - 1].push(e.point)
  }
  polyline.value.paths[polyline.value.paths.length - 1][path.length - 1] = e.point;
};
// 清理未完成的路径(未闭合或单点的路径)
const cleanIncompletePath = () => {
  if (polyline.value.paths && polyline.value.paths.length > 0) {
    const currentPath = polyline.value.paths[polyline.value.paths.length - 1];
    
    // 如果当前路径有点,移除最后一个点
    if (currentPath && currentPath.length > 0) {
      currentPath.pop();
    }
  }
};
// 开始新绘制线段
const newPolyline = () => {
  if (!polyline.value.editing) {
    return
  }
  console.log(polyline.value.paths);
  if (!polyline.value.paths.length) {
    polyline.value.paths.push([])
  }
  const path = polyline.value.paths[polyline.value.paths.length - 1]
  path.pop()
  if (path.length) {
    polyline.value.paths.push([])
  }
};

// 添加点到绘制路径
const paintPolyline = (e) => {
  if (!polyline.value.editing) {
    return
  }
  console.log(polyline.value.paths);
  !polyline.value.paths.length && polyline.value.paths.push([])
  polyline.value.paths[polyline.value.paths.length - 1].push(e.point)
};

// 确认操作
const confirmAction = () => {
  if (mode.value === 1) {
    emit("confirm", clickPosition.value,mode.value); // 返回标点坐标
  } else if (mode.value === 0) {
    emit("confirm", polyline.value.paths[0],mode.value); // 返回路径数据
  }
  show.value = false;
};

//清空绘制
const clearPaths = () => {
  console.log(polyline.value.paths);
  polyline.value.paths = []; // 清空所有路径
  polyline.value.editing = false; // 停止绘制状态
};
const cancelAction = () => {
 
    clickPosition.value = null; // 重置点击位置
    clearPaths();
    console.log(polyline.value.paths);
    
    show.value = false; // 关闭对话框

  
};

// 暴露给父组件
defineExpose({ showModal });
</script>

<style lang="scss" scoped>
#container-wrapper {
  position: relative;
  width: 100%;
  padding-bottom: 100%; /* 确保地图为正方形 */
  overflow: hidden;
}

.bm-view {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.coordinates {
  margin: 10px 0;
  font-size: 14px;
  color: #333;
}
</style>

后台管理效果如图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值