This commit is contained in:
sulu 2023-11-19 17:06:38 +08:00
parent fd6a30d064
commit 75da53f3c6
28 changed files with 804 additions and 4116 deletions

46
.drone.yml Normal file
View File

@ -0,0 +1,46 @@
kind: pipeline
type: docker
name: autoDispatchDeploy
steps:
# 项目打包并发布
- name: autoDispatchBuild
pull: if-not-exists
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- cd AutoDispathingWork
- dotnet publish -c Release -o ../release
- name: push
image: plugins/docker
pull: if-not-exists
depends_on: [ autoDispatchBuild ]
settings:
dockerfile: ./AutoDispathingWork/Dockerfile
username:
from_secret: local_registry_username
password:
from_secret: local_registry_password
tags:
- latest
registry: 192.168.100.10:5000
insecure: true
repo: 192.168.100.10:5000/autodispatch/web
- name: deploy
image: appleboy/drone-ssh
depends_on: [ ZhiLiaoWebApiBuild,ZhiLiaoWebApiPush ]
settings:
host:
from_secret: server_host
user:
from_secret: server_username
password:
from_secret: server_password
port: 22
command_timeout: 2m
script:
- docker stop autodispatch
- docker rm autodispatch
- docker rmi 121.4.75.240:5000/autodispatch/web
- docker pull 121.4.75.240:5000/autodispatch/web
- docker run -d --name autodispatch -p 88:80 121.4.75.240:5000/autodispatch/web

View File

@ -4,6 +4,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoDispatching", "AutoDisp
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoDispathingWork", "AutoDispathingWork\AutoDispathingWork.csproj", "{39E15372-E957-4785-ABE7-D160ECC6440C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoDispathingWork", "AutoDispathingWork\AutoDispathingWork.csproj", "{39E15372-E957-4785-ABE7-D160ECC6440C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject1", "TestProject1\TestProject1.csproj", "{0826BC27-E113-40D1-8074-5CEC89B1C934}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4C15AA6B-6940-4D5F-90F8-56FE0D3886AC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E543FEBD-A632-490C-96B5-78E91BF2BC82}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "devops", "devops", "{E0EBE80F-EB42-4C22-995B-33A082D963CF}"
ProjectSection(SolutionItems) = preProject
.drone.yml = .drone.yml
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -18,5 +29,14 @@ Global
{39E15372-E957-4785-ABE7-D160ECC6440C}.Debug|Any CPU.Build.0 = Debug|Any CPU {39E15372-E957-4785-ABE7-D160ECC6440C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39E15372-E957-4785-ABE7-D160ECC6440C}.Release|Any CPU.ActiveCfg = Release|Any CPU {39E15372-E957-4785-ABE7-D160ECC6440C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39E15372-E957-4785-ABE7-D160ECC6440C}.Release|Any CPU.Build.0 = Release|Any CPU {39E15372-E957-4785-ABE7-D160ECC6440C}.Release|Any CPU.Build.0 = Release|Any CPU
{0826BC27-E113-40D1-8074-5CEC89B1C934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0826BC27-E113-40D1-8074-5CEC89B1C934}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0826BC27-E113-40D1-8074-5CEC89B1C934}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0826BC27-E113-40D1-8074-5CEC89B1C934}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2C965E22-EBA5-4F50-A979-C11AD28B61B2} = {4C15AA6B-6940-4D5F-90F8-56FE0D3886AC}
{39E15372-E957-4785-ABE7-D160ECC6440C} = {4C15AA6B-6940-4D5F-90F8-56FE0D3886AC}
{0826BC27-E113-40D1-8074-5CEC89B1C934} = {E543FEBD-A632-490C-96B5-78E91BF2BC82}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,4 +1,5 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using WorkerService1.Domains;
using WorkerService1.Dto.Configuration; using WorkerService1.Dto.Configuration;
using WorkerService1.Services; using WorkerService1.Services;
@ -22,6 +23,9 @@ public class CloseWorker : BackgroundService
{ {
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{ {
using var scope = _serviceProvider.CreateScope();
var settingServices = scope.ServiceProvider.GetRequiredService<SettingServices>();
var options = settingServices.GetClientOptions();
if (_logger.IsEnabled(LogLevel.Information)) if (_logger.IsEnabled(LogLevel.Information))
{ {
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
@ -29,17 +33,16 @@ public class CloseWorker : BackgroundService
try try
{ {
await Handle(); if (options.CloseFileRunning)
await Handle();
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError("执行控制器发生错误,错误信息:ex{}", e.StackTrace); $"执行控制器发生错误,错误信息:ex{e.StackTrace}".Error();
} }
finally finally
{ {
using var scope = _serviceProvider.CreateScope(); await Task.Delay(options.Delay, stoppingToken);
var options = scope.ServiceProvider.GetRequiredService<IOptionsMonitor<ClientOptions>>();
await Task.Delay(options.CurrentValue.Delay, stoppingToken);
} }
} }
} }
@ -57,6 +60,16 @@ public class CloseWorker : BackgroundService
{ {
//2.结案操作 //2.结案操作
var result = await _spiderServices.CloseFile(item.caseNumber, ""); var result = await _spiderServices.CloseFile(item.caseNumber, "");
if (result.IsSuccess)
{
var message = $"结案成功,任务编号:{item.caseNumber},任务地址:{item.address},任务类型:{item.typeCode}";
message.Info();
}
else
{
var message = $"结案失败,错误信息:{result.Message}";
message.Error();
}
} }
} }
} }

View File

