BrokJSON

The space saving GeoJSON alternative

Specification

Every BrokJSON MUST BE a valid JSON object. BrokJSON uses the same way to store geographical information as GeoJSON. Therefore this specification will not describe Geometry Objects. See the GeoJSON Specification. A BrokJSON-Converter is not interested in knowing the Geometry Object Type (Point, Polygone, etc.). It will just take Objects from GeoJSON and convert it to BrokJSON.

The structure

A BrokJSON follows this structure whereas properties and foreignMembers are optional:

{
    "properties": [],
    "foreignMembers": [],
    "geometries": []
  }

properties (Array, optional)

Contains all property keys from each GeoJSON-Feature properties.

Example
This GeoJSON-Feature...

"features": [
    {
      "type": "Feature",
      "properties": {
        "prop1": 1,
        "prop2": 2
      },
      "geometry": {/* ... */}
    }

... leads to this BrokJSON-property-Array:

["prop1", "prop2"]

foreignMembers (Array, optional)

Contains all member keys found on all feature root node except type, properties and geometry. Can be used to store bbox, id or not defined members.

Example:
In GeoJSON, non-geometry-data should be stored under property. But sometimes, there will be information stored directly in the feature-Object. The keys of this custom members will be stored in foreignMembers. Look at this GeoJSON-Feature:

{
    "type": "Feature",
    "properties": { /* ... */},
    "id": 4,
    "title": "The Univers",
    "geometry": { /* ... */ }
  }

It contains id and title. Both are not official GeoJSON-Members. The BrokJSON-foreignMember-Array will look like this:

["id", "title"]

geometries (Array)

geometries contains an array of GeometryGroup.

GeometryGroup

Each GeometryGroup contains geometries of the same type (Points, Polygones, etc.). There can by more than one GeometryGroup with the same type! A GeometryGroup has two members, type and features, both required.

type: The type of the following geometries. The type must not be a valid GeoJSON-Type, BrokJSON copies every type.
features: Contains multiple BrokJSON-features. These features contains data like the geometries or the property-data.

Example:
The following GeoJSON contains two points. BrokJSON will create one GeometryGroup, because both geometries have the same type.

{
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "geometry": {
          "type": "Point",
          "coordinates": [8.5402,47.3782]
        }
      },
      {
        "type": "Feature",
        "geometry": {
          "type": "Point",
          "coordinates": [8.5637,47.4504]
        }
      }
    ]
  }
And the corresponding BrokJSON:
{
    "geometries": [
      {"type": "Point", "features": [ // GeometryGroup
        [[8.5402, 47.3782]], // Feature 1
        [[8.5637, 47.4504]] // Feature 2
      ]}
    ]
  }
Be aware: The order of features must be preserved! It MAY BE necessary to create multiple GeometryGroups of the same type. This GeoJSON-Example contains two Points and one MultiPoint. But the Points are not direct neighbors, they are interrupted by a MultiPoint-Feature.

    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [8.5402,47.3782]
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPoint",
                "coordinates": [[8.5637,47.4504]]
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [8.5637,47.4504]
            }
        }
    ]
  }
The corresponding BrokJSON will therefore have three GeometryGroups.
{
    "geometries": [
      {"type": "Point", "features": [[[8.5402, 47.3782]]]},
      {"type": "MultiPoint", "features": [[[[8.5637, 47.4504]]]]},
      {"type": "Point", "features": [[[8.5637, 47.4504]]]}
    ]
  }

BrokJSON-Feature

A BrokJSON-Feature is an array with three possible entries:

Index 0:
The coordinates of the GeoJSON-Feature as defined by GeoJSON

Index 1 (optional):
The values of the properties as an array. They MUST BE stored in the same order as the corresponding keys in the properties-Array at the beginning of a BrokJSON. It MAY NOT have the same length as the properties-Array. Does a GeoJSON-Feature not contains a key from BrokJSON-features, it will not be added to the array. Contains the GeoJSON-Feature keys later in the BrokJSON-features-Array, there will be added null-values. Converting a BrokJSON to GeoJSON, null-values will be skiped.

Index 2 (optional):
Contains all other members of a feature like bbox or custom properties as an array. They MUST BE stored in the same order as the corresponding keys in the foreignMembers-Array at the beginning of the BrokJSON. It MAY NOT have the same length as the properties-Array.

Example:
Have a look at this GeoJSON-Feature. It contains foreignMembers ("name") and two properties ("id" and "title").

{
    "type": "Feature",
    "name": "Georg",
    "properties": {
      "id": 1,
      "title": "Hello world"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [8.5402,47.3782]
    }
  }
The corresponding BrokJSON-feature looks like this:
[
    [8.5402, 47.3782], // Index 0: The coordinates
    [1,"Hello world"], // Index 1: The values of the properties, corresponding to the keys in "properties"
    ["Georg"] // Index 2: The values of all unknown members, corresponding to the keys in "foreignMembers"
  ]

GeometryCollections

GeoJSONs GeometryCollections are a bit special. In BrokJSON, a GeometryGroup with the type GeometryCollection will contain again GeometryGroups as features.

Example
Have a look at this BrokJSON. It contains a GeometryCollection. The GeometryCollection contains two GeometryGroups, Point and LineString.

{
    "props": [],
    "geometries": [
      {
        "type": "GeometryCollection",
        "features": [{
          "type": "Point",
          "features": [
            [[100, 0.0]]
          ]
        },
        {
          "type": "LineString",
          "features": [
            [[101.0, 0.0],[102.0, 1.0]]
          ]
        }]
    }]
  }

Unknown Properties

BrokJSON will adopt every unknown property on the root node. The following GeoJSON contains an unspecified member called myCustomProperty.
{
    "type": "FeatureCollection",
    "myCustomProperty": "I love frogs!",
    "features": []
  }
This custom property will be stored the same way in a BrokJSON:
{
    "myCustomProperty": "I love frogs!",
    "geometries": []
  }

featureCollection

A GeoJSON with more than one feature contains the member `featureCollection`. This keyword will not be transfered to BrokJSON, because every BrokJSON IS a featureCollection.