Ejemplo n.º 1
0
def image_offsets(img, coordinates):
    gt = img.GetGeoTransform()
    inv_gt = gdal.InvGeoTransform(gt)
    offsets_ul = list(
        map(int, gdal.ApplyGeoTransform(inv_gt, coordinates[0],
                                        coordinates[1])))
    offsets_lr = list(
        map(int, gdal.ApplyGeoTransform(inv_gt, coordinates[2],
                                        coordinates[3])))
    return offsets_ul + offsets_lr
Ejemplo n.º 2
0
def RasterOverlapToArray(file_list):
    UL_x_list = []
    UL_y_list = []
    LR_x_list = []
    LR_y_list = []
    for file in file_list:
        ds = gdal.Open(root_folder + file, gdal.GA_ReadOnly)
        gt = ds.GetGeoTransform(
        )  # UL_x, x-coordinate spatial resolution, UL_y, # y-coord. spat.res.
        # Upper left
        UL_x, UL_y = gt[0], gt[
            3]  #calculate corner lat/lon coordinates (for x/y cell coordinates use inv_gt)
        UL_x_list.append(UL_x)
        UL_y_list.append(UL_y)
        # Lower right
        LR_x = UL_x + (gt[1] * ds.RasterXSize)
        LR_y = UL_y + (gt[5] * ds.RasterYSize)
        LR_x_list.append(LR_x)
        LR_y_list.append(LR_y)
    UL_x_ext = max(UL_x_list)  #corner coordinates and extent of common extent
    UL_y_ext = min(UL_y_list)
    LR_x_ext = min(LR_x_list)
    LR_y_ext = max(LR_y_list)
    extent_x = int(round(
        (min(LR_x_list) - max(UL_x_list)) /
        gt[1]))  #width of common extent/pixel width = number of columns
    extent_y = int(
        round(min(UL_y_list) - max(LR_y_list)) /
        gt[1])  #height of common extent/pixel height = number of rows
    overlap = [UL_x_ext, UL_y_ext, LR_x_ext,
               LR_y_ext]  #only upper left and lower right coordinates
    print("Common extent UL/LR coordinates: ", overlap)
    print("Common extent in x and y direction: ", extent_x, extent_y)
    spat_res = [gt[1], abs(gt[5])]
    print("Common extent spatial resolution: ", spat_res, "\n")
    for file in file_list:  #convert real-world coordinates (lat/lon) to image coordinates (x,y)
        print(file)  #for overview in console
        ds = gdal.Open(root_folder + file, gdal.GA_ReadOnly)
        gt = ds.GetGeoTransform(
        )  # UL_x, x-coordinate spatial resolution, UL_y, # y-coord. spat.res.
        inv_gt = gdal.InvGeoTransform(
            gt)  # transform geographic coordinates into array coordinates
        x1, y1 = gdal.ApplyGeoTransform(inv_gt, overlap[0], overlap[1])
        x2, y2 = gdal.ApplyGeoTransform(inv_gt, overlap[2], overlap[3])
        minX = int(round(min(x1, x2)))  # x value for UL/origin
        minY = int(round(min(y1, y2)))  # y value for UL/origin
        maxX = int(round(max(x1, x2)))  # x value for LR
        maxY = int(round(max(y1, y2)))  # y value for LR
        print("Cell coordinates of common extent: ", minX, maxX, minY,
              maxY)  #cell coordinates of extent for each file
        x1off, y1off = map(int, [x1, y1])  #UL
        print("UL x offset: ", x1off)
        print("UL y offset: ", y1off, "\n")
        array_list.append(ds.ReadAsArray(x1off, y1off, extent_x,
                                         extent_y))  #Upper Left corner
Ejemplo n.º 3
0
    def transbox(self, ds, bbox, topix=False, clip=False):
        ''' transform bounding box coordinates in lonlat to projected coordinates or pixel coordinates '''
        src = osr.SpatialReference()
        src.ImportFromEPSG(4326)
        dest = osr.SpatialReference()
        dsproj = ds.GetProjection()
        dest.ImportFromWkt(dsproj)
        trans = osr.CoordinateTransformation(src, dest)

        x1, y1, x2, y2 = bbox
        ll = trans.TransformPoint(x1, y1)
        ul = trans.TransformPoint(x1, y2)
        lr = trans.TransformPoint(x2, y1)
        ur = trans.TransformPoint(x2, y2)

        x1 = min(ll[0], ul[0])
        x2 = max(lr[0], ur[0])
        y1 = min(ll[1], lr[1])
        y2 = max(ul[1], ur[1])

        if clip or topix:
            fwd = ds.GetGeoTransform()
            inv = gdal.InvGeoTransform(fwd)
            px1, py1 = gdal.ApplyGeoTransform(inv, x1, y1)
            px2, py2 = gdal.ApplyGeoTransform(inv, x2, y2)
            if py1 > py2:
                t = py1
                py1 = py2
                py2 = t
            if clip:
                px1 = int(max(0, px1))
                py1 = int(max(0, py1))
                px2 = int(min(ds.RasterXSize - 1, px2))
                py2 = int(min(ds.RasterYSize - 1, py2))

            if topix:
                x1 = px1
                y1 = py1
                x2 = px2
                y2 = py2
            else:
                x1, y1 = gdal.ApplyGeoTransform(fwd, px1, py1)
                x2, y2 = gdal.ApplyGeoTransform(fwd, px2, py2)

        if y1 > y2:
            return (x1, y2, x2, y1)
        else:
            return (x1, y1, x2, y2)
Ejemplo n.º 4
0
    def pixel_to_point(self, pixel_x, pixel_y, geotransform):
        """Translates grid pixels coordinates to output projection points 
        (using the geotransformation of the output projection)"""

        point_x, point_y = gdal.ApplyGeoTransform(geotransform, pixel_x,
                                                  pixel_y)
        return point_x, point_y
Ejemplo n.º 5
0
def image_offsets(img, coordinates):
    '''
    Function that calculates the image offsets from the upper left and lower right corners.
    :param img:
    :param coordinates:
    :return:
    '''
    gt = img.GetGeoTransform()
    inv_gt = gdal.InvGeoTransform(gt)
    offsets_ul = list(
        map(int, gdal.ApplyGeoTransform(inv_gt, coordinates[0],
                                        coordinates[1])))
    offsets_lr = list(
        map(int, gdal.ApplyGeoTransform(inv_gt, coordinates[2],
                                        coordinates[3])))
    return offsets_ul + offsets_lr
Ejemplo n.º 6
0
 def center_of_raster(self):
     geo_transform = self.raster.GetGeoTransform(
     )  # col, row --->  lon, lat
     x, y = gdal.ApplyGeoTransform(geo_transform,
                                   self.raster.RasterXSize / 2,
                                   self.raster.RasterYSize / 2)
     return x, y
