
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
my-openlayer
Advanced tools
my-openlayer 是一个基于 [OpenLayers](https://openlayers.org/) 的现代地图组件库,专为 Web GIS 应用开发者设计。提供完整的 TypeScript 支持、模块化的类型定义、强大的错误处理和事件管理系统,支持天地图底图加载、要素绘制、图层管理、事件监听等丰富功能,极大提升地图开发效率。
my-openlayer 是一个基于 OpenLayers 的现代地图组件库,专为 Web GIS 应用开发者设计。提供完整的 TypeScript 支持、模块化的类型定义、强大的错误处理和事件管理系统,支持天地图底图加载、要素绘制、图层管理、事件监听等丰富功能,极大提升地图开发效率。
在线 Demo · 文档 · 迁移指南 (2.x → 3.0)
3.0 是一次 API 形态层的范式转移,核心目标是统一 lifecycle、降低学习成本:
add* 返回 { layer, remove(), setVisible() } 形态的句柄,跨 Point / Line / Polygon 复用同一套 lifecycle 模型addDomPoint / addVueTemplatePoint 返回 { target, remove(), setVisible() },并保留 anchors / getPoints() 等原有能力addPoint / addClusterPoint / addPulsePointLayer 直接接受 PointData[]、GeoJSON FeatureCollection、Feature、MultiPoint geometry,内部统一标准化,创建后的 Feature 可直接通过 feature.get('name') / feature.getProperties() 读取业务字段MyOl.addGeoJSON(data, options) 自动识别点/线/面几何类型,按分组创建图层,返回统一 GeoJSONRenderHandle,支持 groupBy 分组、styleByProperties 逐要素样式、数组/Record 多数据集输入addPointByUrl / addLineByUrl / addPolygonByUrl 统一先获取 JSON,再返回完整 HandleMyOl.destroy() 现在依次调用 SelectHandler.destroy / Line.destroyAll / Point.destroyAll / Polygon.destroyAll,确保静态线、流动线 rAF / Overlay / Vue 实例 / Select interaction 全部释放ProjectionManager.register({ code, def }) 在 MyOl 实例之外注册任意 EPSGthrow 使用 MyOpenLayersError 并携带 ErrorType(VALIDATION_ERROR / MAP_ERROR / LAYER_ERROR / COORDINATE_ERROR / DATA_ERROR / COMPONENT_ERROR),另有 LayerNotFoundError / InvalidGeoJSONError / ProjectionError 子类,方便 instanceof 判别add* 方法签名上 layerName 变成必填(编译时强制)src → img — 统一命名,旧 src 标 @deprecated从 2.x 升级请参考 MIGRATION-3.0.md。3.0 会把旧
add*的原始 layer 返回值改为 Handle;访问 OL 图层请使用handle.layer。
my-openlayer🗺️ 底图管理 (MapBaseLayers)
📍 要素操作
🛠️ 地图工具
clipMap)⚡ 高级特性
setDefaultsEPSG:4326 / EPSG:4490 / EPSG:4549,支持 ProjectionManager.register() 注册任意自定义投影npm install my-openlayer
# 或
yarn add my-openlayer
# 或
pnpm add my-openlayer
本仓库已按 CC Switch 技能仓库结构提供 my-openlayer-helper:
skills/my-openlayer-helper/SKILL.md
在 CC Switch 的“添加技能仓库”中填写:
仓库 URL:cuteyuchen/my-openlayer
分支:main
CC Switch 扫描后会识别到 my-openlayer-helper。后续更新只需要同步本仓库,使用者在 CC Switch 中刷新/更新技能即可。
import { MyOl } from 'my-openlayer';
const map = new MyOl('map-container', {
center: [119.81, 29.969],
zoom: 10,
token: import.meta.env.VITE_TIANDITU_TOKEN, // 天地图 Token
annotation: true
});
// 获取模块实例(懒加载)
const point = map.getPoint();
const line = map.getLine();
const polygon = map.getPolygon();
// 添加点位(3.0 add* 返回统一 LayerHandle)
const handle = point.addPoint(
[{ lgtd: 119.81, lttd: 29.969, name: '示例点' }],
{ layerName: 'example-point', img: 'marker.png' }
);
handle?.remove(); // 统一的生命周期管理
// 也支持直接传 GeoJSON FeatureCollection
const geoHandle = point.addPoint(
{ type: 'FeatureCollection', features: [
{ type: 'Feature', properties: { name: '杭州' }, geometry: { type: 'Point', coordinates: [120.15, 30.27] } }
]},
{ layerName: 'geojson-points', textKey: 'name' }
);
const feature = geoHandle?.layer.getSource()?.getFeatures()[0];
feature?.get('name'); // '杭州'
// feature.get('rawData') 仅保留兼容旧代码,新代码优先读取顶层业务字段。
当需要展示大量预警点位时,优先使用 addPulsePointLayer。它与 addPoint 保持一致的 img、scale、textKey 等参数习惯,通过单个 requestAnimationFrame 驱动整个 VectorLayer,避免为每个点创建 DOM 动画。
const pulseLayer = point.addPulsePointLayer(
[
{ lgtd: 119.81, lttd: 29.969, lev: 0, stnm: '风险村' },
{ lgtd: 119.86, lttd: 29.992, lev: 3, stnm: '普通村' }
],
{
layerName: 'village-pulse',
levelKey: 'lev',
textKey: 'stnm',
img: '/icons/village.svg',
scale: 0.8,
textVisible: true,
pulse: {
duration: 2400,
radius: [8, 28],
colorMap: {
0: 'rgba(255, 48, 54, 0.48)',
1: 'rgba(255, 136, 0, 0.45)',
2: 'rgba(253, 216, 46, 0.4)',
3: 'rgba(6, 183, 253, 0.32)'
}
}
}
);
pulseLayer?.stop();
pulseLayer?.start();
pulseLayer?.remove();
const flow = map.getLine().addFlowLine(lineData, {
layerName: 'river-flow',
animationMode: 'icon+dash',
strokeColor: '#19b1ff',
strokeWidth: 3,
flowSymbol: {
src: '/symbols/boat.svg',
scale: 0.9,
count: 2,
spacing: 0.2
}
});
flow?.pause();
flow?.resume();
flow?.remove();
const tools = map.getTools();
// 裁剪整张地图(底图 + 注记 + 用户图层全部只在区域内可见)
tools.clipMap(geoJsonBoundary);
// 或只裁剪当前底图
const baseLayers = map.getMapBaseLayers().getCurrentBaseLayers();
baseLayers.forEach(layer => MapTools.setMapClip(layer, geoJsonBoundary));
import { ProjectionManager } from 'my-openlayer';
// 在 MyOl 实例之外注册任意 EPSG
ProjectionManager.register({
code: 'EPSG:4528',
def: '+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs'
});
// 之后 MyOl 构造时直接用
const map = new MyOl('map', { projection: { code: 'EPSG:4528' } });
import { ConfigManager } from 'my-openlayer';
// 所有后续 addLine 调用的默认 strokeWidth 变为 4
ConfigManager.setDefaults('LINE_OPTIONS', { strokeWidth: 4 });
// 恢复内置默认
ConfigManager.resetDefaults('LINE_OPTIONS');
自动识别点/线/面几何类型,按分组创建图层,返回统一句柄:
// 混合 FeatureCollection — 自动拆分为点、线、面图层
const handle = map.addGeoJSON(geojsonData, {
layerName: 'risk',
groupBy: 'level', // 按 properties.level 分组
point: { textKey: 'name', textVisible: true },
line: { strokeColor: '#3b82f6', strokeWidth: 3 },
polygon: { fillColor: 'rgba(239,68,68,0.15)' }
});
// 句柄操作
handle.setVisible(false); // 隐藏全部
handle.setGroupVisible('high', false); // 只隐藏 high 组
handle.removeGroup('low'); // 只移除 low 组
handle.remove(); // 移除全部
// styleByProperties — 按 feature 属性返回不同样式
map.addGeoJSON(points, {
layerName: 'styled',
point: {
styleByProperties: (props) => ({
circleColor: props.risk === 'high' ? '#ef4444' : '#22c55e',
circleRadius: props.risk === 'high' ? 10 : 6
})
}
});
详细文档请访问 在线文档,交互式 Demo 请访问 Demo 站点。
register() 注册任意 EPSG。setDefaults。LayerNotFoundError / InvalidGeoJSONError / ProjectionError。clipMap 全图裁剪)。const baseLayers = map.getMapBaseLayers();
baseLayers.switchBaseLayer('img_c'); // 切换到影像底图
import { MeasureHandler } from 'my-openlayer';
// 需要传入原生的 OpenLayers map 实例
const measure = new MeasureHandler(map.map);
measure.start('LineString'); // 开始测距
measure.end(); // 结束测量
const selectHandler = map.getSelectHandler();
selectHandler.enableSelect('click', {
layerFilter: ['cities'],
onSelect: (event) => console.log('选中:', event.selected)
});
// 编程式选择
selectHandler.selectByProperty('name', '杭州', { fitView: true });
注意:更多示例请访问 Demo 站点,每个公开类都有独立的交互式演示页。
欢迎提交 Issue 或 Pull Request!
git checkout -b feature/your-featuregit commit -m 'feat: 新功能描述'git push origin feature/your-feature联系方式: 2364184627@qq.com | GitHub Issues
FAQs
my-openlayer 是一个基于 [OpenLayers](https://openlayers.org/) 的现代地图组件库,专为 Web GIS 应用开发者设计。提供完整的 TypeScript 支持、模块化的类型定义、强大的错误处理和事件管理系统,支持天地图底图加载、要素绘制、图层管理、事件监听等丰富功能,极大提升地图开发效率。
The npm package my-openlayer receives a total of 58 weekly downloads. As such, my-openlayer popularity was classified as not popular.
We found that my-openlayer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.