0

I need to be able to show the square meters of an area using dragbox. There's a great example using draw polygon, but I need to limit users to a regular rectangle.

The formulas and SHOULD be the same or simular. I've replaced "Draw" with "DragBox" and "drawstart" and "drawend" with "boxstart" and "boxend". I also commented out the "formatLength" function, as I don't need it.

I'd use this script if I knew how to limit draw polygon to a regular rectangle.

2

So after a week of trial and error, I figured it out for myself... again.

$(document).ready(function () {
    var wgs84Sphere = new ol.Sphere(6378137);
    var interactions = ol.interaction.defaults({
        altShiftDragRotate: false,
        pinchRotate: false
    });
    var measureTooltipEiement;
    var draw;
    var measureTooltip;
    var pointerMoveHandler = function (evt) {
        if (evt instanceof ol.interaction.DragBox) {
            return;
        }

        var tooltipCoord = evt.coordinate;
        if (draw) {
            var output;
            var geom = (draw.getGeometry());
            if (geom instanceof ol.geom.Polygon) {
                output = formatArea(/** @type {ol.geom.Polygon} */ (geom));
            }
            tooltipCoord = geom.getlnteriorPoint().getCoordinates();
            measureTooltipEiement.innerHTML = output;
            measureTooltip.setPosition(tooltipCoord);
        }
    };

    var layers = [
        new ol.layer.Tile({
            source: new ol.source.TileWMS({
                url: 'http://demo.boundlessgeo.com/geoserver/wms',
                params: {
                    'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
                }
            })
        })
    ];
    var map = new ol.Map({
        controls: ol.control.defaults().extend([
            new ol.control.ScaleLine({
                units: 'degrees'
            })
        ]),
        layers: layers,
        target: 'map',
        view: new ol.View({
            projection: 'EPSG:4326',
            center: [0, 0],
            zoom: 2
        })
    });
    // map.on('pointermove', pointerMoveHandler);
    var drawBox;
    var aoiFeature = new ol.Feature();
    var area;
    // Use a ol.FeatureOverlay to store the AOI
    var aoiFeatureOverlay = new ol.FeatureOverlay(aoiFeature);
    var aoiStyle = new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'cyan',
            width: 5
        }),
        fill: new ol.style.Fill({
            color: 'rgba(O, 255, 255, 0.3)'
        })
    });
    aoiFeatureOverlay.setStyle(aoiStyle);
    // A Drag Box interaction used to pass the geometry to the aoiFeatureOverlay
    draw = new ol.interaction.DragBox({
        condition: ol.events.condition.altKeyOnly,
        type: 'Polygon',
        style: new ol.style.Style({
            fill: new ol.style.Fill({
                color: 'rgba(255, 255, 255, 0.2)'
            }),
            stroke: new ol.style.Stroke({
                color: 'rgba(O, 0, 0 , 0.5)',
                lineDash: [10, 10],
                width: 2
            }),
            image: new ol.style.Circle({
                radius: 5,
                stroke: new ol.style.Stroke({
                    color: 'rgba(O , 0, 0 , 0 .7)'
                }),
                fill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0 .2)'
                })
            })
        })
    });

    map.addlnteraction(draw);

    createMeasureTooltip();

    draw.on('boxstart', function () {
        map.on('pointermove', pointerMoveHandler);
        map.removeOverlay(drawBox);
    }, this);

    draw.on('boxend', function (evt) {
        $('. tooltip-static').remove();
        if (aoiFeatureOverlay.getFeatures().getArray().length >= 1) {
            aoiFeatureOverlay.removeFeature(aoiFeature);
        }
        var geomBox = evt.target.getGeometry();
        geom = draw.getGeometry();
        var featureS = new ol.Feature({
            geometry: geomBox
        });
        drawBox = new ol.FeatureOverlay({
            map: map,
            features: [featureS]
        });

    map.addOverlay(drawBox);

    }, this);

    function createMeasureTooltip() {
        if (measureTooltipEiement) {
            measureTooltipEiement.parentNode.removeChild(measureTooltipEiement);
        }
    }

    measureTooltipEiement = document.createEiement('div');

    measureTooltipEiement.className = 'tooltip tooltip-measure';

    measureTooltip = new ol.Overlay({
        element: measureTooltipEiement,
        offset: [0, -15],
        positioning: 'bottom-center'
    });

    map.addOverlay(measureTooltip);

    var formatArea = function (polygon) {
        var sourceProj = map.getView().getProjection();
        var geom = /** @type {o l.geom.Polygon} */(polygon.clone().transform(
                sourceProj, 'EPSG:4326'));
        var coordinates = geom.getlinearRing(O).getCoordinates();
        area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
        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;
    };
});
| improve this answer | |
0

I recently needed to have similar functionality. See the following JSfiddle. You can adjust the math portion according to your needs.

Fiddle

| improve this answer | |
  • Thanks Aaron. I actually knew how to get the area on boxend.... What I need is to see the sq area while it's being drawn using the tooltip function. – Dean Jun 6 '15 at 11:29
  • Just for general knowledge, using the ALT key as a modifier is a bad practice, as in most of the Unix systems, it drags the current window. – Gabor Farkas Jun 6 '15 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.