How convert wgs 84 to lat/long in SQL Server - sql

I having a little trouble figuring out how to convert between types of coordinates. I have a list of coordinate sets with the following description. I have been searching around and did find some code to do this, but it does not SQL Query.
"Coordinates are always in the WGS84 system. All coordinates a represented as Decimal values x and y.
An example:
Ellipsoid:
wgs84 (world geodetic system 1984)
UTM Zone:
39 - 48E to 54E
UTM Projection:
X, m: 702964.0000 -------> latitude : 27.7818550282488
Y, m: 3074740.0000 -------> longitude : 53.0598812425032
The query should be SQL Server Query.
Well, I need to convert these to long/lat
Anyone who can provide some code for doing this?
Here is a db<>fiddle.

You can probably use the UF_utm_to_lat() function from this previous answer.
Easting northing to latitude longitude

I haven't found suitable t-sql code for this, so I have finally developed a library in .NET to be called from transact sql
Converts WGS84/UTM coordinates to Latitude and Longitude
You can download it from github:
https://github.com/j-v-garcia/UTM2LATITUDE
usage:
SELECT dbo.UTM2LATITUDE(723399.51,4373328.5,'S',30) AS Latitude, dbo.UTM2LONGITUDE(723399.51,4373328.5,'S',30) AS Longitude
result:
39,4805657453054 -0,402592727245112
<param name="XUTM">pos UTM X</param>
<param name="YUTM">pos UTM Y</param>
<param name="LatBand">Latitude band grid zone designation letter (see http://www.dmap.co.uk/utmworld.htm) </param>
<param name="LongBand">Longitude band grid zone designation number (see http://www.dmap.co.uk/utmworld.htm) </param>

This T-SQL was adapted from some JavaScript code supplied by Xander Bakker at ESRI (replace [column_name] with your own geography shape field).
180.0 / PI() * (2.0 * ATAN(EXP(([column_name].Shape.STY / (2.0 * PI() * 6378137.0 / 2.0) * 180.0) * PI() / 180.0)) - PI() / 2.0) as Latitude, -- Convert Y to Latitude
([column_name].Shape.STX / (2.0 * PI() * 6378137.0 / 2.0) * 180.0) as Longitude, -- Convert X to Longitude
I spot checked numerous locations and they were all spot on.

Related

Given a long/lat, convert meters into longitude/latitude degrees

I have a longitude and latitude stored as a geometry with SRID 4326.
I want to make a line that is exactly 1000 meters long that is 90 degrees (to the right).
I know that the conversion from a longitudal/latitudal degree to a meter varies about where you are on the globe. That is why I will pass a reference long/lat that can be taken into consideration.
I am looking for something "good enough" that assumes that the distance you want will be no greater than 100 miles.
Given a long/lat and a meter distance of 1000 meters, return to me the size of the line long/lat degrees.
This question is specific to one example but I am looking for a general solution, because I have many functions that work upon "SRID Units" and the SRID I work with is long/lat (4326) but I always want to deal with meters and not degrees.
The hope is that I can call scaler function to convert the meters I want to the 4326 units.
Some hacks I have considered for finding X meters is converting the geometry into a geography and using the STBuffer(X) to make a circle with a radius equal to that of X, then create a long line that intersects the buffer and to find the point of the intersection, which will be the long/lat of exactly X meters away. This seems very hacky and inefficient but might be the most accurate
Edit:
To find the deltaX and deltaY the function is doing the the following:
DeltaX = Cos(#AngleRads) * #DistanceInDegrees;
DeltaY = Sin(#AngleRads) * #DistanceInDegrees;
I can supply #AngleRads and #DistanceInDegrees.
The problem is that #DistanceInDegrees has to match 4326 units (degrees). Is it even possible to find a #DistanceInDegrees that will correspond to 1000 meters no matter what angle is given?
When I use the formula
#DistanceInDegrees = (#Meters / 6371008.7714) * (180 / pi()) / cos(#Lat1 * pi()/180) and a angle of 90 degrees, then the length of the line is 1002 meters, close but not identically 1000.. If I use a degree of 45 the length of the line is 1191.67 meters.
If I understand your question, this can be done with a little math.
This also assumes the mean radius of the earth to be 6,371,008.7714 meters.
Example
Declare #Lat1 float = -37.786570
Declare #Lng1 float = 145.178179
Declare #Meters float = -1000
Select Lat1 = #Lat1
,Lng1 = #Lng1
,Lat2 = #Lat1
,Lng2 = #Lng1 + (#Meters / 6371008.7714) * (180 / pi()) / cos(#Lat1 * pi()/180)
Returns
The results can be validated here
After your EDIT, It seems you are looking for DISTANCE and BEARING
Here is a Table-Valued Function which may help
Example
Select * from [dbo].[tvf-Geo-Distance-Bearing](-37.786570,145.178179,1000,-45)
Returns
RetLat RetLng
-37.7802105711301 145.170133170589
Now, when I calculate the distance, I get 999.99999448737 meters
The Table-Valued Function If Interested
CREATE Function [dbo].[tvf-Geo-Distance-Bearing] (#Lat1 float,#Lng1 float,#Dist Float,#Degr float)
Returns #LatLng Table (RetLat float,RetLng Float)
As
Begin
Declare #Lat2 float,#Lng2 float,#eRad float = 6371008.7714
Select #Lat1 = RADIANS(#Lat1)
,#Lng1 = RADIANS(#Lng1)
,#Degr = RADIANS(#Degr)
Set #Lat2 = Asin(Sin(#Lat1) * Cos(#Dist / #eRad ) + Cos(#Lat1) * Sin(#Dist / #eRad ) * Cos(#Degr ))
Set #Lng2 = #Lng1 + Atn2(Sin(#Degr) * Sin(#Dist / #eRad ) * Cos(#Lat1), Cos(#Dist / #eRad ) - Sin(#Lat1) * Sin(#Lat2))
Insert Into #LatLng
Select Degrees(#Lat2)
,Degrees(#Lng2)
Return;
End

How to get lat and long from open street map

I want to get latitude and longitude from open street map in angular when I clicked on the location, but i can't , how I can do it??I used to get this from google map , but now i want to change it to open street map
You need to do it programmatically, there's a section here
https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
you need to know the tile position x/y that you are clicking on (in floating point) and the zoom level (z).
n = 2 ^ zoom
lon_deg = xtile / n * 360.0 - 180.0
lat_rad = arctan(sinh(π * (1 - 2 * ytile / n)))
lat_deg = lat_rad * 180.0 / π
Source: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
You can install JOSM place a singular node and in the bottom left corner of the application, there will be a latitude & longitude display.

How can I create SQL Server Geography polygons that are of a specific size?

I want to create a group of polygons for a city that are 80km x 80km. Given a starting Lat and Long, my thought is I can add 80km to that point so that I get 4 points to create the polygon.
(x,y) -> (x+80km, y) -> (x+80km, y+80km) -> (x, y+80km) -> (x,y)
Where I'm having difficulty is finding a way to calculate the point +80km. I've found the SQL Server Spatial Tools and there is a function
SqlGeography LocateAlongGeog(SqlGeography g, double distance)
But so far I haven't been able to figure out how to use it. I will continue to play with this but if there are any other approaches I can take, or if anyone knows how to properly use this function, I'd be grateful.
Longitude is a "great circle" measure, i.e. if you draw a circle representing a particular longitude round the Earth, it's always a circle whose centre is the centre of the Earth - so to circumnavigate the Earth at a constant longitude, you always travel the same distance:
2 * PI * 6378 /* 6378 is the radius of the Earth in km */
So, moving North (i.e travelling along the same longitude) 80 km will increase your latitude by:
360 * 80 / (2 * PI * 6378)
Latitude is trickier cos the distance travelled when you circumnavigate the Earth at the same latitude changes depending on the latitude at which you're travelling: however, the formula is simple and I looked it up at: http://www.newton.dep.anl.gov/askasci/env99/env086.htm
2 * PI * 6378 * COS(LAT) /* where LAT is your Latitude */
So, if you are at latitude LAT, and move 80km East, you will increase your longitude by:
360 * 80 / (2 * PI * 6378 * COS(LAT))
Couple of things to note:
a) 6378 is only accurate to the nearest km
b) The East/West between your two Northerly points will not be precisely 80km - not significantly different for Latitudes between about 80 degrees North and 80 degrees South - as long as you're not looking for high-precision pinpoint accuracy (which I'm guessing with base measurements of 80 km you're not) it'll do just nicely (and point nicelt at Bing or Google, say)
c) SQL calculates trigonometry functions using radians not degrees - so in SQL your cosine will need to be:
COS(PI * LAT / 180)
HTH and makes some sort of sense

Mapkit coordinates of point on a line

I have a CLLocationCoordinate2D (c1) and a CLLocation (l1), so I have lat/long values for each point and I can calculate the distance in meters between them using:
[c1 distanceFromLocation:l1]
How can I find the coordinates of a point (c2) 100 meters closer to l1 than c1 (along the same bearing)?
I have calculated it using basic trig using the following:
used the difference in latitude and longitude to calculate the hypotenuse and angle
used the ratio between the distance to cl and the distance to c2 to get the hypotenuse of a triangle ending at c2
used cos and sin to calculate the longitude and latitude of c2
But this seems like a hacky way of doing it as it doesn't take into account of curvature and seems to be using latitude and longitude in a way they are not supposed to be used. It does seem to work over short distances though.
After a bit of research, I found a basic formula for calculating curved distance between two points on the earth's surface:
dlon = lon2 - lon1
dlat = lat2 - lat1
a = { sin(dlat/2) }^2 + [ cos(lat1) * cos(lat2) * { sin(dlon/2) }^2 ]
c = 2 * arcsin(min(1,sqrt(a)))
d = R * c
Although Rickay's answer was helpful, I eventually used the following excellent library which has many useful functions for Core Location calculations: https://github.com/100grams/CoreLocationUtils

How to find latitude and longitude

I have latitude and longitude of a point.I have to find out the latitude and longitude of another point from a relative distance from the known point.For example point A has some location with latitude and longitude.What is the latitude and longitude after moving 1000m south and 500m west from point A.Is there any direct equation to find this? Thanks in advance
Note the accepted answer is basically the flat earth projection equations:
x = δlon * EarthRadius * cos( lat )
y = δlat * EarthRadius
For better accuracy over larger distances, you should compute the final lat/lon from a typical bearing/range calculation. See the section Destination point given distance and bearing from start point at this website: http://www.movable-type.co.uk/scripts/latlong.html
Instead of looking up an equation you can calculate as follows. Let R be the radius of the Earth. Let a be the current latitude and b be the current longitude. Then if you move δx metres east (negative for west) then δy metres south, calculating the new longitude can be done as follows.
Intersecting a horizontal plane with the Earth at the current latitude will give you a circle of radius R*cos(a). So to convert δx to the change in longitude, you get something like
δlong = δx * 2π / (2π * R * cos(a)) = δx / (R * cos (a))
The change in latitude is easier, since it doesn't depend on the current position. You're always moving around a great circle through the two poles. Then δlat = δy / R. (Of course you need to mod out by 2 π at some point).