[GIS] How to stop or deactivate draw polygon control after the first polygon has been drawn in Openlayers

javascriptmapsopenlayers-2polygonvector

I want to only be able to draw one circle on my map and then disable the control. Below is my code, Any suggestions?

                <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', 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);


      if (console && console.log) {
          function report(event) {
              console.log(event.type, event.feature ? event.feature.id : event.components);
          }
          vectors.events.on({
              "beforefeaturemodified": report,
              "featuremodified": report,
              "afterfeaturemodified": report,
              "vertexmodified": report,
              "sketchmodified": report,
              "sketchstarted": report,
              "sketchcomplete": report
          });
      }

      // 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);
      }

       vectors.events.on({
          afterfeaturemodified: afterFeaturesModified
      });

      function afterFeaturesModified(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);
      }


      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>

Best Answer

You should deactivate the control after the first draw operation. For instance you could add this code

controls['regular'].deactivate()

to the afterfeaturemodified event hook (currently assigned to the report function).