Composant Delphi / Google Maps / OpenStreetMap / Leaflet  / Mappilary / Native Maps 100% Delphi 0% WebBrowser 0% Javascript


TECNativeMap is available in VCL and Firemonkey (Windows , Mac OS X, iOs and Android) for the same price !

you access an offline mode, not using the Google Maps service and other Bing Maps lets you keep control over your data.

Fig. 2 ECNativeMap on Mac OS X
Fig. 2 ECNativeMap on Mac OS X

TECNativeMap allows you to use OpenStreetMap maps, MapBox, OpenCycleMap, OPNV, TomTom etc.., These maps are also available with TECMap.To select a map provider use the property TileServer

map.TileServer := tsOsm;


By filling in the BingKey property with your Bing key you can use Bing Maps tiles ( tsBingRoad, tsBingAerial and tsBingAerialLabels )

map.BingKey := YOUR_BING_KEY
map.TileServer := tsBingRoad;

Fig. 3 Bing Maps


By filling the HereApiKey propertie You can use the Here tiles ( tsHereNormal, tsHereTerrain, tsHereSatellite, tsHereHybrid, tsHereMobile, tsHereHiRes, tsHereTransit, tsHereTraffic, tsHereFlow, tsHereTruck, tsHereTruckTransparent )

map.HereID := YOUR_HERE_ID
map.HereCode := YOUR_HERE_CODE
map.TileServer := tsHereTraffic;

Fig. 4 Here Traffic


To use the tiles from MapBox ( tsMapBoxSatellite, tsMapBoxStreets,tsMapBoxStreetsSatellite,tsMapBoxStreetsBasic ) enter your token in MapBoxToken.

Fig. 5 MapBoxStreets


tsYandexNormal, tsYandexSatellite et tsYandexHybrid are also usable (thanks alexey t.) and allow you to use tiles of Yandex.

Yandex uses the elliptical Mercator projection that is different from the default projection (spherical Mercator style google maps), this is supported by TECNativeMap so you have nothing to do.

You won't be able to use tsYandexHybrid with a tile base that does not use the same projection !



To use TomTom tiles ( tsTomTomBasic, tsTomTomHybrid, tsTomTomNight, tsTomTomIncident, tsTomTomFlow ) you must obtain a key and fill in the TomTomKey property of your map.

map.TomTomKey := your_tomtom_key
map.TileServer := tsTomTomBasic;

Fig. 6 TomTom Basic

map.TileServer := tsHereSatellite;

// add overlay tiles for TomTom Hybrid

// mandatory, reset api key for overlay
map.TomTomKey := Your_TomTomKey;

Fig. 7 Here Satellite + TomTom Hybrid

For tsTomTomIncident and tsTomTomFlow you have the choice between 4 styles

var oc:TECOverlayTileLayer;
// add overlay tiles for incident
oc := map.AddOverlayTileServer(tsTomTomIncident);

oc.MapStyle := 's1'; // default style
oc.MapStyle := 's2';
oc.MapStyle := 's3';
oc.MapStyle := 'night';

// mandatory, reset api key for overlay
// use your key !
map.TomTomKey := map.TomTomKey;

oc := map.AddOverlayTileServer(tsTomTomflow);

oc.MapStyle := 'absolute'; // default style
oc.MapStyle := 'relative';
oc.MapStyle := 'relative-delay';
oc.MapStyle := 'reduced-sensitivity';

// mandatory, reset api key for overlay
// use your key !
map.TomTomKey := map.TomTomKey;

You can display your map background in grayscale with map.Grayscale := true


Use your own tile server

In addition to the previous maps you can use any other provider using the same format, the example below should not be used in production for legal reasons.

procedure TForm.FormCreate(Sender: TObject);
Map.LocalCache := ExtractFilePath(application.exename) + 'cache';
Map.MaxZoom := 21;
// provider of custom tiles
Map.TileServerInfo.Name := 'GGL-ROAD';
Map.TileServerInfo.GetTileFilename := GetGoogleTile;

procedure TForm.GetGoogleTile(var TileFilename:string;const x,y,z:integer);
TileFilename := format('',[random( 4),x,y,z]);

For licensing questions you cannot directly use the tiles from Google, but you can through the component TECMap .



This property allows you to modify/change certain colors of your tiles.

In VCL mode only the Grey filter is available and you will not be able to keep or replace a color.

map.ColorFilter.filter := fcGrey;
// normal color
map.ColorFilter.filter := fcNone;

With Firemonkey you can use the Light and Dark filters

map.Shapes.CSV.OnCreateCSVPoint := doCSVPoint;

