Differenze tra le versioni di "Individuare il punto di intersezione degli angoli di direzione di due elementi geografici rispetto all'osservatore"

Da Gambas-it.org - Wikipedia.
Riga 22: Riga 22:
 
<BR>Modalità di funzionamento:
 
<BR>Modalità di funzionamento:
 
<BR>1) aumentare lo zoom della mappa al valore desiderato, usando l'apposito Slider in alto a sinistra sulla mappa oppure ruotando la rotellina del mouse;
 
<BR>1) aumentare lo zoom della mappa al valore desiderato, usando l'apposito Slider in alto a sinistra sulla mappa oppure ruotando la rotellina del mouse;
<BR>2) cliccare con il tasto centrale del mouse sul primo punto (preso sempre in considerazione in senso orario rispetto a quello che sarà il secondo punto);
+
<BR>2) cliccare con il tasto centrale del mouse sul primo punto (considerando che il secondo punto dovrà essere preso in senso orario rispetto al primo);
 
<BR>3) inserire i gradi rilevati dalla bussola e premere OK;
 
<BR>3) inserire i gradi rilevati dalla bussola e premere OK;
 
<BR>4) cliccare con il tasto centrale del mouse sul secondo punto (preso sempre in considerazione in senso orario rispetto a quello che è il primo punto);
 
<BR>4) cliccare con il tasto centrale del mouse sul secondo punto (preso sempre in considerazione in senso orario rispetto a quello che è il primo punto);
Riga 34: Riga 34:
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
   
 
   
 
   With Me
 
   With Me
Riga 52: Riga 52:
 
   pn = .Children[0]
 
   pn = .Children[0]
 
   End With  
 
   End With  
 
 
'''End'''
 
 
   
 
   
  '''Public''' Sub Form_Close()
+
  End
 +
 +
 +
Public Sub Form_Close()
 
    
 
    
 
   Quit
 
   Quit
 
    
 
    
  '''End '''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub MapView1_MouseWheel()
+
  Public Sub MapView1_MouseWheel()
 
    
 
    
 
   Me.Caption = "Zoom = " & CStr(MapView1.Map.Zoom)
 
   Me.Caption = "Zoom = " & CStr(MapView1.Map.Zoom)
 
    
 
    
  '''End'''
+
  End
 +
 
   
 
   
  '''Public''' Sub MapView1_MouseDown()
+
  Public Sub MapView1_MouseDown()
 
    
 
    
 
   Dim pt As New Point(Mouse.X, Mouse.Y)
 
   Dim pt As New Point(Mouse.X, Mouse.Y)
Riga 75: Riga 77:
 
               " -  Lon. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lon, "0.000000")
 
               " -  Lon. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lon, "0.000000")
 
    
 
    
  '''End'''
+
  End
 +
 +
 +
Public Sub MapView1_MouseUp()
 
   
 
   
'''Public''' Sub MapView1_MouseUp()
 
 
 
 
   Dim pt As Point
 
   Dim pt As Point
 
    
 
    
Riga 109: Riga 112:
 
   Endif  
 
   Endif  
 
    
 
    
  '''End'''
+
  End
 +
 
   
 
   
  '''Public''' Sub MapView1_Draw()
+
  Public Sub MapView1_Draw()
 
    
 
    
 
   If Not Object.IsValid(c) Then
 
   If Not Object.IsValid(c) Then
Riga 148: Riga 152:
 
   End With
 
   End With
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Function ImmissioneGradi() As Short
+
  Private Function ImmissioneGradi() As Short
 
    
 
    
 
   Dim s As String
 
   Dim s As String
Riga 162: Riga 166:
 
   Return (CShort(Val(s)) - 90)
 
   Return (CShort(Val(s)) - 90)
 
    
 
    
  '''End'''
+
  End
  
  

Versione delle 07:51, 9 giu 2024

E' possibile conoscere la propria posizione sulla mappa, se non si è in possesso di dispositivo di rilevamento delle porprie coordinate (GPS, Galileo, etc), purché si disponga di una bussola (possibilmente di tipo "da rilevamento" o "da orientamento").

