public void Serialize(Stream stream, IUnique source, AlertLog log = null) { log?.RaiseAlert("BEG", "Beginning serialisation..."); _Format = new Dictionary <string, TypeFieldsFormat>(); _Aliases = new Dictionary <Type, string>(); _Uniques = new UniquesCollection(); _Writer = new StreamWriter(stream); // Write base item: _Writer.WriteLine(SerializeItem(source)); // Write uniques: int i = 0; while (i < _Uniques.Count) { log?.RaiseAlert("PROG", "Writing...", (double)i / (double)_Uniques.Count, AlertLevel.Information); IUnique unique = _Uniques[i]; _Writer.WriteLine(SerializeItem(unique)); i++; } //_Writer.WriteLine(); //_Writer.WriteLine(FORMAT); //_Writer.Write(GenerateFormatDescription()); _Writer.Flush(); log?.RaiseAlert("BEG", "Serialisation complete."); }
private void WriteModel(RobotController robot, AlertLog log) { log?.RaiseAlert("Writing Salamander model to Robot..."); RobotIDMappingTable idMap = new RobotIDMappingTable(); bool result = robot.WriteModelToRobot(FilePath, Document.Model, ref idMap, null, log); if (result) { robot.Close(); log?.RaiseAlert("Robot file written successfully."); } else { log?.RaiseAlert("Writing Robot file failed!", Nucleus.Alerts.AlertLevel.Error); } robot.Release(result); idMap.LinkToFile(FilePath); Document.IDMappings[FilePath] = idMap; idMap.SaveAsCSV(FilePath.AddNameSuffix("_Mapping", ".csv")); Result = result; }
/// <summary> /// Download map data for a specified bounding box as a byte array /// </summary> /// <param name="left"></param> /// <param name="bottom"></param> /// <param name="right"></param> /// <param name="top"></param> /// <returns></returns> public byte[] DownloadMapData(double left, double bottom, double right, double top, AlertLog log = null) { string osmAPIGet = BuildGetURL(left, bottom, right, top); using (var client = new WebClient()) { try { return(client.DownloadData(osmAPIGet)); } catch (Exception ex) { log?.RaiseAlert("Error downloading map data " + ex.Message, AlertLevel.Warning); return(new byte[] { }); } } }
/// <summary> /// Download a map for the given coordinate range and save it at the specified location /// </summary> /// <param name="left">The lower-bound longitude</param> /// <param name="bottom">The lower-bound latitude</param> /// <param name="right">The upper-bound longitude</param> /// <param name="top">The upper-bound latitude</param> /// <param name="saveTo">The filepath to save the map file to</param> public bool DownloadMap(double left, double bottom, double right, double top, FilePath saveTo, AlertLog log = null) { //Compile the OpenStreetMap API URL: string osmAPIGet = BuildGetURL(left, bottom, right, top); using (var client = new WebClient()) { try { client.DownloadFile(osmAPIGet, saveTo); } catch (Exception ex) { log?.RaiseAlert("Error downloading map " + ex.Message, AlertLevel.Warning); return(false); } } return(true); }
/// <summary> /// Parse a line of text as a data format /// </summary> /// <param name="line"></param> /// <returns></returns> public TypeFieldsFormat ReadFormat(string line, AlertLog log = null) { TypeFieldsFormat result; int i = FORMAT.Length; string alias = line.NextChunk(ref i, KEY_SEPARATOR); string typeName = line.NextChunk(ref i, OPEN_DATABLOCK); Type type = GetType(typeName); var fields = new List <FieldInfo>(); if (type != null) { while (i < line.Length) { string fieldName = line.NextChunk(ref i, SEPARATOR, CLOSE_DATABLOCK); if (!string.IsNullOrEmpty(fieldName)) { FieldInfo field = type.GetBaseField(fieldName); //TODO: check for mapped fields if null if (field == null) { log?.RaiseAlert("FNF " + fieldName + " on " + typeName, "Field '" + fieldName + "' cannot be found on type '" + type.Name + "'.", AlertLevel.Warning); } fields.Add(field); } } result = new TypeFieldsFormat(alias, type, fields); if (_Format != null) { _Format.Add(alias, result); } if (_Aliases != null) { _Aliases.Add(type, alias); } return(result); } else { return(null); } }
/// <summary> /// Read map geometry data, automatically retrieving map data from the OpenStreetMap servers /// </summary> /// <param name="latitude">The latitude, in degrees</param> /// <param name="longitude">The longitude, in degrees</param> /// <param name="range">The range around the specified latitude and longitude to be collected, in degrees</param> /// <param name="layerNames"></param> /// <returns></returns> public GeometryLayerTable ReadMap(double latitude, double longitude, double range = 0.005, IList <string> layerNames = null, AlertLog log = null) { //FilePath osmFile = FilePath.Temp + "TempMap.osm"; //DownloadMap(latitude, longitude, osmFile, range); //return ReadMap(osmFile, latitude, longitude); var data = DownloadMapData(longitude - range, latitude - range, longitude + range, latitude + range); try { using (var stream = new MemoryStream(data)) { return(ReadMap(stream, AnglePair.FromDegrees(latitude, longitude), layerNames)); } } catch (Exception ex) { log?.RaiseAlert("Error reading map " + ex.Message, AlertLevel.Information); return(null); } }
/// <summary> /// Run an analysis on the specified model /// </summary> /// <param name="model"></param> /// <param name="alertLog"></param> /// <returns></returns> public ModelResults AnalyseModel(Model.Model model, AnalysisCaseCollection cases, AlertLog alertLog = null) { alertLog?.RaiseAlert("BLD", "Building analysis model..."); var results = new ModelResults(); // Create model: var feModel = new BFE.Model(); // Create nodes: var nodesMap = new Dictionary <Guid, BFE.Node>(); foreach (var node in model.Nodes) { var bfeNode = ToBFE.Convert(node); feModel.Nodes.Add(bfeNode); nodesMap.Add(node.GUID, bfeNode); } // Create materials: /*var materialsMap = new Dictionary<Guid, BFE.Materials.BaseMaterial>(); * foreach (var material in model.Materials) * { * var bfeMat = ToBFE.Convert(material); * materialsMap.Add(material.GUID, bfeMat); * }*/ // Create sections: /*foreach (var family in model.Families) * { * if (family is SectionFamily) * { * SectionFamily section = (SectionFamily)family; * //TODO? * } * }*/ // Create elements: var elementMap = new Dictionary <Guid, BFE.FrameElement2Node>(); foreach (var element in model.Elements) { if (element is LinearElement) { var linEl = (LinearElement)element; if (linEl.StartNode != null && linEl.EndNode != null && linEl.Family != null) { var el = new BFE.FrameElement2Node( nodesMap[linEl.StartNode.GUID], nodesMap[linEl.EndNode.GUID]); //TODO: Releases //TODO: Orientation //TODO: Offsets if (linEl.Family.Profile?.Perimeter != null) { var profile = ToBFE.Convert(linEl.Family.Profile.Perimeter); el.Geometry = profile; el.UseOverridedProperties = false; //TODO: Hollow sections } el.E = linEl.Family.GetPrimaryMaterial()?.GetE(Geometry.Direction.X) ?? 210e9; feModel.Elements.Add(el); elementMap.Add(element.GUID, el); } else { alertLog.RaiseAlert("INCOMPLETE DATA", linEl, "Incomplete data. Will be excluded from analysis."); } } } //Loading time! // TODO: Limit to specific load cases? foreach (var load in model.Loads) { if (load is LinearElementLoad) { var lEL = (LinearElementLoad)load; if (lEL.IsMoment) { alertLog.RaiseAlert("MOMENTS UNSUPPORTED", load, "Moment line loads are not supported.", AlertLevel.Error); } else { // TODO: Set load case var bLoad = new BFE.UniformLoad1D(lEL.Value, ToBFE.Convert(lEL.Direction), ToBFE.Convert(lEL.Axes)); // TODO: Generalise var elements = lEL.AppliedTo.Items; foreach (var el in elements) { elementMap[el.GUID].Loads.Add(bLoad); } } } else if (load is NodeLoad) { var nL = (NodeLoad)load; } else { alertLog.RaiseAlert("LOAD TYPE UNSUPPORTED", load, "Load type is not supported.", AlertLevel.Error); } } alertLog?.RaiseAlert("BLD", "Analysis model built."); alertLog.RaiseAlert("SLV", "Solving..."); feModel.Solve(); alertLog.RaiseAlert("SLV", "Solved."); foreach (var kvp in nodesMap) { var disp = kvp.Value.GetNodalDisplacement(); var nR = new NodeResults(); var cNR = new CaseNodeResults(); //nR.Add(cNR); } /*foreach (var element in model.Elements) * { * bNS = nodesMap[element] * }*/ return(results); }
protected void PopulateFields(ref object target, TypeFieldsFormat format, ref int i, string line, AlertLog log) { string chunk; int j = 0; IList items = null; //Items for array reinstantiation object currentKey = null; //Current key object for Dictionaries while (i < line.Length) // && j < format.Fields.Count()) { char c; chunk = line.NextChunk(out c, ref i, SEPARATOR, OPEN_DATABLOCK, CLOSE_DATABLOCK, KEY_SEPARATOR); if (c == SEPARATOR || c == CLOSE_DATABLOCK) { // Chunk is simple value if (!string.IsNullOrEmpty(chunk)) { if (j < format.Fields.Count()) { FieldInfo fI = format.Fields[j]; object value = String2Object(chunk, fI.FieldType); fI.SetValue(target, value); } else if (target is IDictionary && currentKey != null) //Dictionary value { //Add to dictionary IDictionary dic = (IDictionary)target; Type[] arguments = dic.GetType().GetGenericArguments(); if (arguments.Length > 1) { object value = String2Object(chunk, arguments[1]); //TODO: What if value is complex object? dic[currentKey] = value; } currentKey = null; } else if (format.Type.IsList()) { Type type = format.Type.GetElementType(); if (format.Type.ContainsGenericParameters) { type = format.Type.GenericTypeArguments[0]; } object value = String2Object(chunk, type); if (format.Type.IsArray) { if (items == null) { Type listType = typeof(List <>).MakeGenericType(type); items = Activator.CreateInstance(listType) as IList; //TODO!!! Create list of required type! } items.Add(value); } else { IList list = (IList)target; list.Add(value); } //TODO } } j++; if (c == CLOSE_DATABLOCK) { // The current object definition is finished - can step out if (items != null) { Type type = format.Type.GetElementType(); Array targetArray = Array.CreateInstance(type, items.Count); for (int k = 0; k < items.Count; k++) { targetArray.SetValue(items[k], k); } target = targetArray; } return; } } else if (c == OPEN_DATABLOCK) { // Chunk is the type alias of an embedded object if (_Format.ContainsKey(chunk)) { TypeFieldsFormat subFormat = _Format[chunk]; object value = null; if (!subFormat.Type.IsArray) { value = subFormat.Type.Instantiate(); } else { value = Activator.CreateInstance(subFormat.Type, new object[] { 0 }); } PopulateFields(ref value, subFormat, ref i, line, log); if (j < format.Fields.Count) { // Is sub-object belonging to a field FieldInfo fI = format.Fields[j]; fI.SetValue(target, value); } else if (target is Array) { if (items == null) { items = new List <object>(); //TODO: Create list of specified type } items.Add(value); } else if (target is IDictionary && currentKey != null) //Dictionary value { IDictionary dic = (IDictionary)target; dic[currentKey] = value; currentKey = null; } else if (target is IDictionary && line[i] == KEY_SEPARATOR) //Dictionary key { currentKey = value; i++; //Skip the key separator character } else if (target is IList) { // Is an entry in the target collection IList list = (IList)target; list.Add(value); } //j++; //i++; //Skip the next separator? } else { log?.RaiseAlert("FNF" + chunk, "Formatting data for type alias '" + chunk + "' not found.", AlertLevel.Warning); } } else if (c == KEY_SEPARATOR && target is IDictionary) { // Is a key for a dictionary: Type[] genTypes = target.GetType().GetGenericArguments(); currentKey = String2Object(chunk, genTypes[0]); } else { // Line is not closed correctly - must be a multiline string // TODO } } }
public IUnique Deserialize(Stream stream, AlertLog log = null) { IUnique result = null; _Format = new Dictionary <string, TypeFieldsFormat>(); _Aliases = new Dictionary <Type, string>(); _Uniques = new UniquesCollection(); _Reader = new StreamReader(stream); // First, read through once to end: log?.RaiseAlert("FORM", "Reading format data..."); string line; int lineCount = 0; while ((line = _Reader.ReadLine()) != null) { lineCount++; if (line.StartsWith(FORMAT)) { ReadFormat(line, log); } else if (line.StartsWith(DATA)) { // Initial pass: Create object int i = DATA.Length; string guid = line.NextChunk(ref i, KEY_SEPARATOR); string typeAlias = line.NextChunk(ref i, OPEN_DATABLOCK); if (_Format.ContainsKey(typeAlias)) { TypeFieldsFormat format = _Format[typeAlias]; IUnique unique = format.Type.Instantiate() as IUnique;//FormatterServices.GetUninitializedObject(format.Type) as IUnique; if (unique is IUniqueWithModifiableGUID) { var uniqueMG = (IUniqueWithModifiableGUID)unique; uniqueMG.SetGUID(new Guid(guid)); } else { FieldInfo fI = format.Type.GetBaseField("_GUID"); // Will not work if backing field is named differently! fI.SetValue(unique, new Guid(guid)); } _Uniques.Add(unique); if (result == null) { result = unique; // Set primary output object } } else { log?.RaiseAlert("FNF" + typeAlias, "Formatting data for type alias '" + typeAlias + "' not found.", AlertLevel.Warning); } } } log?.RaiseAlert("FORM", "Format data read."); // Next: Second pass - populate fields with data // Rewind: stream.Seek(0, SeekOrigin.Begin); _Reader = new StreamReader(stream); int lineNum = 0; while ((line = _Reader.ReadLine()) != null) { log?.RaiseAlert("DAT", "Reading data...", (double)lineNum / (double)lineCount); if (line.StartsWith(DATA)) { // Initial pass: Create object int i = DATA.Length; string guid = line.NextChunk(ref i, KEY_SEPARATOR); string typeAlias = line.NextChunk(ref i, OPEN_DATABLOCK); if (_Format.ContainsKey(typeAlias)) { TypeFieldsFormat format = _Format[typeAlias]; object unique = _Uniques[new Guid(guid)]; PopulateFields(ref unique, format, ref i, line, log); } } lineNum++; } log?.RaiseAlert("DAT", "Reading data complete.", 1.0); log?.RaiseAlert("FIN", "Finalising..."); // Finally: Call OnDeserialized function on each object foreach (var unique in _Uniques) { MethodInfo mInfo = unique.GetType().GetOnDeserializedMethod(); if (mInfo != null) { mInfo.Invoke(unique, new object[] { new StreamingContext() }); } // TODO: Pass in populated streamingcontext arguments? } log?.RaiseAlert("FIN", "Finalised"); return(result); }