创建/更新电子围栏
仅定义围栏本身(支持POLYGON/CIRCLE/RECTANGLE等图形类型),不绑定资源;如需生效请调用分配接口。
仅企业超管和管理员可操作
| 接口名 | POST: /login-register/open-api/geofences | |||
| 入参:(body传值) | application/json | |||
| 是否必传 | 默认值 | 描述 | 备注 | |
| id | 否 | - | 围栏ID | 更新时传入 |
| shapeType | 是 | - | 围栏名称 | POLYGON-多边形 CIRCLE-圆形 RECTANGLE-矩形 |
| fenceName | 是 | - | 几何数据 |
|
| geometry | 是 | - | 多边形/折线顶点坐标数组 | 详细说明见下方描述 |
| coordinates | 否 | - | 多边形/折线顶点坐标数组 | shapeType=POLYGON时必填 |
| center | 否 | - | 圆形圆心 | shapeType=CIRCLE时必填 |
| radius | 否 | - | 圆形半径(单位:米) | shapeType=CIRCLE时必填 |
| southwest | 否 | - | 矩形西南角坐标(左下角) | shapeType=RECTANGLE时必填 |
| northeast | 否 | - | 矩形东北角坐标(右上角) | shapeType=RECTANGLE时必填 |
| coordSystem | 否 | WGS84 | 围栏几何坐标所属坐标系 | WGS84:国际标准坐标系 GCJ02:国测局火星坐标系 BD09:百度坐标系 |
| enabled | 否 | y | 是否启用该围栏 | 是:y 否:n |
| 入参:(Header传值) | ||||
| Authorization | 是 | - | 传递AccessToken | 格式:Bearer {AccessToken} |
| 入参示例:(application/json) | ||||
|
{
"fenceName": "园区矩形围栏",
"shapeType": "RECTANGLE",
"coordSystem": "WGS84",
"enabled": "y",
"geometry": {
"southwest": { "lat": 31.232600, "lng": 121.500000 },
"northeast": { "lat": 31.236800, "lng": 121.506000 }
}
}
|
||||
| 回参示例:(application/json) | ||||
|
{
"code": 0,
"msg": null,
"data": {
"fenceId": "fence_789"
},
"ok": true
}
|
||||
geometry详细说明
- POLYGON 多边形(至少 3 个顶点)
{
"fenceName": "上海研发中心禁区",
"shapeType": "POLYGON",
"coordSystem": "WGS84",
"enabled": "y",
"geometry": {
"coordinates": [
{ "lat": 31.234500, "lng": 121.501200 },
{ "lat": 31.235800, "lng": 121.503600 },
{ "lat": 31.233900, "lng": 121.505100 },
{ "lat": 31.232600, "lng": 121.502400 }
]
}
}
- CIRCLE 圆形(中心点 + 半径,单位米)
{
"fenceName": "厂区圆形管控区",
"shapeType": "CIRCLE",
"coordSystem": "GCJ02",
"enabled": "y",
"geometry": {
"center": { "lat": 31.234500, "lng": 121.501200 },
"radius": 500.0
}
}
- RECTANGLE 矩形(西南角 + 东北角)
{
"fenceName": "园区矩形围栏",
"shapeType": "RECTANGLE",
"coordSystem": "WGS84",
"enabled": "y",
"geometry": {
"southwest": { "lat": 31.232600, "lng": 121.500000 },
"northeast": { "lat": 31.236800, "lng": 121.506000 }
}
}
package com.hoteam.sview.demo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 创建/更新电子围栏 调用 Demo
* <p>
* 接口:POST /login-register/open-api/geofences
* 鉴权:Header Authorization: Bearer {AccessToken}
* 注意:本接口要求使用管理员账号的个人身份登录(grant_type=mobile, IntegrationId 方式)获取 token
* 支持三种图形:POLYGON多边形 / CIRCLE圆形 / RECTANGLE矩形
* 传入 fenceId 为更新,不传为新建
*/
@Slf4j
public class CreateOrUpdateGeofenceDemo {
// 业务网关地址,部署时替换为实际 gateway 地址
private static final String CREATE_GEOFENCE_URL = "http://your-host/login-register/open-api/geofences";
// 图形类型常量
public static final String SHAPE_POLYGON = "POLYGON";
public static final String SHAPE_CIRCLE = "CIRCLE";
public static final String SHAPE_RECTANGLE = "RECTANGLE";
// 坐标系常量
public static final String COORD_WGS84 = "WGS84";
public static final String COORD_GCJ02 = "GCJ02";
public static final String COORD_BD09 = "BD09";
// 是否启用围栏
public static final String ENABLED_YES = "y";
public static final String ENABLED_NO = "n";
/**
* 经纬度点位实体
*/
@Data
@AllArgsConstructor
public static class Point {
private Double lat; // 纬度
private Double lng; // 经度
}
/**
* 矩形对角点位
*/
@Data
@AllArgsConstructor
public static class RectPoint {
private Point southwest; // 西南角(左下角)
private Point northeast; // 东北角(右上角)
}
//==================== 重载方法:三种围栏创建/更新入口 ====================
/**
* 多边形围栏 创建/更新
* @param accessToken 令牌
* @param fenceId 围栏ID,传null/空=新建,有值=更新
* @param fenceName 围栏名称 必填
* @param coordSystem 坐标系 WGS84/GCJ02/BD09
* @param enabled 是否启用 y/n
* @param polygon 多边形顶点集合,至少3个点位
* @return 围栏ID,失败返回null
*/
public static String createOrUpdatePolygonFence(String accessToken,
String fenceId,
String fenceName,
String coordSystem,
String enabled,
List<Point> polygon) {
// 参数校验
if (StrUtil.isBlank(accessToken)) {
log.warn("accessToken 不能为空");
return null;
}
if (StrUtil.isBlank(fenceName)) {
log.warn("围栏名称 fenceName 不能为空");
return null;
}
if (CollUtil.size(polygon) < 3) {
log.warn("多边形顶点至少需要3个,当前数量:{}", CollUtil.size(polygon));
return null;
}
// 组装请求体
JSONObject body = new JSONObject();
if (StrUtil.isNotBlank(fenceId)) {
body.set("id", fenceId);
}
body.set("fenceName", fenceName);
body.set("shapeType", SHAPE_POLYGON);
body.set("coordSystem", StrUtil.blankToDefault(coordSystem, COORD_WGS84));
body.set("enabled", StrUtil.blankToDefault(enabled, ENABLED_YES));
JSONObject geometry = new JSONObject();
JSONArray coordinatesArr = new JSONArray();
for (Point point : polygon) {
JSONObject pointObj = new JSONObject();
pointObj.set("lat", point.getLat());
pointObj.set("lng", point.getLng());
coordinatesArr.add(pointObj);
}
geometry.set("coordinates", coordinatesArr);
body.set("geometry", geometry);
return doHttpPost(accessToken, body);
}
/**
* 圆形围栏 创建/更新
* @param accessToken 令牌
* @param fenceId 围栏ID,传null/空=新建,有值=更新
* @param fenceName 围栏名称 必填
* @param coordSystem 坐标系 WGS84/GCJ02/BD09
* @param enabled 是否启用 y/n
* @param center 圆心点位
* @param radius 半径 单位米
* @return 围栏ID,失败返回null
*/
public static String createOrUpdateCircleFence(String accessToken,
String fenceId,
String fenceName,
String coordSystem,
String enabled,
Point center,
Double radius) {
// 参数校验
if (StrUtil.isBlank(accessToken)) {
log.warn("accessToken 不能为空");
return null;
}
if (StrUtil.isBlank(fenceName)) {
log.warn("围栏名称 fenceName 不能为空");
return null;
}
if (center == null || radius == null || radius <= 0) {
log.warn("圆形圆心、半径参数非法");
return null;
}
// 组装请求体
JSONObject body = new JSONObject();
if (StrUtil.isNotBlank(fenceId)) {
body.set("id", fenceId);
}
body.set("fenceName", fenceName);
body.set("shapeType", SHAPE_CIRCLE);
body.set("coordSystem", StrUtil.blankToDefault(coordSystem, COORD_WGS84));
body.set("enabled", StrUtil.blankToDefault(enabled, ENABLED_YES));
JSONObject geometry = new JSONObject();
JSONObject centerObj = new JSONObject();
centerObj.set("lat", center.getLat());
centerObj.set("lng", center.getLng());
geometry.set("center", centerObj);
geometry.set("radius", radius);
body.set("geometry", geometry);
return doHttpPost(accessToken, body);
}
/**
* 矩形围栏 创建/更新
* @param accessToken 令牌
* @param fenceId 围栏ID,传null/空=新建,有值=更新
* @param fenceName 围栏名称 必填
* @param coordSystem 坐标系 WGS84/GCJ02/BD09
* @param enabled 是否启用 y/n
* @param rectPoint 矩形对角点位(西南+东北)
* @return 围栏ID,失败返回null
*/
public static String createOrUpdateRectFence(String accessToken,
String fenceId,
String fenceName,
String coordSystem,
String enabled,
RectPoint rectPoint) {
// 参数校验
if (StrUtil.isBlank(accessToken)) {
log.warn("accessToken 不能为空");
return null;
}
if (StrUtil.isBlank(fenceName)) {
log.warn("围栏名称 fenceName 不能为空");
return null;
}
if (rectPoint == null || rectPoint.getSouthwest() == null || rectPoint.getNortheast() == null) {
log.warn("矩形对角坐标不能为空");
return null;
}
// 组装请求体
JSONObject body = new JSONObject();
if (StrUtil.isNotBlank(fenceId)) {
body.set("id", fenceId);
}
body.set("fenceName", fenceName);
body.set("shapeType", SHAPE_RECTANGLE);
body.set("coordSystem", StrUtil.blankToDefault(coordSystem, COORD_WGS84));
body.set("enabled", StrUtil.blankToDefault(enabled, ENABLED_YES));
JSONObject geometry = new JSONObject();
JSONObject swObj = new JSONObject();
swObj.set("lat", rectPoint.getSouthwest().getLat());
swObj.set("lng", rectPoint.getSouthwest().getLng());
geometry.set("southwest", swObj);
JSONObject neObj = new JSONObject();
neObj.set("lat", rectPoint.getNortheast().getLat());
neObj.set("lng", rectPoint.getNortheast().getLng());
geometry.set("northeast", neObj);
body.set("geometry", geometry);
return doHttpPost(accessToken, body);
}
/**
* 统一发送HTTP POST 请求 & 解析响应
*/
private static String doHttpPost(String accessToken, JSONObject body) {
HttpRequest request = HttpRequest.post(CREATE_GEOFENCE_URL)
.header(Header.AUTHORIZATION, "Bearer " + accessToken)
.header(Header.CONTENT_TYPE, ContentType.JSON.getValue())
.timeout(10_000)
.body(body.toString());
// 可按需注入公共请求头
// CommonHeaderUtil.withCommonHeaders(request, deviceId, deviceModel, deviceType, lang);
try (HttpResponse response = request.execute()) {
int status = response.getStatus();
String respBody = response.body();
log.info("创建/更新电子围栏响应: status=[{}], body=[{}]", status, respBody);
if (status == HttpStatus.HTTP_UNAUTHORIZED) {
log.warn("认证失败,请确认使用的是管理员个人身份token");
return null;
}
if (!response.isOk() || StrUtil.isBlank(respBody)) {
log.warn("创建电子围栏异常: status=[{}], body=[{}]", status, respBody);
return null;
}
JSONObject json = JSONUtil.parseObj(respBody);
Integer code = json.getInt("code");
if (code == null || code != 0) {
log.warn("创建电子围栏业务失败: code=[{}], msg=[{}], body=[{}]",
code, json.getStr("msg"), respBody);
return null;
}
JSONObject data = json.getJSONObject("data");
if (data == null) {
log.warn("响应中未提取到data: {}", respBody);
return null;
}
String fenceId = data.getStr("fenceId");
if (StrUtil.isBlank(fenceId)) {
log.warn("响应中未获取到 fenceId, data=[{}]", data);
return null;
}
return fenceId;
} catch (Exception e) {
log.error("创建/更新电子围栏接口异常", e);
return null;
}
}
// ===================== 调用示例入口 =====================
public static void main(String[] args) {
// 替换为你自己的有效token
String token = "your-access-token-here";
// 示例1:新建矩形围栏
RectPoint rect = new RectPoint(
new Point(31.232600, 121.500000),
new Point(31.236800, 121.506000)
);
String rectFenceId = createOrUpdateRectFence(token, null, "园区矩形围栏", COORD_WGS84, ENABLED_YES, rect);
log.info("矩形围栏结果ID: {}", rectFenceId);
// 示例2:新建圆形围栏
Point circleCenter = new Point(31.234500, 121.501200);
String circleFenceId = createOrUpdateCircleFence(token, null, "厂区圆形管控区", COORD_GCJ02, ENABLED_YES, circleCenter, 500.0);
log.info("圆形围栏结果ID: {}", circleFenceId);
// 示例3:新建多边形围栏
/*
List<Point> polygonList = List.of(
new Point(31.234500, 121.501200),
new Point(31.235800, 121.503600),
new Point(31.233900, 121.505100),
new Point(31.232600, 121.502400)
);
String polygonFenceId = createOrUpdatePolygonFence(token, null, "上海研发中心禁区", COORD_WGS84, ENABLED_YES, polygonList);
log.info("多边形围栏结果ID: {}", polygonFenceId);
*/
// 示例4:更新已有围栏(传入已存在fenceId)
// String updateId = createOrUpdateRectFence(token, "fence_789", "修改后的围栏名称", COORD_WGS84, ENABLED_YES, rect);
}
}