This is the 9th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021.”


Previous articles in this series:

  1. 【 VUe-Cesium 】 3d map development using Cesium on VUE (part 1)
  2. 【 VUe-Cesium 】 3d map development using Cesium on VUE (part 2)
  3. 【 VUe-cesium 】 3d map development using Cesium on VUE (ii) Continued
  4. 【 VUe-Cesium 】 3d map development using Cesium on VUE (3)
  5. 【 VUe-cesium 】 using CESium on VUE to develop 3d map (four) map loading
  6. 【 VUe-cesium 】 Using CESium on VUE to develop 3d map (five) point loading

Common webGIS functions are shown as follows:

Today under thePoint bounced

Optimize yesterday’s code

Before we talk about today’s code, let’s first optimize yesterday’s code to the optimized effect:

In order to be closer to the real project, I used axiOS to adjust the interface to obtain the data of points, and I wrote the method of installing AXIOS here [VUE Start] to build vUE project quickly and introduce third-party plug-ins

And the simulated JSON data, I have also written in this article, you can go to see

To optimize

Now, as I said before, in the real world, you have different points, so you need to show different point ICONS according to the point type and we’re going to write the point ICONS as a way to determine the point type

Clear the previous point data, also changed to a method

The method of loading point points, using Axios

Point bounced

The effect is as follows:

Feature begins, click on the event

Dot pop-ups come out after clicks, so the first thing we’re going to do now is fix cesium’s click events

ScreenSpaceEventHandler ScreenSpaceEventType

Latitude and longitude acquisition

The effect of popover is to click on an existing point model and open it on the right side of the point. The principle is to obtain the screen coordinates of the click point and assign the coordinates Y and X to the top and left attributes of div respectively. Now we need to get screen coordinates.

The following is related to creating a pop-up

The Sence of the cesiumAPI is used here

Show and hide the bullet box, using jquery, also install it, refer to [VUE start] quick build VUE project to introduce a third party plug-in

1. Create a popover div

There are two ways to create a popbox. Choose according to your actual situation:

  1. You can create one directly in HTML<div> I'm popbox </div>The TAB then pops the content throughJs to add to it
  2. You can also use js methods directlydocument.createElement('div');The method inCreate HTML tags in js, and then construct the frame

Because we are the vue development, component thinking is more suitable for our this scenario, we will choose the first way, in HTML to create a < div > I was bounced < / div > tags, bounced the content inside can be different according to the business, to show the content of the page, the content we introduced by means of component, and this way, It also avoids the complexity of writing a lot of code in the same.vue file.

  <div id="container" class="box">
    <div id="cesiumContainer"></div>
    <! -- Map bubble box -->
    <div class="" id="one">
        <module1Popup :pointInfo="popData" ref="popUp"/>

import cesiumPopup from "./cesiumPopup.vue";

