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

Location

you are here :TECMap

API Keys

TECNativeMap uses OpenStreetMap.

If you want to use these services of PTV or TomTom or MapBox you must register on their site to obtain a user key .

Offline mode

If you specify a directory in the LocalCache property, all your geolocation data will be cached and can be reused in offline mode.

Address format

You benefit from the services of geolocation via the property GeoLocalise de type TECGelocalise

The Address property gives you the address of the center of the map, it is of type string and is accessible in read/write

TECGeolocalise uses the services of OpenStreetMap and OpenMapQuest

You can also use ArcGis through functions
function TECGeolocalise.ArcGisReverse(const Lat,Lng:double):string;
function TECGeolocalise.ArcGisFind(const data:string;var Lat,Lng:double):boolean;

Geolocalisation

To obtain the address of a specific you have the function GetAddressFromLatLng(const dLatitude,dLongitude:double):string;

You can get the various parts of the address by using the property TECGeolocalise.ReverseResults:TStringList

adr := map.GetAddressFromLatLng(Latitude,Longitude) ;

// now ReverseResults contains tags in nominatim <addressparts>
// see https://nominatim.org/release-docs/latest/api/Reverse/

country := map.Geolocalise.ReverseResults.values['country'];
road := map.Geolocalise.ReverseResults.values['road'];
postcode:= map.Geolocalise.ReverseResults.values['postcode'];
...

You can get the coordinates of an address with the function GetLatLngFromAddress(const sAddress:string;var dLatitude,dLongitude:double):boolean;

By assigning a value to the property Address you will change the position of the center of your map to match to the address

Places

TECGeolocalise allows you to search specific locations in a data area, for example to find restaurants within a radius of 500 metres.

It is Overpass-api that uses data from OpenStreetMap which is used

The property TECGeolocalise.Places.XapiServer allows you to use another server Xapi than MapQuest

// Delphi map component ECMap
// use overpass-api.de

map.GeoLocalise.Places.XapiServer := 'http://www.overpass-api.de/api/xapi?';
procedure Search( Tags:string);

Launch a search, tags contains the query

Documentation Xapi

adr := map.GetAddressFromLatLng(Latitude,Longitude) ;

// now ReverseResults contains tags in nominatim <addressparts>
// see https://nominatim.org/release-docs/latest/api/Reverse/

country := map.Geolocalise.ReverseResults.values['country'];
road := map.Geolocalise.ReverseResults.values['road'];
postcode:= map.Geolocalise.ReverseResults.values['postcode'];
...

When the search is complete, the Geolocalise.OnSearch event is raised

Each launch of Search clears the results of a previous search

1
property Adress : string read FAdress write FAdress;
Property read/write indicating the focal point of the search box, it takes precedence over the properties Latitude et Longitude
property Status : string;

Property read-only that returns a string indicating the status of the search, 'OK' if all went well

The status is available in the event GeoLocalise.OnSearch

property ItemDetail : integer;
Property read-only that contains the index of the result which is more details
property Latitude : double;
Property read/write that indicates the latitude of the central point of the area of research, this invalid the contents of the property Address
property Longitude: double;
Property read/write indicating the longitude of the central point of the area of research, this invalid the contents of the property Address
property Radius : integer;
Property read/write that indicates the radius of search in metres
property maxResult : integer;
limits the number of results for a search in the OpenStreetMap data
property Searching: boolean;
Propriété en lecture seule qui indique si une recherche est en cours
property Results:TECPlaceResults;
Results list, the OnPlacesSearch event is raised when the results are available

TECPlacesResults

This class manages the list of the results returned by Search

procedure Clear;
Clears all the results
function Count:integer;
Returns the number of result for the query
procedure Delete(const index:integer);
Clears the result which we pass the index
property Result[index:integer]:TECPlaceResult
Table allowing access to results

TECPlaceResult

Class handling a result corresponding to a search

