openlayer矢量查询并弹出框显示-基于overlay

官方api:OpenLayers v6.14.1 API - Class: Overlay

在线预览:

WebGIS之家WebGIS之家,openlayers示例源码,cesium示例源码,openlayers在线调试预览,cesium在线调试预览,webgis,数字地球,数字孪生icon-default.png?t=N7T8https://www.webgishome.com/preview?id=94&example_name=overlay2&title=overlay%E5%BC%B9%E7%AA%972

例1:

效果图:

代码实现:

<template>
  <div class="_leftTop">
    <div id="map"></div>
    <div id="popup" class="olPopup">
      <div style="text-align: right;">
        <span @click="overlayer.setPosition(undefined)" class="popupClose">X</span>
      </div>
      <div id="popup-content"></div>
    </div>
  </div>
</template>

<script>
import "ol/ol.css";
import { Map, View, Overlay } from "ol";
import { TileWMS, OSM, Vector as VectorSource, XYZ } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";

import Select from "ol/interaction/Select";
import { altKeyOnly, click, pointerMove } from "ol/events/condition";

import {
  defaults as defaultControls,
  OverviewMap,
  FullScreen,
  ScaleLine,
  ZoomSlider,
  MousePosition,
  ZoomToExtent
} from "ol/control";
import GeoJSON from "ol/format/GeoJSON";
import { Fill, Stroke, Style, Text } from "ol/style";
export default {
  components: {},
  data() {
    return {
      map: {},
      select: {},
      overlayer: {}
    };
  },
  created() {},
  mounted() {
    this.initMap();
  },
  computed: {},
  methods: {
    initMap() {
      var layer_osm = new TileLayer({
        source: new OSM()
      });
      var layer_xyz = new TileLayer({
        // source: new OSM()
        source: new XYZ({
          url: "http://t3.tianditu.com/DataServer?T=img_w&tk=5a257cd2df1b3311723bd77b0de14baf&x={x}&y={y}&l={z}"
        })
      });
      var style = new Style({
        fill: new Fill({
          //矢量图层填充颜色,以及透明度
          color: "rgba(33,194,219,0.5)"
        }),
        stroke: new Stroke({
          //边界样式
          color: "rgba(100, 90, 209, 0.6)",
          width: 3
        })
      });
      var layer_sichuan = new VectorLayer({
        source: new VectorSource({
          url: "xxx",
          format: new GeoJSON()
        }),
        style: style
      });
      var layers = [layer_osm, layer_xyz, layer_sichuan];
      this.map = new Map({
        layers: layers,
        target: "map",
        view: new View({
          projection: "EPSG:4326",
          center: [115, 39],
          zoom: 4
        })
      });

      var container = document.getElementById("popup");
      var content = document.getElementById("popup-content");
      var popupCloser = document.getElementById("popup-close");
      // 2. 创建Overlay图层
      var overlayer = new Overlay({
        element: container,
        autuPan: true
      });

      this.select = new Select({
        condition: click
      });
      this.map.addInteraction(this.select);
      this.select.on("select", e => {
        if (e.selected.length != 0) {
          // 当前点的坐标
          var coordinate = e.mapBrowserEvent.coordinate;
          // 当前点的属性信息
          var properties = e.selected[0].getProperties();
          // 将信息填入弹出框
          content.innerHTML =
             `
              <div>name:${properties.name}</div>
              <br>
              <div>center:${properties.center}</div>
          `
          // 调整overlayer层的位置
          overlayer.setPosition(coordinate);
          // 将overlayer层添加到map当中
          this.map.addOverlay(overlayer);
        } else {
          overlayer.setPosition(undefined);
        }
        this.overlayer = overlayer;
      });

      // 设置鼠标划过矢量要素的样式
      this.map.on("pointermove", e => {
        var pixel = this.map.getEventPixel(e.originalEvent); //pixel为当前鼠标屏幕坐标,如 [0,0],[304,642]
        var feature = this.map.forEachFeatureAtPixel(pixel, function(feature) {
          return feature;
        });
        console.log("feature", feature);
        if (feature == undefined) {
          this.map.getTargetElement().style.cursor = "auto";
        } else {
          this.map.getTargetElement().style.cursor = "pointer";
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
._leftTop {
  height: 80vh;
  width: 80vw;
  #map {
    height: 100%;
    width: 100%;
  }
  .olPopup {
    position: absolute;
    background-color: rgba(47, 57, 90, 0.678);
    padding: 15px;
    color: white;
    border-radius: 10px;
    border: 1px solid #cccccc;
    bottom: 20px;
    left: 30px;
    min-width: 280px;
    .popupClose {
      cursor: pointer;
    }
    .popupClose:hover {
      color: rgba(255, 255, 255, 0.719);
    }
  }
}
</style>

其中url地址可见:openlayer中加载geojson的几种方式_~疆的博客-CSDN博客_openlayers 加载geojson

例2:推荐

基于<el-popover>

也可以不用el-popover组件。用div也可以,只要给这个div添加一个id,用于指向overlayer对象即可。

<template>
  <div class="test">
    <div id="map"></div>
    <el-popover
      id="popup"
      placement="bottom"
      :title="title"
      width="100"
      trigger="click"
      v-model="visible"
    >
      <el-image :src="img" fit="fill" style="margin: 5px;" />
    </el-popover>
  </div>
</template>
 
<script>
import "ol/ol.css";
import { Map, View, Overlay } from "ol";
import { TileWMS, OSM, Vector as VectorSource, XYZ } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";

import Select from "ol/interaction/Select";
import { altKeyOnly, click, pointerMove } from "ol/events/condition";

import {
  defaults as defaultControls,
  OverviewMap,
  FullScreen,
  ScaleLine,
  ZoomSlider,
  MousePosition,
  ZoomToExtent
} from "ol/control";
import GeoJSON from "ol/format/GeoJSON";
import { Fill, Stroke, Style, Circle } from "ol/style";

export default {
  components: {},
  data() {
    return {
      map: {},
      select: {},
      overlayer: {},
      visible: true,
      title: "标题",
      img: ""
    };
  },
  created() {},
  mounted() {
    this.initMap();
  },
  computed: {},
  methods: {
    initMap() {
      let layer_osm = new TileLayer({
        source: new OSM()
      });
      let layer_xyz = new TileLayer({
        source: new XYZ({
          url:
            "http://t3.tianditu.com/DataServer?T=img_w&tk=5a257cd2df1b3311723bd77b0de14baf&x={x}&y={y}&l={z}"
        })
      });
      let style = new Style({
        image: new Circle({
          radius: 20,
          fill: new Fill({
            //矢量图层填充颜色,以及透明度
            color: "rgba(33,194,219,0.5)"
          }),
          stroke: new Stroke({
            //边界样式
            color: "rgba(100, 90, 209, 0.6)",
            width: 3
          })
        })
      });
      let layer_sichuan = new VectorLayer({
        source: new VectorSource({
          url: "test.json", //这个json文件在public文件夹里
          format: new GeoJSON()
        }),
        style: style
      });
      let layers = [layer_osm, layer_xyz, layer_sichuan];
      this.map = new Map({
        layers: layers,
        target: "map",
        view: new View({
          projection: "EPSG:4326",
          center: [104.1, 30.7],
          zoom: 9
        })
      });

      // 2. 创建Overlay图层
      let overlayer = new Overlay({
        element: document.getElementById("popup"),
        autuPan: true
      });

      let select = new Select({
        condition: click,
      });

      this.map.addInteraction(select);
      select.on("select", (e) => {
        if (e.selected.length != 0) {
          let coordinate = e.mapBrowserEvent.coordinate;

          this.properties = e.selected[0].getProperties();

          overlayer.setPosition(coordinate);
          this.map.addOverlay(overlayer);
        } else {
          overlayer.setPosition("");
        }
        this.overlayer = overlayer;
      });
      this.select = select;

      // 设置鼠标划过矢量要素的样式
      this.map.on("pointermove", e => {
        let pixel = this.map.getEventPixel(e.originalEvent); //pixel为当前鼠标屏幕坐标,如 [0,0],[304,642]
        let feature = this.map.forEachFeatureAtPixel(pixel, function(feature) {
          return feature;
        });
        if (feature) {
          this.map.getTargetElement().style.cursor = "pointer";
        } else {
          this.map.getTargetElement().style.cursor = "auto";
        }
      });
    }
  }
};
</script>
 
<style lang="scss" scoped>
.test {
  height: 80vh;
  width: 80vw;
  #map {
    height: 100%;
    width: 100%;
  }
  #popup {
    position: absolute;
    background-color: rgba(47, 57, 90, 0.678);
    bottom: 20px;
    left: 30px;
  }
}
</style>

public/test.json:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "name": "金毛",
                "img": "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=4137348304,121327190&fm=26&gp=0.jpg"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    104.35089111328125,
                    30.8951543714447
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "name": "二哈",
                "img": "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1247111737,2344380133&fm=26&gp=0.jpg"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    103.765869140625,
                    30.59772974841203
                ]
            }
        }
    ]
}

