Index: /inundation/pmesh/mesh.py
===================================================================
--- /inundation/pmesh/mesh.py	(revision 2296)
+++ /inundation/pmesh/mesh.py	(revision 2297)
@@ -598,4 +598,15 @@
         return h
    
+    def add_hole(self, x,y, geo_reference=None):
+        """
+        adds a point, which represents a hole.
+
+        The point data can have it's own geo_refernece.
+        If geo_reference is None the data is asumed to be absolute
+        """
+        [[x,y]] = self.geo_reference.change_points_geo_ref([x,y],
+                                                 points_geo_ref=geo_reference)
+        return self._addHole(x, y)
+
     def _addRegion(self, x,y):
         h=Region(x, y)
@@ -618,7 +629,8 @@
         print "depreciated, use add_region"
         return self.add_region(x,y)
-    
-    def add_region_from_polygon(self, polygon, tags=None,
-                                max_triangle_area=None, geo_reference=None):
+
+    
+    
+    def add_hole_from_polygon(self, polygon, tags=None, geo_reference=None):
         """
         Add a polygon with tags to the current mesh, as a region.
@@ -635,17 +647,61 @@
 
         This returns the region instance, so if the user whats to modify
+        it they can.       
+        """
+        return self._add_area_from_polygon(polygon, tags=tags,
+                                           hole=True,
+                                           geo_reference=geo_reference
+                                           )
+
+        
+    def add_region_from_polygon(self, polygon, tags=None,
+                                max_triangle_area=None, geo_reference=None):
+        """
+        Add a polygon with tags to the current mesh, as a region.
+        The maxArea of the region can be specified.
+
+        If a geo_reference of the polygon points is given, this is used.
+        If not;
+        The x,y info is assumed to be Easting and Northing, absolute,
+        for the meshes zone.
+
+        polygon a list of points, in meters that describe the polygon
+             (e.g. [[x1,y1],[x2,y2],...]
+        tags (e.g.{'wall':[0,1,3],'ocean':[2]})
+
+        This returns the region instance (if a max_triangle_area is given),
+        so if the user whats to modify it they can.     
+        """
+        return self._add_area_from_polygon(polygon, tags=tags,
+                                max_triangle_area=max_triangle_area,
+                                      geo_reference=geo_reference)
+        
+    def _add_area_from_polygon(self, polygon, tags=None,
+                                max_triangle_area=None,
+                               geo_reference=None,
+                               hole=False):
+        """
+        Add a polygon with tags to the current mesh, as a region.
+        The maxArea of the region can be specified.
+
+        If a geo_reference of the polygon points is given, this is used.
+        If not;
+        The x,y info is assumed to be Easting and Northing, absolute,
+        for the meshes zone.
+
+        polygon a list of points, in meters that describe the polygon
+             (e.g. [[x1,y1],[x2,y2],...]
+        tags (e.g.{'wall':[0,1,3],'ocean':[2]})
+
+        This returns the region instance, so if the user whats to modify
         it they can.
         
         """
-        #take into account georef on mesh side
-        #polygon = self.geo_reference.change_points_geo_ref(polygon,
-                         #                        points_geo_ref=geo_reference)
-        #print "polygon - should be relative to poly geo_ref",polygon 
-
         #get absolute values
         if geo_reference is not None:
             polygon = geo_reference.get_absolute(polygon)
         # polygon is now absolute
-        #print "polygon  should be absolute",polygon 
+        #print "polygon  should be absolute",polygon
+        
         #create points, segs and tags
         region_dict = {}
@@ -681,5 +737,5 @@
         inner = None
         
-        if max_triangle_area is not None:
+        if max_triangle_area is not None and hole is False:
             #get inner point - absolute values
             inner_point = point_in_polygon(polygon)
@@ -687,4 +743,10 @@
                                     geo_reference=None) 
             inner.setMaxArea(max_triangle_area)
+
+        if hole is True:
+            #get inner point - absolute values
+            inner_point = point_in_polygon(polygon)
+            inner = self.add_hole(inner_point[0], inner_point[1],
+                                    geo_reference=None) 
             
         return inner
@@ -744,5 +806,5 @@
     def generate_mesh(self,
                       maximum_triangle_area=None,
-                      minimum_triangle_angle=None,
+                      minimum_triangle_angle=28.0,
                       verbose=False):
         if verbose is True:
Index: /inundation/pmesh/test_mesh.py
===================================================================
--- /inundation/pmesh/test_mesh.py	(revision 2296)
+++ /inundation/pmesh/test_mesh.py	(revision 2297)
@@ -1793,4 +1793,62 @@
 
 
+    def test_add_hole_from_polygon(self):
+        x=-500
+        y=-1000
+        m=Mesh(geo_reference=Geo_reference(56,x,y))
+
+        # These are the absolute values
+        polygon_absolute = [[0,0],[1,0],[1,1],[0,1]]
+        
+        x_p = -10
+        y_p = -40
+        geo_ref_poly = Geo_reference(56, x_p, y_p)
+        polygon = geo_ref_poly.change_points_geo_ref(polygon_absolute)
+        
+        poly_point = m.add_hole_from_polygon(polygon,
+                                               {'tagin':[0,1],'bom':[2]},
+                                               geo_reference=geo_ref_poly)
+        # poly_point values are relative to the mesh geo-ref
+        # make them absolute
+        #print "poly_point.x+x",poly_point.x+x
+        #print "polygon_absolute", polygon_absolute 
+        self.failUnless(inside_polygon([poly_point.x+x,poly_point.y+y],
+                                       polygon_absolute, closed = False),
+                        'FAILED!')
+               
+        self.failUnless(len(m.holes)==1,
+                        'FAILED!')
+        segs = m.getUserSegments()
+        self.failUnless(len(segs)==4,
+                        'FAILED!')
+        self.failUnless(len(m.userVertices)==4,
+                        'FAILED!') 
+        self.failUnless(segs[0].tag=='tagin',
+                        'FAILED!')  
+        self.failUnless(segs[1].tag=='tagin',
+                        'FAILED!') 
+         
+        self.failUnless(segs[2].tag=='bom',
+                        'FAILED!') 
+        self.failUnless(segs[3].tag=='',
+                        'FAILED!')
+        verts = m.getUserVertices()
+        #print "User verts",verts
+        #print 'polygon',polygon
+        #vert values are relative
+        for point,new_point in map(None,polygon,verts):
+            point_x = point[0] + geo_ref_poly.get_xllcorner()
+            new_point_x = new_point.x + m.geo_reference.get_xllcorner()
+            point_y = point[1] + geo_ref_poly.get_yllcorner()
+            #print "new_point.y",new_point.y
+            #print "m.geo_ref.get_yllcorner()",m.geo_reference.get_yllcorner() 
+            new_point_y = new_point.y + m.geo_reference.get_yllcorner()
+            #print "point_y",point_y
+            #print "new_point_y",new_point_y 
+            
+            self.failUnless(point_x == new_point_x, ' failed')
+            self.failUnless(point_y == new_point_y, ' failed')
+            
+       
        
 def list_comp(A,B):
