Skip to content

Commit

Permalink
- Pievienota C++ programmēšanas valodas koordinātu pārveidošanas klase
Browse files Browse the repository at this point in the history
- Tiek izmantots vienots LKS92WGS84.* klases nosaukums visās programmēšanas valodās
- Citas nelielas izmaiņas un labojumi
  • Loading branch information
arvislacis committed Jan 20, 2016
1 parent e186311 commit 1faee59
Show file tree
Hide file tree
Showing 14 changed files with 373 additions and 174 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ koordinātu sistēmā (WGS-84) un otrādi.

1. Atkarībā no vēlamās programmēšanas valodas izvēlas pirmkoda direktoriju (piemēram, `javascript`).
2. Izvēlētā pirmkoda direktorija satur divas datnes:
- `lks92-wgs84.*` - atbilstošajā programmēšanas valodā uzrakstītā koordinātu pārveidošanas klase;
- `LKS92WGS84.*` - atbilstošajā programmēšanas valodā uzrakstītā koordinātu pārveidošanas klase;
- `example.*` - klases izmantošanas paraugs ar Latvijas galējo punktu (skatīt zemāk) koordinātu pārveidojumu testpiemēriem.
3. Vēlamo koordinātu pārveidošanas klasi `lks92-wgs84.*` lejupielādē/saglabā, veicot tās pirmkoda aplūkošanu un noklikšķinot
3. Vēlamo koordinātu pārveidošanas klasi `LKS92WGS84.*` lejupielādē/saglabā, veicot tās pirmkoda aplūkošanu un noklikšķinot
uz spiedpogas `Raw`, pēc tam izsaucot lapas/datnes saglabāšanas funkcionalitāti no pārlūkprogrammas.
4. Lejupielādēto datni iekļauj un izmanto vēlamajā projektā, vadoties pēc `example.*` parauga; ja nepieciešams, maina datnes nosaukumu.

Expand Down Expand Up @@ -42,6 +42,7 @@ Saraksts ar projektā pašlaik pieejamajām programmēšanas valodām - valodas,

