C# : can't execute code from R - c#

I want to show ellipse in c#. My codes is fine when it running in R but i get message from c# like this :
"Object is static; operation not allowed (Exception from HRESULT: 0x8004000B (OLE_E_STATIC))"
here this my codes :
df.rconn.Evaluate("library(cluster)")
df.rconn.Evaluate("library(rrcov)")
public void setScatter(int xAxis, int yAxis, int zAxis, List<string> variable)
{
// plot from R
//to show outlier with method : classic & robust Mve
this.comboBoxXAxis.SelectedIndex = xAxis;
this.comboBoxYAxis.SelectedIndex = yAxis;
dataform.rconn.EvaluateNoReturn("x<-X[," + xAxis + "] ");
dataform.rconn.EvaluateNoReturn("y<-X[," + yAxis + "] ");
dataform.rconn.EvaluateNoReturn("shape <- cov(X)");
dataform.rconn.EvaluateNoReturn("center<- colMeans(X)");
dataform.rconn.EvaluateNoReturn("d2.95 <- qchisq(0.95, df = 2)");
//dataform.rconn.EvaluateNoReturn("gr<- grid(lty=3,col='lightgray', equilogs = 'TRUE')");
//dataform.rconn.Evaluate("mtext('with classical (red) and robust (blue)')");
dataform.rconn.EvaluateNoReturn("plot(x,y, main='Draw Ellipse ', pch=19,col='black', type='p')");
dataform.rconn.EvaluateNoReturn("elp<- unname(ellipsoidPoints(shape, d2.95,center))");
dataform.rconn.Evaluate(" lines(elp, col='red' , lty=7 , lwd=2)");
//dataform.rconn.EvaluateNoReturn("lines(e)");
//dataform.rconn.EvaluateNoReturn("lines(ellipsoidPoints(mve#cov, d2 = d2.95, loc=mve#center), col='blue', lty='7' , lwd='2') ");
axGraphicsDevice2.RemoveFromConnector();
}
in any code that I comment always got the same error. I don't know why this problem happen. Any idea how to show that ellipse ? Thank you very much because you have helped me in completing my thesis.

Some missing contextual information, but going by what you provide a guess is that your "rconn" (statconnector?) is not happy when operations refresh a graphic device (lines, mtext, etc.).
As I needed to test some R graphic stuff from c# (with R.NET) for my own purposes, I used your code as a basis and propose it as a workaround for you to try. You'll find a sample console application that works, using R.NET, on GitHub under:
https://github.com/jmp75/rdotnet-support/tree/master/samples/DrawEllipse
compiled/run from VS2013, Windows7 64 bits, .NET framework 4.5.
I noticed I needed optionally to use dev.hold and dev.flush to get the intuitive refreshes.
e.Evaluate("dev.hold()");
e.Evaluate("mtext('with classical (red) and robust (blue)')");
e.Evaluate("dev.flush()");
Hope this helps.

Related

Google map API- display alternative routes with distance on info window

