def publishPgTable(self, tree, explorer):
        if not xmlNameIsValid(self.element.name, xmlNameRegex()):
            QtGui.QMessageBox.warning(explorer, "Invalid name",
                                      ("The table name (%s) is not a valid XML name.\n"
                                      + "This could cause problems when published to GeoServer.\n"
                                      + "Please rename it and retry publishing.") % self.element.name)
            return
        dlg = PublishLayerDialog(explorer.catalogs(), self.element)
        dlg.exec_()
        if dlg.catalog is None:
            return
        cat = dlg.catalog
        catItem = tree.findFirstItem(cat)
        toUpdate = [catItem]
        if int(self.element.srid) == 0:
            explorer.setWarning("PostGIS table '{0}' has no SRID; ESPG:4326 "
                                "will be assigned.".format(self.element.name))
        if explorer.run(publishTable,
                        "Publish table '" + self.element.name + "'",
                        toUpdate,
                        self.element, cat, dlg.workspace, True, dlg.layername):

            # add existing style to layer, or later some operations may fail,
            # like malformed XML when getting capabilities for OWS connections
            pglyr = cat.get_layer(dlg.layername)
            pgitem = tree.findFirstItem(pglyr)
            if pgitem is None:
                return
            if not pgitem.addStyleToLayer(explorer):  # handles refresh of item
                # user cancelled AddStyleToLayerDialog
                noDefaultStyleError(explorer, dlg.layername)
            else:
                catItem.layersItem.refreshContent(explorer)
示例#2
0
    def publishPgTable(self, tree, explorer):
        if not xmlNameIsValid(self.element.name, xmlNameRegex()):
            QtGui.QMessageBox.warning(
                explorer, "Invalid name",
                ("The table name (%s) is not a valid XML name.\n" +
                 "This could cause problems when published to GeoServer.\n" +
                 "Please rename it and retry publishing.") % self.element.name)
            return
        dlg = PublishLayerDialog(explorer.catalogs(), self.element)
        dlg.exec_()
        if dlg.catalog is None:
            return
        cat = dlg.catalog
        catItem = tree.findFirstItem(cat)
        toUpdate = [catItem]
        if int(self.element.srid) == 0:
            explorer.setWarning("PostGIS table '{0}' has no SRID; ESPG:4326 "
                                "will be assigned.".format(self.element.name))
        if explorer.run(publishTable,
                        "Publish table '" + self.element.name + "'", toUpdate,
                        self.element, cat, dlg.workspace, True, dlg.layername):

            # add existing style to layer, or later some operations may fail,
            # like malformed XML when getting capabilities for OWS connections
            pglyr = cat.get_layer(dlg.layername)
            pgitem = tree.findFirstItem(pglyr)
            if pgitem is None:
                return
            if not pgitem.addStyleToLayer(explorer):  # handles refresh of item
                # user cancelled AddStyleToLayerDialog
                noDefaultStyleError(explorer, dlg.layername)
            else:
                catItem.layersItem.refreshContent(explorer)
示例#3
0
	def okPressed(self):
		self.name = unicode(self.editName.text())
		self.editName.setStyleSheet("QLineEdit{background: white}")
		if not xmlNameIsValid(self.name, xmlNameRegex()):
			self.editName.setStyleSheet("QLineEdit{background: yellow}")
			return
		if self.table.rowCount() == 0:
			QMessageBox.information(self, self.tr("Sorry"), self.tr("add some fields!"))
			return

		self.useGeomColumn = self.chkGeomColumn.isChecked()
		if self.useGeomColumn:
			self.geomColumn = unicode(self.editGeomColumn.text())
			if len(self.geomColumn) == 0:
				self.editGeomColumn.setStyleSheet("QLineEdit{background: yellow}")
				return

			self.geomType = self.GEOM_TYPES[ self.cboGeomType.currentIndex() ]
			self.geomDim = self.spinGeomDim.value()
			try:
				self.geomSrid = int(self.editGeomSrid.text())
			except ValueError:
				self.geomSrid = -1
			self.useSpatialIndex = self.chkSpatialIndex.isChecked()

		self.fields = []
		for i in xrange(self.table.rowCount()):
			name = self.table.cellWidget(i, 0).text()
			type = self.table.cellWidget(i, 1).currentText()
			null = self.table.cellWidget(i, 2).currentIndex == 0
			self.fields.append(TableField(name, type, null))
		self.pk = self.cboPrimaryKey.currentText()
		self.ok = True
		self.close()