@ -3,6 +3,7 @@ using LiteDB;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using WorkerService1.Domains; using WorkerService1.Domains;
using WorkerService1.Dto; using WorkerService1.Dto;
using WorkerService1.Dto.Configuration;
using WorkerService1.Dto.QueryRequest; using WorkerService1.Dto.QueryRequest;
using WorkerService1.Dto.QueryResponse; using WorkerService1.Dto.QueryResponse;
using WorkerService1.Services; using WorkerService1.Services;
@ -34,18 +35,16 @@ public class UserController : ControllerBase
var polygon = db.GetCollection<Polygon>(); var polygon = db.GetCollection<Polygon>();
var result = polygon.FindAll().ToList(); var result = polygon.FindAll().ToList();
var cameras = await spiderServices.GetCameras(); var cameras = await spiderServices.GetCameras();
var cameraLocation = cameras.Result?.Records.Select(x => (x.name, Location: new Points(x.lon, x.lat)))
.ToList();
foreach (var item in result) foreach (var item in result)
{ {
// item.RangeCameras ??= new List<string>(); if (cameraLocation == null) continue;
foreach (var x in cameras.Result?.Records.Select(x => foreach (var (camera, location) in cameraLocation)
{
var tempGps = GpsUtil.Bd09ToGcj02(x.lon, x.lat);
return (x.name, new Points(tempGps[0], tempGps[1]));
}).ToList()!.Where(x => x.Item2.IsPointInsidePolygon(item))!)
{ {
if (!location.IsPointInsidePolygon(item)) continue;
item.RangeCameras ??= new List<string>(); item.RangeCameras ??= new List<string>();
item.RangeCameras?.Add(x.name); item.RangeCameras?.Add(camera);
} }
} }
@ -124,11 +123,12 @@ public class UserController : ControllerBase
[HttpPut("/api/Polygon/{polygonId}/UserId/{userId}")] [HttpPut("/api/Polygon/{polygonId}/UserId/{userId}")]
public SpiderResponse<bool> BindPolygonUserId([FromRoute] Guid polygonId, [FromRoute] string userId, public async Task<SpiderResponse<bool>> BindPolygonUserId([FromRoute] Guid polygonId, [FromRoute] string userId,
[FromServices] LiteDatabase db) [FromServices] LiteDatabase db, [FromServices] SpiderServices spiderServices)
{ {
var polygon = db.GetCollection<Polygon>(); var polygon = db.GetCollection<Polygon>();
var result = polygon.FindOne(x => x.PolygonId == polygonId); var result = polygon.FindOne(x => x.PolygonId == polygonId);
if (result == null) if (result == null)
{ {
return new SpiderResponse<bool>() return new SpiderResponse<bool>()
@ -137,7 +137,20 @@ public class UserController : ControllerBase
}; };
} }
var user = await spiderServices.GetUsers(new UserQuery()
{
Condition =
{
Id = userId
}
});
result.UserId = userId; result.UserId = userId;
var currentUser = user.Result?.Records.FirstOrDefault();
if (currentUser != null)
{
result.UserName = currentUser.UserRealName;
}
polygon.Update(result); polygon.Update(result);
return new SpiderResponse<bool>() return new SpiderResponse<bool>()
{ {
@ -195,4 +208,60 @@ public class UserController : ControllerBase
{ {
return await spiderServices.GetCameras(); return await spiderServices.GetCameras();
} }
[HttpGet("/api/Setting")]
public SpiderResponse<ClientOptions> GetClientOptions([FromServices] SettingServices settingServices)
{
return new SpiderResponse<ClientOptions>()
{
IsSuccess = true, Code = SpiderResponseCode.Success, Message = "获取配置成功",
Result = settingServices.GetClientOptions()
};
}
[HttpPost("/api/Setting")]
public SpiderResponse<ClientOptions> SettingClientOptions([FromBody] ClientOptionsReq options,
[FromServices] SettingServices settingServices)
{
var setting = settingServices.GetClientOptions();
setting.Delay = options.Delay;
setting.DispatchingRunning = options.DispatchingRunning;
setting.CloseFileRunning = options.CloseFileRunning;
setting.ApiGateway = options.ApiGateway;
if (!string.IsNullOrWhiteSpace(options.UserName))
setting.UserName = options.UserName;
if (!string.IsNullOrWhiteSpace(options.Password))
setting.Password = options.Password;
var resp = settingServices.SettingClientOptions(setting);
return new SpiderResponse<ClientOptions>()
{
IsSuccess = true, Code = SpiderResponseCode.Success, Message = "获取配置成功",
Result = settingServices.SettingClientOptions(resp)
};
}
[HttpGet("/api/Log")]
public SpiderResponse<PageResponse<LogInfo>> GetLog([FromQuery] PageRequest request, [FromServices] LiteDatabase db)
{
var collection = db.GetCollection<LogInfo>();
var logs = collection.Query()
.OrderByDescending(x => x.CreateTime)
.Skip((request.Page - 1) * request.PageSize)
.Limit(request.PageSize)
.ToList();
var total = collection.Count();
return new SpiderResponse<PageResponse<LogInfo>>()
{
IsSuccess = true, Code = SpiderResponseCode.Success, Message = "获取日志成功",
Result = new PageResponse<LogInfo>()
{
Data = logs.ToList(),
Page = request.Page,
PageSize = request.PageSize,
Total = total
}
};
}
} }

Binary file not shown.

Binary file not shown.

View File

@ -1,18 +1,7 @@
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base 
FROM 192.168.100.10:5000/dotnet/aspnet:8.0 AS base
WORKDIR /app WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build EXPOSE 443
WORKDIR /src COPY ./release .
COPY ["WorkerService1/WorkerService1.csproj", "WorkerService1/"] ENTRYPOINT ["dotnet", "AutoDispathingWork.dll"]
RUN dotnet restore "WorkerService1/WorkerService1.csproj"
COPY . .
WORKDIR "/src/WorkerService1"
RUN dotnet build "WorkerService1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WorkerService1.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WorkerService1.dll"]

