1 votos

Desproyección de radios con Openlayers con proyección CRS:84

He hecho un mapa integrado en Openlayers que te permite dibujar un círculo, Al completar el círculo le he dicho al mapa que me dé , Bounds, Center Long and Lats, y por último el radio. Mi problema es que no puedo entender en que decimal me da el radio. Abajo hay una imagen que muestra que he dibujado un círculo muy grande y la alerta para el radio. ¿Cuántos kilómetros son? (He hecho un mapa de google con la misma funcionalidad y el radio funciona en metros con la proyección EPSG.

enter image description here

Abajo está mi código. Estoy usando CRS:84 para mi proyección de mapa.

Aquí está el trozo de código inicial que quiero que funcione en Metros en lugar de la estructura decimal de la imagen anterior.

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

Abajo está mi documento html completo:

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

2voto

Vasu Puntos 11

El resultado está en metros. Para obtener los kilómetros, multiplica el radio por 0,001.

Llegué a esta conclusión probando su código contra la herramienta de medición de google earth. Y tiene sentido porque las unidades de su mapa están en metros. Sin embargo, estoy confundido en cuanto a lo que el código que utilizó para obtener la captura de pantalla anterior, porque cuando pruebo su código me da algo muy diferente.

Esto es lo que parece más o menos 8 metros de radio cuando probé su código. Ciertamente no cubría algunos países de África occidental.

enter image description here

ACTUALIZACIÓN:

Basado en tus comentarios y tu nuevo ejemplo de código todo lo que necesitas hacer es usar getGeodesicArea() para obtener los metros cuadrados. Y su radio resultante estará en metros.

Cambia esta línea:

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

Para esta línea:

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

Devuelve {float} El área geodésica aproximada del polígono en cuadrados metros.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X