def test_exif(self):
        """Read exif data from a known test image."""

        filename = resource_filename(
            "lizard_progress", "/testdata/IMG_0366.JPG")
        image = Image.open(filename)
        exif_data = get_exif_data(image)
        lat, lon = get_lat_lon(exif_data)

        self.assertEquals(lat, 52.08)
        self.assertEquals(lon, 5.011166666666667)
    def parse(self, check_only=False):
        if not isinstance(self.file_object, ImageFile):
            return UnSuccessfulParserResult()

        try:
            measurement_type = MeasurementType.objects.get(project=self.project, mtype__slug="foto")
        except MeasurementType.DoesNotExist:
            return self.error("no_mtype")

        # Uniek_id: Part of the filename before the extension, in
        # upper case.
        uniek_id = os.path.splitext(self.file_object.name)[0].upper()

        try:
            location = Location.objects.get(location_code=uniek_id, project=self.project)
        except Location.DoesNotExist:
            return self.error(uniek_id)

        exif_data = get_exif_data(self.file_object)
        lat, lon = get_lat_lon(exif_data)

        if not lat or not lon:
            return self.error("gps")

        x, y = wgs84_to_rd(lon, lat)
        x0, y0 = location.the_geom.x, location.the_geom.y
        d = sqrt((x - x0) ** 2 + (y - y0) ** 2)

        if d > 75.0:
            return self.error("toofar", d)

        try:
            scheduled_measurement = ScheduledMeasurement.objects.get(
                project=self.project, contractor=self.contractor, location=location, measurement_type=measurement_type
            )
        except ScheduledMeasurement.DoesNotExist:
            return self.error("scheduled", id, str(measurement_type))

        if not check_only:
            m, _ = Measurement.objects.get_or_create(scheduled=scheduled_measurement)

            m.data = {}
            m.date = None
            m.the_geom = Point(x, y, srid=SRID)
            m.save()

            scheduled_measurement.complete = True
            scheduled_measurement.save()
            measurements = (m,)
        else:
            measurements = ()

        return SuccessfulParserResult(measurements)
    def parse(self, check_only=False):
        if not isinstance(self.file_object, ImageFile):
            return UnSuccessfulParserResult()

        try:
            measurement_type = MeasurementType.objects.get(
                project=self.project,
                mtype__slug='oeverfoto')
        except MeasurementType.DoesNotExist:
            return self.error('no_mtype')

        # Filename is of the format "ID_L" or "ID_R", possibly in
        # mixed case. Since IDs are upper case, we change the filename
        # to upper case first.
        filename_no_suffix = os.path.splitext(self.file_object.name)[0].upper()

        is_left = filename_no_suffix.endswith('_L')
        is_right = filename_no_suffix.endswith('_R')
        if not (is_left or is_right):
            return self.error('notleftright')

        uniek_id = filename_no_suffix[:-2]

        try:
            location = Location.objects.get(
                location_code=uniek_id,
                project=self.project)
        except Location.DoesNotExist:
            return self.error('nolocation', uniek_id)

        exif_data = get_exif_data(self.file_object)
        lat, lon = get_lat_lon(exif_data)

        if not lat or not lon:
            return self.error('gps')

        x, y = wgs84_to_rd(lon, lat)
        x0, y0 = location.the_geom.x, location.the_geom.y
        d = sqrt((x - x0) ** 2 + (y - y0) ** 2)

        if d > 75.0:
            return self.error('toofar', d)

        try:
            scheduled_measurement = (ScheduledMeasurement.objects.
                                     get(project=self.project,
                                         contractor=self.contractor,
                                         location=location,
                                         measurement_type=measurement_type))
        except ScheduledMeasurement.DoesNotExist:
            return self.error('notscheduled', id, str(measurement_type))

        # Several measurements per scheduled measurement, find if ours exists
        # The measurements store 'left' or 'right' in the data field.
        data_field = 'left' if is_left else 'right'

        if not check_only:
            measurements = {}
            for m in scheduled_measurement.measurement_set.all():
                measurements[m.data] = m

            if data_field in measurements:
                measurement = measurements[data_field]
            else:
                # New
                measurement = Measurement(
                    scheduled=scheduled_measurement, data=data_field)
            measurements[data_field] = measurement

            measurement.date = None
            measurement.the_geom = Point(x, y, srid=SRID)
            measurement.save()

            if 'left' in measurements and 'right' in measurements:
                scheduled_measurement.complete = True
                scheduled_measurement.save()

            return self.success((measurement,))
        else:
            return self.success(())