0

I need to create a JavaScript database of shops that will sort by the user's specified postcode. The limitations are that this needs to run entirely in the browser. After the user has input their postcode, I need to display a list of the nearest first, displaying the shop name, town, county, and distance in miles, with a link to another page for more details.

I have thought of displaying every shop on a google map and somehow using it to calculate the distance between the user postcode and the nearest shop, though not sure if this is possible?

I have also thought of using TaffyDB to create the in-browser database:

    var shops = TAFFY([{
        name: "Spaday",
        town: "Canterbury",
        county: "Kent",
        postcode: "CT1 1FG"
    }, {
        name: "BodySan",
        town: "Southend-on-Sea",
        county: "Essex",
        postcode: "SS1 1PG"
    }]);

But the crucial point is that I have no idea how to implement the postcode sort, would be ideal if the user could also sort within a specified range e.g. 10 miles etc. I do not need extreme distance accuracy but the more accurate the better.

What would be the best way to sort the shops by postcode in the browser? And might there be a better way of creating this in-browser shop database?

Any help would be greatly appreciated.

  • 1
    without some sort of co-ordinates in the data, there's no way to sort by distance .... and sorting postcodes, you mean alphbetically? – Jaromanda X Aug 26 '15 at 11:55
  • You can use standard array.sort to sort the postcodes. For the distances, you can indeed use google maps to find all locations. Add a field setting the distance to each shop object, so you can sort those as well. If you don't want to calculate the distances real time, you can precalc the distance of each shop to a fixed location and then use basic maths to calculate the distance between two places. – Shilly Aug 26 '15 at 12:07

2 Answers2

0

I have done something similar in the past. In my scenario, I've used a mysql database where I specified all the information I needed to display (pay attention to not generate a javascript too big) and I haven't implemented the possibility to find something in a specified radius, only the closest thing. To calculate the distance (knowing from the beginning the coordinates of my points, which in your scenario are the shops) I got the Latitude and Longitude of the customer's postcode using the Here Maps javascript reverse geocoding API and then you can choose to calculate by yourself the distance or using another API (I calculated by myself the distance, cycling every point on the map with the customer coordinates and saving the closest ones... but you can decide whatever you want, I think that there are also API to do this).

Hope this helps

P.S. I choose the Here Maps API instead of the Google Maps one because I needed to have more freedom to manipulate the map

tabris963
  • 110
  • 2
  • 14
0

If you really need it in browser you might be able to do something with this little snippet I wrote offhand just because I liked the challenge ;-)

You can search by town, county, zipcode part, full zipcode, partial zipcode

It's pretty easy stuff, hopefully you can modify it to suit your needs :-)

function PhysicalLocation(name,postcode,town,county) {
  this.name = name;
  this.postcode = postcode;
  this.town = town;
  this.county = county;
}
function SearchBase() {
  this.postcode = {};
  this.town = {};
  this.county = {};
  
  }
SearchBase.prototype.TOWN = 1;
SearchBase.prototype.POSTCODE = 2;
SearchBase.prototype.COUNTY = 3;

function PostcodeRegion(key) {
   this.isRegion = true;
   this.regionKey = key;
}
SearchBase.prototype.feed = function(arrayList){
  for(item in arrayList) {
    var current = arrayList[item];
    var split = current.postcode.split(' ');
    var first = split[0];
    var last = split[1];
    if(typeof this.postcode[first] === 'undefined') {
      this.postcode[first] = new PostcodeRegion(first);
    }
    if(typeof this.postcode[first][last] === 'undefined') {
        this.postcode[first][last] = []; 
    }
    this.postcode[first][last].push(current);
    if(typeof this.county[current.county] === 'undefined') {
       this.county[current.county] = [];
    }
    this.county[current.county].push(current);
    if(typeof this.town[current.town] === 'undefined') {
       this.town[current.town] = [];
    }
    this.town[current.town].push(current);
  }
}
SearchBase.prototype.isPostcodeRegion = function(what) {
  return what instanceof PostcodeRegion;
  }
SearchBase.prototype.seek = function(part,searchtype) {
  if(typeof searchtype === 'undefined') {
    throw new Error("Yea, if you could define a searchtype, that'd be great");
    }
  if(searchtype === this.TOWN) {
    return this.seekByTown(part);
  }
  if(searchtype === this.COUNTY) {
     return this.seekByCounty(part);
    }
  if(searchtype === this.POSTCODE) {
    return this.seekByPostcode(part);
    }
  throw new Error("unsupported search type supplied");
 }
SearchBase.prototype.seekByCounty = function(part) {
  var list = [];
  jQuery.map(this.county,function(entry,key) { 
    if(key.startsWith(part)) {
      list = list.concat(entry);
    }
  });
  return list;
}
SearchBase.prototype.seekByTown = function(part) {
  var list = [];
  jQuery.map(this.town,function(entry,key) { 
    if(key.startsWith(part)) {
      list = list.concat(entry);
    }
  });
  return list;
}
SearchBase.prototype.seekByPostcode = function(part) {
var arr = ((part.indexOf(' ') > -1) ? part.split(' '):[part]);
var list = [];
  
jQuery.map(this.postcode,function(entry,key) { 
    if(key.startsWith(arr[0])) {
       if(arr[0].length == 3 && arr.length > 1 && typeof arr[1] !== 'undefined' && arr[1].length > 0) {
          $.map(entry,function(entry2,key2){
            
               if(key2.startsWith(arr[1])) {
                  list = list.concat(entry2);
               }
           });
        }
        else {
           list.push(entry);
        }
    }
});
return list;
}
allcodes = [new PhysicalLocation('cadbury','aaa bbb','somewhere','conwall'),new PhysicalLocation('whoa', 'aaa ccc', 'london', 'where')];
/**
 * Create our database 
 **/
searchbase = new SearchBase();

/**
 * Seed with data
 **/
searchbase.feed(allcodes);

/**
 * Test if it works
 **/
console.log(searchbase.seek('con',searchbase.COUNTY) );
var search = searchbase.seek('a',searchbase.POSTCODE) ;
for(part in search) {
 if(searchbase.isPostcodeRegion(search[part])) {
    console.log("This is a region, containing multiple postcode parts",search[part]);
  }
  else {
    console.log("normal postcodes",search[part]);
  }
}
console.log(searchbase.seek('aaa',searchbase.POSTCODE) );
console.log(searchbase.seek('aaa b',searchbase.POSTCODE) );
console.log(searchbase.seek('lo',searchbase.TOWN) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Tschallacka
  • 27,901
  • 14
  • 88
  • 133