public async void Example7() { Map map = MapView.Active.Map; StreamLayer streamLayer = null; await QueuedTask.Run(() => { #region Check the Realtime Feature Class is Track Aware using (var rfc = streamLayer.GetFeatureClass()) using (var rfc_def = rfc.GetDefinition()) { if (rfc_def.HasTrackIDField()) { //Track aware } } #endregion #region Get the Track Id Field from the Realtime Feature class //Must be on QueuedTask using (var rfc = streamLayer.GetFeatureClass()) using (var rfc_def = rfc.GetDefinition()) { if (rfc_def.HasTrackIDField()) { var fld_name = rfc_def.GetTrackIDField(); } } #endregion }); }
protected async override void OnClick() { MapView mapView = MapView.Active; Map map = mapView.Map; #region initial setup if ((_rtCursor != null) && (_rtCursor.GetState() == RealtimeCursorState.Subscribed)) { _rtCursor.Unsubscribe(); foreach (var vs in mapView.GetExploratoryAnalysisCollection()) { await mapView.RemoveExploratoryAnalysis(vs); } _vwDict = null; return; } _vwDict = new Dictionary <int, Viewshed>() { { 1, null }, { 2, null } }; StreamLayer streamFLyr = map.Layers[0] as StreamLayer; //FeatureLayer vehicleFLyr = map.Layers[1] as FeatureLayer;//.Where(x => x.Name.Equals("Vehicles", StringComparison.InvariantCultureIgnoreCase)) as FeatureLayer; MapPoint searchPoint = null; #endregion await QueuedTask.Run(async() => { RealtimeFeatureClass reatltimeFeatureClass = streamFLyr.GetFeatureClass(); //RealtimeCursor _rtCursor = streamFLyr.Subscribe(null, true); //Waiting for new streamed features while (await _rtCursor.WaitForRowsAsync()) { while (_rtCursor.MoveNext()) { using (var rtFeature = _rtCursor.Current) { switch (rtFeature.GetRowSource()) { case RealtimeRowSource.EventInsert: var featureId = (int)rtFeature["TrackID"]; searchPoint = await ShowViewshed(mapView, featureId); continue; case RealtimeRowSource.EventDelete: default: continue; } ; } } } }); }
public async void SubscribeToStreamData() { Map map = MapView.Active.Map; FeatureLayer countyFeatureLayer = null; StreamLayer streamLayer = null; QueryFilter qfilter = null; #region Subscribe to Streaming Data //Note: with feature class we can also use a System Task to subscribe and //process rows await QueuedTask.Run(async() => { // or var rfc = realtimeDatastore.OpenTable(name) as RealtimeFeatureClass using (var rfc = streamLayer.GetFeatureClass()) { //non-recycling cursor - 2nd param "false" //subscribe, pre-existing rows are not searched using (var rc = rfc.Subscribe(qfilter, false)) { SpatialQueryFilter spatialFilter = new SpatialQueryFilter(); //waiting for new features to be streamed //default is no cancellation while (await rc.WaitForRowsAsync()) { while (rc.MoveNext()) { using (var row = rc.Current) { switch (row.GetRowSource()) { case RealtimeRowSource.EventInsert: //getting geometry from new events as they arrive Polygon poly = ((RealtimeFeature)row).GetShape() as Polygon; //using the geometry to select features from another feature layer spatialFilter.FilterGeometry = poly;//project poly if needed... countyFeatureLayer.Select(spatialFilter); continue; default: continue; } } } } }//row cursor is disposed. row cursor is unsubscribed } }); #endregion }
protected async override void OnClick() { Map map = MapView.Active.Map; if ((_rtCursor != null) && (_rtCursor.GetState() == RealtimeCursorState.Subscribed)) { _rtCursor.Unsubscribe(); return; } StreamLayer streamFLyr = map.Layers[0] as StreamLayer; SpatialQueryFilter sf = new SpatialQueryFilter(); sf.SpatialRelationship = SpatialRelationship.Intersects; FeatureLayer countiesFLyr = map.Layers[1] as FeatureLayer; //var serviceConnectionProperties = // new RealtimeServiceConnectionProperties(new Uri("https://zihans.esri.com:6443/arcgis/rest/services/Florence-Polygon-Out/StreamServer"), RealtimeDatastoreType.StreamService); //RealtimeDatastore realtimeDatastore = null; //string tableName = ""; RealtimeFeatureClass realTimeFC = null; await QueuedTask.Run(async() => { realTimeFC = streamFLyr.GetFeatureClass(); _rtCursor = realTimeFC.SearchAndSubscribe(null, true); while (await _rtCursor.WaitForRowsAsync()) { while (_rtCursor.MoveNext()) { using (var rtFeature = _rtCursor.Current as RealtimeFeature) { switch (rtFeature.GetRowSource()) { case RealtimeRowSource.EventInsert: Polygon searchGeom = rtFeature.GetShape() as Polygon; sf.FilterGeometry = searchGeom; countiesFLyr.Select(sf); continue; default: continue; } } } } }); }
private async void StreamLayerSubscribe() { if (_rtCursor?.GetState() == RealtimeCursorState.Subscribed) { _rtCursor.Unsubscribe(); return; } Map map = MapView.Active.Map; if (map == null) { return; } StreamLayer streamLayer = map.Layers[0] as StreamLayer; await QueuedTask.Run(async() => { var rtFC = streamLayer.GetFeatureClass(); _rtCursor = rtFC.Subscribe(null, true); while (await _rtCursor.WaitForRowsAsync()) { while (_rtCursor.MoveNext()) { using (var _rtFeature = _rtCursor.Current as RealtimeFeature) { switch (_rtFeature.GetRowSource()) { case RealtimeRowSource.EventInsert: var point = _rtFeature.GetShape() as MapPoint; Module1.Current.Long = point.X; Module1.Current.Lat = point.Y; var pane = FrameworkApplication.DockPaneManager.Find(BingSearchResultViewModel._dockPaneID) as BingSearchResultViewModel; pane?.DoSearch(); continue; default: continue; } } } } ; }); }
protected async override void OnClick() { #region initial setup if ((_rtfc != null) && (_rtfc.GetState() == RealtimeCursorState.Subscribed)) { _rtfc.Unsubscribe(); _featuresGeoFenced = null; return; } Map map = MapView.Active.Map; Polygon geofence = null; _featuresGeoFenced = new Dictionary <int, bool> { { 1, false }, { 2, false } }; #endregion #region getting geofence geometry FeatureLayer flyr = map.Layers[1] as FeatureLayer; await QueuedTask.Run(() => { RowCursor rc = flyr.Search(null); rc.MoveNext(); using (Feature f = rc.Current as Feature) { geofence = f.GetShape().Clone() as Polygon; } }); #endregion #region Setting geo-fencing using a spatial filter StreamLayer streamLayer = map.Layers[0] as StreamLayer; SpatialQueryFilter sf = new SpatialQueryFilter { SpatialRelationship = SpatialRelationship.Intersects, FilterGeometry = geofence }; await QueuedTask.Run(async() => { RealtimeFeatureClass rtfcls = streamLayer.GetFeatureClass(); //Subscribing with a spatial filter _rtfc = rtfcls.Subscribe(sf, true); while (await _rtfc.WaitForRowsAsync()) { while (_rtfc.MoveNext()) { using (var rtFeature = _rtfc.Current) { switch (rtFeature.GetRowSource()) { case RealtimeRowSource.EventInsert: RealtimeFeature rtfeat = rtFeature as RealtimeFeature; int featureID = (int)rtfeat["TrackID"]; if (!_featuresGeoFenced[featureID]) { _featuresGeoFenced[featureID] = true; ShowAlert(featureID.ToString()); } continue; default: continue; } } } } }); #endregion }
public async void Example8() { Map map = MapView.Active.Map; StreamLayer streamLayer = null; QueryFilter qfilter = null; //Don't change this name! harcoded in the Realtime feature class "///" #region Search Existing Data and Subscribe for Streaming Data //Note we can use System Task with the Realtime feature class //for subscribe await System.Threading.Tasks.Task.Run(async() => // or use ... QueuedTask.Run() { using (var rfc = streamLayer.GetFeatureClass()) { //non-recycling cursor - 2nd param "false" using (var rc = rfc.SearchAndSubscribe(qfilter, false)) { //waiting for new features to be streamed //default is no cancellation while (await rc.WaitForRowsAsync()) { //pre-existing rows will be retrieved that were searched while (rc.MoveNext()) { var row = rc.Current; var row_source = row.GetRowSource(); switch (row_source) { case RealtimeRowSource.EventDelete: //TODO - handle deletes break; case RealtimeRowSource.EventInsert: //TODO handle inserts break; case RealtimeRowSource.PreExisting: //TODO handle pre-existing rows break; } } } }//row cursor is disposed. row cursor is unsubscribed } }); #endregion #region Search And Subscribe With Cancellation await System.Threading.Tasks.Task.Run(async() => // or use ... QueuedTask.Run() { using (var rfc = streamLayer.GetFeatureClass()) { //Recycling cursor - 2nd param "true" using (var rc = rfc.SearchAndSubscribe(qfilter, true)) { //auto-cancel after 20 seconds var cancel = new CancellationTokenSource(new TimeSpan(0, 0, 20)); //catch TaskCanceledException try { while (await rc.WaitForRowsAsync(cancel.Token)) { //check for row events while (rc.MoveNext()) { //etc } } } catch (TaskCanceledException tce) { //Handle cancellation as needed } cancel.Dispose(); } } }); #endregion }
public async void SearchAndSubscribeToStreamData() { Map map = MapView.Active.Map; StreamLayer streamLayer = null; QueryFilter qfilter = null; #region Search And Subscribe for Streaming Data await QueuedTask.Run(async() => { //query filter can be null to search and retrieve all rows //true means recycling cursor using (var rc = streamLayer.SearchAndSubscribe(qfilter, true)) { //waiting for new features to be streamed //default is no cancellation while (await rc.WaitForRowsAsync()) { while (rc.MoveNext()) { //determine the origin of the row event switch (rc.Current.GetRowSource()) { case RealtimeRowSource.PreExisting: //pre-existing row at the time of subscribe continue; case RealtimeRowSource.EventInsert: //row was inserted after subscribe continue; case RealtimeRowSource.EventDelete: //row was deleted after subscribe continue; } } } }//row cursor is disposed. row cursor is unsubscribed //....or.... //Use the feature class instead of the layer using (var rfc = streamLayer.GetFeatureClass()) { //non-recycling cursor - 2nd param "false" using (var rc = rfc.SearchAndSubscribe(qfilter, false)) { //waiting for new features to be streamed //default is no cancellation while (await rc.WaitForRowsAsync()) { //etc } } } }); #endregion #region Search And Subscribe With Cancellation await QueuedTask.Run(async() => { //Recycling cursor - 2nd param "true" //or streamLayer.Subscribe(qfilter, true) to just subscribe using (var rc = streamLayer.SearchAndSubscribe(qfilter, true)) { //auto-cancel after 20 seconds var cancel = new CancellationTokenSource(new TimeSpan(0, 0, 20)); //catch TaskCanceledException try { while (await rc.WaitForRowsAsync(cancel.Token)) { //check for row events while (rc.MoveNext()) { //etc } } } catch (TaskCanceledException tce) { //Handle cancellation as needed } cancel.Dispose(); } }); #endregion }
public async void Example6() { Map map = MapView.Active.Map; await QueuedTask.Run(() => { StreamLayer streamLayer = null; //https://geoeventsample1.esri.com:6443/arcgis/rest/services/AirportTraffics/StreamServer #region Defining a unique value renderer definition var uvrDef = new UniqueValueRendererDefinition() { ValueFields = new string[] { "ACTYPE" }, SymbolTemplate = SymbolFactory.Instance.ConstructPointSymbol( ColorFactory.Instance.RedRGB, 10, SimpleMarkerStyle.Hexagon) .MakeSymbolReference(), ValuesLimit = 5 }; //Note: CreateRenderer can only create value classes based on //the current events it has received streamLayer.SetRenderer(streamLayer.CreateRenderer(uvrDef)); #endregion #region Setting a unique value renderer for latest observations //Define the classes by hand to avoid using CreateRenderer(...) CIMUniqueValueClass uvcB727 = new CIMUniqueValueClass() { Values = new CIMUniqueValue[] { new CIMUniqueValue() { FieldValues = new string[] { "B727" } } }, Visible = true, Label = "Boeing 727", Symbol = SymbolFactory.Instance.ConstructPointSymbol(CIMColor.CreateRGBColor(255, 0, 0), 8, SimpleMarkerStyle.Hexagon).MakeSymbolReference() }; CIMUniqueValueClass uvcD9 = new CIMUniqueValueClass() { Values = new CIMUniqueValue[] { new CIMUniqueValue() { FieldValues = new string[] { "DC9" } } }, Visible = true, Label = "DC 9", Symbol = SymbolFactory.Instance.ConstructPointSymbol(CIMColor.CreateRGBColor(0, 255, 0), 8, SimpleMarkerStyle.Hexagon).MakeSymbolReference() }; //Assign the classes to a group CIMUniqueValueGroup uvGrp = new CIMUniqueValueGroup() { Classes = new CIMUniqueValueClass[] { uvcB727, uvcD9 } }; //assign the group to the renderer var UVrndr = new CIMUniqueValueRenderer() { Fields = new string[] { "ACTYPE" }, Groups = new CIMUniqueValueGroup[] { uvGrp }, UseDefaultSymbol = true, DefaultLabel = "Others", DefaultSymbol = SymbolFactory.Instance.ConstructPointSymbol( CIMColor.CreateRGBColor(185, 185, 185), 8, SimpleMarkerStyle.Hexagon).MakeSymbolReference() }; //set the renderer. Depending on the current events recieved, the //layer may or may not have events for each of the specified //unique value classes streamLayer.SetRenderer(UVrndr); #endregion #region Setting a unique value renderer for previous observations //The layer must be track aware and spatial if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask! //Define unique value classes same as we do for current observations //or use "CreateRenderer(...)" to assign them automatically CIMUniqueValueClass uvcB727Prev = new CIMUniqueValueClass() { Values = new CIMUniqueValue[] { new CIMUniqueValue() { FieldValues = new string[] { "B727" } } }, Visible = true, Label = "Boeing 727", Symbol = SymbolFactory.Instance.ConstructPointSymbol( CIMColor.CreateRGBColor(255, 0, 0), 4, SimpleMarkerStyle.Hexagon) .MakeSymbolReference() }; CIMUniqueValueClass uvcD9Prev = new CIMUniqueValueClass() { Values = new CIMUniqueValue[] { new CIMUniqueValue() { FieldValues = new string[] { "DC9" } } }, Visible = true, Label = "DC 9", Symbol = SymbolFactory.Instance.ConstructPointSymbol( CIMColor.CreateRGBColor(0, 255, 0), 4, SimpleMarkerStyle.Hexagon) .MakeSymbolReference() }; CIMUniqueValueGroup uvGrpPrev = new CIMUniqueValueGroup() { Classes = new CIMUniqueValueClass[] { uvcB727Prev, uvcD9Prev } }; var UVrndrPrev = new CIMUniqueValueRenderer() { Fields = new string[] { "ACTYPE" }, Groups = new CIMUniqueValueGroup[] { uvGrpPrev }, UseDefaultSymbol = true, DefaultLabel = "Others", DefaultSymbol = SymbolFactory.Instance.ConstructPointSymbol( CIMColor.CreateRGBColor(185, 185, 185), 4, SimpleMarkerStyle.Hexagon) .MakeSymbolReference() }; #endregion #region Setting a simple renderer to draw track lines //The layer must be track aware and spatial if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask! //Note: only a simple renderer with solid line symbol is supported for track //line renderer var trackRenderer = new SimpleRendererDefinition() { SymbolTemplate = SymbolFactory.Instance.ConstructLineSymbol( ColorFactory.Instance.BlueRGB, 2, SimpleLineStyle.Solid) .MakeSymbolReference() }; streamLayer.SetRenderer( streamLayer.CreateRenderer(trackRenderer), FeatureRendererTarget.TrackLines); #endregion #region Check Previous Observation and Track Line Visibility //The layer must be track aware and spatial for these settings //to have an effect if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask if (!streamLayer.AreTrackLinesVisible) { streamLayer.SetTrackLinesVisibility(true); } if (!streamLayer.ArePreviousObservationsVisible) { streamLayer.SetPreviousObservationsVisibility(true); } #endregion #region Make Track Lines and Previous Observations Visible //The layer must be track aware and spatial for these settings //to have an effect if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask //Note: Setting PreviousObservationsCount larger than the //"SetExpirationMaxCount()" has no effect streamLayer.SetPreviousObservationsCount(6); if (!streamLayer.AreTrackLinesVisible) { streamLayer.SetTrackLinesVisibility(true); } if (!streamLayer.ArePreviousObservationsVisible) { streamLayer.SetPreviousObservationsVisibility(true); } #endregion #region Retrieve the current observation renderer //Must be on QueuedTask! var renderer = streamLayer.GetRenderer(); #endregion #region Retrieve the previous observation renderer //The layer must be track aware and spatial if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask! var prev_renderer = streamLayer.GetRenderer( FeatureRendererTarget.PreviousObservations); #endregion #region Retrieve the track lines renderer //The layer must be track aware and spatial if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask! var track_renderer = streamLayer.GetRenderer( FeatureRendererTarget.TrackLines); #endregion }); }
public async void Example5() { Map map = MapView.Active.Map; StreamLayer streamLayer = null; #region Find all Stream Layers that are Track Aware var trackAwareLayers = MapView.Active.Map.GetLayersAsFlattenedList() .OfType <StreamLayer>().Where(sl => sl.IsTrackAware)?.ToList(); #endregion #region Determine the Stream Layer type //spatial or non-spatial? if (streamLayer.TrackType == TrackType.AttributeOnly) { //this is a non-spatial stream layer } else { //this must be a spatial stream layer } #endregion #region Check the Stream Layer connection state if (!streamLayer.IsStreamingConnectionOpen) { //Must be on QueuedTask! streamLayer.StartStreaming(); } #endregion #region Start and stop streaming //Must be on QueuedTask! //Start... streamLayer.StartStreaming(); //Stop... streamLayer.StopStreaming(); #endregion #region Delete all current and previous observations //Must be on QueuedTask! //Must be called on the feature class using (var rfc = streamLayer.GetFeatureClass()) rfc.Truncate(); #endregion #region Get the Track Id Field if (streamLayer.IsTrackAware) { var trackField = streamLayer.TrackIdFieldName; //TODO use the field name } #endregion #region Get The Track Type var trackType = streamLayer.TrackType; switch (trackType) { //TODO deal with tracktype case TrackType.None: case TrackType.AttributeOnly: case TrackType.Spatial: break; } #endregion #region Set the Maximum Count of Previous Observations to be Stored in Memory //Must be on QueuedTask //Set Expiration Method and Max Expiration Count if (streamLayer.GetExpirationMethod() != FeatureExpirationMethod.MaximumFeatureCount) { streamLayer.SetExpirationMethod(FeatureExpirationMethod.MaximumFeatureCount); } streamLayer.SetExpirationMaxCount(15); //FYI if (streamLayer.IsTrackAware) { //MaxCount is per track! otherwise for the entire layer } #endregion #region Set the Maximum Age of Previous Observations to be Stored in Memory //Must be on QueuedTask //Set Expiration Method and Max Expiration Age if (streamLayer.GetExpirationMethod() != FeatureExpirationMethod.MaximumFeatureAge) { streamLayer.SetExpirationMethod(FeatureExpirationMethod.MaximumFeatureAge); } //set to 12 hours (max is 24 hours) streamLayer.SetExpirationMaxAge(new TimeSpan(12, 0, 0)); //FYI if (streamLayer.IsTrackAware) { //MaxAge is per track! otherwise for the entire layer } #endregion #region Set Various Stream Layer properties via the CIM //The layer must be track aware and spatial if (streamLayer.TrackType != TrackType.Spatial) { return; } //Must be on QueuedTask //get the CIM Definition var def = streamLayer.GetDefinition() as CIMFeatureLayer; //set the number of previous observations, def.PreviousObservationsCount = (int)streamLayer.GetExpirationMaxCount() - 1; //set show previous observations and track lines to true def.ShowPreviousObservations = true; def.ShowTracks = true; //commit the changes streamLayer.SetDefinition(def); #endregion await QueuedTask.Run(() => { }); }