Determining UTM zone (to convert) from longitude/latitude
Edit: For (non-R) code that works for all non-polar areas on earth, see here or here.
Unless you are dealing with data from a couple of exceptional areas (Svalbard and parts of Norway), this is a simple enough calculation that you might as well just do it yourself in R. Here is Wikipedia's description of how longitude relates to UTM Zone number:
The UTM system divides the surface of Earth between 80°S and 84°N latitude into 60 zones, each 6° of longitude in width. Zone 1 covers longitude 180° to 174° W; zone numbering increases eastward to zone 60 that covers longitude 174 to 180 East.
So, assuming that in your data longitudes to the west of the Prime Meridian are encoded as running from -180 to 0 degrees, here's an R-code version of the above:
long2UTM <- function(long) {
(floor((long + 180)/6) %% 60) + 1
}
# Trying it out for San Francisco, clearly in UTM Zone 10
# in the figure in the Wikipedia article linked above
SFlong <- -122.4192
long2UTM(SFlong)
# [1] 10
That expression could obviously be simplified a bit, but I think in this form the logic underlying its construction is most clear. The %% 60
bit is in there just in case some of your longitudes are greater than 180 or less than -180.
Converting latitude and longitude data to UTM with points from multiple UTM zones in R
UPDATE
Here is a much faster and elegant workaround using dplyr
and spTransfrom
Augmented data (60k+ rows):
test_coordinates <- data.frame(x = c(13.637398, -3.58627, -5.178889), y = c(41.30736, 40.72913, 40.17528), x_correct = c(385936, 450492, 314480), y_correct = c(4573773, 4508854, 4449488 ), zone = c(33, 30, 30), key = c(1, 2, 3), country = c("italy", "spain", "spain"))
test_coordinates = rbind(test_coordinates, test_coordinates[rep(1,60*1000),]) # simulate big data
library(dplyr)
library(sp)
get_utm <- function(x, y, zone, loc){
points = SpatialPoints(cbind(x, y), proj4string = CRS("+proj=longlat +datum=WGS84"))
points_utm = spTransform(points, CRS(paste0("+proj=utm +zone=",zone[1]," +ellps=WGS84")))
if (loc == "x") {
return(coordinates(points_utm)[,1])
} else if (loc == "y") {
return(coordinates(points_utm)[,2])
}
}
test_coordinates %<>%
mutate(zone2 = (floor((x + 180)/6) %% 60) + 1, keep = "all"
) %>%
group_by(zone2) %>%
mutate(utm_x = get_utm(x, y, zone2, loc = "x"),
utm_y = get_utm(x, y, zone2, loc = "y"))
Output (5 rows only)
test_coordinates
# A tibble: 603 × 10
# Groups: zone2 [2]
x y x_correct y_correct zone key country zone2 utm_x utm_y
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl>
1 13.6 41.3 385936 4573773 33 1 italy 33 385936. 4573773.
2 -3.59 40.7 450492 4508854 30 2 spain 30 450492. 4508854.
3 -5.18 40.2 314480 4449488 30 3 spain 30 314480. 4449488.
4 13.6 41.3 385936 4573773 33 1 italy 33 385936. 4573773.
5 13.6 41.3 385936 4573773 33 1 italy 33 385936. 4573773.
ORIGINAL RESPONSE
Replace:
data.frame(t(sapply(converted_points,c))) #Makes this list into a dataframe
With:
test_coordinates$utm_x <- unlist(converted_points)[c(T,F)]
test_coordinates$utm_y <- unlist(converted_points)[c(F,T)]
x y x_correct y_correct zone key country utm_x utm_y
1 13.637398 41.30736 385936 4573773 33 1 italy 385935.7 4573773
2 -3.586270 40.72913 450492 4508854 30 2 spain 450492.4 4508854
3 -5.178889 40.17528 314480 4449488 30 3 spain 314479.5 4449488
Easiest way convert UTM ZONE to lat long
In order to convert UTM coordinates (easting
and northing
) to latitude and longitude you need the zone number
and zone letter
as well.
Without these your easting / northing values could be in any of the 60 zones defined by UTM.
As for libraries, there are packages for Python, Javascript and probably others.
Sample for JS:
utm.toLatLon(easting, northing, zoneNum, zoneLetter)
//returns { latitude, longitude }
utm.fromLatLon(latitude, longitude)
//returns { easting, northing, zoneNum, zoneLetter }
Need to convert latitude and longitude to UTM with specific zone in Java
What I did was to use this converter and then changed the code a little. In the class LatLon2UTM's setVariables(double latitude, double longitude) method I changed the zone variable var1 to 33 and removed the calculation that calculated the real UTM zone.
original:
var1 = ((int) (longitude / 6)) + 31;
new:
var1 = 33;
Nothing great, but at least now I can convert to the zone I want!
How to find UTM zone using current latitude and longitude in android?
You also see that answer for get time utm as you want
demo(36.7783,-119.4175);
demo function
private void demo(double Lat, double Lon)
{
Zone= (int) Math.floor(Lon/6+31);
System.out.println("Zone"+Zone);
if (Lat<-72)
Letter='C';
else if (Lat<-64)
Letter='D';
else if (Lat<-56)
Letter='E';
else if (Lat<-48)
Letter='F';
else if (Lat<-40)
Letter='G';
else if (Lat<-32)
Letter='H';
else if (Lat<-24)
Letter='J';
else if (Lat<-16)
Letter='K';
else if (Lat<-8)
Letter='L';
else if (Lat<0)
Letter='M';
else if (Lat<8)
Letter='N';
else if (Lat<16)
Letter='P';
else if (Lat<24)
Letter='Q';
else if (Lat<32)
Letter='R';
else if (Lat<40)
Letter='S';
else if (Lat<48)
Letter='T';
else if (Lat<56)
Letter='U';
else if (Lat<64)
Letter='V';
else if (Lat<72)
Letter='W';
else
Letter='X';
Easting=0.5*Math.log((1+Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180))/(1-Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180)))*0.9996*6399593.62/Math.pow((1+Math.pow(0.0820944379, 2)*Math.pow(Math.cos(Lat*Math.PI/180), 2)), 0.5)*(1+ Math.pow(0.0820944379,2)/2*Math.pow((0.5*Math.log((1+Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180))/(1-Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180)))),2)*Math.pow(Math.cos(Lat*Math.PI/180),2)/3)+500000;
Easting=Math.round(Easting*100)*0.01;
System.out.println("Easting"+Easting);
Northing = (Math.atan(Math.tan(Lat*Math.PI/180)/Math.cos((Lon*Math.PI/180-(6*Zone -183)*Math.PI/180)))-Lat*Math.PI/180)*0.9996*6399593.625/Math.sqrt(1+0.006739496742*Math.pow(Math.cos(Lat*Math.PI/180),2))*(1+0.006739496742/2*Math.pow(0.5*Math.log((1+Math.cos(Lat*Math.PI/180)*Math.sin((Lon*Math.PI/180-(6*Zone -183)*Math.PI/180)))/(1-Math.cos(Lat*Math.PI/180)*Math.sin((Lon*Math.PI/180-(6*Zone -183)*Math.PI/180)))),2)*Math.pow(Math.cos(Lat*Math.PI/180),2))+0.9996*6399593.625*(Lat*Math.PI/180-0.005054622556*(Lat*Math.PI/180+Math.sin(2*Lat*Math.PI/180)/2)+4.258201531e-05*(3*(Lat*Math.PI/180+Math.sin(2*Lat*Math.PI/180)/2)+Math.sin(2*Lat*Math.PI/180)*Math.pow(Math.cos(Lat*Math.PI/180),2))/4-1.674057895e-07*(5*(3*(Lat*Math.PI/180+Math.sin(2*Lat*Math.PI/180)/2)+Math.sin(2*Lat*Math.PI/180)*Math.pow(Math.cos(Lat*Math.PI/180),2))/4+Math.sin(2*Lat*Math.PI/180)*Math.pow(Math.cos(Lat*Math.PI/180),2)*Math.pow(Math.cos(Lat*Math.PI/180),2))/3);
if (Letter<'M')
Northing = Northing + 10000000;
Northing=Math.round(Northing*100)*0.01;
System.out.println("Northing"+Northing);
}
as our discussion you need to convert to utm as calfornia lat long.... Please see this link for lat long take like that.... and do this...
https://gis.stackexchange.com/questions/120083/converting-a-california-coordinate-system-zone-6-value
I bet those values are US survey feet, and based on the document, also on NAD 1927, not NAD 1983.
The app you're using is using the NAD 1983 definitions of the State Plane zones. The parameters are different, so you're not going to be able to convert NAD 1927 coordinates using it.
If I convert the given values (cropping to integers) using the NAD 1927 definition, I get
longitude = -116.591154
latitude = 33.0709033
Please view this Link also......
Java, convert lat/lon to UTM
double utmZoneCenterLongitude = ... // Center lon of zone, example: zone 10 = -123
int zoneNumber = ... // zone number, example: 10
double latitude, longitude = ... // lat, lon in degrees
MathTransformFactory mtFactory = ReferencingFactoryFinder.getMathTransformFactory(null);
ReferencingFactoryContainer factories = new ReferencingFactoryContainer(null);
GeographicCRS geoCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
CartesianCS cartCS = org.geotools.referencing.cs.DefaultCartesianCS.GENERIC_2D;
ParameterValueGroup parameters = mtFactory.getDefaultParameters("Transverse_Mercator");
parameters.parameter("central_meridian").setValue(utmZoneCenterLongitude);
parameters.parameter("latitude_of_origin").setValue(0.0);
parameters.parameter("scale_factor").setValue(0.9996);
parameters.parameter("false_easting").setValue(500000.0);
parameters.parameter("false_northing").setValue(0.0);
Map properties = Collections.singletonMap("name", "WGS 84 / UTM Zone " + zoneNumber);
ProjectedCRS projCRS = factories.createProjectedCRS(properties, geoCRS, null, parameters, cartCS);
MathTransform transform = CRS.findMathTransform(geoCRS, projCRS);
double[] dest = new double[2];
transform.transform(new double[] {longitude, latitude}, 0, dest, 0, 1);
int easting = (int)Math.round(dest[0]);
int northing = (int)Math.round(dest[1]);
How to deal with possible zone changes when converting LatLong to UTM, adding offset to UTM, and converting offset UTM back to LatLong?
You can have coordinates outside zone, see e.g. the subsection Overlapping grids in UTM.
In fact, such coordinate system (or better the MGRS) was designed also for such cases: on a military ground (battles) you should not care much about changing zones or to do transformations (and so spheric or ellipsoid coordinates).
Just test that your libraries allows such values: some libraries are more strict (they may requires normalized coordinates). By UTM design they should allows coordinates outside proper zone, but a test is always better.
Related Topics
How to Make Gradient Color Filled Timeseries Plot in R
Convert Four Digit Year Values to Class Date
Shiny App: Downloadhandler Does Not Produce a File
Setting Absolute Size of Facets in Ggplot2
How to Parametrize Function Calls in Dplyr 0.7
R Shiny Rest API Communication
Joining Aggregated Values Back to the Original Data Frame
Formatting Reactive Data.Frames in Shiny
Add Number of Observations Per Group in Ggplot2 Boxplot
What Is Integer Overflow in R and How Can It Happen
Returning Anonymous Functions from Lapply - What Is Going Wrong
Struggling with Integers (Maximum Integer Size)
Libstdc++.So.6: Version 'Glibcxx_3.4.26' Not Found on Linux
How to Show a Legend on Dual Y-Axis Ggplot
How to Directly Select the Same Column from All Nested Lists Within a List