示例#4
0
def publishDraggedTable(tree, explorer, table, workspace):
    if not xmlNameIsValid(table.name, xmlNameRegex()):
        QtGui.QMessageBox.warning(explorer, "Invalid name",
                                  ("The table name (%s) is not a valid XML name.\n"
                                  + "This could cause problems when published to GeoServer.\n"
                                  + "Please rename it and retry publishing.") % table.name)
        return False
    cat = workspace.catalog
    if int(table.srid) == 0:
        explorer.setWarning("PostGIS table '{0}' has no SRID; ESPG:4326 will "
                            "be assigned.".format(table.name))

    gslayers = [lyr.name for lyr in cat.get_layers()]
    try:
        lyrname = getGSLayerName(name=xmlNameFixUp(table.name + "_table"),
                                 names=gslayers,
                                 unique=False)
    except UserCanceledOperation:
        return False

    catItem = tree.findFirstItem(cat)
    toUpdate = [catItem.layersItem]
    res = explorer.run(publishTable,
                       "Publish table from table '" + table.name + "'",
                       toUpdate,
                       table, cat, workspace, True, lyrname)
    if res:
        # add existing style to layer, or later some operations may fail,
        # like malformed XML when getting capabilities for OWS connections
        pglyr = cat.get_layer(lyrname)
        pgitem = tree.findFirstItem(pglyr)
        if pgitem is None:
            print "pgitem not found"
            return False
        if not pgitem.addStyleToLayer(explorer):  # handles refresh of item
            # user cancelled AddStyleToLayerDialog
            noDefaultStyleError(explorer, lyrname)
            return False
        else:
            catItem.layersItem.refreshContent(explorer)
    return res
示例#5
0
def publishDraggedTable(tree, explorer, table, workspace):
    if not xmlNameIsValid(table.name, xmlNameRegex()):
        QtGui.QMessageBox.warning(
            explorer, "Invalid name",
            ("The table name (%s) is not a valid XML name.\n" +
             "This could cause problems when published to GeoServer.\n" +
             "Please rename it and retry publishing.") % table.name)
        return False
    cat = workspace.catalog
    if int(table.srid) == 0:
        explorer.setWarning("PostGIS table '{0}' has no SRID; ESPG:4326 will "
                            "be assigned.".format(table.name))

    gslayers = [lyr.name for lyr in cat.get_layers()]
    try:
        lyrname = getGSLayerName(name=xmlNameFixUp(table.name + "_table"),
                                 names=gslayers,
                                 unique=False)
    except UserCanceledOperation:
        return False

    catItem = tree.findFirstItem(cat)
    toUpdate = [catItem.layersItem]
    res = explorer.run(publishTable,
                       "Publish table from table '" + table.name + "'",
                       toUpdate, table, cat, workspace, True, lyrname)
    if res:
        # add existing style to layer, or later some operations may fail,
        # like malformed XML when getting capabilities for OWS connections
        pglyr = cat.get_layer(lyrname)
        pgitem = tree.findFirstItem(pglyr)
        if pgitem is None:
            print "pgitem not found"
            return False
        if not pgitem.addStyleToLayer(explorer):  # handles refresh of item
            # user cancelled AddStyleToLayerDialog
            noDefaultStyleError(explorer, lyrname)
            return False
        else:
            catItem.layersItem.refreshContent(explorer)
    return res
