npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bbl-mapbox-react

v0.0.17

Published

React Mapbox 地图组件库,支持雷达、图像、标记、轨迹等多种 GIS 实体渲染

Readme

bbl-mapbox-react

React Mapbox 地图组件库,支持雷达、图像、标记、轨迹、多边形、折线、圆形等多种 GIS 实体的数据驱动渲染。

安装

pnpm add bbl-mapbox-react

Peer Dependencies

pnpm add mapbox-gl @turf/turf @svgdotjs/svg.js lodash-es dayjs eventemitter3 hotkeys-js uid pbf @mapbox/vector-tile

快速开始

import { Mapbox } from 'bbl-mapbox-react';
import 'bbl-mapbox-react/style.css';

function App() {
  return (
    <Mapbox
      center={[116.4074, 39.9042]}
      zoom={12}
      style="mapbox://styles/mapbox/dark-v11"
      entities={[
        {
          id: 'marker-1',
          type: 'marker',
          center: [116.4074, 39.9042],
          src: '/icon.png',
          width: 32,
          name: '标记点',
        },
      ]}
    />
  );
}

组件 Props

MapboxProps

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | center | [number, number] | [116.4074, 39.9042] | 地图中心点 [经度, 纬度] | | zoom | number | 12 | 缩放级别 | | pitch | number | 0 | 俯仰角度 | | bearing | number | 0 | 方位角度 | | style | string | 'mapbox://styles/mapbox/dark-v11' | Mapbox 地图样式 URL | | maxBounds | [[number, number], [number, number]] | - | 地图边界限制 [[西南], [东北]] | | mode | 'display' \| 'edit' \| 'picker' | 'display' | 地图模式 | | entities | MapEntity[] | [] | 实体数据数组 | | selectedIds | EntityId[] | [] | 选中的实体 ID 数组 | | layers | LayerConfig[] | [] | 自定义底图图层配置 | | interactive | InteractionOptions | - | 交互控制配置 | | showCoordinates | boolean \| CoordinateDisplayConfig | true | 坐标显示控件 | | showScale | boolean \| ScaleControlConfig | true | 比例尺控件 | | showResetView | boolean \| ResetViewControlConfig | true | 重置视图控件 | | showRoadHighlight | boolean \| RoadHighlightControlConfig | false | 路网高亮控件 | | popupDefaults | PopupDefaults | - | 全局 Popup 默认配置 | | renderPopup | (entity: MapEntity) => ReactNode | - | Popup 渲染回调 | | editConfig | EditModeConfig | - | 编辑模式配置 | | pickerConfig | PickerModeConfig | - | 选址模式配置 | | onMapLoad | (map: MapboxMap) => void | - | 地图加载完成回调 | | onEntityClick | (entity: MapEntity) => void | - | 实体点击回调 | | onPick | (result: PickerResult) => void | - | 选址回调 | | onPopupOpen | (entityId: EntityId) => void | - | Popup 打开回调 | | onPopupClose | (entityId: EntityId) => void | - | Popup 关闭回调 | | className | string | - | 自定义类名 | | containerStyle | CSSProperties | - | 容器样式 |

实体类型

所有实体均继承自 BaseEntity,包含以下公共字段:

| 字段 | 类型 | 说明 | |------|------|------| | id | string \| number | 唯一标识 | | type | string | 实体类型 | | name | string? | 显示名称 | | confidence | number? | 置信度 0-1,影响透明度 | | popup | PopupConfig? | Popup 配置 | | center | [number, number]? | 中心点坐标 | | customData | T? | 自定义附加数据 |

Radar - 雷达

{
  type: 'radar',
  center: [116.4074, 39.9042],
  radius: 5000,             // 半径(米)
  sectorAngle: 60,          // 扇形角度
  isAnimating: true,        // 是否播放扫描动画
  rotationSpeed: 1,         // 旋转速度(度/帧)
  colorScheme: 'green',     // 'blue' | 'green' | 'red' | 'purple' | 'cyan' | 'orange'
  opacity: 70,              // 透明度 0-100
  showRings: true,          // 显示距离环
  showCenter: true,         // 显示中心点
  showScanLine: true,       // 显示扫描线
}

Image - 图片

{
  type: 'image',
  center: [116.4074, 39.9042],
  width: 1000,       // 宽度(米),高度按比例计算
  src: '/map.png',   // 图片 URL
  rotation: 0,       // 旋转角度
}

Marker - 标记

{
  type: 'marker',
  center: [116.4074, 39.9042],
  src: '/icon.png',  // 图标 URL
  width: 32,         // 宽度(像素)
  rotation: 0,       // 旋转角度
  anchor: 'center',  // 锚点位置
}

