首页 / 浏览问题 / WebGIS / 问题详情
更新地图上图标位置速度过快,浏览器后台警告且更新频率下降
9EXP 2023年03月01日

使用产品:SuperMap REST 地图服务底图

操作系统:win10 x64 edge

问题描述以及问题重现步骤:

1. 地图上加载一个图标

2. 一秒钟移动20次位置,持续一段时间

3. 浏览器后台频繁提示

Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently

4. 连续移动几秒后,图标移动频率降低到大约1次/秒,重新缩放地图,则再次恢复移动速度到 20次/秒

有没有办法取消掉后台这个警告?以及解决一秒内多次移动的问题


问题补充:

请求的是这个地址:

'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China'
  const url = (window.isLocal ? window.server : 'https://iserver.supermap.io') + '/iserver/services/map-china400/rest/maps/China'

  window.map = new ol.Map({
    target: 'map2d-box',
    controls: ol.control.defaults(
      {
        attributionOptions: {
          collapsed: false
        }
      }),

    view: new ol.View({
      center: ol.proj.fromLonLat([113.5, 32.5]),
      zoom: 3.1,
      projection: 'EPSG:3857',
      multiWorld: true
    })
  })

1秒钟移动20次指的是:我这边有个物体移动轨迹,一秒钟给20个位置坐标,然后我把这个物体用图标表示在地图上。移动物体图标代码:

setInterval(() => {
    
    const feature = layer.getSource().getFeatureById(id)// 这个是那个物体的feature

    feature.getGeometry().setCoordinates(fromLonLat(location)) // 这个是物体的新的位置

}, 50);

我不知道我表述清楚没有,有些词我不明白是啥意思,我直接给你上代码吧

库我用的是iclient-ol, 开发的时候参照 openlayers.org


和这个问题不相关的疑问:

链接: openlayers 在地图上绘制矩形框,非鼠标框选

1个回答

您好,您是使用具体哪个iClient加载rest地图服务有问题,还是iserver地图服务内置的哪个预览有这个问题。

1秒钟移动20次您具体指的是什么样的实际应用场景,

鼠标快速拖动地图范围、代码移动地图范围、未切缓存的地图服务使用数据服务修改数据集中的数据点位、

和rest地图服务无关,使用iClient前端代码动态添加的点对象修改点位位置或者是什么其他情况呢?

需要您准确具体的描述下您的问题才好帮您排查。
于丁
1
9,623EXP 2023年03月01日

surprisesurprisesurprise

你电脑上的话,你看看和浏览器品种有没有关系,浏览器的缩放比例,windows的缩放比例、像素,屏幕。

那你知道这个为啥这么写吗?

var polygon = new ol.geom.Polygon([coords]); // 矩形构造方法,不知道这里为啥又套了一层数组,去掉这层数组则无法显示矩形
如果这么写的话,按照上面的例子,传入的内容为[ [ [110,20],[112,22],[114,25],[116,28],[111,40],[110,20] ] ]岂不是没有按照一般人的思路来,为什么多套一层?


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title data-i18n="resources.title_tiledMapLayer3857"></title>
<script type="text/javascript" src="../js/include-web.js"></script>
<script type="text/javascript" src="../../dist/ol/include-ol.js"></script>
</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>
<script type="text/javascript">
      var map,
        url =
          (window.isLocal ? window.server : 'https://iserver.supermap.io') +
          '/iserver/services/map-china400/rest/maps/China';
      // 方式一:1.调用 ol.supermap.initMap,根据 SuperMap iServer 地图服务的地图信息,创建地图和底图
    //   ol.supermap.initMap(url, {
    //     mapOptions: {
    //       controls: ol.control
    //         .defaults({ attributionOptions: { collapsed: false } })
    //         .extend([new ol.supermap.control.Logo()])
    //     }
    //   });
      
      /* 方式二:1.调用 ol.supermap.MapService,获取 SuperMap iServer 地图服务的地图信息
                2.调用 ol.supermap.viewOptionsFromMapJSON 获取地图视图参数
                3.调用 ol.Map 创建地图
                4.调用 ol.layer.Tile 与 ol.source.TileSuperMapRest 创建底图
      */
      new ol.supermap.MapService(url).getMapInfo(function (serviceResult) {
        const mapObj = serviceResult.result;
        map = new ol.Map({
          target: 'map',
          controls: ol.control
            .defaults({ attributionOptions: { collapsed: false } })
            .extend([new ol.supermap.control.Logo()]),
          view: new ol.View(ol.supermap.viewOptionsFromMapJSON(mapObj))
        });
        var layer = new ol.layer.Tile({
          source: new ol.source.TileSuperMapRest(ol.source.TileSuperMapRest.optionsFromMapJSON(url, mapObj, true))
        });
        map.addLayer(layer);
        map.addControl(new ol.supermap.control.ScaleLine());
        
        
        var coords = [[110,20],[112,22],[114,25],[116,28],[111,40],[110,20]]; // 矩形坐标数组
        
        var vectorLayer = new ol.layer.Vector();
        var vectorSource = new ol.source.Vector();
        var polygon = new ol.geom.Polygon([coords]); // 矩形构造方法,不知道这里为啥又套了一层数组,去掉这层数组则无法显示矩形
        polygon.applyTransform(ol.proj.getTransform('EPSG:4326', 'EPSG:3857')); // 4326 对应的是经纬度坐标系,3857叫墨卡托?反正不是经纬度,需要做个转换
        vectorSource.addFeature(new ol.Feature(polygon)); // 形成Feature,并添加到source
        vectorLayer.setSource(vectorSource); // layer设置source
        map.addLayer(vectorLayer); // 将layer加入地图
      });
    </script>