I am using google map and I am bit stuck at one point. I want to display alternative routes for my source and destination point. Currently I am using the code which is working perfectly and displaying correct result but the only the problem is that this code displaying infowindow for all routes with distance and time. And it needs to be differently colored for alternative routes..
Please help me out.
var request = {
origin: source,
destination: destination,
travelMode: google.maps.TravelMode.DRIVING,
provideRouteAlternatives: true,
optimizeWaypoints
unitSystem: google.maps.UnitSystem.METRIC
};
directionsService.route(request,
function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var step=2;
for (var i = 0, len = response.routes.length; i < len; i++) {
new google.maps.DirectionsRenderer({
map: mapObject,
directions: response,
routeIndex: i
});
stepDisplay.setContent(response.routes[i].legs[i].steps[step].distance.text + "<br>" + response.routes[i].legs[i].steps[step].duration.text + " ");
stepDisplay.setPosition(response.routes[i].legs[i].steps[step].end_location);
stepDisplay.open(mapObject);
}
} else {
$("#error").append("Unable to retrieve your route<br />");
}
});
I analyzed your code as much as I could (not really that experienced with JS). So I'm gonna go on ahead and try to address the concerns on your comment.
InfoWindow for all routes
Based on the code snippet you provided, the for loop already iterates over the response.routes. In here, I see you are already setting an InfoWindow (showing distance and time), based on the route:
stepDisplay.setContent(response.routes[i].legs[i].steps[step].distance.text + "<br>" + response.routes[i].legs[i].steps[step].duration.text + " ");
stepDisplay.setPosition(response.routes[i].legs[i].steps[step].end_location);
stepDisplay.open(mapObject);
-- It made me wonder as to why you still specified this as a problem. Then it hit me, is it that the only InfoWindow shown here is for the last route? If so, your probably not setting it to the map properly. So I looked around and found this JSFiddle Sample where I can try out if it's possible to show multiple InfoWindows. I just added the code where you include an InfoWindow like so:
directionsDisplay.setDirections(response);
var step = 1;
var infowindow2 = new google.maps.InfoWindow();
infowindow2.setContent(response.routes[0].legs[0].steps[step].distance.text + "<br>" + response.routes[0].legs[0].steps[step].duration.text + " ");
infowindow2.setPosition(response.routes[0].legs[0].steps[step].end_location);
infowindow2.open(map);
-- when you open the JSFiddle Sample above, just add the code snippet like above, below the directionsDisplay.setDirections(response); and it will show something like this:
[Multiple InfoWindow Map Screenshot][1]
Route lines should be different colors
For this concern, I found a similar post here. From the answer:
You can specify the color of the line when you create the DirectionsRenderer, using the optional DirectionsRendererOptions struct.
Here's a part of the snippet in the answer:
directionsDisplay = new google.maps.DirectionsRenderer({
polylineOptions: {
strokeColor: "red"
}
});
I tried it out and this is how it looked like:
[Route Different Color Screenshot][2]
How you set the color of each route is up to you though.
Hope this helps. Good luck. :)
PS: Included the Screenshot links in the comments.*

Launch AutoCAD 2013 from an Existing .NET Application and Write to Window

