Select to view content in your preferred language

Find a specific graphic in GraphicsOverlay

508
3
Jump to solution
07-07-2022 10:49 PM
FranciscoLopez
Emerging Contributor

I have a GraphicsOverlay with n graphics and I want to find out a number of them with some attributes. Now I have the following code:

for (int i = 0; i < _graphicsOverlay.Graphics.Count(); i++)
{
int _index = Convert.ToInt32(_graphicsOverlay.Graphics[i].Attributes["ORDER"].ToString());
int _range = Convert.ToInt32(_graphicsOverlay.Graphics[i].Attributes["RANGE"].ToString());
string _type = _graphicsOverlay.Graphics[i].Attributes["TYPE"].ToString();
if (_index == mapUnits.Order && _range == range && _type== "RING")
{
_graphicsOverlay.Graphics.Remove(_graphicsOverlay.Graphics[i]);
return false;
}
}

So, my question is, Is there a better way to get a graphics group that meet certain criteria for certain attributes of the graph?

 

Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
JoeHershman
MVP Regular Contributor

Not sure I understand the

return false;

inside the conditional, because it will only remove the first one it finds that meets this condition.

I would use LINQ to get a IEnumerable of the graphics I want to remove and then loop through it to do the removals.  Again not clear on the purpose of the return, but the below example would return false if anything needed to be removed

var graphics = _graphicsOverlay.Graphics.Where(g =>
	(int)g.Attributes["ORDER"] == mapUnits.Order && (int)g.Attributes["RANGE"] == range &&
	g.Attributes["TYPE"].ToString() == "RING");

bool result = true;

foreach (var graphic in graphics)
{
	_graphicsOverlay.Graphics.Remove(graphic);
	result = false;
}

return result;

  You are going to get an illegal cast exception if either ORDER or RANGE is null.  You could do something along these lines to avoid that possibility

var graphics = _graphicsOverlay.Graphics.Where(g =>
{
	int order = g.Attributes["ORDER"] == null ? 0 : (int)g.Attributes["ORDER"];
	int range = g.Attributes["RANGE"] == null ? 0 : (int)g.Attributes["RANGE"];
	string type = g.Attributes["TYPE"] == null ? string.Empty : g.Attributes["TYPE"].ToString();

	return order == mapUnits.Order && range == _range && type == "RING";
});

bool result = true;
foreach (var graphic in graphics)
{
	result = false;
	_graphicsOverlay.Graphics.Remove(graphic);
}

return result;
Thanks,
-Joe

View solution in original post

0 Kudos
3 Replies
JoeHershman
MVP Regular Contributor

Not sure I understand the

return false;

inside the conditional, because it will only remove the first one it finds that meets this condition.

I would use LINQ to get a IEnumerable of the graphics I want to remove and then loop through it to do the removals.  Again not clear on the purpose of the return, but the below example would return false if anything needed to be removed

var graphics = _graphicsOverlay.Graphics.Where(g =>
	(int)g.Attributes["ORDER"] == mapUnits.Order && (int)g.Attributes["RANGE"] == range &&
	g.Attributes["TYPE"].ToString() == "RING");

bool result = true;

foreach (var graphic in graphics)
{
	_graphicsOverlay.Graphics.Remove(graphic);
	result = false;
}

return result;

  You are going to get an illegal cast exception if either ORDER or RANGE is null.  You could do something along these lines to avoid that possibility

var graphics = _graphicsOverlay.Graphics.Where(g =>
{
	int order = g.Attributes["ORDER"] == null ? 0 : (int)g.Attributes["ORDER"];
	int range = g.Attributes["RANGE"] == null ? 0 : (int)g.Attributes["RANGE"];
	string type = g.Attributes["TYPE"] == null ? string.Empty : g.Attributes["TYPE"].ToString();

	return order == mapUnits.Order && range == _range && type == "RING";
});

bool result = true;
foreach (var graphic in graphics)
{
	result = false;
	_graphicsOverlay.Graphics.Remove(graphic);
}

return result;
Thanks,
-Joe
0 Kudos
FranciscoLopez
Emerging Contributor

Thanks a lot. Now is working perfectly.

The idea of this code is to find out a specific graph, in this case a circle, and move it at a new position instead of to delete it and create a new circle around a point.

The problem now, is that when a move the circle it changes, but the rest of the circles I have in the GraphicsOverlay  blink. That is normal?

Here there is the code.

 

private bool ExitGraphicRing(GisStructs.MapUnits mapUnits)
{
bool result = false;
try
{

// New point to move the circle
MapPoint pointGeometry = new MapPoint(mapUnits.Longitude, mapUnits.Latitude);
if (_ringRange_GO == null)
{
Logger.Error("There is not a GraphicsOverlay for:" + mapUnits.UnitTypes.ToString()); ;
return result;
}
var graphics = _ringRange_GO.Graphics.Where(g => (int)g.Attributes["ORDER"] == mapUnits.Order && g.Attributes["TYPE"].ToString() == "RING");
int x = graphics.Count();
foreach (var graphic in graphics)
{

//RANGE has the diameter of the circle.
graphic.Geometry = MakeEllipseGeometry(pointGeometry, (int)graphic.Attributes["RANGE"]);
result = true;
}
return result;
}
catch (Exception ex)
{
Logger.Error("Error:" + ex.Message + "-" + mapUnits.UnitTypes.ToString());
return result;
}
}

0 Kudos
FranciscoLopez
Emerging Contributor

Sorry, I am new and I do not know to use the web side. Here there is the code.

0 Kudos