Jump to content

Determine corner XY coordinates


Go to solution Solved by mac_gyver,

Recommended Posts

I am trying to determine the four corner coordinates of a list. Any ideas?

 

48.010918880032534,-102.27871447619208,
48.007298546092386,-102.27871873313035,
48.007300404087175,-102.28410804755288,
48.007302263082124,-102.28949736197535,
48.007304121076913,-102.29488670439923,
48.007305979071589,-102.30027601882199,
48.010925506717513,-102.30027931864152,
48.014545007363211,-102.30028259146059,
48.018163867996407,-102.3002842242235,
48.023143739025727,-102.30028731751861,
48.023143709229146,-102.29967535036019,
48.023140964347476,-102.29489150234963,
48.023137856666608,-102.28949565918271,
48.023137825974516,-102.28890660889158,
48.023135053987971,-102.28409987201547,
48.023131946306933,-102.2787040848512,
48.018158490915084,-102.27870810340568,
48.014539184972818,-102.27871024825487,
48.010918880032534,-102.27871447619208

 

 

 

post-146636-0-40244900-1365721037_thumb.jpg

Link to comment
https://forums.phpfreaks.com/topic/276844-determine-corner-xy-coordinates/
Share on other sites

It will always be rectangular. It's just section corners. The min/max XY is what I'm using now, and it's close but not 100% accurate. If you look at the picture attached, how could the top right corner be determined from a list? If I did min/max to the XY, I would end up with 5,0 for the coordinate when it should actually be 4, -1. 

Your image is not to scale. And if I remember by geometry correctly, X is specified first and represents the horizontal axis; Y is second and represents the vertical axis. The MIN(X) then represents the left side of the box. The top of that box is at MAX(Y) and the bottom of the box is at MIN(Y). MAX(X) represents the right side of the box, with the same top and bottom.

 

You have to take MIN(X) independent of the Y values, same with MAX(X) and the same with Y (with respect to X).

Yeah, the Y is vertical. I just see a lot of people refer to coordinates as XY. The picture is a ghetto POS I slapped into fireworks to wrap my mind around this. The 1,-7 dot isn't even in the right spot lol.

 

The problem is that my box isn't a square. It's a rhombus. If you use the example coordinates, the arrays would be:

 

Latitude (

5,

4,

1,

0)

Longitude (

-6,

-7,

-1,

0)

 

 

If I take the max X and max Y i'll 5 and 0, but the actual top right corner is 4,-1. 

I'm saying I don't want the *top right*. I'm saying I need the exact corners. The XY coordinates give a list of all the coordinates a section from the BLM. If I simply take the highest latitude and highest longitude, I won't get the exact corner because the top left corner might be at a higher y value, so if I use the highest Y value for the top right corner, I end up with a wrong number.

 $String = '48.010918880032534,-102.27871447619208,48.007298546092386,-102.27871873313035,48.007300404087175,-102.28410804755288,48.007302263082124,-102.28949736197535,48.007304121076913,-102.29488670439923,48.007305979071589,-102.30027601882199,48.010925506717513,-102.30027931864152,48.014545007363211,-102.30028259146059,48.018163867996407,-102.3002842242235,48.023143739025727,-102.30028731751861,48.023143709229146,-102.29967535036019,48.023140964347476,-102.29489150234963,48.023137856666608,-102.28949565918271,48.023137825974516,-102.28890660889158,48.023135053987971,-102.28409987201547,48.023131946306933,-102.2787040848512,48.018158490915084,-102.27870810340568,48.014539184972818,-102.27871024825487,48.010918880032534,-102.27871447619208';$Exp = explode(',',$String);   if(is_array($Exp)) {$C = 1;foreach($Exp as $Exp2) {if(!empty($Exp2)) {if($Exp2 > 0) {$Latitude[] = $Exp2; } else {$Longitude[] = $Exp2; }}}}$MaxLong = max($Longitude);$MinLong = min($Longitude);$MaxLat = max($Latitude);$MinLat = min($Latitude);
 
// SECOND IDEA!
array_multisort($Latitude, SORT_ASC, $Longitude, SORT_DESC);
// NO, SAME ISSUE
 
 
 

 

 

This doesn't work as I explained, since it gathers the highest values when in reality, one corner might have a Y value 10, the other may have a Y value of 8 (because it's a mile a part, and township/range/sections are not exactly square).

Edited by caleb87

it might help if you state what it is you are trying to accomplish, rather than stating what you are doing that doesn't produce the result you want.

 

what i think you are trying to do is use a search radius and add/subtract that radius to the starting point's lat/longitude to quick find all the points within that bounding square, then to actually calculate the distance from the starting point to those quick find points to remove any that are outside the search radius.