View File

@ -0,0 +1,70 @@
using System.Runtime.CompilerServices;
using AutoDispathingWork.Utils;
using LiteDB;
namespace WorkerService1.Domains;
public class LogInfo
{
public LogInfo()
{
}
public LogInfo(string level, string message, [CallerMemberName] string from = "")
{
Id = Guid.NewGuid();
CreateTime = DateTime.Now;
Message = message;
Level = level;
From = from;
}
public Guid Id { get; set; }
public string Message { get; set; }
public string From { get; set; }
public string Level { get; set; }
public DateTime CreateTime { get; set; }
}
public static class LogInfoExtensions
{
public static LogInfo Info(this string message, [CallerMemberName] string from = "")
{
var logger = StaticServiceProvider.GetLogger(from);
logger.LogInformation(message);
var db = StaticServiceProvider.GetLogDb();
var log = new LogInfo("Info", message, from);
db.Insert(log);
return log;
}
public static LogInfo Error(this string message, [CallerMemberName] string from = "")
{
var logger = StaticServiceProvider.GetLogger(from);
logger.LogError(message);
var db = StaticServiceProvider.GetLogDb();
var log = new LogInfo("Error", message, from);
db.Insert(log);
return log;
}
public static LogInfo Warning(this string message, [CallerMemberName] string from = "")
{
var logger = StaticServiceProvider.GetLogger(from);
logger.LogWarning(message);
var db = StaticServiceProvider.GetLogDb();
var log = new LogInfo("Warning", message, from);
db.Insert(log);
return log;
}
public static LogInfo Debug(this string message, [CallerMemberName] string from = "")
{
var logger = StaticServiceProvider.GetLogger(from);
logger.LogDebug(message);
var db = StaticServiceProvider.GetLogDb();
var log = new LogInfo("Debug", message, from);
db.Insert(log);
return log;
}
}

View File

@ -5,6 +5,7 @@ public class Polygon
public Guid? PolygonId { get; set; } public Guid? PolygonId { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string? UserId { get; set; } public string? UserId { get; set; }
public string? UserName { get; set; }
public List<List<Points>>? Points { get; set; } public List<List<Points>>? Points { get; set; }
public List<string>? RangeCameras { get; set; } = new List<string>(); public List<string>? RangeCameras { get; set; } = new List<string>();
@ -21,3 +22,16 @@ public struct Points
public double Y { get; set; } public double Y { get; set; }
} }
public struct CameraLocation
{
public CameraLocation(string name, double x, double y)
{
Name = name;
X = x;
Y = y;
}
public string Name { get; set; }
public double X { get; set; }
public double Y { get; set; }
}

View File

@ -7,8 +7,11 @@ public class ClientOptions
public string ApiGateway { get; set; } = "http://121.4.75.240/"; public string ApiGateway { get; set; } = "http://121.4.75.240/";
[JsonPropertyName("username")] [JsonPropertyName("username")]
public string UserName { get; set; } = "ganquanjiedao"; public string UserName { get; set; } = "ganquanjiedao";
[JsonPropertyName("password")]
public string Password { get; set; } = "12345678a"; public string Password { get; set; } = "12345678a";
public int Delay { get; set; } = 1000; public int Delay { get; set; } = 1000;
public bool DispatchingRunning { get; set; } = false;
public bool CloseFileRunning { get; set; } = false;
public string LoginApi { get; set; } = "api/auth/v5/users/login"; public string LoginApi { get; set; } = "api/auth/v5/users/login";
public string GetTaskApi { get; set; } = "api/megcity/v1/events/queryByWaterFall"; public string GetTaskApi { get; set; } = "api/megcity/v1/events/queryByWaterFall";

View File

@ -0,0 +1,11 @@
namespace WorkerService1.Dto.Configuration;
public class ClientOptionsReq
{
public string ApiGateway { get; set; } = "http://121.4.75.240/";
public string UserName { get; set; } = "ganquanjiedao";
public string Password { get; set; } = "12345678a";
public int Delay { get; set; }
public bool DispatchingRunning { get; set; } = false;
public bool CloseFileRunning { get; set; } = false;
}

View File

@ -2,4 +2,7 @@
public class PageRequest public class PageRequest
{ {
public int Page { get; set; }
public int PageSize { get; set; }
} }

View File

@ -10,7 +10,7 @@ public class DispatchReq
[JsonPropertyName("target")] [JsonPropertyName("target")]
public int Target { get; set; } = 2; public int Target { get; set; } = 2;
[JsonPropertyName("handlerId")] [JsonPropertyName("handlerId")]
public string HandlerId { get; set; } = "66fa9261-16f6-49aa-a391-5848f40301e0"; public string? HandlerId { get; set; } = "66fa9261-16f6-49aa-a391-5848f40301e0";
[JsonPropertyName("typeCode")] [JsonPropertyName("typeCode")]
public string TypeCode { get; set; } = "A2-01-10"; public string TypeCode { get; set; } = "A2-01-10";
} }

View File

@ -20,5 +20,7 @@ public class Condition
{ {
[JsonPropertyName("roleIds")] [JsonPropertyName("roleIds")]
public string[] RoleIds { get; set; } = new string[] { "a2e267c0-d88d-4ecb-a4b5-d904e85dfbb6" }; public string[] RoleIds { get; set; } = new string[] { "a2e267c0-d88d-4ecb-a4b5-d904e85dfbb6" };
[JsonPropertyName("id")]
public string? Id { get; set; }
} }

View File