property Result[const key:string]:string;
Returns the value of the key that is passes as a parameter
property Detail[const Key:string]:string;
Returns the value of the key that is passes as a parameter for details
property NameResult[const index:integer]:string;
Returns the key of a result based on its index
property NameDetail[const index:integer]:string;
Returns the key of a detail based on its index
property CountResult:integer;
Returns the number of result element (key = value)
property CountDetail:integer read getCountDetail;
Returns the number of a detail element (key = value)
property Latitude : double;
Latitude of the result
property Longitude: double;
Longitude of the result
property RawResult : string;
Returns the set of the result elements in the form of a string of rows key = value
property RawDetail : string;
Returns the set of elements of the detail in the form of a string of rows key = value

DemonativeLocalise

the DemoNativeLocalise program shows you how to manage Places

Fig. 1 DemoLocalise
Fig. 1 DemoLocalise

Geofences

Geofence is a virtual area that triggers an alert when you enter or exit.

function Add(const Lat,Lng:double;const RadiusMeter:integer;const Name:string=''):integer;overload;

Adds a circular area defined by its center point and RADIUS in meters.

map.geofences.add(43.231572,0.080853,50);
function Add(const dLatLngs: array of double;const Name:string=''):integer;overload;

Adds a polygonal area defined by an array containing the various points

map.geofences.add([lat1,lng1,lat2,lng2,lat3,lng3],"triangle");
function Add(const Polygone:TECShapePolygone;const Name:string=''):integer;overload;

Adds a polygonal area defined by a polygon

map.geofences.add(map.shapes.polygones[0]);
function Add(const Line:TECShapeLine;const Name:string=''):integer;overload;

Adds a area defined by a line

map.geofences.add(map.shapes.lines[0]);
procedure Delete(index:integer);
Delete a geofence
function Count:integer;
Returns the number of geofences
function IndexOf(value:TECBaseGeofence):integer;
Returns the index of the geofence
procedure Clear;
Clears all the geofences
property Active : boolean ;
Activate or not the geofences detection
property toTxt:string ;

Import / export geofences in text format

By default, when you Save the map in text format the geofences are saved and can be recharged

property Geofence[index : integer]:TECBaseGeofence ;
Returns a geofence

TECBaseGeofence

property TECBaseGeofence.Name:string ;
Name of the geofence
property TECBaseGeofence.Active : boolean
Activate or not the geofence (enabled by default)
property TECBaseGeofence.ActiveDuration : integer

Maximum activation time (milliseconds) (default 0 infinite)

// Activate for 3 seconds
map.geofences.geofence[0].ActiveDuration := 3000;
property Color : TColor ;
Color of the area
property HoverColor : TColor ;
Color of the area when mouseover
property Item : TObject;
You can use this property to store your data
property Tag : integer;
You can use this property to store your data
property TECBaseGeofence.Shapes : TECShapesList
The list of items that are currently in the geofence

TECCirclegeoFence

property RadiusMeter : integer
Radius of the circle in meters

TECLineGeoFence

property MargingMeter : integer
Tolerance in meters to determine if an element enters or leaves the line

Évenements Geofences

To respond connect you on OnEnterGeofence and OnLeaveGeofence of TECNativeMap events.

...
map.OnEnterGeofence := mapEnterGeofence;
map.OnLeaveGeofence := mapLeaveGeofence;
...
procedure TForm1.mapEnterGeofence(sender: TObject; const Geofence: TECBaseGeofence; const item: TECShape);
begin
caption := 'item '+inttostr(item.id)+' enter in '+Geofence.Name;
end;

procedure TForm1.mapLeaveGeofence(sender: TObject; const Geofence: TECBaseGeofence; const item: TECShape);
begin
caption := 'item '+inttostr(item.id)+' leave '+Geofence.Name;
end;

The detection is done when a shape is moved, the test is performed on location (latitude and longitude) not on the actual surface of the object.

Fig. 2 Demo Geofences

Boundary

Boundary allows you to obtain the polygons, polylines and data of an area just by indicating a geographical point or an address..

function Address(value:string; const limit:integer=1):integer

Find the geometry of the address

Limit sets the maximum number of results

Returns the number of elements

var line:TECShapeLine;
poly:TECShapePolygone;
...
for i := 0 to map.Boundary.Address('Paris') - 1 do
begin
poly := nil;
line := nil;

if (map.Boundary.Items[i] is TECShapePolygone) then
poly := TECShapePolygone(map.Boundary.Items[i])
else if (map.Boundary.Items[i] is TECShapeLine) then
line := TECShapeLine(map.Boundary.Items[i]);

