Beispiel #1
0
 def tile_box(self):
     """ Expands the bounding box to the next even tile box.
     
     If the previously calculated box of tiles is smaller than the window size
     tiles are added until the box is larger than the window size
     
     @returns: the geographic coordinates of the bounding box of the displayed tiles
     @rtype: [min_lon, min_lat, max_lon, max_lat]
     """ 
     (min_x, max_y), (max_x, min_y) = self.__tiles_zoom_level
     while self.__d_tiles_x * TILE_SIZE < self.__window_width:
         self.__d_tiles_x += 1 #: stores the number of displayed tiles in x-direction
         max_x += 1
     while self.__d_tiles_y * TILE_SIZE < self.__window_height:
         self.__d_tiles_y += 1 #: stores the number of displayed tiles in y-direction
         min_y += 1
     
     # recalculate the tiles that will be displayed
     self.__tiles_zoom_level = [(min_x, max_y), (max_x, min_y)]
     # calculate the geographic coordinates of the edges
     s1, w1, n1, e1 = tileEdges(min_x, max_y, self.__zoom_level)
     s2, w2, n2, e2 = tileEdges(max_x, min_y, self.__zoom_level)
     
     # calculate the expansion of the displayed tiles in pixels
     self.__box_pixel = (self.__d_tiles_x * TILE_SIZE, self.__d_tiles_y * TILE_SIZE) #: pixel size of the box spanned by the displayed tiles (width, height)
     return [w1, s2, e2, n1]
Beispiel #2
0
def genInfoFile(tileCollection):
    infoFileName = tileCollection.getMapName(" ") + ".info"
    print("Writing info file to", infoFileName)

    # S lat, W lon, N lat, E lon
    startCornerCoords = tilenames.tileEdges(tileCollection.tileStartX, tileCollection.tileStartY, tileCollection.zoom)
    endCornerCoords = tilenames.tileEdges(tileCollection.tileEndX, tileCollection.tileEndY, tileCollection.zoom)

    latStartCorner, lonStartCorner = startCornerCoords[2], startCornerCoords[1]  # Get's north-west tile start lat & lon
    latEndCorner, lonEndCorner = endCornerCoords[0], endCornerCoords[3]  # Get's south-east tile end lat & lon

    infoFile = open(infoFileName, "w")
    print("// Generated with Anaxi Tile Downloader", file=infoFile)
    print("lat_north=", latStartCorner, file=infoFile)
    print("lat_south=", latEndCorner, file=infoFile)
    print("lon_east=", lonEndCorner, file=infoFile)
    print("lon_west=", lonStartCorner, file=infoFile)
    print("tileStartX=", tileCollection.tileStartX, file=infoFile)
    print("tileStartY=", tileCollection.tileStartY, file=infoFile)
    print("tileEndX=", tileCollection.tileEndX, file=infoFile)
    print("tileEndY=", tileCollection.tileEndY, file=infoFile)
    print("zoom=", tileCollection.zoom, file=infoFile)
    print("numTiles=", len(tileCollection.tiles), file=infoFile)
    print("mapFile=", tileCollection.getMapName(), file=infoFile)
    print("cmd=", " ".join(sys.argv), file=infoFile)
Beispiel #3
0
def GetOsmTileData(z,x,y):
  """Download OSM data for the region covering a slippy-map tile"""
  if(x < 0 or y < 0 or z < 0 or z > 25):
    print("Disallowed (%d,%d) at zoom level %d" % (x, y, z))
    return
  
  directory = 'cache/%d/%d/%d' % (z,x,y)
  filename = '%s/data.osm.pkl' % (directory)
  if(not os.path.exists(directory)):
    os.makedirs(directory)

  if(z == DownloadLevel()):
    # Download the data
    s,w,n,e = tileEdges(x,y,z)
    # /api/0.6/map?bbox=left,bottom,right,top
    URL = 'http://api.openstreetmap.org/api/0.6/map?bbox={},{},{},{}'.format(w,s,e,n)

     
    if(not os.path.exists(filename)): # TODO: allow expiry of old data
      urlretrieve(URL, filename)
    return(filename)
    
  elif(z > DownloadLevel()):
    # use larger tile
    while(z > DownloadLevel()):
      z = z - 1
      x = int(x / 2)
      y = int(y / 2)
    return(GetOsmTileData(z,x,y))
  return(None)
Beispiel #4
0
def GetOsmTileData(z, x, y):
    """Download OSM data for the region covering a slippy-map tile"""
    if (x < 0 or y < 0 or z < 0 or z > 25):
        print("Disallowed (%d,%d) at zoom level %d" % (x, y, z))
        return

    directory = 'cache/%d/%d/%d' % (z, x, y)
    filename = '%s/data.osm.pkl' % (directory)
    if (not os.path.exists(directory)):
        os.makedirs(directory)

    if (z == DownloadLevel()):
        # Download the data
        s, w, n, e = tileEdges(x, y, z)
        # /api/0.6/map?bbox=left,bottom,right,top
        URL = 'http://api.openstreetmap.org/api/0.6/map?bbox={},{},{},{}'.format(
            w, s, e, n)

        if (not os.path.exists(filename)):  # TODO: allow expiry of old data
            urlretrieve(URL, filename)
        return (filename)

    elif (z > DownloadLevel()):
        # use larger tile
        while (z > DownloadLevel()):
            z = z - 1
            x = int(x / 2)
            y = int(y / 2)
        return (GetOsmTileData(z, x, y))
    return (None)
Beispiel #5
0
 def get_tile_coordinates(self, lat, lon):
     """ Gets for a point given by its geographic coordinates the geographic coordinates of the edges
     of the tile this point lies in.
     
     @param lat: Geographic latitude of a point
     @param lon: Geographic longitude of a point
     @returns: Geographic coordinates of the edges of the corresponding tile
     @rtype: (min_lat, min_lon, max_lat, max_lon)
     """
     x, y = tileXY(lat, lon, self.__zoom_level)
     return tileEdges(x, y, self.__zoom_level) # S, W, N, E
