def __create_and_populate_layer(self, name, srs, ogr_type, geom_type,
                                    lyrIn, codierung, ly_tmp):

        try:
            i = 0
            feldanzahl = lyrIn.GetLayerDefn().GetFieldCount()
            while i < feldanzahl:
                Fdefn = lyrIn.GetLayerDefn().GetFieldDefn(i)
                Fdefn.SetName(string.lower(Fdefn.GetName()))
                ly_tmp.CreateField(Fdefn)
                i = i + 1

            # Der gesmate Layer muss neu geschrieben werden
            # damit Probleme beim Laden in die Datenbank
            # möglichst ausgeschlossen werden
            for fea in lyrIn:

                # Umwandeln der Geometrie in ein MultiLinestring
                gemi = fea.GetGeometryRef()

                if geom_type == 'point':
                    gemi = ogr.ForceToMultiPoint(gemi)
                if geom_type == 'line':
                    gemi = ogr.ForceToMultiLineString(gemi)
                if geom_type == 'polygon':
                    gemi = ogr.ForceToMultiPolygon(gemi)

                fea_tmp = ogr.Feature(fea.GetDefnRef())

                # gemoetrie einfügen (die geänderte)
                fea_tmp.SetGeometry(gemi)

                # sachinformation einfügen

                i = 0
                while i < feldanzahl:
                    if not fea.GetField(i) == None:

                        if fea.GetFieldDefnRef(i).GetType() == 4:  # Textfeld
                            if codierung == 'nein' or '':
                                fea_tmp.SetField(i, fea.GetFieldAsString(i))
                            else:  # bei Bedarf umcodieren
                                kasperle = fea.GetFieldAsString(i).decode(
                                    codierung,
                                    'replace').encode('utf8', 'replace')
                                fea_tmp.SetField(i, kasperle)
                        else:  # numerisches Feld
                            fea_tmp.SetField(i, fea.GetField(i))
                    i = i + 1

                # ein neues (konvertiertes) Feature im Memory Layer erzeugen
                fea_tmp.SetFID(-1)
                ly_tmp.CreateFeature(fea_tmp)

            #Layer erfolgreich erstellt
            return True

        # Layer nicht erfolgreich erstellt!
        except:
            return False
Beispiel #2
0
def test_ogr_factory_6():

    src_wkt_list = [
        None,
        'POINT EMPTY',
        'LINESTRING EMPTY',
        'POLYGON EMPTY',
        'MULTIPOINT EMPTY',
        'MULTILINESTRING EMPTY',
        'MULTIPOLYGON EMPTY',
        'GEOMETRYCOLLECTION EMPTY',
        'POINT(0 0)',
        'LINESTRING(0 0)',
        'POLYGON((0 0))',
        'POLYGON(EMPTY,(0 0),EMPTY,(1 1))',
        'MULTIPOINT(EMPTY,(0 0),EMPTY,(1 1))',
        'MULTILINESTRING(EMPTY,(0 0),EMPTY,(1 1))',
        'MULTIPOLYGON(((0 0),EMPTY,(1 1)),EMPTY,((2 2)))',
        'GEOMETRYCOLLECTION(POINT EMPTY)',
        'GEOMETRYCOLLECTION(LINESTRING EMPTY)',
        'GEOMETRYCOLLECTION(POLYGON EMPTY)',
        'GEOMETRYCOLLECTION(MULTIPOINT EMPTY)',
        'GEOMETRYCOLLECTION(MULTILINESTRING EMPTY)',
        'GEOMETRYCOLLECTION(MULTIPOLYGON EMPTY)',
        'GEOMETRYCOLLECTION(GEOMETRYCOLLECTION EMPTY)',
        'GEOMETRYCOLLECTION(POINT(0 0))',
        'GEOMETRYCOLLECTION(LINESTRING(0 0),LINESTRING(1 1))',
        'GEOMETRYCOLLECTION(POLYGON((0 0),EMPTY,(2 2)), POLYGON((1 1)))',
        'CURVEPOLYGON EMPTY',
        'CURVEPOLYGON ((0 0,0 1,1 1,1 0,0 0))',
        'CURVEPOLYGON (CIRCULARSTRING(0 0,1 0,0 0))',
        'COMPOUNDCURVE EMPTY',
        'COMPOUNDCURVE ((0 0,0 1,1 1,1 0,0 0))',
        'COMPOUNDCURVE (CIRCULARSTRING(0 0,1 0,0 0))',
        'CIRCULARSTRING EMPTY',
        'CIRCULARSTRING (0 0,1 0,0 0)',
        'MULTISURFACE EMPTY',
        'MULTISURFACE (((0 0,0 1,1 1,1 0,0 0)))',
        'MULTISURFACE (CURVEPOLYGON((0 0,0 1,1 1,1 0,0 0)))',
        'MULTICURVE EMPTY',
        'MULTICURVE ((0 0,0 1))',
        'MULTICURVE (COMPOUNDCURVE((0 0,0 1)))',
        'MULTICURVE (CIRCULARSTRING (0 0,1 0,0 0))',
    ]

    for src_wkt in src_wkt_list:
        if src_wkt is None:
            src_geom = None
        else:
            src_geom = ogr.CreateGeometryFromWkt(src_wkt)

        ogr.ForceToPolygon(src_geom)
        ogr.ForceToMultiPolygon(src_geom)
        ogr.ForceToMultiPoint(src_geom)
        ogr.ForceToMultiLineString(src_geom)
        ogr.ForceToLineString(src_geom)
        for target_type in range(ogr.wkbMultiSurface):
            gdal.PushErrorHandler('CPLQuietErrorHandler')
            ogr.ForceTo(src_geom, 1 + target_type)
            gdal.PopErrorHandler()
