terrastudios

10-30-2005, 04:29 AM

All,

I have compiled together a class for using MapPoint (currently 2004) with Delphi. The class creates MapPoint as an ole object, and will display it on any twincontrol (e.g. a panel). I have compiled some of the routines from code found on this forum - credit to the original authors. If anyone feels like extending/improving this class, then please feel free - all I ask is that you can share your results with the rest of the members on this forum so that others can benefit from it too.

Many thanks in advance and I hope its of use to someone.

Regards

Matt Brocklehurst,

TerraStudios Limited.

----------

unit mappoint;

{

TTSMapPoint Class

Author: Matt Brocklehurst

Ties various mappoint (ole) delphi routines together, uses code found at www.MP2KMag.com

Credit to the various authors of some of the routines I use.

}

interface

uses Controls, extCtrls, Classes, Variants, OleCtnrs, OleServer, MapPoint_TLB;

type

TTSMapPoint = class

constructor Create(AOwner: TComponent;ParentControl:TWinControl);

destructor Destroy;

private

OleContainer1: TOleContainer;

locNorthPole:Location;

locSantaCruz:Location; //Center of western hemisphere

Pi, dblHalfEarth, dblQuarterEarth:double;

function Arccos(x:double):double;

function GetStreetName2(Longitude,Latitude:double; out StreetName: string):boolean;

public

FMap: _Map; // the active map

function GetLat(locx:Location):double;

function GetLon(locx:Location):double;

function GetStreetName(xlongitude,xlatitude:double):string;

procedure GetLatLonPostcode(Postcode:string; out Longitude,Latitude: double);

end;

implementation

constructor TTSMapPoint.Create(AOwner: TComponent;ParentControl:TWinControl);

var

vGuid: TGuid;

begin;

OleContainer1:=TOleContainer.create(aowner);

OleContainer1.Width:=ParentControl.Width;

OleContainer1.Height:=ParentControl.height;

OleContainer1.Parent:=ParentControl;

OleContainer1.CreateObject('MapPoint.Map.EU.11',Fa lse);

OleContainer1.DoVerb(1);

OleContainer1.OleObjectInterface.GetUserClassID(vG uid);

FMap:= IDispatch(OleContainer1.OleObject) as map;

locNorthPole:=fmap.GetLocation(90,0,0);

locSantaCruz:=fmap.GetLocation(0,-90,0);

dblHalfEarth:=fmap.Distance(locNorthPole, fmap.GetLocation(-90, 0,0));

dblQuarterEarth:=dblHalfEarth/2;

Pi:=3.14159265358979;

end;

destructor TTSMapPoint.Destroy;

begin;

FMap:=nil;

OleContainer1.DestroyObject;

// OleContainer1.Destroy;

end;

function TTSMapPoint.Arccos(x:double):double;

var

ret:double;

begin

if x=1 then

ret:=0

else

ret:=ArcTan(-x/Sqrt(-x*x+1))+2*ArcTan(1);

result:=ret;

end;

function TTSMapPoint.GetLat(locx:Location):double;

var

ret:double;

begin

ret:=90 - 180 * fmap.Distance(locNorthPole, locX) / dblHalfEarth;

result:=ret;

end;

function TTSMapPoint.GetLon(locx:Location):double;

var

ret, l , d , lat:double;

begin

lat:=GetLat(locx);

d:= fmap.Distance(fmap.GetLocation(lat, 0, 0), locX);

l:= (Lat / 180) * Pi;

ret:= 180 * Arccos((Cos((d * 2 * Pi) / (2 * dblHalfEarth)) - Sin(l) * Sin(l)) / (Cos(l) * Cos(l))) / Pi;

If fmap.Distance(locSantaCruz, locX) < dblQuarterEarth Then ret:= -ret;

result:=ret;

end;

function TTSMapPoint.GetStreetName2(Longitude,Latitude:doub le; out StreetName: string):boolean;

var

vFindResult : FindResults;

vStreetAddress : StreetAddress;

vResult : string;

i : integer;

iOle : OleVariant;

Loc: Location;

GoodHit: boolean;

begin

Loc:=FMap.GetLocation(longitude,latitude,1);

Loc.Goto_;

