calculates the distance between two towns

calculates the distance between two towns

Postby Otto » Mon Oct 12, 2020 3:55 pm

Hello,
I converted a javascript program to FW.
This routine calculates the distance between two points (given the latitude/longitude of those points). It is being used to calculate the distance between two locations using GeoDataSource (TM) prodducts

Best regards,
Otto

Code: Select all  Expand view

#include "FiveWin.ch"
//----------------------------------------------------------------------------//

function Main()
   local  dist :=0
   local  lat1:=46.7528                         //Sillian
   local  lon1:=12.4211

   local  lat2:=48.2077                         //Lienz
   local  lon2:=16.3705
   local  unit:="K"



   dist = distance( lat1, lon1, lat2, lon2, unit )

   msginfo( dist )

   //https://www.luftlinie.org/Sillian/Wien

   //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   //:::                                                                         :::
   //:::  This routine calculates the distance between two points (given the     :::
   //:::  latitude/longitude of those points). It is being used to calculate     :::
   //:::  the distance between two locations using GeoDataSource (TM) prodducts  :::
   //:::                                                                         :::
   //:::  Definitions:                                                           :::
   //:::    South latitudes are negative, east longitudes are positive           :::
   //:::                                                                         :::
   //:::  Passed to function:                                                    :::
   //:::    lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)  :::
   //:::    lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)  :::
   //:::    unit = the unit you desire for results                               :::
   //:::           where: 'M' is statute miles (default)                         :::
   //:::                  'K' is kilometers                                      :::
   //:::                  'N' is nautical miles                                  :::
   //:::                                                                         :::
   //:::  Worldwide cities and other features databases with latitude longitude  :::
   //:::  are available at https://www.geodatasource.com                         :::
   //:::                                                                         :::
   //:::  For enquiries, please contact sales@geodatasource.com                  :::
   //:::                                                                         :::
   //:::  Official Web site: https://www.geodatasource.com                       :::
   //:::                                                                         :::
   //:::               GeoDataSource.com (C) All Rights Reserved 2018            :::
   //:::                                                                         :::
   //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

   function distance( lat1, lon1, lat2, lon2, unit)

  /*
    if ((lat1 == lat2) && (lon1 == lon2)) {
        return 0;
    }
    else {

    */

      local  radlat1 := PI() * lat1/180
      local  radlat2 := PI() * lat2/180
      local  theta := lon1-lon2
      local  radtheta := PI() * theta/180

      local  dist :=  sin(radlat1) *  sin(radlat2) +  cos(radlat1) *  cos(radlat2) *  cos(radtheta)

      if (dist > 1)
         dist = 1
      else
         dist = acos(dist)
         dist = dist * 180/PI()
         dist = dist * 60 * 1.1515

         if (unit=="K")
            dist = dist * 1.609344
         endif
         if (unit=="N")
            dist = dist * 0.8684
         endif
      endif

return dist

//----------------------------------------------------------------------------//


 
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6005
Joined: Fri Oct 07, 2005 7:07 pm

Re: calculates the distance between two towns

Postby Armando » Mon Oct 12, 2020 4:32 pm

Otto:

Nice and interesting job.

Regards
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Armando
 
Posts: 3061
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Re: calculates the distance between two towns

Postby Silvio.Falconi » Tue Oct 13, 2020 7:08 pm

Otto wrote:Hello,
I converted a javascript program to FW.
This routine calculates the distance between two points (given the latitude/longitude of those points). It is being used to calculate the distance between two locations using GeoDataSource (TM) prodducts

Best regards,
Otto

Code: Select all  Expand view

#include "FiveWin.ch"
//----------------------------------------------------------------------------//