Unit - 单位(含轨迹预测)

{
  type: 'unit',
  center: [116.4074, 39.9042],
  src: '/unit.png',
  width: 40,
  predicted_traj: [          // 预测轨迹
    { lon: 116.41, lat: 39.91, alt: 0 },
    { lon: 116.42, lat: 39.92, alt: 0 },
  ],
  showTrajectory: 'all',       // 轨迹显示数量:number | 'all'
  showTrajectoryPoints: false, // 是否显示轨迹点
}

Polygon - 多边形

{
  type: 'polygon',
  coordinates: [
    [116.40, 39.90],
    [116.41, 39.91],
    [116.42, 39.90],
  ],
  strokeColor: '#3388ff',
  strokeWidth: 2,
  fillColor: '#3388ff',
  fillOpacity: 0.2,
}

Polyline - 折线

{
  type: 'polyline',
  coordinates: [
    [116.40, 39.90],
    [116.41, 39.91],
    [116.42, 39.90],
  ],
  strokeColor: '#3388ff',
  strokeWidth: 2,
  lineCap: 'round',
  lineJoin: 'round',
  dashArray: [4, 4],  // 虚线模式
}

Circle - 圆形

{
  type: 'circle',
  center: [116.4074, 39.9042],
  radius: 1000,                 // 半径(米)
  strokeColor: '#3388ff',
  fillColor: '#3388ff',
  fillOpacity: 0.2,
  fillType: 'solid',            // 'solid' | 'radial-gradient'
  showCenterPoint: true,
  gradientAnimation: 'flicker', // 'static' | 'flicker' | 'breath' | 'pulse'
  isAnimating: false,
}

Square - 正方形

{
  type: 'square',
  center: [116.4074, 39.9042],
  length: 1000,     // 边长(米)
  strokeColor: '#3388ff',
  fillColor: '#3388ff',
  fillOpacity: 0.2,
}

Rectangle - 矩形

{
  type: 'rectangle',
  bounds: [[116.40, 39.90], [116.42, 39.92]], // 对角点
  strokeColor: '#3388ff',
  fillColor: '#3388ff',
  fillOpacity: 0.2,
}

Ref 方法

通过 useRef<MapboxRef> 获取组件实例,可调用以下方法:

const mapRef = useRef<MapboxRef>(null);

<Mapbox ref={mapRef} />

| 方法 | 签名 | 说明 | |------|------|------| | getMap | () => MapboxMap \| null | 获取 Mapbox GL 地图实例 | | flyTo | (center, zoom?, options?) => void | 飞行到指定位置 | | flyToEntities | (ids, zoom?, options?) => void | 飞行到指定实体 | | startAnimation | (id) => void | 启动实体动画 | | stopAnimation | (id) => void | 停止实体动画 | | toggleAnimation | (id) => void | 切换实体动画状态 | | openPopup | (id) => void | 程序化打开 Popup | | closePopup | (id) => void | 关闭指定 Popup | | closeAllPopups | () => void | 关闭所有 Popup | | isPopupOpen | (id) => boolean | 检查 Popup 是否打开 | | toggleUnitTrajectory | (ids?) => void | 切换 Unit 轨迹显示 | | getMode | () => MapMode | 获取当前模式 | | setMode | (mode) => void | 设置地图模式 | | startDrawing | (options) => void | 开始绘制 | | getPickedLocation | () => PickerResult \| null | 获取选址坐标 | | clearPickedLocation | () => void | 清除选址坐标 |

地图模式

Display 模式(默认)

只读查看模式,支持点击实体、Popup 展示。

Edit 模式

编辑模式,支持在地图上绘制和放置实体。

<Mapbox
  mode="edit"
  editConfig={{
    showEditTools: true,
    showRectangleTool: true,
    showCircleTool: true,
    showPolygonTool: true,
    showSquareTool: true,
    showPolylineTool: true,
    markerTemplates: [
      { id: 'drone', name: '无人机', icon: '/drone.png', width: 40 },
    ],
    onMarkerAdd: (marker) => console.log('新增 Marker', marker),
    onRectangleAdd: (rect) => console.log('新增矩形', rect),
    onCircleAdd: (circle) => console.log('新增圆形', circle),
    onPolygonAdd: (polygon) => console.log('新增多边形', polygon),
    onSquareAdd: (square) => console.log('新增正方形', square),
    onPolylineAdd: (polyline) => console.log('新增折线', polyline),
    onEntityDelete: (entity) => console.log('删除实体', entity),
  }}
/>

通过 Ref 的 startDrawing API 程序化触发绘制:

