TransWikia.com

I Implemented the delete Feature in OpenLayers 4 but cannot delete the corresponding Popup

Geographic Information Systems Asked by Bello Oluwasegun Cornelius on December 19, 2020

I have tried implementing the measure feature from an OpenLayers example and implemented a delete feature button. It works well but I was unable make it delete the corresponding measure popup with it. I am a JavaScript beginner.

<!DOCTYPE html>
<html>

<head>
    <title>Measure</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css" />
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script
        src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
    <style>
        .tooltip {
            position: relative;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 4px;
            color: white;
            padding: 4px 8px;
            opacity: 0.7;
            white-space: nowrap;
        }

        .tooltip-measure {
            opacity: 1;
            font-weight: bold;
        }

        .tooltip-static {
            background-color: #ffcc33;
            color: black;
            border: 1px solid white;
        }

        .tooltip-measure:before,
        .tooltip-static:before {
            border-top: 6px solid rgba(0, 0, 0, 0.5);
            border-right: 6px solid transparent;
            border-left: 6px solid transparent;
            content: "";
            position: absolute;
            bottom: -6px;
            margin-left: -7px;
            left: 50%;
        }

        .tooltip-static:before {
            border-top-color: #ffcc33;
        }
    </style>
</head>

<body>
    <div id="map" class="map"></div>
    <form class="form-inline">
        <label>Measurement type &nbsp;</label>
        <select id="type">
            <option value="length">Length (LineString)</option>
            <option value="area">Area (Polygon)</option>
        </select>
        <button id="delete-button" type="button" class="btn btn-danger">
            Delete
        </button>

        <div id="js-overlay">
            <button id="js-remove">Remove</button>
        </div>
    </form>
    <p>jhghjgjh jg jh</p>
    <script>
        var raster = new ol.layer.Tile({
            source: new ol.source.OSM(),
        });

        var source = new ol.source.Vector();

        var vector = new ol.layer.Vector({
            source: source,
            style: new ol.style.Style({
                fill: new ol.style.Fill({
                    color: "rgba(255, 255, 255, 0.2)",
                }),
                stroke: new ol.style.Stroke({
                    color: "#ffcc33",
                    width: 2,
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({
                        color: "#ffcc33",
                    }),
                }),
            }),
        });

        /**
         * Currently drawn feature.
         * @type {ol.Feature}
         */
        var sketch;

        /**
         * The help tooltip element.
         * @type {Element}
         */
        var helpTooltipElement;

        /**
         * Overlay to show the help messages.
         * @type {ol.Overlay}
         */
        var helpTooltip;

        /**
         * The measure tooltip element.
         * @type {Element}
         */
        var measureTooltipElement;

        /**
         * Overlay to show the measurement.
         * @type {ol.Overlay}
         */
        var measureTooltip;

        /**
         * Message to show when the user is drawing a polygon.
         * @type {string}
         */
        var continuePolygonMsg = "Click to continue drawing the polygon";

        /**
         * Message to show when the user is drawing a line.
         * @type {string}
         */
        var continueLineMsg = "Click to continue drawing the line";

        /**
         * Handle pointer move.
         * @param {ol.MapBrowserEvent} evt The event.
         */
        var pointerMoveHandler = function (evt) {
            if (evt.dragging) {
                return;
            }
            /** @type {string} */
            var helpMsg = "Click to start drawing";

            if (sketch) {
                var geom = sketch.getGeometry();
                if (geom instanceof ol.geom.Polygon) {
                    helpMsg = continuePolygonMsg;
                } else if (geom instanceof ol.geom.LineString) {
                    helpMsg = continueLineMsg;
                }
            }

            helpTooltipElement.innerHTML = helpMsg;
            helpTooltip.setPosition(evt.coordinate);

            helpTooltipElement.classList.remove("hidden");
        };

        var map = new ol.Map({
            layers: [raster, vector],
            target: "map",
            view: new ol.View({
                center: [-11000000, 4600000],
                zoom: 15,
            }),
        });

        map.on("pointermove", pointerMoveHandler);

        map.getViewport().addEventListener("mouseout", function () {
            helpTooltipElement.classList.add("hidden");
        });

        var typeSelect = document.getElementById("type");

        var draw; // global so we can remove it later

        /**
         * Format length output.
         * @param {ol.geom.LineString} line The line.
         * @return {string} The formatted length.
         */
        var formatLength = function (line) {
            var length = ol.Sphere.getLength(line);
            var output;
            if (length > 100) {
                output =
                    Math.round((length / 1000) * 100) / 100 + " " + "km";
            } else {
                output = Math.round(length * 100) / 100 + " " + "m";
            }
            return output;
        };

        /**
         * Format area output.
         * @param {ol.geom.Polygon} polygon The polygon.
         * @return {string} Formatted area.
         */
        var formatArea = function (polygon) {
            var area = ol.Sphere.getArea(polygon);
            var output;
            if (area > 10000) {
                output =
                    Math.round((area / 1000000) * 100) / 100 +
                    " " +
                    "km<sup>2</sup>";
            } else {
                output =
                    Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
            }
            return output;
        };

        function addInteraction() {
            var type =
                typeSelect.value == "area" ? "Polygon" : "LineString";
            draw = new ol.interaction.Draw({
                source: source,
                type: type,
                style: new ol.style.Style({
                    fill: new ol.style.Fill({
                        color: "rgba(255, 255, 255, 0.2)",
                    }),
                    stroke: new ol.style.Stroke({
                        color: "rgba(0, 0, 0, 0.5)",
                        lineDash: [10, 10],
                        width: 2,
                    }),
                    image: new ol.style.Circle({
                        radius: 5,
                        stroke: new ol.style.Stroke({
                            color: "rgba(0, 0, 0, 0.7)",
                        }),
                        fill: new ol.style.Fill({
                            color: "rgba(255, 255, 255, 0.2)",
                        }),
                    }),
                }),
            });
            map.addInteraction(draw);

            createMeasureTooltip();
            createHelpTooltip();

            var listener;
            draw.on(
                "drawstart",
                function (evt) {
                    // set sketch
                    sketch = evt.feature;

                    /** @type {ol.Coordinate|undefined} */
                    var tooltipCoord = evt.coordinate;

                    listener = sketch
                        .getGeometry()
                        .on("change", function (evt) {
                            var geom = evt.target;
                            var output;
                            if (geom instanceof ol.geom.Polygon) {
                                output = formatArea(geom);
                                tooltipCoord = geom
                                    .getInteriorPoint()
                                    .getCoordinates();
                            } else if (geom instanceof ol.geom.LineString) {
                                output = formatLength(geom);
                                tooltipCoord = geom.getLastCoordinate();
                            }
                            measureTooltipElement.innerHTML = output;
                            measureTooltip.setPosition(tooltipCoord);
                        });
                },
                this
            );

            draw.on(
                "drawend",
                function () {
                    measureTooltipElement.className =
                        "tooltip tooltip-static";
                    measureTooltip.setOffset([0, -7]);
                    // unset sketch
                    sketch = null;
                    // unset tooltip so that a new one can be created
                    measureTooltipElement = null;
                    createMeasureTooltip();
                    ol.Observable.unByKey(listener);
                },
                this
            );
        }

        /**
         * Creates a new help tooltip
         */
        function createHelpTooltip() {
            if (helpTooltipElement) {
                helpTooltipElement.parentNode.removeChild(
                    helpTooltipElement
                );
            }
            helpTooltipElement = document.createElement("div");
            helpTooltipElement.className = "tooltip hidden";
            helpTooltip = new ol.Overlay({
                element: helpTooltipElement,
                offset: [15, 0],
                positioning: "center-left",
            });
            map.addOverlay(helpTooltip);
        }

        /**
         * Creates a new measure tooltip
         */
        function createMeasureTooltip() {
            if (measureTooltipElement) {
                measureTooltipElement.parentNode.removeChild(
                    measureTooltipElement
                );
            }
            measureTooltipElement = document.createElement("div");
            measureTooltipElement.className = "tooltip tooltip-measure";
            measureTooltip = new ol.Overlay({
                element: measureTooltipElement,
                offset: [0, -15],
                positioning: "bottom-center",
            });
            map.addOverlay(measureTooltip);
        }

        /**
         * Let user change the geometry type.
         */
        typeSelect.onchange = function () {
            map.removeInteraction(draw);
            addInteraction();
        };

        addInteraction();



        //IT ALL STARTS HERE
        document.getElementById("js-remove").addEventListener("click", function () {
            vector.getSource().removeFeature(selectedFeature);
            overlay.setPosition(undefined);
            interaction.getFeatures().clear();
        });
        var remove_b = document.getElementById("js-overlay");
        var overlay = new ol.Overlay({
            element: remove_b,
        });
        map.addOverlay(overlay);
        document.getElementById("js-overlay").style.display = "block";


        var selectedFeature;
        function onClick(id, callback) {
            document.getElementById(id).addEventListener("click", callback);
        }


        interaction = new ol.interaction.Select({
            condition: ol.events.condition.click,
            layers: [vector],
        });
        map.addInteraction(interaction);

        interaction.on("select", function (event) {
            selectedFeature = event.selected[0];
            selectedFeature
                ? overlay.setPosition(
                    selectedFeature.getGeometry().getExtent()
                )
                : overlay.setPosition(undefined);
        });



    </script>