function Main()
   local  dist :=0
   local  lat1:=46.7528                         //Sillian
   local  lon1:=12.4211

   local  lat2:=48.2077                         //Lienz
   local  lon2:=16.3705
   local  unit:="K"



   dist = distance( lat1, lon1, lat2, lon2, unit )

   msginfo( dist )

   //https://www.luftlinie.org/Sillian/Wien

   //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   //:::                                                                         :::
   //:::  This routine calculates the distance between two points (given the     :::
   //:::  latitude/longitude of those points). It is being used to calculate     :::
   //:::  the distance between two locations using GeoDataSource (TM) prodducts  :::
   //:::                                                                         :::
   //:::  Definitions:                                                           :::
   //:::    South latitudes are negative, east longitudes are positive           :::
   //:::                                                                         :::
   //:::  Passed to function:                                                    :::
   //:::    lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)  :::
   //:::    lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)  :::
   //:::    unit = the unit you desire for results                               :::
   //:::           where: 'M' is statute miles (default)                         :::
   //:::                  'K' is kilometers                                      :::
   //:::                  'N' is nautical miles                                  :::
   //:::                                                                         :::
   //:::  Worldwide cities and other features databases with latitude longitude  :::
   //:::  are available at https://www.geodatasource.com                         :::
   //:::                                                                         :::
   //:::  For enquiries, please contact sales@geodatasource.com                  :::
   //:::                                                                         :::
   //:::  Official Web site: https://www.geodatasource.com                       :::
   //:::                                                                         :::
   //:::               GeoDataSource.com (C) All Rights Reserved 2018            :::
   //:::                                                                         :::
   //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

   function distance( lat1, lon1, lat2, lon2, unit)

  /*
    if ((lat1 == lat2) && (lon1 == lon2)) {
        return 0;
    }
    else {

    */

      local  radlat1 := PI() * lat1/180
      local  radlat2 := PI() * lat2/180
      local  theta := lon1-lon2
      local  radtheta := PI() * theta/180

      local  dist :=  sin(radlat1) *  sin(radlat2) +  cos(radlat1) *  cos(radlat2) *  cos(radtheta)

      if (dist > 1)
         dist = 1
      else
         dist = acos(dist)
         dist = dist * 180/PI()
         dist = dist * 60 * 1.1515

         if (unit=="K")
            dist = dist * 1.609344
         endif
         if (unit=="N")
            dist = dist * 0.8684
         endif
      endif

return dist

//----------------------------------------------------------------------------//


 

this is a good Job
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby Silvio.Falconi » Wed Oct 14, 2020 8:57 am

Otto, Do you Know how show on a GoogleMAp a line from one point to another and calculate the distance ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby Silvio.Falconi » Thu Oct 15, 2020 3:09 pm

Otto,

the lat and long are wrong

but I create the map with a new class ( no googlemap)
these are right

Local aLineaTest:={;
{ "Brunic" , "46.79300837", "11.95655823" },;
{ "Sillian" , "46.7474103", "12.4196248" },;
{ "Lienz" , "46.82872429" , "12.76405334" } }


Image
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby Otto » Thu Oct 15, 2020 5:21 pm

Hello Silvio,
>the lat and long are wrong
what do you mean with this.

Very good. Can you share your source code.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6005
Joined: Fri Oct 07, 2005 7:07 pm

Re: calculates the distance between two towns

Postby Silvio.Falconi » Thu Oct 15, 2020 5:47 pm

Otto wrote:Hello Silvio,
>the lat and long are wrong
what do you mean with this.

Very good. Can you share your source code.
Best regards,
Otto


I mean the latitude the longitude of Sillian and Lienz that you wrote are wrong

I use a MapControl class that they published at least two years ago,
I'm doing some tests such as marking the route of a bus in my city you see below,
the starting point is marked with a red marker, the stations they are marked with a blue marker and finally the finish in green

Image
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby AntoninoP » Fri Oct 16, 2020 12:48 pm

Silvio.Falconi wrote:I use a MapControl class that they published at least two years ago,

:D :D am I "they" ?!
Anyway it is not private, it was an experiment, so I re-share this messy and undocumented code:

Code: Select all  Expand view
#include <fivewin.ch>

