Layer search

1157
8
05-24-2017 11:06 AM
BrianE
by
Occasional Contributor II

I have a bunch of buildings as shapes and was wondering if there is a way to easily locate and select specific buildings. They are all named with their addresses. In the "Search layers, object, attributes" box I type out the name of the shape in quotes("") and I get a building. However I need to locate MORE than one building at a time.

Is there a way to do this?

I am very new to City Engine.

0 Kudos
8 Replies
CherylLau
Esri Regular Contributor

You can use wildcards to search for multiple items with similar names.  For example, if you search for "*Broadway", you will get all the ones on Broadway.  Note that *Broadway and "*Broadway" might give you different results.  For example, the former will include a shape called 23 Broadway North (and all shapes with the word Broadway in it), but the latter will not.  You can also use spaces to signify a logical AND.  Here is the help page (look at the Search Field section at the bottom), but it's not quite up to date unfortunately.  I can only advise to just experiment with the wildcards and spaces at this point in time.

The Scene Editor 

BrianE
by
Occasional Contributor II

Thank you, this is very helpful. What about if I'd like to find two different addresses? For example, 123 Broadway and 456 Main Street? Is there a way to enter this into the Search Field so I can select both buildings at the same time?

0 Kudos
CherylLau
Esri Regular Contributor

Sorry, at this point in time, I don't think this is possible.  I don't think the logical OR is available in the search field.

If you want to write a python script though, you can probably do this.

0 Kudos
ThomasFuchs
Esri Regular Contributor

Here is an example of how to write a basic address search with GUI in Python:

from scripting import *

import org.eclipse.swt as swt
import org.eclipse.swt.widgets as widgets
import org.eclipse.swt.layout.RowLayout as layout

# get a CityEngine instance
ce = CE()

if __name__ == '__main__':

    result = None
    
    display = widgets.Display()
    
    shell = widgets.Shell(display)
    shell.pack()
    shell.open()
    
    dialog = widgets.Shell(shell, swt.SWT.DIALOG_TRIM | swt.SWT.APPLICATION_MODAL)
    dialog.setLayout(layout())
    dialog.setText("Address Search")
    
    names = []
    OIDs = []
    sceneShapes = ce.getObjectsFrom(ce.scene, ce.isShape)
    for s in sceneShapes:
        name = ce.getAttribute(s, 'name')
        if not (name == None) | (name == ""):
            names.append(name)
            OIDs.append(ce.getOID(s))
    
    searchName = widgets.Combo(dialog, swt.SWT.READ_ONLY)
    searchName.setItems(names)
    ok = widgets.Button(dialog, swt.SWT.PUSH)
    ok.setText ("OK")
    cancel = widgets.Button(dialog, swt.SWT.PUSH);
    cancel.setText("Cancel");
    
    class MyListener(widgets.Listener):
        def handleEvent(self, event):
            global result
            if event.widget == ok:
                result = searchName.getSelectionIndex()
            else:
                result = -1
            dialog.close()
    
    listener = MyListener()
    ok.addListener(swt.SWT.Selection, listener)
    cancel.addListener(swt.SWT.Selection, listener)
    
    dialog.pack()
    dialog.open()
    while not dialog.isDisposed():
        if not display.readAndDispatch():
            display.sleep ()

    display.dispose()

    if result>-1:
        print "Selection:", names[result]
        ce.setSelection(ce.findByOID(OIDs[result]))
        views = ce.getObjectsFrom(ce.get3DViews())
        views[0].frame(ce.selection())

You can add this script as a shortcut to CityEngine

0 Kudos
ThomasFuchs
Esri Regular Contributor

Updated the code snippet for creating an SWT dialog with Python in CityEngine

Tags (3)
0 Kudos
BrianE
by
Occasional Contributor II

Address Search

Thank you Thomas. That was super helpful. I was able to add the script.
Two questions:

Is there a way to choose multiple addresses?

Is there a way to display the addresses in numerical order?

Thanks!

0 Kudos
ThomasFuchs
Esri Regular Contributor

Q1: Is there a way to choose multiple addresses?

A1: You could add a second combo widget and set the names again:

from scripting import *

import org.eclipse.swt as swt
import org.eclipse.swt.widgets as widgets
import org.eclipse.swt.layout as layout

# get a CityEngine instance
ce = CE()

if __name__ == '__main__':

    result = None
    
    display = widgets.Display()
    
    shell = widgets.Shell(display)
    shell.pack()
    shell.open()
    
    dialog = widgets.Shell(shell, swt.SWT.DIALOG_TRIM | swt.SWT.APPLICATION_MODAL)
    dialog.setLayout(layout.RowLayout())
    dialog.setText("Address Search")
    
    names = []
    OIDs = []
    sceneShapes = ce.getObjectsFrom(ce.scene, ce.isShape)
    for s in sceneShapes:
        name = ce.getAttribute(s, 'name')
        if not (name == None) | (name == ""):
            names.append(name)
            OIDs.append(ce.getOID(s))
    
    searchName = widgets.Combo(dialog, swt.SWT.READ_ONLY)
    searchName.setItems(names)    
    searchName2 = widgets.Combo(dialog, swt.SWT.READ_ONLY)
    searchName2.setItems(names)
    ok = widgets.Button(dialog, swt.SWT.PUSH)
    ok.setText ("OK")
    cancel = widgets.Button(dialog, swt.SWT.PUSH);
    cancel.setText("Cancel");
    
    class MyListener(widgets.Listener):
        def handleEvent(self, event):
            global result, result2
            if event.widget == ok:
                result = searchName.getSelectionIndex()
                result2 = searchName2.getSelectionIndex()
            else:
                result = -1
            dialog.close()
    
    listener = MyListener()
    ok.addListener(swt.SWT.Selection, listener)
    cancel.addListener(swt.SWT.Selection, listener)
    
    dialog.pack()
    dialog.open()
    while not dialog.isDisposed():
        if not display.readAndDispatch():
            display.sleep ()

    display.dispose()

    if result>-1:
        print "Selection:", names[result], names[result2]
        ce.setSelection(ce.findByOID(OIDs[result]))
        if result2>-1:
            ce.setSelection([ce.findByOID(OIDs[result]), ce.findByOID(OIDs[result2])])
        views = ce.getObjectsFrom(ce.get3DViews())
        views[0].frame(ce.selection())

for more help on SWT widgets please visit: SWT Widgets 

Q2: Is there a way to display the addresses in numerical order?

A2: "names" is a list of of strings please refer Python data structure sort list alphabetically - Stack Overflow on how to sort such lists. You probably also want to cut away the street numbers prior to sorting: python - How to split a string into a list? - Stack Overflow 

0 Kudos
Giota_Zachariadou
New Contributor

Hi, I using the same code above so to select different land uses. In my case, I have multiple shapes with the same name (for example buildings, gardens, etc.) but when I choose one of the names, only one shape is chosen.

Giota_Zachariadou_0-1639679845646.png

 

Any idea? Thanks. 

 

0 Kudos