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

CityJSON overview

Hugo Ledoux
November 27, 2017
1.3k

CityJSON overview

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

Hugo Ledoux

November 27, 2017
Tweet

Transcript

  1. 2

  2. 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.
  3. 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
  4. 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
  5. 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)
  6. 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)
  7. +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
  8. 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": [] } }
  9. 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
  10. 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
  11. 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
  12. 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”
  13. 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
  14. 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] ] } ]
  15. 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", ... } }
  16. 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", ... } }
  17. 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"
  18. “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
  19. 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"}
  20. 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"}
  21. 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>
  22. 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>
  23. 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>
  24. 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
  25. 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