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

CityJSON overview

9c7f843b850f4e4beeb53c93893c4ff0?s=47 Hugo Ledoux
November 27, 2017
820

CityJSON overview

presentation Given at the Geonovum Springplank (Amersfoort, the Netherlands)

9c7f843b850f4e4beeb53c93893c4ff0?s=128

Hugo Ledoux

November 27, 2017
Tweet

Transcript

  1. Hugo Ledoux Geonovum Springplank Amersfoort, the Netherlands 2017-11-27 CityGML is

    dood, lang leven CityJSON! as an encoding
  2. 2

  3. I personally convert immediately to OBJ 3 and I’m not

    the only one
  4. CityGML as a data model is ! Its GML encoding

    is
  5. None
  6. CityJSON v0.5 is already out! 6

  7. CityJSON v0.5 is already out! 7 All CityGML modules have

    been mapped
  8. yeah yeah, I’m fully aware 8

  9. JSON 9 • JavaScript Object Notation • *not* linked to

    Java language • 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.
  10. Virtually all languages have support for it 10 It is

    built on two (very common) data structures: 1. collection of name-value pairs • Python dictionaries • hashes • C++ std::map 2. arrays
  11. I did it by hand… a few observations 11 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: • no raster DTM • all primitives in the same CRS • *one* way to represent something
  12. 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)
  13. 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)
  14. +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
  15. A CityJSON file 15 { "type": "CityModel", "version": “0.5", "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": [] } }
  16. A CityJSON file 16 { "type": "CityJSON", "version": “0.5", "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
  17. A CityJSON file 17 { "type": "CityJSON", "version": “0.5", "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
  18. A CityJSON file 18 { "type": "CityJSON", "version": “0.5", "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
  19. A CityJSON file 19 { "type": "CityJSON", "version": “0.5", "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”
  20. A CityJSON file 20 { "type": "CityJSON", "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
  21. Semantics surfaces, with attributes 21 “geometry": [ { "type": "Solid",

    “lod": 2.2, "boundaries": [ [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]], [[1, 2, 6, 5]], [[2, 3, 7, 6]], [[3, 0, 4, 7]] ] ], "semantics": { "surfaces" : [ { "type": "RoofSurface", "slope": 33.4 }, { "type": "RoofSurface", "slope": 66.6 }, { "type": "WallSurface", "paint": "blue" } ], "values": [ [0, 1, null, 2, 2, 2] ] } ]
  22. BuildingParts: links between City Objects 22 "CityObjects": { "id-1": {

    "type": "Building", "attributes": { "roofType": "gable" }, "Parts": ["id-56", "id-832"], "Installations": ["mybalcony"] }, "id-56": { "type": "BuildingPart", ... }, "mybalcony": { "type": "BuildingInstallation", ... } }
  23. BuildingParts: links between City Objects 23 "CityObjects": { "id-1": {

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

    "type": "MultiSurface", "lod": 1, "boundaries": [ [[0, 3, 2, 1]], [[4, 5, 6, 7]], [[0, 1, 5, 4]] ] }] } 1. "Building" 2. "BuildingPart" 3. "BuildingInstallation" 4. "Road" 5. "Railway" 6. "TransportSquare" 7. "TINRelief" 8. "WaterBody" 9. "PlantCover" 10. "SolitaryVegetationObject" 11. "LandUse" 12. "CityFurniture" 13. "GenericCityObject" 14. "Bridge" 15. "BridgePart" 16. "BridgeInstallation" 17. "BridgeConstructionElement" 18. "Tunnel" 19. "TunnelPart" 20. “TunnelInstallation"
  25. “Is it not like GeoJSON?” 25 1. 3D types not

    supported (~MultiPatch) 2. Simple Features used (repetitions of coordinates) 3. can’t mix diff types/classes in one file
  26. I probably borrow more from TopoJSON 26

  27. JSON Schema: also possible and there’s already one 27 {

    "$schema": "http://json-schema.org/draft-04/schema#", "title": "CityJSON v0.5", "description": "CityJSON specifications v0.5”, "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"}
  28. JSON Schema: also possible and there’s already one 28 {

    "$schema": "http://json-schema.org/draft-04/schema#", "title": "CityJSON v0.5", "description": "CityJSON specifications v0.5”, "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"}
  29. I ate my own dog food 29

  30. CityJSON will compress ~4X-10X

  31. often unnecessary repetitions in CityGML 31 <bldg:Building gml:id=“BLDG_0003000000000201"> … <bldg:boundedBy>

    <bldg:WallSurface gml:id="UUID_4acbfc0d-f6ec-44d4-a400-950f49865195"> <gml:boundedBy> <gml:Envelope srsName="urn:ogc:def:crs,crs:EPSG::25833,crs:EPSG::5783" srsDimension="3"> <gml:lowerCorner>378548.909850201 5818775.0976939 30.2299995422363</gml:lowerCorner> <gml:upperCorner>378549.984676693 5818780.48705406 33.23</gml:upperCorner> </gml:Envelope> </gml:boundedBy> <creationDate>2014-07-10</creationDate> <bldg:lod2MultiSurface> <gml:MultiSurface gml:id="UUID_fa02f430-a4d3-432a-9cd0-8e78b5b0c9af"> <gml:surfaceMember> <gml:Polygon gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c"> <gml:exterior> <gml:LinearRing gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c_0_"> <gml:posList srsDimension="3">378549.012008586 5818780.48695927 30.2299995422363 … </gml:posList> </gml:LinearRing> </gml:exterior> </gml:Polygon> </gml:surfaceMember> </gml:MultiSurface> </bldg:lod2MultiSurface> </bldg:WallSurface> </bldg:boundedBy> … </bldg:Building>
  32. often unnecessary repetitions in CityGML 32 <bldg:Building gml:id=“BLDG_0003000000000201"> … <bldg:boundedBy>

    <bldg:WallSurface gml:id="UUID_4acbfc0d-f6ec-44d4-a400-950f49865195"> <gml:boundedBy> <gml:Envelope srsName="urn:ogc:def:crs,crs:EPSG::25833,crs:EPSG::5783" srsDimension="3"> <gml:lowerCorner>378548.909850201 5818775.0976939 30.2299995422363</gml:lowerCorner> <gml:upperCorner>378549.984676693 5818780.48705406 33.23</gml:upperCorner> </gml:Envelope> </gml:boundedBy> <creationDate>2014-07-10</creationDate> <bldg:lod2MultiSurface> <gml:MultiSurface gml:id="UUID_fa02f430-a4d3-432a-9cd0-8e78b5b0c9af"> <gml:surfaceMember> <gml:Polygon gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c"> <gml:exterior> <gml:LinearRing gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c_0_"> <gml:posList srsDimension="3">378549.012008586 5818780.48695927 30.2299995422363 … </gml:posList> </gml:LinearRing> </gml:exterior> </gml:Polygon> </gml:surfaceMember> </gml:MultiSurface> </bldg:lod2MultiSurface> </bldg:WallSurface> </bldg:boundedBy> … </bldg:Building>
  33. often unnecessary repetitions in CityGML 33 <bldg:Building gml:id=“BLDG_0003000000000201"> … <bldg:boundedBy>

    <bldg:WallSurface gml:id="UUID_4acbfc0d-f6ec-44d4-a400-950f49865195"> <gml:boundedBy> <gml:Envelope srsName="urn:ogc:def:crs,crs:EPSG::25833,crs:EPSG::5783" srsDimension="3"> <gml:lowerCorner>378548.909850201 5818775.0976939 30.2299995422363</gml:lowerCorner> <gml:upperCorner>378549.984676693 5818780.48705406 33.23</gml:upperCorner> </gml:Envelope> </gml:boundedBy> <creationDate>2014-07-10</creationDate> <bldg:lod2MultiSurface> <gml:MultiSurface gml:id="UUID_fa02f430-a4d3-432a-9cd0-8e78b5b0c9af"> <gml:surfaceMember> <gml:Polygon gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c"> <gml:exterior> <gml:LinearRing gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c_0_"> <gml:posList srsDimension="3">378549.012008586 5818780.48695927 30.2299995422363 … </gml:posList> </gml:LinearRing> </gml:exterior> </gml:Polygon> </gml:surfaceMember> </gml:MultiSurface> </bldg:lod2MultiSurface> </bldg:WallSurface> </bldg:boundedBy> … </bldg:Building>
  34. often unnecessary repetitions in CityGML 34 <bldg:Building gml:id=“BLDG_0003000000000201"> … <bldg:boundedBy>

    <bldg:WallSurface gml:id="UUID_4acbfc0d-f6ec-44d4-a400-950f49865195"> <gml:boundedBy> <gml:Envelope srsName="urn:ogc:def:crs,crs:EPSG::25833,crs:EPSG::5783" srsDimension="3"> <gml:lowerCorner>378548.909850201 5818775.0976939 30.2299995422363</gml:lowerCorner> <gml:upperCorner>378549.984676693 5818780.48705406 33.23</gml:upperCorner> </gml:Envelope> </gml:boundedBy> <creationDate>2014-07-10</creationDate> <bldg:lod2MultiSurface> <gml:MultiSurface gml:id="UUID_fa02f430-a4d3-432a-9cd0-8e78b5b0c9af"> <gml:surfaceMember> <gml:Polygon gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c"> <gml:exterior> <gml:LinearRing gml:id="UUID_488383e3-2fb7-441b-8a76-b89eb31f175c_0_"> <gml:posList srsDimension="3">378549.012008586 5818780.48695927 30.2299995422363 … </gml:posList> </gml:LinearRing> </gml:exterior> </gml:Polygon> </gml:surfaceMember> </gml:MultiSurface> </bldg:lod2MultiSurface> </bldg:WallSurface> </bldg:boundedBy> … </bldg:Building> for each of the 19 surfaces of this single building Part of Berlin: • 22,771 buildings • 428,581 semantic surfaces
  35. Python parser is 1-line 35 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
  36. citygml4j == full conversion from CityGML (beta) 36 #+! to

    Claus Nagel from virtualcitySYSTEMS
  37. We need & want your input

  38. www.cityjson.org (all dev/discussions are open on GitHub)

  39. thank you. Hugo Ledoux 3d.bk.tudelft.nl/hledoux h.ledoux@tudelft.nl