示例#1
0
    def test_geocoded_fields_are_changed_appropriately_if_a_user_manually_updates_latitude_or_longitude_of_geocoded_property(self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id
        property_details['latitude'] = 39.765251
        property_details['longitude'] = -104.986138
        property_details['long_lat'] = 'POINT (-104.986138 39.765251)'
        property_details['geocoding_confidence'] = 'High (P1AAA)'
        property = PropertyState(**property_details)
        property.save()

        # Make sure geocoding_confidence isn't overriden to be Manual given latitude and longitude are updated
        refreshed_property = PropertyState.objects.get(pk=property.id)
        self.assertEqual('High (P1AAA)', refreshed_property.geocoding_confidence)

        # Try updating latitude
        refreshed_property.latitude = 39.81
        refreshed_property.save()

        refreshed_property = PropertyState.objects.get(pk=property.id)
        self.assertEqual(39.81, refreshed_property.latitude)
        self.assertEqual('POINT (-104.986138 39.81)', long_lat_wkt(refreshed_property))
        self.assertEqual("Manually geocoded (N/A)", refreshed_property.geocoding_confidence)

        # If latitude or longitude are not there long_lat and geocoding_confidence should be empty
        refreshed_property.latitude = None
        refreshed_property.save()

        self.assertIsNone(refreshed_property.latitude)
        self.assertIsNone(long_lat_wkt(refreshed_property))
        self.assertIsNone(refreshed_property.geocoding_confidence)
示例#2
0
    def test_geocoded_fields_are_changed_appropriately_if_a_user_manually_updates_latitude_or_longitude_of_ungeocoded_property(self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id
        property = PropertyState(**property_details)
        property.save()

        refreshed_property = PropertyState.objects.get(pk=property.id)
        self.assertIsNone(long_lat_wkt(refreshed_property))
        self.assertIsNone(refreshed_property.geocoding_confidence)

        refreshed_property.latitude = 39.765251
        refreshed_property.save()

        refreshed_property = PropertyState.objects.get(pk=property.id)
        self.assertEqual(39.765251, refreshed_property.latitude)
        self.assertIsNone(long_lat_wkt(refreshed_property))
        self.assertIsNone(refreshed_property.geocoding_confidence)

        refreshed_property.longitude = -104.986138
        refreshed_property.save()

        refreshed_property = PropertyState.objects.get(pk=property.id)
        self.assertEqual(-104.986138, refreshed_property.longitude)
        self.assertEqual('POINT (-104.986138 39.765251)', long_lat_wkt(refreshed_property))
        self.assertEqual("Manually geocoded (N/A)", refreshed_property.geocoding_confidence)
示例#3
0
    def test_geocoding_an_address_again_after_successful_geocode_executes_successfully(self):
        with base_vcr.use_cassette('seed/tests/data/vcr_cassettes/geocode_same_record_twice.yaml'):
            property_details = self.property_state_factory.get_details()
            property_details['organization_id'] = self.org.id
            property_details['address_line_1'] = "3001 Brighton Blvd"
            property_details['address_line_2'] = "suite 2693"
            property_details['city'] = "Denver"
            property_details['state'] = "Colorado"
            property_details['postal_code'] = "80216"
            property = PropertyState(**property_details)
            property.save()

            properties = PropertyState.objects.filter(pk=property.id)
            geocode_buildings(properties)

            refreshed_property = PropertyState.objects.get(pk=property.id)
            refreshed_property.address_line_1 = "2020 Lawrence St"
            refreshed_property.address_line_2 = "unit A"
            refreshed_property.postal_code = "80205"
            refreshed_property.save()

            refreshed_properties = PropertyState.objects.filter(pk=refreshed_property.id)
            geocode_buildings(refreshed_properties)

            refreshed_updated_property = PropertyState.objects.get(pk=refreshed_property.id)

            self.assertEqual('POINT (-104.991046 39.752396)', long_lat_wkt(refreshed_updated_property))
            self.assertEqual('High (P1AAA)', refreshed_updated_property.geocoding_confidence)
            self.assertEqual(-104.991046, refreshed_updated_property.longitude)
            self.assertEqual(39.752396, refreshed_updated_property.latitude)
示例#4
0
    def test_geocode_buildings_is_successful_even_if_two_buildings_have_same_address(self):
        with base_vcr.use_cassette('seed/tests/data/vcr_cassettes/geocode_dup_addresses.yaml'):
            property_details = self.property_state_factory.get_details()
            property_details['organization_id'] = self.org.id
            property_details['address_line_1'] = "3001 Brighton Blvd"
            property_details['address_line_2'] = "suite 2693"
            property_details['city'] = "Denver"
            property_details['state'] = "Colorado"
            property_details['postal_code'] = "80216"

            property_1 = PropertyState(**property_details)
            property_2 = PropertyState(**property_details)
            property_1.save()
            property_2.save()

            ids = [property_1.id, property_2.id]

            properties = PropertyState.objects.filter(id__in=ids)

            geocode_buildings(properties)

            refreshed_properties = PropertyState.objects.filter(id__in=ids)

            for property in refreshed_properties:
                self.assertEqual('POINT (-104.986138 39.765251)', long_lat_wkt(property))
                self.assertEqual('High (P1AAA)', property.geocoding_confidence)
                self.assertEqual(-104.986138, property.longitude)
                self.assertEqual(39.765251, property.latitude)
示例#5
0
    def test_merge_geocoding_ignore_merge_protection(self):
        """
        When merging records with geocoding columns including the
        ignore_merge_protection flag as True always takes the "new" state's
        geocoding results regardless of geocoding columns merge protection setting.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
            latitude=39.765251,
            longitude=-104.986138,
            geocoding_confidence='High (P1AAA)',
            long_lat='POINT (-104.986138 39.765251)',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor Existing',
            'latitude': 'Favor New',
            'longitude': 'Favor New',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities, True)
        self.assertEqual(result.geocoding_confidence, 'High (P1AAA)')
        self.assertEqual(result.latitude, 39.765251)
        self.assertEqual(result.longitude, -104.986138)
        self.assertEqual(long_lat_wkt(result), 'POINT (-104.986138 39.765251)')
示例#6
0
    def test_geocode_address_can_handle_addresses_with_reserved_and_unsafe_characters(
            self):
        with base_vcr.use_cassette(
                'seed/tests/data/vcr_cassettes/geocode_reserved_and_unsafe_characters.yaml'
        ):
            property_details = self.property_state_factory.get_details()
            property_details['organization_id'] = self.org.id
            property_details[
                'address_line_1'] = r'3001 Brighton Blvd;/?:@=&<>#%{}|"\^~[]`'
            property_details['address_line_2'] = "suite 2693"
            property_details['city'] = "Denver"
            property_details['state'] = "Colorado"
            property_details['postal_code'] = "80216"

            property = PropertyState(**property_details)
            property.save()

            properties = PropertyState.objects.filter(pk=property.id)

            geocode_buildings(properties)

            refreshed_properties = PropertyState.objects.filter(pk=property.id)

            self.assertEqual('POINT (-104.986138 39.765251)',
                             long_lat_wkt(refreshed_properties[0]))
示例#7
0
    def test_merge_geocoding_results_with_merge_protection(self):
        """
        When merging records that have geocoding results, if any of the
        geocoding results columns have merge protection, and both records have
        some form of geocoding results, completely "take" the results from
        the "existing" state.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            latitude=39.765251,
            longitude=-104.986138,
            geocoding_confidence='High (P1AAA)',
            long_lat='POINT (-104.986138 39.765251)',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor Existing',
            'latitude': 'Favor New',
            'longitude': 'Favor New',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities)
        self.assertEqual(result.geocoding_confidence, 'High (P1AAA)')
        self.assertEqual(result.latitude, 39.765251)
        self.assertEqual(result.longitude, -104.986138)
        self.assertEqual(long_lat_wkt(result), 'POINT (-104.986138 39.765251)')
示例#8
0
    def test_geocode_endpoint_base_with_prepopulated_lat_long_no_api_request(
            self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id
        property_details['latitude'] = 39.765251
        property_details['longitude'] = -104.986138

        property = PropertyState(**property_details)
        property.save()

        property_view = self.property_view_factory.get_property_view(
            state=property)

        post_params = {
            'property_view_ids': [property_view.id],
            'taxlot_view_ids': []
        }

        url = reverse('api:v3:geocode-geocode-by-ids'
                      ) + '?organization_id=%s' % self.org.pk
        self.client.post(url, post_params)

        refreshed_property = PropertyState.objects.get(pk=property.id)

        self.assertEqual('POINT (-104.986138 39.765251)',
                         long_lat_wkt(refreshed_property))
示例#9
0
    def test_geocode_buildings_successful_when_real_fields_provided(self):
        with base_vcr.use_cassette(
                'seed/tests/data/vcr_cassettes/geocode_base_case.yaml'):
            property_details = self.property_state_factory.get_details()
            property_details['organization_id'] = self.org.id
            property_details['address_line_1'] = "3001 Brighton Blvd"
            property_details['address_line_2'] = "suite 2693"
            property_details['city'] = "Denver"
            property_details['state'] = "Colorado"
            property_details['postal_code'] = "80216"

            property = PropertyState(**property_details)
            property.save()
            properties = PropertyState.objects.filter(pk=property.id)

            tax_lot_details = self.tax_lot_state_factory.get_details()
            tax_lot_details['organization_id'] = self.org.id
            tax_lot_details['address_line_1'] = "2020 Lawrence St"
            tax_lot_details['address_line_2'] = "unit A"
            tax_lot_details['city'] = "Denver"
            tax_lot_details['state'] = "Colorado"
            tax_lot_details['postal_code'] = "80205"

            tax_lot = TaxLotState(**tax_lot_details)
            tax_lot.save()
            tax_lots = TaxLotState.objects.filter(pk=tax_lot.id)

            geocode_buildings(properties)
            geocode_buildings(tax_lots)

            refreshed_property = PropertyState.objects.get(pk=property.id)
            refreshed_tax_lot = TaxLotState.objects.get(pk=tax_lot.id)

            self.assertEqual('POINT (-104.986138 39.765251)',
                             long_lat_wkt(refreshed_property))
            self.assertEqual('High (P1AAA)',
                             refreshed_property.geocoding_confidence)
            self.assertEqual(-104.986138, refreshed_property.longitude)
            self.assertEqual(39.765251, refreshed_property.latitude)

            self.assertEqual('POINT (-104.991046 39.752396)',
                             long_lat_wkt(refreshed_tax_lot))
            self.assertEqual('High (P1AAA)',
                             refreshed_tax_lot.geocoding_confidence)
示例#10
0
    def test_long_lat_wkt_takes_a_state_and_returns_the_WKT_string_or_None(self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id

        no_long_lat_property = PropertyState(**property_details)
        no_long_lat_property.save()

        property_details['long_lat'] = 'POINT (-104.985765 39.764984)'

        geocoded_property = PropertyState(**property_details)
        geocoded_property.save()

        no_long_lat_record = PropertyState.objects.get(pk=no_long_lat_property.id)
        geocoded_record = PropertyState.objects.get(pk=geocoded_property.id)

        self.assertIsNone(no_long_lat_record.long_lat)
        self.assertIsNone(long_lat_wkt(no_long_lat_record))

        self.assertIsInstance(geocoded_record.long_lat, Point)
        self.assertEqual('POINT (-104.985765 39.764984)', long_lat_wkt(geocoded_property))
示例#11
0
    def test_geocode_address_can_use_prepopulated_lat_and_long_fields(self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id
        property_details['latitude'] = 39.765251
        property_details['longitude'] = -104.986138

        property = PropertyState(**property_details)
        property.save()

        properties = PropertyState.objects.filter(pk=property.id)

        geocode_buildings(properties)

        refreshed_property = PropertyState.objects.get(pk=property.id)

        self.assertEqual('POINT (-104.986138 39.765251)', long_lat_wkt(refreshed_property))
        self.assertEqual("Manually geocoded (N/A)", refreshed_property.geocoding_confidence)
示例#12
0
    def get_related(cls, object_list, show_columns, columns_from_database):
        """
        This method takes a list of TaxLotViews or PropertyViews and returns the data along
        with the related TaxLotView or PropertyView.

        The columns are the items as seen by the front end. This means that the columns
        are prepended with tax_ or property_ if they are the related columns.

        This method is just a copy/abstraction from the _get_filtered_results in the
        Property/TaxLot viewset.  In the future this should become a serializer. For now it is
        here so that we can use this method to create the data for exporting to CSV on the backend.

        :param object_list: list
        :param show_columns: list, columns (as defined by backend), Pass None to default to all columns excluding extra
                             data
        :param columns_from_database: list, columns from the database as list of dict
        :return: list
        """
        results = []

        if len(object_list) == 0:
            return results

        Note = apps.get_model('seed', 'Note')

        if object_list[0].__class__.__name__ == 'PropertyView':
            lookups = {
                'obj_class': 'PropertyView',
                'obj_query_in': 'property_view_id__in',
                'obj_state_id': 'property_state_id',
                'obj_view_id': 'property_view_id',
                'obj_id': 'property_id',
                'centroid': 'centroid',
                'bounding_box': 'bounding_box',
                'long_lat': 'long_lat',
                'related_class': 'TaxLotView',
                'related_query_in': 'taxlot_view_id__in',
                'select_related': 'taxlot',
                'related_view': 'taxlot_view',
                'related_view_id': 'taxlot_view_id',
                'related_state_id': 'taxlot_state_id',
            }
        else:
            lookups = {
                'obj_class': 'TaxLotView',
                'obj_query_in': 'taxlot_view_id__in',
                'obj_state_id': 'taxlot_state_id',
                'obj_view_id': 'taxlot_view_id',
                'obj_id': 'taxlot_id',
                'centroid': 'centroid',
                'bounding_box': 'bounding_box',
                'long_lat': 'long_lat',
                'related_class': 'PropertyView',
                'related_query_in': 'property_view_id__in',
                'select_related': 'property',
                'related_view': 'property_view',
                'related_view_id': 'property_view_id',
                'related_state_id': 'property_state_id',
            }

        # Ids of views to look up in m2m
        ids = [obj.pk for obj in object_list]
        joins = TaxLotProperty.objects.filter(**{lookups['obj_query_in']: ids}).select_related(lookups['related_view'])

        # Get all ids of related views on these joins
        related_ids = [getattr(j, lookups['related_view_id']) for j in joins]

        # Get all related views from the related_class
        related_views = apps.get_model('seed', lookups['related_class']).objects.select_related(
            lookups['select_related'], 'state', 'cycle').filter(pk__in=related_ids)

        related_columns = []
        related_column_name_mapping = {}
        obj_columns = []
        obj_column_name_mapping = {}
        for column in columns_from_database:
            if column['related']:
                related_columns.append(column)
                related_column_name_mapping[column['column_name']] = column['name']
            else:
                obj_columns.append(column)
                obj_column_name_mapping[column['column_name']] = column['name']

        related_map = {}

        if show_columns is None:
            filtered_fields = set([col['column_name'] for col in related_columns if not col['is_extra_data']])
        else:
            filtered_fields = set([col['column_name'] for col in related_columns if not col['is_extra_data']
                                   and col['id'] in show_columns])
            filtered_extra_data_fields = set([col['column_name'] for col in related_columns if col['is_extra_data']
                                              and col['id'] in show_columns])

        for related_view in related_views:
            related_dict = TaxLotProperty.model_to_dict_with_mapping(
                related_view.state,
                related_column_name_mapping,
                fields=filtered_fields,
                exclude=['extra_data']
            )

            related_dict[lookups['related_state_id']] = related_view.state.id

            # Add GIS stuff to the related dict
            # (I guess these are special fields not in columns and not directly JSON serializable...)
            related_dict[lookups['bounding_box']] = bounding_box_wkt(related_view.state)
            related_dict[lookups['long_lat']] = long_lat_wkt(related_view.state)
            related_dict[lookups['centroid']] = centroid_wkt(related_view.state)

            # custom handling for when it is TaxLotView
            if lookups['obj_class'] == 'TaxLotView':
                if 'campus' in filtered_fields:
                    related_dict[related_column_name_mapping['campus']] = related_view.property.campus
                # Do not make these timestamps naive. They persist correctly.
                if 'updated' in filtered_fields:
                    related_dict[related_column_name_mapping['updated']] = related_view.property.updated
                if 'created' in filtered_fields:
                    related_dict[related_column_name_mapping['created']] = related_view.property.created
                # Replace the enumerations
                if 'analysis_state' in filtered_fields:
                    related_dict[
                        related_column_name_mapping['analysis_state']] = related_view.state.get_analysis_state_display()
            elif lookups['obj_class'] == 'PropertyView':
                # Do not make these timestamps naive. They persist correctly.
                if 'updated' in filtered_fields:
                    related_dict[related_column_name_mapping['updated']] = related_view.taxlot.updated
                if 'created' in filtered_fields:
                    related_dict[related_column_name_mapping['created']] = related_view.taxlot.created

            # Only add extra data columns if a settings profile was used
            if show_columns is not None:
                related_dict.update(
                    TaxLotProperty.extra_data_to_dict_with_mapping(
                        related_view.state.extra_data,
                        related_column_name_mapping,
                        fields=filtered_extra_data_fields
                    ).items()
                )
            related_map[related_view.pk] = related_dict

            # Replace taxlot_view id with taxlot id
            related_map[related_view.pk]['id'] = getattr(related_view, lookups['select_related']).id

        # Not sure what this code is really doing, but it only exists for TaxLotViews
        if lookups['obj_class'] == 'TaxLotView':
            # Get whole taxlotstate table:
            tuple_prop_to_jurisdiction_tl = tuple(
                TaxLotProperty.objects.values_list('property_view_id', 'taxlot_view__state__jurisdiction_tax_lot_id')
            )

            # create a mapping that defaults to an empty list
            prop_to_jurisdiction_tl = defaultdict(list)

            # populate the mapping
            for name, pth in tuple_prop_to_jurisdiction_tl:
                prop_to_jurisdiction_tl[name].append(pth)

        join_note_counts = {x[0]: x[1] for x in Note.objects.filter(**{lookups['related_query_in']: related_ids})
                            .values_list(lookups['related_view_id']).order_by().annotate(Count(lookups['related_view_id']))}

        # A mapping of object's view pk to a list of related state info for a related view
        join_map = {}
        for join in joins:
            # Another taxlot specific view
            if lookups['obj_class'] == 'TaxLotView':
                jurisdiction_tax_lot_ids = prop_to_jurisdiction_tl[join.property_view_id]

                # Filter out associated tax lots that are present but which do not have preferred
                none_in_jurisdiction_tax_lot_ids = None in jurisdiction_tax_lot_ids
                jurisdiction_tax_lot_ids = list(filter(lambda x: x is not None, jurisdiction_tax_lot_ids))

                if none_in_jurisdiction_tax_lot_ids:
                    jurisdiction_tax_lot_ids.append('Missing')

                join_dict = related_map[getattr(join, lookups['related_view_id'])].copy()
                join_dict.update({
                    # 'primary': 'P' if join.primary else 'S',
                    # 'calculated_taxlot_ids': '; '.join(jurisdiction_tax_lot_ids),
                    lookups['related_view_id']: getattr(join, lookups['related_view_id'])
                })

            else:
                join_dict = related_map[getattr(join, lookups['related_view_id'])].copy()
                join_dict.update({
                    # 'primary': 'P' if join.primary else 'S',
                    lookups['related_view_id']: getattr(join, lookups['related_view_id'])
                })

            join_dict['notes_count'] = join_note_counts.get(join.id, 0)

            # remove the measures from this view for now
            if join_dict.get('measures'):
                del join_dict['measures']

            try:
                join_map[getattr(join, lookups['obj_view_id'])].append(join_dict)
            except KeyError:
                join_map[getattr(join, lookups['obj_view_id'])] = [join_dict]

        if show_columns is None:
            filtered_fields = set([col['column_name'] for col in obj_columns if not col['is_extra_data']])
        else:
            filtered_fields = set([col['column_name'] for col in obj_columns if not col['is_extra_data']
                                   and col['id'] in show_columns])
            filtered_extra_data_fields = set([col['column_name'] for col in obj_columns if col['is_extra_data']
                                              and col['id'] in show_columns])

        obj_note_counts = {x[0]: x[1] for x in Note.objects.filter(**{lookups['obj_query_in']: ids})
                           .values_list(lookups['obj_view_id']).order_by().annotate(Count(lookups['obj_view_id']))}

        for obj in object_list:
            # Each object in the response is built from the state data, with related data added on.
            obj_dict = TaxLotProperty.model_to_dict_with_mapping(obj.state,
                                                                 obj_column_name_mapping,
                                                                 fields=filtered_fields,
                                                                 exclude=['extra_data'])

            # Only add extra data columns if a settings profile was used
            if show_columns is not None:
                obj_dict.update(
                    TaxLotProperty.extra_data_to_dict_with_mapping(
                        obj.state.extra_data,
                        obj_column_name_mapping,
                        fields=filtered_extra_data_fields
                    ).items()
                )

            # Use property_id instead of default (state_id)
            obj_dict['id'] = getattr(obj, lookups['obj_id'])
            obj_dict['notes_count'] = obj_note_counts.get(obj.id, 0)

            obj_dict[lookups['obj_state_id']] = obj.state.id
            obj_dict[lookups['obj_view_id']] = obj.id

            # bring in GIS data
            obj_dict[lookups['bounding_box']] = bounding_box_wkt(obj.state)
            obj_dict[lookups['long_lat']] = long_lat_wkt(obj.state)

            # store the property / taxlot data to the object dictionary as well. This is hacky.
            if lookups['obj_class'] == 'PropertyView':
                # bring in property-specific GIS data
                obj_dict[lookups['centroid']] = centroid_wkt(obj.state)

                if 'campus' in filtered_fields:
                    obj_dict[obj_column_name_mapping['campus']] = obj.property.campus
                # Do not make these timestamps naive. They persist correctly.
                if 'created' in filtered_fields:
                    obj_dict[obj_column_name_mapping['created']] = obj.property.created
                if 'updated' in filtered_fields:
                    obj_dict[obj_column_name_mapping['updated']] = obj.property.updated
                if 'analysis_state' in filtered_fields:
                    obj_dict[obj_column_name_mapping['analysis_state']] = obj.state.get_analysis_state_display()
            elif lookups['obj_class'] == 'TaxLotView':
                # Do not make these timestamps naive. They persist correctly.
                if 'updated' in filtered_fields:
                    obj_dict[obj_column_name_mapping['updated']] = obj.taxlot.updated
                if 'created' in filtered_fields:
                    obj_dict[obj_column_name_mapping['created']] = obj.taxlot.created

            # All the related tax lot states.
            obj_dict['related'] = join_map.get(obj.pk, [])

            # remove the measures from this view for now
            if obj_dict.get('measures'):
                del obj_dict['measures']

            results.append(obj_dict)

        return results
示例#13
0
    def test_geocode_taxlots_with_custom_fields(self):
        with base_vcr.use_cassette(
                'seed/tests/data/vcr_cassettes/geocode_taxlots_custom_fields.yaml'
        ):
            taxlot_details = self.tax_lot_state_factory.get_details()
            taxlot_details['organization_id'] = self.org.id
            taxlot_details['jurisdiction_tax_lot_id'] = "3001 Brighton Blvd"
            taxlot_details['block_number'] = "suite 2693"
            taxlot_details['custom_id_1'] = None  # can handle empty DB col
            taxlot_details['state'] = "Colorado"
            taxlot_details['extra_data'] = {
                'ed_city': "Denver",
                'ed_zip': 80216,  # can handle numbers
                'ed_empty': None,  # can handle empty extra_data col
            }

            taxlot = TaxLotState(**taxlot_details)
            taxlot.save()
            taxlots = TaxLotState.objects.filter(pk=taxlot.id)

            # Activate and order geocoding columns
            self.org.column_set.filter(
                column_name='jurisdiction_tax_lot_id',
                table_name="TaxLotState").update(geocoding_order=1)
            self.org.column_set.filter(
                column_name='block_number',
                table_name="TaxLotState").update(geocoding_order=2)
            self.org.column_set.create(column_name='ed_city',
                                       is_extra_data=True,
                                       table_name='TaxLotState',
                                       geocoding_order=3)
            self.org.column_set.filter(
                column_name='state',
                table_name="TaxLotState").update(geocoding_order=4)
            self.org.column_set.create(column_name='ed_zip',
                                       is_extra_data=True,
                                       table_name='TaxLotState',
                                       geocoding_order=5)
            self.org.column_set.create(column_name='ed_empty',
                                       is_extra_data=True,
                                       table_name='TaxLotState',
                                       geocoding_order=6)
            self.org.column_set.filter(
                column_name='custom_id_1',
                table_name="TaxLotState").update(geocoding_order=7)

            # Deactivate default geocoding columns
            self.org.column_set.filter(
                column_name__in=[
                    'address_line_1', 'address_line_2', 'city', 'postal_code'
                ],
                table_name="TaxLotState").update(geocoding_order=0)

            geocode_buildings(taxlots)

            refreshed_taxlot = TaxLotState.objects.get(pk=taxlot.id)

            self.assertEqual('POINT (-104.986138 39.765251)',
                             long_lat_wkt(refreshed_taxlot))
            self.assertEqual('High (P1AAA)',
                             refreshed_taxlot.geocoding_confidence)
            self.assertEqual(-104.986138, refreshed_taxlot.longitude)
            self.assertEqual(39.765251, refreshed_taxlot.latitude)
示例#14
0
    def test_geocode_properties_with_custom_fields(self):
        with base_vcr.use_cassette(
                'seed/tests/data/vcr_cassettes/geocode_property_custom_fields.yaml'
        ):
            property_details = self.property_state_factory.get_details()
            property_details['organization_id'] = self.org.id
            property_details['pm_parent_property_id'] = "3001 Brighton Blvd"
            property_details['pm_property_id'] = "suite 2693"
            property_details['property_name'] = None  # can handle empty DB col
            property_details['state'] = "Colorado"
            property_details['extra_data'] = {
                'ed_city': "Denver",
                'ed_zip': 80216,  # can handle numbers
                'ed_empty': None,  # can handle empty extra_data col
            }

            property = PropertyState(**property_details)
            property.save()
            properties = PropertyState.objects.filter(pk=property.id)

            # Activate and order geocoding columns
            self.org.column_set.filter(
                column_name='pm_parent_property_id',
                table_name="PropertyState").update(geocoding_order=1)
            self.org.column_set.filter(
                column_name='pm_property_id',
                table_name="PropertyState").update(geocoding_order=2)
            self.org.column_set.create(column_name='ed_city',
                                       is_extra_data=True,
                                       table_name='PropertyState',
                                       geocoding_order=3)
            self.org.column_set.filter(
                column_name='state',
                table_name="PropertyState").update(geocoding_order=4)
            self.org.column_set.create(column_name='ed_zip',
                                       is_extra_data=True,
                                       table_name='PropertyState',
                                       geocoding_order=5)
            self.org.column_set.create(column_name='ed_empty',
                                       is_extra_data=True,
                                       table_name='PropertyState',
                                       geocoding_order=6)
            self.org.column_set.filter(
                column_name='property_name',
                table_name="PropertyState").update(geocoding_order=7)

            # Deactivate default geocoding columns
            self.org.column_set.filter(
                column_name__in=[
                    'address_line_1', 'address_line_2', 'city', 'postal_code'
                ],
                table_name="PropertyState").update(geocoding_order=0)

            geocode_buildings(properties)

            refreshed_property = PropertyState.objects.get(pk=property.id)

            self.assertEqual('POINT (-104.986138 39.765251)',
                             long_lat_wkt(refreshed_property))
            self.assertEqual('High (P1AAA)',
                             refreshed_property.geocoding_confidence)
            self.assertEqual(-104.986138, refreshed_property.longitude)
            self.assertEqual(39.765251, refreshed_property.latitude)