Back to all posts

Example: Check existence of duplicate entities

This script example checks the existence of duplicate entities in a model layer or background layer. You can print and/or shift the duplicates.

Example

# edit layer name 'Conduits' in line 54 to your interested ayer name. 
# the layer can be model layer or background layer. For background layer, edit 'Name' in line 49 
# to an attribute name in the layer because it may not exist.

def get_key(entity):
  # create a key for each entity
  key = ''
  vertices = entity.Geometry.Vertices
  for vert in vertices:
    key += '%.3f-%.3f' % (vert.X, vert.Y)    # create a key with three decimals of each vertex X and Y
  return key
 
def find_duplicates(entities):
  # create a dictionary of the entities. key = tuple of the entity vertices, value = list of entity names
  dict_entity = {}
  for entity in entities:
    key = get_key(entity)
    if not key in dict_entity:
      dict_entity[key] = []
 
    # record the entity name for print. For background layer, use the name of an attribute with unique values
    dict_entity[key].append(entity)
  return dict_entity
 
def shift_duplicates(dict_entity, shift_distance=5):
  # shift the duplicate entities so you can easily select and edit them
  for key, value in dict_entity.iteritems():
    if len(value) > 1:   # value is a list and each element is a PyEntity
      for i in range(1, len(value)):    # no need to shift the first PyEntity (index 0)
        distance = i * shift_distance   # actual distance if multiple duplicates exist
        # add two vertices at both ends of the link
        vertices = list(value[i].Geometry.Vertices)
        new_vertices = []
        new_vertices.append( vertices[0] )
        new_vertices.append(pcpy.Vertex(vertices[0].X+distance, vertices[0].Y+distance))
        for k in range(1, len(vertices)-1):
          new_vertices.append(pcpy.Vertex(vertices[k].X+distance, vertices[k].Y+distance))
        new_vertices.append(pcpy.Vertex(vertices[-1].X+distance, vertices[-1].Y+distance))
        new_vertices.append( vertices[-1] )
        value[i].Geometry.Vertices = new_vertices
  pcpy.Map.refresh()

def print_duplicates(dict_entity):
  # print duplicate entities
  has_duplicate = False
  for key, value in dict_entity.iteritems():
    if len(value) > 1:
      has_duplicate = True
      names = [ entity['Name'] for entity in value ]
      print 'The following entities have the same geometry {0}'.format(names)
  if not has_duplicate:
    print 'There are no duplicate entities'
 
entities = pcpy.Map.Layer['Conduits'].get_entities()
dict_entity = find_duplicates(entities)
print_duplicates(dict_entity)
shift_duplicates(dict_entity)