B4J Library jOpenStreetMaps library

Thanks to "WarWound" and his original library project "JfxtrasMapPane" in the post OSM Open Street Map for B4J back in 2014 which was based on the jfxtras 2.2 r5 source, I have been able to release this updated library.https://www.b4x.com/android/forum/threads/jopenstreetmaps-library.8

Bug fixes:
... Left mouse click now works. In fact all 3 mouse buttons are resolved.

Additions:
... Polygons can now be added/removed from map (MapPolygon class)
... Map tile providers have been updated.
... proper attributions for map tile providers have been added to the maps.
... now supports a local map cache for faster redraws.
... added a default Map Icon class containing ready to use icons (pins, car, truck, etc)
... map markers and can have their size, rotation, shadow set at initialisation.

Most Classes have been renamed and additional properties/functions added to classes.
... MapPane class is now OpenStreetMaps class.
... SimpleMapMarker class is now MapSpot class.
... MapLine is now MapPolyline.
... Initialisation functions for many classes have been changed and added.

Generally this library is a lot more friendly, in fact similar in a lot of ways to jGooleMaps library.

Just to note that the OpenStreetMap® is open data, licensed under the Open Data Commons Open Database License (ODbL) by the OpenStreetMap Foundation (OSMF).

Mapnik map tiles are released under LGPL (GNU Lesser General Public Licence v2.1).

The included map tile sets by © Stamen Design, are under a
Creative Commons Attribution (CC BY 3.0) license.

----------------------------------------------

Here is the new library "jOpenStreetMaps" now v1-03

for v1-03 changes refer to post #14 below.

I have also made available an example B4j project called "My OSM Demo".
The demo has also been updated to demonstrate some of the new features.
 

Attachments

  • My OSM Demo.zip
    57.1 KB · Views: 590
  • jOpenStreetMaps Library v1-03.zip
    138.1 KB · Views: 319
Last edited:

Starchild

Active Member
Licensed User
Apart from the fact that your demo requires libraries that are not really required, I have frequently this error while using it (silent error, without crash):
java.lang.IllegalArgumentException: image == null!

I have updated the "My OSM Demo" project so that it no longer referances the unused libraries.

Regarding the null image error, if it relates to the generation of a custom tile source then try declaring a
cs.GetAttributionImage = YourLogoImage
in the procedure
CreateMyCustomTileSource

If not, please post the error report so I can check in the library code.
 

Starchild

Active Member
Licensed User
I have updated the jOpenStreetMaps library to v1.01
Also updated the "My OSM Demo" to help demonstrate some of the additions.

v1.01 changes
... MapMarker.Initialize3() now supports loading an image using Dir and File strings (ie can now load from assets folder)
... added MapDraggable property to enable/disable internal mouse dragging of the map.
... revealed map OSM events; MousePressed, MouseReleased, MouseClicked, MouseMoved, MouseDragged.
... added MapSpot events, now has; MousePressed, MouseReleased, MouseClicked, MouseDragged.
... added MapMarker events, now has; MousePressed, MouseReleased, MouseClicked, MouseDragged.
... removed some unrequired legacy functions revealed by the original MapPane project.
 

Informatix

Expert
Licensed User
I have updated the jOpenStreetMaps library to v1.01
Also updated the "My OSM Demo" to help demonstrate some of the additions.

