1.9.8 • Published 20 days ago

isoxml v1.9.8

Weekly downloads
-
License
Apache-2.0
Repository
-
Last release
20 days ago

Introduction

ISOXML.js is a JavaScript library to parse and generate ISOXML (ISO11783-10) files.

The main features:

  • Supports all entities from the ISOXML v4.3 (ISO11783-10:2015) including proprietart attributes and elements
  • Works in both browsers and NodeJS
  • Can handle ISOXML of both versions 4 and 3 (including transformation between versions)
  • ISOXML Grids can be generated from GeoJSON polygons
  • Uses LINKLIST file to keep FMIS identificators (only in v4)
  • Field and TreatmentZones geometry can be provided as GeoJSON
  • Includes TypeScript types
  • ISOXML files validation (WiP)

Installation

Just run

npm install isoxml

or

yarn add isoxml

Usage Examples

Parse ISOXML (Node.js environments):

import { readFileSync } from 'fs'
import { join } from 'path'
import { ISOXMLManager, Partfield } from 'isoxml'

// read a zipped ISOXML
const isoxmlData = readFileSync(join(__dirname, '../data/task_with_warnings.zip'))

// create new ISOXMLManager instance with default parameters
const isoxmlManager = new ISOXMLManager()

// parse the file
isoxmlManager.parseISOXMLFile(new Uint8Array(isoxmlData.buffer), 'application/zip').then(() => {

    // getWarnings() method returns all the warnings from the last parsing
    console.log(isoxmlManager.getWarnings())

    // all global attributes of the parsed file
    console.log(isoxmlManager.options)

    // get all the Partfileds
    const partfields: Partfield[] = isoxmlManager.rootElement.attributes.Partfield || []

    // print designators of all the Partfields
    partfields.forEach(partfield => {
        console.log(`${partfield.attributes.PartfieldDesignator}`)
    })
})

Create manually and save ISOXML (Node.js environment):

import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'
import { ISOXMLManager, TAGS, TaskTaskStatusEnum, ExtendedTask } from 'isoxml'

const isoxmlManager = new ISOXMLManager()

// create an instance of Task entity
const task = isoxmlManager.createEntityFromAttributes(TAGS.Task, {
    TaskStatus: TaskTaskStatusEnum.Planned
}) as ExtendedTask

const geoJSONdata = JSON.parse(readFileSync(join(__dirname, '../data/test.geojson'), 'utf-8'))

// add Grid to the task from GeoJSON. "1" is DDI
task.addGridFromGeoJSON(geoJSONdata, 1)

// assign a local ID to the task ("TSK1" in our case)
isoxmlManager.registerEntity(task)

// add the task to the root element
isoxmlManager.rootElement.attributes.Task = [task]

// save ISOXML as a zip file
isoxmlManager.saveISOXML().then((data: Uint8Array) => {
    writeFileSync('./isoxml.zip', data)
})

You can find these examples in the examples folder. Note, that you must build the library before running them locally. For example:

npm run build
ts-node examples/parse.ts

Classes Overview

ISOMXLManager

ISOMXLManager is the main class. It handles all the operations with ISOXML files.

Constructor

new ISOXMLManager(options)

Options are:

rootFolder?: string   // the folder with TASKDATA.XML file. Default: "TASKDATA"
fmisTitle?: string    // FMIS title. Default: "FMIS"
fmisURI?: string      // FMIS URL. Used in LINKLIST.XML file to store matching with FMIS IDs
fmisVersion?: string  // FMIS version. Default: "1.0"
version?: number      // Version of ISOXML file. Only values "3" and "4" are supported. Default: "4"

If you want to save matchings between FMIS IDs and ISOXML IDs, you must set fmisURI option before parsing any ISOXML files. All the rest parameters will be overwritten during ISOXML parsing.

Parse ISOXML file

parseISOXMLFile(data: Uint8Array|string, dataType: string): Promise<void> 