Beispiel #6
0
        def draw_tile_box(x, y):
            """
            Draws the slippy map tile x, y on the screen
            """
            
            key = (self.zoom_level,x,y)
            # Read tile from disk if not in memory cache
            if self.tiles.has_key(key):
                t = self.tiles[key]
            else:
                t = Tile(x, y, self.zoom_level)
                t.load()
                self.tiles[key] = t

            edges = tilenames.tileEdges(x, y, self.zoom_level)
            offsetlat = edges[2]-focus[0]  # North edge offset
            offsetlong = edges[1]-focus[1] # West edge offset
            self.tileheight_deg = edges[2]-edges[0]
            self.tilewidth_deg = edges[3]-edges[1]

            px = int(offsetlong / self.tilewidth_deg * 256)
            py = int(-offsetlat / self.tileheight_deg * 256)

            self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL],
                    t.pixbuf, 0, 0, w/2 + int(px), h/2 + int(py) )
            
            """
            Adding placemark icons from the database and removing them when user is moving the map
            """      
            if (self.draw_icons == True):
                self.dbobjects = self.get_objects_from_db()
                
                
                #if (self.i % 20 == 0):
                for e in self.dbobjects:
                                        
                    (f,g) = self._coord_to_pixel(e.long,e.lat)                    
                    if e.__class__ == Mission:
                        
                        if (e.status != 3):
                            self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.mission_pic, 0, 0, int(f), int(g)-10,19,33)
                            
                    if e.__class__ == Placemark:
                        if (e.type == 1):
                            self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.obstacle_pic, 0, 0, int(f), int(g),29,29)
                        if (e.type == 2):
                            self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.water_pic, 0, 0, int(f), int(g),29,29)    
                        if (e.type == 3):
                            self.window.draw_pixbuf(self.get_style().fg_gc[gtk.STATE_NORMAL], self.power_pic, 0, 0, int(f), int(g),29,29)    
                self.i = self.i-1  
Beispiel #7
0
 def get_coord_by_position_in_tile(self, tile_x, tile_y, x, y):
     """ Calculates for the pixel coordinates of a point within a tile the corresponding geographic cordinates
     
     @type tile_x: C{int}
     @param tile_x: slippy map tilename in x direction
     @type tile_y: C{int}
     @param tile_y: slippy map tilename in y direction
     @type x: C{int}
     @param x: x coordinate within the tile
     @type y: C{int}
     @param y: y coordinate within the tile
     @returns: Geographic coordinates of the point as a tuple (lat, lon)
     @rtype: C{lat, lon)}
     """
     s, w, n, e = tileEdges(tile_x, tile_y, self.__zoom_level)
     lat = y * (s - n) / TILE_SIZE + n
     lon = x * (e - w) / TILE_SIZE + w
     return (lat, lon)
Beispiel #8
0
        def draw_tile_box(x, y):
            edges = tilenames.tileEdges(x, y, self.zoom_level)
            #print edges
            offsetlat = edges[0]-focus[0]
            offsetlong = edges[1]-focus[1]
            self.tileheight_deg = edges[2]-edges[0]

            self.context.rectangle(
                    offsetlong / self.tilewidth_deg * 256,
                    offsetlat / self.tileheight_deg * 256,
                    256,
                    256)
            self.context.fill()

            self.context.move_to(
                    offsetlong / self.tilewidth_deg * 256 + 128,
                    offsetlat / self.tileheight_deg * 256 + 128)
            self.context.set_source_rgb(0, 0, 0)
            self.context.set_font_size(12)
            self.context.show_text("%s, %s" % (x, y))
Beispiel #9
0
def GetOsmTileData(z, x, y):
    """Download OSM data for the region covering a slippy-map tile"""
    if x < 0 or y < 0 or z < 0 or z > 25:
        print "Disallowed %d,%d at %d" % (x, y, z)
        return

    directory = "cache/%d/%d/" % (z, x)
    filename = "%s/%s.png" % (directory, y)
    if not os.path.exists(directory):
        os.makedirs(directory)

    (S, W, N, E) = tileEdges(x, y, z)

    # Download the data
    # URL = 'http://dev.openstreetmap.org/~ojw/api/?/map/%d/%d/%d' % (z,x,y)
    # URL = 'http://map02.eniro.com/geowebcache/service/tms1.0.0/map/%s/%s/%s.png' % (z,x,y)
    # URL = 'http://%s/api/0.6/map?bbox=%f,%f,%f,%f' % ('api.openstreetmap.org',W,S,E,N)
    URL = "http://c.tile.openstreetmap.org/%s/%s/%s.png" % (z, x, y)
    print URL

    if not os.path.exists(filename):  # TODO: allow expiry of old data
        print "Downloading %d/%d/%d from network" % (z, x, y)
        urlretrieve(URL, filename)
    return filename