********** TEST CODE **********
proc main
   LOCAL oWnd, oMap, oMarker, bDraw
   Local oDataLink := CreateObject("Datalinks")

   DEFINE WINDOW oWnd TITLE "Map Test"
   SetWndDefault(oWnd)
   oMarker := FW_ReadImage(oWnd,"667px-Map_marker.svg.png")
   oMap := TMapControl():New()
   //oMap:bUrl := {|x,y,z| MapControlGooogleMaps(x,y,z)}
   //oMap:nMaxZoom := 20
   //oMap:bUrl := {|x,y,z| MapControlBing(x,y,z)}
   //oMap:nMaxZoom := 20
   oMap:SetCenter(13.7,42.6,10)
   bDraw := {|hDC,x,y| FW_DrawImage(hDC, oMarker, {y-30,x-10,y,x+10},.t.) }
   oMap:AddMarker(13.7025,42.6582,30,bDraw)
   oWnd:oClient := oMap
   ACTIVATE WINDOW oWnd
*******************************

/// https://wiki.openstreetmap.org/wiki/Sli ... _tilenames
static function MapControlOSMMaps(x,y,z)
   LOCAL cUrl
   static lastServerUsed:=0
   lastServerUsed+=1
   if lastServerUsed>3
      lastServerUsed:=1
   endif
   cUrl := 'https://' + {"a","b","c"}[lastServerUsed] + '.tile.openstreetmap.org/{z}/{x}/{y}.png'
   cUrl := StrTran(cUrl,"{z}", allTrim(str(z)))
   cUrl := StrTran(cUrl,"{x}", allTrim(str(x)))
   cUrl := StrTran(cUrl,"{y}", allTrim(str(y)))
return cUrl

function MapControlGooogleMaps(x,y,z)
   LOCAL cUrl
   static lastServerUsed:=-1
   lastServerUsed+=1
   if lastServerUsed>3
      lastServerUsed:=0
   endif
   cUrl := 'http://mt'+str(lastServerUsed,1)+'.google.com/vt/lyrs=m&' + 'x={x}&' + 'y={y}&' + 'z={z}&' + 's=Ga'
   cUrl := StrTran(cUrl,"{z}", allTrim(str(z)))
   cUrl := StrTran(cUrl,"{x}", allTrim(str(x)))
   cUrl := StrTran(cUrl,"{y}", allTrim(str(y)))
return cUrl

function MapControlBing(x,y,z)
   LOCAL cQuad:="", i, n, v
   static lastServerUsed:=-1
   lastServerUsed+=1
   if lastServerUsed>3
      lastServerUsed:=0
   endif
   for i:=z-1 to 0 step -1
      n := hb_bitShift(1,i)
      v:=0
      if(hb_bitAnd(x,n)>0); v+=1; endif
      if(hb_bitAnd(y,n)>0); v+=2; endif
      cQuad += str(v,1)
   next
return "http://ecn.t"+str(lastServerUsed,1)+".tiles.virtualearth.net/tiles/r"+cQuad+".jpeg?g=414&mkt=en"

