OpenLayers 4标尺

时间:2018-12-18 12:22:17

标签: javascript module openlayers

我正在使用模块重构应用程序的整个代码,现在我对OpenLayers 4的Ruler功能有一些疑问。

在前面的代码中工作正常,但是现在当我双击地图以停止当前度量并开始一个新度量时,屏幕上唯一剩下的就是弹出窗口,即该行(正在测量)。

这是我的代码:

const initVector = (mapView) => {
  /**
   * vector layers sources
   */
  $('.form-inline').click(function () {
    addRuler()
    alert("initialize")
  })

  let Rsource = new ol.source.Vector()

  let rulerLayer = new ol.layer.Vector({
    source: Rsource,
    style: new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new ol.style.Stroke({
        color: 'rgba(0, 0, 0, 0.7)',
        width: 3
      }),
      image: new ol.style.Circle({
        radius: 7,
        fill: new ol.style.Fill({
          color: 'rgba(0, 0, 0, 0.7)'
        })
      })
    })
  })
  /*
   * ruler tool handler
   */

  /**
   * global vars
   */

  // this style is done by javascript to bypass the override rule that enter in conflict with FRA
  $('.markers button').css({'margin': '5px 7px', 'padding': '0 10px'})
  $('#markloc').css('margin-left', '5px')

  // these var are for the creation of the text and all the related element during the measure
  let sketch
  let helpTooltipElement
  let helpTooltip
  let measureTooltipElement
  let measureTooltip
  let ruler

  /*
   * pointer handler
   */

  const pointerMoveHandler = (evt) => {
    /*
     * if the mouse is dragging the map return
     */

    if (evt.dragging) {
      return
    }

    /**
     * default message to display
     */

    let helpMsg = 'Click to start drawing'

    /**
     * check the message if you are measuring
     */

    if (sketch) {
      helpMsg = 'Click to continue drawing the line or double click to stop.'
    }

    /**
     * attach to the tooltip the correct message
     * set the position near the mouse cursor
     * display the tooltip
     */

    helpTooltipElement.innerHTML = helpMsg
    helpTooltip.setPosition(evt.coordinate)
    helpTooltipElement.classList.remove('hidden')
  }

  /**
   * display the actual measured length
   */

  function formatLength (line) {
    const length = ol.Sphere.getLength(line)
    let output

    if (length > 100) {
      output = `${Math.round(length / 1000 * 100) / 100} km`
    }
    else {
      output = `${Math.round(length * 100) / 100} m`
    }
    return output
  }

  /**
   * create a new tooltip
   */

  function createHelpTooltip () {
    helpTooltipElement = document.createElement('div')
    helpTooltipElement.className = 'tooltip hidden'
    helpTooltip = new ol.Overlay({
      element: helpTooltipElement,
      offset: [15, 0],
      positioning: 'center-left'
    })
    mapView.addOverlay(helpTooltip)
  }

  /**
   * Creates a new measure tooltip
   */

  function createMeasureTooltip () {
    measureTooltipElement = document.createElement('div')
    measureTooltipElement.className = 'tooltip tooltip-measure'
    measureTooltip = new ol.Overlay({
      element: measureTooltipElement,
      offset: [0, -15],
      positioning: 'bottom-center'
    })
    mapView.addOverlay(measureTooltip)
  }

  /**
   * add the ruler when you click on the button
   */

  function addRuler () {
    /**
     * add a selected class to the ruler button to make it visible that it's in use
     */

    $('#tlruler').addClass('custbtnsel')

    /**
     * styling ruler
     */

    ruler = new ol.interaction.Draw({
      source: Rsource,
      type: 'LineString',
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new ol.style.Circle({
          radius: 5,
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          })
        })
      })
    })

    /**
     * call the pointerMoveHandler to create the element on the screen when the ruler it's in use
     */

    mapView.on('pointermove', pointerMoveHandler)

    /**
     * mouseout event listener to hidden the popup
     */

    mapView.getViewport().addEventListener('mouseout', () => {
      helpTooltipElement.classList.add('hidden')
    })

    /**
     * add the ruler interaction to the map
     */

    mapView.addInteraction(ruler)

    /**
     * create the tooltip
     */

    createMeasureTooltip()
    createHelpTooltip()

    let listener

    /**
     * drawstart event
     */

    ruler.on('drawstart', function (evt) {
      // set sketch
      sketch = evt.feature
      // tooltip coordinate
      let tooltipCoord = evt.coordinate

      /**
       * sketch event listener on change
       * called during a mouse move
       */

      listener = sketch.getGeometry().on('change', function (evt) {
        let geom = evt.target

        /**
         * as we don't use polygon we check justfor line
         * get last position of the cursor and the length
         */

        let output

        // OL 5 CODE
        // if (geom instanceof LineString)

        if (geom instanceof ol.geom.LineString) {
          output = formatLength(geom)
          tooltipCoord = geom.getLastCoordinate()
        }

        /**
         * append to the tooltip the measure
         * set the position of the tooltip to the last cursor coord
         */

        measureTooltipElement.innerHTML = output
        measureTooltip.setPosition(tooltipCoord)
      })
    }, this)

    /**
     * drawend event
     */

    ruler.on('drawend', () => {
      /**
       * create the static tooltip with the last measure
       */
      console.log('drawend')

      measureTooltipElement.className = 'tooltip tooltip-static'
      measureTooltip.setOffset([0, -7])

      /**
       * set sketch and the tooltip element to null
       */

      sketch = null
      measureTooltipElement = null

      /**
       * set sketch and the tooltip element to null
       */

      createMeasureTooltip()
      // OL 5 code
      // unByKey(listener);
      ol.Observable.unByKey(listener)
    }, this)

    /**
     * end addRuler function
     */
  }
}

const mapLayer = new ol.layer.Tile({
  source: new ol.source.OSM()
});

let map = new ol.Map({
  layers: [mapLayer],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 10
  })
})
initVector(map)  

笔的链接,以便您可以对其进行测试

https://codepen.io/sebalaini/pen/OrRELp?editors=0010

以及此处的工作方式:

https://openlayers.org/en/latest/examples/measure.html

请注意,由于我的地图是在模块内部创建的,而标尺是在另一个模块中创建的,因此我创建了一个用于初始化标尺以模拟模块的函数,然后导入该函数并使用map变量对其进行初始化< / p>

1 个答案:

答案 0 :(得分:0)

感谢@Mike在Gis.stackexchange中回答了我。

在创建RulerLayer之后,在initVector中需要将其添加到地图map.addLayer(rulerLayer);

一个很小的错误。