// 绘制 Marker
mapRef.current?.startDrawing({
  id: 'drone',
  name: '无人机',
  icon: '/drone.png',
  width: 60,
});

// 绘制矩形
mapRef.current?.startDrawing({ mode: 'rectangle' });

// 绘制圆形(自定义样式)
mapRef.current?.startDrawing({
  mode: 'circle',
  circleStyle: { fillColor: '#ff0000', fillOpacity: 0.3 },
});

// 绘制多边形
mapRef.current?.startDrawing({ mode: 'polygon' });

// 绘制折线
mapRef.current?.startDrawing({ mode: 'polyline' });

绘制操作:

  • 矩形/正方形/圆形:第一次点击设置起点/中心,第二次点击完成
  • 多边形:逐点点击添加顶点,点击第一个点附近闭合,或右键完成
  • 折线:逐点点击添加顶点,右键完成
  • Esc 键取消当前绘制
  • 右键 取消或完成绘制

Picker 模式

选址模式,点击地图获取坐标。

<Mapbox
  mode="picker"
  pickerConfig={{
    showMarker: true,
    markerColor: '#3388ff',
    showCrosshair: true,
  }}
  onPick={(result) => {
    console.log(`选中坐标: ${result.lng}, ${result.lat}`);
  }}
/>

底图图层

支持三种类型的底图图层叠加:

<Mapbox
  layers={[
    // 栅格瓦片
    {
      id: 'satellite',
      type: 'raster',
      url: 'https://example.com/tiles/{z}/{x}/{y}.png',
      opacity: 0.8,
    },
    // Style JSON
    {
      id: 'custom-style',
      type: 'style',
      url: 'http://localhost:8080/styles/basic/style.json',
      hasRoadNetwork: true,
    },
    // TileJSON
    {
      id: 'terrain',
      type: 'tilejson',
      url: 'http://localhost:8080/styles/terrain.json',
    },
  ]}
/>

Popup 配置

实体级 Popup 可通过 popup 字段配置,也可通过 renderPopup 统一渲染:

// 实体级配置
const entities = [
  {
    id: '1',
    type: 'marker',
    center: [116.4074, 39.9042],
    src: '/icon.png',
    width: 32,
    popup: {
      content: <div>自定义内容</div>,
      trigger: 'click',        // 'click' | 'hover'
      position: 'top',         // 'top' | 'bottom' | 'left' | 'right' | 'center'
      animation: 'fade',       // 'fade' | 'scale' | 'fade-scale' | 'none'
      showCloseButton: true,
      closeOnClickOutside: true,
      closeOnEscape: true,
      hoverDelay: 300,
    },
  },
];

// 全局渲染回调
<Mapbox
  entities={entities}
  renderPopup={(entity) => <div>{entity.name}</div>}
  popupDefaults={{
    trigger: 'click',
    position: 'top',
    animation: 'fade',
  }}
/>

交互控制

<Mapbox
  interactive={{
    dragPan: true,
    scrollZoom: true,
    doubleClickZoom: true,
    touchZoomRotate: true,
    keyboard: true,
    dragRotate: true,
    pitchWithRotate: true,
    touchPitch: true,
    boxZoom: true,
  }}
/>

导出

// 主组件
export { Mapbox } from './Mapbox';

// 类型
export type {
  MapboxProps, MapboxRef, MapEntity,
  RadarEntity, ImageEntity, MarkerEntity, UnitEntity,
  PolygonEntity, PolylineEntity, CircleEntity, SquareEntity, RectangleEntity,
  PopupConfig, PopupDefaults, LayerConfig,
  InteractionOptions, MapMode, DrawMode, DrawingOptions,
  MarkerTemplate, PickerResult, EditModeConfig, PickerModeConfig,
  // ...更多类型
};

// 常量
export { COLOR_SCHEMES, RADAR_DEFAULTS, POPUP_DEFAULTS, ROAD_TYPE_OPTIONS };

// 子组件
export {
  EntityPopup, CoordinateDisplay, ScaleControl,
  ResetViewControl, RoadHighlightControl, EditControl, ContextMenu,
};

// 工具函数
export { destinationPoint, distance, bearing, mergePopupConfig, calculatePopupPosition };

// 渲染器(用于扩展)
export {
  MarkerRenderer, UnitRenderer, CircleRenderer,
  PolygonRenderer, PolylineRenderer, SquareRenderer, RectangleRenderer,
  BaseCanvasRenderer, CanvasImageRenderer, CanvasRadarRenderer, CanvasCircleRenderer,
};

开发

# 安装依赖
pnpm install

# 启动开发服务
pnpm dev

# 构建库
pnpm build:lib

# 构建项目
pnpm build

License

GPL-3.0