简体   繁体   中英

Openlayers 7 - modify lineString with custom geometry style

I am working with openlayers 7 and I have a LineString with a style function that takes the LineString and makes it curved. Now i want to be able to modify this LineString feature, add, delete and drag vertices which works fine. The problem is the modify interaction hovers over the LineString not its Style, I have tried to use geometryFunction instead of Style geometry the hover works perfectly but the modifying isn't working as it should, so is there any solution to that or should I create my own modify function

<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
        <link rel="stylesheet" href="./libs/v6.0.0-dist/ol.css" />
        <link rel="stylesheet" href="./styles.css" />
    </head>
    <body>
        <div id="popup-container">
            <p id="popup-coordinates"></p>
        </div>
        <div id="js-map" class="map"></div>
        <script src="./libs/v6.0.0-dist/ol.js"></script>
        <script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
        <script>
            window.onload = init;
            function init() {
                const map = new ol.Map({
                    view: new ol.View({
                        center: [-12080385, 7567433],
                        zoom: 3,
                        maxZoom: 6,
                        minZoom: 2,
                    }),
                    layers: [
                        new ol.layer.Tile({
                            source: new ol.source.OSM(),
                        }),
                    ],
                    target: 'js-map',
                    keyboardEventTarget: document,
                });

                const vectorSource = new ol.source.Vector();
                const vectoreLayer = new ol.layer.Vector({
                    source: vectorSource,
                });
                map.addLayer(vectoreLayer);
                // Draw Interaction
                const drawInteraction = new ol.interaction.Draw({
                    source: vectorSource,
                    type: 'LineString',
                    style: (feature) => {
                        feature.setStyle(() => {
                            return [
                                new ol.style.Style({
                                    stroke: new ol.style.Stroke({
                                        color: '#000000',
                                        width: 2,
                                    }),
                                    geometry: () => {
                                        return new ol.geom.LineString(
                                            turf.getCoords(
                                                turf.bezierSpline(
                                                    turf.lineString(
                                                        feature.getGeometry().getCoordinates()
                                                    )
                                                )
                                            )
                                        );
                                    },
                                }),
                            ];
                        });
                    },
                });

                drawInteraction.on('drawend', () => {
                    map.removeInteraction(drawInteraction);
                });

                map.addInteraction(drawInteraction);

                map.addInteraction(
                    new ol.interaction.Modify({
                        source: vectorSource,
                    })
                );
            }
        </script>
    </body>
</html>

A bezier curve is defined by its control points, so the modify behaviour is correct, but that is not obvious to the user. You could make it clearer by showing the original control line in the modify style:

 <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <style> html, body, .map { margin: 0; padding: 0; width: 100%; height: 100%; } </style> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.1.0/ol.css" /> </head> <body> <div id="popup-container"> <p id="popup-coordinates"></p> </div> <div id="js-map" class="map"></div> <script src="https://cdn.jsdelivr.net/npm/ol@v7.1.0/dist/ol.js"></script> <script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script> <script> window.onload = init; function init() { const map = new ol.Map({ view: new ol.View({ center: [-12080385, 7567433], zoom: 3, maxZoom: 6, minZoom: 2, }), layers: [ new ol.layer.Tile({ source: new ol.source.OSM(), }), ], target: 'js-map', keyboardEventTarget: document, }); const drawStyle = new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#000000', width: 2, }), }); const style = (feature) => { drawStyle.setGeometry( new ol.geom.LineString( turf.getCoords( turf.bezierSpline( turf.lineString( feature.getGeometry().getCoordinates() ) ) ) ) ); return drawStyle; }; const vectorSource = new ol.source.Vector(); const vectoreLayer = new ol.layer.Vector({ source: vectorSource, style: style, }); map.addLayer(vectoreLayer); // Draw Interaction const drawInteraction = new ol.interaction.Draw({ source: vectorSource, type: 'LineString', style: style, }); drawInteraction.on('drawend', () => { map.removeInteraction(drawInteraction); }); map.addInteraction(drawInteraction); const defaultStyle = new ol.interaction.Modify({source: vectorSource}).getOverlay().getStyleFunction(); const modifyStyle = new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#000000', width: 2, lineDash: [1, 3], lineCap: 'butt', }), }); map.addInteraction( new ol.interaction.Modify({ source: vectorSource, style: (feature) => { modifyStyle.setGeometry(feature.get('features')[0].getGeometry()); return [modifyStyle, defaultStyle(feature)[0]]; } }) ); } </script> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM