---
title: svg覆盖物
source: https://vjmap.com/guide/svg.html
---

# svg覆盖物


`SvgOverlay` 在一个地理范围内创建一个随缩放而缩放的svg的覆盖物

svg覆盖物性能低，不建议大量使用，同时在级别特别大时会导致失真，在倾斜角很大时会导致不可见

## 类型定义

```ts
// 在一个地理范围内创建一个随缩放而缩放的svg的覆盖物
export  class SvgOverlay {
    constructor(options?: {
        /** 显示最大级别 */
        minZoom?: number;
        /** 显示最小级别 */
        maxZoom?: number;
        /** 显示最大倾斜角 */
        maxPitch?: number;
        /** 自动更新div大小，（如果需要svg放大，需要设置为true) */
        updateDivSize?: boolean;
        /** 放大div时，最大的div大小，超过了就像素放大了 */
        maxDivSize?: number;
        /** 当移动结束时不自动更新范围 */
        noUpdateBoundsWhenMoveend?: boolean;
        /** 类名 */
        divClassName?: string;
        /** svg初始化时最大像素宽,默认1000 */
        svgMaxWidth?: number;
        /** svg初始化时最大像素高,默认1000 */
        svgMaxHeight?: number;
        /** svg初始化时Offset像素距离,默认100 */
        svgOffset?: number;
    });
    addTo(map: Map, insertId?: string | HTMLElement): void;
    remove(): void;
    /**
     * 增加svg元素
     * @param element 要增加的元素
     * @param noUpdate 不立即更新
     */
    addElement(element: SvgElementOptions | string, noUpdate?: boolean): void;
    /**
     * 增加svg元素
     * @param elements 多个元素内容
     * @param noUpdate 不立即更新
     */
    addElements(elements: SvgElementOptions[], noUpdate?: boolean): void;
    /**
     * 获取svg获取
     */
    getSvgContainer(): SVGSVGElement;
    /**
     * 获取所有的元素
     */
    getElements(): SvgElementOptions[];
    /**
     * 移动一个元素
     */
    removeElements(id: string[] | string): SvgElementOptions[];
    /**
     * 更新一个元素
     */
    updateElements(elements: SvgElementOptions[] | SvgElementOptions): SvgElementOptions[];
    /**
     * 圆心半径属性字符串
     */
    static attr_cx_cy_r(cx: number, cy: number, r: number): string;
    /**
     * 椭圆心半径属性字符串
     */
    static attr_cx_cy_rx_ry(cx: number, cy: number, rx: number, ry: number): string;
    /**
     * 直线坐标属性字符串
     */
    static attr_x1_y1_x2_y2(x1: number, y1: number, x2: number, y2: number): string;
    /**
     * 坐标宽高属性字符串
     */
    static attr_x_y_w_h(x: number, y: number, w: number, h: number): string;
    /**
     * 坐标属性字符串
     */
    static attr_x_y(x: number, y: number): string;
    /**
     * 字体属性字符串
     */
    static attr_fontsize(fontsize: number): string;
    /**
     * 和长度有关属性字符串
     */
    static attr_length(len: number): string;
    /**
     * 和点坐标有关属性字符串
     */
    static attr_point(point: GeoPoint, joinComma?: boolean): string;
    /**
     * 坐标序列属性字符串
     */
    static attr_points(points: GeoPoint[]): string;
    /**
     * 路径序列属性字符串
     */
    static attr_path(points: GeoPoint[]): string;
}
```


## 用法


