Working with TMapView on iOS and Android with RAD Studio XE8
The new maps component in RAD Studio XE8 makes it easy to add mapping functionality to your mobile applications. TMapView provides access to map APIs for iOS and Android. On Android, it uses the Google Maps Android API and on iOS, it uses the Map Kit Framework.
The key features of the TMapView component are:
- Four Types of Maps: Normal, Satellite, Hybrid and Terrain (Android only)
- Gesture Control: Intuitive tilt, rotate and zoom gesture controls
- Control the Map View: Ability to control the map properties such as the map center coordinates, the map orientation and so on
- Custom markers: Ability to add markers to the maps
If you are using TMapView on Android, you will need to obtain a Google Maps API key.
RAD Studio XE8 ships with two maps sample applications for Object Pascal and C++.
Object Pascal:
- C:\Users\Public\Documents\Embarcadero\Studio\16.0\Samples\Object Pascal\Mobile Samples\Device Sensors and Services\Maps
- C:\Users\Public\Documents\Embarcadero\Studio\16.0\Samples\Object Pascal\Mobile Samples\Device Sensors and Services\Map Type Selector
C++:
- C:\Users\Public\Documents\Embarcadero\Studio\16.0\Samples\CPP\Mobile Samples\Device Sensors and Services\Maps
- C:\Users\Public\Documents\Embarcadero\Studio\16.0\Samples\CPP\Mobile Samples\Device Sensors and Services\Map Type Selector
I created a small demo project that uses the Spitcast REST API, REST component framework, FDMemTable and TMapView to display surf locations on my map based on the longitude, latitude and spot name information returned from the REST service. A custom marker graphic in the shape of a surfboard fin is used to indicate the locations on the map.
You can download my demo project here.
Here is a code snippet from the demo project:
procedure TForm26.FormCreate(Sender: TObject); var LongitudeField: TField; LatitudeField: TField; MyLocation: TMapCoordinate; Descr: TMapMarkerDescriptor; SpotName : TField; begin RESTRequest1.Execute; begin LongitudeField := FDMemtable1.FieldByName('longitude'); LatitudeField := FDMemtable1.FieldByName('latitude'); SpotName := FDMemTable1.FieldByName('spot_name'); FDMemTable1.First; while not FDMemTable1.EOF do begin MyLocation := TMapCoordinate.Create(StrToFloat(LatitudeField.AsWideString),StrToFloat(LongitudeField.AsWideString)); MapView1.Location := MyLocation; Descr := TMapMarkerDescriptor.Create(MyLocation, SpotName.AsWideString); Descr.Icon := BitmapSource.Bitmap; BitmapSource.Visible := True; Descr.Draggable := True; MapView1.AddMarker(Descr); MapView1.Zoom := 8; FDMemTable1.Next; end; end; end;
Here is the app running on my iPad:
Here is a quick code snippet on how to clear the markers on the map:
unit Markers; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Generics.Collections, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Maps, FMX.Layouts; type TForm2 = class(TForm) GridPanelLayout1: TGridPanelLayout; MapView1: TMapView; ButtonAdd: TButton; ButtonUndo: TButton; ButtonClear: TButton; ButtonToggle: TButton; procedure ButtonAddClick(Sender: TObject); procedure ButtonUndoClick(Sender: TObject); procedure ButtonClearClick(Sender: TObject); procedure ButtonToggleClick(Sender: TObject); private { Private declarations } FMarkers : TList<TMapMarker>; FShowMarkers: Boolean; procedure CenterMap; public { Public declarations } constructor Create(Owner: TComponent); override; end; var Form2: TForm2; implementation {$R *.fmx} procedure TForm2.ButtonAddClick(Sender: TObject); begin FMarkers.Add(MapView1.AddMarker(TMapMarkerDescriptor.Create(TMapCoordinate.Create((Random(180) - 90) * 0.75, Random(360) - 180), Format(’Marker Placed %d-%d’, [Random(42), Random(54124)])))); CenterMap; end; procedure TForm2.ButtonClearClick(Sender: TObject); var Marker: TMapMarker; begin for Marker in FMarkers do Marker.Remove; FMarkers.Clear; CenterMap; end; procedure TForm2.ButtonToggleClick(Sender: TObject); var Marker: TMapMarker; begin FShowMarkers := not FShowMarkers; for Marker in FMarkers do Marker.SetVisible(FShowMarkers); end; procedure TForm2.ButtonUndoClick(Sender: TObject); begin if FMarkers.Count > 0 then begin FMarkers.Last.Remove; FMarkers.Delete(FMarkers.Count - 1); end; CenterMap; end; procedure TForm2.CenterMap; begin if FMarkers.Count > 0 then MapView1.Location := FMarkers.Last.Descriptor.Position else MapView1.Location := TMapCoordinate.Zero; end; constructor TForm2.Create(Owner: TComponent); begin inherited; FMarkers := TList<TMapMarker>.Create; FShowMarkers := True; end; end.


