This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
access:journal-file-proposal [2018/06/21 00:28] mjallison created |
access:journal-file-proposal [2018/06/26 22:22] (current) mjallison [Area Block (.area)] |
||
---|---|---|---|
Line 9: | Line 9: | ||
Field applications such as SmartDirt/SmartPlan/SmartGrade currently capture this information and save it the Access server by bundling them into KMZ files. There is much value to being able to access this data in the web server or other applications via the Access server API. The Access server will provide the capability to store and retrieve these items. | Field applications such as SmartDirt/SmartPlan/SmartGrade currently capture this information and save it the Access server by bundling them into KMZ files. There is much value to being able to access this data in the web server or other applications via the Access server API. The Access server will provide the capability to store and retrieve these items. | ||
+ | |||
+ | The intention to export these items to KMZ files requires that the original LLA coordinate information be retained. | ||
+ | It is not appropriate to convert these items into an arbitrary NEZ coordinate space. Note that this still might be done | ||
+ | be an application for display purposes, but it is not intended to do so within the file. | ||
The existing server provides native storage for Photos (via files), but does not for Notes/Tracks/Measures. The server database server is inappropriate to store large items such as tracks and measures. The current scaleabale storage mechanism available is the file system. This proposal describes how to extend ADF to enable storage for these new data types. | The existing server provides native storage for Photos (via files), but does not for Notes/Tracks/Measures. The server database server is inappropriate to store large items such as tracks and measures. The current scaleabale storage mechanism available is the file system. This proposal describes how to extend ADF to enable storage for these new data types. | ||
Line 15: | Line 19: | ||
In order to understand how the entire system will work, the server structure must be described. Journal items will either be extracted from KMZ files or stored piecemeal from field applications. The journal entries are maintained in an SQL table (per customer) which looks like: | In order to understand how the entire system will work, the server structure must be described. Journal items will either be extracted from KMZ files or stored piecemeal from field applications. The journal entries are maintained in an SQL table (per customer) which looks like: | ||
- | ^ Field ^ Type ^ Null ^ Key ^ Default ^ Extra ^ Description ^ | + | ^ Field ^ Type ^ Null ^ Key ^ Default ^ Extra ^ Description ^ |
- | | handle | int(16) | NO | PRI | NULL | auto_increment | Auto generated id | | + | | handle | int(16) | NO | PRI | NULL | auto_increment | Auto generated id | |
- | | time | bigint(20) unsigned | NO | | 0 | | Std milliSecond date | | + | | time | bigint(20) unsigned | NO | | 0 | | Std milliSecond date | |
- | | project | int(16) | NO | | -1 | | Handle of the referenced project | | + | | project | int(16) | NO | | -1 | | Handle of the referenced project | |
- | | user | int(16) | NO | | -1 | | Handle of creating user | | + | | user | int(16) | NO | | -1 | | Handle of creating user | |
- | | type | varchar(16) | NO | | unknown | | String value indicating entry type | | + | | codelist | int(16) | NO | | 0 | | Handle of the CodeList, 0 if not used | |
- | | file | int(16) | NO | | -1 | | Handle of StoredFile for object | | + | | code | int(16) | NO | | 0 | | Handle of CodeList item, 0 if not used | |
- | | object | text | YES | | NULL | | JSON Representation | | + | | type | varchar(16) | NO | | unknown | | String value indicating entry type | |
+ | | file | int(16) | NO | | -1 | | Handle of StoredFile for object | | ||
+ | | object | text | YES | | NULL | | JSON Representation | | ||
This table allows user queries against the journal to obtain views of the journal limited by type, user, date, etc. | This table allows user queries against the journal to obtain views of the journal limited by type, user, date, etc. | ||
Line 38: | Line 44: | ||
===== Entry Object JSON Schema ===== | ===== Entry Object JSON Schema ===== | ||
- | Each entry in the SQL table must be supplied with a corresponding JSON object. The generic JSON structure for all entries looks like: | + | Each entry in the SQL table must be supplied with a corresponding JSON object. |
+ | |||
+ | In addition to the SQL table attributes, each entry has the following attributes in common: | ||
+ | |||
+ | * Latitude | ||
+ | * Longitude | ||
+ | * Altitude | ||
+ | |||
+ | The JSON object for all entries will minimally look like: | ||
+ | |||
+ | { | ||
+ | "latitude": number, // LLA | ||
+ | "longitude": number, // LLA | ||
+ | "altitude": number, // LLA | ||
+ | "note": "string" // A comment about the entry. | ||
+ | } | ||
+ | |||
+ | The location contained within the entry's JSON is referred to as the //reference point//. This point will be | ||
+ | used by display applications when drawing a corresponding icon or glyph. | ||
+ | |||
+ | Photos, Tracks, and Areas all have their data stored within a corresponding ADF file (see section on ADF format). | ||
+ | Textual notes do not have an ADF storage, the text of the note is stored as "note". | ||
+ | |||
+ | |||
+ | |||
+ | ====== ADF Structure ====== | ||
+ | The ADF structure will support all of the currently defined Journal entry types. It should be noted that the | ||
+ | the Photo Note entry type will not create ADF files in the server. The definition exists to support an ADF journal export use case. | ||
+ | |||
+ | All Journal entry's are stored under first //Construction Model// of the ADF. If a brand new ADF is bring created the //Construction Model// is the same name as the enclosing project. | ||
+ | |||
+ | The path to the Journal entry's are as follows: | ||
+ | |||
+ | /CM/JournalData/Photos/ | ||
+ | /CM/JournalData/Areas/ | ||
+ | /CM/JournalData/Note/ | ||
+ | /CM/JournalData/Tracks/ | ||
+ | |||
+ | Each section has a JSON descriptor, with corresponding data files. For instance, Photos, might look like: | ||
+ | |||
+ | /CM/JournalData/Photos/photos.json | ||
+ | /CM/JournalData/Photos/Photo1.jpg | ||
+ | /CM/JournalData/Photos/Photo2.jpg | ||
+ | |||
+ | Because notes can be entirely contained in the JSON, the notes structure looks like: | ||
+ | |||
+ | /CM/JournalData/Photos/notes.json | ||
+ | |||
+ | Tracks will look like | ||
+ | |||
+ | /CM/JournalData/UserTracks/usertracks.json | ||
+ | /CM/JournalData/UserTracks/track1.track | ||
+ | /CM/JournalData/UserTracks/tracl2.track | ||
+ | |||
+ | Areas will look like | ||
+ | |||
+ | /CM/JournalData/Areas/areas.json | ||
+ | /CM/JournalData/Areas/Measure1.area | ||
+ | /CM/JournalData/Areas/Measure2.area | ||
+ | |||
+ | While the structure is defined to support multiple data instances, the server may only create single ADF file per entry. | ||
+ | |||
+ | ===== ADF JSON ===== | ||
+ | Each entry type has a json descriptor which describes the rest of the data. Examples of the JSON for each type are: | ||
+ | |||
+ | photos.jpg: | ||
+ | { "photos" : [ | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com" /* Access user ID string */ | ||
+ | "comment": "text", | ||
+ | "file": "Photo1.jpg" | ||
+ | }, | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "text", | ||
+ | "file": "Photo2.jpg" | ||
+ | } | ||
+ | ] } | ||
+ | |||
+ | Notes: | ||
+ | { "notes" : [ | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "Text of note 1" | ||
+ | }, | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "Text of note 2" | ||
+ | } | ||
+ | ] } | ||
+ | |||
+ | Tracks: | ||
+ | { "notes" : [ | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "comment", | ||
+ | "file": "Track1.trk" | ||
+ | }, | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "COmment about track 2" | ||
+ | "file": "Track2.trk" | ||
+ | } | ||
+ | ] } | ||
+ | |||
+ | Areas: | ||
+ | Tracks: | ||
+ | { "notes" : [ | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "An area", | ||
+ | "file": "Area1.trk" | ||
+ | }, | ||
+ | { "latitude": nnn.nn, | ||
+ | "longitude": mmm.mmm, | ||
+ | "altitude": aaa.aa, | ||
+ | "time": tttttttttttt, /* Std mSec time */ | ||
+ | "customer": "custid", /* Access customer ID string */ | ||
+ | "user": "user@example.com", /* Access user ID string */ | ||
+ | "comment": "Measure 2 name" | ||
+ | "file": "Measure2.trk" | ||
+ | } | ||
+ | ] } | ||
+ | |||
+ | ===== ADF Block Types ===== | ||
+ | Photos and Notes have defined data storage types, but Tracks and Areas do not. This section details two new binary | ||
+ | ADF block types. | ||
+ | |||
+ | ===== User Track Block (.track) ===== | ||
+ | The Track block is a zipfile entry, which is a series of track points. A track is defined to have a | ||
+ | starting point (the very first point) and an end point (the very last point). | ||
+ | |||
+ | Block Header: | ||
+ | * Block Code 2001 : Int32 | ||
+ | * Block Size : Int32 = 40 for this definition | ||
+ | * Number of points : Int32 | ||
+ | |||
+ | The series of points are as follows: | ||
+ | * latitude - Double 64 (degrees) | ||
+ | * longitude - Double 64 (degrees) | ||
+ | * altitude - Double 64 (meters above MSL) | ||
+ | * time - Int64 (std mSec time) | ||
+ | * compass - Double 64 (0..359.9999) | ||
+ | |||
+ | ===== Area Block (.area) ===== | ||
+ | The Area block is a zipfile entry, which is a series of points. A area is defined to be a closed | ||
+ | region, e.g. the last point connects to the first point. There is no duplicated points to "close" | ||
+ | the area, and it is expected that applications perform whatever operations needed to represent it | ||
+ | as such. It is considered an error to close an area by duplicating a point for the first and last | ||
+ | in this block. | ||
+ | Block Header: | ||
+ | * Block Code 2002 : Int32 | ||
+ | * Block Size : Int32 = 24 bytes for this definition | ||
+ | * Number of points : Int32 | ||
+ | * | ||
+ | The series of points are as follows: | ||
+ | * latitude - Double 64 (degrees) | ||
+ | * longitude - Double 64 (degrees) | ||
+ | * altitude - Double 64 (meters above MSL) | ||