def pack_shape_scale_binary(self, plot=False): # TODO: select one of the base_shapes randomly # TODO: use bounding circle for first pass # https://www.nayuki.io/res/smallest-enclosing-circle/smallestenclosingcircle.py center = self.random_point() base = self.base_shapes[0] ph = np.random.random() * 2 * np.pi R = np.matrix([[np.cos(ph), -np.sin(ph)], [np.sin(ph), np.cos(ph)]]) rbase = [b * R for b in base] if plot: self.plot_border() plt.plot(center[:, 0], center[:, 1], 'k.') hc, = plt.plot([], [], 'k-') # binary search on scale to find best fit thresh = .001 lo = 0 r = .001 hi = np.inf while True: transformed = [[(r * b + center).tolist(), []] for b in rbase] # a = [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)] # b = [(1, 1), (1, 2), (2, 2), (2, 1), (1, 1)] # mp = MultiPolygon([[a, []], [b, []]]) p = MultiPolygon(transformed) intersected = False for shape in self.shapes: if p.intersects(shape): intersected = True break if intersected: # too big, reduce size and adjust range hi = r r = (lo + r) / 2 else: # too small, increase size lo = r if hi == np.inf: # keep doubling while we haven't yet hit a neighboring shape r = 2*r else: r = (r + hi) / 2 if plot: cc = arc(center, r) hc.set_xdata(cc[:, 0]) hc.set_ydata(cc[:, 1]) plt.show(block=False) # plt.pause(.01) if hi - lo <= thresh: break # print(' radius = %f' % r) self.shapes.append(p)
def insert_randomly(self, grain_object: PySALEObject, max_attempts: int = 100) -> bool: """Insert object into the host at random locations until it fits "fits" means - "is not intersecting with any other objects." Parameters ---------- grain_object : PySALEObject max_attempts : int The number of attempts the algorithm will make before giving up Returns ------- success : bool """ assert type(max_attempts) == int and max_attempts > 0,\ f'Maximum number of attempts ' \ f'MUST be a positive integer and not {max_attempts}' minx, miny, maxx, maxy = self.object.bounds if not self.object.has_children: intersects_with_other_shapes = False else: intersects_with_other_shapes = True is_within_domain = False mp = MultiPolygon(self.object.children) counter = 0 success = False while intersects_with_other_shapes \ or is_within_domain is not True: grain_object = self._move_object_to_random_coordinate_in_domain( grain_object, maxx, maxy, minx, miny) is_within_domain = self.object.contains(grain_object) intersects_with_other_shapes = mp.intersects(grain_object) counter += 1 if counter >= max_attempts: warnings.warn(f'Max insertion attempts ' f'reached ({max_attempts}). ' f'Object can not be placed.') success = False break else: success = True if is_within_domain and not intersects_with_other_shapes: self.object.add_child(grain_object) return success
class VehiclesEmissions(EmissionsBase): hp2num = { 'Menys 8 cf': 3, '8 a 8,9': 8.5, '9 a 9,9': 9.5, '10 a 10,9': 10.5, '11 a 11,9': 11.5, '12 a 12,9': 12.5, '13 a 13,9': 13.5, '14 a 14,9': 14.5, '15 a 15,9': 15.5, '16 a 19,9': 18, '20 i més cf': 25, 'No consta': 5 } total_emissions = 4930000000.0 close_nbrs = 3 def __init__(self): self.cars = download_csv_dataset('est-vehicles-potencia-fiscal-turismes') self.neighborhoods = get_neighborhoods() limits = get_city_limits() self.city_limits = MultiPolygon([Polygon(g[0]) for g in limits]) self.nbr2emi = {} for index, car in self.cars.iterrows(): nbr_id = car['Codi_Barri'] if not nbr_id in self.nbr2emi: self.nbr2emi[nbr_id] = 0 self.nbr2emi[nbr_id] += self.hp2num[car['Potencia_fiscal']] * car['Nombre_turismes'] def prepare_grid(self, min_lat, min_lon, lat_bins, lon_bins, bin_size): self.emis_grid = np.zeros((lat_bins, lon_bins), dtype=float) for i in range(lat_bins): for j in range(lon_bins): lat = min_lat + bin_size * (i + 0.5) lon = min_lon + bin_size * (j + 0.5) if self.city_limits.intersects(Point(lon, lat)): nbrs = [] for index, nbr in self.neighborhoods.iterrows(): dist = geopy.distance.vincenty((lat, lon), (nbr['lat'], nbr['lon'])).km nbrs.append((index, 1.0 / dist)) nbrs.sort(key=lambda n: n[1], reverse=True) nbrs = nbrs[:self.close_nbrs] s = sum([n[1] for n in nbrs]) self.emis_grid[i][j] = np.sum([self.nbr2emi[n[0]] * n[1] / s for n in nbrs]) s = np.sum(self.emis_grid) self.emis_grid = self.total_emissions * self.emis_grid / s def get_emission(self, i, j, lat, lon): return self.emis_grid[i][j]
def intersectIslands(self, paths, islands: List[Island]) -> Tuple[Any, Any]: """ Perform the intersection and overlap tests on the island sub regions. This should be performed before any clipping operations are performed. :param paths: List of coordinates describing the boundary :param islands: A list of Islands to have the intersection and overlap test :return: A tuple containing lists of clipped and unClipped islands """ polys = [] for path in paths: polys += pathsToClosedPolygons(path) poly = MultiPolygon(polys) intersectIslands = [] overlapIslands = [] intersectIslandsSet = set() overlapIslandsSet = set() for i in range(len(islands)): island = islands[i] s = island.boundary() if poly.overlaps(s): overlapIslandsSet.add(i) # id overlapIslands.append(island.boundary) island.setRequiresClipping(True) if poly.intersects(s): intersectIslandsSet.add(i) # id intersectIslands.append(island.boundary) island.setIntersecting(True) unTouchedIslandSet = intersectIslandsSet - overlapIslandsSet unTouchedIslands = [islands[i] for i in unTouchedIslandSet] return overlapIslandsSet, unTouchedIslandSet
# Python sets are used to perform boolean operations on a set to identify unclipped islands intersectIslandsSet = set() overlapIslandsSet = set() # Iterate across all the islands for i in range(len(islands)): island = islands[i] s = island.boundary() if poly.overlaps(s): overlapIslandsSet.add(i) # id overlapIslands.append(island) if poly.intersects(s): intersectIslandsSet.add(i) # id intersectIslands.append(island) unTouchedIslandSet = intersectIslandsSet - overlapIslandsSet unTouchedIslands = [islands[i] for i in unTouchedIslandSet] print('Finished Island Clipping') fig, ax = pyslm.visualise.plotPolygon(geomSlice) # Plot using visualise.plotPolygon the original islands generated before intersection for island in islands: x, y = island.boundary().exterior.xy pyslm.visualise.plotPolygon([np.vstack([x, y]).T], handle=(fig, ax))
# first, calculate a bounding box to restrict the diagram min_x = min(stops_pts[:,0]) - 5000 max_x = max(stops_pts[:,0]) + 5000 min_y = min(stops_pts[:,1]) - 5000 max_y = max(stops_pts[:,1]) + 5000 bbox = np.array([[min_x,min_y], [max_x,max_y], [min_x,max_y], [max_x,min_y]]) # find the voronoi coords = np.vstack([stops_pts, bbox]) vor = Voronoi(coords) # rearrange, so that regions are in the same order as their corresponding # points, so the last four are the bbox dummy observations, and remove them regions = np.array(vor.regions)[vor.point_region] regions = regions[:-4] clipped = [] for region in regions: region_vertices = vor.vertices[region] region_polygon = Polygon(region_vertices) if nyc.intersects(region_polygon): clipped.append(nyc.intersection(region_polygon)) clipped = GeoSeries(clipped) stops = GeoDataFrame(stops) stops.index = np.arange(stops.shape[0]) stops['region'] = clipped pickle.dump(stops,open('save/stops.p','wb')) pickle.dump(nyc,open('save/nyc.p','wb'))
def ReadMossPolygons(mossBaseFileName, printDiagnostic=False): ''' .ms1 file is fixed format Header lines 56 characters char 1-5 : Item Number(NEGATIVE IF THE COORDINATES ARE LON/LAT) char 16-45: Attribute Name char 51-55: Number of coord. pairs X,Y, Coordinate pairs 23 characters 01-11: x coordinate 12-22: y coordinate Long,Lat pairs char 01-10: LONGITUDE char 11-20: LATITUDE char 21-22: FLAG 0-NORMAL 1-INDICATES FIRST POINT OF ISLAND POLYGON ''' # import shapely here so it won't be imported if not needed from shapely.geometry import Polygon, MultiPolygon # what about MAPBOUND, EXTENDEDOUTLOOKTHREAT attributesToRead = [ "MAPLAND", "FORECASTHEAVY", "FORECASTMEDIUM", "FORECASTLIGHT", "FORECASTUNCERTAINTY" ] landBoundariesList = [] heavyBoundariesList = [] mediumBoundariesList = [] lightBoundariesList = [] uncertaintyBoundariesList = [] extension = ".ms1" if os.path.exists(mossBaseFileName + extension): inFile = file(mossBaseFileName + extension, 'rU') alreadyReadNextLine = False while True: # read the header lines if not alreadyReadNextLine: line = inFile.readline() alreadyReadNextLine = False if not line: break # end of this file if line.strip() == "": continue # blank line itemNum = int(line[0:5]) assert itemNum < 0 # we expect long/lat values, so the itemNum should be negative attributeName = line[15:45].strip() numCoordinates = int(line[50:55]) # note: for some versions of GNOME analyst # the number of coordinates in MAPLAND overflows and is reported as a negative number or incorrect number. # To support those files, we will ignore the number and just read lines based on the length of the lines if printDiagnostic: print itemNum, attributeName, numCoordinates readingOuterBoundary = True coordList = [] outerBoundary = None innerBoundaries = [] if numCoordinates <= 0: print "*** ignoring bad %s header line value: numCoordinates: %d ***" % ( attributeName, numCoordinates) # read the points for the polygon for this header while True: #for i in range(0,numCoordinates): # since we don't want to rely on numCoordinates # we need to look to see if this is the end of this block of coordinates ################## line = inFile.readline() # The lines are fixed format, # read until we find a header line # header lines lines are longer than coordinate lines if (not line) or len(line.strip( )) > 50: # must be end of file or a header line alreadyReadNextLine = True break # out of this while loop if attributeName in attributesToRead: #process this line longitudeStr = line[0:10].strip() latitudeStr = line[10:20].strip() flag = line[20:22].strip() if flag == "1": #then we are starting a new "inner hole" # enforce having the last point of the polygon equal the first point if len(coordList ) > 0 and coordList[0] != coordList[-1]: coordList.append(coordList[0]) # save the previous coordList if len( coordList ) >= 4: # less than 4 would be a degenerate case if readingOuterBoundary: outerBoundary = coordList else: innerBoundaries.append(coordList) # reset the coordinate list coordList = [] readingOuterBoundary = False coordList.append((float(longitudeStr), float(latitudeStr))) ############# end of while loop # finished reading the header # record the lists we have filled in if not attributeName in attributesToRead: continue # on to the next header line # enforce having the last point of the polygon equal the first point if len(coordList) > 0 and coordList[0] != coordList[-1]: coordList.append(coordList[0]) #filter out degenerate cases if len(coordList) < 4: # less than 4 would be a degenerate case print "*** ignoring degenerate polygon ***" continue # on to the next header line # save the coordinate list if readingOuterBoundary: outerBoundary = coordList else: innerBoundaries.append(coordList) #save thisPolygon if len(outerBoundary) > 0: # outerBoundary,innerBoundaries = VerifyAndFixGnomeAnalystPolygon(attributeName,outerBoundary,innerBoundaries) if len(outerBoundary) > 0: thisPolygon = (outerBoundary, innerBoundaries) if attributeName == "MAPLAND": landBoundariesList.append(thisPolygon) elif attributeName == "FORECASTHEAVY": heavyBoundariesList.append(thisPolygon) elif attributeName == "FORECASTMEDIUM": mediumBoundariesList.append(thisPolygon) elif attributeName == "FORECASTLIGHT": lightBoundariesList.append(thisPolygon) elif attributeName == "FORECASTUNCERTAINTY": uncertaintyBoundariesList.append(thisPolygon) inFile.close() # convert the lists of MossPolygons to shapely MultiPolygons if len(landBoundariesList) == 0: landPolygons = None else: landPolygons = MultiPolygon(landBoundariesList) if not landPolygons.is_valid: # try analysing and fixing the problem landPolygons = DiagnoseAndFixMultiPolygon("MAPLAND", landBoundariesList) if len(heavyBoundariesList) == 0: heavyPolygons = None else: heavyPolygons = MultiPolygon(heavyBoundariesList) if not heavyPolygons.is_valid: heavyPolygons = DiagnoseAndFixMultiPolygon("FORECASTHEAVY", heavyBoundariesList) if len(mediumBoundariesList) == 0: mediumPolygons = None else: mediumPolygons = MultiPolygon(mediumBoundariesList) if not mediumPolygons.is_valid: mediumPolygons = DiagnoseAndFixMultiPolygon( "FORECASTMEDIUM", mediumBoundariesList) if len(lightBoundariesList) == 0: lightPolygons = None else: lightPolygons = MultiPolygon(lightBoundariesList) if not lightPolygons.is_valid: lightPolygons = DiagnoseAndFixMultiPolygon("FORECASTLIGHT", lightBoundariesList) if len(uncertaintyBoundariesList) == 0: uncertaintyPolygons = None else: uncertaintyPolygons = MultiPolygon(uncertaintyBoundariesList) if not uncertaintyPolygons.is_valid: uncertaintyPolygons = DiagnoseAndFixMultiPolygon( "FORECASTUNCERTAINTY", uncertaintyBoundariesList) # clip the oil contours to the shoreline # note: we need to check that the polygons are valid before trying to clip to prevent shapely from crashing if landPolygons != None: if landPolygons.is_valid == False: print "*** landPolygons is not valid. We will not clip to the shoreline. ***" else: if heavyPolygons != None: if heavyPolygons.is_valid == False: print "*** heavyPolygons is not valid. It will not be clipped to the shoreline. ***" elif heavyPolygons.intersects(landPolygons): print "clipping heavyPolygons to shoreline" heavyPolygons = heavyPolygons.difference(landPolygons) if mediumPolygons != None: if mediumPolygons.is_valid == False: print "*** mediumPolygons is not valid. It will not be clipped to the shoreline. ***" elif mediumPolygons.intersects(landPolygons): print "clipping mediumPolygons to shoreline" mediumPolygons = mediumPolygons.difference(landPolygons) if lightPolygons != None: if lightPolygons.is_valid == False: print "*** lightPolygons is not valid. It will not be clipped to the shoreline. ***" elif lightPolygons.intersects(landPolygons): print "clipping lightPolygons to shoreline" lightPolygons = lightPolygons.difference(landPolygons) # note: JerryM wonders we should clip the uncertainty to the shoreline. That it looks better as simple polygons going over the land. if uncertaintyPolygons != None: if uncertaintyPolygons.is_valid == False: print "*** uncertaintyPolygons is not valid. It will not be clipped to the shoreline or oil polygons ***" else: print "clipping uncertaintyPolygons to shoreline and oil polygons" for polygons, nameOfPolygons in [ (lightPolygons, "lightPolygons"), (mediumPolygons, "mediumPolygons"), (heavyPolygons, "heavyPolygons"), (landPolygons, "landPolygons") ]: if polygons != None: print "taking difference with", nameOfPolygons newUncertaintyPolygons = uncertaintyPolygons.difference( polygons) print "finished taking difference" if not newUncertaintyPolygons.is_valid: #print "Uncertainty Polygon is no longer valid after taking difference with",polygons,nameOfPolygons s = "*** uncertaintyPolygons have not been clipped to %s ***" % ( nameOfPolygons) print s else: uncertaintyPolygons = newUncertaintyPolygons return (landPolygons, heavyPolygons, mediumPolygons, lightPolygons, uncertaintyPolygons)
min_x = min(stops_pts[:, 0]) - 5000 max_x = max(stops_pts[:, 0]) + 5000 min_y = min(stops_pts[:, 1]) - 5000 max_y = max(stops_pts[:, 1]) + 5000 bbox = np.array([[min_x, min_y], [max_x, max_y], [min_x, max_y], [max_x, min_y]]) # find the voronoi coords = np.vstack([stops_pts, bbox]) vor = Voronoi(coords) # rearrange, so that regions are in the same order as their corresponding # points, so the last four are the bbox dummy observations, and remove them regions = np.array(vor.regions)[vor.point_region] regions = regions[:-4] clipped = [] for region in regions: region_vertices = vor.vertices[region] region_polygon = Polygon(region_vertices) if nyc.intersects(region_polygon): clipped.append(nyc.intersection(region_polygon)) clipped = GeoSeries(clipped) stops = GeoDataFrame(stops) stops.index = np.arange(stops.shape[0]) stops['region'] = clipped pickle.dump(stops, open('save/stops.p', 'wb')) pickle.dump(nyc, open('save/nyc.p', 'wb'))
def ReadMossPolygons(mossBaseFileName, printDiagnostic = False): ''' .ms1 file is fixed format Header lines 56 characters char 1-5 : Item Number(NEGATIVE IF THE COORDINATES ARE LON/LAT) char 16-45: Attribute Name char 51-55: Number of coord. pairs X,Y, Coordinate pairs 23 characters 01-11: x coordinate 12-22: y coordinate Long,Lat pairs char 01-10: LONGITUDE char 11-20: LATITUDE char 21-22: FLAG 0-NORMAL 1-INDICATES FIRST POINT OF ISLAND POLYGON ''' # import shapely here so it won't be imported if not needed from shapely.geometry import Polygon, MultiPolygon # what about MAPBOUND, EXTENDEDOUTLOOKTHREAT attributesToRead = ["MAPLAND","FORECASTHEAVY","FORECASTMEDIUM","FORECASTLIGHT","FORECASTUNCERTAINTY"] landBoundariesList = [] heavyBoundariesList = [] mediumBoundariesList = [] lightBoundariesList = [] uncertaintyBoundariesList = [] extension = ".ms1" if os.path.exists(mossBaseFileName + extension): inFile = file(mossBaseFileName + extension, 'rU') alreadyReadNextLine = False while True: # read the header lines if not alreadyReadNextLine: line = inFile.readline() alreadyReadNextLine = False if not line: break # end of this file if line.strip() == "" : continue; # blank line itemNum = int(line[0:5]) assert itemNum < 0 # we expect long/lat values, so the itemNum should be negative attributeName = line[15:45].strip() numCoordinates = int(line[50:55]) # note: for some versions of GNOME analyst # the number of coordinates in MAPLAND overflows and is reported as a negative number or incorrect number. # To support those files, we will ignore the number and just read lines based on the length of the lines if printDiagnostic: print itemNum,attributeName,numCoordinates readingOuterBoundary = True coordList = [] outerBoundary = None innerBoundaries = [] if numCoordinates <= 0: print "*** ignoring bad %s header line value: numCoordinates: %d ***"%(attributeName,numCoordinates) # read the points for the polygon for this header while True: #for i in range(0,numCoordinates): # since we don't want to rely on numCoordinates # we need to look to see if this is the end of this block of coordinates ################## line = inFile.readline() # The lines are fixed format, # read until we find a header line # header lines lines are longer than coordinate lines if (not line) or len(line.strip()) > 50 : # must be end of file or a header line alreadyReadNextLine = True break # out of this while loop if attributeName in attributesToRead: #process this line longitudeStr = line[0:10].strip() latitudeStr = line[10:20].strip() flag = line[20:22].strip() if flag == "1" : #then we are starting a new "inner hole" # enforce having the last point of the polygon equal the first point if len(coordList) > 0 and coordList[0] != coordList[-1]: coordList.append(coordList[0]) # save the previous coordList if len(coordList) >= 4: # less than 4 would be a degenerate case if readingOuterBoundary: outerBoundary = coordList else: innerBoundaries.append(coordList) # reset the coordinate list coordList = [] readingOuterBoundary = False coordList.append((float(longitudeStr),float(latitudeStr))) ############# end of while loop # finished reading the header # record the lists we have filled in if not attributeName in attributesToRead: continue # on to the next header line # enforce having the last point of the polygon equal the first point if len(coordList) > 0 and coordList[0] != coordList[-1]: coordList.append(coordList[0]) #filter out degenerate cases if len(coordList) < 4: # less than 4 would be a degenerate case print "*** ignoring degenerate polygon ***" continue # on to the next header line # save the coordinate list if readingOuterBoundary: outerBoundary = coordList else: innerBoundaries.append(coordList) #save thisPolygon if len (outerBoundary) > 0 : # outerBoundary,innerBoundaries = VerifyAndFixGnomeAnalystPolygon(attributeName,outerBoundary,innerBoundaries) if len (outerBoundary) > 0 : thisPolygon = (outerBoundary,innerBoundaries) if attributeName == "MAPLAND": landBoundariesList.append(thisPolygon) elif attributeName == "FORECASTHEAVY": heavyBoundariesList.append(thisPolygon) elif attributeName == "FORECASTMEDIUM": mediumBoundariesList.append(thisPolygon) elif attributeName == "FORECASTLIGHT": lightBoundariesList.append(thisPolygon) elif attributeName == "FORECASTUNCERTAINTY": uncertaintyBoundariesList.append(thisPolygon) inFile.close() # convert the lists of MossPolygons to shapely MultiPolygons if len(landBoundariesList) == 0: landPolygons = None else: landPolygons = MultiPolygon(landBoundariesList) if not landPolygons.is_valid: # try analysing and fixing the problem landPolygons = DiagnoseAndFixMultiPolygon("MAPLAND",landBoundariesList) if len(heavyBoundariesList) == 0: heavyPolygons = None else: heavyPolygons = MultiPolygon(heavyBoundariesList) if not heavyPolygons.is_valid: heavyPolygons =DiagnoseAndFixMultiPolygon("FORECASTHEAVY",heavyBoundariesList) if len(mediumBoundariesList) == 0: mediumPolygons = None else: mediumPolygons = MultiPolygon(mediumBoundariesList) if not mediumPolygons.is_valid: mediumPolygons = DiagnoseAndFixMultiPolygon("FORECASTMEDIUM",mediumBoundariesList) if len(lightBoundariesList) == 0: lightPolygons = None else: lightPolygons = MultiPolygon(lightBoundariesList) if not lightPolygons.is_valid: lightPolygons = DiagnoseAndFixMultiPolygon("FORECASTLIGHT",lightBoundariesList) if len(uncertaintyBoundariesList) == 0: uncertaintyPolygons = None else: uncertaintyPolygons = MultiPolygon(uncertaintyBoundariesList) if not uncertaintyPolygons.is_valid: uncertaintyPolygons = DiagnoseAndFixMultiPolygon("FORECASTUNCERTAINTY",uncertaintyBoundariesList) # clip the oil contours to the shoreline # note: we need to check that the polygons are valid before trying to clip to prevent shapely from crashing if landPolygons != None : if landPolygons.is_valid == False: print "*** landPolygons is not valid. We will not clip to the shoreline. ***" else : if heavyPolygons != None: if heavyPolygons.is_valid == False: print "*** heavyPolygons is not valid. It will not be clipped to the shoreline. ***" elif heavyPolygons.intersects(landPolygons): print "clipping heavyPolygons to shoreline" heavyPolygons = heavyPolygons.difference(landPolygons) if mediumPolygons != None: if mediumPolygons.is_valid == False: print "*** mediumPolygons is not valid. It will not be clipped to the shoreline. ***" elif mediumPolygons.intersects(landPolygons): print "clipping mediumPolygons to shoreline" mediumPolygons = mediumPolygons.difference(landPolygons) if lightPolygons != None: if lightPolygons.is_valid == False: print "*** lightPolygons is not valid. It will not be clipped to the shoreline. ***" elif lightPolygons.intersects(landPolygons): print "clipping lightPolygons to shoreline" lightPolygons = lightPolygons.difference(landPolygons) # note: JerryM wonders we should clip the uncertainty to the shoreline. That it looks better as simple polygons going over the land. if uncertaintyPolygons != None: if uncertaintyPolygons.is_valid == False: print "*** uncertaintyPolygons is not valid. It will not be clipped to the shoreline or oil polygons ***" else: print "clipping uncertaintyPolygons to shoreline and oil polygons" for polygons,nameOfPolygons in [(lightPolygons,"lightPolygons"),(mediumPolygons,"mediumPolygons"),(heavyPolygons,"heavyPolygons"),(landPolygons,"landPolygons")]: if polygons != None: print "taking difference with",nameOfPolygons newUncertaintyPolygons = uncertaintyPolygons.difference(polygons) print "finished taking difference" if not newUncertaintyPolygons.is_valid: #print "Uncertainty Polygon is no longer valid after taking difference with",polygons,nameOfPolygons s = "*** uncertaintyPolygons have not been clipped to %s ***"%(nameOfPolygons) print s else: uncertaintyPolygons = newUncertaintyPolygons return (landPolygons,heavyPolygons,mediumPolygons,lightPolygons,uncertaintyPolygons)