Ejemplo n.º 7
0
def xy2lcc(name,lon_0,lat_0,x,y):
      radius = 6370e3
      lcc_proj = pyproj.Proj(proj='lcc',
            lat_1=lat_0,
            lat_2=lat_0,
            lat_0=lat_0,
            lon_0=lon_0,
            a=radius, b=radius, towgs84='0,0,0', no_defs=True)
      print 'lcc:',lcc_proj.srs
      tif_proj = pyproj.Proj(projparams=proj_string(name))
      print 'tif:',tif_proj.srs
      print 'ref:',ref_proj.srs 

      ds=gdal.Open(name)
      xoffset, px_w, rot1, yoffset, rot2, px_h = ds.GetGeoTransform()
      posX = px_w * x + rot1 * y + xoffset
      posY = rot2 * x + px_h * y + yoffset
      gX, gY = gdal.ApplyGeoTransform(ds.GetGeoTransform(),x,y)
      print posX, posY
      print gX, gY
      posX += px_w / 2.0
      posY += px_h / 2.0

      print 'tif:', posX, posY 
      lon, lat = pyproj.transform(tif_proj, ref_proj, posX, posY)
      print "ref lon lat:", lon, lat, deg2str(lon,0), deg2str(lat,1)
      lccX, lccY = pyproj.transform(ref_proj,lcc_proj,lon, lat)
      print "lcc x y:", lccX, lccY
      lcc2X, lcc2Y = pyproj.transform(tif_proj, lcc_proj, posX, posY) # different result?
      print "lcc2 x y:", lcc2X, lcc2Y
      lcc3X, lcc3Y = lcc_proj(lon, lat)
      print "lcc3 x y:", lcc3X, lcc3Y
      return lccX, lccY
Ejemplo n.º 8
0
    def get_weights(self, ds, geom):
        fwd = ds.GetGeoTransform()
        _, inv = gdal.InvGeoTransform(fwd)
        x1, x2, y1, y2 = geom.GetEnvelope()
        px1, py1 = gdal.ApplyGeoTransform(inv, x1, y1)
        px2, py2 = gdal.ApplyGeoTransform(inv, x2, y2)
        if py2 < py1:
            t = py1
            py1 = py2
            py2 = t

        px1 = max(0, px1)
        py1 = max(0, py1)
        px2 = min(ds.RasterXSize, px2)
        py2 = min(ds.RasterYSize, py2)

        if px2 < px1 or py2 < py1:
            return []

        weights = []
        for y in range(int(py1), int(py2)):
            for x in range(int(px1), int(px2)):
                x1, y1 = gdal.ApplyGeoTransform(fwd, x, y)
                x2, y2 = gdal.ApplyGeoTransform(fwd, x + 1, y + 1)
                ring = ogr.Geometry(ogr.wkbLinearRing)
                ring.AddPoint(x1, y1)
                ring.AddPoint(x1, y2)
                ring.AddPoint(x2, y2)
                ring.AddPoint(x2, y1)
                ring.AddPoint(x1, y1)
                poly = ogr.Geometry(ogr.wkbPolygon)
                poly.AddGeometry(ring)
                if geom.Contains(poly):
                    frac = 1.0
                else:
                    isect = poly.Intersection(geom)
                    if isect.IsEmpty():
                        frac = 0.0
                    else:
                        frac = isect.GetArea() / poly.GetArea()
                if frac != 0:
                    weights.append([x, y, frac])
        return weights
Ejemplo n.º 9
0
def pix2pos(ds, x, y):
    # position coordinates from geotiff pixel indices
    gt = ds.GetGeoTransform()
    xoffset, px_w, rot1, yoffset, rot2, px_h = gt
    posX, posY = gdal.ApplyGeoTransform(gt, x - 1, y - 1)  # corner is (0,0)
    # move to centers of pixels
    # commented out, because gdalinfo does not
    # posX += px_w / 2.0
    # posY += px_h / 2.0
    return posX, posY
Ejemplo n.º 10
0
    def point_to_pixel(self, point_x, point_y, inverse_geotransform):
        """Translates points from input projection (using the inverse
        transformation of the output projection) to the grid pixel coordinates in data
        array (zero start)"""

        # apply inverse geotranformation to convert to pixels
        pixel_x, pixel_y = gdal.ApplyGeoTransform(inverse_geotransform,
                                                  point_x, point_y)

        return pixel_x, pixel_y
Ejemplo n.º 11
0
    def get_px_coord(self, lon, lat):
        """
        Convert lon-lat into x-y coordinates of pixel
        :param lon: longitude
        :param lat: latitude
        :return: tuple of pixel coordinates
        """
        offsets_coord = gdal.ApplyGeoTransform(self.raster_inv_gt, lon, lat)
        px_x, px_y = map(int, offsets_coord)

        return px_x, px_y
Ejemplo n.º 12
0
def lonlat_to_pixel(lon, lat, inverse_geo_transform):
    """Translates the given lon, lat to the grid pixel coordinates
    in data array (zero start)"""
    wgs84_object = WGS84Transform()
    # transform to utm
    utm_x, utm_y, utm_z = wgs84_object.wgs84_to_utm(lon, lat)

    # apply inverse geo tranform
    pixel_x, pixel_y = gdal.ApplyGeoTransform(inverse_geo_transform, utm_x, utm_y)
    pixel_x = int(pixel_x) - 1  # adjust to 0 start for array
    pixel_y = int(pixel_y) - 1  # adjust to 0 start for array

    return pixel_x, abs(pixel_y)  # y pixel is likly a negative value given geo_transform
Ejemplo n.º 13
0
def misc_8():

    try:
        gdal.ApplyGeoTransform
    except:
        return 'skip'

    gt = (10, 0.1, 0, 20, 0, -1.0)
    res = gdal.ApplyGeoTransform(gt, 10, 1)
    if res != [11.0, 19.0]:
        return 'fail'

    return 'success'
Ejemplo n.º 14
0
    def getcolrow(self, ds, lon, lat):
        proj = ds.GetProjection()
        src = osr.SpatialReference()
        src.ImportFromEPSG(4326)
        dest = osr.SpatialReference()
        dest.ImportFromWkt(proj)
        trans = osr.CoordinateTransformation(src, dest)

        x, y, z = trans.TransformPoint(lon, lat)

        inv = gdal.InvGeoTransform(ds.GetGeoTransform())

        return gdal.ApplyGeoTransform(inv, x, y)
