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
Related
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.
As the title says. The labels I add to the MapLayout ("top" and "bottom") are not really fixed to the given coordinate. Am I missing something to avoid this effect (see screen record below).
my sample code:
final MapContainer mapContainer = new MapContainer(API_KEY, false);
Container actual = new Container();
actual.setLayout(new MapLayout(mapContainer, actual));
Form f = new Form("Maps", new LayeredLayout());
f.add(mapContainer);
f.add(actual);
String[] coordinates = new String[] {
"50.963642, 7.121855"
};
List<MapContainer.MapObject> addedMarkers = new ArrayList<>();
List<Coord> coords = new ArrayList<>();
EncodedImage ei = EncodedImage.createFromImage(
FontImage.createMaterial(FontImage.MATERIAL_GPS_FIXED, f.getUnselectedStyle())
, false);
for(String cStr : coordinates) {
Coord c = toCoordinate(cStr);
MapContainer.MapObject obj = mapContainer.addMarker(ei, c, "Marker", "Long text", (evt) -> {
log.p("clicked on marker" + c);
Component cmp1 = new Label("top");
actual.addComponent(c, cmp1);
MapLayout.setHorizontalAlignment(cmp1, 0.5f);
MapLayout.setVerticalAlignment(cmp1, 1f);
Component cmp2 = new Label("bottom");
actual.addComponent(c, cmp2);
MapLayout.setHorizontalAlignment(cmp2, 0.5f);
MapLayout.setVerticalAlignment(cmp2, 0f);
});
coords.add(c);
addedMarkers.add(obj);
}
f.revalidate();
f.show();
Try using this new API https://www.codenameone.com/blog/map-component-positioning-revisited.html
It works better than the older map layout approach as it converts components to markers back & forth.
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 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!