[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> 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