Ejemplo n.º 15
0
def subset(raster, subset, coordinates=True, multiband=False):
    """
    Subsets a given raster to a set of coordinates [subset] into an array.
    When subset is given as list of geographic coordinates, they will be transformed to array indices.
    When subset is given as array indices, image will be subsetted. Indices must be in format [ulx, uly,lrx,lry]
    Bool-Arguments don't have to be specified, when called. Defaults to function definition.
    :param raster:
    :param subset:
    :param coordinates:
    :param multiband:
    :return array:
    """
    if coordinates:
        gt = raster.GetGeoTransform()
        inv_gt = gdal.InvGeoTransform(gt)
        app_gt_offset_upperleft = gdal.ApplyGeoTransform(
            inv_gt, geo_overlap[0], geo_overlap[1])
        app_gt_offset_lowerright = gdal.ApplyGeoTransform(
            inv_gt, geo_overlap[2], geo_overlap[3])
        off_ulx, off_uly = map(int, app_gt_offset_upperleft)
        off_lrx, off_lry = map(int, app_gt_offset_lowerright)
        rows = off_lry - off_uly
        columns = off_lrx - off_ulx
        # idx = [off_ulx, off_uly, columns, rows ]
        array = raster.ReadAsArray(off_ulx, off_uly, columns, rows)
        return array
    else:
        idx = subset

    if gdal:
        array = raster.ReadAsArray(idx[0], idx[1], idx[2] - idx[0],
                                   idx[3] - idx[1])
    else:
        if multiband:
            array = raster[:, idx[0]:idx[2], idx[1]:idx[3]]
        else:
            array = raster[idx[0]:idx[2], idx[1]:idx[3]]
    return array
Ejemplo n.º 16
0
def get_envelope(filepath):
    ds = gdal.Open(filepath, gdal.GA_ReadOnly)
    y,x = np.mgrid[:ds.RasterYSize:2j,:ds.RasterXSize:2j]
    bbox = np.array([gdal.ApplyGeoTransform(ds.GetGeoTransform(), xx, yy)
                     for xx,yy in zip(x.ravel(), y.ravel())])
    srs = osr.SpatialReference(wkt=ds.GetProjection())
    geom = ogr.CreateGeometryFromWkt(
        'POLYGON(({b[0][0]} {b[0][1]}, '
                 '{b[1][0]} {b[1][1]}, '
                 '{b[3][0]} {b[3][1]}, '
                 '{b[2][0]} {b[2][1]}, '
                 '{b[0][0]} {b[0][1]}))'.format(b=bbox),
        srs)
    return geom
Ejemplo n.º 17
0
 def get_cached_value(self, filename, lon, lat):
     """ Get a single value at (lon,lat) from cache """
     path = os.path.join(self.cache, filename)
     ds = gdal.OpenShared(path)
     fwd = ds.GetGeoTransform()
     inv = gdal.InvGeoTransform(fwd)
     # older versions of gdal have a different signature of InvGeoTransform()
     if inv and len(inv) == 2:
         _success, inv = inv
     x, y = gdal.ApplyGeoTransform(inv, lon, lat)
     x = int(max(0, min(ds.RasterXSize - 1, x)))
     y = int(max(0, min(ds.RasterYSize - 1, y)))
     value = ds.GetRasterBand(1).ReadAsArray(x, y, 1, 1)
     return value[0][0]
Ejemplo n.º 18
0
def read_GPS_file(filename, inv_trans):
    all_data = []
    with open(filename, 'r') as f:
        for line in f.readlines():
            vals = line.split(',')
            if line[:6] == '$GPGGA' and len(vals) > 10:
                lat_str, _, lon_str, _ = vals[2:6]
                lat = str_to_coord(lat_str)
                lon = -str_to_coord(lon_str)  #W = negative, generalize later
                x, y, _, _ = utm.from_latlon(lat, lon)
                all_data.append((x, y))
    ASV_X = []
    ASV_Y = []
    for x, y in all_data:
        row, col = gdal.ApplyGeoTransform(inv_trans, x, y)
        ASV_X.append(row)
        ASV_Y.append(col)

    return np.asarray(ASV_X), np.asarray(ASV_Y)
Ejemplo n.º 19
0
def read_mission_file(filename, inv_trans):
    coords = []
    with open(filename, 'r') as f:
        for line in f.readlines():
            if line[-1] == '\n':
                line = line[:-1]
            coords.append(list(map(float, line.split(','))))
    X_all = []
    Y_all = []
    R = []
    C = []
    for lat, lon in coords:
        x, y, _, _ = utm.from_latlon(lat, lon)
        row, col = gdal.ApplyGeoTransform(inv_trans, x, y)
        X_all.append(x)
        Y_all.append(y)
        R.append(row)
        C.append(col)

    return X_all, Y_all, R, C
Ejemplo n.º 20
0
    def geogrid_index(self):
        """
        Geolocation in a form suitable for geogrid index.

        :return: dictionary key:value 
        """
        # spacing
        dx,dy = self.gt[1],self.gt[5]
        # known points in the center of the array (mass-staggered mesh from 1 at origin)
        known_x = (self.nx+1)/2. 
        known_y = (self.ny+1)/2. 
        # known points in the center of the array (unstaggered mesh from 0 at origin)
        known_x_uns = known_x-.5
        known_y_uns = known_y-.5
        # get pyproj element for reference lat-long coordinates
        ref_proj = self.pyproj.to_latlong()
        # lat/lon known points
        posX, posY = gdal.ApplyGeoTransform(self.gt,known_x_uns,known_y_uns)
        known_lon,known_lat = pyproj.transform(self.pyproj,ref_proj,posX,posY) 
        # print center lon-lat coordinates to check with gdalinfo
        if not self.resampled:
            logging.info('GeoTIFF.geogrid_index - center lon/lat coordinates using pyproj.transform: %s' % coord2str(known_lon,known_lat)) 
            logging.info('GeoTIFF.geogrid_index - center lon/lat coordinates using gdal.Info: %s' % gdal.Info(self.ds).split('Center')[1].split(') (')[1].split(')')[0])  
        # row order depends on dy
        if dy > 0:
            row_order = 'bottom_top'
        else:
            row_order = 'top_bottom'
        # write geogrid index
        return Dict({'projection' : self.projwrf,
            'dx' : dx,
            'dy' : dy,
            'truelat1' : self.crs.GetProjParm("standard_parallel_1"),
            'truelat2' : self.crs.GetProjParm("standard_parallel_2"),
            'stdlon' : self.crs.GetProjParm("longitude_of_center",self.crs.GetProjParm("central_meridian",self.crs.GetProjParm("longitude_of_origin"))),
            'known_x' : known_x,
            'known_y' : known_y,
            'known_lon' : known_lon,
            'known_lat' : known_lat,
            'row_order' : row_order
        })