注意:

当实例化一个Overlay后,这个Overlay里面的元素(这里是popup元素)在页面中就会默认被隐藏

将overlay隐藏:

 this.overlayer.setPosition('');

注销事件:

import { unByKey } from "ol/Observable"; //移除事件

还可在overlay对象中添加属性如下:

  • positioning: "bottom-left",
  • offset: [10, -5],

注意:new Overlay中一定要加上 positioning: "center-center"

positioning: "center-center",//一定要加上,否则会有偏移

  

例3(强烈推荐)

写法1:(数据写死)

<template>
  <div>
    <div id="map" style="height: 100vh; width: 100vw"></div>
    <div
      id="popup"
      style="
        position: absolute;
        background-color: rgba(47, 57, 90, 0.678);
        bottom: 20px;
        left: 30px;
        border: 1px solid white;
        padding: 10px;
        width: 60px;
      "
    >
      {{ properties.name }}
    </div>
  </div>
</template>
 
<script>
import "ol/ol.css";
import { Map, View, Overlay } from "ol";
import { OSM, Vector as VectorSource, XYZ } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";

import Select from "ol/interaction/Select";
import { click } from "ol/events/condition";

import GeoJSON from "ol/format/GeoJSON";
import { Fill, Stroke, Style, Circle } from "ol/style";

