0

In react-leaflet project I've used react-leaflet-draw to draw shapes. for a polyline, I coded a specific form. User can input a buffer for the created polyline. This buffer must be displayed as a shadow for polyline with width in meters or kilometers. Now I want to display (render) all points (markers) that their latlngs are inside that shadow or buffer size. How can I implement this?

Here is a link to my codesandbox

https://codesandbox.io/s/confident-swanson-rfp39?

It contains map component and a small node.js server

first I start server using node mapserver.js and then draw a polyline. after or before that I should input a buffer size either in m or km. Then I click on button and a fetch request begins. after fetch completed, All points that are in buffer area, must be displayed with a marker.

Above all, when updating buffer, it must be displayed as shadow for polyline but I couldn't implement that:|||

I implemented such a search for circles and polygons but my solution for polyline fails.

Here is onCreate method that handles onCreated event:

`

const onCreated = e => {
    console.log(e);
    console.log(editableFG);
    const { layerType, layer } = e;
    const drawnItems = editableFG.leafletElement._layers;
    console.log(drawnItems);
    if (Object.keys(drawnItems).length > 1) {
        Object.keys(drawnItems).forEach((layerid, index) => {
            if (index > 0) return;
            const layer = drawnItems[layerid];
            editableFG.leafletElement.removeLayer(layer);
        });
        console.log(drawnItems);
    }
    if (layerType === 'polyline') {
        setPolylineLayers(() => [
            {
                id: layer._leaflet_id,
                latlngs: layer.getLatLngs(),
                type: layerType
            }
        ]);
    }
};

`

Here is my algorithm for polyline search: `

    fetch('http://localhost:8000/geoData')
        .then(res => {
            if (!res.ok) {
                console.log(Promise.reject('request has been rejected'));
            }
            return res.json();
        })
        .then(data => {
            let m = [];
            let c = [];
            let points = [];
            for (let j = 1; j <= polylineLayers.latlngs.length; j++) {
                // m = (y1-y0)/(x1-x0)
                let x =
                    polylineLayers.latlngs[j][0] -
                    polylineLayers.latlngs[j - 1][0];
                let y =
                    polylineLayers.latlngs[j][1] -
                    polylineLayers.latlngs[j - 1][1];
                let z = y / x;
                m.push(z);
                // y - y0 = m(x-x0) => c = mx0 - y0
                let constant =
                    m[j - 1] * polylineLayers.latlngs[j - 1][0] +
                    polylineLayers.latlngs[j - 1][1];
                c.push(constant);
            }
            for (let i = 0; i < data.latlngs.length; i++) {
                for (let j = 0; j < m.length; j++) {
                    // distance = abs(y0-m*x0 + c)/sqrt(1+m^2)
                    let a = Math.abs(
                        data.latlngs[i][1] -
                            m[j] * data.latlngs[i][0] +
                            c[j]
                    );
                    let b = Math.pow(1 + Math.pow(m[j], 2), 2);
                    let distance = a / b;
                    if (bufferScale === 'm') {
                        if (distance < buffer / 1000) {
                            points.push(data.latlngs[i]);
                        }
                    } else {
                        if (bufferScale === 'km') {
                            if (distance < buffer) {
                                points.push(data.latlngs[i]);
                            }
                        }
                    }
                }
            }
            setPostions(points);
        });

` Any help would be pleasant :))

  • Can we see some code? What do you have so far? What have you tried? – Seth Lutske Aug 02 '21 at 14:56
  • sure i shall share my code – Abolfazl Heidarpour Aug 02 '21 at 19:14
  • hey Seth I updated my question please take a look – Abolfazl Heidarpour Aug 02 '21 at 20:49
  • Woof, that's a heavy meatball. I downloaded your code to get it running. After tracing through it, I see that in `handlePolylineSearchRequest`, you have `polylineLayers.latlngs.length`. But that errors, beacuse your state variable `polylineLayers` is *an array of objects*, that each contain a `latlngs` property. So I'm not sure what you're trying to do there. Then you have a bunch of statements like `latlngs[j][0]`....but each `latlng[x]` is an L.LatLng, which is an *object* with properties `lat` and `lng`, *not* an array. There's *alot* going on here, those are the first things I see. – Seth Lutske Aug 02 '21 at 21:23
  • Also, there are a number of libraries smrt people have written that can help you not have to write this logic yourself. leaflet-GeometryUtil's [closest](http://makinacorpus.github.io/Leaflet.GeometryUtil/global.html#closest) function comes to mind, as does turfjs's [nearestPointOnLine](https://turfjs.org/docs/#nearestPointOnLine) – Seth Lutske Aug 02 '21 at 21:32
  • About polylinelayers.latlngs.length: I'm trying to find all lines between latlngs of polyline – Abolfazl Heidarpour Aug 03 '21 at 04:31
  • Another problem is that buffer which we get from input, must be displayed as a shadow for polyline. How can I achieve that? – Abolfazl Heidarpour Aug 03 '21 at 04:34

0 Answers0