@ -0,0 +1,130 @@
namespace WorkerService1.Dto.QueryResponse;
public class CameraItem
{
public CameraItem(bool alarmShortVideo, string bodyAnalyze, bool closed, string deptId, string deptName,
string faceAnalyze, string gaPlatformDeviceId, string gaPlatformId, string gbPlatformDeviceId, string gbPlatformId,
string id, List<string> labelCodes, List<string> labels, double lat, string location, double lon, bool lowQuality,
string managementId, string managementName, int manufacturer, int monitoringType, string motorVehicleAnalyze,
string name, string nonMotorVehicleAnalyze, string numeration, bool optPermissions, List<string> placeIds,
bool policeNet, bool pulled, int rainbowStatus, string roi, List<string> rois, string sncode, int status,
string systemType, int type, bool vlowQuality)
{
this.alarmShortVideo = alarmShortVideo;
this.bodyAnalyze = bodyAnalyze;
this.closed = closed;
this.deptId = deptId;
this.deptName = deptName;
this.faceAnalyze = faceAnalyze;
this.gaPlatformDeviceId = gaPlatformDeviceId;
this.gaPlatformId = gaPlatformId;
this.gbPlatformDeviceId = gbPlatformDeviceId;
this.gbPlatformId = gbPlatformId;
this.id = id;
this.labelCodes = labelCodes;
this.labels = labels;
this.lat = lat;
this.location = location;
this.lon = lon;
this.lowQuality = lowQuality;
this.managementId = managementId;
this.managementName = managementName;
this.manufacturer = manufacturer;
this.monitoringType = monitoringType;
this.motorVehicleAnalyze = motorVehicleAnalyze;
this.name = name;
this.nonMotorVehicleAnalyze = nonMotorVehicleAnalyze;
this.numeration = numeration;
this.optPermissions = optPermissions;
this.placeIds = placeIds;
this.policeNet = policeNet;
this.pulled = pulled;
this.rainbowStatus = rainbowStatus;
this.roi = roi;
this.rois = rois;
this.sncode = sncode;
this.status = status;
this.systemType = systemType;
this.type = type;
this.vlowQuality = vlowQuality;
}
public bool alarmShortVideo { get; set; }
public string bodyAnalyze { get; set; }
public bool closed { get; set; }
public string deptId { get; set; }
public string deptName { get; set; }
public string faceAnalyze { get; set; }
public string gaPlatformDeviceId { get; set; }
public string gaPlatformId { get; set; }
public string gbPlatformDeviceId { get; set; }
public string gbPlatformId { get; set; }
public string id { get; set; }
public List<string> labelCodes { get; set; }
public List<string> labels { get; set; }
public double lat { get; set; }
public string location { get; set; }
public double lon { get; set; }
public bool lowQuality { get; set; }
public string managementId { get; set; }
public string managementName { get; set; }
public int manufacturer { get; set; }
public int monitoringType { get; set; }
public string motorVehicleAnalyze { get; set; }
public string name { get; set; }
public string nonMotorVehicleAnalyze { get; set; }
public string numeration { get; set; }
public bool optPermissions { get; set; }
public List<string> placeIds { get; set; }
public bool policeNet { get; set; }
public bool pulled { get; set; }
public int rainbowStatus { get; set; }
public string roi { get; set; }
public List<string> rois { get; set; }
public string sncode { get; set; }
public int status { get; set; }
public string systemType { get; set; }
public int type { get; set; }
public bool vlowQuality { get; set; }
public void Deconstruct(out bool alarmShortVideo, out string bodyAnalyze, out bool closed, out string deptId, out string deptName, out string faceAnalyze, out string gaPlatformDeviceId, out string gaPlatformId, out string gbPlatformDeviceId, out string gbPlatformId, out string id, out List<string> labelCodes, out List<string> labels, out double lat, out string location, out double lon, out bool lowQuality, out string managementId, out string managementName, out int manufacturer, out int monitoringType, out string motorVehicleAnalyze, out string name, out string nonMotorVehicleAnalyze, out string numeration, out bool optPermissions, out List<string> placeIds, out bool policeNet, out bool pulled, out int rainbowStatus, out string roi, out List<string> rois, out string sncode, out int status, out string systemType, out int type, out bool vlowQuality)
{
alarmShortVideo = this.alarmShortVideo;
bodyAnalyze = this.bodyAnalyze;
closed = this.closed;
deptId = this.deptId;
deptName = this.deptName;
faceAnalyze = this.faceAnalyze;
gaPlatformDeviceId = this.gaPlatformDeviceId;
gaPlatformId = this.gaPlatformId;
gbPlatformDeviceId = this.gbPlatformDeviceId;
gbPlatformId = this.gbPlatformId;
id = this.id;
labelCodes = this.labelCodes;
labels = this.labels;
lat = this.lat;
location = this.location;
lon = this.lon;
lowQuality = this.lowQuality;
managementId = this.managementId;
managementName = this.managementName;
manufacturer = this.manufacturer;
monitoringType = this.monitoringType;
motorVehicleAnalyze = this.motorVehicleAnalyze;
name = this.name;
nonMotorVehicleAnalyze = this.nonMotorVehicleAnalyze;
numeration = this.numeration;
optPermissions = this.optPermissions;
placeIds = this.placeIds;
policeNet = this.policeNet;
pulled = this.pulled;
rainbowStatus = this.rainbowStatus;
roi = this.roi;
rois = this.rois;
sncode = this.sncode;
status = this.status;
systemType = this.systemType;
type = this.type;
vlowQuality = this.vlowQuality;
}
}

View File

