首页 / 浏览问题 / WebGIS / 问题详情
当wrapX为true时,地图放大到一定级别后,画线不显示
9EXP 2023年07月14日
使用产品:for OpenLayers 数据类型:文集型 问题详细描述: var source = new sourceVector({ wrapX: true, }); 使用画线工具,画出线段后地图放大到一定级别,所画线段消失,缩小又出现,或直接放大到一定级别划线也不会显示。

1个回答

您好,这边在测试了官网版本并未出现该情况,https://iclient.supermap.io/examples/openlayers/editor.html#drawFeatures

请问使用的版本是多少呢?

1,865EXP 2023年07月14日
就是在官网测试的

方法一

1. 源代码改掉52行 var source = new ol.source.Vector({wrapX: true});

2.地图先缩小到能够看到两个中国在上面。

3.放大左边一个中国下面的印度尼亚,10级以上。

4.再去画线就没有不会显示了。
请问是只能在步骤3的位置才会复现吗?这边测试了不管是先绘制再缩放还是缩放了再绘制,线段并未消失。 如果您测试官网依然有问题,可以私信我qq,我联系您看一下具体操作。

已qq联系用户解决。这里统一回复处理结果:原生也存在这样的问题:https://github.com/openlayers/openlayers/issues/5128  这边回复了一个绕行方案,在geometryFunction中处理一下要素的坐标调整到范围内,这个例子里只处理了line,其他的geometry类似处理就行,具体示例见:

<!--********************************************************************
* Copyright© 2000 - 2023 SuperMap Software Co.Ltd. All rights reserved.
*********************************************************************-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title data-i18n="resources.title_drawFeatures">平铺地图绘制几何图形缩放过程消失</title>
    <script type="text/javascript" src="https://iclient.supermap.io/dist/ol/include-ol.js"></script>
    <style>
      .ol-popup {
        position: absolute;
        top: 50px;
        right: 20px;
      }
    </style>
  </head>
  <body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
    <div id="map" style="width: 100%; height: 100%"></div>
    <div id="popup" class="ol-popup">
      <div class="btn-group" role="group" aria-label="...">
        <button
          id="drawPoint"
          value="Point"
          type="button"
          class="btn btn-default"
          data-i18n="resources.text_input_value_drawPoint"
        ></button>
        <button
          id="drawLine"
          value="LineString"
          type="button"
          class="btn btn-default"
          data-i18n="resources.text_input_value_drawLine"
        ></button>
        <button
          id="drawPolygon"
          value="Polygon"
          type="button"
          class="btn btn-default"
          data-i18n="resources.text_input_value_drawPolygon"
        ></button>
        <button
          id="drawCircle"
          value="Circle"
          type="button"
          class="btn btn-default"
          data-i18n="resources.btn_drawCircle"
        ></button>
        <button id="none" value="None" type="button" class="btn btn-default" data-i18n="resources.btn_notDraw"></button>
        <button
          id="clear"
          value="Clear"
          type="button"
          class="btn btn-default"
          data-i18n="resources.text_input_value_clear"
        ></button>
      </div>
    </div>
    <script type="text/javascript" include="jquery,bootstrap" src="https://iclient.supermap.io/examples/js/include-web.js"></script>
    <script type="text/javascript">
      var map,
        draw,
        url =
          (window.isLocal ? window.server : 'https://iserver.supermap.io') +
          '/iserver/services/map-china400/rest/maps/China';
      map = new ol.Map({
        target: 'map',
        wrapX: true,
        controls: ol.control
          .defaults({ attributionOptions: { collapsed: false } })
          .extend([new ol.supermap.control.Logo({ link: 'https://iclient.supermap.io' })]),
        view: new ol.View({
          center: [12957388, 4853991],
          zoom: 1,
          projection: 'EPSG:3857',
          multiWorld: true
        })
      });
      var layer = new ol.layer.Tile({
        source: new ol.source.TileSuperMapRest({
          url: url,
          wrapX: true
        }),
        projection: 'EPSG:3857'
      });
      var source = new ol.source.Vector({ wrapX: true, useSpatialIndex: false });
      var vector = new ol.layer.Vector({
        renderBuffer: 100000,
        source: source
      });
      map.addLayer(layer);
      map.addLayer(vector);
      var info = new ol.control.Control({ element: document.getElementById('popup') });
      info.setMap(map);
      map.addControl(info);

      var buttons = $('.btn-group').children();
      buttons.map(function (key) {
        var value = buttons[key].value;
        if (value === 'None') {
          $(buttons[key]).on('click', function () {
            clearInteraction();
          });
          return;
        }
        if (value === 'Clear') {
          $(buttons[key]).on('click', function () {
            clearInteraction();
            source.clear();
          });
          return;
        }
        $(buttons[key]).on('click', function () {
          clearInteraction();
          draw = new ol.interaction.Draw({
            source: source,
            type: buttons[key].value,
            snapTolerance: 20,
            geometryFunction: function(coord, geometry, projection) {
              let newGeometry = coord.map((coordinate) => {
                return wrapX(coordinate, projection)
              });
              if (geometry) {
                geometry.setCoordinates(newGeometry, this.geometryLayout_);
              } else {
                geometry = new ol.geom.LineString(newGeometry, 'XY');

              }
              return geometry;
            },
            wrapX: true
          });
          map.addInteraction(draw);
        });
      });

      function clearInteraction() {
        if (draw) {
          map.removeInteraction(draw);
        }
      }

      function wrapX(coordinate, projection) {
        if (projection.canWrapX()) {
          const worldWidth = getWidth(projection.getExtent());
          const worldsAway = getWorldsAway(coordinate, projection, worldWidth);
          if (worldsAway) {
            coordinate[0] -= worldsAway * worldWidth;
          }
        }
        return coordinate;
      }

      function getWorldsAway(coordinate, projection, sourceExtentWidth) {
        const projectionExtent = projection.getExtent();
        let worldsAway = 0;
        if (projection.canWrapX() && (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])) {
          sourceExtentWidth = sourceExtentWidth || getWidth(projectionExtent);
          worldsAway = Math.floor((coordinate[0] - projectionExtent[0]) / sourceExtentWidth);
        }
        return worldsAway;
      }

      function getWidth(extent) {
        return extent[2] - extent[0];
      }
    </script>
  </body>
</html>

...