export default {
  components: {},
  data() {
    return {
      map: {},

      select: {},
      properties: {
        name: "标题",
      },

      geojsonData: {
        type: "FeatureCollection",
        features: [
          {
            type: "Feature",
            properties: {
              name: "标题1",
            },
            geometry: {
              type: "Point",
              coordinates: [104.35089111328125, 30.8951543714447],
            },
          },
          {
            type: "Feature",
            properties: {
              name: "标题2",
            },
            geometry: {
              type: "Point",
              coordinates: [103.765869140625, 30.59772974841203],
            },
          },
        ],
      },
    };
  },
  created() {},
  mounted() {
    this.initMap();
  },
  computed: {},
  methods: {
    initMap() {
      this.map = new Map({
        target: "map",
        layers: [
          new TileLayer({
            source: new OSM(),
          }),
          new VectorLayer({
            source: new VectorSource({
              features: new GeoJSON().readFeatures(this.geojsonData),
            }),
            style: new Style({
              image: new Circle({
                radius: 10,
                fill: new Fill({
                  //矢量图层填充颜色,以及透明度
                  color: "rgba(33,194,219,0.5)",
                }),
                stroke: new Stroke({
                  //边界样式
                  color: "rgba(100, 90, 209, 0.6)",
                  width: 3,
                }),
              }),
            }),
          }),
        ],
        view: new View({
          projection: "EPSG:4326",
          center: [104.1, 30.7],
          zoom: 9,
        }),
      });

      // 创建Overlay图层
      let overlayer_popup = new Overlay({
        element: document.getElementById("popup"),
        positioning: "center-center", //一定要加上,否则会有偏移
      });

      //创建select选择器
      this.select = new Select({
        condition: click,
      });
      this.map.addInteraction(this.select);

      this.select.on("select", (e) => {
        let coordinate = e.mapBrowserEvent.coordinate; //获取选择的坐标

        let featureSelect = e.selected[0]; //选中的feature要素

        if (e.selected.length !== 0) {
          overlayer_popup.setPosition(coordinate);
          this.map.addOverlay(overlayer_popup);
        } else {
          overlayer_popup.setPosition("");
        }

        if (featureSelect) {
          this.properties = featureSelect.getProperties(); //获取当前要素的所有属性
          //设置选中的样式
          featureSelect.setStyle(
            new Style({
              image: new Circle({
                radius: 10,
                fill: new Fill({
                  //矢量图层填充颜色,以及透明度
                  color: "rgba(255,0,0,0.5)",
                }),
                stroke: new Stroke({
                  //边界样式
                  color: "rgba(100, 90, 209, 0.6)",
                  width: 3,
                }),
              }),
            })
          );
        }
      });

      // 设置鼠标划过矢量要素的样式
      this.map.on("pointermove", (e) => {
        const isHover = this.map.hasFeatureAtPixel(e.pixel);
        this.map.getTargetElement().style.cursor = isHover ? "pointer" : "";
      });
    },
  },
};
</script>

