Community of VE/MapPoint Users and Developers
This is a discussion on Delphi class within the MapPoint 2006/2009 Discussion forums, part of the Map Forums category; All, I have compiled together a class for using MapPoint (currently 2004) with Delphi. The class creates MapPoint as an ...
| |||||||
| Register | Blogs | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| |||
| Delphi class 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. ---------- Code: 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',False);
OleContainer1.DoVerb(1);
OleContainer1.OleObjectInterface.GetUserClassID(vGuid);
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:double; 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.LocationToX(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:double):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('','','','',postcode,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.
|
| |||
|
Hi, I tryed your class in Delphi 7. Works as a glance, however some strange things: If I make a panel bottom aligned, and a second panel client alignd (for MP), then my bottom alligned pannel dissapears... also resizing does not resize the map. If I only 1 panel bottom aligned and visual the map on the form then I can make my panel visible by making the form larger at runtime, but again the map anchors does not follow the form. OK I did only quick test. but your comments are welcome of course.
__________________ rgds, Wilfried Mestdagh www.mestdagh.biz MapPoint coding demo Order MapPoint 2009 with Routing and User Tools Spreadsheet |
| |||
|
Hi, this is of course solution for the resize. Still other panel dissapears. Will look at it later. Code: OleContainer1.Align := alClient;
__________________ rgds, Wilfried Mestdagh www.mestdagh.biz MapPoint coding demo Order MapPoint 2009 with Routing and User Tools Spreadsheet |
| |||
|
Hi, I could not stop Setting the panel to Aligne=alNone, and his Anchors to top+left+bottom+right then MP will resize perfect (see also my previous mail) and the other panel stay visible
__________________ rgds, Wilfried Mestdagh www.mestdagh.biz MapPoint coding demo Order MapPoint 2009 with Routing and User Tools Spreadsheet |
| |||
|
Hi, this is interesting: Drop a MainMenu on the form ! And see what happens, automaticely without any letter of code I have the whole Mappoint menu and working..... This can be sometime not wanted, but.. Adding menu items will merge with the Mappoint ones...
__________________ rgds, Wilfried Mestdagh www.mestdagh.biz MapPoint coding demo Order MapPoint 2009 with Routing and User Tools Spreadsheet |
| |||
|
Hi! Yep the menu bar is strange - but I guess in some instances it could be quite a useful feature. Thanks for pointing out the resize problem (& solution) I will make this modification to the class. I think that the "jump to the nearest street" bit of code I wrote is adequate atm, however I have seen a much much more clever solution (more maths than I can cope with!) on here (I believe by yourself Wilfried) so I might look at implementing this in the next revision. Is there an easy way of disabling the right click menus/other menus and implementing a custom popup menu (I am guessing by catching an OnMouseDown event, detecting that button == mbRight, and displaying a tpopupmenu). I wish for this menu to display a save as bitmap item, is there an method to save the bitmap? I know there is a kludge which allows you to copy the current map to the tclipboard and then I can save it that way, but I do not feel this is a very good solution for an end product! Cheers again, Matt. |
| |||
|
Hi, I did not really test the methods you have provided, I was just anger to try it because I have a lot of Delhi applications using mappoint, ant this class is fine For the jump to nearest street I think I have published some delphi code to use a vector. If you cannot find it then I post it again. If you are going to expand the class I have following suggestion, because it is no nececary that a user (or even you yourself) do need all methods provided in a program. So I suggest to make a TTSCustomMappoint class where only the nececary things in to start and display mappoint. Then you can derrive components from it with the more advanced methods. For example I have a dozain applications where mappoint is only used to check the nearest street of a vehicle if it is not. Half of them do not even display a map, because position has to be sent to someone, like: "car is 50 meter NE from street name, no at zip city", or "car is in street name, no at zip city". It's your class of course, but only a suggestion For the saveToClipBoard I have no other / better idea's
__________________ rgds, Wilfried Mestdagh www.mestdagh.biz MapPoint coding demo Order MapPoint 2009 with Routing and User Tools Spreadsheet |
| |||
|
Hi Wilfried, Thats actually a great idea - keep TSMapPoint as a parent class and derive any custom methods etc.. from this as seperate child classes - inheritence is good for something! I hope that it proves a useful class in some of your applications, I will look up the vector code that you wrote, and add it to a descendant (I will post the descendant on here as well for all to use). Cheers Matt. |
| |||
| Quote:
I to just need to be able to get Street location without the MAP but am unsure on how to inherit Classes etc. Have you extended your class to enable this yet ( Hoping ). BTW I think theres a small bug in the GetStreetName function that fails if you are Exactly on the Street. Code: function TTSMapPoint.GetStreetName(xlongitude,xlatitude:double):string;
....
flag:=GetStreetName2(longitude,latitude,StreetName);
if(flag) then exit;
oldlongitude:=longitude;
oldlatitude:=latitude;
Code: function TTSMapPoint.GetStreetName(xlongitude,xlatitude:double):string;
....
flag:=GetStreetName2(longitude,latitude,StreetName);
if(flag) then
begin
getstreetname := streetname;
exit;
end;
oldlongitude:=longitude;
oldlatitude:=latitude;
|
| |||
|
Hi, You right. In first example the return value of the function is undefined. Compiler should generate a warning also.
__________________ rgds, Wilfried Mestdagh www.mestdagh.biz MapPoint coding demo Order MapPoint 2009 with Routing and User Tools Spreadsheet |
![]() |
| Tags |
| class, delphi |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
| |
| ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Using MP2004 with Delphi | Anonymous | MapPoint 2006/2009 Discussion | 13 | 03-02-2005 08:50 AM |
| DisplayDataMap in Delphi 7 | Anonymous | MapPoint 2006/2009 Discussion | 0 | 12-17-2004 06:59 AM |
| Delphi | Anonymous | MapPoint 2006/2009 Discussion | 2 | 12-18-2003 12:11 PM |
| 'AddCommand' + Delphi | stuarth | MapPoint 2006/2009 Discussion | 0 | 04-09-2003 10:18 AM |
| Mappoint With Delphi 5 | stuarth | MapPoint 2006/2009 Discussion | 1 | 04-08-2003 11:21 AM |