@ -44,10 +44,3 @@ public class CameraResponse: KSResponse<PageData<CameraItem>>
// "type": 1, // "type": 1,
// "vlowQuality": false // "vlowQuality": false
// } // }
public record CameraItem(bool alarmShortVideo, string bodyAnalyze, bool closed, string deptId, string deptName,
string faceAnalyze, string gaPlatformDeviceId, string gaPlatformId, string gbPlatformDeviceId, string gbPlatformId,
string id, List<string> labelCodes, List<string> labels, double lat, string location, double lon, bool lowQuality,
string managementId, string managementName, int manufacturer, int monitoringType, string motorVehicleAnalyze,
string name, string nonMotorVehicleAnalyze, string numeration, bool optPermissions, List<string> placeIds,
bool policeNet, bool pulled, int rainbowStatus, string roi, List<string> rois, string sncode, int status,
string systemType, int type, bool vlowQuality);

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
using AutoDispathingWork.Utils;
using LiteDB; using LiteDB;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using WorkerService1; using WorkerService1;
@ -34,18 +35,20 @@ builder.Services.AddMemoryCache();
builder.Services.AddLogging(); builder.Services.AddLogging();
// builder.Services.AddMvcCore(); // builder.Services.AddMvcCore();
builder.Services.AddSingleton<SpiderServices>(); builder.Services.AddSingleton<SpiderServices>();
#if !DEBUG builder.Services.AddScoped<SettingServices>();
// #if !DEBUG
builder.Services.AddHostedService<Worker>(); builder.Services.AddHostedService<Worker>();
builder.Services.AddHostedService<CloseWorker>(); builder.Services.AddHostedService<CloseWorker>();
#endif // #endif
var app = builder.Build(); var app = builder.Build();
StaticServiceProvider.SetServiceProvider(app.Services);
app.UseCors("AllowAllOrigin"); app.UseCors("AllowAllOrigin");
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
app.MapControllers(); app.MapControllers();
app.Urls.Add("http://*:80");
app.Run(); app.Run();

View File

@ -0,0 +1,42 @@
using LiteDB;
using Microsoft.Extensions.Options;
using WorkerService1.Dto.Configuration;
namespace WorkerService1.Services;
public class SettingServices
{
private readonly IOptionsMonitor<ClientOptions> _optionsMonitor;
private readonly LiteDatabase _db;
public SettingServices(IOptionsMonitor<ClientOptions> optionsMonitor, LiteDatabase db)
{
_optionsMonitor = optionsMonitor;
_db = db;
}
public void Reset()
{
SettingClientOptions(_optionsMonitor.CurrentValue);
}
public ClientOptions GetClientOptions()
{
var clientOptions = _db.GetCollection<ClientOptions>();
var dbOptions = clientOptions.FindAll().FirstOrDefault();
if (dbOptions != null)
{
return dbOptions;
}
return _optionsMonitor.CurrentValue;
}
public ClientOptions SettingClientOptions(ClientOptions options)
{
var clientOptions = _db.GetCollection<ClientOptions>();
clientOptions.DeleteAll();
clientOptions.Insert(options);
return options;
}
}

View File