Bisognerà effettuare mediante la bussola la misurazione degli angoli di direzione che la propria posizione (ossia quella dell'osservatore) forma con ciascuno dei due elementi geografici reali rispetto alla direzione al nord (azimut). [Nota 1]

 1° elemento      Ⓝ           2° elemento
  geografico      :            geografico
      :               
       \          :              /
         \        :            /
          \       :          /
            \     :        /
             \  a :  b   /
               \^^:^^^^/
                \ :  /
                 \:/
                  🔭
              Osservatore

Ottenuti gli angoli dei due azimut (a° e b°), si potrà anche ottenere il punto di intersezione delle due direzioni che congiungono rispettivamente il 1° e il 2° elemento geografico con la posizione dell'Osservatore.

Mostriamo di seguito un possibile programma Gambas per ottenere il punto di intersezione delle due direzioni rispetto all'Osservatore, e quindi la posizione dell'Osservatore medesimo sulla mappa.
E' necessario attivare il Componente gb.map .
Modalità di funzionamento:
1) aumentare lo zoom della mappa al valore desiderato, usando l'apposito Slider in alto a sinistra sulla mappa oppure ruotando la rotellina del mouse;
2) cliccare con il tasto centrale del mouse sul primo punto (considerando che il secondo punto dovrà essere preso in senso orario rispetto al primo);
3) inserire i gradi rilevati dalla bussola e premere OK;
4) cliccare con il tasto centrale del mouse sul secondo punto (preso sempre in considerazione in senso orario rispetto a quello che è il primo punto);
3) inserire i gradi rilevati dalla bussola e premere OK.
Il punto di convergenza delle rette che attraversano i due punto presi in considerazione rappresenta il punto ove l'osservatore si trova sulla mappa.

Private MapView1 As MapView
Private pn As Panel
Private c As Short[]
Private r As Short
Private mmpp As New MapPoint[]


Public Sub Form_Open()

 With Me
   .W = Screen.AvailableWidth
   .H = Screen.AvailableHeight
   .Arrangement = Arrange.Fill
 End With
 
