OpenLayers 用 WFS 获取 GeoJSON 并上图
在 OpenLayers 里用 WFS 获取 GeoJSON 并上图,标准做法是:用 ol/source/Vector(VectorSource)配合 ol/format/GeoJSON,通过 url 函数动态拼出带 outputFormat=application/json 的 GetFeature 请求,再挂到 ol/layer/Vector(VectorLayer)上显示。视图默认投影多为 EPSG:3857,请求里通常用 bbox 限制范围,并配合 bbox 或 tile 加载策略按需取数。截至 2026 年 11 月,官方示例基于 ol 10.11.0;下面只讲这一章的配置、验收与排错,不展开安装与整站架构。

怎么写 VectorSource 从 WFS 拉 GeoJSON
要解决的问题很具体:浏览器向 WFS 服务发 GetFeature,拿到 FeatureCollection(GeoJSON),解析成要素,画到当前视图。官方推荐路径是 VectorSource + GeoJSON 格式,而不是先用 ol/format/WFS 去解析 GML——服务端已经能吐 JSON 时,直接用 GeoJSON 更省事。可对照 OpenLayers 官方 Vector WFS 示例 核对写法。
- 安装并引入(npm:npm install ol;按需 import VectorSource、VectorLayer、GeoJSON、以及 loadingstrategy 里的 bbox 等)。
- 创建 VectorSource:设置 format: new GeoJSON();把 url 写成函数,入参是当前 extent(以及 resolution、projection),返回完整 GetFeature URL。
- 选择加载策略:按视图范围用 bbox;按瓦片网格用 tile;一次性全量才用默认的 all(大数据慎用)。
- 创建 VectorLayer,把上面的 source 挂上,并设置 style(Style 对象、样式函数或 flat style 均可)。
- 把图层加入 Map;缩放平移时,策略会触发新的 extent 请求,要素会陆续出现。
核心结构示意如下(URL 换成你自己的 GeoServer 或其它 WFS 地址与图层名):
- VectorSource:format 为 GeoJSON;url 函数内拼接 service=WFS&version=1.1.0&request=GetFeature&typename=…&outputFormat=application/json&srsname=EPSG:3857&bbox= + extent.join(‘,’) + ,EPSG:3857。
- strategy:从 ol/loadingstrategy.js 引入 bbox(示例里常写作 bboxStrategy)。
- VectorLayer:source 指向该 VectorSource,再配 stroke/fill 等样式。
GeoJSON 格式默认 dataProjection 为 EPSG:4326;当 VectorSource 用默认 XHR loader + url 时,一般会自动从数据投影转到视图投影。若你自行 readFeatures,需要显式传 dataProjection / featureProjection。格式细节见 ol/format/GeoJSON API 说明。

