<BODY><P>/********************************************************************** * <BR> * @project Fusion<BR> * @revision $Id: Ruler.js,v 1.37 2007/07/04 21:25:54 assefa Exp $<BR> * @purpose Ruler widget<BR> * @author <A href="mailto:pspencer@dmsolutions.ca">pspencer@dmsolutions.ca</A><BR> * Copyright (c) 2007 DM Solutions Group Inc.<BR> *****************************************************************************<BR> * This code shall not be copied or used without the expressed written consent<BR> * of DM Solutions Group Inc.<BR> * <BR> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<BR> * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<BR> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL<BR> * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<BR> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TOR!
T OR OTHERWISE, ARISING<BR> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<BR> * DEALINGS IN THE SOFTWARE.<BR> * <BR> * The above copyright notice and this permission notice shall be included<BR> * in all copies or substantial portions of the Software.<BR> * ********************************************************************<BR> *<BR> * The Ruler widget allows the user to measure distances on the map in<BR> * one or more segments.<BR> *<BR> * Distances for the current segment and the total distance are advertised<BR> * through the Fusion.Event.RULER_DISTANCE_CHANGED event.<BR> * <BR> * **********************************************************************/</P>
<P> </P>
<P>Fusion.Event.RULER_DISTANCE_CHANGED = Fusion.Event.lastEventId++;</P>
<P>Fusion.Widget.Ruler = Class.create();<BR>Fusion.Widget.Ruler.prototype = {<BR> isDigitizing: false,<BR> //distance of each segment<BR> aDistances: [],<BR> //cumulativeDistance distance<BR> cumulativeDistance: 0,<BR> lastDistance: 0,<BR> <BR> /* the units to display distances in */<BR> units: Fusion.UNKNOWN,</P>
<P> /* Precision of the distance displayed */<BR> precision: null,<BR> <BR> /* an HTML container to put the current distance in */<BR> rulerTip: null,<BR> <BR> /* Static position of Tooltip Box TOP */<BR> rulerTipPositionTop: null,<BR> <BR> /* Static position of Tooltip Box LEFT */ <BR> rulerTipPositionLeft: null,<BR> <BR> /* Tooltip appearance: static or dynamic */<BR> tooltipType: '',<BR> <BR> initialize : function(oCommand) {<BR> /*console.log('Ruler.initialize');*/<BR> Object.inheritFrom(this, Fusion.Widget.prototype, ['Ruler', true, oCommand]);<BR> Object.inheritFrom(th!
is, Fusion.Tool.ButtonBase.prototype, []);<BR> Object.inheritFrom(this, Fusion.Tool.Canvas.prototype, []);<BR> this.setMap(oCommand.getMap());<BR> this.asCursor = ['crosshair'];<BR> var json = oCommand.jsonNode;<BR> this.units = (json.Units && (json.Units[0] != '')) ?<BR> Fusion.unitFromName(json.Units[0]): this.units; <BR> this.precision = json.Precision ? json.Precision[0] : 2;<BR> var container = json.RulerTooltipContainer ? json.RulerTooltipContainer[0] : '';<BR> //set default co!
ntainer if not specified<BR>
<BR> var cont = document.getElementById(container);<BR> if (cont == null){<BR> cont = document.createElement('div');<BR> cont.id = container;<BR> }<BR> <BR> if (cont != '') {<BR> this.rulerTip = $(cont);<BR> }<BR> if (this.rulerTip) {<BR> this.tooltipType = json.RulerTooltipType ? json.RulerTooltipType[0] : 'dynamic';<BR> if (this.tooltipType == 'dynamic') {<BR> !
var oDomElem = this.getMap().getDomObj();<BR> oDomElem.appendChild(this.rulerTip);<BR> this.rulerTip.style.position = 'absolute';<BR> this.rulerTip.style.display = 'none';<BR> this.rulerTip.style.top = '0px';<BR> this.rulerTip.style.left = '0px';<BR> this.rulerTip.style.zIndex = 101;<BR> }<BR> &nb!
sp; if (this.tooltipType == 'static') {<BR> &nb
sp; this.rulerTipPositionTop = json.RulerTipPositionTop ? json.RulerTipPositionTop[0] : 15;<BR> this.rulerTipPositionLeft = json.RulerTipPositionLeft ? json.RulerTipPositionLeft[0] : 15; <BR> var oDomElem = this.getMap().getDomObj();<BR> oDomElem.appendChild(this.rulerTip);<BR> this.rulerTip.style.position = 'absolute';<BR> &nbs!
p; this.rulerTip.style.display = 'none';<BR> this.rulerTip.style.top = this.rulerTipPositionTop;<BR> this.rulerTip.style.left = this.rulerTipPositionLeft;<BR> this.rulerTip.style.zIndex = 101;<BR> }<BR> }<BR> <BR> this.registerEventID(Fusion.Event.RULER_DISTANCE_CHANGED);<BR> this.getMap().registerForEvent(Fusion.Event.MAP_EXTENTS_CHANGED, this.resetCanvas.bind(this));<BR> this.keyHandler = this.onKeyPr!
ess.bind(this);<BR> },<BR> <BR>&nb
sp; onKeyPress: function(e) {<BR> //console.log('Rule::onKeyPress');<BR> var charCode = (e.charCode ) ? e.charCode : ((e.keyCode) ? e.keyCode : e.which);<BR> //console.log(charCode);<BR> if (charCode == Event.KEY_ESC) {<BR> this.resetCanvas();<BR> } <BR> },<BR> <BR> /**<BR> * (public) activate()<BR> *<BR> * activate the ruler tool<BR> */<BR> activateTool: function() {<BR> this.getMap().activateWidget(this);<BR> this._oButton.activateTool();<BR>&!
nbsp; },<BR> <BR> <BR> activate: function() {<BR> this.activateCanvas();<BR> this.aDistances = [];<BR> this.cumulativeDistance = 0;<BR> this.lastDistance = 0;<BR> this.triggerEvent(Fusion.Event.RULER_DISTANCE_CHANGED, this);<BR> Event.observe(document,"keypress",this.keyHandler);<BR> },<BR> <BR> /**<BR> * (public) deactivate()<BR> *<BR> * deactivate the ruler tool<BR> */<BR> deactivate: function() {<BR> //console.log('Ruler.deactivate');<BR> &nb!
sp; Event.stopObserving(document, 'keypress',
this.keyHandler); <BR> this._oButton.deactivateTool();<BR> this.deactivateCanvas();<BR> this.resetCanvas();<BR> },<BR> <BR> resetCanvas: function() {<BR> if (this.isDigitizing) {<BR> this.isDigitizing = false;<BR> }<BR> this.clearContext();<BR> this.aDistances = [];<BR> this.cumulativeDistance = 0;<BR> this.lastDistance = 0;<BR> this.triggerEvent(Fusion.Event.RULER_DISTANCE_CHANGED, thi!
s);<BR> if (this.rulerTip) {<BR> this.updateTip(null);<BR> }<BR> },<BR> <BR> /**<BR> * (public) mouseDown(e)<BR> *<BR> * handle the mouse down event<BR> *<BR> * @param e Event the event that happened on the mapObj<BR> */<BR> mouseDown: function(e) {<BR> if (Event.isLeftClick(e)) {<BR> var map = this.getMap();<BR> var p = map.getEventPosition(e);<BR> var gp = map.pixToGeo(p.x, p.y!
);</P>
<P> if (!this.isDigitizing) {<BR> this.currentFeature = new Fusion.Tool.Canvas.Line(map);<BR> this.lastDistance = 0;<BR> this.cumulativeDistance = 0;<BR> this.aDistances = [];<BR> var from = new Fusion.Tool.Canvas.Node(gp.x,gp.y, map);<BR> var to = new Fusion.Tool.Canvas.Node(gp.x,gp.y, map);<BR> &n!
bsp; var seg = new Fusion.Tool.Canvas.Segment(from,to);<BR> seg.setEditing(true);<BR> this.currentFeature.addSegment(seg);<BR> this.clearContext();<BR> this.currentFeature.draw(this.context); <BR> this.isDigitizing = true;<BR> } else {<BR> var seg = this.currentFeature.lastSegment();<BR> &nbs!
p; var d = this.measureSegment(seg);<BR>
this.aDistances.push(d);<BR> this.cumulativeDistance += d;<BR> this.lastDistance = 0;<BR> this.triggerEvent(Fusion.Event.RULER_DISTANCE_CHANGED, this, this.getDistance());<BR> if (this.rulerTip) {<BR> this.updateTip(e);<BR> }<BR> seg.setEditing(false);<BR>!
seg = this.currentFeature.extendLine();<BR> seg.setEditing(true);<BR> this.clearContext();<BR> this.currentFeature.draw(this.context);<BR> }<BR> }<BR> },</P>
<P> /**<BR> * (public) mouseMove(e)<BR> *<BR> * handle the mouse move event<BR> *<BR> * @param e Event the event that happened on the mapObj<BR> */<BR> mouseMove: function(e) {<BR> if (!this.isDigitizing) {<BR> return;<BR> }<BR> <BR> var oElement = this.getMap().getDomObj();<BR> var target = e.target || e.srcElement;<BR> if (target.id != '_oEventDiv_'+oElement.id) {<BR> return;<BR>  !
; }</P>
<P> var p = this.getMap().getEventPosition(e);<BR> var gp = this.getMap().pixToGeo(p.x, p.y);<BR> var seg = this.currentFeature.lastSegment();<BR> seg.to.set(gp.x,gp.y);<BR> this.clearContext();<BR> this.currentFeature.draw(this.context);<BR> this.updateDistance(seg, e);<BR> },</P>
<P> /**<BR> * (public) dblClick(e)<BR> *<BR> * handle the mouse dblclick event<BR> *<BR> * @param e Event the event that happened on the mapObj<BR> */<BR> dblClick: function(e) {<BR> //console.log('Digitizer.dblClick');<BR> if (!this.isDigitizing) return;<BR> var p = this.getMap().getEventPosition(e);<BR> var gp = this.getMap().pixToGeo(p.x, p.y);<BR> var seg = this.currentFeature.lastSegment();<BR> seg.setEditing(false);<BR> seg.to.set(gp.x,gp.y);<BR> this.clearContex!
t();<BR> this.currentFeature.draw(this.context);<BR> this.isDigitizing = false;<BR> },<BR> <BR> measureSegment: function(seg) {<BR> var map = this.getMap();<BR> var dist = Math.sqrt(Math.pow(seg.to.x-seg.from.x,2) +<BR> Math.pow(seg.to.y-seg.from.y,2));<BR> if (this.units != Fusion.PIXELS) {<BR> dist = dist * map._fMetersperunit;<BR> }<BR> /* magic number - this means the map units are meters! */<BR> &nb!
sp; if (map._fMetersperunit == 111319.4908) {<BR> &nb
sp; var center = map.getCurrentCenter();<BR> dist = dist * Math.cos(2 * Math.PI * center.y / 360);<BR> }<BR> return dist;<BR> },<BR> <BR> updateDistance: function(seg, e) {<BR> this.lastDistance = this.measureSegment(seg);<BR> this.triggerEvent(Fusion.Event.RULER_DISTANCE_CHANGED, this, this.getDistance());<BR> if (this.rulerTip) {<BR> this.updateTip(e);<BR> }<BR> },<BR> <BR> getLastDistance: function() {<BR> &!
nbsp; var d = this.lastDistance;<BR> if (this.units != Fusion.PIXELS && this.units != Fusion.METERS) {<BR> d = Fusion.fromMeter(this.units,d);<BR> }<BR> return d;<BR> },<BR> <BR> getDistance: function() {<BR> var totalDistance = this.cumulativeDistance + this.lastDistance;<BR> if (this.units != Fusion.PIXELS && this.units != Fusion.METERS) {<BR> totalDistance = Fusion.fromMeter(this.units,totalDistance);<BR> }<BR> return totalDistance;<BR> },<BR> !
<BR> setParameter: function(param, value) {<BR>&nbs
p; //console.log('setParameter: ' + param + ' = ' + value);<BR> if (param == 'Units') {<BR> this.units = Fusion.unitFromName(value);<BR> }<BR> },<BR> <BR> updateTip: function(e) {<BR> if (!this.rulerTip) {<BR> return;<BR> }<BR> var segDistance = this.getLastDistance();<BR> var totalDistance = this.getDistance();<BR> segDistance = parseInt(segDistance * this.precision)/this.precision;<BR> totalDistance = parseInt(totalDistance * this.precis!
ion)/this.precision;<BR> if (segDistance == 0 && totalDistance == 0) <BR> {<BR> this.rulerTip.innerHTML = '';<BR> if(this.tooltipType == 'dynamic' ||this.tooltipType == 'static' ) <BR> {<BR> this.rulerTip.style.display = 'none';<BR> }<BR> <BR> } <BR> else <BR> { <BR>  !
; if(Fusion.unitName(this.units) == "Meters")<BR> &nb
sp; var unitDisplay = " m";<BR> this.rulerTip.innerHTML = "<table><tr><td align='left' style='font-weight: bold'>Segment: </td><td>&nbsp</td><td>" + segDistance + unitDisplay + "</td>" + "<tr><td align='left' style='font-weight: bold'>Total: </td><td>&nbsp</td><td>" + totalDistance + unitDisplay +"</td></tr></table>";<BR> if(this.tooltipType == 'dynamic') <BR> {<BR> this.rulerTip.style.display = 'block';<BR> this.rulerTip.style.visibility = 'v!
isible';<BR> var p = this.getMap().getEventPosition(e);<BR> var size = Element.getDimensions(this.rulerTip);<BR> var t = (p.y - size.height * 1.5);<BR> if (t < 0) {<BR> t = p.y + size.height * 0.5;<BR> }<BR> <BR> var pSize = Element.getDimen!
sions(this.rulerTip.parentNode);<BR> &nbs
p; var l = p.x;<BR> if (l+size.width > pSize.width) {<BR> l = p.x - size.width;<BR> }<BR> <BR> this.rulerTip.style.top = t + 'px';<BR> this.rulerTip.style.left = l + 'px';<BR> }//end dynamic<BR> if(this.tooltipType == 'static') <BR>&nbs!
p; {<BR> this.rulerTip.style.display = 'block';<BR> this.rulerTip.style.visibility = 'visible';<BR> }//end dynamic<BR> }//else<BR> }<BR>};<BR></P></BODY>