v1.01 changes
... MapMarker.Initialize3() now supports loading an image using Dir and File strings (ie can now load from assets folder)
... added MapDraggable property to enable/disable internal mouse dragging of the map.
... revealed map OSM events; MousePressed, MouseReleased, MouseClicked, MouseMoved, MouseDragged.
... added MapSpot events, now has; MousePressed, MouseReleased, MouseClicked, MouseDragged.
... added MapMarker events, now has; MousePressed, MouseReleased, MouseClicked, MouseDragged.
... removed some unrequired legacy functions revealed by the original MapPane project.
I still have the error below with the new demo and library (as the website still returns a 404 error, I'm not very surprised by the result):
java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1592)
at javax.imageio.ImageIO.write(ImageIO.java:1520)
at starchild.b4j.extras.storage.SaveImageToFile(storage.java:98)
at jfxtras.labs.map.tile.TileRepository$ImageLoadedListener.addImage(TileRepository.java:126)
at jfxtras.labs.map.tile.TileRepository$ImageLoadedListener.changed(TileRepository.java:118)
at jfxtras.labs.map.tile.TileRepository$ImageLoadedListener.changed(TileRepository.java:95)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.BooleanPropertyBase.fireValueChangedEvent(BooleanPropertyBase.java:103)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at jfxtras.labs.map.tile.Tile.setLoadedImage(Tile.java:128)
at jfxtras.labs.map.tile.Tile$2.changed(Tile.java:71)
at jfxtras.labs.map.tile.Tile$2.changed(Tile.java:66)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyDoubleWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyDoubleWrapper.java:177)
at javafx.beans.property.ReadOnlyDoubleWrapper.fireValueChangedEvent(ReadOnlyDoubleWrapper.java:143)
at javafx.beans.property.DoublePropertyBase.markInvalid(DoublePropertyBase.java:113)
at javafx.beans.property.DoublePropertyBase.set(DoublePropertyBase.java:147)
at javafx.scene.image.Image.setProgress(Image.java:198)
at javafx.scene.image.Image.finishImage(Image.java:836)
at javafx.scene.image.Image.access$300(Image.java:122)
at javafx.scene.image.Image$ImageTask.onException(Image.java:1027)
at com.sun.javafx.runtime.async.AbstractAsyncOperation$1.run(AbstractAsyncOperation.java:72)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)

If I replace the line by this one, it works:
cs.Initialize2("My-Custom-TS","http://cartodb-basemaps-a.global.ssl.fastly.net/light_all",1,18)

 
Last edited:

Starchild