WFS 参数怎么拼、策略怎么选
URL 拼错或 CRS 对不上,是要素“请求成功但图上没有”的常见原因。典型参数如下(以 GeoServer 等常见实现为准,具体以你服务 GetCapabilities 为准)。
| 参数 | 常见取值 | 说明 |
|---|---|---|
| service | WFS | 固定 |
| version | 1.1.0(也有 1.0.0 / 2.0.0) | 与服务器协商一致;官方示例多用 1.1.0 |
| request | GetFeature | 取要素 |
| typename / typeNames | 工作区:图层名 | 如 osm:water_areas |
| outputFormat | application/json(兼容别名 json) | 返回 GeoJSON FeatureCollection |
| srsname | EPSG:3857 或 EPSG:4326 | 与视图投影、bbox 的 CRS 对齐 |
| bbox | minx,miny,maxx,maxy[,CRS] | 由 url 函数里的 extent 生成,末尾常带投影代码 |
加载策略怎么选,直接对应你要解决的问题:
- bbox:视图 extent 变化就按范围请求,适合多数业务图层;官方水系示例用的就是它。
- tile:按瓦片网格切分请求(可配合 createXYZ 等),地理坐标示例里常用;适合范围大、要控制单次请求量的场景。
- all:一次拉全量。若 url 写成函数却仍用 all,可能拼出无效“无限” bbox,全量场景更稳妥的是固定字符串 url,或明确限制 maxFeatures/count。
地理坐标视图可先调用 useGeographic(),srsname 用 EPSG:4326,并选用 tile 策略;Web Mercator 视图则与官方 bbox 示例保持一致即可。服务端需已启用 WFS,且浏览器能跨域访问(见下一节)。
投影、CORS 和上图验收要注意什么
三个最容易踩的坑:跨域、投影不一致、异步未就绪就去读要素。
- CORS:WFS 返回 JSON 受同源策略限制(WMS 出图往往没事)。浏览器控制台若报 Access-Control-Allow-Origin 缺失,需在 GeoServer(如 web.xml 的 CrossOriginFilter)放开跨域,或走同源代理;JSONP(text/javascript)需服务端显式启用,且默认常关闭,生产更推荐 CORS 或代理。
- 投影:extent 单位必须是当前视图投影;srsname 与 bbox 末尾 CRS 要服务器支持。错了会出现“有响应但位置飞了或不显示”。自定义投影需用 proj4 定义并 register。CRS84 等别名也可能要额外 defs。
- 验收:缩放平移后要素随范围出现;在控制台或调试面板确认响应是 FeatureCollection;监听 source 的 featuresloadend / change,或检查 getState() 为 ready 后再做统计。样式里 stroke 过细、fill 全透明也会“看起来没上图”。
要素量一大就会卡顿。按需加载只是第一步;本地还要控制绘制与数据量。可结合本站 OpenLayers 加载慢:性能优化、海量点和 GeoJSON 加载 与 OpenLayers 加载 GeoJSON 卡顿的优化示例 做抽样、简化或服务端限流。点状要素过密时,再考虑 OpenLayers 点聚合的实现思路,与 WFS 按需拉取是两条互补链路。
加载失败或没有要素时怎么排查
按下面顺序查,通常能定位到配置问题而不是“库坏了”。
- 看 Network:GetFeature 是否 200;响应是不是 GeoJSON;是否被 CORS 拦下。
- 核对 typename、outputFormat、srsname、bbox 四件套;bbox 是否与视图投影一致,范围是否过大被服务端拒绝。
- 确认策略:全量应用固定 url;bbox/tile 才用 extent 函数。失败时自定义 loader 可在 failure 回调里 removeLoadedExtent,避免脏范围一直占着。
- 确认图层 style、zIndex、可见性;hit detection 大图标可适当加大 renderBuffer。
- 需要强制重载:clear(),或对失效 extent removeLoadedExtent 后再 changed()。
服务端常有 maxFeatures/count 上限;范围过大时返回空集合也属正常,应缩小视图或让服务分页/过滤,而不是在前端一次吞全库。
常见问题
为什么不用 ol/format/WFS,而用 GeoJSON?
ol/format/WFS 主要处理 GML/XML 以及 Transaction 等;当 WFS 已能以 application/json 输出 FeatureCollection 时,用 GeoJSON 格式解析更直接,也是官方矢量 WFS 示例的做法。只有必须吃 GML 或要写事务时,再上 WFS 格式。
bbox 策略下为什么一打开地图没有数据?
请求是异步的,且只加载当前(或策略规定的)extent。先确认初始视图落在有数据的区域,并等待 featuresloadend;若策略或 url 写错,可能根本没发出有效请求。用固定小范围手动拼一条 GetFeature 在浏览器里试,能快速区分是服务问题还是前端拼接问题。
要素位置整体偏移或缩到一个点怎么办?
多半是 dataProjection / featureProjection / srsname 不一致。让默认 loader 自动转换,或在 readFeatures 时写明两端投影;自定义投影务必先 register。同时检查 bbox 末尾 CRS 是否与 extent 单位一致。
开发环境可以用 CDN 吗?版本怎么对齐?
可用 jsDelivr 等引用 ol 完整包做快速验证,生产更推荐 npm + 打包器按需引入。截至 2026 年 11 月,稳定示例对应 ol 10.11.0(约 2026 年 10 月 4 日发布);版本以官网下载页与 npm 为准,避免混用新旧 API。
小结:OpenLayers 用 WFS 取 GeoJSON 上图,就是 VectorSource(GeoJSON + url 函数)+ 合适加载策略 + VectorLayer;请求侧保证 outputFormat 与 CRS,浏览器侧解决 CORS,验收侧确认异步加载与样式。建议先按官方 bbox 示例跑通一条自己的图层,再按数据量加上限与按需策略;性能仍不够时,优先做服务端过滤与前端绘制优化,而不是一次性拉全量。