SView Help Center
English (US)

创建/更新电子围栏

Author: sviewngts Last Updated: 2026-08-25 16:32
仅定义围栏本身(支持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);
    }
}