</body>
</html>

因为 Polygon 可以做多对象复合多边形呢wink


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title data-i18n="resources.title_tiledMapLayer3857"></title>
<script type="text/javascript" src="../js/include-web.js"></script>
<script type="text/javascript" src="../../dist/ol/include-ol.js"></script>
</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>
<script type="text/javascript">
      var map,
        url =
          (window.isLocal ? window.server : 'https://iserver.supermap.io') +
          '/iserver/services/map-china400/rest/maps/China';
      // 方式一:1.调用 ol.supermap.initMap,根据 SuperMap iServer 地图服务的地图信息,创建地图和底图
    //   ol.supermap.initMap(url, {
    //     mapOptions: {
    //       controls: ol.control
    //         .defaults({ attributionOptions: { collapsed: false } })
    //         .extend([new ol.supermap.control.Logo()])
    //     }
    //   });
      
      /* 方式二:1.调用 ol.supermap.MapService,获取 SuperMap iServer 地图服务的地图信息
                2.调用 ol.supermap.viewOptionsFromMapJSON 获取地图视图参数
                3.调用 ol.Map 创建地图
                4.调用 ol.layer.Tile 与 ol.source.TileSuperMapRest 创建底图
      */
      new ol.supermap.MapService(url).getMapInfo(function (serviceResult) {
        const mapObj = serviceResult.result;
        map = new ol.Map({
          target: 'map',
          controls: ol.control
            .defaults({ attributionOptions: { collapsed: false } })
            .extend([new ol.supermap.control.Logo()]),
          view: new ol.View(ol.supermap.viewOptionsFromMapJSON(mapObj))
        });
        var layer = new ol.layer.Tile({
          source: new ol.source.TileSuperMapRest(ol.source.TileSuperMapRest.optionsFromMapJSON(url, mapObj, true))
        });
        map.addLayer(layer);
        map.addControl(new ol.supermap.control.ScaleLine());
        
        
        var coords1 = [[110,20],[116,28],[111,40]]; // 矩形坐标数组
        var coords2 = [[110,40],[116,48],[111,60]]; // 矩形坐标数组
              
        var vectorLayer = new ol.layer.Vector();
        var vectorSource = new ol.source.Vector();
        var polygon = new ol.geom.Polygon([coords1,coords2]); // 矩形构造方法,不知道这里为啥又套了一层数组,去掉这层数组则无法显示矩形
        polygon.applyTransform(ol.proj.getTransform('EPSG:4326', 'EPSG:3857')); // 4326 对应的是经纬度坐标系,3857叫墨卡托?反正不是经纬度,需要做个转换
        vectorSource.addFeature(new ol.Feature(polygon)); // 形成Feature,并添加到source
        vectorLayer.setSource(vectorSource); // layer设置source
        map.addLayer(vectorLayer); // 将layer加入地图
      });
    </script>
</body>
</html>

一个polygon,可以画好几个多边形?
嗯,复合对象。
...