-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Pievienota JavaScript koordinātu pārveidošanas klase (javascript)
- Izveidota projekta dokumentācija README.md
- Loading branch information
1 parent
b284284
commit 937f692
Showing
3 changed files
with
283 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,98 @@ | ||
# lks92-wgs84 | ||
Neliela, dažādās programmēšanas valodās uzrakstīta ģeogrāfisko koordinātu pārveidošanas klase, kas nodrošina Latvijas koordinātu sistēmā (LKS-92) norādīto koordinātu pārveidošanu vispasaules ģeodēzisko koordinātu sistēmā (WGS-84) un otrādi. | ||
# LKS92-WGS84 # | ||
|
||
LKS92-WGS84 ir neliela, dažādās programmēšanas valodās uzrakstīta ģeogrāfisko koordinātu pārveidošanas klase, | ||
kas nodrošina Latvijas koordinātu sistēmā (LKS-92) norādīto koordinātu pārveidošanu vispasaules ģeodēzisko | ||
koordinātu sistēmā (WGS-84) un otrādi. | ||
|
||
## Klases izmantošana ## | ||
|
||
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; | ||
- `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 | ||
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. | ||
|
||
## Papildu piezīmes ## | ||
|
||
- Koordinātu pārveidojumos tiek pielietots LKS-92 variants, kurā punkta koordinātas nobīdītas par `-600 km = -600000 m` ziemeļu virzienā, | ||
mērogojuma faktors - `0.9996`, bet centrālais ass meridiāns - `24 E`. | ||
Šos parametrus iespējams mainīt klases konstantes mainīgajos `OFFSET_Y`, `SCALE` un `CENTRAL_MERIDIAN`; tāpat tiek izmantoti | ||
arī citi konstantie mainīgie, kas var ietekmēt gala rezultātu precizitāti un atbilstību testa datiem. | ||
- Koordinātu pārveidojumos ieteicams izmantot tikai to punktu koordinātas, kuri atrodas Latvijas teritorijā. | ||
- WGS-84 rezultātu kļūda **nav mazāka** par `10^(-8) grāda`, bet LKS-92 rezultātu - `10^(-2) metra`, tādēļ šos pārveidojumus | ||
nav ieteicams izmantot precīzos mērījumos un precīzu aprēķinu veikšanā vai tml. | ||
|
||
## Testpiemēru atskaites punkti ## | ||
|
||
Lai salīdzinātu koordinātu pārveidojumu rezultātus, īpaši veicot jaunu programmēšanas valodu pievienošanu, tiek izmantotas | ||
[Latvijas galējo punktu koordinātas](https://www.vietas.lv/index.php?p=34&gid=15): | ||
|
||
| Punkta nosaukums | Virziens | WGS-84 platums | WGS-84 garums | LKS-92 X | LKS-92 Y | | ||
|:----------------:|:--------:|:----------------:|:---------------:|:----------:|:----------:| | ||
| "Baltās naktis" | Z | 58.079501574948 | 25.189986971284 | 570181.000 | 438180.000 | | ||
| "Austras koks" | A | 56.172282784562 | 28.095216442873 | 754190.003 | 232806.000 | | ||
| "Saules puķe" | D | 55.675228242509 | 26.580528487143 | 662269.000 | 172953.000 | | ||
| "Zaļais stars" | R | 56.377008455189 | 20.979185882058 | 313470.000 | 252137.000 | | ||
|
||
## Programmēšanas valodu pieejamība ## | ||
|
||
Projektā pašlaik pieejamās programmēšanas valodas - valodas, kurām izstrādāta koordinātu pārveidošanas klase `lks92-wgs84.*`: | ||
|
||
| Programmēšanas valoda | Klases autors | Pēdējo izmaiņu datums | | ||
|:---------------------:|:--------------------------------------------:|:---------------------:| | ||
| JavaScript | [Arvis Lācis](https://github.com/arvislacis) | 22.12.2015. | | ||
|
||
Laika gaitā plānots projektu papildināt arī ar citām, mazāk vai vairāk, populārām programmēšanas valodām gan no projekta autora, | ||
gan no citu interesentu puses. | ||
|
||
Jebkuram interesentam ir iespējams iesniegt - gan izmantojot GitHub *Pull requests* sistēmu, 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ējiet jau esošās programmēšanas valodas.** Ja esošajos risinājumos pamanāt kļūdu, tad izveidojiet jaunu problēmas | ||
ziņojumu *(Issues)*, nevis pārstrādājiet vai veidojiet jaunu esoša risinājuma variantu. | ||
- **Stingri ievērojiet projekta autora veidoto klašu pierakstu** - komentāri, funkciju secība, funkciju ieejas un izejas | ||
parametri, vērtības utt. Atkāpes no iepriekš uzskaitī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 ir apšaubāmi. | ||
- **Atļauts izmantot izvēlētajā programmēšanas valodā unikālos operatorus un iebūvētās funkcijas** - gan kā alternatīvu, gan atkārtojošā, | ||
liekā pirmkoda aizvietošanas nolūkiem -, piemēram, izmantojot valodā iebūvēto funkciju grādu pārveidošanai par radiāniem un otrādi, kas | ||
JavaScript valodā nav pieejama utml. Šādu operatoru, funkciju izmantojums nedrīkst pārlieku sarežģīt koordinātu pārveidošanas klasi un | ||
visiem funkciju ieejas, izejas parametriem jāpaliek nemainīgiem. | ||
- **Klases realizācijā stingri jāizvairās no papildus bibliotēku vai klašu izmantošanas**, ja tas nav iespējams, tad 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 | ||
koordinātu pārveidošanas klases vienkāršu izmantošanu un atjaunināšanu, tāpat pārveidošanas funkcionalitātes nodrošināš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.*`.** | ||
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ā ieteicams izveidot jaunu problēmas ziņojumu *(Issues)*. | ||
|
||
## Izmantotie avoti ## | ||
|
||
Lai izveidotu projekta sākotnējo koordinātu pārveidošanas klasi (JavaScript), 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) | ||
|
||
## MIT licence ## | ||
|
||
Copyright (c) 2015-2016 Arvis Lācis | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<script src="lks92-wgs84.js"></script> | ||
</head> | ||
<body> | ||
<script> | ||
function TestCase(coordinates) { | ||
var converted = LKS92WGS84.convertXYToLatLon(LKS92WGS84.convertLatLonToXY(coordinates)), | ||
result; | ||
|
||
if (Math.round(converted[0] * Math.pow(10, 8)) / Math.pow(10, 8) == Math.round(coordinates[0] * Math.pow(10, 8)) / Math.pow(10, 8) && Math.round(converted[1] * Math.pow(10, 8)) / Math.pow(10, 8) == Math.round(coordinates[1] * Math.pow(10, 8)) / Math.pow(10, 8)) { | ||
result = "izpildās"; | ||
} else { | ||
result = "neizpildās"; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
var coordinates = [58.079501574948, 25.189986971284]; | ||
console.log("\"Baltās naktis\" - Latvijas tālākais ziemeļu punkts [" + coordinates + "] => " + TestCase(coordinates)); | ||
coordinates = [56.172282784562, 28.095216442873]; | ||
console.log("\"Austras koks\" - Latvijas tālākais austrumu punkts [" + coordinates + "] => " + TestCase(coordinates)); | ||
coordinates = [55.675228242509, 26.580528487143]; | ||
console.log("\"Saules puķe\" - Latvijas tālākais dienvidu punkts [" + coordinates + "] => " + TestCase(coordinates)); | ||
coordinates = [56.377008455189, 20.979185882058]; | ||
console.log("\"Zaļais stars\" - Latvijas galējais rietumu punkts [" + coordinates + "] => " + TestCase(coordinates)); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
var LKS92WGS84 = { | ||
// Koordinātu pārveidojumos izmantotās konstantes | ||
PI: Math.PI, // Skaitlis pi | ||
A_AXIS: 6378137, // Elipses modeļa lielā ass (a) | ||
B_AXIS: 6356752.31414, // Elipses modeļa mazā ass (b) | ||
CENTRAL_MERIDIAN: 24 / 180 * Math.PI, // Centrālais meridiāns | ||
OFFSET_X: 500000, // Koordinātu nobīde horizontālās (x) ass virzienā | ||
OFFSET_Y: -6000000, // Koordinātu nobīde vertikālās (y) ass virzienā | ||
SCALE: 0.9996, // Kartes mērogojuma faktors (reizinātājs) | ||
|
||
// Aprēķina loka garumu no ekvatora līdz dotā punkta ģeogrāfiskajam platumam | ||
getArcLengthOfMeridian: function(phi) { | ||
var alpha, beta, gamma, delta, epsilon, n; | ||
|
||
n = (this.A_AXIS - this.B_AXIS) / (this.A_AXIS + this.B_AXIS); | ||
alpha = ((this.A_AXIS + this.B_AXIS) / 2) * (1 + (Math.pow(n, 2) / 4) + (Math.pow(n, 4) / 64)); | ||
beta = (-3 * n / 2) + (9 * Math.pow(n, 3) / 16) + (-3 * Math.pow(n, 5) / 32); | ||
gamma = (15 * Math.pow(n, 2) / 16) + (-15 * Math.pow(n, 4) / 32); | ||
delta = (-35 * Math.pow(n, 3) / 48) + (105 * Math.pow(n, 5) / 256); | ||
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 | ||
getFootpointLatitude: function(y) { | ||
var y_, alpha_, beta_, gamma_, delta_, epsilon_, n; | ||
|
||
n = (this.A_AXIS - this.B_AXIS) / (this.A_AXIS + this.B_AXIS); | ||
alpha_ = ((this.A_AXIS + this.B_AXIS) / 2) * (1 + (Math.pow(n, 2) / 4) + (Math.pow(n, 4) / 64)); | ||
y_ = y / alpha_; | ||
beta_ = (3 * n / 2) + (-27 * Math.pow(n, 3) / 32) + (269 * Math.pow(n, 5) / 512); | ||
gamma_ = (21 * Math.pow(n, 2) / 16) + (-55 * Math.pow(n, 4) / 32); | ||
delta_ = (151 * Math.pow(n, 3) / 96) + (-417 * Math.pow(n, 5) / 128); | ||
epsilon_ = (1097 * Math.pow(n, 4) / 512); | ||
|
||
return y_ + (beta_ * Math.sin(2 * y_)) + (gamma_ * Math.sin(4 * y_)) + (delta_ * Math.sin(6 * y_)) + (epsilon_ * Math.sin(8 * y_)); | ||
}, | ||
|
||
// Pārveido punkta ģeogrāfiskā platuma, garuma koordinātas par x, y koordinātām (bez pārvietojuma un mērogojuma) | ||
convertMapLatLngToXY: function(phi, lambda, lambda0) { | ||
var N, nu2, ep2, t, t2, l, | ||
l3coef, l4coef, l5coef, l6coef, l7coef, l8coef, | ||
xy = [0, 0]; | ||
|
||
ep2 = (Math.pow(this.A_AXIS, 2) - Math.pow(this.B_AXIS, 2)) / Math.pow(this.B_AXIS, 2); | ||
nu2 = ep2 * Math.pow(Math.cos(phi), 2); | ||
N = Math.pow(this.A_AXIS, 2) / (this.B_AXIS * Math.sqrt(1 + nu2)); | ||
t = Math.tan(phi); | ||
t2 = t * t; | ||
|
||
l = lambda - lambda0; | ||
l3coef = 1 - t2 + nu2; | ||
l4coef = 5 - t2 + 9 * nu2 + 4 * (nu2 * nu2); | ||
l5coef = 5 - 18 * t2 + (t2 * t2) + 14 * nu2 - 58 * t2 * nu2; | ||
l6coef = 61 - 58 * t2 + (t2 * t2) + 270 * nu2 - 330 * t2 * nu2; | ||
l7coef = 61 - 479 * t2 + 179 * (t2 * t2) - (t2 * t2 * t2); | ||
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] = this.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) | ||
convertMapXYToLatLon: function(x, y, lambda0) { | ||
var phif, Nf, Nfpow, nuf2, ep2, tf, tf2, tf4, cf, | ||
x1frac, x2frac, x3frac, x4frac, x5frac, x6frac, x7frac, x8frac, | ||
x2poly, x3poly, x4poly, x5poly, x6poly, x7poly, x8poly, | ||
latLng = [0, 0]; | ||
|
||
phif = this.getFootpointLatitude(y); | ||
ep2 = (Math.pow(this.A_AXIS, 2) - Math.pow(this.B_AXIS, 2)) / Math.pow(this.B_AXIS, 2); | ||
cf = Math.cos(phif); | ||
nuf2 = ep2 * Math.pow(cf, 2); | ||
Nf = Math.pow(this.A_AXIS, 2) / (this.B_AXIS * Math.sqrt(1 + nuf2)); | ||
Nfpow = Nf; | ||
|
||
tf = Math.tan(phif); | ||
tf2 = tf * tf; | ||
tf4 = tf2 * tf2; | ||
|
||
x1frac = 1 / (Nfpow * cf); | ||
|
||
Nfpow *= Nf; // Nf^2 | ||
x2frac = tf / (2 * Nfpow); | ||
|
||
Nfpow *= Nf; // Nf^3 | ||
x3frac = 1 / (6 * Nfpow * cf); | ||
|
||
Nfpow *= Nf; // Nf^4 | ||
x4frac = tf / (24 * Nfpow); | ||
|
||
Nfpow *= Nf; // Nf^5 | ||
x5frac = 1 / (120 * Nfpow * cf); | ||
|
||
Nfpow *= Nf; // Nf^6 | ||
x6frac = tf / (720 * Nfpow); | ||
|
||
Nfpow *= Nf; // Nf^7 | ||
x7frac = 1 / (5040 * Nfpow * cf); | ||
|
||
Nfpow *= Nf; // Nf^8 | ||
x8frac = tf / (40320 * Nfpow); | ||
|
||
x2poly = -1 - nuf2; | ||
x3poly = -1 - 2 * tf2 - nuf2; | ||
x4poly = 5 + 3 * tf2 + 6 * nuf2 - 6 * tf2 * nuf2 - 3 * (nuf2 *nuf2) - 9 * tf2 * (nuf2 * nuf2); | ||
x5poly = 5 + 28 * tf2 + 24 * tf4 + 6 * nuf2 + 8 * tf2 * nuf2; | ||
x6poly = -61 - 90 * tf2 - 45 * tf4 - 107 * nuf2 + 162 * tf2 * nuf2; | ||
x7poly = -61 - 662 * tf2 - 1320 * tf4 - 720 * (tf4 * tf2); | ||
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) | ||
convertLatLonToXY: function(coordinates) { | ||
var lat = coordinates[0] * this.PI / 180, | ||
lng = coordinates[1] * this.PI / 180, | ||
xy = this.convertMapLatLngToXY(lat, lng, this.CENTRAL_MERIDIAN); | ||
|
||
xy[0] = xy[0] * this.SCALE + this.OFFSET_X; | ||
xy[1] = xy[1] * this.SCALE + this.OFFSET_Y; | ||
|
||
if (xy[1] < 0) { | ||
xy[1] = 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) | ||
convertXYToLatLon: function(coordinates) { | ||
var x = (coordinates[0] - this.OFFSET_X) / this.SCALE, | ||
y = (coordinates[1] - this.OFFSET_Y) / this.SCALE, | ||
latLng = this.convertMapXYToLatLon(x, y, this.CENTRAL_MERIDIAN); | ||
|
||
latLng[0] = latLng[0] / this.PI * 180; | ||
latLng[1] = latLng[1] / this.PI * 180; | ||
|
||
return latLng; | ||
} | ||
}; |