javascript - 传单 map 的绘制线

标签 javascript reactjs leaflet immutable.js

我有一张可用的传单 map ,其中实时显示位置。纬度和经度值每秒出现一次, map 根据每次变化的值显示。现在我想在折线中显示最后 10 个位置历史记录,但要将最后 10 个位置显示为折线,我需要有一个包含 10 个位置的数组。我如何创建一个包含最近 10 个位置历史记录的数组?

这是我所做的

import L from 'leaflet';

componentDidMount() {
  const { currentValue } = this.props;
  const latestValue = currentValue.split(':');
  const lat = getNumber(latestValue[0]);
  const long = getNumber(latestValue[1]);
  this.map = L.map(this.element).setView([lat, long], 15);

  // Google Map
  L.tileLayer('*****', {
    maxZoom: 20,
  }).addTo(this.map);

  this.marker = L.marker([lat, long], { icon: MarkerIcon });
  this.marker.addTo(this.map);
  const polyLinePoints = [
    new L.LatLng(lat, long),
    new L.LatLng(lat, long),
    new L.LatLng(lat, long),
    new L.LatLng(lat, long),
  ];
  const polyLineOptions = {
    color: 'blue',
    weight: '5',
    opacity: 0.9
  };
  const polyline = L.polyline(polyLinePoints, polyLineOptions).addTo(this.map);
  this.map.fitBounds(polyline.getBounds());
}

componentDidUpdate() {
  const { currentValue } = this.props;
  const latestValue = currentValue.split(':');
  const lat = getNumber(latestValue[0]);
  const long = getNumber(latestValue[1]);
  console.log('lat', lat, long);
  // latlng.push([lat,long]);
  const polyLinePoints = [
    new L.LatLng(lat, long),
    new L.LatLng(lat, long),
    new L.LatLng(lat, long),
    new L.LatLng(lat, long),
  ];
  const polyLineOptions = {
    color: 'blue',
    weight: '5',
    opacity: 0.9
  };
  this.marker.remove();
  this.marker = L.marker([lat, long], { icon: MarkerIcon });
  this.marker.addTo(this.map);
  // invalidateSize forces map to recalculate its size
  // next, move the center to given coordinate
  this.map.invalidateSize(false).setView([lat, long]);
  const polyline = L.polyline(polyLinePoints, polyLineOptions).addTo(this.map);
  this.map.fitBounds(polyline.getBounds());
}

render() {
  const { width, height } = this.props;
  return (
    <div
      ref={(element) => { this.element = element; }}
      style={{ width, height }}
    ></div>
  );
}
}

我使用的是传单而不是react-leaflet和immutablejs。

最佳答案

每次更新位置后:

  • 存储 10 个最新景点的列表
  • 删除之前的折线(就像您对标记所做的那样 - 删除之前的折线,否则我们会出现内存泄漏)
  • 根据最新的地点列表创建新的折线。

您还应该创建一些常量(分别是 MAX_SPOT = 10polyLineOptions - 将其移到 componentDidMount() 之外,以便我们可以重复使用它每次绘制新的折线时):

// These can be outside of your react class declaration
const MAX_SPOT = 10;
const polyLineOptions = {
  color: 'blue',
  weight: '5',
  opacity: 0.9
};

创建一些变量来存储polyLinePointspolyline(在构造函数中):

constructor(props){
  super(props);
  // ...
  this.polyLinePoints = [];
  this.polyline = false;
}

下一个:

componentDidMount() {
  // ... keep your previous logics here
  this.polyLinePoints.push(new L.LatLng(lat, long);

  // NOTE HERE: just after the component is mounted, 
  // perhaps there's only 1 location captured, so the polyline should not be created yet
  //this.polyline = L.polyline(this.polyLinePoints, polyLineOptions)
  //this.polyline.addTo(this.map);
  //this.map.fitBounds(this.polyline.getBounds());
}

componentDidUpdate() {  
  // ...your previous logics here
  if (this.polyLinePoints.length < MAX_SPOT) {
    this.polyLinePoints.push(new L.LatLng(lat, long));
  }
  else {
    for (let i = 0; i < MAX_SPOT - 1; i++) { // basic for loop ^^
      this.polyLinePoints[i] = this.polyLinePoints[i + 1];
    }
    this.polyLinePoints[MAX_SPOT] = new L.LatLng(lat, long); 
    // so the polyLinePoints should always have 10 latest spots
  }
  this.marker.remove();
  this.marker = L.marker([lat, long], { icon: MarkerIcon });
  this.marker.addTo(this.map);
  // invalidateSize forces map to recalculate its size
  // next, move the center to given coordinate

  // SET THE POLYLINE HERE, remember to remove the previous one, just like your above marker
  // Try..Catch here because the first polyline after componentDidMount() was not created, so your map cannot find the polyline ^^
  try {
    this.map.removeLayer(this.polyline);
  }
  catch(err) {
    console.log(err);
  }     
  this.polyline = L.polyline(this.polyLinePoints, polyLineOptions)
  this.polyline.addTo(this.map); // the polyline should be added to the map here, should not on the same line as its creation
  this.map.fitBounds(this.polyline.getBounds());
}

这就是思路和算法,如果还不行,请在控制台上显示一些错误,谢谢!

关于javascript - 传单 map 的绘制线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43929621/

相关文章:

javascript - jQuery 表单插件 - 不会在内部服务器错误 (500) 上调用错误回调

Javascript 函数未在视频时间更新时触发

javascript - 在 React/React Native 中配置包

javascript - dc 传单 - 动态标记

javascript - 解析 JSON API 结果并加载到 Leaflet

javascript - SIP CANCEL 请求永远不会收到 200 取消响应

javascript - Visual Studio 代码清理任务

javascript - Next-i18next serverSideTranslations 初始I18nStore 缺少的语言环境

javascript - 使用 fetch 的 XML 请求和响应?

leaflet - 获取Leaflet中的div屏幕位置