Exemplo n.º 1
0
def get_projection(image_type):
    '''
    Generate EXIF data, utm zone and hemisphere.
    :param image_type:
    :return: utm_zone, hemisphere
    '''
    Image = namedtuple('Image', ['image', 'point', 'altitude'])

    kwargs = {'image_type': image_type}

    system.run('exiftool -filename -gpslongitude -gpslatitude -gpsaltitude '
               '-T -n *.{image_type} > imageEXIF.txt'.format(**kwargs))

    with open('imageEXIF.txt', 'r') as f:
        lines = (l.split('\t') for l in f.readlines())
        coords = [
            Image(image=l[0].strip(),
                  point=Point(float(l[1]), float(l[2])),
                  altitude=l[3].strip()) for l in lines
        ]

    p = Point(coords[0][1])
    u = utm.from_latlon(p.y, p.x)
    utm_zone = u[2]
    hemisphere = "north" if p.y > 0 else "south"

    log.MM_INFO('UTM - %s' % utm_zone)
    log.MM_INFO('Hemisphere - %s' % hemisphere)

    return {'utm_zone': utm_zone, 'hemisphere': hemisphere}
Exemplo n.º 2
0
def remove_ortho_tiles():
    '''
    Remove every other orthomosaic tile. Optimizes color balance and radiometric routine,
    speeds up ortho generation using Porto/Tawny module.
    '''
    ort_files = 'Ortho-MEC-Malt/Ort_*.tif'
    if glob.glob(ort_files):
        tiles = glob.glob(ort_files)
        tiles.sort(key=lambda f: int(filter(str.isdigit, f)))
        for tile in tiles[::2]:
            os.remove(tile)
            log.MM_INFO('Removing ortho tile {}'.format(tile))
Exemplo n.º 3
0
def parse_srs_header(header):
    """
    Parse a header coming from GCP or coordinate file
    :param header (str) line
    :return Proj object
    """
    log.MM_INFO('Parsing SRS header: %s' % header)
    header = header.strip()
    ref = header.split(' ')
    try:
        if ref[0] == 'WGS84' and ref[1] == 'UTM':
            datum = ref[0]
            utm_pole = (ref[2][len(ref[2]) - 1]).upper()
            utm_zone = int(ref[2][:len(ref[2]) - 1])

            proj_args = {'zone': utm_zone, 'datum': datum}

            proj4 = '+proj=utm +zone={zone} +datum={datum} +units=m +no_defs=True'
            if utm_pole == 'S':
                proj4 += ' +south=True'

            srs = CRS.from_proj4(proj4.format(**proj_args))
        elif '+proj' in header:
            srs = CRS.from_proj4(header.strip('\''))
        elif header.lower().startswith("epsg:"):
            srs = CRS.from_epsg(header.lower()[5:])
        else:
            log.MM_ERROR('Could not parse coordinates. Bad SRS supplied: %s' %
                         header)
    except RuntimeError as e:
        log.MM_ERROR(
            'Uh oh! There seems to be a problem with your coordinates/GCP file.\n\n'
            'The line: %s\n\n'
            'Is not valid. Projections that are valid include:\n'
            ' - EPSG:*****\n'
            ' - WGS84 UTM **(N|S)\n'
            ' - Any valid proj4 string (for example, +proj=utm +zone=32 +north +ellps=WGS84 +datum=WGS84 +units=m +no_defs)\n\n'
            'Modify your input and try again.' % header)
        raise RuntimeError(e)
    return srs
Exemplo n.º 4
0
        f.write(ccd_size)
        short_name = '\t\t\t\t<ShortName> {} </ShortName>\n'.format(
            camera_model)
        f.write(short_name)
        f.write('\t\t\t</CameraEntry>\n')
        f.write('\t\t</LocCamDataBase>\n')
        f.write('\t</ChantierDescripteur>\n')
        f.write('</Global>\n')


# RUN
if __name__ == '__main__':

    args = config.config()

    log.MM_INFO('Initializing NodeMICMAC app - %s' % system.now())
    log.MM_INFO(args)

    progressbc.set_project_name(args.name)

    project_dir = io.join_paths(args.project_path, args.name)
    image_dir = io.join_paths(project_dir, 'images')

    IN_DOCKER = os.environ.get('DEBIAN_FRONTEND', False)

    if IN_DOCKER:
        mm3d = 'mm3d'
    else:
        mm3d = '/home/drnmppr-micmac/bin/mm3d'  # for dev: locally installed micmac branch

    try:
