Web forum is in read-only mode. Login as active registered customer for write access
  Forum Search   New Posts New Posts

Custom Marker Image Location

 Post Reply Post Reply
Author
Mann Leonard View Drop Down
New Member
New Member
Avatar

Joined: 15 Mar 2012
Posts: 10
Post Options Post Options   Quote Mann Leonard Quote  Post ReplyReply Direct Link To This Post Topic: Custom Marker Image Location
    Posted: 24 Jul 2019 at 2:41pm

Is there a way to use a custom icon file for a marker that is not hosted on a WebServer?
The samples show the custom icon file as a Web hosted URL.


I have found some posts regarding custom markers that use a non-URL file name when adding a Marker.

   Icon := "abc.png";

TMSFMXWebGmaps1.Markers.Add(Latitude, Longitude, Description, Icon, false, true, true, true, false, 0);

 I found that when I compile in Windows 64 debug mode, My custom Icon image does not show unless I compile with a fully qualified path name such as   Icon := "C:\temp\abc.png".

 If I leave the Icon property blank, I get the default as expected.

 When I compile into IOSDevice64 even with a fully qualified path name, I do not get an icon on my device.

 Is there a way to compile my app with the custom icon and have it deployed to the device so I do not have to get the image from Web Host?
Back to Top
Stefan Grube View Drop Down
New Member
New Member
Avatar

Joined: 04 Mar 2019
Posts: 37
Post Options Post Options   Quote Stefan Grube Quote  Post ReplyReply Direct Link To This Post Posted: 24 Jul 2019 at 3:07pm
I show markers on GMaps, that are even stored in a TImageList and are encoded in base64 on showing them. So you don't have to supply additional files with your app.
Back to Top
Mann Leonard View Drop Down
New Member
New Member
Avatar

Joined: 15 Mar 2012
Posts: 10
Post Options Post Options   Quote Mann Leonard Quote  Post ReplyReply Direct Link To This Post Posted: 24 Jul 2019 at 4:35pm
Thanks for the reply, Stefan.

I checked out the post you referenced but am not sure how I would implement the solution using the TMS Software GMaps Components in Delphi RIO. I was able to use an ImageList and bitmaps with other components and thought I could do the same with the GMaps components.

I also issued this question directly to TMS Support and received an answer that local image files are not currently supported on IOS.

I guess I will have to use images from a Web Host.
Back to Top
Stefan Grube View Drop Down
New Member
New Member
Avatar

Joined: 04 Mar 2019
Posts: 37
Post Options Post Options   Quote Stefan Grube Quote  Post ReplyReply Direct Link To This Post Posted: 24 Jul 2019 at 11:10pm
Instead of an URL or local path to an image file, you just post a string, that has a PNG image (from an ImageList) encoded in base64 encoding.
This should work independently from the OS and such, as this is a feature of the Google Maps API and its web server.
Back to Top
Mann Leonard View Drop Down
New Member
New Member
Avatar

Joined: 15 Mar 2012
Posts: 10
Post Options Post Options   Quote Mann Leonard Quote  Post ReplyReply Direct Link To This Post Posted: 25 Jul 2019 at 6:13pm
Thanks again for the response Stefan.
I will look into your suggestion to see how I can integrate it into my application.

Leonard
Back to Top
Stefan Grube View Drop Down
New Member
New Member
Avatar

Joined: 04 Mar 2019
Posts: 37
Post Options Post Options   Quote Stefan Grube Quote  Post ReplyReply Direct Link To This Post Posted: 26 Jul 2019 at 11:35am
Here's a start (the interface might be different from what you have, as I have extended the methods of TMarker):

            WebGMap.Markers.Add(GPSTracks[Track].Startpoint.Latitude, GPSTracks[Track].Startpoint.Longitude, //Koordinaten
                                StringToMarkerTitle(GPSTracks[Track].Startpoint.ToMarkerTitle('Start', MyFormatSettings)), //Titel
                                Encode64(pilMarkerImages.PngImages[pilStartpoint].PngImage), //Icon, Base64-Encoded oder File-URI
                                False, //Draggable
                                True,  //Visible
                                True,  //Clickable
                                True,  //Flat
                                TMarkerAnimation(rgGMMarkerAnimation.ItemIndex), //Animation
                                ziMarkerStartEnd, //zIndex
                                MarkerCoordinates[pilStartpoint].Width,  //IconWidth
                                MarkerCoordinates[pilStartpoint].Height, //IconHeight
                                -1, //IconZoomWidth
                                -1, //IconZoomHeight
                                MarkerCoordinates[pilStartpoint].AnchorWidth,  //IconAnchorWidth
                                MarkerCoordinates[pilStartpoint].AnchorHeight, //IconAnchorHeight
                                0, //IconOriginWidth
                                0  //IconOriginHeight
                               );

