使用PyQt4和GDAL/OGR创建shapefile:舍入小数

2024-06-09 15:31:07 发布

您现在位置:Python中文网/ 问答频道 /正文

另一个帖子是这个帖子的续篇:

Can't write decimal data into shape (shp) attribute table with Python

在那篇文章中,我试图简化问题,但这是一个错误,因为这并不能表达我真正的问题。我很抱歉。在

问题是,我有一个创建shapefile的代码,它可以工作,但是当我在一个简单的pyQt4应用程序中使用它时,最后一篇文章的问题出现了:它舍入了写入字段(Lat和Lng)的值。在

这是有问题的代码:

# -*- coding: utf-8 -*-
# Created: Fri Feb 12 18:05:01 2016
#      by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui
import osgeo.ogr as ogr
import osgeo.osr as osr
import os, sys

DriverExt = {'ESRI Shapefile':'.shp'}

# START OF QT PART

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

# THE MAIN WINDOW

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(150, 70)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))

        # THE BUTTON

        self.boton_procesar = QtGui.QPushButton(self.centralwidget)
        self.boton_procesar.setGeometry(QtCore.QRect(20, 10, 98, 27))
        self.boton_procesar.setObjectName(_fromUtf8("boton_procesar"))

        MainWindow.setCentralWidget(self.centralwidget)

        # THE ACTION: prueba

        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.boton_procesar, QtCore.SIGNAL(_fromUtf8("clicked()")),prueba)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.boton_procesar.setText(_translate("MainWindow", "procesar", None))

# END OF QT PART

# THE FUNCTIONS

def crearShape(arch, lat, lng, theDvr):

    # obtiene el Driver
    driver = ogr.GetDriverByName(theDvr)

    # obtiene la extension de archivo para ese driver mediante el diccionario creado al ppio
    theExt = DriverExt[str(theDvr)]

    # crea el nuevo FN
    FN = arch+theExt

    # crea el DataSource
    if os.path.exists(FN):
        print "el archivo ya existe"
    else:       
        theShp = driver.CreateDataSource(FN)

        # crea el SRS
        theSR = osr.SpatialReference()
        theSR.ImportFromEPSG(4326)

        # crea el Layer a partir del DataSource
        if theShp is None:
            print 'No se puede crear el archivo'
            sys.exit(1)

        capa = theShp.CreateLayer(os.path.basename(FN), theSR, ogr.wkbPoint)

        # crea los campos para las coordenadas
        fldLat = ogr.FieldDefn("Lat", ogr.OFTReal)
        capa.CreateField(fldLat)

        fldLng = ogr.FieldDefn("Lng", ogr.OFTReal)
        capa.CreateField(fldLng)

        # obtiene el tipo de Layer
        featureDefn = capa.GetLayerDefn()

        # crea un feature a partir de la definicion de la capa
        feature = ogr.Feature(featureDefn)

        # escribe sobre los campos
        feature.SetField("Lat", float(lat))
        feature.SetField("Lng", float(lng))

        # crea un punto
        pto = ogr.Geometry(ogr.wkbPoint)
        pto.AddPoint(lng, lat)

        # agrega al pto
        feature.SetGeometry(pto)

        # agrega los nuevos features a la capa
        capa.CreateFeature(feature)

        # DESTRUYE!
        pto.Destroy()
        feature.Destroy()
        theShp.Destroy()

        # mje y salir
        print "Done"
        sys.exit()

def prueba():
    crearShape("prueba_QT", -72.123456, -42.123456, "ESRI Shapefile")   

# ANOTHER QT PART

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

# END OF QT PART

如果我用gene在另一篇文章中建议的代码测试这个代码:

^{pr2}$

我得到:

{"geometry": {"type": "Point", "coordinates": [-42.123456, -72.123456]}, "type": "Feature", "properties": {"Lat": -72.0, "Lng": -42.0}, "id": 0}

这是没有问题的代码:

# -*- coding: utf-8 -*-
# Created: Fri Feb 12 18:05:01 2016
#      by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

import osgeo.ogr as ogr
import osgeo.osr as osr
import os, sys

DriverExt = {'ESRI Shapefile':'.shp'}

# THE FUNCTIONS

def crearShape(arch, lat, lng, theDvr):

    # obtiene el Driver
    driver = ogr.GetDriverByName(theDvr)

    # obtiene la extension de archivo para ese driver mediante el diccionario creado al ppio
    theExt = DriverExt[str(theDvr)]

    # crea el nuevo FN
    FN = arch+theExt

    # crea el DataSource
    if os.path.exists(FN):
        print "el archivo ya existe"
    else:       
        theShp = driver.CreateDataSource(FN)

        # crea el SRS
        theSR = osr.SpatialReference()
        theSR.ImportFromEPSG(4326)

        # crea el Layer a partir del DataSource
        if theShp is None:
            print 'No se puede crear el archivo'
            sys.exit(1)

        capa = theShp.CreateLayer(os.path.basename(FN), theSR, ogr.wkbPoint)

        # crea los campos para las coordenadas
        fldLat = ogr.FieldDefn("Lat", ogr.OFTReal)
        capa.CreateField(fldLat)

        fldLng = ogr.FieldDefn("Lng", ogr.OFTReal)
        capa.CreateField(fldLng)

        # obtiene el tipo de Layer
        featureDefn = capa.GetLayerDefn()

        # crea un feature a partir de la definicion de la capa
        feature = ogr.Feature(featureDefn)

        # escribe sobre los campos
        feature.SetField("Lat", float(lat))
        feature.SetField("Lng", float(lng))

        # crea un punto
        pto = ogr.Geometry(ogr.wkbPoint)
        pto.AddPoint(lng, lat)

        # agrega al pto
        feature.SetGeometry(pto)

        # agrega los nuevos features a la capa
        capa.CreateFeature(feature)

        # DESTRUYE!
        pto.Destroy()
        feature.Destroy()
        theShp.Destroy()

        # mje y salir
        print "Done"
        sys.exit()

def prueba():
    crearShape("prueba_QT", -72.123456, -42.123456, "ESRI Shapefile")   

prueba()

如果我用完全相同的测试代码测试代码,我得到:

{"geometry": {"type": "Point", "coordinates": [-42.123456, -72.123456]}, "type": "Feature", "properties": {"Lat": -72.123456, "Lng": -42.123456}, "id": 0}

如果我运行diff命令来比较我得到的两组文件:

The binary files conQT/prueba_QT.dbf and sinQT/prueba_QT.dbf are different


Tags: importselfdefsysqtelfeatureprueba