def ShapefileToMemory_ForceMultiPoint(shapefileFolder, inFileName, outFileName):
	"""
	Function to take a shapefile of points and create a new memory layer using the original
	but forcing each feature to multipoint.
	
	Args:
		shapefileFolder: path to folder where shapefile is located
		inFileName: name of the input shapefile
		outFileName: name for the memory layer

	Returns: memory data source, memory layer

	"""
	
	# open the inShapefile as the driver type
	inDataSource, inLayer = Open_Shapefile_or_FeatureClass(shapefileFolder, inFileName, 'ESRI Shapefile')
	
	# create the output driver
	outDriver = ogr.GetDriverByName('MEMORY')
	
	print('Out driver set as ' + format(outDriver.GetName()))
	
	# create output shape file
	outDataSource = outDriver.CreateDataSource('memData_' + format(outFileName))
	outLayer = outDataSource.CreateLayer(outFileName, inLayer.GetSpatialRef(), ogr.wkbMultiPoint)
	
	# Add input Layer Fields to the output Layer
	outLayer.CreateFields(inLayer.schema)
	
	# Get the output Layer's Feature Definition
	outLayerDefn = outLayer.GetLayerDefn()
	
	inLayer.ResetReading()
	
	# Add features to the output Layer
	for input_feat in inLayer:
		# Create output Feature
		outFeature = ogr.Feature(outLayerDefn)
		
		# Set geometry as centroid
		geom = input_feat.GetGeometryRef()
		geom_name = geom.GetGeometryName()
		if geom_name == 'POINT':
			geom = ogr.ForceToMultiPoint(geom)
		outFeature.SetGeometry(geom)
		
		# Add field values from input Layer
		for i in range(0, outLayerDefn.GetFieldCount()):
			field_value = input_feat.GetField(i)
			outFeature.SetField(i, field_value)
		
		# Add new feature to output Layer
		outLayer.CreateFeature(outFeature)
	
	# Save and close DataSources
	del inLayer
	del inDataSource
	
	return outDataSource, outLayer
Beispiel #4
0
def test_ogr_factory_4():

    src_wkt = 'POINT(2 5 3)'
    exp_wkt = 'MULTIPOINT(2 5 3)'

    src_geom = ogr.CreateGeometryFromWkt(src_wkt)
    dst_geom = ogr.ForceToMultiPoint(src_geom)

    assert not ogrtest.check_feature_geometry(dst_geom, exp_wkt), dst_geom.ExportToWkt()

    src_wkt = 'GEOMETRYCOLLECTION(POINT(2 5 3),POINT(4 5 5))'
    exp_wkt = 'MULTIPOINT(2 5 3,4 5 5)'

    src_geom = ogr.CreateGeometryFromWkt(src_wkt)
    dst_geom = ogr.ForceToMultiPoint(src_geom)

    assert not ogrtest.check_feature_geometry(dst_geom, exp_wkt), dst_geom.ExportToWkt()
Beispiel #5
0
def geometry_force_multi(ogr_geom):
    geom_type = ogr_geom.GetGeometryType()
    if geom_type == ogr.wkbPoint:
        return ogr.ForceToMultiPoint(ogr_geom)
    if geom_type == ogr.wkbLineString:
        return ogr.ForceToMultiLineString(ogr_geom)
    if geom_type == ogr.wkbPolygon:
        return ogr.ForceToMultiPolygon(ogr_geom)
    return ogr_geom
Beispiel #6
0
def ogr_factory_4():

    src_wkt = 'POINT(2 5 3)'
    exp_wkt = 'MULTIPOINT(2 5 3)'

    src_geom = ogr.CreateGeometryFromWkt(src_wkt)
    dst_geom = ogr.ForceToMultiPoint(src_geom)

    if ogrtest.check_feature_geometry(dst_geom, exp_wkt):
        print(dst_geom.ExportToWkt())
        return 'fail'

    src_wkt = 'GEOMETRYCOLLECTION(POINT(2 5 3),POINT(4 5 5))'
    exp_wkt = 'MULTIPOINT(2 5 3,4 5 5)'

    src_geom = ogr.CreateGeometryFromWkt(src_wkt)
    dst_geom = ogr.ForceToMultiPoint(src_geom)

    if ogrtest.check_feature_geometry(dst_geom, exp_wkt):
        print(dst_geom.ExportToWkt())
        return 'fail'

    return 'success'
    def addpoint(self, coordlist, dim):
        """ajoute un point a une geometrie"""
        self.shapesync()
        if self.type == "1":
            if coordlist is None:
                self.null = True
                return
            self.points.append(list(coordlist[:dim]))
            self.multi = len(self.points) > 1
            self.dim = dim
            # raise
            return

        if self.lignes:
            ligne_active = self.lignes[-1]
            if ligne_active.addpoint(coordlist, dim):
                # la ligne est fermee
                self.nouvelle_ligne_p(coordlist, dim)
                # on ajoute un point a une nouvelle ligne
        else:
            self.lignes = [C.Ligne(C.Section(coordlist, dim))]
        self.sgeom = None
        if coordlist is None:
            return
        if self.type == "1":
            if not self.multi:
                self.geom = ogr.ForceToMultiPoint(self.geom)
                self.multi = True
            for p in coordlist:
                self.geom.addpoint(*p[:dim])
            return

        if self.section is None:
            self.section = ogr.Geometry(ogr.wkbLineString)
        for p in coordlist:
            self.section.addpoint(*p[:dim])
        if self.section.IsRing():
            if self.ligne is None:
                self.section = ogr.Geometry(ogr.wkbLineString)

        if self.lignes:
            ligne_active = self.lignes[-1]
            if ligne_active.addpoint(coords, dim):
                # la ligne est fermee
                self.nouvelle_ligne_p(coords, dim)
                # on ajoute un point a une nouvelle ligne
        else:
            self.lignes = [C.Ligne(C.Section(coords, dim))]
        self.sgeom = None
