I have a list of location nodes, each with a zip code field. I need to be able to search by a zip code and have all the locations that fall within a radius near that zip code show up, even if the search query isn't an exact match to the zip in the field itself.
Does anyone know the best way to go about this using Umbraco 8? I don't want to install any packages or anything, if such things exist.
firstly you will need to find the geocordinates of your zip code (long/lat) you will probably need to make an api call to some external source to do this (google perhaps)
once you have the long/latitude you can use sql to find the distance between locations like below
SELECT (geography::Point({referenceLocation.Longitude},{referenceLocation.Latitude},4326)).STDistance(geography::Point(otherlocation.Longitude, otherlocation.Latitude,4326)) as distance
You can also do it using the System.Data.Spatial.DbGeography library, but I had issues with that on my server, so used sql instead as it was pretty quick at calculating the distances.
Whatever you do it won't be that quick :) If at all possible, you would be better of storing the long/latitude along with your zip codes so you don't need to get them for your search.
no, that is how to get the distance between two points.
There is no simple concept of find me the nearest location. You will need to use some sort of api (googlemaps etc) and quite a bit of code to accomplish it.
I'm assuming you wish to do something similar to this
I have a table of locations, on the form you can enter a postcode and distance and it returns all the locations within that distance.
as I said, you will need to use something to convert your zip code into a latitude/longitude pair before you can do anything.
Would I still need a Google Maps API if I don't want to involve a map at all?
I just want the locations to show up as links on the page, as they exist as nodes/pages in umbraco. I don't want them to show up on a map or as markers on a google map.
Now - I know that Stockport borders Manchester so I know that I want a search in Greater Manchester to return the first two but not North London. You have to think how can an algorithm do this?
The only real answer is to get Latitude and Longitude for the post codes (either get the editor to enter them or look them up from Google Maps / Open Street Maps etc?) and then do a geospatial search.
There might be something you could do with Zip codes to look for the first x digits but UK postcodes are based around the sorting offices NOT on towns / cities / counties. I can't speak for other countries postal codes but I'd imagine similar challenges.
Okay, so there likely isn't a built-in or purely backend method for finding the geo coordinates based off the zip in Umbraco, right? I would have to have the longitude/latitude as a field on the location node.
But what about actually making a search field find the correct locations? I don't know what the actual code that runs when that "search" button is clicked by a site visitor will have to be.
So basically you need the lat and longs stored in your content nodes and then when a search is made you need to be able to convert that zip / postal code to lat and long (usually Google places api or similar) and then run this code to filter results to the nearest X Km of the search place.
I've done it before but it's not code I can share unfortunately.
There are also several ways to do that, I am using simple SQL queries to return the distance between two points, that was the code I posted earlier.
However I decided to store my location data (lat + long in a custome table rather than as content because it made it simpler to query the distance data (I just added the id of the content item to link it's longitude and latitude record.
You can then simple do the following to get all records within X miles
public static Dictionary<Guid, double> FindNearestTo(GeoCoordinate referenceLocation)
{
var locations= new Dictionary<Guid, double>();
var sql = $@"
SELECT ic.LocationId, (geography::Point({referenceLocation.Longitude},{referenceLocation.Latitude},4326)).STDistance(geography::Point(ic.Longitude, ic.Latitude,4326)) as distance
from LocationCache ic
WHERE (geography::Point({referenceLocation.Longitude},{referenceLocation.Latitude},4326)).STDistance(geography::Point(ic.Longitude, ic.Latitude,4326)) < 16044
WHERE distance < X";
using (var scope = Current.ScopeProvider.CreateScope(autoComplete: true))
{
var database = scope.Database;
locations= database.Dictionary<Guid, double>(sql);
}
return locations;
}
referenceLocation is the long/latitutude gepoint object for the postcode that the search enters, ic.LocationId is the guid for an umbraco content item(the location)
there is also a .Net spatial library (that is also tied to sql however) and although worked great on my dev machine errored on the server which is why I switched to a sql query.
There may be other libraries available, i didn't really look myself.
I also do not store my location
Sorry, just about everything you guys are showing to help me (and I thank you for the attempts!) is throwing errors I can't figure out how to fix. There must be something in my site setup that's missing, but I don't know what it is. I'm creating totally new files to test the code rather than trying to adapt to what I have, but it's still not working.
It's always missing definitions/namespaces in the code, and I'm not familiar enough with anything to determine what needs to be changed so that those errors are cleared.
Search by zip/postal code?
I have a list of location nodes, each with a zip code field. I need to be able to search by a zip code and have all the locations that fall within a radius near that zip code show up, even if the search query isn't an exact match to the zip in the field itself.
Does anyone know the best way to go about this using Umbraco 8? I don't want to install any packages or anything, if such things exist.
firstly you will need to find the geocordinates of your zip code (long/lat) you will probably need to make an api call to some external source to do this (google perhaps)
once you have the long/latitude you can use sql to find the distance between locations like below
You can also do it using the System.Data.Spatial.DbGeography library, but I had issues with that on my server, so used sql instead as it was pretty quick at calculating the distances.
Whatever you do it won't be that quick :) If at all possible, you would be better of storing the long/latitude along with your zip codes so you don't need to get them for your search.
Sorry, I don't think I understand how this translates into a search? Is this just how to get the geocoordinates for the locations?
no, that is how to get the distance between two points.
There is no simple concept of find me the nearest location. You will need to use some sort of api (googlemaps etc) and quite a bit of code to accomplish it.
I'm assuming you wish to do something similar to this I have a table of locations, on the form you can enter a postcode and distance and it returns all the locations within that distance.
as I said, you will need to use something to convert your zip code into a latitude/longitude pair before you can do anything.
Would I still need a Google Maps API if I don't want to involve a map at all?
I just want the locations to show up as links on the page, as they exist as nodes/pages in umbraco. I don't want them to show up on a map or as markers on a google map.
Huw is on the money here.
Imagine you have three postcodes.
Now - I know that Stockport borders Manchester so I know that I want a search in Greater Manchester to return the first two but not North London. You have to think how can an algorithm do this?
The only real answer is to get Latitude and Longitude for the post codes (either get the editor to enter them or look them up from Google Maps / Open Street Maps etc?) and then do a geospatial search.
There might be something you could do with Zip codes to look for the first x digits but UK postcodes are based around the sorting offices NOT on towns / cities / counties. I can't speak for other countries postal codes but I'd imagine similar challenges.
Does that help you?
Okay, so there likely isn't a built-in or purely backend method for finding the geo coordinates based off the zip in Umbraco, right? I would have to have the longitude/latitude as a field on the location node.
But what about actually making a search field find the correct locations? I don't know what the actual code that runs when that "search" button is clicked by a site visitor will have to be.
You would need to wire up a surface controller / Umbraco Web API call and do a search on your nodes using Linq.
Create a helper function based on this should work nicely: https://stormconsultancy.co.uk/blog/storm-news/the-haversine-formula-in-c-and-sql/
So basically you need the lat and longs stored in your content nodes and then when a search is made you need to be able to convert that zip / postal code to lat and long (usually Google places api or similar) and then run this code to filter results to the nearest X Km of the search place.
I've done it before but it's not code I can share unfortunately.
Steve
There are also several ways to do that, I am using simple SQL queries to return the distance between two points, that was the code I posted earlier.
However I decided to store my location data (lat + long in a custome table rather than as content because it made it simpler to query the distance data (I just added the id of the content item to link it's longitude and latitude record.
You can then simple do the following to get all records within X miles
referenceLocation is the long/latitutude gepoint object for the postcode that the search enters, ic.LocationId is the guid for an umbraco content item(the location)
there is also a .Net spatial library (that is also tied to sql however) and although worked great on my dev machine errored on the server which is why I switched to a sql query.
There may be other libraries available, i didn't really look myself. I also do not store my location
Sorry, just about everything you guys are showing to help me (and I thank you for the attempts!) is throwing errors I can't figure out how to fix. There must be something in my site setup that's missing, but I don't know what it is. I'm creating totally new files to test the code rather than trying to adapt to what I have, but it's still not working.
what sort of error are you getting?
It's always missing definitions/namespaces in the code, and I'm not familiar enough with anything to determine what needs to be changed so that those errors are cleared.
If you post some of the errors we may be able to point you in the right direction.
I know this isn't the answer you wanted initially, but why not just put a google maps picker on the doctype to get the coordinates and then use this: https://github.com/bjorn2404/jQuery-Store-Locator-Plugin
It will take you like an hour total...
If the number of "stores" is something that can be easily put into a json / xml file and served to each user this is a fantastic solution!
If you have tens of thousands of nodes you'll need something else but I bet Amir has given you an easy solution here!
I think this is what I'm going to end up using. Thanks!
Glad you got it sorted! I can vouch from experience that it can handle ~500 locations without noticeable latency.
is working on a reply...