Slide 1

Slide 1 text

Hugo Ledoux Geonovum Springplank Amersfoort, the Netherlands 2017-11-27 CityGML is dood, lang leven CityJSON! as an encoding

Slide 2

Slide 2 text

2

Slide 3

Slide 3 text

I personally convert immediately to OBJ 3 and I’m not the only one

Slide 4

Slide 4 text

CityGML as a data model is ! Its GML encoding is

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

CityJSON v0.5 is already out! 6

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

yeah yeah, I’m fully aware 8

Slide 9

Slide 9 text

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.

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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] <> _CityObject +informationSystem : xs::anyURI [0..1] <> ExternalReference <> CityModel +name : gml::CodeType [0..*] <> gml::_Feature +name : xs::string [1] +uri : xs::anyURI [1] <> ExternalObjectReference <> gml::_FeatureCollection <> Address <> xAL::AddressDetails <> gml::MultiPoint +mimeType : gml::CodeType +transformationMatrix : TransformationMatrix4x4Type +libraryObject : xs::anyURI <> ImplicitGeometry <> gml::_Geometry <> gml::Point +name : xs::string[1] +codeSpace : xs::anyURI[0..1] <> gml::CodeType +entirelyAboveTerrain +substantiallyAboveTerrain +substantiallyAboveAndBelowTerrain +substantiallyBelowTerrain +entirelyBelowTerrain <> RelativeToTerrainType +entirelyAboveWaterSurface +substantiallyAboveWaterSurface +substantiallyAboveAndBelowWaterSurface +substantiallyBelowWaterSurface +entirelyBelowWaterSurface +temporarilyAboveAndBelowWaterSurface <> RelativeToWaterType +gml::doubleList [16] <> 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)

Slide 13

Slide 13 text

CityGML geometry model, part 1 Copyright © 2012 Open Geospatial Consortium, Inc. All Rights Reserved. 5 <> gml::_GeometricPrimitive <> gml::_Solid <> gml::_Surface <> gml::_Curve +position : gml::DirectPosition [1] <> gml::Point <> gml::CompositeSolid <> gml::Solid <> gml::CompositeSurface <> gml::TriangulatedSurface <> gml::Triangle +stopLines : gml::LineStringSegment [0..*] +breakLines : gml::LineStringSegment [0..*] +maxLength : gml::LengthType [1] +controlPoint : gml::posList [1] <> gml::TIN <> gml::Polygon +orientation : gml::SignType [0..1] <> gml::OrientableSurface <> gml::CompositeCurve +position : gml::DirectPosition [2..*] <> gml::LineString <> gml::_Ring +position : gml::DirectPosition [4..*] <> gml::LinearRing <> gml::Surface <> gml::_SurfacePatch <> gml::_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)

Slide 14

Slide 14 text

+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] <> _AbstractBuilding <> _BoundarySurface <> CeilingSurface <> InteriorWallSurface <> FloorSurface <> RoofSurface <> WallSurfacee <> ClosureSurface +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <> BuildingInstallation +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <> IntBuildingInstallation +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <> Room +class : gml::CodeType [0..1] +function : gml::CodeType [0..*] +usage : gml::CodeType [0..*] <> BuildingFurniture <> _Opening <> Window <> Door <> Building <> BuildingPart <> core::_CityObject <> gml::MultiCurve <> gml::MultiSurface <> core::_Site <> gml::_Solid <> gml::_Geometry <> core::ImplicitGeometry <> GroundSurface <> OuterCeilingSurface <> OuterFloorSurface <> 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

Slide 15

Slide 15 text

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": [] } }

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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”

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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] ] } ]

Slide 22

Slide 22 text

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", ... } }

Slide 23

Slide 23 text

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", ... } }

Slide 24

Slide 24 text

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"

Slide 25

Slide 25 text

“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

Slide 26

Slide 26 text

I probably borrow more from TopoJSON 26

Slide 27

Slide 27 text

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"}

Slide 28

Slide 28 text

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"}

Slide 29

Slide 29 text

I ate my own dog food 29

Slide 30

Slide 30 text

CityJSON will compress ~4X-10X

Slide 31

Slide 31 text

often unnecessary repetitions in CityGML 31 … 378548.909850201 5818775.0976939 30.2299995422363 378549.984676693 5818780.48705406 33.23 2014-07-10 378549.012008586 5818780.48695927 30.2299995422363 … …

Slide 32

Slide 32 text

often unnecessary repetitions in CityGML 32 … 378548.909850201 5818775.0976939 30.2299995422363 378549.984676693 5818780.48705406 33.23 2014-07-10 378549.012008586 5818780.48695927 30.2299995422363 … …

Slide 33

Slide 33 text

often unnecessary repetitions in CityGML 33 … 378548.909850201 5818775.0976939 30.2299995422363 378549.984676693 5818780.48705406 33.23 2014-07-10 378549.012008586 5818780.48695927 30.2299995422363 … …

Slide 34

Slide 34 text

often unnecessary repetitions in CityGML 34 … 378548.909850201 5818775.0976939 30.2299995422363 378549.984676693 5818780.48705406 33.23 2014-07-10 378549.012008586 5818780.48695927 30.2299995422363 … … for each of the 19 surfaces of this single building Part of Berlin: • 22,771 buildings • 428,581 semantic surfaces

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

citygml4j == full conversion from CityGML (beta) 36 #+! to Claus Nagel from virtualcitySYSTEMS

Slide 37

Slide 37 text

We need & want your input

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

thank you. Hugo Ledoux 3d.bk.tudelft.nl/hledoux [email protected]