写法2:(可动态添加数据)【推荐】

<template>
  <div>
    <div id="map" style="height: 100vh; width: 100vw"></div>
    <div
      id="popup"
      style="
        position: absolute;
        background-color: rgba(47, 57, 90, 0.678);
        bottom: 20px;
        left: 30px;
        border: 1px solid white;
        padding: 10px;
        width: 60px;
      "
    >
      {{ properties.name }}
    </div>
  </div>
</template>
 
<script>
import "ol/ol.css";
import { Map, View, Overlay } from "ol";
import { OSM, Vector as VectorSource, XYZ } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";

import Select from "ol/interaction/Select";
import { click } from "ol/events/condition";

import GeoJSON from "ol/format/GeoJSON";
import { Fill, Stroke, Style, Circle } from "ol/style";

export default {
  components: {},
  data() {
    return {
      map: {},

      select: {},
      properties: {
        name: "标题",
      },

      geojsonData: {
        type: "FeatureCollection",
        features: [
          {
            type: "Feature",
            properties: {
              name: "标题1",
            },
            geometry: {
              type: "Point",
              coordinates: [104.35089111328125, 30.8951543714447],
            },
          },
          {
            type: "Feature",
            properties: {
              name: "标题2",
            },
            geometry: {
              type: "Point",
              coordinates: [103.765869140625, 30.59772974841203],
            },
          },
        ],
      },
      pointLayer: {},
    };
  },
  created() {},
  mounted() {
    this.initMap();
    this.pointerMove();
    this.addPointLayer();
    this.addOverlay();
  },
  computed: {},
  methods: {
    initMap() {
      this.map = new Map({
        target: "map",
        layers: [
          new TileLayer({
            source: new OSM(),
          }),
        ],
        view: new View({
          projection: "EPSG:4326",
          center: [104.1, 30.7],
          zoom: 9,
        }),
      });
    },
    // 设置鼠标划过矢量要素的样式
    pointerMove() {
      this.map.on("pointermove", (e) => {
        const isHover = this.map.hasFeatureAtPixel(e.pixel);
        this.map.getTargetElement().style.cursor = isHover ? "pointer" : "";
      });
    },
    addPointLayer() {
      this.pointLayer = new VectorLayer({
        source: new VectorSource(),
      });

      let features = new GeoJSON().readFeatures(this.geojsonData);

      this.pointLayer.getSource().addFeatures(features);

      this.pointLayer.setStyle(
        new Style({
          image: new Circle({
            radius: 10,
            fill: new Fill({
              //矢量图层填充颜色,以及透明度
              color: "rgba(33,194,219,0.5)",
            }),
            stroke: new Stroke({
              //边界样式
              color: "rgba(100, 90, 209, 0.6)",
              width: 3,
            }),
          }),
        })
      );
      this.map.addLayer(this.pointLayer);
    },
    addOverlay() {
      // 创建Overlay图层
      let overlayer_popup = new Overlay({
        element: document.getElementById("popup"),
        positioning: "center-center", //一定要加上,否则会有偏移
      });

      //创建select选择器
      this.select = new Select({
        condition: click,
      });
      this.map.addInteraction(this.select);

      this.select.on("select", (e) => {
        let coordinate = e.mapBrowserEvent.coordinate; //获取选择的坐标

        let featureSelect = e.selected[0]; //选中的feature要素

        if (e.selected.length !== 0) {
          overlayer_popup.setPosition(coordinate);
          this.map.addOverlay(overlayer_popup);
        } else {
          overlayer_popup.setPosition("");
        }

        if (featureSelect) {
          this.properties = featureSelect.getProperties(); //获取当前要素的所有属性
          //设置选中的样式
          featureSelect.setStyle(
            new Style({
              image: new Circle({
                radius: 10,
                fill: new Fill({
                  //矢量图层填充颜色,以及透明度
                  color: "rgba(255,0,0,0.5)",
                }),
                stroke: new Stroke({
                  //边界样式
                  color: "rgba(100, 90, 209, 0.6)",
                  width: 3,
                }),
              }),
            })
          );
        }
      });
    },
  },
};
</script>