// Data contains the values of each field, you can use it to define your element
procedure TForm.doCSVPoint(const Group: TECShapes; var CSVPoint: TECShape; const Lat, Lng: double; const Data:TStringList) ;
var i:integer;
// if you don't want to import this element return CSVPoint := nil

// The elements will be pois stars
i := Group.Pois.Add(lat,lng);
CSVPoint := Group.Pois[i];
TECShapePOI(CSVPoint).POIShape := poiStar;

You can also define certain colors that will be kept or that you can replace without them being modified by the filter.

Fig. 8 Grey mode with one color kept.

Fig. 9 Gray mode with one color replacement

Fig. 10 Dark mode with color replacement

Overlay tiles

You can use several server of tiles to display above your base map.

var overlay:TECOverlayTileLayer;
// overlay clouds tiles
overlay := map.AddOverlayTiles(GetWeatherTile);
// set name for directory
overlay.Name := 'OpenWeatherMap_Clouds';
// you can also use this syntax
overlay := map.AddOverlayTiles(GetWeatherTile,'OpenWeatherMap_Clouds');

// remove overlay


procedure TForm.GetWeatherTile(var TileFilename:string;const x,y,z:integer);
TileFilename := format('',[Char(Ord( 'a') + random(3)),z,x,y]);

Fig. 11 Overlay of clouds

You can still use a stream.

procedure TForm.getOverlayTileStream(var TileStream: TMemoryStream;const x, y, z: integer);
// here fill the stream with your tile



Or directly using a transparent predefined server as tsHereFlow or tsHereTruckTransparent

// mix Bing Aerial Labels and Here Flow
map.TileServer := tsBingAerialLabels;

With VCL your overlay should use pngs, under FMX you can use the opacity property.


var overlay:TECOverlayTileLayer;
// overlay clouds tiles
overlay := map.AddOverlayTiles(GetWeatherTile);

// set opacity 0..1
overlay.opacity := 0.5;

Use RemoveAllOverlayTiles to delete all overlays

You can also embed an image if it is to scale


Positioning on the map

You can determine the coordinates of the center of the map through the Latitude and Longitude properties, they are of type double and accessible in read/write

You can directly modify the coordinates through the procedure setCenter(const dlatitude,dlongitude:double)

// Delphi map component ECMap
var lat,lng:double;
// get center of map
lat := map.Latitude;
lng := map.Longitude;
// move center of map


Mouse position

The latitude and longitude of the point under the mouse cursor are returned by the property MouseLatLng

You can connect on the event OnMapMouseMove to know in time real your positionRéagir au changement de position

When the center of the map is moved, This either by code or the mouse directly, the event OnMapMove(sender: Tobject;const dLatitude,dLongitude:double) is raised

Sender represents the ECNativeMap component that has changed, dLatitude and dLongitude the new coordinates, who are also accessible through Latitude and Longitude

When the map starts to move the event OnMapDragStart is raised, then OnMapDrag while the move and OnMapDragEnd at the end of displacement.

Area displayed

You can determine the coordinates of North East point (top-right) and point South West (lower-left) of the displayed area by the component through the properties NorthEastLatitude, NorthEastLongitude, SouthWestLatitude and SouthWestLongitude, they are double and accessible read-only.

The procedure BoundingBox(maxLatitude,maxLongitude,minLatitude,minLatitude) limit the accessible area of your map, the event OnOutOfBounds is raised if you attempt to access a restricted area.

A call to BoundinBox without parameter throws limitations.


The procedure fitBounds(const dLatlo,dLnglo,dLathi,dLnghi:double) allows you to adjust the view to the coordinates passed.

the procedure boundingCoordinates(const lat, lng, radius: double; var latSW, lngSW,latNE, lngNE: double); Returns the coordinates of a rectangular area on the basis of the focal point and a distance in km.

The function ContainsLatLng(var dLatitude,dLongitude:double):boolean tells you if the dLatitude, dLongitude is in the visible portion of the map.

As soon as the view changes the event OnChangeMapBounds(sender: TObject) is raised.

The function ScreenShot Returns an integer containing the image of the map


The Zoom property allows you to control the definition of your card, it is of type integer and is accessible in read/write

You have access also to the MaxZoom and property MinZoom that allow you to determine the limits of the zoom


Use the ZoomAround(const LatLngZoom:TLatLng; const NewZoom:Integer) procedure to zoom while remaining focused on a specific point (as in mouse)

The zoom change triggers the event OnChangeMapZoom(sender: TObject)

By setting the DragRect property on drZoom you can select an area with the mouse by holding the right button, when you release the button zoom is performed on the selected region.


This property allows you to emulate the intermediate zooms

// emulate zoom 16.35

map.zoom := 16;
map.zoomScaleFactor := 35;

Make right Click + scroll wheel to change ZoomScaleFactor


Fig. 12 ZoomScaleFactor

