1

I have made a Openlayers integrated map that lets you draw a circle, On completion of the circle I have told the map to give me , Bounds, Center Long and Lats, and lastly the radius. My problem is that I can't understand in what decimal it gives the radius to me in. Below is a image that shows you I have drawn a very large circle and the alert for the radius. How many kilometers is this? (I made a google map with the same functionality and the radius works in meters with EPSG Projection.

enter image description here

Below is my code. I am using CRS:84 for my map projection.

Here is the initial bit of code I want working in Meters rather than the decimal structure of the above picture.

            vectors.events.on({
          featuremodified: onFeatureModified
       });

          function onFeatureModified(event) {
           var bounds = event.feature.geometry.getBounds();
           var answer = "bottom: " + bounds.bottom + "\n";
           answer += "left: " + bounds.left + "\n";
           answer += "right: " + bounds.right + "\n";
           answer += "top: " + bounds.top + "\n";
           alert(answer);
           var area = event.feature.geometry.getArea();
           var radius = 0.565352 * Math.sqrt(area);
           alert(radius);
           var lonlat = event.feature.geometry.getBounds().getCenterLonLat()
           alert(lonlat);

Below this is my complete html document:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <!--CSS for Map -->
    <style type="text/css">
    html, body, #map {
    margin: 0;
    width: 100%;
    height: 100%;
    }
    </style>
    <!-- END of CSS for Map -->

    <!--CSS for Controls to draw circle and navigate -->
    <style type="text/css">
    #controls {
    position: absolute;
    bottom: 1em;
    left: 100px;
    width: 400px;
    z-index: 20000;
    padding: 0 0.5em 0.5em 0.5em;
    }

    #controlToggle {
    padding-left: 1em;
    }

    #controlToggle li {
    list-style: none;
    }

    #form {
    position: absolute;
    bottom: 1em;
    left: 400px;
    width: 200px;
    z-index: 20000;
    padding: 0 0.5em 0.5em 0.5em;
    }
   </style>
   <!-- END CSS for Controls to draw circle -->

  <link href="css/style.css" rel="stylesheet" type="text/css" />
  <script src="js/firebug.js"></script>
  <script src="js/OpenLayers.js"></script>

  <script type="text/javascript">
   var lon = 24.0000000000;
   var lat = -29.000000000000;

   var zoom = 4;
   var map, layer, vectors, controls;

   function init() {

       // Because the Streetmaps system uses 300x300 tiles, we need to set up the scaling variables to work with these
       var aRes = [90, 45, 22.500000, 11.250000, 5.625000, 2.812500, 1.406250, 0.703125, 0.351563, 0.175781, 0.087891, 0.043945, 0.021973, 0.010986, 0.005493, 0.002747, 0.001373, 0.000687, 0.000343];
       for (var l = 0; l < aRes.length; l++) { aRes[l] = aRes[l] / 300; }

       // Normal init, but we pass through the info about the zoom/scaling as options
       map = new OpenLayers.Map('map', { tileSize: new OpenLayers.Size(300, 300), projection: 'CRS:84',units: "m", numZoomLevels: aRes.length, resolutions: aRes, maxResolution: 360 / 300 });

       // At this point the control is used as per normal            
       layer1 = new OpenLayers.Layer.WMS(
              'Streetmaps Streets',
              'http://www.streetmaps.co.za/WMS/?',
              {
                  key: 'HZPGNWPNDYPREPTIKSIHWKYKQYYOQVYX',
                  service: 'WMS',
                  request: 'GetMap',
                  version: '1.3.0',
                  layers: 'sm.maps.tiled',
                  format: 'image/png'
              }
    );

       layer2 = new OpenLayers.Layer.WMS(
              'Streetmaps Imagery',
              'http://www.streetmaps.co.za/WMS/?',
              {
                  key: 'HZPGNWPNDYPREPTIKSIHWKYKQYYOQVYX',
                  service: 'WMS',
                  request: 'GetMap',
                  version: '1.3.0',
                  layers: 'sm.imagery',
                  format: 'image/png'
              }
    );

       // This loads the map
       map.addLayer(layer1);
       map.addLayer(layer2);

       map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
       map.addControl(new OpenLayers.Control.LayerSwitcher());
       var vectors = new OpenLayers.Layer.Vector("vector", { isBaseLayer: true });
       map.addLayers([vectors]);

       // This loads the overlays
       var wms = new OpenLayers.Layer.WMS("OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0?", { layers: 'basic' });
       OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';

       // allow testing of specific renderers via "?renderer=Canvas", etc
       var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
       renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;

       vectors = new OpenLayers.Layer.Vector("Vector Layer", {
           renderers: renderer
       });

       map.addLayers([wms, vectors]);
       map.addControl(new OpenLayers.Control.LayerSwitcher());
       map.addControl(new OpenLayers.Control.MousePosition());
       map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);

       // Now we call an alert to get the bounds or coordinates from a circle or vector we have drawn 
       vectors.events.on({
           featuresadded: onFeaturesAdded
       });

       function onFeaturesAdded(event) {
           var bounds = event.features[0].geometry.getBounds();
           var answer = "bottom: " + bounds.bottom + "\n";
           answer += "left: " + bounds.left + "\n";
           answer += "right: " + bounds.right + "\n";
           answer += "top: " + bounds.top + "\n";
           alert(answer);
           var area = event.features[0].geometry.getArea();
           var radius = 0.565352 * Math.sqrt(area);
           alert(radius);
           var lonlat = event.features[0].geometry.getBounds().getCenterLonLat()
           alert(lonlat);

           // GET CENTER LAT + LON
           // AUTOMATICALLY INITIATE: onFeatureModified (Incl. Click)
           // DISABLE DRAW FEATURE

           // ASSIGN VALUES TO HIDDEN FIELDS IN FORM:
           //document.forms.item('hiddenfield').value = answer;
       }

       vectors.events.on({
          featuremodified: onFeatureModified
       });

          function onFeatureModified(event) {
           var bounds = event.feature.geometry.getBounds();
           var answer = "bottom: " + bounds.bottom + "\n";
           answer += "left: " + bounds.left + "\n";
           answer += "right: " + bounds.right + "\n";
           answer += "top: " + bounds.top + "\n";
           alert(answer);
           var area = event.feature.geometry.getArea();
           var radius = 0.565352 * Math.sqrt(area);
           alert(radius);
           var lonlat = event.feature.geometry.getBounds().getCenterLonLat()
           alert(lonlat);

           // DISABLE DRAW FEATURE

           // ASSIGN VALUES TO HIDDEN FIELDS IN FORM:
           //document.forms.item('hiddenfield').value = answer;y
       }

       controls = {
           regular: new OpenLayers.Control.DrawFeature(vectors,
            OpenLayers.Handler.RegularPolygon,
            { handlerOptions: { sides: 40} }),
           modify: new OpenLayers.Control.ModifyFeature(vectors)
       };

       for (var key in controls) {
           map.addControl(controls[key]);
       }

       map.setCenter(new OpenLayers.LonLat(0, 0), 3);
       document.getElementById('noneToggle').checked = true;
       }

       function update() {
       // reset modification mode
       //controls.modify.mode = OpenLayers.Control.ModifyFeature.RESHAPE;
       controls["modify"].activate();
       controls.modify.mode = OpenLayers.Control.ModifyFeature.ROTATE;

       var resize = document.getElementById("resize").checked;
       if (resize) {
           controls.modify.mode |= OpenLayers.Control.ModifyFeature.RESIZE;
           var keepAspectRatio = document.getElementById("keepAspectRatio").checked;
           if (keepAspectRatio) {
               controls.modify.mode &= ~OpenLayers.Control.ModifyFeature.RESHAPE;
           }
       }

       var drag = document.getElementById("drag").checked;
      if (drag) {
          controls.modify.mode |= OpenLayers.Control.ModifyFeature.DRAG;
      }

       //          if (rotate || drag) {
       //              controls.modify.mode &= ~OpenLayers.Control.ModifyFeature.RESHAPE;
       //          }
       //          var sides = parseInt(document.getElementById("sides").value);
       //          sides = Math.max(3, isNaN(sides) ? 0 : sides);
       //          controls.regular.handler.sides = sides;
       //          var irregular = document.getElementById("irregular").checked;
       //          controls.regular.handler.irregular = irregular;
   }


   function toggleControl(element) {
       for (key in controls) {
           var control = controls[key];
           if (element.value == key && element.checked) {
               control.activate();
           } else {
               control.deactivate();
           }
       }
   }