Ejemplo n.º 21
0
 def get_value_at_position(self, lat, lon, raster_band=1):
     band = self.ds.GetRasterBand(raster_band)
     bandtype = gdal.GetDataTypeName(band.DataType)
     px, py = gdal.ApplyGeoTransform(self.transfInv, lon, lat)
     if px > self.cols or py > self.rows:
         return None
     structval = band.ReadRaster(int(px),
                                 int(py),
                                 1,
                                 1,
                                 buf_type=band.DataType)
     fmt = self._pt2fmt(band.DataType)
     value = struct.unpack(fmt, structval)
     if value[0] == band.GetNoDataValue():
         if fmt == 'f':
             return float('nan')
         else:
             return None
     else:
         result = value[0]
     return value[0]
Ejemplo n.º 22
0
    def update_GPS(self):
        '''Get local x, y coordinate from robot. Then convert to utm for graphing'''
        x = self.controller.robot.state_est.x
        y = self.controller.robot.state_est.y
        # print('x,y: ', x, y)

        if self.controller.mode == "SIM MODE":
            heading = self.controller.robot.state_est.theta / math.pi * 180
        else:
            heading = self.controller.robot.state_est.theta

        # Convert local x y to lat lon
        if x <= 0:
            lat = 0.0
            lon = 0.0
        else:
            lat, lon = utm.to_latlon(x, y, 11, 'S')
        self.gps['text'] = 'Latitude: ' + str(lat) + '\nLongitude: ' + str(
            lon) + '\nHeading: ' + str(round(heading, 2))

        # Convert UTM to graphing row and column
        img_col, img_row = gdal.ApplyGeoTransform(self.inv_trans, x, y)
        row = int(img_row * MAP_HEIGHT / IMAGE_HEIGHT)
        col = int(img_col * MAP_WIDTH / IMAGE_WIDTH)

        # Update ASV location on map
        self.draw_arrow(col, row, heading * np.pi / 180.)
        self.gps_local['text'] = 'x: ' + str(
            col - self.origin_coords[0]) + ', y: ' + str(-row +
                                                         self.origin_coords[1])

        if self.goto_coords[0] != -1:
            self.control_wp_dxdy['text'] = 'dx: ' + str(
                int(self.goto_coords[0] - x)) + ', dy: ' + str(
                    int(self.goto_coords[1] - y))

        # Add border
        if self.set_border_mode:
            self.border_markers.append(self.draw_circle(
                col, row, border=True))  #TODO: make this more elegant?
Ejemplo n.º 23
0
def convertChartListGDAL(chartlist):

    for chart in chartlist:

        dataset = gdal.Open(chart, gdal.GA_ReadOnly)
        if dataset is None:
            warn("gdal cannot handle file " + chart)
            continue
        else:
            log("chart " + chart + " succcessfully opened")
        inosr = osr.SpatialReference()
        outosr = osr.SpatialReference()
        llosr = osr.SpatialReference()
        outosr.SetWellKnownGeogCS("WGS84")
        inosr.ImportFromWkt(dataset.GetProjection())
        if not inosr.IsSameGeogCS(outosr):
            warn(chart + " is not in WGS84, cannot convert")
            continue
        llosr.CopyGeogCSFrom(inosr)
        transformer = osr.CoordinateTransformation(inosr, llosr)
        if transformer.this is None:
            warn(
                chart +
                " seems not to have a coordinate system, cannot transform (potentially missing some files)"
            )
            continue
        geotr = dataset.GetGeoTransform()
        (ullon, ullat, z) = transformer.TransformPoint(geotr[0], geotr[3], 0)
        (lrlon, lrlat) = gdal.ApplyGeoTransform(geotr, dataset.RasterXSize,
                                                dataset.RasterYSize)
        log("raster: ullat=%f ullon=%f lrlat=%f lrlon=%f" %
            (geotr[3], geotr[0], lrlat, lrlon))
        (lrlon, lrlat, z) = transformer.TransformPoint(lrlon, lrlat, 0)
        cmd = "%s %s %f %f %f %f" % (imgkap(), chart, ullat, ullon, lrlat,
                                     lrlon)
        log("running " + cmd)
        os.system(cmd)
Ejemplo n.º 24
0
    def visible_region(self,
                       geo_x=None,
                       geo_y=None,
                       width=None,
                       height=None,
                       scale=None):
        if self.raster is None: return
        if geo_x is None: geo_x = self.geo_x
        if geo_y is None: geo_y = self.geo_y
        if width is None: width = self.width()
        if height is None: height = self.height()
        if scale is None: scale = self.scale

        assert geo_x is not None and geo_y is not None

        geo_transform = self.raster.GetGeoTransform(
        )  # col, row --->  lon, lat
        ok, inverse_geo_transform = gdal.InvGeoTransform(
            geo_transform)  # lon, lat --->  col, row
        col, row = gdal.ApplyGeoTransform(inverse_geo_transform, self.geo_x,
                                          self.geo_y)

        # col, row are now where we are centered in the image
        # I want scale=1 to be viewing the image at 1m per pixel.
        # The image may be sampled at a different resolution, fetch the meters-per-pixel from the geo-transform
        # Also, the pixels generally are not square.
        meters_x = geo_transform[1]
        meters_y = geo_transform[5]

        # Determine the size and offset within the raster
        x_size = abs(int(width * meters_x / scale))
        y_size = abs(int(height * meters_y / scale))
        x_off = int(col - x_size / 2)
        y_off = int(row - y_size / 2)

        return x_off, y_off, x_size, y_size
