npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

isoxml-angular

v1.9.5

Published

JavaScript library to parse and generate ISOXML (ISO11783-10) files

Downloads

156

Readme

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
  3. Sort unique values in ascending order
  4. Calculate q1 = values[values.length / 4] and q3 = values[values.length * 3 / 4]
  5. Calculate upper and lower boundaries: upperBoundary = q3 + 2.5 * (q3 - q1), lowerBoundary = q1 - 2.5 * (q3 - q1)
  6. Return as new range min and max values inside [lowerBoundary, upperBoundary]