export default {
  name: 'HelloWorld'.components: {
Copy the code

If I wanted to add something else to the frame, I could add other components to enrich the frame, which would be nice


The HTML part needs to have a pop box

  <div id="container" class="box">
    <div id="cesiumContainer"></div>
    <! -- Map popup -->
    <div class="dynamic-layer" id="one">
      <div class="line"></div>
      <div class="main">
        <cesiumPopup :pointInfo="popData" ref="popUp" />
Copy the code

The CSS section needs to be styled

/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- play style ------------------------------------------------------.dynamic-layer {
  display: none;
  user-select: none;
  pointer-events: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 534px;
  // width: 100%; // Set it to100%Attempts to set specific widths within components based on content have been found to be ineffectivez-index: 99990;
.dynamic-layer .line {
  position: absolute;
  left: 0;
  width: 0;
  /* height: 100px; * /
  bottom: 0;
  /* background: url(./img/line.png); * /
.dynamic-layer .main {
  display: none;
  position: absolute;
  top: 0;
  left: 30px;
  right: 0;
  /* bottom: 100px; * /
  transform: translateY(-100%);
  background: url(~@/assets/map/layer_border.png) no-repeat;
  background-size: 100% 100%;
  color: white;
  padding: 20px 20px 20px 20px;
  font-size: 14px;
  user-select: text;
  pointer-events: auto;
  background-color: rgba(; } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- play style ------------------------------------------------------Copy the code

Big head play, JS part, need to pay attention to the place have written notes, we rest assured to eat

  methods: {
  init(){...// Listen for map click events
      const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
      // Click events
      handler.setInputAction((click) = > {
        console.log("Left-click event:", click.position);
        // Screen coordinates to world coordinates -- key points
        const cartesian =, this.viewer.scene.globe.ellipsoid);
        // Convert Cartesian coordinates to geographic coordinates
        const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        // Convert radians to degrees in decimal notation, reserving 5 decimal places
        const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
        const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);
        console.log(lon, lat);

        // Get the entity coordinates on the map
        const pick = this.viewer.scene.pick(click.position);
        // If pick is not undefined, then it is a point-to-point position
        if (pick && {
          // Locate to the center of the map
          // this.locationToCenter(lon, lat);
          const data = {
            layerId: "layer1".// An internal entity can be used
            lon: lon,
            lat: lat,
            element: "#one".// Unique ID of the subrack
            boxHeightMax: 0.// Maximum height of the middle cube

          this.showDynamicLayer(this.viewer, data, () = > { // The callback changes the contents of the popover;
            this.popData.title =;
            this.popData.pointId =;
          // Call the default method of the popbox
        } else {
          // Remove the popbox
          if (document.querySelector("#one")) {
            this.removeDynamicLayer(this.viewer, { element: "#one" });
            this$("#one").css("z-index", -1); } } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); },...// Create a dynamic entity popover
    showDynamicLayer(viewer, data, callback) {
      /* Dom manipulation of popovers -- the default must be */
      this.$(data.element).css({ opacity: 0 }); // Using hide() or display will not work because cesium is a pre timed redraw div, so the left top display will always be redrawn
      this$(".dynamic-layer .line").css({ width: 0 });
      /* Popover DOM manipulation -- specific manipulation */

      // Add div pop-ups
      const lon = data.lon * 1, lat = * 1;
      // data.boxHeightMax is fine for undef
      var divPosition = this.cesium.Cartesian3.fromDegrees(lon, lat, data.boxHeightMax);
      this$("#one").css({ opacity: 1 });
        width: 50 // Line width
      }, 500.() = > {
      // When true, element is automatically hidden when it is behind the earth. The default is false, set it to false, it won't do that. But at least it takes the pressure off judgment calculations
      this.creatHtmlElement(viewer, data.element, divPosition, [10, -0].true);

    // Create an htmlElement and it will be automatically hidden behind Earth
    creatHtmlElement(viewer, element, position, arr, flog) {
      const Cesium = this.cesium;
      var ele = document.querySelector(element);
      var scratch = new Cesium.Cartesian2(); The Cartesian coordinate system is known as the two-dimensional coordinate system; Same thing in three dimensions
      var scene = viewer.scene, camera =;
      scene.preRender.addEventListener(() = > {
        var canvasPosition = scene.cartesianToCanvasCoordinates(position, scratch); / / cartesianToCanvasCoordinates cartesian coordinates (three dimension) to the canvas coordinates
        if (Cesium.defined(canvasPosition)) {
 = canvasPosition.x + arr[0] + "px";
 = canvasPosition.y + arr[1] + "px";
          /* **/// var px_position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian)
          if (flog && flog == true) {
            var e = position, i = camera.position, n = scene.globe.ellipsoid.cartesianToCartographic(i).height
            if(! (n +=1 * scene.globe.ellipsoid.maximumRadius, Cesium.Cartesian3.distance(i, e) > n)) {
              // $(element).show()
     = "block";
            } else {
     = "none";
              // $(element).hide()}}}}); },// Remove the dynamic popover. In order to make it easier to remove the popover, you need to rebuild the popover doom
    removeDynamicLayer(viewer, data) {
      document.querySelector(data.element).style.opacity = 0; }},Copy the code

Now the popbox is created

Ps: now the unloader cesiumpopup. vue does not put anything in it:

  <div>I am a bullet box</div>

export default {
  methods: {
Copy the code

A quick explanation of the code in JS

2. Bind to the click event

Called in the left click listener event, in the click event through the pick to determine whether the point object is selected (this method can be learned in the official API)

Click on the monitoring event based on the extension, through pick to determine whether to select the object, selected after opening a popup window, display the incoming information

3. Make the popover move with the point

Zooming in and out of the map or moving points will cause the need to move the popover, so it is necessary to complete the effect of popover movement by listening.

Pre-rendered preRender

Scene, as I understand it, is the whole canvas after rendering. The map and a series of things are in this canvas

I find the method of viewer. Scene. PreRender. AddEventListener

Cesium is a container for all 3D graphics objects and states in the virtual scene,

Gets the events raised immediately after the scene is updated and before the scene is rendered.

4. Point to earth behind popup hide

Because my current business is basically on a map of a certain area, you don’t have to scale the map to a globe and then move the globe around. But it’s also implemented in the code, it’s also commented.

Let’s see what happens

Next day forecast

  1. Since we use components to do the box, so must involve the transfer of value
  2. Now the point popbox is displayed on the right, so in our common business, the point popbox is displayed on the top of the point, so how to change?
  3. Gis projects usually have content on the left and right side of the map, and sometimes when you’re working on the left and right side of the map, you have to locate the point, and that’s not when you’re clicking on the point. At this time, through the left and right side operation, the box pops out, this is the point, the four corners of the box can not come out, and then after the box pops out, how do you know which point the box corresponds to?

We’ll find out in the next video

Now that you’ve seen this, please give me a thumbs up before you go, because your thumbs up means a lot to me