Gossamer Forum
Home : Products : DBMan : Customization :

nearest postal code search

(Page 2 of 2)
> >
Quote Reply
Re: [Lex] nearest postal code search In reply to
Please post the code that you've replaced the input field with, from your description I don't understand what you were doing.

If you're now trying to use this code in an ordinary search form with more than a "category" input field,
it won't work. It's designed to work with an input form where a user types only the postal code,
because that's what you said you wanted.

kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
Hi Birgit,

it does work the way it is now, it only doesn't know what to do if there is no result, as the way I've got it now that can be the case...

I'll show the complete (modified) code:

Code:

sub get_nearest_postal_code {
# --------------------------------------------------------
# Postcode script, to find the nearest company and send the result to html_record
&html_print_headers;

my $inputnumber = $in{'Postcode'}; # Postcode = name of form field
my (@Postcode, %difference, %letters, @nearestnumber, %id);

open (DB, "<$db_file_name") || &cgierr ("can't open $db_file_name: $!");
my $pos = $db_def{'Postcode'}[0];
my $id_pos = $db_def{'ID'}[0]; # assuming "ID" is the name of your ID field
my $Discipline_pos = $db_def{'Discipline'}[0];

while (<DB>) {
chomp;
my @line = split/\|/, $_;
# if ($line[$Discipline_pos] eq $in{'Discipline'}) { # exact match
if ($line[$Discipline_pos] =~ m/$in{'Discipline'}/) { # if it contains
push (@Postcode, $line[$pos]);
$id{$line[$pos]} = $line[$id_pos];
# print "Record ID in Hash: $id{$line[pos]}, Record ID: $line[$id_pos], Postcode: $line[$pos]<br>";
}
}

foreach my $Postcode (@Postcode) {
if ($Postcode =~ /(\d+)(\s)(\w+)/) {$Postcode = $1; $letters{$Postcode} = $3;}
$difference{$Postcode} = abs($Postcode-$inputnumber);
}

foreach my $key (sort {$difference{$a} <=> $difference{$b} } keys %difference) {
push (@differencearray, $difference{$key});
}

foreach my $key (keys %difference) {
if ($difference{$key} == $differencearray[0]) {
$key = "$key $letters{$key}";
push (@nearestnumber, $key);}
}

# foreach my $nearestnumber (@nearestnumber) {
# print "Dichtstbije postcode van $inputnumber is: $nearestnumber\n<p>";
# print "$id{$nearestnumber}";
# }

foreach my $nearestnumber (@nearestnumber) {
my %rec = &get_record($id{$nearestnumber});
# &html_record(%rec);

print qq|
<html>
<head>
<title>$html_title: Search the Database.</title>
<META HTTP-EQUIV="refresh" CONTENT='0;url=$build_root_url/$id{$nearestnumber}.shtml'>
</head>
<body bgcolor="#ffffff">
</body>
</html>
|;
}
}

Thanks for again taking the time to look at this!

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
OK, so you want the postal code found only when the record contains a particular string, specified in the input form, in the field "Discipline".
Of course this code doesn't work then, as it assumes that *all* postal codes will be pushed into the array @Postcode, so there will always be at least one array element.