Beispiel #10
0
def pdfer(data, page_size='letter'):
    overlays = data.get('overlays')
    grid = {'zoom': data.get('zoom')}
    center_lon, center_lat = data['center']
    center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon),
                                          int(data['zoom']))
    dim_across, dim_up = data['dimensions']
    if dim_across > dim_up:
        page_height, page_width, tiles_up, tiles_across = PAGE_SIZES[page_size]
        orientation = 'landscape'
    else:
        page_width, page_height, tiles_across, tiles_up = PAGE_SIZES[page_size]
        orientation = 'portrait'
    min_tile_x = center_tile_x - (tiles_across / 2)
    min_tile_y = center_tile_y - (tiles_up / 2)
    max_tile_x = min_tile_x + tiles_across
    max_tile_y = min_tile_y + tiles_up
    links = []
    for ty in range(min_tile_y, max_tile_y + 1):
        for tx in range(min_tile_x, max_tile_x + 1):
            links.append(
                'http://a.tiles.mapbox.com/v3/datamade.hnmob3j3/{0}/{1}/{2}.png'
                .format(grid['zoom'], tx, ty))
    names = dl_write_all(links)
    now = datetime.now()
    date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S')
    outp_name = os.path.join('/tmp', '{0}.png'.format(date_string))
    image_names = ['-'.join(l.split('/')[-3:]) for l in names]
    image_names = sorted([i.split('-') for i in image_names])
    arrays = []
    for k, g in groupby(image_names, key=itemgetter(4)):
        images = list(g)
        fnames = ['/tmp/%s' % ('-'.join(f)) for f in images]
        array = []
        for img in fnames:
            array.append(cv2.imread(img))
        arrays.append(np.vstack(array))
    outp = np.hstack(arrays)
    cv2.imwrite(outp_name, outp)
    for parts in image_names:
        parts = parts[3:]
        parts[-1] = parts[-1].rstrip('.png')
        key = '-'.join(parts[-3:])
        grid[key] = {
            'bbox': tileEdges(float(parts[1]), float(parts[2]), int(parts[0]))
        }
    d = {}
    keys = sorted(grid.keys())
    if overlays:
        polys = []
        for k, v in grid.items():
            try:
                one, two, three, four = grid[k]['bbox']
                polys.append(box(two, one, four, three))
            except TypeError:
                pass
        mpoly = MultiPolygon(polys)
        bb_poly = box(*mpoly.bounds)
        min_key = keys[0]
        max_key = keys[-2]
        bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1]
        bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3]
        bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy)
        bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy)
        bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx, bmin_my,
                                                   float(grid['zoom']))
        bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx, bmax_my,
                                                   float(grid['zoom']))
        bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px, bmin_py,
                                                   int(grid['zoom']))
        im = cairo.ImageSurface.create_from_png(outp_name)
        ctx = cairo.Context(im)
        for beat_overlay in overlays.get('beat_overlays'):
            color = hex_to_rgb('#7B3294')
            boundary = requests.get(
                'http://crimearound.us/data/beats/%s.geojson' % beat_overlay)
            if boundary.status_code == 200:
                coords = boundary.json()['coordinates'][0]
                x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx,
                                        bmin_ry)
                ctx.move_to(x, y)
                ctx.set_line_width(4.0)
                for p in coords[1:]:
                    x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                    red, green, blue = [float(c) for c in color]
                    ctx.set_source_rgba(red / 255, green / 255, blue / 255,
                                        0.7)
                    ctx.line_to(x, y)
                ctx.close_path()
                ctx.stroke()
        if overlays.get('shape_overlay'):
            shape_overlay = overlays['shape_overlay']
            color = hex_to_rgb('#f06eaa')
            coords = shape_overlay['coordinates'][0]
            x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry)
            ctx.move_to(x, y)
            ctx.set_line_width(4.0)
            red, green, blue = [float(c) for c in color]
            ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.3)
            for p in coords[1:]:
                x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                ctx.line_to(x, y)
            ctx.close_path()
            ctx.fill()
            ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.5)
            for p in coords[1:]:
                x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                ctx.line_to(x, y)
            ctx.close_path()
            ctx.stroke()
        ctx.set_line_width(2.0)
        for point_overlay in overlays.get('point_overlays'):
            color = hex_to_rgb(point_overlay['color'])
            for p in point_overlay['points']:
                if p[0] and p[1]:
                    pt = Point((float(p[0]), float(p[1])))
                    if bb_poly.contains(pt):
                        nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx,
                                                  bmin_ry)
                        red, green, blue = [float(c) for c in color]
                        ctx.set_source_rgba(red / 255, green / 255, blue / 255,
                                            0.6)
                        ctx.arc(nx, ny, 5.0, 0,
                                50)  # args: center-x, center-y, radius, ?, ?
                        ctx.fill()
                        ctx.arc(nx, ny, 5.0, 0, 50)
                        ctx.stroke()
        im.write_to_png(outp_name)
    scale = 1
    pdf_name = outp_name.rstrip('.png') + '.pdf'
    pdf = cairo.PDFSurface(pdf_name, page_width, page_height)
    ctx = cairo.Context(pdf)
    image = cairo.ImageSurface.create_from_png(outp_name)
    ctx.set_source_surface(image, 0, 0)
    ctx.paint()
    pdf.finish()
    return pdf_name
