I have a map using Xamarin.Forms.Googlemap in my xamarin forms app.
Is there a way to click on what is behind a pin?
I am creating polygons on the googlemap and then adding custom pins with orchard names on it.
Pin pin = new Pin()
{
Icon = CreateLabels(orchardname, 60),
Flat = true,
Address = string.Empty,
Label = string.Empty,
Position = Xamarin.Forms.GoogleMaps.Bounds.FromPositions(allpositions).Center,
Anchor = new Point(0.5, -1),
IsVisible = _showPropertyzoom
};
protected BitmapDescriptor CreateLabels(string Text, int size)
{
SKBitmap bitmap;
SKCanvas bitmapCanvas;
SKColor white = new SKColor(255,255,255);
SKColor blue = new SKColor(0,88,164);
SKPaint textPaintStroke = new SKPaint { TextSize = size, StrokeWidth=3, Color = white, FakeBoldText=true, Style = SKPaintStyle.Stroke};
SKPaint textPaint = new SKPaint { TextSize = size, Color = blue };
SKRect bounds = new SKRect();
textPaint.MeasureText(Text, ref bounds);
bitmap = new SKBitmap((int)(bounds.Right + 10), (int)(bounds.Height +5));
using (bitmapCanvas = new SKCanvas(bitmap))
{
bitmapCanvas.Clear();
bitmapCanvas.DrawText(Text, bounds.Left, -bounds.Top, textPaintStroke);
bitmapCanvas.DrawText(Text, bounds.Left, -bounds.Top, textPaint);
}
SKData data = SKImage.FromBitmap(bitmap).Encode(SKEncodedImageFormat.Png, 100);
var image = BitmapDescriptorFactory.FromStream(data.AsStream());
return image;
}
The problem i am having is when i click on a polygon to trigger the polygonclicked event i am clicking on the pin so nothing happens.
I can't just use the pinclicked event to trigger the polygonclicked event in this case, because the pin/label can span across multiple polygons.
Related
I need to come up with a way to watermark user generated HTML and display it to the user.
I played around with modifying the HTML by setting a background image, but the solution didn't work if the any html element contained a background color or image.
So I thought it would be easier to display the HTML in a web browser control and watermark the control. Boy was I wrong.
I tried creating a user control and derive from WebBrowser and overwrite the paint method. That didn't work.
Next idea was to just draw on top of a webbrowser control.
here's what I've come up with. In this example I slapped a label, webbrowser control and two picture boxes on a form. I create the image and set it to both picture boxes. I put one picture box over the label and the other over the watermark.
The picturebox over the label displayed as I expected, but the picturebox over the webbrowser control did not.
I'm out of ideas. Any suggestions?
public partial class Form1 : Form
{
string WatermarkText = "Confidential";
Font WatermarkFont = new Font("Microsoft Sans Serif", 24, FontStyle.Bold);
int WatermarkAngle = 45;
Color WatermarkColor = Color.PaleTurquoise;
public Form1()
{
InitializeComponent();
AllowTransparency = true;
label1.AutoSize = false;
label1.Text = "Test Text";
label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
webBrowser1.Navigate("http://www.google.com");
var img = creategraphics(WatermarkText);
label1.Size = pictureBox2.Size = pictureBox1.Size = img.Size;
label1.Controls.Add(pictureBox1);
pictureBox1.Image = img;
pictureBox1.BackColor = Color.Transparent;
pictureBox1.Location = new Point(0, 0);
webBrowser1.Controls.Add(pictureBox2);
pictureBox2.Image = img;
pictureBox2.BackColor = Color.Transparent;
pictureBox2.Location = new Point(0, 0);
}
Image creategraphics(string text)
{
if (String.IsNullOrWhiteSpace(text)) return null;
var size = getWatermarkSize(text, WatermarkAngle, WatermarkFont, out double hypotenuse);
var img = new Bitmap(size.Width, size.Height);
var g = Graphics.FromImage(img);
var brush = new SolidBrush(WatermarkColor);
var stringFormat = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
g.RotateTransform((float)-WatermarkAngle);
g.DrawString(text, WatermarkFont, brush, new Point(0, (int)hypotenuse / 2), stringFormat);
return img;
}
private static Size getWatermarkSize(string text, int angle, Font font, out double hypotenuse)
{
if (angle > 90) throw new ArgumentOutOfRangeException("angle");
using (var bitmap = new Bitmap(1, 1))
using (var graphics = Graphics.FromImage(bitmap))
{
var size = graphics.MeasureString(text, font);
hypotenuse = size.Width + size.Height;
double radians = (angle / 180.0) * Math.PI;
var width = (Math.Cos(radians) * size.Width) + (Math.Sin(radians) * size.Height);
var height = (Math.Cos(radians) * size.Height) + (Math.Sin(radians) * size.Width);
return new Size((int)width, (int)height);
}
}
}
This is what I get
I'm using geoTools 14.1
I'm trying to plot on an image some points
This is the code I'm using:
double[][] points = new double[8][2];
points[0] = new double[]{45.46433710338643, 9.190417528152478};
points[1] = new double[]{45.46195085146914, 9.189746320685355};
points[2] = new double[]{45.460062304163635, 9.19015527826191};
points[3] = new double[]{45.472950871127445, 9.17363731952788};
points[4] = new double[]{45.4737153001908,9.203728795018847};
points[5] = new double[]{45.4849795331724,9.20162835217198};
points[6] = new double[]{45.48560542313713,9.195953607559215};
points[7] = new double[]{45.48348421787171,9.188765287399292};
final SimpleFeatureType TYPE = DataUtilities.createType("Location",
"location:Point:srid=3857,"+// <- the geometry attribute: Point type
"nome:String," + // <- a String attribute
"id:Integer" // a number attribute
);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = new DefaultFeatureCollection();
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
CoordinateReferenceSystem pointSrc = CRS.decode("EPSG:4326");
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857");
MathTransform transform = CRS.findMathTransform(pointSrc, targetCRS);
for (int i = 0; i < points.length; i++)
{
double[] coords = points[i];
Point point = geometryFactory.createPoint(new Coordinate(coords[0], coords[1]));
Point converted = (Point) JTS.transform( point, transform);
featureBuilder.add(converted);
featureBuilder.add("Punto "+i);
featureBuilder.add(i);
SimpleFeature feature = featureBuilder.buildFeature(""+i);
logger.info(""+feature+" feature.getDefaultGeometry() "+feature.getDefaultGeometry()+ " feature.getDefaultGeometryProperty() "+feature.getDefaultGeometryProperty());
((DefaultFeatureCollection)collection).add(feature);
}
String wellKnownName = "Circle";
Style style = SLD.createPointStyle(wellKnownName,Color.RED,Color.RED,0f,10f);
FeatureLayer fl = new FeatureLayer(collection, style);
fl.setVisible(true);
fl.setSelected(true);
logger.info(""+fl);
mapcontent.addLayer((org.geotools.map.Layer)fl); //"1010177.1917802,5688070.7096562,1029133.5747922,5704122.4855938"
ReferencedEnvelope bounds = new ReferencedEnvelope(1010177.1917802,1029133.5747922,5688070.7096562, 5704122.4855938, targetCRS);
BufferedImage ret = buildImage(mapcontent, 5000, 5000, bounds, Color.white);
ImageIO.write((RenderedImage) ret, "png", new File("/home/angelo/Scrivania/immagineResult.png"));
It seems to me all correct, but the generated image contains no point.
This is the generated image
As you can see it's all white; I was expecting only 8 red circles on the image... Is there any error in my code? Am I doing anything wrong?
Thank you
Angelo
UPDATE: added build image method
public BufferedImage buildImage(final MapContent map, final int imageWidth,final int imageHeight,ReferencedEnvelope bounds,Color bgcolor) {
GTRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
renderer.setMapContent(map);
Rectangle imageBounds = null;
ReferencedEnvelope mapBounds = bounds;
try {
if(bounds==null) mapBounds = map.getMaxBounds();
imageBounds = new Rectangle(imageWidth, imageHeight);
} catch (Exception e) {
failed to access map layers
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
int type = AlphaComposite.SRC;
gr.setComposite(AlphaComposite.getInstance(type));
Color c = new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue(), 0);
gr.setBackground(bgcolor);
gr.setColor(c);
gr.fillRect(0, 0, image.getWidth(), image.getHeight());
type = AlphaComposite.SRC_OVER;
gr.setComposite(AlphaComposite.getInstance(type));
try {
renderer.paint(gr, imageBounds, bounds);
} catch (Exception e) {
throw new RuntimeException(e);
}
return image;
}
After a lot of playing I have found the problem :-) There is no bug in your code! There are in fact 8 red dots in that white image, but they are very hard to find!
As the above image shows at 2000% zoom (and panning along the top edge) you will find a dot (I'm assuming the others are there) - the simple answer is either to make the dots 10 times bigger (100px) or the image much smaller (500x500) and in both cases the dots are immediately visible.
I use this code to add custom marker to BING map control. The Map component can't draw Image(), but text works fine. Am I wrong?
private void AddMarkerToMap(double Latitude, double Longitude, string Name)
{
Image markerImg = new Image { Width = 63, Height = 46 };
Uri imgUri = new Uri("Images/GeoPin.png", UriKind.RelativeOrAbsolute);
if (imgUri == null)
{
throw new Exception("Image can't be find");
}
markerImg.Source = new BitmapImage(imgUri);
markerImg.Tag = Name;
//markerImg.Tap += delegate
//{
// // handle tap
//};
var overlay = new MapOverlay
{
PositionOrigin = new Point(0.5, 0.5),
GeoCoordinate = new GeoCoordinate(Latitude, Longitude),
Content = markerImg,
//Content = Name,
};
var mapLayer = new MapLayer { overlay };
MyMap.Layers.Add(mapLayer);
}
If you want to add a pin to Map, use MapIcon class. This can display images as well as text.
private void AddMapIcon()
{
MapIcon MapIcon1 = new MapIcon();
MapIcon1.Location = new Geopoint(new BasicGeoposition() { Latitude = 47.620, Longitude = -122.349 });
MapIcon1.NormalizedAnchorPoint = new Point(0.5, 1.0);
MapIcon1.Title = "Space Needle";
MapIcon1.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));
MapControl1.MapElements.Add(MapIcon1);
}
Does MapIcon present in Windows Phone 8 SDK?
You could use the Phone.Controls.Toolkit in order to have a custom Pushpin as an image on your map.
Reference: Image as pushpin on maps - Windows phone 8
i am following the example
Nokia blog but my problem is ,
1> i need to add image to the location point instead of color
2> i want to show detail information in the popup like Google map
May this help you.
Here i had use textblock to show custom data. Background image for a stack panel
Private void ShoeCustomPushPuin()
{
Pushpin pushPin = null;
StackPanel stackPanel = null;
TextBlock txtblkDownloadSpeed = null;
TextBlock txtblkUploadSpeed = null;
GeoCoordinate cordinates = null;
try
{
cordinates = new GeoCoordinate();
pushPin = new Pushpin();
stackPanel = new StackPanel();
txtblkDownloadSpeed = new TextBlock();
txtblkUploadSpeed = new TextBlock();
cordinates.Latitude = Your latitude value;
cordinates.Longitude = your longitude value;
txtblkUploadSpeed.Text = your data;
txtblkDownloadSpeed.Text =your data;
ImageBrush imgbrush= new ImageBrush
{
ImageSource = new BitmapImage(new Uri("your background image path", UriKind.Relative)),
};
stackPanel.Background = imgbrush;
stackPanel.Children.Add(txtblkDownloadSpeed);
stackPanel.Children.Add(txtblkUploadSpeed);
pushPin.Content = stackPanel;
pushPin.GeoCoordinate = cordinates;
MapOverlay overlay = new MapOverlay
{
GeoCoordinate = cordinates,
Content = pushPin
};
MapLayer layer = new MapLayer();
layer.Add(overlay);
mapHistory.Center = cordinates;
mapHistory.Layers.Add(layer);
}
catch (Exception ex)
{
}
}
I have a map with 100 pushpins. Every time I tap a pushpin, a textbox with description is opened near that pushpin (only 1 textbox can be opened at a time, when you tap a pushpin, the previous opened textbox is closed first), but sometimes the textbox is not on top of other pushpins, other pushpins appear above the textbox, making it hard to read the description. I've tried using Canvas and Canvas.ZIndex, but nothing worked properly.
I had a similar issue, and I solved it my removing and adding the object again whenever it was tapped.
MapLayer theLayer = new MapLayer();
MapOverlay theOverlay = new MapOverlay()
{
GeoCoordinate = new GeoCoordinate(lat, lng)
};
var pp = new StackPanel { Background = new SolidColorBrush(Colors.Black), Orientation = System.Windows.Controls.Orientation.Vertical };
var img = new Image()
{
Source = new BitmapImage(new Uri(url, UriKind.Absolute)),
Width = 50,
Height = 50
};
pp.Children.Add(img);
img.Tap += (object emitter, System.Windows.Input.GestureEventArgs e) => {
theLayer.Remove(theOverlay);
theLayer.Add(theOverlay);
};
theOverlay.Content = pp;
theLayer.Add(theOverlay);
Hope this helps!