vue3中进行封装

 OverlayTool.js

import "ol/ol.css";
import { Map, View, Overlay } from "ol";
import { OSM, Vector as VectorSource, XYZ } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";

import Select from "ol/interaction/Select";
import { click } from "ol/events/condition";

import GeoJSON from "ol/format/GeoJSON";
import { Fill, Stroke, Style, Circle } from "ol/style";
import { unByKey } from "ol/Observable"; //移除事件

import { useTestStore } from '@/store/index.js'
const TestStore = useTestStore()

export default class OverlayTool {
    constructor({ domId_map, domId_overlay }) {
        this.domId_map = domId_map
        this.domId_overlay = domId_overlay
        this.map = null
        this.source = new VectorSource();
        this.pointLayer = new VectorLayer({
            source: this.source
        });
        this.select = null
        this.overlayer_popup = null
        this.selectHandler = null
        this.pointermoveHandler = null
    }
    initMap() {
        this.map = new Map({
            target: this.domId_map,
            layers: [
                new TileLayer({
                    // source: new OSM(),
                    source: new XYZ({
                        url:
                            "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5a257cd2df1b3311723bd77b0de14baf",
                    })
                }),
            ],
            view: new View({
                projection: "EPSG:4326",
                center: [104.1, 30.7],
                zoom: 9,
            }),
        });
    }
    // 设置鼠标划过矢量要素的样式
    pointerMove() {
        this.pointermoveHandler = this.map.on("pointermove", (e) => {
            const isHover = this.map.hasFeatureAtPixel(e.pixel);
            this.map.getTargetElement().style.cursor = isHover ? "pointer" : "";
        });
    }
    unPointerMove() {
        unByKey(this.pointermoveHandler)
    }

    addSource(geojsonData) {
        let features = new GeoJSON().readFeatures(geojsonData);
        this.source.addFeatures(features);
    }
    addPointLayer() {
        this.map.addLayer(this.pointLayer);
    }
    removePointLayer() {
        this.map.removeLayer(this.pointLayer);
    }
    setStyle_point() {
        this.pointLayer.setStyle(
            new Style({
                image: new Circle({
                    radius: 10,
                    fill: new Fill({
                        //矢量图层填充颜色,以及透明度
                        color: "rgba(33,194,219,0.5)",
                    }),
                    stroke: new Stroke({
                        //边界样式
                        color: "rgba(100, 90, 209, 0.6)",
                        width: 3,
                    }),
                }),
            })
        );
    }
    addOverlay() {
        if (this.overlayer_popup) {
            this.map.removeOverlay(this.overlayer_popup);
        }
        // 创建Overlay图层
        this.overlayer_popup = new Overlay({
            element: document.getElementById(this.domId_overlay),
            positioning: "center-center", //一定要加上,否则会有偏移
        });
        this.map.addOverlay(this.overlayer_popup);
    }
    hideOverlay() {
        this.overlayer_popup.setPosition("");
    }
    showOverlay(position) {
        this.overlayer_popup.setPosition(position)
    }
    unSelect() {
        unByKey(this.selectHandler)
        this.map.removeInteraction(this.select);

    }
    onSelect() {
        //创建select选择器
        this.select = new Select({
            condition: click,
        });
        this.map.addInteraction(this.select);

        this.selectHandler = this.select.on("select", (e) => {

            let coordinate = e.mapBrowserEvent.coordinate; //获取选择的坐标
            let featureSelect = e.selected[0]; //选中的feature要素

            if (e.selected.length !== 0) {
                this.showOverlay(coordinate)
            } else {
                this.hideOverlay()
            }

            if (featureSelect) {
                let properties_selectFeature = featureSelect.getProperties(); //获取当前要素的所有属性
                TestStore.properties_selectFeature = properties_selectFeature
                //设置选中的样式
                featureSelect.setStyle(
                    new Style({
                        image: new Circle({
                            radius: 10,
                            fill: new Fill({
                                //矢量图层填充颜色,以及透明度
                                color: "rgba(255,0,0,0.5)",
                            }),
                            stroke: new Stroke({
                                //边界样式
                                color: "rgba(100, 90, 209, 0.6)",
                                width: 3,
                            }),
                        }),
                    })
                );
            }
        });
    }




}

