如何获得米的距离

时间:2017-02-01 07:09:01

标签: sql-server sql-server-2012 sql-server-2008-r2 geography

我有下面的商店程序我想检查我的汽车纬度经度的距离哪个地理围栏距离最近如果距离以米为单位小于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

1 个答案:

答案 0 :(得分:1)

以下解决方案将:

  • 确定每辆车的最新位置
  • 识别每辆车的先前位置
  • 基于多边形字符串或矩形坐标构建地理围栏多边形
  • 识别当前距地理围栏500米(从外面)或在地理围栏内的汽车
  • 显示与之前位置相同的地理围栏距离
;
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
;

示例输出:

Sample query result

您应该能够调整此代码以满足您的需求。例如,您可以通过取消注释INTO #Relevant_Car_Positions来将查询输出存储到临时表中。