def matchAlgo2(self, specialOne, qtree): bs = specialOne.getBounds() TL = Point(lon=bs.leftObj.lon, lat=bs.topObj.lat) BR = Point(lon=bs.rightObj.lon, lat=bs.bottomObj.lat) # Now shift the points by the threshold d = self.match_threshold_metres TL.move(-d, d) BR.move(d, -d) bs_ex = Bounds() bs_ex.registerPoint(TL) bs_ex.registerPoint(BR) # if not bs.overlaps(bt): # self.log.i("No overlap, skipping") # return (0, 0, 0) # Do a query on the qtree for all points in the range of the track # qtreeSub = qtree.queryRangeDebug(bs_ex) qtreeSub = qtree.queryRange(bs_ex) hit = miss = 0 waypoints = [] # Walk through the match track looking for the nearest point in other the track for point in specialOne.points_virtual(interpolate_thres_lower_metres, interpolate_thres_upper_metres): # min is the nearest waypoint, but may be be way of range min, found = point.findNearest4(qtreeSub) self.prePoint(point, found or min) d, wp = (None, None) # Make sure the point really is in range before calling foundPoint. # findNearest4 will always return something even if it is miles away if found: self.foundPoint(point, found) d, wp = found[0] if d and d < self.match_threshold_metres: hit += 1 ## waypoints.append(WayPoint(copyFrom=pt, name="hit %d" % hit, sym="Dot")) else: miss += 1 ## waypoints.append(WayPoint(copyFrom=pt, name="miss %d" % miss, sym="Anchor")) ## self.gpx.writeItem(track) ## for wp in waypoints: ## self.gpx.writeItem(wp) match_pct = hit / float(hit + miss) * 100 return (hit, miss, match_pct)
def subDivide(self): """Divide this region into four equal parts.""" log.dbg("/") L = self.bounds.left().lon R = self.bounds.right().lon T = self.bounds.top().lat B = self.bounds.bottom().lat MID = Point((R - L) / float(2), (T - B) / float(2)) # NW bounds = Bounds() bounds.registerPoint(MID) bounds.registerPoint(Point(L, T)) self.northWest = SegmentsQTree(bounds, self.size) # NE bounds = Bounds() bounds.registerPoint(MID) bounds.registerPoint(Point(R, T)) self.northEast = SegmentsQTree(bounds, self.size) # SW bounds = Bounds() bounds.registerPoint(MID) bounds.registerPoint(Point(L, B)) self.southWest = SegmentsQTree(bounds, self.size) # SE bounds = Bounds() bounds.registerPoint(MID) bounds.registerPoint(Point(R, B)) self.southEast = SegmentsQTree(bounds, self.size) # We don't bother reallocating the ones at this level into the children. # we just have to search current level before children return True
def __init__(self): super(WayPointGatherer, self).__init__() # Note if we used smaller bounds we would automatically exclude points for countries miles away # TODO OPT read the tracks first, work out the (extended) bounds and use for these bounds bounds = Bounds() bounds.registerPoint(Point(-90, -90)) bounds.registerPoint(Point(90, 90)) # Use a quad tree to store the points self.qtree = SegmentsQTree(bounds, 1000) self.distanceThreshold = 300
def __init__(self, bounds, size=5): # no idea what makes good max size before split self.northWest = self.northEast = self.southWest = self.southEast = None self.bounds = bounds # This acts like a filter. Only points within this range are allowed # OPT could also store the bounds that the points actually cover, as opposed to the total size of the box we are covering. # Each segment keeps track of the bounds of the points it contains self.bounds_of_my_points = Bounds() self.size = size self.segment = self.newSegment() # TODO can we hold our segment plus the other 4 in a Segments? Or will this just be too confusing... # it would help compatibility? self.isSplit = False
def queryPoint(self, p, distance_metres=10): """ Query the points around a given point """ bounds = Bounds() p1 = Point(copyFrom=p) p2 = Point(copyFrom=p) # Top right p1.move(distance_metres, distance_metres) # Bottom left p2.move(-distance_metres, -distance_metres) bounds.registerPoint(p1) bounds.registerPoint(p2) return self.queryRange(bounds)
def queryRangeDebugPrint(self, p1, p2): bounds = Bounds() bounds.registerPoint(p1) bounds.registerPoint(p2) return self.queryRangeDebug(bounds)
# Top right p1.move(distance_metres, distance_metres) # Bottom left p2.move(-distance_metres, -distance_metres) bounds.registerPoint(p1) bounds.registerPoint(p2) return self.queryRange(bounds) if __name__ == "__main__": """Just some test code to test the QTree""" # Cover the world bounds = Bounds() # bounds.registerPoint(Point(-90,-90)) # bounds.registerPoint(Point(90, 90)) bounds.registerPoint(Point(0, 0)) bounds.registerPoint(Point(10, 10)) sqt = SegmentsQTree(bounds, 5) for i in range(0, 10): p = Point(i, i) sqt.addPoint(p) # Add a duplicate point sqt.addPoint(Point(5, 5)) sqt.queryRangeDebugPrint(Point(0, 0), Point(20, 20))
def endElement(self, name): if self.content: # print("have full content of type", type(self.content), self.content) content = self.content.strip() # content = self.content.strip().encode('ascii', 'ignore') # this screws up on python3 # print("have full content ENCODED of type", type(content), content) else: content = None obj = self.selectObj() # Handle the content if self.location[:2] == ["gpx", "trk"]: if self.location == ["gpx", "trk"]: [observer.nextTrack(self.track) for observer in self.observers] self.track = None elif self.location == ["gpx", "trk", "name"]: obj.name = content elif self.location == ["gpx", "trk", "type"]: obj.type = content elif self.location == ["gpx", "trk", "trkseg"]: [ observer.nextTrackSegment(self.track.currentSegment) for observer in self.observers ] self.track.endSegment() elif self.location == ["gpx", "trk", "trkseg", "trkpt"]: self.track.addPoint(self.tp) [ observer.nextTrackPoint(self.tp) for observer in self.observers ] self.tp = None elif self.location == [ "gpx", "trk", "trkseg", "trkpt", "extensions", "gpxtpx:TrackPointExtension", "gpxtpx:hr" ]: self.tp.hr = int(content) elif self.location == [ "gpx", "trk", "trkseg", "trkpt", "extensions", "gpxtpx:TrackPointExtension", "gpxtpx:cad" ]: self.tp.cad = int(content) elif self.location == ["gpx", "trk", "trkseg", "trkpt", "time"]: # print("yContent is type", type(content)) # print("yContent value is", content) self.tp.setTime(content) elif self.location == ["gpx", "trk", "trkseg", "trkpt", "ele"]: if content: # print("xContent is type", type(content)) # print("xContent value is", content) self.tp.elevation = float(content) elif self.location[:2] == ['gpx', 'wpt']: if self.location == ['gpx', 'wpt']: [ observer.nextWayPoint(self.wayPoint) for observer in self.observers ] self.wayPoint = None elif self.location == ["gpx", "wpt", "name"]: obj.name = content elif self.location == ["gpx", "wpt", "cmt"]: obj.comment = content else: pass elif self.location[:2] == ['gpx', 'rte']: if self.location == ['gpx', 'rte']: [observer.nextRoute(self.route) for observer in self.observers] self.route = None elif self.location == ['gpx', 'rte', 'name']: self.route.name = content elif self.location == ["gpx", "rte", "rtept"]: self.route.addPoint(self.rp) [ observer.nextRoutePoint(self.rp) for observer in self.observers ] elif self.location == ["gpx", "rte", "rtept", "sym"]: self.rp.sym = content elif self.location == ["gpx", "rte", "rtept", "type"]: self.rp.type = content elif self.location == ['gpx']: pass elif self.location == ["gpx", "metadata", "bounds"]: minlat = self.attrs.getValue("minlat") minlon = self.attrs.getValue("minlon") maxlat = self.attrs.getValue("maxlat") maxlon = self.attrs.getValue("maxlon") bounds = Bounds() bounds.registerPoint(Point(minlon, minlat)) bounds.registerPoint(Point(maxlon, maxlat)) [observer.haveBounds(bounds) for observer in self.observers] elif self.location[:2] == ["gpx", "metadata"]: # elif self.location == ["gpx", "metadata", "time"]: pass else: self.log.i("IGNORED: %s, content: %s" % (self.location, content)) self.content = None self.location.pop()