Ejemplo n.º 25
0
    def __init__(self, controller):
        # Load map for display/GPS conversions
        dataset = gdal.Open(MAP_FILE)
        data = dataset.ReadAsArray()
        self.geo_trans = dataset.GetGeoTransform()
        self.inv_trans = gdal.InvGeoTransform(self.geo_trans)

        # Control parameters
        self.robot_stopped = True
        self.quit_gui = False
        self.mission_wps = []  #format [(lat, lon)...]

        #######################################################################
        # GUI SECTION
        #######################################################################

        # Set up GUI
        self.controller = controller
        self.tk = Tk()
        self.tk.report_callback_exception = handle_exception
        self.tk.title("ASV Control Interface")
        self.tk.protocol("WM_DELETE_WINDOW", self.on_quit)

        # GUI marker variables (labels on map)
        # Go to location
        self.goto_coords = (-1, -1)  #UTM! #TODO: CURRENTLY NOT CHANGED
        self.location_select_mode = False
        self.cur_pos_marker = None
        self.target_pos_marker = None

        # Mission planning
        self.add_wps_mode = False
        self.remove_wps_mode = False
        self.running_mission_mode = False
        self.transect_mode = False
        # self.repeat_mission_mode = False
        self.set_border_mode = False
        self.wp_markers = []
        self.wp_labels = []

        self.border_markers = []

        # Origin setting
        self.origin_coords = (0, 0)  #pixel coords
        x, y = gdal.ApplyGeoTransform(self.geo_trans, 0, 0)
        print('Origin UTM:', x, y)
        self.set_origin_mode = False

        # Frames: Sidebar + Map Area
        self.sidebar_frame = Frame(self.tk,
                                   width=500,
                                   relief='sunken',
                                   borderwidth=2)
        self.map_frame = Frame(self.tk)
        self.sidebar_frame.pack(expand=True,
                                fill='both',
                                side='left',
                                anchor='nw')
        self.map_frame.pack(expand=True, fill='both', side='right')

        #######################################################################
        # SIDEBAR FRAME
        #######################################################################

        # GPS Coordinates
        self.gps_title = Label(self.sidebar_frame,
                               anchor='w',
                               text='ASV GPS Information',
                               font='Helvetica 14 bold').pack()
        self.gps = Label(self.sidebar_frame,
                         anchor='w',
                         width=30,
                         text='Latitude: ???\nLongitude: ???\nHeading: ???')
        self.gps_local = Label(self.sidebar_frame,
                               anchor='w',
                               width=30,
                               text='x: ???, y: ???')
        self.gps.pack()
        #self.gps_local.pack()

        # ADCP Data
        self.adcp_title = Label(self.sidebar_frame,
                                anchor='w',
                                text='ADCP Information',
                                font='Helvetica 14 bold').pack()
        self.adcp_data = Label(self.sidebar_frame,
                               anchor='w',
                               width=30,
                               text='Water depth: ???\nCurrent speed: ???')
        self.adcp_data.pack()

        # ASV Control Panel
        self.control_title = Label(self.sidebar_frame,
                                   anchor='w',
                                   text='ASV Control Panel',
                                   font='Helvetica 14 bold').pack()
        # 1) Go to map location
        # self.control_wp_dxdy = Label(self.sidebar_frame, anchor='w', width=30, text='dx: ???, dy: ???')
        # self.control_wp_dxdy.pack()

        self.auv_status = Label(self.sidebar_frame,
                                anchor='w',
                                text='ASV Status: STOPPED',
                                fg="red")
        self.auv_status.pack()

        self.transect_mission_label = Label(self.sidebar_frame,
                                            anchor='w',
                                            text='Transect Mission: NO',
                                            fg="red")
        self.transect_mission_label.pack()
        self.transect_mission = Button(self.sidebar_frame,
                                       anchor='w',
                                       text='Enable Transect Mission',
                                       command=self.on_toggle_transect)
        self.transect_mission.pack()

        # Repeat mission (has been commented out because not useful)
        # self.repeat_mission_label = Label(self.sidebar_frame, anchor='w', text='Repeat Mission: NO', fg="red")
        # self.repeat_mission_label.pack()

        # self.repeat_frame = Frame(self.sidebar_frame)
        # self.repeat_frame.pack()
        # self.repeat_label = Label(self.repeat_frame, anchor='w', text='# Repeats').pack(side='left')
        # self.repeat_times = Entry(self.repeat_frame, width=5)
        # self.repeat_times.insert(END, '10')
        # self.repeat_times.pack(side='right')
        # self.repeat_mission = Button(self.sidebar_frame, anchor='w', text='Enable Repeat Mission', command=self.on_toggle_repeat_mission)
        # self.repeat_mission.pack()

        self.start_frame = Frame(self.sidebar_frame)
        self.start_frame.pack()
        self.start_stop = Button(self.start_frame,
                                 anchor='w',
                                 text='Start ASV',
                                 command=self.on_startstop)
        self.start_stop.pack(side='left')
        self.mission = Button(self.start_frame,
                              anchor='w',
                              text='Start Mission',
                              command=self.on_toggle_mission)
        self.mission.pack(side='right')

        # 2) Mission planning
        self.mission_title = Label(self.sidebar_frame,
                                   anchor='w',
                                   text='Mission Planning',
                                   font='Helvetica 14 bold').pack()
        self.mission_disclaimer = Label(
            self.sidebar_frame,
            anchor='w',
            text=
            'Red=Point Tracking(1), Orange=Transect(2).\nClick on WP in map to change color.',
            font='Helvetica 10 italic').pack()
        self.mission_frame = Frame(self.sidebar_frame)
        self.scrollbar = Scrollbar(self.mission_frame)
        self.scrollbar.pack(side='right')
        self.w_name = Label(self.mission_frame, text='')
        self.wp_list = Listbox(self.mission_frame,
                               width=30,
                               height=12,
                               yscrollcommand=self.scrollbar.set)
        self.wp_list.pack(side='left')
        self.wp_list.bind('<<ListboxSelect>>', self.on_waypoint_selection)
        self.scrollbar.config(command=self.wp_list.yview)
        self.mission_frame.pack()

        self.mission_file_frame = Frame(self.sidebar_frame)
        self.mission_file_frame.pack()
        self.load_mission = Button(
            self.mission_file_frame,
            anchor='w',
            text='Load Mission File',
            command=self.on_load_mission).pack(side='left')
        self.save_mission = Button(
            self.mission_file_frame,
            anchor='w',
            text='Save Mission to File',
            command=self.on_save_mission).pack(side='right')

        self.mission_add_wps = Button(self.sidebar_frame,
                                      anchor='w',
                                      text='Add Waypoints',
                                      command=self.on_toggle_add_wps)
        self.mission_add_wps.pack()
        self.mission_remove_wps = Button(self.sidebar_frame,
                                         anchor='w',
                                         text='Remove Waypoints',
                                         command=self.on_toggle_remove_wps)
        self.mission_remove_wps.pack()

        self.clear_wps = Button(self.sidebar_frame,
                                anchor='w',
                                text='Clear All Waypoints',
                                command=self.on_clear_wps)
        self.clear_wps.pack()

        #######################################################################
        # MAP CANVAS
        #######################################################################

        # Load map image
        pilImg = Image.open(MAP_FILE)
        pilImg = pilImg.resize((MAP_WIDTH, MAP_HEIGHT), Image.ANTIALIAS)
        self.img = ImageTk.PhotoImage(pilImg)

        # map
        self.canvas = Canvas(self.map_frame,
                             width=MAP_WIDTH,
                             height=MAP_HEIGHT)
        self.canvas.create_image(0, 0, image=self.img, anchor=NW)
        self.canvas.pack(side='top')
        self.canvas.bind("<Button 1>", self.on_location_click)
        self.origin_marker1 = self.canvas.create_line(
            0, -10, 0, 10, fill='black', width=2)  #to create a cross
        self.origin_marker2 = self.canvas.create_line(-10,
                                                      0,
                                                      10,
                                                      0,
                                                      fill='black',
                                                      width=2)

        #######################################################################
        # CONFIGURATION FRAME
        #######################################################################

        self.control_config_frame = Frame(self.map_frame, height=15)
        self.control_config_frame.pack(side='left')

        self.misc_frame = Frame(self.map_frame)
        self.misc_frame.pack(side='right')

        self.border_frame = Frame(self.misc_frame, height=15)
        self.border_frame.pack(side='top')
        self.compass_frame = Frame(self.misc_frame, height=15)
        self.compass_frame.pack(side='bottom')

        # Tracing border
        self.border_label = Label(self.border_frame,
                                  anchor='w',
                                  text='Border Configuration',
                                  font='Helvetica 14 bold').pack()
        self.border = Button(self.border_frame,
                             anchor='w',
                             text='Trace Border',
                             command=self.on_toggle_border)
        self.border.pack()
        self.clear_border = Button(self.border_frame,
                                   anchor='w',
                                   text='Clear Border',
                                   command=self.on_clear_border).pack()
        self.load_border = Button(self.border_frame,
                                  anchor='w',
                                  text='Load Border',
                                  command=self.on_load_border).pack()
        self.save_border = Button(self.border_frame,
                                  anchor='w',
                                  text='Save Border',
                                  command=self.on_save_border).pack()

        # Compass calibration
        self.compass_label = Label(self.compass_frame,
                                   anchor='w',
                                   text='Compass Calibration',
                                   font='Helvetica 14 bold').pack()
        self.heading_frame = Frame(self.compass_frame)
        self.heading_frame.pack()
        self.heading_offset_label = Label(
            self.heading_frame, anchor='w',
            text='Heading Offset (deg)').pack(side='left')
        self.heading_offset = Entry(self.heading_frame, width=6)
        self.heading_offset.insert(END, '-12')
        self.heading_offset.pack(side='right')
        self.set_heading_offset = Button(
            self.compass_frame,
            anchor='w',
            text='Set Heading Offset',
            command=self.on_set_heading_offset).pack()

        # Control parameters/speed
        self.control_config = Label(self.control_config_frame,
                                    anchor='w',
                                    text='Control',
                                    font='Helvetica 14 bold').pack()
        self.control_info = Label(self.control_config_frame,
                                  anchor='w',
                                  text='ASV Speed: ?\n Speed to Dest: ?\n',
                                  fg="red")
        self.control_info.pack()
        # self.origin = Button(self.sidebar_frame, anchor='w', text='Set Map Origin', command=self.on_toggle_set_origin)
        # self.origin.pack()

        self.speed_frame = Frame(self.control_config_frame)
        self.speed_frame.pack()
        # self.set_desired_speed = Button(self.speed_frame, anchor='w', text='Set Desired Speed', command=self.on_set_desired_speed)
        # self.set_desired_speed.pack()
        # self.desired_speed_label = Label(self.speed_frame, anchor='w', text='Desired Speed (m/s)').pack(side='left')
        # self.desired_speed = Entry(self.speed_frame, width=10)

        # self.desired_speed.insert(END, '3')
        # self.desired_speed.bind('<Return>', self.on_set_desired_speed)
        # self.desired_speed.pack(side='right')

        #######################################################################
        # Point Tracking Parameters
        #######################################################################

        self.Kp_frame = Frame(self.control_config_frame)
        self.Kp_frame.pack()

        self.Kp_ang_label = Label(self.Kp_frame, anchor='w',
                                  text='K_ang').pack(side='left')
        self.Kp_ang = Entry(self.Kp_frame, width=5)
        self.Kp_ang.insert(END, '800')
        self.Kp_ang.pack(side='left')
        self.Kp_nom_label = Label(self.Kp_frame, anchor='w',
                                  text='K_nom').pack(side='left')
        self.Kp_nom = Entry(self.Kp_frame, width=5)
        self.Kp_nom.insert(END, '1000')
        self.Kp_nom.pack(side='left')
        self.K_vi_label = Label(self.Kp_frame, anchor='w',
                                text='K_vi').pack(side='left')
        self.K_vi = Entry(self.Kp_frame, width=5)
        self.K_vi.insert(END, '0')
        self.K_vi.pack(side='left')

        #######################################################################
        # Transect Parameters
        #######################################################################

        self.transect_frame1 = Frame(self.control_config_frame)
        self.transect_frame1.pack()
        self.K_v_label = Label(self.transect_frame1, anchor='w',
                               text='K_v').pack(side='left')
        self.K_v = Entry(self.transect_frame1, width=5)
        self.K_v.insert(END, '0.5')
        self.K_v.pack(side='left')
        self.K_latAng_label = Label(self.transect_frame1,
                                    anchor='w',
                                    text='K_latAng').pack(side='left')
        self.K_latAng = Entry(self.transect_frame1, width=5)
        self.K_latAng.insert(END, '0.5')
        self.K_latAng.pack(side='left')
        self.K_vert_label = Label(self.transect_frame1,
                                  anchor='w',
                                  text='K_vert').pack(side='left')
        self.K_vert = Entry(self.transect_frame1, width=5)
        self.K_vert.insert(END, '1000')
        self.K_vert.pack(side='left')

        self.transect_frame2 = Frame(self.control_config_frame)
        self.transect_frame2.pack()
        self.v_rate_label = Label(self.transect_frame2,
                                  anchor='w',
                                  text='v_rate').pack(side='left')
        self.v_rate = Entry(self.transect_frame2, width=5)
        self.v_rate.insert(END, '5')
        self.v_rate.pack(side='left')
        self.a_rate_label = Label(self.transect_frame2,
                                  anchor='w',
                                  text='a_rate').pack(side='left')
        self.a_rate = Entry(self.transect_frame2, width=5)
        self.a_rate.insert(END, '5')
        self.a_rate.pack(side='left')
        self.vx_des_label = Label(self.transect_frame2,
                                  anchor='w',
                                  text='vx_des').pack(side='left')
        self.vx_des = Entry(self.transect_frame2, width=5)
        self.vx_des.insert(END, '1')
        self.vx_des.pack(side='left')

        #######################################################################
        # Throttle Thresholds
        #######################################################################

        self.throttle_frame = Frame(self.control_config_frame)
        self.throttle_frame.pack()
        self.fwd_limit_frame = Frame(self.throttle_frame)
        self.fwd_limit_frame.pack(side='left')
        self.fwd_limit_label = Label(self.fwd_limit_frame,
                                     anchor='w',
                                     text='Fwd Limit').pack(side='left')
        self.fwd_limit = Entry(self.fwd_limit_frame, width=5)
        self.fwd_limit.insert(END, '1000')
        self.fwd_limit.pack(side='right')
        self.bwd_limit_frame = Frame(self.throttle_frame)
        self.bwd_limit_frame.pack(side='right')
        self.bwd_limit_label = Label(self.bwd_limit_frame,
                                     anchor='w',
                                     text='Bwd Limit').pack(side='left')
        self.bwd_limit = Entry(self.bwd_limit_frame, width=5)
        self.bwd_limit.insert(END, '1000')
        self.bwd_limit.pack(side='right')

        self.set_control_params = Button(self.control_config_frame,
                                         anchor='w',
                                         text='Set Control Params',
                                         command=self.on_set_control).pack()