class TMapControl FROM TControl
   CLASSDATA lRegistered AS LOGICAL
   CLASSDATA bUrl as codeBlock INIT {|x,y,z| MapControlOSMMaps(x,y,z) }
   CLASSDATA nMaxZoom AS NUMERIC INIT 19
   CLASSDATA bDefaultMarkerDraw as CodeBlock
   DATA oTimer
   DATA aHttps             // Queue of downloading images, array of { "Msxml2.XMLHTTP.6.0", zoom, x, y, Seconds(), cUrl }
   DATA nZoom, nLat, nLon  // current zoom and center of the screen
   DATA aMarkers AS ARRAY INIT {}   // Couples of lat+lon to mark on map
   DATA aImages AS ARRAY INIT {}    // Array of loaded images
   DATA aTopLeftTileInfo            // Information about tile at top left corner { xpos, ypos, x-tile, y-tile }
   DATA lastMousePos, lastRenderTime   // mouse down position and seconds of last rendering

   METHOD New( nRow, nCol, oWnd, nWidth, nHeight ) CONSTRUCTOR
   METHOD End()
   METHOD Display() INLINE ::BeginPaint(),::Paint(),::EndPaint(),0
   METHOD EraseBkGnd( ) INLINE 1
   METHOD Paint()

   Method SetCenter(nLon,nLat,zoom)
   Method AddMarker(nLon,nLat, bDraw)

   METHOD RButtonDown(nRow, nCol, nKeyFlags, lTouch)
   METHOD LButtonDown(nRow, nCol, nKeyFlags, lTouch)
   METHOD MouseMove( nRow, nCol, nKeyFlags )
   METHOD MouseWheel( nKey, nDelta, nXPos, nYPos )

   METHOD TimerEvent()

   METHOD GetImage(x,y,zoom,lQueue) HIDDEN
   METHOD GetTileNumber(lon,lat,pixelSize,zoom)
   METHOD GetCoordsFromTile(x,y,zoom)
   METHOD GetCoordsFromPixel(x,y)

   METHOD PaintTile(hDCMem,hDCBmp,l,t,tx,ty,zoom) HIDDEN

endclass


METHOD New( nRow, nCol, oWnd, nWidth, nHeight ) CLASS TMapControl
   DEFAULT nRow := 10, nCol := 10, oWnd := GetWndDefault()
   DEFAULT nWidth := 500
   DEFAULT nHeight := 300
   ::nZoom := 15
   ::nLon := 0
   ::nLat := 0
   ::aMarkers := {}

   ::oWnd      := oWnd
   ::nId         := ::GetNewId()
   ::nStyle      := nOR( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_BORDER )
   ::nTop        := nRow
   ::nLeft       := nCol
   ::nBottom     := ::nTop + nHeight - 1
   ::nRight      := ::nLeft + nWidth

   ::aHttps := {}

   ::Register( nOR( CS_VREDRAW, CS_HREDRAW ) )

   if ! Empty( oWnd:hWnd )
      ::Create( )
      oWnd:AddControl( Self )
   else
      oWnd:DefControl( Self )
   endif

   DEFINE TIMER ::oTimer OF SELF INTERVAL 0.1 ACTION ::TimerEvent()
   ::oTimer:Activate()

   if empty(::bDefaultMarkerDraw)
      ::bDefaultMarkerDraw := {|hDC,x,y| MoveTo(hDC,x-5,y-5), LineTo(hDC,x+5,y+5),MoveTo(hDC,x-5,y+5),LineTo(hDC,x+5,y-5) }
   endif
return Self

METHOD End() class TMapControl
   if .not. empty(::oTimer)
      ::oTimer:Deactivate()
      ::oTimer:End()
   endif
return ::Super:End()

Method SetCenter(nLon,nLat,zoom) class TMapControl
   local r := {::nLon,::nLat}
   ::nLon := nLon
   ::nLat := nLat
   ::nZoom := zoom
return r

Method AddMarker(nLon,nLat,pixelSize,bDraw) class TMapControl
   default bDraw := ::bDefaultMarkerDraw
   default pixelSize := 5
return aAdd(::aMarkers, {nLon,nLat, pixelSize,bDraw})

#define SRCCOPY 13369376

