3

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.

4

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

  • Thanks @Mingfeng but will this rotate the image by using mouse? – Harshil Shukla Sep 12 '13 at 14:26
  • Yes, it will just work in the same way as ModifyFeature. – mfdev Sep 12 '13 at 14:30
  • Hi Minfeng, I tried to put this code and but it is not rotating the image and even I think OpenLayers is not supporting this feature. – Harshil Shukla Sep 13 '13 at 9:08
  • I just updated the code. The code is tested and working well. – mfdev Oct 4 '13 at 7:13
0

I fixed Mingfeng's example and now it's work for me.

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: "./static/resources/images/cross.png",
                graphicWidth: 12,
                graphicHeight: 12,
                fillOpacity: 1
            });

        },

        resetVertices: function() {
            // You need to set yours renderIntent or use "vertex"
            if (this.feature && this.feature.renderIntent == "vertex") {
                var vertex = this.feature;
                this.feature = this.backup_feature;
                this.layer.destroyFeatures([this.radiusHandle], {silent: true});
                this.collectRadiusHandle();
                return;
            }
            if (this.dragControl.feature) {
                this.dragControl.outFeature(this.dragControl.feature);
            }
            if (this.vertices.length > 0) {
                this.layer.removeFeatures(this.vertices, {silent: true});
                this.vertices = [];
            }
            if (this.virtualVertices.length > 0) {
                this.layer.removeFeatures(this.virtualVertices, {silent: true});
                this.virtualVertices = [];
            }
            if (this.dragHandle) {
                this.layer.destroyFeatures([this.dragHandle], {silent: true});
                this.dragHandle = null;
            }
            if (this.radiusHandle) {
                this.layer.destroyFeatures([this.radiusHandle], {silent: true});
                this.radiusHandle = null;
            }
            if (this.feature && this.feature.geometry &&
                this.feature.geometry.CLASS_NAME != "OpenLayers.Geometry.Point") {
                if ((this.mode & OpenLayers.Control.ModifyFeature.DRAG)) {
                    this.collectDragHandle();
                }
                if ((this.mode & (OpenLayers.Control.ModifyFeature.ROTATE |
                OpenLayers.Control.ModifyFeature.RESIZE))) {
                    this.collectRadiusHandle();
                }
                if (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE) {
                    if (!(this.mode & OpenLayers.Control.ModifyFeature.RESIZE)) {
                        this.collectVertices();
                    }
                }
            }
            this.collectRadiusHandle();
        },

        collectRadiusHandle: function() {
            var scope = this,
                feature = this.feature,
                geometry = this.feature.geometry || this.backup_feature.geometry,
                centroid = geometry.getCentroid().transform(this.WGS84_google_mercator, this.WGS84),
                lon = centroid.x, lat = centroid.y;

            if (this.feature.geometry) {
                this.backup_feature = this.feature;
            } else {
                this.feature.geometry = this.backup_feature.geometry;
            }

            var originGeometry = new OpenLayers.Geometry.Point(lon, lat);

            // radius geometry position.
            var pixel_dis_x = 10,
                pixel_dis_y = -10;
            var rotationFeatureGeometry = new OpenLayers.Geometry.Point(lon+pixel_dis_x, lat+pixel_dis_y);

            var rotationFeature = new OpenLayers.Feature.Vector(rotationFeatureGeometry, 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);

            rotationFeatureGeometry.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;
                    var old_angle = feature.attributes.angle;
                    var new_angle = old_angle - angle;
                    feature.attributes.angle = new_angle;
                    // redraw the feature
                    scope.feature.layer.redraw.call(scope.feature.layer);
                }
            };
            rotationFeature._sketch = true;
            this.radiusHandle = rotationFeature;
            this.radiusHandle.renderIntent = this.vertexRenderIntent;
            this.layer.addFeatures([this.radiusHandle], {silent: true});
        },

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

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.