You can zoom in progressively from zoom 1 to beyond the maximum zoom provided by the tile server, simply by incrementing zoomScaleFactor, and vice versa to zoom out.

Fig. 13 Progressive zoom

ZoomScaleFactor can vary from -999 to 999, if the maximum zoom is not reached 100 corresponds to zoom+1 (and conversely)


Use the procedure ZoomScaleFactorAround (const LatLngZoom:TLatLng; const NewZoomScaleFactor:Integer) to zoom while remaining focused on a specific point (as with mouse)

The NumericalZoom property groups Zoom and ZoomScaleFactor

map.NumericalZoom := 15.6;

Adapt the markers to the Zoom

Use the ScaleMarkerToZoom property to resize markers depending of Zoom.

Fig. 14 ScaleMarkerToZoom


The Selected property allows you to select items.

// select items in area
nbr_item_selected := map.Selected.ByArea(NorthEastLat,NorthEastLng,SouthWestLat,SouthWestLng);

// select items <=Max_Distance_KM to CenterPointLat,CenterPointLng
nbr_item_selected := map.Selected.ByKMDistance(CenterPointLat,CenterPointLng,Max_Distance_KM);

// loop to all selected items

var shape:TECShape

for shape in map.Selected do

By setting DragRect to drSelect you can make a selection with the mouse by holding the right button and release once the area is delimited.

You can redefine the appearance of the selection rectangle using styles, example to have a line of 10 pixels width, green color, and a dotted line

map.styles.addRule('#_DRAGZOOM_.line {weight:10;color:green;penStyle:dash}');

Fig. 15 stylized selection

To deselect all your items use map.Selected.UnSelectedAll

The GroupFilter list allows to define a filter on the groups allowed

// only elements from these groups will be accepted
// clear list for accept all

You can define your own filter by connecting you on OnSelectShape.

map.Selected.OnSelectShape := doOnSelectShape;
procedure TForm.doOnSelectShape(Sender: TObject; const Shape: TECShape;
var cancel: Boolean);

// accept only TECShapePOI
cancel := not(Shape is TECShapePOI);

Selected items are drawn using the color HoverColor, you can add a distinguishing mark by connecting you on their OnAfterDraw event.

This example adds a red star in the upper right corner of selected items

// when you create item you must connect like this item.OnAfterDraw := doAfterDraw

procedure TForm1.doAfterDraw(const canvas: TECCanvas; var rect: TRect; item: TECShape) ;
var size_start : integer;
if assigned(item) and (item.Selected) then
size_start := (item.Width div 2);
if size_start< 10 then size_start := 10;

canvas.Pen.Color := claBlack;
canvas.Brush.Color := GetHighlightColorBy(claRed,16);

rect.Left := rect.Left + (rect.Right-rect.Left) - size_start;
rect.Top := rect.Top - (size_start div 2);
rect.Bottom := rect.Top + size_start ;


Fig. 16 3 selected items

Or simply you can set a style.

// all shapes selected is red
map.styles.addRule(':selected {color:red}');
// enlarge the selected markers
map.styles.addRule('.marker:selected {scale:1.2}');

Map rotation

Available only in the version Firemonkey

Put your component into a container (TPanel, TRectangle) which will be used to define the visible region and activate property OverSizeForRotation

map.OverSizeForRotation := true;

// To allow or not the rotation gesture use the property EnableTouchRotation

map.EnableTouchRotation := true;

EnableTouchRotation Enable rotation by gesture.


Fig. 17 Rotation map


The Url property returns / accepts a string in the format '#zoom/Latitude/Longitude'

// zoom 18 latitude 48.856527 longitude 2.352104
// welcome to Paris !
map.Url := '#18/48.856527/2.352104';

Assigning a value to this property raises the event OnBeforeUrl(sender : TObject; var Url:string) that can allow you to change the url, and even to cancel the change by returning an empty string.

You can pass a such link in a InfoWindow

// welcome to Paris !
map.Shapes.InfoWindows[0].Content := 'Go to <a href="#18/48.856527/2.352104">Paris !</a>';

Fig. 18 Url Link

If you pass a 'classical' url it will open in your default browser.



The function DistanceFrom(const dLatitudeStart,dLongitudeStart,dLatitudeEnd,dLongitudeEnd:double):double to calculate the distance between 2 points, the result is in kilometers.

Angle to the North

The function Bearing(const dLatitudeStart,dLongitudeStart,dLatitudeEnd,dLongitudeEnd:double):integer gives you the angle, from 0 ° to 360 ° for direction from the point dLatitudeStart,dLongitudeStart to the point dLatitudeEnd,dLongitudeEnd


Fig. 19 MiniMap