I am attempting to launch AutoCAD 2013 from an existing C# desktop application, use database values to draw a diagram, and then save the drawing to the database as a variable bit array (varbyte). I've been having good success with all except getting coordinates into an existing AutoCAD editor window.
I've tried NETLOAD but I can't put a list of 55+ AutoCAD Database Circle objects through the command line. Attempting to pass objects through COM Interop has been met with failure and confusion over the 32-bit versus 64-bit status of AutoCAD and my application. While this site has been helpful, http://through-the-interface.typepad.com/ , I haven't been able to get what I want done.
Any suggestions would be greatly appreciated. Thanks.
EDIT:
I took Locke's advice and I added functions to the .NET DLL to draw single items based on simple arguments (like X, Y coordinates, radius, label, etc.). Here is what the method signature looks like:
[CommandMethod("DrawSmallCircle", CommandFlags.Session)]
public static void DrawSmallCircle(double x, double y, double aRadius, string aGuage, string aLabel, string aTitle)
After netloading the .dll which hosts the above method (and it's containing class), I use SendCommand on the instantiated interop AcadApplication like so:
acApp.ActiveDocument.SendCommand("DrawSmallCircle " +
circ.circle.Center.X.ToString() + ", " +
circ.circle.Center.Y.ToString() + ", " +
circ.circle.Radius.ToString() + ", " +
circ.guage + ", " +
circ.label + ", " +
circ.title + " "
);
Unfortunately the error I get in response is simply "Common Language Runtime detected an invalid program."
I'm not sure if registering a command in my .dll will do any good because, allegedly, "Command methods can't take arguments, but lispFunctions can."
http://forums.autodesk.com/t5/NET/CommandMethod-with-custom-params/td-p/2572973
Okay, so you've run into the Interop/In-Process automation issue. Traditionally, AutoCAD doesn't want to let out of process modules talk to in-process modules, at least in the context of sending parameters back and forth. The formal approach which involves registering the in-process COM interface is challenging to get behaving correctly, especially in the context of x64 bit. I've still yet to see it behave consistently across multiple computers, therefore I tend to default to the following approach.
You are correct in that methods flagged with the [CommandMethod] flag cannot take arguments, so they'll obviously need to be voids. The trick to sending it parameter context at runtime is to include parameter prompts in the defined method itself. Think of it as you're developing the command to be invoked by the user inside AutoCAD, and they are prompted for each piece of data before the command can proceed. Much like other native AutoCAD commands, the parameter data can be sent alongside the call to the command in a single string.
Example:
(Command "._CIRCLE" "0,0" "5") <-- Draws a circle at 0,0 with a radius of 5.
So your command call could end up looking something like this:
(Command "DRAWDBCIRCLE" "2.3,56.12", "7" "Gauge" "Label" "Title")
In-Process Code
[CommandMethod("DRAWDBCIRCLE")]
public void DrawDbCircle()
{
var acDb = HostApplicationServices.WorkingDatabase;
var acEd = Application.DocumentManager.MdiActiveDocument.Editor;
using (var acTrans = acDb.TransactionManager.StartOpenCloseTransaction())
{
var bt = (BlockTable)acTrans.GetObject(acDb.BlockTableId, OpenMode.ForWrite);
var btr = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
Point3d centerPoint;
double radius;
string gauge, label, title;
// Prompt for the centerpoint
var pointResult = acEd.GetPoint("ENTER CIRCLE ORIGIN: \n");
centerPoint = pointResult.Value;
// Prompt for the radius
var doubleResult = acEd.GetDouble("ENTER CIRCLE RADIUS: \n");
radius = doubleResult.Value;
// Prompt for the strings
var stringResult = acEd.GetString("ENTER CIRCLE GAUGE: \n");
gauge = stringResult.StringResult;
stringResult = acEd.GetString("ENTER CIRCLE LABEL: \n");
label = stringResult.StringResult;
stringResult = acEd.GetString("ENTER CIRCLE TITLE: \n");
title = stringResult.StringResult;
// Create the circle
var circ = new Circle(centerPoint, Vector3d.ZAxis, radius);
// <-- Add code for dealing with strings -->
btr.AppendEntity(circ);
acTrans.AddNewlyCreatedDBObject(circ, true);
acTrans.Commit();
}
}
Interop Code
private AcadApplication acApp;
private AcadDocument acDoc;
private void btnRun_Click(object sender, EventArgs e)
{
if (acApp == null) return;
acDoc = acApp.ActiveDocument;
foreach (DataRow row in circleTable.Rows)
DrawDatabaseCircle(row);
}
private void DrawDatabaseCircle(DataRow circRow)
{
var cmdFormat = string.Format("\"{0},{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\"", circRow.ItemArray);
acDoc.SendCommand(string.Format("(Command \"DRAWDBCIRCLE\" {0})\n", cmdFormat));
}
Obviously this is more or less pseudo-code. I assume a number of things here, like the AcadApplication and AcadDocument fields being set correctly, that the dll containing the defined command method has been properly netloaded, and that the database circles are coming out of a DataTable. Error-handling would be needed in the commandmethod for checking the parameters, and it would make sense to enclose the SendCommand method in a try/catch.
This technique really only works when you have data types that can be represented by strings, so it won't cover every situation. It's definitely worth trying to get the COM registered interface working long-term for more robust communication between in/out processes.

Delving into the world of XML (Windows Phone) Error I dont understand (The ' ' character, hexadecimal value 0x20, cannot be included in a name.)

So I am starting to learn how to use XML data within a app and decided to use some free data to do this however I cannot for the life of me get it working this is my code so far. (I have done a few apps with static data before but hey apps are designed to use the web right? :p)
public partial class MainPage : PhoneApplicationPage
{
List<XmlItem> xmlItems = new List<XmlItem>();
// Constructor
public MainPage()
{
InitializeComponent();
LoadXmlItems("http://hatrafficinfo.dft.gov.uk/feeds/datex/England/CurrentRoadworks/content.xml");
test();
}
public void test()
{
foreach (XmlItem item in xmlItems)
{
testing.Text = item.Title;
}
}
public void LoadXmlItems(string xmlUrl)
{
WebClient client = new WebClient();
client.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
return;
Stream str = e.Result;
XDocument xdoc = XDocument.Load(str);
***xmlItems = (from item in xdoc.Descendants("situation id")
select new XmlItem()
{
Title = item.Element("impactOnTraffic").Value,
Description = item.Element("trafficRestrictionType").Value
}).ToList();***
// close
str.Close();
// add results to the list
xmlItems.Clear();
foreach (XmlItem item in xmlItems)
{
xmlItems.Add(item);
}
};
client.OpenReadAsync(new Uri(xmlUrl, UriKind.Absolute));
}
}
I am basically trying to learn how to do this at the moment as I am intrigued how to actually do it (I know there are many ways but ATM this way seems the easiest) I just don't get what the error is ATM. (The bit in * is where it says the error is)
I also know the display function ATM is not great (As it will only show the last item) but for testing this will do for now.
To some this may seem easy, as a learner its not so easy for me just yet.
The error in picture form:
(It seems I cant post images :/)
Thanks in advance for the help
Edit:
Answer below fixed the error :D
However still nothing is coming up. I "think" it's because of the XML layout and the amount of descendants it has (Cant work out what I need to do being a noob at XML and pulling it from the web as a data source)
Maybe I am starting too complicated :/
Still any help/tips on how to pull some elements from the feed (As there all in Descendants) correctly and store them would be great :D
Edit2:
I have it working (In a crude way) but still :D
Thanks Adam Maras!
The last issue was the double listing. (Adding it to a list, to then add it to another list was causing a null exception) Just using the 1 list within the method solved this issue, (Probably not the best way of doing it but it works for now) and allowed for me to add the results to a listbox until I spend some time working out how to use ListBox.ItemTemplate & DataTemplate to make it look more appealing. (Seems easy enough I say now...)
Thanks Again!!!
from item in xdoc.Descendants("situation id")
// ^
XML tag names can't contain spaces. Looking at the XML, you probably just want "situation" to match the <situation> elements.
After looking at your edit and further reviewing the XML, I figured out what the problem is. If you look at the root element of the document:
<d2LogicalModel xmlns="http://datex2.eu/schema/1_0/1_0" modelBaseVersion="1.0">
You'll see that it has a default namespace applied. The easiest solution to your problem will be to first get the namespsace from the root element:
var ns = xdoc.Root.Name.Namespace;
And then apply it wherever you're using a string to identify an element or attribute name:
from item in xdoc.Descendants(ns + "situation")
// ...
item.Element(ns + "impactOnTraffic").Value
item.Element(ns + "trafficRestrictionType").Value
One more thing: <impactOnTraffic> and <trafficRestrictionType> aren't direct children of the <situation> element, so you'll need to change that code as well:
Title = items.Descendants(ns + "impactOnTraffic").Single().Value,
Description = item.Descendants(ns + "trafficRestrictionType").Single().Value

