| | Eric Frost 02-12-2006, 03:50 PM Snap to a Road
Wilfried Mestdagh's article shows how to take a lat/lon and find the nearest road relative to that point. The technique, written entirely in Delphi, employs reverse geocoding and determines the lat/lon using a CalcXY routine.
Read the full article here --
http://www.mp2kmag.com/a130--snap.calcxy.gps.mappoint.html
Post a comment by clicking Post Reply above. RobinX 03-06-2006, 08:18 AM Hello wilfried !
First of all, thanks so much for your effort on the article !
Im pretty new with Delphi, so i was wondering if u could give
me some help, in using your code. I don't understand what your
function expects with : (ErrorProc: TOnError)
This is what i have done sofar :
- Saved your code to mp.pas
- Made a new project and added mp.pas to the project.
procedure TForm1.Button1Click(Sender: TObject);
var
mpx : TMapPoint;
d1, d2 : Double;
st : TStrings;
sx : String;
i : Integer;
begin
d1 := StrToFloat(Edit1.Text);
d2 := StrToFloat(Edit2.Text);
mpx.Create(); //<-- What to put here ?
mpx.GetStreetAddr(d1,d2,st,sx,i);
mpx.Destroy;
end;
I have no clue what to put behind mpx.Create(?). Is the rest of
the code the good way ? Would u be do kind to help me (Or anyone
else). I would love to see this working.
Once again, thanks for the article !
Regards Wilfried 03-06-2006, 12:13 PM Hi Robin,
In the constructor you give a callback function so if the component generates an exception this callback function can log it. You can give also nil to it then nothing is called back.
I made a small testproject to demonstrate how to use it.
Create a new project, add a new unit and copy the code in it as you alrady have done. Call the form TMain, add a button to the form and call it TestBtn.
Then add the following code:
procedure TMain.FormCreate(Sender: TObject);
begin
AllocConsole;
end;
// This is a callback function.
// Just in case mappoint produces an exception then we can display it
procedure TMain.MPError(Sender: TObject; E: Exception);
begin
WriteLn(E.ClassName + ' ' + E.Message);
end;
procedure TMain.TestBtnClick(Sender: TObject);
var
MP : TMapPoint;
Lat, Lon: Double;
Streets: TStrings;
Street, Direction: string;
Distance: integer;
n: integer;
begin
Streets := TStringList.Create;
MP := TMapPoint.Create(MPError);
try
Lat := 51.2497;
Lon := 4.4888;
MP.GetStreetAddr(Lat, Lon, Streets, Direction, Distance);
if Streets.Count = 0 then begin
WriteLn('No match found');
Exit;
end;
// We can have more than 1 streetname in the stringlist.
// In most cases the longest name is the most detailed
// So we display only the most detailed.
Street := '';
for n := 0 to Streets.Count - 1 do
if Length(Streets[n]) > Length(Street) then
Street := Streets[n];
WriteLn('Point is ' + IntToStr(Distance) + ' meter ' + Direction + ' from ' + Street);
finally
MP.Free;
Streets.Free;
end;
Compile it and correct my typo's in the class :( There are some points where I typed >:= wich must be >= of course :) RobinX 03-06-2006, 03:34 PM Wilfried !
You made my day :) It's working flawless !
Thank you so much for your article and your help !
Regards
Robin RobinX 03-06-2006, 04:32 PM Hi Wilfried,
One more question :)
It seems the Country information is missing from the
Street information. Is this caused by MapPoint self, or
is there another way to show the country information
togheter with the found adres ?
(e.g. ..... Amsterdam - Netherlands)
Thanks again !
Regards,
Robin. Wilfried 03-07-2006, 03:12 PM Hi Robin,
StreetAddress has a Country property. Probably not includeded in the Value property. I think it is easy to add. Use Country propretyand add it to the value to see. RobinX 03-08-2006, 05:56 PM Hello Wilfried !
Oke, thanks ! Im going to check it out :)
Cheers
Robin Srinivas Loka 04-28-2006, 01:04 PM Hello Wilfried,
When reverse geocoding, if a point is not on a road, I keep increasing the altitude until it falls onto a road(I limit the max altitude to 15).
Your technique looks interesting. Is it more efficient or better than increasing the altitude ? Because if so, I can give it a try(I need to convert your code to C#).
Thanks Thanks! This article combined with Gilles Kohl's article definitely gave me a jump start on getting reverse geocoding going. I combined the two approaches and added some additional features (making it behave a little like a heuristic search algorithm and trying to make sure we spend our time as well as possible). One *duh* moment I had that can save anyone time that thinks as slow as I do: make sure your map is zoomed in to the right level of detail! MapPoint gives you a lot better results when you do :lol: . DColeman 06-16-2006, 04:42 PM Would anyone have any suggestions for snapping to a road using the map point web service? Thanks Wilfried 07-19-2006, 07:11 AM Hi,
One *duh* moment I had that can save anyone time that thinks as slow as I do: make sure your map is zoomed in to the right level of detail! MapPoint gives you a lot better results when you do :lol: .
Thanks for feedback. Yes this is true and so for many / most find methods on the map. I set Altitude always to 1 to get good results. Wilfried 07-19-2006, 07:13 AM Hi,
When reverse geocoding, if a point is not on a road, I keep increasing the altitude until it falls onto a road(I limit the max altitude to 15). Your technique looks interesting. Is it more efficient or better than increasing the altitude ? Because if so, I can give it a try(I need to convert your code to C#). Thanks
It is more efficient that increasing the altitude, however it is slow, specially if you have a rather large circle and wants to check many points. I have used this technique in NT services that does not have human interface, so no problem if program is busy for sime seconds.
If you need it in C# I can copy/past the code also, have it somewhere... Borja 01-29-2008, 03:42 AM if you have the c# code, it would be very usefull to me
thanks:yellowsmile: | |