$30 off During Our Annual Pro Sale. View Details »

CityJSON: (some of the) engineering decisions taken

Hugo Ledoux
September 13, 2017

CityJSON: (some of the) engineering decisions taken

Invited talk at the OGC meeting on IndoorGML (Southampton, UK)

Hugo Ledoux

September 13, 2017
Tweet

More Decks by Hugo Ledoux

Other Decks in Research

Transcript

  1. Hugo Ledoux OGC IndoorGML meeting 2017-09-13 (some of the) engineering

    decisions taken when developing a JSON encoding for CityGML
  2. 2

  3. CityGML as a data model is ! Its GML encoding

    is
  4. None
  5. CityJSON v0.2 is out 5

  6. JSON 6 • JavaScript Object Notation • Lightweight data-interchange format.

    • It is easy for humans to read and write. • It is text-based • It is easy for machines to parse and generate.
  7. But virtually all languages have support for it 7 It

    is built on two (very common) data structures: 1. collection of name-value pairs • Python dictionaries • hashes • C++ std::map 2. arrays
  8. I did it by hand… a few observations 8 1.

    no automatic conversion: that would have yielded the same complexity 2. flattened the schema as much as possible 3. chose City Objects (Buildings, Vegetations, LandUse, etc) and omitted all abstract classes and others 4. chose a geometric model with vertices and references to these (à la OBJ, OFF, etc.) 5. chose to simplify things, eg: • one texture max per surface • no raster DTM • all primitives in the same CRS
  9. CityGML Core module, part 1 Copyright © 2012 Open Geospatial

    Consortium, Inc. All Rights Reserved. 7 +creationDate : xs::date [0..1] +terminationDate : xs::date [0..1] +relativeToTerrain : RelativeToTerrainType [0..1] +relativeToWater : RelativeToWaterType [0..1] <<Feature>> _CityObject +informationSystem : xs::anyURI [0..1] <<DataType>> ExternalReference <<Feature>> CityModel +name : gml::CodeType [0..*] <<Feature>> gml::_Feature +name : xs::string [1] +uri : xs::anyURI [1] <<Union>> ExternalObjectReference <<Feature>> gml::_FeatureCollection <<Feature>> Address <<DataType>> xAL::AddressDetails <<Geometry>> gml::MultiPoint +mimeType : gml::CodeType +transformationMatrix : TransformationMatrix4x4Type +libraryObject : xs::anyURI <<Object>> ImplicitGeometry <<Geometry>> gml::_Geometry <<Geometry>> gml::Point +name : xs::string[1] +codeSpace : xs::anyURI[0..1] <<DataType>> gml::CodeType +entirelyAboveTerrain +substantiallyAboveTerrain +substantiallyAboveAndBelowTerrain +substantiallyBelowTerrain +entirelyBelowTerrain <<Enumeration>> RelativeToTerrainType +entirelyAboveWaterSurface +substantiallyAboveWaterSurface +substantiallyAboveAndBelowWaterSurface +substantiallyBelowWaterSurface +entirelyBelowWaterSurface +temporarilyAboveAndBelowWaterSurface <<Enumeration>> RelativeToWaterType +gml::doubleList [16] <<PrimitiveType>> TransformationMatrix4x4Type * * cityObjectMember 1 * 0..1 * * 1 externalReference 0..1 * 1 1 externalObject 1 1 * * generalizesTo referencePoint relativeGMLGeometry xalAddress multiPoint Visual Paradigm for UML Standard Edition(Technical University Berlin)
  10. CityGML geometry model, part 1 Copyright © 2012 Open Geospatial

    Consortium, Inc. All Rights Reserved. 5 <<Geometry>> gml::_GeometricPrimitive <<Geometry>> gml::_Solid <<Geometry>> gml::_Surface <<Geometry>> gml::_Curve +position : gml::DirectPosition [1] <<Geometry>> gml::Point <<Geometry>> gml::CompositeSolid <<Geometry>> gml::Solid <<Geometry>> gml::CompositeSurface <<Geometry>> gml::TriangulatedSurface <<Geometry>> gml::Triangle +stopLines : gml::LineStringSegment [0..*] +breakLines : gml::LineStringSegment [0..*] +maxLength : gml::LengthType [1] +controlPoint : gml::posList [1] <<Geometry>> gml::TIN <<Geometry>> gml::Polygon +orientation : gml::SignType [0..1] <<Geometry>> gml::OrientableSurface <<Geometry>> gml::CompositeCurve +position : gml::DirectPosition [2..*] <<Geometry>> gml::LineString <<Geometry>> gml::_Ring +position : gml::DirectPosition [4..*] <<Geometry>> gml::LinearRing <<Geometry>> gml::Surface <<Geometry>> gml::_SurfacePatch <<Geometry>> gml::_Geometry <<Geometry>> gml::Rectangle 0..* 0..1 interior * * 1..* * solidMember 1 * * 1 trianglePatches 0..2 1 baseSurface 1 * 1..* * curveMember 1 0..1 exterior 1..* 1 patches 1 * exterior 1..* * surfaceMember interior exterior exterior Visual Paradigm for UML Standard Edition(Technical University Berlin)
  11. +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage :

    gml::CodeType [0..*] +yearOfConstruction : xs::gYear [0..1] +yearOfDemolition : xs::gYear [0..1] +roofType : gml:CodeType [0..1] +measuredHeight : gml::LengthType [0..1] +storeysAboveGround : xs::nonNegativeInteger [0..1] +storeysBelowGround : xs::nonNegativeInteger [0..1] +storeyHeightsAboveGround : gml::MeasureOrNullListType [0..1] +storeyHeightsBelowGround : gml::MeasureOrNullListType [0..1] <<Feature>> _AbstractBuilding <<Feature>> _BoundarySurface <<Feature>> CeilingSurface <<Feature>> InteriorWallSurface <<Feature>> FloorSurface <<Feature>> RoofSurface <<Feature>> WallSurfacee <<Feature>> ClosureSurface +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <<Feature>> BuildingInstallation +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <<Feature>> IntBuildingInstallation +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <<Feature>> Room +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <<Feature>> BuildingFurniture <<Feature>> _Opening <<Feature>> Window <<Feature>> Door <<Feature>> Building <<Feature>> BuildingPart <<Feature>> core::_CityObject <<Geometry>> gml::MultiCurve <<Geometry>> gml::MultiSurface <<Feature>> core::_Site <<Geometry>> gml::_Solid <<Geometry>> gml::_Geometry <<Object>> core::ImplicitGeometry <<Feature>> GroundSurface <<Feature>> OuterCeilingSurface <<Feature>> OuterFloorSurface <<Feature>> core::Address * lod4MultiSurface * lod3MultiSurface * * boundedBy * 0..1 * 0..1 * * lod4TerrainIntersection * * lod3MultiSurface * lod2MultiSurface * lod4MultiSurface * lod4MultiCurve * 0..1 interiorFurniture * * address 0..1 * 0..1 * lod3MultiSurface * * interiorRoom 0..1 * lod2MultiSurface * lod4MultiSurface * lod4Geometry * * boundedBy * * outerBuildingInstallation * lod3MultiCurve * 0..1 * lod3ImplicitRepresentation 0..1 * lod4Geometry * * lod4ImplicitRepresentation 0..1 * 0..1 * lod0FootPrint * 0..1 boundedBy 0..1 * lod2MultiCurve * lod0RoofEdge * lod3TerrainIntersection * 0..2 opening 0..1 * lod1MultiSurface * * boundedBy * 0..1 roomInstallation 0..1 * lod4MultiSurface 0..1 * * lod3Geometry * * consistsOfBuildingPart * * interiorBuildingInstallation 0..1 * lod4Geometry * * * address 0..1 * lod1TerrainIntersection 0..1 * lod2Geometry * lod2TerrainIntersection lod4ImplicitRepresentation lod3ImplicitRepresentation lod2ImplicitRepresentation lod4ImplicitRepresentation lod4ImplicitRepresentation lod4Solid lod4Solid lod1Solid lod2Solid lod3Solid
  12. A CityJSON file 12 { "type": "CityModel", "version": "http://www.cityjson.org/version/0.2", "metadata":

    { "crs": { "epsg": 7415 } }, "CityObjects": { "id-1": { "type": "Building", "attributes": { "measuredHeight": 22.3, "roofType": "gable", "owner": "Elvis Presley" }, "geometry": [ { "type": "MultiSurface", "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] } ] } }, "vertices": [ [23.1, 2321.2, 11.0], [111.1, 321.1, 12.0], ... ], "appearance": { "materials": [], "textures":[], "vertices-texture": [] } }
  13. A CityJSON file 13 { "type": "CityModel", "version": "http://www.cityjson.org/version/0.2", "metadata":

    { "crs": { "epsg": 7415 } }, "CityObjects": { "id-1": { "type": "Building", "attributes": { "measuredHeight": 22.3, "roofType": "gable", "owner": "Elvis Presley" }, "geometry": [ { "type": "MultiSurface", "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] } ] } }, "vertices": [ [23.1, 2321.2, 11.0], [111.1, 321.1, 12.0], ... ], "appearance": { "materials": [], "textures":[], "vertices-texture": [] } } version CityJSON
  14. A CityJSON file 14 { "type": "CityModel", "version": "http://www.cityjson.org/version/0.2", "metadata":

    { "crs": { "epsg": 7415 } }, "CityObjects": { "id-1": { "type": "Building", "attributes": { "measuredHeight": 22.3, "roofType": "gable", "owner": "Elvis Presley" }, "geometry": [ { "type": "MultiSurface", "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] } ] } }, "vertices": [ [23.1, 2321.2, 11.0], [111.1, 321.1, 12.0], ... ], "appearance": { "materials": [], "textures":[], "vertices-texture": [] } } metadata, ISO19115 “compliant” CityGML has no mechanism, but I felt this is needed ALL geometries have the same CRS, unlike (City)GML
  15. A CityJSON file 15 { "type": "CityModel", "version": "http://www.cityjson.org/version/0.2", "metadata":

    { "crs": { "epsg": 7415 } }, "CityObjects": { "id-1": { "type": "Building", "attributes": { "measuredHeight": 22.3, "roofType": "gable", "owner": "Elvis Presley" }, "geometry": [ { "type": "MultiSurface", "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] } ] } }, "vertices": [ [23.1, 2321.2, 11.0], [111.1, 321.1, 12.0], ... ], "appearance": { "materials": [], "textures":[], "vertices-texture": [] } } All City Objects listed here, indexed by their ID Each have geometries + attributes
  16. A CityJSON file 16 { "type": "CityModel", "version": "http://www.cityjson.org/version/0.2", "metadata":

    { "crs": { "epsg": 7415 } }, "CityObjects": { "id-1": { "type": "Building", "attributes": { "measuredHeight": 22.3, "roofType": "gable", "owner": "Elvis Presley" }, "geometry": [ { "type": "MultiSurface", "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] } ] } }, "vertices": [ [23.1, 2321.2, 11.0], [111.1, 321.1, 12.0], ... ], "appearance": { "materials": [], "textures":[], "vertices-texture": [] } } Geometry is ID of the vertex, global list compression + more “topology”
  17. A CityJSON file 17 { "type": "CityModel", "version": "http://www.cityjson.org/version/0.2", "metadata":

    { "crs": { "epsg": 7415 } }, "CityObjects": { "id-1": { "type": "Building", "attributes": { "measuredHeight": 22.3, "roofType": "gable", "owner": "Elvis Presley" }, "geometry": [ { "type": "MultiSurface", "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] } ] } }, "vertices": [ [23.1, 2321.2, 11.0], [111.1, 321.1, 12.0], ... ], "appearance": { "materials": [], "textures":[], "vertices-texture": [] } } material + texture possible
  18. BuildingParts: links between City Objects 18 "CityObjects": { "id-1": {

    "type": "Building", "attributes": { "roofType": "gable" }, "Parts": ["id-56", "id-832"], "Installations": ["mybalcony"] }, "id-56": { "type": "BuildingPart", ... }, "mybalcony": { "type": "BuildingInstallation", ... } }
  19. Other City Objects 19 "oneparcel": { "type": "LandUse", "geometry": [{

    "type": "MultiSurface", "lod": 1, "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] }] }
  20. JSON Schema: also possible 20 { "$schema": "http://json-schema.org/draft-04/schema#", "title": "CityJSON

    v0.2", "description": "CityJSON specifications v0.2", "type": "object", "definitions": { "Building": { "type": "object", "properties": { "type": { "enum": ["Building"] }, "attributes": { "type": "object", "properties": { "creationDate" : {"type": "string"}, "terminationDate" : {"type": "string"}, "class": {"type": "string"}, "function": {"type": "string"}, "usage": {"type": "string"}, … "Solid": { "type": "object", "properties": { "type": { "enum": ["Solid"] }, "boundaries": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": {"type": "integer"}
  21. JSON Schema: extra validation + warnings 21

  22. I ate my own dog food 22

  23. Python parser is 1-line 23 import json fin = open('mycity.json')

    cm = json.loads(fin.read()) print "CRS:", cm['metadata']['crs']['epsg'] print "There are", len(cm['CityObjects']), "CityObjects" # list all ids for id in cm['CityObjects']: print "\t", id
  24. IndoorJSON? 24 • has many xlinks -> JSON is perfect,

    a name- value pair for everything and directly indexed • geometries can use the same as I did, since ISO19107 used
  25. thank you. Hugo Ledoux 3d.bk.tudelft.nl/hledoux h.ledoux@tudelft.nl