source: inundation/pmesh/mesh_interface.py @ 3183

Last change on this file since 3183 was 3183, checked in by duncan, 18 years ago

bug fixing

File size: 6.4 KB
Line 
1
2#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3# Assume that the root AnuGA dir (inundation) is included in your pythonpath
4#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5
6from coordinate_transforms.geo_reference import Geo_reference,DEFAULT_ZONE
7from utilities.polygon import  point_in_polygon ,populate_polygon
8from utilities.numerical_tools import ensure_numeric
9from Numeric import Float
10from utilities.polygon import inside_polygon
11
12# This is due to pmesh being a package and a module and
13# the current dir being unknown
14try:
15    from pmesh.mesh import Mesh
16except ImportError: 
17    from mesh import Mesh
18
19import exceptions
20class PolygonError(exceptions.Exception): pass
21
22def create_mesh_from_regions(bounding_polygon,
23                             boundary_tags,
24                             maximum_triangle_area,
25                             filename=None,
26                             interior_regions=None,
27                             poly_geo_reference=None,
28                             mesh_geo_reference=None,
29                             minimum_triangle_angle=28.0):
30    """Create mesh from bounding polygons, and resolutions.
31
32    bounding_polygon is a list of points in Eastings and Northings,
33    relative to the poly_geo_reference.
34
35    Boundary tags is a dictionary of symbolic tags. For every tag there
36    is a list of indices referring to segments associated with that tag
37
38    Resolution is the maximal area per triangle for the bounding polygon
39    (excluding interior regions, see later)
40
41    Interior_regions is a list of tuples consisting of (polygon, resolution)
42    for each region to be separately refined.
43
44    This function does not allow segments to share points - use underlying
45    pmesh functionality for that
46
47    poly_geo_reference is the geo_reference of the polygons.
48    The bounding polygon and the interior polygons
49    If none, assume absolute.  Please pass one though, since absolute
50    references have a zone.
51   
52    mesh_geo_reference is the geo_reference of the mesh to be created.
53    If none is given one will be automatically generated.  It was use
54    the lower left hand corner of  bounding_polygon (absolute)
55    as the x and y values for the geo_ref.
56   
57    Returns the mesh instance if no finename is given
58
59    Note, interior regions should be fully nested, as overlaps may cause
60    unintended resolutions.
61   
62    """
63    #FIXME (OLE-DSG)
64    # To do make maximum_triangle_area optional?
65    # check the segment indexes - throw an error if they are out of bounds
66    #(DSG) Yes!
67   
68    #In addition I reckon the polygons could be of class Geospatial_data
69    #(DSG) Yes!
70
71    # First check that interior polygons are fully contained in bounding polygon
72    #Note, Both poly's have the same geo_ref, therefore don't take into account
73    # geo_ref
74    if interior_regions is not None:       
75        # Test that all the interior polygons are inside the bounding_poly
76        for interior_polygon, res in interior_regions:
77            indices = inside_polygon(interior_polygon, bounding_polygon,
78                                     closed = True, verbose = False)
79   
80            if len(indices) <> len(interior_polygon): 
81                msg = 'Interior polygon %s is outside bounding polygon: %s'\
82                      %(str(interior_polygon), str(bounding_polygon))
83                raise PolygonError, msg
84
85
86
87    # Resolve geo referencing       
88    if mesh_geo_reference is None:
89        bounding_polygon = ensure_numeric(bounding_polygon, Float)
90        xllcorner = min(bounding_polygon[:,0])
91        yllcorner = min(bounding_polygon[:,1])   
92        #
93        if poly_geo_reference is None:
94            zone = DEFAULT_ZONE
95        else:
96            zone = poly_geo_reference.get_zone()
97            [(xllcorner,yllcorner)] = poly_geo_reference.get_absolute( \
98            [(xllcorner,yllcorner)])
99        # create a geo_ref, based on the llc of the bounding_polygon
100        mesh_geo_reference = Geo_reference(xllcorner = xllcorner,
101                                           yllcorner = yllcorner,
102                                           zone = zone)
103
104    m = Mesh(geo_reference=mesh_geo_reference)
105
106    # Do bounding polygon
107    m.add_region_from_polygon(bounding_polygon,
108                              tags=boundary_tags,
109                              geo_reference=poly_geo_reference)
110
111    # Find one point inside region automatically
112    if interior_regions is not None:
113        excluded_polygons = []       
114        for polygon, res in interior_regions:
115            excluded_polygons.append( polygon )
116    else:
117        excluded_polygons = None
118
119    from Numeric import array
120
121
122    # Convert bounding poly to absolute values
123    # this sort of thing can be fixed with the geo_points class
124    if poly_geo_reference is not None:
125        bounding_polygon_absolute = \
126            poly_geo_reference.get_absolute(bounding_polygon)
127    else:
128        bounding_polygon_absolute = bounding_polygon
129    # This isn't working it seems   
130    #[inner_point] = populate_polygon(bounding_polygon_absolute,
131    #                                 1, exclude = excluded_polygons)
132   
133    inner_point = point_in_polygon(bounding_polygon_absolute)
134    inner = m.add_region(inner_point[0], inner_point[1])
135    inner.setMaxArea(maximum_triangle_area)
136
137    # Do interior regions
138    if interior_regions is not None:   
139        for polygon, res in interior_regions:
140            m.add_region_from_polygon(polygon,
141                                      geo_reference=poly_geo_reference)
142            # convert bounding poly to absolute values
143            if poly_geo_reference is not None:
144                polygon_absolute = \
145                    poly_geo_reference.get_absolute(polygon)
146            else:
147                polygon_absolute = polygon
148            # This isn't working it seems   
149            #[inner_point] = populate_polygon(polygon_absolute, 1)
150            inner_point = point_in_polygon(polygon_absolute)
151            region = m.add_region(inner_point[0], inner_point[1])
152            region.setMaxArea(res)
153           
154
155    if filename is None:
156        return m
157    else:
158        m.generate_mesh(minimum_triangle_angle=minimum_triangle_angle,
159                        maximum_triangle_area=maximum_triangle_area)       
160        m.export_mesh_file(filename)
161
162
Note: See TracBrowser for help on using the repository browser.