METHOD Paint() class TMapControl
   LOCAL x,y, img, ix,iy, top, left, sx,sy,  hBmpMem
   LOCAL w := ::nWidth,  h := ::nHeight, hDCMem, hDCBmp
   hDCMem  = CreateCompatibleDC( ::hDC )
   hBmpMem = CreateCompatibleBitmap( ::hDC, w, h )
   SelectObject( hDCMem, hBmpMem )
   FillRect( hDCMem, {0,0,h,w}, ::oBrush:hBrush )
   // get tile of center
   x := ::GetTileNumber(::nLon,::nLat)
   y := x[2]
   x := x[1]
   // move the desired pixel in the centre of canvas
   sx := floor(x)
   sy := floor(y)
   top  := h/2 - int((y-sy)*256)
   left := w/2 - int((x-sx)*256)
   // check for fill all area
   do while top>0
      sy-=1
      top-=256
   enddo
   do while left>0
      sx-=1
      left-=256
   enddo
   // draw the map
   ::lastRenderTime := Seconds()
   hDCBmp := CreateCompatibleDC( ::hDC )
   for iy:=0 to ceiling((h-top)/256)
      for ix:=0 to ceiling((w-left)/256)
         ::PaintTile(hDCMem,hDCBmp,left+ix*256,top+iy*256 ,sx+ix,sy+iy,::nZoom)
      next
   next
   DeleteDC( hDCBmp )
   // draw the markers
   for ix:=1 to len(::aMarkers)
      x := ::GetTileNumber(::aMarkers[ix,1],::aMarkers[ix,2])
      y := (x[2] - sy) * 256 + top
      x := (x[1] - sx) * 256 + left
      if x>-::aMarkers[ix,3] .and. x<w+::aMarkers[ix,3] .and. ;
         y>-::aMarkers[ix,3] .and. Y<h+::aMarkers[ix,3]
         Eval(::aMarkers[ix,4],hDCMem,x,y )
      endif
   next
   // save these infos
   ::aTopLeftTileInfo := {top,left,sx,sy}

   //img := "Queue len: " + alltrim(str(len(::aHttps)))
   //TextOut( hDCMem, 4, 4, img, Len( img ) )
   BitBlt( ::hDC, 0,0, w, h, hDCMem, 0,0, SRCCOPY )
   DeleteDC(hDCMem)
return nil

METHOD PaintTile(hDCMem,hDCBmp,l,t,tx,ty,zoom)
   LOCAL img, sx,sy, ix, iy, n
   img := ::GetImage(tx,ty,zoom)
   if .not. empty(img)
         SelectObject(hDCBmp, img)
         BitBlt( hDCMem, l,t, 256, 256, hDCBmp, 0,0, SRCCOPY )
         return nil
   endif

   // try less zoomed images (if they are not in cache it are not downloaded)
   img := ::GetImage(hb_bitShift(tx,-1),hb_bitShift(ty,-1),zoom-1,.F.)
   if .not. empty(img)
      SelectObject(hDCBmp, img)
      StretchBlt( hDCMem, l,t, 256, 256, hDCBmp, hb_bitAnd(tx,1)*128,hb_bitAnd(ty,1)*128,128,128, SRCCOPY )
      return nil
   endif


   sx := hb_bitShift(tx,1)
   sy := hb_bitShift(ty,1)
   for iy:=0 to 1
      for ix:=0 to 1
         img := ::GetImage(sx+ix,sy+iy,zoom+1,.F.)
         if .not. empty(img)
            SelectObject(hDCBmp, img)
            StretchBlt( hDCMem, l+ix*128,t+iy*128, 128, 128, hDCBmp, 0,0,255,255, SRCCOPY )
         endif
      next
   next
return nil

METHOD TimerEvent() class TMapControl
   LOCAL lRedraw := .F., oHttp, img, idx

   for idx:=1 to len(::aHttps)
      oHttp := ::aHttps[idx]
      if oHttp[1]:readyState = 4
         // downloaded a missing image!
         img := GDIP_ImageFromStr(oHttp[1]:ResponseBody(), .t., .f.)
         if .not. empty(img) // correctly created
            lRedraw := .T.
            aAdd(::aImages, { img, oHttp[2], oHttp[3], oHttp[4] })
         endif
         hb_ADel(::aHttps,idx,.t.)
      else
         // stop the unfinisched download that are not relative of current view
         if oHttp[5]<::lastRenderTime
            oHttp[1]:abort()
            hb_ADel(::aHttps,idx,.t.)
         endif
      endif
   next

   if lRedraw
      ::Refresh()
   endif
return nil

