Add custom wms layer to codename one Mapcontainer

466 views Asked by At

I am building an android GPS app with Codename one. I use com.codename1.googlemaps.MapContainer to create a Google map; In my app is use tabs to create different "pages".

Code:

cnt = new MapContainer();
t.addTab("Tab3", cnt);

And for my current location I use:

try {
  Coord position = new Coord(lat,lng);
  cnt.clearMapLayers();
  cnt.setCameraPosition(position);
  cnt.addMarker(EncodedImage.create("/maps-pin.png"), position, "Hi marker", "Optional long description", new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
      // stuff todo...
    }
  });
} catch(IOException err) {
  // since the image is iin the jar this is unlikely
  err.printStackTrace();
}

I like to add a wms layer to the Google Maps. Is this possible? I can't find in codenameone a command addLayer. If yes, do you have a code snippet how to do this? If it is not possiple, can I use openlayers in my codename one app? Can you give me a code snippet to do this?

Edit I started to create an native file to "catch"the addtileoverlay from google maps api. The layer I want to use is a xyz layer, so I think I can use a urltileprovider from the googlemap api

I made the native code for the tileoverlay but the tileoverlay doesn't appear. Is it because i didn't get a link with the mapcontainer. I am little bit stuck. I tried to build from scratch with the googmaps example but the mapcompnent is not anymore used.

package com.Bellproductions.TalkingGps;

import com.google.android.gms.maps.model.UrlTileProvider;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.TileOverlayOptions;
import com.google.android.gms.maps.model.TileProvider;
import com.google.android.gms.maps.model.TileOverlay;
import com.codename1.impl.android.AndroidNativeUtil;
import java.util.Locale;
import java.net.MalformedURLException;

public class SeamarksImpl  { 

private GoogleMap mapInstance;
private TileOverlay m;
  TileProvider provider;
public boolean isSupported() {
    return true;
}

public long addTilelayer (){

 final String URL_FORMAT = "http://t1.openseamap.org/seamark/{z}/{x}/{y}.png";



    AndroidNativeUtil.getActivity().runOnUiThread(new Runnable() {

public void run() {


provider = new UrlTileProvider(256, 256) {

@Override
    public  synchronized URL getTileUrl(int x, int y, int zoom) {

try {
            y = (1 << zoom) - y - 1;
            return new URL(String.format(Locale.US, URL_FORMAT, zoom, x, y ));
        } catch (MalformedURLException e) {
            throw new RuntimeException();
        }

}

TileOverlayOptions tileopt = new TileOverlayOptions().tileProvider(provider);


public void addlayer() {
m = mapInstance.addTileOverlay(tileopt);
}

};

}

});

long p = 1;

return p;}

}

My seamarks.java file has this code to bind with the native interface

import com.codename1.system.NativeInterface;

/**
 *
 * @author Hongerige Wolf
 */


public interface Seamarks extends NativeInterface {
  public void addTilelayer ();
}

In the mainactivity java file i have the statements

public Seamarks seamark;
public void init(Object context) {

  seamark = (Seamarks)NativeLookup.create(Seamarks.class);
}

public void start() { 
      seamark.addTilelayer();
}

Update I created a new googlemaps.CN1lib. But the xyz layer is not showing on the googlemaps. I used native code tot use the Tileoverlay feature and tried to add tileoverlay in the same way as Markers. In the InternalNativeMapsImpl file i changed

 private void installListeners() {
    /*
    if (mapInstance == null) {
        view = null;
        System.out.println("Failed to get map instance, it seems google play services are not installed");
        return;
    }*/
    view.getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mapInstance = googleMap;

TileProvider tileProvider;
    tileProvider = new UrlTileProvider(256, 256) {
    String tileLayer= "http://t1.openseamap.org/seamark/";
        @Override
        public synchronized URL getTileUrl(int x, int y, int zoom) {
            // The moon tile coordinate system is reversed.  This is not normal.
            int reversedY = (1 << zoom) - y - 1;
            //String s = String.format(Locale.US, tileLayer , zoom, x, y);
            String s = tileLayer + "/" + zoom + "/" + x + "/" + reversedY + ".png";
            URL url = null;
            try {
                url = new URL(s);
            } catch (MalformedURLException e) {
                throw new AssertionError(e);
            }
            return url;
        }
    };

    mMoonTiles =  mapInstance.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));




            mapInstance.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
                public boolean onMarkerClick(Marker marker) {
                    Long val = listeners.get(marker);
                    if (val != null) {
                        MapContainer.fireMarkerEvent(InternalNativeMapsImpl.this.mapId, val.longValue());
                        return true;
                    }
                    return false;
                }
            });
            mapInstance.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
                public void onCameraChange(CameraPosition position) {
                    MapContainer.fireMapChangeEvent(InternalNativeMapsImpl.this.mapId, (int) position.zoom, position.target.latitude, position.target.longitude);
                }
            });
            mapInstance.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
                public void onMapClick(LatLng point) {
                    Point p = mapInstance.getProjection().toScreenLocation(point);
                    MapContainer.fireTapEventStatic(InternalNativeMapsImpl.this.mapId, p.x, p.y);
                }
            });


            mapInstance.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {

                public void onMapLongClick(LatLng point) {
                    Point p = mapInstance.getProjection().toScreenLocation(point);
                    MapContainer.fireLongPressEventStatic(InternalNativeMapsImpl.this.mapId, p.x, p.y);
                }
            });
            mapInstance.setMyLocationEnabled(showMyLocation);
            mapInstance.getUiSettings().setRotateGesturesEnabled(rotateGestureEnabled);
        }
    });

}

Secondly i added a addTilexyz method also in the same way as addMarkers

 public long addTilexyz(final String Turl) {
    uniqueIdCounter++;
    final long key = uniqueIdCounter;

AndroidNativeUtil.getActivity().runOnUiThread(new Runnable() { public void run() {

TileProvider tileProvider;
    tileProvider = new UrlTileProvider(256, 256) {
    // Tileurl = "http://t1.openseamap.org/seamark/";
        @Override
        public synchronized URL getTileUrl(int x, int y, int zoom) {
            // The moon tile coordinate system is reversed.  This is not normal.
            int reversedY = (1 << zoom) - y - 1;
            String s = String.format(Locale.US, Turl , zoom, x, reversedY);

            URL url = null;
            try {
                url = new URL(s);
            } catch (MalformedURLException e) {
                throw new AssertionError(e);
            }
            return url;
        }
    };

    mMoonTiles =  mapInstance.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));      

        }
        });

    return key;
}

In the InternalNativeMaps file i added te method

    public long addTilexyz(String Turl);

And in the Mapcontainer file i added

 public MapObject addTilexyz(String Turl) {
    if(internalNative != null) {
         MapObject o = new MapObject();
         Long key = internalNative.addTilexyz(Turl);
         o.mapKey = key;
         markers.add(o);
        return o;
    } else {

        }

        MapObject o = new MapObject();
        return o;
    }

I am puzzeled what is wrong with the code. I wonder if the commands

Long key = internalNative.addTilexyz(Turl);

and 

mMoonTiles =  mapInstance.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));

put the tileoverlay on the googlemap. Or is the tileurl wrong. http://t1.openseamap.org/seamark/z/x/y.png is correct.

1

There are 1 answers

21
Shai Almog On

We don't expose layers in the native maps at this time, you can fork the project and just add an API to support that to the native implementations.