[GIS] How to rotate external graphic using mouse in Openlayers

graphopenlayers-2

I would like to rotate externalGraphic using mouse something like this URL.

In this URL polygon is used to rotate it but I want an image to be rotated using external graphics tag.

Any help is appreciated.

Best Answer

Maybe this one is a better example, and I'm afraid transformFeature control is not the right tool to do this job because it can only change the geometry of the feature but externalGraphic is a style property, which can only apply to a point feature. And another style property you need to use is rotation. So you have to write your own logic by using javascript, probably creating a new custom openlayers control. However, the logic is quite straightforward so you won't need to write a lot of codes. You will need a custom control like the following one, note this code is not guaranteed to work in your application, you may improve it at some point to make it work with your application.


// Create a new openlayers control inherited from ModifyFeature control
OpenLayers.Control.RotateGraphicFeature = OpenLayers.Class(OpenLayers.Control.ModifyFeature, {
    rotateHandleStyle: null,

    initialize: function(layer, options) {
        OpenLayers.Control.ModifyFeature.prototype.initialize.apply(this, arguments);
        this.mode = OpenLayers.Control.ModifyFeature.ROTATE; // This control can only be used to rotate the feature
        this.geometryTypes = ['OpenLayers.Geometry.Point'] // This control can only be used to rotate point because the 'exteralGraphic' is a point style property

        var init_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style.select);
        this.rotateHandleStyle = OpenLayers.Util.extend(init_style, {
            externalGraphic: "img/rotate.png",
            graphicWidth: 15,
            graphicHeight: 14,
            fillOpacity: 1
        });
    },

    resetVertices: function() {
        OpenLayers.Control.ModifyFeature.prototype.resetVertices.apply(this, arguments);
        this.collectRadiusHandle();
    },    

    collectRadiusHandle: function() {
        var geometry = this.feature.geometry;
        var bounds = geometry.getBounds();
        console.log('bounds information: ', bounds);
        var center = bounds.getCenterLonLat();
        var originGeometry = new OpenLayers.Geometry.Point(
            center.lon, center.lat
        );

        var center_px = this.map.getPixelFromLonLat(center);

        var pixel_dis_x = 15; 
        var pixel_dis_y = 15; // you can change this two values to get best radius geometry position.

        var radius_px = center_px.add(pixel_dis_x, pixel_dis_y);
        var raius_lonlat = this.map.getLonLatFromPixel(radius_px);

        var radiusGeometry = new OpenLayers.Geometry.Point(
            raius_lonlat.lon, raius_lonlat.lat
        );
        var radius = new OpenLayers.Feature.Vector(radiusGeometry, null, this.rotateHandleStyle);
        var resize = (this.mode & OpenLayers.Control.ModifyFeature.RESIZE);
        var reshape = (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE);
        var rotate = (this.mode & OpenLayers.Control.ModifyFeature.ROTATE);

        var scope_this = this; // in order to get the feature inside radiusGeometry.move function
        radiusGeometry.move = function(x, y) {
            OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
            var dx1 = this.x - originGeometry.x;
            var dy1 = this.y - originGeometry.y;
            var dx0 = dx1 - x;
            var dy0 = dy1 - y;
            if(rotate) {
                var a0 = Math.atan2(dy0, dx0);
                var a1 = Math.atan2(dy1, dx1);
                var angle = a1 - a0;
                angle *= 180 / Math.PI;
                // if the feature has been set a externalGraphic, then change the rotation property of the feature style
                if (scope_this.feature.attributes.angle !== undefined) {
                    var old_angle = scope_this.feature.attributes.angle;
                    var new_angle = old_angle - angle;
                    scope_this.feature.attributes.angle = new_angle;
                    // redraw the feature
                    scope_this.layer.drawFeature(scope_this.feature);
                }
            }

        };
        radius._sketch = true;
        this.radiusHandle = radius;
        this.radiusHandle.renderIntent = this.vertexRenderIntent;
        this.layer.addFeatures([this.radiusHandle], {silent: true});
    },

    CLASS_NAME: "OpenLayers.Control.RotateGraphicFeature"
});

enter image description here