Ability to get the Polygon's area

I noticed that as of writing this post, there is no way to get the area surface of a polygone, so I implemented it and would like to respectfully propose my changes be considered to be incorporated into the WebGMap functionalities.

Here's what I've done:

Add the following Javascript function in uWebGMapsConst.pas

 ' function getPolygonAreaSqMeters(polygonIndex) {' + #13 +
 '   var polygonBounds = allpolygons[polygonIndex].getPath();' + #13 +
 '   var sqMeters = google.maps.geometry.spherical.computeArea( polygonBounds ); ' + #13 +
   // Save the result string into our hidden input (i.e. "result")
 '   document.getElementById("result").value = sqMeters; ' + #13 +
 ' }' + #13 +
 ' ' + #13 +

Add the following hidden input field in the HTML...
(so to have a placeholder for the result)

 // Hidden input that will be used to get the result from Javascript
 // See the printAllPolygons and getPolygonAreaSqMeters Javascript functions defined above.)
 '  <input type="hidden" name="result" id="result" value="" />' + #13 +

In UwebGMaps.pas...

Add the following routines:

interface

 function InvokeScript(const AScript: String): String;
 function GetPolygonAreaSqMeters( APolygonIndex: Integer ): String;

implementation

function TWebGMaps.InvokeScript(const AScript: String): String;
{Use InvokeScript when you need the result from a JavaScript function.
 It first calls/uses ExecJScript to execute the function, then saves the result
 into a hidden input (i.e. "result") that has been declared in
 UWebGMapsConst.pas (see const HTML_FILE_1). }

  function GetElementIdValue(AWebBrowser: TWebBrowser;
    TagName, TagId, TagAttrib: string):string;
  var
    Document: IHTMLDocument2;
    Body: IHTMLElement2;
    Tags: IHTMLElementCollection;
    Tag: IHTMLElement;
    I: Integer;
  begin
    Result:='';
    if not Supports(AWebBrowser.Document, IHTMLDocument2, Document) then
      raise Exception.Create('Invalid HTML document');
    if not Supports(document.body, IHTMLElement2, Body) then
      raise Exception.Create('Can''t find <body> element');
    Tags := body.getElementsByTagName(UpperCase(TagName));
    for I := 0 to Pred(Tags.length) do begin
      Tag:=Tags.item(I, EmptyParam) as IHTMLElement;
      if Tag.id=TagId then Result := Tag.getAttribute(TagAttrib, 0);
    end;
  end;

begin
  Result := '';

  if bLaunchFinish then
  begin
    // Run the script
    if ExecJScript( AScript { 'Ex: printallpolygons();' } ) then
    begin
      // Get the result
      Result := GetElementIdValue(FWebBrowser, 'input', 'result', 'value')
    end;
  end;
end;


function TWebGMaps.GetPolygonAreaSqMeters(APolygonIndex: Integer): String;
begin
  Result := Trim( InvokeScript( Format( 'getPolygonAreaSqMeters(%d)', [ APolygonIndex ] ) ) );
end;


Now, let's use it:

procedure DisplayArea( APolygonItem: TMapPolygonItem );
var
  SqMetersStr: String;
  SqMeters: Double;
  Hectares: Double;
  Acres: Double;
begin
  ...

  //Get Area Surface

  SqMetersStr := AWebGMaps.GetPolygonAreaSqMeters( APolygonItem.Polygon.ItemIndex -1 );
  SqMeters := StrToFloatDef( SqMetersStr, -1 );

  // 1 Square Meter = 0.0001 Hectare
  Hectares := SqMeters * 0.0001;
  ShowMessage( 'Hectares: ' + Format( '%.2f', [Hectares] ) );

  // 1 Square Meter = 0.000247105 Acre
  Acres := SqMeters * 0.000247105;
  ShowMessage( 'Acres: ' + Format( '%.2f', [Acres] ) );
end;

Please feel free to rip it apart and enhance it as you see fit. 

Thanks in advance,
Richard

Hi,


Thank you for your suggestion.
We'll consider adding this functionality in a future version of TMS WebGMaps.

I forgot to mention, in order for this to work, you'll also have to add the Geometry library:


<script type="text/javascript" src="http://maps.google.com/maps/api/js?%apikey%sensor=false&libraries=panoramio,weather,geometry&language=%lang%">
</script>

Cheers,
Richard