diff --git a/AutoDispatching/AutoDispatching.csproj b/AutoDispatching/AutoDispatching.csproj index 8af374d..c4a6eae 100644 --- a/AutoDispatching/AutoDispatching.csproj +++ b/AutoDispatching/AutoDispatching.csproj @@ -15,6 +15,7 @@ + diff --git a/AutoDispathingWork/AutoDispathingWork.csproj b/AutoDispathingWork/AutoDispathingWork.csproj index aaece96..cc00e31 100644 --- a/AutoDispathingWork/AutoDispathingWork.csproj +++ b/AutoDispathingWork/AutoDispathingWork.csproj @@ -9,9 +9,12 @@ + + + diff --git a/AutoDispathingWork/Controllers/UserController.cs b/AutoDispathingWork/Controllers/UserController.cs index 612b89e..a8152ea 100644 --- a/AutoDispathingWork/Controllers/UserController.cs +++ b/AutoDispathingWork/Controllers/UserController.cs @@ -1,10 +1,12 @@ -using LiteDB; +using AutoDispathingWork.Utils; +using LiteDB; using Microsoft.AspNetCore.Mvc; using WorkerService1.Domains; using WorkerService1.Dto; using WorkerService1.Dto.QueryRequest; using WorkerService1.Dto.QueryResponse; using WorkerService1.Services; +using WorkerService1.Utils; namespace WorkerService1.Controllers; @@ -26,25 +28,171 @@ public class UserController : ControllerBase } [HttpGet("/api/Polygon/Pages")] - public SpiderResponse> GetPolygon([FromQuery] PageRequest request, - [FromServices] LiteDatabase db) + public async Task>> GetPolygon([FromQuery] PageRequest request, + [FromServices] LiteDatabase db, [FromServices] SpiderServices spiderServices) { var polygon = db.GetCollection(); - return new SpiderResponse>() + var result = polygon.FindAll().ToList(); + var cameras = await spiderServices.GetCameras(); + + foreach (var item in result) { - IsSuccess = true, Code = SpiderResponseCode.Success, Message = "", Result = polygon.FindAll() + // item.RangeCameras ??= new List(); + foreach (var x in cameras.Result?.Records.Select(x => + { + var tempGps = GpsUtil.Bd09ToGcj02(x.lon, x.lat); + return (x.name, new Points(tempGps[0], tempGps[1])); + }).ToList()!.Where(x => x.Item2.IsPointInsidePolygon(item))!) + { + item.RangeCameras ??= new List(); + item.RangeCameras?.Add(x.name); + } + } + + return new SpiderResponse>() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "", Result = result }; } [HttpPost("/api/Polygon")] - public SpiderResponse CreatePolygon([FromBody] Polygon request, [FromServices] LiteDatabase db) + public SpiderResponse CreateOrUpdatePolygon([FromBody] Polygon request, [FromServices] LiteDatabase db) { var polygon = db.GetCollection(); - var result = polygon.Insert(request); - return new SpiderResponse() + if (request.PolygonId == null) { - IsSuccess = true, Code = SpiderResponseCode.Success, Message = "", Result = result + request.PolygonId = Guid.NewGuid(); + var result = polygon.Insert(request); + return new SpiderResponse() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "保存成功", Result = true + }; + } + else + { + var old = polygon.FindOne(x => x.PolygonId == request.PolygonId); + old.Points = request.Points; + old.Name = request.Name; + polygon.Update(old); + return new SpiderResponse() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "更新成功", Result = true + }; + } + } + + + [HttpDelete("/api/Polygon/{polygonId}")] + public SpiderResponse DeletePolygon([FromRoute] Guid polygonId, [FromServices] LiteDatabase db) + { + var polygon = db.GetCollection(); + var result = polygon.FindById(polygonId); + if (result == null) + { + return new SpiderResponse() + { + IsSuccess = false, Code = SpiderResponseCode.Fail, Message = "未找到该区域", Result = false + }; + } + + polygon.Delete(polygonId); + return new SpiderResponse() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "删除区域信息成功", Result = true }; } + + [HttpGet("/api/Polygon/{polygonId}")] + public SpiderResponse GetPolygon([FromRoute] Guid polygonId, [FromServices] LiteDatabase db) + { + var polygon = db.GetCollection(); + var result = polygon.FindById(polygonId); + if (result == null) + { + return new SpiderResponse() + { + IsSuccess = false, Code = SpiderResponseCode.Fail, Message = "未找到该区域", Result = null + }; + } + + return new SpiderResponse() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "获取区域信息成功", Result = result + }; + } + + + [HttpPut("/api/Polygon/{polygonId}/UserId/{userId}")] + public SpiderResponse BindPolygonUserId([FromRoute] Guid polygonId, [FromRoute] string userId, + [FromServices] LiteDatabase db) + { + var polygon = db.GetCollection(); + var result = polygon.FindOne(x => x.PolygonId == polygonId); + if (result == null) + { + return new SpiderResponse() + { + IsSuccess = false, Code = SpiderResponseCode.Fail, Message = "未找到该区域", Result = false + }; + } + + result.UserId = userId; + polygon.Update(result); + return new SpiderResponse() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "更新区域信息成功", Result = true + }; + } + + [HttpGet("/api/Polygon/others")] + public SpiderResponse>>> GetAllPoints([FromQuery] Guid? polygonId, + [FromServices] LiteDatabase db) + { + var polygon = db.GetCollection(); + if (polygonId.HasValue) + { + var result = polygon.Find(x => x.PolygonId != polygonId).ToList(); + var points = result.Select(x => x.Points).ToList(); + return new SpiderResponse>>>() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "获取区域信息成功", Result = points + }; + } + else + { + var result = polygon.FindAll().ToList(); + var points = result.Select(x => x.Points).ToList(); + return new SpiderResponse>>>() + { + IsSuccess = true, Code = SpiderResponseCode.Success, Message = "获取区域信息成功", Result = points + }; + } + } + + [HttpGet("/api/Polygon/{polygonId}/InRangeCameras")] + public async IAsyncEnumerable IsRangeInPolygon([FromRoute] Guid polygonId, + [FromServices] LiteDatabase db, [FromServices] SpiderServices spiderServices) + { + var polygon = db.GetCollection(); + var result = polygon.FindOne(x => x.PolygonId == polygonId); + if (result != null) + { + var cameras = await spiderServices.GetCameras(); + foreach (var x in cameras.Result?.Records.Select(x => (x.name, new Points(x.lon, x.lat))).ToList()!) + { + if (x.Item2.IsPointInsidePolygon(result)) + { + yield return x.name; + } + } + } + } + + [HttpGet("/api/Camera/All")] + public async Task>> GetCameras( + [FromServices] SpiderServices spiderServices) + { + return await spiderServices.GetCameras(); + } } \ No newline at end of file diff --git a/AutoDispathingWork/Domains/Polygon.cs b/AutoDispathingWork/Domains/Polygon.cs index 1982d5e..ceac86e 100644 --- a/AutoDispathingWork/Domains/Polygon.cs +++ b/AutoDispathingWork/Domains/Polygon.cs @@ -2,14 +2,22 @@ public class Polygon { - public Guid PolygonId { get; set; } + public Guid? PolygonId { get; set; } public string Name { get; set; } - public string UserId { get; set; } - public Points[] Points { get; set; } + public string? UserId { get; set; } + public List>? Points { get; set; } + + public List? RangeCameras { get; set; } = new List(); } public struct Points { + public Points(double x, double y) + { + X = x; + Y = y; + } public double X { get; set; } public double Y { get; set; } -} \ No newline at end of file +} + diff --git a/AutoDispathingWork/Dto/Configuration/ClientOptions.cs b/AutoDispathingWork/Dto/Configuration/ClientOptions.cs index 9173bc8..32edbf9 100644 --- a/AutoDispathingWork/Dto/Configuration/ClientOptions.cs +++ b/AutoDispathingWork/Dto/Configuration/ClientOptions.cs @@ -16,6 +16,7 @@ public class ClientOptions public string DiposeOrder { get; set; } = "api/megcity/v1/events/dispatch/{0}"; public string CloseFileApi { get; set; } = "api/megcity/v1/events/pass"; + public string GetCamerasApi { get; set; } = "api/galaxy/v1/device/cameras:search"; //登录接口 public string LoginUrl => $"{ApiGateway}{LoginApi}"; @@ -31,6 +32,8 @@ public class ClientOptions public string DiposeOrderUrl => $"{ApiGateway}{DiposeOrder}"; public string CloseFileUrl => $"{ApiGateway}{CloseFileApi}"; + + public string GetCamerasUrl => $"{ApiGateway}{GetCamerasApi}"; } \ No newline at end of file diff --git a/AutoDispathingWork/Dto/QueryResponse/CameraResponse.cs b/AutoDispathingWork/Dto/QueryResponse/CameraResponse.cs new file mode 100644 index 0000000..c78952f --- /dev/null +++ b/AutoDispathingWork/Dto/QueryResponse/CameraResponse.cs @@ -0,0 +1,53 @@ +namespace WorkerService1.Dto.QueryResponse; + +public class CameraResponse: KSResponse> +{ + +} + +// { +// "alarmShortVideo": true, +// "bodyAnalyze": "0", +// "closed": true, +// "deptId": "6e9232ef-7b84-11e8-86b1-6c92bf4e6960", +// "deptName": "甘泉街道", +// "faceAnalyze": "0", +// "gaPlatformDeviceId": "", +// "gaPlatformId": "", +// "gbPlatformDeviceId": "", +// "gbPlatformId": "", +// "id": "14324899222782976", +// "labelCodes": [], +// "labels": [], +// "lat": 31.27466, +// "location": "", +// "lon": 121.44307, +// "lowQuality": false, +// "managementId": "6e9232ef-7b84-11e8-86b1-6c92bf4e6960", +// "managementName": "甘泉街道", +// "manufacturer": 2, +// "monitoringType": 1, +// "motorVehicleAnalyze": "0", +// "name": "新沪小区595弄3号北", +// "nonMotorVehicleAnalyze": "0", +// "numeration": "", +// "optPermissions": true, +// "placeIds": [], +// "policeNet": true, +// "pulled": true, +// "rainbowStatus": 0, +// "roi": "[]", +// "rois": [], +// "sncode": "", +// "status": 1, +// "systemType": "rainbow-device", +// "type": 1, +// "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 labelCodes, List 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 placeIds, + bool policeNet, bool pulled, int rainbowStatus, string roi, List rois, string sncode, int status, + string systemType, int type, bool vlowQuality); \ No newline at end of file diff --git a/AutoDispathingWork/Dto/QueryResponse/UserResp.cs b/AutoDispathingWork/Dto/QueryResponse/UserResp.cs index f514f66..a2e5be0 100644 --- a/AutoDispathingWork/Dto/QueryResponse/UserResp.cs +++ b/AutoDispathingWork/Dto/QueryResponse/UserResp.cs @@ -2,165 +2,29 @@ namespace WorkerService1.Dto.QueryResponse; -public class UserResp +public class KSResponse { -// { -// "code": 0, -// "msg": "成功", -// "data": { -// "pageNo": 1, -// "pageSize": 20, -// "totalRecords": 3, -// "records": [ -// { -// "organization": { -// "users": [], -// "orgName": "甘泉街道", -// "subOrgs": [], -// "userCount": 0, -// "orderCode": 0, -// "orgLevel": 1, -// "userTotalCount": 0, -// "permit": true, -// "id": "6e9232ef-7b84-11e8-86b1-6c92bf4e6960" -// }, -// "online": false, -// "passWDInit": true, -// "ip": "", -// "sso": false, -// "userName": "md123", -// "roles": [ -// { -// "users": [], -// "remark": "禁止编辑删除角色,否则影响系统正常使用", -// "roleName": "执法人员", -// "permissions": [], -// "id": "a2e267c0-d88d-4ecb-a4b5-d904e85dfbb6" -// } -// ], -// "pkiId": "", -// "creator": "27465e20-6942-4569-8141-2ff5c264111e", -// "isApp": false, -// "thumb": "", -// "phoneNo": "", -// "employeeId": "", -// "enabled": true, -// "userRealName": "名都物业", -// "datas": {}, -// "id": "1942ec57-5019-411d-b85f-a67055797e0f" -// }, -// { -// "organization": { -// "users": [], -// "orgName": "甘泉街道", -// "subOrgs": [], -// "userCount": 0, -// "orderCode": 0, -// "orgLevel": 1, -// "userTotalCount": 0, -// "permit": true, -// "id": "6e9232ef-7b84-11e8-86b1-6c92bf4e6960" -// }, -// "online": false, -// "passWDInit": false, -// "ip": "", -// "sso": false, -// "userName": "zgc123", -// "roles": [ -// { -// "users": [], -// "remark": "禁止编辑删除角色,否则影响系统正常使用", -// "roleName": "执法人员", -// "permissions": [], -// "id": "a2e267c0-d88d-4ecb-a4b5-d904e85dfbb6" -// } -// ], -// "pkiId": "", -// "creator": "27465e20-6942-4569-8141-2ff5c264111e", -// "isApp": false, -// "thumb": "", -// "phoneNo": "", -// "employeeId": "", -// "enabled": true, -// "userRealName": "朱龚超", -// "datas": {}, -// "id": "01edee4a-f345-4060-a33a-34bbd9b55247" -// }, -// { -// "organization": { -// "users": [], -// "orgName": "甘泉街道", -// "subOrgs": [], -// "userCount": 0, -// "orderCode": 0, -// "orgLevel": 1, -// "userTotalCount": 0, -// "permit": true, -// "id": "6e9232ef-7b84-11e8-86b1-6c92bf4e6960" -// }, -// "online": false, -// "passWDInit": false, -// "ip": "", -// "sso": false, -// "userName": "gm123", -// "roles": [ -// { -// "users": [], -// "remark": "", -// "roleName": "高级管理员", -// "permissions": [], -// "id": "0c772d50-a4af-439f-a18a-8fd332343d5e" -// }, -// { -// "users": [], -// "remark": "禁止编辑删除角色,否则影响系统正常使用", -// "roleName": "执法人员", -// "permissions": [], -// "id": "a2e267c0-d88d-4ecb-a4b5-d904e85dfbb6" -// } -// ], -// "pkiId": "", -// "creator": "27465e20-6942-4569-8141-2ff5c264111e", -// "isApp": false, -// "thumb": "", -// "phoneNo": "18721100373", -// "employeeId": "12138", -// "enabled": true, -// "userRealName": "张辉", -// "datas": {}, -// "id": "66fa9261-16f6-49aa-a391-5848f40301e0" -// } -// ], -// "totalPage": 1 -// } -// } - [JsonPropertyName("code")] public int Code { get; set; } [JsonPropertyName("msg")] public string Msg { get; set; } - [JsonPropertyName("data")] public Data Data { get; set; } + [JsonPropertyName("data")] public T Data { get; set; } } -public class Data +public class UserResp : KSResponse> { - [JsonPropertyName("pageNo")] - public int PageNo { get; set; } - [JsonPropertyName("pageSize")] - public int PageSize { get; set; } - [JsonPropertyName("totalRecords")] - public int TotalRecords { get; set; } - [JsonPropertyName("records")] - public Record[] Records { get; set; } - [JsonPropertyName("totalPage")] - public int TotalPage { get; set; } - } -public class Record +public class PageData { - [JsonPropertyName("id")] - public string Id { get; set; } - [JsonPropertyName("userName")] - public string UserName { get; set; } - [JsonPropertyName("userRealName")] - public string UserRealName { get; set; } + [JsonPropertyName("pageNo")] public int PageNo { get; set; } + [JsonPropertyName("pageSize")] public int PageSize { get; set; } + [JsonPropertyName("totalRecords")] public int TotalRecords { get; set; } + [JsonPropertyName("records")] public T[] Records { get; set; } + [JsonPropertyName("totalPage")] public int TotalPage { get; set; } +} + +public class UserRecord +{ + [JsonPropertyName("id")] public string Id { get; set; } + [JsonPropertyName("userName")] public string UserName { get; set; } + [JsonPropertyName("userRealName")] public string UserRealName { get; set; } } \ No newline at end of file diff --git a/AutoDispathingWork/Dto/SpiderResponse.cs b/AutoDispathingWork/Dto/SpiderResponse.cs index 05a25f9..6df7ae5 100644 --- a/AutoDispathingWork/Dto/SpiderResponse.cs +++ b/AutoDispathingWork/Dto/SpiderResponse.cs @@ -1,6 +1,6 @@ namespace WorkerService1.Dto; -public class SpiderResponse where T : class +public class SpiderResponse { public bool IsSuccess { get; set; } public SpiderResponseCode Code { get; set; } diff --git a/AutoDispathingWork/Program.cs b/AutoDispathingWork/Program.cs index 8ad065e..0fb635e 100644 --- a/AutoDispathingWork/Program.cs +++ b/AutoDispathingWork/Program.cs @@ -1,10 +1,16 @@ using LiteDB; +using Microsoft.OpenApi.Models; using WorkerService1; using WorkerService1.Dto.Configuration; using WorkerService1.Services; var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddControllers(); +builder.Services + .AddEndpointsApiExplorer(); var config = new ConfigurationManager() .AddJsonFile("appsettings.json", false, true) .Build(); @@ -18,6 +24,7 @@ builder.Services.AddCors(x => .AllowAnyHeader(); }); }); +builder.Services.AddSwaggerGen(); builder.Services.AddSingleton(x => new LiteDatabase(builder.Configuration["Database:ConnectionString"])); builder.Services.AddSingleton(config); @@ -25,7 +32,7 @@ builder.Services.Configure(config.GetSection("ClientOptions")); builder.Services.AddHttpClient(); builder.Services.AddMemoryCache(); builder.Services.AddLogging(); -builder.Services.AddMvcCore(); +// builder.Services.AddMvcCore(); builder.Services.AddSingleton(); #if !DEBUG builder.Services.AddHostedService(); @@ -34,7 +41,11 @@ builder.Services.AddHostedService(); var app = builder.Build(); + app.UseCors("AllowAllOrigin"); +app.UseSwagger(); +app.UseSwaggerUI(); + app.MapControllers(); app.Run(); \ No newline at end of file diff --git a/AutoDispathingWork/Services/SpiderServices.cs b/AutoDispathingWork/Services/SpiderServices.cs index 78a3697..9cdd9a0 100644 --- a/AutoDispathingWork/Services/SpiderServices.cs +++ b/AutoDispathingWork/Services/SpiderServices.cs @@ -151,7 +151,7 @@ public class SpiderServices // {"pageNo":1,"pageSize":20,"condition":{"roleIds":["a2e267c0-d88d-4ecb-a4b5-d904e85dfbb6"],"enabled":"null"}} - public async Task> GetUsers(UserQuery? query = null) + public async Task>> GetUsers(UserQuery? query = null) { var token = await GetToken(); using var client = _httpClientFactory.CreateClient(); @@ -173,7 +173,7 @@ public class SpiderServices { _logger.LogInformation("成功获取监控结果"); - return new SpiderResponse() + return new SpiderResponse>() { IsSuccess = true, Result = spiderRes.Data, @@ -183,7 +183,7 @@ public class SpiderServices } } - return new SpiderResponse() + return new SpiderResponse>() { IsSuccess = false, Result = null, @@ -290,4 +290,48 @@ public class SpiderServices Message = "结案失败" }; } + + //api/galaxy/v1/device/cameras:search + public async Task>> GetCameras() + { + var token = await GetToken(); + using var client = _httpClientFactory.CreateClient(); + client.DefaultRequestHeaders.Add("authorization", $"{token}"); + client.DefaultRequestHeaders.Add("accept-language", "zh-CN,zh;q=0.9"); + client.DefaultRequestHeaders.Add("client-app-id", "megcity-web"); + client.DefaultRequestHeaders.Add("module-alias", "pending-forward"); + client.DefaultRequestHeaders.Add("module-source", "megcity-web"); + var request = @" + {""managementIds"":[""6e9232ef-7b84-11e8-86b1-6c92bf4e6960""],""action"":""all"",""pageNo"":1,""pageSize"":200} +"; + var getCamersPath = OptionsMonitor.CurrentValue.GetCamerasUrl; + var response = await client.PostAsync(getCamersPath, + new StringContent(request, Encoding.UTF8, "application/json")); + var respJsonStr = await response.Content.ReadAsStringAsync(); + _logger.LogInformation("获得列表返回json: {respJsonStr}", respJsonStr); + var spiderRes = JsonSerializer.Deserialize(respJsonStr); + if (response.IsSuccessStatusCode) + { + if (spiderRes?.Code == 0) + { + _logger.LogInformation("成功获取监控结果"); + + return new SpiderResponse>() + { + IsSuccess = true, + Result = spiderRes.Data, + Code = SpiderResponseCode.Success, + Message = "成功获取摄像头结果" + }; + } + } + + return new SpiderResponse>() + { + IsSuccess = false, + Result = null, + Code = SpiderResponseCode.Fail, + Message = "获取摄像头失败" + }; + } } \ No newline at end of file diff --git a/AutoDispathingWork/Utils/GpsUtlity.cs b/AutoDispathingWork/Utils/GpsUtlity.cs new file mode 100644 index 0000000..8d9be5f --- /dev/null +++ b/AutoDispathingWork/Utils/GpsUtlity.cs @@ -0,0 +1,374 @@ +using System.Collections; + +namespace AutoDispathingWork.Utils +{ + /* + * WGS84坐标系 地球坐标系,国际通用坐标系 + * GCJ02坐标系 火星坐标系,WGS84坐标系加密后的坐标系;Google国内地图、高德、QQ地图 使用 + * BD09坐标系 百度坐标系,GCJ02坐标系加密后的坐标系 + * */ + public class GpsUtil + { + public static double pi = 3.1415926535897932384626; + public static double x_pi = 3.1415926535897932384626;// * 3000.0 / 180.0; //转换BD09时偏移 + //public static double cbz = 6378137.0; //长半轴 + public static double cbz = 6378245.0; //长半轴 + public static double ee = 0.00669342162296594323; + + + public static double TransformLat(double x, double y) + { + double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + + 0.2 * Math.Sqrt(Math.Abs(x)); + ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0; + ret += (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0; + return ret; + } + + public static double TransformLon(double x, double y) + { + double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 + * Math.Sqrt(Math.Abs(x)); + ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.Sin(x * pi) + 40.0 * Math.Sin(x / 3.0 * pi)) * 2.0 / 3.0; + ret += (150.0 * Math.Sin(x / 12.0 * pi) + 300.0 * Math.Sin(x / 30.0 + * pi)) * 2.0 / 3.0; + return ret; + } + + public static double[] transform(double lat, double lon) + { + if (OutOfChina(lat, lon)) + { + return new double[] { lat, lon }; + } + double dLat = TransformLat(lon - 105.0, lat - 35.0); + double dLon = TransformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.Sin(radLat); + magic = 1 - ee * magic * magic; + double SqrtMagic = Math.Sqrt(magic); + dLat = (dLat * 180.0) / ((cbz * (1 - ee)) / (magic * SqrtMagic) * pi); + dLon = (dLon * 180.0) / (cbz / SqrtMagic * Math.Cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return new double[] { mgLat, mgLon }; + } + /// + /// 是否是国内地址 + /// + /// + /// + /// + public static bool OutOfChina(double lat, double lon) + { + if (lon < 72.004 || lon > 137.8347) + return true; + if (lat < 0.8293 || lat > 55.8271) + return true; + return false; + } + + /** + * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System + * + * @param lat + * @param lon + * @return + */ + public static double[] Gps84ToGcj02(double lat, double lon) + { + if (OutOfChina(lat, lon)) + { + return new double[] { lat, lon }; + } + double dLat = TransformLat(lon - 105.0, lat - 35.0); + double dLon = TransformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.Sin(radLat); + magic = 1 - ee * magic * magic; + double SqrtMagic = Math.Sqrt(magic); + dLat = (dLat * 180.0) / ((cbz * (1 - ee)) / (magic * SqrtMagic) * pi); + dLon = (dLon * 180.0) / (cbz / SqrtMagic * Math.Cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return new double[] { mgLat, mgLon }; + } + + /** + * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return + * */ + public static double[] Gcj02ToGps84(double lat, double lon) + { + double[] gps = transform(lat, lon); + double lontitude = lon * 2 - gps[1]; + double latitude = lat * 2 - gps[0]; + return new double[] { latitude, lontitude }; + } + /// + /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 + /// 高德谷歌转为百度 + /// + /// + /// + /// + public static double[] Gcj02ToBd09(double lat, double lon) + { + double x = lon, y = lat; + double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * x_pi); + double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * x_pi); + double tempLon = z * Math.Cos(theta) + 0.0065; + double tempLat = z * Math.Sin(theta) + 0.006; + double[] gps = { tempLat, tempLon }; + return gps; + } + + /// + /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 + /// 百度坐标转为高德谷歌坐标 + /// + /// + /// + /// + public static double[] Bd09ToGcj02(double lat, double lon) + { + double x = lon - 0.0065, y = lat - 0.006; + double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi); + double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_pi); + double tempLon = z * Math.Cos(theta); + double tempLat = z * Math.Sin(theta); + double[] gps = { tempLat, tempLon }; + return gps; + } + + /// + /// gps84转为bd09 + /// GPS坐标转为百度坐标 + /// + /// + /// + /// + public static double[] Gps84ToBd09(double lat, double lon) + { + double[] gcj02 = Gps84ToGcj02(lat, lon); + double[] bd09 = Gcj02ToBd09(gcj02[0], gcj02[1]); + return bd09; + } + /// + /// 百度坐标转成GPS坐标 + /// + /// + /// + /// + public static double[] Bd09ToGps84(double lat, double lon) + { + double[] gcj02 = Bd09ToGcj02(lat, lon); + double[] gps84 = Gcj02ToGps84(gcj02[0], gcj02[1]); + //保留小数点后六位 + gps84[0] = Retain6(gps84[0]); + gps84[1] = Retain6(gps84[1]); + return gps84; + } + + /// + /// 保留小数点后六位 + /// + /// + /// + private static double Retain6(double num) + { + //String result = String.Format("%.6f", num); + return Double.Parse(num.ToString("0.000000")); + } + + /// + /// 获取经度(lon) + /// + /// + public static string GetLongitudeValue(double value) + { + ArrayList arrList = LgetValid(value); + if (arrList == null) + return string.Empty; + if (arrList.Count != 3) + return string.Empty; + return string.Format("{0}.{1}.{2}", arrList[0], arrList[1], arrList[2], value > 0 ? "E" : "W"); + } + /// + /// 获取纬度(lat) + /// + /// + public static string GetLatitudeValue(double value) + { + ArrayList arrList = LgetValid(value); + if (arrList == null) + return string.Empty; + if (arrList.Count != 3) + return string.Empty; + return string.Format("{0}.{1}.{2}", arrList[0], arrList[1], arrList[2], value > 0 ? "N" : "S"); + } + /// + /// 获取经纬度度分秒 + /// + /// + /// + public static ArrayList LgetValid(double value) + { + ArrayList aList = new ArrayList(); + string excute = ChangeValue(value); + string[] sArray = excute.Split('|'); + aList.Insert(0, sArray[0]); + aList.Insert(1, sArray[1]); + aList.Insert(2, sArray[2]); + return aList; + } + /// + /// 经纬度转换 + /// + /// 经度 + /// 保留8位值 + /// + protected static string ChangeValue(double degree) + { + if (degree < 0) + { + degree = -degree; + } + double minute = (degree - (int)degree) * 60; + double second = (minute - (int)minute) * 60; + return ((int)degree).ToString() + "|" + ((int)minute).ToString() + "|" + second.ToString("0.000"); + } + /// + /// 度时分 转换成 WGS84 + /// + /// + /// + /// + /// + public static double TimeToValue(string Degrees, string Minutes, string Seconds) + { + double Value = double.Parse(Degrees) + double.Parse(Minutes) / 60 + double.Parse(Seconds) / 3600; + return double.Parse(Value.ToString("0.000000")); + } + + + /// + /// 批量转换 + /// + /// 字符串数组["lng,lat","lng,lat"...] + /// 地心坐标,WGS84,GCJ02,BD09 + public static GpsUtilObject piliangzhuan(List arr, string typename) + { + //地心 + var list_dx = new List(); + //WGS84 + var list_wgs84 = new List(); + //GCJ02 + var list_gcj02 = new List(); + ///BD09 + var list_bd09 = new List(); + ///BD092 + var list_bd092 = new List(); + foreach (var ar in arr) + { + var item = ar.Split(',').ToList(); + //地心 转 w84 + Func dxTow84 = (value) => + { + var v = value.Split('.').ToList(); + if (v.Count > 3) + { + return GpsUtil.TimeToValue(v[0], v[1], v[2] + "." + (v[3] ?? "0")); + } + else + { + return GpsUtil.TimeToValue(v[0], v[1], v[2]); + } + }; + switch (typename) + { + case "地心坐标": + { + list_dx.Add(ar); + double lng = dxTow84(item[0]); + double lat = dxTow84(item[1]); + list_wgs84.Add(lng + "," + lat); + var gcj02 = GpsUtil.Gps84ToGcj02(lat, lng); + list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18")); + var bd09 = GpsUtil.Gps84ToBd09(lat, lng); + list_bd09.Add(bd09[1].ToString("g18") + "," + bd09[0].ToString("g18")); + } + break; + case "WGS84": + { + double lng = double.Parse(item[0]); + double lat = double.Parse(item[1]); + list_wgs84.Add(ar); + list_dx.Add(GpsUtil.GetLongitudeValue(lng) + "," + GpsUtil.GetLatitudeValue(lat)); + var gcj02 = GpsUtil.Gps84ToGcj02(lat, lng); + list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18")); + var bd09 = GpsUtil.Gps84ToBd09(lat, lng); + list_bd09.Add(bd09[1].ToString("g18") + "," + bd09[0].ToString("g18")); + } + break; + case "GCJ02": + { + double lng = double.Parse(item[0]); + double lat = double.Parse(item[1]); + list_gcj02.Add(ar); + var wgs84 = GpsUtil.Gcj02ToGps84(lat, lng); + list_wgs84.Add(wgs84[1].ToString("g18") + "," + wgs84[0].ToString("g18")); + list_dx.Add(GpsUtil.GetLongitudeValue(wgs84[1]) + "," + GpsUtil.GetLatitudeValue(wgs84[0])); + var bd09 = GpsUtil.Gcj02ToBd09(lat, lng); + list_bd09.Add(bd09[1].ToString("g18") + "," + bd09[0].ToString("g18")); + } + break; + case "BD09": + { + double lng = double.Parse(item[0]); + double lat = double.Parse(item[1]); + list_bd09.Add(ar); + var wgs84 = GpsUtil.Bd09ToGps84(lat, lng); + list_wgs84.Add(wgs84[1].ToString("g18") + "," + wgs84[0].ToString("g18")); + list_dx.Add(GpsUtil.GetLongitudeValue(wgs84[1]) + "," + GpsUtil.GetLatitudeValue(wgs84[0])); + var gcj02 = GpsUtil.Bd09ToGcj02(lat, lng); + list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18")); + } + break; + default: + break; + } + + } + return new GpsUtilObject + { + dx = string.Join("|", list_dx), + wgs84 = string.Join("|", list_wgs84), + gcj02 = string.Join("|", list_gcj02), + bd09 = string.Join("|", list_bd09) + }; + } + + public class GpsUtilObject + { + /// + /// 地心坐标 + /// + public string dx { get; set; } + /// + /// WGS84 + /// + public string wgs84 { get; set; } + /// + /// GCJ02 + /// + public string gcj02 { get; set; } + /// + /// BD09 + /// + public string bd09 { get; set; } + } + + } +} \ No newline at end of file diff --git a/AutoDispathingWork/Utils/Utilities.cs b/AutoDispathingWork/Utils/Utilities.cs new file mode 100644 index 0000000..8c46082 --- /dev/null +++ b/AutoDispathingWork/Utils/Utilities.cs @@ -0,0 +1,39 @@ +using WorkerService1.Domains; + +namespace WorkerService1.Utils; + +public static class Utilities +{ + public static bool IsPointInsidePolygon(this Points point, Polygon polygon) + { + // 使用射线交叉法判断点是否在多边形内 + int count = 0; + double x0 = point.X; + double y0 = point.Y; + for (int i = 0; i < polygon.Points.Count; i++) + { + var currentPolygon = polygon.Points[i]; + for (int i2 = 0; i2 < currentPolygon.Count; i2++) + { + 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; + } +} \ No newline at end of file