2

I'm working with gmlib in Delphi Seattle 10. My client application sends the location(Latitude and Longitude) through an fireMonkey application to my database InterBase XE7. My admin console consists in display a google map with markers that come from a query,for later calculate the distance between all markers in the map.

The procedure that creates markers is working perfectly and at the same time i'm filling the GMDirection component with the coordinates of markers. Here is the code of "CreatePoint" procedure:

   amplitud := 1;
   posicion := 0;
   Distancia := 0;
   markerGM.Tag := 1;
   qryDatos.Close;
   qryDatos.Open;

   while not qryDatos.Eof do
   begin
     SetLength(marcadores,amplitud);
     marcadores[posicion] := qryDatos.FieldByName('PLULOG').AsInteger;

     Latitud := qryDatos.FieldByName('LATITUD').AsFloat;
     Longitud := qryDatos.FieldByName('LONGITUD').AsFloat;
     autorizado := qryDatos.FieldByName('AUTORIZADO').AsString;

     with markerGM.Add(Latitud,Longitud) do
     begin
       if autorizado = 'T' then
       begin
         if markerGM.Tag = 1 then
         begin
           directionGM.DirectionsRequest.Origin.LatLng.Lat := Latitud;
           directionGM.DirectionsRequest.Origin.LatLng.Lng := Longitud;
         end
         else if markerGM.Tag = 2 then
              begin
               directionGM.DirectionsRequest.Destination.LatLng.Lat := Latitud;
               directionGM.DirectionsRequest.Destination.LatLng.Lng := Longitud;
               directionGM2.DirectionsRequest.Origin.LatLng.Lat := Latitud;
               directionGM2.DirectionsRequest.Origin.LatLng.Lng := Longitud;

               Distancia :=    DistanceBetween(directionGM.DirectionsRequest.Origin.LatLng.Lat,directionGM.DirectionsRequest.Origin.LatLng.Lng,
                                    directionGM.DirectionsRequest.Destination.LatLng.Lat,directionGM.DirectionsRequest.Destination.LatLng.Lng);
             end
             else if markerGM.Tag = 3 then
                  begin
                    directionGM2.DirectionsRequest.Destination.LatLng.Lat := Latitud;
                    directionGM2.DirectionsRequest.Destination.LatLng.Lng := Longitud;
                    directionGM3.DirectionsRequest.Origin.LatLng.Lat := Latitud;
                    directionGM3.DirectionsRequest.Origin.LatLng.Lng := Longitud;

                    Distancia := Distancia + DistanceBetween(directionGM2.DirectionsRequest.Origin.LatLng.Lat,directionGM2.DirectionsRequest.Origin.LatLng.Lng,
                                                      directionGM2.DirectionsRequest.Destination.LatLng.Lat,directionGM2.DirectionsRequest.Destination.LatLng.Lng);
                  end
                  else if markerGM.Tag = 4 then
                       begin
                         directionGM3.DirectionsRequest.Destination.LatLng.Lat := Latitud;
                         directionGM3.DirectionsRequest.Destination.LatLng.Lng := Longitud;
                         directionGM4.DirectionsRequest.Origin.LatLng.Lat := Latitud;
                         directionGM4.DirectionsRequest.Origin.LatLng.Lng := Longitud;

                         Distancia := Distancia + DistanceBetween(directionGM3.DirectionsRequest.Origin.LatLng.Lat,directionGM3.DirectionsRequest.Origin.LatLng.Lng,
                                                          directionGM3.DirectionsRequest.Destination.LatLng.Lat,directionGM3.DirectionsRequest.Destination.LatLng.Lng);
                       end;


           MarkerType := mtColored;
           ColoredMarker.Width := 48 + (Index * 20);
           ColoredMarker.Height := 48;
           markerGM.Tag := markerGM.Tag + 1;
         end;    
       end;
       mapGM.RequiredProp.Center.Lat := Latitud;
       mapGM.RequiredProp.Center.Lng := Longitud;
       mapGM.RequiredProp.Zoom := 13;
       amplitud := amplitud + 1;
       posicion := posicion + 1;
       qryDatos.Next;
    end;
    mapGM.Active := True;

And here is the code of the procedure of "DistanceBetween" from Internet:

    function TfrmLocationMain.DistanceBetween(const Lat1: Extended; const Lon1: Extended; const Lat2: Extended; const Lon2: Extended): Extended;
    begin
      Result := RadToDeg(ArcCos(Sin(DegToRad(Lat1)) * Sin(DegToRad(Lat2)) + Cos(DegToRad(Lat1)) * Cos(DegToRad(Lat2)) * Cos(DegToRad(Lon1 - Lon2)))) * 69.09;
    end;

And finally. When the google map with the markers are created and the components are full of data. I'm execute all the GMDirection components to calculate the distance and displays in a EditText.

    procedure TfrmLocationMain.btnRutaClick(Sender: TObject);
    begin
      directionGM.Execute;
      directionGM2.Execute;
      directionGM3.Execute;
      directionGM4.Execute;

      Distancia := (Distancia/0.62137); 
      edtDistancia.Text := FloatToStr(Distancia);
      mapGM.RequiredProp.Zoom := 14;
    end;

All this code is working with all registers in a test database. With coordinates from my country El Salvador. But when I implemented in a database from Guatemala. Some coordinates are causing that GMDirection component give me the following error:

Could not convert variant of type(Null) into type(OleStr)

This happens whit some coordinates from a Guatemala's database. For example. If the Query gives me the following data:

14.513,-90.558
14.559,-90.545
14.572,-90.542

All the code works perfectly. But if the Query gives me the following data:

14.505,-90.568
14.667,-90.494
14.666,-90.494

Give me the error above. I don't know what is the problem. And I don't understand why the code works with some registers and with others not. If someone has a similar problem or idea of what may be failing. I would greatly appreciate your help with this.

Regards.

  • Which line of code raises the error? – John Easley Oct 26 '16 at 02:23
  • Hi @JohnEasley the line of code that raises the error, sometimes it is in directionGM.Execute and others in directionGM2.Execute. Depends of coordinates that come from query. I think that the problem is with the component itself. Because when i run it in debugg mode. The exception raises at the moment of execute the following function: GetRetournedData; wich it is part of GMDirection's code. – Luis Chavez Oct 26 '16 at 17:42

1 Answers1

2

I have found the problem. To solve it, open unit GMDirection, add Variants unit to the uses clause

implementation

uses
  {$IFDEF DELPHIXE2}
  System.SysUtils, System.DateUtils, Xml.XMLIntf, Xml.XMLDoc, System.Variants,
  {$ELSE}
  SysUtils, DateUtils, XMLIntf, XMLDoc, Variants,
  {$ENDIF}
  Lang, GMFunctions;

Search line (3575 aprox)

    if SameText(Node.NodeName, LBL_D_SUMMARY) then Result.FSumary := Node.NodeValue;

and replace by

    if SameText(Node.NodeName, LBL_D_SUMMARY) and (Node.NodeValue <> null) then Result.FSumary := Node.NodeValue;

Recompile the components

That's all

cadetill
  • 1,552
  • 16
  • 24
  • That was the problem!!! Thank You So much cadetill !!!. Your solution worked very well and it works for every coordinate. Thank you and Regards. – Luis Chavez Oct 26 '16 at 22:30