【问题标题】:How should one refresh the position of a largish number of marker positions in Here Maps 3.0?应该如何刷新 Here Maps 3.0 中大量标记位置的位置?
【发布时间】:2014-10-04 21:31:04
【问题描述】:

注意:这是一篇旧帖子,我已经弄清楚了要点中的大部分问题,请进一步阅读以获取注释。我已经在第一次编辑中写了剩下的问题。

现在发现2.n系列之后新的3.0 Here Maps,不知道如何实现如下:

  • 清空整个地图
  • 使用一些标记 ID 更新标记位置
  • 使用某些 ID 移除某些特定标记

到此为止的最后一次编辑,我会在这里添加它,因为它很长。我匆匆忙忙,看起来我不知道如何在地图上重绘标记而不会导致标记闪烁(也就是说,地图不闪烁,但标记在删除和读取时会闪烁)! invalidateObject 是 ``H.map.clustering

中的一个方法

问题:应该如何更新标记位置然后重新绘制地图?

进一步查看代码作为此问题的更多上下文。我采取了一种快速的方法,即删除对象而不保留对先前添加的标记的引用,更新它们的位置,然后重新绘制地图。唉,我不知道如何更新标记位置!大约有 50 个标记我每秒更新一次的位置。需要注意的一点是,仅删除所有对象然后重新添加它们(使用看起来大致相同的标准标记)不会导致闪烁(两者都有 useCIT,在 3.0 系列中我也使用 HTTPS) API 2.n 版。闪烁发生在 IE、FF 和 Chrome 上的 Windows 8.1 以及 3.0 版本的 Windows Phone 上。

 //Copied from http://stackoverflow.com/questions/26020199/here-nokia-maps-javascript-api-3-0-explorer-how-to-set-maker-color.
 var markup = '<svg xmlns="http://www.w3.org/2000/svg" width="28px" height="36px" >' +
            '<path d="M 19 31 C 19 32.7 16.3 34 13 34 C 9.7 34 7 32.7 7 31 C 7 29.3 9.7 ' +
            '28 13 28 C 16.3 28 19 29.3 19 31 Z" fill="#000" fill-opacity=".2"></path>' +
            '<path d="M 13 0 C 9.5 0 6.3 1.3 3.8 3.8 C 1.4 7.8 0 9.4 0 12.8 C 0 16.3 1.4 ' +
            '19.5 3.8 21.9 L 13 31 L 22.2 21.9 C 24.6 19.5 25.9 16.3 25.9 12.8 C 25.9 9.4 24.6 ' +
            '6.1 22.1 3.8 C 19.7 1.3 16.5 0 13 0 Z" fill="#fff"></path>' +
            '<path d="M 13 2.2 C 6 2.2 2.3 7.2 2.1 12.8 C 2.1 16.1 3.1 18.4 5.2 20.5 L ' +
            '13 28.2 L 20.8 20.5 C 22.9 18.4 23.8 16.2 23.8 12.8 C 23.6 7.07 20 2.2 ' +
            '13 2.2 Z" fill="${COLOR}"></path><text transform="matrix( 1 0 0 1 13 18 )" x="0" y="0" fill-opacity="1" ' +
            'fill="#fff" text-anchor="middle" font-weight="bold" font-size="13px" font-family="arial" style="fill:black">${TEXT}</text></svg>'

    function createMarker(id, la, ln) {                                    
        var icon = new H.map.Icon(markup.replace('${COLOR}', '#FF8800').replace('${TEXT}', id));
        var marker = new H.map.Marker({ lat: la, lng: ln }, { icon: icon });

        return marker;
    }

var updates = updateBatch;
var len = updates.length;
var newMarkers = [len];
for (i = 0; i < len; i++) {
    var update = updates[i];
    var marker = createMarker(update.Id, update.Latitude, update.Longitude);
     newMarkers[i] = marker;
 }

 map.removeObjects(map.getObjects());
 map.addObjects(newMarkers);

例如,在 2.n 系列中用于清除地图有 {map}.objects.clear,但现在看起来它已经消失了,我找不到 3.0 版 API 的文档.

Maps API for JavaScript Developer's Guide (3.0.5) 的问题,例如在第 76 页,有 removeObjects() 清除所有。

现在我只需要弄清楚如何更新已添加到地图中的标记位置。文档中的简短 sn-p:

添加和删除对象

