MapPoint Forums

MapForums

Community of VE/MapPoint Users and Developers




Delphi class

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 ...


Go Back   MapPoint Forums > Map Forums > MapPoint 2006/2009 Discussion

Register Blogs FAQ Members List Calendar Search Today's Posts Mark Forums Read



Click here to register

Reply

 

LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 10-30-2005
Junior Member
White Belt
 
Join Date: Oct 2005
Posts: 3
Delphi class

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.
----------

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.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #2 (permalink)  
Old 11-02-2005
Senior Member
Black Belt
 
Join Date: Nov 2004
Posts: 2,112
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.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #3 (permalink)  
Old 11-02-2005
Senior Member
Black Belt
 
Join Date: Nov 2004
Posts: 2,112
Hi,

this is of course solution for the resize. Still other panel dissapears. Will look at it later.

Code:
         OleContainer1.Align := alClient;
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #4 (permalink)  
Old 11-02-2005
Senior Member
Black Belt
 
Join Date: Nov 2004
Posts: 2,112
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
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #5 (permalink)  
Old 11-02-2005
Senior Member
Black Belt
 
Join Date: Nov 2004
Posts: 2,112
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...
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #6 (permalink)  
Old 11-03-2005
Junior Member
White Belt
 
Join Date: Oct 2005
Posts: 3
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.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #7 (permalink)  
Old 11-03-2005
Senior Member
Black Belt
 
Join Date: Nov 2004
Posts: 2,112
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
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #8 (permalink)  
Old 11-03-2005
Junior Member
White Belt
 
Join Date: Oct 2005
Posts: 3
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.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #9 (permalink)  
Old 11-30-2005
Junior Member
White Belt
 
Join Date: Nov 2005
Posts: 2
Quote:
Originally Posted by Wilfried
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
Hi Terrastudio / Wilfred
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;
I Think it should be
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;
Thanks for the Class
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
  #10 (permalink)  
Old 12-02-2005
Senior Member
Black Belt
 
Join Date: Nov 2004
Posts: 2,112
Hi,

You right. In first example the return value of the function is undefined. Compiler should generate a warning also.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
Reply

Tags
class, delphi


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads

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


All times are GMT -5. The time now is 07:09 PM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
MP2K Magazine
Visitor Map


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54