// directly from OpenStreetMap wiki
METHOD GetTileNumber(lon,lat,zoom) class TMapControl
   LOCAL x,y,n, latRad
   DEFAULT zoom := ::nZoom
   n := hb_bitShift(1, zoom)
   latRad := lat * PI() / 180
   x := n * (lon + 180) / 360
   y := n * (1-(log(tan(latRad) + 1/cos(latRad)) / PI())) / 2
   do while(x<0)
      x+=n
   enddo
   do while(x>=n)
      x-=n
   enddo
   if y<0
      y:=0
   endif
   if y>=n
      y:=n-1
   endif
return {x,y}

// directly from OpenStreetMap wiki
METHOD GetCoordsFromTile(x,y,zoom) class TMapControl
   LOCAL lon, lat, n, lat_rad
   DEFAULT zoom := ::nZoom
   n := hb_bitShift(1, zoom)
   lon = x / n * 360.0 - 180.0
   lat_rad = atan(sinh(PI() * (1 - 2 * y / n)))
   lat = lat_rad * 180.0 / PI()
return {lon,lat}

// screen to tile, with decimal, using aTopLeftTileInfo
METHOD GetCoordsFromPixel(x,y)  class TMapControl
   LOCAL top  := ::aTopLeftTileInfo[1]
   LOCAL left := ::aTopLeftTileInfo[2]
   LOCAL sx   := ::aTopLeftTileInfo[3]
   LOCAL sy   := ::aTopLeftTileInfo[4]
return ::GetCoordsFromTile(sx+(x-left)/256,sy+(y-top)/256)

METHOD LButtonDown(nRow, nCol, nKeyFlags, lTouch) class TMapControl
   ::lastMousePos := {nRow,nCol}
return ::Super:LButtonDown( nRow, nCol, nKeyFlags, lTouch )

METHOD RButtonDown(nRow, nCol, nKeyFlags, lTouch) class TMapControl
   ::lastMousePos := {nRow,nCol}
return ::Super:RButtonDown( nRow, nCol, nKeyFlags, lTouch )

METHOD MouseMove( nRow, nCol, nKeyFlags ) class TMapControl
   LOCAL oldMouseCoords,newMouseCoords
   if (nKeyFlags<>1 .and. nKeyFlags<>2) .or. empty(::lastMousePos)
      return 0
   endif
   oldMouseCoords := ::GetCoordsFromPixel(::lastMousePos[2],::lastMousePos[1])
   newMouseCoords := ::GetCoordsFromPixel(nCol,nRow)
   ::nLon += oldMouseCoords[1] - newMouseCoords[1]
   ::nLat += oldMouseCoords[2] - newMouseCoords[2]
   ::lastMousePos := {nRow,nCol}
   ::Refresh()
return ::Super:MouseMove( nRow, nCol, nKeyFlags )

METHOD MouseWheel( nKey, nDelta, nXPos, nYPos )  class TMapControl
   if nDelta>0 .and. ::nZoom<::nMaxZoom
      ::nZoom+=1
   endif
   if nDelta<0 .and. ::nZoom>0
      ::nZoom-=1
   endif
   ::Refresh()
return ::Super:MouseWheel( nKey, nDelta, nXPos, nYPos )


METHOD GetImage(x,y,zoom,lQueue) class TMapControl
   local n, cUrl, img
   LOCAL oHttp
   DEFAULT zoom := ::nZoom
   DEFAULT lQueue := .T.

   x:=int(x)
   y:=int(y)
   // looking for the image in the "cache"
   n:= aScan(::aImages, {|v| v[2]=zoom .and. v[3]=x .and. v[4]=y })
   if n>0
      // move the last returned image on top of cache
      img := ::aImages[n][1]
      //aDel(::aImages,n)
      //::aImages[len(::aImages)] := img
      return img
   endif
   if .not. lQueue
      return nil
   endif
   // TODO: Limit cache size
   if (n:=aScan(::aHttps, {|v| v[2] = zoom .and. v[3] = x .and. v[4] = y})) > 0
      // already in download, update last query time
      ::aHttps[n,5]:=Seconds()
      return nil
   endif
   cUrl := eval(::bUrl, x,y, zoom)
   begin sequence
      oHttp := win_oleCreateObject( "Msxml2.XMLHTTP.6.0" )
      oHttp:Open("GET", cUrl, .T. )
      oHttp:Send()
      if oHttp:readyState <> 4
         if oHttp:readyState=1 .or. oHttp:readyState=3
            aAdd(::aHttps,{ oHttp, zoom, x, y, Seconds(), cUrl })
         endif
      else
         img := GDIP_ImageFromStr(oHttp:ResponseBody(), .t., .f.)
         if .not. empty(img)
            aAdd(::aImages, { img, zoom, x, y })
         endif
      endif
   end sequence
