我有下面的商店程序我想检查我的汽车纬度经度的距离哪个地理围栏距离最近如果距离以米为单位小于500显示地理围栏id哪个地理围栏id最近的汽车纬度经度。如果汽车纬度经度最近的多边形显示多边形ID和if矩形显示矩形id我在sql server中是新的,这就是为什么我在这里请帮助我的专业人士我非常感谢你,演示表在共享链接,
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
答案 0 :(得分:1)
以下解决方案将:
;
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
来将查询输出存储到临时表中。