Beispiel #11
0
def pdfer(data, page_size=PAGE_SIZES['letter']):
    overlays = data.get('overlays')
    grid = {'zoom': data.get('zoom')}
    center_lon, center_lat = data['center']
    center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon), int(data['zoom']))
    dim_across, dim_up = data['dimensions']
    if dim_across > dim_up:
        page_height, page_width, tiles_up, tiles_across = page_size
        orientation = 'landscape'
    else:
        page_width, page_height, tiles_across, tiles_up = page_size
        orientation = 'portrait'
    min_tile_x = center_tile_x - (tiles_across / 2)
    min_tile_y = center_tile_y - (tiles_up / 2)
    max_tile_x = min_tile_x + tiles_across
    max_tile_y = min_tile_y + tiles_up
    links = []
    for ty in range(min_tile_y, max_tile_y + 1):
        for tx in range(min_tile_x, max_tile_x + 1):
            links.append('http://a.tiles.mapbox.com/v3/datamade.hnmob3j3/{0}/{1}/{2}.png'.format(grid['zoom'], tx, ty))
    names = dl_write_all(links)
    now = datetime.now()
    date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S')
    outp_name = os.path.join('/tmp', '{0}.png'.format(date_string))
    image_names = ['-'.join(l.split('/')[-3:]) for l in names]
    image_names = sorted([i.split('-') for i in image_names])
    arrays = []
    for k,g in groupby(image_names, key=itemgetter(4)):
        images = list(g)
        fnames = ['/tmp/%s' % ('-'.join(f)) for f in images]
        array = []
        for img in fnames:
            array.append(cv2.imread(img))
        arrays.append(np.vstack(array))
    outp = np.hstack(arrays)
    cv2.imwrite(outp_name, outp)
    for parts in image_names:
        parts = parts[3:]
        parts[-1] = parts[-1].rstrip('.png')
        key = '-'.join(parts[-3:])
        grid[key] = {'bbox': tileEdges(float(parts[1]),float(parts[2]),int(parts[0]))}
    d = {}
    keys = sorted(grid.keys())
    if overlays:
        polys = []
        for k,v in grid.items():
            try:
                one,two,three,four = grid[k]['bbox']
                polys.append(box(two, one, four, three))
            except TypeError:
                pass
        mpoly = MultiPolygon(polys)
        bb_poly = box(*mpoly.bounds)
        min_key = keys[0]
        max_key = keys[-2]
        bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1]
        bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3]
        bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy)
        bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy)
        bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx,bmin_my,float(grid['zoom']))
        bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx,bmax_my,float(grid['zoom']))
        bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px,bmin_py,int(grid['zoom']))
        im = cairo.ImageSurface.create_from_png(outp_name)
        ctx = cairo.Context(im)
        for beat_overlay in overlays.get('beat_overlays'):
            color = hex_to_rgb('#7B3294')
            boundary = requests.get('http://crimearound.us/data/beats/%s.geojson' % beat_overlay)
            if boundary.status_code == 200:
                coords = boundary.json()['coordinates'][0]
                x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry)
                ctx.move_to(x,y)
                ctx.set_line_width(4.0)
                for p in coords[1:]:
                    x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                    red, green, blue = [float(c) for c in color]
                    ctx.set_source_rgba(red/255, green/255, blue/255, 0.7)
                    ctx.line_to(x,y)
                ctx.close_path()
                ctx.stroke()
        if overlays.get('shape_overlay'):
            shape_overlay = overlays['shape_overlay']
            color = hex_to_rgb('#f06eaa')
            coords = shape_overlay['coordinates'][0]
            x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry)
            ctx.move_to(x,y)
            ctx.set_line_width(4.0)
            red, green, blue = [float(c) for c in color]
            ctx.set_source_rgba(red/255, green/255, blue/255, 0.3)
            for p in coords[1:]:
                x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                ctx.line_to(x,y)
            ctx.close_path()
            ctx.fill()
            ctx.set_source_rgba(red/255, green/255, blue/255, 0.5)
            for p in coords[1:]:
                x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                ctx.line_to(x,y)
            ctx.close_path()
            ctx.stroke()
        ctx.set_line_width(2.0)
        for point_overlay in overlays.get('point_overlays'):
            color = hex_to_rgb(point_overlay['color'])
            for p in point_overlay['points']:
                if p[0] and p[1]:
                    pt = Point((float(p[0]), float(p[1])))
                    if bb_poly.contains(pt):
                        nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                        red, green, blue = [float(c) for c in color]
                        ctx.set_source_rgba(red/255, green/255, blue/255, 0.6)
                        ctx.arc(nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ?
                        ctx.fill()
                        ctx.arc(nx, ny, 5.0, 0, 50)
                        ctx.stroke()
        im.write_to_png(outp_name)
    scale = 1
    pdf_name = outp_name.rstrip('.png') + '.pdf'
    pdf = cairo.PDFSurface(pdf_name, page_width, page_height)
    ctx = cairo.Context(pdf)
    image = cairo.ImageSurface.create_from_png(outp_name)
    ctx.set_source_surface(image, 0, 0)
    ctx.paint()
    pdf.finish()
    return pdf_name
Beispiel #12
0
def processTileParams(prefs):
    tileStartX, tileStartY = tilenames.tileXY(prefs.latStart, prefs.lonStart, prefs.zoom, True)
    tileEndX, tileEndY = tilenames.tileXY(prefs.latEnd, prefs.lonEnd, prefs.zoom, True)

    # Sort the numbers low to high
    if tileStartY > tileEndY:
        tileStartY, tileEndY = tileEndY, tileStartY

    if tileStartX > tileEndX:
        tileStartX, tileEndX = tileEndX, tileStartX

    tileStartX, tileStartY = math.floor(tileStartX), math.floor(tileStartY)
    tileEndX, tileEndY = math.ceil(tileEndX), math.ceil(tileEndY)

    # S lat, W lon, N lat, E lon
    startCornerCoords = tilenames.tileEdges(tileStartX, tileStartY, prefs.zoom)
    endCornerCoords = tilenames.tileEdges(tileEndX, tileEndY, prefs.zoom)

    latStartCorner, lonStartCorner = startCornerCoords[2], startCornerCoords[1]  # Get's north-west tile start lat & lon
    latEndCorner, lonEndCorner = endCornerCoords[0], endCornerCoords[3]  # Get's south-east tile end lat & lon

    print("Starting at North-West corner: [" + str(latStartCorner) + ", " + str(lonStartCorner) + "]")
    print("Ending at South-East corner: [" + str(latEndCorner) + ", " + str(lonEndCorner) + "]")

    print("Downloading X tiles", tileStartX, "through", tileEndX)
    print("Downloading Y tiles", tileStartY, "through", tileEndY)

    print("Downloading a total of", abs(tileEndX - tileStartX + 1) * abs(tileEndY - tileStartY + 1), "tiles")

    print("Each tile at this zoom will be ~", str(tilenames.horozontalDistance(latStartCorner, prefs.zoom)), "meters wide")

    if prefs.dryRun:
        try:
            checkPilInstalled()
        except (ImportError, ModuleNotFoundError) as e:
            print("PIL is not installed, image stitching will not be supported")

        print("Dry run, exiting now...")
        return 0

    if not os.path.exists(prefs.name):
        os.mkdir(prefs.name)

    os.chdir(prefs.name)

    tileCol = TileCollection(tileStartX, tileStartY, tileEndX, tileEndY, prefs.zoom, prefs.tileServer, prefs.name)

    if not os.path.exists("raw"):
        os.mkdir("raw")

    os.chdir("raw")

    downloadErr = tileCol.downloadTiles(prefs.forceDownload)
    if downloadErr == 0:
        print("Download Complete!")
        if not prefs.noStitch:
            print("Stitching images...")
            stitchResult = tileCol.stitchImages(prefs.stitchFormat)
            if stitchResult["err"] == 0:
                os.rename(stitchResult["imageName"], "../" + stitchResult["imageName"])
                os.chdir("..")
                return genInfoFile(tileCol)

    return downloadErr
Beispiel #13
0
def pdfer(data, page_size=PAGE_SIZES['letter'], output='pdf'):
    
    shape_overlays = data.get('shape_overlays')
    point_overlays = data.get('point_overlays')

    grid = {'zoom': data.get('zoom')}
    center_lon, center_lat = data['center']
    center_tile_x, center_tile_y = tileXY(float(center_lat), 
                                          float(center_lon), 
                                          int(data['zoom']))

    dim_across, dim_up = data['dimensions']
    
    if dim_across > dim_up:
        page_height, page_width, tiles_up, tiles_across = page_size
    else:
        page_width, page_height, tiles_across, tiles_up = page_size
    
    min_tile_x = center_tile_x - (tiles_across / 2)
    min_tile_y = center_tile_y - (tiles_up / 2)
    max_tile_x = min_tile_x + tiles_across
    max_tile_y = min_tile_y + tiles_up

    # Get base layer tiles
    base_pattern = 'http://d.tile.stamen.com/toner/{z}/{x}/{y}.png'
    if data.get('base_tiles'):
        base_pattern = data['base_tiles']

    base_links = generateLinks(base_pattern, 
                               grid['zoom'], 
                               min_tile_x, 
                               min_tile_y, 
                               max_tile_x, 
                               max_tile_y)

    base_names = dl_write_all(base_links, 'base')
    
    # Get overlay tiles
    overlay_pattern = None
    if data.get('overlay_tiles'):
        overlay_pattern = data['overlay_tiles']
        overlay_links = generateLinks(overlay_pattern, 
                                      grid['zoom'], 
                                      min_tile_x, 
                                      min_tile_y, 
                                      max_tile_x, 
                                      max_tile_y)

        overlay_names = dl_write_all(overlay_links, 'overlay')

    now = datetime.now()
    date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S')
    outp_name = os.path.join('/tmp', '{0}.png'.format(date_string))
    base_image_names = ['-'.join(l.split('/')[-3:]) for l in base_names]
    base_image_names = sorted([i.split('-')[-3:] for i in base_image_names], key=itemgetter(1))
    
    for parts in base_image_names:
        z,x,y = parts
        y = y.rstrip('.png').rstrip('.jpg')
        z = z.rsplit('_', 1)[1]
        key = '-'.join([z,x,y])
        grid[key] = {'bbox': tileEdges(float(x),float(y),int(z))}
    
    keys = sorted(grid.keys())
    
    mercator = GlobalMercator()
    bb_poly = None
    
    bmin_rx = None
    bmin_ry = None

    if shape_overlays or point_overlays:
        polys = []
        for k,v in grid.items():
            try:
                one,two,three,four = grid[k]['bbox']
                polys.append(box(two, one, four, three))
            except TypeError:
                pass
        mpoly = MultiPolygon(polys)
        bb_poly = box(*mpoly.bounds)
        min_key = keys[0]
        max_key = keys[-2]
        bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1]
        bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3]
        bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy)
        bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy)
        bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx,bmin_my,float(grid['zoom']))
        bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx,bmax_my,float(grid['zoom']))
        bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px,bmin_py,int(grid['zoom']))
        
        if shape_overlays:
            all_polys = []
            for shape_overlay in shape_overlays:
                shape_overlay = json.loads(shape_overlay)
                if shape_overlay.get('geometry'):
                    shape_overlay = shape_overlay['geometry']
                coords = shape_overlay['coordinates'][0]
                all_polys.append(Polygon(coords))
            mpoly = MultiPolygon(all_polys)
            
            one, two, three, four, five = list(box(*mpoly.bounds).exterior.coords)
            
            left, right = LineString([one, two]), LineString([three, four])
            top, bottom = LineString([two, three]), LineString([four, five])

            left_to_right = left.distance(right)
            top_to_bottom = top.distance(bottom)

            if left_to_right > top_to_bottom:
                page_height, page_width, _, _ = page_size
            else:
                page_width, page_height, _, _ = page_size

            center_lon, center_lat = list(mpoly.centroid.coords)[0]


        if point_overlays:
            all_points = []
            
            for point_overlay in point_overlays:
                point_overlay = json.loads(point_overlay)
                for p in point_overlay['points']:
                    if p[0] and p[1]:
                        all_points.append(p)
            
            mpoint = MultiPoint(all_points)
            center_lon, center_lat = list(mpoint.centroid.coords)[0]
            
            one, two, three, four, five = list(box(*mpoint.bounds).exterior.coords)
            
            left, right = LineString([one, two]), LineString([three, four])
            top, bottom = LineString([two, three]), LineString([four, five])

            left_to_right = left.distance(right)
            top_to_bottom = top.distance(bottom)

            if left_to_right > top_to_bottom:
                page_height, page_width, _, _ = page_size
            else:
                page_width, page_height, _, _ = page_size
            
            center_lon, center_lat = list(mpoint.centroid.coords)[0]

            print(center_lon, center_lat)
        
    arrays = []
    for k,g in groupby(base_image_names, key=itemgetter(1)):
        images = list(g)
        fnames = ['/tmp/%s' % ('-'.join(f)) for f in images]
        array = []
        for img in fnames:
            i = cv2.imread(img, -1)
            if isinstance(i, type(None)):
                i = np.zeros((256,256,4), np.uint8)
            elif i.shape[2] != 4:
                i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA)
            array.append(i)
        arrays.append(np.vstack(array))
    outp = np.hstack(arrays)
    cv2.imwrite(outp_name, outp)
    if overlay_pattern:
        overlay_outp_name = os.path.join('/tmp', 'overlay_{0}.png'.format(date_string))
        overlay_image_names = ['-'.join(l.split('/')[-3:]) for l in overlay_names]
        overlay_image_names = sorted([i.split('-')[-3:] for i in overlay_image_names], key=itemgetter(1))
        arrays = []
        for k,g in groupby(overlay_image_names, key=itemgetter(1)):
            images = list(g)
            fnames = ['/tmp/%s' % ('-'.join(f)) for f in images]
            array = []
            for img in fnames:
                i = cv2.imread(img, -1)
                if isinstance(i, type(None)):
                    i = np.zeros((256,256,4), np.uint8)
                elif i.shape[2] != 4:
                    i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA)
                array.append(i)
            arrays.append(np.vstack(array))
            nuked = [os.remove(f) for f in fnames]
        outp = np.hstack(arrays)
        cv2.imwrite(overlay_outp_name, outp)
        base = cv2.imread(outp_name, -1)
        overlay = cv2.imread(overlay_outp_name, -1)
        overlay_g = cv2.cvtColor(overlay, cv2.COLOR_BGR2GRAY)
        ret, mask = cv2.threshold(overlay_g, 10, 255, cv2.THRESH_BINARY)
        inverted = cv2.bitwise_not(mask)
        overlay = cv2.bitwise_not(overlay, overlay, mask=inverted)

        base_alpha = 0.55
        overlay_alpha = 1
 
        for channel in range(3):
            x,y,d = overlay.shape
            base[:,:,channel] = (base[:,:,channel] * base_alpha + \
                                     overlay[:,:,channel] * overlay_alpha * \
                                     (1 - base_alpha)) / \
                                     (base_alpha + overlay_alpha * (1 - base_alpha))
        
        cv2.imwrite(outp_name, base)

    ###########################################################################
    # Code below here is for drawing vector layers within the PDF             #
    # Leaving it in just because it was a pain to come up with the first time #
    ###########################################################################
    
    if shape_overlays or point_overlays:
        
        im = cairo.ImageSurface.create_from_png(outp_name)
        ctx = cairo.Context(im)

        if shape_overlays:
            for shape_overlay in shape_overlays:
                shape_overlay = json.loads(shape_overlay)
                if shape_overlay.get('geometry'):
                    shape_overlay = shape_overlay['geometry']
                color = hex_to_rgb('#f06eaa')
                coords = shape_overlay['coordinates'][0]
                x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx, bmin_ry)
                ctx.move_to(x,y)
                ctx.set_line_width(4.0)
                red, green, blue = [float(c) for c in color]
                ctx.set_source_rgba(red/255, green/255, blue/255, 0.3)
                for p in coords[1:]:
                    x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                    ctx.line_to(x,y)
                ctx.close_path()
                ctx.fill()
                ctx.set_source_rgba(red/255, green/255, blue/255, 0.5)
                for p in coords[1:]:
                    x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                    ctx.line_to(x,y)
                ctx.close_path()
                ctx.stroke()
        ctx.set_line_width(2.0)

        if point_overlays:
            for point_overlay in point_overlays:
                point_overlay = json.loads(point_overlay)
                color = hex_to_rgb(point_overlay['color'])
                for p in point_overlay['points']:
                    if p[0] and p[1]:
                        pt = Point((float(p[0]), float(p[1])))
                        if bb_poly.contains(pt):
                            nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                            red, green, blue = [float(c) for c in color]
                            ctx.set_source_rgba(red/255, green/255, blue/255, 0.6)
                            ctx.arc(nx, ny, 5.0, 0, 50) # args: center-x, center-y, radius, ?, ?
                            ctx.fill()
                            ctx.arc(nx, ny, 5.0, 0, 50)
                            ctx.stroke()
        im.write_to_png(outp_name)
    scale = 1
    
    # Crop image from center

    center_point_x, center_point_y = latlon2xy(float(center_lat), 
                                               float(center_lon), 
                                               float(data['zoom']))

    offset_x = (center_point_x - float(center_tile_x)) + 50
    offset_y = (center_point_y - float(center_tile_y)) - 50

    outp_image = cv2.imread(outp_name, -1)
    pixels_up, pixels_across, channels = outp_image.shape
    center_x, center_y = (pixels_across / 2) + offset_x, (pixels_up / 2) + offset_y
    start_y, end_y = center_y - (page_height / 2), center_y + (page_height / 2)
    start_x, end_x = center_x - (page_width / 2), center_x + (page_width / 2)

    cv2.imwrite(outp_name, outp_image[start_y:end_y, start_x:end_x])

    if output == 'pdf':
        outp_file_name = outp_name.rstrip('.png') + '.pdf'

        pdf = cairo.PDFSurface(outp_file_name, page_width, page_height)
        ctx = cairo.Context(pdf)
        image = cairo.ImageSurface.create_from_png(outp_name)
        ctx.set_source_surface(image)
        ctx.paint()
        pdf.finish()
    elif output == 'jpeg':
        outp_file_name = outp_name.rstrip('.png') + '.jpg'
        jpeg = cv2.cvtColor(cv2.imread(outp_name, -1), cv2.COLOR_RGBA2RGB)
        cv2.imwrite(outp_file_name, jpeg)
    return outp_file_name
