唯杰地图 logo唯杰地图
VJMAP
EN

circle-arc

vjmap/references/primitive/circle-arc.md 5.6 KB168 行
原文

本文回答:圆 / 椭圆 / 圆弧 / 椭圆弧 / 贝塞尔曲线 —— vjmap.CircleFill / EllipseFill / 路径辅助函数。

一、分两类

类型 表现 API
填充 有内部填色的实心几何 vjmap.CircleFill / vjmap.EllipseFill
路径 只有边线,没有填色 vjmap.Polyline + 辅助函数生成 coordinate

二、圆填充 CircleFill

const mapBounds = map.getGeoBounds(0.2);

const circle = new vjmap.CircleFill({
  center: mapBounds.center(),        // CAD 坐标
  radius: mapBounds.width() / 4,     // CAD 单位
  fillColor: "yellow",
  fillOpacity: 0.8,
  fillOutlineColor: "#f00"
});
circle.addTo(map);

参数:

参数 说明
center 圆心坐标(CAD)
radius 半径(CAD 单位)
startAngle 起始角(度)—— 弧时必填
endAngle 终止角(度)—— 弧时必填
fillColor / fillOpacity / fillOutlineColor 同 Polygon

三、圆弧填充

new vjmap.CircleFill({
  center, radius,
  startAngle: 120,          // 从 120° 逆时针扫到 60°+360°
  endAngle: 60,             // → 300° 的大扇形;要 60°~120° 小扇形写 startAngle: 60, endAngle: 120
  fillColor: "yellow"
}).addTo(map);

四、椭圆填充 EllipseFill

new vjmap.EllipseFill({
  center,
  majorAxisRadius,
  minorAxisRadius,
  fillColor: "yellow",
  fillOpacity: 0.6
}).addTo(map);

椭圆弧:加 startAngle + endAngle。

五、圆 / 椭圆路径(只有线)

vjmap 提供辅助函数把圆/椭圆采样成坐标串,再用 Polyline 画:

// 圆路径
const circlePath = vjmap.getCirclePolygonCoordinates(
  mapExtent.center(),      // 圆心
  mapExtent.width() / 10,  // 半径
  120,                     // 采样段数
  0,                       // 起始角
  360,                     // 终止角
  false                    // 弧时是否包含圆心(true → 扇形 wedge)
);

new vjmap.Polyline({
  data: map.toLngLat(circlePath),
  lineColor: "#FFA0FD",
  lineWidth: 3
}).addTo(map);

椭圆路径:

const ellipsePath = vjmap.getEllipsePolygonCoordinates(
  mapExtent.center(),
  majorAxisRadius,
  minorAxisRadius,
  360,        // 采样段数
  0, 360,     // 起始 / 终止角
  false
);

六、贝塞尔曲线

vjmap 提供 polylineToBezierCurve + bezierCurveToPolyline 两步:

// 1) 把控制点转 B 样条参数
const curvePoints = [
  mapBounds.min.toArray(),
  mapBounds.center().toArray(),
  vjmap.geoPoint([mapBounds.max.x, mapBounds.min.y]).toArray(),
  mapBounds.max.toArray()
];
const c = vjmap.polylineToBezierCurve(curvePoints);

// 2) 离散成线
const curvePath = vjmap.bezierCurveToPolyline(c);

// 3) 用 Polyline 或 Polygon 渲染
new vjmap.Polyline({
  data: map.toLngLat(curvePath),
  lineColor: "#FFA0FD",
  lineWidth: 3
}).addTo(map);

做成闭合曲线填充:

const c = vjmap.polylineToBezierCurve(pts, true);   // close 参数闭合曲线
const curvePath = vjmap.bezierCurveToPolyline(c);
new vjmap.Polygon({
  data: map.toLngLat(curvePath),
  fillColor: "yellow",
  fillOpacity: 0.6
}).addTo(map);

七、圆/椭圆参数表

函数 参数顺序
getCirclePolygonCoordinates center, radius, points?, startAngle?, endAngle?, includeCenterWhenArc?
getEllipsePolygonCoordinates center, majorR, minorR, points?, startAngle?, endAngle?, includeCenterWhenArc?
polylineToBezierCurve polyline[], close?, offsetA?, offsetB?
bezierCurveToPolyline bezierCurve, precision?, recursiveCount?

includeCenterWhenArc=true 时弧的末点被替换/追加为圆心(扇形闭合用法);⚠️ 全圆(不传起止角)的首尾点并不相同(不闭环)——要闭合环请自行补首点。另注意顶层 vjmap.isPoint(v):只认 {x,y}/{x,y,z} 对象——[x,y] 数组、{lng,lat} 都返回 false,且 isPoint(null) 直接抛 TypeError(无 null 防护)。

八、修改几何

CircleFill / EllipseFill 内部会生成 GeoJSON polygon;要改半径 → 重新 setData 或删除重建。

⚠️ 勿用 setCenter / setRadius / setMajorAxisRadius / setMinorAxisRadius / setStartAngle / setEndAngle / setPoints 改几何:CircleFill / EllipseFill 的内部 updateData 把 (startAngle, endAngle, points) 传进了 (points, startAngle, endAngle) 的位置,自定义了 points 或起止角时几何错乱(如 points: 64 的整圆变成 64° 扇形);CircleEdge 的 setter 引用了未导入的函数,直接抛 ReferenceError。改几何请删除重建或 setData。

circle.remove();
circle = new vjmap.CircleFill({ center, radius: newR, ... });   // addTo 无返回值,不能链尾赋值
circle.addTo(map);

或直接用辅助函数 + Polygon:

const coords = vjmap.getCirclePolygonCoordinates(center, radius, 64, 0, 360, true);
polygon.setData({ type: "Feature", geometry: { type: "Polygon", coordinates: [map.toLngLat(coords)] }});

九、常见坑

  1. 圆看起来椭圆了 → 地图倾斜或高纬度投影失真;用 turf.circle + LngLat 可避免。
  2. 弧方向搞反 → startAngle / endAngle 按数学正向(逆时针为正);测试时交换即可。
  3. 贝塞尔离散点太少 → bezierCurveToPolyline(c, precision) 第二参传精度数值(如 100),或增采样控制点。
  4. 椭圆旋转角 → 目前 EllipseFill 无 rotation;要斜椭圆就手算 + Polygon。