Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.56% covered (success)
97.56%
40 / 41
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
MapUtils
97.56% covered (success)
97.56%
40 / 41
83.33% covered (warning)
83.33%
5 / 6
6
0.00% covered (danger)
0.00%
0 / 1
 WGStoCHy
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 WGStoCHx
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 CHtoWGSlat
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 CHtoWGSlng
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 DECtoSEX
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 fromEnv
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Olz\Utils;
4
5// Source: http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/projections.html (see PDFs under "Documentation")
6// Updated 9 dec 2014
7// Please validate your results with NAVREF on-line service: http://www.swisstopo.admin.ch/internet/swisstopo/en/home/apps/calc/navref.html (difference ~ 1-2m)
8
9class MapUtils {
10    use WithUtilsTrait;
11
12    // Convert WGS lat/long (° dec) to CH y
13    public function WGStoCHy(int|float $lat, int|float $long): int|float {
14        // Converts decimal degrees sexagesimal seconds
15        $lat = $this->DECtoSEX($lat);
16        $long = $this->DECtoSEX($long);
17
18        // Auxiliary values (% Bern)
19        $lat_aux = ($lat - 169028.66) / 10000;
20        $long_aux = ($long - 26782.5) / 10000;
21
22        // Process Y
23        return 600072.37
24            + 211455.93 * $long_aux
25            - 10938.51 * $long_aux * $lat_aux
26            - 0.36 * $long_aux * pow($lat_aux, 2)
27            - 44.54 * pow($long_aux, 3);
28    }
29
30    // Convert WGS lat/long (° dec) to CH x
31    public function WGStoCHx(int|float $lat, int|float $long): int|float {
32        // Converts decimal degrees sexagesimal seconds
33        $lat = $this->DECtoSEX($lat);
34        $long = $this->DECtoSEX($long);
35
36        // Auxiliary values (% Bern)
37        $lat_aux = ($lat - 169028.66) / 10000;
38        $long_aux = ($long - 26782.5) / 10000;
39
40        // Process X
41        return 200147.07
42            + 308807.95 * $lat_aux
43            + 3745.25 * pow($long_aux, 2)
44            + 76.63 * pow($lat_aux, 2)
45            - 194.56 * pow($long_aux, 2) * $lat_aux
46            + 119.79 * pow($lat_aux, 3);
47    }
48
49    // Convert CH y/x to WGS lat
50    public function CHtoWGSlat(int|float $y, int|float $x): int|float {
51        // Converts military to civil and  to unit = 1000km
52        // Auxiliary values (% Bern)
53        $y_aux = ($y - 600000) / 1000000;
54        $x_aux = ($x - 200000) / 1000000;
55
56        // Process lat
57        $lat = 16.9023892
58            + 3.238272 * $x_aux
59            - 0.270978 * pow($y_aux, 2)
60            - 0.002528 * pow($x_aux, 2)
61            - 0.0447 * pow($y_aux, 2) * $x_aux
62            - 0.0140 * pow($x_aux, 3);
63
64        // Unit 10000" to 1 " and converts seconds to degrees (dec)
65        return $lat * 100 / 36;
66    }
67
68    // Convert CH y/x to WGS long
69    public function CHtoWGSlng(int|float $y, int|float $x): int|float {
70        // Converts military to civil and  to unit = 1000km
71        // Auxiliary values (% Bern)
72        $y_aux = ($y - 600000) / 1000000;
73        $x_aux = ($x - 200000) / 1000000;
74
75        // Process long
76        $long = 2.6779094
77            + 4.728982 * $y_aux
78            + 0.791484 * $y_aux * $x_aux
79            + 0.1306 * $y_aux * pow($x_aux, 2)
80            - 0.0436 * pow($y_aux, 3);
81
82        // Unit 10000" to 1 " and converts seconds to degrees (dec)
83        return $long * 100 / 36;
84    }
85
86    // Convert DEC angle to SEX DMS
87    protected function DECtoSEX(int|float $angle): int|float {
88        // Extract DMS
89        $deg = intval($angle);
90        $min = intval(($angle - $deg) * 60);
91        $sec = ((($angle - $deg) * 60) - $min) * 60;
92
93        // Result in sexagesimal seconds
94        return $sec + $min * 60 + $deg * 3600;
95    }
96
97    public static function fromEnv(): self {
98        return new self();
99    }
100}