public static void GetMapGeoCode(SimioMapRoute mapData, string bingMapsKey, string query, List <string> nameList) { try { nameList.Clear(); var r = ServiceManager.GetResponseAsync(new GeocodeRequest() { BingMapsKey = bingMapsKey, Query = query }).GetAwaiter().GetResult(); if (r != null && r.ResourceSets != null && r.ResourceSets.Length > 0 && r.ResourceSets[0].Resources != null && r.ResourceSets[0].Resources.Length > 0) { for (var i = 0; i < r.ResourceSets[0].Resources.Length; i++) { nameList.Add((r.ResourceSets[0].Resources[i] as Location).Name); } } } catch (Exception ex) { throw new ApplicationException($"Err={ex}"); } }
private void LaunchForm(IDesignContext context, SimioMapRoute mapData) { try { } catch (Exception ex) { throw new ApplicationException($"Launch Error={ex}"); } }
/// <summary> /// Method called when the add-in is run. /// </summary> public void Execute(IDesignContext context) { try { // Check to make sure a model has been opened in StrinbSimio if (context.ActiveModel == null) { alert("You must have an active model to run this add-in."); return; } IModel am = context.ActiveModel; StringBuilder sb = new StringBuilder(); // Get the path to the project file string filepath = GetStringProperty(context.ActiveProject, "FileName"); foreach (IIntelligentObject io in context.ActiveModel.Facility.IntelligentObjects) { PointF pt = new PointF((float)io.Location.X, (float)io.Location.Z); sb.AppendLine($"Name={io.ObjectName} Type={io.TypeName} Location={pt}"); var link = io as ILinkObject; if (link == null) { } } string pathToObjects = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); pathToObjects = Path.Combine(pathToObjects, "SimioObjects.txt"); if (Directory.Exists(pathToObjects)) { File.WriteAllText(pathToObjects, sb.ToString()); } SimioMapRoute mapData = new SimioMapRoute("", ""); // Launch the form and give it access to the Simio Design Context FormGis FormViewer = new FormGis(); FormViewer.DesignContext = context; FormViewer.MapRoute = mapData; FormViewer.Show(); } catch (Exception ex) { if (ex.Message != "Canceled") { MessageBox.Show(ex.Message, "Error"); } } }
/// <summary> /// An asynchronous fetch of a map route (untested) /// </summary> /// <param name="mapData"></param> /// <param name="bingMapsKey"></param> /// <param name="StartStopList"></param> public static void GetMapRouteAsync(SimioMapRoute mapData, string bingMapsKey, List <string> StartStopList) { try { List <SimpleWaypoint> wayPointList = new List <SimpleWaypoint>(); foreach (string location in StartStopList) { SimpleWaypoint wayPoint = new SimpleWaypoint(location); wayPointList.Add(wayPoint); } if (true) { var request = new RouteRequest(); request.Waypoints = wayPointList; request.BingMapsKey = bingMapsKey; Task <Response> t = request.Execute(); var result = t.Result; t.RunSynchronously(); var r = t.Result; if (r != null && r.ResourceSets != null && r.ResourceSets.Length > 0 && r.ResourceSets[0].Resources != null && r.ResourceSets[0].Resources.Length > 0) { for (var i = 0; i < r.ResourceSets[0].Resources.Length; i++) { throw new ApplicationException((r.ResourceSets[0].Resources[i] as Location).Name); } } else { throw new ApplicationException("No results found."); } } if (true) { Task <Response> t = ServiceManager.GetResponseAsync(new RouteRequest() { BingMapsKey = bingMapsKey, Waypoints = wayPointList }); t.RunSynchronously(); var r = ServiceManager.GetResponseAsync(new RouteRequest() { BingMapsKey = bingMapsKey, Waypoints = wayPointList }).GetAwaiter().GetResult(); if (r != null && r.ResourceSets != null && r.ResourceSets.Length > 0 && r.ResourceSets[0].Resources != null && r.ResourceSets[0].Resources.Length > 0) { for (var i = 0; i < r.ResourceSets[0].Resources.Length; i++) { throw new ApplicationException((r.ResourceSets[0].Resources[i] as Location).Name); } } else { throw new ApplicationException("No results found."); } } Console.ReadLine(); } catch (Exception ex) { string x = $"Err={ex}"; } }
/// <summary> /// This method has a lot of logic that is specific to the map type. /// To process a request you can easily just call the Execute method on the request. /// This will build much of the SimioMapRoute object. /// </summary> /// <param name="request"></param> public bool GetRoute(string mapsKey, string originAddress, string destinationAddress, out SimioMapRoute mapRoute, out string requestUrl, out string explanation) { explanation = ""; requestUrl = ""; mapRoute = null; try { mapRoute = new SimioMapRoute(originAddress, destinationAddress); // Build a list of our two waypoints (from and to) List <SimpleWaypoint> wpList = new List <SimpleWaypoint>(); wpList.Add(new SimpleWaypoint(originAddress)); //e.g. "Pittsburgh, PA")); wpList.Add(new SimpleWaypoint(destinationAddress)); // e.g. "Sewickley, PA")); List <RouteAttributeType> routeAttributes = new List <RouteAttributeType>(); routeAttributes.Add(RouteAttributeType.RoutePath); // Construct the request and attributes var request = new RouteRequest() { BingMapsKey = mapsKey, Waypoints = wpList }; request.RouteOptions = new RouteOptions(); request.RouteOptions.RouteAttributes = routeAttributes; requestUrl = request.ToString(); var start = DateTime.Now; // Async. Execute the request. var task = Task <Response> .Run(async() => { return(await request.Execute()); }); Response r2 = task.Result; // Check if we got a good response if (r2 != null && r2.ResourceSets != null && r2.ResourceSets.Length > 0 && r2.ResourceSets[0].Resources != null && r2.ResourceSets[0].Resources.Length > 0) { ResourceSet rs = (ResourceSet)r2.ResourceSets[0]; Route route = (Route)rs.Resources[0]; RouteLeg[] legs = route.RouteLegs; ItineraryItem[] itineraries = legs[0].ItineraryItems; ItineraryItem itinItem = itineraries[2]; string bb = route.BoundingBox.ToString(); mapRoute.SegmentList.Clear(); // We could make the bounding box from the one that Bing Maps sends us, // but we're going to do our own to match the usa 'map'. ////PointF ptLoc = new PointF((float)route.BoundingBox[1], (float)route.BoundingBox[0]); ////float width = (float)(route.BoundingBox[3] - route.BoundingBox[1]); ////float height = (float)(route.BoundingBox[2] - route.BoundingBox[0]); ////// We're going to bound according to the contiguous USA, which is appox. ////// lat 20 to 50, and lon -60 to -130 ////PointF ptLoc = transform.LonLatBoundingBox.Location; // new PointF( -130f, 20f); ////float width = lonlatBox.Width; // 70f; ////float height = lonlatBox.Height; // 30f; ////// Turning the thing on its side, since we want latitude to be 'Y' ////mapData.LonLatBoundingBox = new RectangleF(ptLoc.X, ptLoc.Y, width, height); ////mapData.Origin = new PointF(ptLoc.X + width / 2f, ptLoc.Y + height / 2f); ////mapData.SimioScaling = simioScaling; // Build something for the form's 'result textbox StringBuilder sb = new StringBuilder(); // Create segments from the itineraries, and pick up the indices // that reference the RoutePath array of lat,lon coordinates. // We are assuming a single itinerary. See Bing Maps for for info. for (var ii = 0; ii < itineraries.Length; ii++) { ItineraryItem item = itineraries[ii]; if (route.RoutePath != null) { int idxStart = item.Details[0].StartPathIndices[0]; int idxEnd = item.Details[0].EndPathIndices[0]; double lat = route.RoutePath.Line.Coordinates[idxStart][0]; double lon = route.RoutePath.Line.Coordinates[idxStart][1]; MapCoordinate mcStart = new MapCoordinate(lat, lon); lat = route.RoutePath.Line.Coordinates[idxEnd][0]; lon = route.RoutePath.Line.Coordinates[idxEnd][1]; MapCoordinate mcEnd = new MapCoordinate(lat, lon); MapSegment segment = null; if (ii == 0) { segment = mapRoute.AddFirstSegment(mcStart, mcEnd); } else { segment = mapRoute.AppendSegment(mcEnd); } // Now add Bing-specific info segment.Distance = item.TravelDistance; segment.Duration = item.TravelDuration; } sb.AppendLine($"Compass={item.CompassDirection} Distance={item.TravelDistance} >> {item.Instruction.Text}"); } // for each itinerary explanation = sb.ToString(); return(true); } else { explanation = "No results found."; return(false); } } catch (Exception ex) { explanation = $"Err={ex.Message}"; return(false); } }
/// <summary> /// This will create a Facility 'route' from the given SimioMapRoute object /// by building two nodes (start and stop) and a path between them, /// and also attaching the start to a Source and the stop to a Sink. /// </summary> /// <param name="context"></param> /// <param name="mapRoute"></param> public static bool BuildSimioFacilityObjectsFromMapRoute(IDesignContext context, SimioMapRoute mapRoute, SimioMapTransform transform, out string explanation) { explanation = ""; string marker = "Begin"; try { if (mapRoute == null || mapRoute.SegmentList.Count == 0) { explanation = $"MapRoute is null or without Segments"; return(false); } var intelligentObjects = context.ActiveModel.Facility.IntelligentObjects; // Get scale to convert from latlon to simio meters float xScale = transform.SimioScaling.X; // 20f / mapData.LonLatBoundingBox.Width; float yScale = transform.SimioScaling.Y; // 20f / mapData.BoundingBox.Height; // Find the center in latlon coordinates, because we are going to transform before we scale float xCenter = -(float)transform.BoxCenter.X; float yCenter = -(float)transform.BoxCenter.Y; // Build a transformation matrix Matrix mat = new Matrix(); // Create identity matrix //mat.Rotate(-90); mat.Translate(xCenter, yCenter); // move to origin mat.Scale(xScale, yScale, MatrixOrder.Append); // scale to size MapSegment seg = mapRoute.SegmentList[0]; FacilityLocation startLoc = GisHelpers.LatLonToFacilityLocation(mat, seg.StartLocation.Lat, seg.StartLocation.Lon); seg = mapRoute.SegmentList[mapRoute.SegmentList.Count - 1]; FacilityLocation endLoc = GisHelpers.LatLonToFacilityLocation(mat, seg.EndLocation.Lat, seg.EndLocation.Lon); var source = intelligentObjects.CreateObject("Source", startLoc) as IFixedObject; source.ObjectName = ConvertToName(mapRoute.StartName); // e.g. "Seattle"; //var server = intelligentObjects.CreateObject("Server", new FacilityLocation(0, 0, 0)) as IFixedObject; var sink = intelligentObjects.CreateObject("Sink", endLoc) as IFixedObject; var obj = (IPropertyObject)sink; obj.ObjectName = ConvertToName(mapRoute.EndName); // e.g. "Key West"; var node1 = intelligentObjects.CreateObject("BasicNode", startLoc); node1.ObjectName = ConvertToName(mapRoute.StartName) + "1"; var node2 = intelligentObjects.CreateObject("BasicNode", endLoc); node2.ObjectName = ConvertToName(mapRoute.EndName) + "1"; // Nodes is an IEnumerable, so we will create a temporary List from it to quickly get to the first node in the set var sourceoutput = new List <INodeObject>(source.Nodes)[0]; var sinkinput = new List <INodeObject>(sink.Nodes)[0]; // This path goes directly from the output of source to the input of server var path1 = intelligentObjects.CreateLink("Path", sourceoutput, (INodeObject)node1, null); // This path goes from the output of server to the input of sink, with one vertex in between var path2 = intelligentObjects.CreateLink("Path", (INodeObject)node2, sinkinput, new List <FacilityLocation> { endLoc }); // Build a path from node1 to node2 List <FacilityLocation> pathList = new List <FacilityLocation>(); pathList.Add(node1.Location); int segmentCount = 0; foreach (MapSegment segment in mapRoute.SegmentList) { pathList.Add(GisHelpers.LatLonToFacilityLocation(mat, segment.StartLocation.Lat, segment.StartLocation.Lon)); segmentCount++; marker = $"Built Segment#={segmentCount} Segment={segment}"; } pathList.Add(node2.Location); var path3 = intelligentObjects.CreateLink("Path", (INodeObject)node1, (INodeObject)node2, pathList); return(true); } catch (Exception ex) { explanation = $"Cannot Build Nodes. Marker={marker} Err={ex}"; return(false); } }
/// <summary> /// An asynchronous fetch of a map route (untested) /// </summary> /// <param name="mapData"></param> /// <param name="googleMapsKey"></param> /// <param name="StartStopList"></param> public bool GetRoute(string googleMapsKey, string originAddress, string destinationAddress, out SimioMapRoute mapRoute, out string requestUrl, out string explanation) { requestUrl = ""; explanation = ""; mapRoute = null; try { mapRoute = new SimioMapRoute(originAddress, destinationAddress); DirectionsRequest request = new DirectionsRequest { Key = googleMapsKey, Origin = new Location(originAddress), Destination = new Location(destinationAddress) }; requestUrl = request.ToString(); var response = GoogleApi.GoogleMaps.Directions.Query(request); mapRoute.SegmentList.Clear(); // .. wait for response .. // Response has Routes, and Routes have legs. Typically 1-2 routes foreach (Route route in response.Routes) { // Route has an overview summary and boundingbox // We could make the bounding box from the one that Bing Maps sends us, //but we're going to do our own to match the usa 'map'. ////PointF ptLoc = new PointF((float)route.Bounds.NorthEast.Latitude, (float)route.Bounds.NorthEast.Longitude); ////float width = (float)(route.Bounds.NorthEast.Latitude - route.Bounds.SouthWest.Latitude); ////float height = (float)(route.Bounds.NorthEast.Longitude - route.Bounds.SouthWest.Longitude); ////// We're going to bound according to the contiguous USA, which is appox. ////// lat 20 to 50, and lon -60 to -130 ////PointF ptLoc = lonlatBox.Location; // new PointF( -130f, 20f); ////float width = lonlatBox.Width; // 70f; ////float height = lonlatBox.Height; // 30f; ////// Turning the thing on its side, since we want latitude to be 'Y' ////mapData.LonLatBoundingBox = new RectangleF(ptLoc.X, ptLoc.Y, width, height); ////mapData.Origin = new PointF(ptLoc.X + width / 2f, ptLoc.Y + height / 2f); ////mapData.SimioScaling = simioScaling; int ii = 0; StringBuilder sb = new StringBuilder(); foreach (Leg leg in route.Legs) { // Legs have distance and duration // and StartLocation and address, and EndLocation and address foreach (Step step in leg.Steps) { double lat = step.StartLocation.Latitude; double lon = step.StartLocation.Longitude; MapCoordinate mcStart = new MapCoordinate(lat, lon); lat = step.EndLocation.Latitude; lon = step.EndLocation.Longitude; MapCoordinate mcEnd = new MapCoordinate(lat, lon); MapSegment segment = null; if (ii == 0) { segment = mapRoute.AddFirstSegment(mcStart, mcEnd); } else { segment = mapRoute.AppendSegment(mcEnd); } // Now add Google-specific information segment.Distance = step.Distance.Value; segment.Duration = step.Duration.Value; ii++; sb.AppendLine($"Instructions={step.HtmlInstructions} Distance={step.Distance.Text} >> {step.Duration.Text}"); } // foreach step } // foreach leg explanation = sb.ToString(); } return(true); } catch (Exception ex) { explanation = $"From={originAddress} To={destinationAddress} Err={ex}"; return(false); } }