示例#6
0
    def okPressed(self):
        self.name = unicode(self.editName.text())
        self.editName.setStyleSheet("QLineEdit{background: white}")
        if not xmlNameIsValid(self.name, xmlNameRegex()):
            self.editName.setStyleSheet("QLineEdit{background: yellow}")
            return
        if self.table.rowCount() == 0:
            QMessageBox.information(self, self.tr("Sorry"),
                                    self.tr("add some fields!"))
            return

        self.useGeomColumn = self.chkGeomColumn.isChecked()
        if self.useGeomColumn:
            self.geomColumn = unicode(self.editGeomColumn.text())
            if len(self.geomColumn) == 0:
                self.editGeomColumn.setStyleSheet(
                    "QLineEdit{background: yellow}")
                return

            self.geomType = self.GEOM_TYPES[self.cboGeomType.currentIndex()]
            self.geomDim = self.spinGeomDim.value()
            try:
                self.geomSrid = int(self.editGeomSrid.text())
            except ValueError:
                self.geomSrid = -1
            self.useSpatialIndex = self.chkSpatialIndex.isChecked()

        self.fields = []
        for i in xrange(self.table.rowCount()):
            name = self.table.cellWidget(i, 0).text()
            type = self.table.cellWidget(i, 1).currentText()
            null = self.table.cellWidget(i, 2).currentIndex == 0
            self.fields.append(TableField(name, type, null))
        self.pk = self.cboPrimaryKey.currentText()
        self.ok = True
        self.close()
示例#7
0
    def _publishExisting(self, layer, workspace, overwrite,
                         name, storename=None):
        uri = QgsDataSourceURI(layer.dataProvider().dataSourceUri())

        # check for table.name conflict in existing layer names where the
        # table.name is not the same as the user-chosen layer name,
        # i.e. unintended overwrite
        resource = self.catalog.get_resource(uri.table())
        if resource is not None and uri.table() != name:
            raise Exception("QGIS PostGIS layer has table name conflict with "
                            "existing GeoServer layer name: {0}\n"
                            "You may need to rename GeoServer layer name."
                            .format(uri.table()))

        conname = self.getConnectionNameFromLayer(layer)
        storename = xmlNameFixUp(storename or conname)

        if not xmlNameIsValid(storename):
            raise Exception("Database connection name is invalid XML and can "
                            "not be auto-fixed: {0} -> {1}"
                            .format(conname, storename))

        if not uri.username():
            raise Exception("GeoServer requires database connection's username "
                            "to be defined")

        store = createPGFeatureStore(self.catalog,
                                     storename,
                                     workspace = workspace,
                                     overwrite = overwrite,
                                     host = uri.host(),
                                     database = uri.database(),
                                     schema = uri.schema(),
                                     port = uri.port(),
                                     user = uri.username(),
                                     passwd = uri.password())
        if store is not None:
            rscname = name if uri.table() != name else uri.table()
            grpswlyr = []
            if overwrite:
                # TODO: How do we honor *unchecked* user setting of
                #   "Delete resource when deleting layer" here?
                #   Is it an issue, if overwrite is expected?

                # We will soon have two layers with slightly different names,
                # a temp based upon table.name, the other possibly existing
                # layer with the same custom name, which may belong to group(s).
                # If so, remove existing layer from any layer group, before
                # continuing on with layer delete and renaming of new feature
                # type layer to custom name, then add new resultant layer back
                # to any layer groups the existing layer belonged to. Phew!

                flyr = self.catalog.get_layer(rscname)
                if flyr is not None:
                    grpswlyr = groupsWithLayer(self.catalog, flyr)
                    if grpswlyr:
                        removeLayerFromGroups(self.catalog, flyr, grpswlyr)
                    self.catalog.delete(flyr)
                # TODO: What about when the layer name is the same, but the
                #   underlying db connection/store has changed? Not an issue?
                #   The layer is deleted, which is correct, but the original
                #   db store and feature type will not be changed. A conflict?
                frsc = store.get_resources(name=rscname)
                if frsc is not None:
                    self.catalog.delete(frsc)

            # for dbs the name has to be the table name, initially
            ftype = self.catalog.publish_featuretype(uri.table(), store,
                                                     layer.crs().authid())

            # once table-based feature type created, switch name to user-chosen
            if ftype.name != rscname:
                ftype.dirty["name"] = rscname
            self.catalog.save(ftype)

            # now re-add to any previously assigned-to layer groups
            if overwrite and grpswlyr:
                ftype = self.catalog.get_resource(rscname)
                if ftype:
                    addLayerToGroups(self.catalog, ftype, grpswlyr,
                                     workspace=workspace)
