Clefs pour les API
Par défaut TECNativeMap utilise les services d'OpenStreetMap.
Si vous souhaitez utiliser PTV, TomTom ou MapBox vous devez vous enregistrer sur leur site pour obtenir une clef.
Mode hors-ligne
Si vous indiquez un répertoire dans la propriété LocalCache, toutes vos données de géolocalisation seront mise en cache et pourront être réutilisées en mode hors-ligne.
Format de l'adresse
vous bénéficiez des services de géolocalisation au travers de la propriété GeoLocalise de type TECGelocalise
La propriété Address vous donne l'adresse du centre de la carte, elle est de type string et est accessible en lecture/écriture
Pour rechercher une adresse vous pouvez utiliser un format libre du genre "adresse,ville, code postal".
TECGeolocalise utilise les services d'OpenStreetMap et d'OpenMapQuest
Vous pouvez aussi utiliser ArcGis au travers des fonctionsfunction TECGeolocalise.ArcGisFind(const data:string;var Lat,Lng:double):boolean;
Geolocalisation
Pour obtenir l'adresse d'un point précis vous avez la fonction GetAddressFromLatLng(const dLatitude,dLongitude:double):string;
Vous pouvez obtenir les diverses parties de l'adresse en utilisant la propriété TECGeolocalise.ReverseResults:TStringList
// 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'];
...
Vous pouvez obtenir les coordonnées d'une adresse avec la fonction GetLatLngFromAddress(const sAddress:string;var dLatitude,dLongitude:double):boolean;
En attribuant une valeur à la propriété Address vous allez changer la position du centre de votre carte pour la faire correspondre à l'adresse indiquée
Places
TECGeolocalise vous permet d'effectuer des recherches sur des lieux spécifiques dans une zone données, par exemple trouver des restaurants dans un rayon de 500 mètres.
C'est Overpass-api qui utilise les données d'OpenStreetMap qui est utilisé
La propriété TECGeolocalise.Places.XapiServer vous permet d'utiliser un autre serveur Xapi que celui de MapQuest
// use overpass-api.de
map.GeoLocalise.Places.XapiServer := 'http://www.overpass-api.de/api/xapi?';
Lancement d'une recherche, tags contient la requête
//
Delphi map component ECMap
Map.geolocalise.OnSearch := mapPlacesSearch;
Map.GeoLocalise.Places.latitude :=
map.latitude;
Map.GeoLocalise.Places.longitude :=
map.longitude;
Tags := 'node[amenity=restaurant]';
// 500 meters
Map.GEoLocalise.Places.radius := 500;
Map.GEoLocalise.Places.Search(Tags);
...
procedure
TForm.mapPlacesSearch(sender: TObject);
var
i, max: Integer;
types, names: string;
begin
if
map.GEoLocalise.Places.Status <> 'OK' then
exit;
max := map.GEoLocalise.Places.results.count -
1;
for i := 0 to max do
begin
types :=
map.GEoLocalise.Places.results[i].result['types'];
names :=
map.GEoLocalise.Places.results[i].result['name'];
end;
end;
Lorsque la recherche est terminée, l'évènement Geolocalise.OnSearch est déclenché
Chaque lancement de Search efface les résultats d'une précédente recherche
1Propriété en lecture seule qui retourne une string indiquant le status de la recherche, 'OK' si tout c'est bien passé
Le status est consultable dans l'évènement OnPlacesSearch
TECPlacesResults
Cette classe gère la liste des resultats retournés par Search
TECPlaceResult
Classe gérant un résultat correspondant à une recherche
Effectue une requête supplémentaire sur le résultat pour obtenir des détails
Lorsque les détails sont disponibles l'évènement OnPlacesDetail est déclenché.
DemonNativeLocalise
le programme DemoNativeLocalise vous montre comment gérer Places
Geofences
Geofence désigne une zone virtuelle qui déclenche une alerte lorsqu'on y entre ou qu'on en sort.
Ajoute une zone circulaire définie par son point central et son rayon en mètres.
Ajoute une zone polygonale définie par un tableau contenant les divers points
Ajoute une zone polygonale définie à partir d'un polygone
Ajoute une zone définie à partir d'une ligne
Importer / exporter les geofences sous forme textuelle
Par défaut lorsque vous sauvegardez la carte dans le format texte les geofences sont enregistrés et peuvent être rechargés
TECBaseGeofence
Temps maximal d'activation (millisecondes) 0 pour un temps infini (0 par défaut)
map.geofences.geofence[0].ActiveDuration := 3000;
TECCirclegeoFence
property RadiusMeter : integerTECLineGeoFence
property MargingMeter : integerÉvénements Geofences
Pour réagir branchez-vous sur les événements OnEnterGeofence et OnLeaveGeofence de TECNativeMap.
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;
La détection se fait lorsqu'un shape est déplacé, le test est effectué sur le point de localisation (sa latitude et sa longitude) pas sur la surface réelle de l'objet.
Boundary
Boundary permet d'obtenir les polygones, les polylines et les données d'une zone juste en indiquant un point géographique ou une adresse.
function Address(value:string;const limit: integer = 1):integerTrouve la géométrie de l'adresse
Limit permet de spécifier le nombre maximal de résultats
Retourne le nombre d'éléments
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
1poly : 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;
Trouve la zone administrative dont on passe le niveau (de 2 à 10), en indiquant 0 le niveau est déterminé en fonction du zoom
Retourne le nombre d'éléments trouvés
map.boundary.Administrative(43.2332,0.0736); // Level in function of zoom
Permet de controler le niveau administratif en fonction du zoom
Par défaut :
Zoom 0 - 4 = Level 2
Zoom 5 - 8 = Level 4
Zoom 9 - 11 = Level 6
Zoom 12 - 24 = Level 8
map.Boundary.AdminLevelFromZoom := '0-8=4,9-24=8';
// Pass an empty string to reset to default values
map.Boundary.AdminLevelFromZoom := '';
Fonction générique qui vous permet de définir la zone a trouver.
Retourne le nombre d'éléments trouvés
map.boundary.Filter(43.2332,0.0736,'"admin_level"="8"');
Zoome sur la carte pour afficher l'ensembles des éléments contenu dans Items
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;
property Id:int64;
Id OSM de la zone trouvée
property Tags:TStringlist
Contient la liste des tags OSM de la zone, sous la forme key=value
property OverPassUrl:string;
OverPass est utilisé pour trouver la zone ( par défaut https://overpass-api.de/api/interpreter )
Pour obtenir le polygone à partir de l'id de la zone, on se connecte à polygons.openstreetmap.fr
Pour modifier cela assignez une procedure à GetPolygoneFromID
map.Boudary.GetPolygoneFromID := myGetPoygonFromId;
procedure TForm.myGetPoygonFromId(const id:int64;var JSON:string);
begin
// here retourne yours polygons in json format
JSON := ...
end;
Consultez DemoNativeBoundaryArea pour une démo
GeoHash
Geohash est un système de géocodage du domaine public inventé par Gustavo Niemeyer, qui code un emplacement géographique en une courte chaîne de lettres et de chiffres.
Plus d'informations sur wikipedia.
procedure TNativeMapControl.GeoHash.Decode(const geohash: string; var latitude, longitude: double);
map.geoHash.Decode('9xj5smj4w40m',lat,lng);
function TNativeMapControl.GeoHash.Encode(const latitude, longitude: double;const precision:Integer=12): string
s := map.geoHash.encode(map.latitude,map.longitude);
function TNativeMapControl.GeoHash.CardinalPoints(const geohash:string):TCardinalGeoHash;
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);
Open Location Code
L'Open Location Code (OLC) est un système de géocodage permettant d'identifier une zone n'importe où sur la Terre. Il a été développé au bureau d'études Google de Zurich.
Plus d'information sur wikipedia.
function TNativeMapControl.OpenLocationCode.Encode(const latitude,longitude : Double;const codeLength:Integer=10):string;
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;
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);
Dans l'unité uecOpenLocationCode.pas vous trouverez une classe pour utiliser OpenLocationCode indépendamment de TECNativeMap, c'est ma traduction du javascript openlocationcode.js de Google
2QTH Locator
Maidenhead Locator System, souvent abrégé en Locator, est un système de localisation utilisé par les radioamateurs.
L'encodage utilise une série de paires de lettres et de chiffres. Le premier signe d'une paire concerne la longitude, le second la latitude.
QTH:string;
...
map.QTHLocatorToLatlng('JN03AF85UX',lat,lng);
// return locator with 5 pairs
QTH := map.LatLngToQTHLocator(Map.MouseLatLng.Lat,FMap.MouseLatLng.Lng);
Altitude
Les éléments ont une propriété Altitude qui retourne une altitude en mètre.
Une connexion internet est obligatoire, si vous utilisez un cache, l'altitude y sera inscrite.
Si vous déplacez l'élément une nouvelle requête sera effectuée lors du prochain accès à Altitude, autrement l'ancienne valeur est retournée.
Par défaut c'est opentopodata qui est utilisé avec le dataset mapzen, 2 autres services peuvent être utilisé à la place.
map.GeoLocalise.ApiAltitude := altOpenElevation;
// For mapquest you must provide your own key in map.MapQuestKey = 'your_key'.
map.GeoLocalise.ApiAltitude := altMapQuest;
Vous pouvez aussi définir votre propre 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;