每个地图对象类型对应于 API 中的一个类。这种类的新创建实例不会自动出现在地图上,但是,就像 HTML 文档对象模型 (DOM) 中的节点一样,必须将其添加到根。这意味着要使一个对象出现在地图上,必须通过调用地图对象的方法 addObject() 将其添加到地图的根组中。相反,要从地图中移除对象,则需要调用地图对象的方法 removeObject()。

组有自己的 addObject() 和 removeObject() 方法,表现得像容器 HTML 文档对象模型中的元素。可以在地图中添加一个空组并稍后添加单个对象。下面的代码演示了如何创建一个空组,将其添加到地图中,然后创建一个标记并使其成为该组的成员。

// Create a group that can hold map objects:
group = new H.map.Group();
// Add the group to the map object (created earlier):
map.addObject(group);
// Create a marker:
marker = new H.map.Marker(map.getCenter());
// Add the marker to the group (which causes
// it to be displayed on the map)
group.addObject(marker);

H.map.provider 中有一个方法invalidateObject (mapObject, changes),它接受一个H.map 对象。然后changes 是一个位掩码,它定义了更改的类型,但是如果我想用新位置的标记重绘地图,文档并没有说明应该放入什么,只是

可以应用位运算符的有符号 32 位整数(JS 限制)。范围是 [-2,147,483,648 ... 2,147,483,647] 或 [-2^31 ... 2^31 - 1]

问题:是否应该使用 -1 作为位掩码来重绘地图对象? (我暂时不用开发工具了,所以不能假设,但无论如何我都想知道这些位掩码。)

【问题讨论】:

    标签: here-api


    【解决方案1】:

    在删除所有对象然后重新添加它们的情况下,技巧是将标记添加到两个H.map.Group 对象以使用setVisibility = true/false 设置双缓冲,调用.removeAll 到具有已切换到背景(通过将可见性设置为 false)并切换标记容器变量。

    一个更优雅的解决方案是只有一个容器,更新标记的位置,然后删除没有更新的那些(或其他适当的操作)。

    function nonUpdated(markers, updates) {
        var map = {};
        var updatedMarkers = [];
        var nonUpdatedMarkers = [];
    
        for (var i = updates.length; i--;) {
                map[updates[i].Id] = null;
        }
    
        //The updated ones are here in case someone finds the code useful (remove in production).
        for (var key in markers) {
            if (map.hasOwnProperty(key)) {
                    updatedMarkers.push(markers[key]);
            } else {
                nonUpdatedMarkers.push(markers[key]);
            }
        }
    
        return nonUpdatedMarkers;
    }
    
    //JS 6 brings Map, which is superior: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map.
    var markers = Object.create(null);
    var g = new H.map.Group();
    map.addObject(g);
    
    var updates = updateBatch;
    var len = updates.length;
    for (i = 0; i < len; i++) {
        var update = updates[i];
    
        if (update.Id in markers) {
            markers[update.Id].setPosition({ lat: update.Latitude, lng: update.Longitude });
        } else {
            var marker = createMarker(update.Id, update.Latitude, update.Longitude);                        
            markers[update.Id] = marker;
            g.addObject(marker);
        }
    }
    
    var nonUpdatedToBeRemoved = nonUpdated(markers, updates);
    if (nonUpdatedToBeRemoved.length > 0) {
        g.removeObjects(nonUpdatedToBeRemoved);
    }                
    

    【讨论】:

    • 怀着极大的兴趣阅读本文。我可能应该问一个单独的问题,但你能说这些技术是否适用于动画标记吗?也就是说,如果我有一个开始位置和结束位置,并且想在 3 秒内在两者之间移动,我想我必须插入位置,然后根据计时器更改它们。
    • 我会这么说,因为这些是我发现最快的,例如没有闪烁或排序。 Double buffering 只是我懒惰/忙碌,是一种解决方法,而不是正确地做事。我怀疑地图内部会进行双重缓冲。无论如何,在旧 API 中有一个这样的示例,请参阅 here。来自 Demos & Showcases -> 跟踪移动地图对象here
    • 补充一点,我相信这个例子可以很直接地移植到使用新的 API 并且它可以展示你正在寻找的技术和想法。
    • 非常感谢示例的链接!顺便说一句,它们对我不起作用,但我通过转到 developer.here.com/javascript-apis/api-explorer 并选择 Demos and Showcases 找到了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多