Merge pull request #215 from twpayne/scaleline-control
ScaleLine control
This commit is contained in:
+18
@@ -28,6 +28,24 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.ol-scale-line {
|
||||||
|
background: rgba(0,60,136,0.3);
|
||||||
|
border-radius: 4px;
|
||||||
|
bottom: 8px;
|
||||||
|
left: 8px;
|
||||||
|
padding: 2px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.ol-scale-line-inner {
|
||||||
|
border: 1px solid #eeeeee;
|
||||||
|
border-top: none;
|
||||||
|
color: #eeeeee;
|
||||||
|
font-size: 10px;
|
||||||
|
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
margin: 1px;
|
||||||
|
padding: 0px 2px;
|
||||||
|
}
|
||||||
.ol-viewport .ol-unselectable {
|
.ol-viewport .ol-unselectable {
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ goog.require('ol.Coordinate');
|
|||||||
goog.require('ol.Map');
|
goog.require('ol.Map');
|
||||||
goog.require('ol.RendererHint');
|
goog.require('ol.RendererHint');
|
||||||
goog.require('ol.View2D');
|
goog.require('ol.View2D');
|
||||||
|
goog.require('ol.control.ScaleLineUnits');
|
||||||
goog.require('ol.layer.TileLayer');
|
goog.require('ol.layer.TileLayer');
|
||||||
goog.require('ol.projection');
|
goog.require('ol.projection');
|
||||||
goog.require('ol.source.TiledWMS');
|
goog.require('ol.source.TiledWMS');
|
||||||
@@ -39,6 +40,8 @@ var map = new ol.Map({
|
|||||||
layers: layers,
|
layers: layers,
|
||||||
// The OSgeo server does not set cross origin headers, so we cannot use WebGL
|
// The OSgeo server does not set cross origin headers, so we cannot use WebGL
|
||||||
renderers: [ol.RendererHint.CANVAS, ol.RendererHint.DOM],
|
renderers: [ol.RendererHint.CANVAS, ol.RendererHint.DOM],
|
||||||
|
scaleLineControl: true,
|
||||||
|
scaleLineUnits: ol.control.ScaleLineUnits.DEGREES,
|
||||||
target: 'map',
|
target: 'map',
|
||||||
view: new ol.View2D({
|
view: new ol.View2D({
|
||||||
projection: epsg4326,
|
projection: epsg4326,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ var layer = new ol.layer.TileLayer({
|
|||||||
var map = new ol.Map({
|
var map = new ol.Map({
|
||||||
layers: new ol.Collection([layer]),
|
layers: new ol.Collection([layer]),
|
||||||
renderers: ol.RendererHints.createFromQueryData(),
|
renderers: ol.RendererHints.createFromQueryData(),
|
||||||
|
scaleLineControl: true,
|
||||||
target: 'map',
|
target: 'map',
|
||||||
view: new ol.View2D({
|
view: new ol.View2D({
|
||||||
center: new ol.Coordinate(0, 0),
|
center: new ol.Coordinate(0, 0),
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoomDelta number|undefined
|
@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoomDelta number|undefined
|
||||||
@exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined
|
@exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined
|
||||||
@exportObjectLiteralProperty ol.MapOptions.renderers Array.<ol.RendererHint>|undefined
|
@exportObjectLiteralProperty ol.MapOptions.renderers Array.<ol.RendererHint>|undefined
|
||||||
|
@exportObjectLiteralProperty ol.MapOptions.scaleLineControl boolean|undefined
|
||||||
|
@exportObjectLiteralProperty ol.MapOptions.scaleLineUnits ol.control.ScaleLineUnits|undefined
|
||||||
@exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined
|
@exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined
|
||||||
@exportObjectLiteralProperty ol.MapOptions.target Element|string
|
@exportObjectLiteralProperty ol.MapOptions.target Element|string
|
||||||
@exportObjectLiteralProperty ol.MapOptions.touchPan boolean|undefined
|
@exportObjectLiteralProperty ol.MapOptions.touchPan boolean|undefined
|
||||||
@@ -58,6 +60,12 @@
|
|||||||
@exportObjectLiteralProperty ol.control.AttributionOptions.map ol.Map|undefined
|
@exportObjectLiteralProperty ol.control.AttributionOptions.map ol.Map|undefined
|
||||||
@exportObjectLiteralProperty ol.control.AttributionOptions.target Element|undefined
|
@exportObjectLiteralProperty ol.control.AttributionOptions.target Element|undefined
|
||||||
|
|
||||||
|
@exportObjectLiteral ol.control.ScaleLineOptions
|
||||||
|
@exportObjectLiteralProperty ol.control.ScaleLineOptions.map ol.Map|undefined
|
||||||
|
@exportObjectLiteralProperty ol.control.ScaleLineOptions.minWidth number|undefined
|
||||||
|
@exportObjectLiteralProperty ol.control.ScaleLineOptions.target Element|undefined
|
||||||
|
@exportObjectLiteralProperty ol.control.ScaleLineOptions.units ol.control.ScaleLineUnits|undefined
|
||||||
|
|
||||||
@exportObjectLiteral ol.control.MousePositionOptions
|
@exportObjectLiteral ol.control.MousePositionOptions
|
||||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.coordinateFormat ol.CoordinateFormatType|undefined
|
@exportObjectLiteralProperty ol.control.MousePositionOptions.coordinateFormat ol.CoordinateFormatType|undefined
|
||||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.map ol.Map|undefined
|
@exportObjectLiteralProperty ol.control.MousePositionOptions.map ol.Map|undefined
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
@exportClass ol.control.ScaleLine ol.control.ScaleLineOptions
|
||||||
|
@exportProperty ol.control.ScaleLine.prototype.setMap
|
||||||
|
|
||||||
|
@exportSymbol ol.control.ScaleLineUnits
|
||||||
|
@exportProperty ol.control.ScaleLineUnits.DEGREES
|
||||||
|
@exportProperty ol.control.ScaleLineUnits.IMPERIAL
|
||||||
|
@exportProperty ol.control.ScaleLineUnits.NAUTICAL
|
||||||
|
@exportProperty ol.control.ScaleLineUnits.METRIC
|
||||||
|
@exportProperty ol.control.ScaleLineUnits.US
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
goog.provide('ol.control.ScaleLine');
|
||||||
|
goog.provide('ol.control.ScaleLineUnits');
|
||||||
|
|
||||||
|
goog.require('goog.dom');
|
||||||
|
goog.require('goog.style');
|
||||||
|
goog.require('ol.FrameState');
|
||||||
|
goog.require('ol.MapEvent');
|
||||||
|
goog.require('ol.MapEventType');
|
||||||
|
goog.require('ol.ProjectionUnits');
|
||||||
|
goog.require('ol.TransformFunction');
|
||||||
|
goog.require('ol.control.Control');
|
||||||
|
goog.require('ol.projection');
|
||||||
|
goog.require('ol.sphere.NORMAL');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
ol.control.ScaleLineUnits = {
|
||||||
|
DEGREES: 'degrees',
|
||||||
|
IMPERIAL: 'imperial',
|
||||||
|
NAUTICAL: 'nautical',
|
||||||
|
METRIC: 'metric',
|
||||||
|
US: 'us'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.control.Control}
|
||||||
|
* @param {ol.control.ScaleLineOptions=} opt_options Options.
|
||||||
|
*/
|
||||||
|
ol.control.ScaleLine = function(opt_options) {
|
||||||
|
|
||||||
|
var options = opt_options || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Element}
|
||||||
|
*/
|
||||||
|
this.innerElement_ = goog.dom.createDom(goog.dom.TagName.DIV, {
|
||||||
|
'class': 'ol-scale-line-inner'
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Element}
|
||||||
|
*/
|
||||||
|
this.element_ = goog.dom.createDom(goog.dom.TagName.DIV, {
|
||||||
|
'class': 'ol-scale-line ol-unselectable'
|
||||||
|
}, this.innerElement_);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.minWidth_ = goog.isDef(options.minWidth) ? options.minWidth : 64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.control.ScaleLineUnits}
|
||||||
|
*/
|
||||||
|
this.units_ = goog.isDef(options.units) ?
|
||||||
|
options.units : ol.control.ScaleLineUnits.METRIC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Array.<?number>}
|
||||||
|
*/
|
||||||
|
this.listenerKeys_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.renderedVisible_ = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.renderedWidth_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.renderedHTML_ = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {?ol.TransformFunction}
|
||||||
|
*/
|
||||||
|
this.toEPSG4326_ = null;
|
||||||
|
|
||||||
|
goog.base(this, {
|
||||||
|
element: this.element_,
|
||||||
|
map: options.map,
|
||||||
|
target: options.target
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
goog.inherits(ol.control.ScaleLine, ol.control.Control);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Array.<number>}
|
||||||
|
*/
|
||||||
|
ol.control.ScaleLine.LEADING_DIGITS = [1, 2, 5];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.MapEvent} mapEvent Map event.
|
||||||
|
*/
|
||||||
|
ol.control.ScaleLine.prototype.handleMapPostrender = function(mapEvent) {
|
||||||
|
var frameState = mapEvent.frameState;
|
||||||
|
this.updateElement_(mapEvent.frameState);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.control.ScaleLine.prototype.setMap = function(map) {
|
||||||
|
if (!goog.isNull(this.listenerKeys_)) {
|
||||||
|
goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey);
|
||||||
|
this.listenerKeys_ = null;
|
||||||
|
}
|
||||||
|
goog.base(this, 'setMap', map);
|
||||||
|
if (!goog.isNull(map)) {
|
||||||
|
this.listenerKeys_ = [
|
||||||
|
goog.events.listen(map, ol.MapEventType.POSTRENDER,
|
||||||
|
this.handleMapPostrender, false, this)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?ol.FrameState} frameState Frame state.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.control.ScaleLine.prototype.updateElement_ = function(frameState) {
|
||||||
|
|
||||||
|
if (goog.isNull(frameState)) {
|
||||||
|
if (this.renderedVisible_) {
|
||||||
|
goog.style.showElement(this.element_, false);
|
||||||
|
this.renderedVisible_ = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var view2DState = frameState.view2DState;
|
||||||
|
var center = view2DState.center;
|
||||||
|
var projection = view2DState.projection;
|
||||||
|
var pointResolution =
|
||||||
|
projection.getPointResolution(view2DState.resolution, center);
|
||||||
|
var projectionUnits = projection.getUnits();
|
||||||
|
|
||||||
|
var cosLatitude;
|
||||||
|
if (projectionUnits == ol.ProjectionUnits.DEGREES &&
|
||||||
|
(this.units_ == ol.control.ScaleLineUnits.METRIC ||
|
||||||
|
this.units_ == ol.control.ScaleLineUnits.IMPERIAL)) {
|
||||||
|
|
||||||
|
// Convert pointResolution from degrees to meters
|
||||||
|
this.toEPSG4326_ = null;
|
||||||
|
cosLatitude = Math.cos(goog.math.toRadians(center.y));
|
||||||
|
pointResolution *= Math.PI * cosLatitude * ol.sphere.NORMAL.radius / 180;
|
||||||
|
|
||||||
|
} else if (projectionUnits == ol.ProjectionUnits.METERS &&
|
||||||
|
this.units_ == ol.control.ScaleLineUnits.DEGREES) {
|
||||||
|
|
||||||
|
// Convert pointResolution from meters to degrees
|
||||||
|
if (goog.isNull(this.toEPSG4326_)) {
|
||||||
|
this.toEPSG4326_ = ol.projection.getTransform(
|
||||||
|
projection, ol.projection.getFromCode('EPSG:4326'));
|
||||||
|
}
|
||||||
|
var vertex = [center.x, center.y];
|
||||||
|
vertex = this.toEPSG4326_(vertex, vertex, 2);
|
||||||
|
cosLatitude = Math.cos(goog.math.toRadians(vertex[1]));
|
||||||
|
pointResolution *= 180 / (Math.PI * cosLatitude * ol.sphere.NORMAL.radius);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.toEPSG4326_ = null;
|
||||||
|
goog.asserts.assert(
|
||||||
|
((this.units_ == ol.control.ScaleLineUnits.METRIC ||
|
||||||
|
this.units_ == ol.control.ScaleLineUnits.IMPERIAL) &&
|
||||||
|
projectionUnits == ol.ProjectionUnits.METERS) ||
|
||||||
|
(this.units_ == ol.control.ScaleLineUnits.DEGREES &&
|
||||||
|
projectionUnits == ol.ProjectionUnits.DEGREES));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var nominalCount = this.minWidth_ * pointResolution;
|
||||||
|
var suffix = '';
|
||||||
|
if (this.units_ == ol.control.ScaleLineUnits.DEGREES) {
|
||||||
|
if (nominalCount < 1 / 60) {
|
||||||
|
suffix = '\u2033'; // seconds
|
||||||
|
pointResolution *= 3600;
|
||||||
|
} else if (nominalCount < 1) {
|
||||||
|
suffix = '\u2032'; // minutes
|
||||||
|
pointResolution *= 60;
|
||||||
|
} else {
|
||||||
|
suffix = '\u00b0'; // degrees
|
||||||
|
}
|
||||||
|
} else if (this.units_ == ol.control.ScaleLineUnits.IMPERIAL) {
|
||||||
|
if (nominalCount < 0.9144) {
|
||||||
|
suffix = 'in';
|
||||||
|
pointResolution /= 0.0254;
|
||||||
|
} else if (nominalCount < 1609.344) {
|
||||||
|
suffix = 'ft';
|
||||||
|
pointResolution /= 0.3048;
|
||||||
|
} else {
|
||||||
|
suffix = 'mi';
|
||||||
|
pointResolution /= 1609.344;
|
||||||
|
}
|
||||||
|
} else if (this.units_ == ol.control.ScaleLineUnits.NAUTICAL) {
|
||||||
|
pointResolution /= 1852;
|
||||||
|
suffix = 'nm';
|
||||||
|
} else if (this.units_ == ol.control.ScaleLineUnits.METRIC) {
|
||||||
|
if (nominalCount < 1) {
|
||||||
|
suffix = 'mm';
|
||||||
|
pointResolution *= 1000;
|
||||||
|
} else if (nominalCount < 1000) {
|
||||||
|
suffix = 'm';
|
||||||
|
} else {
|
||||||
|
suffix = 'km';
|
||||||
|
pointResolution /= 1000;
|
||||||
|
}
|
||||||
|
} else if (this.units_ == ol.control.ScaleLineUnits.US) {
|
||||||
|
if (nominalCount < 0.9144) {
|
||||||
|
suffix = 'in';
|
||||||
|
pointResolution *= 39.37;
|
||||||
|
} else if (nominalCount < 1609.344) {
|
||||||
|
suffix = 'ft';
|
||||||
|
pointResolution /= 0.30480061;
|
||||||
|
} else {
|
||||||
|
suffix = 'mi';
|
||||||
|
pointResolution /= 1609.3472;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goog.asserts.assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 3 * Math.floor(
|
||||||
|
Math.log(this.minWidth_ * pointResolution) / Math.log(10));
|
||||||
|
var count, width;
|
||||||
|
while (true) {
|
||||||
|
count = ol.control.ScaleLine.LEADING_DIGITS[i % 3] *
|
||||||
|
Math.pow(10, Math.floor(i / 3));
|
||||||
|
width = Math.round(count / pointResolution);
|
||||||
|
if (width >= this.minWidth_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
var html = count + suffix;
|
||||||
|
if (this.renderedHTML_ != html) {
|
||||||
|
this.innerElement_.innerHTML = html;
|
||||||
|
this.renderedHTML_ = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.renderedWidth_ != width) {
|
||||||
|
this.innerElement_.style.width = width + 'px';
|
||||||
|
this.renderedWidth_ = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.renderedVisible_) {
|
||||||
|
goog.style.showElement(this.element_, true);
|
||||||
|
this.renderedVisible_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -45,6 +45,7 @@ goog.require('ol.View');
|
|||||||
goog.require('ol.View2D');
|
goog.require('ol.View2D');
|
||||||
goog.require('ol.control.Attribution');
|
goog.require('ol.control.Attribution');
|
||||||
goog.require('ol.control.Control');
|
goog.require('ol.control.Control');
|
||||||
|
goog.require('ol.control.ScaleLine');
|
||||||
goog.require('ol.control.Zoom');
|
goog.require('ol.control.Zoom');
|
||||||
goog.require('ol.interaction.DblClickZoom');
|
goog.require('ol.interaction.DblClickZoom');
|
||||||
goog.require('ol.interaction.DragPan');
|
goog.require('ol.interaction.DragPan');
|
||||||
@@ -926,6 +927,16 @@ ol.Map.createControls_ = function(mapOptions) {
|
|||||||
controls.push(new ol.control.Attribution({}));
|
controls.push(new ol.control.Attribution({}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scaleLineControl = goog.isDef(mapOptions.scaleLineControl) ?
|
||||||
|
mapOptions.scaleLineControl : false;
|
||||||
|
if (scaleLineControl) {
|
||||||
|
var scaleLineUnits = goog.isDef(mapOptions.scaleLineUnits) ?
|
||||||
|
mapOptions.scaleLineUnits : undefined;
|
||||||
|
controls.push(new ol.control.ScaleLine({
|
||||||
|
units: scaleLineUnits
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
var zoomControl = goog.isDef(mapOptions.zoomControl) ?
|
var zoomControl = goog.isDef(mapOptions.zoomControl) ?
|
||||||
mapOptions.zoomControl : true;
|
mapOptions.zoomControl : true;
|
||||||
if (zoomControl) {
|
if (zoomControl) {
|
||||||
|
|||||||
Reference in New Issue
Block a user