Beispiel #14
0
def pdfer(data, page_size=PAGE_SIZES['letter'], output='pdf'):

    shape_overlays = data.get('shape_overlays')
    point_overlays = data.get('point_overlays')

    grid = {'zoom': data.get('zoom')}
    center_lon, center_lat = data['center']
    center_tile_x, center_tile_y = tileXY(float(center_lat), float(center_lon),
                                          int(data['zoom']))

    dim_across, dim_up = data['dimensions']

    if dim_across > dim_up:
        page_height, page_width, tiles_up, tiles_across = page_size
    else:
        page_width, page_height, tiles_across, tiles_up = page_size

    min_tile_x = center_tile_x - (tiles_across / 2)
    min_tile_y = center_tile_y - (tiles_up / 2)
    max_tile_x = min_tile_x + tiles_across
    max_tile_y = min_tile_y + tiles_up

    # Get base layer tiles
    base_pattern = 'http://d.tile.stamen.com/toner/{z}/{x}/{y}.png'
    if data.get('base_tiles'):
        base_pattern = data['base_tiles']

    base_links = generateLinks(base_pattern, grid['zoom'], min_tile_x,
                               min_tile_y, max_tile_x, max_tile_y)

    base_names = dl_write_all(base_links, 'base')

    # Get overlay tiles
    overlay_pattern = None
    if data.get('overlay_tiles'):
        overlay_pattern = data['overlay_tiles']
        overlay_links = generateLinks(overlay_pattern, grid['zoom'],
                                      min_tile_x, min_tile_y, max_tile_x,
                                      max_tile_y)

        overlay_names = dl_write_all(overlay_links, 'overlay')

    now = datetime.now()
    date_string = datetime.strftime(now, '%Y-%m-%d_%H-%M-%S')
    outp_name = os.path.join('/tmp', '{0}.png'.format(date_string))
    base_image_names = ['-'.join(l.split('/')[-3:]) for l in base_names]
    base_image_names = sorted([i.split('-')[-3:] for i in base_image_names],
                              key=itemgetter(1))

    for parts in base_image_names:
        z, x, y = parts
        y = y.rstrip('.png').rstrip('.jpg')
        z = z.rsplit('_', 1)[1]
        key = '-'.join([z, x, y])
        grid[key] = {'bbox': tileEdges(float(x), float(y), int(z))}

    keys = sorted(grid.keys())

    mercator = GlobalMercator()
    bb_poly = None

    bmin_rx = None
    bmin_ry = None

    if shape_overlays or point_overlays:
        polys = []
        for k, v in grid.items():
            try:
                one, two, three, four = grid[k]['bbox']
                polys.append(box(two, one, four, three))
            except TypeError:
                pass
        mpoly = MultiPolygon(polys)
        bb_poly = box(*mpoly.bounds)
        min_key = keys[0]
        max_key = keys[-2]
        bminx, bminy = grid[min_key]['bbox'][0], grid[min_key]['bbox'][1]
        bmaxx, bmaxy = grid[max_key]['bbox'][2], grid[max_key]['bbox'][3]
        bmin_mx, bmin_my = mercator.LatLonToMeters(bminx, bminy)
        bmax_mx, bmax_my = mercator.LatLonToMeters(bmaxx, bmaxy)
        bmin_px, bmin_py = mercator.MetersToPixels(bmin_mx, bmin_my,
                                                   float(grid['zoom']))
        bmax_px, bmax_py = mercator.MetersToPixels(bmax_mx, bmax_my,
                                                   float(grid['zoom']))
        bmin_rx, bmin_ry = mercator.PixelsToRaster(bmin_px, bmin_py,
                                                   int(grid['zoom']))

        if shape_overlays:
            all_polys = []
            for shape_overlay in shape_overlays:
                shape_overlay = json.loads(shape_overlay)
                if shape_overlay.get('geometry'):
                    shape_overlay = shape_overlay['geometry']
                coords = shape_overlay['coordinates'][0]
                all_polys.append(Polygon(coords))
            mpoly = MultiPolygon(all_polys)

            one, two, three, four, five = list(
                box(*mpoly.bounds).exterior.coords)

            left, right = LineString([one, two]), LineString([three, four])
            top, bottom = LineString([two, three]), LineString([four, five])

            left_to_right = left.distance(right)
            top_to_bottom = top.distance(bottom)

            if left_to_right > top_to_bottom:
                page_height, page_width, _, _ = page_size
            else:
                page_width, page_height, _, _ = page_size

            center_lon, center_lat = list(mpoly.centroid.coords)[0]

        if point_overlays:
            all_points = []

            for point_overlay in point_overlays:
                point_overlay = json.loads(point_overlay)
                for p in point_overlay['points']:
                    if p[0] and p[1]:
                        all_points.append(p)

            mpoint = MultiPoint(all_points)
            center_lon, center_lat = list(mpoint.centroid.coords)[0]

            one, two, three, four, five = list(
                box(*mpoint.bounds).exterior.coords)

            left, right = LineString([one, two]), LineString([three, four])
            top, bottom = LineString([two, three]), LineString([four, five])

            left_to_right = left.distance(right)
            top_to_bottom = top.distance(bottom)

            if left_to_right > top_to_bottom:
                page_height, page_width, _, _ = page_size
            else:
                page_width, page_height, _, _ = page_size

            center_lon, center_lat = list(mpoint.centroid.coords)[0]

            print(center_lon, center_lat)

    arrays = []
    for k, g in groupby(base_image_names, key=itemgetter(1)):
        images = list(g)
        fnames = ['/tmp/%s' % ('-'.join(f)) for f in images]
        array = []
        for img in fnames:
            i = cv2.imread(img, -1)
            if isinstance(i, type(None)):
                i = np.zeros((256, 256, 4), np.uint8)
            elif i.shape[2] != 4:
                i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA)
            array.append(i)
        arrays.append(np.vstack(array))
    outp = np.hstack(arrays)
    cv2.imwrite(outp_name, outp)
    if overlay_pattern:
        overlay_outp_name = os.path.join('/tmp',
                                         'overlay_{0}.png'.format(date_string))
        overlay_image_names = [
            '-'.join(l.split('/')[-3:]) for l in overlay_names
        ]
        overlay_image_names = sorted(
            [i.split('-')[-3:] for i in overlay_image_names],
            key=itemgetter(1))
        arrays = []
        for k, g in groupby(overlay_image_names, key=itemgetter(1)):
            images = list(g)
            fnames = ['/tmp/%s' % ('-'.join(f)) for f in images]
            array = []
            for img in fnames:
                i = cv2.imread(img, -1)
                if isinstance(i, type(None)):
                    i = np.zeros((256, 256, 4), np.uint8)
                elif i.shape[2] != 4:
                    i = cv2.cvtColor(cv2.imread(img), cv2.COLOR_BGR2BGRA)
                array.append(i)
            arrays.append(np.vstack(array))
            nuked = [os.remove(f) for f in fnames]
        outp = np.hstack(arrays)
        cv2.imwrite(overlay_outp_name, outp)
        base = cv2.imread(outp_name, -1)
        overlay = cv2.imread(overlay_outp_name, -1)
        overlay_g = cv2.cvtColor(overlay, cv2.COLOR_BGR2GRAY)
        ret, mask = cv2.threshold(overlay_g, 10, 255, cv2.THRESH_BINARY)
        inverted = cv2.bitwise_not(mask)
        overlay = cv2.bitwise_not(overlay, overlay, mask=inverted)

        base_alpha = 0.55
        overlay_alpha = 1

        for channel in range(3):
            x, y, d = overlay.shape
            base[:,:,channel] = (base[:,:,channel] * base_alpha + \
                                     overlay[:,:,channel] * overlay_alpha * \
                                     (1 - base_alpha)) / \
                                     (base_alpha + overlay_alpha * (1 - base_alpha))

        cv2.imwrite(outp_name, base)

    ###########################################################################
    # Code below here is for drawing vector layers within the PDF             #
    # Leaving it in just because it was a pain to come up with the first time #
    ###########################################################################

    if shape_overlays or point_overlays:

        im = cairo.ImageSurface.create_from_png(outp_name)
        ctx = cairo.Context(im)

        if shape_overlays:
            for shape_overlay in shape_overlays:
                shape_overlay = json.loads(shape_overlay)
                if shape_overlay.get('geometry'):
                    shape_overlay = shape_overlay['geometry']
                color = hex_to_rgb('#f06eaa')
                coords = shape_overlay['coordinates'][0]
                x, y = get_pixel_coords(coords[0], grid['zoom'], bmin_rx,
                                        bmin_ry)
                ctx.move_to(x, y)
                ctx.set_line_width(4.0)
                red, green, blue = [float(c) for c in color]
                ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.3)
                for p in coords[1:]:
                    x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                    ctx.line_to(x, y)
                ctx.close_path()
                ctx.fill()
                ctx.set_source_rgba(red / 255, green / 255, blue / 255, 0.5)
                for p in coords[1:]:
                    x, y = get_pixel_coords(p, grid['zoom'], bmin_rx, bmin_ry)
                    ctx.line_to(x, y)
                ctx.close_path()
                ctx.stroke()
        ctx.set_line_width(2.0)

        if point_overlays:
            for point_overlay in point_overlays:
                point_overlay = json.loads(point_overlay)
                color = hex_to_rgb(point_overlay['color'])
                for p in point_overlay['points']:
                    if p[0] and p[1]:
                        pt = Point((float(p[0]), float(p[1])))
                        if bb_poly.contains(pt):
                            nx, ny = get_pixel_coords(p, grid['zoom'], bmin_rx,
                                                      bmin_ry)
                            red, green, blue = [float(c) for c in color]
                            ctx.set_source_rgba(red / 255, green / 255,
                                                blue / 255, 0.6)
                            ctx.arc(
                                nx, ny, 5.0, 0,
                                50)  # args: center-x, center-y, radius, ?, ?
                            ctx.fill()
                            ctx.arc(nx, ny, 5.0, 0, 50)
                            ctx.stroke()
        im.write_to_png(outp_name)
    scale = 1

    # Crop image from center

    center_point_x, center_point_y = latlon2xy(float(center_lat),
                                               float(center_lon),
                                               float(data['zoom']))

    offset_x = (center_point_x - float(center_tile_x)) + 50
    offset_y = (center_point_y - float(center_tile_y)) - 50

    outp_image = cv2.imread(outp_name, -1)
    pixels_up, pixels_across, channels = outp_image.shape
    center_x, center_y = (pixels_across / 2) + offset_x, (pixels_up /
                                                          2) + offset_y
    start_y, end_y = center_y - (page_height / 2), center_y + (page_height / 2)
    start_x, end_x = center_x - (page_width / 2), center_x + (page_width / 2)

    cv2.imwrite(outp_name, outp_image[start_y:end_y, start_x:end_x])

    if output == 'pdf':
        outp_file_name = outp_name.rstrip('.png') + '.pdf'

        pdf = cairo.PDFSurface(outp_file_name, page_width, page_height)
        ctx = cairo.Context(pdf)
        image = cairo.ImageSurface.create_from_png(outp_name)
        ctx.set_source_surface(image)
        ctx.paint()
        pdf.finish()
    elif output == 'jpeg':
        outp_file_name = outp_name.rstrip('.png') + '.jpg'
        jpeg = cv2.cvtColor(cv2.imread(outp_name, -1), cv2.COLOR_RGBA2RGB)
        cv2.imwrite(outp_file_name, jpeg)
    return outp_file_name