如何获得以米为单位的距离

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