HowTo only update feature if Date is after existing date

1719
2
12-21-2016 08:55 AM
MaartenTromp
Esri Contributor

I have an input connector looking at new XML-files in a shared folder. Everything works fine if the order in which the new XML files arrive in the folder is correct.

The XML file contains the parameters ID (INT), value (String) and ChangeDate (Date). In the output connector I update features in a featureservice. Depending on connectivity of the fieldworkers the latest XML-file does not necessarily have the latest Value of the asset.

Is there a way to make sure the Value field is only updated when the ChangeDate of the incoming event is after the existing ChangeDate of the existing feature? 

I tried using the tags TIME_START and TIME_END on the ChangedDate Filed in the geoeventdefinitions of input- and output-connectors, but that did not force the required behavior.

A solution might be to join the incoming event with existing features and compare the Date in the event with the existing date. Any suggestions?

Thank for your help!

Regards, Maarten Tromp

0 Kudos
2 Replies
MarkBramer
Occasional Contributor II

Maarten Tromp‌, You are on the right path with your idea.  I have what I think you're looking for.  

Here is a sample geoevent in XML:

<root>
  <GE_ID>1</GE_ID>
  <GE_X>-92.47439554</GE_X>
  <GE_Y>35.08497411</GE_Y>
  <GE_ORDER>first</GE_ORDER>
  <GE_DATE>12/29/16 15:26:00</GE_DATE>
</root>

The 'GE_' prefix is to help identify the fields that came from the raw event.  You'll see how this comes in handy in a moment.  

 

Here's a screen shot of my feature class I'm serving out via a feature service:

feature class for geoevent service to output only latest date

My GeoEvent Service only emits a new feature if the geoevent's date is after the date that was in the database for that particular track.

Here's a screen shot of the GeoEvent Service:

geoevent service for only outputting latest date

Let's break it down:

The green input is a surrogate for what you have.  It's a " Receive XML on a REST Endpoint" instance, set up like so:

receive xml on a rest endpoint input

I use Chrome Poster to submit a geoevent to the REST endpoint of the input.  For each geoevent I want to send, I update the value for GE_DATE in the xml, and optionally the X and/or Y if I want to see the point move on a map (if it happens to be a geoevent that's "after" the last one).  Each new geoevent I submit this way is a surrogate for a new XML file in your case.

The first processor is a Field Enricher called "get existing date".  It retrieves the date of the latest feature in the database:

 field enricher to get the date of the latest feature in the database

The properties are presented rather randomly, so I'll explain each one in a logical order:

1. This field enricher is going to connect to the local ArcGIS Server ("ArcGIS Server Connection: Default"), and

2. look for a feature service called "latest_feature".  

3. It will look for the first layer in that feature service ("Layer: 0").

4. It will attempt to fetch the date value ("Enrichment Fields: THE_DATE") from that layer for the feature whose "TRACKID" value matches the geoevent's "GE_ID" value.

5. After the date is fetched from the database, its value will be appended to the geoevent in a new field ("Target Fields: New Fields").

6. Because appending this value alters the GeoEvent Definition (e.g. schema), the field enricher will emit a geoevent with a new GeoEvent Definition ("New GeoEvent Definition Name: SDE_DBO_latest_feature-with-last-date"

The next processor is simpler, and it's job is to cast the geoevent's date value from a Date data type to a Long data type.  This is required in order to do simple "date math".  There are no "isAfter" or "isBefore" type operations in GeoEvent so instead we just do some simple math on dates as numbers. That calculation doesn't happen in this step, but rather this step is simply to prepare the geoevent's date for that operation. This processor is called "ge date as long" and looks like:

Field Calculator for casting an incoming date value to long format

It simply uses the value in GE_DATE and places it into a new field called "GE_DATE-as-long".  Because this new field is of data type Long, this casts the date from its original Date data type to a Long data type.  Just like how the field enricher modified the GeoEvent definition (e.g. schema), this Field Calculator modifies the schema again.  Because of this, we must specify the name of the new GeoEvent Definition that will be emitted.  That GeoEvent Definition's name is "xml-enriched-with-date-as-long".  

The next processor is exactly the same in purpose, but for the date that came from the feature service layer:

Field Calculator for casting a date to long format

The next component is a filter.  This is what filters out any geoevents whose date is not after the date of the last one written to the feature class.  It looks like this:

filter out any geoevents whose date is less than (before) another date

or in the actual editing UI, it looks like this:

filter out any geoevents whose date is less than (before) another date

Finally, for any geoevents that do meet the filter's criteria, the geoevent's GeoEvent Definition must be mapped to the GeoEvent Definition of the feature service using a Field Mapper processor.  In my case, it looks like this:

field mapper for mapping a geoevent

or in the editing UI, it looks like this:

field mapper for mapping a geoevent

So with that GeoEvent Service published, any geoevent I send will overwrite the last-written one ONLY if its date is after that last-written one.  I can verify this simply by looking at the data in the feature class, but I can also see this in a map shown as a moving dot.  But in order to see the dot move, I have to update the X and/or Y in addition to the newer date value.  

Note: I do not know how this particular configuration will work on the very first geovent that's sent.  If you already have a feature service with features, you should be ok.  If you have a blank one, you may want to temporarily unhook the filter from the process flow of the GE Service, write one feature, then re-hook up the filter.  Or you could manually add a feature.  Otherwise, I'm not sure how a null date will be returned/handled by the Field Enricher when there isn't a record retrieved.  You could also incorporate a filter clause looking for null or NOT null to catch for the case.

Hope this helps.

Mark

MaartenTromp
Esri Contributor

Hi Mark,

thank you very much for the excellent example, this helps a lot!!

Regards, Maarten

0 Kudos