To display a mini map in your main card simply add the uecNativeMiniMap unit to your listing and add the following lines.

// Delphi native map component TECNativeMap

var FMiniMap : TECNativeMiniMap;
// create and show minimap on Map
FMiniMap := TECNativeMiniMap.create(Map);

// for hide minimap
FMiniMap.Map := nil;

// for show
FMiniMap.Map := Map;

You do not have to release your minimap, It will be automatically during the destruction of the card to which it is attached.


You can change the corner of anchor with the property ancragePosition (apTopLeft, apTopRight, apBottomLeft, apBottomRight )

XMargin and YMargin allow you to adjust the position relative to the edges

BorderColor and BorderSize changes the color and size of the border surrounding the mini map.

Screenshot allows you to get an image of your miniMap, you will have to release it yourself!

Scale bar

To display the scale you need to add the uecNativeScaleMap unit and the following lines.

procedure TForm1.FormCreate(Sender: TObject);

FECNativeScaleMap := TECNativeScaleMap.create ;
FECNativeScaleMap.Map := map;


procedure TForm1.FormDestroy(Sender: TObject);


Fig. 20 Scale bar

The following properties are available :

AnchorPosition (apTopLeft, apTopRight, apBottomLeft, apBottomRight )

XMargin and YMargin to adjust from the corners

BarSize fineness of the bar (default 2)

Color color (default black)

MaxWidth maximum length of bar in pixels (default 80)

MesureSystem measurement system (msMetric, msImperial) defaut msMetric

Shadow Adds a shadow (defaut true)

Measurement tool

You can use a measuring tool by adding the uecNativeMeasureMap unit and lines

procedure TForm1.FormCreate(Sender: TObject);

FECNativeMeasureMap := TECNativeMeasureMap.create ;
FECNativeMeasureMap.Map := map;



procedure TForm1.FormDestroy(Sender: TObject);


Fig. 21 Measurement tool

The following properties are available :

Color line color default black

MeasureSystem unit of measure (msMetric, msImperial) default msMetric

Distance : double the distance in the selected unit
DistanceLabel : string the distance in text (the one that appears on the screen)

ShowDistance allows to show or not the distance on the screen (default true)

Hint the text of information when leaving the mouse on the line

OnChange : TNotifyEvent raised when the distance changes


An observer allows you to be notified when events is fired in map or in shape.

This has the advantage of not to block the main events of the map and the shapes.

TNativeMapObserver = class(TObject)

property OnMapFree : TNotifyEvent ;
property OnMapHiResChange : TNotifyEvent ;
property OnMapActiveChange : TNotifyEvent
property OnMapAnimation : TNotifyEvent;
property OnMapResize : TNotifyEvent;
property OnMapRotation : TNotifyEvent;
property OnMapMove : TNotifyEvent;
property OnMapMouseMove : TNotifyEvent;
property OnMapMouseClick : TNotifyEvent;
property OnMapEndMove : TNotifyEvent;
property OnMapzoom : TNotifyEvent;
property OnMapLoad : TNotifyEvent;
property OnMapBounds : TNotifyEvent;
property OnMapChangeBounds : TNotifyEvent;
property OnMapTileServer : TNotifyEvent;
property OnMapAddRoute : TNotifyEvent;
property OnMapErrorRoute : TNotifyEvent;
property OnMapChangeRoute : TNotifyEvent;
property OnMapPaint : TNotifyEvent;
property OnShapesPaint : TNotifyEvent;
property OnMapShapeDescription : TNotifyEvent;
property OnMapShapeProperties : TNotifyEvent;
property OnMapShapeHint : TNotifyEvent;
property OnMapShapeClick : TNotifyEvent;
property OnMapShapeMove : TNotifyEvent;
property OnMapShapeDblClick : TNotifyEvent;
property OnMapShapeMouseOut : TNotifyEvent;
property OnMapShapeMouseOver : TNotifyEvent;
property OnMapShapeDrag : TNotifyEvent;
property OnMapShapeDragEnd : TNotifyEvent;
property OnMapShapePathChange : TNotifyEvent;
property OnMapShapeRightClick : TNotifyEvent;
property OnMapShapesChange : TNotifyEvent;

You can add as many observers as you want.

FObserver1 := TNativeMapObserver.Create;
FObserver1.OnMapResize := Map_Resize;
FObserver1.OnMapMove := Map_Move;

FObserver2 := TNativeMapObserver.Create;
FObserver2.OnMapBounds := Map_Bounds;
FObserver2.OnMapTileServer := Map_TileServer;
FObserver2.OnMapRotation := Map_Rotate;

// attach observer
// detach

The layers using observers to react to the change of position.

go to page
© 2016 ESCOT-SEP Christophe - Made width Help&Web - RSS - Google+