In my previous tutorial, we implemented to save Geolocation (latitude, longitude) in Geography data type column in Sql Server. Now, we will get the nearest N places from the current geo-location of user.
Environment: VS2012,.NET Framework 4.5, ASP.NET Empty Website template, C#, SQL Server v11.0, Entity Framework 5.0 Database First approach.
HTML Structure:
Add a new Web Form and reference jQuery in head tag
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.js"></script>
Add following code
<form id="form1" runat="server"> <p id="message"></p> <asp:HiddenField ID="hdnLocation" runat="server" /> <asp:Button ID="btnSubmit" runat="server" Text="Get 5 Nearest Places" OnClick="btnSubmit_Click" /> <asp:GridView ID="GridView1" runat="server" CellPadding="3"></asp:GridView> <div id="map" style="width: 600px; height: 400px;"></div> </form>
Hidden field is used to save current user geographical position similar to previous post. On submit, Gridview and Map will display the nearest 5 places.
To Get Current User Geo-Location:
We use same HTML5 Geo-Location API to get current user geographical position.
$('[id*=btnSubmit]').prop('disabled', true); var currentLatLng; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition, showError); } else { $("#message").html("Geolocation is not supported by this browser."); } function showPosition(position) { currentLatLng = position.coords; var latlon = "Latitude" + currentLatLng.latitude + "," + "Longitude" + currentLatLng.longitude; $("#message").html(latlon); $("[id*=hdnLocation]").val(currentLatLng.longitude + " " + currentLatLng.latitude); $('[id*=btnSubmit]').prop('disabled',false); } function showError(error) { if (error.code == 1) { $("#message").html("User denied the request for Geolocation."); } else if (error.code == 2) { $("#message").html("Location information is unavailable."); } else if (error.code == 3) { $("#message").html("The request to get user location timed out."); } else { $("#message").html("An unknown error occurred."); } }
By default, submit button is disabled. It is enabled on getting current user geo-location.
Getting The Nearest Places:
First, I would recommend to read my previous post to get idea about database structure. I am using same scene here. The following code is to get the nearest 5 places:
var currentLocation = DbGeography.FromText("POINT(" + hdnLocation.Value + ")"); string[] latlng = hdnLocation.Value.Split(new char[]{' '}); using ( var context = new SampleDBEntities()){ var places = (from u in context.PlaceInfoes orderby u.Geolocation.Distance(currentLocation) select u).Take(5).Select(x => new { Name = x.Name, Address = x.Address, City = x.City, State = x.State, Latitude = x.Geolocation.Latitude, Longitude = x.Geolocation.Longitude });
Entity Framework 5 and above supports spatial type operations. Here we are doing order by distance from current location and take top 5 records in LINQ. EF5+ makes it very easy.
To Display Data In GridView:
//Bind GridView GridView1.DataSource = places.ToList(); GridView1.DataBind();
To Display Data In Map:
We serialize and assign marker points in javascript variable points from server side and on client side, this variable will be used to display markers
//Set points for map JavaScriptSerializer serializer = new JavaScriptSerializer(); var output = serializer.Serialize(places); ClientScript.RegisterClientScriptBlock(GetType(), "points", "var points = " + output + ";var currentLoc = { 'Latitude' : " + latlng[1] + ", 'Longitude':"+latlng[0] +" }", true); }
In above code, currentLoc variable is used to hold current geo-location of user.
on client side:
var map2, infoWindow; if (typeof points !== "undefined") { var mapOptions = { center: new google.maps.LatLng(points[0].Latitude, points[0].Longitude), zoom: 9, mapTypeId: google.maps.MapTypeId.ROADMAP }; infoWindow = new google.maps.InfoWindow(); map2 = new google.maps.Map(document.getElementById("map"), mapOptions); //marker for current location var marker = new google.maps.Marker({ position: new google.maps.LatLng(currentLoc.Latitude, currentLoc.Longitude), map: map2, icon: 'https://maps.google.com/mapfiles/kml/shapes/schools_maps.png' }); //marker for nearest places for (i = 0; i < points.length; i++) { var data = points[i] var myLatlng = new google.maps.LatLng(data.Latitude, data.Longitude); var marker2 = new google.maps.Marker({ position: myLatlng, map: map2, title: data.Name }); (function (marker2, data) { google.maps.event.addListener(marker2, "click", function (e) { infoWindow.setContent(data.Name); infoWindow.open(map2, marker2); }); })(marker2, data); } }
In above javascript code, current location is defined with different marker icon.
Output:
Conclusion:
We saw the application of Sql server Geography data type and good support of Entity framework which makes few lines of code to get the nearest N places done.
Enjoy EF !!
Thank u so much it’s works good, but the map is not showing! is there any solution