天地图如何展示POI点位 圆形区域 关闭Graphic不冲突

自定义POI图标:

如果有多个Graphic,如何不清除之前的Graphic:

点击图标弹出框:

设置圆形:

展示:

有多边形的Graphic,还有标记的Graphic,如何点击新标记只删除标记的Graphic,而不删除多边形的Graphic?

修改circle的半径:

重新更新Graphic即可:

点击“定位”后关闭抽屉:

全部代码:
 

<template>
  <div style="width: 100vw; height: 100%; position: relative">
    <el-drawer title="poi缓存搜索" :visible.sync="drawer" :with-header="false">
      <el-card class="box-card" style="margin: 20px">
        <div class="text item">
          <p>1.漕河泾</p>
          <p>地址:上海市徐汇区漕河泾1011号</p>
          <p>电话:021-54210000</p>
          <p>坐标:121.42524531217315,31.167829642058244</p>
          <p>
            <button @click="changeCenter(121.42524531217315, 31.167829642058244)">
              定位
            </button>
          </p>
        </div>
      </el-card>

      <el-card class="box-card" style="margin: 20px">
        <div class="text item">
          <p>1.世博大道</p>
          <p>地址:上海市浦东世博大道1011号</p>
          <p>电话:021-54210000</p>
          <p>坐标:121.47944750034962,31.18516747580588</p>
          <p>
            <button @click="changeCenter(121.47944750034962, 31.18516747580588)">
              定位
            </button>
          </p>
        </div>
      </el-card>

      <el-card class="box-card" style="margin: 20px">
        <div class="text item">
          <p>1.世博大道</p>
          <p>地址:上海市浦东世博大道1011号</p>
          <p>电话:021-54210000</p>
          <p>坐标:121.47944750034962,31.18516747580588</p>
          <p>
            <button @click="changeCenter(121.47944750034962, 31.18516747580588)">
              定位
            </button>
          </p>
        </div>
      </el-card>
    </el-drawer>

    <el-drawer title="常规搜索" :visible.sync="drawer2" :with-header="false">
      <span>我来啦!2</span>
    </el-drawer>

    <!-- 弹出框 -->
    <!-- 弹出对话框 -->
    <el-dialog
      title="编辑poi信息"
      :visible.sync="dialogVisible"
      width="500px"
      @close="handleClose"
    >
      <el-form :model="form" label-width="100px">
        <el-form-item label="项目类型">
          <el-input v-model="form.projectType"></el-input>
        </el-form-item>

        <el-form-item label="所属区域">
          <el-input v-model="form.area"></el-input>
        </el-form-item>

        <el-form-item label="项目名称">
          <el-input v-model="form.projectName"></el-input>
        </el-form-item>

        <el-form-item label="项目编号">
          <el-input v-model="form.projectCode"></el-input>
        </el-form-item>

        <el-form-item label="委托单位">
          <el-input v-model="form.client"></el-input>
        </el-form-item>

        <el-form-item label="批复时间">
          <el-date-picker
            v-model="form.approvalDate"
            type="date"
            placeholder="选择日期"
          ></el-date-picker>
        </el-form-item>

        <el-form-item label="缓冲宽度">
          <el-input v-model="form.bufferWidth" type="number"></el-input>
        </el-form-item>
      </el-form>

      <!-- 对话框操作按钮 -->
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </div>
    </el-dialog>

    <div id="mapDom">
      <div
        style="
          position: absolute;
          top: 5px;
          left: 5px;
          z-index: 1;
          display: flex;
          flex-direction: column;
        "
      >
        <el-button @click="drawer = true" type="primary"> poi缓存搜索 </el-button>
        <br />

        <el-button @click="drawer2 = true" type="primary"> 常规搜索 </el-button>
      </div>

      <!-- 地图实例 -->
      <div id="mapView" />
      <!-- 底图切换 -->
      <div id="baseMapToggle" />
      <!-- 比例尺 -->
      <div id="scaleBar" />
      <!-- 缩放 -->
      <div id="zoom" />
      <!-- 指北针 -->
      <div id="compass" />
      <!-- 图例 -->
      <div id="selfLegend" />
      <!-- Sketch -->
      <div id="selfSketch" />
      <div class="copyRight">©2023 上海营邑城市规划设计股份有限公司 荣誉出品</div>
      <div id="maskDiv" class="hide screenshotCursor" />
    </div>
  </div>
</template>