</script>
</head>
<body onLoad="init()">
<div id="map" class="smallmap"></div>
<div id="controls">
<ul id="controlToggle">
  <li>
<input type="radio" name="type" value="none" id="noneToggle"
       onclick="toggleControl(this);" checked="checked" />

  <label for="noneToggle">navigate</label>
  </li>
   <li>
  <input type="radio" name="type" value="regular" id="regularToggle" onClick="toggleControl(this);" />
<label for="regularToggle">draw regular polygon</label>
 </li>
 <li>
   <input type="radio" name="type" value="modify" id="modifyToggle"
       onclick="update();" />

      <label for="modifyToggle">modify feature</label>
  <ul>
    <li>
          <input id="rotate" type="hidden" 
               name="rotate" onChange="update()"  checked="checked"/>
    </li>
    <li>
        <input id="resize" type="hidden"
               name="resize" onChange="update()"  checked="checked"/>
        <input id="keepAspectRatio" type="hidden"
               name="keepAspectRatio" onChange="update()" checked="checked" />
        <label for="keepAspectRatio"></label>
    </li>
    <li>
        <input id="drag" type="hidden"
               name="drag" onChange="update()"  checked="checked"/>
    </li>
  </ul>
  </li>
  </ul>
  </div>
  </body> 
  </html> 
