mapjfx-demo

Caching of data

Version 1.7.0 adds the possibility to cache the data that is loaded from the web in a directory to both speed loading at a later time and to be able to use the application later when offline.

technical information

Alas the JavaFX WebView does not offer the possibility to enable caching, so I had to integrate my solution deep into the Java networking by installing a custom URLStreamHandlerFactory. This means that all http and http connections that are made from the application are passing through this caching mechanism. As a custom URLStreamHandlerFactory can only be installed once in a JVM, this also means that mapjfx caching cannot be used together with another component that also does install a URLStreamHandlerFactory.

As long as the caching in mapjfx is not explicitly enabled, the URLStreamHandlerFactory is not set, this is done when the cache is programmatically set to active for the first time.

prevent URLs from being cached.

As of version 1.30.0 it is possible to define a list of Java Regex Patterns which will prevent URLs that match these patterns from being cached. The code for this is for example:

offlineCache.setNoCacheFilters(Collections.singletonList(".*\\.sothawo\\.com/.*"));
offlineCache.setActive(true);

The argument to setNoCacheFilters is an Collection of String objects containing regular expressions.

restrictions / Problems

The following restrictions or problems have been found during the development:

  • caching of Bing Maps data only works with an internet connection. The image data is cached quite well, but when reloading, there is a REST call to bing which I have not further investigated, so that this prevents loading and using the cache data when offline. When online, the cache can still be used to speed up loading. OpenStreetmap data does not have this problem.
  • Caching will probably removed for the JDK11+ versions. The implementation needs to get the default  URLStreamHandlers from the default URLStreamHandlerFactory and this is only possible with a reflective access the is not allowed anymore in the JDK versions since version 9.

code example

The following cod shows how the cache directory is set and how the cache is activated in the mapjfx-demo application:

// init MapView-Cache
final OfflineCache offlineCache = mapView.getOfflineCache();
final String cacheDir = System.getProperty("java.io.tmpdir") + "/mapjfx-cache";
logger.info("using dir for cache: " + cacheDir);
try {
    Files.createDirectories(Paths.get(cacheDir));
    offlineCache.setCacheDirectory(cacheDir);
    offlineCache.setActive(true);
} catch (IOException e) {
    logger.warn("could not activate offline cache", e);
}

 

Have fun testing and using the mapjfx component.

Comments and contributions are welcome!

