我使用ol.interaction.Transform
在选择Map上的一个图像后旋转它。最终目标是能够缩放、拉伸、旋转和平移(拖放)图像。
我的问题是:
1.当我旋转图像时,它不会保持纵横比(图像的大小会发生变化,并且会进一步拉伸)
1.当图像被选中时,沿图像周长出现的红色虚线并不跟随旋转运动,例如,这是我开始旋转之前的样子:
这是我旋转时的样子:
我确实想这样(黑色虚线):
我怎样才能修好它?
这是我的代码:
var styleCache = {};
function getStyle(img, scaleX, scaleY) {
var view = map.getView();
var resolutionAtEquator = view.getResolution();
var y = Math.round(img.height * scaleY);
var x = Math.round(img.width * scaleX);
var key = img.src + ',' + x + ',' + y;
var style = styleCache[key];
if (!style) {
var canvas = document.createElement('canvas');
canvas.width = x;
canvas.height = y;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, x, y);
var resizeImageUrl = canvas.toDataURL();
canvas.remove();
var keys = Object.keys(styleCache);
if (keys.length >= 100) {
// delete an old entry to limit the cache size
delete styleCache[keys[0]];
}
var style = new ol.style.Style({
image: new ol.style.Icon({
src: resizeImageUrl,
opacity: imageOpacity,
})
});
styleCache[key] = style;
}
return style;
}
styles = [
new ol.style.Style({
fill: new ol.style.Fill({
color: transparent
})
}),
new ol.style.Style({
stroke: new ol.style.Stroke({
color: transparent,
width: width + 2
})
}),
new ol.style.Style({
stroke: new ol.style.Stroke({
color: transparent,
width: width
})
}),
new ol.style.Style({
image: new ol.style.Circle({
radius: width * 2,
fill: new ol.style.Fill({
color: blue
}),
stroke: new ol.style.Stroke({
color: transparent,
width: width / 2
})
}),
zIndex: Infinity
})
];
var florplanStyle = new ol.style.Style({
image: new ol.style.Icon({
src: img.src,
opacity: imageOpacity,
})
});
styleFunction = function(feature, resolution) {
var rayDrawValueX = img.width/2;
var resAdjustX = rayDrawValueX * resolution;
var rayDrawValueY = img.height/2;
var resAdjustY = rayDrawValueY * resolution;
var rotation = feature.get('rotation');
if (rotation !== undefined) {
var extent = feature.getGeometry().getExtent();
var coordinates = feature.getGeometry().getCoordinates()[0];
var getBottomLeft = ol.extent.getBottomLeft(extent);
var getBottomRight = ol.extent.getBottomRight(extent);
var getTopLeft = ol.extent.getTopLeft(extent);
var getTopRight = ol.extent.getTopRight(extent);
var center = ol.extent.getCenter(extent);
var dx = center[0] - getBottomLeft[0];
var dy = 0;
var scaleX = Math.sqrt(dx * dx + dy * dy)/resAdjustX;
var dx = 0;
var dy = getTopRight[1] - center[1];
var scaleY = Math.sqrt(dx * dx + dy * dy)/resAdjustY;
var florplanStyle2 = getStyle(img, scaleX, scaleY);
florplanStyle2.setGeometry(new ol.geom.Point(center));
florplanStyle2.getImage().setRotation(rotation);
return debug ? styles.concat([florplanStyle2]) : florplanStyle2;
} else if (feature.getGeometry().getCenter) {
//scrolling map case
florplanStyle.setGeometry(new ol.geom.Point(feature.getGeometry().getCenter()));
// get rotation from drawn feature or geometry
florplanStyle.getImage().setRotation(feature.getGeometry().get('rotation'));
florplanStyle.getImage().setScale(feature.getGeometry().getRadius()/resAdjustX);
return florplanStyle;
} else {
return styles;
}
};
if ( this.nord && this.sud && this.est && this.ovest && this.floorplanImage && this.opacity) {
var extent = ol.proj.transformExtent([this.ovest, this.sud, this.est, this.nord], 'EPSG:4326', 'EPSG:3857');
var center = ol.extent.getCenter(extent);
var size = ol.extent.getSize(extent);
var view = map.getView();
var resolutionAtEquator = view.getResolution();
var width = ol.extent.getWidth(extent);
var height = ol.extent.getHeight(extent);
var radius = width/2;
var rotation = 0;
var circle = circle || new ol.geom.Circle(center, radius);
var circleFeature = new ol.Feature(circle);
circleFeature.set('rotation', rotation);
var geom = ol.geom.Polygon.fromExtent(extent);
circleFeature.setGeometry(geom);
this.features.push(circleFeature);
this.mapView.fit(geom, {minResolution: 0.05});
} else {
this.controller.fireEvent('mapstaterequest');
}
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector({
wrapX: false,
features: this.features
});
var vector = new ol.layer.Vector({
source: source,
style: styleFunction
});
vector.setMap(map);
var draw = new ol.interaction.Draw({
source: source,
type: 'Circle',
geometryFunction: function(coordinates, geometry) {
var center = coordinates[0];
var last = coordinates[1];
var dx = center[0] - last[0];
var dy = center[1] - last[1];
var radius = dx;
var rotation = Math.PI - Math.atan2(dy, dx);
geometry = geometry || new ol.geom.Circle(center, radius);
geometry.setCenterAndRadius(center, radius);
geometry.set('rotation', rotation);
return geometry;
},
style: styleFunction,
handler: 'onSaveClick'
});
draw.on('drawstart', function () {
source.clear();
});
draw.on('drawend', function (evt) {
// move rotation from geometry to drawn feature
var rotation = evt.feature.getGeometry().get('rotation');
evt.feature.set('rotation', rotation);
var extent = evt.feature.getGeometry().getExtent();
var geom = ol.geom.Polygon.fromExtent(extent);
if(img.width!==img.height){
scaleY = img.height/img.width
geom.scale(1,scaleY);
}
evt.feature.setGeometry(geom);
});
this.map.addInteraction(draw);
var isCorner = true; // use opposite corner to scale/stretch, (false = use center);
var transform = new ol.interaction.Transform({
features: this.features,
translateFeature: false,
// flip wouldn't be compatible with rotation
noFlip: true,
rotate: true,
modifyCenter: function(){ return isCorner; }
});
var startangle = 0;
transform.on('select', function(e) {
draw.setActive(e.features.length == 0 );
});
transform.on('rotatestart', function(e) {
startangle = e.feature.get('rotation') || 0;
});
transform.on('rotating', function (e) {
// Set angle attribute to be used on style !
e.feature.set('rotation', startangle - e.angle);
});
this.map.addInteraction(transform);
这是代码的一部分,我觉得自己做错了什么,但我不明白是什么:
if (rotation !== undefined) {
var extent = feature.getGeometry().getExtent();
var coordinates = feature.getGeometry().getCoordinates()[0];
var getBottomLeft = ol.extent.getBottomLeft(extent);
var getBottomRight = ol.extent.getBottomRight(extent);
var getTopLeft = ol.extent.getTopLeft(extent);
var getTopRight = ol.extent.getTopRight(extent);
var center = ol.extent.getCenter(extent);
var dx = center[0] - getBottomLeft[0];
var dy = 0;
var scaleX = Math.sqrt(dx * dx + dy * dy)/resAdjustX;
var dx = 0;
var dy = getTopRight[1] - center[1];
var scaleY = Math.sqrt(dx * dx + dy * dy)/resAdjustY;
var florplanStyle2 = getStyle(img, scaleX, scaleY);
florplanStyle2.setGeometry(new ol.geom.Point(center));
florplanStyle2.getImage().setRotation(rotation);
return debug ? styles.concat([florplanStyle2]) : florplanStyle2;
}
1条答案
按热度按时间swvgeqrz1#
我找到了解决我两个问题的方法。关于我在问题底部提到的代码部分,我觉得是对的。我用错误的方法计算scaleX和scaleY。
这是解决我第一个问题的正确代码
当我旋转图像时,它不会保持纵横比
关于我的第二个问题
当选定图像时,沿图像周长出现的红色虚线不跟随旋转的移动
为了拥有此功能,我必须将
keepRectangle: true
添加到我的ol.interaction中。变换变量。这个功能最初在我的应用程序上不起作用,因为我使用的是ol-extv3.1.2,所以我必须先将其更改为ol-ext v3.2.24才能使用它。这是我的完整代码: