Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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. 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.
  4. 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
  5. 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
  6. 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)
  7. 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)
  8. +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
  9. 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": [] } }
  10. 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
  11. 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
  12. 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
  13. 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”
  14. 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
  15. 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", ... } }
  16. 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]] ] }] }
  17. 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"}
  18. 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
  19. 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