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);
        }
Example #8
0
 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);
		}
Example #10
0
        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;
            }
        }
Example #18
0
        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);
            }
        }