To test whether there are elements in the array:
if (@Postcode) { # do stuff to print out nearest postal code record}
else { # print out error message or whatever}

HOWEVER: If you're involving a field search in some other field (as you do with "Discipline"), it would be much more efficient to tie up the postal code routine with ordinary search routines, via html_view_success/html_record.
For instance, in html_record, you could call a (then modified) sub get_nearest_postcode only when the search was called with search input in "Discipline":

if ($in{'Discipline'}) { my $nearest_code = &get_nearest_postcode($in{'Postcode'});}
# or something like this
The sub would have to be rewritten for that purpose, though.

I don't mean to be rude, but if you had given that possibility a thought from the beginning - and I had initially started out from this assumption, but you said you only wanted an input form where the user types the postal code, with no other searches involved -, it would have saved us both a lot of time. This is just to emphasize that sometimes, when you're asking a question here, it might be worthwhile thinking about whether that question makes sense, or whether it might not be useful to revise it.


kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
Hi Birgit,

You're not rude at all, I can but totally agree with what you say. However... (now it comes obviously)

The idea wasn't like this from the beginning, it has evolved, people I work with have asked for these kind of changes.

As for now, I am actually pleased and do not (at the moment) 'need' the changes, I've modified user input possibilities and now there is no chance the returned result would be empty. I was actually asking for this for when I would like to use it, as I do see a lot of possibilities with this script now I've been working a bit with it!

And you are right on what you say "if you had given that possibility a thought from the beginning" and I must say that is axaclty what I am trying to achieve more every time I am in a meeting with somebody who is ventilating ideas.

Thanks for the clues though, and thanks for all the time you have already invested. I am sure this can be of help to many others on this forum.

Greetings,

Lex
Quote Reply
Re: [kellner] nearest postal code search In reply to
Hi Birgit,

Yes it's me again...

In your last message you gave some hints as how one should try to do if it was in combination with the search form.

In stead of 'doing' it at html_record, I thought it'd be better at view_success, as there can be only one 'nearest' postal code right?

So, where it says

&html_record (&array_to_hash($_, @hits));

it sends the found records to html_record. And in stead, it should send the found records to get_nearest_postal_code where the nearest postcode whould be picked.

Now, as stated before, my knowledge of perl is still very poor, and that's why I do not know how to do the following:

in stead of the database file (in your piece of code)

Code:
open (DB, "<$db_file_name") || &cgierr ("can't open $db_file_name: $!");
my $pos = $db_def{'Postcode'}[0];
my $id_pos = $db_def{'ID'}[0]; # assuming "ID" is the name of your ID field

while (<DB>) {
chomp;
my @line = split/\|/, $_;

push (@Postcode, $line[$pos]);
$id{$line[$pos]} = $line[$id_pos];
[$id_pos], Postcode: $line[$pos]<br>";

}

it should use the @hits that came from html_view_success as source for the records that do have the discipline that's wanted.

Can you give me a clue as how I should do this?

Thanks a lot for all the time you've spent for helping me!

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
Well, even though there will be only one nearest postal code, there might be many hits to whom a nearest postal code exists, and in sub html_view_success, you have *all* of them stored in @hits. How should the sub get_nearest_postalcode know which one to use, if all of them are passed to it?

The logic is this:

sub html_view_success:
results 1,2,3,4,5 stored in @hits
send @hits to get_nearest_postalcode: yes, but which record out of results 1,2,3,4,5 should the nearest postalcode be the nearest to?

sub html_record:
- result 1 - get_nearest_postalcode: nearest postalcode for record 1
- result 2 - get_nearest_postalcode: nearest postalcode for record 2

You could also call the sub inside the "for (0 .. $numhits - 1) { ...}" loop in html_view_success, as there the results will already be "individualized", but I don't really see what would be the advantage of this over doing it in html_record.
html_record already provides you with a nice hash %rec where you can access the value that you're searching the nearest postal code for by name - it doesn't get any simpler!
kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
I'm trying to understand this, and I think I might have not been clear and that that is the problem now...

The database is not searched in the normal way. It's from a custom page where visitors of the site give their own postal code, and check disciplines they want from the company.

Now I thought: first get all the companies that do have the selected disciplines, and from these, check the one that has the 'nearest postal code'. The nearest is the one we want to show, and only that one.

Do you now think: "aha" or do you think: "this guy doesn't have a clue what I'm on about..."

I'll post this, and reread your message to see if I am looking at it with the wrong perspective...

Lex

Last edited by:

Lex: Nov 12, 2001, 6:23 AM
Quote Reply
Re: [Lex] nearest postal code search In reply to
Hi Lex,

I guess now I understand better what you want. I'd do it like this:

1) Code the search form like this:
<form action="$db_script_url" method="post" name="form1">
<input type=hidden name="db" value="$db_setup">
<input type=hidden name="uid" value="$db_uid">
<input type="text" name="get_postal_code" size="7" maxlength="7">
<input type="checkbox" name="disciplines" value"">firstdiscipline
<input type="checkbox" name="disciplines" value"">seconddiscipline
<input type="submit" name="view_records" value="submit"></form>

Note that the input field for the postal code does *not* have the same name as the database field used for the postal code. If it did, dbman would search for the postal_code AND the disciplines, and that's not what you want, is it?

2) modify html_view_success like this
my @hits = @_;
my $numhits = ($#hits+1) / ($#db_cols+1);
my $maxhits = $in{'mh'} || $db_max_hits;
&html_page_top;
my $number;
($number = $in{'get_postal_code'}) =~ s/\D//g;
my %disciplinehash;
for (0 .. $numhits - 1) {
my %rec = &array_to_hash($_, @hits);
$disciplinehash{$rec{$db_key}} = $rec{'postal_code'};
}
my $nearest_postal_code = &get_nearest_postal_code ($number, %disciplinehash);
foreach my $key (keys %disciplinehash) {
if ($disciplinehash{$key} eq $nearest_postal_code) {
my %rec = &get_record($key);
&html_record(%rec);}
}
&html_page_bottom;


3) modify sub get_nearest_postal_code like this:
sub get_nearest_postal_code {
my $inputnumber = shift;
my %disciplinehash = @_;
my ($nearest_code, @postal_code, %difference, %letters, @nearestnumber, %id);

foreach my $value (values %disciplinehash) {
push (@postal_code, $value);
}
foreach (@postal_code) { print "$_\n";}

foreach my $postal_code (@postal_code) {
if ($postal_code =~ /(\d+)(\s)(\w+)/) {
$postal_code = $1;
print "realcode: $postal_code\n";
$letters{$postal_code} = $3;}
$difference{$postal_code} = abs($postal_code-$inputnumber);
print "difference: $difference{$postal_code}, $inputnumber\n";
}

foreach my $key (sort {$difference{$a} <=> $difference{$b} } keys %difference) {
push (@differencearray, $difference{$key}); }
foreach my $key (keys %difference) {
if ($difference{$key} == $differencearray[0]) {
$nearest_code = "$key $letters{$key}\n";}
}
return ($nearestnumber);
}

