Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am trying to make a OpenLayers measure tool that displays the length of each segment on top of each segment and the total length of the measurement as shown below:

Measure control with length of each segment

I have used this example http://openlayers.org/dev/examples/measure.html. I can see in the example that the geometry created is one big LineString.

Therefore my general thought was to get the measure control to create a new line segment (LineString) for each of the user click except the first, then add an attribute with the segment length and display it with the label parameter in the style.

But I don't know if it will conflict with the current design of the measure control or if this is the correct approach to my problem?

All comments or guidance would be appreciated.

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

Your suggestions sounds fine. Also every geometry object has a distanceTo() function which can be used like:

geometry.distanceTo(anothergeometry)

EDIT:

After more thought and testing the example, i think it would be easiest for you add new layer for labeling purposes. Possibly a layer of just points which you would set the labelXOffset and labelYOffset to half the distance between each point in your measuring linestring. But i don't think you'll be able to rotate the labels.

Look at how this measure tool is, it's probably the best you'll be able to do: http://chamaps.com/watervliet/

Check out how he does it: http://chamaps.com/watervliet/js/map.js

var lineStyle = new OpenLayers.Style();
lineStyle.addRules([
new OpenLayers.Rule({
    symbolizer: linemeasureStyles
})]);
var linemeasureStyleMap = new OpenLayers.StyleMap({
    "default": lineStyle
});
var length = new OpenLayers.Control.Measure(OpenLayers.Handler.Path, {
    displaySystem: "english",
    geodesic: true,
    persist: true,
    handlerOptions: {
        layerOptions: {
            styleMap: linemeasureStyleMap
        }
    },
    textNodes: null,
    callbacks: {
        create: function () {
            this.textNodes = [];
            layerRuler.removeFeatures(layerRuler.features);
            mouseMovements = 0;
        },
        modify: function (point, line) {
            if (mouseMovements++ < 5) {
                return;
            }
            var len = line.geometry.components.length;
            var from = line.geometry.components[len - 2];
            var to = line.geometry.components[len - 1];
            var ls = new OpenLayers.Geometry.LineString([from, to]);
            var dist = this.getBestLength(ls);
            if (!dist[0]) {
                return;
            }
            var total = this.getBestLength(line.geometry);
            var label = dist[0].toFixed(2) + " " + dist[1];
            var textNode = this.textNodes[len - 2] || null;
            if (textNode && !textNode.layer) {
                this.textNodes.pop();
                textNode = null;
            }
            if (!textNode) {
                var c = ls.getCentroid();
                textNode = new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(c.x, c.y), {}, {
                    label: '',
                    fontColor: "#FF0000",
                    fontSize: "14px",
                    fontFamily: "Arial",
                    fontWeight: "bold",
                    labelAlign: "cm"
                });
                this.textNodes.push(textNode);
                layerRuler.addFeatures([textNode]);
            }
            textNode.geometry.x = (from.x + to.x) / 2;
            textNode.geometry.y = (from.y + to.y) / 2;
            textNode.style.label = label;
            textNode.layer.drawFeature(textNode);
            this.events.triggerEvent("measuredynamic", {
                measure: dist[0],
                total: total[0],
                units: dist[1],
                order: 1,
                geometry: ls
            });
        }
    }
});
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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