Rafael Albani
Rafael Albani

Reputation: 27

Mapbox and GWT integration

I am trying to make the MapBox Javascript Library work with GWT(Google Web Toolkit).

Below is a snippet of the code that i'm using:

    HorizontalPanel horizontalPanel = new HorizontalPanel();
    horizontalPanel.setHeight("400px");
    horizontalPanel.setWidth("600px");
    horizontalPanel.getElement().setId("geo-map");

    ScriptInjector.fromUrl("https://api.tiles.mapbox.com/mapbox.js/v2.1.4/mapbox.js").setCallback(new Callback<Void, Exception>() {

        @Override
        public void onFailure(Exception reason) {

        }

        @Override
        public void onSuccess(Void result) {

            ScriptInjector.fromString("$wnd.$(document).ready(function() {" +
                            "console.log(\"Ok, it's me!\");" +
                            "L.mapbox.accessToken = \"Some Acess Token\";" +
                            "var map = L.mapbox.map(\"geo-map\", \"geo-map-id\").setView([40, -74.50], 9);" +
                            "console.log(\"Ok, it's me again!\");" +
                        "});").inject();

        }
    }).inject();

    // Add the nameField and sendButton to the RootPanel
    // Use RootPanel.get() to get the entire body element
    RootPanel.get("nameFieldContainer").add(horizontalPanel);

When i run the code, i receive the following exception:

[15:00:46.146] Error: Map container not found. @ https://api.tiles.mapbox.com/mapbox.js/v2.1.4/mapbox.js:1

Thanks in Advance

Update: I finally make it work, i had to put the javascript function in the end of the body tag of my HTML file of the module.

Upvotes: 2

Views: 597

Answers (2)

Rodrigo Fava
Rodrigo Fava

Reputation: 338

Using GWT 2.8 JsInterop with MapBox GL JS goes like this:

  1. Add the css and js on your index page as per MapBox Tutorial
  2. Make the mapboxgl.Map available to your Java:

    @JsType(isNative = true, namespace = "mapboxgl")
    
     class Map {
    
        @JsOverlay
        private static long serial = 0L; 
    
        @JsConstructor
        protected Map(JavaScriptObject options) { }
    
        @JsOverlay
        public static Map build(AbsolutePanel panel) {
            return Map.build(panel, new JSONObject());
        }
    
        @JsOverlay
        public static Map build(AbsolutePanel panel, JSONObject mapOptions) {
    
            String id = "map" + serial++;
            mapOptions.put("container", new JSONString(id));
    
            panel.getElement().setId(id);
            Map result = new Map(mapOptions.getJavaScriptObject());     
            return result;
        }
    
    }
    
  3. Later on you can add other Methods, Properties, Events to your Map class

  4. Use the parameter JSONObject mapOptions to set your map properties, for example:

    { center: [-122.420679, 37.772537],

    zoom: 13,

    style: 'mapbox://styles/mapbox/dark-v9' }

  5. Create a class that extends AbsolutePanel to become your Map Widget

    public class MapPanel extends AbsolutePanel {
    
    private static boolean accessTokenIsSet = false; 
    
    Map map;
    JSONObject mapOptions;
    MapPanel instance;
    
    public MapPanel(int width, int height) {
        this(width, height, new MapOptions());
    }
    
    public MapPanel(int width, int height, JSONObject mapOptions) {     
        instance = this;
        this.mapOptions = mapOptions;
    
        if ( !accessTokenIsSet ) {
            setAccessToken();
            accessTokenIsSet = true;
        }
    
        getElement().getStyle().setWidth(width, Unit.PX);
        getElement().getStyle().setHeight(height, Unit.PX);
        this.addEvents();
    }
    
    private void addEvents() {
        addAttachHandler(new AttachEvent.Handler() {
    
            @Override
            public void onAttachOrDetach(AttachEvent event) {
                if ( event.isAttached() ) {
                    map = Map.build(instance, mapOptions);
                }
    
            }
        });
    }
    
    private static native void setAccessToken() /*-{
        mapboxgl.accessToken = '<your-key>';
    }-*/;
    

    }

  6. Instantiate your MapPanel widget and add wherever needed

    JSONObject mapOptions = new JSONObject();
    
    JSONArray center = new JSONArray();
    center.set(0, new JSONNumber(-122.420679));
    center.set(1, new JSONNumber(37.772537));
    
    mapOptions.put("style", new JSONString("mapbox://styles/mapbox/streets-v9"));
    mapOptions.put("zoom", new JSONNumber(13));
    mapOptions.put("center", center);
    MapPanel mapPanel = new MapPanel(300, 300, mapOptions);
    RootPanel.get().add(mapPanel);
    

Upvotes: 3

FYI: I have been writing a GWT client for the Mapbox GL JS library. It still needs to be completed/improved, but you can already use a good part of its features:

Currently used here:

Upvotes: 3

Related Questions