Answer the question
In order to leave comments, you need to log in
How to convert latitude and longitude to pixels?
There is an array of coordinates on the ground: latitude and longitude:
coords = [
{'lat':55.992405, 'lon':37.263676},
{'lat':55.992622, 'lon':37.263103},
{'lat':55.992840, 'lon':37.262547},
]
Answer the question
In order to leave comments, you need to log in
in general yes.
and if accuracy is needed, then everything will be more difficult.
the earth is not round, it is a geoid, in practice an ellipsoid is used. depends on the data provider.
geographical coordinates are converted to flat coordinates according to rather cumbersome formulas according to GOST R 51794-2008,
and then you coordinate these flat coordinates with your pixels, depending on the resolution and viewport,
I once sat closely on this topic and wrote a library in C # that calculates according to these provided formulas.
Here is a piece from there
, forgive me for such a sloppy design, I’m lying around sick, I don’t have access to normal code, I tore it out of an old archive, I write through an iron.
but I think you'll understand
/// <summary>
/// Возвращает плоскую координату X для пары угловых координат (зона проекции определена константой)
/// </summary>
/// <param name="Bd">Широта, град</param>
/// <param name="Ld">Долгота, град</param>
/// <returns></returns>
static public double flat_x(double Bd, double Ld)
{
int N = 6;
//int N = GetProjectionZone(Ld);
return flat_x(Bd, Ld, N);
}
/// <summary>
/// Возвращает плоскую координату X для пары угловых координат в заданной зоне проекции
/// </summary>
/// <param name="Bd">Широта, град</param>
/// <param name="Ld">Долгота, град</param>
/// <param name="N">Зона проекции</param>
/// <returns></returns>
static public double flat_x(double Bd, double Ld, int N)
{
double b, L, l_rad;
b = Bd * Math.PI / 180;
L = Ld * Math.PI / 180;
l_rad = (Ld - (3 + 6 * (N - 1))) / 57.29577951;
double Result, R1, R2, R3, R4, M1, M2;
R1 = 1594561.25 + 5336.535 * Math.Pow((Math.Sin(b)), 2) + 26.79 * Math.Pow((Math.Sin(b)), 4) + 0.149 * Math.Pow((Math.Sin(b)), 6);
R2 = 672483.4 - 811219.9 * Math.Pow((Math.Sin(b)), 2) + 5420.0 * Math.Pow((Math.Sin(b)), 4) - 10.6 * Math.Pow((Math.Sin(b)), 6);
R3 = 278194 - 830174 * Math.Pow((Math.Sin(b)), 2) + 572434 * Math.Pow((Math.Sin(b)), 4) - 16010 * Math.Pow((Math.Sin(b)), 6);
R4 = 109500 - 574700 * Math.Pow((Math.Sin(b)), 2) + 863700 * Math.Pow((Math.Sin(b)), 4) - 398600 * Math.Pow((Math.Sin(b)), 6);
M2 = (R2 + (Math.Pow(l_rad, 2)) * (R3 + (Math.Pow(l_rad, 2)) * (R4)));
M1 = (R1 + (Math.Pow(l_rad, 2)) * M2);
Result = 6367558.4698 * b - Math.Sin(2 * b) * (16002.89 + 66.9607 * Math.Pow((Math.Sin(b)), 2) + 0.3515 * Math.Pow((Math.Sin(b)), 4) - Math.Pow(l_rad, 2) * M1);
return Result;
}
/// <summary>
/// Возвращает плоскую координату Y для пары угловых координат (зона проекции определена константой)
/// </summary>
/// <param name="Bd">Широта, град</param>
/// <param name="Ld">Долгота, град</param>
/// <returns></returns>
static public double flat_y(double Bd, double Ld)
{
int N = 6;
//int N = GetProjectionZone(Ld);
return flat_y(Bd, Ld, N);
}
/// <summary>
/// Возвращает плоскую координату Y для пары угловых координат в заданной зоне проекции
/// </summary>
/// <param name="Bd">Широта, град</param>
/// <param name="Ld">Долгота, град</param>
/// <param name="N">Зона проекции</param>
/// <returns></returns>
static public double flat_y(double Bd, double Ld, int N)
{
double b, L, l_rad;
b = Bd * Math.PI / 180;
L = Ld * Math.PI / 180;
l_rad = (Ld - (3 + 6 * (N - 1))) / 57.29577951;
double Result, R1, R2, R3, R4, M1;
R1 = 6378245 + 21346.1415 * Math.Pow((Math.Sin(b)), 2) + 107.159 * Math.Pow((Math.Sin(b)), 4) + 0.5977 * Math.Pow((Math.Sin(b)), 6);
R2 = 1070204.16 - 2136826.66 * Math.Pow((Math.Sin(b)), 2) + 17.98 * Math.Pow((Math.Sin(b)), 4) - 11.99 * Math.Pow((Math.Sin(b)), 6);
R3 = 270806 - 1523417 * Math.Pow((Math.Sin(b)), 2) + 1327645 * Math.Pow((Math.Sin(b)), 4) - 21701 * Math.Pow((Math.Sin(b)), 6);
R4 = 79690 - 866190 * Math.Pow((Math.Sin(b)), 2) + 1730360 * Math.Pow((Math.Sin(b)), 4) - 945460 * Math.Pow((Math.Sin(b)), 6);
M1 = Math.Pow(l_rad, 2) * (R2 + Math.Pow(l_rad, 2) * (R3 + Math.Pow(l_rad, 2) * (R4)));
Result = (5 + 10 * N) * Math.Pow(10, 5) + l_rad * Math.Cos(b) * (R1 + M1);
return Result;
}
/// <summary>
/// Возвращает значение зоны проекции для заданного значения долготы
/// </summary>
/// <param name="Ld">Долгота, град</param>
/// <returns>Значение зоны</returns>
static public int GetProjectionZone(double Ld)
{
return Convert.ToInt32(Microsoft.VisualBasic.Conversion.Fix((6 + Ld) / 6));
}
/// <summary>
/// Возвращает значение зоны проекции, пригодное для проецирования большинства из массива долгот
/// </summary>
/// <param name="longitudes">Массив долгот, град</param>
/// <returns></returns>
static public int GetProjectionZone(double[] longitudes)
{
// Значения зон
List<int> lst_values = new List<int>();
// Количество вхождений
List<int> lst_valueCounts = new List<int>();
foreach (double longitude in longitudes)
{
// Зона для текущей долготы
int currentN = GetProjectionZone(longitude);
// Если значение новое, то занесем его в список и создадим нулевой счетчик этого значения
if (!lst_values.Exists(p => p == currentN))
{
lst_values.Add(currentN);
lst_valueCounts.Add(0);
}
int index = lst_values.IndexOf(currentN); // Иднекс этого значения
lst_valueCounts[index] += 1; // Увеличим счетчик этого значения
}
// Индекс значения с максимальным вхождением
int maxIndex = lst_valueCounts.IndexOf(lst_valueCounts.Max());
return lst_values[maxIndex];
}
static public double DegreesMinutesToDouble(int degrees, double minutes)
{
return DegreesMinutesSecondsToDouble((double)degrees, minutes, 0);
}
static public double DegreesMinutesSecondsToDouble(int degrees, int minutes, double seconds)
{
return DegreesMinutesSecondsToDouble((double)degrees, minutes, seconds);
}
static public double DegreesMinutesSecondsToDouble(double degrees, double minutes, double seconds)
{
minutes += seconds / 60;
degrees += minutes / 60;
return degrees;
}
}
When you change the latitude, you move along the arc of a great circle - along the meridian. Accordingly, 1deg==1/57radian<~>1/57radius_Earth
When you change longitude, you move along a parallel - a circle with a radius proportional to the cosine of latitude.
That's the whole formula.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question