function Encode64(Src, Dest: TStream): Boolean;
const
  Map: array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'+
                                  'abcdefghijklmnopqrstuvwxyz'+
                                  '0123456789+/';
var
  Size: Integer;
  Data: array[0..2] of Byte;
  EncodedData: array[0..3] of AnsiChar;
begin
  Result:=false;
  if not assigned(Src) or not assigned(Dest)
    then Exit;
  while Src.Position<Src.Size do
  begin
    Size:=Src.Read(Data,SizeOf(Data));
    EncodedData[0]:=Map[Data[0] shr 2];
    EncodedData[1]:=Map[((Data[0] shl 4) or (Data[1] shr 4)) and $3F];
    EncodedData[2]:=Map[((Data[1] shl 2) or (Data[2] shr 6)) and $3F];
    EncodedData[3]:=Map[Data[2] and $3F];
    case Size of
      0: Exit;
      1: begin
           EncodedData[2]:='=';
           EncodedData[3]:='=';
         end;
      2: EncodedData[3]:='=';
      3: ;
    end;
    Dest.Write(EncodedData,SizeOf(EncodedData));
  end;
end;

function Encode64(Data: TStream; const MediaType: String): String;
var
  Stream: TStringStream;
begin
  Result := '';
  if not assigned(Data)
    then Exit;
  Stream := TStringStream.Create('data:'+MediaType+';base64,');
  try
    Stream.Seek(0, soFromEnd);
    Encode64(Data, Stream);
    Stream.Seek(0, soFromBeginning);
    Result := Stream.DataString;
  finally
    Stream.Free;
  end;
end;

function Encode64(Image: TPNGImage): String;
var
  Stream: TMemoryStream;
begin
  Result := '';
  if not assigned(Image)
    then Exit;
  Stream := TMemoryStream.Create;
  try
    Image.SaveToStream(Stream);
    Stream.Seek(0, soFromBeginning);
    Result := Encode64(Stream, 'image/png');
  finally
    Stream.Free;
  end;
end;

The sources for encode64() are from the net somewhere I can't remember.
The PNG image is loaded from pilMarkerImages, a TPNGImageList.
Back to Top
Mann Leonard View Drop Down
New Member
New Member
Avatar

Joined: 15 Mar 2012
Posts: 10
Post Options Post Options   Quote Mann Leonard Quote  Post ReplyReply Direct Link To This Post Posted: 26 Jul 2019 at 4:52pm
Thanks for the code, Stefan,

I found and installed the pngcomponents from here:

The documentation says it should be Delphi RIO compatible.

However, I am getting compiler errors when trying to use the components.

[dcc64 Error] pngzlib.pas(149): E2045 Bad object file format: '..\Components\PNGComponents-master\PngObject\obj\adler32.obj'.
[dcc64 Error] pngzlib.pas(45): E2065 Unsatisfied forward or external declaration: 'inflateInit_'

I like your solution and will work on the compiler errors when I come back from holidays in a week. :)

I appreciate all your help.


Back to Top
Stefan Grube View Drop Down
New Member
New Member
Avatar

Joined: 04 Mar 2019
Posts: 37
Post Options Post Options   Quote Stefan Grube Quote  Post ReplyReply Direct Link To This Post Posted: 26 Jul 2019 at 5:13pm
Here are the original PNGComponents by Uwe Raabe, that I'm using since ages.
Though not officially stated, they work fine with Rio.

https://bitbucket.org/uweraabe/pngcomponents/src/default/
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down