index.vue:

<template>
    <div class="main">
        <el-button @click="cancelSelect">取消选中</el-button>
        <div id="olContainer" style="height: 100vh; width: 100vw"></div>
        <div id="popup" style="
        position: absolute;
        background-color: rgba(47, 57, 90, 0.678);
        bottom: 20px;
        left: 30px;
        border: 1px solid white;
        padding: 10px;
        width: 60px;
      ">
            {{TestStore.properties_selectFeature?.name}}
        </div>

    </div>

</template>
  
<script setup>
import OverlayTool from './OverlayTool'
import { useTestStore } from '@/store/index.js'
const TestStore = useTestStore()
const geojsonData = {
    type: "FeatureCollection",
    features: [
        {
            type: "Feature",
            properties: {
                name: "标题1",
            },
            geometry: {
                type: "Point",
                coordinates: [104.35089111328125, 30.8951543714447],
            },
        },
        {
            type: "Feature",
            properties: {
                name: "标题2",
            },
            geometry: {
                type: "Point",
                coordinates: [103.765869140625, 30.59772974841203],
            },
        },
    ],
}
let _overlay = null
const cancelSelect = () => {
    _overlay.unPointerMove()
    _overlay.hideOverlay()
    _overlay.unSelect()
}
onMounted(() => {
    const overlay = new OverlayTool({ domId_map: 'olContainer', domId_overlay: 'popup' })
    overlay.initMap()
    overlay.addSource(geojsonData)
    overlay.addPointLayer()
    overlay.pointerMove()
    overlay.setStyle_point()
    overlay.addOverlay()
    overlay.onSelect()

    _overlay = overlay

})
</script>
<style lang="scss" scoped>
.main {
    position: relative;
    height: 100vh;
    width: 100vw;

    #olContainer {
        position: absolute;
        height: 100vh;
        width: 100vw;
    }

}
</style>

pinia中全局存储 store/index.js: 

import { defineStore } from "pinia";
export const useTestStore = defineStore('Test', {
    state: () => {
        return {
            properties_selectFeature: {
                name: ""
            }
        }
    },
    getters: {
    },
    actions: {
    },
})

示例3

 

 实现代码:


<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>openlayers|js2d</title>

    <script src="https://file.ljgis.com/ol/latest/dist/ol.js"></script>
    <link rel="stylesheet" href="https://file.ljgis.com/ol/latest/ol.css">
    <style>
        html,
        body,
        #map {
            width: 100vw;
            height: 100vh;
            margin: 0px;
            padding: 0px;
        }

        .ol-popup {
            position: absolute;
            background-color: white;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
            padding: 15px;
            border-radius: 10px;
            border: 1px solid #cccccc;
            bottom: 12px;
            left: -50px;
            min-width: 280px;
        }

        .ol-popup:after,
        .ol-popup:before {
            top: 100%;
            border: solid transparent;
            content: " ";
            height: 0;
            width: 0;
            position: absolute;
            pointer-events: none;
        }

        .ol-popup:after {
            border-top-color: white;
            border-width: 10px;
            left: 48px;
            margin-left: -10px;
        }

        .ol-popup:before {
            border-top-color: #cccccc;
            border-width: 11px;
            left: 48px;
            margin-left: -11px;
        }

        .ol-popup-closer {
            text-decoration: none;
            position: absolute;
            top: 2px;
            right: 8px;
        }

        .ol-popup-closer:after {
            content: "✖";
        }
    </style>