vFindResult:=FMap.ObjectsFromPoint(FMap.LocationTo X(Loc),FMap.LocationToY(Loc)) as FindResults;

GoodHit:=false;

for i := 1 to vFindResult.Count do

begin

iOle := i;

vStreetAddress := (vFindResult[iOle] as Location).StreetAddress;

if Assigned(vStreetAddress) then

begin

StreetName:=(vStreetAddress.Street);

goodhit:=true;

break;

end

else

begin;

goodhit:=false;

end;

end;

GetStreetName2:=goodhit;

end;

function TTSMapPoint.GetStreetName(xlongitude,xlatitude:dou ble):string;

var

longitude, latitude: double;

oldlongitude,oldlatitude: double;

streetname: string;

flag: boolean;

i: integer;

begin

// for some reason longitude and latitude are back to front?

// to avoid conversion - we flip em over for the purpose of our routines

longitude:=xlatitude;

latitude:=xlongitude;

streetname:='';

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then exit;

oldlongitude:=longitude;

oldlatitude:=latitude;

for i:=1 to 10 do

begin;

longitude:=longitude+0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

latitude:=oldlatitude;

longitude:=oldlongitude;

for i:=1 to 10 do

begin;

longitude:=longitude-0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

latitude:=oldlatitude;

longitude:=oldlongitude;

for i:=1 to 10 do

begin;

latitude:=latitude-0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

latitude:=oldlatitude;

longitude:=oldlongitude;

for i:=1 to 10 do

begin;

latitude:=latitude+0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

getstreetname:='';

end;

procedure TTSMapPoint.GetLatLonPostcode(Postcode:string; out Longitude,Latitude: double);

var

vFindResult : FindResults;

vStreetAddress : StreetAddress;

loc: location;

iOle: olevariant;

i: integer;

begin;

vFindResult:=FMap.FindAddressResults('','','','',p ostcode,0);

for i := 1 to vFindResult.Count do

begin

iOle := i;

loc:=(vFindResult[iOle] as Location);

if(assigned(loc)) then

begin;

latitude:=getlat(loc);

longitude:=getlon(loc);

exit;

end;

end;

end;

end.

I have compiled together a class for using MapPoint (currently 2004) with Delphi. The class creates MapPoint as an ole object, and will display it on any twincontrol (e.g. a panel). I have compiled some of the routines from code found on this forum - credit to the original authors. If anyone feels like extending/improving this class, then please feel free - all I ask is that you can share your results with the rest of the members on this forum so that others can benefit from it too.

Many thanks in advance and I hope its of use to someone.

Regards

Matt Brocklehurst,

TerraStudios Limited.

----------

unit mappoint;

{

TTSMapPoint Class

Author: Matt Brocklehurst

Ties various mappoint (ole) delphi routines together, uses code found at www.MP2KMag.com

Credit to the various authors of some of the routines I use.

}

interface

uses Controls, extCtrls, Classes, Variants, OleCtnrs, OleServer, MapPoint_TLB;

type

TTSMapPoint = class

constructor Create(AOwner: TComponent;ParentControl:TWinControl);

destructor Destroy;

private

OleContainer1: TOleContainer;

locNorthPole:Location;

locSantaCruz:Location; //Center of western hemisphere

Pi, dblHalfEarth, dblQuarterEarth:double;

function Arccos(x:double):double;

function GetStreetName2(Longitude,Latitude:double; out StreetName: string):boolean;

public

FMap: _Map; // the active map

function GetLat(locx:Location):double;

function GetLon(locx:Location):double;

function GetStreetName(xlongitude,xlatitude:double):string;

procedure GetLatLonPostcode(Postcode:string; out Longitude,Latitude: double);

end;

implementation

constructor TTSMapPoint.Create(AOwner: TComponent;ParentControl:TWinControl);

var

vGuid: TGuid;

begin;

OleContainer1:=TOleContainer.create(aowner);

OleContainer1.Width:=ParentControl.Width;

OleContainer1.Height:=ParentControl.height;

OleContainer1.Parent:=ParentControl;

OleContainer1.CreateObject('MapPoint.Map.EU.11',Fa lse);

OleContainer1.DoVerb(1);

OleContainer1.OleObjectInterface.GetUserClassID(vG uid);

FMap:= IDispatch(OleContainer1.OleObject) as map;