I stated in my first post "I am trying to determine the four corner coordinates of a list. Any ideas?". The prior suggestions don't determine the actual coordinates. They get ballpark coordinates, which end up producing an exact square. I want the exact corner coordinates which typically produces a rhombus. 

 

I am sending a request to the Bureau of Land Management for a tract or section coordinates. The response includes all the coordinates within the section as well (quarters, and quarter quarters). I don't want those, but the BLM doesn't always return the exact same number of coordinates, so I want to determine the four corners regardless of the response. Sometimes I'll combine multiple sections (a section is 1 mile, so it could be 4 square miles, or 2 miles by 1 mile). I use the coordinates to work with other database data that is in coordinates such as finding objects that are within the section. 

You need to figure out how you define the "four" corners". That's an idea your brain is recognizing but a computer needs to be told specific rules.

 

What if you have the points:

1,1

2,0

2,3

1,4,

3,3

 

What are the "four corners"

LOL Barand. :) I must have messed up writing it because I drew something much different on paper. Hang on.

 

Change 2,3 to -1,3.

 

BTW, how are you going to handle plots that don't have four corners? I almost bought this place (but the house had termites). This property is a triangle. (The major highway cuts through at an angle to what the original lots all were, so there's lots of triangle lots.)

 

https://maps.google.com/?ll=33.326714,-96.491447&spn=0.0019,0.004128&t=h&z=19

 

I also some some 5-sided lots out there.

 

Edit: Here's a 5 pointed one.

https://maps.google.com/maps?hl=en&ll=33.190146,-96.643148&spn=0.000952,0.002064&sll=33.190169,-96.643066&sspn=0.000956,0.002064&t=h&z=20

Edited by Jessica

You need to figure out how you define the "four" corners". That's an idea your brain is recognizing but a computer needs to be told specific rules.

 

 

exactly what i was going to write. without a state-able rule, there's no way to write any code to do it.

 

how does this sound - form the prefect rectangle using the min/max x/y values then find the distance between those 4 "prefect" corners and the actual points and the closest point to each of the "perfect" corner points is the corner point you are trying to find?

Barand would be right, all but 2,3.

 

I think you both get what I want, but see attached image. Red square is what's produced using min/max. I need the blue square. There will always be 4 coordinates that make up a square/rectangle more or less. 

 

I want the exact coordinates, because when I combine two sections vertically, I should end up with an approx. 2x1 mile tract of land. The method I'm using now is min/max, but it produces a 2.1x1.25 mile tract more or less. If I go out four sections, it really gets bad.

post-146636-0-59974500-1365789351_thumb.jpg

exactly what i was going to write. without a state-able rule, there's no way to write any code to do it.

 

how does this sound - form the prefect rectangle using the min/max x/y values then find the distance between those 4 "prefect" corners and the actual points and the closest point to each of the "perfect" corner points is the corner point you are trying to find?

 

 

That's a good idea. I'm going to try something like this.

Just for S&G, ya'll can checkout this site: http://www.darrinward.com/lat-long/

 

And put in this value: 

 

48.010918880032534,-102.27871447619208
48.007298546092386,-102.27871873313035
48.007300404087175,-102.28410804755288
48.007302263082124,-102.28949736197535
48.007304121076913,-102.29488670439923
48.007305979071589,-102.30027601882199
48.010925506717513,-102.30027931864152
48.014545007363211,-102.30028259146059
48.018163867996407,-102.3002842242235
48.023143739025727,-102.30028731751861
48.023143709229146,-102.29967535036019
48.023140964347476,-102.29489150234963
48.023137856666608,-102.28949565918271
48.023137825974516,-102.28890660889158
48.023135053987971,-102.28409987201547
48.023131946306933,-102.2787040848512
48.018158490915084,-102.27870810340568
48.014539184972818,-102.27871024825487
48.010918880032534,-102.27871447619208

 

 

And see all the coordinates actually pulled from the BLM. There are sections along the border of townships called "Fractional Sections", which reduce/add acreage to a section to account for the curvature of the earth. These sections are generally what cause me issues since they are less square shaped. If I get 4 fractional sections stacked up, the variance is horrible.

 

My plan was to use the min/max values to find potential matches, then use the exact coordinates and math to determine if the object is actually inside the tract of land. I'm going to try to determine the coordinate with the min/max values, though I still think there's a better way lol.

 

Thanks for all the replies!

 

 

Oh and no... the website is not mine. It's just the only one I can find that I can easily add a list of XY values. Can't believe how few there are that actually work.

Edited by caleb87
  • Solution

test code that implements the suggestion i made -