</head>

<body>
    <div id="map" class="map"></div>
    <div id="popup" class="ol-popup">
        <a id="popup-closer" class="ol-popup-closer"></a>
        <div id="popup-content"></div>
    </div>
    <script>
        let map = new ol.Map({
            target: "map",
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
                    })
                })],
            view: new ol.View({
                projection: "EPSG:3857",
                center: ol.proj.fromLonLat([108.522097, 37.272848]),
                zoom: 4,
            }),
        });
        let source = new ol.source.Vector({
            url: "https://file.ljgis.com/common/vectorSource/geojson/sichuan/sichuan.json",
            format: new ol.format.GeoJSON()
        })

        let layer = new ol.layer.Vector()
        layer.setSource(source)

        map.addLayer(layer)

        let style = new ol.style.Style({
            fill: new ol.style.Fill({
                color: "rgba(255, 255, 255, 0.2)",
            }),
            stroke: new ol.style.Stroke({
                color: "#ffcc33",
                width: 2,
            }),
            image: new ol.style.Circle({
                radius: 7,
                fill: new ol.style.Fill({
                    color: "#ffcc33",
                }),
            }),
        })

        let select = new ol.interaction.Select({
            condition: ol.events.condition.click, //将默认的singleClick声明为click,使点击无延迟
            style: style
        });
        map.addInteraction(select)

        map.on("pointermove", (e) => {
            map.getTargetElement().style.cursor = map.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
        });

        const container = document.getElementById("popup");
        const content = document.getElementById("popup-content");
        const closer = document.getElementById("popup-closer");

        let overlay = new ol.Overlay({
            element: container,
            positioning: "center-center", //一定要加上,否则会有偏移
        });
        map.addOverlay(overlay)

        select.on("select", e => {
            let feature = e.selected[0];
            if (!feature) {
                overlay.setPosition("")
                return
            };
            let { name, adcode } = feature?.getProperties();
            content.innerHTML = `
                <div>name:${name}</div>
                <div>adcode:${adcode}</div>
            `
            overlay.setPosition(e.mapBrowserEvent.coordinate)
        })

        closer.onclick = () => {
            overlay.setPosition("")
        }



    </script>
</body>

</html>

要在OpenLayers地图上点击位置后弹出提示框,可以使用Overlay和Popup来实现。以下是一个简单的例子: ```javascript // 创建地图 var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([116.3975, 39.9086]), zoom: 10 }) }); // 创建一个VectorLayer用于添加点 var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); // 创建一个Overlay用于显示提示框 var popupOverlay = new ol.Overlay({ element: document.getElementById('popup'), autoPan: true, autoPanAnimation: { duration: 250 } }); // 创建一个点击事件处理函数 function handleMapClick(event) { // 获取点击位置的坐标 var coordinate = event.coordinate; // 创建一个点Feature并添加到VectorLayer上 var feature = new ol.Feature({ geometry: new ol.geom.Point(coordinate) }); vectorLayer.getSource().addFeature(feature); // 设置提示框内容为坐标 var content = '<p>坐标:' + coordinate + '</p>'; document.getElementById('popup-content').innerHTML = content; // 将提示框显示在点击位置上 popupOverlay.setPosition(coordinate); map.addOverlay(popupOverlay); } // 监听Map对象的"click"事件,并在回调函数中处理点击事件 map.on('click', handleMapClick); // 将VectorLayer添加到地图上 map.addLayer(vectorLayer); ``` 在HTML中还需要添加一个Popup的容器,如下所示: ```html <div id="map"></div> <div id="popup" class="ol-popup"> <a href="#" id="popup-closer" class="ol-popup-closer"></a> <div id="popup-content"></div> </div> ``` 这样就可以在地图上点击位置后弹出提示框了,提示框会显示点击位置的坐标。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值