locNorthPole:=fmap.GetLocation(90,0,0);

locSantaCruz:=fmap.GetLocation(0,-90,0);

dblHalfEarth:=fmap.Distance(locNorthPole, fmap.GetLocation(-90, 0,0));

dblQuarterEarth:=dblHalfEarth/2;

Pi:=3.14159265358979;

end;

destructor TTSMapPoint.Destroy;

begin;

FMap:=nil;

OleContainer1.DestroyObject;

// OleContainer1.Destroy;

end;

function TTSMapPoint.Arccos(x:double):double;

var

ret:double;

begin

if x=1 then

ret:=0

else

ret:=ArcTan(-x/Sqrt(-x*x+1))+2*ArcTan(1);

result:=ret;

end;

function TTSMapPoint.GetLat(locx:Location):double;

var

ret:double;

begin

ret:=90 - 180 * fmap.Distance(locNorthPole, locX) / dblHalfEarth;

result:=ret;

end;

function TTSMapPoint.GetLon(locx:Location):double;

var

ret, l , d , lat:double;

begin

lat:=GetLat(locx);

d:= fmap.Distance(fmap.GetLocation(lat, 0, 0), locX);

l:= (Lat / 180) * Pi;

ret:= 180 * Arccos((Cos((d * 2 * Pi) / (2 * dblHalfEarth)) - Sin(l) * Sin(l)) / (Cos(l) * Cos(l))) / Pi;

If fmap.Distance(locSantaCruz, locX) < dblQuarterEarth Then ret:= -ret;

result:=ret;

end;

function TTSMapPoint.GetStreetName2(Longitude,Latitude:doub le; out StreetName: string):boolean;

var

vFindResult : FindResults;

vStreetAddress : StreetAddress;

vResult : string;

i : integer;

iOle : OleVariant;

Loc: Location;

GoodHit: boolean;

begin

Loc:=FMap.GetLocation(longitude,latitude,1);

Loc.Goto_;

vFindResult:=FMap.ObjectsFromPoint(FMap.LocationTo X(Loc),FMap.LocationToY(Loc)) as FindResults;

GoodHit:=false;

for i := 1 to vFindResult.Count do

begin

iOle := i;

vStreetAddress := (vFindResult[iOle] as Location).StreetAddress;

if Assigned(vStreetAddress) then

begin

StreetName:=(vStreetAddress.Street);

goodhit:=true;

break;

end

else

begin;

goodhit:=false;

end;

end;

GetStreetName2:=goodhit;

end;

function TTSMapPoint.GetStreetName(xlongitude,xlatitude:dou ble):string;

var

longitude, latitude: double;

oldlongitude,oldlatitude: double;

streetname: string;

flag: boolean;

i: integer;

begin

// for some reason longitude and latitude are back to front?

// to avoid conversion - we flip em over for the purpose of our routines

longitude:=xlatitude;

latitude:=xlongitude;

streetname:='';

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then exit;

oldlongitude:=longitude;

oldlatitude:=latitude;

for i:=1 to 10 do

begin;

longitude:=longitude+0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

latitude:=oldlatitude;

longitude:=oldlongitude;

for i:=1 to 10 do

begin;

longitude:=longitude-0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

latitude:=oldlatitude;

longitude:=oldlongitude;

for i:=1 to 10 do

begin;

latitude:=latitude-0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

latitude:=oldlatitude;

longitude:=oldlongitude;

for i:=1 to 10 do

begin;

latitude:=latitude+0.001;

flag:=GetStreetName2(longitude,latitude,StreetName );

if(flag) then

begin;

getstreetname:=streetname;

exit;

end;

end;

getstreetname:='';

end;

procedure TTSMapPoint.GetLatLonPostcode(Postcode:string; out Longitude,Latitude: double);

var

vFindResult : FindResults;

vStreetAddress : StreetAddress;

loc: location;

iOle: olevariant;

i: integer;

begin;

vFindResult:=FMap.FindAddressResults('','','','',p ostcode,0);

for i := 1 to vFindResult.Count do

begin

iOle := i;

loc:=(vFindResult[iOle] as Location);

if(assigned(loc)) then

begin;

latitude:=getlat(loc);

longitude:=getlon(loc);

exit;

end;

end;

end;

end.