I am following this tutorial for adding polygons onto a map in Xamarin. I am currently implementing the iOS section of this tutorial, but because I want to add multiple polygons to my map instead of the single polygon shown in the tutorial, I am using the addOverlays() function which takes in an array of IMKOverlay objects, instead of the addOverlay() function which takes 1 IMKOverlay object.
For some reason all of my polygons are being plotted at the same coordinates as my first polygon in my List, similar to an issue this person had!
Here is my code:
void addPolygonsToMap()
{
overlayList = new List<IMKOverlay>();
for (int i = 0; i < polygons.Count; i++)
{
CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[polygons[i].Count];
int index=0;
foreach (var position in polygons[i])
{
coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
index++;
}
var blockOverlay = MKPolygon.FromCoordinates(coords);
overlayList.Add(blockOverlay);
}
IMKOverlay[] imko = overlayList.ToArray();
nativeMap.AddOverlays(imko);
}
You have to edit the code in MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper) which is in the tutorial. Just remove the if statement or remove the polygonRenderer == null && in the if statement, like this:
MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
{
if (!Equals(overlayWrapper, null))
{
var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;
polygonRenderer = new MKPolygonRenderer(overlay as MKPolygon)
{
FillColor = UIColor.Red,
StrokeColor = UIColor.Blue,
Alpha = 0.4f,
LineWidth = 9
};
}
return polygonRenderer;
}
Otherwise, it will always return the first polygonRenderer which is including your first coordinates group.
Related
To learn and of course for fun I'm building a snake imitation, the only difference should be that instead of an endless chain, a lot of enemies or objects appear on the map and the game should be made more and more difficult.
The code snippet is supposed to show how I create my controls, but I have the problem that only the last created control is actually captured by my "IntersectsWith", all those created before that, as well as the very first one, are then no longer any opponents for me and my player just goes through them.
What is the best way to do this so that all created objects can be found under one definition so that I don't have to write hundreds of IntersectsWith If statements.
I would like to learn how to dynamically create controls and also dynamically have direct access to them, in which my player can interact with them through collision.
I really thought I could solve this with a random character generator and different control names can solve this, but alas - that's not the reality ^^
Random rnd = new Random();
PictureBox Enemy = new PictureBox();
private async void timer1_Tick(object sender, EventArgs e)
{
if (Person.Bounds.IntersectsWith(Food.Bounds))
{
int ascii_index2 = rnd.Next(97, 123);
char char1 = Convert.ToChar(ascii_index2);
char char2 = Convert.ToChar(ascii_index2);
string myletter = Convert.ToString(char1) + Convert.ToString(char2);
Enemy = new PictureBox
{
Location = new Point(rnd.Next(20, playground.Right - 20), rnd.Next(20, playground.Bottom - 20)),
Name = "Enemy" + myletter,
Size = new Size(24,24),
BackColor = Color.Red,
};
this.Controls.Add(Enemy);
Enemy.BringToFront();
Food.Location = new Point(rnd.Next(20, playground.Right - 20), rnd.Next(20, playground.Bottom - 20));
score++;
lbScore.Text = "Score: " + score.ToString();
}
if(Person.Bounds.IntersectsWith(Enemy.Bounds))
{
timer1.Stop();
}
if (Person.Left <= playground.Left && !changed)
{
Person.Location = new Point(playground.Right, Person.Location.Y);
changed = true;
}
else
if (Person.Right >= playground.Right && !changed)
{
Person.Location = new Point(playground.Left, Person.Location.Y);
changed = true;
}
else
if (Person.Top <= playground.Top && !changed)
{
Person.Location = new Point(Person.Location.X, playground.Bottom);
changed = true;
}
else
if (Person.Bottom >= playground.Bottom && !changed)
{
Person.Location = new Point(Person.Location.X, playground.Top);
changed = true;
}
Here a picture from what i have : Player = BlackDot, Food = GreenDot, Enemy = RedDot
It moves auto in the direction you clicked and you can move faster if you hold the Key.
Move Keys: W,A,S,D
You need to create a list and store all the created enemies in there.
First you need to create a List:
List<PictureBox> enemyList = new List<PictureBox>();
and after you've created a new Enemy add it to your List
Enemy = new PictureBox{};
enemieList.add(Enemy);
Because then you can check for every PictureBox in this List and whether it Intersects with your Player or not.
foreach(PictureBox p in enemyList)
{
if(Person.Bounds.IntersectsWith(p.Bounds))
{
timer1.Stop();
}
}
That would be my fast solution to your problem.
Assuming that Person is your player, instead of having an enemy field of type PictureBox, have an enemies field of type List<PictureBox>. You then add each new enemy PictureBox to that list and then you can do this:
if (enemies.Any(enemy => person.Bounds.IntersectsWith(enemy.Bounds))
I want to draw a border outline of matching braces by clicking on one of them. Just like ReSharpers Brace Matching option.
The code itself kinda works but I want the border to be a simple square and I have absolutely no idea how to achieve that.
What it looks like now:
What I want:
Here's the Code. It's based on a Microsofts exmple vor Visual Studio Extentions for mark a specific char.
private void Draw(int from, int to)
{
var fromTo = new List<int> { from, to }.OrderBy(x => x).ToList();
from = fromTo.First();
to = fromTo.Last();
var textViewLines = this.view.TextViewLines;
var span = new SnapshotSpan(this.view.TextSnapshot, Span.FromBounds(from, to + 1));
var geometry = (textViewLines as IWpfTextViewLineCollection).GetMarkerGeometry(span);
if (geometry != null)
{
this.Draw(span, geometry);
}
}
private void Draw(SnapshotSpan span, Geometry geometry)
{
var drawing = new GeometryDrawing(new SolidColorBrush(), this.pen, geometry);
drawing.Freeze();
var drawingImage = new DrawingImage(drawing);
drawingImage.Freeze();
var image = new Image {
Source = drawingImage
};
Canvas.SetLeft(image, geometry.Bounds.Left);
Canvas.SetTop(image, geometry.Bounds.Top);
this.layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null);
}
Currently I need to develop a tool with chart as the major component. Chart control is also new for me. I have do a lot of reading, researching to learn and understand the whole picture of the chart control.
After all, I had stuck and question on how to draw a horizontal line (blue & red horizontal line) on stacked column chart as image shown below:
Here what I have done so far:
This is my code so far:
// X-Axis labels settings
chart.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
chart.ChartAreas[0].AxisX.Interval = 1;
// Y-Axis labels settings
//chart.ChartAreas[0].AxisY.Minimum = 100;
chart.ChartAreas[0].AxisY.Minimum = 95;
// Plotting chart
using (YieldEntities context = new YieldEntities())
{
// Extract yield loss list
var yeilds = (
from yeild in context.YeildDatas
group yeild by new { yeild.Loss } into newyeild
select new
{
Loss = newyeild.Key.Loss,
Percentage = newyeild.Sum(p => p.Percentage)
}).OrderByDescending(p => p.Percentage);
//context.YeildDatas.Select(p => new { p.Loss, Percentage = p }).Distinct();
// Create new series
foreach (var yield in yeilds)
{
chart.Series.Add(yield.Loss);
chart.Series[yield.Loss].ChartType = SeriesChartType.StackedColumn100;
}
// Label settings for first series
chart.Series[0].SmartLabelStyle.Enabled = false;
chart.Series[0].LabelAngle = -90;
chart.Series[0].Font = new Font(Font.FontFamily, 15, FontStyle.Bold);
chart.Series[0].IsValueShownAsLabel = true;
var query = context.YeildDatas.ToList();
foreach (var item in query)
{
DataPoint dp = new DataPoint();
dp.SetValueXY(item.DateString, item.Percentage);
chart.Series[item.Loss].Points.Add(dp);
}
// Set empty datapoint for each series
foreach (var yield in yeilds)
{
DataPoint nulldp = new DataPoint();
nulldp.SetValueXY("", 0);
chart.Series[yield.Loss].Points.Insert(1, nulldp);
chart.Series[yield.Loss].Points.Insert(6, nulldp);
chart.Series[yield.Loss].Points.Insert(11, nulldp);
}
chart.Legends["Legend"].IsEquallySpacedItems = true;
chart.Legends["Legend"].IsTextAutoFit = true;
}
I hope to get any expert to guide me to solve this problem.
This is only sample, you can start from there:
// Data point to pixel
var pixelX = this.chart1.ChartAreas[0].AxisX.ValueToPixelPosition(dataPointX);
var pixelY = this.chart1.ChartAreas[0].AxisY.ValueToPixelPosition(dataPointY);
// Pixel to data point
var dataPointX = this.chart1.ChartAreas[0].AxisX.PixelPositionToValue(pixelX);
var dataPointY = this.chart1.ChartAreas[0].AxisY.PixelPositionToValue(pixelY);
// Use event Paint to draw your line
private void chart1_Paint(object sender, PaintEventArgs e)
{
// Convert dataPoint to pixel
var dataPointX = this.chart1.Series[0].Points[0].XValue;
var dataPointY = this.chart1.Series[0].Points[0].YValues[0];
var pixelX = this.chart1.ChartAreas[0].AxisX.ValueToPixelPosition(dataPointX);
var pixelY = this.chart1.ChartAreas[0].AxisY.ValueToPixelPosition(dataPointY);
// Only sample, pen should be initialized outside Paint method
Pen pen = new Pen(Brushes.Red);
// Example of drawing line with width=100 pixel
e.Graphics.DrawLine(pen, pixelX, pixelY, pixelX + 100, pixelY);
}
Im adding multiple MapIcons to my UWP app MapControl. I want to change the MapIcon size based map zoom level.
This works almost ok, but when I update marker sizes (call UpdatMarkerSizes()) not all MapIcons get new image.
I have around 200 MapIcons in my map, which I try to update. Is this some performance issue or how I should try to update all MapIcons?
Here is how I initially add MapIcons:
public void AddMapIcons(IReadOnlyCollection<IItem> items)
{
var icon = (CurrentMarkerIconSize == MarkerIconSize.Small) ? _markerSmall : _markerNormal;
foreach (var item in items)
{
var stopIcon = new MapIcon
{
Location = new Geopoint(item.Location),
NormalizedAnchorPoint = new Point(0.5, 0.5),
ZIndex = 5,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
Image = icon
};
MapControl.MapElements.Add(stopIcon);
}
}
And here is my MapIcon Image update functionality, this is called when map zoomlevel is changed.
private void UpdatMarkerSizes(MarkerIconSize newSize)
{
var newImage = (newSize == StopIconSize.Small) ? _markerSmall : _markerNormal;
foreach (var element in MapControl.MapElements)
{
(element as MapIcon).Image = newImage;
}
}
UPDATE 1:
I just noticed that if I also update MapIcon NormalizedAnchorPoint, ZIndex and CollisionBehaviorDesired (set same value again), this issue is not so bad. Previously when I updated my markers (UpdatMarkerSizes()) there was always couple of markers which did not get the new image. Now after this update, I get rarely one or two markers which did not get new image.
Updated code:
private void UpdatMarkerSizes(MarkerIconSize newSize)
{
var newImage = (newSize == StopIconSize.Small) ? _markerSmall : _markerNormal;
foreach (var element in MapControl.MapElements)
{
var mapIconElement = element as MapIcon;
if(mapIconElement != null)
{
mapIconElement.Image = newImage;
mapIconElement.NormalizedAnchorPoint = new Point(0.5, 0.5);
mapIconElement.ZIndex = 5;
mapIconElement.CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible;
}
}
}
UPDATE 2:
I think that my solution in update 1 is good enough for now. I have posted new question which is related to MapIcons and their image updating too: Dynamically update collection of MapIcons, update process gets out of sync?
I am starting to learn silverlight and to practice I am doing a simple space invaders type videogame.
My issue is I am creating custom controls (bullets) programmatically like so:
if(shooting)
{
if(currBulletRate == bulletRate)
{
Bullet aBullet = new Bullet();
aBullet.X = mouse.X - 5;
aBullet.Y = mouse.Y - Ship.Height;
aBullet.Width = 10;
aBullet.Height = 40;
aBullet.Tag = "Bullet";
LayoutRoot.Children.Add(aBullet);
currBulletRate = 0;
}
else
currBulletRate++;
}
However I am having trouble removing them once they go off bounds (leave the LayoutRoot).
I tried looping throught the LayoutRoot.Children and removing but I can't seem to get it right.
UIElement[] tmp = new UIElement[LayoutRoot.Children.Count];
LayoutRoot.Children.CopyTo(tmp, 0);
foreach (UIElement aElement in tmp)
{
Shape aShape = aElement as Shape;
if (aShape != null && aShape.Tag != null)
{
if (aShape.Tag.ToString().Contains("Bullet"))
{
if (Canvas.GetTop(aShape) + aShape.ActualHeight < 0) // This checks if it leaves the top
{
LayoutRoot.Children.Remove(aElement);
}
else if(Canvas.GetTop(aShape) > Canvas.ActualHeight) // This condition checks if it leaves the bottom
{
LayoutRoot.Children.Remove(aElement);
}
}
}
}
The code you pasted was only checking if the bullet left the top of the canvas.