[ka-Map-users] Ruler tool
Lorenzo Becchi
lorenzo at ominiverdi.com
Mon Sep 18 09:41:13 EDT 2006
thanks Stephane,
I'm pretty busy right now but your code is interesting and I'll try
to add it to the user interface at soon as possible.
ciao
Lorenzo
On 13/set/06, at 17:16, Stéphane RIFF wrote:
> Hello,
>
> I have developped a Ruler tool based on the kaTool prototype.
> I don't know it's perfect (maybe not) but it's enough for my needs.
> If someone is interested I send the code
>
> Thanks,
> Steff
>
> /
> **********************************************************************
> *
> *
> * purpose: a simple tool for measuring distance
> *
> * author: RIFF Stéphane
> *
> *
> **********************************************************************
> *
> * Copyright (c) 2005, DM Solutions Group Inc.
> *
> * Permission is hereby granted, free of charge, to any person
> obtaining a
> * copy of this software and associated documentation files (the
> "Software"),
> * to deal in the Software without restriction, including without
> limitation
> * the rights to use, copy, modify, merge, publish, distribute,
> sublicense,
> * and/or sell copies of the Software, and to permit persons to whom
> the
> * Software is furnished to do so, subject to the following conditions:
> *
> * The above copyright notice and this permission notice shall be
> included
> * in all copies or substantial portions of the Software.
> *
> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR
> * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
> EVENT SHALL
> * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
> OR OTHER
> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> ARISING
> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> * DEALINGS IN THE SOFTWARE.
> *
> **********************************************************************
> *
> * To use this tool:
> *
> * 1) add a script tag to your page
> *
> * <script type="text/javascript" src="myKaRuler.js"></script>
> *
> * 2) create a new instance of myKaRuler
> *
> * myKaRuler = new myKaRuler( myKaMap);
> *
> * 3) provide some way of activating it. This example would allow
> switching
> * between querying and navigating.
> *
> * <input type="button" name="navigate" value="Navigate"
> * onclick="myKaNavigator.activate()">
> * <input type="button" name="query" value="Query"
> * onclick="myKaQuery.activate()">
> * <input type="button" name="ruler" value="Measuring"
> * onclick="myKaRuler.activate()">
> *
> *
> *
> **********************************************************************
> *******/
>
> /**
> * myKaRuler constructor
> *
> * construct a new myKaRuler object of a given type for a given
> kaMap instance
> *
> * oKaMap - a kaMap instance
> *
> */
> function myKaRuler( oKaMap ) {
> kaTool.apply( this, [oKaMap] );
> this.name = 'myKaRuler';
> this.cursor = 'default';
> this.canvas = null;
> // the units abrevations (if map units is DD, the
> distance is in kilometers)
> this.unitsAbrevations = new Array
> ("ft","in","km","m","mi","km");
> //this is the HTML element that is visible
> this.domObj = document.createElement( 'div' );
> this.domObj.id = 'measureResult';
> this.domObj.style.position = 'absolute';
> this.domObj.style.top = '-300px';
> this.domObj.style.left = '-300px';
> this.domObj.style.width = '150px';
> this.domObj.style.height = '65px';
> this.domObj.style.zIndex = 300;
> this.domObj.style.visibility = 'hidden';
> this.domObj.style.backgroundColor = 'white';
> this.domObj.style.border = '1px solid #999999';
> this.domObj.style.fontFamily = 'Verdana, Arial';
> this.domObj.style.fontSize = '10px';
> document.body.appendChild( this.domObj );
> // the jsgraphic object
> this.jg = null;
> // store the user clicks coordinates
> this.startx = null;
> this.starty = null;
> this.endx = null;
> this.endy = null;
> // the total polyline length
> this.total = 0.0;
> this.input = getRawObject('coords');
> for (var p in kaTool.prototype) {
> if (!myKaRuler.prototype[p])
> myKaRuler.prototype[p]= kaTool.prototype[p];
> }
> };
>
> /**
> * activate this tool. Activating the tool causes any existing
> tools to be
> * deactivated.
> */
> myKaRuler.prototype.activate = function() {
> this.kaMap.activateTool( this );
> document.kaCurrentTool = this;
> this.domObj.innerHTML = "<h3> Seg : <input
> type='text' id='measureSeg' style='border:none;background-
> color:transparent;width:75px;' /> "+this.unitsAbrevations
> [this.kaMap.getCurrentMap().units]+"<br><br> Tot : <input
> type='text' id='measureTot' style='border:none;background-
> color:transparent;width:75px;' /> "+this.unitsAbrevations
> [this.kaMap.getCurrentMap().units];
> if(this.canvas == null){
> this.canvas = this.kaMap.createDrawingCanvas( 300 );
> this.canvas.id = "measureCanvas";
> }
> if(this.jg == null){
> this.jg = new jsGraphics("measureCanvas");
> this.jg.setColor("#ff0000");
> this.jg.setStroke(3);
> }
> this.domObj.style.visibility='visible';
> };
>
> /**
> * deactivate this tool. */
> myKaRuler.prototype.deactivate = function() {
> this.kaMap.deactivateTool( this );
> document.kaCurrentTool = null;
> this.jg.clear();
> this.jg=null;
> this.kaMap.removeDrawingCanvas(this.canvas);
> this.canvas=null;
> this.domObj.style.visibility='hidden';
> };
>
> /*
> * draw line representing the measure.
> *
> */
> myKaRuler.prototype.drawLine = function() {
> this.jg.drawLine((this.startx-this.kaMap.xOrigin), (this.starty-
> this.kaMap.yOrigin),
> (this.endx-this.kaMap.xOrigin), (this.endy-
> this.kaMap.yOrigin)); // co-ordinates related to "myCanvas"
> this.jg.paint();
> this.startx = this.endx;
> this.starty = this.endy;
> };
>
> /**
> * myKaRuler.onmouseout( e )
> *
> * called when the mouse leaves theInsideLayer. hide the result box
> *
> * e - object, the event object or null (in ie)
> */
> myKaRuler.prototype.onmouseout = function(e) {
> e = (e)?e:((event)?event:null);
> if (!e.target) e.target = e.srcElement;
> this.domObj.style.visibility='hidden';
> };
>
> /**
> * myKaRuler.onmouseout( e )
> *
> * called when the mouse leaves theInsideLayer. show the result box
> *
> * e - object, the event object or null (in ie)
> */
> myKaRuler.prototype.onmouseover = function(e) {
> e = (e)?e:((event)?event:null);
> if (!e.target) e.target = e.srcElement;
> this.domObj.style.visibility='visible';
> };
>
> /**
> * myKaRuler.onmousemove( e )
> *
> * called when the mouse moves over theInsideLayer.
> *
> * e - object, the event object or null (in ie)
> */
> myKaRuler.prototype.onmousemove = function(e) {
> e = (e)?e:((event)?event:null);
>
> //show coordinate
> var x = e.pageX || (e.clientX +
> (document.documentElement.scrollLeft ||
> document.body.scrollLeft));
> var y = e.pageY || (e.clientY +
> (document.documentElement.scrollTop ||
> document.body.scrollTop));
> var aPixPos = this.adjustPixPosition( x,y );
> var geoCoo= this.kaMap.pixToGeo(aPixPos[0],aPixPos[1]);
> var gX = geoCoo[0];
> var gY = geoCoo[1];
> var gX= (parseInt(gX*10000))/10000;
> var gY= (parseInt(gY*10000))/10000;
> if(this.input)
> {
> if(this.kaMap.getCurrentMap().units == 5)
> this.input.value = "Lon.: "+gX+" Lat.: "+gY;
> else
> this.input.value = "X: "+gX+" Y: "+gY;
> }
> //**//
> this.domObj.style.left = (e.clientX+5)+"px";
> this.domObj.style.top = (e.clientY+5)+"px";
> if(this.startx !== null)
> {
> this.endx=-aPixPos[0];
> this.endy=-aPixPos[1];
> if(this.kaMap.getCurrentMap().units == 5) {
> document.getElementById("measureSeg").value =
> this.measureSphericalDistance2Points
> (this.startx,this.starty,this.endx,this.endy);
> }else{
> document.getElementById("measureSeg").value =
> this.measure2points(this.startx,this.starty,this.endx,this.endy);
> }
> }
> return false;
> }
> ;
> /**
> * myKaRuler.onmousedown( e )
> *
> * called when a mouse button is pressed over theInsideLayer.
> *
> * e - object, the event object or null (in ie)
> */
> myKaRuler.prototype.onmousedown = function(e) {
> e = (e)?e:((event)?event:null);
> if (e.button==2) {
> this.jg.clear();
> this.startx=this.starty=this.endx=this.endy=null;
> document.getElementById("measureSeg").value="0.0";
> document.getElementById("measureTot").value="0.0";
> this.total = 0.0;
> return this.cancelEvent(e);
> } else {
> if (this.kaMap.isIE4) document.onkeydown =
> kaTool_redirect_onkeypress;
> document.onkeypress = kaTool_redirect_onkeypress;
> var x = e.pageX || (e.clientX +
> (document.documentElement.scrollLeft ||
> document.body.scrollLeft));
> var y = e.pageY || (e.clientY +
> (document.documentElement.scrollTop ||
> document.body.scrollTop));
> var aPixPos = this.adjustPixPosition( x,y );
> if(this.endx == null)
> {
> this.startx=this.endx=-aPixPos[0];
> this.starty=this.endy=-aPixPos[1];
> }
> else
> {
> this.endx=-aPixPos[0];
> this.endy=-aPixPos[1];
> }
> if(this.kaMap.getCurrentMap().units ==
> 5) {
> this.total += this.measureSphericalDistance2Points
> (this.startx,this.starty,this.endx,this.endy);
> }else{
> this.total += this.measure2points
> (this.startx,this.starty,this.endx,this.endy);
> }
> this.total = parseInt(this.total*100)/100;
> document.getElementById("measureTot").value =
> this.total;
> this.drawLine();
> e.cancelBubble = true;
> e.returnValue = false;
> if (e.stopPropogation) e.stopPropogation();
> if (e.preventDefault) e.preventDefault();
> return false;
> }
> };
>
> /**
> * myKaRuler.onmouseup( e )
> *
> * called when a mouse button is clicked over theInsideLayer.
> *
> * e - object, the event object or null (in ie)
> */
> myKaRuler.prototype.onmouseup = function(e) {
> e = (e)?e:((event)?event:null);
> return false;
> };
> /**
> * myKaRuler.measureSphericalDistance2Points
> *
> * pix1,piy1 - pixel coordinates of the first point
> * pix2,piy2 - pixel coordinates of the second point
> *
> * This function is used to calculate the distance between two
> points in decimel degree unit.
> * It assume that the earth is a perfect sphere, so the calculation
> isn't accurate.
> * In fact the further you are from the equator the least accurate
> the calulation is.
> */
> myKaRuler.prototype.measureSphericalDistance2Points = function
> (pix1,piy1,pix2,piy2)
> {
> var pt1 = this.kaMap.pixToGeo(pix1,piy1);
> var pt2 = this.kaMap.pixToGeo(pix2,piy2);
> /* Convert all the degrees to radians */
> var la1 = pt1[0] * Math.PI/180.0;
> var lo1 = pt1[1] * Math.PI/180.0;
> var la2 = pt2[0] * Math.PI/180.0;
> var lo2 = pt2[1] * Math.PI/180.0;
> /* Find the Great Circle distance */
> var EARTH_RADIUS = 6378;//kilometers //3956;//miles
> var distance = Math.acos(Math.sin(la1)*Math.sin(la2)+Math.cos
> (la1)*Math.cos(la2)*Math.cos(lo2-lo1)) * EARTH_RADIUS ;
> return distance ;
> };
>
> /**
> * myKaRuler.measureSphericalDistance2Points
> *
> * p1X,p1Y - pixel coordinates of the first point
> * p2X,p2Y - pixel coordinates of the second point
> *
> * This function is used to calculate the distance between two
> points in planar projection.
> * I use the Pythagor algorythm. The result unit is the same as the
> projection unit and is round
> * at two decimals.
> */
> myKaRuler.prototype.measure2points = function(p1X,p1Y,p2X,p2Y)
> {
> // Diff X/Y between current new and previous click
> var x_delta = p1X - p2X;
> var y_delta = p1Y - p2Y;
> // Segment length in Pixel
> var segLenPix = Math.sqrt((Math.pow(x_delta, 2)) + (Math.pow
> (y_delta, 2)));
> // Segment length in map coordinates, write values to input boxes
> var extent = this.kaMap.getGeoExtents();
> var xdelta_geo = extent[2]-extent[0];
> var segLenGEO = parseInt( ((segLenPix/this.kaMap.viewportWidth )
> * xdelta_geo)*100 )/100;
> return segLenGEO;
> };
> _______________________________________________
> ka-Map-users mailing list
> ka-Map-users at lists.maptools.org
> http://lists.maptools.org/mailman/listinfo/ka-map-users
More information about the ka-Map-users
mailing list