Simply Postcode Lookup                     Phone: 01945 464854 

   Log In       
Postcode Address Lookup Software
 

Nearest to Postcode Address Functionality:


  Advantages/Uses:

  • Nearest store functionality

  • Nearest consultants, agents, garages, office, houses for sale

  • Use Local Data held in your Database, for maximum flexibility

  • Use Web Data, for easy integration.  Upload of data via Microsoft Excel

  • Use Web Data, for displaying Google Map with pins

  • Earn commission by becoming a reseller

  [More About being a Reseller]

The following discusses implementing the nearest store functionality, but the Stores could be consultants, agents, garages, offices, companies, houses for sale, etc….

We offer two methods of calculating the Nearest to Postcode:

  • Option 1 Local Data, best for large number of addresses which are dynamic

    This option uses your table of Stores, and our COM object to retrieve the Nearest data.  Only one call is made to our server during this operation, or none if the COM Object is in Local Mode.   

      Demo Video : Show me Option 1 in action and how to do nearest

+ More information on Option 1 Click this line for more information


The principle is:  

[Click here for more information on COM Object]

  You have two indexed fields in your “Store” database table called Longitude and Latitude.

You write a procedure to call our PostZon database to populate the Longitude and Latitude fields, for any where  Longitude and Latitude = 0.   You then either call this after bulk additions, or populate these fields every time new records are added. 

 [Click here for code]

  You provide the user with some kind of query window/web page, to enter their Postcode.  When queried you then call the Nearest_StartList(TargetPostcode, WithInKm, Longitude, Latitude, Difference) data call to get the Difference, Longitude and Latitude for the query Postcode.

 

Then query your database with SQL:

"((Nearest.Longitude)>" & Longitude - Difference & ") and ((Nearest.Longitude)<" & Longitude + Difference  & ") and "
"((Nearest.Latitude)>" & Latitude -
Difference & ") and ((Nearest.Latitude)<" & Latitude + Difference & ")"

 

For each result you then call Nearest_AddToList(RecordLongitude, RecordLatitude, YouData1, YouData2, YouData3)

Where YouData1, YouData2, YouData3 can be any string data you want to display or use to identify records.

 

The COM Object now has a List of results.  

So call Nearest_GetNumberOfRecordsReturned() to Get Number of records found and sort them

 

Then to retrieve the data

For x = 1 To NumberOfRecordToDisplay
   .Nearest_GetRecord x, Distance, Longitude, Latitude, YouData1, _

             YouData2, YouData3

   'Build string to display
   GetAddressesWithIn = GetAddressesWithIn & Distance & " " & _

             YourData1 & " " & YouData2 & vbCrLf
Next

 

Further pagination functionality can then be added to this process.

If the process returns a very small number of results, then widen the search area, if need be.

  We have a Microsoft Access Example which demonstrates this functionality, contained in our Programming Examples Download. see "Using COM Object.mdb".  This contains a table called "Nearest" which contains 500 example address.

  Please download examples here

 

+ Option 1 Example Code Click this line for more information

How to populate your table with Longitude and Latitude fields:

Dim Rec As New ADODB.Recordset
Dim SQL As String, DataKey As String, c&
SQL = "SELECT Nearest.* FROM Nearest WHERE (((Nearest.Longtitude)=0) and ((Nearest.Latitude)=0));"

'Open connection for updating records
Rec.Open SQL, CurrentProject.Connection, adOpenDynamic, adLockOptimistic ', adCmdTableDirect"

'Get Data Key for accessing the Postcode data
DataKey = NullToBlank(Forms![mainForm].txtDataKey)

If Not Rec.BOF Then Rec.MoveFirst

Do While Not Rec.EOF
  Me.Caption = "Filling in Postcode:" & Rec![Postcode]

  Dim LongValue#, LatValue#, KeyValue#

  If GetLongLat(DataKey, Rec![Postcode], LongValue, LatValue) Then
    'Go Longtitude/Latitude , so put in record
    Rec![Longtitude] = LongValue
    Rec![Latitude] = LatValue
    Rec.Update
  End If

  'Next record
  Rec.MoveNext
  c = c + 1