<script>
import { loadModules } from "esri-loader";
import config from "@/config/mapOptions";
import { centerPoint, tiandituInfo } from "@/config/mapConfig";
import { showScreenLoading, hideScreenLoading } from "@/utils/loadingContent";
import { listGis } from "@/api/search/gis.js"; // 数据来源的地方
import { geojsonToArcGIS } from "@terraformer/arcgis";

export default {
  name: "Search",
  data() {
    return {
      marker: null,
      circleGraphic: null,
      dialogVisible: false, // 控制对话框显示
      form: {
        projectType: "", // 项目类型
        area: "", // 所属区域
        projectName: "", // 项目名称
        projectCode: "", // 项目编号
        client: "", // 委托单位
        approvalDate: "", // 批复时间
        bufferWidth: "2000", // 缓冲宽度
      },
      drawer: false,
      drawer2: false,
      mapView: null, // 存储 MapView 实例
      vectorMapUrl: require("@/assets/dashbord/one.png"),
      imageMapUrl: require("@/assets/dashbord/two.png"),
    };
  },
  mounted() {
    // 页面加载时调用_createMapView 方法初始化地图
    let promiseList = [];

    promiseList.push(this._createMapView());
    Promise.all(promiseList).then(() => {
      console.log("ok");
    });
  },

  methods: {
    /**
     * @description: 初始化地图
     * @return {*}
     */
    async _createMapView() {
      showScreenLoading({ text: "地图加载中..." });
      const [
        Map,
        GraphicsLayer,
        Legend,
        Expand,
        Sketch,
        WebTileLayer,
        TileInfo,
        MapView,
        SpatialReference,
        Point,
        ScaleBar,
        Zoom,
        BasemapToggle,
        Compass,

        // esriConfig,
        // Print
      ] = await loadModules(
        [
          "esri/Map",
          "esri/layers/GraphicsLayer",
          "esri/widgets/Legend",
          "esri/widgets/Expand",
          "esri/widgets/Sketch",
          "esri/layers/WebTileLayer",
          "esri/layers/support/TileInfo",
          "esri/views/MapView",
          "esri/geometry/SpatialReference",
          "esri/geometry/Point",
          "esri/widgets/ScaleBar",
          "esri/widgets/Zoom",
          "esri/widgets/BasemapToggle",
          "esri/widgets/Compass",
          "esri/config",

          // "esri/widgets/Print",
        ],
        config.options
      );

      // =================================创建mapView start==========================
      // 设置天地图配置(影像地图和矢量地图)
      const { tianDiTuBaseUrl, token, TileInfoMsg } = tiandituInfo;
      const tileInfo = new TileInfo(TileInfoMsg);

      //影像地图
      const tiledLayer = new WebTileLayer({
        urlTemplate:
          tianDiTuBaseUrl + "/DataServer?T=img_c&x={col}&y={row}&l={level}&tk=" + token,
        subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
        tileInfo: tileInfo,
        spatialReference: { wkid: 4490 },
      });

      //影像注记
      const tiledLayerAnno = new WebTileLayer({
        urlTemplate:
          tianDiTuBaseUrl + "/DataServer?T=cia_c&x={col}&y={row}&l={level}&tk=" + token,
        subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
        tileInfo: tileInfo,
        spatialReference: { wkid: 4490 },
      });

      // 矢量地图
      const vecLayer = new WebTileLayer({
        urlTemplate:
          tianDiTuBaseUrl + "/DataServer?T=vec_c&x={col}&y={row}&l={level}&tk=" + token,
        subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
        tileInfo: tileInfo,
        spatialReference: { wkid: 4490 },
      });

      const vecLayerAnno = new WebTileLayer({
        urlTemplate:
          tianDiTuBaseUrl + "/DataServer?T=cva_c&x={col}&y={row}&l={level}&tk=" + token,
        subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
        tileInfo: tileInfo,
        spatialReference: { wkid: 4490 },
      });

      // Layer
      const layer = new GraphicsLayer({
        id: "selfSketchLayer",
      });
      await layer.load();

      // 创建地图
      const map = new Map({
        basemap: {
          // baseLayers: [tiledLayer, tiledLayerAnno],
          thumbnailUrl: this.vectorMapUrl,
          baseLayers: [vecLayer, vecLayerAnno],
        },
        layers: [layer],
      });

      // 定位到中心,设置地图中心点
      const cityCenter = new Point(
        centerPoint.x,
        centerPoint.y,
        new SpatialReference({ wkid: 4490 })
      );

      // 创建地图视图
      this.mapView = new MapView({
        container: "mapView",
        map: map,
        center: cityCenter,
        zoom: 14,
      });
      //start/

      // 地图点击事件监听器
      this.mapView.on("click", (event) => {
        const latitude = event.mapPoint.latitude;
        const longitude = event.mapPoint.longitude;
        console.log("Clicked location - Latitude:", latitude, "Longitude:", longitude);

        // 你可以在这里执行其他操作,比如显示在界面上或将坐标存储在变量中
      });

      let resListGis = await listGis(); //获取数据

      // 动态加载Polygon模块
      const [Polygon, Graphic] = await loadModules([
        "esri/geometry/Polygon",
        "esri/Graphic",
      ]);

      // 添加GIS数据到地图图层
      resListGis.rows.forEach((item) => {
        // 解析geometry
        const geometryData = JSON.parse(item.geometry);

        // 创建Polygon对象
        const polygon = new Polygon({
          rings: geometryData.coordinates[0],
          spatialReference: { wkid: 4490 },
        });

        // 创建Graphic对象
        const graphic = new Graphic({
          geometry: polygon,
          symbol: {
            type: "simple-fill",
            color: [51, 51, 204, 0.6], // 填充颜色
            outline: {
              color: [0, 0, 0], // 边界颜色
              width: 2,
            },
          },
          attributes: {
            title: item.title,
            leader: item.leader,
            code: item.code,
            area: item.area,
          },
          popupTemplate: {
            title: "{title}",
            content: [
              {
                type: "fields",
                fieldInfos: [
                  { fieldName: "leader", label: "负责人" },
                  { fieldName: "code", label: "项目编号" },
                  { fieldName: "area", label: "区域" },
                ],
              },
            ],
          },
        });

        // 添加Graphic到图层
        layer.add(graphic);
      });

      ///end

      // 实例化底图切换控件
      const mapToggle = new BasemapToggle({
        view: this.mapView,
        nextBasemap: {
          // baseLayers: [vecLayer, vecLayerAnno],
          baseLayers: [tiledLayer, tiledLayerAnno],
          thumbnailUrl: this.imageMapUrl,
        },
        // nextBasemap: { baseLayers: [tiledLayer, tiledLayerAnno] },
        container: "baseMapToggle",
      });
      // mapView.ui.add(mapToggle);

      // ==============================  创建mapView end  ================
      await this.mapView
        .when(async () => {
          // this.$store.commit("map/CHANGE_MAP_VIEW", mapView);//临时
          // 去除控件UI
          this.mapView.ui.components = [];
          // 实例化比例尺
          const mapScaleBar = new ScaleBar({
            view: this.mapView,
            container: "scaleBar",
            unit: "metric",
          });
          this.mapView.ui.add(mapScaleBar);

          // 实例化缩放控件
          const mapZoom = new Zoom({
            container: "zoom",
            view: this.mapView,
          });
          this.mapView.ui.add(mapZoom);

          const mapCompass = new Compass({
            container: "compass",
            view: this.mapView,
          });
          this.mapView.ui.add(mapCompass);

          const legend = new Expand({
            content: new Legend({
              view: this.mapView,
              // style: "card",
            }),
            view: this.mapView,
            expanded: false,
            container: "selfLegend",
          });

          this.mapView.ui.add(legend, "bottom-right");
        })
        .then(async () => {
          hideScreenLoading();
          //弹框自定义操作
          this.mapView.popup.viewModel.on("trigger-action", async (event) => {
            await triggerAction.call(this, event);
          });
        });
    },

    // 按钮点击事件:修改中心点
    async changeCenter(xx, yy) {
      this.drawer = false;
      if (this.mapView) {
        const newCenter = {
          x: xx, // 新经度
          y: yy, // 新纬度
        };

        const [Point, SpatialReference, Graphic, Circle] = await loadModules([
          "esri/geometry/Point",
          "esri/geometry/SpatialReference",
          "esri/Graphic",
          "esri/geometry/Circle",
        ]);

        this.mapView.center = new Point({
          x: newCenter.x,
          y: newCenter.y,
          spatialReference: new SpatialReference({ wkid: 4490 }),
        });

        // 如果存在之前的标记,删除它
        if (this.marker) {
          const layer = this.mapView.map.findLayerById("selfSketchLayer");
          if (layer) {
            layer.remove(this.marker); // 从图层中删除   marker
            layer.remove(this.circleGraphic); // 从图层中删除  绿色圆形
          }
        }

        // 设置标记

        this.marker = new Graphic({
          geometry: new Point({
            x: newCenter.x,
            y: newCenter.y,
            spatialReference: { wkid: 4490 },
          }),
          symbol: {
            type: "picture-marker",
            url: "/pos.png",
            width: "48px",
            height: "48px",
          },
        });

        // 创建圆形框选区域
        const circleGeometry = new Circle({
          center: new Point({
            x: newCenter.x,
            y: newCenter.y,
            spatialReference: { wkid: 4490 },
          }),
          radius: 2000, // 圆的半径,单位为地图坐标单位
          spatialReference: { wkid: 4490 },
        });

        this.circleGraphic = new Graphic({
          geometry: circleGeometry,
          symbol: {
            type: "simple-fill",
            color: [0, 255, 0, 0.5], // 填充绿色半透明
            outline: {
              color: [0, 0, 255], // 边框颜色
              width: 0, // 边框宽度
            },
          },
        });

        const layer = this.mapView.map.findLayerById("selfSketchLayer");
        if (layer) {
          //layer.removeAll();

          layer.add(this.circleGraphic); // 添加圆形
          layer.add(this.marker);
        }

        // 为地图视图添加点击事件
        this.mapView.on("click", (event) => {
          this.mapView.hitTest(event).then((response) => {
            // 检查是否点击到标记
            if (response.results.length) {
              const graphic = response.results[0].graphic;
              if (graphic === this.marker) {
                this.dialogVisible = true; // 显示对话框
              }
            }
          });
        });
      }
    },

    handleClose() {
      // 关闭对话框时的处理,可以清空数据或其他操作
      this.dialogVisible = false;
    },

    // 处理保存
    async handleSave() {
      const [Graphic, Circle] = await loadModules([
        "esri/Graphic",
        "esri/geometry/Circle",
      ]);

      // 获取缓冲宽度值
      const bufferWidth = this.form.bufferWidth;

      // 确保 bufferWidth 是有效的
      if (bufferWidth && this.marker) {
        // 更新 circleGeometry 的 radius
        const radius = bufferWidth; // 将缓冲宽度赋值给半径
        const circleGeometry = new Circle({
          center: this.marker.geometry, // 使用当前标记的位置
          radius: radius, // 新的半径值
          spatialReference: { wkid: 4490 },
        });

        // 创建新的 Graphic 对象并添加到图层
        const circleGraphic = new Graphic({
          geometry: circleGeometry,
          symbol: {
            type: "simple-fill",
            color: [0, 255, 0, 0.5], // 填充颜色为半透明绿色
            outline: {
              color: [0, 0, 255], // 边框颜色
              width: 0, // 边框宽度
            },
          },
        });

        const layer = this.mapView.map.findLayerById("selfSketchLayer");
        if (layer) {
          layer.remove(this.circleGraphic); // 如果有之前的圆形,先移除
          layer.add(circleGraphic); // 添加新的圆形
          this.circleGraphic = circleGraphic; // 保存对圆形的引用
        }

        // 关闭对话框
        this.dialogVisible = false;
      } else {
        alert("请确保缓冲宽度有效!");
      }
    },
  },
};
</script>

