ArcGis 有polygon有marker数组,只删除marker数组

场景:

ArcGis 有polygon有marker,只删除marker数组,不删除polygon。

定义markers:

循环删除:

将marker放在markers中:

代码:

<template>
  <div style="width: 100vw; height: 100%; position: relative">
    <el-drawer title="poi缓存搜索" :visible.sync="drawer" :with-header="false">
      <div style="display: flex; height: 100vh; width: 100%; flex-direction: column">
        <div style="display: flex; margin: 20px; margin-bottom: 0">
          <el-input
            v-model="keyword"
            @keyup.enter.native="searchPOI"
            placeholder="输入关键词搜索POI"
            clearable=""
            style="flex: 1"
          />
          <el-button type="primary" @click="searchPOI" style="margin: 0 10px"
            >搜索</el-button
          >
        </div>

        <div v-if="poiList.length > 0" style="flex: 1; overflow-y: auto">
          <el-card
            class="box-card"
            style="margin: 20px"
            v-for="(poi, index) in poiList"
            :key="poi.hotPointID"
          >
            <div class="text item">
              <p>{
   
   { index + 1 }}. {
   
   { poi.name }}</p>
              <p>地址:{
   
   { poi.address }}</p>
              <p>电话:{
   
   { poi.phone }}</p>
              <p>坐标:{
   
   { poi.lonlat }}</p>
              <p>
                <button @click="showMarker(poi.lonlat, 1,1,1)">定位</button>
              </p>
            </div>
          </el-card>
        </div>

        <p
          v-if="poiList.length == 0"
          style="
            margin: 20px;
            width: calc(100% - 40px);
            display: flex;
            flex: 1;
            align-items: center;
            justify-content: center;
            background-color: #f9f9f9;
            color: #c0c0c0;
            font-size: 20px;
            text-align: center;
          "
        >
          {
   
   { noMessage }}
        </p>
      </div>
    </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 axios from "axios";
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 {
      keyword: "",
      poiList: [],
      noMessage: "暂无POI列表信息",
      errorMessage: "",
      marker: null,
      markers: [],
      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: {
    async searchPOI() {
      const layer = this.mapView.map.findLayerById("selfSketchLayer");
      //每次搜索之前 start
      if (this.markers) {
        if (layer) {
          this.markers.forEach((marker) => {
            layer.remove(marker); // 从图层中移除 marker
          });
          this.markers = []; // 清空 markers 数组
        }
      }

      ///

      //

      //每次搜索之前  end

      if (!this.keyword) {
        this.poiList = [];
        this.noMessage = "暂无POI列表信息";
        return;
      }

      const postStr = {
        queryType: "1",
        start: 0,
        mapBound:
          "121.40641563476055,31.166685323878824,121.44761436522919,31.176654597384555",
        yingjiType: 0,
        queryTerminal: 10000,
        level: 15,
        keyWord: this.keyword,
        count: 10,
        sourceType: 0,
      };

      try {
        const response = await axios.get(`http://api.tianditu.gov.cn/v2/search`, {
          params: {
            postStr: JSON.stringify(postStr),
            type: "query",
            tk: tiandituInfo.token, // 确保使用正确的token
          },
        });

        this.poiList = [];
        this.poiList = response.data.pois || [];
        // 循环
        // 循环 poiList,调用 showMarker 方法
        this.poiList.forEach((poi) => {
          if (poi.lonlat) {
            this.showMarker(poi.lonlat, 0, 0,0); //无圆圈,不清除marker
          }
        });

        this.errorMessage =
          response.data.status.cndesc === "服务正常" ? "" : response.data.status.cndesc;
      } catch (error) {
        console.error("Error fetching POI data:", error);
        this.errorMessage = "获取POI数据失败";
      }
    },
    /**
     * @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: 1,
            },
          },
          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);
          });
        });
    },

    // 按钮点击事件:修改中心点   isCircle 是点击单个定位 显示高亮圆圈, isRemove是考虑到搜索多poi列表的时候显示多个marker而不要清除。
    async showMarker(zuobiao_str, isCircle = 0, isRemove = 1,isCloseDrawer=0) {
      let zuobiao_arr = zuobiao_str.split(",");
      const new_x = zuobiao_arr[0];
      const new_y = zuobiao_arr[1];
      if (isCloseDrawer==1) { 
        this.drawer = false;
      }
      
      if (this.mapView) {
        const newCenter = {
          x: new_x, // 新经度
          y: new_y, // 新纬度
        };

        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 && isRemove == 1) {
            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",
          },
        });

        if (isCircle == 1) {
          // 创建圆形框选区域
          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) {
          if (isCircle == 1) {
            layer.add(this.circleGraphic); // 添加圆形
          }
          layer.add(this.marker);
          this.markers.push(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/143437800