在传单和 OSM 中用箭头指示单向路线方向

问题描述 投票:0回答:1

我目前正在开发一个路径映射 Next.js React 应用程序,我从 OpenStreetMap 获取数据并使用传单折线在地图上说明路径。有些小径有标签 oneway= 'yes',我想使用折线本身上的箭头直观地表示它,这样就可以很容易地知道每条小径的走向。

我已经搜索并尝试了许多不同的途径来尝试在我的应用程序中复制此功能,使用传单插件,例如 leaflet-polylineDecorator 或 leaflet-arrowheads。我什至尝试渲染一堆标记并旋转它们以指向下一个节点,但我没有设法使其工作,而且对于如此简单的事情来说,它似乎太复杂了。

我正在考虑实现一个简单且轻量级的解决方案,以避免减慢应用程序的速度。有没有我缺少的简单解决方案?

reactjs next.js leaflet openstreetmap polyline
1个回答
0
投票

您可以相对轻松地添加装饰

leaflet.polylineDecorator

我建议您将装饰器添加到单独的

L.FeatureGroup
中,以便您可以根据缩放级别轻松显示和隐藏它们。

这是一个例子:

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>StackOverflow Question 79028922 - Trail Directions</title>

    <link rel="stylesheet" href="leaflet.css" />
    <script src="leaflet.js"></script>

    <script src="leaflet.polylineDecorator.js"></script>

    <style>
        body {
            margin: 0;
        }

        #map {
            height: 100vh;
        }
    </style>

</head>

<body>

    <div id="map"></div>

    <script>

        const coordinate = [46.948056, 7.4475];

        const map = L.map('map').setView(coordinate, 15);

        L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 22,
            // add link to attribution, omitted in this code example
            // due to width limit, i.e., avoid horizontal scrolling
            attribution: '&copy; OpenStreetMap',
        }).addTo(map);

        fetch('trails.geojson')
            .then(response => response.json())
            .then(trails => {

                const trailLayer = L.geoJSON(trails, {
                    style: (feature) => {
                        const isOneWay = feature.properties['oneway'] == 'yes';
                        return {
                            color: isOneWay ? '#a14242' : '#160042',
                        };
                    }, 
                }).addTo(map);

                // create decorators
                const decorators = trailLayer.getLayers()
                    .filter(layer => layer.feature.properties['oneway'] == 'yes')
                    .map(layer => {

                        // swap lat/lon (needed as GeoJSON uses a different order)
                        const coordinates = layer.feature.geometry.coordinates
                            .map(c => [c[1], c[0]]);

                        // create the decorator for the trail
                        return L.polylineDecorator(L.polyline(coordinates), {
                            patterns: [{ 
                                offset: '5%', 
                                repeat: '50px', 
                                symbol: L.Symbol.arrowHead({ 
                                    pixelSize: 10, 
                                    polygon: false, 
                                    pathOptions: { 
                                        stroke: true, 
                                        color: '#a14242' 
                                    } 
                                }) 
                            }]
                        });

                    });

                const featureGroup = L.featureGroup(decorators, {}).addTo(map);

                map.on('zoom', event => {
                    featureGroup.clearLayers();
                    if (map.getZoom() >= 15) {
                        decorators.forEach(decorator => {
                            featureGroup.addLayer(decorator);
                        });
                    }
                });

            });

    </script>

</body>

</html>

文件

trails.geojson
可以在这里找到。

我还将代码上传到 GitHub 存储库这里,并且可以在这里找到演示。


我认为使用

leaflet.polylineDecorator
leaflet-arrowheads
等库可能是最轻量级的解决方案,否则您需要手动操作 SVG 路径。

© www.soinside.com 2019 - 2024. All rights reserved.