Dart Documentationdartkart.layerWMSLayer

WMSLayer class

WMSLayer loads map tiles from a Web Map Server.

class WMSLayer extends TileLayer {

 String _serviceUrl;
 final List<String> _layers = [];
 Map<String, String> _defaultParameters;

 _initParameters(Map userParameters) {
   if (userParameters == null) {
     userParameters = {};
   }

   _defaultParameters = new Map();
   // normalize case
   userParameters.keys.forEach((k) {
     _defaultParameters[k.toUpperCase()] = userParameters[k];
   });
   if (!_defaultParameters.containsKey("SERVICE")) {
     _defaultParameters["SERVICE"] = "WMS";
   }
   if (!_defaultParameters.containsKey("VERSION")) {
     _defaultParameters["VERSION"] = "1.0.0";
   }
   if (!_defaultParameters.containsKey("FORMAT")) {
     _defaultParameters["FORMAT"] = "image/png";
   }
   if (!_defaultParameters.containsKey("SRS")) {
     _defaultParameters["SRS"] = "EPSG:4326";
   }
 }
 /**
  * [serviceUrl] is base URL of the WMS server.
  *
  * [layers] is either a single layer name or a list of layer
  * names.
  *
  * [parameters] is a map of WMS request parameters.
  * 
  * [renderer] is one of the renderer values supported by
  * [TileLayer].
  *
  * ##Examples
  *      var layer1 = new WmsLayer(
  *        serviceUrl: "https://wms.geo.admin.ch?",
  *        layers: "ch.are.gemeindetypen"
  *      );
  *
  *      var layer2 = new WmsLayer(
  *        serviceUrl: "https://wms.geo.admin.ch?",
  *        layers: ["ch.are.gemeindetypen", "ch.are.alpenkonvention"],
  *        parameters: {
  *          "FORMAT": "image/jpeg"
  *        }
  *      );
  */
 WMSLayer({String serviceUrl, layers, Map parameters, renderer})
   : super(renderer:renderer)
 {
     if (?serviceUrl) this.serviceUrl = serviceUrl;
     if (?layers) this.layers = layers;
     _initParameters(parameters);
 }

 /// the layer(s) to be loaded from the WMS server
 List<String> get layers => _layers;

 /**
  * Sets the layer(s) to be retrieved from the WMS server.
  *
  * ## Possible values
  * * [String] - a single layer
  * * [List] - a list of layer names
  */
 void set layers(value) {
   if (value is String) {
     _layers.clear();
     _layers.add(value);
   } else if (value is List) {
     _layers.clear();
     _layers.addAll(value);
   } else {
     throw new ArgumentError("expected String or list thereof, got $value");
   }
 }

 /// sets the service URL
 void set serviceUrl(String value) {
   if (value != null && value.endsWith("?")) {
     value = value.substring(0, value.length -1);
   }
   _serviceUrl = value;
 }

 /// the URL of the WMS server or null, if the server URL
 /// isn't configured yet
 String get serviceUrl => _serviceUrl;

 /**
  * Builds the tile bounding box for tile ([x],[y]) in geographic
  * coordinates.
  */
 //TODO: Order of components in the bbox string changed in WMS 1.3.0?
 String _buildGeographicTileBBox(int x, int y, int zoom) {
   var size = tileSize;
   var tx = x * tileSize.width;
   var ty = y * tileSize.height + (tileSize.height - 1);
   var min = map.mapToEarth(map.zoomPlaneToMap(new Point2D(tx, ty)));

   tx = tx + tileSize.width - 1;
   ty = y * tileSize.height;
   var max = map.mapToEarth(map.zoomPlaneToMap(new Point2D(tx, ty)));
   return "${min.lon},${min.lat},${max.lon},${max.lat}";
 }

 /**
  * Indicates whether the bounding box of a WMS `GetMap`request is
  * expressed in geographic or in projected coordinates.
  *
  * * if false, the bounding box is expressed in geographic coordinates,
  *   i.e. in WGS84 aka
  *   [EPSG:4326](http://spatialreference.org/ref/epsg/4326/)
  *
  * * if true, the bounding box is expressed in projected coordinates,
  *   that is coordinate reference system configured on the
  *   map viewport, see [MapViewport.crs].
  *
  * Default value is false.
  */
 bool useProjectedCoordinates = false;

 /**
  * Builds the tile bounding box for tile ([x],[y]) in projected
  * coordinates
  */
 //TODO: Order of components in the bbox string changed in WMS 1.3.0?
 String _buildProjectedTileBBox(int x, int y, int zoom) {
   var tx = x * tileSize.width;
   var ty = y * tileSize.height + (tileSize.height - 1);
   var min = map.zoomPlaneToMap(new Point2D(tx, ty));

   tx = tx + tileSize.width - 1;
   ty = y * tileSize.height;
   var max = map.zoomPlaneToMap(new Point2D(tx, ty));
   return "${min.x},${min.y},${max.x},${max.y}";
 }

