Simple Offline OSM Maps viewer

User projects written in or related to FreeBASIC.
Posts: 74
Joined: Feb 24, 2010 10:08
Location: Spain (Bilbao)

Simple Offline OSM Maps viewer

Postby jepalza » Jun 20, 2021 14:50

This is a simple OSM (Open Street Maps) viewer. Only for fun!!!
Take "snapshot" from OSM Web, max 50000 NODE.

Example, Guggenheim Bilbao: ... 3/-2.93285
And export it in "osm" (xml text) format.

Another complex example, my little town, Sopelana: (this with almost 50000 NODES)

Using FILL Routine from:

named: fill.bas

Code: Select all

Sub fill_polygon(a() As Long, bound As Integer, ByVal c As ULong)
   'translation of a c snippet by Angad
   ' jepalza: variable "bound"
   'source of c code:
   Dim As Long      i, j, k, dy, dx, x, y, temp
   Dim As Long      xi(0 to bound)
   Dim As Single    slope(0 to bound)
   'join first and last vertex
   a(bound, 0) = a(0, 0)
   a(bound, 1) = a(0, 1)

   For i = 0 To bound - 1

      dy = a(i+1, 1) - a(i, 1)
      dx = a(i+1, 0) - a(i, 0)

      If (dy = 0) Then slope(i) = 1.0
      If (dx = 0) Then slope(i) = 0.0

      If (dy <> 0) AndAlso (dx <> 0) Then slope(i) = dx / dy
   Next i

   For y = 0 to RESX - 1
      k = 0
      ' using FB's short-cut operators (which C doesn't have!)
      For i = 0 to bound - 1
         If (a(i, 1) <= y AndAlso a(i+1, 1) > y) OrElse _
             (a(i, 1) > y AndAlso a(i+1, 1) <= y) Then
            xi(k) = CLng(a(i, 0) + slope(i) * (y - a(i, 1)))
            k += 1
         End If
      Next i

      For j = 0 to k - 2
         'Arrange x-intersections in order
         For i = 0 To k - 2
            If (xi(i) > xi(i + 1)) Then
               temp = xi(i)
               xi(i) = xi(i + 1)
               xi(i + 1) = temp
            End If
         Next i
      Next j
      'line filling
      For i = 0 To k - 2 Step 2
         Line (xi(i), y)-(xi(i + 1) + 1, y), c
      Next i
   Next y
End Sub


Code: Select all

' variables de uso general
Dim As String sa, sc

Dim As Integer a, b, c, d, e, f, g, h, n

Dim shared As Integer RESX,RESY,MICOLOR


#Include "fill.bas"

' WAY ID, NODO ID, numero de nodos leidos, num. de bordes leidos, num. de ways leidas, y su numero de nodos internos
Dim As ulong WID,NID
Dim As ULong REF ' las asociaciones leidas dentro de los WAY

Dim As Double LAT,LON ' NODES
Dim As Integer MAXNODES=50000 ' por el momento, maximo en 50k, por que es el limite impuesto por OSM en los EXPORT!!



Dim As Integer hayway=0 ' si hay WAY se activa para ir leyendo todos los nodos que lo componen

Dim shared As Double nodosc(MAXNODES,1) ' latitud y longitud de nodos leidos
Dim shared As ULong nodosi(MAXNODES) ' su indentificacion

Dim shared As uLong waysi(5000,1000) ' ways leidas y su asociaciones de nodos dentro del way, vamos, la polilinea

Dim As Integer x1,x2,y1,y2,xini,yini

Dim As Double factorx,factory ' no es real, falla en cuadratura, pero es suficiente para ver mapa

ScreenRes RESX,RESY,32
Line(0,0)-(RESX,RESY), RGB(255,255,255),bf ' fondo blanco , para fondo negro quitar

Dim Shared As long w(1000,1) ' guarda las coord. X e Y para la rutina de relleno FILL

If sc="" Then sc="Guggenheim_Bilbao.osm" ' para pruebas

Open sc For Input As 1
'Open "salida.txt" For Output As 2
While Not Eof(1)
   Line Input #1, sa
   If InStr(sa,"<node ") Then
      If Mid(sa,a+8,5)="false" Then end If
      'Print "NODO :";NODE,NID,LAT,LON
      ' si no se localiza BOUNDS, los calculo segun leo NODOS
      If BOUNDS=0 Then
         if LAT<MINLAT Then MINLAT=LAT
         if LAT>MAXLAT Then MAXLAT=LAT
         if LON<MINLON Then MINLON=LON
         if LON>MAXLON Then MAXLON=LON
      End If
      If NODES>MAXNODES Then Print "Superados 50000 nodos!!!":Sleep:end

   If InStr(sa,"<bounds ") Then
   ' si tenemos WAY vamos leyendo sus asociaciones
   If hayway=1 Then
      If InStr(sa,"<nd ") Then
         'Print WAYS,REF
   If InStr(sa,"<way ") Then
      If Mid(sa,a+8,5)="false" Then end If
      WID=Val(Mid(sa,a+4)) ' no es necesario por ahora, pero lo guardo para un futuro
      'Print "WAY  :";WAYS,WID

   If InStr(sa,"</way>") Then ' se acabo, salimos de buscar WAY
      'For f=0 To a
      '   w(f,0)=0
      '   w(f,1)=0
      For f=0 To n-1
         For g=0 To NODES-1
            If NID=nodosi(g) Then
         'Print NID,LON,LAT
         If a Then
            'Print x1,y1,x2,y2
            Line (x1,RESY-y1)-(x2,RESY-y2),MICOLOR
         If a=0 Then
            xini=x1 ' las guardo para luego calcular poligono cerrado o no
      ' si coinciden punto de entrada y salida, es poligono cerrado, rellenamos
      If xini=x1 And yini=y1 And a<1000 Then ' si el FILL tiene mas de 1000 elementos, no actua, porque da error
         fill_polygon w(),a-1,MICOLOR
      If BOUNDS=0 Then
         Exit while

   ' activar para ver los NODOS
      '   For g=0 To NODES-1
      '      NID=nodosi(g)
      '      LON=nodosc(g,0)
      '      LAT=nodosc(g,1)
      '      x2=((LON-MINLON)*factorx)'*1000
      '      y2=((LAT-MINLAT)*factory)'*1000
      '      Circle (x2,RESY-y2),2,NID
      '   Next

Print "WAY   TOTAL :";WAYS

Close 1, 2
Print "...FIN"

-is not perfect, not control about NODES number, and maybe can fail.
-colors is random, only for fun

It's good skeleton for a big maps project!!

edit: little bug with bound out
Last edited by jepalza on Jun 21, 2021 16:48, edited 1 time in total.
Posts: 2340
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Simple Offline OSM Maps viewer

Postby badidea » Jun 20, 2021 21:39

Hi, that code could be useful, but I get an error with "-exx" compile option:
"Aborting due to runtime error 6 (out of bounds array access) at line 156 of test.bas::()"
The maps is shown briefly, before the runtime error. Without "-exx" it segfaults.

Also with 64-fbc the code does not compile, but that can be fixed quickly by changing array w() to type long.
Posts: 74
Joined: Feb 24, 2010 10:08
Location: Spain (Bilbao)

Re: Simple Offline OSM Maps viewer

Postby jepalza » Jun 21, 2021 15:53

I'm using lastest FB version (1.08) 32 bits in win7 without -exx, and i's running good.
I'm working on it in order to get best performance, and then publish it.

This first version not verify bounds limits, and if they goes out of limits, crashed.

edit: simple check in NODES limit to 50k in first post. This 50k limit is from OSM EXPORT in format XML. Did check my code with FB v1.08 x64 in Win10, and it's run fine.

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 5 guests