美文网首页
在vite+ts中使用leftlet做工厂平面(室内)地图

在vite+ts中使用leftlet做工厂平面(室内)地图

作者: zZ_d205 | 来源:发表于2023-11-20 17:33 被阅读0次

实现效果
初始化:


image.png

点击标识点时自动放大:


image.png

参考文章
Leaflet
https://github.com/Leaflet/Leaflet
https://leafletjs.com/index.html
中文文档:https://leafletjs.cn/
Leaflet Indoor
https://github.com/cbaines/leaflet-indoor
npm 安装 Leaflet

npm install leaflet

yarn 安装 Leaflet

yarn add leaflet

这将在你的项目中安装 Leaflet 库。安装完成后,你可以在你的 Vue 项目中按照以下方式引入 Leaflet:

import L from 'leaflet';
import 'leaflet/dist/leaflet.css';

leaflet可能会报错,我是在app.vue中做的demo,所以需要在vite-env.d.ts中声明

declare module 'leaflet';
image.png
<template>
  <div class="mapBox">
    <div id="map"></div>
    <div id="warehouse2"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted } from "vue";
import * as L from "leaflet";
import "leaflet/dist/leaflet.css";
import imageUrl from "./assets/warehouse1.png";
import warehouse2 from "./assets/warehouse2.png";
import marker from "./assets/jarMarker.png";
// const leftBottomLat = 0; // 左下角经度
// const leftBottomLng = 0; // 左下角纬度
const getRealitySize = (size: number) => {
  // type: "Lat" | "Lng"
  // return type === "Lat"
  //   ? leftBottomLat + size / (40008000 / 360)
  //   : leftBottomLng + size / (40008000 / 360);// 40008000 是地球周长
  return size / (40008000 / 360);
};
const initMap1 = () => {
  // 创建地图实例并设置初始视图
  // Create the map
  //地图底图
  //  var osmUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
  //         osm = new L.TileLayer(osmUrl, {
  //             maxZoom: 22,
  //             // attribution: "Map data &copy; OpenStreetMap contributors"
  //         });
  // 假设当前左下角坐标为 [leftBottomLat, leftBottomLng]
  const factoryWidth = 1144; // 宽度,单位:米
  const factoryHeight = 676; // 高度,单位:米

  // 计算右上角的经纬度
  const rightTopLng = getRealitySize(factoryWidth); //经度
  const rightTopLat = getRealitySize(factoryHeight); //纬度

  //[[最小底部纬度, 最左侧经度(左下角的点位)], [最大顶部纬度, 最右侧经度(右上角的点位)]];
  // 坐标的顺序应该是[纬度, 经度]
  var imageBounds = [
    [0, 0],
    [rightTopLat, rightTopLng],
  ];
  var map = new L.Map("map", {
    // layers: [osm],
    center: new L.LatLng(0, 0),
    zoom: 16,
    maxBounds: imageBounds,
    attributionControl: false,
    minZoom: 16, // 设置最小缩放级别
    maxZoom: 25, // 设置最大缩放级别
  });
  var imageOverlay = L.imageOverlay(imageUrl, imageBounds).addTo(map);
  imageOverlay.setOpacity(0.5); // 设置不透明度为 0.5
  // Add markers with custom icons
  // var marker1 = L.marker([0, 0]).addTo(map);
  // var popup1 = L.popup().setContent("Marker 1 Popup");
  // marker1.bindPopup(popup1);
  // var marker1 = L.marker([49.41873, 8.67689]).addTo(map);
  // var popup1 = L.popup().setContent("Marker 1 Popup");
  // marker1.bindPopup(popup1);

  // var marker2 = L.marker([0.0002, 0.0003]).addTo(map);
  // var popup2 = L.popup().setContent("Marker 2 Popup");
  // marker2.bindPopup(popup2);

  // L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
  //     maxZoom: 19,
  //     attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
  // }).addTo(map);
  // // 添加一个简单的标记
  // L.marker([51.5, -0.09]).addTo(map)
  //   .bindPopup('A pretty CSS3 popup. <br> Easily customizable.')
  //   .openPopup();

  // // 添加一个简单的圆
  // L.circle([51.508, -0.11], {
  //   color: 'red',
  //   fillColor: '#f03',
  //   fillOpacity: 0.5,
  //   radius: 500
  // }).addTo(map).bindPopup('I am a circle.');

  // 添加一个多边形
  const polygon = L.polygon(
    [
      [getRealitySize(45), getRealitySize(202)], // 左下角
      [getRealitySize(48), getRealitySize(528)], // 右下角
      [getRealitySize(156), getRealitySize(528)], // 右上角
      [getRealitySize(156), getRealitySize(202)], // 左上角
    ],
    {
      color: "white", // 边框颜色
      fillColor: "white", // 填充颜色
      fillOpacity: 1, // 完全不透明
    }
  )
    .addTo(map)
    .bindTooltip(
      "<div style='font-weight:bold'>Dirty Staging</br>Clean Room</div>",
      {
        permanent: true,
        direction: "center",
      }
    ) // 添加 Tooltip
    .on("click", function () {
      const bounds = polygon.getBounds();
      map.fitBounds(bounds);
    });
  // 你可以使用 polygon.getBounds() 获取多边形的边界框
  const polygonBounds = polygon.getBounds();

  const numberOfMarkers = 50;
  const customIcon = L.icon({
    iconUrl: marker, // 图标的 URL
    iconSize: [32, 32], // 图标的尺寸
    iconAnchor: [16, 16], // 图标的锚点,即图标的中心点
  });
  for (let i = 0; i < numberOfMarkers; i++) {
    // 随机生成一个在多边形内的点
    const randomPoint = getRandomPointInsidePolygon(polygonBounds);

    // 添加标记
    L.marker([randomPoint.lat, randomPoint.lng], { icon: customIcon })
      .addTo(map)
      .bindPopup(
        `<div><h3>Marker ${
          i + 1
        }</h3><p>Your custom HTML content goes here</p></div>`
      )
      .on("click", function () {
        const bounds = polygon.getBounds();
        map.fitBounds(bounds);
      });
  }

  // 随机生成一个在多边形内的点
  function getRandomPointInsidePolygon(bounds: {
    getSouthWest: () => any;
    getNorthEast: () => any;
  }) {
    const southWest = bounds.getSouthWest();
    const northEast = bounds.getNorthEast();

    const lat = Math.random() * (northEast.lat - southWest.lat) + southWest.lat;
    const lng = Math.random() * (northEast.lng - southWest.lng) + southWest.lng;

    return { lat, lng };
  }
  // // 例如,在多边形内的点的坐标
  // const pointInsidePolygon = [getRealitySize(90), getRealitySize(200)];

  // // 检查点是否在多边形内
  // if (
  //   polygonBounds.contains(
  //     L.latLng(pointInsidePolygon[0], pointInsidePolygon[1])
  //   )
  // ) {
  //   // 在多边形内,添加标记
  //   const marker = L.marker([pointInsidePolygon[0], pointInsidePolygon[1]])
  //     .addTo(map)
  //     .bindPopup("Marker inside the polygon");
  // }

  // const demoText = L.divIcon({
  //   className: "demo-text",
  //   html: `<div style=''>PM</br>WH</div>`,
  // });

  // const textMarker = L.marker(polygon.getBounds().getCenter(), {
  //   icon: demoText,
  // }).addTo(map);
};
onMounted(() => {
  initMap1();
});
</script>
<style>
/* 去掉 Leaflet Tooltip 的默认样式 */
.leaflet-tooltip {
  box-shadow: none !important;
  border: none !important;
  background-color: transparent !important;
}