How to reset digital signature of an InfoPath form during c# workflow in Sharepoint 2010?

As the question says, I have an InfoPath form running on SP2010 using a c# workflow upon submission. If the form is rejected during workflow, then I need to reset it. I have everything under control, EXCEPT how to reset digital signatures to null, nill, nada, nothing, non-extant! Any ideas? I'm looking at Google now, but at current, I'm not even sure of an om for digital signatures?
Wow, i notice this question suddenly gaining alot of pop with bounty almost gone. Just putting it out there, I did not intend to not bounty someone, but i needed the answer earlier this week (2nd week Nov 2012) and thus i searched and played and teetered with code as much as possible till i ended up finding my own answer before anyone else answered me. However, for future reference, if someone gives a better answer, i'll gladly come back and rep them. Thank you all for the support and I really hope my answer is as useful to another as it was to me.
NOW Bloggered && Gisted May no one ever again have to search as hard as I did for this answer, :P
¡¡¡ I F O U N D M Y F R I G G I N ' A N S W E R ! ! !
¡¡¡ And it works from the workflow !!!
Through much trial and tribulation I was finally able to come up with a solution. It involves a few steps. One, elevate security! Otherwise, non-admin users will cause the workflow to error. Seems like it should work this way, but ... Secondly, get the right schema! It took me a while to find mine, i forgot the exact steps, but, it's not hard to find. UPDATED: Can be found as an attribute of xmlDoc.Document, see updated code Step through (debug) your workflow, without the namespace/schema and highlight your document when it gets to it. One of the properties is an url that is the schema link. Anyway, you wanna see the solution!? Do ya? Look down!
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPFile formFile = workflowProperties.Item.File;
MemoryStream ms = new MemoryStream(formFile.OpenBinary());
XmlTextReader rdr = new XmlTextReader(ms);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(rdr);
rdr.Close();
ms.Close();
XmlNamespaceManager nsm = new XmlNamespaceManager(xmlDoc.NameTable);
String schemaUri = xmlDoc.DocumentElement.GetAttributeNode("xmlns:my") != null ? xmlDoc.DocumentElement.GetAttributeNode("xmlns:my").Value : "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-09-04T20:19:31";
nsm.AddNamespace("my", schemaUri);
XmlNode nodeSignatureCollection = xmlDoc.DocumentElement.SelectSingleNode("my:signatures1", nsm);
if (nodeSignatureCollection != null)
{
if (nodeSignatureCollection.HasChildNodes)
{
foreach (XmlNode nodeSignature in nodeSignatureCollection.ChildNodes)
{
// HERE IT IS!!!
if (nodeSignature.HasChildNodes && !nodeSignature.IsReadOnly) nodeSignature.RemoveAll();
}
}
}
byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xmlDoc.OuterXml);
formFile.SaveBinary(xmlData);
formFile.Update();
});
Keep in mind, this setup is for going through multiple signatures. Although I doubt anything would change if there was only one signature.
Any suggestions on making this sweeter and smaller are accepted, however, I must request an explanation. Honestly, I barely understand what is going on here!
The following answer only HALF works. It is left here for instructional purpose. (Full working answer can be found here.) It works for admin users, but nothing less. It also only works from the InfoPath form behind code. NOT from the workflow.
Adding elevated privlage seems to have 0 effect
I'm leaving this answer up here along with my other so that someone may learn from both examples or possibly even instruct others (including myself) via comments and what not on why one way may be better than the other. At this point, I really don't care to explain anymore as I really don't care to see any of this code ever again! LoL!
public void FormEvents_Loading(object sender, LoadingEventArgs e)
{
string[] actionFields = new string[] { "/my:myFields/my:.../my:...", "/my:myFields/my:.../my:...", etc... };
for (int i = 0; i < actionFields.Length; i++)
{
String field = actionFields[i];
XPathNavigator node = this.MainDataSource.CreateNavigator().SelectSingleNode(field, this.NamespaceManager);
if (node.Value.ToLower() == "reject")
{
XPathNavigator sigNode = this.MainDataSource.CreateNavigator();
if (this.Signed) //then unsign it
{
for (int ii = 2; ii <= 13; ii++)
{
try
{
XPathNavigator xSignedSection = sigNode.SelectSingleNode(String.Format("my:myFields/my:signatures1/my:signatures{0}", ii), this.NamespaceManager);
if (xSignedSection.HasChildren)
{
xSignedSection.MoveToChild(XPathNodeType.Element); xSignedSection.DeleteSelf();
};
}
catch (Exception ex) { };
};
};
};
};
}

