Google Maps already has a layer Panoramio , let's see how to wear this feature to all apis.
Let's create a class on the same model as that manages the interactive road design .
Operation
The principle is simple, every time that the view of the map changes we recover panoramio images available in the visible area, before display placed in a Group to be able to handle them more easily.
It connects to the OnChangeMapBounds event to detect the change of view.
It uses PanoramioView.Search to search for images, It is launched in a separate Thread, we connect us on the OnPanoramioSearch event to retrieve our image list.
It will transform each image in marker and manage the Click to display an InfoWindow containing the title and the image in size medium.
Using the class TPanoramioLayer
FPanoramioLayer :=
TPanoramioLayer.create;
...
// connect TECMap component for
show Panoramio layer
FPanoramioLayer.Map := map;
// deconnect layer
FPanoramioLayer.Map := nil
Source of TPanoramioLayer
unit
UPanoramioLayer;
interface
uses Windows, SysUtils,
Classes, Graphics, ECMaps, UECMapUtil;
type
TOnPanoramioLayerPhotoClick = procedure(sender: Tobject; const PhotoId : integer) of object;
TPanoramioLayer = class
private
FECMap : TECMap;
FOldOnPanoramioSearch : TOnPanoramioSearch;
FOldOnChangeMapBounds : TNotifyEvent;
FOnPanoramio : TNotifyEvent;
FOnClick : TOnPanoramioLayerPhotoClick;
FChangedBounds,
FInfowindow,
FShow : boolean;
FIdInfoWindow,
FMaxPhoto : integer;
procedure
setMap(const
ecMap:TECMap);
procedure
setShow(const
value:boolean);
procedure
AssignEvents;
procedure
RestoreEvents;
procedure
doOnPanoramioSearch(sender: TObject; const First,Last: Integer);
procedure
doOnChangeMapbounds(sender: TObject);
procedure
doOnMarkerClick(sender: Tobject; const Index: integer;
const dLatitude, dLongitude:
double);
public
constructor Create ;
destructor Destroy ;
override;
procedure Clear;
property Map : TECMap
read FECMap write setMap;
property MaxPhoto : integer
read FMaxPhoto write FMaxPhoto;
property Show : boolean
read FShow write setShow;
property Infowindow :
boolean read FInfowindow
write FInfowindow;
property OnPanoramio :
TNotifyEvent read
FOnPanoramio write
FOnPanoramio;
property OnClick :
TOnPanoramioLayerPhotoClick read FOnClick write FOnClick;
end;
implementation
constructor
TPanoramioLayer.Create;
begin
FMaxPhoto := 300;
FInfowindow := true;
inherited;
end;
destructor
TPanoramioLayer.Destroy ;
begin
Clear;
Map := nil;
inherited;
end;
procedure
TPanoramioLayer.AssignEvents;
begin
if not assigned(Map) then exit;
// save the events of
Origins
FOldOnPanoramioSearch := Map.OnPanoramioSearch;
FOldOnChangeMapBounds := Map.OnChangeMapBounds;
// connect to the events that
interest us
Map.OnPanoramioSearch := doOnPanoramioSearch;
Map.OnChangeMapBounds := doOnChangeMapbounds;
end;
// Reassign the events of
origins
procedure
TPanoramioLayer.RestoreEvents;
begin
if not assigned(Map) then exit;
Map.InfoWindows.delete(FIdInfoWindow);
end;
procedure
TPanoramioLayer.setMap(const
ecMap:TECMap);
begin
Clear;
RestoreEvents;
FECMap := ecMap;
FIdInfoWindow := -1;
FChangedBounds := false;
AssignEvents;
if assigned(FECMap)
then Show := true;
end;
procedure
TPanoramioLayer.Clear;
begin
if not assigned(Map) then exit;
Map.Groups['panoramio'].Delete;
end;
procedure
TPanoramioLayer.setShow (const value:boolean);
begin
// delete old images
Clear;
if value then
begin
Map.PanoramioView.LatSW := Map.SouthWestLatitude;
Map.PanoramioView.LatNE := Map.NorthEastLatitude;
Map.PanoramioView.LngSW := Map.SouthWestLongitude;
Map.PanoramioView.LngNE := Map.NorthEastLongitude;
// search for images, called
doOnPanoramioSearch when they are found
Map.PanoramioView.Search;
end;
FShow := value;
end;
// triggered by Show :=
true
procedure
TPanoramioLayer.doOnPanoramioSearch(sender: TObject;
const First,Last:
Integer);
var i,j:integer;
marker : TECMapMarker;
Lat,Lng : double;
url : string;
begin
for i := first to Last -
1 do
begin
Lat := Map.PanoramioView.photo_lat[i];
Lng := Map.PanoramioView.photo_lng[i];
url :=
remplace_str(Map.PanoramioView.photo_file_url[i],
'/medium/', '/mini_square/');
j := Map.AddMarker(lat,lng);
marker := Map.Markers[j];
marker.Draggable := false;
marker.Icon := url;
marker.Group := Map.Groups['panoramio'];
marker.Tag := i;
marker.OnMarkerClick := doOnMarkerClick;
end;
Map.Groups['panoramio'].show;
if assigned(FOnPanoramio)
then
FOnPanoramio(self);
if
(Map.PanoramioView.HasMore) and (Map.Groups['panoramio'].count<MaxPhoto)
then
begin
Map.PanoramioView.NextSearch;
exit;
end;
if
assigned(FOldOnChangeMapBounds) and FChangedBounds then
FOldOnChangeMapBounds(self);
FChangedBounds := false;
end;
procedure
TPanoramioLayer.doOnChangeMapbounds(sender:
TObject);
begin
if FChangedBounds
then exit;
FChangedBounds := true;
Show := true;
end;
procedure
TPanoramioLayer.doOnMarkerClick(sender: Tobject;
const Index: integer;
const dLatitude, dLongitude:
double);
var i:integer;
s : string;
begin
if not assigned(Map.Markers[index]) then exit;
if Infowindow then
begin
i := Map.Markers[index].tag;
s := '<h3>'+Map.PanoramioView.photo_title[i]+
'</h3>'+
Map.PanoramioView.HtmlPhoto(i,pimMedium)+
Map.PanoramioView.HtmlCopyright(i) ;
if FIdInfoWindow<
0 then
FIdInfoWindow := Map.InfoWindows.add(s)
else
Map.InfoWindows[FidInfoWindow].Content := s;
// for Bing maps
Map.InfoWindows[FidInfoWindow].SetOptions('width :550, height
:450,zIndex:500');
Map.InfoWindows[FidInfoWindow].SetPosition(dLatitude,
dLongitude);
Map.InfoWindows[FidInfoWindow].Open := true;
end;
if assigned(FOnClick)
then
FOnClick(self,Map.Markers[index].tag);
end;
end.