/* 设置 Tooltip 文字的样式 */
.leaflet-tooltip-content {
  color: black; /* 文字颜色 */
  font-size: 14px; /* 文字大小 */
}
</style>
<style scoped>
body {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
  width: 100%;
}
.mapBox {
  display: flex;
  align-items: center;
  height: 100vh;
}
#map {
  height: 100%;
  width: 50%;
}
.info {
  width: 150px;
  padding: 6px 8px;
  font: 14px/16px Arial, Helvetica, sans-serif;
  background: white;
  background: rgba(255, 255, 255, 1);
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
  border-radius: 5px;
}
#warehouse2 {
  width: 50%;
  height: 100%;
}
</style>

相关文章

  • ios开发使用的第三方资料

    ios开发使用的第三方资料 自己搜索使用过的一些资料,仅供参考。 室内地图-室内三维地图引擎导航及制作|易景地图:...

  • 室内定位产业与相关十大创业公司

    ❶定义 实现室内场景中的人、物品的位置标定和跟踪,通常和室内数字地图配合使用,是对传统室外定位的补全。 ❷定位 从...

  • Xcode混编oc和C++

    前景:在谷歌室内地图v2.2.0中使用到.mm文件 为什么要使用C++混编 1)需要使用工具库或者源码是C++的2...

  • iOS-百度地图点聚合

    一、坐标点转换 坐标分为:平面坐标、球面坐标(地理经纬度);在地图应用上使用的平面坐标,如果拿到的是地理经纬度坐标...

  • 基于leaflet用svg图片实现一个最简单的室内地图

    之前在CSDN上写了一些关于室内地图的博客,很多人问我要室内地图的资料,今天特地分享一个室内地图的demo,非常简...

  • IOS使用百度地图SDK

    【 新 增 】  基础地图 1、新增室内地图功能 新增室内地图信息类:BMKBaseIndoorMapInfo ...

  • 爱上 iOS12 原生地图的简洁

    地图是我们生活中不可取代的一个工具,国内也不乏许多优秀的地图软件。而且必须承认的是,在车辆导航和室内导航的使用体验...

  • 洁净室怎么灭菌

    在食品工厂设计中,对食品工厂洁净室不仅依靠空气过滤的方法,使送入食品工厂洁净室内的空气中的生物或非生物微粒数量受到...

  • MOSGL室内地图开放指南

    MosGL室内地图渲染SDK,基于WebGL图形渲染,同时支持2D&3D地图;在小场景渲染中,iOS及Andoid...

  • ionic 使用 Leaflet,click事件失效

    项目需求:使用Ionic1做混合App开发,使用Leaflet提供地图服务遇到问题:地图上的click事件在Ion...

网友评论

      本文标题:在vite+ts中使用leftlet做工厂平面(室内)地图

      本文链接:https://www.haomeiwen.com/subject/ytvvwdtx.html