 @override
 String bindTileToUrl(int x, int y, int zoom) {
   var ts = tileSize;
   var parameters = new Map.from(_defaultParameters);
   parameters["REQUEST"] = "GetMap";
   parameters["LAYERS"] = _layers.join(",");
   parameters["WIDTH"] = ts.width.toString();
   parameters["HEIGHT"] = ts.height.toString();
   if (useProjectedCoordinates) {
     parameters["BBOX"] = _buildProjectedTileBBox(x,y,zoom);
     parameters["SRS"] = _map.crs.code;
   } else {
     parameters["BBOX"] = _buildGeographicTileBBox(x,y,zoom);
     parameters["SRS"] = "EPSG:4326";
   }

   var query = parameters.keys.map((k) => "$k=${parameters[k]}").join("&");
   var url = "$_serviceUrl?$query";
   return url;
 }

 @override
 void render() {
   if (_serviceUrl == null) {
     print("WARNING: can't render, serviceUrl not defined");
     return;
   }
   if (_layers.isEmpty) {
     print("WARNING: can't render, no layers defined");
     return;
   }
   super.render();
 }
}

Extends

Object_PropertyObservable > Layer > TileLayer > WMSLayer

Constructors

new WMSLayer({String serviceUrl, layers, Map parameters, renderer}) #

serviceUrl is base URL of the WMS server.

layers is either a single layer name or a list of layer names.

parameters is a map of WMS request parameters.

renderer is one of the renderer values supported by TileLayer.

Examples

 var layer1 = new WmsLayer(
   serviceUrl: "https://wms.geo.admin.ch?",
   layers: "ch.are.gemeindetypen"
 );

 var layer2 = new WmsLayer(
   serviceUrl: "https://wms.geo.admin.ch?",
   layers: ["ch.are.gemeindetypen", "ch.are.alpenkonvention"],
   parameters: {
     "FORMAT": "image/jpeg"
   }
 );
WMSLayer({String serviceUrl, layers, Map parameters, renderer})
 : super(renderer:renderer)
{
   if (?serviceUrl) this.serviceUrl = serviceUrl;
   if (?layers) this.layers = layers;
   _initParameters(parameters);
}

Properties

final DivElement container #

inherited from Layer
DivElement get container => _container;

String get domId #

inherited from Layer

the unique layer id

String get domId => _container.attributes["id"];

void set domId(String value) #

inherited from Layer

Sets the DOM id on the layer container.

If value is null or empty, sets a default id.

void set domId(String value) {
 if (value != null) value = value.trim();
 if (value == null || value.isEmpty) {
   value = _defaultDOMId();
 }
 _container.attributes["id"] = value;
}

final int id #

inherited from Layer

the unique numeric id for this layer

int get id => _nid;

List<String> get layers #

the layer(s) to be loaded from the WMS server

List<String> get layers => _layers;

void set layers(value) #

Sets the layer(s) to be retrieved from the WMS server.

Possible values

  • String - a single layer
  • List - a list of layer names
void set layers(value) {
 if (value is String) {
   _layers.clear();
   _layers.add(value);
 } else if (value is List) {
   _layers.clear();
   _layers.addAll(value);
 } else {
   throw new ArgumentError("expected String or list thereof, got $value");
 }
}

final MapViewport map #

inherited from Layer

the map this layer is attached to, or null

MapViewport get map => _map;

String get name #

inherited from Layer

the layer name

String get name {
 if (_name == null) return _defaultName;
 return _name;
}

void set name(String value) #

inherited from Layer

sets the layer name. If value is null or consists of white space only, a default name is chosen.

void set name(String value) {
 if (value != null) value = value.trim();
 var old = _name;
 if (value == null || value.isEmpty) {
   _name = null;
 } else {
   _name = value;
 }
 notify("name", old, name);
}

final Stream<PropertyChangeEvent> onPropertyChanged #

the stream of property change events

Example

 // an observable with a mixed in PropertyObservable
 var observable = ...;
 // listen for property change events for the property
 // 'my_property'
 observable.onPropertyChanged
   .where((evt) => evt.name == "my_property")
   .listen((evt) => print("new value: ${evt.newValue}"));