Beispiel #8
0
def get_segment_intersection_point(segment: List[PointData],
                                   region_of_interest: ogr.Geometry):
    geographic_geom, projected_geom = get_segment_geometry(segment)
    boundary = region_of_interest.GetBoundary()
    intersection = geographic_geom.Intersection(boundary)
    # `intersection` might be single or multi, convert to multi to make uniform
    multi_intersection = ogr.ForceToMultiPoint(intersection)
    first_intersection_geom = multi_intersection.GetGeometryRef(0)
    if first_intersection_geom is None:
        result = None
    else:
        intersection_coords = first_intersection_geom.GetPoint()
        result = PointData(
            acceleration_x=segment[1].acceleration_x,
            acceleration_y=segment[1].acceleration_y,
            acceleration_z=segment[1].acceleration_z,
            accuracy=segment[1].accuracy,
            battery_consumption_per_hour=segment[1].
            battery_consumption_per_hour,
            battery_level=segment[1].battery_level,
            device_bearing=segment[1].device_bearing,
            device_pitch=segment[1].device_pitch,
            device_roll=segment[1].device_roll,
            elevation=segment[1].elevation,
            gps_bearing=segment[1].gps_bearing,
            humidity=segment[1].humidity,
            lumen=segment[1].lumen,
            pressure=segment[1].pressure,
            proximity=segment[1].proximity,
            serial_version_uid=segment[1].serial_version_uid,
            session_id=segment[1].session_id,
            speed=segment[1].speed,
            temperature=segment[1].temperature,
            timestamp=segment[1].timestamp,
            vehicle_type=segment[1].vehicle_type,
            latitude=intersection_coords[1],
            longitude=intersection_coords[0],
        )
        # now adjust the timestamp
        new_segment = [segment[0], result]
        new_segment_projected_geom = get_segment_geometry(new_segment)[1]
        length_factor = (new_segment_projected_geom.Length() /
                         projected_geom.Length())
        segment_duration = get_segment_duration(segment)
        new_segment_duration = segment_duration * length_factor
        result.timestamp = segment[0].timestamp + dt.timedelta(
            seconds=new_segment_duration)
    return result
Beispiel #9
0
def ogr_factory_6():

    src_wkt_list = [
        None,
        'POINT EMPTY',
        'LINESTRING EMPTY',
        'POLYGON EMPTY',
        'MULTIPOINT EMPTY',
        'MULTILINESTRING EMPTY',
        'MULTIPOLYGON EMPTY',
        'GEOMETRYCOLLECTION EMPTY',
        'POINT(0 0)',
        'LINESTRING(0 0)',
        'POLYGON((0 0))',
        'POLYGON(EMPTY,(0 0),EMPTY,(1 1))',
        'MULTIPOINT(EMPTY,(0 0),EMPTY,(1 1))',
        'MULTILINESTRING(EMPTY,(0 0),EMPTY,(1 1))',
        'MULTIPOLYGON(((0 0),EMPTY,(1 1)),EMPTY,((2 2)))',
        'GEOMETRYCOLLECTION(POINT EMPTY)',
        'GEOMETRYCOLLECTION(LINESTRING EMPTY)',
        'GEOMETRYCOLLECTION(POLYGON EMPTY)',
        'GEOMETRYCOLLECTION(MULTIPOINT EMPTY)',
        'GEOMETRYCOLLECTION(MULTILINESTRING EMPTY)',
        'GEOMETRYCOLLECTION(MULTIPOLYGON EMPTY)',
        'GEOMETRYCOLLECTION(GEOMETRYCOLLECTION EMPTY)',
        'GEOMETRYCOLLECTION(POINT(0 0))',
        'GEOMETRYCOLLECTION(LINESTRING(0 0),LINESTRING(1 1))',
        'GEOMETRYCOLLECTION(POLYGON((0 0),EMPTY,(2 2)), POLYGON((1 1)))',
    ]

    for src_wkt in src_wkt_list:
        if src_wkt is None:
            src_geom = None
        else:
            src_geom = ogr.CreateGeometryFromWkt(src_wkt)
        dst_geom1 = ogr.ForceToPolygon(src_geom)
        dst_geom2 = ogr.ForceToMultiPolygon(src_geom)
        dst_geom3 = ogr.ForceToMultiPoint(src_geom)
        dst_geom4 = ogr.ForceToMultiLineString(src_geom)
        dst_geom5 = ogr.ForceToLineString(src_geom)
        #print(src_geom.ExportToWkt(), dst_geom1.ExportToWkt(), dst_geom2.ExportToWkt(), dst_geom3.ExportToWkt(), dst_geom4.ExportToWkt())

    return 'success'