return img
AntoninoP
 
Posts: 375
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy

Re: calculates the distance between two towns

Postby Silvio.Falconi » Sat Oct 17, 2020 7:59 am

AntoninoP wrote:
Silvio.Falconi wrote:I use a MapControl class that they published at least two years ago,

:D :D am I "they" ?!
Anyway it is not private, it was an experiment, so I re-share this messy and undocumented code:



it was not my intention to offend anyone, "they" is a mistake I made in writing
so much so that in the image it is clearly written that the class belongs to a certain Signor Antonino
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby Otto » Sat Oct 17, 2020 9:38 pm

Hello Antonino,
thank you so much for this source code.
All is working fine.
Silvio can you please show how you inserted the markers.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6005
Joined: Fri Oct 07, 2005 7:07 pm

Re: calculates the distance between two towns

Postby Silvio.Falconi » Sun Oct 18, 2020 4:03 pm

Read the class before..


For show markervyou must use use omap:addmarker method
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby Otto » Sun Oct 18, 2020 4:59 pm

Hello Silvio,
Thank you.
I see that there are values inside ::aMarkers.
But there are no markers painted.
Best regards,
Otto


xbrowse( ::aMarkers )

// draw the markers
for ix:=1 to len(::aMarkers)
x := ::GetTileNumber(::aMarkers[ix,1],::aMarkers[ix,2])
y := (x[2] - sy) * 256 + top
x := (x[1] - sx) * 256 + left
if x>-::aMarkers[ix,3] .and. x<w+::aMarkers[ix,3] .and. ;
y>-::aMarkers[ix,3] .and. Y<h+::aMarkers[ix,3]
Eval(::aMarkers[ix,4],hDCMem,x,y )
endif
next
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6005
Joined: Fri Oct 07, 2005 7:07 pm

Re: calculates the distance between two towns

Postby Silvio.Falconi » Sun Oct 18, 2020 11:58 pm

I NOT UNDERSTOOD
YOU MUST INSERT
OMAP:ADDMARKER(LONG,LAT,BDRAW)
AND THIS DRAW THE MARKER ON X,Y
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 6772
Joined: Thu Oct 18, 2012 7:17 pm

Re: calculates the distance between two towns

Postby Otto » Mon Oct 19, 2020 6:26 am

Hello Silvio,
This is what I tried. But I do not see the marker.
I see that the array containing the marker is filled. But in my case, the marker is not painted.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6005
Joined: Fri Oct 07, 2005 7:07 pm

Re: calculates the distance between two towns

Postby AntoninoP » Mon Oct 19, 2020 6:51 am

Hi Otto,
see this piece of code:
Code: Select all  Expand view
  bDraw := {|hDC,x,y| FW_DrawImage(hDC, oMarker, {y-30,x-10,y,x+10},.t.) }
   oMap:AddMarker(13.7025,42.6582,30,bDraw)

The method AddMarker has parameters: Longitude, Latitude, Radius and a Block,
The map drawing code calls the Block if the point at Longitude, Latitude is inside the screen or near the border of less "radius" pixels.
If you don't provide the drawing codeblock the mapControl draw a little X on the marker (see bDefaultMarkerDraw)
How to obtain the Longitude and Latitude, we are already talking about it on other thread viewtopic.php?f=3&t=36454
AntoninoP
 
Posts: 375
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Rick Lipkin and 104 guests