How to add your knowledge

Selecting assets within a buffer

    Using FDO commands, it's possible to buffer an asset and then use that buffer to select other assets.

    The following script relies on some kind of existing selected set of assets to select all buildings with their centroid within 100m of the selected assets.  Here's what you do:

    1. Select an asset or two in the model
    2. Open the script window (CTRL+2)
    3. Paste in this script
    4. Run it
    5. Wait and then look at the script output panel

    Here's an example where I selected two roads in the middle of a city area:

    Here's what I see in the main window after I run the script:

    Here's what I see in the script window.  Note that 87 buildings were selected.  If I had wanted to, I also could have created some simple calculations to sum floor space or to make calculations on any of the available attributes of the buildings.  I could also have modified the selection algorithm to, for example, exclude all of the buildings that were classified as Residential, if I had the appropriate attribution on the model.

    Stability warning

    Running this script on large models with too many initially selected assets can crash Infrastructure Modeler.  This script stretches the boundaries a bit for the unsupported scripting engine, but it's a good example of what should be exposed better over time with better support for this capability.

    • Start with one or a few selected assets, not with a giant initial selection set
    • Before running the script, push the "Reset context" button which cleans up the JavaScript container (that is... frees memory) 

    Stylistic notes

    There are several ways that this script could be enhanced:

    • Refinements could be made to constrain the selection to a subset of buildings
    • Selection could be done across more asset classes than just buildings
    • The selection routine could be called in a 'callback function'
    • The script might run faster if the selected object buffers are merged in GeoJSON format as a multipolygon

    Sample script

    Copy and paste the following script into your model and see how it works!

    var sel = app.ActiveSelectionSet;
    var db = app.ActiveModelDb;
     
    var bldgsID = db.TableIndex("BUILDINGS");
    var bldgsTable   = db.Table(bldgsID);
     
    var fset = null;
    var table = null;
    var row = null;
    var buffer = null;
    var nxt = null;
    var selectedIDs = null;
    var numSelected = null;
     
    //Loop through the classes
    print("Wait a sec, I'm running...");
    for (id in sel.UsedClassIDs){
        fset = sel.GetFeatureSet(sel.UsedClassIDs[id]);
        table   = db.Table(sel.UsedClassIDs[id]);
     
        selectedIDs = [];
        numSelected = fset.QueryFeatureIDs(selectedIDs);
     
        //If a class has a selected geometry, then buffer the geometry and select the buildings within the buffer
        if (numSelected > 0){
            for (selectedID in selectedIDs){
                row = table.QueryFeature(parseInt(selectedIDs[selectedID]));
     
                buffer = row.GEOMETRY.Buffer2d(100);
     
                bldgsTable.StartQuery();
                nxt = bldgsTable.Next();
                while (nxt){
                    if (buffer.ContainsPoint2d(nxt.GEOMETRY.Centroid2d)){
                    sel.CombineFeatures(adsk.Enums.Add, bldgsID, [nxt.ID]);
                    }
                    nxt = bldgsTable.Next();
                }
                bldgsTable.EndQuery();
            }
        }
    }
     
    //Print out the number of selected assets per asset type (includes original selected assets)
    print();
    sel = app.ActiveDocument().ActiveSelectionSet;
    print("Total selected: " + sel.QueryCount());
    var count = 0;
    for ( i in db.TableNames){
        if (db.TableNames[i].slice(0,4) != "__jo"){
            count = sel.QueryCount(i);
            if (count > 0){
                print(" "+ db.TableNames[i] + " " + count);
            }
        }
    }