Ejemplo n.º 26
0
def CoordToIndex(geoTransform, x, y):
    """Return the offset of the provided co-ordinate from origin of raster"""
    invGeotransform = gdal.InvGeoTransform(geoTransform)
    x1, y1 = gdal.ApplyGeoTransform(invGeotransform, x, y)
    columnPosition, RowPosition = int(x1), int(y1)
    return (columnPosition, RowPosition)
Ejemplo n.º 27
0
def rasterise_vector(raster_fname,
                     vector_fname,
                     where_statement=None,
                     output_fname="",
                     output_format="MEM",
                     verbose=False):
    """Rasterises a vector file to produce a mask where some condition 
    in the vector dataset is true. The mask will have the same extent and
    projection as a (provided) 'master' dataset. The selection of the feature
    for the mask will be performed by a command of the form field_name='Value',
    where the single quotes are mandatory (e.g. NAME='Ireland').
    
    Parameters
    -----------
    raster_fname: str
        A GDAL-compatible raster filename that will be used to extract the
        shape, projection, resolution, ... for the rasterisation.
    vector_fname: str
        The vector filename (e.g. Shapefile)
    where_statement: str
        The where statement (e.g. "NAME='Colombia'").
    output_fname: str, optinal
        The output filename, if not provided, an "in-memory array" will be 
        selected. If not provided and the output_format is other than `MEM`
        an error will be raised.
    output_format: str, optional
        An output format. By default, `MEM`
    verbose: Boolean
        Whether to get some extra inforamation
    
    Returns
    --------
    The mask as a Numpy array, 0 where the mask is off, 1 where it is on.    
    
    """
    if output_fname == "" and output_format != "MEM":
        raise ValueError("You need to provide an ouput filename" +
                         " for format{:s}".format(output_format))
    g = gdal.Open(raster_fname)
    if g is None:
        raise IOError("Could not open file {:s}".format(raster_fname))
    raster_proj = g.GetProjectionRef()
    geoT = g.GetGeoTransform()
    if verbose:
        print(">>> Opened file {:s}".format(raster_fname))
        print(">>> Projection: {:s}".format(raster_proj))
    xs = []
    ys = []
    for x, y in [[0, 0], [0, g.RasterYSize], [g.RasterXSize, g.RasterYSize],
                 [g.RasterXSize, 0]]:
        xx, yy = gdal.ApplyGeoTransform(geoT, x, y)
        xs.append(xx)
        ys.append(yy)
    extent = [min(xs), min(ys), max(xs), max(ys)]
    xRes = geoT[1]
    yRes = geoT[-1]
    nx = g.RasterXSize
    ny = g.RasterYSize
    if verbose:
        print(">>> File size {:d} rows, {:d} columns".format(nx, ny))
        print(">>> UL corner: {:g}, {:g}".format(min(xs), max(ys)))

    src_ds = gdal.OpenEx(vector_fname)
    if src_ds is None:
        raise IOError("Can't read the vector file {}".format(vector_fname))
    v = gdal.VectorTranslate('',
                             src_ds,
                             format='Memory',
                             dstSRS=raster_proj,
                             where=where_statement)
    gg = gdal.Rasterize(output_fname,
                        v,
                        format=output_format,
                        outputType=gdal.GDT_Byte,
                        xRes=xRes,
                        yRes=yRes,
                        where=where_statement,
                        outputBounds=[min(xs),
                                      min(ys),
                                      max(xs),
                                      max(ys)],
                        width=nx,
                        height=ny,
                        noData=0,
                        burnValues=1)

    if gg is not None:
        if verbose:
            print("Done! {:d} non-zero pixels".format(gg.ReadAsArray().sum()))
    else:
        raise ValueError("Couldn't generate the mask. Check input parameters")
    return gg.ReadAsArray()
