I´ve been following this post about using an image overlay for bing maps:
http://blogs.msdn.com/b/bingdevcenter/archive/2014/04/04/image-overlays-with-bing-maps-native.aspx
What I want to now is to be able to add polygons/polylines on top of this image. Lets say for example that we use the following code:
(From here: http://blogs.bing.com/maps/2014/01/23/make-clickable-shapes-in-the-native-bing-maps-control/)
private void MyMapLoaded(object sender, RoutedEventArgs e)
{
//Add a shape layer to the map
shapeLayer = new MapShapeLayer();
MyMap.ShapeLayers.Add(shapeLayer);
//Create mock data points
var locs = new LocationCollection();
locs.Add(new Location(coordinates that are over the image));
locs.Add(new Location(coordinates that are over the image));
locs.Add(new Location(coordinates that are over the image));
//Create test polygon
var polygon = new MapPolygon();
polygon.Locations = locs;
polygon.FillColor = Colors.Red;
shapeLayer.Shapes.Add(polygon);
var locs2 = new LocationCollection();
locs2.Add(new Location(20, 20));
locs2.Add(new Location(40, 40));
locs2.Add(new Location(50, 20));
//Create test polyline
var polyline = new MapPolyline();
polyline.Locations = locs2;
polyline.Width = 5;
polyline.Color = Colors.Blue;
//Add the shape to the map
shapeLayer.Shapes.Add(polyline);
}
The problem is that the polygon/polyline will always appear beneath the image.
ShapeLayer has a property for z-index but it does not help. Is there a way for my polygons to always be on top?
Not sure why you want to do this, but you won't be able to show a MapPolygon above a user control that is added as a child of the map. That said, you can create WPF Polygons and added them. What you could do is create a custom user control that combines the image overlay functionality with something like this: http://blogs.msdn.com/b/bingdevcenter/archive/2014/03/25/custom-shapes-in-windows-store-apps-c.aspx
Related
I have created a WPF application where I need to allow a user to draw a rectangle on an existing loaded image(tif image) and have it save the coordinates/the portion of the rectangle as a separate image.
I am using the Leadtools.Windows.Controls reference and using the RasterImageViewer
Below is the code for the event handler when the user has completed drawing the rectangle.
private void ImageViewer_InteractiveUserRectangle(object sender, RectangleInteractiveEventArgs e)
{
if (e.Status == InteractiveModeStatus.End)
{
var img = ImageViewer.Image;
var top =Convert.ToInt32(e.Bounds.Top);
var left = Convert.ToInt32(e.Bounds.Left);
var width = Convert.ToInt32(e.Bounds.Width);
var height = Convert.ToInt32(e.Bounds.Height);
var rect = new Leadtools.LeadRect(left, top, width, height);
var cmd = new Leadtools.ImageProcessing.CropCommand(rect);
cmd.Run(img);
_codecs.Save(img, #"c:\temp\test.tif",
RasterImageFormat.CcittGroup4, 1, 1, 1, -1, CodecsSavePageMode.Append);
}
}
I am getting a separate cropped image, but it does not match the area drawn with the rectangle. I have tried various methods from the examples but they were all for Windows Forms applications and not WPF. Any help with what I am missing would be greatly appreciated.
The issue is that the ImageViewer UserRectangle bounds returns the coordinates in Control coordiates and you need to convert these to Image Coordinates which the Crop Command is looking for.
According to the Documentation here:
https://www.leadtools.com/help/leadtools/v19/dh/wl/rectangleinteractiveeventargs-bounds.html
The coordinates are always in control (display) to image coordinates.
You can use PointToImageCoordinates and BoundsToImageCoordinates to
map a value in control or display coordinates (what is on screen) to
image coordinates (actual x and y location in the image pixels). You
can use PointFromImageCoordinates and BoundsFromImageCoordinates to
map a value in image coordinates (actual x and y location in t he
image pixels) to control or display coordinates (what is on screen).
Here is the updated code to make it work for you project:
if (e.Status == Leadtools.Windows.Controls.InteractiveModeStatus.End)
{
var img = imageViewer.Image;
var imgRect = imageViewer.BoundsToImageCoordinates(e.Bounds);
var top = Convert.ToInt32(imgRect.Top);
var left = Convert.ToInt32(imgRect.Left);
var width = Convert.ToInt32(imgRect.Width);
var height = Convert.ToInt32(imgRect.Height);
var rect = new Leadtools.LeadRect(left, top, width, height);
var cmd = new Leadtools.ImageProcessing.CropCommand(rect);
cmd.Run(img);
_codecs.Save(img, #"c:\temp\test.tif",
RasterImageFormat.CcittGroup4, 1, 1, 1, -1, CodecsSavePageMode.Append);
}
I am trying to set some layers' layout visible property to 'visible' using the 'setLayoutProperty' method in mapbox-gl-js.
this.toggleCanvasMarkersVisibility(true); // This code sets visibility to visible
// Create a snapshot of the map as follows:
this.map.getCanvas().toBlob(function (blob) {
canvasContext.strokeStyle = '#CCCCCC';
canvasContext.strokeRect(leftPosition, topPosition, width, height);
var img = new Image();
img.setAttribute("crossOrigin", "anonymous");
var srcURL = URL.createObjectURL(blob);
img.onload = function () {
canvasContext.drawImage(img, leftPosition, topPosition, width, height);
// Other operations
});
The layers which I just set to 'visible' are not visible yet on the map. How do I detect if they are visible other than the visible property, because the 'visible' property is set to 'visible'?
The PNG as a result does not consist of the markers.
Any help is appreciated!
I am writing a new Imageview with mask in Javafx.
The mask can show according to the direction of mouse.
Using Timeline makes it work well. But when the mask leaves, the mask is still visible.
I want to hide the part of mask, which is out of the Image. How can I scale it?
When mouse enter:
When mouse leave:
And my animation code
private void leftOut() {
KeyFrame k1 = new KeyFrame(Duration.ZERO, new KeyValue(mask.translateXProperty(), 0));
KeyFrame k2 = new KeyFrame(time, new KeyValue(mask.translateXProperty(), control.getWidth()*-1.0));
timeline = new Timeline();
timeline.getKeyFrames().addAll(k1,k2);
timeline.play();
}
Other directions are just like this.
You don't need to resize the mask at all. Simply apply a clip to it that has the same size as the image:
Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF.jpg/164px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF.jpg");
ImageView imageView = new ImageView(image);
// init mask
Label mask = new Label("SomeText");
mask.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
mask.setPrefSize(image.getWidth(), image.getHeight());
mask.setStyle("-fx-background-color: rgba(255, 255, 255, 0.6);");
mask.setAlignment(Pos.CENTER);
// create clip
Rectangle clip = new Rectangle(image.getWidth(), image.getHeight());
mask.setClip(clip);
// keep clip in position horizontally in root
clip.translateXProperty().bind(mask.translateXProperty().negate());
StackPane root = new StackPane(imageView, mask);
root.setPrefSize(500, 500);
root.setStyle("-fx-background-color: orange;");
// probably a bit simpler to use TranslateTransition instead of Timeline
TranslateTransition transition = new TranslateTransition(Duration.seconds(5), mask);
transition.setByX(image.getWidth());
transition.play();
I'm using an imageoverlay in leaflet
var imageUrl = 'img.png';
L.imageOverlay(imageUrl,mapBounds1).addTo(map);
When i zoom the map, the image zooms also , is there any way to make the image static ?
I also tried tiles (from the image), and it zooms also, i'm wondering if the only way is to create multiple tiles for each zoom.
Any help ?
You could try something like this...
map.on('zoomstart', function(e) {
//remove layer
});
map.on('zoomend', function(e) {
//add layer back with new bounds
});
You need to subscribe somehow to the viewreset event
viewreset is fired when the map needs to reposition its layers (e.g. on zoom), and latLngToLayerPoint is used to get coordinates for the layer's new position. (http://leafletjs.com/reference.html#map-viewreset)
I'm not sure this will work, but try something like
var imageUrl = 'img.png';
var overlay = L.imageOverlay(imageUrl,mapBounds1).addTo(map);
overlay.off('viewreset');
I'm having a bit of difficulty getting some functionality to work. I'm trying to create an eraser and erase parts of an image using easelJS. I've seen other people do this, but only erasing other graphics - and when I try to erase an image, I can't get anything to work. If I wanted to erase a bitmap instead of other graphics, is that possible?
I also tried to use the AlphaMaskFilter, but it's giving me the exact opposite of what I'm looking for (it's masking everything, and only revealing what I paint).
var c = createjs, stage, art;
var x, y, listener, color, hue=0;
stage = new c.Stage("test");
var testImg = new c.Bitmap("http://lorempixel.com/output/animals-q-c-640-480-5.jpg");
art = stage.addChild(testImg, new c.Shape());
art.cache(0,0,600,400);
stage.on("stagemousedown", startDraw, this);
function startDraw(evt) {
listener = stage.on("stagemousemove", draw, this);
stage.on("stagemouseup", endDraw, this);
color = c.Graphics.getHSL(hue+=85, 50, 50);
x = evt.stageX-0.001; // offset so we draw an initial dot
y = evt.stageY-0.001;
draw(evt); // draw the initial dot
}
function draw(evt) {
art.graphics.ss(20,1).s(color).mt(x,y).lt(evt.stageX, evt.stageY);
// the composite operation is the secret sauce.
// we'll either draw or erase what the user drew.
art.updateCache(erase.checked ? "destination-out" : "source-over");
art.graphics.clear();
x = evt.stageX;
y = evt.stageY;
stage.update();
}
function endDraw(evt) {
stage.off("stagemousemove", listener);
evt.remove();
}
http://jsfiddle.net/17xec9y5/8/
Your example is only affecting the Shape instance that you have cached. When you use multiple arguments in addChild(), it returns the last added item, so in your sample, the art variable just references the shape. So the image is just below the "painted area" that you are drawing to.
To fix this, create and cache a container instead. A few minor additions:
Once the image loads, update the cache one time (to apply the image).
Then remove the image so it is no longer applied every time you update the cache while drawing.
That's it!
Here is a fiddle:
http://jsfiddle.net/lannymcnie/17xec9y5/9/
Relevant Code:
// Listen for the image load
testImg.image.onload = function() {
cont.updateCache("source-over"); // Update cache once
cont.removeChild(testImg); // Remove image
stage.update(); // Draw the stage to see the image
}
// Create a sub-container that will hold the art and image
var cont = stage.addChild(new c.Container());
art = new c.Shape(); // Art is just the shape
cont.cache(0,0,600,400); // Cache the container instead
cont.addChild(testImg, art);
// Then, later update the container's cache (instead of the art)
cont.updateCache(erase.checked ? "destination-out" : "source-over");