This method parses the ISOXML file and saves all the parsed information in the ISOXMLManager "dataType" can be either "text/xml" (standalone TASKDATA.XML file) or "application/zip" (zipped folder). Notes:

  • ISOXMLManager's options will be updated
  • All the entities added the ISOXMLManager before calling this method will be removed
  • You can check parsing errors and warnings using "getWarnings(): string[]" method

Save ISOXML file

saveISOXML(): Promise<Uint8Array>

All the entities will be saved as a ZIP archive.

Modify ISOXML Entities Manually

There are two types of Entities in the ISO11783-10 standard: the entities with ID and entities without ID. IDs must be unique inside the ISOXML file. IDs are not part of Entity instances. Instead, they are stored separately in ISOXMLManager and accessable as xmlReferences public property.

You can create new Entity using the following method

createEntityFromAttributes(tagName: TAGS, attrs: EntityAttributes): Entity

Note, that you can't provide ID in this method. To assign an ID, you need to "register" the entity using the following method:

registerEntity(entity?: Entity, xmlId?: string, fmisId?: string): ISOXMLReference

If you provide only entity, ISOXMLManager will generate a unique ID for it and internally saves it. Instead, you can explicitly set xmlId. Also, you always can add fmisId for an entity - it will be saved in "LINKLIST.XML" file for future utilization by FMIS.

To add en entity to the ISOXML file, use the rootElement: ExtendedISO11783TaskDataFile public property of the ISOXMLManager. For example:

isoxmlManager.rootElement.attributes.Task = [task]

You can modify entities in the same way.

Internal Structure

The base classes and types are generated from XSD files. The generation script is stored in the /generation folder. To run the generation, call the command npm run gen. The output of generation is class defenitions and types stored in the /src/baseEntities folder (note that the folder will be reset during generation). The generated files are part of the project.

The original XSDs are taken from https://www.isobus.net/isobus/file/supportingDocuments

All NPM Commands

  • npm run gen - generate base classes and put them in /src/baseEntities folder
  • npm run build - generate JS files in /dist folder
  • npm run test - run tests (based on Jest)
  • npm run coverage - show test coverage report

Outliers Removal Algorithm

ExtendedTimeLog class includes an algorithm to detect outliers in the data. Use method rangesWithoutOutliers() to calculate the range of values without outliers:

  const timelog = task.attributes.TimeLog[0]

  // one range per DLV. Order corresponds to order of DLVs
  const newRanges: {min: number, max: number}[] = timelog.rangesWithoutOutliers()

The outliers a modified and a more conservative version of the Boxplot algorithm. It doesn't work well in all the cases, but sometimes it can be useful. Here is a more detailed algorithm description: 1. Calculate all unique timelog values 2. If number of unique values < 8, return original range 2. Sort unique values in ascending order 3. Calculate q1 = valuesvalues.length / 4 and q3 = valuesvalues.length * 3 / 4 4. Calculate upper and lower boundaries: upperBoundary = q3 + 2.5 (q3 - q1), lowerBoundary = q1 - 2.5 (q3 - q1) 5. Return as new range min and max values inside lowerBoundary, upperBoundary

1.9.8

20 days ago

1.9.7

5 months ago

1.9.6

6 months ago

1.9.5

6 months ago

1.9.4

7 months ago

1.9.3

8 months ago

1.9.2

8 months ago

1.9.1

1 year ago

1.9.0

1 year ago

1.8.2

1 year ago

1.8.1

1 year ago

1.7.2

1 year ago

1.6.3

1 year ago

1.8.0

1 year ago

1.7.1

1 year ago

1.6.2

2 years ago

1.7.0

1 year ago

1.6.1

2 years ago

1.6.0

2 years ago

1.5.0

2 years ago

1.4.0

2 years ago

1.3.0

3 years ago

1.2.3

3 years ago

1.2.2

3 years ago

1.2.1

3 years ago

1.2.0

3 years ago

1.1.0

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago