cityjson / specs

Specifications for CityJSON, a JSON-based encoding for 3D city models
https://cityjson.org
Creative Commons Zero v1.0 Universal
107 stars 25 forks source link

LoD1 terrain #77

Closed AdrianKriger closed 3 years ago

AdrianKriger commented 3 years ago

I am sorry to bother you with this trivial matter but I need your help.

I would like to create a basic LoD1 cityjson terrain model but am unable too. Vertices and geometry boundaries (indices / simplices) are via a Constrained Delaunay with python bindings of Shewchuck's; Triangle [option 'p' with holes - concavities removed].

Wavefront.obj is successfully created but I fail with cityjson. The code is:

def output_citysjon(extent, minz, maxz, T, pts):
    """
    basic function to produce LoD1 cityjson terrain
    """
    #-- create the JSON data structure for the City Model
    cm = {}
    cm["type"] = "CityJSON"
    cm["version"] = "0.9"
    cm["CityObjects"] = {}
    cm["vertices"] = []
    #-- Metadata is added manually
    cm["metadata"] = {
    "datasetTitle": "LoD1 terrain model of CPUT (Bellville) campus",
    "datasetReferenceDate": "2021-07-31",
    "geographicLocation": "Cape Town, South Africa",
    "referenceSystem": "urn:ogc:def:crs:EPSG::32733",
    "geographicalExtent": [
        extent[0],
        extent[1],
        minz ,
        extent[1],
        extent[1],
        maxz
      ],
    "datasetPointOfContact": {
        "contactName": "arkriger",
        "linkedin": "www.linkedin.com/in/adrian-kriger",
        "contactType": "private",
        "github": "https://github.com/AdrianKriger/osm_LoD1_3Dbuildings"
        },
    "metadataStandard": "ISO 19115 - Geographic Information - Metadata",
    "metadataStandardVersion": "ISO 19115:2014(E)"
    }

    add_terrain_v(pts, cm)
    grd = {}
    grd['type'] = 'TINRelief'
    grd['geometry'] = [] #-- a cityobject can have >1 
     #-- the geometry
    g = {} 
    g['type'] = 'CompositeSurface'
    g['lod'] = 1
    allsurfaces = [] #-- list of surfaces
    add_terrain_b(T, allsurfaces)
    g['boundaries'] = []
    g['boundaries'].append(allsurfaces)
      #-- add the geom 
    grd['geometry'].append(g)
      #-- insert the terrain as one new city object
    cm['CityObjects']['terrain01'] = grd

    return cm

def add_terrain_v(pts, cm):
    for p in pts:
        cm['vertices'].append([[p[0], p[1], p[2]]])

def add_terrain_b(T, allsurfaces):
    for i in T:
        allsurfaces.append([i[0] + 1, i[1] + 1, i[2] + 1])

where T and pts are the simplices and points respectively. The complete workflow is here. Your guidance is appreciated.

liberostelios commented 3 years ago

Hi Adrian. Glad to see you are interested in CityJSON.

I think your issue is in add_terrain_v, where there seems to be one extra square bracket wrapped around the vertex coordinates. The right code should be:

def add_terrain_v(pts, cm):
    for p in pts:
        cm['vertices'].append([p[0], p[1], p[2]]) # <- There was an extra square bracket here

Haven't checked thoroughly the rest of the code, but this for sure is an issue.

PS: It's very nice to see that you have some nice metadata in your model! 👏