Beispiel #10
0
    def load_from_ogr(self, ogrlayer, strdecode):
        source_osr = ogrlayer.GetSpatialRef()
        target_osr = osr.SpatialReference()
        target_osr.ImportFromEPSG(self.srs_id)

        transform = osr.CoordinateTransformation(source_osr, target_osr)

        feature = ogrlayer.GetNextFeature()
        fid = 0
        while feature:
            fid += 1
            geom = feature.GetGeometryRef()

            if geom.GetGeometryType() == ogr.wkbPoint:
                geom = ogr.ForceToMultiPoint(geom)
            elif geom.GetGeometryType() == ogr.wkbLineString:
                geom = ogr.ForceToMultiLineString(geom)
            elif geom.GetGeometryType() == ogr.wkbPolygon:
                geom = ogr.ForceToMultiPolygon(geom)

            geom.Transform(transform)

            fld_values = dict()
            for i in range(feature.GetFieldCount()):
                fld_type = feature.GetFieldDefnRef(i).GetType()
                fld_value = None
                if fld_type == ogr.OFTInteger:
                    fld_value = feature.GetFieldAsInteger(i)
                elif fld_type == ogr.OFTReal:
                    fld_value = feature.GetFieldAsDouble(i)
                elif fld_type == ogr.OFTString:
                    fld_value = strdecode(feature.GetFieldAsString(i))

                fld_values[self[feature.GetFieldDefnRef(
                    i).GetNameRef()].key] = fld_value

            obj = self.model(fid=fid,
                             geom=ga.WKTSpatialElement(str(geom), self.srs_id),
                             **fld_values)
            DBSession.add(obj)

            feature = ogrlayer.GetNextFeature()