```js
let mapBounds = map.getGeoBounds();
let len = mapBounds.width() / 5;
let svgOverlay = new vjmap.SvgOverlay({
    maxZoom: 5, // 第5级时全部不显示了
    maxPitch: 60 // 倾角超过60度就不显示了
});
svgOverlay.addTo(map);

// 增加一个渐变色
svgOverlay.addElement(`
          <defs>
            <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
              <stop offset="0%" style="stop-color:${vjmap.randomColor()};stop-opacity:0.8" />
              <stop offset="100%" style="stop-color:${vjmap.randomColor()};stop-opacity:1" />
            </radialGradient>
          </defs>
        `)
const getStyle = (style = {}) => {
    return Object.keys(style).map(key => `${key}:${style[key]}`).join(";")
}
const svgCircleHtml = (id, point, r, style) => {
    return ` <circle id="${id}" ${vjmap.SvgOverlay.attr_cx_cy_r(point.x, point.y, r)} style="${getStyle(style)}"/>`
}

const addCircle = ()=> {
    let id = "circle" + vjmap.RandomID();
    return svgOverlay.addElement({
        html: svgCircleHtml(id, mapBounds.randomPoint(), len / 4, {fill: "url(#grad1)", stroke: vjmap.randomColor(), "stroke-width": 3, cursor: "pointer"}),
        event: svgParentElement => {
            // 事件回调
            let ele = svgParentElement.getElementById(id);
            if (!ele) return;
            ele.addEventListener("mouseover", e => ele.style.opacity = 0.6);
            ele.addEventListener("mouseout", e => ele.style.opacity = 1.0);
            ele.addEventListener("click", e => message.info("点击了圆" + id));
        }
    })
}
for(let i = 0; i < 10; i++) {
    addCircle();
}
```


<mapFrameEx>
<pre>
// 新建地图服务对象，传入服务地址和token
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
    mapid: env.exampleMapId, // 地图ID,(请确保此ID已存在，可上传新图形新建ID)
    mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
    style: vjmap.openMapDarkStyle() // div为深色背景颜色时，这里也传深色背景样式
})
if (res.error) {
    message.error(res.error)
}
// 获取地图的范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 建立坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 新建地图对象
let map = new vjmap.Map({
    container: 'map', // container ID
    style: svc.rasterStyle(), // 栅格瓦片样式
    center: prj.toLngLat(mapExtent.center()), // 中心点
    zoom: 2,
    renderWorldCopies: false
});
// 地图关联服务对象和坐标系
map.attach(svc, prj);
await map.onLoad();
let mapBounds = map.getGeoBounds();
let len = mapBounds.width() / 5;
let svgOverlay = new vjmap.SvgOverlay({
    maxZoom: 5, // 第5级时全部不显示了
    maxPitch: 60 // 倾角超过60度就不显示了
});
svgOverlay.addTo(map);
// 增加一个渐变色
svgOverlay.addElement(`
          &lt;defs&gt;
            &lt;radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"&gt;
              &lt;stop offset="0%" style="stop-color:${vjmap.randomColor()};stop-opacity:0.6" /&gt;
              &lt;stop offset="100%" style="stop-color:${vjmap.randomColor()};stop-opacity:1" /&gt;
            &lt;/radialGradient&gt;
          &lt;/defs&gt;
        `)
const getStyle = (style = {}) =&gt; {
    return Object.keys(style).map(key =&gt; `${key}:${style[key]}`).join(";")
}
const svgCircleHtml = (id, point, r, style) =&gt; {
    return ` &lt;circle id="${id}" ${vjmap.SvgOverlay.attr_cx_cy_r(point.x, point.y, r)} style="${getStyle(style)}"/&gt;`
}
const addCircle = ()=&gt; {
    let id = "circle" + vjmap.RandomID();
    return svgOverlay.addElement({
        html: svgCircleHtml(id, mapBounds.randomPoint(), len / 4, {fill: "url(#grad1)", stroke: vjmap.randomColor(), "stroke-width": 3, cursor: "pointer"}),
        event: svgParentElement =&gt; {
            // 事件回调
            let ele = svgParentElement.getElementById(id);
            if (!ele) return;
            ele.addEventListener("mouseover", e =&gt; ele.style.opacity = 0.4);
            ele.addEventListener("mouseout", e =&gt; ele.style.opacity = 0.6);
            ele.addEventListener("click", e =&gt; map.logInfo("点击了圆" + id));
        }
    })
}
for(let i = 0; i &lt; 10; i++) {
    addCircle();
}
</pre>
</mapFrameEx>
<br/>
<br/>


## 示例

![image-20240928104939832](https://vjmap.com/blogimages/202409281049871.png)

[SVG覆盖物](https://vjmap.com/demo/#/demo/map/overlay/svg/svgOverlay)

[SVG事件](https://vjmap.com/demo/#/demo/map/overlay/svg/svgOverlayEvent)

[SVG动画](https://vjmap.com/demo/#/demo/map/overlay/svg/svgOverlayFlow)