hex c
hex c

Reputation: 745

C# Code to list locations within certain location

I have a list of locations and I want to be able to enter a location and for locations within X mile radius of my specified location to populate in a data grid. Does anyone have any experience on writing the code for C# to be able to accomplish this?

I do have the latitude and longitude for my data.

Any help would be greatly appreciated! Thanks!

I figured it out! This seems to work. I enter a location it then compares that lat/long to the remaining 1300 fields shows the data in a table. IF anyone has any suggestions to condensing the code that would be amazing!!

private void btnSubmit_Click(object sender, EventArgs e)
    {


        if (comboBox1.SelectedIndex != 0)
        {
            lblMsg.Text = "Please select Location no From DropDown for Radius search";
            return;
        }
        else
        {
            if (txtRadius.Text == "")
            {
                lblMsg.Text = "Please enter radius value";
                return;
            }

            double radius = Convert.ToDouble(txtRadius.Text);
            searchData = txtLocNo.Text;
            str = "Select latitude,longitude from details where locno='" + searchData + "'";
            con.Open();
            cmd = new OleDbCommand(str, con);
            dr = cmd.ExecuteReader();

            if (!dr.HasRows)
            {
                lblMsg.Text = "No Records Found";
                dataGridView1.Visible = false;
                con.Close();
                return;
            }
            else
            {
                dr.Read();
                double lat1 = dr.GetDouble(0);
                double lng1 = dr.GetDouble(1);
                double lat2, lng2,dist;
                String loc="";

                lblMsg.Text = lat1 + "  " + lng1;
                dr.Dispose();
                str = "Select locno,latitude,longitude from details";
                cmd = new OleDbCommand(str, con);
                dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    loc=dr.GetString(0);
                    lat2 = dr.GetDouble(1);
                    lng2 = dr.GetDouble(2);
                    dist=calculateDistance(lat1,lng1,lat2,lng2);

                    str = "Update details set distance=" + dist + " where locno='"+loc+"'";
                    cmd = new OleDbCommand(str, con);
                    cmd.ExecuteNonQuery();

                }

                str = "select * from details where distance<=" + radius;
                con.Close();
                lblResult.Text = "Radius Search Results";
                fillGrid();
            }


        }
    }

    private double calculateDistance(double lat1,double lng1,double lat2,double lng2)
    {
        double x= 69.1 * (lat2 - lat1); 
        double y = 69.1 * (lng2 - lng1) * Math.Cos(lat1 / 57.3);

        double dist = Math.Sqrt(x * x + y * y);
        dist = Math.Round(dist, 2);
        return dist;

    }

    private double calculateDistance1(double lat1, double lng1, double lat2, double lng2)
    {
        double theta = lng1 - lng2;
        double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) +
            Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) *
            Math.Cos(deg2rad(theta));
        dist = Math.Acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        dist = Math.Round(dist, 2);
        return dist;
    }

    private double deg2rad(double deg)
    {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(double rad)
    {
        return (rad / Math.PI * 180.0);
    }

    private void txtRadius_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar != '0' && e.KeyChar != '1' && e.KeyChar != '2' && e.KeyChar != '3' &&
            e.KeyChar != '4' && e.KeyChar != '5' && e.KeyChar != '6' && e.KeyChar != '7' &&
            e.KeyChar != '8' && e.KeyChar != '9' && e.KeyChar != '.' && e.KeyChar!= Convert.ToChar(8))
        {
            e.Handled = true;
        }

Upvotes: 1

Views: 2227

Answers (3)

noobob
noobob

Reputation: 532

I had such task before but I solved it using an SQL function, which may be not your scenario but for anyone interested:

-- =============================================
-- Description: Return list of myTable within provided radius and location
-- =============================================
ALTER PROCEDURE [dbo].[proc_] 
    @lattitude DECIMAL(9, 6) = 0 ,
    @longitude DECIMAL(9, 6) = 0 ,
    @radius DECIMAL(18, 3) = 0
AS 
    BEGIN

        DECLARE @point GEOGRAPHY = GEOGRAPHY::Point(@lattitude, @longitude, 4326)

        SELECT  *
        FROM    myTable a
        WHERE   @point.STDistance(GEOGRAPHY::Point(a.Lattitude, a.Longitude, 4326)) <= @radius *2

    END

myTable columns contain:

Lattitude   decimal
Longitude   decimal

Note: SQL version is 2008 or higher.

A helpful link

Hope this help

Upvotes: 0

I4V
I4V

Reputation: 35353

You can use System.Device.Location.GeoCoordinate class

var loc = new GeoCoordinate(0, 0);
var dist = loc.GetDistanceTo(new GeoCoordinate(1, 1));

EDIT

The data set has 1300 rows

1300-rows dataset is too small. You can use any method, no need for optimizations (You don't even need a db. You can load all of your data to memory)

double radius = ....
List<GeoCoordinate> locations = .....;
var result = locations.Where(l=>l.GetDistanceTo(loc)<radius);

Upvotes: 4

ppetrov
ppetrov

Reputation: 3105

It all depends on how fast your algorithm has to be and how much locations you have.

You can do it by iterating through all your locations and only keep the ones that are within your radius, but if you have a lot of locations this will be slow.

Another way is to put your locations into linked lists, and on each node have a list of distances to the next ones, this could speed up the search. Also you can put these nodes in areas so that you can quickly find which node to start your search with.

Then if your question is only about calculating a distance between two locations, see @I4V's answer

Upvotes: 1

Related Questions