public object QueryValue(INetworkElement element, IRow row) { if (m_VerboseLogging) { ++m_queryValue_count; } // If this evaluator is queried without specifying a time, then the element is not traversable. return(-1); }
private void UnhookVariables(INetworkElement feature) { var modelledVars = Scenario.Network.FunctionManager.GetVariablesForElement(feature); foreach (var mv in modelledVars) { mv.ProjectViewRow = null; } }
/// <summary> /// Occurs when a dataGrid row header is clicked. /// It is used here to flash the geometry of the newly selected row /// <param name="sender">The control raising this event</param> /// <param name="e">Arguments associated with the event</param> /// </summary> private void dataGridView_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { // make sure none of the cells are in edit mode. When in edit mode, the values obtained // programmatically will not yet match the value the user has changed the cell to DataGridView dgv = (DataGridView)sender; dgv.EndEdit(); // Only flash when there is one selected row if (dgv.SelectedRows.Count > 1) { return; } DataGridViewRow selectedRow = dgv.SelectedRows[0]; // If it is the extra dataGrid row or has errors, then don't try to flash it ValidateRow(selectedRow); if (selectedRow.IsNewRow || selectedRow.ErrorText != "") { return; } // also, if any of the row's cell have no value, then don't want to flash it foreach (DataGridViewCell cell in selectedRow.Cells) { if (cell.Value == null) { return; } } // use the EID to obtain the barrier's corresponding network element and source feature INetworkElement element = GetElementByEID(selectedRow.Cells[0].Value.ToString(), dgv.Name); if (element == null) { return; } IFeature sourceFeature = GetSourceFeature(element); // For an edge, get the part geometry of the barrier covered portion of the source feature // that should be displayed INetworkEdge netEdge = element as INetworkEdge; esriNetworkEdgeDirection displayDirection = esriNetworkEdgeDirection.esriNEDNone; if (netEdge != null) { sourceFeature.Shape = GetBarrierSubcurve(netEdge, sourceFeature, selectedRow); displayDirection = GetDirectionValue(selectedRow); } // Draw FlashFeature(sourceFeature, displayDirection); }
/// <summary> /// Take a network element and return its corresponding source feature /// <param name="element">The return source feature corresponds to this element</param> /// </summary> private IFeature GetSourceFeature(INetworkElement element) { // To draw the network element, we will need its corresponding source feature information // Get the sourceID and OID from the element int sourceID = element.SourceID; int sourceOID = element.OID; // Get the source feature from the network source INetworkSource netSource = m_context.NetworkDataset.get_SourceByID(sourceID); IFeatureClassContainer fClassContainer = m_context.NetworkDataset as IFeatureClassContainer; IFeatureClass sourceFClass = fClassContainer.get_ClassByName(netSource.Name); return(sourceFClass.GetFeature(sourceOID)); }
public object QueryValue(INetworkElement Element, IRow Row) { if (m_countSourceEIDs <= 0) { return(false); } bool restrict = !m_restrictFilterElements; int eid = -1; if (m_sourceEIDHashTable.TryGetValue(Element.EID, out eid)) { restrict = m_restrictFilterElements; } return(restrict); }
public object QueryValue(INetworkElement Element, IRow Row) { if (m_baseNetworkAttributeID < 0) { return(-1); } object value = Element.get_AttributeValue(m_baseNetworkAttributeID); if (value == null) { return(-1); } double baseValue = (double)value; if (baseValue <= 0 || m_scaleFactor == 1 || m_countSourceEIDs <= 0) { return(baseValue); } bool isScaled = false; int eid = -1; if (m_sourceEIDHashTable.TryGetValue(Element.EID, out eid)) { isScaled = (eid > 0); } object resultValue = baseValue; if (isScaled) { if (m_scaleFactor >= 0) { resultValue = m_scaleFactor * baseValue; } else { resultValue = -1; } } return(resultValue); }
/// <summary> /// Take an EID value as a string from one of the dataGridView controls and find /// the network element that corresponds to the EID /// <param name="eidString">The EID value as a string</param> /// <param name="datagridviewName">The name of the dataGrid that held the EID</param> /// </summary> private INetworkElement GetElementByEID(string eidString, string datagridviewName) { int eid = -1; if (!Int32.TryParse(eidString, out eid)) { return(null); } INetworkQuery netQuery = m_context.NetworkDataset as INetworkQuery; INetworkEdge edge = netQuery.CreateNetworkElement(esriNetworkElementType.esriNETEdge) as INetworkEdge; INetworkJunction junction = netQuery.CreateNetworkElement(esriNetworkElementType.esriNETJunction) as INetworkJunction; INetworkElement element = null; try { // Populate the network element from the EID if (datagridviewName == "dataGridViewEdges") { netQuery.QueryEdge(eid, esriNetworkEdgeDirection.esriNEDAlongDigitized, edge); element = edge as INetworkElement; } else if (datagridviewName == "dataGridViewJunctions") { netQuery.QueryJunction(eid, junction); element = junction as INetworkElement; } } catch { // if the query fails, the element will not be displayed } return(element); }
public object QueryValue(INetworkElement element, IRow row) { // This element is restricted if its associated ObjectID is currently stored within the network source's hashtable return(m_sourceHashTable.ContainsKey(element.OID)); }
public object QueryValue(INetworkElement element, IRow row) { // This element is restricted if its associated ObjectID is currently stored within the network source's hashtable return m_sourceHashTable.ContainsKey(element.OID); }
private void btnFindWC_Click(object sender, EventArgs e) { clear(); clearDeep(); IFdeCursor cursor = null; try { if (closestFacilitySolver == null) { closestFacilitySolver = network.CreateClosestFacilitySolver(); closestFacilitySolver.ImpedanceAttributeName = "Length"; } closestFacilitySolver.LocationSearchTolerance = double.Parse(txtSearchTolerance.Text); closestFacilitySolver.ClearFacilityLocations(); closestFacilitySolver.ClearEventLocations(); // 添加WC设施点 foreach (IFeatureClass fc in fcMap_POI.Keys) { if (fc.Name.Contains("WC")) { cursor = fc.Search(null, true); IRowBuffer row = null; while ((row = cursor.NextRow()) != null) { try { INetworkLocation facility = new NetworkLocation(); int pos = row.FieldIndex("Geometry"); IPoint point = row.GetValue(pos) as IPoint; facility.Position = point; facility.Name = fc.Guid.ToString() + "_" + row.GetValue(0).ToString(); //设定名字"fcGUID_oid" closestFacilitySolver.AddFacilityLocation(facility); } catch (COMException ex) { } } break; } } if (closestFacilitySolver.FacilityLocationCount == 0) { MessageBox.Show("添加的厕所数为0,请调整LocationSearchTolerance大小"); return; } // 添加人所在的位置 INetworkEventLocation location = new NetworkEventLocation(); this.axRenderControl1.Camera.GetCamera2(out fdepoint, out ang); location.Position = fdepoint; location.Name = "I'mHere"; location.TargetFacilityCount = int.Parse(txtMaxNum.Text); location.SetCutoff("Length", double.Parse(txtCutoff.Text)); closestFacilitySolver.AddEventLocation(location); // 可视化人的位置 IImagePointSymbol ips = new ImagePointSymbol(); ips.ImageName = "#(i)"; ips.Size = 50; renderPoint = this.axRenderControl1.ObjectManager.CreateRenderPoint(fdepoint, ips, rootId); if (closestFacilitySolver.Solve()) { int routeCount = closestFacilitySolver.RouteCount; if (routeCount == 0) { MessageBox.Show("没有厕所在指定范围内"); return; } for (int i = 0; i < routeCount; i++) { INetworkRoute route = closestFacilitySolver.GetRoute(i); if (route != null) { // 可视化线路 ICurveSymbol lineSym = new CurveSymbol(); lineSym.Color = System.Drawing.Color.Yellow; lineSym.Width = -2; IGeometry geo = route.GetRouteGeometry(); if (geo.GeometryType == gviGeometryType.gviGeometryPolyline) { IPolyline line = geo as IPolyline; renderLine = this.axRenderControl1.ObjectManager.CreateRenderPolyline(line, lineSym, rootId); renderLine.MaxVisibleDistance = 10000; renderLineArray.Add(renderLine); } else if (geo.GeometryType == gviGeometryType.gviGeometryMultiPolyline) { IMultiPolyline line = geo as IMultiPolyline; multiRenderLine = this.axRenderControl1.ObjectManager.CreateRenderMultiPolyline(line, lineSym, rootId); multiRenderLine.MaxVisibleDistance = 10000; multiRenderLineArray.Add(multiRenderLine); } drawTempLine(route); // 高亮厕所 int segmentCount = route.SegmentCount; for (int j = 0; j < segmentCount; j++) { INetworkLocation endLocation = route.GetSegment(j).EndLocation; string[] strs = endLocation.Name.Split('_'); foreach (IFeatureClass fc in fcMap_POI.Keys) { if (fc.Guid.ToString() == strs[0]) { this.axRenderControl1.FeatureManager.HighlightFeature(fc, int.Parse(strs[1]), System.Drawing.Color.Yellow); break; } } //////////////////////测试NetworkElement相关////////////////////////////////// INetworkElementCollection elementCols = route.GetSegment(j).GetNetworkElements(); for (int c = 0; c < elementCols.Count; c++) { INetworkElement element = elementCols.Get(c); if (element.Type == gviNetworkElementType.gviEdge) { INetworkEdge edge = element as INetworkEdge; int subId = edge.SubID; } else { INetworkJunction junction = element as INetworkJunction; INetworkEdgeCollection edgeCol = junction.IncomingEdges; for (int ee = 0; ee < edgeCol.Count; ee++) { INetworkEdge edge = edgeCol.Get(ee); int subId = edge.SubID; } } } ////////////////////////////////////////////////////////////////////////// } } } } else { MessageBox.Show("查找失败"); } } catch (COMException ex) { MessageBox.Show(ex.Message); } finally { if (cursor != null) { //Marshal.ReleaseComObject(cursor); cursor = null; } } }
public object QueryValueAtTime(INetworkElement element, DateTime queryTime, esriNetworkTimeUsage timeUsage) { // Grab the correct cache for this network Dictionary <string, Trip> m_trips = m_caches[m_workspace_path_name].m_trips; Dictionary <long, long> m_linefeatures = m_caches[m_workspace_path_name].m_linefeatures; Dictionary <string, Calendar> m_calendars = m_caches[m_workspace_path_name].m_calendars; Dictionary <string, Dictionary <DateTime, CalendarExceptionType> > m_calExceptions = m_caches[m_workspace_path_name].m_calExceptions; Dictionary <long, List <trip_instance> > m_eids = m_caches[m_workspace_path_name].m_eids; if (m_VerboseLogging) { ++m_queryValueAtTime_Count; } int eid = element.EID; // Note that all query times are local times in the time zone of the network element. DateTime queryDate = queryTime.Date; DayOfWeek queryDayOfWeek = queryTime.DayOfWeek; List <trip_instance> trip_instances; // Get the trip instances associated with the EID if (m_eids.TryGetValue(eid, out trip_instances)) { // This is the query time in seconds since midnight. double seconds_since_midnight = queryTime.TimeOfDay.TotalSeconds; // This will be the final answer. // Initialize it to infinity. double final_travel_time = double.PositiveInfinity; // Initialize a variable showing the max start time of trip on this EID (which is sometimes after midnight because trips run into the next day) long max_trip_start_time = 0; ///////////////////////////////////////////////////// // Each network edge has a set of instances when a trip uses it. Each trip instance // contains a trip_id (unique), a start time, and an end time. We want to loop through all the // possible trips and find the one that minimizes overall travle time (wait time until the trip begins and // travel time to traverse the edge) and return that as the impedance of the edge. // Iterate through all trips with this EID. foreach (trip_instance instance in trip_instances) { // Get the trip object for this trip instance so we can determine if this trip should be considered. Trip tr; // PATRICK: Is there a way to get the trip without this boolean thing? bool hasTripInfo = m_trips.TryGetValue(instance.trip_id, out tr); if (!hasTripInfo) // Something is messed up in their GTFS data - a trip value in stop_times isn't in trips.txt. Just ignore it. { continue; } string service_id = tr.service_id; // service_id is needed to determine calendar information // This trip is restricted, so skip it if (IsTripRestricted(instance.trip_id, tr)) { continue; } // Figure out what the latest start time for trips on this element is. // We use this later when we consider trips running early in the day which // might have carryover from the previous day's trips. if (instance.start_time > max_trip_start_time) { max_trip_start_time = instance.start_time; } // Get the date range and days of the week that this trip run Calendar cal = null; bool hasCalendar = m_calendars.TryGetValue(service_id, out cal); // Get added and removed dates for this trip Dictionary <DateTime, CalendarExceptionType> calExceptions = null; bool hasCalendarExceptions = m_calExceptions.TryGetValue(service_id, out calExceptions); // Three reasons to calculate a travel time on this trip: // 1) Solving against a general day of the week, and this trip runs on that day of the week // 2) Solving against a specific date of the year, and this trip has an added exception that day // 3) Specific day, falls within calendar date range, has trip that day // 1 bool isGeneralDayWithTrip = (!m_UseSpecificDates && hasCalendar && HasTripToday(queryDayOfWeek, cal)); // 2 // Consider the schedule date ranges and exceptions // Comparing dates for the key should be fine as long as the datetimes are created only using year, month, and day bool isSpecificDayWithException = (m_UseSpecificDates && hasCalendarExceptions && calExceptions.ContainsKey(queryDate)); bool isSpecificDayWithAddedException = (isSpecificDayWithException && calExceptions[queryDate] == CalendarExceptionType.added); // 3 bool isSpecificDayInTripRange = (m_UseSpecificDates && hasCalendar && DateFallsBetween(queryDate, cal.start_date, cal.end_date) && HasTripToday(queryDayOfWeek, cal)); // Do not calculate travel time for this trip if the specific date is a removed exception bool isSpecificDayWithRemovedException = (isSpecificDayWithException && calExceptions[queryDate] == CalendarExceptionType.removed); // The one reason to be sure NOT to use this trip for this element if (isSpecificDayWithRemovedException) { continue; } // All of the reasons to figure out the traversal time for this element and this trip else if (isGeneralDayWithTrip || isSpecificDayWithAddedException || isSpecificDayInTripRange) { CalculateTravelTime(timeUsage, seconds_since_midnight, instance, ref final_travel_time); } } // Special conditions to check if our trip is occurring late in the day. // If our query time and min travel time pushes us past midnight, look at trips from the next day as well. // This only matters if we're going forward in time. if (timeUsage == esriNetworkTimeUsage.esriNTUBeforeTraversal && (seconds_since_midnight + final_travel_time) > SECONDS_IN_A_DAY) { // Find the date for the day after the query day. DateTime DayAfterQuery = queryDate.AddDays(1); foreach (trip_instance instance in trip_instances) { Trip tr; bool hasTripInfo = m_trips.TryGetValue(instance.trip_id, out tr); if (!hasTripInfo) // Something is messed up in their GTFS data - a trip value in stop_times isn't in trips.txt. Just ignore it. { continue; } string service_id = tr.service_id; // This trip is restricted, so skip it if (IsTripRestricted(instance.trip_id, tr)) { continue; } // How many seconds are left in the current day. double secondsLeftInDay = SECONDS_IN_A_DAY - seconds_since_midnight; // Ignore this trip if it starts after our current shortest travel time double seconds_since_midnight_tomorrow = (final_travel_time - secondsLeftInDay); bool tripStartsTooLate = (instance.start_time >= seconds_since_midnight_tomorrow - 0.5); // Pad by half a second to avoid rounding errors if (tripStartsTooLate) { continue; } // Get the date range and days of the week that this trip run Calendar cal = null; bool hasCalendar = m_calendars.TryGetValue(service_id, out cal); // Get added and removed dates for this trip Dictionary <DateTime, CalendarExceptionType> calExceptions = null; bool hasCalendarExceptions = m_calExceptions.TryGetValue(service_id, out calExceptions); // Reasons to calculate the travel time: // 1) Generic day of the week, has trip tomorrow bool isGeneralDayWithTrip = (!m_UseSpecificDates && hasCalendar && HasTripTomorrow(queryDayOfWeek, cal)); // 2) Specific date, has added exception bool isSpecificDayWithException = (m_UseSpecificDates && hasCalendarExceptions && calExceptions.ContainsKey(DayAfterQuery)); bool isSpecificDayWithAddedException = (isSpecificDayWithException && calExceptions[DayAfterQuery] == CalendarExceptionType.added); // 3) Specific date, falls within date range, has trip tomorrow bool isSpecificDayInTripRange = (m_UseSpecificDates && hasCalendar && DateFallsBetween(DayAfterQuery, cal.start_date, cal.end_date) && HasTripTomorrow(queryDayOfWeek, cal)); // Do not calculate travel time for this trip if the specific date is a removed exception bool isSpecificDayWithRemovedException = (isSpecificDayWithException && calExceptions[DayAfterQuery] == CalendarExceptionType.removed); // All of the reasons to figure out the traversal time for this element and this trip if (isGeneralDayWithTrip || isSpecificDayWithAddedException || isSpecificDayInTripRange) { // Select only those trips starting before our current min travel time. if (instance.start_time <= seconds_since_midnight_tomorrow - 0.5) { double travel_time = SECONDS_IN_A_DAY + instance.end_time - seconds_since_midnight; if (travel_time < final_travel_time) { // If the travel time we just calculated is less than our current minimum, // update the current minimum. final_travel_time = travel_time; } } } // The one reason to be sure NOT to use this trip for this element else if (isSpecificDayWithRemovedException) { continue; } } } // Special conditions if our trip is occurring early in the day // Only do this part if our trip is occurring before trips from the previous day have stopped running if (seconds_since_midnight - 0.5 <= max_trip_start_time - SECONDS_IN_A_DAY) { // Figure out the query time in seconds since the previous day's midnight double secondsSinceMidnightYesterday = SECONDS_IN_A_DAY + seconds_since_midnight; // Find the date for the day prior to the query day. DateTime DayBeforeQuery = queryDate.AddDays(-1); foreach (trip_instance instance in trip_instances) { Trip tr; bool hasTripInfo = m_trips.TryGetValue(instance.trip_id, out tr); if (!hasTripInfo) // Something is messed up in their GTFS data - a trip value in stop_times isn't in trips.txt. Just ignore it. { continue; } string service_id = tr.service_id; // This trip is restricted, so skip it if (IsTripRestricted(instance.trip_id, tr)) { continue; } // Get the date range and days of the week that this trip run Calendar cal = null; bool hasCalendar = m_calendars.TryGetValue(service_id, out cal); // Get added and removed dates for this trip Dictionary <DateTime, CalendarExceptionType> calExceptions = null; bool hasCalendarExceptions = m_calExceptions.TryGetValue(service_id, out calExceptions); // Reasons to calculate the travel time: // 1) Generic day of the week, has trip yesterday bool isGeneralDayWithTrip = (!m_UseSpecificDates && hasCalendar && HasTripYesterday(queryDayOfWeek, cal)); // 2) Specific date, has added exception bool isSpecificDayWithException = (m_UseSpecificDates && hasCalendarExceptions && calExceptions.ContainsKey(DayBeforeQuery)); bool isSpecificDayWithAddedException = (isSpecificDayWithException && calExceptions[DayBeforeQuery] == CalendarExceptionType.added); // 3) Specific date, falls within date range, has trip tomorrow bool isSpecificDayInTripRange = (m_UseSpecificDates && hasCalendar && DateFallsBetween(DayBeforeQuery, cal.start_date, cal.end_date) && HasTripTomorrow(queryDayOfWeek, cal)); // Do not calculate travel time for this trip if the specific date is a removed exception bool isSpecificDayWithRemovedException = (isSpecificDayWithException && calExceptions[DayBeforeQuery] == CalendarExceptionType.removed); // All of the reasons to figure out the traversal time for this element and this trip if (isGeneralDayWithTrip || isSpecificDayWithAddedException || isSpecificDayInTripRange) { CalculateTravelTime(timeUsage, secondsSinceMidnightYesterday, instance, ref final_travel_time); } // The one reason to be sure NOT to use this trip for this element else if (isSpecificDayWithRemovedException) { continue; } } } // If we didn't find any valid trips at all, set it equal to -1 so it's not traversable. if (final_travel_time == double.PositiveInfinity) { return(-1); } else { // Return the final minimum travel time across the element. // Divide by 60 to convert to minutes. return(final_travel_time / 60.0); } } // If the EID wasn't even in our list, return -1. This should never happen. else { return(-1); } }
private byte[] QueryByExtentHandler(NameValueCollection boundVariables, JsonObject operationInput, string outputFormat, string requestProperties, out string responseProperties) { responseProperties = null; if (networkDataset == null) { throw new NullReferenceException("Could not access the network dataset."); } if (!operationInput.TryGetString("Extent", out var envelopeString)) { throw new ArgumentNullException("Extent is invalid."); } var coords = envelopeString.Split(';'); var minCoords = coords[0].Split(','); var maxCoords = coords[1].Split(','); double.TryParse(minCoords[0].Trim(), out var minX); double.TryParse(minCoords[1].Trim(), out var minY); double.TryParse(maxCoords[0].Trim(), out var maxX); double.TryParse(maxCoords[0].Trim(), out var maxY); // Find features in envelope IEnvelope env = new EnvelopeClass(); env.PutCoords(minX, minY, maxX, maxY); ISpatialFilter spatialFilter = new SpatialFilter(); spatialFilter.Geometry = env; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; // Add selected features OID into LongArray ILongArray oIDs = new LongArray(); IFeatureCursor fCursor = streetFC.Search(spatialFilter, true); IFeature feature = fCursor.NextFeature(); while (feature != null) { oIDs.Add(feature.OID); feature = fCursor.NextFeature(); } // Get the network edges corresponding to the streets and write out information about them INetworkQuery networkQuery = networkDataset as INetworkQuery; INetworkJunction fromJunction = networkQuery.CreateNetworkElement(esriNetworkElementType.esriNETJunction) as INetworkJunction; INetworkJunction toJunction = networkQuery.CreateNetworkElement(esriNetworkElementType.esriNETJunction) as INetworkJunction; IEnumNetworkElement networkElements = networkQuery.ElementsByOIDs[streetsSourceID, oIDs]; INetworkElement networkElement = networkElements.Next(); JSONObject result = new JSONObject(); JSONArray elementArray = new JSONArray(); INetworkEdge networkEdge; while (networkElement != null) { JSONObject jo = new JSONObject(); networkEdge = networkElement as INetworkEdge; networkEdge.QueryJunctions(fromJunction, toJunction); double travelTime = (double)networkEdge.AttributeValue[travelTimeAttributeID]; jo.AddLong("EdgeID", networkEdge.EID); jo.AddLong("FromJunctionID", fromJunction.EID); jo.AddLong("ToJunctionID", toJunction.EID); jo.AddDoubleEx(costAttributeName, travelTime, 4); elementArray.AddJSONObject(jo); networkElement = networkElements.Next(); } result.AddJSONArray("NetworkElements", elementArray); return(Encoding.UTF8.GetBytes(result.ToJSONString(null))); }
/// <summary> /// Take a network element and return its corresponding source feature /// <param name="element">The return source feature corresponds to this element</param> /// </summary> private IFeature GetSourceFeature(INetworkElement element) { // To draw the network element, we will need its corresponding source feature information // Get the sourceID and OID from the element int sourceID = element.SourceID; int sourceOID = element.OID; // Get the source feature from the network source INetworkSource netSource = m_context.NetworkDataset.get_SourceByID(sourceID); IFeatureClassContainer fClassContainer = m_context.NetworkDataset as IFeatureClassContainer; IFeatureClass sourceFClass = fClassContainer.get_ClassByName(netSource.Name); return sourceFClass.GetFeature(sourceOID); }
public object QueryValue(INetworkElement Element, IRow Row) { if (m_countSourceEIDs <= 0) return false; bool restrict = !m_restrictFilterElements; int eid = -1; if (m_sourceEIDHashTable.TryGetValue(Element.EID, out eid)) restrict = m_restrictFilterElements; return restrict; }
public object QueryValue(INetworkElement element, IRow row) { if (m_VerboseLogging) ++m_queryValue_count; // If this evaluator is queried without specifying a time, then the element is not traversable. return -1; }
public object QueryValue(INetworkElement Element, IRow Row) { if (m_baseNetworkAttributeID < 0) return -1; object value = Element.get_AttributeValue(m_baseNetworkAttributeID); if (value == null) return -1; double baseValue = (double)value; if (baseValue <= 0 || m_scaleFactor == 1 || m_countSourceEIDs <= 0) return baseValue; bool isScaled = false; int eid = -1; if (m_sourceEIDHashTable.TryGetValue(Element.EID, out eid)) isScaled = (eid > 0); object resultValue = baseValue; if (isScaled) { if (m_scaleFactor >= 0) resultValue = m_scaleFactor * baseValue; else resultValue = -1; } return resultValue; }
public object QueryValueAtTime(INetworkElement element, DateTime queryTime, esriNetworkTimeUsage timeUsage) { if (m_VerboseLogging) ++m_queryValueAtTime_Count; int eid = element.EID; // Note that all query times are local times in the time zone of the network element. DateTime queryDate = queryTime.Date; DayOfWeek queryDayOfWeek = queryTime.DayOfWeek; List<trip_instance> trip_instances; // Get the trip instances associated with the EID if (m_eids.TryGetValue(eid, out trip_instances)) { // This is the query time in seconds since midnight. double seconds_since_midnight = queryTime.TimeOfDay.TotalSeconds; // This will be the final answer. // Initialize it to infinity. double final_travel_time = double.PositiveInfinity; // Initialize a variable showing the max start time of trip on this EID (which is sometimes after midnight because trips run into the next day) long max_trip_start_time = 0; ///////////////////////////////////////////////////// // Each network edge has a set of instances when a trip uses it. Each trip instance // contains a trip_id (unique), a start time, and an end time. We want to loop through all the // possible trips and find the one that minimizes overall travle time (wait time until the trip begins and // travel time to traverse the edge) and return that as the impedance of the edge. // Iterate through all trips with this EID. foreach (trip_instance instance in trip_instances) { // Get the trip object for this trip instance so we can determine if this trip should be considered. Trip tr; // PATRICK: Is there a way to get the trip without this boolean thing? bool hasTripInfo = m_trips.TryGetValue(instance.trip_id, out tr); if (!hasTripInfo) // Something is messed up in their GTFS data - a trip value in stop_times isn't in trips.txt. Just ignore it. { continue; } string service_id = tr.service_id; // service_id is needed to determine calendar information // This trip is restricted, so skip it if (IsTripRestricted(instance.trip_id, tr)) { continue; } // Figure out what the latest start time for trips on this element is. // We use this later when we consider trips running early in the day which // might have carryover from the previous day's trips. if (instance.start_time > max_trip_start_time) { max_trip_start_time = instance.start_time; } // Get the date range and days of the week that this trip run Calendar cal = null; bool hasCalendar = m_calendars.TryGetValue(service_id, out cal); // Get added and removed dates for this trip Dictionary<DateTime, CalendarExceptionType> calExceptions = null; bool hasCalendarExceptions = m_calExceptions.TryGetValue(service_id, out calExceptions); // Three reasons to calculate a travel time on this trip: // 1) Solving against a general day of the week, and this trip runs on that day of the week // 2) Solving against a specific date of the year, and this trip has an added exception that day // 3) Specific day, falls within calendar date range, has trip that day // 1 bool isGeneralDayWithTrip = (!m_UseSpecificDates && hasCalendar && HasTripToday(queryDayOfWeek, cal)); // 2 // Consider the schedule date ranges and exceptions // Comparing dates for the key should be fine as long as the datetimes are created only using year, month, and day bool isSpecificDayWithException = (m_UseSpecificDates && hasCalendarExceptions && calExceptions.ContainsKey(queryDate)); bool isSpecificDayWithAddedException = (isSpecificDayWithException && calExceptions[queryDate] == CalendarExceptionType.added); // 3 bool isSpecificDayInTripRange = (m_UseSpecificDates && hasCalendar && DateFallsBetween(queryDate, cal.start_date, cal.end_date) && HasTripToday(queryDayOfWeek, cal)); // Do not calculate travel time for this trip if the specific date is a removed exception bool isSpecificDayWithRemovedException = (isSpecificDayWithException && calExceptions[queryDate] == CalendarExceptionType.removed); // The one reason to be sure NOT to use this trip for this element if (isSpecificDayWithRemovedException) { continue; } // All of the reasons to figure out the traversal time for this element and this trip else if (isGeneralDayWithTrip || isSpecificDayWithAddedException || isSpecificDayInTripRange) { CalculateTravelTime(timeUsage, seconds_since_midnight, instance, ref final_travel_time); } } // Special conditions to check if our trip is occurring late in the day. // If our query time and min travel time pushes us past midnight, look at trips from the next day as well. // This only matters if we're going forward in time. if (timeUsage == esriNetworkTimeUsage.esriNTUBeforeTraversal && (seconds_since_midnight + final_travel_time) > SECONDS_IN_A_DAY) { // Find the date for the day after the query day. DateTime DayAfterQuery = queryDate.AddDays(1); foreach (trip_instance instance in trip_instances) { Trip tr; bool hasTripInfo = m_trips.TryGetValue(instance.trip_id, out tr); if (!hasTripInfo) // Something is messed up in their GTFS data - a trip value in stop_times isn't in trips.txt. Just ignore it. { continue; } string service_id = tr.service_id; // This trip is restricted, so skip it if (IsTripRestricted(instance.trip_id, tr)) { continue; } // How many seconds are left in the current day. double secondsLeftInDay = SECONDS_IN_A_DAY - seconds_since_midnight; // Ignore this trip if it starts after our current shortest travel time double seconds_since_midnight_tomorrow = (final_travel_time - secondsLeftInDay); bool tripStartsTooLate = (instance.start_time >= seconds_since_midnight_tomorrow-0.5); // Pad by half a second to avoid rounding errors if (tripStartsTooLate) continue; // Get the date range and days of the week that this trip run Calendar cal = null; bool hasCalendar = m_calendars.TryGetValue(service_id, out cal); // Get added and removed dates for this trip Dictionary<DateTime, CalendarExceptionType> calExceptions = null; bool hasCalendarExceptions = m_calExceptions.TryGetValue(service_id, out calExceptions); // Reasons to calculate the travel time: // 1) Generic day of the week, has trip tomorrow bool isGeneralDayWithTrip = (!m_UseSpecificDates && hasCalendar && HasTripTomorrow(queryDayOfWeek, cal)); // 2) Specific date, has added exception bool isSpecificDayWithException = (m_UseSpecificDates && hasCalendarExceptions && calExceptions.ContainsKey(DayAfterQuery)); bool isSpecificDayWithAddedException = (isSpecificDayWithException && calExceptions[DayAfterQuery] == CalendarExceptionType.added); // 3) Specific date, falls within date range, has trip tomorrow bool isSpecificDayInTripRange = (m_UseSpecificDates && hasCalendar && DateFallsBetween(DayAfterQuery, cal.start_date, cal.end_date) && HasTripTomorrow(queryDayOfWeek, cal)); // Do not calculate travel time for this trip if the specific date is a removed exception bool isSpecificDayWithRemovedException = (isSpecificDayWithException && calExceptions[DayAfterQuery] == CalendarExceptionType.removed); // All of the reasons to figure out the traversal time for this element and this trip if (isGeneralDayWithTrip || isSpecificDayWithAddedException || isSpecificDayInTripRange) { // Select only those trips starting before our current min travel time. if (instance.start_time <= seconds_since_midnight_tomorrow-0.5) { double travel_time = SECONDS_IN_A_DAY + instance.end_time - seconds_since_midnight; if (travel_time < final_travel_time) { // If the travel time we just calculated is less than our current minimum, // update the current minimum. final_travel_time = travel_time; } } } // The one reason to be sure NOT to use this trip for this element else if (isSpecificDayWithRemovedException) { continue; } } } // Special conditions if our trip is occurring early in the day // Only do this part if our trip is occurring before trips from the previous day have stopped running if (seconds_since_midnight-0.5 <= max_trip_start_time - SECONDS_IN_A_DAY) { // Figure out the query time in seconds since the previous day's midnight double secondsSinceMidnightYesterday = SECONDS_IN_A_DAY + seconds_since_midnight; // Find the date for the day prior to the query day. DateTime DayBeforeQuery = queryDate.AddDays(-1); foreach (trip_instance instance in trip_instances) { Trip tr; bool hasTripInfo = m_trips.TryGetValue(instance.trip_id, out tr); if (!hasTripInfo) // Something is messed up in their GTFS data - a trip value in stop_times isn't in trips.txt. Just ignore it. { continue; } string service_id = tr.service_id; // This trip is restricted, so skip it if (IsTripRestricted(instance.trip_id, tr)) { continue; } // Get the date range and days of the week that this trip run Calendar cal = null; bool hasCalendar = m_calendars.TryGetValue(service_id, out cal); // Get added and removed dates for this trip Dictionary<DateTime, CalendarExceptionType> calExceptions = null; bool hasCalendarExceptions = m_calExceptions.TryGetValue(service_id, out calExceptions); // Reasons to calculate the travel time: // 1) Generic day of the week, has trip yesterday bool isGeneralDayWithTrip = (!m_UseSpecificDates && hasCalendar && HasTripYesterday(queryDayOfWeek, cal)); // 2) Specific date, has added exception bool isSpecificDayWithException = (m_UseSpecificDates && hasCalendarExceptions && calExceptions.ContainsKey(DayBeforeQuery)); bool isSpecificDayWithAddedException = (isSpecificDayWithException && calExceptions[DayBeforeQuery] == CalendarExceptionType.added); // 3) Specific date, falls within date range, has trip tomorrow bool isSpecificDayInTripRange = (m_UseSpecificDates && hasCalendar && DateFallsBetween(DayBeforeQuery, cal.start_date, cal.end_date) && HasTripTomorrow(queryDayOfWeek, cal)); // Do not calculate travel time for this trip if the specific date is a removed exception bool isSpecificDayWithRemovedException = (isSpecificDayWithException && calExceptions[DayBeforeQuery] == CalendarExceptionType.removed); // All of the reasons to figure out the traversal time for this element and this trip if (isGeneralDayWithTrip || isSpecificDayWithAddedException || isSpecificDayInTripRange) { CalculateTravelTime(timeUsage, secondsSinceMidnightYesterday, instance, ref final_travel_time); } // The one reason to be sure NOT to use this trip for this element else if (isSpecificDayWithRemovedException) { continue; } } } // If we didn't find any valid trips at all, set it equal to -1 so it's not traversable. if (final_travel_time == double.PositiveInfinity) { return -1; } else { // Return the final minimum travel time across the element. // Divide by 60 to convert to minutes. return final_travel_time / 60.0; } } // If the EID wasn't even in our list, return -1. This should never happen. else { return -1; } }
static void Main(string[] args) { try { // Initialize ArcObjects ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop); LicenseInitializer aoLicenseInitializer = new LicenseInitializer(); if (!aoLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeBasic, esriLicenseProductCode.esriLicenseProductCodeStandard, esriLicenseProductCode.esriLicenseProductCodeAdvanced }, new esriLicenseExtensionCode[] { esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork })) { System.Windows.Forms.MessageBox.Show("This application could not initialize with the correct ArcGIS license and will shutdown. LicenseMessage: " + aoLicenseInitializer.LicenseMessage()); aoLicenseInitializer.ShutdownApplication(); return; } // Get the network dataset string networkDatasetPath = args[0]; INetworkDataset nd = GetNetworkDatasetFromPath(networkDatasetPath); var networkQuery = nd as INetworkQuery3; // Name of source containing transit lines. Probably hard-wired to "TransitLines" string sourceName = args[1]; // Get the source object from the network INetworkSource networkSource = nd.get_SourceByName(sourceName); int networkSourceID = networkSource.ID; // The SQLDbase containing the transit schedules string SQLDbase_path = args[2]; // Connect to the SQL database, loop through the network's features, and add EID values to the table for each SourceOID. string workspaceConnectionString = @"Data Source=" + SQLDbase_path + "; Version=3;"; using (SQLiteConnection conn = new SQLiteConnection(workspaceConnectionString)) { conn.Open(); using (SQLiteCommand cmd = new SQLiteCommand(conn)) { using (var transaction = conn.BeginTransaction()) { List <int> BadSourceOIDs = new List <int>(); // Get all the transit lines from the network IEnumNetworkElement transit_lines = networkQuery.get_ElementsForSource(networkSourceID); // Loop through all the transit lines and add their EIDs to the SQL table INetworkElement transit_line = transit_lines.Next(); while (transit_line != null) { // Note: We are assuming that there is a one-to-one mapping between SourceOID and EID. This should always be // the case for transit lines feature classes correctly created using the Add GTFS to a Network Dataset toolbox. int EID = transit_line.EID; int SourceOID = transit_line.OID; try { string updateStmt = string.Format("UPDATE linefeatures SET eid={0} WHERE SourceOID={1}", EID.ToString(), SourceOID.ToString()); cmd.CommandText = updateStmt; cmd.ExecuteNonQuery(); } catch { // For some reason, the item couldn't be inserted into the table, likely because SourceOID couldn't be found. BadSourceOIDs.Add(SourceOID); continue; } transit_line = transit_lines.Next(); } // Add the eids to the table in batch. transaction.Commit(); if (BadSourceOIDs.Count != 0) { // Write out an error if something went wrong while filling the table. Console.Error.WriteLine("The network EID value could not be determined for the following transit line source OIDs:"); foreach (int BadSourceOID in BadSourceOIDs) { Console.Error.WriteLine(BadSourceOID); } Console.Error.WriteLine("You probably need to recreate your transit lines feature class."); } } } } } catch (Exception e) { Console.Error.WriteLine(e.Message); } }