Beispiel #11
0
    def load_from_ogr(self, ogrlayer, strdecode):
        source_osr = ogrlayer.GetSpatialRef()
        target_osr = osr.SpatialReference()
        target_osr.ImportFromEPSG(self.srs_id)

        transform = osr.CoordinateTransformation(source_osr, target_osr)

        is_multi = self.geometry_type in GEOM_TYPE.is_multi
        has_z = self.geometry_type in GEOM_TYPE.has_z

        for fid, feature in enumerate(ogrlayer):
            geom = feature.GetGeometryRef()

            gtype = geom.GetGeometryType()
            if gtype not in GEOM_TYPE_OGR:
                raise ValidationError(
                    _("Unknown geometry type: %d (%s).") %
                    (gtype, ogr.GeometryTypeToName(gtype)))

            geom.Transform(transform)

            # Force single geometries to multi
            if is_multi:
                if gtype in (ogr.wkbPoint, ogr.wkbPoint25D):
                    geom = ogr.ForceToMultiPoint(geom)
                elif gtype in (ogr.wkbLineString, ogr.wkbLineString25D):
                    geom = ogr.ForceToMultiLineString(geom)
                elif gtype in (ogr.wkbPolygon, ogr.wkbPolygon25D):
                    geom = ogr.ForceToMultiPolygon(geom)

            # Force Z
            if has_z and not geom.Is3D():
                geom.Set3D(True)

            # Check geometry type again
            gtype = geom.GetGeometryType()
            if gtype not in GEOM_TYPE_OGR or _GEOM_OGR_2_TYPE[
                    gtype] != self.geometry_type:
                raise ValidationError(
                    _("Unknown geometry type: %d (%s).") %
                    (gtype, ogr.GeometryTypeToName(gtype)))

            fld_values = dict()
            for i in range(feature.GetFieldCount()):
                fld_type = feature.GetFieldDefnRef(i).GetType()

                if (not feature.IsFieldSet(i) or feature.IsFieldNull(i)):
                    fld_value = None
                elif fld_type == ogr.OFTInteger:
                    fld_value = feature.GetFieldAsInteger(i)
                elif fld_type == ogr.OFTInteger64:
                    fld_value = feature.GetFieldAsInteger64(i)
                elif fld_type == ogr.OFTReal:
                    fld_value = feature.GetFieldAsDouble(i)
                elif fld_type == ogr.OFTDate:
                    year, month, day = feature.GetFieldAsDateTime(i)[0:3]
                    fld_value = date(year, month, day)
                elif fld_type == ogr.OFTTime:
                    hour, minute, second = feature.GetFieldAsDateTime(i)[3:6]
                    fld_value = time(hour, minute, int(second))
                elif fld_type == ogr.OFTDateTime:
                    year, month, day, hour, minute, second, tz = \
                        feature.GetFieldAsDateTime(i)
                    fld_value = datetime(year, month, day, hour, minute,
                                         int(second))
                elif fld_type == ogr.OFTIntegerList:
                    fld_value = json.dumps(feature.GetFieldAsIntegerList(i))
                elif fld_type == ogr.OFTInteger64List:
                    fld_value = json.dumps(feature.GetFieldAsInteger64List(i))
                elif fld_type == ogr.OFTRealList:
                    fld_value = json.dumps(feature.GetFieldAsDoubleList(i))
                elif fld_type == ogr.OFTStringList:
                    # TODO: encoding
                    fld_value = json.dumps(feature.GetFieldAsStringList(i))
                elif fld_type == ogr.OFTString:
                    try:
                        fld_value = strdecode(feature.GetFieldAsString(i))
                    except UnicodeDecodeError:
                        raise ValidationError(
                            _("It seems like declared and actual attributes "
                              "encodings do not match. Unable to decode "
                              "attribute #%(attr)d of feature #%(feat)d. "
                              "Try declaring different encoding.") %
                            dict(feat=fid, attr=i))

                fld_name = strdecode(feature.GetFieldDefnRef(i).GetNameRef())
                fld_values[self[fld_name].key] = fld_value

            obj = self.model(fid=fid,
                             geom=ga.elements.WKBElement(bytearray(
                                 geom.ExportToWkb()),
                                                         srid=self.srs_id),
                             **fld_values)

            DBSession.add(obj)
    def openGeoJson(self, check_field, filename):

        driver = ogr.GetDriverByName("GeoJSON")
        dataSource = driver.Open(filename, 0)
        layer = dataSource.GetLayer()

        wfs_result = dict()
        for feat in layer:

            #create geometry object
            geom = feat.GetGeometryRef()
            if geom is not None:
                sr = osr.SpatialReference()
                sr.ImportFromEPSG(3857)
                geom_type = geom.GetGeometryType()  #say to Dima

                if self.ForceToMultiGeom:
                    if geom_type == ogr.wkbLineString:
                        mercator_geom = ogr.ForceToLineString(geom)
                    elif geom_type == ogr.wkbPolygon:
                        mercator_geom = ogr.ForceToPolygon(geom)
                    elif geom_type == ogr.wkbPoint:
                        mercator_geom = ogr.ForceToMultiPoint(geom)
                    elif geom_type == ogr.wkbMultiPolygon:
                        mercator_geom = ogr.ForceToMultiPolygon(geom)
                    elif geom_type == ogr.wkbMultiPoint:
                        mercator_geom = ogr.ForceToMultiPoint(geom)
                    elif geom_type == ogr.wkbMultiLineString:
                        mercator_geom = ogr.ForceToMultiPolygon(geom)
                    else:
                        mercator_geom = geom
                else:
                    mercator_geom = geom
            else:
                continue

            #Read broker fields

            feat_defn = layer.GetLayerDefn()
            wfs_fields = dict()

            for i in range(feat_defn.GetFieldCount()):
                field_defn = feat_defn.GetFieldDefn(i)
                #if field_defn.GetName() == 'gml_id':
                #    continue

                #Compare by one control field

                if field_defn.GetName() == check_field:
                    check_field_val = feat.GetFieldAsString(i).decode(
                        'utf-8')  #GetFieldAsInteger64(i)

                #Read fields
                if field_defn.GetType(
                ) == ogr.OFTInteger:  #or field_defn.GetType() == ogr.OFTInteger64:
                    wfs_fields[field_defn.GetName()] = feat.GetFieldAsInteger(
                        i)  #GetFieldAsInteger64(i)
#                    print "%s = %d" % (field_defn.GetName(), feat.GetFieldAsInteger64(i))
                elif field_defn.GetType() == ogr.OFTReal:
                    wfs_fields[field_defn.GetName()] = feat.GetFieldAsDouble(i)


#                    print "%s = %.3f" % (field_defn.GetName(), feat.GetFieldAsDouble(i))
                elif field_defn.GetType() == ogr.OFTString:
                    #                    print "%s = %s" % (field_defn.GetName(), feat.GetFieldAsString(i))
                    wfs_fields[field_defn.GetName()] = feat.GetFieldAsString(
                        i).decode('utf-8')
                else:
                    #                    print "%s = %s" % (field_defn.GetName(), feat.GetFieldAsString(i))
                    wfs_fields[field_defn.GetName()] = feat.GetFieldAsString(
                        i).decode('utf-8')

            #Object with keys - as values of one control field
            wfs_result[check_field_val] = dict()
            wfs_result[check_field_val]['id'] = check_field_val
            wfs_result[check_field_val]['fields'] = wfs_fields
            wfs_result[check_field_val]['geom'] = mercator_geom.Clone()

        layer_result_sorted = dict()
        for key in sorted(wfs_result):
            layer_result_sorted[key] = wfs_result[key]

        return layer_result_sorted
