0

I use a external GeoServer that contains routes (LineString). I'm creating a Node JS backend in order to find and manipulate those routes.

In order to find the routes I thought to first send a WFS request to the GeoServer with a bounding box where the center of the box is the starting coordinate from where we need to find routes within a certain radius. Then use a Turf js function called pointToLineDistance because the bounding box is square and a radius is round.

I have two questions about this solution. First if this is a solid way to find the right features or if some one knows something better?

Second problem is how can I calculate the bounding box when I know the center and WFS server is using the Web Mercator coordinates. I have found a solution: Stackexchange. But how do I convert distance to Web Mercator units?

Edit:

I have found that the units of the Pseudo Web Mercator are already in meters.

Vince
  • 20,017
  • 15
  • 45
  • 64
Stephen
  • 275
  • 3
  • 18
  • 1
    Please do not ever use EPSG:3857 (Web Mercator) to carry out any sort of distance related analysis. The longitude (X) axis is distorted to infinity as you move north or south of the Equator. – Ian Turton Oct 06 '21 at 10:29
  • Just because the units are meters doesn't mean that the result is actually in the same "meters" in both X and Y dimensions. In fact, with Web Mercator, they aren't. – Vince Oct 06 '21 at 10:50
  • @IanTurton What about EPSG:4326 in order to calculate distance? – Stephen Oct 06 '21 at 10:55
  • provided you measure distances in degrees 4326 is fine – Ian Turton Oct 06 '21 at 12:44
  • You can convert [lat, lng] coordinate to Mercator with the turf.toMercator method. – TomazicM Oct 07 '21 at 07:49
  • What is the CRS of your WFS layer? – TomazicM Oct 09 '21 at 12:30
  • @TomazicM It is EPSG:3857 – Stephen Oct 09 '21 at 12:31
  • Have you considered using WPS? or a SQL View? seems a bit simpler. you could build the view or process and simply send the coordinates of the center and radius and let geoserver handle the buffer creation and selection – Dror Bogin Oct 10 '21 at 09:13

1 Answers1

1

To get bounding box in Mercator coordinates (EPSG:3857) of a circle with a given center [lng, lat] coordinates and radius in kilometers, you can use turf.destination and turf.toMercator methods.

With the turf.destination(point, distance, bearing) method you can get coordinates of a point that is distance kilometers offset from the source point in the bearing direction.

With the turf.toMercator method you can then convert [lng, lat] coordinates to projected Mercator ones.

Simple function for creating Mercator bounding box could then look something like this:

function getMercBbox(center, radius) {

function coordOffsetMerc(bearing) { var centerPoint = turf.point(center); return(turf.getCoord(turf.toMercator(turf.destination(centerPoint, radius, bearing)))); }

var centerUpMerc = coordOffsetMerc(0); var centerRightMerc = coordOffsetMerc(90); var centerDownMerc = coordOffsetMerc(180); var centerLeftMerc = coordOffsetMerc(270);

return { lowerLeft: [centerLeftMerc[0], centerDownMerc[1]], upperRight: [centerRightMerc[0], centerUpMerc[1]] }; }

You can then test this function with the following code:

var center = [12, 51];
var radius = 10  // kilometers

var bboxMerc = getMercBbox(center, radius); var bboxMercWidth = Math.abs(bboxMerc.lowerLeft[0] - bboxMerc.upperRight[0]); var bboxMercHeight = Math.abs(bboxMerc.lowerLeft[1] - bboxMerc.upperRight[1]);

var ratioWidth = (radius * 2 * 1000) / bboxMercWidth; var ratioHeight = (radius * 2 * 1000) / bboxMercHeight;

var mercFactor = Math.cos(center[1] * Math.PI / 180);

console.log(ratioWidth, ratioHeight, mercFactor);

If you look at the ratio between actual bbox width and width (or height) in projected Mercator meters, you get value to one decimal equal with the value of cos() of bbox latitude, which is considered to be approx method for calculating Mercator length distortions (see Better Distance Measurements in Web Mercator Projection):

ratioWidth: 0.6286178504081783
ratioHeight: 0.6286178504081783

mercFactor: 0.6293203910498375

TomazicM
  • 25,601
  • 22
  • 29
  • 39