@ -1,12 +1,17 @@
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text; using System.Text;
using System.Text.Json; using AutoDispathingWork.Utils;
using LiteDB;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using WorkerService1.Domains;
using WorkerService1.Dto; using WorkerService1.Dto;
using WorkerService1.Dto.Configuration; using WorkerService1.Dto.Configuration;
using WorkerService1.Dto.QueryRequest; using WorkerService1.Dto.QueryRequest;
using WorkerService1.Dto.QueryResponse; using WorkerService1.Dto.QueryResponse;
using WorkerService1.Utils;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Utilities = WorkerService1.Utils.Utilities;
namespace WorkerService1.Services; namespace WorkerService1.Services;
@ -31,13 +36,19 @@ public class SpiderServices
private IOptionsMonitor<ClientOptions> OptionsMonitor => _serviceProvider.CreateScope().ServiceProvider private IOptionsMonitor<ClientOptions> OptionsMonitor => _serviceProvider.CreateScope().ServiceProvider
.GetRequiredService<IOptionsMonitor<ClientOptions>>(); .GetRequiredService<IOptionsMonitor<ClientOptions>>();
private ClientOptions GetClientOptions => _serviceProvider.CreateScope().ServiceProvider
.GetRequiredService<SettingServices>()
.GetClientOptions();
private LiteDatabase GetLiteDatabase => _serviceProvider
.GetRequiredService<LiteDatabase>();
public async Task<SpiderResponse<LoginResultData>> Login() public async Task<SpiderResponse<LoginResultData>> Login()
{ {
using var client = _httpClientFactory.CreateClient(); using var client = _httpClientFactory.CreateClient();
var loginApi = OptionsMonitor.CurrentValue.LoginUrl; var loginApi = GetClientOptions.LoginUrl;
var json = $@" var json = $@"
{{""userName"":""{_optionsMonitor.CurrentValue.UserName}"",""userPwd"":""{_optionsMonitor.CurrentValue.Password}"",""type"":""account"",""clientAppId"":""megcity-web""}} {{""userName"":""{GetClientOptions.UserName}"",""userPwd"":""{GetClientOptions.Password}"",""type"":""account"",""clientAppId"":""megcity-web""}}
"; ";
client.DefaultRequestHeaders.Add("Module-Alias", "pending-forward"); client.DefaultRequestHeaders.Add("Module-Alias", "pending-forward");
client.DefaultRequestHeaders.Add("Module-Source", "megcity-web"); client.DefaultRequestHeaders.Add("Module-Source", "megcity-web");
@ -118,7 +129,7 @@ public class SpiderServices
// {"state":[3],"pageNo":1,"pageSize":50,"sortType":[40,10],"handleStartTime":1697293650750,"handleEndTime":1699885650750} // {"state":[3],"pageNo":1,"pageSize":50,"sortType":[40,10],"handleStartTime":1697293650750,"handleEndTime":1699885650750}
// {"state":[1],"pageNo":1,"pageSize":50,"sortType":[20,10],"createStartTime":1697290618034,"createEndTime":1699882618034} // {"state":[1],"pageNo":1,"pageSize":50,"sortType":[20,10],"createStartTime":1697290618034,"createEndTime":1699882618034}
// {\"state\":[1],\"pageNo\":1,\"pageSize\":50,\"sortType\":[20,10],\"createStartTime\":1697204639551,\"createEndTime\":1697204639551} // {\"state\":[1],\"pageNo\":1,\"pageSize\":50,\"sortType\":[20,10],\"createStartTime\":1697204639551,\"createEndTime\":1697204639551}
var taskPath = OptionsMonitor.CurrentValue.GetTaskUrl; var taskPath = GetClientOptions.GetTaskUrl;
var response = await client.PostAsync(taskPath, var response = await client.PostAsync(taskPath,
new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")); new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json"));
var respJsonStr = await response.Content.ReadAsStringAsync(); var respJsonStr = await response.Content.ReadAsStringAsync();
@ -161,7 +172,7 @@ public class SpiderServices
client.DefaultRequestHeaders.Add("module-alias", "pending-forward"); client.DefaultRequestHeaders.Add("module-alias", "pending-forward");
client.DefaultRequestHeaders.Add("module-source", "megcity-web"); client.DefaultRequestHeaders.Add("module-source", "megcity-web");
var request = query ?? new UserQuery(); var request = query ?? new UserQuery();
var userPath = OptionsMonitor.CurrentValue.GetUserUrl; var userPath = GetClientOptions.GetUserUrl;
var response = await client.PostAsync(userPath, var response = await client.PostAsync(userPath,
new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json")); new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"));
var respJsonStr = await response.Content.ReadAsStringAsync(); var respJsonStr = await response.Content.ReadAsStringAsync();
@ -194,7 +205,7 @@ public class SpiderServices
//{"acceptTypeCode":"A2-01-10","target":2,"handlerId":"66fa9261-16f6-49aa-a391-5848f40301e0","typeCode":"A2-01-10"} //{"acceptTypeCode":"A2-01-10","target":2,"handlerId":"66fa9261-16f6-49aa-a391-5848f40301e0","typeCode":"A2-01-10"}
//{ "code": 0, "msg": "SUCCESS", "data": {} } //{ "code": 0, "msg": "SUCCESS", "data": {} }
public async Task<SpiderResponse<object>> DispatchTask(string caseNumber, string handlerId, string typeCode) public async Task<SpiderResponse<object>> DispatchTask(string caseNumber, string cameraName, string typeCode)
{ {
var token = await GetToken(); var token = await GetToken();
using var client = _httpClientFactory.CreateClient(); using var client = _httpClientFactory.CreateClient();
@ -203,6 +214,19 @@ public class SpiderServices
client.DefaultRequestHeaders.Add("client-app-id", "megcity-web"); client.DefaultRequestHeaders.Add("client-app-id", "megcity-web");
client.DefaultRequestHeaders.Add("module-alias", "pending-forward"); client.DefaultRequestHeaders.Add("module-alias", "pending-forward");
client.DefaultRequestHeaders.Add("module-source", "megcity-web"); client.DefaultRequestHeaders.Add("module-source", "megcity-web");
var (handlerId, userRealName) = await GetUserIdByCamera(cameraName);
if (string.IsNullOrWhiteSpace(handlerId))
{
return new SpiderResponse<object>()
{
IsSuccess = false,
Result = null,
Code = SpiderResponseCode.Fail,
Message = $"分发任务失败, 案件编号:{caseNumber}, 未找到摄像头:{cameraName}对应的处理人员"
};
}
var request = new DispatchReq var request = new DispatchReq
{ {
AcceptTypeCode = typeCode, AcceptTypeCode = typeCode,
@ -210,7 +234,7 @@ public class SpiderServices
HandlerId = handlerId, HandlerId = handlerId,
TypeCode = typeCode TypeCode = typeCode
}; };
var dispatchPath = string.Format(OptionsMonitor.CurrentValue.DiposeOrderUrl, caseNumber); var dispatchPath = string.Format(GetClientOptions.DiposeOrderUrl, caseNumber);
var response = await client.PostAsync(dispatchPath, var response = await client.PostAsync(dispatchPath,
new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json")); new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"));
@ -222,7 +246,8 @@ public class SpiderServices
{ {
if (spiderRes?.code == 0) if (spiderRes?.code == 0)
{ {
_logger.LogInformation("成功分发任务"); var msg = $"成功分发任务,任务编号:{caseNumber},任务地址:{cameraName},任务类型:{typeCode},处理人:{userRealName}";
_logger.LogInformation(msg);
return new SpiderResponse<object>() return new SpiderResponse<object>()
{ {
@ -259,7 +284,7 @@ public class SpiderServices
//Region为请求文件接口需要的参数根据调用接口参数而定 //Region为请求文件接口需要的参数根据调用接口参数而定
form.Add(new StringContent(caseNumber), "caseNumber"); form.Add(new StringContent(caseNumber), "caseNumber");
form.Add(new StringContent(suggestion), "suggestion"); form.Add(new StringContent(suggestion), "suggestion");
var closeFile = OptionsMonitor.CurrentValue.CloseFileUrl; var closeFile = GetClientOptions.CloseFileUrl;
var response = await client.PostAsync(closeFile, form); var response = await client.PostAsync(closeFile, form);
var respJsonStr = await response.Content.ReadAsStringAsync(); var respJsonStr = await response.Content.ReadAsStringAsync();
@ -292,7 +317,7 @@ public class SpiderServices
} }
//api/galaxy/v1/device/cameras:search //api/galaxy/v1/device/cameras:search
public async Task<SpiderResponse<PageData<CameraItem>>> GetCameras() public async Task<SpiderResponse<PageData<CameraItem>>> GetCameras(string? name = null)
{ {
var token = await GetToken(); var token = await GetToken();
using var client = _httpClientFactory.CreateClient(); using var client = _httpClientFactory.CreateClient();
@ -301,10 +326,10 @@ public class SpiderServices
client.DefaultRequestHeaders.Add("client-app-id", "megcity-web"); client.DefaultRequestHeaders.Add("client-app-id", "megcity-web");
client.DefaultRequestHeaders.Add("module-alias", "pending-forward"); client.DefaultRequestHeaders.Add("module-alias", "pending-forward");
client.DefaultRequestHeaders.Add("module-source", "megcity-web"); client.DefaultRequestHeaders.Add("module-source", "megcity-web");
var request = @" var request = $@"
{""managementIds"":[""6e9232ef-7b84-11e8-86b1-6c92bf4e6960""],""action"":""all"",""pageNo"":1,""pageSize"":200} {{""managementIds"":[""6e9232ef-7b84-11e8-86b1-6c92bf4e6960""],""name"":""{name}"" ,""action"":""all"",""pageNo"":1,""pageSize"":200}}
"; ";
var getCamersPath = OptionsMonitor.CurrentValue.GetCamerasUrl; var getCamersPath = GetClientOptions.GetCamerasUrl;
var response = await client.PostAsync(getCamersPath, var response = await client.PostAsync(getCamersPath,
new StringContent(request, Encoding.UTF8, "application/json")); new StringContent(request, Encoding.UTF8, "application/json"));
var respJsonStr = await response.Content.ReadAsStringAsync(); var respJsonStr = await response.Content.ReadAsStringAsync();
@ -315,6 +340,13 @@ public class SpiderServices
if (spiderRes?.Code == 0) if (spiderRes?.Code == 0)
{ {
_logger.LogInformation("成功获取监控结果"); _logger.LogInformation("成功获取监控结果");
foreach (var record in spiderRes.Data.Records)
{
_logger.LogInformation("摄像头: {name}", record.name);
var transferRes = GpsUtil.BaiduToGaode(record.lat, record.lon);
record.lat = transferRes.Item1;
record.lon = transferRes.Item2;
}
return new SpiderResponse<PageData<CameraItem>>() return new SpiderResponse<PageData<CameraItem>>()
{ {
@ -334,4 +366,24 @@ public class SpiderServices
Message = "获取摄像头失败" Message = "获取摄像头失败"
}; };
} }
public async Task<(string userId, string userRealName )> GetUserIdByCamera(string cameraAddress)
{
var camerasResp = await GetCameras(cameraAddress);
var camera = camerasResp.Result?.Records.FirstOrDefault();
if (camera == null) return (string.Empty, string.Empty);
var location = new Points(camera.lon, camera.lat);
var db = _serviceProvider.GetRequiredService<LiteDatabase>();
var polygonDb = db.GetCollection<Polygon>();
var polygons = polygonDb.FindAll();
foreach (var polygon in polygons)
{
if (location.IsPointInsidePolygon(polygon))
{
return (polygon.UserId, polygon.UserName);
}
}
return (string.Empty, string.Empty);
}
} }

View File

@ -142,6 +142,19 @@ namespace AutoDispathingWork.Utils
return gps; return gps;
} }
public static Tuple<double, double> BaiduToGaode(double bdLat, double bdLng)
{
double x = bdLng - 0.0065;
double y = bdLat - 0.006;
double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * Math.PI);
double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * Math.PI);
double ggLng = z * Math.Cos(theta);
double ggLat = z * Math.Sin(theta);
return Tuple.Create(ggLat, ggLng);
}
/// <summary> /// <summary>
/// gps84转为bd09 /// gps84转为bd09
/// GPS坐标转为百度坐标 /// GPS坐标转为百度坐标

View File

@ -0,0 +1,34 @@
using LiteDB;
using WorkerService1.Domains;
namespace AutoDispathingWork.Utils;
public class StaticServiceProvider
{
public static void SetServiceProvider(IServiceProvider serviceProvider)
{
Current = serviceProvider;
}
private static IServiceProvider Current { get; set; }
public static T GetRequiredService<T>()
{
return Current.GetRequiredService<T>();
}
public static T? GetService<T>()
{
return Current.GetService<T>();
}
public static ILiteCollection<LogInfo> GetLogDb()
{
return Current.GetRequiredService<LiteDatabase>().GetCollection<LogInfo>();
}
public static ILogger GetLogger(string methodName)
{
return Current.GetRequiredService<ILoggerFactory>().CreateLogger(methodName);
}
}

View File

@ -1,4 +1,7 @@
using WorkerService1.Domains; using GeoAPI.Geometries;
using NetTopologySuite.Geometries;
using WorkerService1.Domains;
using Polygon = WorkerService1.Domains.Polygon;
namespace WorkerService1.Utils; namespace WorkerService1.Utils;
@ -6,34 +9,27 @@ public static class Utilities
{ {
public static bool IsPointInsidePolygon(this Points point, Polygon polygon) public static bool IsPointInsidePolygon(this Points point, Polygon polygon)
{ {
// 使用射线交叉法判断点是否在多边形内 if (polygon.Points == null) return false;
int count = 0; var testPoint = new Coordinate(point.X, point.Y);
double x0 = point.X; foreach (var points in polygon.Points)
double y0 = point.Y;
for (int i = 0; i < polygon.Points.Count; i++)
{ {
var currentPolygon = polygon.Points[i]; var polygonPoints = points.Select(x => new Coordinate(x.X, x.Y)).ToArray();
for (int i2 = 0; i2 < currentPolygon.Count; i2++) var isInside = IsPointInsidePolygon(testPoint, polygonPoints);
{ if (isInside) return true;
int next = (i2 + 1) % currentPolygon.Count;
int prev = (i2 - 1 + currentPolygon.Count) % currentPolygon.Count;
double x1 = currentPolygon[next].X;
double y1 = currentPolygon[next].Y;
double x2 = currentPolygon[prev].X;
double y2 = currentPolygon[prev].Y;
if (((y1 > y0) && (y2 <= y0)) || ((y2 > y0) && (y1 <= y0)))
{
double intersection = (x1 - x2) * (y0 - y2) / (y1 - y2) + x2;
if (x0 < intersection)
{
count++;
}
}
}
if (count % 2 == 1) return true;
} }
return false; return false;
} }
public static bool IsPointInsidePolygon(Coordinate testPoint, Coordinate[] polygonPoints)
{
var geometryFactory = new GeometryFactory();
var testPointGeom = geometryFactory.CreatePoint(testPoint);
var linearRing = new LinearRing(polygonPoints.Append(polygonPoints.First()).ToArray());
var polygon = geometryFactory.CreatePolygon(linearRing);
return polygon.Intersects(testPointGeom);
}
} }

View File

@ -1,4 +1,5 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using WorkerService1.Domains;
using WorkerService1.Dto.Configuration; using WorkerService1.Dto.Configuration;
using WorkerService1.Services; using WorkerService1.Services;
@ -10,7 +11,7 @@ public class Worker : BackgroundService
private readonly SpiderServices _spiderServices; private readonly SpiderServices _spiderServices;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
public Worker(ILogger<Worker> logger,IServiceProvider serviceProvider, SpiderServices spiderServices) public Worker(ILogger<Worker> logger, IServiceProvider serviceProvider, SpiderServices spiderServices)
{ {
_logger = logger; _logger = logger;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
@ -21,24 +22,26 @@ public class Worker : BackgroundService
{ {
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{ {
using var scope = _serviceProvider.CreateScope();
var settingServices = scope.ServiceProvider.GetRequiredService<SettingServices>();
var options = settingServices.GetClientOptions();
if (_logger.IsEnabled(LogLevel.Information)) if (_logger.IsEnabled(LogLevel.Information))
{ {
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now.LocalDateTime);
} }
try try
{ {
await Handle(); if (options.DispatchingRunning)
await Handle();
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError("执行控制器发生错误,错误信息:ex{}", e.StackTrace); $"执行控制器发生错误,错误信息:ex{e.StackTrace}".Error();
} }
finally finally
{ {
using var scope = _serviceProvider.CreateScope(); await Task.Delay(options.Delay, stoppingToken);
var options = scope.ServiceProvider.GetRequiredService<IOptionsMonitor<ClientOptions>>();
await Task.Delay(options.CurrentValue.Delay, stoppingToken);
} }
} }
} }
@ -54,15 +57,24 @@ public class Worker : BackgroundService
{ {
//处理逻辑 //处理逻辑
//1.查询角色是 城管?的用户 //1.查询角色是 城管?的用户
var users = await _spiderServices.GetUsers(); // var users = await _spiderServices.GetUsers();
var cityManager = users.Result?.Records; // var cityManager = users.Result?.Records;
if (cityManager?.Any() ?? false) // if (cityManager?.Any() ?? false)
// {
foreach (var item in needDispose)
{ {
foreach (var item in needDispose) //2.进行派单操作
var result =
await _spiderServices.DispatchTask(item.caseNumber, item.address, item.typeCode);
if (result.IsSuccess)
{ {
//2.进行派单操作 var message = $"成功派发任务,任务编号:{item.caseNumber},任务地址:{item.address},任务类型:{item.typeCode}";
var result = message.Info();
await _spiderServices.DispatchTask(item.caseNumber, cityManager.First().Id, item.typeCode); }
else
{
var message = $"派发任务失败,错误信息:{result.Message}";
message.Error();
} }
} }
} }

View File

@ -17,6 +17,8 @@
"GetTaskApi": "api/megcity/v1/events/queryByWaterFall", "GetTaskApi": "api/megcity/v1/events/queryByWaterFall",
"GetUserApi": "api/galaxy/v1/auth/users/query", "GetUserApi": "api/galaxy/v1/auth/users/query",
"DiposeOrder": "api/megcity/v1/events/dispatch/{0}", "DiposeOrder": "api/megcity/v1/events/dispatch/{0}",
"CloseFileApi": "api/megcity/v1/events/pass" "CloseFileApi": "api/megcity/v1/events/pass",
"GetCamerasApi": "api/galaxy/v1/device/cameras:search",
"IsRunning": false
} }
} }

View File

@ -0,0 +1 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4"/>
<PackageReference Include="MSTest.TestFramework" Version="3.0.4"/>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="NetTopologySuite" Version="2.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AutoDispathingWork\AutoDispathingWork.csproj" />
</ItemGroup>
</Project>

38
TestProject1/UnitTest1.cs Normal file
View File

@ -0,0 +1,38 @@
using NetTopologySuite.Geometries;
using NetTopologySuite.Operation.Overlay;
using WorkerService1.Domains;
using WorkerService1.Utils;
using Polygon = WorkerService1.Domains.Polygon;
namespace TestProject1;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Points points = new Points(121.43779625955115, 31.26871446396198);
Polygon polygon = new Polygon()
{
Name = "",
Points = new List<List<Points>>
{
new List<Points>
{
new(121.435776, 31.269835),
new(121.435361, 31.268672),
new Points(121.435854, 31.267829),
new Points(121.439541, 31.268048),
new Points(121.439324, 31.269312),
}
}
};
var res = Utilities.IsPointInsidePolygon(points, polygon);
}
}