So now the sub does not search for nearest postal codes in *all* database records, but only in the search results, whose id keys and postal codes we pass to the sub in %diciplinehash.

Note: There might still be *two* nearest postal codes, because e.g. 1234 and 1246 have the same distance from 1240. At present, the code does not take this possibility into account, but I don't have time now to do more.

Hope it works ...
kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
Hi Birgit,

the bit with the form I had worked out already (good hey?)

and your code works fine until :

return ($nearestnumber);

...

If, just above it, I print $nearest_code : no problem, it does the trick (as in: it has picked out the nearest one), but after that, nothing seems to happen. (no $nearestnumber seems to go back to html_view_success)

Any idea?

(I'll keep on trying though)

Thanks a lot!

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
sorry, this should be "return($nearest_code)".
kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
Hi Birgit,

the value now is returned, but nothing seems to happen with it...

What is:

foreach my $key (keys %disciplinehash) {
if ($disciplinehash{$key} eq $nearest_postal_code) {

supposed to do? And how is it supposed to know what $key (keys %disciplinehash) is?

Maybe you think these are really dumb questions, and you are probably right. I'm just trying to see how it is supposed to work.

And don't be sorry for if there's a mistake in one of your messages!!! Hey, it's all up to your good will.

Thanks! Wink

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
Forget that...

I now know what it does,

the problem sofar is; that

$nearest_postal_code

has a space at the end of it, so it doesn't match

$disciplinehash{$key}

I'll think (hope) I can manage solving this, will let you know.

Thanks,

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
I did manage that, and now I'm really happy! Smile

Thanks a million times!

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
my pleasure Wink
kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
I've found one small problem though...

in

for (0 .. $numhits - 1)

$numhits here is the same as maximum hits per page ($db_max_hits), even if there should be a lot more hits.

And I haven't found out yet how to change this...

?

Lex
Quote Reply
Re: [Lex] nearest postal code search In reply to
I reckon that's a problem when you have more hits than maximum hits, because with the nearest postal code search, you wouldn't want to break search results down into pages; you'd want to compute *all* search results. You could simply change $db_max_hits in your db.cgi to some obscenely large number, like "10000" - any number that is larger than that of your database entries would be safe.

If you don't want to do that, as you may have other searches where you' want $db_max_hits to be smaller, I guess you can solve the problem by changing the following code in db.cgi:
Code:
$in{'mh'} ? ($maxhits = $in{'mh'}) : ($maxhits = $db_max_hits);

Change this to:
Code:
if ($in{'get_postal_code'}) { $maxhits = 200000;#or some other obscenely large number}
elsif ($in{'mh'}) { $maxhits = $in{'mh'};}
else { $maxhits = $db_max_hits;}

But make sure that there's no input field for "mh" ("maxhimum hits") on the search form you use to get the nearest postal code.
kellner
Quote Reply
Re: [kellner] nearest postal code search In reply to
Exactly what I was looking for Birgit!!!

Great!Angelic

Thanks a lot,

Lex
> >