31 thoughts on “mapjfx-demo

  1. Pingback: mapjfx 1.7.0 with the ability for caching map data | sothawo

    • Hello,

      on which System? Which map type? Do you run software like vpn etc?

      The demo has enabled the offline cache for the embedded browser, can you change the line 271 in Controller.java so that the cache is not used, either by putting a comment in front or by changing it to offlineCache.setActive(false);?

      When starting the program from the console/terminal, do you see some errors in the output?

      greetings
      Peter

      • Hello,

        thank you for the answer.
        The system is Windows7.

        Now,I have tested the demo on another PC, and here I can see the OSM-Map, when starting from console.
        But in Netbeans-IDE, the map still does not appear.

        Setting offlineCache to false takes no effect.

        Greetings,

        Tursic

          • No errors, just this:
            10:34:44.789 [JavaFX Application Thread] INFO com.sothawo.mapjfx.demo.DemoApp – starting DemoApp
            10:34:44.791 [JavaFX Application Thread] DEBUG com.sothawo.mapjfx.demo.DemoApp – loading fxml file /fxml/DemoApp.fxml
            10:34:45.039 [JavaFX Application Thread] DEBUG com.sothawo.mapjfx.demo.Controller – map type toggled to RadioButton[id=radioMsOSM, styleClass=radio-button]’OSM’
            10:34:45.532 [JavaFX Application Thread] DEBUG com.sothawo.mapjfx.demo.Controller – initialization finished
            10:34:45.858 [JavaFX Application Thread] DEBUG com.sothawo.mapjfx.demo.DemoApp – application start method finished.
            10:34:46.081 [JavaFX Application Thread] DEBUG com.sothawo.mapjfx.demo.Controller – setting center and enabling controls…

            On the other PC (with Windows 10) the map still doesn’t appear, even if started from console.

            Maybe a performance-problem? The rendering of the map is very slow anyway.

            • strange. When I start the program on Windows the from a console with the command mvn clean package && cd target/mapjfx-demo && ./bin/mapjfx-demo) I get the following output:

              04:55:53.545 INFO [JavaFX Application Thread] com.sothawo.mapjfx.demo.DemoApp - starting DemoApp
              04:55:53.545 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.demo.DemoApp - loading fxml file /fxml/DemoApp.fxml
              04:55:53.792 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - begin initialize
              04:55:53.797 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - location buttons done
              04:55:53.821 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - options and labels done
              04:55:53.823 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - map type toggled to RadioButton[id=radioMsOSM, styleClass=radio-button]'OSM'
              04:55:53.826 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - map handlers initialized
              04:55:53.869 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - marker checks done
              04:55:53.879 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - tracks loaded
              04:55:53.879 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - tracks checks done
              04:55:53.880 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - start map initialization
              04:55:53.880 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - initializing...
              04:55:53.881 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/mapview.html
              04:55:53.885 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/ol/4.0.1/ol.css
              04:55:53.886 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/polyfill.js
              04:55:53.886 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/ol/4.0.1/ol.js
              04:55:53.908 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/mapview.css
              04:55:53.909 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading custom mapview css from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-demo-1.12.1.jar!/custom_mapview.css
              04:55:53.910 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/functions.js
              04:55:53.911 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/MapObject.js
              04:55:53.911 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/WMSParams.js
              04:55:53.911 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/coordinateline.js
              04:55:53.911 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - loading from jar:file:/C:/Users/peter/Entwicklung/mapjfx-demo/target/mapjfx-demo/lib/mapjfx-1.12.2.jar!/mapview.js
              04:55:53.985 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - WebView created
              04:55:53.986 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - Java Version: 1.8.0_121-b13
              04:55:53.986 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - JavaFX Version: 8.0.121-b13
              04:55:53.987 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - OS: Windows 10, 10.0, amd64
              04:55:53.987 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/602.1 (KHTML, like Gecko) JavaFX/8.0 Safari/602.1
              04:55:53.988 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - load html into WebEngine
              04:55:54.007 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - WebEngine loader state READY -> SCHEDULED
              04:55:54.008 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - WebEngine loader state SCHEDULED -> RUNNING
              04:55:54.010 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - initialization finished
              04:55:54.010 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.DemoApp - stage loaded
              04:55:54.059 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.DemoApp - scene created
              04:55:54.060 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.DemoApp - showing scene
              04:55:54.500 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.demo.DemoApp - application start method finished.
              04:55:54.732 DEBUG [JavaFX Application Thread] com.sothawo.mapjfx.MapView - WebEngine loader state RUNNING -> SUCCEEDED
              04:55:54.735 TRACE [JavaFX Application Thread] com.sothawo.mapjfx.demo.Controller - map intialized

              That’s a lot more before the Map is shown. Can you use a debugger to step through the Controller.initialize() method?

  2. For some reason the logger.trace is not shown im my debug-output.

    And when I step into ‘mapView.initialize()’, only the Logger.finer – Method is called.

  3. Hello,

    is it possible to add markers and labels at runtime?
    I have tried it, but only the markers defined in the constructor are visible.

    Greetings,
    Tursic

    • Sure it’s possible. You have to take care that you keep a reference of the created markers, otherwise they are immediately garbage-collected.

      If for example you add the following property to the Controller class:

      private Map<String, Marker> markersCreatedOnClick = new HashMap<>();

      and add this code in the event handler initializer:


      mapView.addEventHandler(MapViewEvent.MAP_CLICKED, event -> {
      final Marker marker = Marker.createProvided(Marker.Provided.ORANGE)
      .setPosition(event.getCoordinate())
      .setVisible(true);
      mapView.addMarker(marker);
      markersCreatedOnClick.put(marker.getId(), marker);
      });
      mapView.addEventHandler(MarkerEvent.MARKER_CLICKED, event -> {
      event.consume();
      Marker marker = markersCreatedOnClick.remove(event.getMarker().getId());
      if (null != marker) {
      mapView.removeMarker(marker);
      }
      });

      then with every click you will add a new marker and clicking on the marker will remove it again.

      • Thank you very much.

        On my development-PC it works now fine (except from the missing map when started in the IDE, but that would be ok), but unfortunately on every other PC I tested, the map does not appear at all.

        Could it be the WMSParam-Urls?

        It looks like the map is loaded somehow, because the markers appear and I can move and zoom, only the map itself is missing, there is only a grey background.

          • Hello everyone I had the same issue when the map was not showing in the demo app even though cache was disabled.

            The fix was that I adjusted the Java version to instead using an old JRE 1.8.0_66 to use a new JDK 1.8.0_121.

            Then the map was shown correctly.

  4. Hello,
    is it posible to use map in JFXPanel of Swing application, i see only zoom in/out after calling initialize(). But no map?
    I have set mapType to OSM.
    Thanks for answer

    • Does the mapjfx-demo application work on your system? I am just asking to make sure that there is no problem in the combination of OS, Java version with mapjfx component. Please check this.

  5. Hello,

    The map is not displaying for me. All I can see are zoom buttons, but none of the map layers.

    I’m running Java 8 on Windows 10 with 1.15. Any ideas?

    • Hello Chris,
      which version of Java? JDK or JRE? At the moment when running this on 1.8.0_162 on OSX the loading of the map tiles was quite slow, but now it’s working here.

      There is an open issue (https://github.com/sothawo/mapjfx/issues/29) where I am investigating a similar problem, but I have no solution for that. Is this only happening for the OSM map? The WMS Gis Landsat server seems not to be available anymore, but can you try the WMS world food programme map and zoom out to level 3? This should give you a grey map with some darker grey boundaries especially in Africa and the middle east.

      You can sign up for a Bing Maps API key, that does not cost anything for up to 125.000 calls a year. At least that what give you the possibility to check if this map type is working.

  6. Very interesting and useful code!!!

    Can you explain how can i use “stamen watercolor” type map ?

    Thank you in advanced.

    • in the demo app by selecting ‘map style’ on the left and then the ‘Stamen Watercolor” radio button.
      But as this is a OpenStreetmap map as wellm you might run into the problems with the mpa tiles not properly loading; see the blog posts and jira issues for more details.

  7. Is it possible to use this library in an offline application? We currently have a swing based application which renders a map and various layers using OpenMap and all our data is stored locally. Plus OpenMap supports a bunch of mapping standards like VMAP and DTED. Does your library support something like those or would we have to write something?

    • as written here (https://www.sothawo.com/projects/mapjfx-demo/6/) there is an offline caching mode which caches the tiles during an online session, so they are available later even when offline.

      **But**: this will not work from probably Java 11 on, as I need to use some reflection to get this working which will not be allowed in Java versions to come

Leave a Reply

Your email address will not be published.