if assigned(poly) then
poly.Hint := poly.PropertyValue['display_name'];
else if assigned(line) then
line.Hint := line.PropertyValue['display_name'];

end;

map.Boundary.FitBounds;

AddLineFromAddress et AddPolygoneFromAddress utilisent en interne Address avec la limite maximale de résultats

1
var line : TECShapeLine;
poly : TECShapePolygone;
first_item:integer;
...
// use default group
first_item := map.shapes.lines.count;
line := map.AddLineFromAddress('avenue des champs-élysées, paris');
// line is the last find,total is (line.indexof - first_item + 1)
if assigned(line) then
line.fitBounds;

map['polyAddress'].clear;
poly := map.AddPolygoneFromAddress('parking, tarbes','polyAddress');
if assigned(poly) then
map['polyAddress'].fitBounds;

function Administrative(const lat,lng:double;Level:integer=0):integer;

Finds the administrative area whose level is crossed (from 2 to 10), indicating 0 the level is determined according to the zoom

Returns the number of elements

map.boundary.Administrative(43.2332,0.0736,8); // Level 8 = town
map.boundary.Administrative(43.2332,0.0736); // Level in function of zoom
property AdminLevelFromZoom:string

Allows to control the administrative level according to the zoom level

Default :

Zoom 0 - 4 = Level 2

Zoom 5 - 8 = Level 4

Zoom 9 - 11 = Level 6

Zoom 12 - 24 = Level 8

// only Level 4 et 8
map.Boundary.AdminLevelFromZoom := '0-8=4,9-24=8';

// Pass an empty string to reset to default values
map.Boundary.AdminLevelFromZoom := '';
function Filter(const lat,lng:double;const AreaFilter:string):integer;

Generic function that allows you to define the area to be found.

Returns the number of elements

// like administrative level 8
map.boundary.Filter(43.2332,0.0736,'"admin_level"="8"');
property Items: TECShapesList
List of items (TECShapePolyone and TECShapeLine) found by the Address, Administrative and Filter functions
procedure FitBounds

Zooms in on the map to display the set of items contained in Items

for i := 0 to map.Boundary.Address(Address.Text)-1 do
begin
poly := nil;
line := nil;

if (map.Boundary.Items[i] is TECShapePolygone) then
poly := TECShapePolygone(map.Boundary.Items[i])
else
if (map.Boundary.Items[i] is TECShapeLine) then
line := TECShapeLine(map.Boundary.Items[i]) ;

if assigned(poly) then
begin
Poly.FillColor := GetHashColor(Address.Text);
Poly.FillOpacity := 10;
Poly.Opacity := 100;
Poly.PenStyle := psDash;
Poly.BorderColor := Poly.FillColor;
Poly.BorderSize := 4;
end;

if assigned(line) then
begin
line.Color := GetHashColor(Address.Text);
line.Opacity := 100;
line.PenStyle := psDash;
line.weight := 4;
end;
end;

map.Boundary.fitBounds;

Fig. 3 Geographic boundary of an address

property Id:int64;

ID OSM of the found area


property Tags:TStringlist

Contains the list of tags OSM of the area, in the form key = value


property OverPassUrl:string;