<style lang="scss" scoped>
#mapDom {
  position: relative;
  display: flex;
  width: 100%;
  overflow: hidden;
  height: calc(100vh - 86px);

  /* stylelint-disable-next-line selector-id-pattern */
  #mapView {
    flex: 1;
  }

  /* stylelint-disable-next-line selector-id-pattern */
  #baseMapToggle {
    position: absolute;
    right: 30px;
    top: 109px;
    transform: scale(0.44);
    border: 2px solid #fff;
  }

  /* stylelint-disable-next-line selector-id-pattern */
  #scaleBar {
    position: absolute;
    bottom: 15px;
    right: 60px;
  }

  /* stylelint-disable-next-line selector-id-pattern */
  #mapTools {
    position: absolute;
    top: 0px;
    right: 0px;
  }

  #zoom {
    position: absolute;
    right: 48px;
    top: 50px;
    transform: scale(0.9);
  }

  #compass {
    position: absolute;
    right: 48px;
    top: 180px;
  }
  #selfLegend {
    position: absolute;
    right: 47px;
    bottom: 30px;
  }
  #selfSketch {
    position: absolute;
    left: 630px;
    bottom: 15px;
    transform: translateX(-50%);
  }

  #currentComponent {
    position: absolute;
  }
  #maskDiv {
    position: absolute;
    background: rgba(255, 51, 0, 0.1);
    border: 2px dashed rgb(255, 51, 0);
  }
  .hide {
    display: none;
  }
  .screenshotCursor {
    cursor: crosshair;
  }
}
.copyRight {
  position: absolute;
  bottom: 5px;
  left: 60%;
  transform: translateX(-50%);
  color: #fff;
  font-weight: 500;
  font-size: 15px;
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_36152801/article/details/143406423