</body>

</html>

One Answer

You will need to delete the parents of the tooltip-static under js-remove click event. However, to only delete the selected features tooltip together with the feature, you need to bind the tooltip with the feature using the feature id feature.xp by adding the feature.xp in the draw.on("drawend"..) method.

        draw.on(
            "drawend",
            function (evt) {
                // Attach the feature xp to the className to get the feature tooltip
                measureTooltipElement.className =
                    "tooltip tooltip-static " + evt.feature.xp;
                measureTooltip.setOffset([0, -7]);
                // unset sketch
                sketch = null;
                // unset tooltip so that a new one can be created
                measureTooltipElement = null;
                createMeasureTooltip();
                ol.Observable.unByKey(listener);
            },
            this
        );
    
    

Then remove only the selected and being removed feature's tooltip using the code below.

    document.getElementById("js-remove").addEventListener("click", function () {
        vector.getSource().removeFeature(selectedFeature);
        overlay.setPosition(undefined);
        interaction.getFeatures().clear();

        // Get the feature's measure tooltip only
        var tips = document.getElementsByClassName(selectedFeature.xp);
        //Remove the tip associated with this current feature being removed
        if (tips.length > 0){
               tips[0].parentNode.remove();
        }
    });

Check it out on JSFiddle

Correct answer by wondim on December 19, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP