using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<LocationData> data = new List<LocationData>();
using (IDbConnection connection = new SqlConnection("Data Source=...;Initial Catalog=...;;User Id=sa;Password=...;"))
{
connection.Open();
string sqltext = @" SELECT [ID]
,[LONGITUDE]
,[LATITUDE]
,[X]
,[Y]
FROM [WAP_CONFIG2].[dbo].[MOBILE_LOCATION]
Where TIME Between @starttime and @endtime and USER_ID=2 Order by TIME asc";
DateTime dastart = Convert.ToDateTime("2019-03-01 14:08:37.613");
DateTime daend = Convert.ToDateTime("2019-03-01 14:10:37.200");
var result = connection.Query<LocationData>(sqltext, new { starttime = dastart, endtime = daend });
data = (result == null || result.Count() == 0) ? new List<LocationData>() : result.ToList();
}
double getinstance = 0.00;
for (int i = 0; i < data.Count(); i++)
{
if (i < data.Count() - 1)
{
double lng1 = Convert.ToDouble(data[i].LONGITUDE);
double lat1 = Convert.ToDouble(data[i].LATITUDE);
double lng2 = Convert.ToDouble(data[i + 1].LONGITUDE);
double lat2 = Convert.ToDouble(data[i + 1].LATITUDE);
getinstance += DistanceCount(lat1, lng1, lat2, lng2);
}
}
Console.WriteLine(getinstance);
Console.ReadKey();
}
public const double EARTH_RADIUS = 6378.137;
public static double rad(double d)
{
return d * Math.PI / 180.00;
}
public static double DistanceCount(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2))) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2);
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
}
internal class LocationData
{
public int ID { get; set; }
public double LONGITUDE { get; set; }
public double LATITUDE { get; set; }
public double X { get; set; }
public double Y { get; set; }
}
}
![]()
/****** Object: UserDefinedFunction [dbo].[fnQueryDistance] Script Date: 2019/3/2 15:01:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fnQueryDistance]
(
@userId INT ,
@startTime DATETIME ,
@endTime DATETIME
)
RETURNS FLOAT
AS
BEGIN
/*
[fnQueryDistance]和[fnQueryUserOdo],同样为计算里程的函数
【差别,以米为单位】
【fnQueryDistance计算值略大于fnQueryUserOdo
【差异:两者结果在小数点后第二位开始数值不同,不影响整体的统计
*/
--地图坐标范围
DECLARE @maxLon DATETIME;
DECLARE @maxLat DATETIME;
DECLARE @minLon DATETIME;
DECLARE @minLat DATETIME;
SET @maxLon = 113.713401;
SET @minLon = 114.67351;
SET @maxLat = 22.80835;
SET @minLat = 22.833933;
--如果任务没有结束获取当前时间为结束时间,时间范围不大于1天
DECLARE @dayTimeEnd DATETIME;
DECLARE @nowDate DATETIME;
IF ( ISNULL(@endTime, 0) = 0 )
BEGIN
SET @nowDate = GETDATE();
SET @dayTimeEnd = CONVERT(VARCHAR(10), @startTime, 120)
+ ' 23:59:59';
IF ( CAST(@dayTimeEnd AS DATETIME) <= CAST(@nowDate AS DATETIME) )
SET @endTime = @dayTimeEnd;
ELSE
SET @endTime = @nowDate;
END;
--游标循环的参数
DECLARE @LngBegin REAL;
DECLARE @LatBegin REAL;
DECLARE @LngEnd REAL;
DECLARE @LatEnd REAL;
--距离(千米)
DECLARE @Distance REAL;
declare @DistanceResult real=0.0;
declare @DistanceCount Real;
DECLARE @EARTH_RADIUS REAL;
SET @EARTH_RADIUS = 6378.137 ;
DECLARE @RadLatBegin REAL,
@RadLatEnd REAL,
@RadLatDiff REAL,
@RadLngDiff REAL;
DECLARE @gisdata_lon DECIMAL(18, 6);
DECLARE @gisdata_lat DECIMAL(18, 6);
DECLARE gisdata CURSOR
FOR
SELECT LONGITUDE ,
LATITUDE
FROM WAP_CONFIG2.dbo.MOBILE_LOCATION
WHERE USER_ID = @userId
--AND LONGITUDE BETWEEN @minLon AND @maxLon
--AND LATITUDE BETWEEN @minLat AND @maxLat
AND TIME BETWEEN @startTime AND @endTime
ORDER BY TIME ASC;
OPEN gisdata;
FETCH NEXT FROM gisdata INTO @gisdata_lon, @gisdata_lat;
WHILE ( @@FETCH_STATUS = 0 )
BEGIN
set @LngBegin=@gisdata_lon;
set @LatBegin=@gisdata_lat;
FETCH NEXT FROM gisdata INTO @gisdata_lon, @gisdata_lat;
set @LngEnd=@gisdata_lon;
set @LatEnd=@gisdata_lat;
SET @RadLatBegin = @LatBegin *PI()/ 180.0 ;
SET @RadLatEnd = @LatEnd *PI()/ 180.0 ;
SET @RadLatDiff = @RadLatBegin - @RadLatEnd ;
SET @RadLngDiff = @LngBegin *PI()/ 180.0 - @LngEnd *PI()/ 180.0 ;
SET @Distance = 2 *ASIN(SQRT(POWER(SIN(@RadLatDiff / 2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd)*POWER(SIN(@RadLngDiff / 2), 2)));
set @DistanceResult=@DistanceResult+(@Distance * @EARTH_RADIUS);
END;
CLOSE gisdata;
DEALLOCATE gisdata;
RETURN cast((@DistanceResult*1000) as decimal(18,5));
END
GO
![]()