This commit is contained in:
djes
2016-09-05 16:42:00 +02:00
parent 3a889a9bdd
commit f5a382ff59

209
PBMap.pb
View File

@@ -60,12 +60,12 @@ Module PBMap
EnableExplicit EnableExplicit
Structure Location Structure GeographicCoordinates
Longitude.d Longitude.d
Latitude.d Latitude.d
EndStructure EndStructure
Structure Position Structure Coordinates
x.d x.d
y.d y.d
EndStructure EndStructure
@@ -77,7 +77,7 @@ Module PBMap
;- Tile Structure ;- Tile Structure
Structure Tile Structure Tile
Position.Position Position.Coordinates
PBMapTileX.i PBMapTileX.i
PBMapTileY.i PBMapTileY.i
PBMapZoom.i PBMapZoom.i
@@ -90,18 +90,18 @@ Module PBMap
EndStructure EndStructure
Structure TileBounds Structure TileBounds
NorthWest.Position NorthWest.Coordinates
SouthEast.Position SouthEast.Coordinates
EndStructure EndStructure
Structure DrawingParameters Structure DrawingParameters
Position.Position TilePosition.Coordinates
Bounds.TileBounds Bounds.TileBounds
Canvas.i Canvas.i
PBMapTileX.i PBMapTileX.i
PBMapTileY.i PBMapTileY.i
PBMapZoom.i PBMapZoom.i
TargetLocation.Location TargetLocation.GeographicCoordinates
CenterX.i CenterX.i
CenterY.i CenterY.i
DeltaX.i DeltaX.i
@@ -128,7 +128,7 @@ Module PBMap
EndStructure EndStructure
Structure Marker Structure Marker
Location.Location ; Marker latitude and longitude Location.GeographicCoordinates ; Marker latitude and longitude
color.l ; Marker color color.l ; Marker color
CallBackPointer.i ; @Procedure(X.i, Y.i) to DrawPointer (you must use VectorDrawing lib) CallBackPointer.i ; @Procedure(X.i, Y.i) to DrawPointer (you must use VectorDrawing lib)
EndStructure EndStructure
@@ -144,13 +144,13 @@ Module PBMap
Gadget.i ; Canvas Gadget Id Gadget.i ; Canvas Gadget Id
Font.i ; Font to uses when write on the map Font.i ; Font to uses when write on the map
Timer.i Timer.i
TargetLocation.Location ; Latitude and Longitude from focus point TargetLocation.GeographicCoordinates ; Latitude and Longitude from focus point
Drawing.DrawingParameters ; Drawing parameters based on focus point Drawing.DrawingParameters ; Drawing parameters based on focus point
; ;
CallBackLocation.i ; @Procedure(latitude.d,lontitude.d) CallBackLocation.i ; @Procedure(latitude.d,lontitude.d)
CallBackMainPointer.i ; @Procedure(X.i, Y.i) to DrawPointer (you must use VectorDrawing lib) CallBackMainPointer.i ; @Procedure(X.i, Y.i) to DrawPointer (you must use VectorDrawing lib)
; ;
Position.PixelPosition ; Actual focus point coords in pixels (global) PixelPosition.PixelPosition ; Actual focus point coords in pixels (global)
MoveStartingPoint.PixelPosition ; Start mouse position coords when dragging the map MoveStartingPoint.PixelPosition ; Start mouse position coords when dragging the map
; ;
Array ServerURL.s(0) ; Web URL ex: http://tile.openstreetmap.org/ Array ServerURL.s(0) ; Web URL ex: http://tile.openstreetmap.org/
@@ -170,7 +170,7 @@ Module PBMap
; ;
MainDrawingThread.i MainDrawingThread.i
TileThreadMutex.i; ;Mutex to protect resources TileThreadMutex.i; ;Mutex to protect resources
List track.Location() ; To display a GPX track List track.GeographicCoordinates() ; To display a GPX track
List Marker.Marker() ; To diplay marker List Marker.Marker() ; To diplay marker
EditMarkerIndex.l EditMarkerIndex.l
@@ -388,8 +388,8 @@ Module PBMap
;*** Converts coords to tile.decimal ;*** Converts coords to tile.decimal
;Warning, structures used in parameters are not tested ;Warning, structures used in parameters are not tested
Procedure LatLon2XY(*Location.Location, *Coords.Position) Procedure LatLon2XY(*Location.GeographicCoordinates, *Coords.Coordinates, Zoom)
Protected n.d = Pow(2.0, PBMap\Zoom) Protected n.d = Pow(2.0, Zoom)
Protected LatRad.d = Radian(*Location\Latitude) Protected LatRad.d = Radian(*Location\Latitude)
*Coords\x = n * (Mod( *Location\Longitude + 180.0, 360) / 360.0 ) *Coords\x = n * (Mod( *Location\Longitude + 180.0, 360) / 360.0 )
*Coords\y = n * ( 1.0 - Log(Tan(LatRad) + (1.0/Cos(LatRad))) / #PI ) / 2.0 *Coords\y = n * ( 1.0 - Log(Tan(LatRad) + (1.0/Cos(LatRad))) / #PI ) / 2.0
@@ -399,8 +399,8 @@ Module PBMap
;*** Converts tile.decimal to coords ;*** Converts tile.decimal to coords
;Warning, structures used in parameters are not tested ;Warning, structures used in parameters are not tested
Procedure XY2LatLon(*Coords.Position, *Location.Location) Procedure XY2LatLon(*Coords.Coordinates, *Location.GeographicCoordinates, Zoom)
Protected n.d = Pow(2.0, PBMap\Zoom) Protected n.d = Pow(2.0, Zoom)
Protected LatitudeRad.d Protected LatitudeRad.d
;Ensures the longitude to be in the range [-180;180[ ;Ensures the longitude to be in the range [-180;180[
*Location\Longitude = Mod(Mod(*Coords\x / n * 360.0, 360.0) + 360.0, 360.0) - 180 *Location\Longitude = Mod(Mod(*Coords\x / n * 360.0, 360.0) + 360.0, 360.0) - 180
@@ -413,11 +413,11 @@ Module PBMap
*Location\Latitude = Degree(LatitudeRad) *Location\Latitude = Degree(LatitudeRad)
EndProcedure EndProcedure
Procedure LatLon2Pixel(*Location.Location, *Pixel.PixelPosition) Procedure LatLon2Pixel(*Location.GeographicCoordinates, *Pixel.PixelPosition, Zoom)
Protected Pos.Position Protected Pos.Coordinates
Protected tilemax = Pow(2.0, PBMap\Zoom) Protected tilemax = Pow(2.0, Zoom)
Protected cx.d = PBMap\Drawing\CenterX, dpx.d = PBMap\Drawing\Position\x Protected cx.d = PBMap\Drawing\CenterX, dpx.d = PBMap\Drawing\TilePosition\x
LatLon2XY(*Location, @Pos) LatLon2XY(*Location, @Pos, Zoom)
Protected px.d = Pos\x Protected px.d = Pos\x
;check the x boundaries of the map to adjust the position (coz of the longitude wrapping) ;check the x boundaries of the map to adjust the position (coz of the longitude wrapping)
If dpx - px > tilemax / 2 If dpx - px > tilemax / 2
@@ -433,14 +433,14 @@ Module PBMap
;Debug "c0" ;Debug "c0"
*Pixel\x = cx + (px - dpx) * PBMap\TileSize *Pixel\x = cx + (px - dpx) * PBMap\TileSize
EndIf EndIf
*Pixel\y = PBMap\Drawing\CenterY + (Pos\y - PBMap\Drawing\Position\y) * PBMap\TileSize *Pixel\y = PBMap\Drawing\CenterY + (Pos\y - PBMap\Drawing\TilePosition\y) * PBMap\TileSize
;Debug "Longitude : " + StrD(*Location\Longitude) + " ; Pos : " + StrD(Pos\x) + " ; Drawing pos : " + StrD(PBMap\Drawing\Position\x) + "/" + Str(tilemax) + ;Debug "Longitude : " + StrD(*Location\Longitude) + " ; Pos : " + StrD(Pos\x) + " ; Drawing pos : " + StrD(PBMap\Drawing\Position\x) + "/" + Str(tilemax) +
; " ; XY : " + Str(*Pixel\x) + "," + Str(*Pixel\y) ; " ; XY : " + Str(*Pixel\x) + "," + Str(*Pixel\y)
EndProcedure EndProcedure
; HaversineAlgorithm ; HaversineAlgorithm
; http://andrew.hedges.name/experiments/haversine/ ; http://andrew.hedges.name/experiments/haversine/
Procedure.d HaversineInKM(*posA.Location, *posB.Location) Procedure.d HaversineInKM(*posA.GeographicCoordinates, *posB.GeographicCoordinates)
Protected eQuatorialEarthRadius.d = 6378.1370;6372.795477598; Protected eQuatorialEarthRadius.d = 6378.1370;6372.795477598;
Protected dlong.d = (*posB\Longitude - *posA\Longitude); Protected dlong.d = (*posB\Longitude - *posA\Longitude);
Protected dlat.d = (*posB\Latitude - *posA\Latitude) ; Protected dlat.d = (*posB\Latitude - *posA\Latitude) ;
@@ -452,13 +452,13 @@ Module PBMap
ProcedureReturn distance ; ProcedureReturn distance ;
EndProcedure EndProcedure
Procedure.d HaversineInM(*posA.Location, *posB.Location) Procedure.d HaversineInM(*posA.GeographicCoordinates, *posB.GeographicCoordinates)
ProcedureReturn (1000 * HaversineInKM(@*posA,@*posB)); ProcedureReturn (1000 * HaversineInKM(@*posA,@*posB));
EndProcedure EndProcedure
Procedure GetPixelCoordFromLocation(*Location.Location, *Pixel.PixelPosition) ; TODO to Optimize Procedure GetPixelCoordFromLocation(*Location.GeographicCoordinates, *Pixel.PixelPosition, Zoom) ; TODO to Optimize
Protected mapWidth.l = Pow(2, PBMap\Zoom + 8) Protected mapWidth.l = Pow(2, Zoom + 8)
Protected mapHeight.l = Pow(2, PBMap\Zoom + 8) Protected mapHeight.l = Pow(2, Zoom + 8)
Protected x1.l,y1.l Protected x1.l,y1.l
; get x value ; get x value
x1 = (*Location\Longitude+180)*(mapWidth/360) x1 = (*Location\Longitude+180)*(mapWidth/360)
@@ -654,8 +654,8 @@ Module PBMap
Procedure DrawTiles(*Drawing.DrawingParameters, Layer.i, alpha.i=255) Procedure DrawTiles(*Drawing.DrawingParameters, Layer.i, alpha.i=255)
;DisableDebugger ;DisableDebugger
Protected x.i, y.i,kq.q Protected x.i, y.i,kq.q
Protected tx = Int(*Drawing\Position\x) ;Don't forget the Int() ! Protected tx = Int(*Drawing\TilePosition\x) ;Don't forget the Int() !
Protected ty = Int(*Drawing\Position\y) Protected ty = Int(*Drawing\TilePosition\y)
Protected nx = *Drawing\CenterX / PBMap\TileSize ;How many tiles around the point Protected nx = *Drawing\CenterX / PBMap\TileSize ;How many tiles around the point
Protected ny = *Drawing\CenterY / PBMap\TileSize Protected ny = *Drawing\CenterY / PBMap\TileSize
Protected px, py, img, tilex,tiley, key.s, CacheFile.s Protected px, py, img, tilex,tiley, key.s, CacheFile.s
@@ -760,12 +760,12 @@ Module PBMap
StrokePath(1) StrokePath(1)
EndProcedure EndProcedure
Procedure DrawDegrees(*Drawing.DrawingParameters,alpha=192) Procedure DrawDegrees(*Drawing.DrawingParameters, alpha=192)
Protected tx, ty, nx,ny,nx1,ny1,x,y,n,cx,dperpixel.d Protected tx, ty, nx,ny,nx1,ny1,x,y,n,cx,dperpixel.d
Protected pos1.PixelPosition,pos2.PixelPosition,Degrees1.Location,degrees2.Location Protected pos1.PixelPosition,pos2.PixelPosition,Degrees1.GeographicCoordinates,degrees2.GeographicCoordinates
Protected realx Protected realx
tx = Int(*Drawing\Position\x) tx = Int(*Drawing\TilePosition\x)
ty = Int(*Drawing\Position\y) ty = Int(*Drawing\TilePosition\y)
nx = *Drawing\CenterX / PBMap\TileSize ;How many tiles around the point nx = *Drawing\CenterX / PBMap\TileSize ;How many tiles around the point
ny = *Drawing\CenterY / PBMap\TileSize ny = *Drawing\CenterY / PBMap\TileSize
*Drawing\Bounds\NorthWest\x = tx-nx-1 *Drawing\Bounds\NorthWest\x = tx-nx-1
@@ -773,8 +773,8 @@ Module PBMap
*Drawing\Bounds\SouthEast\x = tx+nx+2 *Drawing\Bounds\SouthEast\x = tx+nx+2
*Drawing\Bounds\SouthEast\y = ty+ny+2 *Drawing\Bounds\SouthEast\y = ty+ny+2
; Debug "------------------" ; Debug "------------------"
XY2LatLon(*Drawing\Bounds\NorthWest, @Degrees1) XY2LatLon(*Drawing\Bounds\NorthWest, @Degrees1, PBMap\Zoom)
XY2LatLon(*Drawing\Bounds\SouthEast, @Degrees2) XY2LatLon(*Drawing\Bounds\SouthEast, @Degrees2, PBMap\Zoom)
;ensure we stay positive for the drawing ;ensure we stay positive for the drawing
nx = Mod(Mod(Round(Degrees1\Longitude, #PB_Round_Down)-1, 360) + 360, 360) nx = Mod(Mod(Round(Degrees1\Longitude, #PB_Round_Down)-1, 360) + 360, 360)
ny = Round(Degrees1\Latitude, #PB_Round_Up) +1 ny = Round(Degrees1\Latitude, #PB_Round_Up) +1
@@ -785,15 +785,15 @@ Module PBMap
Degrees2\Longitude = nx1 Degrees2\Longitude = nx1
Degrees2\Latitude = ny1 Degrees2\Latitude = ny1
; Debug "NW : " + StrD(Degrees1\Longitude) + " ; NE : " + StrD(Degrees2\Longitude) ; Debug "NW : " + StrD(Degrees1\Longitude) + " ; NE : " + StrD(Degrees2\Longitude)
LatLon2Pixel(@Degrees1, @pos1) LatLon2Pixel(@Degrees1, @pos1, PBMap\Zoom)
LatLon2Pixel(@Degrees2, @pos2) LatLon2Pixel(@Degrees2, @pos2, PBMap\Zoom)
VectorFont(FontID(PBMap\Font), 10) VectorFont(FontID(PBMap\Font), 10)
VectorSourceColor(RGBA(0, 0, 0, alpha)) VectorSourceColor(RGBA(0, 0, 0, alpha))
;draw latitudes ;draw latitudes
For y = ny1 To ny For y = ny1 To ny
Degrees1\Longitude = nx Degrees1\Longitude = nx
Degrees1\Latitude = y Degrees1\Latitude = y
LatLon2Pixel(@Degrees1, @pos1) LatLon2Pixel(@Degrees1, @pos1, PBMap\Zoom)
MovePathCursor(pos1\x, pos1\y) MovePathCursor(pos1\x, pos1\y)
AddPathLine( pos2\x, pos1\y) AddPathLine( pos2\x, pos1\y)
MovePathCursor(10, pos1\y) MovePathCursor(10, pos1\y)
@@ -804,7 +804,7 @@ Module PBMap
Repeat Repeat
Degrees1\Longitude = x Degrees1\Longitude = x
Degrees1\Latitude = ny Degrees1\Latitude = ny
LatLon2Pixel(@Degrees1, @pos1) LatLon2Pixel(@Degrees1, @pos1, PBMap\Zoom)
MovePathCursor(pos1\x, pos1\y) MovePathCursor(pos1\x, pos1\y)
AddPathLine( pos1\x, pos2\y) AddPathLine( pos1\x, pos2\y)
MovePathCursor(pos1\x,10) MovePathCursor(pos1\x,10)
@@ -835,14 +835,14 @@ Module PBMap
Procedure DrawTrack(*Drawing.DrawingParameters) Procedure DrawTrack(*Drawing.DrawingParameters)
Protected Pixel.PixelPosition Protected Pixel.PixelPosition
Protected Location.Location Protected Location.GeographicCoordinates
Protected km.f, memKm.i Protected km.f, memKm.i
If ListSize(PBMap\track())>0 If ListSize(PBMap\track())>0
;Trace Track ;Trace Track
ForEach PBMap\track() ForEach PBMap\track()
If *Drawing\TargetLocation\Latitude<>0 And *Drawing\TargetLocation\Longitude<>0 If *Drawing\TargetLocation\Latitude<>0 And *Drawing\TargetLocation\Longitude<>0
;GetPixelCoordFromLocation(@PBMap\track(),@Pixel) ;GetPixelCoordFromLocation(@PBMap\track(),@Pixel)
LatLon2Pixel(@PBMap\track(),@Pixel) LatLon2Pixel(@PBMap\track(), @Pixel, PBMap\Zoom)
If ListIndex(PBMap\track())=0 If ListIndex(PBMap\track())=0
MovePathCursor(Pixel\X, Pixel\Y) MovePathCursor(Pixel\X, Pixel\Y)
Else Else
@@ -864,7 +864,7 @@ Module PBMap
Location\Longitude=PBMap\track()\Longitude Location\Longitude=PBMap\track()\Longitude
EndIf EndIf
;GetPixelCoordFromLocation(@PBMap\track(),@Pixel) ;GetPixelCoordFromLocation(@PBMap\track(),@Pixel)
LatLon2Pixel(@PBMap\track(),@Pixel) LatLon2Pixel(@PBMap\track(),@Pixel, PBMap\Zoom)
If Int(km)<>memKm If Int(km)<>memKm
memKm=Int(km) memKm=Int(km)
If PBMap\Zoom>10 If PBMap\Zoom>10
@@ -907,7 +907,7 @@ Module PBMap
ForEach PBMap\Marker() ForEach PBMap\Marker()
If PBMap\Marker()\Location\Latitude <> 0 And PBMap\Marker()\Location\Longitude <> 0 If PBMap\Marker()\Location\Latitude <> 0 And PBMap\Marker()\Location\Longitude <> 0
;GetPixelCoordFromLocation(PBMap\Marker()\Location, @Pixel) ;GetPixelCoordFromLocation(PBMap\Marker()\Location, @Pixel)
LatLon2Pixel(PBMap\Marker()\Location, @Pixel) LatLon2Pixel(PBMap\Marker()\Location, @Pixel, PBMap\Zoom)
If Pixel\X >= 0 And Pixel\Y >= 0 And Pixel\X < GadgetWidth(PBMap\Gadget) And Pixel\Y < GadgetHeight(PBMap\Gadget) ; Only if visible ^_^ If Pixel\X >= 0 And Pixel\Y >= 0 And Pixel\X < GadgetWidth(PBMap\Gadget) And Pixel\Y < GadgetHeight(PBMap\Gadget) ; Only if visible ^_^
If PBMap\Marker()\CallBackPointer > 0 If PBMap\Marker()\CallBackPointer > 0
CallFunctionFast(PBMap\Marker()\CallBackPointer, Pixel\X, Pixel\Y) CallFunctionFast(PBMap\Marker()\CallBackPointer, Pixel\X, Pixel\Y)
@@ -929,7 +929,7 @@ Module PBMap
*Drawing\CenterX = GadgetWidth(PBMap\Gadget) / 2 *Drawing\CenterX = GadgetWidth(PBMap\Gadget) / 2
*Drawing\CenterY = GadgetHeight(PBMap\Gadget) / 2 *Drawing\CenterY = GadgetHeight(PBMap\Gadget) / 2
;Pixel shift, aka position in the tile ;Pixel shift, aka position in the tile
Px = *Drawing\Position\x : Py = *Drawing\Position\y Px = *Drawing\TilePosition\x : Py = *Drawing\TilePosition\y
*Drawing\DeltaX = Px * ts - (Int(Px) * ts) ;Don't forget the Int() ! *Drawing\DeltaX = Px * ts - (Int(Px) * ts) ;Don't forget the Int() !
*Drawing\DeltaY = Py * ts - (Int(Py) * ts) *Drawing\DeltaY = Py * ts - (Int(Py) * ts)
*Drawing\TargetLocation\Latitude = PBMap\TargetLocation\Latitude *Drawing\TargetLocation\Latitude = PBMap\TargetLocation\Latitude
@@ -971,6 +971,19 @@ Module PBMap
;Drawing() ;Drawing()
EndProcedure EndProcedure
Procedure.d MouseLongitude()
Protected MouseX.d = (PBMap\PixelPosition\x - GadgetWidth(PBMap\Gadget) / 2 + GetGadgetAttribute(PBMap\Gadget, #PB_Canvas_MouseX)) / PBMap\TileSize
Protected n.d = Pow(2.0, PBMap\Zoom)
;double mod is to ensure the longitude to be in the range [-180;180[
ProcedureReturn Mod(Mod(MouseX / n * 360.0, 360.0) + 360.0, 360.0) - 180
EndProcedure
Procedure.d MouseLatitude()
Protected MouseY.d = (PBMap\PixelPosition\y - GadgetHeight(PBMap\Gadget) / 2 + GetGadgetAttribute(PBMap\Gadget, #PB_Canvas_MouseY)) / PBMap\TileSize
Protected n.d = Pow(2.0, PBMap\Zoom)
ProcedureReturn Degree(ATan(SinH(#PI * (1.0 - 2.0 * MouseY / n))))
EndProcedure
Procedure SetLocation(latitude.d, longitude.d, zoom = 15, Mode.i = #PB_Absolute) Procedure SetLocation(latitude.d, longitude.d, zoom = 15, Mode.i = #PB_Absolute)
Select Mode Select Mode
Case #PB_Absolute Case #PB_Absolute
@@ -984,10 +997,10 @@ Module PBMap
EndSelect EndSelect
If PBMap\Zoom > PBMap\ZoomMax : PBMap\Zoom = PBMap\ZoomMax : EndIf If PBMap\Zoom > PBMap\ZoomMax : PBMap\Zoom = PBMap\ZoomMax : EndIf
If PBMap\Zoom < PBMap\ZoomMin : PBMap\Zoom = PBMap\ZoomMin : EndIf If PBMap\Zoom < PBMap\ZoomMin : PBMap\Zoom = PBMap\ZoomMin : EndIf
LatLon2XY(@PBMap\TargetLocation, @PBMap\Drawing) LatLon2XY(@PBMap\TargetLocation, @PBMap\Drawing, PBMap\Zoom)
;Convert X, Y in tile.decimal into real pixels ;Convert X, Y in tile.decimal into real pixels
PBMap\Position\x = PBMap\Drawing\Position\x * PBMap\TileSize PBMap\PixelPosition\x = PBMap\Drawing\TilePosition\x * PBMap\TileSize
PBMap\Position\y = PBMap\Drawing\Position\y * PBMap\TileSize PBMap\PixelPosition\y = PBMap\Drawing\TilePosition\y * PBMap\TileSize
PBMap\Drawing\PassNb = 1 PBMap\Drawing\PassNb = 1
PBMap\Redraw = #True PBMap\Redraw = #True
;Drawing() ;Drawing()
@@ -1047,10 +1060,10 @@ Module PBMap
EndSelect EndSelect
If PBMap\Zoom > PBMap\ZoomMax : PBMap\Zoom = PBMap\ZoomMax : EndIf If PBMap\Zoom > PBMap\ZoomMax : PBMap\Zoom = PBMap\ZoomMax : EndIf
If PBMap\Zoom < PBMap\ZoomMin : PBMap\Zoom = PBMap\ZoomMin : EndIf If PBMap\Zoom < PBMap\ZoomMin : PBMap\Zoom = PBMap\ZoomMin : EndIf
LatLon2XY(@PBMap\TargetLocation, @PBMap\Drawing\Position) LatLon2XY(@PBMap\TargetLocation, @PBMap\Drawing\TilePosition, PBMap\Zoom)
;Convert X, Y in tile.decimal into real pixels ;Convert X, Y in tile.decimal into real pixels
PBMap\Position\X = PBMap\Drawing\Position\x * PBMap\TileSize PBMap\PixelPosition\X = PBMap\Drawing\TilePosition\x * PBMap\TileSize
PBMap\Position\Y = PBMap\Drawing\Position\y * PBMap\TileSize PBMap\PixelPosition\Y = PBMap\Drawing\TilePosition\y * PBMap\TileSize
;First drawing ;First drawing
PBMap\Redraw = #True PBMap\Redraw = #True
;Drawing() ;Drawing()
@@ -1075,35 +1088,46 @@ Module PBMap
;Zoom on x, y position relative to the canvas gadget ;Zoom on x, y position relative to the canvas gadget
Procedure SetZoomOnPosition(x, y, zoom) Procedure SetZoomOnPosition(x, y, zoom)
Debug "----"
Debug MouseLatitude()
Debug MouseLongitude()
Protected MouseX.d, MouseY.d Protected MouseX.d, MouseY.d
Protected OldPx.d, OldPy.d, OldMx.d, OldMy.d Protected OldPx.d, OldPy.d, OldMx.d, OldMy.d, Px.d, Py.d
Protected MapWidth = Pow(2, PBMap\Zoom) * PBMap\TileSize Protected CenterX = GadgetWidth(PBMap\Gadget) / 2, CenterY = GadgetHeight(PBMap\Gadget) / 2
;Fast and dirty code ;Fast and dirty code
OldPx = PBMap\Position\x : OldPy = PBMap\Position\y OldPx = PBMap\PixelPosition\x : OldPy = PBMap\PixelPosition\y
OldMx = OldPx + GadgetWidth(PBMap\Gadget) / 2 - x OldMx = OldPx + CenterX - x
OldMy = OldPy + GadgetHeight(PBMap\Gadget) / 2 - y OldMy = OldPy + CenterY - y
PBMap\Zoom = PBMap\Zoom + zoom PBMap\Zoom = PBMap\Zoom + zoom
If PBMap\Zoom > PBMap\ZoomMax : PBMap\Zoom = PBMap\ZoomMax : EndIf If PBMap\Zoom > PBMap\ZoomMax : PBMap\Zoom = PBMap\ZoomMax : EndIf
If PBMap\Zoom < PBMap\ZoomMin : PBMap\Zoom = PBMap\ZoomMin : EndIf If PBMap\Zoom < PBMap\ZoomMin : PBMap\Zoom = PBMap\ZoomMin : EndIf
Protected MapWidth = Pow(2, PBMap\Zoom) * PBMap\TileSize
;Centered Zoom ;Centered Zoom
LatLon2XY(@PBMap\TargetLocation, @PBMap\Drawing\Position) LatLon2XY(@PBMap\TargetLocation, @PBMap\Drawing\TilePosition, PBMap\Zoom)
;Convert X, Y in tile.decimal into real pixels ;Convert X, Y in tile.decimal into real pixels
MouseX = PBMap\Drawing\Position\x * PBMap\TileSize + GadgetWidth(PBMap\Gadget) / 2 - x ; Px = PBMap\Drawing\TilePosition\x * PBMap\TileSize
MouseY = PBMap\Drawing\Position\y * PBMap\TileSize + GadgetHeight(PBMap\Gadget) / 2 - y ; Py = PBMap\Drawing\TilePosition\y * PBMap\TileSize
If MouseX > MapWidth ; MouseX = Px + CenterX - x
Debug "kaboum" ; MouseY = Py + CenterY - y
EndIf ;
Debug "------" ;TODO bug when zoom near the wrap ; If MouseX > MapWidth
Debug "Mx : " +StrD(MouseX) ; Debug "kaboum"
Debug PBMap\Position\x ; EndIf
;Cross-multiply to get the new center ; ; Debug "------" ;TODO bug when zoom near the wrap
PBMap\Position\x = (OldPx * MouseX) / OldMx ; ; Debug "Mx : " +StrD(MouseX)
PBMap\Position\y = (OldPy * MouseY) / OldMy ; ; Debug PBMap\TilePosition\x
;PBMap tile position in tile.decimal ; ;Cross-multiply to get the new center
PBMap\Drawing\Position\x = PBMap\Position\x / PBMap\TileSize ; PBMap\PixelPosition\x = (OldPx * MouseX) / OldMx
PBMap\Drawing\Position\y = PBMap\Position\y / PBMap\TileSize ; PBMap\PixelPosition\y = (OldPy * MouseY) / OldMy
PBMap\Drawing\PassNb = 1 ; ;PBMap tile position in tile.decimal
XY2LatLon(@PBMap\Drawing, @PBMap\TargetLocation) ; PBMap\Drawing\TilePosition\x = PBMap\PixelPosition\x / PBMap\TileSize
; PBMap\Drawing\TilePosition\y = PBMap\PixelPosition\y / PBMap\TileSize
; PBMap\Drawing\PassNb = 1
XY2LatLon(@PBMap\Drawing, @PBMap\TargetLocation, PBMap\Zoom)
LatLon2Pixel(@PBMap\TargetLocation, @PBMap\PixelPosition, PBMap\Zoom)
;Start drawing ;Start drawing
PBMap\Redraw = #True PBMap\Redraw = #True
;Drawing() ;Drawing()
@@ -1131,7 +1155,7 @@ Module PBMap
Procedure CanvasEvents() Procedure CanvasEvents()
Protected MouseX.i, MouseY.i Protected MouseX.i, MouseY.i
Protected Marker.Position, *Tile.Tile, MapWidth = Pow(2, PBMap\Zoom) * PBMap\TileSize Protected Marker.Coordinates, *Tile.Tile, MapWidth = Pow(2, PBMap\Zoom) * PBMap\TileSize
PBMap\Moving = #False PBMap\Moving = #False
Select EventType() Select EventType()
Case #PB_EventType_MouseWheel Case #PB_EventType_MouseWheel
@@ -1141,18 +1165,18 @@ Module PBMap
Else Else
;Absolute zoom (centered on the center of the map) ;Absolute zoom (centered on the center of the map)
SetZoom(GetGadgetAttribute(PBMap\Gadget,#PB_Canvas_WheelDelta), #PB_Relative) SetZoom(GetGadgetAttribute(PBMap\Gadget,#PB_Canvas_WheelDelta), #PB_Relative)
EndIf EndIf
Case #PB_EventType_LeftButtonDown Case #PB_EventType_LeftButtonDown
;Check if we select a marker ;Check if we select a marker
MouseX = PBMap\Position\x - GadgetWidth(PBMap\Gadget) / 2 + GetGadgetAttribute(PBMap\Gadget, #PB_Canvas_MouseX) MouseX = PBMap\PixelPosition\x - GadgetWidth(PBMap\Gadget) / 2 + GetGadgetAttribute(PBMap\Gadget, #PB_Canvas_MouseX)
MouseY = PBMap\Position\y - GadgetHeight(PBMap\Gadget) / 2 + GetGadgetAttribute(PBMap\Gadget, #PB_Canvas_MouseY) MouseY = PBMap\PixelPosition\y - GadgetHeight(PBMap\Gadget) / 2 + GetGadgetAttribute(PBMap\Gadget, #PB_Canvas_MouseY)
;Clip MouseX to the map range (in X, the map is infinite) ;Clip MouseX to the map range (in X, the map is infinite)
MouseX = Mod(Mod(MouseX, MapWidth) + MapWidth, MapWidth) MouseX = Mod(Mod(MouseX, MapWidth) + MapWidth, MapWidth)
ForEach PBMap\Marker() ForEach PBMap\Marker()
LatLon2XY(@PBMap\Marker()\Location, @Marker) LatLon2XY(@PBMap\Marker()\Location, @Marker, PBMap\Zoom)
Marker\x * PBMap\TileSize Marker\x * PBMap\TileSize
Marker\y * PBMap\TileSize Marker\y * PBMap\TileSize
; Debug "Pos : " + StrD(Marker\x) + " ; Drawing pos : " + StrD(PBMap\Drawing\Position\x) ;Debug "Pos : " + StrD(Marker\x) + " ; Drawing pos : " + StrD(PBMap\Drawing\TilePosition\x)
If Distance(Marker\x, Marker\y, MouseX, MouseY) < 8 If Distance(Marker\x, Marker\y, MouseX, MouseY) < 8
PBMap\EditMarkerIndex = ListIndex(PBMap\Marker()) PBMap\EditMarkerIndex = ListIndex(PBMap\Marker())
Break Break
@@ -1169,25 +1193,22 @@ Module PBMap
;Move marker ;Move marker
If PBMap\EditMarkerIndex > -1 If PBMap\EditMarkerIndex > -1
SelectElement(PBMap\Marker(), PBMap\EditMarkerIndex) SelectElement(PBMap\Marker(), PBMap\EditMarkerIndex)
LatLon2XY(@PBMap\Marker()\Location, @Marker) LatLon2XY(@PBMap\Marker()\Location, @Marker, PBMap\Zoom)
Marker\x + MouseX / PBMap\TileSize Marker\x + MouseX / PBMap\TileSize
Marker\y + MouseY / PBMap\TileSize Marker\y + MouseY / PBMap\TileSize
XY2LatLon(@Marker, @PBMap\Marker()\Location) XY2LatLon(@Marker, @PBMap\Marker()\Location, PBMap\Zoom)
Else Else
;New move values ;New move values
;PBMap\Position\x - MouseX ;PBMap\Position\x - MouseX
;Ensures that pixel position stay in the range [0..2^Zoom*PBMap\TileSize[ coz of the wrapping of the map ;Ensures that pixel position stay in the range [0..2^Zoom*PBMap\TileSize[ coz of the wrapping of the map
PBMap\Position\x = PBMap\Position\x - MouseX PBMap\PixelPosition\x - MouseX
If PBMap\Position\x < 0 PBMap\PixelPosition\x = Mod(Mod(PBMap\PixelPosition\x, MapWidth) + MapWidth, MapWidth)
PBMap\Position\x + Pow(2, PBMap\Zoom) * PBMap\TileSize PBMap\PixelPosition\y - MouseY
EndIf
PBMap\Position\x = Mod(PBMap\Position\x, Pow(2, PBMap\Zoom) * PBMap\TileSize)
PBMap\Position\y - MouseY
;PBMap tile position in tile.decimal ;PBMap tile position in tile.decimal
PBMap\Drawing\Position\x = PBMap\Position\x / PBMap\TileSize PBMap\Drawing\TilePosition\x = PBMap\PixelPosition\x / PBMap\TileSize
PBMap\Drawing\Position\y = PBMap\Position\y / PBMap\TileSize PBMap\Drawing\TilePosition\y = PBMap\PixelPosition\y / PBMap\TileSize
PBMap\Drawing\PassNb = 1 PBMap\Drawing\PassNb = 1
XY2LatLon(@PBMap\Drawing, @PBMap\TargetLocation) XY2LatLon(@PBMap\Drawing, @PBMap\TargetLocation, PBMap\Zoom)
;If CallBackLocation send Location to function ;If CallBackLocation send Location to function
If PBMap\CallBackLocation > 0 If PBMap\CallBackLocation > 0
CallFunctionFast(PBMap\CallBackLocation, @PBMap\TargetLocation) CallFunctionFast(PBMap\CallBackLocation, @PBMap\TargetLocation)
@@ -1202,10 +1223,10 @@ Module PBMap
If PBMap\EditMarkerIndex > -1 If PBMap\EditMarkerIndex > -1
PBMap\EditMarkerIndex = -1 PBMap\EditMarkerIndex = -1
Else ;Move Map Else ;Move Map
PBMap\Drawing\Position\x = PBMap\Position\x / PBMap\TileSize PBMap\Drawing\TilePosition\x = PBMap\PixelPosition\x / PBMap\TileSize
PBMap\Drawing\Position\y = PBMap\Position\y / PBMap\TileSize PBMap\Drawing\TilePosition\y = PBMap\PixelPosition\y / PBMap\TileSize
MyDebug("PBMap\Drawing\Position\x " + Str(PBMap\Drawing\Position\x) + " ; PBMap\Drawing\Position\y " + Str(PBMap\Drawing\Position\y) ) MyDebug("PBMap\Drawing\TilePosition\x " + Str(PBMap\Drawing\TilePosition\x) + " ; PBMap\Drawing\TilePosition\y " + Str(PBMap\Drawing\TilePosition\y) )
XY2LatLon(@PBMap\Drawing, @PBMap\TargetLocation) XY2LatLon(@PBMap\Drawing, @PBMap\TargetLocation, PBMap\Zoom)
PBMap\Redraw = #True PBMap\Redraw = #True
EndIf EndIf
Case #PB_MAP_REDRAW Case #PB_MAP_REDRAW
@@ -1391,8 +1412,8 @@ CompilerIf #PB_Compiler_IsMainFile
CompilerEndIf CompilerEndIf
; IDE Options = PureBasic 5.50 (Windows - x64) ; IDE Options = PureBasic 5.50 (Windows - x64)
; CursorPosition = 1094 ; CursorPosition = 343
; FirstLine = 1076 ; FirstLine = 314
; Folding = ---------- ; Folding = ----------
; EnableThread ; EnableThread
; EnableXP ; EnableXP