Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The data formats, examples, and available web service interfaces will all change

| Schema version | Java | SPIDAcalc | SPIDAstudio |
|----------------------------------------------------------------------------------|------|-------------------------|-------------|
| [12.0.1](https://github.com/spidasoftware/schema/releases/tag/v12.0.1) | 11+ | SPIDAcalc 25.0.0 | |
| [11.0.3](https://github.com/spidasoftware/schema/releases/tag/v11.0.3) | 11+ | SPIDAcalc 24.1.1 - 24.1.2 | |
| [11.0.2](https://github.com/spidasoftware/schema/releases/tag/v11.0.2) | 11+ | SPIDAcalc 24.1.0 | |
| [10.0.1](https://github.com/spidasoftware/schema/releases/tag/v10.0.1) | 11+ | SPIDAcalc 24.0.0 | |
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ apply plugin: 'com.spidasoftware.releaseNotes'
apply plugin: 'application'

group = 'com.spidasoftware'
version = '12.0.2' // If you're changing the major version also change the currentVersion in ConverterUtils.
version = '13.0.0-SNAPSHOT' // If you're changing the major version also change the currentVersion in ConverterUtils.

def schemaReleaseVersion = System.getenv("SCHEMA_RELEASE_VERSION")
if(schemaReleaseVersion){
Expand Down
57 changes: 57 additions & 0 deletions resources/schema/spidacalc/calc/structure_group.schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"type": "object",
"id": "#/spidacalc/calc/structure_group.schema",
"description": "A mapping of structures to analyze",
"required": [
"primaryStructureId",
"primaryStructure",
"neighbors",
"spanningWireConnections"
],
"properties": {
"primaryStructureId": {
"type": "string",
"description": "The ID of the primary structures parent"
},
"primaryStructure": {
"description": "The primary structure to analyze",
"$ref": "../../spidacalc/calc/structure.schema"
},
"neighbors": {
"description": "List of neighbor structures to include in analysis finite model",
"type": "array",
"items": {
"$ref": "../../spidacalc/calc/structure.schema"
}
},
"spanningWireConnections": {
"description": "Attach height of the guy attach point.",
"type": "array",
"items": {
"description": "A mapping of (sourceStructureId, sourceWireId) -> (targetStructureId, targetWireId) for spanning wire connections",
"type": "object",
"required": [
"sourceStructureId",
"sourceWireId",
"targetStructureId",
"targetWireId"
],
"properties": {
"sourceStructureId": {
"type": "string"
},
"sourceWireId": {
"type": "string"
},
"targetStructureId": {
"type": "string"
},
"targetWireId": {
"type": "string"
}
}
}
}
},
"additionalProperties": false
}
8 changes: 4 additions & 4 deletions resources/schema/spidacalc/cee/analysis.schema
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "SPIDA CEE analysis object. The analysis objects are validated by the specific version of the engine that specified.",
"type": "object",
"required": [
"structure",
"structureGroup",
"analysisCase",
"clientData"
],
Expand All @@ -23,9 +23,9 @@
{"$ref": "../../spidacalc/client/strength_case.schema"}
]
},
"structure": {
"description": "The structure to be analyzed.",
"$ref": "../../spidacalc/calc/structure.schema"
"structureGroup": {
"description": "The structure group to be analyzed. Includes primary structure and optional neighbor structures.",
"$ref": "../../spidacalc/calc/structure_group.schema"
},
"clientData": {
"description": "The engineering data to be used to fill in the references on the structure.",
Expand Down
3 changes: 3 additions & 0 deletions resources/schema/spidacalc/client/load_case.schema
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
"ALL"
]
},
"includeNeighborStructures": {
"type": "boolean"
},
"analyzeGroundLineOnly": {
"type": "boolean"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Bentley Systems, Incorporated. All rights reserved.
* Copyright (c) 2026 Bentley Systems, Incorporated. All rights reserved.
*/
package com.spidasoftware.schema.conversion.changeset

Expand All @@ -16,13 +16,14 @@ import com.spidasoftware.schema.conversion.changeset.v9.*
import com.spidasoftware.schema.conversion.changeset.v10.*
import com.spidasoftware.schema.conversion.changeset.v11.*
import com.spidasoftware.schema.conversion.changeset.v12.*
import com.spidasoftware.schema.conversion.changeset.v13.*
import groovy.util.logging.Slf4j
import org.apache.commons.lang3.StringUtils

@Slf4j
class ConverterUtils {

static final int currentVersion = 12
static final int currentVersion = 13

static {
addCalcConverter(new CalcProjectConverter())
Expand Down Expand Up @@ -89,6 +90,7 @@ class ConverterUtils {
converter.addChangeSet(12, new ComponentBraceChangeset())
converter.addChangeSet(12, new SidedPoleChangeset())
converter.addChangeSet(12, new CSAMaxWindLoadFactorsChangeSet())
converter.addChangeSet(13, new LeadAnalysisChangeSet())
// add calc changesets above here

converter.setCurrentVersion(currentVersion)
Expand Down Expand Up @@ -118,6 +120,7 @@ class ConverterUtils {
converter.addChangeSet(12, new ComponentBraceChangeset())
converter.addChangeSet(12, new SidedPoleChangeset())
converter.addChangeSet(12, new CSAMaxWindLoadFactorsChangeSet())
converter.addChangeSet(13, new LeadAnalysisChangeSet())
// add client data changesets above here

converter.setCurrentVersion(currentVersion)
Expand Down Expand Up @@ -148,6 +151,7 @@ class ConverterUtils {
converter.addChangeSet(12, new ComponentBraceChangeset())
converter.addChangeSet(12, new SidedPoleChangeset())
converter.addChangeSet(12, new CSAMaxWindLoadFactorsChangeSet())
converter.addChangeSet(13, new LeadAnalysisChangeSet())
// add result changesets above here

converter.setCurrentVersion(currentVersion)
Expand Down Expand Up @@ -185,6 +189,8 @@ class ConverterUtils {
return null
}
switch (engineVersion) {
case 26.0:
return 13
case 25.0:
return 12
case 24.1:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2026 Bentley Systems, Incorporated. All rights reserved.
*/
package com.spidasoftware.schema.conversion.changeset.v13

import com.spidasoftware.schema.conversion.changeset.ConversionException
import com.spidasoftware.schema.conversion.changeset.client.AbstractClientDataChangeSet
import groovy.transform.CompileStatic

@CompileStatic
class LeadAnalysisChangeSet extends AbstractClientDataChangeSet {

@Override
boolean applyToClientData(Map clientDataJSON) throws ConversionException {
// do nothing
return false
}

@Override
boolean revertClientData(Map clientDataJSON) throws ConversionException {
boolean changed = false
clientDataJSON.analysisCases?.each { Map analysisCase ->
changed |= (analysisCase.remove("includeNeighborStructures") != null)
}
return changed
}

@Override
void revertProject(Map projectJSON) throws ConversionException {
super.revertProject(projectJSON)
projectJSON.defaultLoadCases?.each { Map loadCase ->
loadCase.remove("includeNeighborStructures")
}
}

@Override
void revertDesign(Map designJSON) throws ConversionException {
super.revertDesign(designJSON)
designJSON.analysis?.each { Map analysis ->
Map analysisCase = analysis.analysisCaseDetails as Map
analysisCase?.remove("includeNeighborStructures")
}
}

@Override
boolean revertResults(Map resultsJSON) throws ConversionException {
boolean changed = super.revertResults(resultsJSON)
resultsJSON.results?.each { Map result ->
Map analysisCase = result.analysisCaseDetails as Map
if (analysisCase) {
changed |= (analysisCase.remove("includeNeighborStructures") != null)
}
}
return changed
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Bentley Systems, Incorporated. All rights reserved.
* Copyright (c) 2026 Bentley Systems, Incorporated. All rights reserved.
*/
package com.spidasoftware.schema.conversion.changeset

Expand Down Expand Up @@ -60,7 +60,7 @@ class ConverterUtilsSpec extends Specification {

def "test getPossibleVersionsNewestToOldest"() {
expect:
ConverterUtils.getPossibleVersionsNewestToOldest() == [12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2] as LinkedHashSet
ConverterUtils.getPossibleVersionsNewestToOldest() == [13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2] as LinkedHashSet
}

def "pole-lean validation"() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2026 Bentley Systems, Incorporated. All rights reserved.
*/
package com.spidasoftware.schema.conversion.changeset.v13

import groovy.json.JsonSlurper
import spock.lang.Specification

class LeadAnalysisChangeSetTest extends Specification {

static LeadAnalysisChangeSet changeSet

def setupSpec() {
changeSet = new LeadAnalysisChangeSet()
}

def "revert client data"() {
setup:
InputStream stream = LeadAnalysisChangeSetTest.getResourceAsStream("/conversions/v13/leadAnalysis-v13-project.json")
Map json = new JsonSlurper().parse(stream) as Map
stream.close()
expect:
json.clientData.analysisCases[0].includeNeighborStructures == false
json.clientData.analysisCases[1].includeNeighborStructures == true
when:
boolean reverted = changeSet.revertClientData(json.clientData as Map)
then:
reverted
json.clientData.analysisCases[0].includeNeighborStructures == null
json.clientData.analysisCases[1].includeNeighborStructures == null
}

def "revert project"() {
setup:
InputStream stream = LeadAnalysisChangeSetTest.getResourceAsStream("/conversions/v13/leadAnalysis-v13-project.json")
Map json = new JsonSlurper().parse(stream) as Map
stream.close()
expect:
json.clientData.analysisCases[0].includeNeighborStructures == false
json.clientData.analysisCases[1].includeNeighborStructures == true
json.defaultLoadCases[0].includeNeighborStructures == false
json.defaultLoadCases[1].includeNeighborStructures == true
json.leads[0].locations[0].designs[0].analysis[0].analysisCaseDetails.includeNeighborStructures == false
json.leads[0].locations[0].designs[0].analysis[1].analysisCaseDetails.includeNeighborStructures == true
when:
changeSet.revertProject(json)
then:
json.clientData.analysisCases[0].includeNeighborStructures == null
json.clientData.analysisCases[1].includeNeighborStructures == null
json.defaultLoadCases[0].includeNeighborStructures == null
json.defaultLoadCases[1].includeNeighborStructures == null
json.leads[0].locations[0].designs[0].analysis[0].analysisCaseDetails.includeNeighborStructures == null
json.leads[0].locations[0].designs[0].analysis[1].analysisCaseDetails.includeNeighborStructures == null
}

def "revert results"() {
setup:
InputStream stream = LeadAnalysisChangeSetTest.getResourceAsStream("/conversions/v13/leadAnalysis-v13-results.json")
Map json = new JsonSlurper().parse(stream) as Map
stream.close()
expect:
json.clientData.analysisCases[0].includeNeighborStructures == false
json.clientData.analysisCases[1].includeNeighborStructures == true
json.results[0].analysisCaseDetails.includeNeighborStructures == false
json.results[1].analysisCaseDetails.includeNeighborStructures == true
when:
boolean reverted = changeSet.revertResults(json)
then:
reverted
json.clientData.analysisCases[0].includeNeighborStructures == null
json.clientData.analysisCases[1].includeNeighborStructures == null
json.results[0].analysisCaseDetails.includeNeighborStructures == null
json.results[1].analysisCaseDetails.includeNeighborStructures == null
}
}
Loading