支持多边形查询

This commit is contained in:
lin
2025-10-10 00:12:09 +08:00
parent ca04df1fec
commit a3c4f02e3f
6 changed files with 245 additions and 24 deletions

View File

@@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.web.custom.bean.CameraChannel;
import com.genersoft.iot.vmp.web.custom.bean.CameraGroup;
import com.genersoft.iot.vmp.web.custom.bean.Point;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
@@ -612,11 +613,32 @@ public interface CommonGBChannelMapper {
@SelectProvider(type = ChannelProvider.class, method = "queryGbChannelByChannelDeviceIdAndGbDeviceId")
CommonGBChannel queryGbChannelByChannelDeviceIdAndGbDeviceId(@Param("channelDeviceId") String channelDeviceId, @Param("gbDeviceId") String gbDeviceId);
CameraChannel queryGbChannelByChannelDeviceIdAndGbDeviceId(@Param("channelDeviceId") String channelDeviceId, @Param("gbDeviceId") String gbDeviceId);
@SelectProvider(type = ChannelProvider.class, method = "queryListByDeviceIds")
List<CameraChannel> queryListByDeviceIds(List<String> deviceIds);
@SelectProvider(type = ChannelProvider.class, method = "queryListWithChildForSy")
List<CameraChannel> queryListWithChildForSy(@Param("query") String query, @Param("sortName") String sortName, @Param("order") Boolean order, @Param("groupList") List<CameraGroup> groupList, @Param("online") Boolean online);
@SelectProvider(type = ChannelProvider.class, method = "queryListByAddressAndDirectionType")
List<CameraChannel> queryListByAddressAndDirectionType(@Param("address") String address, @Param("directionType") Integer directionType);
@SelectProvider(type = ChannelProvider.class, method = "queryListInBox")
List<CameraChannel> queryListInBox(@Param("minLongitude") Double minLongitude, @Param("maxLongitude") Double maxLongitude,
@Param("minLatitude") Double minLatitude, @Param("maxLatitude") Double maxLatitude,
@Param("level") Integer level, @Param("groupList") List<CameraGroup> groupList);
@SelectProvider(type = ChannelProvider.class, method = "queryListInCircleForMysql", databaseId = "mysql")
@SelectProvider(type = ChannelProvider.class, method = "queryListInCircleForH2", databaseId = "h2")
@SelectProvider(type = ChannelProvider.class, method = "queryListInCircleForKingBase", databaseId = "kingbase")
@SelectProvider(type = ChannelProvider.class, method = "queryListInCircleForPostgresql", databaseId = "postgresql")
List<CameraChannel> queryListInCircle(Double centerLongitude, Double centerLatitude, Double radius, Integer level, List<CameraGroup> groupList);
@SelectProvider(type = ChannelProvider.class, method = "queryListInPolygonForMysql", databaseId = "mysql")
@SelectProvider(type = ChannelProvider.class, method = "queryListInPolygonForH2", databaseId = "h2")
@SelectProvider(type = ChannelProvider.class, method = "queryListInPolygonForKingBase", databaseId = "kingbase")
@SelectProvider(type = ChannelProvider.class, method = "queryListInPolygonForPostgresql", databaseId = "postgresql")
List<CameraChannel> queryListInPolygon(@Param("pointList") List<Point> pointList, @Param("level") Integer level, @Param("groupList") List<CameraGroup> groupList);
}

View File

