如何获得以米为单位的距离
how to get distance in meter
我有以下存储程序我想检查我的汽车纬度经度的距离哪个地理围栏最近如果距离以米为单位小于 500 显示地理围栏 ID 哪个地理围栏 ID 最近的汽车纬度 longitude.if 汽车纬度经度最近的多边形显示多边形 ID 和如果矩形显示矩形 ID 我是 sql 服务器的新手,这就是我在这里的原因请帮助我的专业人士我非常感谢你,演示 table 在共享 link,
question and demo table is here
CREATE TABLE CarDistance
(
ID int IDENTITY(1,1) PRIMARY KEY,
car_id int,
latitude float,
longitude float
)
insert into CarDistance values(1234, '52.582191','-2.878418')
CREATE TABLE tblgeofencing2
(
ID int IDENTITY(1,1) PRIMARY KEY,
car_id int,
ShapeType varchar(255),
PolygonLatLng varchar(max),
minlatitude [float] NULL,
[minlongitude] [float] NULL,
[maxlatitude] [float] NULL,
[maxlongitude] [float] NULL,
)
insert into tblgeofencing2 values(123, 'polygon','24.835300590037598 67.06858277320862,24.835933468801272 67.06929624080658,24.83532979989791 67.07035303115845,24.83454113125045 67.0697683095932,24.835300590037598 67.06858277320862',NULL,NULL,NULL,NULL)
insert into tblgeofencing2 values(1234, 'rectangle','NULL','52.582191','-2.878418','52.233687','-2.702637')
Alter PROCEDURE [dbo].[Sp_CheckCarStatusMeter]
DECLARE @g GEOGRAPHY,
@ID INT,
@curVal INT,
@preVal INT ,
@CarSuggested INT,
@carlatprevious VARCHAR(10),
@carlongprevious VARCHAR(10),
@AllLatitudeLongitude VARCHAR(255),
@pprevious GEOGRAPHY
DECLARE SuggestCursor CURSOR FOR
SELECT TOP 100 rtha.car_id , rtha.latitude,
rtha.longitude
FROM CarDistance rtha WHERE rtha.car_id = 123;
OPEN SuggestCursor;
FETCH NEXT FROM SuggestCursor INTO @CarSuggestedID , @carlatprevious , @carlongprevious;
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE ShapeCursor CURSOR FOR
SELECT g.ID, @CarSuggestedID, g.ShapeType FROM tblgeofencing AS g
WHERE car_id =@CarSuggestedID
FETCH NEXT FROM ShapeCursor INTO @ID , @CarIdx , @ShapeType;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@ShapeType = 'polygon')
BEGIN --Polygon IF
PRINT 'polygon if';
SELECT @GeofenceIDnew = g.GeoFenceId, @minY = g.PolygonLatLng ROM tblgeofencing AS g
WHERE g.ID = =@CarSuggestedID
SET @g = geography ::STPolyFromText('POLYGON((' + @AllLatitudeLongitude + '))', 4326);
SET @pprevious = geography ::STPointFromText(
'POINT(' + @carlatprevious + ' ' + @carlongprevious + ')', 4326 );
SELECT @preVal = @g.STIntersects(@pprevious)
PRINT @preVal
IF @curVal = 1 AND @preVal = 0
BEGIN
PRINT 'Enter In GEOFENCE';
SELECT @geofencename = geofenceName,
@geofenceidforresult = ID
FROM tblgeofencing where ID = @CarSuggestedID;
INSERT INTO tblGeofenceCarStatus
VALUES
(
@CarSuggestedID, @geofenceidforresult,@geofencename,
@gpstime, @g.STDistance(@pprevious), 'Enter' );
END
ELSE
BEGIN
Print Not in Geofence
END
END; --- END POLYGON IF
FETCH NEXT FROM ShapeCursor INTO @ID , @CarIdx , @ShapeType;
END; --- END CHECK GEOFENCING RECTANGLE OR CIRCLE OR PLYGON
FETCH NEXT FROM SuggestCursor INTO @CarSuggestedID , @carlatprevious , @carlongprevious;
END;
CLOSE ShapeCursor;
DEALLOCATE ShapeCursor;
CLOSE SuggestCursor;
DEALLOCATE SuggestCursor;
SELECT * FROM tblGeofenceCarStatus;
END;
END; --- END SP BEGIN STATEMENT
以下解决方案将:
- 识别每辆车最近的位置
- 识别每辆车之前的位置
- 根据多边形字符串或矩形坐标构造地理围栏多边形
- 识别当前在 geo-fence 500 米范围内(从外部)或在 geo-fence
内的汽车
- 显示距 geo-fence 与之前位置的距离
;
WITH car_location_seq AS (
SELECT car_id
,ID
,latitude
,longitude
,ROW_NUMBER() OVER (PARTITION BY car_id ORDER BY ID DESC) AS Pos_Sequence
FROM #CarDistance
),
car_location AS (
SELECT c1.car_id
,geography::Point(c1.longitude, c1.latitude, 4326) AS Geo_Point_Current
,CASE WHEN c2.car_id IS NOT NULL THEN geography::Point(c2.longitude, c2.latitude, 4326) END AS Geo_Point_Previous
FROM car_location_seq c1 -- Most recent position
LEFT JOIN car_location_seq c2 -- Previous position
ON c1.car_id = c2.car_id
AND c2.Pos_Sequence = 2
WHERE c1.Pos_Sequence = 1
),
fences AS (
SELECT ID
,Car_ID
,CASE WHEN ShapeType = 'polygon' THEN geography::STPolyFromText('POLYGON((' + PolygonLatLng + '))', 4326)
WHEN ShapeType = 'rectangle' THEN geography::STPolyFromText('POLYGON((' +
CAST(maxlatitude AS VARCHAR(100)) + ' ' + CAST(minlongitude AS VARCHAR(100)) + ', ' +
CAST(minlatitude AS VARCHAR(100)) + ' ' + CAST(minlongitude AS VARCHAR(100)) + ', ' +
CAST(minlatitude AS VARCHAR(100)) + ' ' + CAST(maxlongitude AS VARCHAR(100)) + ', ' +
CAST(maxlatitude AS VARCHAR(100)) + ' ' + CAST(maxlongitude AS VARCHAR(100)) + ', ' +
CAST(maxlatitude AS VARCHAR(100)) + ' ' + CAST(minlongitude AS VARCHAR(100)) +
'))', 4326)
END AS Geo_Polygon
FROM #tblgeofencing2
)
SELECT f.ID AS Fence_ID
,c.car_id
,c.Geo_Point_Current
--,c.Geo_Point_Current.STAsText()
,f.Geo_Polygon
--,f.Geo_Polygon.STAsText()
,f.Geo_Polygon.STIntersects(c.Geo_Point_Current) AS Is_Inside_Fence_Current
,f.Geo_Polygon.STIntersects(c.Geo_Point_Previous) AS Is_Inside_Fence_Previous
,f.Geo_Polygon.STDistance(c.Geo_Point_Current) AS Distance_Current
,f.Geo_Polygon.STDistance(c.Geo_Point_Previous) AS Distance_Previous
--INTO #Relevant_Car_Positions
FROM fences f
INNER JOIN car_location c
ON f.car_id = c.car_id
WHERE f.Geo_Polygon.STDistance(c.Geo_Point_Current) < 500
;
示例输出:
您应该能够修改此代码以满足您的需要。例如,您可以先通过取消注释 INTO #Relevant_Car_Positions
.
将查询输出存储到临时 table
我有以下存储程序我想检查我的汽车纬度经度的距离哪个地理围栏最近如果距离以米为单位小于 500 显示地理围栏 ID 哪个地理围栏 ID 最近的汽车纬度 longitude.if 汽车纬度经度最近的多边形显示多边形 ID 和如果矩形显示矩形 ID 我是 sql 服务器的新手,这就是我在这里的原因请帮助我的专业人士我非常感谢你,演示 table 在共享 link,
question and demo table is here
CREATE TABLE CarDistance
(
ID int IDENTITY(1,1) PRIMARY KEY,
car_id int,
latitude float,
longitude float
)
insert into CarDistance values(1234, '52.582191','-2.878418')
CREATE TABLE tblgeofencing2
(
ID int IDENTITY(1,1) PRIMARY KEY,
car_id int,
ShapeType varchar(255),
PolygonLatLng varchar(max),
minlatitude [float] NULL,
[minlongitude] [float] NULL,
[maxlatitude] [float] NULL,
[maxlongitude] [float] NULL,
)
insert into tblgeofencing2 values(123, 'polygon','24.835300590037598 67.06858277320862,24.835933468801272 67.06929624080658,24.83532979989791 67.07035303115845,24.83454113125045 67.0697683095932,24.835300590037598 67.06858277320862',NULL,NULL,NULL,NULL)
insert into tblgeofencing2 values(1234, 'rectangle','NULL','52.582191','-2.878418','52.233687','-2.702637')
Alter PROCEDURE [dbo].[Sp_CheckCarStatusMeter]
DECLARE @g GEOGRAPHY,
@ID INT,
@curVal INT,
@preVal INT ,
@CarSuggested INT,
@carlatprevious VARCHAR(10),
@carlongprevious VARCHAR(10),
@AllLatitudeLongitude VARCHAR(255),
@pprevious GEOGRAPHY
DECLARE SuggestCursor CURSOR FOR
SELECT TOP 100 rtha.car_id , rtha.latitude,
rtha.longitude
FROM CarDistance rtha WHERE rtha.car_id = 123;
OPEN SuggestCursor;
FETCH NEXT FROM SuggestCursor INTO @CarSuggestedID , @carlatprevious , @carlongprevious;
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE ShapeCursor CURSOR FOR
SELECT g.ID, @CarSuggestedID, g.ShapeType FROM tblgeofencing AS g
WHERE car_id =@CarSuggestedID
FETCH NEXT FROM ShapeCursor INTO @ID , @CarIdx , @ShapeType;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@ShapeType = 'polygon')
BEGIN --Polygon IF
PRINT 'polygon if';
SELECT @GeofenceIDnew = g.GeoFenceId, @minY = g.PolygonLatLng ROM tblgeofencing AS g
WHERE g.ID = =@CarSuggestedID
SET @g = geography ::STPolyFromText('POLYGON((' + @AllLatitudeLongitude + '))', 4326);
SET @pprevious = geography ::STPointFromText(
'POINT(' + @carlatprevious + ' ' + @carlongprevious + ')', 4326 );
SELECT @preVal = @g.STIntersects(@pprevious)
PRINT @preVal
IF @curVal = 1 AND @preVal = 0
BEGIN
PRINT 'Enter In GEOFENCE';
SELECT @geofencename = geofenceName,
@geofenceidforresult = ID
FROM tblgeofencing where ID = @CarSuggestedID;
INSERT INTO tblGeofenceCarStatus
VALUES
(
@CarSuggestedID, @geofenceidforresult,@geofencename,
@gpstime, @g.STDistance(@pprevious), 'Enter' );
END
ELSE
BEGIN
Print Not in Geofence
END
END; --- END POLYGON IF
FETCH NEXT FROM ShapeCursor INTO @ID , @CarIdx , @ShapeType;
END; --- END CHECK GEOFENCING RECTANGLE OR CIRCLE OR PLYGON
FETCH NEXT FROM SuggestCursor INTO @CarSuggestedID , @carlatprevious , @carlongprevious;
END;
CLOSE ShapeCursor;
DEALLOCATE ShapeCursor;
CLOSE SuggestCursor;
DEALLOCATE SuggestCursor;
SELECT * FROM tblGeofenceCarStatus;
END;
END; --- END SP BEGIN STATEMENT
以下解决方案将:
- 识别每辆车最近的位置
- 识别每辆车之前的位置
- 根据多边形字符串或矩形坐标构造地理围栏多边形
- 识别当前在 geo-fence 500 米范围内(从外部)或在 geo-fence 内的汽车
- 显示距 geo-fence 与之前位置的距离
;
WITH car_location_seq AS (
SELECT car_id
,ID
,latitude
,longitude
,ROW_NUMBER() OVER (PARTITION BY car_id ORDER BY ID DESC) AS Pos_Sequence
FROM #CarDistance
),
car_location AS (
SELECT c1.car_id
,geography::Point(c1.longitude, c1.latitude, 4326) AS Geo_Point_Current
,CASE WHEN c2.car_id IS NOT NULL THEN geography::Point(c2.longitude, c2.latitude, 4326) END AS Geo_Point_Previous
FROM car_location_seq c1 -- Most recent position
LEFT JOIN car_location_seq c2 -- Previous position
ON c1.car_id = c2.car_id
AND c2.Pos_Sequence = 2
WHERE c1.Pos_Sequence = 1
),
fences AS (
SELECT ID
,Car_ID
,CASE WHEN ShapeType = 'polygon' THEN geography::STPolyFromText('POLYGON((' + PolygonLatLng + '))', 4326)
WHEN ShapeType = 'rectangle' THEN geography::STPolyFromText('POLYGON((' +
CAST(maxlatitude AS VARCHAR(100)) + ' ' + CAST(minlongitude AS VARCHAR(100)) + ', ' +
CAST(minlatitude AS VARCHAR(100)) + ' ' + CAST(minlongitude AS VARCHAR(100)) + ', ' +
CAST(minlatitude AS VARCHAR(100)) + ' ' + CAST(maxlongitude AS VARCHAR(100)) + ', ' +
CAST(maxlatitude AS VARCHAR(100)) + ' ' + CAST(maxlongitude AS VARCHAR(100)) + ', ' +
CAST(maxlatitude AS VARCHAR(100)) + ' ' + CAST(minlongitude AS VARCHAR(100)) +
'))', 4326)
END AS Geo_Polygon
FROM #tblgeofencing2
)
SELECT f.ID AS Fence_ID
,c.car_id
,c.Geo_Point_Current
--,c.Geo_Point_Current.STAsText()
,f.Geo_Polygon
--,f.Geo_Polygon.STAsText()
,f.Geo_Polygon.STIntersects(c.Geo_Point_Current) AS Is_Inside_Fence_Current
,f.Geo_Polygon.STIntersects(c.Geo_Point_Previous) AS Is_Inside_Fence_Previous
,f.Geo_Polygon.STDistance(c.Geo_Point_Current) AS Distance_Current
,f.Geo_Polygon.STDistance(c.Geo_Point_Previous) AS Distance_Previous
--INTO #Relevant_Car_Positions
FROM fences f
INNER JOIN car_location c
ON f.car_id = c.car_id
WHERE f.Geo_Polygon.STDistance(c.Geo_Point_Current) < 500
;
示例输出:
您应该能够修改此代码以满足您的需要。例如,您可以先通过取消注释 INTO #Relevant_Car_Positions
.