Stream<PropertyChangeEvent> get onPropertyChanged {
 //TODO: fix this - if at least one listener is present,
 // change events are emitted, regardless of whether the
 // individual listeners are paused or not. Consequence:
 // lots of change events are possibly queued up in
 // paused listener streams. => need a custom implementation
 // of a multiplexing stream which disards events if
 // they are streamed to a disabled listener
 //
 if (_stream == null) {
   _stream = _controller.stream.asBroadcastStream();
 }
 return _stream;
}

double get opacity #

inherited from Layer

the opacity of this layer

double get opacity => _opacity;

void set opacity(num value) #

inherited from Layer

set the opacity of this layer. value is a num in the range (0.0 - 1.0). The lower the value, the more transparent the layer.

void set opacity(num value) {
 value = math.max(0, value);
 value = math.min(value, 1);
 var oldvalue = _opacity;
 this._opacity = value.toDouble();
 if (oldvalue != this._opacity) {
   notify("opacity", oldvalue, this._opacity);
   if (_map != null) {
     _map.render();
   }
 }
}

String get serviceUrl #

the URL of the WMS server or null, if the server URL isn't configured yet

String get serviceUrl => _serviceUrl;

void set serviceUrl(String value) #

sets the service URL

void set serviceUrl(String value) {
 if (value != null && value.endsWith("?")) {
   value = value.substring(0, value.length -1);
 }
 _serviceUrl = value;
}

final Dimension tileSize #

inherited from TileLayer

the tile size used by this tile layer

Dimension get tileSize => DEFAULT_TILE_SIZE;

bool useProjectedCoordinates #

Indicates whether the bounding box of a WMS GetMaprequest is expressed in geographic or in projected coordinates.

  • if false, the bounding box is expressed in geographic coordinates, i.e. in WGS84 aka EPSG:4326

  • if true, the bounding box is expressed in projected coordinates, that is coordinate reference system configured on the map viewport, see MapViewport.crs.

Default value is false.

bool useProjectedCoordinates = false

bool get visible #

inherited from Layer

the layer visibility

bool get visible => _visible;

void set visible(bool value) #

inherited from Layer

sets whether this layer is visible or not

void set visible(bool value) {
 var old = _visible;
 if (value != old) {
   if (_container != null) {
     _container.style.visibility =
         value ? "visible" : "hidden";
   }
   _visible = value;
   notify("visible", old, value);
 }
}

Methods

void attach(MapViewport m) #

inherited from TileLayer

Attaches the layer to a map viewport m.

Throws StateError if this layer is already attached.

docs inherited from Layer
@override
void attach(MapViewport m) {
 super.attach(m);
 var viewportSize = map.viewportSize;
 var tl = map.topLeftInPage;
 _container.style
   ..width="100%"
   ..height="100%"
   ..position = "absolute"
   ..left = "0px"
   ..top = "0px";
}

String bindTileToUrl(int x, int y, int zoom) #

returns a tile URL for the tile at tile coordinates x, y in the tile plane at zoom level zoom

docs inherited from TileLayer
@override
String bindTileToUrl(int x, int y, int zoom) {
 var ts = tileSize;
 var parameters = new Map.from(_defaultParameters);
 parameters["REQUEST"] = "GetMap";
 parameters["LAYERS"] = _layers.join(",");
 parameters["WIDTH"] = ts.width.toString();
 parameters["HEIGHT"] = ts.height.toString();
 if (useProjectedCoordinates) {
   parameters["BBOX"] = _buildProjectedTileBBox(x,y,zoom);
   parameters["SRS"] = _map.crs.code;
 } else {
   parameters["BBOX"] = _buildGeographicTileBBox(x,y,zoom);
   parameters["SRS"] = "EPSG:4326";
 }

 var query = parameters.keys.map((k) => "$k=${parameters[k]}").join("&");
 var url = "$_serviceUrl?$query";
 return url;
}

void detach() #

inherited from Layer

Detaches this layer from the map viewport it is currently attached to.

void detach(){
 _map = null;
}

void notify(String property, oldValue, newValue) #

Notifies observers about an update of the property with name property in this object. oldValue was replaced by newValue.

Observers are only notified, provided newValue is different from oldValue and if there is at least one listener.

void notify(String property, oldValue, newValue) {
 if (oldValue == newValue) return;
 //TODO: fix me - see notes in onPropertyChanged
 if (!_controller.hasListener || _controller.isPaused) return;
 _controller.sink.add(
     new PropertyChangeEvent(this, property,oldValue,newValue)
 );
}

void render() #

renders the layer

docs inherited from Layer
@override
void render() {
 if (_serviceUrl == null) {
   print("WARNING: can't render, serviceUrl not defined");
   return;
 }
 if (_layers.isEmpty) {
   print("WARNING: can't render, no layers defined");
   return;
 }
 super.render();
}