TECNativeLayer est la classe de base des layers qui vous permettent de réagir en fonction de la zone affichée et des actions de la souris.
TECNativeLayer = class
private
FObserver : TNativeMapObserver;
FShapes : TECShapes;
FMap : TNativeMapControl;
FOnShapeRightClick,
FOnShapeClick : TOnShapeMouseEvent;
FOnMouseClick,
FOnMouseMove : TNotifyEvent;
function getMinZoom :
byte;
function getMaxZoom :
byte;
procedure
setMinZoom(value:byte);
procedure
setMaxZoom(value:byte);
function getVisible :
boolean;
protected
procedure
doOnMapEndMove(sender : TObject); virtual;
procedure
doOnShapeClick(sender : TObject); virtual;
procedure
doOnShapeRightClick(sender : TObject); virtual;
procedure
doOnMapMouseMove(sender : TObject); virtual;
procedure
doOnMapMouseClick(sender : TObject); virtual;
procedure
doOnMapHiResChange(sender : TObject); virtual;
public
procedure
setVisible(const
value:boolean); virtual;
constructor
Create(_FMap:TnativeMapControl;const Name:string); virtual;
destructor Destroy;
override;
property OnShapeClick :
TOnShapeMouseEvent read
FOnShapeClick write
FOnShapeClick;
property OnShapeRightClick :
TOnShapeMouseEvent read
FOnShaperightClick write
FOnShapeRightClick;
property OnMouseMove :
TNotifyEvent read
FOnMouseMove write
FOnMouseMove;
property OnMouseClick :
TNotifyEvent read
FOnMouseClick write
FOnMouseClick;
property Map :
TNativeMapControl read
FMap;
property Shapes : TECShapes
read FShapes;
property Visible : boolean
read getVisible write setVisible;
property MaxZoom : byte
read getMaxZoom write setMaxZoom;
property MinZoom : byte
read getMinZoom write setMinZoom;
end;
Vous pouvez soit vous brancher sur OnMapHiResChange soit surcharger la procedure doOnMapHiResChange(sender : TObject) pour que votre layer s'adapte au changement de résolution
1TECNativePlaceLayer
Vous permet d'afficher automatiquement le résultat d'une recherche
Pour utiliser ce layer vous devez incorporer l'unité uecNativePlaceLayer ou FMX.uecNativePlaceLayer selon que vous utilisiez la version VCL ou FireMonkey
1Exemple : un layer qui affiche les restaurants
// search
Layer
FPlacesLayer :=
TECNativePlaceLayer.create(map,'PLACES_LAYER');
FPlacesLayer.OnPLaceClick := doOnPlaceClick;
FPlacesLayer.Visible := true;
FPlacesLayer.Search := 'node[amenity=restaurant]';
// standard image
32x32
FPlacesLayer.MarkerFilename := 'http://www.helpandweb.com/cake_32.png';
// lat,lng on center of
image
FPlacesLayer.XAnchor := 16;
FPlacesLayer.YAnchor := 16;
// hi-res image 64*64
FPlacesLayer.MarkerHiResFilename := 'http://www.helpandweb.com/cake_64.png';
// lat,lng on center of
image
FPlacesLayer.HiResXAnchor := 32;
FPlacesLayer.HiResYAnchor := 32;
...
// event click on place
shape
procedure
TForm1.doOnPlaceClick(sender : TECShape);
var
pResult : TECPlaceResult;
r,
n,
Content : string;
i : integer;
begin
// here Sender and Sender.Item are
allway assigned, and Sender.Item is
TECPlaceResult
pResult :=TECPlaceResult(Sender.item)
for i:=0 to pResult.CountResult-1 do
begin
n := pResult.NameResult[i];
r := pResult.Result[n];
if length(n)<
9 then
n := n+'<tab="65">';
content := content+'<b>'+n+'</b>: '+r+'<br>';
end;
if
FPlacesLayer.Shapes.InfoWindows.Count=0 then
begin
FPlacesLayer.Shapes.InfoWindows.add(0,0,'');
FPlacesLayer.Shapes.InfoWindows[0].zindex := 100;
end;
FPlacesLayer.Shapes.InfoWindows[0].content := Content;
FPlacesLayer.Shapes.InfoWindows[0].SetPosition(Shape.Latitude,shape.Longitude);
FPlacesLayer.Shapes.InfoWindows[0].Visible := true;
end;
end;
Par défaut les éléments du layer sont des TECShapeMarker mais vous pouvez changer le type de TECShape en redéfinissant TECNativePlaceLayer.doCreateShape(SearchResult : TECPlaceResult):TECShape;
XapiLayer
Préférez plutôt le layer OverPassApi
1XapiLayer utilise TECNativePlaceLayer et est directement intégrer dans TECNativeMap pour une utilisation simplifié.
La recherche s'effectue dans la zone affichée par votre carte et est mise à jour à chaque déplacement
property Shapes:TECShapes
property Search : string
La recherche s'effectue en faisant une requête sur un serveur XAPI
Vous pouvez rechercher tous les tags OSM en utilisant une syntaxe du type 'node[key=value]'
map.XapiLayer.Search := 'node[highway=bus_stop]';
Pour les nodes vous pouvez utiliser une syntaxe simplifiée.
map.XapiLayer.Search := 'highway=bus_stop';
Pour les clef amenity vous pouvez simplifier encore plus.
map.XapiLayer.Search := 'restaurant|bar|cafe';
Si vous ne spécifiez pas node dans votre requête les surfaces vont aussi être affichées.
2Pour les cacher définissez le style
Un point est rajouté au centre des surfaces, pour ne pas l'afficher, rajoutez le style
property Visible : boolean
property MaxItem : integer
property OnClick : TOnShape
property OnChange : TNotifyEvent
map.XapiLayer.OnChange := doOnXapiChange;
...
procedure TForm1.doOnXapiChange(sender : TObject);
begin
//
end;
// event click on xapi shape
procedure TForm1.doOnXapiClick(sender : TECshape);
begin
//
end;
Utilisez les styles pour habiller vos éléments
map.styles.addRule(Selector+':restaurant' +
'{graphic:base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAaBAMAAABI' +
'sxEJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJQTFRFAAAA////AAAAAAA'
+ 'AAAAAAAAA/h6U3wAAAAV0Uk5TAAAQgL++EJOXAAAAOElEQVQY02MIFQ0MFWRUCXVigLBcQ0OgrNDQUH'
+ 'JYQIDOMg0NDYawBIFC2FgCSCxBerFMg0Es02AAP34wMx8/aIAAAAAASUVORK5CYII=;visible:true;');
map.styles.addRule(Selector+':bar' +
'{graphic:base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAzklEQVRIx+2WUQ3'
+ 'FIAxFK2ES8HANVMIkIGUOkICESUDCJCABCdtPSQgJC2UjeXlZk3402e1ZoRSIGgZgA3AqfSOtAYgDoK'
+ 'iFmCxWaDLMaEAsoqDQBNGsGlDeHyexnbJPAHwpKuIe9zSwDFzFPR6egM4P9HMgX3YQgDSr67gQrsq51'
+ 'z8ZqqqSwHrOkhsZqguAo0iyS5weL1kD5qZUcjPNfXV1HPIThmaY9vr4QH8KknbPXbfMgtiqvSMA+1Zy'
+ 'lrNy9/SK8g0PVamc2NlTK98F1MyKB+QkmGEAAAAASUVORK5CYII=;visible:true;}');
map.styles.addRule(Selector+':cafe' +
'{graphic:base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOA'
+ 'AAAuUlEQVRIx2NgIACMjY0F0PgN+OTJBkCD9iMbCsT/cclTYkkCzGCoJfuB+D02eUosKQAZAjIM5nKQ'
+ 'JUBsgE2eEotQDIHyHXDJU2JRPyn8wQmgcfCfTPye1HghGw8/i4D4PBrbgVYWYcMGtLAoAakUmQ8VW0/'
+ 'TOALyFXDGHZUtEqCXRbCy8DzNLAKlNqTMn0ATi0AVI5LYflol7/1I7Pk4a18q5Zv3BKsPKpUMCvQogh'
+ 'RGS2+aW0SzGhYAB5lDXBZ7NtoAAAAASUVORK5CYII=;visible:true;}');
map.styles.addRule('#'+map.XapiLayer.Shapes.Name+ '.marker.highway:bus_stop {color:blue;styleicon:Flat;visible:true;}');
map.styles.addRule('#'+map.XapiLayer.Shapes.Name+ '.marker {scale:1;}');
map.styles.addRule('#'+map.XapiLayer.Shapes.Name+ '.marker:hover {scale:1.5;}');
Way
Avec une syntaxe du type way[key=value] pour pouvez extraire des chemins.
map.styles.addRule(Selector+':restaurant' +
'{graphic:base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAaBAMAAABI' +
'sxEJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJQTFRFAAAA////AAAAAAA'
+ 'AAAAAAAAA/h6U3wAAAAV0Uk5TAAAQgL++EJOXAAAAOElEQVQY02MIFQ0MFWRUCXVigLBcQ0OgrNDQUH'
+ 'JYQIDOMg0NDYawBIFC2FgCSCxBerFMg0Es02AAP34wMx8/aIAAAAAASUVORK5CYII=;visible:true;');
map.styles.addRule(Selector+':bar' +
'{graphic:base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAzklEQVRIx+2WUQ3'
+ 'FIAxFK2ES8HANVMIkIGUOkICESUDCJCABCdtPSQgJC2UjeXlZk3402e1ZoRSIGgZgA3AqfSOtAYgDoK'
+ 'iFmCxWaDLMaEAsoqDQBNGsGlDeHyexnbJPAHwpKuIe9zSwDFzFPR6egM4P9HMgX3YQgDSr67gQrsq51'
+ 'z8ZqqqSwHrOkhsZqguAo0iyS5weL1kD5qZUcjPNfXV1HPIThmaY9vr4QH8KknbPXbfMgtiqvSMA+1Zy'
+ 'lrNy9/SK8g0PVamc2NlTK98F1MyKB+QkmGEAAAAASUVORK5CYII=;visible:true;}');
map.styles.addRule(Selector+':cafe' +
'{graphic:base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOA'
+ 'AAAuUlEQVRIx2NgIACMjY0F0PgN+OTJBkCD9iMbCsT/cclTYkkCzGCoJfuB+D02eUosKQAZAjIM5nKQ'
+ 'JUBsgE2eEotQDIHyHXDJU2JRPyn8wQmgcfCfTPye1HghGw8/i4D4PBrbgVYWYcMGtLAoAakUmQ8VW0/'
+ 'TOALyFXDGHZUtEqCXRbCy8DzNLAKlNqTMn0ATi0AVI5LYflol7/1I7Pk4a18q5Zv3BKsPKpUMCvQogh'
+ 'RGS2+aW0SzGhYAB5lDXBZ7NtoAAAAASUVORK5CYII=;visible:true;}');
map.styles.addRule('#'+map.XapiLayer.Shapes.Name+ '.marker.highway:bus_stop {color:blue;styleicon:Flat;visible:true;}');
map.styles.addRule('#'+map.XapiLayer.Shapes.Name+ '.marker {scale:1;}');
map.styles.addRule('#'+map.XapiLayer.Shapes.Name+ '.marker:hover {scale:1.5;}');
Vous pouvez aussi trouver les jonctions entres les routes.
Recherche manuelle
Lorsque le layer est visible la recherche est synchronisée avec la zone visible de votre carte.
Pour pouvoir effectuer une recherche sur n'importe quelle zone vous devez cacher le layer et utiliser Bound pour délimiter la zone de recherche.
Mapillary
Uniquement disponible pour Delphi 10.x et supérieur !
1Mapillary est un service du même type que Google Street Map, il permet d'afficher des photos au niveau des rues, l'avantage est que vous pouvez vous-même l'enrichir en enregistrant vos parcours.
TECNativeMap se contente d'utiliser les informations en libre accès au près de Mapillary, vous devez obtenir une clef pour utiliser les service de Mapillary.
Pour cela allez sur le site www.mapillary.com, connectez-vous, ajoutez vos applications, vous obtiendrez alors un token qui vous servira de clef.
Pour utiliser mapillary vous devez incorporer l'unité uecMappilary ou FMX.uecMappilary selon que vous utilisiez la version VCL ou FireMonkey
2Utilisez TECMapillaryLayer pour incorporer un layer Mapillary.
FMapillaryLayer.OnClick := doOnMapillaryLayerClick;
FMapillaryLayer.OnTrafficSignClick := doOnMapillaryLayerTrafficSignClick;
FMapillaryLayer.OnBeginRequest := doBeginRequest;
FMapillaryLayer.OnendRequest := doEndRequest;
FMapillaryLayer.LocalCache := ExtractfilePath(ParamStr(0)) + 'cache';
FMapillaryLayer.Visible := true;
TECMapillaryLayer
function FindImageClose(const Lat, Lng: double; Distance: integer; var seq : TMapillarySequence; var PhotoIndex : integer ) : integer;
Trouver la photo la plus proche parmis celles affichées dans le layer, la recherche est en local.
Lat,Lng indique le point de départ de la recherche
Distance indique la distance maximale en mètres de la zone de recherche
Seq contiendra la séquence trouvée ou nil
PhotoIndex contiendra l'index de la photo dans seq ou -1
Retourne la distance en mètres entre le point de recherche et la photo, 0 si pas de photo
function SearchImageClose(const Lat,Lng:double; DistanceMeter : integer; ListSequenceImage : TListSequenceImage):integer;
Recherche l'ensemble des images comprise dans un rayon de DistanceMeter metres, la recherche est en local
Lat,Lng indique le point de départ de la recherche
DistanceMeter indique la distance maximale en mètres du rayon de recherche
ListSequenceImage contiendra une liste de TSequenceImage (un couple sequence, image index)
Retourne le nombre d'images trouvées
Voyez la démo MappilarySearchImages pour un exemple d'utilisation
3procedure SearchBounds(NorthEastLatitude, NorthEastLongitude, SouthWestLatitude, SouthWestLongitude: double);
function DetectionsImage(const image_id:int64;const List:TListDataDetections):integer;
id,
value,
create_at,
geometry : string;
end;
Remplir la liste avec l'ensemble des éléments détectés dans l'image, retourne le nombre d'éléments
L := TListDataDetections.Create;
try
n := FMapillaryLayer.DetectionsImage(SelectedSequence[SelectedImageIndex].Id,L);
Detections.Lines.BeginUpdate;
for i := 0 to n-1 do
Detections.Lines.Add(L[i].value);
Detections.Lines.EndUpdate;
finally
L.Free;
end;
property AccessToken: string ;
property Tiles: TMapillaryTiles
une TMapillaryTile contient une property Sequences:TMapillarySequences qui est une liste de TMapillarySequence qui elle même est une liste de TMapillaryImage
property Compass_angle: int64 ;
property Lat: double ;
property Lng: double ;
property Sequence_id: string ;
property Organization_id: int64 ;
property Id: int64 ;
property Captured_at: TDateTime ;
property is_Pano: boolean ;
property Url256: string;
property Url1024: string;
property Url2048: string;
end;
il y a aussi un property TrafficSign:TListTrafficSign qui est une liste de TTrafficSign
id : int64;
First_seen_at,
last_seen_at : TDateTime;
lat,lng : double;
value: string;
end;
procedure Clear;
Les données contenues dans les Tiles ne sont pas effacées, il n'y aura donc pas besoin d'une reconnexion aux serveurs mapillary pour les réafficher
4procedure ClearAll;
property Visible : boolean
property TrafficSignVisible : boolean
Affiche ou cache la signalisation
Déclenché lors d'un click sur une image mapillary
procedure TForm.doOnMapillaryLayerClick(Layer : TECMapillaryLayer; item : TECShape;
MapillarySequence : TMapillarySequence; ImageIndex : integer);
var bmp:TBitmap;
begin
// show photo in a TImage
bmp := TBitmap.Create;
try
// load image 256*256
// also url1024 and url2048
if FMapillaryLayer.LoadMapillaryBitmap(MapillarySequence[ImageIndex].Url256,bmp) then
Image.Picture.Assign(bmp);
finally
bmp.Free;
end;
end;
Déclenché lors d'un click sur un élément de traffic mapillary
procedure TForm30.doOnMapillaryLayerTrafficSignClick(layer: TECMapillaryLayer; item: TECShape;
ListTrafficSign: TListTrafficSign; TrafficSignIndex: integer) ;
begin
FMapillaryLayer.OpenWindow(item.Latitude,item.Longitude,
'<h4>'+ListTrafficSign[TrafficSignIndex].value+ '</h4><br>'+
'<tab="10"><b>Id</b><tab="40"> : '+IntToStr(ListTrafficSign[TrafficSignIndex].id)+ '<br>'+
'<tab="10"><b>Lat</b><tab="40"> : '+DoubleToStrDigit(ListTrafficSign[TrafficSignIndex].lat, 5)+'<br>'+
'<tab="10"><b>Lng</b><tab="40"> : '+DoubleToStrDigit(ListTrafficSign[TrafficSignIndex].lng, 5),
250 // width=250
);
end;
property OnSequenceColor:TOnMapillaySequenceColor;
Permet d'attribuer une couleur à une séquence.
Par défaut une couleur unique est attribuée en fonction de la clef de la séquence, une séquence aura donc toujours la même couleur.
6property OnBeginRequest: TNotifyEvent
property OnEndRequest: TNotifyEvent
procedure TForm.doEndRequest(sender: TObject);
var i,j:integer;
begin
ComboSequences.Items.BeginUpdate;
ComboSequences.items.clear;
for i := 0 to FMapillaryLayer.Tiles.Count-1 do
for j :=0 to FMapillaryLayer.Tiles[i].Sequences.Count-1 do
// store name and TMapillarySequence
ComboSequences.items.addObject(FMapillaryLayer.Tiles[i].Sequences[j].Sequence_id,FMapillaryLayer.Tiles[i].Sequences[j]);
ComboSequences.Items.EndUpdate;
end;
Heatmap
Une carte thermique permet de représenter l'intensité des données pour des points géographiques.
TECHeatmapLayer est la classe qui permet de gérer ce type de layer.
constructor Create(_FMap: TECNativeMap);HeatmapLayer := TECHeatmapLayer.Create(map);
procedure Clear;
Effacer l'ensemble des données
procedure Add(const Latitude, Longitude: double; const value: double = 1);
Ajouter un point géographique et lui assigner une valeur, vous pouvez faire plusieurs ajouts sur un même point.
procedure Remove(const latitude, longitude: double; const Value: double);
Après l'ajout des points, appelez Update pour actualiser le layer
property AutomaticUpdate: boolean
property Palette: THeatPalette
Palette permet de gérer les couleurs qui sont utilisées pour créer le dégradé
// addColor(Red,Green,Blue,Value)
// Red,Green, and Blue byte 0..255
// value double 0..1
// this is the default palette, you can also use Palette.reset for recreate it
HeatmapLayer.Palette.AddColor(0,0,0,0); // black for value=0
HeatmapLayer.Palette.AddColor(0,0,255,0.1);// blue for value=0.1
HeatmapLayer.Palette.AddColor(0,255,255,0.25); // cyan for value=0.25
HeatmapLayer.Palette.AddColor(0,255,0,0.5); // green for value=0.5
HeatmapLayer.Palette.AddColor(255,255,0,0.75); // yellow for value=0.75
HeatmapLayer.Palette.AddColor(255,0,0,1); // red for value=1
property Visible: boolean ;
property PointIsDisc : boolean;
Détermine si le point est affiché sous la forme d'un disque, sinon c'est un carré
Property Radius:integer;
Taille du point
property Opacity : byte;
Change l'opacité du layer (de 0 à 100)
property MinZoom: byte ;
Zoom minimal pour que le layer s'affiche
property MaxZoom: byte ;
Zoom maximal pour que le layer s'affiche
property GroupZIndex: integer ;
Zindex du groupe contenant l'ensemble des heatmaps, l'affichage s'effectue dans l'ordre croissant des ZIndex
property ZIndex: integer ;
ZIndex du layer par rapport aux autres heatmap
property OnUpdate: TNotifyEvent;
Événement déclenché lorsque la carte thermique a été généré
Weather Layer
En utilisant les services d'OpenWeathermap.org vous pourrez superposer des layers owPrecipitation, owSnow, owClouds, owPressure, owTemp, owWind// see pressure
map.OpenWeatherTilesLayer.Add(owPressure) ;
// see precipitation
map.OpenWeatherTilesLayer.Add(owPrecipitation) ;
// remove pressure
map.OpenWeatherTilesLayer.remove(owPressure) ;
TomTom Traffic Incidents
Contrairement aux tuiles incidents de tomtom, ce layer permet d'obtenir des informations sur les incidents lors du survol de la souris ou par une pression du doigt.
map.TomTom.Key := 'your api key';
map.TomTom.Incident.Layer := true;
TECTomTomIncident
property CategoryLabel : TStringList
Vous pouvez l'utiliser pour effectuer une traduction mais veillez bien à respecter l'ordre et le nombre d'éléments.
property CacheTime : int64
property Layer : boolean
property InfoStyle : TInfoWindowStyle
property FontColor : TColor
property BorderColor : TColor
property Break : integer
property Tab : integer
property TextDelay : string
property TextLength : string
property TextFrom : string
property TextTo : string
property Width : integer
property YAnchor : integer
property OnClick : TOnShapeMouseEvent
// show all properties
procedure TForm1.doIncidentClick(sender: TObject; const item: TECShape);
var Key, Value, content: string;
win: TECShapeInfoWindow;
begin
content := '';
if item.PropertiesFindFirst(Key, Value) then
begin
repeat
// if necessary line break
if content<>'' then content := content+'<br>';
// align the values to 110 pixels
Key := Key + '<tab=110>';
// Bold the keys
content := content + '<b>' + Key + '</b>: ' + Value ;
// continue as long as there are properties
until item.PropertiesFindNext(Key, Value);
end;
// create window if not exists
if map['info'].InfoWindows.count = 0 then
begin
win := map['info'].AddInfoWindow;
win.Width := 350;
end
else
win := map['info'].InfoWindows[0];
win.content := content;
win.SetPosition(map.MouseLatLng.Lat, map.MouseLatLng.lng);
win.Visible := true;
end;
Styler les informations
property Style : string
Contient les styles attribués aux lignes.
Par défaut comme pour les tuiles de TomTom les couleurs sont fonctions de l'amplitude du délai
'#TOMTOM-INCIDENT.line.magnitudeOfDelay:0 {color:#BFBFBF}';
'#TOMTOM-INCIDENT.line.magnitudeOfDelay:1 {color:#F58240}';
'#TOMTOM-INCIDENT.line.magnitudeOfDelay:2 {color:#EB4C13}';
'#TOMTOM-INCIDENT.line.magnitudeOfDelay:3 {color:#AB0000}';
'#TOMTOM-INCIDENT.line.magnitudeOfDelay:4 {color:#8B837D}';
L'infoWindow est dotée de propriétés qui vont vous permettre de définir un style en réaction
- iconCategory : 0-14 index sur la liste CategoryLabel
- delay : nombre de secondes
- length : nombre de mètres
map.Styles.addRule('#TOMTOM-INCIDENT.infowindow{bcolor:light(gray,128);color:white;fontcolor:black}');
// style if the wait is more than 5mn (delay>300)
map.Styles.addRule('#TOMTOM-INCIDENT.infowindow{if:delay>300;bcolor:dark(red,128);color:light(red,96);fontcolor:white}');
Layer OverPassApi
Ce layer a la même utilité que le layer XAPI mais il utilise OverPassApi qui est une technologie plus récente et doit donc être vu comme le remplaçant du layer XAPI.
Le but est d'extraire des données spécifique d'OpenStreetMap se trouvant dans la zone affichée de votre carte, une réactualisation automatique a lieu après chaque déplacement.
Si vous définissez un cache local les recherches y seront enregistrées et seront disponibles en mode hors-ligne.
7procedure Amenity(value: string;const Data:TSetOSMData=[odNode,odWay]);
Data indique si l'on cherche les node et/ou les Way
procedure Amenity(values: array of string;const Data:TSetOSMData=[odNode,odWay]; const Op: TBinaryFilterOSM = bfOr);
les procedures Amenity() sont une simplification des procedures Tag(), avec un tag_key implicitement égal à "amenity"
8procedure Tag(const key, value: string;const Data:TSetOSMData=[odNode,odWay]);
Data indique si l'on cherche les Nodes et/ou les Ways.
procedure Tag(const key:string;const values: array of string;const Data:TSetOSMData=[odNode,odWay]; const Op: TBinaryFilterOSM = bfAnd);
op=bfAnd ne retourne les tags que s'ils ont toutes les values
op=bfOr sélection le tag s'il a au moins une Value
procedure Tag(const tags: array of string;const Data:TSetOSMData=[odNode,odWay]; const Op: TBinaryFilterOSM = bfAnd);
property Query: string
map.OverPassApi.layer.Tag('highway','residential',[odWay]);
// search Way 'highway'='residential' OR 'highway'='primary'
map.OverPassApi.layer.Tag('highway',['residential','primary'],[odWay],bfOr);
//search Way width highway=residential AND name='Park Avenue'
map.OverPassApi.layer.Tag(['highway','residential','name','Park Avenue'],[odWay],bfAnd);
// search Nodes and Way amenity=parking
map.OverPassApi.layer.Amenity('parking']);
// search only Nodes amenity=restautant or amenity=parking
map.OverPassApi.layer.Amenity(['restaurant','parking',[odNode]);
// search nodes and ways amenity=parking
map.OverPassApi.layer.Query := 'nw[amenity=parking]';
property Group: TECShapes
property Visible: boolean
property TimeOut: integer
property OnBeginQuery: TNotifyEvent
property OnEndQuery: TNotifyEvent
property OnClick: TOnShapeMouseEvent
property OnData:TECOnOverPassLayerData
map.OverPassApi.Layer.OnEndQuery := doOnEndQuery;
map.OverPassApi.Layer.OnClick := doOnClick;
map.OverPassApi.Layer.OnData := doOnData;
...
// fired when xml data ready
procedure TForm9.doOnData(const XmlValue:string);
begin
XmlData.Lines.Text := XmlValue;
end;
// fired when click on ovepassapi layer item
procedure TForm9.doOnClick(sender: TObject; const item: TECShape);
var Key, Value, content: string;
win: TECShapeInfoWindow;
begin
content := '';
if item.PropertiesFindFirst(Key, Value) then
begin
repeat
// if necessary line break
if content<>'' then content := content+'<br>';
// align the values to 100 pixels
Key := Key + '<tab=100>';
// Bold the keys
content := content + '<b>' + Key + '</b>: ' + Value ;
// continue as long as there are properties
until item.PropertiesFindNext(Key, Value);
end;
// create window if not exists
if map.OverPassApi.Layer.Group.InfoWindows.count = 0 then
begin
win := map.OverPassApi.Layer.Group.AddInfoWindow;
win.Width := 270;
end
else
win := map.OverPassApi.Layer.Group.InfoWindows[0];
win.content := content;
win.SetPosition(map.MouseLatLng.Lat, map.MouseLatLng.lng);
win.Visible := true;
end;
// start query
procedure TForm9.doOnBeginQuery(sender : TObject);
begin
QuerySearch.Visible := true;
end;
// end query
procedure TForm9.doOnEndQuery(sender : TObject);
begin
QuerySearch.Visible := false;
end;