[OpenLayers-Users] how to best extend drawing tools to includemeasure

Mike Quentel mikequentel at yahoo.com
Wed May 16 13:32:20 EDT 2007


Bob,

Thanks very much for sharing your code and ideas.

What I've done to add the distance measure functionality to a line drawing tool (in addition to the code I attached in my previous email) is the following:

1.  I created another handler class called OpenLayers.Handler.MeasureTool, with essentially the same implementation as the Path.js, with a few modifications.

2.  In MeasureTool, I added a class member representing the Measure control, as in:

measure: null,

3.  In MeasureTool, I overrided the setMap function of OpenLayers.Control, so that the class member measure is added to the map, as in:

setMap: function() {
  OpenLayers.Control.prototype.setMap.apply(this, arguments);
    this.map.addControl(this.measure);
},

4.  In the MeasureTool (which is almost identical to Path.js), I added the following to the drawGeometry function:

drawGeometry: function() {
   this.layer.renderer.drawGeometry(this.line, this.style);
   this.layer.renderer.drawGeometry(this.point, this.style);

   // here is the call to the Measure control...
   this.measure.showDistance(this.line);

},

Not clear what I'd have to do to change the functionality if I'm using WGS84, lat/lon.  Doesn't the Vincenty formula work acceptably for lat/lon values?

Many thanks for your help.

Mike Quentel


----- Original Message ----
From: "Cicconetti, Bob" <BCicconetti at dnr.state.md.us>
To: Mike Quentel <mikequentel at yahoo.com>; OpenLayers Users <users at openlayers.org>
Sent: Wednesday, 16 May, 2007 10:50:23 AM
Subject: RE: [OpenLayers-Users] how to best extend drawing tools to includemeasure

What I've done is fairly similar, but use the much simpler getArea and
getLength calls. My maps are set in State Plane Nad83m, and you may have
to change a few things if you're in lat/lon.

R C

1) First, extend the drawing controls div to allow for more buttons, and
define the buttons. Copy or create new buttons in gimp/whatever.

--- theme/default/style.css     (revision 3151)
+++ theme/default/style.css     (working copy)
@@ -108,7 +108,7 @@
     float:right;
     right: 0px;
     height: 30px;
-    width: 200px;
+    width: 270px;
 }
 .olControlEditingToolbar div {
   float:right;
@@ -148,3 +148,15 @@
   background-image: url("img/draw_polygon_on.png");
   background-repeat: no-repeat;
 }
+.olControlEditingToolbar .olControlSelectFeatureItemInactive {
+  background-image: url("img/info_off.png");
+}
+.olControlEditingToolbar .olControlSelectFeatureItemActive {
+  background-image: url("img/info_on.png");
+}
+.olControlEditingToolbar .olControlDeleteFeatureItemInactive {
+  background-image: url("img/delete_off.png");
+}
+.olControlEditingToolbar .olControlDeleteFeatureItemActive {
+  background-image: url("img/delete_on.png");
+}

2) Add this to my javascript:
[...]
  // Extend the edit tool bar to allow deleting features, and gather
  // info about them.
  var selectTool = new OpenLayers.Control.SelectFeature(vlayer,
        {
        onSelect:feature_info,
        onUnselect:clear_feature_info
        });

  var deleteTool = new OpenLayers.Control.SelectFeature(vlayer,
        {
        onSelect:deleteFeature,
        onUnselect:clear_feature_info
        });

  var editToolBar = new OpenLayers.Control.EditingToolbar(vlayer);

  var myControls = [ selectTool, deleteTool ];
  // Fun with gimp. Be sure to use patched style.css.
  myControls[0].displayClass = 'olControlSelectFeature';
  myControls[1].displayClass = 'olControlDeleteFeature';

  editToolBar.addControls(myControls);
  map.addControl(editToolBar);

[...]

  function feature_info(feature) {
   //Extend to allow string length as well.
      if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon")
        {

        var str = feature.geometry.getArea();
        // Assume units are meters, for now.
        // Magic numbers are evil, but ah well.
        var sqft = str / 0.09290304;
        var acres = str / 4046.856422;

        // FIXME: Round and truncate. 8 sig figs?
        if (sqft < 4000)
         str = "Area: (sq ft.) " + sqft;
        else
         str = "Area: (acres) " + acres;

        document.getElementById('area').innerHTML = str;

        }
      else if (feature.geometry.CLASS_NAME ==
"OpenLayers.Geometry.LineString")
        {
        var str = feature.geometry.getLength();
        var feet = str / 0.3048;
        var miles = str / 1609.344;

        if (feet < 2000)
         str = "Length: (feet) " + feet;
        else
         str = "Length: (miles) " + miles;

        document.getElementById('area').innerHTML = str;
        }

  }

  function clear_feature_info(geometry) {
        document.getElementById('area').innerHTML = "Select Feature for
Area or
Length.";
  }

  function deleteFeature(geometry) {
        this.layer.removeFeatures(geometry);
        }

> -----Original Message-----
> From: users-bounces at openlayers.org
[mailto:users-bounces at openlayers.org]
> On Behalf Of Mike Quentel
> Sent: Tuesday, May 15, 2007 3:56 PM
> To: OpenLayers Users
> Subject: [OpenLayers-Users] how to best extend drawing tools to
> includemeasure
> 
> I created a measure control (OpenLayers.Control.Measure) that uses a
div
> (like the mouse position control) to display distance.
> 
> So far, I have an example where the user can select a drawn line, and
get
> back the total distance of the line.  It employs the
> OpenLayers.Util.distVincenty function to calculate the distances of
the
> components of the geometry, adding up the results.  It also handles
> situations like the user attempting to measure the entire globe
(handles
> situation if the pixel clicks exceed what they should for a
hemisphere).
> This is still in its raw state, so if you see bugs, please let me
know.
> The attached example seems to work well.
> 
> Please, need advice...I would like to add this functionality to the
> drawing tools, such that when the user draws a line, the total
distance is
> displayed in the measure control.  I am not sure how to go about doing
> this.  Would it be best to include this control in the
> OpenLayers.Handler.Path handler class?
> 
> Attached is Measure.js, which represents OpenLayers.Control.Measure,
as
> well as measure.html, to show an example.
> 
> If you want to add this control to your OL directory tree.....
> 
> The style.css would include the following:
> 
> div.olControlMeasure {
>       background-color: #FFFFFF;
>     top: 30px;
>     left: 400px;
>     display: block;
>     position: absolute;
>     font-family: Arial;
>     font-size: smaller;
>     font-weight: bold;
> }
> 
> The base OpenLayers class would need to include the Measure.js in its
JS
> files array:
> 
> var jsfiles=new Array(
> ...
> "OpenLayers/Control/Measure.js"
> );
> 
> 
> 
> 
> 
> 
> 
> 
> 
>       ___________________________________________________________
> Yahoo! Mail is the world's favourite email. Don't settle for less,
sign up
> for
> your free account today
>
http://uk.rd.yahoo.com/evt=44106/*http://uk.docs.yahoo.com/mail/winter07
.h
> tml





	
	
		
___________________________________________________________ 
New Yahoo! Mail is the ultimate force in competitive emailing. Find out more at the Yahoo! Mail Championships. Plus: play games and win prizes. 
http://uk.rd.yahoo.com/evt=44106/*http://mail.yahoo.net/uk 



More information about the Users mailing list