Beispiel #13
0
    def load_from_ogr(self, ogrlayer, strdecode):
        source_osr = ogrlayer.GetSpatialRef()
        target_osr = osr.SpatialReference()
        target_osr.ImportFromEPSG(self.srs_id)

        ltype = ogrlayer.GetGeomType() & (~ogr.wkb25DBit)
        transform = osr.CoordinateTransformation(source_osr, target_osr)

        for fid, feature in enumerate(ogrlayer):
            geom = feature.GetGeometryRef()

            # Bring 25D geometries to 2D
            if geom.GetGeometryType() & ogr.wkb25DBit:
                geom.FlattenTo2D()

            gtype = geom.GetGeometryType()
            if gtype not in self.accepted_gtype:
                raise ValidationError(
                    _("Geometry type (%s) does not match column type (%s).") %
                    (GEOM_TYPE_DISPLAY[gtype - 1],
                     GEOM_TYPE_DISPLAY[ltype - 1]))

            geom.Transform(transform)

            if (self.geometry_type
                    in (GEOM_TYPE.MULTIPOINT, GEOM_TYPE.MULTILINESTRING,
                        GEOM_TYPE.MULTIPOLYGON)):
                if gtype == ogr.wkbPoint:
                    geom = ogr.ForceToMultiPoint(geom)
                elif gtype == ogr.wkbLineString:
                    geom = ogr.ForceToMultiLineString(geom)
                elif gtype == ogr.wkbPolygon:
                    geom = ogr.ForceToMultiPolygon(geom)

            fld_values = dict()
            for i in range(feature.GetFieldCount()):
                fld_type = feature.GetFieldDefnRef(i).GetType()

                if (not feature.IsFieldSet(i)
                        or (gdal_gt_22 and feature.IsFieldNull(i))):
                    fld_value = None
                elif fld_type == ogr.OFTInteger:
                    fld_value = feature.GetFieldAsInteger(i)
                elif gdal_gt_20 and fld_type == ogr.OFTInteger64:
                    fld_value = feature.GetFieldAsInteger64(i)
                elif fld_type == ogr.OFTReal:
                    fld_value = feature.GetFieldAsDouble(i)
                elif fld_type == ogr.OFTDate:
                    year, month, day = feature.GetFieldAsDateTime(i)[0:3]
                    fld_value = date(year, month, day)
                elif fld_type == ogr.OFTTime:
                    hour, minute, second = feature.GetFieldAsDateTime(i)[3:6]
                    fld_value = time(hour, minute, int(second))
                elif fld_type == ogr.OFTDateTime:
                    year, month, day, hour, minute, second, tz = \
                        feature.GetFieldAsDateTime(i)
                    fld_value = datetime(year, month, day, hour, minute,
                                         int(second))
                elif fld_type == ogr.OFTIntegerList:
                    fld_value = json.dumps(feature.GetFieldAsIntegerList(i))
                elif gdal_gt_20 and fld_type == ogr.OFTInteger64List:
                    fld_value = json.dumps(feature.GetFieldAsInteger64List(i))
                elif fld_type == ogr.OFTRealList:
                    fld_value = json.dumps(feature.GetFieldAsDoubleList(i))
                elif fld_type == ogr.OFTStringList:
                    # TODO: encoding
                    fld_value = json.dumps(feature.GetFieldAsStringList(i))
                elif fld_type == ogr.OFTString:
                    try:
                        fld_value = strdecode(feature.GetFieldAsString(i))
                    except UnicodeDecodeError:
                        raise ValidationError(
                            _("It seems like declared and actual attributes "
                              "encodings do not match. Unable to decode "
                              "attribute #%(attr)d of feature #%(feat)d. "
                              "Try declaring different encoding.") %
                            dict(feat=fid, attr=i))

                fld_name = strdecode(feature.GetFieldDefnRef(i).GetNameRef())
                fld_values[self[fld_name].key] = fld_value

            obj = self.model(fid=fid,
                             geom=ga.elements.WKTElement(str(geom),
                                                         srid=self.srs_id),
                             **fld_values)

            DBSession.add(obj)
    def kopieren(self, dsOut, lyrIn, name, zieltyp, codierung=''):

        try:
            #srs = osr.SpatialReference()
            #srs.ImportFromEPSG( 31254 )

            ly = None  # unser zukünftiges Layerobjekt
            # lyrIn (das Eingangsshape) hat bereits eine SRS (original oder vom kopierprogramm vorher zugewiesen)
            # im Modul verglRef überprüft un bei Bedarf neu zugewiesen!
            srs = lyrIn.GetSpatialRef()

            if not dsOut == None:
                driverName = dsOut.GetDriver().GetName()
            else:
                if zieltyp == 'file':
                    driverName = "ESRI Shapefile"
                elif zieltyp == 'sqlite':
                    drivername = "SQLite"
                elif zieltyp == 'postgres':
                    driverName == "PostgreSQL"
                else:
                    raise Exception

            #Das Ziel des Kopierprozesses
            #wird anhand des Treibernamens identifiziert: ACHTUNG: Ist der Workspace
            #leer, dann ist dsOut None (z.B. kein Shape im Verzeichnis)
            if driverName == "ESRI Shapefile":
                ly = dsOut.CopyLayer(lyrIn, name)  #das Kopieren, unabhängig
                if ly == None:  #vom OGR Treiber!

                    raise Exception

                #arcgis Attributindex Dateien
                #glob liefert eine liste mit Pfadnamen zurück
                # 1.PROBLEM: Sind quasi Doppelsuffix
                # 2.PROBLEM: Gross Kleinschreibung sollte einheitlich sein mit dem
                # anderen Kopierprozesse!!
                atxes = glob.glob(self.dsIn.GetName() + '/' + lyrIn.GetName() +
                                  ".*.atx")
                for atx in atxes:
                    if os.path.exists(atx):

                        #Wegen der gleichen Gross/Kleinschreibung wie in
                        # outputname angegeben!!!!!!!!
                        atx_suffix = os.path.splitext(atx)
                        atx_suffix = os.path.splitext(
                            atx_suffix[0])[1] + atx_suffix[1]

                        shutil.copyfile(
                            atx,
                            dsOut.GetName() + '/' + name + atx_suffix)

            elif driverName == "PostgreSQL" or driverName == "SQLite":

                #falls noch ein temp Layer existiert
                #(Beim Aktualisieren ist der name ja XXX_tmp_aktual!)
                if string.count(name, 'temp_aktual') > 0:
                    if dsOut.GetLayerByName(name) > 0:
                        dsOut.DeleteLayer(name)

                # Create a memory OGR datasource to put results in. Von frank W. Die Doku ist einfach schwach
                # Deshalb wirds hier zu Dokumentationszwecken dringelassen:
                # Der Memory Layer ist deutlich performanter bei CreateFeature als wenn es direkt auf eine
                # Spatial Lite DB angewandt wird
                mem_drv = ogr.GetDriverByName('Memory')
                mem_ds = mem_drv.CreateDataSource('out')

                ##                if lyrIn.GetGeomType() == 100 and driverName == "SQLite":   #Also keine Geometrie vorhanden

                ##                    if driverName == "PostgreSQL":
                ##                        ly = dsOut.CopyLayer(lyrIn,name, ['SPATIAL_INDEX=no','PRECISION=no','GEOMETRY_NAME=the_geom', 'LAUNDER=no'])
                ##                    elif driverName == "SQLite":
                ##                        ly = dsOut.CopyLayer(lyrIn,name, ['GEOMETRY_NAME=the_geom', 'LAUNDER=no'])

                if driverName == "SQLite":

                    if lyrIn.GetGeomType(
                    ) == 100:  # also KEINE Geometrie Tabelle
                        ly = dsOut.CopyLayer(
                            lyrIn, name,
                            ['GEOMETRY_NAME=the_geom', 'LAUNDER=no'])
                    else:
                        memme = mem_ds.CreateLayer(name, srs,
                                                   lyrIn.GetGeomType())

                        i = 0
                        feldanzahl = lyrIn.GetLayerDefn().GetFieldCount()
                        while i < feldanzahl:
                            Fdefn = lyrIn.GetLayerDefn().GetFieldDefn(i)
                            memme.CreateField(Fdefn)
                            i = i + 1

                        # Unbedingt die Geometrie vereinheitlichen, im Shape ist das anscheinend
                        # nicht immer sauber und würde sonst nicht in die DB übernommen werden!!!
                        # Mehr Unterscheidungen (der Geometrie) gibt es derzeit noch nicht, also Single point oder line
                        for fea in lyrIn:

                            # None kann vom Shape weg vorkommen, deshalb die Prüfung
                            # Gibts ein Feature ohne Geometrie (das kann beim Shape vorkommen), wirds
                            # ignoriert.
                            if not fea.GetGeometryRef() == None:
                                gemi = fea.GetGeometryRef().Clone()
                            else:
                                next

                            if lyrIn.GetGeomType() == ogr.wkbMultiPoint:
                                gemi = ogr.ForceToMultiPoint(gemi)
                            elif lyrIn.GetGeomType() == ogr.wkbMultiLineString:
                                gemi = ogr.ForceToMultiLineString(gemi)
                            elif lyrIn.GetGeomType() == ogr.wkbMultiPolygon:
                                gemi = ogr.ForceToMultiPolygon(gemi)
                            elif lyrIn.GetGeomType() == ogr.wkbPolygon:
                                gemi = ogr.ForceToPolygon(gemi)
                            else:
                                gemi = gemi.Clone()

                            fea.SetGeometry(gemi)
                            memme.CreateFeature(fea)
                        if memme == None:
                            raise Exception

                        dsOut.CopyLayer(memme, name, [
                            'SPATIAL_INDEX=no', 'GEOM_TYPE=geometry',
                            'GEOMETRY_NAME=the_geom', 'LAUNDER=no'
                        ])

                # Einen leeren Layer in der Postgis erzeugen
                # ACHTUNG: Beim Shape wird zwischen Linestring und Multilinestring etc.
                # nicht unterschieden, es können also in einem Shape beide Arten vorkommen!
                # Es muss deshalb per Default immer die Multi- Version erzeugt werden!
                elif driverName == "PostgreSQL":

                    if lyrIn.GetGeomType() == 100:  # Keine Geometrie
                        ly = mem_ds.CreateLayer(name, None, ogr.wkbNone)

                        i = 0

                        feldanzahl = lyrIn.GetLayerDefn().GetFieldCount()
                        while i < feldanzahl:
                            Fdefn = lyrIn.GetLayerDefn().GetFieldDefn(i)
                            Fdefn.SetName(string.lower(Fdefn.GetName()))
                            ly.CreateField(Fdefn)
                            i = i + 1

                        # Der gesmate Layer muss neu geschrieben werden
                        # damit Probleme beim Laden in die Datenbank
                        # möglichst ausgeschlossen werden
                        for fea in lyrIn:

                            fea_tmp = ogr.Feature(fea.GetDefnRef())

                            # sachinformation einfügen

                            i = 0
                            while i < feldanzahl:
                                if not fea.GetField(i) == None:

                                    if fea.GetFieldDefnRef(
                                            i).GetType() == 4:  # Textfeld
                                        if codierung == 'nein' or '':
                                            fea_tmp.SetField(
                                                i, fea.GetFieldAsString(i))
                                        else:  # bei Bedarf umcodieren
                                            kasperle = fea.GetFieldAsString(
                                                i).decode(
                                                    codierung,
                                                    'replace').encode(
                                                        'utf8', 'replace')
                                            fea_tmp.SetField(i, kasperle)
                                    else:  # numerisches Feld
                                        fea_tmp.SetField(i, fea.GetField(i))
                                i = i + 1

                            # ein neues (konvertiertes) Feature im Memory Layer erzeugen
                            fea_tmp.SetFID(-1)
                            ly.CreateFeature(fea_tmp)

                    #########################################
                    # Alle Formen von Punktgeometrien
                    #########################################

                    #Point oder Multipoint
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPoint or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPoint:

                        ly = mem_ds.CreateLayer(name, srs, ogr.wkbMultiPoint)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPoint, 'point', lyrIn,
                                codierung, ly):
                            ly = None

                    #Point oder Multipoint mit M
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPointM or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPointM:

                        ly = mem_ds.CreateLayer(name, srs, ogr.wkbMultiPointM)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPointM, 'point', lyrIn,
                                codierung, ly):
                            ly = None

                    #Point oder Multipoint 3D mit M
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPointZM or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPointZM:

                        ly = mem_ds.CreateLayer(name, srs, ogr.wkbMultiPointZM)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPointZM, 'point', lyrIn,
                                codierung, ly):
                            ly = None

                    #Point oder Multipoint 3D
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPoint25D or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPoint25D:

                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiPoint25D)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPoint25D, 'point',
                                lyrIn, codierung, ly):
                            ly = None

                    #########################################
                    # Alle Formen von Liniengeometrien
                    #########################################

                    # Line oder Multiline
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbLineString or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiLineString:

                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiLineString)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiLineString, 'line',
                                lyrIn, codierung, ly):
                            ly = None

                    # Line oder Multiline mit M
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbLineStringM or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiLineStringM:
                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiLineStringM)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiLineStringM, 'line',
                                lyrIn, codierung, ly):
                            ly = None

                    # Line oder Multiline 3D mit M
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbLineStringZM or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiLineStringZM:
                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiLineStringZM)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiLineStringZM, 'line',
                                lyrIn, codierung, ly):
                            ly = None

                    # Linien mit 3D
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbMultiLineString25D or lyrIn.GetGeomType(
                    ) == ogr.wkbLineString25D:

                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiLineString25D)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiLineString25D, 'line',
                                lyrIn, codierung, ly):
                            ly = None

                    #########################################
                    # Alle Formen von Polygongeometrien
                    #########################################

                    #Polygon oder Multipolygon
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPolygon or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPolygon:

                        ly = mem_ds.CreateLayer(name, srs, ogr.wkbMultiPolygon)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPolygon, 'polygon',
                                lyrIn, codierung, ly):
                            ly = None

                    #Polygon oder Multipolygon mit M
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPolygonM or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPolygonM:

                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiPolygonM)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPolygonM, 'polygon',
                                lyrIn, codierung, ly):
                            ly = None

                    #Polygon oder Multipolygon 3D mit M
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbPolygonZM or lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPolygonZM:

                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiPolygonZM)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPolygonZM, 'polygon',
                                lyrIn, codierung, ly):
                            ly = None

                    # Polygone mit 3D
                    elif lyrIn.GetGeomType(
                    ) == ogr.wkbMultiPolygon25D or lyrIn.GetGeomType(
                    ) == ogr.wkbPolygon25D:

                        ly = mem_ds.CreateLayer(name, srs,
                                                ogr.wkbMultiPolygon25D)
                        # ACHTUNG: return hat mit dem im sub erzeugten Layer Objekt nicht funktioniert (crash)
                        # dh wird das Lyerobjekt ly bereits vorher erzeugt und im Sub (Pointer!) verändert.
                        # zurückgegeben wird nur das fehlerstatement
                        if not self.__create_and_populate_layer(
                                name, srs, ogr.wkbMultiPolygon25D, 'polygon',
                                lyrIn, codierung, ly):
                            ly = None

                    # alles andere
                    else:
                        dsOut.CopyLayer(lyrIn, name, [
                            'SPATIAL_INDEX=no', 'PRECISION=NO',
                            'GEOM_TYPE=geometry', 'GEOMETRY_NAME=the_geom',
                            'LAUNDER=yes'
                        ])

                    # Fertig: der Memorylayer mit dem gesäuberten Inhalt des Shapes kann in die Datenbank kopiert werden
                    if not ly == None:
                        dsOut.CopyLayer(ly, name, [
                            'SPATIAL_INDEX=no', 'PRECISION=NO',
                            'GEOM_TYPE=geometry', 'GEOMETRY_NAME=the_geom',
                            'LAUNDER=yes'
                        ])
                    else:
                        return [
                            False,
                            'Geometrietyp nicht unterstuetzt oder Layer Nachbesserung fehlgeschlagen'
                        ]

            return [True]

        # Wir geben die Exception auch mit zurück - damit die fehlermeldung informativer ist!
        except Exception as e:
            print str(e)
            return [False, e]