[OpenLayers-Users] Handler.RegularPolygon

Tim Langlois tlanglois at archetypecorp.com
Wed May 23 12:23:13 EDT 2007


Looks like security restrictions where preventing the old URL from
working, so I thought I would resend this.

I wrote a custom handler to draw an N-sided regular polygon by clicking
and dragging a line to specify the radius.  The polygon is drawn on
mouse up.  The number of sides is specified by the "sides" attribute.

Here's an example.  Click the polygon button in the toolbar in the upper
right corner and click and drag to create the polygon.  To change the
sides, enter the number of sides you want and click submit.

http://maps.terratrace.net/vmaptest.html



The information transmitted is the property of Archetype, Inc. and is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Statements and opinions expressed in this e-mail may not represent those of the company.  Any review, retransmission, dissemination and other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender immediately and delete the material from any computer. E-mail transmission cannot be guaranteed to be secured or error-free as information could be intercepted, corrupted, lost, destroyed, received late or incomplete, or could contain viruses. The sender therefore does not accept liability for any error or omission in the contents of this message, which arises as a result of e-mail transmission.
-------------- next part --------------
/**
 * Handler to draw an N sided regular ploygon on the map.  A point is drawn on mouse down,
 * a line is drawn on mouse move (representing the radius), and the polygon is drawn on mouse up.
 * Use the "sides" option to set the number of polygon sides.
 * 
 * @class
 * @requires OpenLayers/Handler/Point.js
 * @requires OpenLayers/Geometry/Polygon.js
 */
OpenLayers.Handler.RegularPolygon = OpenLayers.Class.create();
OpenLayers.Handler.RegularPolygon.prototype = 
  OpenLayers.Class.inherit(OpenLayers.Handler.Point, {
    
    /**
     * @type OpenLayers.Feature.Vector
     * @private
     */
    line: null,

    /**
     * @type OpenLayers.Feature.Vector
     * @private
     */
    regularPolygon: null,

    /**
     * The number of sides the polygon will have
     * @type int
     */
    sides: 50,

    /**
     * @constructor
     *
     * @param {OpenLayers.Control} control
     * @param {Array} callbacks An object with a 'done' property whos value is
     *                          a function to be called when the path drawing is
     *                          finished. The callback should expect to recieve a
     *                          single argument, the polygon geometry.
     *                          If the callbacks object contains a 'point'
     *                          property, this function will be sent each point
     *                          as they are added.  If the callbacks object contains
     *                          a 'cancel' property, this function will be called when
     *                          the handler is deactivated while drawing.  The cancel
     *                          should expect to receive a geometry.
     * @param {Object} options
     */
    initialize: function(control, callbacks, options) {
        OpenLayers.Handler.Point.prototype.initialize.apply(this, arguments);
    },
    
    /**
     * Add temporary geometries
     */
    createFeature: function() {
        this.line = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString());
        this.point = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point());
        this.regularPolygon = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon());
    },

    /**
     * Destroy temporary geometries
     */
    destroyFeature: function() {
        this.line.destroy();
        this.point.destroy();
        this.regularPolygon.destroy();
        this.line = null;
        this.regularPolygon = null;
    },

    /**
     * Modify the existing geometry given the new point
     *
     */
    modifyFeature: function() {
        var index = this.line.geometry.components.length - 1;
        this.line.geometry.components[index].x = this.point.geometry.x;
        this.line.geometry.components[index].y = this.point.geometry.y;
    },


    /**
     * Render geometries on the temporary layer.
     */
    drawFeature: function() {
        this.layer.drawFeature(this.line,  this.style);
        this.layer.drawFeature(this.point, this.style);
    },

    /**
     * Add point to geometry.  Send the point index to override
     * the behavior of LinearRing that disregards adding duplicate points.
     */
    addPoint: function() {
        this.line.geometry.addComponent(this.point.geometry.clone(),
                                        this.line.geometry.components.length);
        this.callback("point", [this.point.geometry]);
    },

    /**
     * Return a clone of the relevant geometry.
     *
     * @type OpenLayers.Geometry.LineString
     */
    geometryClone: function() {
        return this.regularPolygon.geometry.clone();
    },

    createRegularPolygon: function() {
    	var pointList = [];
        // the radius is the length of the line segment
        var radius = this.line.geometry.getLength();

        // draw the polygon, the center is the first point drawn at mousedown
        if (radius > 0) {
            var cenx = this.line.geometry.components[0].x;
            var ceny = this.line.geometry.components[0].y;
            var piNum = Math.PI * 2;
            var segments = piNum / this.sides;

            for (var a = 0; a < piNum; a += segments) {
    		var x = cenx + radius * Math.sin(a);
    		var y = ceny + radius * Math.cos(a);         	
                var newPoint = new OpenLayers.Geometry.Point(x,y);
                pointList.push(newPoint);
            }
            pointList.push(pointList[0]);
            var linearRing = new OpenLayers.Geometry.LinearRing(pointList);
            this.regularPolygon.geometry.addComponent(linearRing);            
        } 
    },

    /**
     * Return the radius of the polygon
     *
     * @type int
     */
    getRadius: function() {
        this.line.geometry.getLength();
    },

    /**
     * Handle mouse down.  Add the starting (center) point of the polygon and render it
     * Return determines whether to propagate the event on the map.
     *
     * @param {Event} evt
     * @type Boolean
     */
    mousedown: function(evt) {
        if(this.point == null) {
            this.createFeature();
        }
        this.mouseDown = true;
        var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
        this.point.geometry.x = lonlat.lon;
        this.point.geometry.y = lonlat.lat;
        this.addPoint();
        this.drawFeature();
        return true;
    },

    /**
     * Handle mouse move.  Adjust the geometry and redraw the line.
     * Return determines whether to propagate the event on the map.
     *
     * @param {Event} evt
     * @type Boolean
     */
    mousemove: function (evt) {
        if ((this.line == null) || (this.line.geometry == null))
           return true;

        if(this.line.geometry.components.length > 0) {
            var lonlat = this.map.getLonLatFromPixel(evt.xy);
            if (this.line.geometry.components.length == 1) {
                this.point = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point());
                this.addPoint();
            }
            this.point.geometry.x = lonlat.lon;
            this.point.geometry.y = lonlat.lat;
            this.modifyFeature();
            this.drawFeature();
        }
        return false;
    },

    /**
     * Handle mouse up.  Send the last point in the geometry to the control. If we
     * have a valid line segment (radius), then draw the polygon.
     * Return determines whether to propagate the event on the map.
     *
     * @param {Event} evt
     * @type Boolean
     */
    mouseup: function (evt) {
        this.mouseDown = false;
        if (this.line.geometry.components.length == 2) {
            this.createRegularPolygon();
            this.line.destroy();
        }
        this.point.destroy();
        this.line = null;
        this.point = null;
        this.finalize();
        return false;
     },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Handler.RegularPolygon"
});


More information about the Users mailing list