Reputation: 75
I'm trying to hide some leaflet features outside of a defined area.
I have a leaflet map displaying rivers as features on a RiverLayer and a circleLayer used to draw an area around the current center of the map.
Each river is separated in multiple parts inside my database and I retrieve only the parts intersecting with my current circle area.
The rivers are showing outside the area, because I selected the parts intersecting with it. I could select in my database all the parts within the area but I would lose the parts that are not entirely inside the area.
Calculating the intersection point for each part concerned in order to adjust the coordinates would be a solution but a complex one.
In fact, I would prefer to simply hide these overflows on the client side but I can't find a solution.
Is there a possibility with leaflet to do something like this?
Thanks for you time
Upvotes: 1
Views: 898
Reputation: 396
Here is an example using turfJS using the booleanWithin and lineSplit functions.
I did the example on a simple basic HTML and Vanilla JS. I added another linestring on the "river" to simulate an outside the circle river
var mymap = L.map('mapid').setView([43.63458105967136, 1.1613321304321291], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 20,
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
}).addTo(mymap);
var center = [43.63458105967136, 1.1613321304321291];
var radius = 1500;
// L.circle(center, radius, {
// color: '#ff4081', fillColor: '#ff4081', fillOpacity: 0.5
// }).addTo(mymap);
var riverGeoJSON = [
{ "type": "Feature", "geometry": { "coordinates": [[1.159444487444759, 43.633815447205706], [1.160243520516838, 43.634633600388156], [1.160731009187281, 43.6350432633719], [1.161774921971743, 43.63541373375439], [1.162079879908259, 43.63564209781788], [1.162320030539753, 43.635959368371424], [1.162373764624914, 43.636409391647234], [1.161800286153361, 43.637212422659154], [1.160910734693605, 43.63832601539633], [1.160651867030764, 43.63886255455486], [1.160332394101095, 43.639317964879666], [1.159189872203288, 43.640743176542664], [1.158053840843969, 43.641810274789506], [1.156922548158863, 43.642651534145514], [1.155851918485514, 43.64349381183714], [1.155156982509935, 43.644214650781954], [1.15326441791592, 43.64594659208024], [1.152374775964331, 43.6470151231795], [1.151428904349222, 43.64790448439313], [1.151107886218696, 43.64840394819371]], "type": "LineString" } },
{ "type": "Feature", "geometry": { "coordinates": [[1.156570800342349, 43.632121495293006], [1.158291185472127, 43.63272397754135], [1.158901458643683, 43.633090727638866], [1.159444487444759, 43.633815447205706]], "type": "LineString" } },
{ "type": "Feature", "geometry": { "coordinates": [[1.168152938761366, 43.62917262321181], [1.167467920251437, 43.62939958202886], [1.166101976396903, 43.62960874939632], [1.164673843635074, 43.629863651007135], [1.163738326615552, 43.63021236020524], [1.163236303364402, 43.630566588076604], [1.162728104605807, 43.63119071739829], [1.161282685092185, 43.632253508072225], [1.160336935333006, 43.633151033736986], [1.159444487444759, 43.633815447205706]], "type": "LineString" } },
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
1.0526275634765625,
43.550289946081115
],
[
1.07940673828125,
43.63334186269
],
[
1.0764884948730469,
43.6336524704596
]
]
}
}
];
// L.geoJSON(riverGeoJSON, {}).addTo(mymap);
var centerGeoJSON = [center[1], center[0]];
var radiusGeoJSON = radius / 1000;
var options = { steps: 50, units: 'kilometers' };
var circleGeoJSON = turf.circle(centerGeoJSON, radiusGeoJSON, options);
L.geoJSON(circleGeoJSON, {}).addTo(mymap);
var riverClipped = {}
for (let index = 0; index < riverGeoJSON.length; index++) {
const feature = riverGeoJSON[index];
var within = turf.booleanWithin(feature, circleGeoJSON);
console.log({ within });
var split = turf.lineSplit(feature, circleGeoJSON);
console.log({ split });
if (within && split.features.length === 0) {
L.geoJSON(feature, {}).addTo(mymap);
} else {
L.geoJSON(split.features[0], {}).addTo(mymap);
}
}
Circle is calculated with turfJS to have a valid GeoJSON feature. This feature is then used as a splitter.
When line is completely inside the circle, the within
function returns true
, the split function doesn't return a split feature.
When line is completely outside the circle, the within
function is false
and the split function doesn't return a split feature.
When the line intersect the circle, the within
function returns false
, and the first feature from the split feature collection is the one inside the circle.
Complete source code on JSFiddle: https://jsfiddle.net/tsamaya/6sc58m7u/
Upvotes: 1