def importer(self, config_entity, db_entity, **kwargs):
        """
            Creates various GeojsonFeature classes by importing geojson and saving it to the database via a dynamic subclass of GeojsonFeature
        :schema: The optional schema to use for the dynamic subclass's meta db_table attribute, which will allow the class's table to be saved in the specified schema. Defaults to public
        :data: Optional python dict data to use instead of loading from the db_entity.url
        :return: a list of lists. Each list is a list of features of distinct subclass of GeoJsonFeature that is created dynamically. To persist these features, you must first create the subclass's table in the database using create_table_for_dynamic_class(). You should also register the table as a DbEntity.
        """
        if self.seed_data:
            data = geojson.loads(jsonify(self.seed_data), object_hook=geojson.GeoJSON.to_instance)
        else:
            fp = open(db_entity.url.replace('file://', ''))
            data = geojson.load(fp, object_hook=geojson.GeoJSON.to_instance)
        feature_class_creator = FeatureClassCreator(config_entity, db_entity)
        # find all unique properties
        feature_class_configuration = feature_class_creator.feature_class_configuration_from_geojson_introspection(data)
        feature_class_creator.update_db_entity(feature_class_configuration)
        feature_class = feature_class_creator.dynamic_model_class(base_only=True)
        # Create our base table. Normally this is done by the import, but we're just importing into memory
        create_tables_for_dynamic_classes(feature_class)
        # Now write each feature to our newly created table
        for feature in map(lambda feature: self.instantiate_sub_class(feature_class, feature), data.features):
            feature.save()
        # Create the rel table too
        rel_feature_class = feature_class_creator.dynamic_model_class()
        create_tables_for_dynamic_classes(rel_feature_class)

        # PostGIS 2 handles this for us now
        # if InformationSchema.objects.table_exists(db_entity.schema, db_entity.table):
        #     # Tell PostGIS about the new geometry column or the table
        #     sync_geometry_columns(db_entity.schema, db_entity.table)

        # Create association classes and tables and populate them with data
        create_and_populate_relations(config_entity, db_entity)
Example #2
0
    def hydrate_bounds(self, bundle):
        """
            Convert the bounds from JSON to the GEOSGeometry format
            bounds is a python getter/setter that sets the geometry field and the features list
            by executing a geodjango query
        :param bundle
        :return:
        """
        if bundle.data['bounds'] and len(bundle.data['bounds'].keys()) > 0:
            try:
                bundle.obj.bounds = GEOSGeometry(jsonify(bundle.data['bounds']))
            except:
                # TODO log warning
                bundle.obj.bounds = GEOSGeometry('MULTIPOLYGON EMPTY')
        elif not bundle.data['query']:
            bundle.obj.bounds = GEOSGeometry('MULTIPOLYGON EMPTY')

        return bundle
Example #3
0
 def instantiate_sub_class(feature):
     """
         Instantiates an instance of the dynamic subclass of GeoJsonFeature based on the given feature.
     :param feature: A feature parsed django-geojson. The feature is actually reserialized to json in order to construct a GEOSGeometry instance.
     :return: An instance of the GeoJsonFeature subclass, which contains the geometry, properties of the feature, and perhaps the crs
     """
     # TODO, crs should be read from the geojson when present.
     # This crs isn't actually picked up by the GEOSGeometry constructor
     srid = settings.SRID_PREFIX.format(settings.DEFAULT_SRID)
     crs = {
         "type": "name",
         "properties": {
             "name": srid
         }
     }
     # Ironically, we have to rejsonify the data so that GEOSGeometry can parse the feature as json
     json = jsonify({'type':feature.geometry.type, 'coordinates':feature.geometry.coordinates, 'crs':crs})
     geometry = GEOSGeometry(json)
     properties = feature.properties
     return GeoJsonFeatureSubclass(geometry=geometry, properties=properties)
 def instantiate_sub_class(self, feature_class, feature):
     """
         Instantiates an instance of the dynamic subclass of GeoJsonFeature based on the given feature.
     :param feature: A feature parsed django-geojson. The feature is actually reserialized to json in order to construct a GEOSGeometry instance.
     :return: An instance of the GeoJsonFeature subclass, which contains the geometry, properties of the feature, and perhaps the crs
     """
     # TODO, crs should be read from the geojson when present.
     # This crs isn't actually picked up by the GEOSGeometry constructor
     srid = settings.SRID_PREFIX.format(settings.DEFAULT_SRID)
     crs = {
         "type": "name",
         "properties": {
             "name": srid
         }
     }
     # Ironically, we have to rejsonify the data so that GEOSGeometry can parse the feature as json
     json = jsonify({'type':feature.geometry.type, 'coordinates':feature.geometry.coordinates, 'crs':crs})
     geometry = GEOSGeometry(json)
     field_dict = map_to_dict(lambda field: [field.name, feature.properties[field.name]],
                              filter(lambda field: feature.properties.get(field.name, None), feature_class._meta.fields))
     return feature_class(wkb_geometry=geometry, **field_dict)