<?php
$String = '48.010918880032534,-102.27871447619208,48.007298546092386,-102.27871873313035,48.007300404087175,-102.28410804755288,48.007302263082124,-102.28949736197535,48.007304121076913,-102.29488670439923,48.007305979071589,-102.30027601882199,48.010925506717513,-102.30027931864152,48.014545007363211,-102.30028259146059,48.018163867996407,-102.3002842242235,48.023143739025727,-102.30028731751861,48.023143709229146,-102.29967535036019,48.023140964347476,-102.29489150234963,48.023137856666608,-102.28949565918271,48.023137825974516,-102.28890660889158,48.023135053987971,-102.28409987201547,48.023131946306933,-102.2787040848512,48.018158490915084,-102.27870810340568,48.014539184972818,-102.27871024825487,48.010918880032534,-102.27871447619208';
$Exp = explode(',',$String);
if(is_array($Exp)){
    $C = 1;
    foreach($Exp as $Exp2){
        if(!empty($Exp2)){
            if($Exp2 > 0){
                $latitude[] = $Exp2;
            } else {
                $longitude[] = $Exp2;
            }
        }
    }
}

$m['maxlat'] = max($latitude);
$m['minlat'] = min($latitude);
$m['maxlong'] = max($longitude);
$m['minlong'] = min($longitude);

// the prefect corners
$c[1] = array($m['minlat'],$m['minlong']);
$c[2] = array($m['maxlat'],$m['maxlong']);
$c[3] = array($m['minlat'],$m['maxlong']);
$c[4] = array($m['maxlat'],$m['minlong']);

function distance($lat1, $lon1, $lat2, $lon2, $unit) {
  $theta = $lon1 - $lon2;
  $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
  $dist = acos($dist);
  $dist = rad2deg($dist);
  $miles = $dist * 60 * 1.1515;
  $unit = strtoupper($unit);
  if ($unit == "K") {
    return ($miles * 1.609344);
  } else if ($unit == "N") {
      return ($miles * 0.8684);
    } else {
        return $miles;
    }
}

foreach($c as $corner=>$arr){
    foreach($latitude as $key=>$lat){
        $dist = abs(distance($arr[0],$arr[1],$lat,$longitude[$key], "M"));
        $result[$corner]["$dist"][] = array($lat,$longitude[$key]);
    }
    ksort($result[$corner]);
}

echo "The four corners found are:<br>";
foreach($result as $arr){
    $first = array_shift($arr);
    echo $first[0][0] .' '. $first[0][1] . '<br>';
}

 

test code that implements the suggestion i made -

<?php
$String = '48.010918880032534,-102.27871447619208,48.007298546092386,-102.27871873313035,48.007300404087175,-102.28410804755288,48.007302263082124,-102.28949736197535,48.007304121076913,-102.29488670439923,48.007305979071589,-102.30027601882199,48.010925506717513,-102.30027931864152,48.014545007363211,-102.30028259146059,48.018163867996407,-102.3002842242235,48.023143739025727,-102.30028731751861,48.023143709229146,-102.29967535036019,48.023140964347476,-102.29489150234963,48.023137856666608,-102.28949565918271,48.023137825974516,-102.28890660889158,48.023135053987971,-102.28409987201547,48.023131946306933,-102.2787040848512,48.018158490915084,-102.27870810340568,48.014539184972818,-102.27871024825487,48.010918880032534,-102.27871447619208';
$Exp = explode(',',$String);
if(is_array($Exp)){
    $C = 1;
    foreach($Exp as $Exp2){
        if(!empty($Exp2)){
            if($Exp2 > 0){
                $latitude[] = $Exp2;
            } else {
                $longitude[] = $Exp2;
            }
        }
    }
}

$m['maxlat'] = max($latitude);
$m['minlat'] = min($latitude);
$m['maxlong'] = max($longitude);
$m['minlong'] = min($longitude);

// the prefect corners
$c[1] = array($m['minlat'],$m['minlong']);
$c[2] = array($m['maxlat'],$m['maxlong']);
$c[3] = array($m['minlat'],$m['maxlong']);
$c[4] = array($m['maxlat'],$m['minlong']);

function distance($lat1, $lon1, $lat2, $lon2, $unit) {
  $theta = $lon1 - $lon2;
  $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
  $dist = acos($dist);
  $dist = rad2deg($dist);
  $miles = $dist * 60 * 1.1515;
  $unit = strtoupper($unit);
  if ($unit == "K") {
    return ($miles * 1.609344);
  } else if ($unit == "N") {
      return ($miles * 0.8684);
    } else {
        return $miles;
    }
}

foreach($c as $corner=>$arr){
    foreach($latitude as $key=>$lat){
        $dist = abs(distance($arr[0],$arr[1],$lat,$longitude[$key], "M"));
        $result[$corner]["$dist"][] = array($lat,$longitude[$key]);
    }
    ksort($result[$corner]);
}

echo "The four corners found are:<br>";
foreach($result as $arr){
    $first = array_shift($arr);
    echo $first[0][0] .' '. $first[0][1] . '<br>';
}

 

 

Wow. More than I expected  :happy-04:  Thanks mac!

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.