Loop

Me.Caption = "Updated " & c & " records, Finished"
Rec.Close

And Get Longitude and Latitude from our Database:

Function GetLongLat(DataKey$, Postcode$, RetLong#, RetLat#) As Boolean
  'Get Longitude/Latitude from PostZon database

  SimplyPostCodeLookup.SetDataKey (DataKey)

  With SimplyPostCodeLookup
    If .GetPostZonAddressRecord(Postcode) Then
      'Add data to records
      RetLong = .PostZon_Longitude_wgs84
      RetLat = .PostZon_Latitude_wgs84
      GetLongLat = True
    End If
  End With
End Function


How to display 10 nearest addresses to Target Postcode:


Answer = GetAddressesWithIn(DataKey, TargetPostcode, WithInKm, _

              MaxRecords, NumberOfRecordsReturned)
MsgBox "Found:" & NumberOfRecordsReturned & vbCrLf & Answer

And the function:

Function GetAddressesWithIn(DataKey$, TargetPostcode$, WithInKm#, _

              MaxNumber, NumberOfRecordsReturned&) As String
  'Get addresses within xKm of target Longitude/Latitude

  Dim Rec As New ADODB.Recordset
  Dim SQL As String, c&, Difference#
  Dim YouData1$, YouData2$, YouData3$, x&, Distance#, Longitude#, Latitude#

  With SimplyPostCodeLookup
    .SetDataKey (DataKey)

    'Get Differance in Longitude/Latitude from COM Object
    'then we can get all addresses within +- x km of target
    If .Nearest_StartList(TargetPostcode, WithInKm#, Longitude, _

                  Latitude, Difference) Then

      SQL = "SELECT Nearest.* FROM Nearest WHERE ("
      SQL = SQL & "((Nearest.Longitude)>" & Longitude - Difference & _

         ") and ((Nearest.Longitude)<" & Longitude + Difference & ") and "
      SQL = SQL & "((Nearest.Latitude)>" & Latitude - Difference & _

         ") and ((Nearest.Latitude)<" & Latitude + Difference & ")"
      SQL = SQL & ");"

      'Open connection of records
      Rec.Open SQL, CurrentProject.Connection, adOpenForwardOnly

      NumberOfRecordsReturned = 0
      If Not Rec.BOF Then Rec.MoveFirst


      Do While Not Rec.EOF
        'Now give the COM object the record details. 

        'To sort into Nearest order later

        'DO NOT put "|" in your data
        YouData1 = Rec![Postcode] 'This could be any data you want
        YouData2 = Rec![Address]
        .Nearest_AddToList Rec![Longitude], Rec![Latitude], _

                      YouData1, YouData2, YouData3

        'Next record
        Rec.MoveNext
        c = c + 1
      Loop

      'Now get the number of records returned withinKm

      'The COM Object now sorts the results in memory
      NumberOfRecordsReturned = .Nearest_GetNumberOfRecordsReturned()

      Dim NumberOfRecordToDisplay&
      NumberOfRecordToDisplay = NumberOfRecordsReturned
      If NumberOfRecordToDisplay > MaxNumber Then _

                  NumberOfRecordToDisplay = MaxNumber

      'Now get list for displaying
      For x = 1 To NumberOfRecordToDisplay
        .Nearest_GetRecord x, Distance, Longitude, Latitude, YouData1, _

                         YouData2, YouData3
        GetAddressesWithIn = GetAddressesWithIn & Distance & " " & _

                         YourData1 & " " & YouData2 & vbCrLf
      Next

      'now inform COM Object we are done so it can clear the memory
      .Nearest_EndList
    Else
      MsgBox "Error:" & .General_errormessage & " calling Nearest_StartList"
    End If

  End With
End Function


This functionality can be implemented in PHP using one of the many "Nearest Store" PHP examples available on the internet.  The example in the "PHP Core Code\PostZon core code" shows how to get the Longitude and Latitude in from our service in PHP.

 



  • Option 2 Web Data, best for a small to medium, relatively static list of addresses

    Using this option you load the list of stores into our database, and then make a simple request for nearest Stores to a given Postcode.  The call returns your Store data, merged with your template, to format the output into HTML which can be directly written to a web page.   You have total control over the appearance of your page.

    A more advance call is available to return a Google map with map pins, which when clicked on can display data from your templates in up to four tabs.  The pins can also have different Icons to allow you to display other points of interest, other than your stores.

    The Map or Nearest list can be retrieved by an SOAP or HTTP call

    The example downloads include a PHP and .NET 2005 web page to return a simple page with map and nearest list. 

  Tutorial Video : Show me Option 2

(Sound Required)

+ More information on Option 2 Click this line for more information


 

   Option 2: Nearest Requirements


This functionality requires an Internal Use PostZon License, to allow data to be uploaded, and used internally on one machine.  To trial the system you can simply used LicenseID = 0, this will give 500 demo address in list 1 and 2 as listed on the upload spreadsheet.

[Prices]

[Click here for live Web Demo of Option 2]

Note: Any lists or templates that has not been used for 6 months will deleted.  

 

  Nearest Web Data


We offer a Web based solution to allow the location of Stores to be loaded onto our server, either by putting the data in an Excel spreadsheet and simply importing the data using the tool provided by us.  Or for those who want total integration we provide a Web SOAP Service which allows calls to manage list by your program/web site.   

Then a simple call web page, SOAP service or HTTP request to return the closest stores to the TargetPostCode. 

[Click here to see simple web page results]

The returned results can be either returned as XML or merged with a template you provide to give desired HTML to produce the list.   So simply call using server side script, and pop the returned HTML into your page .   Another function will return Google Map code, together with the HTML to display results on a map together with the nearest store list. 

If the process returns a very small number of results, then widen the search area if need be.

[Download Pins used in examples]

+ Our Database Structure Click this line for more information

  Our "Store" database structure is:

Name

Description

YourID

Your identifier, you can use to get full record from your database.

UNIQUE REQUIRED Integer

YourData1

This can be loaded with any text you want to display.  This could be loaded with the ID of your record, full address, directions, etc.

This data is then merged with your template to expand to full HTML

[Click here for simple example]

YourData2

As YourData1

YourData3

As YourData1

YourData4

As YourData1

YourData5

As YourData1

YourData6

As YourData1  

If using filters then can stop details being shown on pin click if set to "NODETAILS".  This allows control over each Pin

YourData7

As YourData1

YourData8

As YourData1

Longitude

We populate this for you when added to database

Latitude

We populate this for you when added to database

PostCode

The Postcode of your store. 

REQUIRED

DataAdded

Date added to database. 

We assign this when added.

format YYYYMMDD

Type

Can be used to filter out certain kinds of locations, in nearest list and show different icons on a map

Optional Char

[See Example 5]

TypeFilter will optionally filter out records from the nearest list.  You could use "A" for major stores, "B" small stores and "C" for Petrol stations.  Then if displayed on map they could all have different Pins.   The actual list returned could only include "AB", so the petrol stations would not be listed.

 

This field could also be loaded with codes, which relate to qualifications.  Then the service is called with the type code (qualification code) to product a list of nearest consultants with curtail qualifications.

Area

Allows you to display all Stores in a certain area.

Optional String (2)

To display a map for Area simple call the GetNearestToPostCodeTemplateAndMap with ExtraFlags="AreaCode=Area" the TargetPostcode should be set to center the map

[See Example 6,7]

The Excel spreadsheet allows you to upload the above data very easily



+ Functions to manage Stores List Click this line for more information

Nearest to Postcode Functions Provided are:


Common Parameters:

LicenseID 

Your License ID (Account Number)

This is given to you when you open an account with us

 

ListID

1-10, allows you to have multiple lists.  

Password

Password to your account

ErrorDesc

Returns any errors if they occur, other wise “” if OK

For Trail use set to 0.  ListID=1 and 2 which are List 1 and 2 on the spreadsheet.   When calling these lists the DataKey, LicenseID and Password are ignored.   You will NOT be able to update these list.

SOAP Functions to Manage nearest Stores List:


The following functions allow you to manage your store list on our server, but we provide an Excel spreadsheet which allows you to easily manage the list from with Microsoft Excel.

[Download Data Importer]

 

SOAP Service URL:

http://www.simplylookupadmin.co.uk/webservicenearest.asmx

 

  RemoveAllFromList(LicenseID as long,_

                     ListID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string) as Boolean

Returns TRUE if removed, else error in ErrorDesc  

if ListID =-1 then delete all lists

  RemoveEntryFromList(LicenseID as long,_

                     ListID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     YourID as Long) as Boolean

Returns TRUE if removed, else error in ErrorDesc

  GetListCount(LicenseID as long,_

                     ListID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     YourCurrentLimit as long) as long

Returns count, else –1 and error in ErrorDesc
YourCurrentLimit
is the list limit you currently have.  if ListID =-1 then get count for all lists

 

  AddOrUpdateEntry(LicenseID as long,_

                     Datakey as string,_

                     ListID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     MachineID as string,_

                     Postcode as string,_

                     YourID as long, _

                     YourData1 as string,_

                     YourData2 as string,_

                     YourData3 as string,_

                     YourData4 as string,_

                     YourData5 as string,_

                     YourData6 as string,_

                     YourData7 as string,_

                     YourData8 as string,_

                     Type as string,_

                     Area as string) as Boolean

Returns TRUE if added/updated, else error in ErrorDesc

MachineID must be the Computer name of the machine calling the function

Datakey is you datakey given to you when you opened the account

  GetAllInList(LicenseID as long,_

                     ListID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     ExtraParameters as string) as String

Returns XML List if set, else error in ErrorDesc

ExtraParameters may be used to filter the results in future versions

   Returns:

<list>

<errordesc></errordesc>

<recordcount>2</recordcount>

<record>

            <yourid>531252</yourid>

            <yourdata1>My store at Wisbech</yourdata1>

            <yourdata2>Turn left at the polices station. <b>Phone 08512 251258</b></yourdata2>

            <yourdata3>ShowDetails.aspx?=829835</yourdata3>

            <yourdata4></yourdata4>

            <yourdata5></yourdata5>

            <yourdata6></yourdata6>

            <yourdata7></yourdata7>

            <yourdata8></yourdata8>

            <type></type>

            <area></area>

            <postcode>PE132XQ</Postcode>

            <longitude>2.3512126</longitude>

            <latitude>1.2162363</latitude>

            <dateadded>20070304</dateadded>

</record>

<record>

            <yourid>531253</yourid>

            <yourdata1>My store at Kings Lynn</yourdata1>

            <yourdata2>Turn right at the polices station. <b>Phone 08512 253522</b></yourdata2>

            <yourdata3>ShowDetails.aspx?=829833</yourdata3>

            <yourdata4></yourdata4>

            <yourdata5></yourdata5>

            <yourdata6></yourdata6>

            <yourdata7></yourdata7>

            <yourdata8></yourdata8>

            <type></type>

            <area></area>

            <postcode>PE132XQ</postcode>

            <longitude>2.3542126</longitude>

            <latitude>1.2122233</latitude>

            <dateadded>20070304</dateadded>

</record>

</list>

 

  GetEntryFromList(LicenseID as long,_

                     ListID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     YourID as long) as String

Returns XML List if set, else error in ErrorDesc

 





+ Functions to Manage Templates Click this line for more information

SOAP Functions to Manage Nearest Templates:


The Templates drive the system, please look at the web demo page and tick "show template information" to examine how the system works.  [Web Demo Page]   [Template example]

SOAP Service URL:

http://www.simplylookupadmin.co.uk/webservicenearest.asmx

 

  SetTempate(LicenseID as long,_

                     TemplateID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     HeaderTemplate as string,_

                     DetailsTemplate as string,_

                     FooterTemplate as string,_

                     NextPageURL as string) as Boolean

 

  SetTempateWithGoogleDetails(LicenseID as long,_

                     TemplateID as long,_

                     Password as string,_

                     ByRef ErrorDesc as string,_

                     HeaderTemplate as string,_

                     DetailsTemplate as string,_

                     FooterTemplate as string,_

                     NextPageURL as string,_

                     MapIconsLocation as string,_

                     ShowTargetPin as boolean,_

                     ShowShadowOnPins as boolean,_

                     UseNumberedPins as boolean,_

                     UseTypeFilterPins as boolean,_

                     MapTargetPin_Details as string,_

                     Target_PinIcon_Details as string,_

                     Included_PinIcon_Details as string,_

                     FilteredOut_PinIcon_Details as string,_

                     MapTabTemplate1 as string,_

                     MapTabTemplate2 as string,_

                     MapTabTemplate3 as string,_

                     MapTabTemplate4 as string,_

                     ExtraFlags as string) as Boolean

Returns TRUE if set template for List, else error in ErrorDesc

The HeaderTemplate,DetailsTemplate and FooterTemplate can be any text which contains a series of tags, which will be replaced by the data in your table

Header Tags for use in Templates


For DetailsTemplate:

Tag Description

_yourid_

Replaced with Your ID,from the database

_yourdata1_

Replaced with Your Data1, from the database

_yourdata2_

Replaced with Your Data2, from the database

_yourdata3_

Replaced with Your Data3, from the database

_yourdata4_

Replaced with Your Data4, from the database

_yourdata5_

Replaced with Your Data5, from the database

_yourdata6_

Replaced with Your Data6, from the database

If using filters then can stop details being shown on pin if "NODETAILS"

_yourdata7_

Replaced with Your Data7, from the database

_yourdata8_

Replaced with Your Data8, from the database

_postcode_

Replaced with postcode,from the database

_longitude_

Replaced with Longitude,from the database

_latitude_

Replaced with Latitude,from the database

_km_ or _mile_

Distance from target

_dateadded_

Replaced with date added to the database

_rank_

Replaced with rank count for page of results

_type_

Replaced with type

_alphcount_

Replaced with A,B,C... count for page of results

For HeaderTemplate and FooterTemplate:

Tag Description

_recordcount_

Replaced with record count of results found in list.

_pincount_

Replaced with map pin count of results found in list.

_listcount_

Replaced with number of items in list on current page

_nopages_

Replaced with number of pages of results

_pageno_

Replaced with page number

_pageselection_ 

Replaced with link to pages [1] [2] [3]...

_previouspage_

Replaced with link to previous page if on page 2 onwards

_nextpage_

Replaced with link to next page if on page 1 to last but one.  See example below...

For NextPageURL:

Tag Description

_targetpostcode_

Replaced with Target Postcode in link

_page_

Replaced with Target Page in link 

See example below...

All must be in lower case

All the other parameters are used by mapping functions, and can be left blank if map is not needed.

IconsLocation is optional, but should point to web directory where pin icons can be found.   Icons should be named "icon" & type & ".png" so different icons can be used for different types of nearest property. Such as schools etc.  If blank will use default Google pin.  If type is not used you should give a "icon.png", and "shadicon.png" if shadows are on.    [See Example 5 shows type icons]

if ShowTargetPin then displays a ping for the Target Postcode "icontarget.png", and "shadicontarget.png" if shadows are on.     [See Example 2 and 3]

TargetPin_Details show if user clicks on pins.  Leave blank if not needed.  Click on target pin in example 2 and 3.

ShowShadowOnPins, if true then uses shadow pins.  Uses the same names as other icon with prefix "shad". Therefore "icontarget.png" becomes "shadicontarget.png".  If using filter on types then icon for shadow is called "shadiconfilterout.png".  All examples use shadows.

UseNumberedPins if True then uses "iconx.png" where x is the rank in the results.  This allows you to create pins representing 1-10 (or A-Z) and display them which match the text results (using _rank_ or

_alphcount_ tag to match).  [See Example 4 and 5]

Target_PinIcon_Details,Included_PinIcon_Details and FilteredOut_PinIcon_Details 

should be a list of co-ordinates for each type of icon.  IconsSizeX, IconSizeY, ShadowSizeX, ShadowSizeY, IconAnchorX, IconAnchorY, InfoWindowAnchorX and InfoWindowAnchorY

TabTemplate1 template to merge with your data to show details when user clicks on pin.   Leave blank to just show pins.   [See Example 2]

TabTemplate2-4 extra tabs on pins.