Active Member
Licensed User
I still have the error below with the new demo and library (as the website still returns a 404 error, I'm not very surprised by the result):

If I replace the line by this one, it works:
cs.Initialize2("My-Custom-TS","http://cartodb-basemaps-a.global.ssl.fastly.net/light_all",1,18)
Interesting. I did not realise that "My Custom TS" was not presenting ANY map tiles for you as it worked fine for me without any errors. I think that maybe this tile server is blocked to your location.

I decided to try to access the tile server with the firewall blocked and then I experienced the reported error.
This bug has now been fixed, trapped and now presents an "X" blank tile if no valid map tile was received from the server.

As others may also have the same problem accessing this tile server I am updating my demo project with your recommended custom tile source.

Thanks.
 

Starchild

Active Member
Licensed User
I have updated the jOpenStreetMaps library to v1.02

v1.02 changes
... fixed the custom tile source issue reported above by "Informatix". Now displays "X" tile if no valid map tile is received from server.
... Added X() and Y() functions (read only) to the MapSpot. The current map X/Y position. Add them to EventData X/Y values.
... Added MoveTo(lat,lon) function to a MapSpot. This with the Pressed/Dragged/Released events allows the Spot to be dragged on the Map. Now useful as "Anchors" for editing Polylines and Polygons.
... removed the legacy SetLat() and SetLon() functions from the MapSpot class as they were incomplete functions, no redraw.

Update the "My OSM Demo" B4j project to demonstrate dragging a Map Spot (Cairo spot is now draggable).
Also, changed the custom tile server for a more available one.
 
Last edited:

Philip Prins

Active Member
Licensed User
I have updated the jOpenStreetMaps library to v1.02

v1.02 changes
... fixed the custom tile source issue reported above by "Informatix". Now displays "X" tile if no valid map tile is received from server.
... Added X() and Y() functions (read only) to the MapSpot. The current map X/Y position. Add them to EventData X/Y values.
... Added MoveTo(lat,lon) function to a MapSpot. This with the Pressed/Dragged/Released events allows the Spot to be dragged on the Map. Now useful as "Anchors" for editing Polylines and Polygons.
... removed the legacy SetLat() and SetLon() functions from the MapSpot class as they were incomplete functions, no redraw.

Update the "My OSM Demo" B4j project to demonstrate dragging a Map Spot (Cairo spot is now draggable).
Also, changed the custom tile server for a more available one.

Hello

Nice job,

Is it possible to use a local map created with Mobile Atlas Creator or another program?

Regards,
Philip
 

DonManfred

Expert
Licensed User
Can you add a LocalTilesource and an Example of using Local Tiles?

Is it possible to use a local map created with Mobile Atlas Creator or another program?
It would be great if we could read Tiles created like Mobile Atlas Creator does generate them.
I do that with free python scripts to generate Tiles up to zoom level 21.

May you want to share the Source maybe? I would be pleased to try to build some additions..
 
Last edited:

Philip Prins

Active Member
Licensed User
Thanks to "WarWound" and his original library project "JfxtrasMapPane" in the post OSM Open Street Map for B4J back in 2014 which was based on the jfxtras 2.2 r5 source, I have been able to release this updated library.

Bug fixes:
... Left mouse click now works. In fact all 3 mouse buttons are resolved.

Additions:
... Polygons can now be added/removed from map (MapPolygon class)
... Map tile providers have been updated.
... proper attributions for map tile providers have been added to the maps.
... now supports a local map cache for faster redraws.
... added a default Map Icon class containing ready to use icons (pins, car, truck, etc)
... map markers and can have their size, rotation, shadow set at initialisation.

Most Classes have been renamed and additional properties/functions added to classes.
... MapPane class is now OpenStreetMaps class.
... SimpleMapMarker class is now MapSpot class.
... MapLine is now MapPolyline.
... Initialisation functions for many classes have been changed and added.

Generally this library is a lot more friendly, in fact similar in a lot of ways to jGooleMaps library.

Just to note that the OpenStreetMap® is open data, licensed under the Open Data Commons Open Database License (ODbL) by the OpenStreetMap Foundation (OSMF).

Mapnik map tiles are released under LGPL (GNU Lesser General Public Licence v2.1).

The included map tile sets by © Stamen Design, are under a Creative Commons Attribution (CC BY 3.0) license.

----------------------------------------------

Here is the new library "jOpenStreetMaps" now v1-02

I have also made available an example B4j project called "My OSM Demo".
The demo has also been updated to demonstrate some of the new features.
Hello Starchild

The map is not working anymore , only certain parts

Regards,
Philip
 

Starchild

Active Member
Licensed User
Hello Starchild

The map is not working anymore , only certain parts

Regards,
Philip

Access to the osm map tile server has been blocked. The map tiles that are still being displayed are the ones already stored in your local tile cache.

It seems that OpenStreetMap is being hammered more and more (and even more)
Refer to these announcements by OSM.
https://lists.openstreetmap.org/pipermail/dev/2019-May/030632.html

I use jOpenStreetMaps Library to target my own map server.
I used the following link to set it all up using an old quad-core PC I had.
I only required Australia, so the hardware requirement wasn't so bad. (Although, for the world it becomes a serious machine)
You can do the same.
https://switch2osm.org/manually-building-a-tile-server-18-04-lts/
This one uses Linux Ubuntu, but there are other instructions for Windows Based Servers.

There is a wealth of information on the web to help get a map tile server up and running.
I loaded my map source data from https://download.geofabrik.de/

Alternately, there are several paid map tile services that can be subscribed to.
Some have a free developer subscription available.
I think jOpenStreetMaps library would be able to target some of them (by configuring a CustomTileSource)
 

js486dog

Active Member
Licensed User
Access to the osm map tile server has been blocked. The map tiles that are still being displayed are the ones already stored in your local tile cache.

It seems that OpenStreetMap is being hammered more and more (and even more)
Refer to these announcements by OSM.
https://lists.openstreetmap.org/pipermail/dev/2019-May/030632.html

I use jOpenStreetMaps Library to target my own map server.
I used the following link to set it all up using an old quad-core PC I had.
I only required Australia, so the hardware requirement wasn't so bad. (Although, for the world it becomes a serious machine)
You can do the same.
https://switch2osm.org/manually-building-a-tile-server-18-04-lts/
This one uses Linux Ubuntu, but there are other instructions for Windows Based Servers.

There is a wealth of information on the web to help get a map tile server up and running.
I loaded my map source data from https://download.geofabrik.de/

Alternately, there are several paid map tile services that can be subscribed to.
Some have a free developer subscription available.
I think jOpenStreetMaps library would be able to target some of them (by configuring a CustomTileSource)
Please is it possible to use own map tiles like this ?
local disk map tiles:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Title="jFXtrasMapPane demo"
    
    '    the offline tiles used in this example can be downloaded from
    '    http://b4j.martinpearman.co.uk/jfxtras.labs.map/tiles/map_of_the_uk.zip
    '    be sure to modify the path to the offline tiles in CustomTileSource1.Initialize2
    
    Dim CustomTileSource1 As CustomTileSource
    CustomTileSource1.Initialize2("Panorama", "D:\d\map_of_the_uk", 0, 3)
    
    '    the offline custom tiles are JPG images
    '    so i'll use a CustomTilePathBuilder so jpg tiles are requested
    '    (by default png tile are requested)
    Dim CustomTilePathBuilder1 As CustomTilePathBuilder
    CustomTilePathBuilder1.Initialize
    CustomTilePathBuilder1.SetTileType("jpg")
    
    CustomTileSource1.SetTilePathBuilder(CustomTilePathBuilder1)
    
    MapPane1.Initialize3("", CustomTileSource1, 0, 0, 640, 480, 0)
    MapPane1.SetDisplayPositionByLatLon(0, 0)
    
    MainForm.RootPane.AddNode(MapPane1, 0, 0, 640, 480)
    
    MainForm.Show
End Sub
 

Starchild

Active Member
Licensed User
Please is it possible to use own map tiles like this ?
local disk map tiles:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Title="jFXtrasMapPane demo"
 
    '    the offline tiles used in this example can be downloaded from
    '    http://b4j.martinpearman.co.uk/jfxtras.labs.map/tiles/map_of_the_uk.zip
    '    be sure to modify the path to the offline tiles in CustomTileSource1.Initialize2
 
    Dim CustomTileSource1 As CustomTileSource
    CustomTileSource1.Initialize2("Panorama", "D:\d\map_of_the_uk", 0, 3)
 
    '    the offline custom tiles are JPG images
    '    so i'll use a CustomTilePathBuilder so jpg tiles are requested
    '    (by default png tile are requested)
    Dim CustomTilePathBuilder1 As CustomTilePathBuilder
    CustomTilePathBuilder1.Initialize
    CustomTilePathBuilder1.SetTileType("jpg")
 
    CustomTileSource1.SetTilePathBuilder(CustomTilePathBuilder1)
 
    MapPane1.Initialize3("", CustomTileSource1, 0, 0, 640, 480, 0)
    MapPane1.SetDisplayPositionByLatLon(0, 0)
 
    MainForm.RootPane.AddNode(MapPane1, 0, 0, 640, 480)
 
    MainForm.Show
End Sub

You code should have worked.
After looking into the library code I see that the Tile type was hard coded to "png".
I have made changes to the library and your code now works.
"Well I had to change the minimum zoom level (in your example) from 0 to 1"

Try the attached "test.zip" of the new library. If it's OK, let me know so I can update the top post.

---------------------------------
EDITED: As the "test.zip" was successful, the "jOpenStreetMaps Library.zip" file in the top post has now been updated as v1-03
 
Last edited:

js486dog

Active Member
Licensed User
You code should have worked.
After looking into the library code I see that the Tile type was hard coded to "png".
I have made changes to the library and your code now works.
"Well I had to change the minimum zoom level (in your example) from 0 to 1"

Try the attached "test.zip" of the new library. If it's OK, let me know so I can update the top post.
Thank you very much Starchild. It works fine.
 

js486dog

Active Member
Licensed User
You code should have worked.
After looking into the library code I see that the Tile type was hard coded to "png".
I have made changes to the library and your code now works.
"Well I had to change the minimum zoom level (in your example) from 0 to 1"

Try the attached "test.zip" of the new library. If it's OK, let me know so I can update the top post.
Thank you very much this works fine with offline map tiles.
Please is it possible to use also zipped offline map tiles ?
Osmdroid for Android works with zip file (there are map tiles in the zip). And app works with zip file.
 

js486dog

Active Member
Licensed User
You code should have worked.
After looking into the library code I see that the Tile type was hard coded to "png".
I have made changes to the library and your code now works.
"Well I had to change the minimum zoom level (in your example) from 0 to 1"

Try the attached "test.zip" of the new library. If it's OK, let me know so I can update the top post.
MapMarker and MapSpot - Title or Description always visible.

Please is it possible to show MapMarker or MapSpot with text below it without click on it and without the white background?
Text (Title or Description) will be there always - I do not need to click on it.
Now it is possible to show title and description when I click on MapMarker or MapSpot and there s white background.
 

Starchild

Active Member
Licensed User
MapMarker and MapSpot - Title or Description always visible.

Please is it possible to show MapMarker or MapSpot with text below it without click on it and without the white background?
Text (Title or Description) will be there always - I do not need to click on it.
Now it is possible to show title and description when I click on MapMarker or MapSpot and there s white background.

I add a NodeHost to the map and add a LABEL to that NodeHost. I reposition the Node host (to the left/right/above or below) the MapMarker whenever I move the MapMarker. This way they appear to move together. You can set the Background colour of the Label to transparent if you wish (I think that's the default anyway).

I only use the Title/description properties similar to a TAG property. By this I mean I use them to carry text information relating to that MapMarker. I use the NodeHost to present that information.

I also use the click event from that NodeHost's label to hide the MapMarker's information. You can also use the Label's TAG property to reference the MapMarker object (and MapMarker's TAG to it's NodeHost) that it relates to making it easy to work with the MapMarker from the mouse events.

Works very well for me.
 
Last edited:

Starchild

Active Member
Licensed User
Thank you very much this works fine with offline map tiles.
Please is it possible to use also zipped offline map tiles ?
Osmdroid for Android works with zip file (there are map tiles in the zip). And app works with zip file.

I'm sorry. No plans at this time to implement the referencing of a ZIP file containing the tile cache.
 

Starchild

Active Member
Licensed User
I add a NodeHost to the map and add a LABEL to that NodeHost. I reposition the Node host (to the left/right/above or below) the MapMarker whenever I move the MapMarker. This way they appear to move together. You can set the Background colour of the Label to transparent if you wish (I think that's the default anyway).

I only use the Title/description properties similar to a TAG property. By this I mean I use them to carry text information relating to that MapMarker. I use the NodeHost to present that information.

I also use the click event from that NodeHost's label to hide the MapMarker's information. You can also use the Label's TAG property to reference the MapMarker object (and MapMarker's TAG to it's NodeHost) that it relates to making it easy to work with the MapMarker from the mouse events.

Works very well for me.

I had a further thought. You could create your own Server class to mimic a tile server using your own port number and local IP (127.0.0.1). When your server class receives a HTTP: request for a map tile, you can fetch it from the ZIP file and send it as the reply. This Server class could be a separate program or within your the same mapping program. This way, the existing jOpenStreetMaps library could access your Zip Cache file.

Below is a tutorial provided by Erel. It will help get you started.
B4J Tutorial - [Server] Building web servers with B4J
 
Top