def exportVersionDiffs(commita, commitb = None): layers = {} if commitb is None: commitb = commita commita = commita.parent layernames = commita.repo.difftreestats(commita, commitb).keys() name = "%s_%s" % (commita.id[:8], commitb.id[:8]) for layername in layernames: layers[layername] = [] filepath = os.path.join(tempFolder(), "diff_%s_%s_before.shp" % (layername, name)) try: if not os.path.exists(filepath): commita.repo.exportdiffs(commita, commitb, layername, filepath, True, True) beforeLayer = loadLayerNoCrsDialog(filepath, layername + "_[%s][before]" % name, "ogr") beforeLayer.setReadOnly(True) vectorType = beforeLayer.geometryType() styleBefore, _ = styles[vectorType] beforeLayer.loadNamedStyle(styleBefore) layers[layername].append(beforeLayer) except GeoGigException: layers[layername].append(None) try: filepath = os.path.join(tempFolder(), "diff_%s_%s_after.shp" % (layername, name)) if not os.path.exists(filepath): commitb.repo.exportdiffs(commita, commitb, layername, filepath, False, True) afterLayer = loadLayerNoCrsDialog(filepath, layername + "_[%s][after]" % name, "ogr") afterLayer.setReadOnly(True) vectorType = afterLayer.geometryType() _, styleAfter = styles[vectorType] afterLayer.loadNamedStyle(styleAfter) layers[layername].append(afterLayer) except GeoGigException: layers[layername].append(None) return layers
def testPullWithConflicts(self): repo = _createSimpleTestRepo(True) repo2 = _createEmptyTestRepo(True) repo.addremote("myremote", repo2.url) repo2.addremote("myremote", repo.url) repo.push("myremote", "master") filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref=repo.HEAD) layer = loadLayerNoCrsDialog(filename, "points", "ogr") idx = layer.dataProvider().fieldNameIndex("n") features = list(layer.getFeatures()) with edit(layer): layer.changeAttributeValue(features[0].id(), idx, 1000) layer.changeAttributeValue(features[1].id(), idx, 2000) _, _, conflicts, _ = repo.importgeopkg(layer, "master", "message", "me", "*****@*****.**", True) filename2 = tempFilename("gpkg") repo2.checkoutlayer(filename2, "points", ref=repo.HEAD) layer2 = loadLayerNoCrsDialog(filename2, "points", "ogr") features = list(layer2.getFeatures()) with edit(layer2): layer2.changeAttributeValue(features[0].id(), idx, 1001) layer2.changeAttributeValue(features[1].id(), idx, 2001) _, _, conflicts, _ = repo2.importgeopkg(layer2, "master", "message2", "me", "*****@*****.**", True) conflicts = repo2.pull("myremote", "master") self.assertEqual(2, len(conflicts))
def _createConflict(self): repo = _createSimpleTestRepo(True) log = repo.log() filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref=log[0].commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") idx = layer.dataProvider().fieldNameIndex("n") filename2 = tempFilename("gpkg") repo.checkoutlayer(filename2, "points", ref=log[0].commitid) layer2 = loadLayerNoCrsDialog(filename2, "points", "ogr") features = list(layer.getFeatures()) with edit(layer): layer.changeAttributeValue(features[0].id(), idx, 1000) layer.changeAttributeValue(features[1].id(), idx, 2000) _, _, conflicts, _ = repo.importgeopkg(layer, "master", "message", "me", "*****@*****.**", True) self.assertEqual(0, len(conflicts)) features2 = list(layer2.getFeatures()) with edit(layer2): layer2.changeAttributeValue(features2[0].id(), idx, 1001) layer2.changeAttributeValue(features2[1].id(), idx, 2001) layer3 = loadLayerNoCrsDialog(filename2, "points", "ogr") feature = next(layer3.getFeatures(QgsFeatureRequest( features2[0].id()))) self.assertEquals(1001, feature["n"]) _, _, conflicts, _ = repo.importgeopkg(layer2, "master", "another message", "me", "*****@*****.**", True) self.assertEqual(2, len(conflicts)) self.assertEqual(conflicts[0].localFeature['n'], 1001) return repo, conflicts
def testConflictsWithDeleteAndModify(self): repo = _createSimpleTestRepo(True) log = repo.log() origCommit = log[0].commitid filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref=log[0].commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") idx = layer.dataProvider().fieldNameIndex("n") filename2 = tempFilename("gpkg") repo.checkoutlayer(filename2, "points", ref=log[0].commitid) layer2 = loadLayerNoCrsDialog(filename2, "points", "ogr") features = list(layer.getFeatures()) with edit(layer): layer.changeAttributeValue(features[0].id(), idx, 1000) layer.changeAttributeValue(features[1].id(), idx, 2000) _, _, conflicts, _ = repo.importgeopkg(layer, "master", "message", "me", "*****@*****.**", True) self.assertEqual(0, len(conflicts)) features2 = list(layer2.getFeatures()) with edit(layer2): layer2.deleteFeatures([features2[0].id()]) layer2.deleteFeatures([features2[1].id()]) _, _, conflicts, _ = repo.importgeopkg(layer2, "master", "another message", "me", "*****@*****.**", True) self.assertEqual(2, len(conflicts)) diff = repo.diff(repo.log()[0].commitid, repo.log()[1].commitid) self.assertEqual(diff[0].path, conflicts[0].path) self.assertEqual(origCommit, conflicts[0].originCommit) self.assertEqual(diff[1].path, conflicts[1].path)
def createLayers(self): types = [("Point", ptOursStyle, ptTheirsStyle), ("LineString", lineOursStyle, lineTheirsStyle), ("Polygon", polygonOursStyle, polygonTheirsStyle)] if self.oursgeom is not None: qgsgeom = QgsGeometry.fromWkt(self.oursgeom.geom) geomtype = types[int(qgsgeom.type())][0] if self.oursgeom.crs is not None: targetCrs = self.mapCanvas.mapRenderer().destinationCrs() crsTransform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(self.oursgeom.crs), targetCrs) qgsgeom.transform(crsTransform) style = types[int(qgsgeom.type())][1] self.oursLayer = loadLayerNoCrsDialog(geomtype + "?crs=EPSG:4326", "ours", "memory") pr = self.oursLayer.dataProvider() feat = QgsFeature() feat.setGeometry(qgsgeom) pr.addFeatures([feat]) self.oursLayer.loadNamedStyle(style) self.oursLayer.updateExtents() #this is to correct a problem with memory layers in qgis 2.2 self.oursLayer.selectAll() self.oursLayer.setExtent(self.oursLayer.boundingBoxOfSelected()) self.oursLayer.invertSelection() QgsMapLayerRegistry.instance().addMapLayer(self.oursLayer, False) else: self.oursLayer = None if self.theirsgeom is not None: qgsgeom = QgsGeometry.fromWkt(self.theirsgeom.geom) geomtype = types[int(qgsgeom.type())][0] if self.theirsgeom.crs is not None: targetCrs = self.mapCanvas.mapRenderer().destinationCrs() crsTransform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(self.theirsgeom.crs), targetCrs) qgsgeom.transform(crsTransform) style = types[int(qgsgeom.type())][2] self.theirsLayer = loadLayerNoCrsDialog(geomtype + "?crs=EPSG:4326", "theirs", "memory") pr = self.theirsLayer.dataProvider() feat = QgsFeature() feat.setGeometry(qgsgeom) pr.addFeatures([feat]) self.theirsLayer.loadNamedStyle(style) self.theirsLayer.updateExtents() #this is to correct a problem with memory layers in qgis 2.2 self.theirsLayer.selectAll() self.theirsLayer.setExtent(self.theirsLayer.boundingBoxOfSelected()) self.theirsLayer.invertSelection() QgsMapLayerRegistry.instance().addMapLayer(self.theirsLayer, False) else: self.theirsLayer = None
def addLayers(self): formats = QgsVectorFileWriter.supportedFiltersAndFormats() exts = ['shp'] for extension in formats.keys(): extension = unicode(extension) extension = extension[extension.find('*.') + 2:] extension = extension[:extension.find(' ')] if extension.lower() != 'shp': exts.append(extension) for i in range(len(exts)): exts[i] = exts[i].upper() + ' files(*.' + exts[i].lower() + ')' filefilter = ';;'.join(exts) files = QtGui.QFileDialog.getOpenFileNames(self, 'Add layers', '', filefilter) for f in files: layer = loadLayerNoCrsDialog(f, "layer", "ogr") if not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer: QtGui.QMessageBox.critical( self, "Error", "Error reading file %s or it is not a valid vector layer file" % f) return for f in files: item = LayerItem(f) self.ui.layersList.addItem(item) widget = LayerWidget(item, self.ui.layersList) self.ui.layersList.setItemWidget(item, widget) self._commonFields = None
def testLayerCommitId(self): repo = _createSimpleTestRepo(True) log = repo.log() filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref=log[1].commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") self.assertTrue(log[1].commitid, getCommitId(layer))
def updateTrackedLayers(repo): head = repo.revparse(geogig.HEAD) repoLayers = [tree.path for tree in repo.trees] repoLayersInProject = False notLoaded = [] toUnload = [] for trackedlayer in tracked: if trackedlayer.repoFolder == repo.url: if trackedlayer.layername in repoLayers: if (trackedlayer.ref != head or not os.path.exists(trackedlayer.source)): repo.exportshp(geogig.HEAD, trackedlayer.layername, trackedlayer.source, 'utf-8') try: layer = resolveLayerFromSource(trackedlayer.source) layer.dataProvider().forceReload() layer.setCacheImage(None) layer.triggerRepaint() repoLayersInProject = True except WrongLayerSourceException: notLoaded.append(trackedlayer) trackedlayer.ref = head else: try: layer = resolveLayerFromSource(trackedlayer.source) repoLayersInProject = True except WrongLayerSourceException: notLoaded.append(trackedlayer) else: try: layer = resolveLayerFromSource(trackedlayer.source) toUnload.append(layer) except WrongLayerSourceException: pass saveTracked() if repoLayersInProject: if notLoaded: ret = QtGui.QMessageBox.warning(config.iface.mainWindow(), "Update layers", "The current QGIS project only contains certain layers from the\n" "current version of the repository.\n" "Do you want to load the remaining ones?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes); if ret == QtGui.QMessageBox.Yes: layersToLoad = [] for layer in notLoaded: layersToLoad.append(loadLayerNoCrsDialog(layer.source, layer.layername, "ogr")) QgsMapLayerRegistry.instance().addMapLayers(layersToLoad) if toUnload: ret = QtGui.QMessageBox.warning(config.iface.mainWindow(), "Update layers", "The following layers are not present anymore in the repository:\n" "\t- " + "\n\t- ".join([layer.name() for layer in toUnload]) + "\nDo you want to remove them from the current QGIS project?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes); if ret == QtGui.QMessageBox.Yes: for layer in toUnload: QgsMapLayerRegistry.instance().removeMapLayer(layer.id()) config.iface.mapCanvas().refresh()
def _createSimpleTestRepo(modifiesRepo = False): conf.update([(k, os.getenv(k)) for k in conf if k in os.environ]) if modifiesRepo: repo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test", "simple_%s" % str(time.time())) else: global simpleTestRepo if simpleTestRepo is not None: return simpleTestRepo try: simpleTestRepo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test", "original_simple") except GeoGigException: simpleTestRepo = Repository(conf['REPOS_SERVER_URL'] + "repos/original_simple/", "test", "original_simple") return simpleTestRepo repo = simpleTestRepo _importLayerToRepo(repo, "first") log = repo.log() filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref = log[0].commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") with edit(layer): feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) feat.setAttributes([3, 2]) layer.addFeatures([feat]) repo.importgeopkg(layer, "master", "second", "tester", "*****@*****.**", True) log = repo.log() filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref = log[0].commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") features = list(layer.getFeatures()) for feature in features: pt = feature.geometry().asPoint() if pt.x() == 10 and pt.y()== 10: featureid = feature.id() break with edit(layer): layer.changeGeometry(featureid, QgsGeometry.fromPoint(QgsPoint(5, 5))) repo.importgeopkg(layer, "master", "third", "tester", "*****@*****.**", True) repo.createbranch(repo.HEAD, "mybranch") repo.createtag(repo.HEAD, "mytag") global _lastRepo _lastRepo = repo return _lastRepo
def _doConflictImport(layername = "points"): filename = tempFilename("gpkg") tests._lastRepo.checkoutlayer(filename, layername) layer = loadLayerNoCrsDialog(filename, layername, "ogr") idx = layer.dataProvider().fieldNameIndex("n") features = list(layer.getFeatures()) with edit(layer): layer.changeAttributeValue(features[0].id(), idx, 1001) tests._lastRepo.importgeopkg(layer, "master", "changed_%s_2" % layername, "me", "*****@*****.**", True)
def commitClicked(self): feature = self.listWidget.currentItem().feature geom = None self.attributesTable.setRowCount(len(feature)) for idx, attrname in enumerate(feature): value = feature[attrname] font = QFont() font.setBold(True) font.setWeight(75) item = QTableWidgetItem(attrname) item.setFont(font) self.attributesTable.setItem(idx, 0, item) self.attributesTable.setItem(idx, 1, QTableWidgetItem(str(value))) if geom is None: try: geom = QgsGeometry.fromWkt(value) except: pass self.attributesTable.resizeRowsToContents() self.attributesTable.horizontalHeader().setMinimumSectionSize(150) self.attributesTable.horizontalHeader().setStretchLastSection(True) settings = QSettings() prjSetting = settings.value('/Projections/defaultBehaviour') settings.setValue('/Projections/defaultBehaviour', '') types = ["Point", "LineString", "Polygon"] layers = [] if geom is not None: geomtype = types[int(geom.type())] layer = loadLayerNoCrsDialog(geomtype + "?crs=EPSG:4326", "temp", "memory") pr = layer.dataProvider() feat = QgsFeature() feat.setGeometry(geom) pr.addFeatures([feat]) layer.updateExtents() layer.selectAll() layer.setExtent(layer.boundingBoxOfSelected()) layer.invertSelection() symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol.setColor(Qt.green) symbol.setAlpha(0.5) if QGis.QGIS_VERSION_INT < 29900: layer.setRendererV2(QgsSingleSymbolRendererV2(symbol)) else: layer.setRenderer(QgsSingleSymbolRenderer(symbol)) self.mapCanvas.setRenderFlag(False) self.mapCanvas.setLayerSet([QgsMapCanvasLayer(layer)]) QgsMapLayerRegistry.instance().addMapLayer(layer, False) self.mapCanvas.setExtent(layer.extent()) self.mapCanvas.setRenderFlag(True) layers.append(layer) else: self.mapCanvas.setLayerSet([]) settings.setValue('/Projections/defaultBehaviour', prjSetting)
def _createWithMergeTestRepo(modifiesRepo = False): conf.update([(k, os.getenv(k)) for k in conf if k in os.environ]) if modifiesRepo: repo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test", "withmerge_%s" % str(time.time())) else: global withMergeTestRepo if withMergeTestRepo is not None: return withMergeTestRepo try: withMergeTestRepo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test", "original_withmerge") except GeoGigException: withMergeTestRepo = Repository(conf['REPOS_SERVER_URL'] + "repos/original_withmerge/", "test", "original_withmerge") return withMergeTestRepo repo = withMergeTestRepo _importLayerToRepo(repo, "first") repo.createbranch(repo.HEAD, "mybranch") filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref = repo.HEAD) layer = loadLayerNoCrsDialog(filename, "points", "ogr") with edit(layer): feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) feat.setAttributes([3, 2]) layer.addFeatures([feat]) repo.importgeopkg(layer, "mybranch", "second", "tester", "*****@*****.**", True) filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref = repo.HEAD) layer = loadLayerNoCrsDialog(filename, "points", "ogr") with edit(layer): feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(9, 9))) feat.setAttributes([9, 9]) layer.addFeatures([feat]) repo.importgeopkg(layer, "master", "second", "tester", "*****@*****.**", True) repo.merge("mybranch", "master") global _lastRepo _lastRepo = repo return _lastRepo
def testDownloadNonHead(self): repo = _createSimpleTestRepo() log = repo.log() self.assertEqual(3, len(log)) commitid = log[-1].commitid filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref=commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") self.assertTrue(layer.isValid()) features = list(layer.getFeatures()) self.assertEqual(1, len(features))
def exportAndLoadVersion(commit): trees = commit.root.trees layers = [] for tree in trees: filepath = os.path.join(tempFolder(), "%s_%s.shp" % (tree.path, commit.commitid)) if not os.path.exists(filepath): commit.repo.exportshp(commit.commitid, tree.path, filepath) layer = loadLayerNoCrsDialog(filepath, tree.path + "_[%s]" % commit.commitid[:8], "ogr") layer.setReadOnly(True) layers.append(layer) QgsMapLayerRegistry.instance().addMapLayers(layers)
def commonFields(self): if self._commonFields is None: for i in xrange(self.ui.layersList.count()): item = self.ui.layersList.item(i) path = item.path layer = loadLayerNoCrsDialog(path, "layer", "ogr") fields = set(f.name() for f in layer.dataProvider().fields()) if self._commonFields is None: self._commonFields = fields else: self._commonFields = self._commonFields & fields return self._commonFields
def exportVersionDiffs(commita, commitb=None): layers = {} if commitb is None: commitb = commita commita = commita.parent layernames = commita.repo.difftreestats(commita, commitb).keys() name = "%s_%s" % (commita.id[:8], commitb.id[:8]) for layername in layernames: layers[layername] = [] filepath = os.path.join(tempFolder(), "diff_%s_%s_before.shp" % (layername, name)) try: if not os.path.exists(filepath): commita.repo.exportdiffs(commita, commitb, layername, filepath, True, True, "utf-8") beforeLayer = loadLayerNoCrsDialog( filepath, layername + "_[%s][before]" % name, "ogr") beforeLayer.setReadOnly(True) vectorType = beforeLayer.geometryType() styleBefore, _ = styles[vectorType] beforeLayer.loadNamedStyle(styleBefore) layers[layername].append(beforeLayer) except GeoGigException: layers[layername].append(None) try: filepath = os.path.join(tempFolder(), "diff_%s_%s_after.shp" % (layername, name)) if not os.path.exists(filepath): commitb.repo.exportdiffs(commita, commitb, layername, filepath, False, True, "utf-8") afterLayer = loadLayerNoCrsDialog( filepath, layername + "_[%s][after]" % name, "ogr") afterLayer.setReadOnly(True) vectorType = afterLayer.geometryType() _, styleAfter = styles[vectorType] afterLayer.loadNamedStyle(styleAfter) layers[layername].append(afterLayer) except GeoGigException: layers[layername].append(None) return layers
def _exportAndCreateConflictWithRemoveAndModify(): layer = checkoutLayer(tests._lastRepo, "points", None) idx = layer.dataProvider().fieldNameIndex("n") features = list(layer.getFeatures()) with edit(layer): layer.deleteFeatures([features[0].id()]) filename = tempFilename("gpkg") tests._lastRepo.checkoutlayer(filename, "points") layer2 = loadLayerNoCrsDialog(filename, "points2", "ogr") features2 = list(layer2.getFeatures()) with edit(layer2): layer2.changeAttributeValue(features[0].id(), idx, 1000) _, _, conflicts, _ = tests._lastRepo.importgeopkg(layer2, "master", "message", "me", "*****@*****.**", True)
def commitClicked(self): feature = self.ui.listWidget.currentItem().feature geom = None self.ui.attributesTable.setRowCount(len(feature)) for idx, attrname in enumerate(feature): value, typename = feature[attrname] font = QtGui.QFont() font.setBold(True) font.setWeight(75) item = QtGui.QTableWidgetItem(attrname) item.setFont(font) self.ui.attributesTable.setItem(idx, 0, item); self.ui.attributesTable.setItem(idx, 1, QtGui.QTableWidgetItem(unicode(value))); if geom is None: if isinstance(value, Geometry): geom = value self.ui.attributesTable.resizeRowsToContents() self.ui.attributesTable.horizontalHeader().setMinimumSectionSize(150) self.ui.attributesTable.horizontalHeader().setStretchLastSection(True) settings = QtCore.QSettings() prjSetting = settings.value('/Projections/defaultBehaviour') settings.setValue('/Projections/defaultBehaviour', '') types = ["Point", "LineString", "Polygon"] layers = [] if geom is not None: qgsgeom = QgsGeometry.fromWkt(geom.geom) geomtype = types[int(qgsgeom.type())] layer = loadLayerNoCrsDialog(geomtype + "?crs=EPSG:4326", "temp", "memory") pr = layer.dataProvider() feat = QgsFeature() feat.setGeometry(qgsgeom) pr.addFeatures([feat]) layer.updateExtents() layer.selectAll() layer.setExtent(layer.boundingBoxOfSelected()) layer.invertSelection() symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol.setColor(QtCore.Qt.green) symbol.setAlpha(0.5) layer.setRendererV2(QgsSingleSymbolRendererV2(symbol)) self.mapCanvas.setRenderFlag(False) self.mapCanvas.setLayerSet([QgsMapCanvasLayer(layer)]) QgsMapLayerRegistry.instance().addMapLayer(layer, False) self.mapCanvas.setExtent(layer.extent()) self.mapCanvas.setRenderFlag(True) layers.append(layer) else: self.mapCanvas.setLayerSet([]) settings.setValue('/Projections/defaultBehaviour', prjSetting)
def _createConflictedPullScenario(): global _localRepo _localRepo = _createSimpleTestRepo(True) global _remoteRepo _remoteRepo = _createEmptyTestRepo(True) _localRepo.addremote("myremote", _remoteRepo.url) _remoteRepo.addremote("myremote", _localRepo.url) _localRepo.push("myremote", "master") filename = tempFilename("gpkg") _localRepo.checkoutlayer(filename, "points") layer = loadLayerNoCrsDialog(filename, "points", "ogr") features = list(layer.getFeatures()) idx = layer.dataProvider().fieldNameIndex("n") with edit(layer): layer.changeAttributeValue(features[0].id(), idx, 1000) filename2 = tempFilename("gpkg") _remoteRepo.checkoutlayer(filename2, "points") layer2 = loadLayerNoCrsDialog(filename2, "points2", "ogr") features2 = list(layer2.getFeatures()) with edit(layer2): layer2.changeAttributeValue(features2[0].id(), idx, 1001) _localRepo.importgeopkg(layer, "master", "message", "me", "*****@*****.**", True) _remoteRepo.importgeopkg(layer2, "master", "message", "me", "*****@*****.**", True)
def testImportInterchangeFormat(self): repo = _createSimpleTestRepo(True) filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points") layer = loadLayerNoCrsDialog(filename, "points", "ogr") self.assertTrue(layer.isValid()) features = list(layer.getFeatures()) self.assertEqual(2, len(features)) with edit(layer): layer.deleteFeatures([features[0].id()]) features = list(layer.getFeatures()) self.assertEqual(1, len(features)) repo.importgeopkg(layer, "master", "message", "me", "*****@*****.**", True) log = repo.log() self.assertEqual("message", log[0].message) self.assertEqual(["points"], repo.trees()) filename2 = tempFilename("gpkg") repo.checkoutlayer(filename2, "points") layer2 = loadLayerNoCrsDialog(filename, "points2", "ogr") self.assertTrue(layer2.isValid()) features2 = list(layer2.getFeatures()) self.assertEqual(1, len(features2))
def testResolveConflictWithNewFeature(self): repo, conflicts = self._createConflict() conflicts[0].resolveWithNewFeature({"fid": 1, "n": 1002}) conflicts[1].resolveWithRemoteVersion() repo.commitAndCloseMergeAndTransaction("user", "*****@*****.**", "conflict resolution", conflicts[0].transactionId) self.assertTrue("conflict resolution" in repo.log()[0].message) filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref=repo.HEAD) layer = loadLayerNoCrsDialog(filename, "points", "ogr") features = list(layer.getFeatures()) self.assertTrue([1, 1002], features[0].attributes()) self.assertTrue([2, 2000], features[1].attributes())
def loadRepoExportedLayers(repo): paths = getTrackedPathsForRepo(repo) layers = [] for f in paths: try: layer = resolveLayerFromSource(f) layer.reload() layer.triggerRepaint() except WrongLayerSourceException: layername = os.path.splitext(os.path.basename(f))[0] layer = loadLayerNoCrsDialog(f, layername, "ogr") layers.append(layer) if layers: QgsMapLayerRegistry.instance().addMapLayers(layers)
def _exportAndCreateConflictWithNulls(): layer = checkoutLayer(tests._lastRepo, "points", None) idx = layer.dataProvider().fieldNameIndex("n") features = list(layer.getFeatures()) with edit(layer): layer.changeGeometry(features[0].id(), QgsGeometry.fromPoint(QgsPoint(123, 456))) layer.changeAttributeValue(features[0].id(), idx, None) filename = tempFilename("gpkg") tests._lastRepo.checkoutlayer(filename, "points") layer2 = loadLayerNoCrsDialog(filename, "points2", "ogr") features2 = list(layer2.getFeatures()) with edit(layer2): layer2.changeGeometry(features[0].id(), QgsGeometry.fromPoint(QgsPoint(124, 457))) layer2.changeAttributeValue(features2[0].id(), idx, None) _, _, conflicts, _ = tests._lastRepo.importgeopkg(layer2, "master", "message", "me", "*****@*****.**", True)
def exportAndLoadVersion(commit): trees = commit.root.trees layers = [] for tree in trees: filepath = os.path.join(tempFolder(), "%s_%s.shp" % (tree.path, commit.commitid)) if not os.path.exists(filepath): commit.repo.exportshp(commit.commitid, tree.path, filepath, "utf-8") layer = loadLayerNoCrsDialog(filepath, tree.path + "_[%s]" % commit.commitid[:8], "ogr") layer.setReadOnly(True) layers.append(layer) QgsMapLayerRegistry.instance().addMapLayers(layers)
def loadRepoExportedLayers(repo): paths = getTrackedPathsForRepo(repo) layers = [] for f in paths: try: layer = resolveLayerFromSource(f) layer.dataProvider().forceReload() layer.setCacheImage(None) layer.triggerRepaint() except WrongLayerSourceException: layername = os.path.splitext(os.path.basename(f))[0] layer = loadLayerNoCrsDialog(f, layername, "ogr") layers.append(layer) if layers: QgsMapLayerRegistry.instance().addMapLayers(layers)
def testChangeVersion(self): repo = _createSimpleTestRepo() log = repo.log() self.assertEqual(3, len(log)) commitid = log[-1].commitid filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points", ref = commitid) layer = loadLayerNoCrsDialog(filename, "points", "ogr") self.assertTrue(layer.isValid()) features = list(layer.getFeatures()) self.assertEqual(1, len(features)) applyLayerChanges(repo, layer, commitid, repo.HEAD) layer.reload() self.assertTrue(layer.isValid()) features = list(layer.getFeatures()) self.assertEqual(2, len(features)) self.assertEqual(getCommitId(layer), log[0].commitid)
def testImportWithNullValue(self): repo = _createSimpleTestRepo(True) filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points") layer = loadLayerNoCrsDialog(filename, "points", "ogr") self.assertTrue(layer.isValid()) features = list(layer.getFeatures()) self.assertEqual(2, len(features)) idx = layer.dataProvider().fieldNameIndex("n") features = list(layer.getFeatures()) with edit(layer): layer.changeGeometry(features[0].id(), QgsGeometry.fromPoint(QgsPoint(123, 456))) layer.changeAttributeValue(features[0].id(), idx, None) repo.importgeopkg(layer, "master", "message", "me", "*****@*****.**", True) log = repo.log() self.assertEqual("message", log[0].message)
def testCanCleanAuditTableAfterEdit(self): src = os.path.join(os.path.dirname(__file__), "data", "layers", "points.gpkg") dest = tempFilename("gpkg") shutil.copy(src, dest) layer = loadLayerNoCrsDialog(dest, "points", "ogr") self.assertTrue(layer.isValid()) features = list(layer.getFeatures()) geom = QgsGeometry.fromPoint(QgsPoint(12,12)) self.assertTrue(layer.startEditing()) self.assertTrue(layer.changeGeometry(features[0].id(), geom)) self.assertTrue(layer.commitChanges()) con = sqlite3.connect(dest) cursor = con.cursor() cursor.execute("DELETE FROM points_audit;") self.assertRaises(OperationalError, con.commit) con.close() layer.reload() con = sqlite3.connect(dest) cursor = con.cursor() cursor.execute("DELETE FROM points_audit;") con.commit()
def addDiffLayer(repo, layername, commit): styles = [diffStylePoints, diffStyleLines, diffStylePolygons] geomTypes = ["Point","LineString","Polygon"] beforeFilename = tempFilename("gpkg") repo.exportdiff(layername, commit.commitid, commit.parent.commitid, beforeFilename) beforeLayer = loadLayerNoCrsDialog(beforeFilename, layername, "ogr") afterFilename = tempFilename("gpkg") repo.exportdiff(layername, commit.parent.commitid, commit.commitid, afterFilename) afterLayer = loadLayerNoCrsDialog(afterFilename, layername, "ogr") beforeCon = sqlite3.connect(beforeFilename) beforeCursor = beforeCon.cursor() afterCon = sqlite3.connect(afterFilename) afterCursor = afterCon.cursor() attributes = [v[1] for v in beforeCursor.execute("PRAGMA table_info('%s');" % layername)] attrnames = [f.name() for f in beforeLayer.pendingFields()] layerFeatures = [] beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=2;" % layername) modified = beforeCursor.fetchall() for m in modified: geogigfid = m[0] beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid) beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid)) featureRow = beforeCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = MODIFIED_BEFORE request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(beforeLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid) afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername,afterGpkgfid)) featureRow = afterCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = MODIFIED_AFTER request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(afterLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) afterCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername) added = afterCursor.fetchall() for a in added: geogigfid = a[0] afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid) afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, afterGpkgfid)) featureRow = afterCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = ADDED request = QgsFeatureRequest() request.setFilterFid(afterGpkgfid) feature = next(afterLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername) removed = beforeCursor.fetchall() for r in removed: geogigfid = r[0] beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid) beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid)) featureRow = beforeCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = REMOVED request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(beforeLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) attrnames.append("changetype") uriFields = "&".join(["field=%s" % f for f in attrnames]) uri = "%s?crs=%s&%s" % (geomTypes[beforeLayer.geometryType()], beforeLayer.crs().authid(), uriFields) layer = QgsVectorLayer(uri, "diff", "memory") featuresList = [] for feature in layerFeatures: qgsfeature = QgsFeature() qgsfeature.setGeometry(feature["geom"]) qgsfeature.setAttributes([feature["attrs"][attr] for attr in attrnames]) featuresList.append(qgsfeature) layer.dataProvider().addFeatures(featuresList) layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayers([layer]) layer.loadNamedStyle(styles[layer.geometryType()])
def _getQgisTestLayer(self): dest = self._copyTestLayer() iface.newProject() layer = loadLayerNoCrsDialog(dest, "points", "ogr") QgsMapLayerRegistry.instance().addMapLayers([layer]) return layer
def createLayers(self): textGeometries = [] for geom in self.geoms: text = geom.exportToWkt() valid = " 1234567890.," text = "".join([c for c in text if c in valid]) textGeometries.append(text.split(",")) lines = difflib.Differ().compare(textGeometries[0], textGeometries[1]) self.data = [] for line in lines: if line.startswith("+"): self.data.append([None, line[2:]]) if line.startswith("-"): self.data.append([line[2:], None]) if line.startswith(" "): self.data.append([line[2:], line[2:]]) types = [("LineString", lineBeforeStyle, lineAfterStyle), ("Polygon", polygonBeforeStyle, polygonAfterStyle)] layers = [] extent = self.geoms[0].boundingBox() for i, geom in enumerate(self.geoms): geomtype = types[int(geom.type() - 1)][0] style = types[int(geom.type() - 1)][i + 1] layer = loadLayerNoCrsDialog(geomtype + "?crs=" + self.crs.authid(), "layer", "memory") pr = layer.dataProvider() feat = QgsFeature() feat.setGeometry(geom) pr.addFeatures([feat]) layer.loadNamedStyle(style) layer.updateExtents() layers.append(layer) QgsMapLayerRegistry.instance().addMapLayer(layer, False) extent.combineExtentWith(geom.boundingBox()) layer = loadLayerNoCrsDialog("Point?crs=%s&field=changetype:string" % self.crs.authid(), "points", "memory") pr = layer.dataProvider() feats = [] for coords in self.data: coord = coords[0] or coords[1] feat = QgsFeature() x, y = coord.split(" ") x, y = (float(x), float(y)) pt = QgsGeometry.fromPoint(QgsPoint(x, y)) feat.setGeometry(pt) if coords[0] is None: changetype = "A" elif coords[1] is None: changetype = "R" else: changetype = "U" feat.setAttributes([changetype]) feats.append(feat) pr.addFeatures(feats) layer.loadNamedStyle(pointsStyle) QgsMapLayerRegistry.instance().addMapLayer(layer, False) layers.append(layer) self.mapLayers = [QgsMapCanvasLayer(lay) for lay in layers] self.canvas.setLayerSet(self.mapLayers) self.canvas.setExtent(extent) self.canvas.refresh()
def checkoutLayer(repo, layername, bbox, ref=None): ref = ref or repo.HEAD newCommitId = repo.revparse(ref) trackedlayer = getTrackingInfoForGeogigLayer(repo.url, layername) if trackedlayer is not None: if not os.path.exists(trackedlayer.geopkg): removeTrackedLayer(trackedlayer.source) trackedlayer = None filename = layerGeopackageFilename(layername, repo.title, repo.group) source = "%s|layername=%s" % (filename, layername) else: source = trackedlayer.source else: filename = layerGeopackageFilename(layername, repo.title, repo.group) source = "%s|layername=%s" % (filename, layername) if trackedlayer is None: repo.checkoutlayer(filename, layername, bbox, ref or repo.HEAD) addTrackedLayer(source, repo.url) try: layer = resolveLayerFromSource(source) iface.messageBar().pushMessage( "GeoGig", "Layer was already included in the current QGIS project", level=QgsMessageBar.INFO, duration=5) except WrongLayerSourceException: layer = loadLayerNoCrsDialog(source, layername, "ogr") QgsMapLayerRegistry.instance().addMapLayers([layer]) iface.messageBar().pushMessage("GeoGig", "Layer correctly added to project", level=QgsMessageBar.INFO, duration=5) elif ref is not None: currentCommitId = getCommitId(source) try: layer = resolveLayerFromSource(source) wasLoaded = True except WrongLayerSourceException: layer = loadLayerNoCrsDialog(source, layername, "ogr") wasLoaded = False if newCommitId != currentCommitId: if hasLocalChanges(layer): raise HasLocalChangesError() filename, layername = namesFromLayer(layer) repo.checkoutlayer(filename, layername, bbox, ref) layer.reload() if not wasLoaded: QgsMapLayerRegistry.instance().addMapLayers([layer]) iface.messageBar().pushMessage( "GeoGig", "Layer correctly added to project", level=QgsMessageBar.INFO, duration=5) else: iface.messageBar().pushMessage( "GeoGig", "Layer correctly updated to specified version", level=QgsMessageBar.INFO, duration=5) layer.triggerRepaint() else: if wasLoaded: iface.messageBar().pushMessage( "GeoGig", "Layer was already included in the current QGIS project", level=QgsMessageBar.INFO, duration=5) else: QgsMapLayerRegistry.instance().addMapLayers([layer]) iface.messageBar().pushMessage( "GeoGig", "Layer correctly added to the current QGIS project", level=QgsMessageBar.INFO, duration=5) repoWatcher.repoChanged.emit(repo) return layer
def accept(self): QtGui.QApplication.setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor)) try: self.ui.featureIdBox.setStyleSheet("QLineEdit{background: white}") self.ui.destTreeBox.setStyleSheet("QLineEdit{background: white}") self.ui.commitTextBox.setStyleSheet( "QPlainTextEdit{background: white}") dest = self.ui.destTreeBox.text().strip() if dest == '': self.ui.destTreeBox.setStyleSheet( "QLineEdit{background: yellow}") return fid = self.ui.featureIdBox.text().strip() pattern = self.ui.commitTextBox.toPlainText().strip() if pattern == '': self.ui.commitTextBox.setStyleSheet( "QPlainTextEdit{background: yellow}") return layers = [] fieldsInFid = [f[1:-1] for f in re.findall("\[.*?\]", fid)] for i in xrange(self.ui.layersList.count()): item = self.ui.layersList.item(i) path = item.path item.setBackground(QtCore.Qt.white) layer = loadLayerNoCrsDialog(path, "layer", "ogr") if not layer.isValid( ) or layer.type() != QgsMapLayer.VectorLayer: raise Exception( "Error reading file %s or it is not a valid vector layer file" % path) provider = layer.dataProvider() for field in fieldsInFid: idx = provider.fieldNameIndex(field) if idx == -1: raise Exception("Field %s not found in layer %s " % (field, path)) layers.append(layer) try: self.repo.connector.setShowProgress(False) for i, layer in enumerate(layers): item = self.ui.layersList.item(i) path = layer.source() exported, charset = exportVectorLayerAddingId(layer, fid) self.repo.importshp(exported, False, dest, self.GEOGIGID, True, charset) message = pattern.replace("%f", os.path.basename(path)).replace( "%d", dest) self.repo.add() self.repo.commit(message) item.setBackground(QtCore.Qt.green) QtCore.QCoreApplication.processEvents() except GeoGigException, e: raise Exception("Cannot import layer " + path) finally: self.repo.connector.setShowProgress(True) self.ok = True QtGui.QApplication.restoreOverrideCursor() config.iface.messageBar().pushMessage( "Layer files correctly added to repository", level=QgsMessageBar.INFO, duration=4) self.reject()
def testDownload(self): repo = _createSimpleTestRepo() filename = tempFilename("gpkg") repo.checkoutlayer(filename, "points") layer = loadLayerNoCrsDialog(filename, "points", "ogr") self.assertTrue(layer.isValid())