packageDocumentation module import { assert , DbResult , Id64String } from "@itwin/core-bentley" ; import { ECSqlStatement , ElementAspect , IModelDb , PhysicalElement , SpatialLocationElement } from "@itwin/core-backend" ; import { Code , ElementProps , GeometricElement3dProps , IModelError , PhysicalElementProps , RelatedElement } from "@itwin/core-common" ; import { ComparisonOption , LinearLocationReference , LinearlyLocatedAttributionProps , LinearlyReferencedAtLocationAspectProps , LinearlyReferencedAtLocationProps , LinearlyReferencedFromToLocationAspectProps , LinearlyReferencedFromToLocationProps , LinearlyReferencedLocationType , QueryParams , ReferentElementProps , } from "@itwin/linear-referencing-common" ; import { LinearlyReferencedAtLocation , LinearlyReferencedFromToLocation } from "./LinearReferencingElementAspects" ; import { ILinearLocationLocatesElement , ILinearlyLocatedAlongILinearElement , ILinearlyLocatedAttributesElement , IReferentReferencesElement , } from "./LinearReferencingRelationships" ; beta export abstract class LinearlyLocatedAttribution extends SpatialLocationElement implements LinearlyLocatedAttributionProps , LinearlyLocatedBase { internal public static override get className ( ) : string { return "LinearlyLocatedAttribution" ; } public attributedElement ? : ILinearlyLocatedAttributesElement ; public constructor ( props , iModel ) { super ( props , iModel ) ; this . attributedElement = RelatedElement . fromJSON ( props . attributedElement ) ; } public getLinearElementId ( ) { return LinearlyLocated . getLinearElementId ( this . iModel , this . id ) ; } } beta export abstract class LinearLocationElement extends SpatialLocationElement implements LinearlyLocatedBase { internal public static override get className ( ) : string { return "LinearLocationElement" ; } public constructor ( props , iModel ) { super ( props , iModel ) ; } public getLinearElementId ( ) { return LinearlyLocated . getLinearElementId ( this . iModel , this . id ) ; } } beta export class LinearLocation extends LinearLocationElement { internal public static override get className ( ) : string { return "LinearLocation" ; } public constructor ( props , iModel ) { super ( props , iModel ) ; } private static toProps ( modelId , categoryId ) { const props = { classFullName : LinearLocation . classFullName , category : categoryId , model : modelId , code : Code . createEmpty ( ) } ; return props ; } public static create ( iModel , modelId , categoryId ) { return new LinearLocation ( this . toProps ( modelId , categoryId ) , iModel ) ; } public static insertFromTo ( iModel , modelId , categoryId , linearElementId , fromToPosition , locatedElementId ) { const newId = LinearlyLocated . insertFromTo ( iModel , this . toProps ( modelId , categoryId ) , linearElementId , fromToPosition ) ; ILinearLocationLocatesElement . insert ( iModel , newId , locatedElementId ) ; return newId ; } public insertFromTo ( iModel , linearElementId , fromToPosition , locatedElementId ) { const newId = LinearlyLocated . insertFromTo ( iModel , this , linearElementId , fromToPosition ) ; ILinearLocationLocatesElement . insert ( iModel , newId , locatedElementId ) ; return newId ; } public static insertAt ( iModel , modelId , categoryId , linearElementId , atPosition , locatedElementId ) { const newId = LinearlyLocated . insertAt ( iModel , this . toProps ( modelId , categoryId ) , linearElementId , atPosition ) ; ILinearLocationLocatesElement . insert ( iModel , newId , locatedElementId ) ; return newId ; } public insertAt ( iModel , linearElementId , atPosition , locatedElementId ) { const newId = LinearlyLocated . insertAt ( iModel , this , linearElementId , atPosition ) ; ILinearLocationLocatesElement . insert ( iModel , newId , locatedElementId ) ; return newId ; } } beta export abstract class LinearPhysicalElement extends PhysicalElement { internal public static override get className ( ) : string { return "LinearPhysicalElement" ; } public constructor ( props , iModel ) { super ( props , iModel ) ; } } beta export abstract class ReferentElement extends SpatialLocationElement implements ReferentElementProps , LinearlyLocatedBase { internal public static override get className ( ) : string { return "ReferentElement" ; } public referencedElement ? : IReferentReferencesElement ; public constructor ( props , iModel ) { super ( props , iModel ) ; this . referencedElement = RelatedElement . fromJSON ( props . referencedElement ) ; } public getLinearElementId ( ) { return LinearlyLocated . getLinearElementId ( this . iModel , this . id ) ; } } beta export class Referent extends ReferentElement { internal public static override get className ( ) : string { return "Referent" ; } public constructor ( props , iModel ) { super ( props , iModel ) ; } private static toProps ( modelId , categoryId , referencedElementId ) { const props = { classFullName : LinearLocation . classFullName , category : categoryId , model : modelId , code : Code . createEmpty ( ) , referencedElement : new IReferentReferencesElement ( referencedElementId ) } ; return props ; } public static create ( iModel , modelId , categoryId , referencedElementId ) { return new Referent ( this . toProps ( modelId , categoryId , referencedElementId ) , iModel ) ; } public static insertAt ( iModel , modelId , categoryId , linearElementId , atPosition , referencedElementId ) { return LinearlyLocated . insertAt ( iModel , this . toProps ( modelId , categoryId , referencedElementId ) , linearElementId , atPosition ) ; } public insertAt ( iModel , linearElementId , atPosition ) { return LinearlyLocated . insertAt ( iModel , this , linearElementId , atPosition ) ; } } abstract class ECSQLGenImpl { public abstract genSelect ( ) ; public selectDistinct ( ) { return false ; } public abstract genFromJoin ( ) ; public abstract genWhere ( bindVals ? , from ? , inclusiveFrom ? , to ? , inclusiveTo ? ) ; public abstract genOrderBy ( ) ; } class AtAndFromToECSQLGenImpl extends ECSQLGenImpl { public genSelect ( ) { return "coalesce(AtLocation.AtPosition.DistanceAlongFromStart, FromToLocation.FromPosition.DistanceAlongFromStart) StartDistanceAlong, " + "coalesce(AtLocation.AtPosition.DistanceAlongFromStart, FromToLocation.ToPosition.DistanceAlongFromStart) StopDistanceAlong, " + "coalesce(AtLocation.ECInstanceId, FromToLocation.ECInstanceId) LocationAspectId " ; } public override selectDistinct ( ) { return true ; } public genFromJoin ( ) { return "LEFT JOIN LinearReferencing.LinearlyReferencedAtLocation AtLocation ON LinearlyLocated.InstanceId = AtLocation.Element.Id " + "LEFT JOIN LinearReferencing.LinearlyReferencedFromToLocation FromToLocation ON LinearlyLocated.InstanceId = FromToLocation.Element.Id " ; } public genWhere ( bindVals , from ? , inclusiveFrom ? , to ? , inclusiveTo ? ) { const fromCompOp = ( inclusiveFrom === undefined || inclusiveFrom ) ? ">=" : ">" ; const toCompOp = ( inclusiveTo === undefined || inclusiveTo ) ? "<=" : "<" ; let ecSql = "" ; if ( from !== undefined && to !== undefined ) { ecSql += "(AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? AND AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ?) OR (FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? AND FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ?) " + "OR (FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? AND FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ?) OR (FromToLocation.FromPosition.DistanceAlongFromStart <= ? AND FromToLocation.ToPosition.DistanceAlongFromStart >= ?) " ; bindVals . push ( from ) ; bindVals . push ( to ) ; bindVals . push ( from ) ; bindVals . push ( to ) ; bindVals . push ( from ) ; bindVals . push ( to ) ; bindVals . push ( from ) ; bindVals . push ( to ) ; } else if ( from !== undefined ) { ecSql += "AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? OR FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? OR FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? " ; bindVals . push ( from ) ; bindVals . push ( from ) ; bindVals . push ( from ) ; } else if ( to !== undefined ) { ecSql += "AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ? OR FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ? OR FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ? " ; bindVals . push ( to ) ; bindVals . push ( to ) ; bindVals . push ( to ) ; } else { ecSql += "(AtLocation.AtPosition.DistanceAlongFromStart IS NOT NULL) OR " ; ecSql += "(FromToLocation.FromPosition.DistanceAlongFromStart IS NOT NULL) " ; } return ecSql ; } public genOrderBy ( ) { return "coalesce(AtLocation.AtPosition.DistanceAlongFromStart, FromToLocation.FromPosition.DistanceAlongFromStart)" ; } } class FromToECSQLGenImpl extends ECSQLGenImpl { public genSelect ( ) { return "FromToLocation.FromPosition.DistanceAlongFromStart StartDistanceAlong, FromToLocation.ToPosition.DistanceAlongFromStart StopDistanceAlong, FromToLocation.ECInstanceId LocationAspectId " ; } public genFromJoin ( ) { return "INNER JOIN LinearReferencing.LinearlyReferencedFromToLocation FromToLocation ON LinearlyLocated.InstanceId = FromToLocation.Element.Id " ; } public genWhere ( bindVals , from ? , inclusiveFrom ? , to ? , inclusiveTo ? ) { const fromCompOp = ( inclusiveFrom === undefined || inclusiveFrom ) ? ">=" : ">" ; const toCompOp = ( inclusiveTo === undefined || inclusiveTo ) ? "<=" : "<" ; let ecSql = "" ; if ( from !== undefined && to !== undefined ) { ecSql += "AND ((FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? AND FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ?) OR (FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? AND FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ?) OR (FromToLocation.FromPosition.DistanceAlongFromStart <= ? AND FromToLocation.ToPosition.DistanceAlongFromStart >= ?)) " ; bindVals . push ( from ) ; bindVals . push ( to ) ; bindVals . push ( from ) ; bindVals . push ( to ) ; bindVals . push ( from ) ; bindVals . push ( to ) ; } else if ( from !== undefined ) { ecSql += "AND (FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? OR FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ?)" ; bindVals . push ( from ) ; bindVals . push ( from ) ; } else if ( to !== undefined ) { ecSql += "AND (FromToLocation.FromPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ? OR FromToLocation.ToPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ?) " ; bindVals . push ( to ) ; bindVals . push ( to ) ; } else { ecSql += "FromToLocation.FromPosition.DistanceAlongFromStart IS NOT NULL " ; } return ecSql ; } public genOrderBy ( ) { return "FromToLocation.FromPosition.DistanceAlongFromStart" ; } } class AtECSQLGenImpl extends ECSQLGenImpl { public genSelect ( ) { return "AtLocation.AtPosition.DistanceAlongFromStart StartDistanceAlong, AtLocation.AtPosition.DistanceAlongFromStart StopDistanceAlong, AtLocation.ECInstanceId LocationAspectId " ; } public genFromJoin ( ) { return "INNER JOIN LinearReferencing.LinearlyReferencedAtLocation AtLocation ON LinearlyLocated.InstanceId = AtLocation.Element.Id " ; } public genWhere ( bindVals , from ? , inclusiveFrom ? , to ? , inclusiveTo ? ) { const fromCompOp = ( inclusiveFrom === undefined || inclusiveFrom ) ? ">=" : ">" ; const toCompOp = ( inclusiveTo === undefined || inclusiveTo ) ? "<=" : "<" ; let ecSql = "" ; if ( from !== undefined && to !== undefined ) { ecSql += "AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? AND AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ? " ; bindVals . push ( from ) ; bindVals . push ( to ) ; } else if ( from !== undefined ) { ecSql += "AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += fromCompOp ; ecSql += " ? " ; bindVals . push ( from ) ; } else if ( to !== undefined ) { ecSql += "AtLocation.AtPosition.DistanceAlongFromStart " ; ecSql += toCompOp ; ecSql += " ? " ; bindVals . push ( to ) ; } else ecSql += "AtLocation.AtPosition.DistanceAlongFromStart IS NOT NULL " ; return ecSql ; } public genOrderBy ( ) { return "AtLocation.AtPosition.DistanceAlongFromStart" ; } } class QueryLinearLocationsECSQLGen { private readonly _params : QueryParams ; private _ecSql : string ; private _addSelectClause ( impl ) { let select = "SELECT " ; if ( impl . selectDistinct ( ) ) select += "DISTINCT " ; select += "LinearlyLocated.InstanceId LinearlyLocatedId, printf('%s:%s', meta.ECSchemaDef.Name, meta.ECClassDef.Name) LinearlyLocatedClassFullName, " ; select += impl . genSelect ( ) ; this . _ecSql += select ; } private _parseClassFullName ( classFullName ) { const parts = classFullName . split ( ":" ) ; if ( parts . length !== 2 ) return undefined ; return [ parts [ 0 ] , parts [ 1 ] ] ; } private _genLinearlyLocated ( ) { return "meta.ECSchemaDef JOIN meta.ECClassDef USING meta.SchemaOwnsClasses JOIN " + "(SELECT coalesce(Located.TargetECInstanceId, Along.SourceECInstanceId) InstanceId, " + "coalesce(Located.TargetECClassId, Along.SourceECClassId) ClassId " + "FROM LinearReferencing.ILinearlyLocatedAlongILinearElement Along LEFT JOIN " + "LinearReferencing.ILinearLocationLocatesElement Located ON Along.SourceECInstanceId = Located.SourceECInstanceId " + "WHERE Along.TargetECInstanceId = ?) LinearlyLocated ON meta.ECClassDef.ECInstanceId = LinearlyLocated.ClassId " ; } private _addFromClause ( impl ) { let from = "FROM " ; from += this . _genLinearlyLocated ( ) ; from += impl . genFromJoin ( ) ; this . _ecSql += from ; } private _addWhereClause ( impl , bindVals ) { let where = "WHERE " ; where += impl . genWhere ( bindVals , this . _params . fromDistanceAlong , ( this . _params . fromComparisonOption === undefined || this . _params . fromComparisonOption === ComparisonOption . Inclusive ) , this . _params . toDistanceAlong , ( this . _params . toComparisonOption === undefined || this . _params . toComparisonOption === ComparisonOption . Inclusive ) ) ; if ( this . _params . linearlyLocatedClassFullNames !== undefined ) { if ( where . length > 6 ) where += "AND " ; if ( 1 === this . _params . linearlyLocatedClassFullNames . length ) { const classFullName = this . _params . linearlyLocatedClassFullNames [ 0 ] ; const schemaNameClassName = this . _parseClassFullName ( classFullName ) ; if ( schemaNameClassName === undefined ) throw new IModelError ( 0 , "Invalid full class name" ) ; where += `meta.ECSchemaDef.Name='${ schemaNameClassName [ 0 ] }' AND meta.ECClassDef.Name='${ schemaNameClassName [ 1 ] }' ` ; } else if ( 1 < this . _params . linearlyLocatedClassFullNames . length ) { where += "(" ; for ( const classFullName of this . _params . linearlyLocatedClassFullNames ) { if ( classFullName === undefined ) continue ; const schemaNameClassName = this . _parseClassFullName ( classFullName ) ; if ( schemaNameClassName === undefined ) continue ; where += `(meta.ECSchemaDef.Name='${ schemaNameClassName [ 0 ] }' AND meta.ECClassDef.Name='${ schemaNameClassName [ 1 ] }') OR ` ; } where = where . substr ( 0 , where . length - 4 ) ; where += ") " ; } } this . _ecSql += where ; } private _addOrderByClause ( impl ) { let orderBy = "ORDER BY " ; orderBy += impl . genOrderBy ( ) ; this . _ecSql += orderBy ; } private _createImpl ( ) { if ( this . _params . linearlyReferencedLocationTypeFilter === undefined || this . _params . linearlyReferencedLocationTypeFilter === LinearlyReferencedLocationType . Any ) { return new AtAndFromToECSQLGenImpl ( ) ; } else if ( this . _params . linearlyReferencedLocationTypeFilter === LinearlyReferencedLocationType . FromTo ) { return new FromToECSQLGenImpl ( ) ; } else { return new AtECSQLGenImpl ( ) ; } } public constructor ( params ) { this . _params = params ; this . _ecSql = "" ; } public generate ( linearElementId ) { this . _ecSql = "" ; const impl = this . _createImpl ( ) ; const bindVals = [ linearElementId ] ; this . _addSelectClause ( impl ) ; this . _addFromClause ( impl ) ; this . _addWhereClause ( impl , bindVals ) ; this . _addOrderByClause ( impl ) ; return [ this . _ecSql , bindVals ] ; } } beta export class LinearlyLocated { private static insertBasic ( iModel , elProps , linearElementId ) { const newId = iModel . elements . insertElement ( elProps ) ; const linearlyLocatedAlongLinearElement = ILinearlyLocatedAlongILinearElement . create ( iModel , newId , linearElementId ) ; linearlyLocatedAlongLinearElement . insert ( ) ; return newId ; } param iModel param elProps param linearElementId param atPosition returns throws public static insertAt ( iModel , elProps , linearElementId , atPosition ) { const newId = this . insertBasic ( iModel , elProps , linearElementId ) ; LinearlyReferencedAtLocation . insert ( iModel , newId , atPosition . atPosition , ( atPosition . fromReferent === undefined ) ? undefined : atPosition . fromReferent . id ) ; return newId ; } param iModel param elProps param linearElementId param fromToPosition returns throws public static insertFromTo ( iModel , elProps , linearElementId , fromToPosition ) { const newId = this . insertBasic ( iModel , elProps , linearElementId ) ; LinearlyReferencedFromToLocation . insert ( iModel , newId , fromToPosition . fromPosition , fromToPosition . toPosition , ( fromToPosition . fromPositionFromReferent === undefined ) ? undefined : fromToPosition . fromPositionFromReferent . id , ( fromToPosition . toPositionFromReferent === undefined ) ? undefined : fromToPosition . toPositionFromReferent . id ) ; return newId ; } private static getLinearLocations < T > ( iModel , linearlyLocatedElementId , fullClassName ) { const aspects = iModel . elements . getAspects ( linearlyLocatedElementId , fullClassName ) ; if ( aspects . length === 0 ) return [ ] ; const retVal = [ ] ; for ( const aspect of aspects ) { const linearAspect = ( aspect as unknown ) as T ; retVal . push ( linearAspect ) ; } return retVal ; } private static queryFirstLinearLocationAspectId ( iModel , linearlyLocatedElementId , className ) { let aspectId ; iModel . withPreparedStatement ( `SELECT ECInstanceId FROM LinearReferencing.${ className } WHERE Element.Id=? LIMIT 1` , ( stmt ) => { stmt . bindId ( 1 , linearlyLocatedElementId ) ; if ( stmt . step ( ) === DbResult . BE_SQLITE_ROW ) aspectId = stmt . getValue ( 0 ) . getId ( ) ; } ) ; return aspectId ; } param iModel param linearlyLocatedElementId returns throws public static getAtLocations ( iModel , linearlyLocatedElementId ) { return this . getLinearLocations < LinearlyReferencedAtLocation > ( iModel , linearlyLocatedElementId , "LinearReferencing:LinearlyReferencedAtLocation" ) ; } param iModel param linearlyLocatedElementId returns throws public static getAtLocation ( iModel , linearlyLocatedElementId ) { const linearLocations = this . getAtLocations ( iModel , linearlyLocatedElementId ) ; if ( linearLocations . length === 0 ) return undefined ; else { assert ( linearLocations . length === 1 ) ; return linearLocations [ 0 ] ; } } param iModel param linearlyLocatedElementId param linearLocationProps param aspectId throws public static updateAtLocation ( iModel , linearlyLocatedElementId , linearLocationProps , aspectId ? ) { let linearLocAspectId ; if ( aspectId !== undefined ) linearLocAspectId = aspectId ; else { linearLocAspectId = this . queryFirstLinearLocationAspectId ( iModel , linearlyLocatedElementId , "LinearlyReferencedAtLocation" ) ! ; } const linearLocationAspectProps = { id : linearLocAspectId , element : { id : linearlyLocatedElementId } , classFullName : "LinearReferencing:LinearlyReferencedAtLocation" , atPosition : linearLocationProps . atPosition , fromReferent : linearLocationProps . fromReferent } ; iModel . elements . updateAspect ( linearLocationAspectProps ) ; } param iModel param linearlyLocatedElementId param linearLocationProps param aspectId throws public static updateFromToLocation ( iModel , linearlyLocatedElementId , linearLocationProps , aspectId ? ) { let linearLocAspectId ; if ( aspectId !== undefined ) linearLocAspectId = aspectId ; else { linearLocAspectId = this . queryFirstLinearLocationAspectId ( iModel , linearlyLocatedElementId , "LinearlyReferencedFromToLocation" ) ! ; } const linearLocationAspectProps = { id : linearLocAspectId , element : { id : linearlyLocatedElementId , relClassName : "LinearReferencing:ILinearlyLocatedOwnsFromToLocations" } , classFullName : "LinearReferencing:LinearlyReferencedFromToLocation" , fromPosition : linearLocationProps . fromPosition , fromPositionFromReferent : linearLocationProps . fromPositionFromReferent , toPosition : linearLocationProps . toPosition , toPositionFromReferent : linearLocationProps . toPositionFromReferent } ; iModel . elements . updateAspect ( linearLocationAspectProps ) ; } param iModel param linearlyLocatedElementId returns public static getLinearElementId ( iModel , linearlyLocatedElementId ) { let linearElementId ; iModel . withPreparedStatement ( "SELECT TargetECInstanceId FROM LinearReferencing.ILinearlyLocatedAlongILinearElement WHERE SourceECInstanceId = ?" , ( stmt ) => { stmt . bindId ( 1 , linearlyLocatedElementId ) ; if ( DbResult . BE_SQLITE_ROW === stmt . step ( ) ) linearElementId = stmt . getValue ( 0 ) . getId ( ) ; else linearElementId = undefined ; } ) ; return linearElementId ; } param iModel param linearlyLocatedElementId returns throws public static getFromToLocations ( iModel , linearlyLocatedElementId ) { return this . getLinearLocations < LinearlyReferencedFromToLocation > ( iModel , linearlyLocatedElementId , "LinearReferencing:LinearlyReferencedFromToLocation" ) ; } param iModel param linearlyLocatedElementId returns throws public static getFromToLocation ( iModel , linearlyLocatedElementId ) { const linearLocations = this . getFromToLocations ( iModel , linearlyLocatedElementId ) ; if ( linearLocations . length === 0 ) return undefined ; else { assert ( linearLocations . length === 1 ) ; return linearLocations [ 0 ] ; } } } beta export interface LinearlyLocatedBase { getLinearElementId ( ) : Id64String | undefined ; } beta export interface LinearlyLocatedSingleAt extends LinearlyLocatedBase { getAtLocation ( ) : LinearlyReferencedAtLocation | undefined ; updateAtLocation ( linearLocation , aspectId ? ) : void ; } beta export interface LinearlyLocatedMultipleAt extends LinearlyLocatedBase { getAtLocations ( ) : LinearlyReferencedAtLocation [ ] ; updateAtLocation ( linearLocation , aspectId ) : void ; } beta export interface LinearlyLocatedSingleFromTo extends LinearlyLocatedBase { getFromToLocation ( ) : LinearlyReferencedFromToLocation | undefined ; updateFromToLocation ( linearLocation , aspectId ? ) : void ; } beta export interface LinearlyLocatedMultipleFromTo extends LinearlyLocatedBase { getFromToLocations ( ) : LinearlyReferencedFromToLocation [ ] ; updateFromToLocation ( linearLocation , aspectId ) : void ; } beta export class LinearElement { returns throws public static queryLinearLocations ( iModel , linearElementId , queryParams ) { const ecSqlGen = new QueryLinearLocationsECSQLGen ( queryParams ) ; const ecsqlAndBindVals = ecSqlGen . generate ( linearElementId ) ; const linearLocationRefs = [ ] ; iModel . withPreparedStatement ( ecsqlAndBindVals [ 0 ] , ( stmt ) => { stmt . bindValues ( ecsqlAndBindVals [ 1 ] ) ; while ( DbResult . BE_SQLITE_ROW === stmt . step ( ) ) { const linearLocationRef = { linearlyLocatedId : stmt . getValue ( 0 ) . getId ( ) , linearlyLocatedClassFullName : stmt . getValue ( 1 ) . getString ( ) , startDistanceAlong : stmt . getValue ( 2 ) . getDouble ( ) , stopDistanceAlong : stmt . getValue ( 3 ) . getDouble ( ) , locationAspectId : stmt . getValue ( 4 ) . getId ( ) } ; linearLocationRefs . push ( linearLocationRef ) ; } } ) ; return linearLocationRefs ; } }