本节摘要:服务端开发面向浏览器与业务系统集成,武器是 REST 接口——把 5.2 发布的服务当"数据 API"来调。本节拆解一次接口调用的完整解剖:地址组成、参数组装、返回结构、错误语义,再写一个供其他系统调用的查询接口封装。学完你能把 IGServer 无缝接进任何业务系统。
REST 风格的接口地址自带语义。拿最常见的文档查询接口开刀,把地址按段拆解,每一段都是"查错先查它"的候选:

地址里那段"图层号"最容易被忽视。一个地图文档服务下挂着多个图层,从 0 开始编号——查询打到了 3 号图层却当成 0 号解读,数据"看起来全错",实际是问错了对象。开发期先调一次图层列表接口,把"图层号加图层名"的对照表打印出来贴在屏幕边,能省掉一大类低级事故。
阅读完本节,你应当能够:
裸调用适合调试,业务系统要的是"自己的一层"。场景继续用耕地保护:县里审批系统需要"给一个坐标点,返回所在图斑的地类与权属"。这层封装用 C# 的 Web 接口写,上游系统只认我们的地址,不感知 IGServer 的存在——这就是集成层的意义。
using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/plot")] public class PlotController : ControllerBase { // 业务接口:GET api/plot/locate 经纬度与坐标系统参数 [HttpGet("locate")] public IActionResult Locate(double lon, double lat) { if (lon < 113 || lon > 115 || lat < 33 || lat > 35) return BadRequest("坐标超出本县范围"); // 先做范围防御 // 组装 IGServer 查询 参数含义见图中左下注解 var query = new DocQuery("farmland_protect", 2) // 2号图层为耕地图斑 { GeometryType = 1, // 点查询 Geometry = $"{lon},{lat}", Radius = 0.0005, // 容差 半个图斑级别 F = "json", PageCount = 1 // 只要一个 }; var result = IGServerClient.Post(query); // 统一封装的调用器 if (result.Code != 200) return StatusCode(502, "图斑服务暂不可用"); // 下游故障不裸抛 if (result.TotalCount == 0) return Ok(new { hit = false }); // 没点中也是合法结果 var f = result.Features[0]; return Ok(new { hit = true, 地类 = f.Get("地类编码"), // 按下标取值封装成按名取值 权属 = f.Get("权属单位"), 面积 = f.Get("椭球面积") }); } } // 输出:api地址传入 113.86 与 34.05 返回 hit true 地类 011 水田 权属 河东村 面积 0.42 公顷
这段封装值得咀嚼的是三个防御动作:入口的坐标范围校验挡掉无意义请求;下游非 200 时返回统一错误而不是把原始异常抛给调用方;点不中要素返回"合法的未命中"而不是 404。集成层的价值一半在转发,另一半就在这些"边界情形的语义翻译"。
查询接口之外,另一族高频接口是地理处理——缓冲区、叠加、最短路径这些重计算放在服务端跑,浏览器只交参数收结果。这类接口的调用特征与查询不同:耗时长(秒级到分钟级)、结果可能是异步的(先提交任务拿任务号,再轮询取结果)、参数是结构化的(几何要按类型编码)。
// 概念演示:调服务端缓冲区分析接口(浏览器端 示意) var body = { geometryType: 1, // 1 点 geometry: { coordinates: [113.86, 34.05] }, bufferRadius: 500, // 单位米 analysisUnit: 3 // 3 表示米制 }; fetch('http://服务器地址:6163/igs/rest/spatialanalyst/buffer', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) .then(function (r) { return r.json(); }) .then(function (data) { if (data.ResultCode !== 200) { showErr(data.Message); return; } drawPolygon(data.BufferGeometry); // 缓冲区多边形画到地图 console.log('缓冲完成 顶点数', data.BufferGeometry.rings[0].length / 2); }); // 输出:缓冲完成 顶点数 36 // 分析类接口的三条纪律: // 1 超时放宽到30秒以上 别用查询类的3秒 // 2 大范围高密度输入先化简再提交 服务端不是无限耐心的 // 3 长任务版接口返回任务号 按号轮询 防止请求悬挂
分析接口最能体现 5.1 那句"计算集中在服务端"的分量:手机浏览器跑不动几十万要素的叠加,但提交给服务端,回来只是一张结果图。计算放哪一层的争论,在分析接口这里有了最直观的答案——放数据最近、算力最足的那一层。
业务系统调 GIS 服务,网络抖动与服务重启是躲不开的日常。生存策略三件套按序上:超时必设,默认无限等待的请求会把上游线程拖死;重试只对幂等的查询做,且用退避间隔连试两三次即止;降级给"图查不到"准备一条退路——返回上一次成功结果加时间戳,或干脆返回边界加提示。审批系统宁可看到五分钟前的旧图斑,也不要整条流程卡死在一个查询上。
# 接口调用生存策略配置(示例值) 超时 查询类 3 秒 出图类 10 秒 分析类 30 秒 重试 仅GET 指数退避 最多3次 降级 返回缓存结果并附数据时间 供上游标注展示 熔断 一分钟内失败超半 直接短路走降级 半分钟后试探恢复 # 排障对应表(沿用图解) 连接拒绝 服务未起或端口错 404 服务名或图层号错 空结果 几何或where条件错 坐标系不匹配 超时 无分页拉大结果集 或服务负载高
💡 关键直觉:集成接口的口碑取决于最糟时刻的表现。晴天里大家都能查出图斑,暴雨天(服务重启、网络抖动)还能给出明确反馈的系统,才是业务方敢依赖的系统。
下一节转向两条轻量路线:插件把功能挂进桌面端菜单,脚本把批处理交给机器——二八定律在那里最灵验,八成的小需求用两成的成本解决。