首页 > 解决方案 > 重新实例化地图对象的问题 HERE 地图

问题描述

我有一个使用地址搜索创建的可拖动标记,我需要在标记周围创建一个圆圈,每当我移动标记时删除圆圈并在我停止移动标记时创建另一个圆圈。问题是:当我只进行一次搜索时,它没有一个问题,当我第二次搜索时,它会在新标记所在的位置创建一个新圆圈,在我尝试移动标记或地图后,其他 2 个圆圈不知从何处创建,如果我在创建另外两个圆圈后移动标记,这两个圆圈将转到第一个标记的起始坐标(现在已删除)和同一个第一个标记的最终坐标。我怎样才能永远删除这些圈子?我已经尝试过 group.removeObject、group.removeAll 以及 delete circle、circle = null 和 circle = undefined,这些都没有奏效。

Uncaught IllegalOperationError: H.map.Group#removeObject object not found
function addDraggableMarker(map, behavior) {
  group.removeAll();

  let marker = new H.map.Marker(
    { lat: latit, lng: longi },
    {
      volatility: true,
    }
  );
  marker.draggable = true;
  group.addObject(marker);
  circle = new H.map.Circle({ lat: lati, lng: long }, raioF);
  group.addObject(circle);

  map.addEventListener(
    "dragstart",
    function (ev) {
      group.removeObject(circle);
      let target = ev.target,
        pointer = ev.currentPointer;
      if (target instanceof H.map.Marker) {
        let targetPosition = map.geoToScreen(target.getGeometry());
        target["offset"] = new H.math.Point(
          pointer.viewportX - targetPosition.x,
          pointer.viewportY - targetPosition.y
        );
        behavior.disable();
      }
    },
    false
  );

  map.addEventListener(
    "dragend",
    function (ev) {
      let target = ev.target;
      if (target instanceof H.map.Marker) {
        behavior.enable();
        latit = marker.b.lat;
        longi = marker.b.lng;
      }
      circle = new H.map.Circle({ lat: lati, lng: long }, raioF);
      group.addObject(circle);
    },
    false
  );

  map.addEventListener(
    "drag",
    function (ev) {
      let target = ev.target,
        pointer = ev.currentPointer;
      if (target instanceof H.map.Marker) {
        target.setGeometry(
          map.screenToGeo(
            pointer.viewportX - target["offset"].x,
            pointer.viewportY - target["offset"].y
          )
        );
      }
    },
    false
  );
}

标签: javascripthere-apiheremaps

解决方案


您从这个示例中获取了基本代码,从我的角度来看,最好将这个示例代码用于您的案例。

您的代码的主要问题是,当您第二次调用函数 addDraggableMarker 时,地图对象的所有事件(dragstart、dragend、drag)也将第二次添加,然后地图对象的功能加倍(dragstart、dragend、drag)。

另一个问题是每个圆圈都应该绑定到他自己的标记上,以区分它们的删除/添加或可见/不可见。

我在这里为您提供了重新编写的代码(也在JSFiddle 上):

function addDraggableMarker(map, behavior, coord, isEventsExist) {
  //group.removeAll();
  let raioF = 10000;

  let marker = new H.map.Marker(
    coord,
    {
      volatility: true,
    }
  );
  marker.draggable = true;  
  let circle = new H.map.Circle(coord, raioF, {volatility: true,});
  marker.setData({myCircle: circle}); //to distinguish circles which belogs to different markkers
  group.addObject(circle);
  group.addObject(marker);
  
  if(isEventsExist) return; //we need to add such events (dragstart, dragend, drag) for map object only once!

  map.addEventListener(
    "dragstart",
    function (ev) {
      let target = ev.target,
        pointer = ev.currentPointer;
      if (target instanceof H.map.Marker) {
        behavior.disable();
        target.getData().myCircle.setVisibility(false); // maybe better to use visibilty instead of removeObject/addObject ? 
        //group.removeObject(target.getData().myCircle);
        let targetPosition = map.geoToScreen(target.getGeometry());
        target["offset"] = new H.math.Point(
          pointer.viewportX - targetPosition.x,
          pointer.viewportY - targetPosition.y
        );
      }
    },
    false
  );

  map.addEventListener(
    "dragend",
    function (ev) {
      let target = ev.target;
      if (target instanceof H.map.Marker) {
        target.getData().myCircle.setCenter(target.getGeometry());
        //group.addObject(target.getData().myCircle);
        target.getData().myCircle.setVisibility(true);
        behavior.enable();
      }
    },
    false
  );

  map.addEventListener(
    "drag",
    function (ev) {
      let target = ev.target,
        pointer = ev.currentPointer;
      if (target instanceof H.map.Marker) {
        target.setGeometry(
          map.screenToGeo(
            pointer.viewportX - target["offset"].x,
            pointer.viewportY - target["offset"].y
          )
        );
      }
    },
    false
  );
}

/**
 * Moves the map to display over Berlin
 *
 * @param  {H.Map} map      A HERE Map instance within the application
 */
function moveMapToBerlin(map){
  map.setCenter({lat:52.5159, lng:13.3777});
  map.setZoom(7);
}

/**
 * Boilerplate map initialization code starts below:
 */

//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
  apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();

//Step 2: initialize a map - this map is centered over Europe
var map = new H.Map(document.getElementById('map'),
  defaultLayers.vector.normal.map,{
  center: {lat:50, lng:5},
  zoom: 4,
  pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());

//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));

// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);

var group = new H.map.Group();

// Now use the map as required...
window.onload = function () {
  moveMapToBerlin(map);
  map.addObject(group);
  addDraggableMarker(map, behavior, {lat:52.5159, lng:13.3777});
  addDraggableMarker(map, behavior, {lat:52, lng:13}, true);
}

推荐阅读