Changeset 5764e38 in osmose-backend


Ignore:
Timestamp:
Jan 27, 2013 6:19:15 PM (7 years ago)
Author:
Frédéric Rodrigo <frodrigo@…>
Branches:
master
Children:
1e21a9e
Parents:
451a5ec
Message:

Rewrite polygon clipping, speedup

Location:
modules
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • modules/OsmoseErrorFile.py

    recca6f1 r5764e38  
    3434            try: 
    3535                self.filter = PolygonErrorFilter(config.polygon_id) 
    36             except: 
     36            except Exception, e: 
     37                print e 
    3738                pass 
    3839        self.geom_type_renderer = {"node": self.node, "way": self.way, "relation": self.relation, "position": self.position} 
  • modules/OsmoseErrorFile_ErrorFilter.py

    r8e089e6 r5764e38  
    2323from shapely.geometry import Point 
    2424from modules import downloader 
     25from interval_tree import IntervalTree 
    2526 
    2627 
     
    4041            s = s.split(";", 1)[1] 
    4142        self.polygon = loads(s) 
     43        self.build() 
     44 
     45    def sameVDir(self, x1, y1, x2, y2, x3, y3): 
     46        # Check if next segment have same direction again vertical. 
     47        if y1 < y2: 
     48            return y2 < y3 
     49        else: 
     50            return y2 > y3 
     51 
     52    class Interval: 
     53        def __init__(self, x1, y1, x2, y2, sameDir): 
     54            # Need for IntervalTree 
     55            self.start = min(y1,y2) 
     56            self.stop = max(y1,y2) 
     57            # Segment 
     58            self.x1 = x1 
     59            self.x2 = x2 
     60            self.y1 = y1 
     61            self.y2 = y2 
     62            self.sameDir = sameDir 
     63 
     64    def build_polygon(self, coords): 
     65        (x,y) = coords.xy 
     66        n = len(x) 
     67        ivals = [] 
     68        for i in range(n): 
     69            ivals.append(self.Interval(x[i], y[i], x[(i+1)%n], y[(i+1)%n], self.sameVDir(x[i], y[i], x[(i+1)%n], y[(i+1)%n], x[(i+2)%n], y[(i+2)%n]))) 
     70        return ivals 
     71 
     72    def build(self): 
     73        ivals = [] 
     74        for p in self.polygon: 
     75            ivals += self.build_polygon(p.exterior.coords) 
     76            for i in p.interiors: 
     77                ivals += self.build_polygon(i.coords) 
     78        self.tree = IntervalTree(ivals) 
     79 
     80    def point_inside_polygon(self, x, y): 
     81        poly = self.tree.find(y, y) 
     82        inside = False 
     83 
     84        for p in poly: 
     85            if p.y1 != p.y2: 
     86                if p.y2 != y or p.sameDir: # This is a true cross and not a tangent 
     87                    xinters = (y-p.y1)*(p.x2-p.x1)/(p.y2-p.y1)+p.x1 
     88                    if x < xinters: 
     89                        inside = not inside 
     90            elif x <= max(p.x1, p.x2): 
     91                inside = not inside 
     92 
     93        return inside 
    4294 
    4395    def apply(self, classs, subclass, geom): 
     
    49101                lat = float(position["lat"]) 
    50102                lon = float(position["lon"]) 
    51                 pt = Point((lon, lat)) 
    52                 inside |= self.polygon.intersects(pt) 
     103                inside |= self.point_inside_polygon(lon, lat) 
    53104            return inside 
Note: See TracChangeset for help on using the changeset viewer.