Can i Read code from a file and and let that code run in an application

I am developing an Desktop Application in WPF using C# .
For the sake of simplicity, Assume my Application has functions which draw lines in said direction goleft() , goright() , goforward() , goback() .
when any of these function is called a line of one inch will be drawn on screen.
I want to make application where user will write code in a file in any editor (say notepad) and save that file in some fixed format (say .abc or .xyz)
Imaginary Example :
(section_start)
For(int i = 0 ; i<= 20 ; i++ )
{
if(i<5)
goforward();
else if(i==5)
goleft();
else if(i < 10)
forward();
.......
........
}
(section_End)
Can i make application which should be capable of reading this file and execute code which is written in between of (section_start) and (section_End). and only if possible can check for syntax errors too... (Not compulsory).
Please guide me on this issue :
Disclosure : My actual Application is somewhat else and could not discuss here due to my company's rules.
Thanks to all who replied to my question. Stackoverflow is fantastic site , i have found the roadmap where to go , till today morning i did not have any clue but now i can go ahead , thanks all of you once again
Will ask question again if i get stucked somewhere
You can read the file content using FileInfo and get the code you need to execute.
Then you can execute the code using CSharpCodeProvider like in this post:
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return \"output!\";}}"
);
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}
You can choose CodeDOM or IL Emit
More help on CodeDOM
More information on IL Generator / Emit
This is called scripting your application if I understand correctly. C# does not support this out of the box. One thing to look into could be the new Roselyn compiler from Microsoft (it is a new take on the C# compiler, which lets you do just this).
For more info on Roselyn check out:
http://blogs.msdn.com/b/csharpfaq/archive/2011/12/02/introduction-to-the-roslyn-scripting-api.aspx
I've only seen a demo of it, but it looks very promissing, and should solve your problem.
It's not clear what kind of code you want compiled but here is a guide on how to compile code code with C#.
You could use IronPython to handle the script.
Here's an example of how to do this:
First you need a navigation object to perform the operations on:
public class NavigationObject
{
public int Offset { get; private set; }
public void GoForwards()
{
Offset++;
}
public void GoBackwards()
{
Offset--;
}
}
Then the code to execute the file:
public void RunNavigationScript(string filePath, NavigationObject navObject)
{
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
scope.SetVariable("navigation", navObject);
var source = engine.CreateScriptSourceFromFile(filePath);
try
{
source.Execute(scope);
}
catch(Exception
{
}
}
The script file can then take the form of something like:
for x in range(0,20):
if x == 5:
navigation.GoBackwards()
else:
navigation.GoForwards()

Categories