Пример #1
0
    def fetch_locations(self):
        """
        This method is responsible for delivering the list of locations for which we have expert created data.
        This currently grabs a csv file containing information from the Digital Library.  It parses that file
        and then looks through the location data in the Data Warehouse.  If it can't find a match it hides that
        result from the user.
        NOTE: During the last Digital Library outage we moved the file into the adapter itself.

        :returns: Dictionary containing location information where the keys are the location indexes
        """
        # TODO: Raise exceptions instead of returning -1

        try:
            if self.model_id == 1:
                csv = self.EMOD_buffer
            elif self.model_id == 2:
                csv = self.OM_buffer
            # csv = urllib2.urlopen(self.csv_url, timeout=30)  # Creates a "file-like" object containing the csv information
        except urllib2.URLError:
            print "There has been an error retrieving the csv from the meta data catalog"
            return -1

        # Skip the first line, as it contains header information
        contents = csv.readline()

        contents = csv.read().split('\n')

        # If self.location_dict exists, wipe it out
        self.locations_dict.clear()

        for line in contents:
            elements = line.split(',')
            if line == '': continue
            # Find locations and get location id
            loc_filter = DimLocation.objects.filter(
                Q(admin3=elements[1]) |
                Q(admin2=elements[1]) |
                Q(admin1=elements[1]) |
                Q(admin0=elements[1])
            )
            if loc_filter.exists():
                # Takes the first one it finds
                location = loc_filter[0]
            else:
                loc_filter = GisBaseTable.objects.filter(s_name=elements[1])
                if not loc_filter.exists():
                    #Not in our database, so it shouldn't be presented to the tools
                    continue
                contains = GisBaseTable.objects.filter(geom__contains=loc_filter[0].geom)
                geo_dict = {
                    -1: None,
                    0: None,
                    1: None,
                    2: None,
                    3: None
                }
                for geo in contains:
                    geodict[geo.admin_level] = geo.s_name
                location = DimLocation(
                    admin007=geo_dict[-1],
                    admin0=geo_dict[0],
                    admin1=geo_dict[1],
                    admin2=geo_dict[2],
                    admin3=geo_dict[3],
                    geom_key_id=loc_filter[0].id
                )
                location.save()

            if elements[3] == 'NA':
                start_date = ''
                end_date = ''
            else:
                start = elements[3].split('-')[0]
                end = elements[3].split('-')[1]
                start_date = '{0}-{1}-{2}'.format(start[0:4], start[4:6], start[6:8])
                end_date = '{0}-{1}-{2}'.format(end[0:4], end[4:6], end[6:8])

            # Fill the location dictionary
            self.locations_dict[location.id] = {
                "country": elements[0],
                "place": elements[1],
                "resolution": elements[2],
                "start_date": start_date,
                "end_date": end_date,
                "link": self.library_url + elements[4]
            }

            self.EMOD_buffer.seek(0)
            self.OM_buffer.seek(0)

        return self.locations_dict
Пример #2
0
    def locationMap(self, obj, row, cols):
        """This method is used to map the location key.

        Due to the complicated nature of gis data, a custom method was necessary
        to handle location fields. This method is responsible for ingesting location data
        into the database. It relies on Django's raw query capabilities.

        :return: A DimLocation object.
        """
        
        tmpdict = {}
        # if lattitude and longitude were given, use a stored procedure to find the location
        # containing the given lat/lon. Return the corresponding location, creating it if necessary.
        if 'lattitude' in obj and 'longitude' in obj:
            # Note this hasn't been tested yet (no test cases are available for ingestor)
            return DimLocation.vecnet_fill_location_from_point(row[cols[obj['lattitude']]], row[cols[obj['longitude']]])

            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            # Query below (SELECT vecnet_fill_location_from_point) will no longer works after removing
            # partition on gis_base_table. Stored procedure vecnet_fill_location_from_point assumes that
            # gis_adm_007, gis_adm_0lev and other tables exist.
            # This query can be replaced with
            # SELECT * FROM gis_base_table WHERE ST_CONTAINS(geom, ST_GeomFromText('point(%s %s)', 4326));
            # There are no test cases for ingester yet to update the code
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            # conn = connections['default']
            # cursor = conn.cursor()
            # cursor.execute("SELECT vecnet_fill_location_from_point(%s, %s);", [row[cols[obj['lattitude']]], row[cols[obj['longitude']]]])
            # tmp = cursor.fetchone()
            # tmpstr = tmp[0][2:][:-1]
            # tmplist = tmpstr.split(',')
            # tmpdict['geom_key'] = tmplist[0]
            # tmpdict['admin007'] = tmplist[1]
            # tmpdict['admin0'] = tmplist[2]
            # tmpdict['admin1'] = tmplist[3]
            # tmpdict['admin2'] = tmplist[4]
            # model, created = DimLocation.objects.get_or_create(**tmpdict)
            # conn.close()
            # return model
        # if lat/lon wasn't given, use the admin levels to determine the location. Create a
        # location object if necessary, and return the location object.
        else:
            if 'admin2' in obj:
                # Could be replaced with
                # GisBaseTable.object.get(s_name=row[obj['admin2']], admin_level = 2)
                # Double-check admin_level though
                gisobj = GisBaseTable.objects.get(s_name=row[cols[obj['admin2']]], admin_level=2)
                tmpdict['geom_key'] = gisobj.id
                tmpdict['admin2'] = gisobj.s_name
            elif 'admin1' in obj:
                gisobj = GisBaseTable.objects.get(s_name=row[cols[obj['admin1']]], admin_level=1)
                tmpdict['geom_key'] = gisobj.id
                tmpdict['admin1'] = gisobj.s_name
            elif 'admin0' in obj:
                gisobj = GisBaseTable.objects.get(s_name=row[cols[obj['admin0']]], admin_level=0)
                tmpdict['geom_key'] = gisobj.id
                tmpdict['admin0'] = gisobj.s_name
            elif 'admin007' in obj:
                gisobj = GisBaseTable.objects.get(s_name=row[cols[obj['admin007']]], admin_level=-1)
                tmpdict['geom_key'] = gisobj.id
                tmpdict['admin007'] = gisobj.s_name
            model, created = DimLocation.objects.get_or_create(**tmpdict)
            return model