Files
openlayers/lib/OpenLayers/Control/Measure.js
Tim Schaub 8ba31e4a91 Consistent event type listing for controls.
git-svn-id: http://svn.openlayers.org/trunk/openlayers@9154 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
2009-03-31 21:57:08 +00:00

247 lines
7.2 KiB
JavaScript

/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Control.js
* @requires OpenLayers/Feature/Vector.js
*/
/**
* Class: OpenLayers.Control.Measure
* Allows for drawing of features for measurements.
*
* Inherits from:
* - <OpenLayers.Control>
*/
OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
/**
* Constant: EVENT_TYPES
* {Array(String)} Supported application event types. Register a listener
* for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Listeners will be called with a reference to an event object. The
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from <OpenLayers.Control>):
* measure - Triggered when a measurement sketch is complete. Listeners
* will receive an event with measure, units, order, and geometry
* properties.
* measurepartial - Triggered when a new point is added to the
* measurement sketch. Listeners receive an event with measure,
* units, order, and geometry.
*/
EVENT_TYPES: ['measure', 'measurepartial'],
/**
* APIProperty: handlerOptions
* {Object} Used to set non-default properties on the control's handler
*/
handlerOptions: null,
/**
* Property: callbacks
* {Object} The functions that are sent to the handler for callback
*/
callbacks: null,
/**
* Property: displaySystem
* {String} Display system for output measurements. Supported values
* are 'english', 'metric', and 'geographic'. Default is 'metric'.
*/
displaySystem: 'metric',
/**
* Property: displaySystemUnits
* {Object} Units for various measurement systems. Values are arrays
* of unit abbreviations (from OpenLayers.INCHES_PER_UNIT) in decreasing
* order of length.
*/
displaySystemUnits: {
geographic: ['dd'],
english: ['mi', 'ft', 'in'],
metric: ['km', 'm']
},
/**
* Constructor: OpenLayers.Control.Measure
*
* Parameters:
* handler - {<OpenLayers.Handler>}
* options - {Object}
*/
initialize: function(handler, options) {
// concatenate events specific to measure with those from the base
this.EVENT_TYPES =
OpenLayers.Control.Measure.prototype.EVENT_TYPES.concat(
OpenLayers.Control.prototype.EVENT_TYPES
);
OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.callbacks = OpenLayers.Util.extend(
{done: this.measureComplete, point: this.measurePartial},
this.callbacks
);
this.handler = new handler(this, this.callbacks, this.handlerOptions);
},
/**
* Method: updateHandler
*
* Parameters:
* handler - {Function} One of the sketch handler constructors.
* options - {Object} Options for the handler.
*/
updateHandler: function(handler, options) {
var active = this.active;
if(active) {
this.deactivate();
}
this.handler = new handler(this, this.callbacks, options);
if(active) {
this.activate();
}
},
/**
* Method: measureComplete
* Called when the measurement sketch is done.
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
*/
measureComplete: function(geometry) {
this.measure(geometry, "measure");
},
/**
* Method: measurePartial
* Called each time a new point is added to the measurement sketch.
*
* Parameters:
* point - {<OpenLayers.Geometry.Point>} The last point added.
* geometry - {<OpenLayers.Geometry>} The sketch geometry.
*/
measurePartial: function(point, geometry) {
this.measure(geometry, "measurepartial");
},
/**
* Method: measure
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
* eventType - {String}
*/
measure: function(geometry, eventType) {
var stat, order;
if(geometry.CLASS_NAME.indexOf('LineString') > -1) {
stat = this.getBestLength(geometry);
order = 1;
} else {
stat = this.getBestArea(geometry);
order = 2;
}
this.events.triggerEvent(eventType, {
measure: stat[0],
units: stat[1],
order: order,
geometry: geometry
});
},
/**
* Method: getBestArea
* Based on the <displaySystem> returns the area of a geometry.
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
*
* Returns:
* {Array([Float, String])} Returns a two item array containing the
* area and the units abbreviation.
*/
getBestArea: function(geometry) {
var units = this.displaySystemUnits[this.displaySystem];
var unit, area;
for(var i=0, len=units.length; i<len; ++i) {
unit = units[i];
area = this.getArea(geometry, unit);
if(area > 1) {
break;
}
}
return [area, unit];
},
/**
* Method: getArea
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
* units - {String} Unit abbreviation
*
* Returns:
* {Float} The geometry area in the given units.
*/
getArea: function(geometry, units) {
var area = geometry.getArea();
var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[units];
if(inPerDisplayUnit) {
var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.getUnits()];
area *= Math.pow((inPerMapUnit / inPerDisplayUnit), 2);
}
return area;
},
/**
* Method: getBestLength
* Based on the <displaySystem> returns the length of a geometry.
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
*
* Returns:
* {Array([Float, String])} Returns a two item array containing the
* length and the units abbreviation.
*/
getBestLength: function(geometry) {
var units = this.displaySystemUnits[this.displaySystem];
var unit, length;
for(var i=0, len=units.length; i<len; ++i) {
unit = units[i];
length = this.getLength(geometry, unit);
if(length > 1) {
break;
}
}
return [length, unit];
},
/**
* Method: getLength
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
* units - {String} Unit abbreviation
*
* Returns:
* {Float} The geometry length in the given units.
*/
getLength: function(geometry, units) {
var length = geometry.getLength();
var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[units];
if(inPerDisplayUnit) {
var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.getUnits()];
length *= (inPerMapUnit / inPerDisplayUnit);
}
return length;
},
CLASS_NAME: "OpenLayers.Control.Measure"
});