gwidgets / gwty-leaflet

A GWT JsInterop wrapper for Leaflet.
Apache License 2.0
32 stars 14 forks source link

How to pass another TileLayerOptions implementation to L.tileLayer ? #8

Closed olivergg closed 7 years ago

olivergg commented 7 years ago

I'm wondering how to use a custom TileLayerOptions with :

public static native TileLayer tileLayer(String urlTemplate, 
TileLayerOptions options);

To call this method, you have to pass an instance of TileLayerOptions. But in the leaflet docs, there is no actual object that corresponds to TileLayerOptions, it's rather an object literal.

So how do you pass for example a TileLayerWMSOption to this method ? Or any other options map for another provider.

ps : I don't know why all the JsType constructors are mostly private, but because of that, we can't extend L to add other static method, or extend TileLayerOption.

Thanks

zak905 commented 7 years ago

Hi @olivergg ,

The reason why I used a private constructor is because I am using the builder pattern to build all *Options objects to make sure that the developer would only create options through their builders, and thus make sure required fields are provided. For example:

TileLayerOptions options = new TileLayerOptions .Builder().attribution ("map").build();

because TileLayerOptions does not have any required values the Builder() has no argument

but for MapOptions you need some required fields, so an example would be: //required values: center point, zoom, and a min zoom MapOptions options = new MapOptions.Builder(L.latLng(52.51, 13.40), 12, 12).dragging(false).build();

TileLayerOptions contains all the options that you need http://leafletjs.com/reference-1.0.0.html#tilelayer

TileLayerWMSOption is not for TileLayer but rather for WMS object so:

@JsMethod public static native WMS wms(String baseUrl, TileLayerWMSOptions options);

Why do want to extend it? what do you want to add exactly?

olivergg commented 7 years ago

@zak905 thanks for your answer, let me explain what I'm trying to achieve. I get the builder pattern and I think fluent interfaces are great for the purpose of a library such as Leaflet. But when you say that the TileLayerOptions contains all the options, it's not entirely true. In the javascript world, there is no distinction between an object and a map of properties, so for example

L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'});

The {foo:'bar'} is the object literal, but all the available properties are not exhaustive in the documentation (and couldn't possibly be). For example, for a HERE layer, I need some more :

L.tileLayer('http://{s}.{base}.maps.cit.api.here.com/maptile/2.1/{type}/{mapID}/{scheme}/{z}/{x}/{y}/{size}/{format}?app_id={app_id}&app_code={app_code}&lg={language}', {
  attribution: 'Map &copy; 2016 <a href="http://developer.here.com">HERE</a>',
  subdomains: '1234',
  base: 'base',
  type: 'maptile',
  scheme: 'pedestrian.day',
  app_id: '{app_id}',
  app_code: '{app_code}',
  mapID: 'newest',
  maxZoom: 20,
  language: 'eng',
  format: 'png8',
  size: '256'
});

Right now, if one wants to call the gwidgets API

public static native TileLayer tileLayer(String  urlTemplate, TileLayerOptions options)

one have to pass a TileLayerOptions. If I try to pass a TileLayerHereOptions with the custom properties besides the one from TileLayerOptions, I have to rewrite everything from TileLayerOptions (because of the private constructor)

In Java, you have to declare them in a new type annotated @JsType(name="Object") which is fine and idiomatic for Java (you enforce some rules over the various options). But at the core of Leaflet, the various "options" parameters are not types, in the sense there are different from the ILayer or Evented interfaces which can be easily translated to a Java type.

I'm not asking for a public constructor, but a protected one should be enough (same as com.gwidgets.api.leaflet.Control).

Needless to say that this applies to every "options map" of the leaflet API even though I admit the TileLayerOptions is a specific case and most of the time there is no need to extend, but it shouldn't be disallowed.

What do you think ?

zak905 commented 7 years ago

Hi @olivergg,

I have changed the visibility of the constructor of TileLayerOptions and TileLayerWMSOptions, you can use the 1.0-SNAPSHOT version. Let me know if you need anything else.

Cheers.

olivergg commented 7 years ago

@zak905 thanks