示例#8
0
def publishTable(table, catalog = None, workspace = None, overwrite=True,
                 name=None, storename=None):
    if catalog is None:
        pass

    lyrname = xmlNameFixUp(name)  # usually fixed up by now

    # check for table.name conflict in existing layer names where the table.name
    # is not the same as the user-chosen layer name, i.e. unintended overwrite
    resource = catalog.get_resource(table.name)
    if resource is not None and table.name != lyrname:
        raise Exception("PostGIS table name conflicts with "
                        "existing GeoServer layer name: {0}\n"
                        "You may need to rename GeoServer layer name."
                        .format(table.name))

    workspace = workspace if workspace is not None else catalog.get_default_workspace()
    connection = table.conn
    geodb = connection.geodb
    conname = "{0}_{1}".format(connection.name, table.schema)
    storename = xmlNameFixUp(storename or conname)

    if not xmlNameIsValid(storename):
        raise Exception("Database connection name is invalid XML and can "
                        "not be auto-fixed: {0} -> {1}"
                        .format(conname, storename))

    if not geodb.user:
        raise Exception("GeoServer requires database connection's username "
                        "to be defined")

    store = createPGFeatureStore(catalog,
                         storename,
                         workspace = workspace,
                         overwrite = True,
                         host = geodb.host,
                         database = geodb.dbname,
                         schema = table.schema,
                         port = geodb.port,
                         user = geodb.user,
                         passwd = geodb.passwd)
    if store is not None:
        rscname = name if table.name != name else table.name
        grpswlyr = []
        if overwrite:
            # See notes about possible issues in OGCatalog._publishExisting()
            flyr = catalog.get_layer(rscname)
            if flyr is not None:
                grpswlyr = groupsWithLayer(catalog, flyr)
                if grpswlyr:
                    removeLayerFromGroups(catalog, flyr, grpswlyr)
                catalog.delete(flyr)

            frsc = store.get_resources(name=rscname)
            if frsc is not None:
                catalog.delete(frsc)

        epsg = table.srid if int(table.srid) != 0 else 4326
        ftype = catalog.publish_featuretype(table.name, store,
                                            "EPSG:" + str(epsg))
        # once table-based layer created, switch name to user-chosen
        if table.name != rscname:
            ftype.dirty["name"] = rscname
            ftype.dirty["title"] = rscname
        catalog.save(ftype)

        if overwrite and grpswlyr:
            ftype = catalog.get_resource(rscname)
            if ftype:
                addLayerToGroups(catalog, ftype, grpswlyr, workspace=workspace)