Exemplo n.º 5
0
def convert_gcp(gcp_dir, utm_zone, hemisphere):
    '''
    Convert MicMac GCP TXT files to MicMac GCP XML format
    :param image_dir: path
    :return:

    Expects files to be named, DroneMapperGCP_2D.txt and DroneMapperGCP_3D.txt or ODM format: gcp_list.txt

    DroneMapperGCP_2D.txt format (single space delimiter):
    GCP IMAGENAME PIXELX PIXELY

    DroneMapperGCP_3D.txt format (single space delimiter):
    GCP UTMX UTMY Z PRECISION X/Y PRECISIONZ
    '''
    from opendm import gcp

    log.MM_INFO('Converting GCP.')

    gcp_files = os.listdir(gcp_dir)
    for file in gcp_files:
        if '3d' in file.lower():
            gcp_3d_file = file
        if '2d' in file.lower():
            gcp_2d_file = file
        if 'gcp_list' in file.lower():
            gcp_file = gcp.GCPFile(os.path.join(gcp_dir, file))
            gcp_file.make_micmac_copy(gcp_dir,
                                      utm_zone='WGS84 UTM {}{}'.format(
                                          utm_zone, hemisphere))
            gcp_2d_file = '2d_gcp.txt'
            gcp_3d_file = '3d_gcp.txt'

    # MicMac GCP 2D - target locations in images
    # GCPNAME IMAGE PIXELX PIXELY
    MM2D = namedtuple('MM2D', ['gcp', 'img', 'px', 'py'])

    with open(io.join_paths(gcp_dir, gcp_2d_file), 'r') as f2d_txt:
        lines = (l.split() for l in f2d_txt.readlines())
        images = [
            MM2D(gcp=l[0].strip(),
                 img=l[1].strip(),
                 px=l[2].strip(),
                 py=l[3].strip()) for l in lines
        ]

    with open(io.join_paths(image_dir, 'images.xml'), 'wb') as images_xml:
        images_xml.write('<?xml version="1.0"?>\n')
        images_xml.write('<SetOfMesureAppuisFlottants>\n')
        for image in images:
            log.MM_INFO('GCP in image {}'.format(image))
            gcp = image[0]
            img = image[1]
            px = image[2]
            py = image[3]
            images_xml.write('\t<MesureAppuiFlottant1Im>\n')
            name_im = '\t\t<NameIm> {} </NameIm>\n'.format(img)
            images_xml.write(name_im)
            images_xml.write('\t\t<OneMesureAF1I>\n')
            name_pt = '\t\t\t<NamePt> {} </NamePt>\n'.format(gcp)
            images_xml.write(name_pt)
            pt_im = '\t\t\t<PtIm> {} {} </PtIm>\n'.format(px, py)
            images_xml.write(pt_im)
            images_xml.write('\t\t</OneMesureAF1I>\n')
            images_xml.write('\t</MesureAppuiFlottant1Im>\n')
        images_xml.write('</SetOfMesureAppuisFlottants>\n')

    # MicMac GCP 3D - real world target position on ground (UTM)
    # GCPNAME UTMX UTMY Z PRECISIONXY PRECISIONZ
    MM3D = namedtuple('MM3D', ['gcp', 'x', 'y', 'z', 'pxy', 'pz'])

    with open(io.join_paths(gcp_dir, gcp_3d_file), 'r') as f3d_txt:
        lines = (l.split() for l in f3d_txt.readlines())
        coords = [
            MM3D(gcp=l[0].strip(),
                 x=l[1].strip(),
                 y=l[2].strip(),
                 z=l[3].strip(),
                 pxy=l[4].strip(),
                 pz=l[5].strip()) for l in lines
        ]

    with open(io.join_paths(image_dir, 'ground.xml'), 'wb') as ground_xml:
        ground_xml.write('<?xml version="1.0"?>\n')
        ground_xml.write('<Global>\n')
        ground_xml.write('\t<DicoAppuisFlottant>\n')
        for c in coords:
            log.MM_INFO('GCP on ground {}'.format(c))
            gcp = c[0]
            x = c[1]
            y = c[2]
            z = c[3]
            pxy = c[4]
            pz = c[5]
            ground_xml.write('\t\t<OneAppuisDAF>\n')
            pt = '\t\t\t<Pt> {} {} {} </Pt>\n'.format(x, y, z)
            ground_xml.write(pt)
            name_pt = '\t\t\t<NamePt> {} </NamePt>\n'.format(gcp)
            ground_xml.write(name_pt)
            precision = '\t\t\t<Incertitude> {} {} {} </Incertitude>\n'.format(
                pxy, pxy, pz)
            ground_xml.write(precision)
            ground_xml.write('\t\t</OneAppuisDAF>\n')
        ground_xml.write('\t</DicoAppuisFlottant>\n')
        ground_xml.write('</Global>\n')