def add_obj(obj, ui, josm, server): print "Add object in JOSM:", obj if type(obj) is not GpxWaypoint: ui.error(_("Only waypoints can be sent to JOSM")) return # Create an OSM XML file containing the desired point. fh = StringIO.StringIO() osm = OsmWriter(fh, "GPX Trip Planner") tags = sym_to_tags.get(obj.sym, {}) osm.new_node(obj.lat, obj.lon, tags) osm.save() osm_text = fh.getvalue() # Ask our internal HTTP server to dispense the text of the # OSM XML file when JOSM asks for it. The HTTP server gives us # the URL to pass to JOSM. temp_url = server.add_temp(osm_text) # Create a bounding box to describe a small area around the new point. bbox = BoundingBox() bbox.add_point(Point(obj.lat + 0.001, obj.lon - 0.001)) bbox.add_point(Point(obj.lat - 0.001, obj.lon + 0.001)) josm.cmd_zoom(bbox) josm.send_cmd("import", {'url': temp_url})
def __init__(self, bbox, properties=None, style=None): MapVectorObj.__init__(self, properties) self.orig_bbox = bbox self.geometry = Polygon(( Point(bbox.max_lat, bbox.min_lon), # NW Point(bbox.max_lat, bbox.max_lon), # NE Point(bbox.min_lat, bbox.max_lon), # SE Point(bbox.min_lat, bbox.min_lon), # SW )) self.style = {"line-width": 1, "line-dasharray": (3, 2)} if style is not None: self.style.update(style)
def do_viewport(self): lat, lon, zoom = self.containing_map.get_center_and_zoom() bbox = self.containing_map.get_bbox() # Download layer which overlays lines on roads. int_zoom = min(int(zoom + 0.5), 18) self.scale_factor = math.pow(2, zoom) / (1 << int_zoom) print "Traffic int_zoom:", int_zoom print "Traffic scale_factor:", self.scale_factor self.map_height = self.containing_map.height self.map_width = self.containing_map.width self.image_height = self.map_height / self.scale_factor self.image_width = self.map_width / self.scale_factor params = { 'key':self.app_key, 'projection':'merc', 'mapLat': str(lat), 'mapLng': str(lon), 'mapHeight': str(int(self.image_height)), 'mapWidth': str(int(self.image_width)), 'mapScale': self.scales[int_zoom], } url = "http://www.mapquestapi.com/traffic/v1/flow?%s" % urllib.urlencode(params) print "Traffic overlay URL:", url response = simple_urlopen(url, {}) content_length = int(response.getheader("content-length")) print "content-length:", content_length if content_length > 0: data = response.read() print "data length:", len(data) loader = gtk.gdk.PixbufLoader() loader.write(data) try: loader.close() # fails due to incomplete GIF except: pass self.traffic_overlay = surface_from_pixbuf(loader.get_pixbuf()) else: self.traffic_overlay = None # Download markers which indicate locations of construction or incidents params = { 'key':self.app_key, 'inFormat':'kvp', 'boundingBox':"%f,%f,%f,%f" % (bbox.max_lat, bbox.min_lon, bbox.min_lat, bbox.max_lon), } url = "http://www.mapquestapi.com/traffic/v1/incidents?%s" % urllib.urlencode(params) print "Traffic incidents URL:", url response = simple_urlopen(url, {}) self.incidents = json.loads(response.read()) print json.dumps(self.incidents, indent=4, separators=(',', ': ')) self.visible_objs = [] for incident in self.incidents['incidents']: x, y = self.containing_map.project_point(Point(incident['lat'], incident['lng'])) symbol_name = self.incident_symbols.get(incident['type'], "Dot") symbol = self.containing_map.symbols.get_symbol(symbol_name) renderer = symbol.get_renderer(self.containing_map) self.visible_objs.append([x, y, renderer, incident['shortDesc']])
def make_visible(self, lat, lon): self.feedback.debug(1, "make_visible(%f, %f)" % (lat, lon)) bbox = BoundingBox(self.get_bbox()) bbox.scale(0.9) point = Point(lat, lon) if not bbox.contains_point(point): bbox.add_point(point) self.zoom_to_extent(bbox)
def zoom_to_extent(self, bbox, padding=10, rotate_ok=False): self.feedback.debug( 1, "zoom_to_extent(bbox, padding=%d, rotate_ok=%s)" % (padding, str(rotate_ok))) center = bbox.center() if center: # If there is at least one point in the bbox, # Center on the bounding box and zoom to an arbitrarily selected level. lat, lon = center self.set_center_and_zoom(lat, lon, 16) # Figure out the size of the bounding box in pixels at this zoom level. p1 = Point(bbox.max_lat, bbox.min_lon) # top left p2 = Point(bbox.min_lat, bbox.max_lon) # bottom right p1x, p1y = self.project_point(p1) p2x, p2y = self.project_point(p2) width = (p2x - p1x) height = (p2y - p1y) # Avoid division by zero width = max(width, 1) height = max(height, 1) self.feedback.debug( 1, " extent pixel dimensions: %f x %f" % (width, height)) self.feedback.debug( 1, " map pixel dimensions: %f x %f" % (self.width, self.height)) if rotate_ok: if self.rotate: page_landscape = self.height > self.width else: page_landscape = self.width > self.height extent_landscape = width > height print " extent_landscape:", extent_landscape print " page_landscape:", page_landscape self.set_rotation(extent_landscape != page_landscape and self.oblongness(width, height) > 0.1) x_zoom_diff = math.log( float(width) / float(self.width - 2 * padding), 2) y_zoom_diff = math.log( float(height) / float(self.height - 2 * padding), 2) #print "x_zoom_diff:", x_zoom_diff #print "y_zoom_diff:", y_zoom_diff self.set_zoom(16 - max(x_zoom_diff, y_zoom_diff))
def do_viewport(self): map_bbox = self.containing_map.get_bbox() self.visible_objs = [] for shape in self.sf.shapes(): if shape.shapeType == 3: # polyline shape_bbox = BoundingBox(shape.bbox) if shape_bbox.overlaps(map_bbox): points = map(lambda p: Point(p[1], p[0]), shape.points) self.visible_objs.append(self.containing_map.project_points(points))
def place_polygon(place, bbox): polygonpoints = place.get('polygonpoints') if polygonpoints is not None: return Polygon(map(lambda i: Point(float(i[1]), float(i[0])), json.loads(polygonpoints)[:-1])) # Sometime around January 2011 Nominatim stopped returning polygons for some objects. # If there is no polygon, make one out of the bounding box. else: p = BoundingBox(bbox) p.scale(1.05) return p.as_polygon()
def set_marker(self, fix): pos_threshold = 360.0 / 256.0 / (2.0 ** self.containing_map.get_zoom()) if fix is None or self.fix is None \ or abs(fix.lat - self.fix.lat) >= pos_threshold \ or (abs(fix.lon - self.fix.lon) % 360.0) >= pos_threshold \ or (fix.heading is None != self.fix.heading is None) \ or (abs(fix.heading - self.fix.heading) % 360.0) >= 5.0 \ or abs(fix.speed - self.fix.speed) >= 1.0: print "GPS marker moved" self.fix = fix # If the marker is in the viewport (or just was), refresh layer. now_onscreen = self.containing_map.get_bbox().contains_point(Point(fix.lat, fix.lon)) if fix else False if now_onscreen or self.onscreen: self.set_stale() self.onscreen = now_onscreen
def snap_search(self, gdkevent, source_obj, enable, need_pt): if enable: for obj in self.visible_objs: if obj is not source_obj: snap = obj.snap_search(gdkevent) if snap is not None: #print "Snap:", gdkevent.x, gdkevent.y, map(str,snap) x, y, pt = snap if need_pt: return (x, y, Point(pt)) else: return (x, y, None) if need_pt: return (gdkevent.x, gdkevent.y, self.containing_map.unproject_point( gdkevent.x, gdkevent.y)) else: return (gdkevent.x, gdkevent.y, None)
def get_draggable_point(self, gdkevent): evpoint = (gdkevent.x, gdkevent.y) # Real points i = 0 for point in self.projected_points: if points_close(evpoint, point): return i i += 1 i = 0 # Phantom points for point in self.phantom_points: if points_close(evpoint, point): self.projected_points.insert( i + 1, self.phantom_points[i]) # make it a real point self.geometry.points.insert(i + 1, Point( 0.0, 0.0)) # FIXME: should be able to use None here return i + 1 i += 1 return None
def do_viewport(self): self.screen_gps_pos = None self.screen_gps_arrow = None # If GPSd has reported a result which includes location, find # the cooresponding pixel position on the canvas. if self.fix: self.screen_gps_pos = self.containing_map.project_point(Point(self.fix.lat, self.fix.lon)) # If a heading was reported, prepare to draw a vector. if self.fix.heading is not None: heading = math.radians(self.fix.heading) # If the speed is known, make the vector proportionally longer. if self.fix.speed: arrow_length = self.marker_radius + self.fix.speed else: arrow_length = self.marker_radius x, y = self.screen_gps_pos self.screen_gps_arrow = ( x + arrow_length * math.sin(heading), y - arrow_length * math.cos(heading) )
#! /usr/bin/python import sys sys.path.insert(1, "../..") import gobject import gtk from pykarta.geometry import Point from pykarta.maps.widget import MapWidget gobject.threads_init() window = gtk.Window() window.set_default_size(800, 800) window.connect('delete-event', lambda window, event: gtk.main_quit()) map_widget = MapWidget() map_widget.set_center_and_zoom(42.125, -72.75, 12) window.add(map_widget) window.show_all() # Make a bunch of points point = Point(42.00, -72.00) points = [] for i in range(10000): points.append(point) # Benchmark projection # Hatter: 300000 points/second import timeit print "Starting..." seconds = timeit.timeit('map_widget.project_points(points)', number=100, setup="from __main__ import map_widget, points") print "%d points/second" % (len(points) * 100 / seconds)
debug_level=0, ) window.add(map_widget) window.show_all() # The map has a set of SVG symbols which can be used by marker layers. # The set starts empty. This loads one symbol which will be used by # the vector layer which we create below to display markers. map_widget.symbols.add_symbol("Dot.svg") # Vector layer vector = MapLayerVector() map_widget.add_layer("vector-doodles", vector) vector.add_obj(MapVectorMarker(Point(42.125, -72.73), {"label": "a house"})) vector.add_obj( MapVectorLineString( Polygon([ Point(42.120, -72.80), Point(42.10, -72.73), Point(42.115, -72.745) ]))) vector.add_obj( MapVectorPolygon( Polygon( [Point(42.125, -72.75), Point(42.2, -72.75), Point(42.125, -72.8)])))
def do_viewport(self): print "Test layer: new viewport:", self.containing_map.get_bbox() # Project three points into tilespace points = (Point(42.125, -72.75), Point(42.125, -72.70), Point(42.10, -72.70)) self.points_projected = self.containing_map.project_points(points)
def unproject_point(self, x, y): tile_x = self.top_left_pixel[0] + x / 256.0 tile_y = self.top_left_pixel[1] + y / 256.0 return Point(unproject_from_tilespace(tile_x, tile_y, self.zoom))
def get_bbox(self): bbox = BoundingBox() for marker_group in self.markers.values(): for marker in marker_group: bbox.add_point(Point(marker.lat, marker.lon)) return bbox
def __init__(self, *args): self.points = [Point(*args)] self.bbox = None