@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
import com.genersoft.iot.vmp.gb28181.bean.Group;
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.web.custom.bean.CameraGroup;
import com.genersoft.iot.vmp.web.custom.bean.Point;
import java.util.Collection;
import java.util.List;
@@ -622,6 +623,99 @@ public class ChannelProvider {
}
}
public String queryListInBox(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND (wdc.gb_ptz_type is null || wdc.gb_ptz_type != 99) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
List<CameraGroup> groupList = (List<CameraGroup>)params.get("groupList");
boolean first = true;
for (CameraGroup group : groupList) {
if (!first) {
sqlBuild.append(",");
}
sqlBuild.append("'" + group.getDeviceId() + "'");
first = false;
}
sqlBuild.append(" )");
sqlBuild.append(" AND coalesce(wdc.gb_longitude, wdc.longitude) >= #{minLongitude} AND coalesce(wdc.gb_longitude, wdc.longitude) <= #{maxLongitude}");
sqlBuild.append(" AND coalesce(wdc.gb_latitude, wdc.latitude) >= #{minLatitude} AND coalesce(wdc.gb_latitude, wdc.latitude) <= #{maxLatitude}");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
}
return sqlBuild.toString();
}
public String queryListInCircleForMysql(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND (wdc.gb_ptz_type is null || wdc.gb_ptz_type != 99) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
List<CameraGroup> groupList = (List<CameraGroup>)params.get("groupList");
boolean first = true;
for (CameraGroup group : groupList) {
if (!first) {
sqlBuild.append(",");
}
sqlBuild.append("'" + group.getDeviceId() + "'");
first = false;
}
sqlBuild.append(" )");
sqlBuild.append(" AND coalesce(wdc.gb_longitude, wdc.longitude) >= #{minLongitude} AND coalesce(wdc.gb_longitude, wdc.longitude) <= #{maxLongitude}");
sqlBuild.append(" AND coalesce(wdc.gb_latitude, wdc.latitude) >= #{minLatitude} AND coalesce(wdc.gb_latitude, wdc.latitude) <= #{maxLatitude}");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
}
return sqlBuild.toString();
}
public String queryListInPolygonForMysql(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND (wdc.gb_ptz_type is null || wdc.gb_ptz_type != 99) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
List<CameraGroup> groupList = (List<CameraGroup>)params.get("groupList");
boolean first = true;
for (CameraGroup group : groupList) {
if (!first) {
sqlBuild.append(",");
}
sqlBuild.append("'" + group.getDeviceId() + "'");
first = false;
}
sqlBuild.append(" )");
StringBuilder geomTextBuilder = new StringBuilder();
geomTextBuilder.append("POLYGON((");
List<Point> pointList = (List<Point>)params.get("pointList");
for (int i = 0; i < pointList.size(); i++) {
if (i > 0) {
geomTextBuilder.append(", ");
}
Point point = pointList.get(i);
geomTextBuilder.append(point.getLng()).append(" ").append(point.getLat());
}
sqlBuild.append("AND ST_Within(point(coalesce(wdc.gb_longitude, wdc.longitude), coalesce(wdc.gb_latitude, wdc.latitude)), ST_GeomFromText('").append(geomTextBuilder).append("))'))");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
}
return sqlBuild.toString();
}
public String queryGbChannelByChannelDeviceIdAndGbDeviceId(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
@@ -632,11 +726,18 @@ public class ChannelProvider {
return sqlBuild.toString();
}
public String queryListByAddressAndDirectionType(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where coalesce(wdc.gb_address, wdc.address) = #{address} and coalesce(wdc.gb_direction_type, wdc.direction_type) = #{directionType}");
return sqlBuild.toString();
}
public String queryListByDeviceIds(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where coalesce(wdc.gb_device_id, wdc.device_id) in");
sqlBuild.append(" where coalesce(wdc.gb_device_id, wdc.device_id) in ( ");
List<String> deviceIds = (List<String>)params.get("deviceIds");
boolean first = true;

View File

@@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.genersoft.iot.vmp.web.custom.bean.CameraChannel;
import com.genersoft.iot.vmp.web.custom.bean.CameraStreamContent;
import com.genersoft.iot.vmp.web.custom.bean.IdsQueryParam;
import com.genersoft.iot.vmp.web.custom.bean.PolygonQueryParam;
import com.genersoft.iot.vmp.web.custom.service.CameraChannelService;
import com.github.pagehelper.PageInfo;
@@ -99,7 +100,7 @@ public class CameraChannelController {
@Parameter(name = "deviceId", description = "通道编号")
@Parameter(name = "deviceCode", description = "摄像头设备国标编号, 对于非国标摄像头可以不设置此参数")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public CameraChannel getOne(@RequestParam(required = true) String deviceId, @RequestParam(required = true) String deviceCode,
public CameraChannel getOne(String deviceId, @RequestParam(required = false) String deviceCode,
@RequestParam(required = false) String geoCoordSys) {
return channelService.queryOne(deviceId, deviceCode, geoCoordSys);
}
@@ -125,8 +126,8 @@ public class CameraChannelController {
@PostMapping(value = "/camera/list/ids")
@ResponseBody
@Operation(summary = "根据编号查询多个摄像头信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
public List<CameraChannel> queryListByDeviceIds(@RequestBody List<String> deviceIds) {
return channelService.queryListByDeviceIds(deviceIds);
public List<CameraChannel> queryListByDeviceIds(@RequestBody IdsQueryParam param) {
return channelService.queryListByDeviceIds(param.getDeviceIds(), param.getGeoCoordSys());
}
@GetMapping(value = "/camera/list/box")
@@ -144,18 +145,14 @@ public class CameraChannelController {
@RequestParam(required = false) Integer level,
String groupAlias,
@RequestParam(required = false) String geoCoordSys) {
return null;
return channelService.queryListInBox(minLongitude, maxLongitude, minLatitude, maxLatitude, level, groupAlias, geoCoordSys);
}
@GetMapping(value = "/camera/list/polygon")
@PostMapping(value = "/camera/list/polygon")
@ResponseBody
@Operation(summary = "根据多边形查询摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "position", description = "多边形位置,格式: [{'lng':116.32, 'lat': 39: 39.2}, {'lng':115.32, 'lat': 39: 38.2}, {'lng':125.32, 'lat': 39: 38.2}]")
@Parameter(name = "level", description = "地图级别")
@Parameter(name = "groupAlias", description = "分组别名")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public List<CameraChannel> queryListInPolygon(@RequestBody PolygonQueryParam param) {
return null;
return channelService.queryListInPolygon(param.getPosition(), param.getGroupAlias(), param.getLevel(), param.getGeoCoordSys());
}
@GetMapping(value = "/camera/list/circle")
@@ -164,11 +161,12 @@ public class CameraChannelController {
@Parameter(name = "centerLongitude", description = "圆心经度")
@Parameter(name = "centerLatitude", description = "圆心纬度")
@Parameter(name = "radius", description = "查询范围的半径,单位米")
@Parameter(name = "level", description = "地图级别")
@Parameter(name = "groupAlias", description = "分组别名")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public List<CameraChannel> queryListInCircle(Double centerLongitude, Double centerLatitude, Double radius, String groupAlias,
String geoCoordSys) {
return null;
@RequestParam(required = false) String geoCoordSys, @RequestParam(required = false) Integer level) {
return channelService.queryListInCircle(centerLongitude, centerLatitude, radius, level, groupAlias, geoCoordSys);
}
@GetMapping(value = "/camera/list/address")
@@ -177,8 +175,8 @@ public class CameraChannelController {
@Parameter(name = "address", description = "安装地址")
@Parameter(name = "directionType", description = "监视方位")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public List<CameraChannel> queryListByAddressAndDirectionType(String address, Integer directionType, String geoCoordSys) {
return null;
public List<CameraChannel> queryListByAddressAndDirectionType(String address, Integer directionType, @RequestParam(required = false) String geoCoordSys) {
return channelService.queryListByAddressAndDirectionType(address, directionType, geoCoordSys);
}
@GetMapping(value = "/camera/control/play")

View File

@@ -10,7 +10,7 @@ import java.util.List;
public class IdsQueryParam {
@Schema(description = "通道编号列表")
private List<ChannelParam> deviceIds;
private List<String> deviceIds;
@Schema(description = "坐标系类型WGS84,GCJ02、BD09")
private String geoCoordSys;

View File

@@ -9,9 +9,15 @@ import java.util.List;
@Schema(description = "多边形检索摄像头参数")
public class PolygonQueryParam {
@Schema(description = "多边形位置,格式: [{'lng':116.32, 'lat': 39: 39.2}, {'lng':115.32, 'lat': 39: 38.2}, {'lng':125.32, 'lat': 39: 38.2}]")
private List<Point> position;
@Schema(description = "地图级别")
private Integer level;
@Schema(description = "分组别名")
private String groupAlias;
private String topGroupAlias;
@Schema(description = "坐标系类型WGS84,GCJ02、BD09")
private String geoCoordSys;
}

View File

@@ -19,6 +19,8 @@ import com.genersoft.iot.vmp.utils.Coordtransform;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.web.custom.bean.CameraChannel;
import com.genersoft.iot.vmp.web.custom.bean.CameraGroup;
import com.genersoft.iot.vmp.web.custom.bean.Point;
import com.genersoft.iot.vmp.web.custom.bean.PolygonQueryParam;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.core.util.Assert;
@@ -166,7 +168,7 @@ public class CameraChannelService implements CommandLineRunner {
}
public CameraChannel queryOne(String deviceId, String deviceCode, String geoCoordSys) {
CommonGBChannel channel = channelMapper.queryGbChannelByChannelDeviceIdAndGbDeviceId(deviceId, deviceCode);
CameraChannel channel = channelMapper.queryGbChannelByChannelDeviceIdAndGbDeviceId(deviceId, deviceCode);
Assert.notNull(channel, "通道不存在");
if (geoCoordSys != null && channel.getGbLongitude() != null && channel.getGbLatitude() != null
@@ -182,11 +184,10 @@ public class CameraChannelService implements CommandLineRunner {
channel.setGbLatitude(position[1]);
}
}
CameraChannel resultChannel = (CameraChannel)channel;
if (deviceCode != null) {
resultChannel.setDeviceCode(deviceCode);
channel.setDeviceCode(deviceCode);
}
return resultChannel;
return channel;
}
/**
@@ -294,10 +295,103 @@ public class CameraChannelService implements CommandLineRunner {
channelMapper.update(commonGBChannel);
}
public List<CameraChannel> queryListByDeviceIds(List<String> deviceIds) {
return channelMapper.queryListByDeviceIds(deviceIds);
public List<CameraChannel> queryListByDeviceIds(List<String> deviceIds, String geoCoordSys) {
List<CameraChannel> cameraChannels = channelMapper.queryListByDeviceIds(deviceIds);
return addIconPathAndPositionForCameraChannelList(cameraChannels, geoCoordSys);
}
public List<CameraChannel> queryListByAddressAndDirectionType(String address, Integer directionType, String geoCoordSys) {
List<CameraChannel> cameraChannels = channelMapper.queryListByAddressAndDirectionType(address, directionType);
return addIconPathAndPositionForCameraChannelList(cameraChannels, geoCoordSys);
}
public List<CameraChannel> queryListInBox(Double minLongitude, Double maxLongitude, Double minLatitude, Double maxLatitude, Integer level, String groupAlias, String geoCoordSys) {
// 构建组织结构信息
CameraGroup group = groupMapper.queryGroupByAlias(groupAlias);
Assert.notNull(group, "获取组织结构失败");
// 获取所有子节点
List<CameraGroup> groupList = queryAllGroupChildren(group.getId(), group.getBusinessGroup());
groupList.add(group);
// 参数坐标系列转换
if (geoCoordSys != null) {
if (geoCoordSys.equalsIgnoreCase("GCJ02")) {
Double[] minPosition = Coordtransform.WGS84ToGCJ02(minLongitude, minLatitude);
minLongitude = minPosition[0];
minLatitude = minPosition[1];
Double[] maxPosition = Coordtransform.WGS84ToGCJ02(maxLongitude, maxLatitude);
maxLongitude = maxPosition[0];
maxLatitude = maxPosition[1];
}else if (geoCoordSys.equalsIgnoreCase("BD09")) {
Double[] gcj02MinPosition = Coordtransform.WGS84ToGCJ02(minLongitude, minLatitude);
Double[] minPosition = Coordtransform.GCJ02ToBD09(gcj02MinPosition[0], gcj02MinPosition[1]);
minLongitude = minPosition[0];
minLatitude = minPosition[1];
Double[] gcj02MaxPosition = Coordtransform.WGS84ToGCJ02(maxLongitude, maxLatitude);
Double[] maxPosition = Coordtransform.GCJ02ToBD09(gcj02MaxPosition[0], gcj02MaxPosition[1]);
maxLongitude = maxPosition[0];
maxLatitude = maxPosition[1];
}
}
List<CameraChannel> all = channelMapper.queryListInBox(minLongitude, maxLongitude, minLatitude, maxLatitude, level, groupList);
return addIconPathAndPositionForCameraChannelList(all, geoCoordSys);
}
public List<CameraChannel> queryListInCircle(Double centerLongitude, Double centerLatitude, Double radius, Integer level, String groupAlias, String geoCoordSys) {
// 构建组织结构信息
CameraGroup group = groupMapper.queryGroupByAlias(groupAlias);
Assert.notNull(group, "获取组织结构失败");
// 获取所有子节点
List<CameraGroup> groupList = queryAllGroupChildren(group.getId(), group.getBusinessGroup());
groupList.add(group);
// 参数坐标系列转换
if (geoCoordSys != null) {
if (geoCoordSys.equalsIgnoreCase("GCJ02")) {
Double[] position = Coordtransform.WGS84ToGCJ02(centerLongitude, centerLatitude);
centerLongitude = position[0];
centerLatitude = position[1];
}else if (geoCoordSys.equalsIgnoreCase("BD09")) {
Double[] gcj02Position = Coordtransform.WGS84ToGCJ02(centerLongitude, centerLatitude);
Double[] position = Coordtransform.GCJ02ToBD09(gcj02Position[0], gcj02Position[1]);
centerLongitude = position[0];
centerLatitude = position[1];
}
}
List<CameraChannel> all = channelMapper.queryListInCircle(centerLongitude, centerLatitude, radius, level, groupList);
return addIconPathAndPositionForCameraChannelList(all, geoCoordSys);
}
public List<CameraChannel> queryListInPolygon(List<Point> pointList, String groupAlias, Integer level, String geoCoordSys) {
// 构建组织结构信息
CameraGroup group = groupMapper.queryGroupByAlias(groupAlias);
Assert.notNull(group, "获取组织结构失败");
// 获取所有子节点
List<CameraGroup> groupList = queryAllGroupChildren(group.getId(), group.getBusinessGroup());
groupList.add(group);
// 参数坐标系列转换
if (geoCoordSys != null) {
for (Point point : pointList) {
if (geoCoordSys.equalsIgnoreCase("GCJ02")) {
Double[] position = Coordtransform.WGS84ToGCJ02(point.getLng(), point.getLat());
point.setLng(position[0]);
point.setLat(position[1]);
}else if (geoCoordSys.equalsIgnoreCase("BD09")) {
Double[] gcj02Position = Coordtransform.WGS84ToGCJ02(point.getLng(), point.getLat());
Double[] position = Coordtransform.GCJ02ToBD09(gcj02Position[0], gcj02Position[1]);
point.setLng(position[0]);
point.setLat(position[1]);
}
}
}
List<CameraChannel> all = channelMapper.queryListInPolygon(pointList, level, groupList);
return addIconPathAndPositionForCameraChannelList(all, geoCoordSys);
}
}