OverPass is used to find the area ( by default https://overpass-api.de/api/interpreter )


For the polygon from the id of the area, it connects to polygons.openstreetmap.fr

To change that assign a procedure to GetPolygoneFromID

// set nil for use polygons.openstreetmap.fr
map.Boudary.GetPolygoneFromID := myGetPoygonFromId;

procedure TForm.myGetPoygonFromId(const id:int64;var JSON:string);
begin

// here retourne yours polygons in json format

JSON := ...
end;

See DemoNativeBoundaryArea for a demo

Fig. 4 DemoNativeBoundaryArea

GeoHash

Geohash is a public domain geocoding system invented by Gustavo Niemeyer,which encodes a geographic location into a short string of letters and digits..

More information on wikipedia.

procedure TNativeMapControl.GeoHash.Decode(const geohash: string; var latitude, longitude: double);

var lat,lng : double;

map.geoHash.Decode('9xj5smj4w40m',lat,lng);

function TNativeMapControl.GeoHash.Encode(const latitude, longitude: double;const precision:Integer=12): string

// return the geoHash for the center of map
s := map.geoHash.encode(map.latitude,map.longitude);

function TNativeMapControl.GeoHash.CardinalPoints(const geohash:string):TCardinalGeoHash;

// get geoHashs located at the 8 cardinal points around a geoHash

var cgh : TCardinalGeoHash;

cgh := map.geoHash.CardinalPoints('9xj5smj4w40m');

cgh.North;
cgh.NorthEast;
cgh.East;
cgh.SouthEast;
cgh.South;
cgh.SouthWest;
cgh.West;
cgh.NorthWest;

procedure TNativeMapControl.GeoHash.MoveTo(const geohash:string);

map.GeoHash.Moveto('9xj5smj4w40m');

Open Location Code

Open Location Code (OLC) is a system of geocoding identifying an area anywhere on the Earth. It was developed at Google's Zurich Office.

More information on wikipedia.

function TNativeMapControl.OpenLocationCode.Encode(const latitude,longitude : Double;const codeLength:Integer=10):string;

// Provides a normal precision code, approximately 14x14 meters.
olc := map.OpenLocationCode.encode(lat,lng);

// Provides an extra precision code, approximately 2x3 meters.
olc := map.OpenLocationCode.encode(lat,lng,11);

function TNativeMapControl.OpenLocationCode.Decode(const code:string):TecOLC_CODEAREA;

var olcArea : TecOLC_CODEAREA;

olcArea := map.OpenLocationCode.Decode('8FM263JF+PM');

olcArea.latitudeLo;
olcArea.longitudeLo;
olcArea.latitudeHi;
olcArea.longitudeHi;
olcArea.latitudeCenter;
olcArea.longitudeCenter;
olcArea.codeLength;

// zoom to the area
map.fitbounds(olcArea)
// draw polygone
map.AddPolygone(olcArea);

procedure TNativeMapControl.OpenLocationCode.MoveTo(const OpenLocationCode:string);

map.OpenLocationCode.MoveTo('8FM263JF+PM');

In the uecOpenLocationCode.pas unit you will find a class to use OpenLocationCode regardless of TECNativeMap, this is my translation of the openlocationcode.js of Google

2

QTH Locator

Maidenhead Locator System, (a.k.a. QTH Locator and IARU Locator) is a geocode system used by amateur radio operators to succinctly describe their geographic coordinates.

The encoding uses a series of pairs of letters and numbers. The first sign of a pair concerns the longitude, the second the latitude.

var lat,lng:double;
QTH:string;
...
map.QTHLocatorToLatlng('JN03AF85UX',lat,lng);
// return locator with 5 pairs
QTH := map.LatLngToQTHLocator(Map.MouseLatLng.Lat,FMap.MouseLatLng.Lng);

Altitude

The elements have an Altitude property that returns an altitude in meters.

An internet connection is required, if you use a cache, the altitude will be written there.

SIf you move the element a new query will be performed the next time Altitude is accessed, otherwise the old value is returned.

By default it is opentopodata that is used with the mapzen dataset, 2 other services can be used instead.

map.GeoLocalise.ApiAltitude := altOpenTopoData;
map.GeoLocalise.ApiAltitude := altOpenElevation;
// For mapquest you must provide your own key in map.MapQuestKey = 'your_key'.
map.GeoLocalise.ApiAltitude := altMapQuest;

You can also define your own service.


map.GeoLocalise.ApiAltitude := altCustom;
// get 1 point
map.GeoLocalise.OnGetAltitude := your_getAltitude;
// get n points
map.GeoLocalise.OnGetAltitudes := your_getAltitudes;

procedure your_getAltitude(const LocalCache:string;const Latitude,Longitude:double;var altitude:double);
begin
// put result in altitude
end;

procedure your_getAltitudes(const LocalCache:string;const sLatLngs: string;var altitudes:string);
begin
// sLatLngs = lat1,lng1,lat2,lng2...
// put results in altitudes ( '310,120,158' )
end;
go to page
Réalisé avec la version gratuite pour les particuliers d'Help&Web