| Programmēšanas valoda | Klases autors | Pēdējo būtisko izmaiņu datums |
|:---------------------:|:------------------------------------------------:|:-----------------------------:|
| C++ | [Arvis Lācis](https://github.com/arvislacis) | 21.01.2016. |
| C# | [Arvis Lācis](https://github.com/arvislacis) | 28.12.2015. |
| Java | [Arvis Lācis](https://github.com/arvislacis) | 11.01.2016. |
| JavaScript | [Arvis Lācis](https://github.com/arvislacis) | 22.12.2015. |
Expand All @@ -51,10 +52,10 @@ Saraksts ar projektā pašlaik pieejamajām programmēšanas valodām - valodas,
Laika gaitā plānots projektu papildināt ar citām, mazāk vai vairāk, populārām programmēšanas valodām gan no projekta autora,
gan citu interesentu puses.

Jebkuram interesentam ir iespējams iesniegt - gan izmantojot GitHub *Pull requests* sistēmu, gan rakstot personīgi -
Jebkuram interesentam ir iespējams iesniegt - gan izmantojot GitHub *[Pull requests sadaļu](https://github.com/arvislacis/lks92-wgs84/pulls)*, gan rakstot personīgi -
jaunu koordinātu pārveidošanas klasi citā, viņam labi zināmā, programmēšanas valodā, ievērojot sekojošus nosacījumus:
- **Nedublēt esošās programmēšanas valodas.** Ja esošajos risinājumos tiek pamanīta kļūda, tad nepieciešams izveidot jaunu problēmas
ziņojumu *(Issues)*, nevis pārstrādāt vai veidot no jauna esoša risinājuma variantu.
ziņojumu *([Issues sadaļā](https://github.com/arvislacis/lks92-wgs84/issues))*, nevis pārstrādāt vai veidot no jauna esoša risinājuma variantu.
- **Stingri ievērot projekta autora veidoto klašu pierakstu** - komentāri, funkciju secība, funkciju ieejas un izejas
parametri, vērtības utt. Atkāpes no iepriekš minētajām normām pieļaujamas tikai tad, ja izvēlētajā programmēšanas valodā nav iespējams
izmantot tāda paša veida risinājumu, kas vairumā gadījumu ir apšaubāmi.
Expand All @@ -66,14 +67,14 @@ visiem funkciju ieejas, izejas parametriem jāpaliek nemainīgiem.
pieļaujama standarta bibliotēku iekļaušana.
- Ja vien to pieļauj programmēšanas valoda, **pirmkods jāstrukturē klases veidā ar statiski izsaucamām funkcijām**, kas nodrošina
klases vienkāršu izmantošanu un atjaunināšanu, kā arī koordinātu pārveidošanas funkciju izsaukšanai nav nepieciešams veidot jaunu klases objektu.
- **Iesniegtajam pirmkodam jāsatur gan klases datne `lks92-wgs84.*`, gan klases izmantošanas parauga un testpiemēru datne `example.*`.**
- **Iesniegtajam pirmkodam jāsatur gan klases datne `LKS92WGS84.*`, gan klases izmantošanas parauga un testpiemēru datne `example.*`.**
Neskaidrību gadījumā ieteicams vadīties pēc projektā esošo datņu paraugiem.

Ieteikumu, uzlabojumu vai cita veida kļūdu atklāšanas gadījumā vēlams izveidot jaunu problēmas ziņojumu *(Issues)*.
Ieteikumu, uzlabojumu vai cita veida kļūdu atklāšanas gadījumā vēlams izveidot jaunu problēmas ziņojumu *([Issues sadaļā](https://github.com/arvislacis/lks92-wgs84/issues))*.

## Izmantotie avoti ##

Lai izveidotu projekta sākotnējo koordinātu pārveidošanas klasi (JavaScript), tika izmantoti šādi informācijas avoti:
Lai izveidotu projekta sākotnējo koordinātu pārveidošanas klasi JavaScript programmēšanas valodā, tika izmantoti šādi informācijas avoti:

1. [Koordinātu pārrēķinātājs - NeoGeo.lv](https://neogeo.lv/ekartes/koord2/)
2. [Transverse Mercator: Redfearn series - Wikipedia](https://en.wikipedia.org/wiki/Transverse_Mercator:_Redfearn_series)
Expand Down
153 changes: 153 additions & 0 deletions c#/LKS92WGS84.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
using System;

static class LKS92WGS84
{
// Koordinātu pārveidojumos izmantotās konstantes
private static double PI = Math.PI; // Skaitlis pi
private static double A_AXIS = 6378137; // Elipses modeļa lielā ass (a)
private static double B_AXIS = 6356752.31414; // Elipses modeļa mazā ass (b)
private static double CENTRAL_MERIDIAN = PI * 24 / 180; // Centrālais meridiāns
private static double OFFSET_X = 500000; // Koordinātu nobīde horizontālās (x) ass virzienā
private static double OFFSET_Y = -6000000; // Koordinātu nobīde vertikālās (y) ass virzienā
private static double SCALE = 0.9996; // Kartes mērogojuma faktors (reizinātājs)

// Aprēķina loka garumu no ekvatora līdz dotā punkta ģeogrāfiskajam platumam
private static double getArcLengthOfMeridian(double phi)
{
double n = (A_AXIS - B_AXIS) / (A_AXIS + B_AXIS);
double alpha = ((A_AXIS + B_AXIS) / 2) * (1 + (Math.Pow(n, 2) / 4) + (Math.Pow(n, 4) / 64));
double beta = (-3 * n / 2) + (9 * Math.Pow(n, 3) / 16) + (-3 * Math.Pow(n, 5) / 32);
double gamma = (15 * Math.Pow(n, 2) / 16) + (-15 * Math.Pow(n, 4) / 32);
double delta = (-35 * Math.Pow(n, 3) / 48) + (105 * Math.Pow(n, 5) / 256);
double epsilon = (315 * Math.Pow(n, 4) / 512);

return alpha * (phi + (beta * Math.Sin(2 * phi)) + (gamma * Math.Sin(4 * phi)) + (delta * Math.Sin(6 * phi)) + (epsilon * Math.Sin(8 * phi)));
}

// Aprēķina ģeogrāfisko platumu centrālā meridiāna punktam
private static double getFootpointLatitude(double y)
{
double n = (A_AXIS - B_AXIS) / (A_AXIS + B_AXIS);
double alpha = ((A_AXIS + B_AXIS) / 2) * (1 + (Math.Pow(n, 2) / 4) + (Math.Pow(n, 4) / 64));
double yd = y / alpha;
double beta = (3 * n / 2) + (-27 * Math.Pow(n, 3) / 32) + (269 * Math.Pow(n, 5) / 512);
double gamma = (21 * Math.Pow(n, 2) / 16) + (-55 * Math.Pow(n, 4) / 32);
double delta = (151 * Math.Pow(n, 3) / 96) + (-417 * Math.Pow(n, 5) / 128);
double epsilon = (1097 * Math.Pow(n, 4) / 512);

return yd + (beta * Math.Sin(2 * yd)) + (gamma * Math.Sin(4 * yd)) + (delta * Math.Sin(6 * yd)) + (epsilon * Math.Sin(8 * yd));
}

// Pārveido punkta ģeogrāfiskā platuma, garuma koordinātas par x, y koordinātām (bez pārvietojuma un mērogojuma)
private static double[] convertMapLatLngToXY(double phi, double lambda, double lambda0)
{
double[] xy = new double[2] {0, 0};

double ep2 = (Math.Pow(A_AXIS, 2) - Math.Pow(B_AXIS, 2)) / Math.Pow(B_AXIS, 2);
double nu2 = ep2 * Math.Pow(Math.Cos(phi), 2);
double N = Math.Pow(A_AXIS, 2) / (B_AXIS * Math.Sqrt(1 + nu2));
double t = Math.Tan(phi);
double t2 = t * t;

double l = lambda - lambda0;
double l3coef = 1 - t2 + nu2;
double l4coef = 5 - t2 + 9 * nu2 + 4 * (nu2 * nu2);
double l5coef = 5 - 18 * t2 + (t2 * t2) + 14 * nu2 - 58 * t2 * nu2;
double l6coef = 61 - 58 * t2 + (t2 * t2) + 270 * nu2 - 330 * t2 * nu2;
double l7coef = 61 - 479 * t2 + 179 * (t2 * t2) - (t2 * t2 * t2);
double l8coef = 1385 - 3111 * t2 + 543 * (t2 * t2) - (t2 * t2 * t2);

// x koordināta
xy[0] = N * Math.Cos(phi) * l + (N / 6 * Math.Pow(Math.Cos(phi), 3) * l3coef * Math.Pow(l, 3)) + (N / 120 * Math.Pow(Math.Cos(phi), 5) * l5coef * Math.Pow(l, 5)) + (N / 5040 * Math.Pow(Math.Cos(phi), 7) * l7coef * Math.Pow(l, 7));

// y koordināta
xy[1] = getArcLengthOfMeridian(phi) + (t / 2 * N * Math.Pow(Math.Cos(phi), 2) * Math.Pow(l, 2)) + (t / 24 * N * Math.Pow(Math.Cos(phi), 4) * l4coef * Math.Pow(l, 4)) + (t / 720 * N * Math.Pow(Math.Cos(phi), 6) * l6coef * Math.Pow(l, 6)) + (t / 40320 * N * Math.Pow(Math.Cos(phi), 8) * l8coef * Math.Pow(l, 8));
return xy;
}

// Pārveido punkta x, y koordinātas par ģeogrāfiskā platuma, garuma koordinātām (bez pārvietojuma un mērogojuma)
private static double[] convertMapXYToLatLon(double x, double y, double lambda0)
{
double[] latLng = new double[2] {0, 0};

double phif = getFootpointLatitude(y);
double ep2 = (Math.Pow(A_AXIS, 2) - Math.Pow(B_AXIS, 2)) / Math.Pow(B_AXIS, 2);
double cf = Math.Cos(phif);
double nuf2 = ep2 * Math.Pow(cf, 2);
double Nf = Math.Pow(A_AXIS, 2) / (B_AXIS * Math.Sqrt(1 + nuf2));
double Nfpow = Nf;

double tf = Math.Tan(phif);
double tf2 = tf * tf;
double tf4 = tf2 * tf2;

double x1frac = 1 / (Nfpow * cf);

Nfpow *= Nf; // Nf^2
double x2frac = tf / (2 * Nfpow);

Nfpow *= Nf; // Nf^3
double x3frac = 1 / (6 * Nfpow * cf);

Nfpow *= Nf; // Nf^4
double x4frac = tf / (24 * Nfpow);

Nfpow *= Nf; // Nf^5
double x5frac = 1 / (120 * Nfpow * cf);

Nfpow *= Nf; // Nf^6
double x6frac = tf / (720 * Nfpow);

Nfpow *= Nf; // Nf^7
double x7frac = 1 / (5040 * Nfpow * cf);

Nfpow *= Nf; // Nf^8
double x8frac = tf / (40320 * Nfpow);

double x2poly = -1 - nuf2;
double x3poly = -1 - 2 * tf2 - nuf2;
double x4poly = 5 + 3 * tf2 + 6 * nuf2 - 6 * tf2 * nuf2 - 3 * (nuf2 * nuf2) - 9 * tf2 * (nuf2 * nuf2);
double x5poly = 5 + 28 * tf2 + 24 * tf4 + 6 * nuf2 + 8 * tf2 * nuf2;
double x6poly = -61 - 90 * tf2 - 45 * tf4 - 107 * nuf2 + 162 * tf2 * nuf2;
double x7poly = -61 - 662 * tf2 - 1320 * tf4 - 720 * (tf4 * tf2);
double x8poly = 1385 + 3633 * tf2 + 4095 * tf4 + 1575 * (tf4 * tf2);

// Ģeogrāfiskais platums
latLng[0] = phif + x2frac * x2poly * (x * x) + x4frac * x4poly * Math.Pow(x, 4) + x6frac * x6poly * Math.Pow(x, 6) + x8frac * x8poly * Math.Pow(x, 8);

// Ģeogrāfiskais garums
latLng[1] = lambda0 + x1frac * x + x3frac * x3poly * Math.Pow(x, 3) + x5frac * x5poly * Math.Pow(x, 5) + x7frac * x7poly * Math.Pow(x, 7);

return latLng;
}

// Pārveido punkta ģeogrāfiskā platuma, garuma koordinātas par x, y koordinātām (ar pārvietojumu un mērogojumu)
public static double[] convertLatLonToXY(double[] coordinates)
{
double lat = coordinates[0] * PI / 180;
double lng = coordinates[1] * PI / 180;
double[] xy = convertMapLatLngToXY(lat, lng, CENTRAL_MERIDIAN);

xy[0] = xy[0] * SCALE + OFFSET_X;
xy[1] = xy[1] * SCALE + OFFSET_Y;

if (xy[1] < 0) {
xy[1] += 10000000;
}

return xy;
}

// Pārveido punkta x, y koordinātas par ģeogrāfiskā platuma, garuma koordinātām (ar pārvietojumu un mērogojumu)
public static double[] convertXYToLatLon(double[] coordinates)
{
double x = (coordinates[0] - OFFSET_X) / SCALE;
double y = (coordinates[1] - OFFSET_Y) / SCALE;
double[] latLng = convertMapXYToLatLon(x, y, CENTRAL_MERIDIAN);

latLng[0] = latLng[0] / PI * 180;
latLng[1] = latLng[1] / PI * 180;

return latLng;
}
}
8 changes: 4 additions & 4 deletions c#/example.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using lks92_wgs84;
using LKS92WGS84;
using System;
using System.IO;

class MainClass
{
public static string testCase(double[] coordinates)
static string testCase(double[] coordinates)
{
double[] converted = LKS92WGS84.convertXYToLatLon(LKS92WGS84.convertLatLonToXY(coordinates));
string result;
Expand All @@ -18,7 +18,7 @@ public static string testCase(double[] coordinates)
return result;
}

public static string testCase2(double[] coordinates, double[] lksValidate)
static string testCase2(double[] coordinates, double[] lksValidate)
{
double[] converted = LKS92WGS84.convertLatLonToXY(coordinates);
string result;
Expand All @@ -43,4 +43,4 @@ public static void Main()
coordinates = new double[2] {56.377008455189, 20.979185882058};
Console.WriteLine("\"Zaļais stars\" - Latvijas tālākais rietumu punkts [" + String.Join(", ", coordinates) + "] => " + testCase(coordinates) + " => " + testCase2(coordinates, new double[2] {313470.00, 252137.00}));
}
}
}
Loading

0 comments on commit 1faee59

Please sign in to comment.