Ejemplo n.º 28
0
def main():
    img, inv_trans, geo_trans, MAP_WIDTH, MAP_HEIGHT = load_map(map_file)

    #GPS DATA
    ASV_X, ASV_Y = read_GPS_file(GPS_file, inv_trans)
    num_measurements = len(ASV_X)

    #ADCP DATA
    Z = read_ADCP_file(depths_file, num_measurements)  #Z = water depths
    min_depth = Z.min()

    #HEADINGS
    headings = read_heading_file(heading_file, num_measurements)

    #Normalize positions
    min_x = min(ASV_X)
    min_y = min(ASV_Y)
    X = [v - min_x for v in ASV_X]
    Y = [v - min_y for v in ASV_Y]
    max_x = max(X)
    max_y = max(Y)

    # Method 0: 1D Kalman Filter
    m = int(np.ceil(max_x / CELL_RES))
    n = int(np.ceil(max_y / CELL_RES))
    baseFloor = min_depth
    B = baseFloor * np.ones((m, n))
    Bvar = np.zeros((m, n))

    for t in range(num_measurements):
        cur_x = X[t]
        cur_y = Y[t]
        cur_alt = Z[t]

        i = int(np.floor(cur_x / CELL_RES))
        j = int(np.floor(cur_y / CELL_RES))

        for k in range(max(0, i - win), min(m, i + win)):
            for l in range(max(0, j - win), min(n, j + win)):
                dist2 = 0.1 + CELL_RES * ((k - i)**2 + (l - j)**2)**0.5

                if B[k][l] == baseFloor:
                    B[k][l] = cur_alt
                    Bvar[k][l] = (dist2 * sigma_slope + sigma_offset)**2
                else:
                    var = (dist2 * sigma_slope + sigma_offset)**2
                    cur_K = float(Bvar[k][l]) / (Bvar[k][l] + var)
                    B[k][l] = B[k][l] + cur_K * (cur_alt - B[k][l])
                    Bvar[k][l] = Bvar[k][l] - cur_K * Bvar[k][l]

    # Method 1: Linear Interpolation
    xi, yi = np.mgrid[ASV_X.min():ASV_X.max():1000j,
                      ASV_Y.min():ASV_Y.max():1000j]

    # Z is a matrix of x-y values
    points = []
    for i in range(len(ASV_X)):
        points.append([ASV_X[i], ASV_Y[i]])

    zi = griddata(points, Z, (xi, yi), method='linear')
    for i in range(len(zi)):
        for j in range(len(zi[0])):
            if np.isnan(zi[i][j]):
                zi[i][j] = min_depth

    ###########################################################################
    # PLOTS
    # 1) Map w/ ASV path
    imgplot = plt.imshow(img)
    plt.plot(ASV_X, ASV_Y, color='black', zorder=2)
    plt.xlabel('Meters')
    plt.ylabel('Meters')

    x0, y0 = gdal.ApplyGeoTransform(geo_trans, 0, 0)  #UTM of top left corner
    x1, y1 = gdal.ApplyGeoTransform(geo_trans, 4000, 3000)
    print('Offsets', x1 - x0, y1 - y0)

    ax = plt.gca()  # grab the current axis
    ax.set_xticks(np.arange(0, MAP_WIDTH + 500,
                            500))  # choose which x locations to have ticks
    xlabels = np.linspace(0, x1 - x0, int(MAP_WIDTH / 500.) + 1)
    xlabels = [int(p) for p in xlabels]
    ax.set_xticklabels(xlabels)  # set the labels to display at those ticks

    ax.set_yticks(np.arange(0, MAP_HEIGHT,
                            500))  # choose which x locations to have ticks
    ylabels = np.linspace(0, y0 - y1, int(MAP_HEIGHT / 500.) + 1)
    ylabels = [int(p) for p in ylabels]
    ax.set_yticklabels(ylabels)  # set the labels to display at those ticks

    #plt.contourf(xi, yi, zi, 10, cmap=plt.cm.rainbow, zorder=1)

    # 2) Depth surface map
    # B_new = np.zeros((n,m))
    # for i in range(n):
    #     for j in range(m):
    #         B_new[i][j] = B[j][i]

    # X_plot, Y_plot = np.meshgrid(np.arange(m), np.arange(n))
    # ax1 = plt.figure(figsize=(8,6)).gca(projection='3d')
    # surf = ax1.plot_surface(X_plot, Y_plot, B_new, cmap=cm.viridis)

    # p = ax1.plot(X, Y, np.zeros(len(X)), color='red')
    # ax1.view_init(200, -50)
    # ax1.set_zlabel('Depth (m)')
    # ax1.invert_zaxis()
    # ax1.set_xlabel('Easting (m)')
    # ax1.set_ylabel('Northing (m)')
    plt.show()
