[ka-Map-users] Ruler tool

Pje pjebra at gmail.com
Thu Sep 14 07:27:02 EDT 2006


Interesting... I'm already using your code and doing some tests.

On 9/13/06, Stéphane RIFF <stephane.riff at cerene.fr> 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>&nbsp;Seg : <input type='text'
> id='measureSeg'
> style='border:none;background-color:transparent;width:75px;' />
> "+this.unitsAbrevations[this.kaMap.getCurrentMap().units]+"<br><br>&nbsp;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