Comments
-
Jimmie J24836 Monday, 21 November 2016
Hi Sarina!
I realize this is somewhat late, so you might not watch it, but Im giving it a try!
When you click a marker, you see the "title" and the "snippet". As seen in your second picture of California Surf Spots (Point Reyes Beach).
Is there anyway that I can listen to click-events on this "balloon" or "popup" (or whatever you might call it), that contains the title and snippet?
I want a user to be able to click a marker, get a little information about the location, and then, if they choose to, they can click the title to get further information.
See my question here:
https://community.embarcadero.com/answers/my-questions/onmarkertitleclick-event-in-tmapview,-alternatively-custommarker
for full context.
Thanks a bunch in advance! -
Michał J11323 Friday, 6 May 2016
Hello,
I have a question about markers.
When I set marker icon to large bitmap and I add it on the map everything is ok. Now when I "move" map to the position when upper-left corner of the bitmap(marker) is outside of MapView component area, then the marker(my bitmap) disappears. Marker appear if I restore map position. Is there any possibility that markers will be no disappear even if their 'handles' positions are not in current map view?
Or maybe is some solution to set bitmap as background of the polygon?
Thanks,
Michal -
Victor Zepeda Monday, 22 February 2016
Hi! i want to create a marker when the form is created. i write a short code:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TMapCoordinate Coor = TMapCoordinate::Create(19.057959, -98.230856);
TMapMarkerDescriptor myMarker = TMapMarkerDescriptor::Create(Coor,"Test");
MapView1->Location = Coor;
MapView1->Zoom = 18;
MapView1->AddMarker(myMarker);
}
Apparently the code should work, but does not!!!!
I tested the demo project and also doesn´t work!!! -
Raphael C7051 Monday, 6 July 2015
Hello Sarina,
I followed the procedure above, but the Map not appeared, only appeared the Marker.
already I looked the links below:
https://www.youtube.com/watch?v=pmTKOElylA0
http://docwiki.embarcadero.com/RADStudio/XE8/en/Configuring_Android_Applications_to_Use_Google_Maps
http://docwiki.embarcadero.com/RADStudio/XE8/en/Mobile_Tutorial:_Using_a_Map_Component_to_Work_with_Maps_(iOS_and_Android)
I don't what know....
Can you help me?
Att
Raphael Comba Franco -
DzairLogiciel D6467 Tuesday, 16 June 2015
Hi Sarina,
I forgot to give you source code used is below:
DescriptionText_ := 'Lat: '+ FormatFloat('0.00000',Lat) +' , Long: '+
FormatFloat('0.00000',Lgn)+#13#10+' hire first text'
+#13#10+' hire second text'
+#13#10+' hire 3third text....';
MyMarkerDes := TMapMarkerDescriptor.Create(mapCenter, DescriptionText_ );
MyMarker_ := MapView1.AddMarker(MyMarkerDes);
MyMarkerDes.Draggable := True;
MyMarkerDes.Visible := True;
MyMarkerDes.Appearance:= TMarkerAppearance.Billboard;
//MapView1.DoMarkerClick(MyMarker_); -
DzairLogiciel D6467 Tuesday, 16 June 2015
Hi Sarina,
I have a Souci, I ask you for what the carriage return (warped text) does not function in the title marks,
I want to customize the tilte of marker so I can master the carriage return ( warped ) and display a long text using a different font without using an image,
also how I can make this appear marker title without clicking . Is there a function to do display via code.
Thanks in advance -
Sarina D Monday, 15 June 2015
Hi Benjamin,
There is no auto-zoom functionality, but you can use MapView1.Zoom to zoom in on the map or use the gesture controls to allow the user to zoom in.
http://docwiki.embarcadero.com/RADStudio/XE8/en/Mobile_Tutorial:_Using_a_Map_Component_to_Work_with_Maps_%28iOS_and_Android%29
Regards,
Sarina -
Sarina D Wednesday, 10 June 2015
Hi Joko,
If you want to be able to delete a marker by tapping on it, you can handle that just like I did in my code snippet above that I added to my blog post.
If there is no need to track the markers, you can simply handle it like this:
procedure TForm2.MarkerClicked(Marker: TMapMarker); // Handler of TMapView.OnMarkerClick
begin
Marker.DisposeOf;
end;
Regards,
Sarina -
Sarina D Wednesday, 10 June 2015
Hi Alex,
Here is a quick code snippet. It has a button that enables the location sensor and two labels, one for the longitude and one for the latitude. Once the sensor has been activated, it will request permission to access your location.
At that point, your current location will be shown on the map using a custom graphic (you will need to add a TImage to your form with a graphic assigned to it).
procedure TForm2.EnableLocationSensorClick(Sender: TObject);
begin
LocationSensor1.Active := True;
end;
procedure TForm2.LocationSensor1LocationChanged(Sender: TObject;
const OldLocation, NewLocation: TLocationCoord2D);
var
LDecSeparator: String;
MyLocation: TMapCoordinate;
Desqr: TMapMarkerDescriptor;
begin
LDecSeparator := FormatSettings.DecimalSeparator;
FormatSettings.DecimalSeparator := '.';
Lat.Text := Format('%2.6f', [NewLocation.Latitude]);
Long.Text := Format('%2.6f', [NewLocation.Longitude]);
MyLocation := TMapCoordinate.Create(StrToFloat(Lat.Text),StrToFloat(Long.Text));
MapView1.Location := MyLocation;
Desqr := TMapMarkerDescriptor.Create(MyLocation, 'Dropped marker');
Desqr.Icon := BitmapSource.Bitmap; //custom icon to show map location that uses a TImage component
Desqr.Draggable := True;
MapView1.AddMarker(Desqr);
MapView1.Zoom := 8;
end; -
Please login first in order for you to submit comments
Hi, Sarina! Thank You for this great tutorial!
Is it possible to show the marker description directy after creating without need to tap on the marker first?