' Imposta la dimensione del raggio:
 r = 30000
 
 With MapView1 = New MapView(Me) As "MapView1"
  .Map.AddTile("topo", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png")
  .Font.Size = 8
  .Map["topo"].Copyright = "© OpenTopoMap"
' Individua dapprima l'Oggetto "Figlio" della "MapView", che è un "Panel":
  pn = .Children[0]
 End With 

End


Public Sub Form_Close()
 
 Quit
 
End


Public Sub MapView1_MouseWheel()
 
 Me.Caption = "Zoom = " & CStr(MapView1.Map.Zoom)
 
End


Public Sub MapView1_MouseDown()
 
 Dim pt As New Point(Mouse.X, Mouse.Y)
 
 Me.Caption = "Lat. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lat, "0.000000") &
              " -  Lon. " & Format(MapView1.Map.PixelToMapPointRel(pt).Lon, "0.000000")
 
End


Public Sub MapView1_MouseUp()

 Dim pt As Point
 
 If Not Mouse.Middle Then 
   Me.Caption = "Zoom = " & CStr(MapView1.Map.Zoom)
   Return 
 Endif
 
 pt = New Point(Mouse.X, Mouse.Y)

 If Object.IsValid(c) Then 
   If c.Count == 2 Then
     c = Null
     mmpp = Null
   Endif
 Endif
 If Not Object.IsValid(c) Then
    c = New Short[]
    mmpp = New MapPoint[]
 Endif
 
 c.Push(ImmissioneGradi())
 
' Si usa l'Oggetto "MapPoint" per garantire la coerenza del puntamento su un punto della mappa anche nel caso di spostamento o variazione dello zoom della mappa medesima:
 mmpp.Push(MapView1.Map.PixelToMapPointRel(pt))
 
 If mmpp.count == 2 Then
    Me.Caption = "Distanza fra i due punti: m. " & Format(MapPoint.Distance(mmpp[0], mmpp[1]), "0.00") &
    "  -  Bearing: " & Geo.DecToSex(MapPoint.Bearing(mmpp[0], mmpp[1]), 0)
 Endif 
 
End


Public Sub MapView1_Draw()
 
 If Not Object.IsValid(c) Then
   Return 
 Else
   If c.Count < 2 Then Return
 Endif 
 
 With Paint
' Disegna sull'Oggetto "Figlio" del "Panel", che è una "DrawingArea", la stessa che la Classe "MapView" usa per mostrare la mappa:
   .Begin(pn.Children[0])
' Disegna il primo obiettivo con un cerchietto rosso:
   .Brush = Paint.Color(Color.Red)
   .Arc(MapView1.Map.MapPointToPixelRel(mmpp[0]).X, MapView1.Map.MapPointToPixelRel(mmpp[0]).Y, 3, Rad(0), Rad(360), False)
' Disegna la linea del primo obiettivo:
   .MoveTo(MapView1.Map.MapPointToPixelRel(mmpp[0]).X, MapView1.Map.MapPointToPixelRel(mmpp[0]).Y)
   .LineTo(MapView1.Map.MapPointToPixelRel(mmpp[0]).X + (r * Cos(Rad(c[0]))), MapView1.Map.MapPointToPixelRel(mmpp[0]).Y + (r * Sin(Rad(c[0]))))
   .Stroke
   .MoveTo(MapView1.Map.MapPointToPixelRel(mmpp[0]).X, MapView1.Map.MapPointToPixelRel(mmpp[0]).Y)
' Aggiunge 180° per disegnare anche la parte opposta del raggio, completando così il diametro:
   .LineTo(MapView1.Map.MapPointToPixelRel(mmpp[0]).X + (r * Cos(Rad(c[0] + 180))), MapView1.Map.MapPointToPixelRel(mmpp[0]).Y + (r * Sin(Rad(c[0] + 180))))
   .Stroke
   
' Disegna il secondo obiettivo con un cerchietto rosso:
   .Brush = Paint.Color(Color.Blue)
   .Arc(MapView1.Map.MapPointToPixelRel(mmpp[1]).X, MapView1.Map.MapPointToPixelRel(mmpp[1]).Y, 3, Rad(0), Rad(360), False)
' Disegna la linea del secondo obiettivo:
   .MoveTo(MapView1.Map.MapPointToPixelRel(mmpp[1]).X, MapView1.Map.MapPointToPixelRel(mmpp[1]).Y)
   .LineTo(MapView1.Map.MapPointToPixelRel(mmpp[1]).X + (r * Cos(Rad(c[1]))), MapView1.Map.MapPointToPixelRel(mmpp[1]).Y + (r * Sin(Rad(c[1]))))
   .Stroke
   .MoveTo(MapView1.Map.MapPointToPixelRel(mmpp[1]).X, MapView1.Map.MapPointToPixelRel(mmpp[1]).Y)
' Aggiunge 180° per disegnare anche la parte opposta del raggio, completando così il diametro:
   .LineTo(MapView1.Map.MapPointToPixelRel(mmpp[1]).X + (r * Cos(Rad(c[1] + 180))), MapView1.Map.MapPointToPixelRel(mmpp[1]).Y + (r * Sin(Rad(c[1] + 180))))
   .Stroke
   .End
 End With
 
End


Private Function ImmissioneGradi() As Short
 
 Dim s As String
 
 s = InputBox("Immettere un valore intero (tra 0 e 360):")
 If IsNull(s) Then ImmissioneGradi() 
 If (Not IsNumber(s)) Or (Val(s) > 360) Or (Val(s) < 0) Then ImmissioneGradi()  
 
' Poiché il punto corrispondente a 0° è posto tra il I e il IV quadrante, sottrae 90° per porlo tra il I e il II quadrante lungo il verso ideale del Polo Nord magnetico:
 Return (CShort(Val(s)) - 90)
 
End


Note

[1] Come è noto, il Polo Nord "magnetico" non coincide esattamente con il Polo Nord "geografico" (che corrisponde a una delle estremità dell'asse di rotazione terrestre). Per ottenere la direzione esatta del Polo Nord "geografico", è necessario compensare la declinazione magnetica, ossia lo scostamento della direzione magnetica da quella geografica.


Riferimenti