J'utilise Gmap.net API pour un projet de suivi de petits véhicules. Ce projet est sous forme de Windows C#. Je reçois des informations de l'appareil comme: Latitude, Longitude, Vitesse, En-tête et d'autres informations. L'information de cap est en degré (0 ~ 359), Comment je peux montrer que le véhicule se déplace dans une certaine direction avec une flèche?Comment montrer la direction de déplacement d'un véhicule dans Gmap.Net
Répondre
Ce n'est pas aussi trivial que cela puisse paraître. Une option consiste simplement à utiliser une image bitmap et à la faire pivoter si nécessaire. J'avais besoin d'un peu plus de flexibilité (et de vitesse) et utilisé les fonctions de dessin pour effectuer cette tâche.
En supposant que vous ayez la possibilité de dessiner des polygones sur la carte en utilisant les coordonnées locales (pixels), vous pouvez dessiner manuellement un indicateur. Par exemple, ce code:
int position_size = 20;
GPoint gp = FromLatLngToLocal(longlatposition);
Point[] pnts = new Point[4];
pnts[0] = new Point((int)gp.X - (position_size * 2), (int)gp.Y + (position_size * 2));
pnts[1] = new Point((int)gp.X, (int)gp.Y - (position_size * 4));
pnts[2] = new Point((int)gp.X + (position_size * 2), (int)gp.Y + (position_size * 2));
pnts[3] = new Point((int)gp.X, (int)gp.Y + position_size);
float heading_ = 45; //this is where you define how much to rotate
pnts = Rotate(pnts, new PointF(gp.X, gp.Y), heading_);
g.FillPolygon(new SolidBrush(color), pnts);
tirerai une flèche qui ressemble à ceci:
La fonction de rotation est une variation de ce poste: Rotate bunch of points thourgh an origin).
private static PointF[] Rotate(PointF[] point, PointF pivot, double angleDegree)
{
double angle = angleDegree * Math.PI/180;
double cos = Math.Cos(angle);
double sin = Math.Sin(angle);
PointF[] rotated = new PointF[point.Length];
for (int i = 0; i < point.Length; i++)
{
float dx = point[i].X - pivot.X;
float dy = point[i].Y - pivot.Y;
double x = (cos * dx) - (sin * dy) + pivot.X;
double y = (sin * dx) + (cos * dy) + pivot.Y;
rotated[i] = new PointF((float)x, (float)y);
}
return rotated;
}
Maintenant, la partie difficile est d'incorporer tout cela en utilisant le plugin GMap. Il y a plusieurs façons de le faire. Personnellement, j'ai choisi de modifier le code source GMap car cela donne le plus de flexibilité pour travailler avec les coordonnées des pixels. Une autre option, en supposant que vous ne voulez pas modifier la source, consiste à créer une nouvelle superposition de polygones et à mettre à jour les points lorsque vous souhaitez afficher une nouvelle position et un nouvel en-tête. Rappelez-vous simplement que la superposition de polygones prend des coordonnées en latitude, donc vous devrez faire quelques conversions pour que cela fonctionne correctement, surtout si vous ne voulez pas que l'indicateur de position s'adapte à tout le reste.
J'espère que cela aide.
Je sais que ce fil a presque un an mais c'est comme ça que je crée un marqueur de bateau que je fais pivoter en fonction de l'orientation du bateau. Je dessine aussi le bateau différemment en fonction du niveau de zoom.
Désolé pour le manque de commentaires!
Namespace GMap.NET.WindowsForms.Markers
Public Class GMapMarkerBoat
Inherits GMapMarker
Public Brush As Brush
Public boatHeading As Double
Public Sub New(ic As SEAS_DATA.ImageCluster, b As Brush)
MyBase.New(ic.LatLong)
boatHeading = ic.IMU_Heading
Brush = b
'Size of the marker
Size = New Size(8, 8)
End Sub
Public Overrides Sub OnRender(g As Graphics)
Dim newSize As Size
Dim maxZoomLevel As Integer = SEAS_Forms.frmMain.myMap.MaxZoom
Select Case SEAS_Forms.frmMain.myMap.Zoom
Case maxZoomLevel
newSize = New Size(Size.Width * 2, Size.Height * 2)
Case maxZoomLevel - 1 To maxZoomLevel
newSize = New Size(CInt(Size.Width * 1.5), CInt(Size.Height * 1.5))
Case maxZoomLevel - 2 To maxZoomLevel - 1
newSize = Size
Case SEAS_Forms.frmMain.myMap.MinZoom To maxZoomLevel - 2
newSize = New Size(CInt(Size.Width/2), CInt(Size.Height/2))
End Select
'boat
Dim boat(4) As PointF
boat(0).X = CSng(-newSize.Width/2)
boat(0).Y = CSng(-newSize.Height/2)
boat(1).X = (boat(0).X + newSize.Width)
boat(1).Y = boat(0).Y
boat(3).X = boat(0).X
boat(3).Y = (boat(0).Y + newSize.Height)
boat(2).X = boat(1).X
boat(2).Y = boat(3).Y
boat(4).X = CSng(boat(0).X - newSize.Width/2)
boat(4).Y = CSng(boat(0).Y + newSize.Width/2)
If SEAS_Forms.frmMain.myMap.Zoom > maxZoomLevel - 4 Then
boat = TransformAndRotate(boatHeading, boat) 'simplified rotation and transformation matrix
Else
boat = TransformAndRotate(0, boat)
End If
'start drawing here
Select Case SEAS_Forms.frmMain.myMap.Zoom
Case maxZoomLevel - 3 To maxZoomLevel
g.FillPolygon(Brush, boat)
Case SEAS_Forms.frmMain.myMap.MinZoom To maxZoomLevel - 3
Dim newRect As New RectangleF(boat(0).X, boat(0).Y, newSize.Width, newSize.Height)
g.FillEllipse(Brush, newRect)
End Select
End Sub
Private Function TransformAndRotate(heading As Double, points() As PointF) As PointF()
Dim cosRot As Double = Math.Cos((heading + 90) * Math.PI/180)
Dim sinRot As Double = Math.Sin((heading + 90) * Math.PI/180)
For i = 0 To points.Length - 1
Dim x As Single = points(i).X
Dim y As Single = points(i).Y
points(i).X = CSng((LocalPosition.X) + (x * cosRot - y * sinRot)) 'simplified rotation and transformation matrix
points(i).Y = CSng((LocalPosition.Y) + (x * sinRot + y * cosRot))
Next
Return points
End Function
End Class
End Namespace
L'objet classe personnalisée Je passe dans (IC ImageCluster) a les propriétés du PointLatLng et le cap.
Voici comment ajouter le marqueur
'add the marker to the overlay
newOverlay.Markers.Add(New GMap.NET.WindowsForms.Markers.GMapMarkerBoat(ic, Brushes.Red))
Faire un long triangle isocèle et tourner dans le sens du véhicule est en mouvement. Peut-être que l'un des triangles de la page suivante vous aidera: https://www.google.com/search?q=types+of+triangles&espv=2&biw=1680&bih=944&tbm=isch&tbo=u&source=univ&sa=X&sqi=2&ved=0ahUKEwjHh4Tnr7nPAhWCKyYKHUqNAcsQsAQIGw – jdweng