I'm trying to put an image according to its geopoints. However, the image does not show up on the map. I want to make sure that when we zoom in/out the map, the image will stay in place and adjust its size based on its fixed coordinate. Do i have to insert the image in the xaml page also? Currently I'm only adding image on the cs page.
can someone tell me how to fix this? MapView is MapControl in this code.
namespace HelpMe
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
addImage();
}
//adding image
public void addImage()
{
Image img = new Image();
img.Height = 100;
img.Width = 100;
img.Source = new BitmapImage(new Uri("ms-appx:///Assets/Unknown.jpg"));
img.RenderTransform = new CompositeTransform() { Rotation = 0 };
MapControl.SetNormalizedAnchorPoint(img, new Point(0.5, 0.5));
MapControl.SetLocation(img, new Geopoint(new BasicGeoposition() { Latitude = 0, Longitude = 0, Altitude = 0 }));
MapView.Children.Add(img);
}
}
}
What you have looks correct - you just need to add it to the .Children of the map control instance, not the page. You don't need to set a render transform. You might check that your bitmap asset is loading correctly and the BasicGeoposition you've chosen is where you want it.
Image img = new Image();
img.Height = 100;
img.Width = 100;
img.Source = new BitmapImage(new Uri("ms-appx:///Assets/YourBitmapName.jpg"));
MapControl.SetNormalizedAnchorPoint(img, new Point(0.5, 0.5));
MapControl.SetLocation(img, new Geopoint(new BasicGeoposition() { Latitude = 47, Longitude = -122, Altitude = 0 }, AltitudeReferenceSystem.Terrain));
yourMapControlInstanceName.Children.Add(img);
Note that for a simple image like this it's better to use a MapIcon. This will be higher performance and synchronize better with map movement than pinned XAML elements.
If you want an image to automatically scale as you zoom in/out, a MapBillboard is appropriate.
Related
I am trying to add different page contents in order to pass it to the Print Manager interface. However, when trying to add multiple BitmapImages, it's returning a "Element is already the child of another element." error.
Here's what my current code looks like:
Canvas page = new Canvas
{
Width = pageDescription.PageSize.Width,
Height = pageDescription.PageSize.Height
};
Canvas viewablePage = new Canvas()
{
Width = pageDescription.ViewablePageSize.Width,
Height = pageDescription.ViewablePageSize.Height
};
viewablePage.SetValue(Canvas.LeftProperty, pageDescription.Margin.Width);
viewablePage.SetValue(Canvas.TopProperty, pageDescription.Margin.Height);
// The image "frame" which also acts as a viewport
Grid photoView = new Grid
{
Width = pageDescription.PictureViewSize.Width,
Height = pageDescription.PictureViewSize.Height
};
The foreach loop wherein a different image is added to the a different page
foreach(var btm in bitmapImages)
{
Image image = new Image
{
Source = btm,
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
};
// Use the real image size when croping or if the image is smaller then the target area (prevent a scale-up).
if ((btm.PixelWidth <= pageDescription.PictureViewSize.Width &&
btm.PixelHeight <= pageDescription.PictureViewSize.Height))
{
image.Stretch = Stretch.None;
image.Width = bitmap.PixelWidth;
image.Height = bitmap.PixelHeight;
}
photoView.Children.Add(image);
viewablePage.Children.Add(photoView);
page.Children.Add(viewablePage);
pages.Add(page);
}
bitmapImages is a list of bitmaps. It works if there's only one image to be added but when adding < 1 image to a page, it returns the error. Do you have any suggestions on how should I implement this?
Thanks alot.
Each UI element in UWP can only be used in the UI in one place at one time.
You need to define the UI element every loop.
foreach(var btm in bitmapImages)
{
Canvas page = new Canvas
{
Width = pageDescription.PageSize.Width,
Height = pageDescription.PageSize.Height
};
Canvas viewablePage = new Canvas()
{
Width = pageDescription.ViewablePageSize.Width,
Height = pageDescription.ViewablePageSize.Height
};
viewablePage.SetValue(Canvas.LeftProperty, pageDescription.Margin.Width);
viewablePage.SetValue(Canvas.TopProperty, pageDescription.Margin.Height);
// The image "frame" which also acts as a viewport
Grid photoView = new Grid
{
Width = pageDescription.PictureViewSize.Width,
Height = pageDescription.PictureViewSize.Height
};
Image image = new Image
{
Source = btm,
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
};
// Use the real image size when croping or if the image is smaller then the target area (prevent a scale-up).
if ((btm.PixelWidth <= pageDescription.PictureViewSize.Width &&
btm.PixelHeight <= pageDescription.PictureViewSize.Height))
{
image.Stretch = Stretch.None;
image.Width = bitmap.PixelWidth;
image.Height = bitmap.PixelHeight;
}
photoView.Children.Add(image);
viewablePage.Children.Add(photoView);
page.Children.Add(viewablePage);
pages.Add(page);
}
I am aware of technique to draw a circle by generating points by basic math and then use the points to create a MapPolygon.
Is there another way?
For example, I see there is a class for circles:
public sealed class Geocircle : IGeocircle, IGeoshape
But I don't know how to use it, there doesn't seem to be any MapLayer for it.
Geocircle is used to create a geographic circle object for the given position and radius. It often use to make map Geofence, but not to display the cycle on the map.
There many way that draw a circle on the map
generating points by basic math
for (var i = 0; i < 360; i++)
{
//draw a cycle
BasicGeoposition point = new BasicGeoposition()
{ Latitude = centerLatitude + ri * Math.Cos(3.6 * i * 3.14 / 180), Longitude = centerLongitude + ri * Math.Sin(3.6 * i * 3.14 / 180) };
list.Add(point);
}
Add Ellipse to map
private void MyMap_Loaded(object sender, RoutedEventArgs e)
{
// Specify a known location.
BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
Geopoint snPoint = new Geopoint(snPosition);
// Create a XAML border.
var ellipse1 = new Ellipse();
ellipse1.Fill = new SolidColorBrush(Windows.UI.Colors.Coral);
ellipse1.Width = 200;
ellipse1.Height = 200;
// Center the map over the POI.
MyMap.Center = snPoint;
MyMap.ZoomLevel = 14;
// Add XAML to the map.
MyMap.Children.Add(ellipse1);
MapControl.SetLocation(ellipse1, snPoint);
MapControl.SetNormalizedAnchorPoint(ellipse1, new Point(0.5, 0.5));
}
You can create XAML shapes and add them as a child to the MapControl. Then you set their location using SetLocation:
var circle = new Ellipse() {
Height = 20,
Width = 20,
Fill = new SolidColorBrush(Colors.Blue)
};
map.Children.Add(circle);
var location = new Geopoint(new BasicGeoposition()
{
Latitude = 51.1789,
Longitude = -1.8261
});
map.SetLocation(circle, location);
The Geocircle class is used for geofencing, so it is not applicable here.
I'm playing with this library because it seems quite useful for app developing that involves locations.
Q1: I was able to implement this in code-behind but I'm not able to transfer this to MVVM architecture. How can I do it?
Q2: if you see my code you can notice that I'm trying to use markers but for some reason I am only able to use marker.Shape (rectangle, ellipse, wtv). I want to use the standard ones from the GoogleMaps. Gmarkergoogle doesn't seems to exists anymore in GMap API. How can I do it? There is some other library to use? Need a little help over here as well.
OverviewView CODE
public partial class OverviewView : UserControl
{
public OverviewView()
{
InitializeComponent();
// Initialize map:
myMap.MapProvider = GoogleMapProvider.Instance;
GMaps.Instance.Mode = AccessMode.ServerOnly; // get tiles from server only
PointLatLng point = new PointLatLng(42.742826, -77.030212);
PointLatLng point1 = new PointLatLng(41.742826, -77.030212);
//Not use proxy
//Center map on a point
//GMapMarker marker = new GMapMarker(point);
var marker = new GMapMarker(point);
var marker1 = new GMapMarker(point1);
marker.Shape = new Rectangle
{
Width = 1,
Height = 100,
Stroke = Brushes.Black,
StrokeThickness = 1.5
};
marker1.Shape = new Rectangle
{
Width = 1,
Height = 100,
Stroke = Brushes.Black,
StrokeThickness = 1.5
};
myMap.Markers.Add(marker);
myMap.Markers.Add(marker1);
myMap.ZoomAndCenterMarkers(5);
myMap.Position = point;
/* GMapOverlay markersOverlay = new GMapOverlay("markers");
GMarkerGoogle marker = new GMarkerGoogle(new PointLatLng(-25.966688, 32.580528),
GMarkerGoogleType.green);
markersOverlay.Markers.Add(marker);
gmap.Overlays.Add(markersOverlay);*/
}
}
Best regards and thanks in advance for the time,
Antoine
I want to add a pin on a certain location on a map for a windows phone 8.0 app.
My code so far is the following:
private async void Button_Click(object sender, RoutedEventArgs e)
{
BasicGeoposition bGeo = new BasicGeoposition();
bGeo.Latitude = 37.4333;
bGeo.Longitude = 24.9167;
Geopoint geoPoint = new Geopoint(bGeo,0);
myMap.ZoomLevel = 13;
myMap.Center = geoPoint;
}
private void AddMapIcon()
{
MapIcon MapIcon1 = new MapIcon();
MapIcon1.Location = new Geopoint(new BasicGeoposition()
{
Latitude = 37.4333,
Longitude = 24.9167
});
MapIcon1.NormalizedAnchorPoint = new Point(2.0, 2.0);
myMap.MapElements.Add(MapIcon1);
}
The map is loading properly, but the pin won't appear. Any ideas on this? Is there any way to do it without using xaml controls for the pin?
This is a general way of adding any UI on map control in windows phone:
We need to create "map layers" and "map overlays" and specify the coordinates where we want to place it. Sample code:
Read the tutorial here
You can add an Image control in the overlay and point its source to the pin image you want to plot. Hope this help
You can try..
BitmapImage myImage1;
myImage1 = new BitmapImage(new Uri("/Assets/Images/pushpin-google-hi.png", UriKind.RelativeOrAbsolute));
var image = new Image();
image.Width = 50;
image.Height = 50;
image.Opacity = 100;
image.Source = myImage1;
var mapOverlay = new MapOverlay();
mapOverlay.Content = image;
mapOverlay.GeoCoordinate = new GeoCoordinate(lats, lons);
var mapLayer = new MapLayer();
mapLayer.Add(mapOverlay);
MyMap.Layers.Add(mapLayer);
MyMap.SetView(new GeoCoordinate(lats, lons), 16);
I created an Image with this code
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = ""; // Default file name
myImage = new Image();
try
{
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
string sUri = #dlg.FileName;
Uri src = new Uri(sUri, UriKind.RelativeOrAbsolute);
BitmapImage bmp = new BitmapImage(src);
myImage.Source = bmp;
myImage.Width = 100;
myImage.Height = 100;
}
}
I can zoom in/out on this image
public void Scale(int i, Point center)
{
Matrix m = myImage.RenderTransform.Value;
if (i > 0)
m.ScaleAtPrepend(1.1, 1.1, center.X, center.Y);
else
m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, center.X, center.Y);
myImage.RenderTransform = new MatrixTransform(m);
}
but when I get the ActualWidth or Width or ActualHeight/Height returns the number 100. this means that these changes not applied to origin image (myImage).
Now How to apply the changes (zoom or any changes) to origin Image?
Tanx all;
Transforms only affect the appearance / layout of the object they are applied to and won't make any changes directly to the source. For this you'll need to resize the image yourself, reading the values of the scaling and applying those to the original width and height.
Take a look at something like AForge.Net which has myriad methods for manipulating images allowing control over the quality of the transformation etc.