ScaleIndicatorControl class
A scale indicator control displays information about the current map scale.
class ScaleIndicatorControl extends MapControl { static const SVG_CONTENT = """<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1"> <g class="scale-indicator-control"> <g class="scale-kilometers"> <rect class="bar" x="0" y="0" width="100" height="15"/> <text class="label" x="5" y="12">1000 km</text> </g> <g class="scale-miles"> <rect class="bar" x="0" y="20" width="100" height="15"/> <text class="label" x="5" y="32">500 mi</text> </g> </g> </svg> """; @override ScaleIndicatorControl([MapViewport map]): super(map); @override void build() { _root = new Element.tag("div"); var svg = new SvgElement.svg(SVG_CONTENT); var size = _map.viewportSize; var y = size.height - 100; _root.style ..position = "relative" ..left = "20px" ..top = "${y}px" ..width="200px" ..height = "100px"; _root.children.add(svg); _subscriptions.add( _map.onPropertyChanged .where((e) => e.name == "zoom") .listen((e) => _refresh()) ); _refresh(); } _100PixelDistance() { var zh = _map.zoomPlaneSize.width; var w = _map.crs.projectedBounds.width; var dist = 100 / zh * w; return dist; } String _formatMeterDistance(m) { if (m > 1000) { m = m ~/ 1000; m = m.round().toInt(); return "$m km"; } else if (m > 0) { m = m.round().toInt(); return "$m m"; } else if (m < 0) { m = (m * 100).round().toInt(); return "$m cm"; } } String _formatMilesDistance(ft) { if (ft > 5000) { ft = (ft * 0.000189394).round().toInt(); return "$ft mi"; } else if (ft > 0) { ft = ft.round().toInt(); return "$ft ft"; } else { ft = (ft * 10).round().toInt(); return "$ft in"; } } _refresh() { var m = _100PixelDistance(); var ft = m * 3.28084; _root.query(".scale-kilometers text").text = _formatMeterDistance(m); _root.query(".scale-miles text").text = _formatMilesDistance(ft); } @override get defaultPosition { if (map != null) { var vs = map.viewportSize; if (vs.width != 0 && vs.height != 0) { return new Point2D(20, vs.height - 150); } else { return null; } } return null; } @override void layout() { applyPosition(); } }
Extends
MapControl > ScaleIndicatorControl
Static Properties
const SVG_CONTENT #
static const SVG_CONTENT = """<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1"> <g class="scale-indicator-control"> <g class="scale-kilometers"> <rect class="bar" x="0" y="0" width="100" height="15"/> <text class="label" x="5" y="12">1000 km</text> </g> <g class="scale-miles"> <rect class="bar" x="0" y="20" width="100" height="15"/> <text class="label" x="5" y="32">500 mi</text> </g> </g> </svg> """
Constructors
new ScaleIndicatorControl([MapViewport map]) #
@override ScaleIndicatorControl([MapViewport map]): super(map);
Properties
final defaultPosition #
the default position of the control if no position has been
set explicitly using placeAt
.
Override in subclasses.
docs inherited from MapControl
@override get defaultPosition { if (map != null) { var vs = map.viewportSize; if (vs.width != 0 && vs.height != 0) { return new Point2D(20, vs.height - 150); } else { return null; } } return null; }
final MapViewport map #
inherited from MapControl
the map this control is attached to, or null
MapViewport get map => _map;
final Element root #
inherited from MapControl
the root DOM element for this map control
Element get root => _root;
Methods
void applyPosition() #
inherited from MapControl
Applies the current position to the appropriate DOM element.
void applyPosition() { if (root == null) return; var pos = _position == null ? defaultPosition : _position; if (pos == null) { //TODO: log a warning ? return; } root.style ..left = "${pos.x}px" ..top = "${pos.y}px"; }
void attach(MapViewport viewport) #
inherited from MapControl
Attaches this control to the map viewport.
void attach(MapViewport viewport) { _require(viewport != null, "viewport must not be null"); // already attached ? if (_map != null) { if (_map == viewport) { return; // don't attach again } else { detach(); // detach the currently attached, then attach the new one } } this._map = viewport; var controlsPane = _map.controlsPane; //TODO: log a warning? if (controlsPane == null) return; build(); controlsPane.controls.add(this); controlsPane.root.children.add(root); applyPosition(); }
void build() #
Abstract method which builds the DOM tree for the control. Override in subclasses.
docs inherited from MapControl
@override void build() { _root = new Element.tag("div"); var svg = new SvgElement.svg(SVG_CONTENT); var size = _map.viewportSize; var y = size.height - 100; _root.style ..position = "relative" ..left = "20px" ..top = "${y}px" ..width="200px" ..height = "100px"; _root.children.add(svg); _subscriptions.add( _map.onPropertyChanged .where((e) => e.name == "zoom") .listen((e) => _refresh()) ); _refresh(); }
void detach() #
inherited from MapControl
Detaches this control from the map viewport it is currently attached to (if any).
void detach() { if (_map == null) return; if (_root == null) return; if (_map._controlsPane == null) return; _map.controlsPane.root.children.remove(root); _subscriptions.forEach((s) => s.cancel()); _subscriptions.clear(); }
void layout() #
Invoke this to force to (re-)layout the map control in the current map viewport.
docs inherited from MapControl
@override void layout() { applyPosition(); }
void placeAt(int x, int y) #
inherited from MapControl
Places the control at the position ( x, y).
void placeAt(int x, int y) { _position = new Point2D(x,y); applyPosition(); }