2
  • 1
    This question seems to cover the same ground as the last 12 or so of your questions. Doesn't the reply at gis.stackexchange.com/a/21173 do the job?
    – whuber
    Commented Mar 19, 2012 at 20:53
  • @whuber I am having trouble unprojecting the area and Radius. Not exactly sure how to use the code for the radius. Commented Mar 21, 2012 at 12:09

1 Answer 1

2

The result is in meters. To get the kilometers, multiply the radius by .001.

I came to this conclusion by testing your code against google earth's measuring tool. And it makes sense because your map units are in meters. However, i'm confused as to what code you used to get the screenshot above because when i test your code i get something very different.

This is what more or less 8 meter radius looks like when i tested your code. It certainly did not cover a few countries in west Africa.

enter image description here

UPDATE:

Based on your comments and your new code example all you need to do is use getGeodesicArea() to get the square meters. And your resulting radius will be in meters.

Change this line:

var area = event.features[0].geometry.getArea();

For this line:

var area = event.features[0].geometry.getGeodesicArea();

Returns {float} The approximate geodesic area of the polygon in square meters.

4
  • Sorry my mistake I have edited the code to the correct maps, I showed my google maps version of my code by mistake, Please run the code I have edited. Commented Mar 22, 2012 at 8:39
  • But you are correct my google maps version is in metres, If you run edited code you will see that if you draw a circle like the pic above you get what I am getting. Commented Mar 22, 2012 at 8:41
  • @BlakeLoizides No problem, check my update.
    – CaptDragon
    Commented Mar 22, 2012 at 13:03
  • That worked 100%. Thanks for the Update. I really do appreciate this @CaptDragon. You have helped me learn alot with regards to Openlayers. So Thanks Commented Mar 22, 2012 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.