Ejemplo n.º 29
0
index = 0
for i in convexhulls:
    # 0 means read-only. 1 means writeable.
    vect_data_source = driver.Open(i, 0)

    # Get the Layer class object
    layer = vect_data_source.GetLayer(0)

    # Determine the spatial extent of the track
    # is a list with x_left, x_right, y_bottom, y_top
    extent = layer.GetExtent()
    print('vector extent is', extent)

    # Decide on the size of the buffer around the track
    buffer = 0.002
    x1, y1 = gdal.ApplyGeoTransform(inv_gt, extent[0] - buffer,
                                    extent[2] - buffer)
    x2, y2 = gdal.ApplyGeoTransform(inv_gt, extent[1] + buffer,
                                    extent[3] + buffer)

    # round these indices, (especially when not using a buffer)
    # y indices increase from top to bottom!!
    #print('column numbers are', x1, x2, y1, y2)
    x1 = int(round(x1))
    y1 = int(round(y1))
    x2 = int(round(x2))
    y2 = int(round(y2))
    print(x1, x2, y1, y2)
    #print('column numbers are', x1, x2, y1, y2)
    # calculate how many rows and columns the ranges cover
    out_columns = x2 - x1
    # y indices increase from top to bottom!!
Ejemplo n.º 30
0
def main(args):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--input_geon',
        # default='../out_geon/D4_Curve_Geon.npy',
        type=str,
        help='input geon file.')
    parser.add_argument(
        '--input_dtm',
        # default='/dvmm-filer2/projects/Core3D/D4_Jacksonville/DTMs/D4_DTM.tif',
        type=str,
        help='Input dtm')  # D3_UCSD D4_Jacksonville
    parser.add_argument(
        '--output_mesh',
        # default='../out_geon/D4_Curve_Mesh.ply',
        type=str,
        help='Output ply mesh file.')
    parser.add_argument(
        '--as-text',
        action='store_true',
        default=False,
        help='Output ply as ASCII instead of binary')
    args = parser.parse_args(args)

    original_dtm = gdal.Open(args.input_dtm, gdal.GA_ReadOnly)
    gt = original_dtm.GetGeoTransform()  # captures origin and pixel size
    left = gdal.ApplyGeoTransform(gt, 0, 0)[0]
    top = gdal.ApplyGeoTransform(gt, 0, 0)[1]
    right = gdal.ApplyGeoTransform(
        gt, original_dtm.RasterXSize, original_dtm.RasterYSize)[0]
    bottom = gdal.ApplyGeoTransform(
        gt, original_dtm.RasterXSize, original_dtm.RasterYSize)[1]

    dtm = original_dtm.ReadAsArray()

    projection_model = {}
    projection_model['corners'] = [left, top, right, bottom]
    projection_model['project_model'] = gt
    projection_model['scale'] = 1.0

    geon_model = []
    all_vertex = []
    all_face = []

    center_of_mess, geon_model = pickle.load(open(args.input_geon, "rb"))

    for model in geon_model:
        if model['name'] == 'poly_cylinder':
            centroid, ex, ey, coefficients, min_axis_z,\
                max_axis_z, ortho_x_min, ortho_x_max, fitted_indices_length, mean_diff = model[
                    'model']
            vertex, face = utils.get_poly_ply_volume(dtm, projection_model, centroid, ex, ey,
                                                     coefficients, min_axis_z, max_axis_z,
                                                     ortho_x_min, ortho_x_max, len(all_vertex),
                                                     center_of_mess)
            if len(all_vertex) > 0:
                all_vertex.extend(vertex)
                all_face.extend(face)
            else:
                all_vertex = vertex
                all_face = face

        elif model['name'] == 'sphere':
            centroid, r, min_axis_z,\
                max_axis_z, fitted_indices_length = model['model']
            theta_max = get_theta(min_axis_z, r)
            theta_min = get_theta(max_axis_z, r)

            vertex, face = utils.get_sphere_volume(dtm, projection_model, centroid, r,
                                                   theta_min, theta_max, len(all_vertex),
                                                   center_of_mess)

            if len(all_vertex) > 0:
                all_vertex.extend(vertex)
                all_face.extend(face)
            else:
                all_vertex = vertex
                all_face = face

    for idx in range(len(all_vertex)):
        all_vertex[idx] = (all_vertex[idx][0]+center_of_mess[0],
                           all_vertex[idx][1]+center_of_mess[1],
                           all_vertex[idx][2]+center_of_mess[2])

    all_vertex = np.array(
        all_vertex, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
    all_face = np.array(all_face, dtype=[(
        'vertex_indices', 'i4', (3,)), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])

    el_vertex = plyfile.PlyElement.describe(all_vertex, 'vertex')
    el_face = plyfile.PlyElement.describe(all_face, 'face')
    plyfile.PlyData([el_vertex, el_face],
                    text=args.as_text).write(args.output_mesh)