Welcome to MapForums!

Register, sign in, or use Facebook Connect above to join in and participate in the forum.

When you are signed in, this message, the ads in this row, and the red-underlined link ads all go away.

Subscribe to receive our newsletter.
Subscribe Unsubscribe
Results 1 to 10 of 10

Delphi class

This is a discussion on Delphi class within the MapPoint Desktop 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 ...

  1. #1
    terrastudios is offline 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&#40;locSantaCruz, locX&#41; < dblQuarterEarth Then ret&#58;= -ret;
            result&#58;=ret;
    end;
    
    function TTSMapPoint.GetStreetName2&#40;Longitude,Latitude&#58;double; out StreetName&#58; string&#41;&#58;boolean;
    var
            vFindResult &#58; FindResults;
            vStreetAddress &#58; StreetAddress;
            vResult &#58; string;
            i &#58; integer;
            iOle &#58; OleVariant;
            Loc&#58; Location;
            GoodHit&#58; boolean;
    begin
            Loc&#58;=FMap.GetLocation&#40;longitude,latitude,1&#41;;
            Loc.Goto_;
            vFindResult&#58;=FMap.ObjectsFromPoint&#40;FMap.LocationToX&#40;Loc&#41;,FMap.LocationToY&#40;Loc&#41;&#41; as FindResults;
            GoodHit&#58;=false;
            for i &#58;= 1 to vFindResult.Count do
            begin
                    iOle &#58;= i;
                    vStreetAddress &#58;= &#40;vFindResult&#91;iOle&#93; as Location&#41;.StreetAddress;
                    if Assigned&#40;vStreetAddress&#41; then
                    begin
                            StreetName&#58;=&#40;vStreetAddress.Street&#41;;
                            goodhit&#58;=true;
                            break;
                    end
                     else
                    begin;
                            goodhit&#58;=false;
                    end;
            end;
            GetStreetName2&#58;=goodhit;
    end;
    
    function TTSMapPoint.GetStreetName&#40;xlongitude,xlatitude&#58;double&#41;&#58;string;
    var
         longitude, latitude&#58; double;
         oldlongitude,oldlatitude&#58; double;
         streetname&#58; string;
         flag&#58; boolean;
         i&#58; 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&#58;=xlatitude;
         latitude&#58;=xlongitude;
         streetname&#58;='';
         flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;;
         if&#40;flag&#41; then exit;
         oldlongitude&#58;=longitude;
         oldlatitude&#58;=latitude;
         for i&#58;=1 to 10 do
         begin;
                 longitude&#58;=longitude+0.001;
                 flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;;
                 if&#40;flag&#41; then
                 begin;
                         getstreetname&#58;=streetname;
                         exit;
                 end;
         end;
         latitude&#58;=oldlatitude;
         longitude&#58;=oldlongitude;
         for i&#58;=1 to 10 do
         begin;
                 longitude&#58;=longitude-0.001;
                 flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;;
                 if&#40;flag&#41; then
                 begin;
                         getstreetname&#58;=streetname;
                         exit;
                 end;
         end;
         latitude&#58;=oldlatitude;
         longitude&#58;=oldlongitude;
         for i&#58;=1 to 10 do
         begin;
                 latitude&#58;=latitude-0.001;
                 flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;;
                 if&#40;flag&#41; then
                 begin;
                         getstreetname&#58;=streetname;
                         exit;
                 end;
         end;
         latitude&#58;=oldlatitude;
         longitude&#58;=oldlongitude;
         for i&#58;=1 to 10 do
         begin;
                 latitude&#58;=latitude+0.001;
                 flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;;
                 if&#40;flag&#41; then
                 begin;
                         getstreetname&#58;=streetname;
                         exit;
                 end;
         end;
    
         getstreetname&#58;='';
    end;
    
    procedure TTSMapPoint.GetLatLonPostcode&#40;Postcode&#58;string; out Longitude,Latitude&#58; double&#41;;
    var
         vFindResult &#58; FindResults;
         vStreetAddress &#58; StreetAddress;
         loc&#58; location;
         iOle&#58; olevariant;
         i&#58; integer;
    begin;
         vFindResult&#58;=FMap.FindAddressResults&#40;'','','','',postcode,0&#41;;
         for i &#58;= 1 to vFindResult.Count do
         begin
               iOle &#58;= i;
               loc&#58;=&#40;vFindResult&#91;iOle&#93; as Location&#41;;
               if&#40;assigned&#40;loc&#41;&#41; then
               begin;
                 latitude&#58;=getlat&#40;loc&#41;;
                 longitude&#58;=getlon&#40;loc&#41;;
                 exit;
               end;
         end;
    end;
    
    end.

  2. #2
    Wilfried is offline Senior Member Black Belt
    Join Date
    Nov 2004
    Location
    Belgium
    Posts
    2,433
    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.

  3. #3
    Wilfried is offline Senior Member Black Belt
    Join Date
    Nov 2004
    Location
    Belgium
    Posts
    2,433
    Hi,

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

    Code:
             OleContainer1.Align &#58;= alClient;

  4. #4
    Wilfried is offline Senior Member Black Belt
    Join Date
    Nov 2004
    Location
    Belgium
    Posts
    2,433
    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

  5. #5
    Wilfried is offline Senior Member Black Belt
    Join Date
    Nov 2004
    Location
    Belgium
    Posts
    2,433
    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...

  6. #6
    terrastudios is offline 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.

  7. #7
    Wilfried is offline Senior Member Black Belt
    Join Date
    Nov 2004
    Location
    Belgium
    Posts
    2,433
    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

  8. #8
    terrastudios is offline 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.

  9. #9
    KeithW is offline 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&#40;xlongitude,xlatitude&#58;double&#41;&#58;string; 
    ....
         flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;; 
         if&#40;flag&#41; then exit; 
         oldlongitude&#58;=longitude; 
         oldlatitude&#58;=latitude;
    I Think it should be
    Code:
    function TTSMapPoint.GetStreetName&#40;xlongitude,xlatitude&#58;double&#41;&#58;string; 
    ....
         flag&#58;=GetStreetName2&#40;longitude,latitude,StreetName&#41;; 
         if&#40;flag&#41; then 
         begin
             getstreetname &#58;= streetname;
             exit; 
         end;
         oldlongitude&#58;=longitude; 
         oldlatitude&#58;=latitude;
    Thanks for the Class

  10. #10
    Wilfried is offline Senior Member Black Belt
    Join Date
    Nov 2004
    Location
    Belgium
    Posts
    2,433
    Hi,

    You right. In first example the return value of the function is undefined. Compiler should generate a warning also.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Using MP2004 with Delphi
    By Anonymous in forum MapPoint Desktop Discussion
    Replies: 13
    Last Post: 03-02-2005, 08:50 AM
  2. DisplayDataMap in Delphi 7
    By Anonymous in forum MapPoint Desktop Discussion
    Replies: 0
    Last Post: 12-17-2004, 06:59 AM
  3. Delphi
    By Anonymous in forum MapPoint Desktop Discussion
    Replies: 2
    Last Post: 12-18-2003, 12:11 PM
  4. 'AddCommand' + Delphi
    By stuarth in forum MapPoint Desktop Discussion
    Replies: 0
    Last Post: 04-09-2003, 10:18 AM
  5. Mappoint With Delphi 5
    By stuarth in forum MapPoint Desktop Discussion
    Replies: 1
    Last Post: 04-08-2003, 11:21 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96