def testStepSize(self): ml = QgsMeshLayer( os.path.join(unitTestDataPath(), '3d', 'elev_mesh.2dm'), 'mdal', 'mdal') self.assertTrue(ml.isValid()) ml.setCrs(QgsCoordinateReferenceSystem('EPSG:27700')) curve = QgsLineString() curve.fromWkt( 'LineString (-348095.18706532847136259 6633687.0235139261931181, -347271.57799367723055184 6633093.13086318597197533, -346140.60267287614988163 6632697.89590711053460836, -345777.013075890194159 6631575.50219972990453243)' ) req = QgsProfileRequest(curve) # set a smaller step size then would be automatically calculated req.setStepDistance(10) # set correct crs for linestring and re-try req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = ml.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) r = generator.takeResults() results = r.distanceToHeightMap() self.assertEqual(len(results), 216) first_point = min(results.keys()) last_point = max(results.keys()) self.assertAlmostEqual(results[first_point], 152.87405434310168, 0) self.assertAlmostEqual(results[last_point], 98.78085001573021, 0) self.assertAlmostEqual(r.zRange().lower(), 80, 2) self.assertAlmostEqual(r.zRange().upper(), 152.874, 0)
def testProfileRenderFixedColor(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) pcl.elevationProperties().setPointSymbol(Qgis.PointCloudSymbol.Square) pcl.elevationProperties().setPointColor(QColor(255, 0, 255)) pcl.elevationProperties().setPointSize(3) pcl.elevationProperties().setPointSizeUnit( QgsUnitTypes.RenderMillimeters) pcl.elevationProperties().setRespectLayerColors(False) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) plot_renderer = QgsProfilePlotRenderer([pcl], req) plot_renderer.startGeneration() plot_renderer.waitForFinished() res = plot_renderer.renderToImage(400, 400, 0, curve.length(), 2320, 2330) self.assertTrue( self.imageCheck('point_cloud_layer_fixed_color', 'point_cloud_layer_fixed_color', res))
def testGenerationWithStepSize(self): rl = QgsRasterLayer(os.path.join(unitTestDataPath(), '3d', 'dtm.tif'), 'DTM') self.assertTrue(rl.isValid()) curve = QgsLineString() curve.fromWkt('LineString (-348095.18706532847136259 6633687.0235139261931181, -347271.57799367723055184 6633093.13086318597197533, -346140.60267287614988163 6632697.89590711053460836, -345777.013075890194159 6631575.50219972990453243)') req = QgsProfileRequest(curve) req.setStepDistance(10) generator = rl.createProfileGenerator(req) # not enabled for elevation self.assertIsNone(generator) rl.elevationProperties().setEnabled(True) generator = rl.createProfileGenerator(req) self.assertIsNotNone(generator) # the request did not have the crs of the linestring set, so the whole linestring falls outside the raster extent self.assertFalse(generator.generateProfile()) # set correct crs for linestring and re-try req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = rl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) r = generator.takeResults() results = r.distanceToHeightMap() self.assertEqual(len(results), 341) first_point = min(results.keys()) last_point = max(results.keys()) self.assertEqual(results[first_point], 154) self.assertEqual(results[last_point], 99) self.assertEqual(r.zRange().lower(), 74) self.assertEqual(r.zRange().upper(), 154)
def testPointGenerationMultiPoint(self): vl = QgsVectorLayer('MultipointZ?crs=EPSG:27700', 'trees', 'memory') self.assertTrue(vl.isValid()) f = QgsFeature() f.setGeometry(QgsGeometry.fromWkt('MultiPointZ(322069 129893 89.1, 322077 129889 90.2, 322093 129888 92.4)')) self.assertTrue(vl.dataProvider().addFeature(f)) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Absolute) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) curve = QgsLineString() curve.fromWkt( 'LineString (-347557.39478182751918212 6632716.59644229710102081, -346435.3875386503059417 6632277.86440025269985199, -346234.1061912341392599 6632242.03022097796201706, -346185.31071307259844616 6632150.53869942482560873)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) req.setTolerance(110) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {1158.2: 232.8, 1172.4: 235.5, 1196.5: 241.0}) self.assertAlmostEqual(results.zRange().lower(), 232.75, 2) self.assertAlmostEqual(results.zRange().upper(), 241.0, 2)
def testPointGenerationRelativeExtrusion(self): """ Points layer with relative clamping and extrusion """ vl = QgsVectorLayer(os.path.join(unitTestDataPath(), '3d', 'points_with_z.shp'), 'trees') self.assertTrue(vl.isValid()) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Relative) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) vl.elevationProperties().setExtrusionEnabled(True) vl.elevationProperties().setExtrusionHeight(7) rl = QgsRasterLayer(os.path.join(unitTestDataPath(), '3d', 'dtm.tif'), 'DTM') self.assertTrue(rl.isValid()) curve = QgsLineString() curve.fromWkt( 'LineString (-347557.39478182751918212 6632716.59644229710102081, -346435.3875386503059417 6632277.86440025269985199, -346234.1061912341392599 6632242.03022097796201706, -346185.31071307259844616 6632150.53869942482560873)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) terrain_provider = QgsRasterDemTerrainProvider() terrain_provider.setLayer(rl) terrain_provider.setScale(0.3) terrain_provider.setOffset(-5) req.setTerrainProvider(terrain_provider) req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) req.setTolerance(15) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() if QgsProjUtils.projVersionMajor() >= 8: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {31.2: 333.5, 175.6: 333.5, 1242.5: 267.0}) else: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {31.2: 331.2, 175.6: 329.8, 1242.5: 264.0}) if QgsProjUtils.projVersionMajor() >= 8: self.assertCountEqual([g.asWkt(1) for g in results.asGeometries()], ['LineStringZ (-347395 6632649.6 333.5, -347395 6632649.6 340.5)', 'LineStringZ (-347533.4 6632692.2 333.5, -347533.4 6632692.2 340.5)', 'LineStringZ (-346399.2 6632265.6 267, -346399.2 6632265.6 274)']) self.assertAlmostEqual(results.zRange().lower(), 267.0, 2) self.assertAlmostEqual(results.zRange().upper(), 340.5, 2) else: self.assertCountEqual([g.asWkt(1) for g in results.asGeometries()], ['LineStringZ (-347395 6632649.6 329.8, -347395 6632649.6 336.8)', 'LineStringZ (-347533.4 6632692.2 331.3, -347533.4 6632692.2 338.3)', 'LineStringZ (-346399.2 6632265.6 264, -346399.2 6632265.6 271)']) self.assertAlmostEqual(results.zRange().lower(), 264.0, 2) self.assertAlmostEqual(results.zRange().upper(), 338.25, 2)
def testPolygonGenerationTerrain(self): vl = QgsVectorLayer('PolygonZ?crs=EPSG:27700', 'lines', 'memory') self.assertTrue(vl.isValid()) for line in [ 'PolygonZ ((321829.48893365426920354 129991.38697145861806348 1, 321847.89668515208177269 129996.63588572069420479 1, 321848.97131609614007175 129979.22330882755341008 1, 321830.31725845142500475 129978.07136809575604275 1, 321829.48893365426920354 129991.38697145861806348 1))', 'PolygonZ ((321920.00953056826256216 129924.58260190498549491 2, 321924.65299345907988027 129908.43546159457764588 2, 321904.78543491888558492 129903.99811821122420952 2, 321900.80605239619035274 129931.39860145389684476 2, 321904.84799937985371798 129931.71552911199978553 2, 321908.93646715773502365 129912.90030360443051904 2, 321914.20495146053144708 129913.67693978428724222 2, 321911.30165811872575432 129923.01272751353099011 2, 321920.00953056826256216 129924.58260190498549491 2))', 'PolygonZ ((321923.10517279652412981 129919.61521573827485554 3, 321922.23537852568551898 129928.3598982143739704 3, 321928.60423935484141111 129934.22530528216157109 3, 321929.39881197665818036 129923.29054521876969375 3, 321930.55804549407912418 129916.53248518184409477 3, 321923.10517279652412981 129919.61521573827485554 3))', 'PolygonZ ((321990.47451346553862095 129909.63588680300745182 4, 321995.04325810901354998 129891.84052284323843196 4, 321989.66826330573530868 129890.5092018858413212 4, 321990.78512359503656626 129886.49917887404444627 4, 321987.37291929306229576 129885.64982962771318853 4, 321985.2254804756375961 129893.81317058412241749 4, 321987.63158903241856024 129894.41078495365218259 4, 321984.34022761805681512 129907.57450046355370432 4, 321990.47451346553862095 129909.63588680300745182 4))', 'PolygonZ ((322103.03910495212767273 129795.91051736124791205 5, 322108.25568856322206557 129804.76113295342656784 5, 322113.29666162584908307 129803.9285887333098799 5, 322117.78645010641776025 129794.48194090687320568 5, 322103.03910495212767273 129795.91051736124791205 5))']: f = QgsFeature() f.setGeometry(QgsGeometry.fromWkt(line)) self.assertTrue(vl.dataProvider().addFeature(f)) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Terrain) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) curve = QgsLineString() curve.fromWkt( 'LineString (-347701.59207547508412972 6632766.96282589063048363, -346577.00878971704514697 6632369.7371364813297987, -346449.93654899462126195 6632331.81857067719101906, -346383.52035177784273401 6632216.85897350125014782)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) rl = QgsRasterLayer(os.path.join(unitTestDataPath(), '3d', 'dtm.tif'), 'DTM') self.assertTrue(rl.isValid()) terrain_provider = QgsRasterDemTerrainProvider() terrain_provider.setLayer(rl) terrain_provider.setScale(0.3) terrain_provider.setOffset(-5) req.setTerrainProvider(terrain_provider) req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() if QgsProjUtils.projVersionMajor() >= 8: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {1041.8: 55.3, 1042.4: 55.2, 1049.5: 55.2, 1070.2: 55.2, 1073.1: 55.2, 1074.8: 55.3, 1078.9: 54.5, 1083.9: 54.5, 1091.1: 54.5, 1186.8: 49.3, 1189.8: 49.2, 1192.7: 49.2, 1199.2: 49.2, 1450.0: 53.0, 1455.6: 53.0, 1458.1: 53.0}) self.assertAlmostEqual(results.zRange().lower(), 49.25, 2) self.assertAlmostEqual(results.zRange().upper(), 55.250, 2) else: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {1041.8: 48.5, 1042.4: 48.5, 1049.5: 48.5, 1070.2: 48.5, 1073.1: 48.5, 1074.8: 48.5, 1078.9: 48.5, 1083.9: 48.5, 1091.1: 48.5, 1186.8: 52.3, 1189.8: 52.2, 1192.7: 52.2, 1199.2: 52.2, 1450.0: 54.5, 1455.6: 54.5, 1458.1: 54.5}) self.assertAlmostEqual(results.zRange().lower(), 48.5, 2) self.assertAlmostEqual(results.zRange().upper(), 54.500000, 2)
def testLineGenerationRelative(self): vl = QgsVectorLayer('LineStringZ?crs=EPSG:27700', 'lines', 'memory') self.assertTrue(vl.isValid()) for line in ['LineStringZ(322006 129874 12, 322008 129910 13, 322038 129909 14, 322037 129868 15)', 'LineStringZ(322068 129900 16, 322128 129813 17)', 'LineStringZ(321996 129914 11, 321990 129896 15)', 'LineStringZ(321595 130176 1, 321507 130104 10)', 'LineStringZ(321558 129930 1, 321568 130029 10, 321516 130049 5)', 'LineStringZ(321603 129967 3, 321725 130042 9)']: f = QgsFeature() f.setGeometry(QgsGeometry.fromWkt(line)) self.assertTrue(vl.dataProvider().addFeature(f)) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Relative) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) curve = QgsLineString() curve.fromWkt( 'LineString (-347692.88994020794052631 6632796.97473032586276531, -346576.99897185183363035 6632367.38372825458645821, -346396.02439485350623727 6632344.35087973903864622, -346374.34608158958144486 6632220.09952207934111357)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) rl = QgsRasterLayer(os.path.join(unitTestDataPath(), '3d', 'dtm.tif'), 'DTM') self.assertTrue(rl.isValid()) terrain_provider = QgsRasterDemTerrainProvider() terrain_provider.setLayer(rl) terrain_provider.setScale(0.3) terrain_provider.setOffset(-5) req.setTerrainProvider(terrain_provider) req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() if QgsProjUtils.projVersionMajor() >= 8: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {675.2: 84.2, 1195.7: 86.8, 1223.1: 81.4, 1272.0: 90.0, 1339.4: 98.7, 1444.4: 100.0}) self.assertAlmostEqual(results.zRange().lower(), 81.358, 2) self.assertAlmostEqual(results.zRange().upper(), 100.009, 2) else: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {675.2: 80.5, 1195.7: 90.5, 1223.1: 87.4, 1272.0: 94.5, 1339.4: 98.0, 1444.4: 94.0}) self.assertAlmostEqual(results.zRange().lower(), 80.4564, 2) self.assertAlmostEqual(results.zRange().upper(), 97.9811, 2)
def testPointGenerationTerrain(self): """ Points layer with terrain clamping """ vl = QgsVectorLayer(os.path.join(unitTestDataPath(), '3d', 'points_with_z.shp'), 'trees') self.assertTrue(vl.isValid()) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Terrain) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) rl = QgsRasterLayer(os.path.join(unitTestDataPath(), '3d', 'dtm.tif'), 'DTM') self.assertTrue(rl.isValid()) curve = QgsLineString() curve.fromWkt( 'LineString (-347557.39478182751918212 6632716.59644229710102081, -346435.3875386503059417 6632277.86440025269985199, -346234.1061912341392599 6632242.03022097796201706, -346185.31071307259844616 6632150.53869942482560873)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) terrain_provider = QgsRasterDemTerrainProvider() terrain_provider.setLayer(rl) terrain_provider.setScale(0.3) terrain_provider.setOffset(-5) req.setTerrainProvider(terrain_provider) req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) # no tolerance => no hits results = generator.takeResults() self.assertFalse(results.distanceToHeightMap()) req.setTolerance(15) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() if QgsProjUtils.projVersionMajor() >= 8: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {175.6: 69.5, 31.2: 69.5, 1242.5: 55.2}) self.assertAlmostEqual(results.zRange().lower(), 55.249, 2) self.assertAlmostEqual(results.zRange().upper(), 69.5, 2) else: self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {31.2: 67.2, 175.6: 65.8, 1242.5: 52.2}) self.assertAlmostEqual(results.zRange().lower(), 52.25, 2) self.assertAlmostEqual(results.zRange().upper(), 67.25, 2)
def testPointGenerationAbsolute(self): vl = QgsVectorLayer(os.path.join(unitTestDataPath(), '3d', 'points_with_z.shp'), 'trees') self.assertTrue(vl.isValid()) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Absolute) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) curve = QgsLineString() curve.fromWkt( 'LineString (-347557.39478182751918212 6632716.59644229710102081, -346435.3875386503059417 6632277.86440025269985199, -346234.1061912341392599 6632242.03022097796201706, -346185.31071307259844616 6632150.53869942482560873)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) generator = vl.createProfileGenerator(req) self.assertIsNotNone(generator) # the request did not have the crs of the linestring set, so the whole linestring falls outside the vector extent self.assertFalse(generator.generateProfile()) # set correct crs for linestring and re-try req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) # no tolerance => no hits results = generator.takeResults() self.assertFalse(results.distanceToHeightMap()) req.setTolerance(90) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {31.2: 274.0, 1223.2: 227.2, 1213.4: 241.0, 175.6: 274.0, 1242.5: 221.8, 1172.3: 235.5, 1159.1: 232.8}) # lower tolerance req.setTolerance(15) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {31.2: 274.0, 175.6: 274.0, 1242.5: 221.8}) self.assertAlmostEqual(results.zRange().lower(), 221.75, 2) self.assertAlmostEqual(results.zRange().upper(), 274.0, 2)
def testBasic(self): req = QgsProfileRequest(QgsLineString([[1, 2], [3, 4]])) self.assertEqual(req.profileCurve().asWkt(), 'LineString (1 2, 3 4)') req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')).setTolerance( 5).setStepDistance(15) self.assertEqual(req.crs().authid(), 'EPSG:3857') self.assertEqual(req.tolerance(), 5) self.assertEqual(req.stepDistance(), 15) proj_string = '+proj=pipeline +step +inv +proj=lcc +lat_0=-37 +lon_0=145 +lat_1=-36 +lat_2=-38 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' transform_context = QgsCoordinateTransformContext() transform_context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), proj_string) req.setTransformContext(transform_context) self.assertEqual( req.transformContext().calculateCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), proj_string) exp_context = QgsExpressionContext() context_scope = QgsExpressionContextScope() context_scope.setVariable('test_var', 5, True) exp_context.appendScope(context_scope) req.setExpressionContext(exp_context) self.assertEqual(req.expressionContext().variable('test_var'), 5) terrain = QgsFlatTerrainProvider() terrain.setOffset(5) req.setTerrainProvider(terrain) self.assertEqual(req.terrainProvider().offset(), 5) copy = QgsProfileRequest(req) self.assertEqual(copy.profileCurve().asWkt(), 'LineString (1 2, 3 4)') self.assertEqual(copy.crs().authid(), 'EPSG:3857') self.assertEqual(copy.tolerance(), 5) self.assertEqual(copy.stepDistance(), 15) self.assertEqual( copy.transformContext().calculateCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), proj_string) self.assertIsInstance(copy.terrainProvider(), QgsFlatTerrainProvider) self.assertEqual(copy.terrainProvider().offset(), 5) self.assertEqual(copy.expressionContext().variable('test_var'), 5)
def testSnapping(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) generator = pcl.createProfileGenerator(req) generator.generateProfile(context) r = generator.takeResults() # try snapping some points context = QgsProfileSnapContext() res = r.snapPoint(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res.isValid()) context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 context.maximumSurfaceElevationDelta = 3 context.maximumSurfaceDistanceDelta = 1 res = r.snapPoint(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res.isValid()) context.maximumPointDistanceDelta = 1 context.maximumPointElevationDelta = 1 context.maximumSurfaceElevationDelta = 0 context.maximumSurfaceDistanceDelta = 0 res = r.snapPoint(QgsProfilePoint(0.27, 2335), context) self.assertTrue(res.isValid()) self.assertAlmostEqual(res.snappedPoint.distance(), 0.2783, 2) self.assertAlmostEqual(res.snappedPoint.elevation(), 2335.04575, 2)
def testLineGenerationAbsolute(self): vl = QgsVectorLayer('LineStringZ?crs=EPSG:27700', 'lines', 'memory') self.assertTrue(vl.isValid()) for line in ['LineStringZ(322006 129874 12, 322008 129910 13, 322038 129909 14, 322037 129868 15)', 'LineStringZ(322068 129900 16, 322128 129813 17)', 'LineStringZ(321996 129914 11, 321990 129896 15)', 'LineStringZ(321595 130176 1, 321507 130104 10)', 'LineStringZ(321558 129930 1, 321568 130029 10, 321516 130049 5)', 'LineStringZ(321603 129967 3, 321725 130042 9)']: f = QgsFeature() f.setGeometry(QgsGeometry.fromWkt(line)) self.assertTrue(vl.dataProvider().addFeature(f)) vl.elevationProperties().setClamping(Qgis.AltitudeClamping.Absolute) vl.elevationProperties().setZScale(2.5) vl.elevationProperties().setZOffset(10) curve = QgsLineString() curve.fromWkt( 'LineString (-347692.88994020794052631 6632796.97473032586276531, -346576.99897185183363035 6632367.38372825458645821, -346396.02439485350623727 6632344.35087973903864622, -346374.34608158958144486 6632220.09952207934111357)') req = QgsProfileRequest(curve) req.setTransformContext(self.create_transform_context()) generator = vl.createProfileGenerator(req) self.assertIsNotNone(generator) # the request did not have the crs of the linestring set, so the whole linestring falls outside the vector extent self.assertFalse(generator.generateProfile()) # set correct crs for linestring and re-try req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) generator = vl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() self.assertEqual(self.round_dict(results.distanceToHeightMap(), 1), {675.2: 27.7, 1195.7: 47.5, 1223.1: 41.4, 1272.0: 46.2, 1339.4: 50.5, 1444.4: 51.8}) self.assertAlmostEqual(results.zRange().lower(), 27.7064, 2) self.assertAlmostEqual(results.zRange().upper(), 51.7598, 2)
def testProfileGeneration(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) # zero tolerance => no points generator = pcl.createProfileGenerator(req) self.assertTrue(generator.generateProfile()) results = generator.takeResults() self.assertFalse(results.distanceToHeightMap()) req.setTolerance(0.05) generator = pcl.createProfileGenerator(req) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 1), { 0.0: 2325.2, 0.2: 2332.6, 0.3: 2325.1, 0.6: 2331.4, 0.7: 2330.5, 0.9: 2332.7, 1.0: 2325.3, 1.1: 2325.6 }) print([g.asWkt(1) for g in results.asGeometries()]) self.assertCountEqual([g.asWkt(1) for g in results.asGeometries()], [ 'PointZ (515389.1 4918366.7 2326.1)', 'PointZ (515389.1 4918366.6 2325.6)', 'PointZ (515389 4918366.6 2325.3)', 'PointZ (515388.2 4918366.6 2325.2)', 'PointZ (515388.3 4918366.7 2325.1)', 'PointZ (515387.9 4918366.7 2325.2)', 'PointZ (515388.7 4918366.6 2330.5)', 'PointZ (515388.6 4918366.6 2331.2)', 'PointZ (515388.9 4918366.6 2332.7)', 'PointZ (515388.9 4918366.7 2332.7)', 'PointZ (515388.6 4918366.6 2331.4)', 'PointZ (515388.2 4918366.7 2332.2)', 'PointZ (515388.2 4918366.7 2332.6)', 'PointZ (515388.2 4918366.6 2335)', 'PointZ (515388.6 4918366.6 2334.6)' ]) self.assertAlmostEqual(results.zRange().lower(), 2325.1325, 2) self.assertAlmostEqual(results.zRange().upper(), 2335.04575, 2) # ensure maximum error is considered context.setMapUnitsPerDistancePixel(0.0001) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 2), { 0.0: 2325.17, 0.01: 2325.14, 0.02: 2325.18, 0.03: 2325.14, 0.08: 2325.16, 0.11: 2325.16, 0.12: 2325.14, 0.14: 2325.16, 0.15: 2325.14, 0.18: 2325.15, 0.19: 2325.15, 0.21: 2332.45, 0.22: 2332.68, 0.23: 2332.44, 0.24: 2332.38, 0.25: 2332.37, 0.26: 2325.16, 0.27: 2332.27, 0.28: 2335.05, 0.29: 2335.08, 0.3: 2334.71, 0.31: 2325.13, 0.32: 2325.14, 0.33: 2325.14, 0.34: 2325.13, 0.36: 2325.14, 0.39: 2325.14, 0.41: 2325.13, 0.42: 2325.14, 0.44: 2325.14, 0.46: 2325.14, 0.49: 2325.14, 0.53: 2325.14, 0.56: 2325.16, 0.57: 2325.16, 0.61: 2325.17, 0.62: 2331.38, 0.63: 2330.44, 0.64: 2331.31, 0.65: 2331.41, 0.66: 2331.33, 0.67: 2331.13, 0.68: 2331.14, 0.69: 2331.01, 0.7: 2331.0, 0.71: 2330.52, 0.72: 2330.61, 0.92: 2332.72, 1.0: 2325.29, 1.01: 2325.25, 1.02: 2325.27, 1.03: 2325.39, 1.04: 2325.36, 1.05: 2325.24, 1.07: 2325.41, 1.08: 2325.38, 1.09: 2325.23, 1.1: 2325.21, 1.11: 2325.3, 1.12: 2325.28, 1.13: 2325.24, 1.15: 2326.11, 1.16: 2325.22, 1.17: 2325.82, 1.18: 2325.49, 1.19: 2325.55, 1.2: 2325.58, 1.21: 2325.62 }) # ensure distance/elevation ranges are respected context.setDistanceRange(QgsDoubleRange(0.3, 0.7)) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 2), { 0.3: 2334.71, 0.31: 2325.13, 0.32: 2325.14, 0.33: 2325.14, 0.34: 2325.13, 0.36: 2325.14, 0.39: 2325.14, 0.41: 2325.13, 0.42: 2325.14, 0.44: 2325.14, 0.46: 2325.14, 0.49: 2325.14, 0.53: 2325.14, 0.56: 2325.16, 0.57: 2325.16, 0.61: 2325.17, 0.62: 2331.38, 0.63: 2330.44, 0.64: 2331.31, 0.65: 2331.41, 0.66: 2331.33, 0.67: 2331.13, 0.68: 2331.14, 0.69: 2331.01, 0.7: 2330.97 }) context.setElevationRange(QgsDoubleRange(2325, 2326)) self.assertTrue(generator.generateProfile(context)) results = generator.takeResults() self.assertEqual( self.round_dict(results.distanceToHeightMap(), 2), { 0.31: 2325.13, 0.32: 2325.14, 0.33: 2325.14, 0.34: 2325.13, 0.36: 2325.14, 0.39: 2325.14, 0.41: 2325.13, 0.42: 2325.14, 0.44: 2325.14, 0.46: 2325.14, 0.49: 2325.14, 0.53: 2325.14, 0.56: 2325.16, 0.57: 2325.16, 0.61: 2325.17, 0.64: 2325.18, 0.68: 2325.19 })
def testIdentify(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) generator = pcl.createProfileGenerator(req) generator.generateProfile(context) r = generator.takeResults() # try identifying some points context = QgsProfileIdentifyContext() context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res) context.maximumPointDistanceDelta = 1 context.maximumPointElevationDelta = 1 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 199, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.60825, 'Y': 4918366.628, 'Z': 2334.60175 }]) context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsDoubleRange(0.2, 0.3), QgsDoubleRange(2330, 2360), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertCountEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 565, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.21275, 'Y': 4918366.65675, 'Z': 2332.19075 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1357, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17375, 'Y': 4918366.679, 'Z': 2332.56025 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }])
def testEquality(self): """ Test equality operator """ req = QgsProfileRequest(None) req2 = QgsProfileRequest(None) self.assertEqual(req, req2) req.setProfileCurve(QgsLineString([[1, 2], [3, 4]])) self.assertNotEqual(req, req2) req2.setProfileCurve(QgsLineString([[1, 2], [3, 5]])) self.assertNotEqual(req, req2) req.setProfileCurve(None) self.assertNotEqual(req, req2) req.setProfileCurve(QgsLineString([[1, 2], [3, 5]])) self.assertEqual(req, req2) req.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertNotEqual(req, req2) req2.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(req, req2) proj_string = '+proj=pipeline +step +inv +proj=lcc +lat_0=-37 +lon_0=145 +lat_1=-36 +lat_2=-38 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' transform_context = QgsCoordinateTransformContext() transform_context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), proj_string) req.setTransformContext(transform_context) self.assertNotEqual(req, req2) req2.setTransformContext(transform_context) self.assertEqual(req, req2) req.setTolerance(5) self.assertNotEqual(req, req2) req2.setTolerance(5) self.assertEqual(req, req2) req.setStepDistance(15) self.assertNotEqual(req, req2) req2.setStepDistance(15) self.assertEqual(req, req2) terrain = QgsFlatTerrainProvider() terrain.setOffset(5) req.setTerrainProvider(terrain) self.assertNotEqual(req, req2) req2.setTerrainProvider(QgsMeshTerrainProvider()) self.assertNotEqual(req, req2) req.setTerrainProvider(None) self.assertNotEqual(req, req2) req.setTerrainProvider(QgsFlatTerrainProvider()) self.assertNotEqual(req, req2) req.setTerrainProvider(QgsMeshTerrainProvider()) self.assertEqual(req, req2)
def testIdentify(self): pcl = QgsPointCloudLayer( os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'lone-star-laszip', 'ept.json'), 'test', 'ept') self.assertTrue(pcl.isValid()) pcl.elevationProperties().setMaximumScreenError(30) pcl.elevationProperties().setMaximumScreenErrorUnit( QgsUnitTypes.RenderMillimeters) curve = QgsLineString() curve.fromWkt( 'LineString (515387.94696552358800545 4918366.65919817332178354, 515389.15378401038469747 4918366.63842081092298031)' ) req = QgsProfileRequest(curve) req.setCrs(pcl.crs()) req.setTolerance(0.05) context = QgsProfileGenerationContext() context.setMapUnitsPerDistancePixel(0.50) generator = pcl.createProfileGenerator(req) generator.generateProfile(context) r = generator.takeResults() # try identifying some points context = QgsProfileIdentifyContext() context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertFalse(res) context.maximumPointDistanceDelta = 1 context.maximumPointElevationDelta = 1 res = r.identify(QgsProfilePoint(0.27, 2335), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertCountEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 199, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.60825, 'Y': 4918366.628, 'Z': 2334.60175 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1678, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.27575, 'Y': 4918366.6325, 'Z': 2334.728 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1605, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.25025, 'Y': 4918366.62825, 'Z': 2334.7095 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1633, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.28575, 'Y': 4918366.66725, 'Z': 2334.7065 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1547, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.238, 'Y': 4918366.6555, 'Z': 2335.0755 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1603, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.26675, 'Y': 4918366.685, 'Z': 2334.69125 }]) context.maximumPointDistanceDelta = 0 context.maximumPointElevationDelta = 0 res = r.identify(QgsDoubleRange(0.2, 0.3), QgsDoubleRange(2330, 2360), context) self.assertEqual(len(res), 1) self.assertEqual(res[0].layer(), pcl) self.assertCountEqual(res[0].results(), [{ 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 565, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.21275, 'Y': 4918366.65675, 'Z': 2332.19075 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1357, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17375, 'Y': 4918366.679, 'Z': 2332.56025 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1612, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2245, 'Y': 4918366.61, 'Z': 2335.04575 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1452, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1985, 'Y': 4918366.61025, 'Z': 2332.38325 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 501, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2145, 'Y': 4918366.66275, 'Z': 2332.16675 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1197, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.22125, 'Y': 4918366.68675, 'Z': 2332.2715 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 202, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.16825, 'Y': 4918366.6625, 'Z': 2332.73325 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 922, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.165, 'Y': 4918366.65025, 'Z': 2332.6565 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 955, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1715, 'Y': 4918366.673, 'Z': 2332.6835 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1195, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1785, 'Y': 4918366.6955, 'Z': 2332.6125 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1432, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.15825, 'Y': 4918366.62575, 'Z': 2332.501 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1413, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1615, 'Y': 4918366.63675, 'Z': 2332.453 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1547, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.238, 'Y': 4918366.6555, 'Z': 2335.0755 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1259, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.20925, 'Y': 4918366.646, 'Z': 2332.29025 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1369, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1895, 'Y': 4918366.662, 'Z': 2332.38325 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1394, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.2015, 'Y': 4918366.703, 'Z': 2332.36625 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 688, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.166, 'Y': 4918366.654, 'Z': 2332.7065 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1399, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17225, 'Y': 4918366.60575, 'Z': 2332.57475 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1024, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.17475, 'Y': 4918366.683, 'Z': 2332.636 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1274, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1585, 'Y': 4918366.62625, 'Z': 2332.5265 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1443, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.15875, 'Y': 4918366.62725, 'Z': 2332.4765 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1332, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.18, 'Y': 4918366.69875, 'Z': 2332.43775 }, { 'Classification': 0, 'EdgeOfFlightLine': 0, 'GpsTime': 0.0, 'Intensity': 1295, 'NumberOfReturns': 1, 'OriginId': 3, 'PointSourceId': 0, 'ReturnNumber': 1, 'ScanAngleRank': 0.0, 'ScanDirectionFlag': 1, 'UserData': 0, 'X': 515388.1725, 'Y': 4918366.67475, 'Z': 2332.5855 }])