In short:
A pointer from one point towards another, angle calculated with any Bearing tool / formula in hand, did not show correctly, but some degrees wrong. Calculate made in lat / lon values and shown in another CRS than calculations were made. EPSG:3067 is used as map CRS.
How to "convert" the bearing from CRS to another and with which extra parameters?
Long story:
I want to have a pointer on map, which points from its current position over map to my desired destination - an arrow, that I can point from one to another, drawn as overlay on openlayers map. For that the tool seems to be to calculated correct Rhumb-Bearing.
So codewise I place a pointer symbol (circle where inside an centered arrow) and I rotate it with calculated bearing value.
I have learned about Bearing, that you can calculate it from [lat,lon] pair of coordinates either by hand 1 or using a library, like turf.js [2], [3]. I have tried all these three approaches, but my pointer does not point to correct direction. The issue is what is happening in my source [4]: I use a map with EPSG:3067 coordinate system, whereas
Turf.js library deals with GeoJSON vector data, so it uses unprojected WGS84 coordinate system, which is EPSG:6326.
and there comes the issue: in [4] they say that Bearing may vary depending on crs. So, my pointer, whether it is calculated with Bearing or Rhumb-bearing method, always has some deviation in the direction, at least on large distances, say > 200km.
I would like to be able to find a way to calculating the bearing in EPSG:3067 or somewhat to convert the one I get with turf.js or my current formula with lan-lot values.
How is bearing converted (one my sources said it alone cannot be converted)?
At least the formula and needed params.
I use map of Finland, which is quite north, and that may have an impact.
Code:
import { transform as transform2 } from 'ol/proj'; // openlayers.
// From map coords come with EPSG:3067
// I convert to EPSG:4326, which is one part of same WGS84 [6] as EPSG:6326 used in turf.js.
const lonlat = transform2([parseFloat(X1), parseFloat(Y1)], 'EPSG:3067', 'EPSG:4326');
//.. same to another one, too.
// Then with turf.js:
var point1 = Turf.point([startlon, startlat]);
var point2 = Turf.point([destlon, destlat]);
return (Turf.rhumbBearing(point1, point2, true) + 360) % 360;
#Then in css of an arrow pointing up on an overlay in same point of map where is (X1,Y1):
transform: [{ rotateZ: direction + ' deg' }] # Program is react native, this is part of the css of the element inside React code.
The result kind of shows to correct direction, but not directly (some degrees wrong, if you see with a ruler.
Coordinates on pic: (EPSG:3067)
start:
289792.8753007395 6780621.145424524
target:
290219.31183128356 6781279.348593385, 290339.9582224339 6781381.352886491
target calculated from extent of a polygon, I gave the extent. Code for calculation:
function getCenterOfExtent(Extent){
var X = parseFloat(Extent[0]) + (parseFloat(Extent[2])-parseFloat(Extent[0]))/2;
var Y = parseFloat(Extent[1]) + (parseFloat(Extent[3])-parseFloat(Extent[1]))/2;
return [X, Y];
}
Sources:
1 https://www.movable-type.co.uk/scripts/latlong.html
[2] https://turfjs.org/docs/#bearing
[3] https://turfjs.org/docs/#rhumbBearing
[4] Azimuth (bearing) changes depending on map/project projection