I have a mapping application which takes string arguments in the form of string arrays. I parse these and then perform an action on the map. One of these is MoveVertex
which lets the user pass in the name of an existing shape/feature on the map, the index of the vertex to move, and a new x,y location to move that vertex to.
I'm currently getting thousands of these in a row, all for the same shape. It takes anywhere from 3-10ish seconds to parse them all and complete the action. I'm looking for any improvements I could make.
One thing I did so far was stop the map from refreshing every time a vertex is moved. This helped a bit, but it's still slow.
Example of the string[] commands being sent:
command[0] = "move" //command type
command[1] = "vertex" //what to move
command[2] = "testLine[10]" //move the vertex at index 10 in testLine's list of vertices
command[3] = "x" //new x value for the vertex
command[4] = "y" //new y value for the vertex
Here's the function that does the work:
public static void MoveVertex(string[] command, Layer inMemoryFeatureLayer, Map map)
{
int index; //this will be the index of the vertex in the collection of vertices of the shape
string featureName; //name of the shape/feature that has the vertex to move
if (command.Length < 5) //can't be more than 5 parameters
{
return;
}
try
{
if (!command[2].Contains('[')) //if it doesn't contain brackets which contain an index of the vertices
{
return;
}
const string pattern = @"\[(.*?)\]";
var query = command[2];
var matches = Regex.Matches(query, pattern); //Gets anything inside the brackets
index = Convert.ToInt32(matches[0].Groups[1].Value); //should be an int
featureName = command[2].Substring(0, command[2].IndexOf('[')).ToUpper(); //everything before the bracket is the name of the object
}
catch (Exception ex)
{
return;
}
if (!double.TryParse(command[3], out double longitude) || !double.TryParse(command[4], out double latitude))
{
return;
}
try
{
BaseShape shape;
inMemoryFeatureLayer.Open(); //make sure the layer is open
if (inMemoryFeatureLayer.Name.Contains(GlobalVars.LineType)) if it's the layer holding line shapes
{
shape = (LineShape)inMemoryFeatureLayer.FeatureSource.GetFeatureById(featureName, ReturningColumnsType.NoColumns).GetShape();
((LineShape)shape).Vertices[index] = new Vertex(longitude, latitude); //set the vertex to a new location
}
else //it's the layer holdilng polygone shapes
{
shape = (PolygonShape)inMemoryFeatureLayer.FeatureSource.GetFeatureById(featureName, ReturningColumnsType.NoColumns).GetShape();
((PolygonShape)shape).OuterRing.Vertices[index] = new Vertex(longitude, latitude); //set the vertex to a new location
}
inMemoryFeatureLayer.EditTools.BeginTransaction();
inMemoryFeatureLayer.EditTools.Update(shape);
inMemoryFeatureLayer.EditTools.CommitTransaction();
map.Refresh(); //this won't happen because I suspend refreshes beforehand
}
catch (Exception ex)
{
//log it
}
}
RegexOptions.Compiled
option \$\endgroup\$