Engine3D and google maps coordinate problem y axis flipped

Everything related to 3D programming
Philippe-felixer76-3
User
User
Posts: 45
Joined: Mon Dec 30, 2013 10:12 pm

Engine3D and google maps coordinate problem y axis flipped

Post by Philippe-felixer76-3 »

Hi,

I want to map google map images to 3d planes using world coordinates.
So first i convert lat/lon to world coords and then i create plane/mesh/material/texture/entity for all the images.
Finaly i place the 3D camera x/y position to the actual world coordinates.

Problem is the Y axis seems to be flipped in 3D, see this example, line 49 MoveEntity (commented) should be right but using this line it get's flipped:

Code: Select all

; Maps Engine3D coords test
InitEngine3D(): InitSprite(): InitKeyboard(): InitMouse(): UseJPEGImageDecoder()
; structure
Structure maps
  img.l
  ent.l
  mat.l
  txt.l
EndStructure
Global NewMap map3d.maps()
; open window/screen
If OpenWindow(0, 0, 0, 1024, 768, "Maps test 3D Engine", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered  )
  OpenWindowedScreen(WindowID(0), 0,    0,  WindowWidth(0), WindowHeight(0), #True, 0, 0, #PB_Screen_NoSynchronization ) 
  ; define some vars .. 
  pathmaps.s = "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"
  zoom.l     = 18
  lat.d      = 52.370216
  lon.d      = 4.895168
  camzoom    = 0
  ; convert lat/lon to world coords
  n.d        = Pow(2.0, zoom)
  LatRad.d   = Radian(lat)
  px.d       = n * (Mod( lon + 180.0, 360) / 360.0 )
  py.d       = n * ( 1.0 - Log(Tan(LatRad) + (1.0/Cos(LatRad))) / #PI ) / 2.0
  ; create 3d stuff
  CreateCamera(0, 0, 0, 100, 100)
  msh.l = CreatePlane(#PB_Any, 1, 1, 1, 1, 1, 1)
  num.l = 2 ; amount of tiles left/right above/below
  For y = -num To num
    For x = -num To num
      id.s = "" + Int(px) + x + "x" + Int(py) + y
      url.s = ReplaceString(pathmaps.s, "{z}", ""+zoom+"")
      url.s = ReplaceString(url.s, "{x}", ""+Int(px+x)+"")
      url.s = ReplaceString(url.s, "{y}", ""+Int(py+y)+"")
      HttpRequest = HTTPRequestMemory(#PB_HTTP_Get, url.s)
      If HttpRequest
        *Response = HTTPMemory(HTTPRequest)
        map3d(id.s)\img = CatchImage(#PB_Any, *Response, MemorySize(*Response))
        FreeMemory(*Response)
        If IsImage(map3d(id.s)\img)
          map3d(id.s)\txt = CreateTexture(#PB_Any, 256, 256)
          StartDrawing(TextureOutput(map3d(id.s)\txt))
            DrawImage(ImageID(map3d(id.s)\img), 0, 0)
          StopDrawing()
          map3d(id.s)\mat = CreateMaterial(#PB_Any, TextureID(map3d(id.s)\txt))
          DisableMaterialLighting(map3d(id.s)\mat, #True)
          map3d(id.s)\ent = CreateEntity(#PB_Any, MeshID(msh), MaterialID(map3d(id.s)\mat))
          RotateEntity(map3d(id.s)\ent, -90.0, 0.0,  180.0, #PB_Absolute)
          ;MoveEntity(map3d(id.s)\ent, Int(px) + x, Int(py) + y, 0, #PB_Absolute)  ; THIS SHOULD BE USED BUT THEN ALL Y LINES ARE FLIPPED
          MoveEntity(map3d(id.s)\ent, Int(px) + x, Int(py) - y, 0, #PB_Absolute)
        EndIf
        FinishHTTP(HTTPRequest)
      EndIf
    Next
  Next
  ; loop .. 
  Repeat
    wevent = WindowEvent()
    If ExamineMouse()
      mw = MouseWheel(): camzoom = camzoom + (-MouseWheel() * 2)
    EndIf
    If ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
        wevent = #PB_Event_CloseWindow
      EndIf
    EndIf
    MoveCamera(0, px, py, 10 + camzoom, #PB_Absolute)
    RenderWorld()
    FlipBuffers()
  Until wevent = #PB_Event_CloseWindow
EndIf
End
In this example it's not a problem to use line 50, but when i want to add more map data, going down or up the map, the Y axis images get screwed.
I could add a example of that also if needed, help!
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Engine3D and google maps coordinate problem y axis flipped

Post by Caronte3D »

Why you said: "THIS SHOULD BE USED BUT THEN ALL Y LINES ARE FLIPPED" ?

Anyway, if that line should be with "+y" Try to put the camera on the other side of the plane
Philippe-felixer76-3
User
User
Posts: 45
Joined: Mon Dec 30, 2013 10:12 pm

Re: Engine3D and google maps coordinate problem y axis flipped

Post by Philippe-felixer76-3 »

Hi Caronte3D,

It should because when you want to go up/down the map then the planes on the y axis are wrong placed. See this example, it starts using the right way to show the maps and when you press left/right everything is ok, but when you go up/down things go wrong. When you press F1 then the planes are Y flipped BUT the planes are placed RIGHT you can go left/right/up/down without errors except the y axis is flipped, see this example:

Code: Select all

; Maps Engine3D coords test
InitEngine3D(): InitSprite(): InitKeyboard(): InitMouse(): UseJPEGImageDecoder()
; structure
Structure maps
  img.l
  ent.l
  mat.l
  txt.l
  px.d
  py.d
  xx.l
  yy.l
  x.l
  y.l
  id.s
  et.l
  url.s
EndStructure
; Globals
Global NewMap map3d.maps(), NewList tload.maps(), cachedir.s, pathmaps.s, px.d, py.d, x.l, y.l, id.s, xx, yy, msh.l, zoom.l, url.s, curid.s, lat.d, lon.d
; procedures
Procedure latlon2pxpy()
  n.d        = Pow(2.0, zoom)
  LatRad.d   = Radian(lat)
  px.d       = n * (Mod( lon + 180.0, 360) / 360.0 )
  py.d       = n * ( 1.0 - Log(Tan(LatRad) + (1.0/Cos(LatRad))) / #PI ) / 2.0
  ;Debug "lon: " + lon + ", lat: " + lat + ", px: " + px + ", py: " + py
EndProcedure
Procedure ptload(nm.l)
  ResetList(tload())
  While NextElement(tload())
    HttpRequest = HTTPRequestMemory(#PB_HTTP_Get, tload()\url.s)
    If HttpRequest
      *Response = HTTPMemory(HTTPRequest)
      map3d(tload()\id)\img = CatchImage(#PB_Any, *Response, MemorySize(*Response)) 
      If IsImage(map3d(tload()\id)\img)
        map3d(tload()\id)\et = ElapsedMilliseconds()
        SaveImage(map3d(tload()\id)\img, map3d(tload()\id)\id)
      EndIf
      FreeMemory(*Response)
      FinishHTTP(HTTPRequest)
    EndIf
    DeleteElement(tload())
  Wend
EndProcedure
; open window/screen
If OpenWindow(0, 0, 0, 1024, 768, "Maps test 3D Engine", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered  )
  OpenWindowedScreen(WindowID(0), 0,    0,  WindowWidth(0), WindowHeight(0), #True, 0, 0, #PB_Screen_NoSynchronization ) 
  ; define some vars .. 
  pathmaps.s = "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"
  zoom.l     = 18
  lat.d      = 52.055116
  lon.d      = 4.895168
  camzoom    = 0
  Result$    = GetUserDirectory(#PB_Directory_Documents)
  cachedir.s = Result$  + "maps\pvc\" 
  If ExamineDirectory(0, cachedir.s, "*.*")  = 0
    CreateDirectory(Result$ + "maps")
    CreateDirectory(Result$ + "maps\pvc\")
  EndIf
  msh.l      = CreatePlane(#PB_Any, 1, 1, 1, 1, 1, 1)
  num.l      = 4 ; amount of tiles left/right above/below
  tid.l      = 0
  showyaxis  = 1
  ; convert lat/lon to world coords
  latlon2pxpy()
  ; create 3d stuff
  CreateCamera(0, 0, 0, 100, 100)
  ; loop .. 
  Repeat
    wevent = WindowEvent()
    ; check mouse
    If ExamineMouse()
      mw = MouseWheel(): camzoom = camzoom + (-MouseWheel() * 1.2): If camzoom<-9: camzoom=-9: EndIf
    EndIf
    ; check keyboard
    If ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
        wevent = #PB_Event_CloseWindow
      EndIf
      If KeyboardReleased(#PB_Key_Left)
        lon = lon - 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_Right)
        lon = lon + 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_Up)
        lat = lat - 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_Down)
        lat = lat + 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_F1)
        If showyaxis=0: showyaxis=1: Else: showyaxis = 0: EndIf
      EndIf
    EndIf
    ; Check if need to add planes..
    For y = -num To num
      For x = -num To num
        xx = px + x
        yy = py + y
        id.s = cachedir.s + zoom + "\" + xx + "\" + yy + ".png" 
        If ExamineDirectory(0, GetPathPart(id.s), "*.*")  < 1
          CreateDirectory(cachedir.s + zoom + "\")
          CreateDirectory(cachedir.s + zoom + "\" + xx + "\")
        EndIf
        If map3d(id.s)\id=""
          map3d(id.s)\id = id.s        
          map3d(id.s)\py = py  ; needed to position planes right
          map3d(id.s)\y = y    ; needed to position planes right
          map3d(id.s)\xx = xx
          map3d(id.s)\yy = yy  ; should be needed to position planes right
          url.s = ReplaceString(pathmaps.s, "{z}", ""+zoom+"")
          url.s = ReplaceString(url.s, "{x}", ""+Int(xx)+"")
          url.s = ReplaceString(url.s, "{y}", ""+Int(yy)+"")
          map3d(id.s)\url = url.s
          If FileSize(id.s)>0 
            map3d(id.s)\img = LoadImage(#PB_Any, id.s)
            map3d(id.s)\et = ElapsedMilliseconds()
          EndIf
        EndIf
      Next
    Next
    ; mark add thread to load new images when possible.
    addth = 0
    If ListSize(tload())<1 And IsThread(tid)<1
      addth  = 1
    EndIf
    ; check map images 
    ForEach map3d()
      id.s = map3d()\id
      ; does a image need to load? add to load thread
      If IsImage(map3d(id.s)\img)<1 And addth  = 1 
        ; does image already exists in the to be loaded image thread list?
        ResetList(tload()): exists = 0
        While NextElement(tload())
          If tload()\id = id.s
            exists = 1
            LastElement(tload())
          EndIf
        Wend
        ; if not exists add image to the thread list
        If exists=0
          AddElement(tload())
          tload()\url = map3d(id.s)\url
          tload()\id = id.s
        EndIf
      EndIf
      ; is image available without texture/material/entity? then place new entity with texture and material
      If IsTexture(map3d(id.s)\txt) < 1 And IsImage(map3d(id.s)\img)>0
        map3d(id.s)\txt = CreateTexture(#PB_Any, 256, 256)
        StartDrawing(TextureOutput(map3d(id.s)\txt))
          DrawImage(ImageID(map3d(id.s)\img), 0, 0)
        StopDrawing()
        map3d(id.s)\mat = CreateMaterial(#PB_Any, TextureID(map3d(id.s)\txt))
        DisableMaterialLighting(map3d(id.s)\mat, #True)
        MaterialCullingMode(map3d(id.s)\mat, #PB_Material_NoCulling )
        map3d(id.s)\ent = CreateEntity(#PB_Any, MeshID(msh), MaterialID(map3d(id.s)\mat))
        RotateEntity(map3d(id.s)\ent, -90.0, 0.0,  180.0, #PB_Absolute)
        If showyaxis = 0 
          MoveEntity(map3d(id.s)\ent, Int(map3d(id.s)\xx), Int(map3d(id.s)\yy), 0, #PB_Absolute) ; USING THIS THE POSITIONS OF THE PLANES ARE OK BUT Y IS FLIPPED   
        Else
          MoveEntity(map3d(id.s)\ent, Int(map3d(id.s)\xx), Int(map3d(id.s)\py - map3d(id.s)\y), 0, #PB_Absolute) ; USING THIS THE POSITION OF PLANES GET SCRAMBLED WHEN MOVING UP/DOWN
        EndIf
      EndIf
    Next
    ; start image load thread?
    If IsThread(tid)<1 And ListSize(tload())>0
      tid = CreateThread(@ptload(), 0)
    EndIf    
    ; TODO: Remove maps elements if max size (let's say 256) reached .. 
    ; Place camera ans render stuff..
    MoveCamera(0, px, py, 10 + camzoom, #PB_Absolute)
    CameraLookAt(0, px, py, 0)
    RenderWorld()
    FlipBuffers()
  Until wevent = #PB_Event_CloseWindow
EndIf
End
Last edited by Philippe-felixer76-3 on Thu Sep 15, 2022 8:01 pm, edited 2 times in total.
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Engine3D and google maps coordinate problem y axis flipped

Post by Caronte3D »

Done! :D

Code: Select all

; Maps Engine3D coords test
InitEngine3D(): InitSprite(): InitKeyboard(): InitMouse(): UseJPEGImageDecoder()
; structure
Structure maps
  img.l
  ent.l
  mat.l
  txt.l
  px.d
  py.d
  xx.l
  yy.l
  x.l
  y.l
  id.s
  et.l
  url.s
EndStructure
; Globals
Global NewMap map3d.maps(), NewList tload.maps(), cachedir.s, pathmaps.s, px.d, py.d, x.l, y.l, id.s, xx, yy, msh.l, zoom.l, url.s, curid.s, lat.d, lon.d
; procedures
Procedure latlon2pxpy()
  n.d        = Pow(2.0, zoom)
  LatRad.d   = Radian(lat)
  px.d       = n * (Mod( lon + 180.0, 360) / 360.0 )
  py.d       = n * ( 1.0 - Log(Tan(LatRad) + (1.0/Cos(LatRad))) / #PI ) / 2.0
  ;Debug "lon: " + lon + ", lat: " + lat + ", px: " + px + ", py: " + py
EndProcedure
Procedure ptload(nm.l)
  ResetList(tload())
  While NextElement(tload())
    HttpRequest = HTTPRequestMemory(#PB_HTTP_Get, tload()\url.s)
    If HttpRequest
      *Response = HTTPMemory(HTTPRequest)
      map3d(tload()\id)\img = CatchImage(#PB_Any, *Response, MemorySize(*Response)) 
      If IsImage(map3d(tload()\id)\img)
        map3d(tload()\id)\et = ElapsedMilliseconds()
      EndIf
      FreeMemory(*Response)
      FinishHTTP(HTTPRequest)
    EndIf
    DeleteElement(tload())
  Wend
EndProcedure
; open window/screen
If OpenWindow(0, 0, 0, 1024, 768, "Maps test 3D Engine", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered  )
  OpenWindowedScreen(WindowID(0), 0,    0,  WindowWidth(0), WindowHeight(0), #True, 0, 0, #PB_Screen_NoSynchronization ) 
  ; define some vars .. 
  pathmaps.s = "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"
  zoom.l     = 18
  lat.d      = 52.055116
  lon.d      = 4.895168
  camzoom    = 0
  Result$    = GetUserDirectory(#PB_Directory_Documents)
  cachedir.s = Result$  + "maps\pvc\" 
  If ExamineDirectory(0, cachedir.s, "*.*")  < 1
    CreateDirectory(cachedir.s + "maps")
    CreateDirectory(cachedir.s + "maps\pvc\")
  EndIf
  msh.l      = CreatePlane(#PB_Any, 1, 1, 1, 1, 1, 1)
  num.l      = 4 ; amount of tiles left/right above/below
  tid.l      = 0
  showyaxis  = 1
  ; convert lat/lon to world coords
  latlon2pxpy()
  ; create 3d stuff
  CreateCamera(0, 0, 0, 100, 100)
  ; loop .. 
  Repeat
    wevent = WindowEvent()
    ; check mouse
    If ExamineMouse()
      mw = MouseWheel(): camzoom = camzoom + (-MouseWheel() * 1.2): If camzoom<-9: camzoom=-9: EndIf
    EndIf
    ; check keyboard
    If ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
        wevent = #PB_Event_CloseWindow
      EndIf
      If KeyboardReleased(#PB_Key_Left)
        lon = lon - 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_Right)
        lon = lon + 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_Up)
        lat = lat + 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_Down)
        lat = lat - 0.001
        latlon2pxpy()
      EndIf
      If KeyboardReleased(#PB_Key_F1)
        If showyaxis=0: showyaxis=1: Else: showyaxis = 0: EndIf
      EndIf
    EndIf
    ; Check if need to add planes..
    For y = -num To num
      For x = -num To num
        xx = px + x
        yy = py + y
        
        id.s = cachedir.s + zoom + "\" + xx + "\" + yy + ".png" 
        If ExamineDirectory(0, GetPathPart(id.s), "*.*")  < 1
          CreateDirectory(cachedir.s + zoom + "\")
          CreateDirectory(cachedir.s + zoom + "\" + xx + "\")
        EndIf
        If map3d(id.s)\id=""
          map3d(id.s)\id = id.s        
          map3d(id.s)\py = py  ; needed to position planes right
          map3d(id.s)\y = y    ; needed to position planes right
          map3d(id.s)\xx = xx
          map3d(id.s)\yy = yy  ; should be needed to position planes right
          url.s = ReplaceString(pathmaps.s, "{z}", ""+zoom+"")
          url.s = ReplaceString(url.s, "{x}", ""+Int(xx)+"")
          url.s = ReplaceString(url.s, "{y}", ""+Int(yy)+"")
          map3d(id.s)\url = url.s
          If FileSize(id.s)>0 
            map3d(id.s)\img = LoadImage(#PB_Any, id.s)
            map3d(id.s)\et = ElapsedMilliseconds()
          EndIf
        EndIf
      Next
    Next
    ; mark add thread to load new images when possible.
    addth = 0
    If ListSize(tload())<1 And IsThread(tid)<1
      addth  = 1
    EndIf
    ; check map images 
    ForEach map3d()
      id.s = map3d()\id
      ; does a image need to load? add to load thread
      If IsImage(map3d(id.s)\img)<1 And addth  = 1 
        ; does image already exists in the to be loaded image thread list?
        ResetList(tload()): exists = 0
        While NextElement(tload())
          If tload()\id = id.s
            exists = 1
            LastElement(tload())
          EndIf
        Wend
        ; if not exists add image to the thread list
        If exists=0
          AddElement(tload())
          tload()\url = map3d(id.s)\url
          tload()\id = id.s
        EndIf
      EndIf
      ; is image available without texture/material/entity? then place new entity with texture and material
      If IsTexture(map3d(id.s)\txt) < 1 And IsImage(map3d(id.s)\img)>0
        map3d(id.s)\txt = CreateTexture(#PB_Any, 256, 256)
        StartDrawing(TextureOutput(map3d(id.s)\txt))
          DrawImage(ImageID(map3d(id.s)\img), 0, 0)
        StopDrawing()
        map3d(id.s)\mat = CreateMaterial(#PB_Any, TextureID(map3d(id.s)\txt))
        DisableMaterialLighting(map3d(id.s)\mat, #True)
        MaterialCullingMode(map3d(id.s)\mat, #PB_Material_NoCulling )
        map3d(id.s)\ent = CreateEntity(#PB_Any, MeshID(msh), MaterialID(map3d(id.s)\mat))
        
        RotateEntity(map3d(id.s)\ent, 90.0, 0.0,  180.0, #PB_Absolute)
        MoveEntity(map3d(id.s)\ent, Int(map3d(id.s)\xx), Int(map3d(id.s)\yy), 0, #PB_Absolute) ; USING THIS THE POSITIONS OF THE PLANES ARE OK BUT Y IS FLIPPED   
        
      EndIf
    Next
    ; start image load thread?
    If IsThread(tid)<1 And ListSize(tload())>0
      tid = CreateThread(@ptload(), 0)
    EndIf    
    ; TODO: Remove maps elements if max size (let's say 256) reached .. 
    ; Place camera ans render stuff..
    MoveCamera(0, px, py, -(10 + camzoom), #PB_Absolute)
    CameraLookAt(0, px, py, 0)
    RotateCamera(0, 180, 0, 0)

    RenderWorld()
    FlipBuffers()
  Until wevent = #PB_Event_CloseWindow
EndIf
End
Philippe-felixer76-3
User
User
Posts: 45
Joined: Mon Dec 30, 2013 10:12 pm

Re: Engine3D and google maps coordinate problem y axis flipped

Post by Philippe-felixer76-3 »

The RotateCamera :) So simple .. Tnx man!
Post Reply