示例#9
0
    def importFileOrLayer(self, source, schema, tablename, overwrite, singleGeom = False):

        if isinstance(source, basestring):
            layerName = QtCore.QFileInfo(source).completeBaseName()
        else:
            layerName = source.name()

        if tablename is None:
            tablename = layerName

        if not xmlNameIsValid(tablename, xmlNameRegex()):
            tablename = getPostGisTableName(name=tablename, names=[], unique=False)

        if overwrite:
            pk = "id"
            geom = "geom"
            providerName = "postgres"

            uri = QgsDataSourceURI()
            uri.setConnection(self.geodb.host, str(self.geodb.port), self.geodb.dbname, self.geodb.user, self.geodb.passwd)
            uri.setDataSource(schema, tablename, geom, "", pk)

            options = {}
            options['overwrite'] = True
            if singleGeom:
                options['forceSinglePartGeometryType'] = True

            if isinstance(source, basestring):
                layer = QgsVectorLayer(source, layerName, "ogr")
                if not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer:
                    layer.deleteLater()
                    raise WrongLayerFileError("Error reading file {} or it is not a valid vector layer file".format(source))
            else:
                layer = source
                if not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer:
                    raise WrongLayerFileError("Layer '%s' is not valid or is not a vector layer".format(layer.name()))

            ret, errMsg = QgsVectorLayerImport.importLayer(layer, uri.uri(), providerName, layer.crs(), False, False, options)
            if ret != 0:
                raise Exception(errMsg)
        else:
            if isinstance(source, QgsMapLayer):
                source = source.source()

            args = ["shp2pgsql", "-a"]
            if singleGeom:
                args.append("-S")
            args.extend([source, schema + "." + tablename])
            if os.name == 'nt':
                cmdline = subprocess.list2cmdline(args)
                data = None

                p = os.popen3(cmdline)
                data = p[1].read()

                cursor = self.geodb.con.cursor()
                newcommand = re.compile(";$", re.MULTILINE)

                # split the commands
                cmds = newcommand.split(data)
                for cmd in cmds[:-1]:
                    # run SQL commands within current DB connection
                    self.geodb._exec_sql(cursor, cmd)
                data = cmds[-1]

                self.geodb.con.commit()

                if data is None or len(data) == 0:
                    raise Exception("".join(p[2].readlines()))
            else:
                # start shp2pgsql as subprocess
                p = subprocess.Popen(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

                # read the output while the process is running
                data = ''
                cursor = self.geodb.con.cursor()
                newcommand = re.compile(";$", re.MULTILINE)
                while p.poll() == None:
                    data += p.stdout.read()

                    # split the commands
                    cmds = newcommand.split(data)
                    for cmd in cmds[:-1]:
                        # run SQL commands within current DB connection
                        self.geodb._exec_sql(cursor, cmd)
                    data = cmds[-1]

                # commit!
                self.db.con.commit()

                if p.returncode != 0:
                    raise Exception(p.stderr.readlines().join("\n"))
示例#10
0
    def _publishExisting(self,
                         layer,
                         workspace,
                         overwrite,
                         name,
                         storename=None):
        uri = QgsDataSourceURI(layer.dataProvider().dataSourceUri())

        # check for table.name conflict in existing layer names where the
        # table.name is not the same as the user-chosen layer name,
        # i.e. unintended overwrite
        resource = self.catalog.get_resource(uri.table())
        if resource is not None and uri.table() != name:
            raise Exception(
                "QGIS PostGIS layer has table name conflict with "
                "existing GeoServer layer name: {0}\n"
                "You may need to rename GeoServer layer name.".format(
                    uri.table()))

        conname = self.getConnectionNameFromLayer(layer)
        storename = xmlNameFixUp(storename or conname)

        if not xmlNameIsValid(storename):
            raise Exception("Database connection name is invalid XML and can "
                            "not be auto-fixed: {0} -> {1}".format(
                                conname, storename))

        if not uri.username():
            raise Exception(
                "GeoServer requires database connection's username "
                "to be defined")

        store = createPGFeatureStore(self.catalog,
                                     storename,
                                     workspace=workspace,
                                     overwrite=overwrite,
                                     host=uri.host(),
                                     database=uri.database(),
                                     schema=uri.schema(),
                                     port=uri.port(),
                                     user=uri.username(),
                                     passwd=uri.password())
        if store is not None:
            rscname = name if uri.table() != name else uri.table()
            grpswlyr = []
            if overwrite:
                # TODO: How do we honor *unchecked* user setting of
                #   "Delete resource when deleting layer" here?
                #   Is it an issue, if overwrite is expected?

                # We will soon have two layers with slightly different names,
                # a temp based upon table.name, the other possibly existing
                # layer with the same custom name, which may belong to group(s).
                # If so, remove existing layer from any layer group, before
                # continuing on with layer delete and renaming of new feature
                # type layer to custom name, then add new resultant layer back
                # to any layer groups the existing layer belonged to. Phew!

                flyr = self.catalog.get_layer(rscname)
                if flyr is not None:
                    grpswlyr = groupsWithLayer(self.catalog, flyr)
                    if grpswlyr:
                        removeLayerFromGroups(self.catalog, flyr, grpswlyr)
                    self.catalog.delete(flyr)
                # TODO: What about when the layer name is the same, but the
                #   underlying db connection/store has changed? Not an issue?
                #   The layer is deleted, which is correct, but the original
                #   db store and feature type will not be changed. A conflict?
                frsc = store.get_resources(name=rscname)
                if frsc is not None:
                    self.catalog.delete(frsc)

            # for dbs the name has to be the table name, initially
            ftype = self.catalog.publish_featuretype(uri.table(), store,
                                                     layer.crs().authid())

            # once table-based feature type created, switch name to user-chosen
            if ftype.name != rscname:
                ftype.dirty["name"] = rscname
            self.catalog.save(ftype)

            # now re-add to any previously assigned-to layer groups
            if overwrite and grpswlyr:
                ftype = self.catalog.get_resource(rscname)
                if ftype:
                    addLayerToGroups(self.catalog,
                                     ftype,
                                     grpswlyr,
                                     workspace=workspace)
示例#11
0
def publishTable(table,
                 catalog=None,
                 workspace=None,
                 overwrite=True,
                 name=None,
                 storename=None):
    if catalog is None:
        pass

    lyrname = xmlNameFixUp(name)  # usually fixed up by now

    # check for table.name conflict in existing layer names where the table.name
    # is not the same as the user-chosen layer name, i.e. unintended overwrite
    resource = catalog.get_resource(table.name)
    if resource is not None and table.name != lyrname:
        raise Exception("PostGIS table name conflicts with "
                        "existing GeoServer layer name: {0}\n"
                        "You may need to rename GeoServer layer name.".format(
                            table.name))

    workspace = workspace if workspace is not None else catalog.get_default_workspace(
    )
    connection = table.conn
    geodb = connection.geodb
    conname = "{0}_{1}".format(connection.name, table.schema)
    storename = xmlNameFixUp(storename or conname)

    if not xmlNameIsValid(storename):
        raise Exception("Database connection name is invalid XML and can "
                        "not be auto-fixed: {0} -> {1}".format(
                            conname, storename))

    if not geodb.user:
        raise Exception("GeoServer requires database connection's username "
                        "to be defined")

    store = createPGFeatureStore(catalog,
                                 storename,
                                 workspace=workspace,
                                 overwrite=True,
                                 host=geodb.host,
                                 database=geodb.dbname,
                                 schema=table.schema,
                                 port=geodb.port,
                                 user=geodb.user,
                                 passwd=geodb.passwd)
    if store is not None:
        rscname = name if table.name != name else table.name
        grpswlyr = []
        if overwrite:
            # See notes about possible issues in OGCatalog._publishExisting()
            flyr = catalog.get_layer(rscname)
            if flyr is not None:
                grpswlyr = groupsWithLayer(catalog, flyr)
                if grpswlyr:
                    removeLayerFromGroups(catalog, flyr, grpswlyr)
                catalog.delete(flyr)

            frsc = store.get_resources(name=rscname)
            if frsc is not None:
                catalog.delete(frsc)

        epsg = table.srid if int(table.srid) != 0 else 4326
        ftype = catalog.publish_featuretype(table.name, store,
                                            "EPSG:" + str(epsg))
        # once table-based layer created, switch name to user-chosen
        if table.name != rscname:
            ftype.dirty["name"] = rscname
            ftype.dirty["title"] = rscname
        catalog.save(ftype)

        if overwrite and grpswlyr:
            ftype = catalog.get_resource(rscname)
            if ftype:
                addLayerToGroups(catalog, ftype, grpswlyr, workspace=workspace)