Search code examples
google-mapsdelphigoogle-maps-markersgmlib

GM Direction Component is Null with specifics coordinates


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.


Solution

  • 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