├── README.md ├── .gitignore ├── Where to find the variables of QgsPolygon and QgsPolyline?.md ├── How can I always run an algorithm with standard input shapefiles from mapcanvas in QGIS 2.0.1?.md ├── How to write an equivalent to MapBasic's CreateLine in pyQGIS?.md ├── How would one get the end points of a polyline?.md ├── How can I create a vector layer in PyQGIS from a table without geom column?.md ├── Is there a way to get at C's OGRLayer.Intersection() or OGRLayer.Clip() in Python?.md ├── How to perform a cascaded combine from python script in QGIS?.md ├── Is there any way to extract coordinates of a road segment using QGIS?.md ├── Get vector features inside a specific extent.md ├── How to identify qgsvectorlayer area?.md ├── How to find the middle point of a line in QGIS.md ├── How to create points based on the distance and bearing from a survey point.md ├── Using the API of QSpatiaLite plugin.md ├── Create a pie shaped object in shapely and export to gis polygon object.md ├── Serialize python list containing geometry.md ├── How to call processing toolbox in Qgis' python console.md ├── Why provider.nextFeature(feat) does not iterate over all layer features?.md ├── Why is SQLite python command not working?.md ├── Extract coordinates from vector layer in PyQgis.md ├── Get the vertices on a LineString either side of a Point.md ├── Shapely unable to tell if polygon contains point.md ├── How to draw perpendicular lines in QGIS?.md ├── Better way to duplicate a layer using ogr in python?.md ├── Is there are QGIS plugin to allow the 3d visualisation of geological borehole data similar to the functionality of Target for ArcGIS?.md ├── How can I create a line with three points with Python in QGIS?.md ├── How to terminate Python scripts in Processing framework properly?.md ├── Extract a record by name in pyshp?.md ├── TIN Interpolation using a vector layer.md ├── Problem with converting rasters to arrays and adding them to main array, then converting to raster via NumPyArrayToRaster : output is NoData values.md ├── Programmatically manipulate GPX data.md ├── PyQGIS 2.0 API problem reading attributes.md ├── Updating Attributes using Pyshp.md ├── What is the unit the shapely length attribute?.md ├── How to add a column in QGIS via python.md ├── How to programmatically convert arbitrary XML data to shapefile?.md ├── Standalone applications using QGIS and environment variables.md ├── Is it possible to open rasters as array in NumPy without using another library?.md ├── OGR: retrieved feature is NoneType.md ├── Is it possible to route shapefiles using python and without ArcGIS, QGIS, or Pgrouting?.md ├── OGR Layer Intersection.md ├── How to add Direction and Distance to attribute table?.md ├── Python-GDAL └── OGR:retrieved feature is NoneType.md ├── How to find the polygons bordering a feature programmatically with qgis?.md ├── Save input in plugin as pdf format file.md ├── Display a georeferenced DEM surface in 3D matplotlib.md ├── How to create equidistant points in QGIS along a polygon?.md ├── Creating Shapely MultiPolygons from shape file MultiPolygons.md ├── How to get field names in pyqgis 2.0.md ├── Fiona - Preffered method for defining a schema.md ├── Using the python shape library: pyshp - how to convert polygons in .csv file to .shp.md ├── How to create a 3D shapefile from a raster?.md ├── Efficient algorithms to split and join lines?.md ├── OGR Projection transformation error.md ├── How to count the number of lines connected to a point?.md ├── How to script map production in GRASS?.md ├── Using Python to parse an XML containing GML tags.md ├── Shapely MultiPolygon Construction - Will not accept the entire set of Polygons.md ├── Visualize shapefile in Python.md ├── Shapely-Finding differences between two shapefiles.md ├── How to create points in a specified distance along the line in QGIS.md ├── Geoprocessing across multiple vector layers QGIS2.md ├── Convert points to lines with Python GDAL.md ├── Find Nearest Line Segments to Point.md ├── How to use a field-to-RGB mapping for symbology in QGIS?.md ├── Is there Python library (other than ArcPy) for geoprocessing such as buffer?.md ├── Python Script for getting elevation difference between two points.md ├── How to access vector coordinates in GRASS GIS from python?.md ├── QGIS - How to store attributes of a large shapefile in a list?.md ├── How to install Fiona to read Shapefile attributes with OSGeo4W?.md ├── How do I find vector line bearing in QGIS or GRASS?.md ├── How to calculate distances in a point sequence?.md └── Python Script examples for geoprocessing shapefiles without using arcpy.md /README.md: -------------------------------------------------------------------------------- 1 | ###Mes réponses sur GIS_StacExchange - Mis respuestas en GIS_StacExchange - My GIS_StacExchange answers 2 | 3 | 4 | 5 | - Pour avoir une synthèse personnelle de toutes mes solutions en Python fournies sur GIS_StacExchange 6 | 7 | - Para tener una síntesis personal de todas mis soluciones en Python en GIS_StacExchange 8 | 9 | - To have a personal synthesis of all my Python solutions provided on GIS_StacExchange 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | __pycache__ 21 | 22 | # Installer logs 23 | pip-log.txt 24 | 25 | # Unit test / coverage reports 26 | .coverage 27 | .tox 28 | nosetests.xml 29 | 30 | # Translations 31 | *.mo 32 | 33 | # Mr Developer 34 | .mr.developer.cfg 35 | .project 36 | .pydevproject 37 | -------------------------------------------------------------------------------- /Where to find the variables of QgsPolygon and QgsPolyline?.md: -------------------------------------------------------------------------------- 1 | From [Where to find the variables of QgsPolygon and QgsPolyline?](http://gis.stackexchange.com/questions/64247/where-to-find-the-variables-of-qgspolygon-and-qgspolyline) 2 | 3 | 4 | see [Geometry Handling][1] 5 | 6 | 1. a point: QgsPoint(x,y) 7 | 2. a line: QgsGeometry.fromPolyline([QgsPoint(x1,y1),QgsPoint(x2,y2)])) 8 | 3. a polygon: QgsGeometry.fromPolygon([[**QgsPoint(x1,y1)**,QgsPoint(x2,y2), QgsPoint(x3,y3),**QgsPoint(x1,y1)**]]) -> the polygon must be closed. 9 | 10 | thus: 11 | 12 | ```python 13 | line_start= QgsPoint(50,50) 14 | line_end= QgsPoint(100,100) 15 | line = QgsGeometry.fromPolyline([line_start, line_end]) 16 | points = [QgsPoint(60,60),QgsPoint(60,80),QgsPoint(80,80),QgsPoint(80,60),QgsPoint(60,60)] 17 | polygon= QgsGeometry.fromPolygon([points]) 18 | ``` 19 | 20 | and: 21 | 22 | ```python 23 | 24 | feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 25 | feature.setGeometry(QgsGeometry.fromPolygon([points])) 26 | ``` 27 | 28 | 29 | [1]: http://www.qgis.org/pyqgis-cookbook/geometry.html 30 | -------------------------------------------------------------------------------- /How can I always run an algorithm with standard input shapefiles from mapcanvas in QGIS 2.0.1?.md: -------------------------------------------------------------------------------- 1 | From [How can I always run an algorithm with standard input shapefiles from mapcanvas in QGIS 2.0.1?](http://gis.stackexchange.com/questions/78758/how-can-i-always-run-an-algorithm-with-standard-input-shapefiles-from-mapcanvas/) 2 | 3 | 4 | Change you script in: 5 | 6 | 7 | ```python 8 | 9 | 10 | ##difference_between_pst/astenot=name 11 | ##output_alg0=output vector 12 | ##output_alg1=output vector 13 | ##output_layer_alg2=output vector 14 | ##output_layer_alg3=output vector 15 | vectorlayer_1 = "pst" 16 | vectorlayer_2 = "astenot" 17 | outputs_0=Processing.runalg("qgis:difference", vectorlayer_1, vectorlayer_2, output_alg0) 18 | outputs_1=Processing.runalg("qgis:difference", vectorlayer_2, vectorlayer_1, output_alg1) 19 | outputs_2=Processing.runalg("qgis:saveselectedfeatures", outputs_0['OUTPUT'], output_layer_alg2) 20 | outputs_3=Processing.runalg("qgis:saveselectedfeatures", outputs_1['OUTPUT'], output_layer_alg3) 21 | 22 | ``` 23 | 24 | ![enter image description here][1] 25 | 26 | 27 | 28 | 29 | [1]: http://i.stack.imgur.com/qGvWi.jpg 30 | -------------------------------------------------------------------------------- /How to write an equivalent to MapBasic's CreateLine in pyQGIS?.md: -------------------------------------------------------------------------------- 1 | 2 | From [How to write an equivalent to MapBasic's CreateLine in pyQGIS](http://gis.stackexchange.com/questions/56932/how-to-write-an-equivalent-to-mapbasics-createline-in-pyqgis) 3 | 4 | You can even use the original coordinates of the point shapefile 5 | 6 | ```python 7 | 8 | 9 | # iterator, iterate over pairs of points in a list, a layer 10 | `def pair_points(iterable): 11 | iterator = iter(iterable) 12 | prev = None 13 | item = iterator.next() 14 | for next in iterator: 15 | yield (item,next) 16 | prev = item 17 | item = next 18 | 19 | `# using the iterator 20 | `for pt1,pt2 in pair_points(layer.getFeatures()): 21 | ptA = pt1.geometry().asPoint() 22 | ptB = pt2.geometry().asPoint() 23 | print ptA, ptB, 24 | ..... 25 | line = QgsGeometry.fromPolyline([QgsPoint(ptA), QgsPoint(ptB)]) 26 | print line.asPolyline() 27 | ..... 28 | ``` 29 | Example with one of my points layers 30 | ```python 31 | 32 | (271927,155249) (272361,153856) line: [(271927,155249), (272361,153856)] 33 | (272361,153856) (272689,152802) line: [(272361,153856), (272689,152802)] 34 | .... 35 | ``` 36 | 37 | 38 | -------------------------------------------------------------------------------- /How would one get the end points of a polyline?.md: -------------------------------------------------------------------------------- 1 | From [how would one get the end points of a polyline?](http://gis.stackexchange.com/questions/86040/how-would-one-get-the-end-points-of-a-polyline) 2 | 3 | It is easier with [Fiona][1], more "Pythonic", and list slicing: 4 | 5 | ```python 6 | import fiona 7 | with fiona.drivers(): 8 | for line in fiona.open("some_shapefile.shp"): 9 | # print first and last point of every line 10 | print line['geometry']['coordinates'][0], line['geometry']['coordinates'][-1] 11 | ``` 12 | 13 | And with [shapely][2]: 14 | 15 | ```python 16 | 17 | from shapely.geometry import Point 18 | for line in fiona.open("some_shapefile.shp"): 19 | print Point(line['geometry']['coordinates'][0]), Point(line['geometry']['coordinates'][-1]) 20 | ``` 21 | 22 | And you can construct you polygon and save it with Fiona 23 | 24 | 25 | New: using the suggestion of sgillies (boundary) with the shape function of shapely 26 | 27 | ```python 28 | 29 | from shapely.geometry import shape 30 | for line in fiona.open("some_shapefile.shp"): 31 | print shape(line['geometry']).boundary[0], shape(line['geometry']).boundary[1] 32 | 33 | ``` 34 | 35 | 36 | [1]: http://toblerity.org/fiona/manual.html 37 | [2]: http://toblerity.org/shapely/manual.html 38 | -------------------------------------------------------------------------------- /How can I create a vector layer in PyQGIS from a table without geom column?.md: -------------------------------------------------------------------------------- 1 | From [How can I create a vector layer in PyQGIS from a table without geom column?](http://gis.stackexchange.com/questions/70962/how-can-i-create-a-vector-layer-in-pyqgis-from-a-table-without-geom-column) 2 | 3 | Nothing 4 | 5 | With a SQLite layer (not spatial) 6 | 7 | ```python 8 | 9 | uri = QgsDataSourceURI() 10 | uri.setDatabase('Midv_31370.sqlite') 11 | uri.setDataSource('', 'obs_points','','','obsid') 12 | vlayer = QgsVectorLayer(uri.uri(), 'TestLayer2', 'spatialite') 13 | QgsMapLayerRegistry.instance().addMapLayer(vlayer) 14 | vlayer.isValid() 15 | True 16 | ``` 17 | 18 | ![enter image description here][1] 19 | 20 | If you want a spatial layer (Spatialite), you must indicate the geometry column: 21 | 22 | ```python 23 | 24 | uri = QgsDataSourceURI() 25 | uri.setDatabase('Midv_31370.sqlite') 26 | uri.setDataSource('', 'obs_points', 'geometry') 27 | vlayer = QgsVectorLayer(uri.uri(), 'TestLayer2', 'spatialite') 28 | QgsMapLayerRegistry.instance().addMapLayer(vlayer) 29 | vlayer.isValid() 30 | True 31 | ``` 32 | 33 | ![enter image description here][3] 34 | 35 | 36 | [1]: http://i.stack.imgur.com/8TzYE.jpg 37 | [2]: http://i.stack.imgur.com/USt5h.jpg 38 | [3]: http://i.stack.imgur.com/PY6GM.jpg 39 | -------------------------------------------------------------------------------- /Is there a way to get at C's OGRLayer.Intersection() or OGRLayer.Clip() in Python?.md: -------------------------------------------------------------------------------- 1 | from [Is there a way to get at C's OGRLayer.Intersection() or OGRLayer.Clip() in Python?](http://gis.stackexchange.com/questions/33370/is-there-a-way-to-get-at-cs-ogrlayer-intersection-or-ogrlayer-clip-in-pytho/33428) 2 | 3 | A layer is composed of one or several geometries. For the intersection of layers, you must iterate through each layer geometries. With shapely it is easy, example with two shapefiles: 4 | 5 | ```python 6 | from osgeo import ogr 7 | from shapely.wkb import loads 8 | from shapely.geometry import * 9 | # first layer, a polygon shapefile 10 | first = Polygon() 11 | # open shapefile 12 | source1 = ogr.Open("test1.shp") 13 | layer1 = source1.GetLayer() 14 | # combination of all the geometries of the layer in a single shapely object 15 | for element in layer1: 16 | geom = loads(element.GetGeometryRef().ExportToWkb()) 17 | first = first.union(geom) 18 | # second layer, a polygon shapefile 19 | two = Polygon() 20 | source2 = ogr.Open("test2.shp") 21 | layer2 = source2.GetLayer() 22 | for element in layer2: 23 | geom = loads(element.GetGeometryRef().ExportToWkb()) 24 | two = two.union(geom) 25 | 26 | # intersection between the two layers 27 | print first.intersection(two).wkt 28 | ``` 29 | 30 | It is possible to use the same type of treatment for Clip(). Another solution is provided by [Creating a little clipbox for your GIS projects in Python][1] 31 | 32 | 33 | [1]: http://blog.technokrat.nl/?p=369 34 | -------------------------------------------------------------------------------- /How to perform a cascaded combine from python script in QGIS?.md: -------------------------------------------------------------------------------- 1 | From [How to perform a cascaded combine from python script in QGIS?](http://gis.stackexchange.com/questions/63921/how-to-perform-a-cascaded-combine-from-python-script-in-qgis) 2 | 3 | [Shapely][1] is one of the Geos Python bindings and has [cascaded_union][2] and [unary_union][3] implemented since versions 2.16 (GEOSCascadedUnion is deprecated since GEOS version 3.2.+ and GEOSUnaryUnion must be used instead: it can operate on different geometry types, not only polygons as is the case for the older cascaded unions). 4 | 5 | Convert QGIS geometries to Shapely geometries in the Python console is very easy: 6 | 7 | ```python 8 | from shapely.wkb import loads 9 | from shapely.ops import cascaded_union, unary_union 10 | # transform QGIS geometries to a list of shapely geometries 11 | geoms =[loads(feature.geometry().asWkb()) for feature in layer] 12 | # cascaded union 13 | cu= cascaded_union(geoms) 14 | cu 15 | 16 | # unary union 17 | un = unary_union(geoms) 18 | un 19 | 20 | # convert to Qgis geometry 21 | geom = QgsGeometry.fromWkt(un.wkt) 22 | geom 23 | 24 | ``` 25 | 26 | You can even do it without QGIS with modules like [Fiona][4] to read and write a Shapefile layer. 27 | 28 | 29 | [1]: https://pypi.python.org/pypi/Shapely 30 | [2]: http://toblerity.github.io/shapely/manual.html#shapely.ops.cascaded_union 31 | [3]: http://toblerity.github.io/shapely/manual.html#shapely.ops.unary_union 32 | [4]: https://pypi.python.org/pypi/Fiona 33 | -------------------------------------------------------------------------------- /Is there any way to extract coordinates of a road segment using QGIS?.md: -------------------------------------------------------------------------------- 1 | From [Is there any way to extract coordinates of a road segment using QGIS?](http://gis.stackexchange.com/questions/28092/is-there-any-way-to-extract-coordinates-of-a-road-segment-using-qgis) 2 | 3 | In fact, it is very easy in the Python console 4 | 5 | ```python 6 | 7 | def select_all(layer): 8 | layer.select([]) 9 | layer.setSelectedFeatures([obj.id() for obj in couche]) 10 | 11 | # selection of the active layer 12 | mylayer = qgis.utils.iface.activeLayer() 13 | 14 | # selection of all the elements (geometry + attributes) of active layer 15 | select_all(mylayer) 16 | 17 | # coordinates of the vertices/nodes of every feature of a polyline 18 | for i, feature in enumerate(mylayer.selectedFeatures()): 19 | geom= feature.geometry() 20 | xy=geom.asPolyline() 21 | print "i, xy 22 | 23 | 0 [(206643,125181), (201007,121518), (208616,118700), (199035,115037), (200726,111937), (192835,107428), (192835,107428)] 24 | 1 [(196157,123493), (193933,121483), (198411,119320), (195456,117523), (198137,117614)] 25 | 26 | # extraction in wkt format 27 | for i, feature in enumerate(mylayer.selectedFeatures()): 28 | geom= feature.geometry() 29 | wkt = geom.exportToWkt() 30 | print i, wkt 31 | 32 | 0 LINESTRING(206643.215176 125181.180586, 201007.334329 121517.855521, 208615.775876 118699.916872, 199034.777658 115036.590588, 200725.543215 111936.856010, 192835.309877 107428.147942, 192835.309877 107428.147942) 33 | 1 LINESTRING(196156.747710 123492.901991, 193933.267396 121482.632118, 198410.686659 119320.069073, 195456.199118 117523.009641, 198136.558949 117614.385545) 34 | ``` 35 | -------------------------------------------------------------------------------- /Get vector features inside a specific extent.md: -------------------------------------------------------------------------------- 1 | From [Get vector features inside a specific extent](http://gis.stackexchange.com/questions/57964/get-vector-features-inside-a-specific-extent) 2 | 3 | 4 | You don't need a SQL-query to do that, only Python with, once again, the modules [Fiona][1] and [Shapely][2] of Sean Gillies. 5 | 6 | I want only the records which are within the blue frame (analogy of a raster layer). 7 | 8 | ![enter image description here][3] 9 | 10 | See [the Fiona user Manual][4], the filter() method returns an iterator over records that intersect a given (minx, miny, maxx, maxy) bounding box: 11 | 12 | ```python 13 | from shapely.geometry import mapping, shape 14 | import fiona 15 | # Read the original Shapefile 16 | input = fiona.open('data.shp', 'r') 17 | # bounds of the original shapefile 18 | input.bounds 19 | (258018.9133083854, 158162.863836, 268763.670357, 162621.686305) 20 | # clip the shapefile with the raster bounds 21 | clipped = input.filter(bbox=((262236.3101588468, 159973.80344954136, 263491.7250217228, 160827.485556297))) 22 | # create the clipped shapefile with the same schema 23 | clipped_schema = input.schema.copy() 24 | with fiona.collection('clipped.shp', 'w', 'ESRI Shapefile', clipped_schema) as output: 25 | for elem in clipped: 26 | output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))}) 27 | ``` 28 | Result: 29 | 30 | ![enter image description here][5] 31 | 32 | 33 | 34 | 35 | [1]: https://pypi.python.org/pypi/Fiona/0.10 36 | [2]: https://pypi.python.org/pypi/Shapely/1.2.17 37 | [3]: http://i.stack.imgur.com/aXP4g.jpg 38 | [4]: http://toblerity.github.io/fiona/manual.html#filtering 39 | [5]: http://i.stack.imgur.com/Ej95G.jpg 40 | -------------------------------------------------------------------------------- /How to identify qgsvectorlayer area?.md: -------------------------------------------------------------------------------- 1 | From [how to identify qgsvectorlayer area?](http://gis.stackexchange.com/questions/76193/how-to-identify-qgsvectorlayer-area) 2 | 3 | A Polygon vectorlayer is composed of many features (geometries), each with an area. 4 | 5 | If the geometries don't overlap, you can iterate over the vector layer and sum the areas: 6 | 7 | ```python 8 | layer = iface.activeLayer() 9 | areatot = 0 10 | for elem in layer.getFeatures() 11 | geom = elem.geometry() 12 | areatot += geom.area() 13 | ``` 14 | or in one line: 15 | ```python 16 | aeratot = [sum(elem.geometry().area() for elem in layer.getFeatures())] 17 | ``` 18 | But if some geometries overlap, this result is wrong: 19 | 20 | ![enter image description here][1] 21 | 22 | You can then Union all the geometries and use the area of the resulting geometry: 23 | 24 | ![enter image description here][2] 25 | 26 | ```python 27 | # creation of a empty geometry for unioning 28 | geomtot = QgsGeometry.fromWkt('GEOMETRYCOLLECTION EMPTY') 29 | # union 30 | for elem in layer.getFeatures(): 31 | geomtot = geomtot.combine(elem.geometry()) 32 | area = geomtot.area() 33 | ``` 34 | For QGIS 1.8: 35 | ---- 36 | 37 | ```python 38 | layer = qgis.utils.iface.activeLayer() 39 | areatot = 0 40 | layer.select() 41 | for elem in layer: 42 | geom = elem.geometry() 43 | areatot += geom.area() 44 | ``` 45 | and: 46 | 47 | ```python 48 | geomtot = QgsGeometry.fromWkt('GEOMETRYCOLLECTION EMPTY') 49 | layer.select() 50 | for elem in layer: 51 | geomtot = geomtot.combine(elem.geometry()) 52 | area = geomtot.area() 53 | ``` 54 | 55 | 56 | [1]: http://i.stack.imgur.com/bEPLc.jpg 57 | [2]: http://i.stack.imgur.com/evMPJ.jpg 58 | -------------------------------------------------------------------------------- /How to find the middle point of a line in QGIS.md: -------------------------------------------------------------------------------- 1 | from [How to find the middle point of a line in QGIS](http://gis.stackexchange.com/questions/58079/how-to-find-the-middle-point-of-a-line-in-qgis) 2 | 3 | 4 | It is a pure geometry problem that can be solved in the Python console 5 | 6 | The problem: 7 | 8 | ![test][1] 9 | 10 | Find the midpoint of a segment x1,y1,x2,y2 is easy 11 | 12 | 13 | ```python 14 | 15 | x = (x1 + x2)/2 16 | y = (y1 + y2)/2 17 | 18 | ``` 19 | 20 | so in the Python console 21 | 22 | 23 | ```python 24 | 25 | def mid(pt1, pt2): 26 | x = (pt1.x() + pt2.x())/2 27 | y = (pt1.y() + pt2.y())/2 28 | return QgsPoint(x,y) 29 | 30 | def pair(list): 31 | '''Iterate over pairs in a list ''' 32 | for i in range(1, len(list)): 33 | yield list[i-1], list[i] 34 | 35 | def create_geometry(point,pr): 36 | # create geometry record 37 | seg = QgsFeature() 38 | seg.setGeometry(QgsGeometry.fromPoint(point)) 39 | pr.addFeatures( [seg] ) 40 | 41 | # memory layer 42 | pt_layer = QgsVectorLayer("Point", "midpoint", "memory") 43 | pr = pt_layer.dataProvider() 44 | 45 | for elem in mylayer.selectedFeatures(): 46 | line = elem.geometry() 47 | for seg_start, seg_end in pair(line.asPolyline()): 48 | line_start = QgsPoint(seg_start) 49 | line_end = QgsPoint(seg_end) 50 | # midpoint 51 | midpt= mid(line_start, line_end) 52 | # add midpoint point to layer 53 | create_geometry(midpt,pr) 54 | pt_layer.updateExtents() 55 | 56 | QgsMapLayerRegistry.instance().addMapLayers([pt_layer]) 57 | 58 | ``` 59 | 60 | Result 61 | 62 | ![final][2] 63 | 64 | 65 | 66 | 67 | 68 | [1]: http://i.stack.imgur.com/PP1Sr.jpg 69 | [2]: http://i.stack.imgur.com/r1HgU.jpg 70 | -------------------------------------------------------------------------------- /How to create points based on the distance and bearing from a survey point.md: -------------------------------------------------------------------------------- 1 | from [How to create points based on the distance and bearing from a survey point?](http://gis.stackexchange.com/questions/77974/how-to-convert-gml-to-geojson-using-python-and-ogr-with-geometry-transformation/77999) 2 | 3 | 4 | It is pure trigonometry or vector calculus problem and you can get the result using polar coordinates (center of the figure) or the direction cosines (right) with 2D cartesian coordinates : 5 | 6 | ![enter image description here][1] 7 | 8 | #with polar coordinates in Python 9 | 10 | from a point = QgsPoint(-1004.00,635.00), a distance of 160m and a bearing of 103° 11 | 12 | ```python 13 | # bearing in radians 14 | bearing = math.radians(bearing) 15 | dist_x, dist_y = (distance * math.sin(angle),distance * math.cos(angle)) 16 | print dist_x, dist_y 17 | (155.89921036563763, -35.992168695018407) 18 | xfinal, yfinal = (point.x() + dist_x, point.y() + dist_y) 19 | print xfinal, yfinal 20 | (-848.1007896343624, 599.00783130498155) 21 | # resulting point 22 | point_res= QgsPoint(xfinal,yfinal) 23 | ``` 24 | 25 | #with direction cosines in Python 26 | 27 | ```python 28 | # bearing in radians 29 | bearing = math.radians(bearing) 30 | # direction cosines 31 | cosa = math.sin(bearing) 32 | cosb = math.cos(bearing) 33 | xfinal, yfinal = (point.x() +(distance*cosa), point.y()+(distance*cosb)) 34 | print xfinal,yfinal 35 | (-848.1007896343624, 599.00783130498155) 36 | ``` 37 | 38 | Result 39 | 40 | ![enter image description here][2] 41 | 42 | see also [How to create points in a specified distance along the line in QGIS?][3] 43 | 44 | 45 | [1]: http://i.stack.imgur.com/Zo2Do.jpg 46 | [2]: http://i.stack.imgur.com/Nb0jK.jpg 47 | [3]: http://gis.stackexchange.com/questions/63201/how-to-create-points-in-a-specified-distance-along-the-line-in-qgis/63238#63238 48 | -------------------------------------------------------------------------------- /Using the API of QSpatiaLite plugin.md: -------------------------------------------------------------------------------- 1 | from [Using the API of QSpatiaLite plugin] 2 | 3 | If you use Python, you can perfectly use one of the modules that can read shapefiles like ogr, Fiona or Pyshp to extract the geometries and the attributes of a shapefile and insert them into SQLite/SpatiaLite with pyspatialite without QGIS and QSpatiaLite. 4 | 5 | With [pyshp][1] (result = Python lists) 6 | 7 | ```python 8 | 9 | import shapefile 10 | input = shapefile.Reader("joinpolypt.shp") 11 | # fields 12 | input.fields[1:] 13 | [['test', 'N', 1, 0], ['color', 'C', 80, 0]] 14 | # geometries and attributes of the layer 15 | shapes = input.shapes() 16 | attributes = input.records() 17 | # first record 18 | shapes[0].points[0] 19 | [273781.244220372, 154668.35103545961] 20 | attributes[0] 21 | [1, 'red'] 22 | ..... 23 | ``` 24 | 25 | 26 | With [Fiona][2] (result = Python dictionaries): 27 | 28 | ```python 29 | 30 | import fiona 31 | points = fiona.open('testpoint.shp') 32 | # schema of the shapefile 33 | points.schema 34 | {'geometry': 'Point', 'properties': {u'test': 'int', u'color': 'str'}} 35 | # first point 36 | points.next() 37 | {'geometry': {'type': 'Point', 'coordinates': (273781.244220372, 154668.35103545961)}, 'id': '0', 'properties': {'test': 1, 'color': u'red'}} 38 | ... 39 | ``` 40 | 41 | It is similar with ogr. 42 | 43 | In all the cases you get the geometries and the attributes as lists or dictionaries 44 | 45 | Then it is easy to use pyspatialite to incorporate these values ​​in a spatialite database. 46 | 47 | Note that with OGR 1.10, the GDAL/OGR library can be loaded as a SQLite extension (like spatialite) and you can use directly Python and ogr ([SQLite / Spatialite RDBMS][3]) 48 | 49 | 50 | [1]: http://code.google.com/p/pyshp/ 51 | [2]: https://pypi.python.org/pypi/Fiona 52 | [3]: http://www.gdal.org/ogr/drv_sqlite.html 53 | -------------------------------------------------------------------------------- /Create a pie shaped object in shapely and export to gis polygon object.md: -------------------------------------------------------------------------------- 1 | from [create a pie shaped object in shapely and export to gis polygon object](http://gis.stackexchange.com/questions/84412/create-a-pie-shaped-object-in-shapely-and-export-to-gis-polygon-object) 2 | 3 | You should use [Fiona][1] and the `mapping` function of shapely 4 | 5 | 6 | ```Python 7 | from shapely.geometry import mapping 8 | import fiona 9 | # schema of the shapefile (or GeoJSON file, or...) for the lines 10 | schema = {'geometry': 'LineString','properties': {'test': 'int'}} 11 | with fiona.open('lines.shp','w','ESRI Shapefile', schema) as e: 12 | for i in lines: 13 | e.write({'geometry':mapping(i), 'properties':{'test':1}}) 14 | ``` 15 | 16 | Result: 17 | 18 | ![enter image description here][2] 19 | 20 | You can do the same thing with the buffers but you'll never get a ring polygon as result with your solution (only a superposition of polygons) 21 | 22 | You need to use the solution given by [MappaGnosis][3] in [Does shapely within function identify inner holes?][4] 23 | 24 | ```Python 25 | 26 | one = list(buffers[1].exterior.coords) 27 | interior = LinearRing(one) 28 | exterior = LinearRing(list(buffers[2].exterior.coords) 29 | ring = Polygon(exterior,[interior]) 30 | # new schema 31 | schema = {'geometry': 'Polygon','properties': {'test': 'int'}} 32 | # write the shapefile 33 | with fiona.open('ring.shp','w','ESRI Shapefile', schema) as e: 34 | e.write({'geometry':mapping(ring), 'properties':{'test':1}}) 35 | ``` 36 | 37 | Result: 38 | ![enter image description here][5] 39 | 40 | 41 | [1]: http://toblerity.org/fiona/manual.html 42 | [2]: http://i.stack.imgur.com/0HABx.jpg 43 | [3]: http://gis.stackexchange.com/users/5222/mappagnosis 44 | [4]: http://gis.stackexchange.com/questions/72306/does-shapely-within-function-identify-inner-holes 45 | [5]: http://i.stack.imgur.com/nycPm.jpg 46 | -------------------------------------------------------------------------------- /Serialize python list containing geometry.md: -------------------------------------------------------------------------------- 1 | From [Serialize python list containing geometry](http://gis.stackexchange.com/questions/82850/serialize-python-list-containing-geometry) 2 | 3 | Use the `mapping`function of shapely (and the reverse: `shape`): 4 | 5 | ```Python 6 | from shapely geometry import Point, mapping, shape 7 | point = Point(3,4) 8 | print mapping(point) 9 | {'type': 'Point', 'coordinates': (3.0, 4.0)} 10 | # and the reverse 11 | print shape(mapping(point)) 12 | POINT (3.0000000000000000 4.0000000000000000) 13 | ``` 14 | 15 | Test: 16 | 17 | ```Python 18 | result = dict(fields="a", id=2, label="label", geom=mapping(point)) 19 | geojson.dumps(result) 20 | '{"fields": "a", "geom": {"type": "Point", "coordinates": [3.0, 4.0]}, "id": 2, "label": "label"}' 21 | import json 22 | json.dumps(result) 23 | '{"fields": "a", "geom": {"type": "Point", "coordinates": [3.0, 4.0]}, "id": 2, "label": "label"}' 24 | ``` 25 | 26 | So, in your case: 27 | 28 | ```Python 29 | result = [dict(f.fields, id=f.id, label=f.label, geom=mapping(f.geom)) for f in features] 30 | ``` 31 | 32 | Look for examples of the use of [Fiona][1] on Gis StackExchange. This module uses the GeoJSON format to read and write shapefiles and other ogr formats.. 33 | 34 | ```Python 35 | import fiona 36 | # schema of the shapefile 37 | schema = {'geometry': 'Point', 'properties': {'id':'int:2', 'name':'str'}} 38 | # write the shapefile with the shapely point 39 | with fiona.open('point.shp','w','ESRI Shapefile', schema) as w: 40 | w.write({'geometry':mapping(point), 'properties':{'id':1, 'name':'a point'}}) 41 | # open and read the features of the shapefile 42 | features = fiona.open('point.shp') 43 | features.next() 44 | {'geometry': {'type': 'Point', 'coordinates': (3.0, 4.0)}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'id', 1), (u'name', u'a point')])} 45 | 46 | ``` 47 | 48 | 49 | 50 | 51 | 52 | 53 | [1]: http://toblerity.org/fiona/manual.html 54 | -------------------------------------------------------------------------------- /How to call processing toolbox in Qgis' python console.md: -------------------------------------------------------------------------------- 1 | From [How to call processing toolbox in Qgis' python console](http://gis.stackexchange.com/questions/75666/how-to-call-processing-toolbox-in-qgis-python-console) 2 | 3 | 4 | To learn the processing module in Python, the easiest solution for me is: 5 | 6 | 1. execute the Processing command (from the Toolbox), for example v.to.rast.val 7 | 2. examine the "processing_qgis.log" file in the ".qgis2/processing/" folder 8 | 9 | where you can examine all the running algorithms: 10 | 11 | ALGORITHM|Mon Oct 28 2013 12 | 12:30:34|processing.runalg("grass:v.to.rast.value","/Users/Shared/polygon.shp",0,1,"202563.92575,204206.182887,89106.9864984,89783.2100251",0,-1,0.0001,"/Users/Shared/polyraster.tif") 13 | 14 | The actual commands are in: 15 | 16 | - "grass_batch_job.sh" or "grass_batch_job.bat" files (in the ".qgis2/processing/" folder) for GRASS GIS; 17 | - "saga_batch_job.sh" or "saga_batch_job.bat" files for SAGA GIS; 18 | - "processing_script.r" file for R. 19 | 20 | 21 | So, in the Python console: 22 | 23 | ```python 24 | import processing 25 | processing.runalg("grass:v.to.rast.value","/Users/Shared/polygon.shp",0,1,"202563.92575,204206.182887,89106.9864984,89783.2100251",0,-1,0.0001,"/Users/Shared/polyraster.tif") 26 | processing.runalg("grass:r.statistics","/Users/Shared/polyraster.tif","/Users/Shared/mydem.asc",1,True,"202086.577,205625.414407,88411.048,90534.3504441",0,"/Users/Shared/test.tif") 27 | ``` 28 | You can also use one of the displayed layers: 29 | 30 | ```python 31 | vectorlayer = qgis.utils.iface.mapCanvas().currentLayer().source() 32 | processing.runalg("grass:v.to.rast.value",vectorlayer,0,1,"202563.92575,204206.182887,89106.9864984,89783.2100251",0,-1,0.0001,"/Users/Shared/polyraster.tif") 33 | ``` 34 | 35 | but before, you need to understand all the parameters of the command [r.statistics][1] and the problems as [r.statistics limitation to CELL][2] 36 | 37 | 38 | [1]: http://grass.osgeo.org/grass64/manuals/r.statistics.html 39 | [2]: http://osgeo-org.1560.x6.nabble.com/r-statistics-limitation-to-CELL-td4017639.html 40 | -------------------------------------------------------------------------------- /Why provider.nextFeature(feat) does not iterate over all layer features?.md: -------------------------------------------------------------------------------- 1 | 2 | From [Why provider.nextFeature(feat) does not iterate over all layer features?](http://gis.stackexchange.com/questions/72359/why-provider-nextfeaturefeat-does-not-iterate-over-all-layer-features) 3 | 4 | The while loop is not recommended in such cases, use a for loop, it is easier: 5 | 6 | - a layer has n features -> layer.featureCount() 7 | - a feature has an id -> feature.id(), a geometry and attributes 8 | 9 | with QGIS 1.8 10 | -------- 11 | ```Python 12 | layer = qgis.utils.iface.activeLayer() 13 | layer.select() 14 | for feature in layer: 15 | geom = feature.geometry() 16 | attrs = feature.attributeMap() 17 | # the result is a dictionary 18 | for atr in attrs.values(): 19 | print '{0} de {1}: {2}'.format(feature.id(), layer.featureCount(), atr.toString()) 20 | ``` 21 | Result with one of my examples: 22 | 23 | ```Python 24 | 0 de 3: Aachen Formation 25 | 0 de 3: AAC 26 | 0 de 3: COU 27 | 0 de 3: 175 28 | 1 de 3: VAALS Formation 29 | 1 de 3: VAA 30 | 1 de 3: COU 31 | 1 de 3: 185 32 | .... 33 | ``` 34 | 35 | with QGIS 2.0 36 | ----------- 37 | ```Python 38 | layer = qgis.utils.iface.activeLayer() 39 | for feature in layer.getFeatures(): 40 | geom = feature.geometry() 41 | attrs = feature.attributes() 42 | # the result is a list 43 | for elem in attrs: 44 | print '{0} de {1}: {2}'.format(feature.id(), layer.featureCount(), elem) 45 | ``` 46 | 47 | and with a dictionary, you can access the field names: 48 | 49 | ```Python 50 | 51 | fields = layer.pendingFields() 52 | # name of the fields 53 | field_names = [field.name() for field in fields] 54 | for feature in layer.getFeatures(): 55 | atr = dict(zip(field_names, feature.attributes())) 56 | print atr 57 | ``` 58 | Result 59 | 60 | ```Python 61 | 62 | {u'FORM': u'AAC', u'DESCRIPTIO': u"Aachen Formation", u'CLASSE': u'COU',u'SYMBOL': 175.0} 63 | {u'FORM': u'AAC', u'DESCRIPTIO': u"Vaals Formation", u'CLASSE': u'COU', u'SYMBOL': 185.0} 64 | .... 65 | ``` 66 | -------------------------------------------------------------------------------- /Why is SQLite python command not working?.md: -------------------------------------------------------------------------------- 1 | From [Why is SQLite python command not working?](http://gis.stackexchange.com/questions/43590/why-is-sqlite-python-command-not-working) 2 | 3 | First, the name index is reserved by SQLite ( [SQLite: create Index][1] ). 4 | 5 | Then you need to review the string formatting in Python ( see for example [Python String Format][2] ) 6 | 7 | What you want is, in SQL (index is renamed ind): 8 | 9 | 'INSERT INTO bbi_catalog_aug2012 (ind,path,filename) VALUES ("...","...","....");' 10 | 11 | In Python with the older "%" string formatter: 12 | 13 | ```python 14 | statement = "INSERT INTO %s (%s) VALUES (%s,%s,%s);" %(table,columns,1,2,3) 15 | ``` 16 | or with the new string.format() 17 | ```python 18 | statement = "INSERT INTO {0} ({1}) VALUES ({2},{3},{4});".format(table,columns,1,2,3) 19 | ``` 20 | and the result is: 21 | ```python 22 | 'INSERT INTO bbi_catalog_aug2012 (ind,path,filename) VALUES (1,2,3);' 23 | ``` 24 | So your script: 25 | 26 | ```python 27 | conn = sqlite.connect("ngi.sqlite") 28 | with conn: 29 | cur = conn.cursor() 30 | for root, dirnames, filenames in os.walk(basedir): 31 | print 'root is ' + root 32 | for filename in filenames: 33 | ext = os.path.splitext(filename)[1].lower() 34 | if ext == extension: 35 | index = filename[:9] 36 | filebase = os.path.splitext(filename)[0] 37 | fullpath = os.path.join(root,filename) 38 | statement = "INSERT INTO {0} ({1}) VALUES ('{2}','{3}','{4}');".format(table,columns,index,fullpath,filebase) 39 | cur.execute(statement) 40 | ``` 41 | 42 | The problem of replacing string formating by ? is not important here: 43 | 44 | > Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack ([1.13. sqlite3][3] ) 45 | 46 | 47 | [1]: http://www.sqlite.org/lang_createindex.html 48 | [2]: http://mkaz.com/solog/python-string-format 49 | [3]: http://docs.python.org/2/library/sqlite3.html 50 | -------------------------------------------------------------------------------- /Extract coordinates from vector layer in PyQgis.md: -------------------------------------------------------------------------------- 1 | From [Extract coordinates from vector layer in PyQgis](http://gis.stackexchange.com/questions/53594/extract-coordinates-from-vector-layer-in-pyqgis) 2 | 3 | Everything can be simplified in a more Pythonic way (see in [How to add Direction and Distance to attribute table?][1] ): 4 | 5 | 1) function to select all the elements (geometry and attributes) of a layer: 6 | 7 | ```python 8 | def select_all(layer): 9 | layer.select([]) 10 | layer.setSelectedFeatures([obj.id() for obj in layer]) 11 | ``` 12 | 2) selection of the layer 13 | 14 | ```python 15 | mylayer = qgis.utils.iface.activeLayer() 16 | select_all(mylayer) 17 | ``` 18 | 3) processing the layer 19 | 20 | ```python 21 | for elem in mylayer.selectedFeatures(): 22 | geom= elem.geometry() 23 | attrs = elem.attributeMap() 24 | 25 | # example with geometry 26 | wkt = geom.exportToWkt() 27 | print wkt 28 | 29 | # example with attributes 30 | for (k,atr) in attrs.iteritems(): 31 | print "%d: %s" % (k, atr.toString()) 32 | ``` 33 | example of results: 34 | 35 | for geometry: 36 | 37 | LINESTRING(110923.171250 113663.674220, 117364.375933 120736.374336, 117364.375933 120736.374336) 38 | 39 | LINESTRING(112501.896619 119157.645479, 118248.464701 116189.640235)... 40 | 41 | for attributes: 42 | 43 | 0, -100, test 44 | 45 | 1, -200, test2 46 | 47 | ... 48 | 49 | If you want an iterator: 50 | 51 | ```python 52 | for i, elem in enumerate(mylayer.selectedFeatures()): 53 | geom= elem.geometry() 54 | wkt = geom.exportToWkt() 55 | print "element: ", i, "wkt: ", wkt 56 | 57 | element: 0 wkt: LINESTRING(110923.171250 113663.674220, 117364.375933 120736.374336, 117364.375933 120736.374336) 58 | element: 1 wkt: LINESTRING(112501.896619 119157.645479, 118248.464701 116189.640235) 59 | ```python 60 | 61 | and for the extraction of the xy coordinates, see [How to add Direction and Distance to attribute table?][2] 62 | 63 | 64 | 65 | [1]: http://gis.stackexchange.com/questions/24260/how-to-add-direction-and-distance-to-attribute-table 66 | [2]: http://gis.stackexchange.com/questions/24260/how-to-add-direction-and-distance-to-attribute-table 67 | 68 | -------------------------------------------------------------------------------- /Get the vertices on a LineString either side of a Point.md: -------------------------------------------------------------------------------- 1 | From [Get the vertices on a LineString either side of a Point](http://gis.stackexchange.com/questions/84512/get-the-vertices-on-a-linestring-either-side-of-a-point) 2 | 3 | 4 | I don't understand your question: 5 | 6 | ```Python 7 | line = LineString([(0, 0), (2, 2)]) 8 | # create a point which lies along the line 9 | point = line.interpolate(1) 10 | line.contains(point) 11 | True 12 | ``` 13 | 14 | ![enter image description here][1] 15 | 16 | You want the two lines which lie either side of the point ? 17 | 18 | ```Python 19 | 20 | line1 = LineString([line.coords[0],(point.x, point.y)]) 21 | line2 = LineString([(point.x, point.y), line.coords[1]]) 22 | ``` 23 | 24 | ![enter image description here][2] 25 | 26 | ###Upgrade 1: with a line with multiple vertices 27 | 28 | ![enter image description here][3] 29 | 30 | You need to iterate through the segments of the LineString to find the one that contains the point 31 | 32 | The LineString must be iterate as pair to divide the line in segments. 33 | 34 | ```Python 35 | def pairs(lst): 36 | for i in range(1, len(lst)): 37 | yield lst[i-1], lst[i] 38 | 39 | line = LineString([(0,0),(1,2), (2, 2), (2,3), (4,2),(5,5)]) 40 | 41 | for pair in pairs(list(line.coords)): 42 | if LineString([pair[0],pair[1]]).contains(point): 43 | print LineString([pair[0],pair[1]]) 44 | 45 | LINESTRING (2.00 2.00, 2.00 3.00) 46 | 47 | ``` 48 | 49 | And you can use the previous answer: a rapid solution, for example ( this can be done better): 50 | 51 | ```Python 52 | line1 = [] 53 | line2 = [] 54 | cp = False 55 | for pair in pairs(list(line.coords)): 56 | if cp == False: 57 | line1.append(pair[0]) 58 | if cp == True: 59 | line2.append(pair[1]) 60 | if LineString([pair[0],pair[1]]).contains(point): 61 | line1.append((point.x,point.y)) 62 | line2.append((point.x,point.y)) 63 | line2.append(pair[1]) 64 | cp = True 65 | line1 = LineString(line1) 66 | line2 = LineString(line2) 67 | ``` 68 | 69 | Result: 70 | 71 | ![enter image description here][4] 72 | 73 | 74 | 75 | [1]: http://i.stack.imgur.com/21aIy.jpg 76 | [2]: http://i.stack.imgur.com/bjlHd.jpg 77 | [3]: http://i.stack.imgur.com/y4btW.jpg 78 | [4]: http://i.stack.imgur.com/tu7LT.jpg 79 | -------------------------------------------------------------------------------- /Shapely unable to tell if polygon contains point.md: -------------------------------------------------------------------------------- 1 | From [Shapely unable to tell if polygon contains point](http://gis.stackexchange.com/questions/84114/shapely-unable-to-tell-if-polygon-contains-point) 2 | 3 | If we examine your polygon: 4 | 5 | ```Python 6 | polygon = shapefile_record['geometry'] 7 | print polygon.bounds 8 | (77.84476181915733, 30.711096140487314, 78.59476181915738, 31.28199614048725) 9 | 10 | ``` 11 | 12 | From [Shapely manual][1], `object.bounds`: 13 | 14 | > Returns a (minx, miny, maxx, maxy) tuple (float values) that bounds the object. 15 | 16 | Here minx = 77.84476181915733, miny = 30.711096140487314 17 | 18 | = here, min longitude = 77.844... and min latitude = 30.711... 19 | 20 | Setting your point as Point(30.9787, 78.8900) or Point(latitude, longitude), you reverse the coordinates: 21 | 22 | 23 | ```Python 24 | your_point = Point(30.9787, 78.8900) # = Point(y, x) 25 | xy_point = Point(78.8900,30.9787) # = Point(x,y) 26 | polygon.contains(xy_point) 27 | False 28 | 29 | ``` 30 | 31 | Which is correct: 32 | 33 | ![enter image description here][2] 34 | 35 | So, the script with your example: 36 | 37 | 38 | ```Python 39 | 40 | from shapely.geometry import Point, shape 41 | point = Point(78.8900,30.9787) 42 | fc = fiona.open("AC_All_Final.shp") 43 | print fc.schema 44 | {'geometry': 'Polygon', 'properties': OrderedDict([(u'DIST_NAME', 'str:254'), (u'Assem_No', 'int:4'), (u'AREA', 'float:18.3'), (u'PERIMETER', 'float:18.3'), (u'INDIAASSEM', 'float:11'), (u'INDIAASS', 'float:11'), (u'NO', 'float:11'), (u'ST_CODE', 'str:254'), (u'AC_NAME', 'str:254'), (u'AC_TYPE', 'str:254'), (u'PC_NO', 'float:11'), (u'AC_NO', 'float:19.11'), (u'AC_HNAME', 'str:254'), (u'PARTY', 'str:254'), (u'CODE_NO', 'str:254'), (u'Longitude', 'float:19.17'), (u'Latitude', 'float:19.17'), (u'State', 'str:50'), (u'PC_NAME', 'str:25'), (u'PC_TYPE', 'str:3'), (u'PC_CODE', 'str:10'), (u'PC_NO_1', 'int:4')])} 45 | from feature in fc: 46 | if shape(feature['geometry']).contains(point): 47 | print feature['properties']['DIST_NAME'], feature['properties']['Longitude'], feature['properties']['Latitude'] 48 | 49 | Uttarkashi 78.8900584624 30.9787742252 50 | 51 | 52 | ``` 53 | 54 | 55 | Result: 56 | 57 | ![enter image description here][3] 58 | 59 | 60 | 61 | 62 | 63 | [1]: http://toblerity.org/shapely/manual.html 64 | [2]: http://i.stack.imgur.com/tWFpx.jpg 65 | [3]: http://i.stack.imgur.com/xMJXD.jpg 66 | -------------------------------------------------------------------------------- /How to draw perpendicular lines in QGIS?.md: -------------------------------------------------------------------------------- 1 | from [How to draw perpendicular lines in QGIS?](http://gis.stackexchange.com/questions/59169/how-to-draw-perpendicular-lines-in-qgis/59196) 2 | 3 | 4 | 5 | It is a problem of analytical geometry and the solution was given by Paul Bourke in 1998 ([Minimum Distance betweena Point and a Line][1]). The shortest distance from a point to a line or line segment is the perpendicular from this point to the line segment. Several versions of his algorithm have been proposed in various languages ​​including Python as in [Measuring distance from a point to a line segment in Python.][2] but there are many others (like [Nearest neighbor between a point layer and a line layer][3] with Shapely) 6 | 7 | ```python 8 | # basic example with PyQGIS 9 | # the end points of the line 10 | line_start = QgsPoint(50,50) 11 | line_end = QgsPoint(100,150) 12 | # the line 13 | line = QgsGeometry.fromPolyline([line_start,line_end]) 14 | # the point 15 | point = QgsPoint(30,120) 16 | ``` 17 | 18 | ![pt line][4] 19 | 20 | ```python 21 | def intersect_point_to_line(point, line_start, line_end): 22 | ''' Calc minimum distance from a point and a line segment and intersection''' 23 | # sqrDist of the line (PyQGIS function = magnitude (length) of a line **2) 24 | magnitude2 = line_start.sqrDist(line_end) 25 | # minimum distance 26 | u = ((point.x() - line_start.x()) * (line_end.x() - line_start.x()) + (point.y() - line_start.y()) * (line_end.y() - line_start.y()))/(magnitude2) 27 | # intersection point on the line 28 | ix = line_start.x() + u * (line_end.x() - line_start.x()) 29 | iy = line_start.y() + u * (line_end.y() - line_start.y()) 30 | return QgsPoint(ix,iy) 31 | 32 | line = QgsGeometry.fromPolyline([point,intersect_point_to_line(point, line_start, line_end)]) 33 | ``` 34 | 35 | and the result is 36 | 37 | ![result][5] 38 | 39 | Adapting the solution to your problem is easy,just loop through all line segments, extracting the segments end points and apply the function. 40 | 41 | 42 | [1]: http://paulbourke.net/geometry/pointlineplane/ 43 | [2]: http://nodedangles.wordpress.com/2010/05/16/measuring-distance-from-a-point-to-a-line-segment/ 44 | [3]: http://gis.stackexchange.com/questions/396/nearest-neighbor-between-a-point-layer-and-a-line-layer 45 | [4]: http://i.stack.imgur.com/xwYK9.jpg 46 | [5]: http://i.stack.imgur.com/onESj.jpg 47 | -------------------------------------------------------------------------------- /Better way to duplicate a layer using ogr in python?.md: -------------------------------------------------------------------------------- 1 | From [better way to duplicate a layer using ogr in python?](http://gis.stackexchange.com/questions/56703/better-way-to-duplicate-a-layer-using-ogr-in-python/56722) 2 | 3 | Use [Fiona][1] of Sean Gillies , a very simple wrapper of the OGR library ([The Fiona User Manual][2]) 4 | 5 | All the elements of a shapefile (schema, records) are processed using Python dictionaries: 6 | 7 | schema of one of my shapefiles as example: 8 | 9 | > {'geometry': 'LineString', 'properties': {u'faille': 'str:20', u'type': 'str:20', u'id': 'int'}} 10 | 11 | one record in the shapefile: 12 | 13 | > {'geometry': {'type': 'LineString', 'coordinates': [(269884.20917418826, 151805.1917153612), (270409.89083992655, 153146.21637285672), (272298.05355768028, 154047.38494269375), (272941.74539327814, 155484.96337552898), (272169.31519056071, 156117.92701386689)]}, 'id': '1', 'properties': {'faille': u'de Salinas', 'type': u'normale'}} 14 | 15 | 16 | so to duplicate a shapefile: 17 | 18 | ```python 19 | 20 | from shapely.geometry import mapping, shape 21 | import fiona 22 | # Read the original Shapefile 23 | with fiona.collection('original.shp', 'r') as input: 24 | # The output has the same schema 25 | schema = input.schema.copy() 26 | # write a new shapefile 27 | with fiona.collection(''file1.shp', 'w', 'ESRI Shapefile', schema) as output: 28 | for elem in input: 29 | output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))}) 30 | ``` 31 | 32 | If you want to split a large shapefile into many smaller ones, everything takes place in the for loop but all the schemas of the original shapefile are preserved in the dictionary with schema = input.schema.copy() and {'properties': elem['properties'] 33 | 34 | see [How do I find vector line bearing in QGIS or GRASS?][3] for an example of 35 | 36 | 1. spliting a shapefile 37 | 2. preserve the attributes of the original shapefile in the splitted shapefile 38 | 3. and add a new field in the splitted shapefile 39 | 40 | For Mac OS X or Linux users, it is easy to install. For Windows users, use the version of Christoph Gohlke [Unofficial Windows Binaries for Python Extension Packages][4] 41 | 42 | 43 | [1]: https://pypi.python.org/pypi/Fiona/0.10 44 | [2]: http://toblerity.github.com/fiona/manual.html 45 | [3]: http://gis.stackexchange.com/questions/55449/how-do-i-find-vector-line-bearing-in-qgis-or-grass/55480#55480 46 | [4]: http://www.lfd.uci.edu/~gohlke/pythonlibs/#fiona 47 | -------------------------------------------------------------------------------- /Is there are QGIS plugin to allow the 3d visualisation of geological borehole data similar to the functionality of Target for ArcGIS?.md: -------------------------------------------------------------------------------- 1 | 2 | From [Is there are QGIS plugin to allow the 3d visualisation of geological borehole data similar to the functionality of Target for ArcGIS?](http://gis.stackexchange.com/questions/41701/is-there-are-qgis-plugin-to-allow-the-3d-visualisation-of-geological-borehole-da) 3 | 4 | 5 | Yes, it is possible but using a Python script in the console 6 | see [For geologists: 3D geological boreholes ][1] 7 | 8 | ![3D surfaces in QGIS][2] 9 | ![boreholes in QGIS][3] 10 | 11 | I presented the scripts in [visualizing 3D data (Z values) or data with z attribute: a solution ][4] 12 | or [QGIS, représentation 3D des couches vectorielles (shapefiles dits 3D ou shapefiles avec attributs z) avec les modules Python Matplotlib ou Visvis à partir de la console Python][5] in French and [QGIS, visualización 3D de capas vectoriales con Python ][6] in Spanish. 13 | 14 | More generally I use GRASS GIS to do, see [Automatic 3D geological boreholes representation (automate v.extrude from a table ?): my solution in Python ][7] and [3D geological volume modeling (raster 3D): is it really possible ?][8] 15 | 16 | ![boreholes][9] boreholes 17 | 18 | ![layer one][10] layer one 19 | 20 | ![layer 2][11] layer two 21 | 22 | with interpolated surfaces and cross sections: 23 | ![enter image description here][12] 24 | 25 | or 26 | 27 | ![enter image description here][13] 28 | 29 | 30 | [1]: http://osgeo-org.1560.n6.nabble.com/For-geologists-3D-geological-boreholes-td5007085.html 31 | [2]: http://i.stack.imgur.com/ylHp8.jpg 32 | [3]: http://i.stack.imgur.com/Kx9Il.jpg 33 | [4]: http://osgeo-org.1560.n6.nabble.com/visualizing-3D-data-Z-values-or-data-with-z-attribute-a-solution-td5005360.html 34 | [5]: http://www.portailsig.org/content/qgis-representation-3d-des-couches-vectorielles-shapefiles-dits-3d-ou-shapefiles-avec-attrib 35 | [6]: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/315-qgis-visualizacion-3d-de-capas-vectoriales-con-python 36 | [7]: http://osgeo-org.1560.n6.nabble.com/Automatic-3D-geological-boreholes-representation-automate-v-extrude-from-a-table-my-solution-in-Pythn-td4978801.html 37 | [8]: http://osgeo-org.1560.n6.nabble.com/3D-geological-volume-modeling-raster-3D-is-it-really-possible-td4980148.html 38 | [9]: http://i.stack.imgur.com/doQjU.png 39 | [10]: http://i.stack.imgur.com/JYLUM.png 40 | [11]: http://i.stack.imgur.com/yiryI.png 41 | [12]: http://i.stack.imgur.com/r7tuL.jpg 42 | [13]: http://i.stack.imgur.com/Dq4Gm.jpg 43 | -------------------------------------------------------------------------------- /How can I create a line with three points with Python in QGIS?.md: -------------------------------------------------------------------------------- 1 | You must first understand how PyQGIS handles geometry ([Geometry Handling][1]) 2 | 3 | from [How can I create a line with three points with Python in QGIS?](http://gis.stackexchange.com/questions/60307/how-can-i-create-a-line-with-three-points-with-python-in-qgis/60382) 4 | 5 | 6 | The most important element is the point: 7 | 8 | > QgsPoint(x,y) 9 | 10 | and a line or a segment of line are composed of two points: 11 | 12 | > QgsGeometry.fromPolyline([QgsPoint(x1,y1),QgsPoint(x2,y2)])); 13 | 14 | So to construct a line: 15 | 16 | ```python 17 | line_start = QgsPoint(50,50) 18 | line_end = QgsPoint(100,150) 19 | line = QgsGeometry.fromPolyline([line_start,line_end]) 20 | ``` 21 | 22 | and with a memory layer (geometry only, without the attributes): 23 | 24 | 25 | ```python 26 | # create a new memory layer 27 | v_layer = QgsVectorLayer("LineString", "line", "memory") 28 | pr = v_layer.dataProvider() 29 | # create a new feature 30 | seg = QgsFeature() 31 | # add the geometry to the feature, 32 | seg.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 33 | # ...it was here that you can add attributes, after having defined.... 34 | # add the geometry to the layer 35 | pr.addFeatures( [ seg ] ) 36 | # update extent of the layer (not necessary) 37 | v_layer.updateExtents() 38 | # show the line 39 | QgsMapLayerRegistry.instance().addMapLayers([v_layer]) 40 | ``` 41 | 42 | the result is: 43 | 44 | ![enter image description here][2] 45 | 46 | with 3 points, just add it as a new feature: 47 | 48 | ```python 49 | newpoint = QgsPoint(143,125) 50 | v_layer = QgsVectorLayer("LineString", "line_3pt", "memory") 51 | pr = v_layer.dataProvider() 52 | seg = QgsFeature() 53 | seg.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 54 | # new feature: line from line_end to newpoint 55 | seg = QgsFeature() 56 | seg.setGeometry(QgsGeometry.fromPolyline([line_end, newpoint])) 57 | pr.addFeatures( [ seg ] ) 58 | v_layer.updateExtents() 59 | # add the line to 60 | QgsMapLayerRegistry.instance().addMapLayers([v_layer]) 61 | ``` 62 | 63 | and the result is: 64 | 65 | ![enter image description here][3] 66 | 67 | And with a for loop you can create a line with many segments: 68 | 69 | ![enter image description here][4] 70 | 71 | 72 | [1]: http://www.qgis.org/pyqgis-cookbook/geometry.html 73 | [2]: http://i.stack.imgur.com/S1VCk.jpg 74 | [3]: http://i.stack.imgur.com/EpNor.jpg 75 | [4]: http://i.stack.imgur.com/6Vw0p.jpg 76 | -------------------------------------------------------------------------------- /How to terminate Python scripts in Processing framework properly?.md: -------------------------------------------------------------------------------- 1 | From [How to terminate Python scripts in Processing framework properly?](http://gis.stackexchange.com/questions/81530/how-to-terminate-python-scripts-in-processing-framework-properly) 2 | 3 | - first thing, `osgeo.gdal` is for pure Python scripting: 4 | 5 | ```python 6 | from osgeo import gdal 7 | raster = gdal.Open('your.tif') 8 | raster.GetProjection() 9 | ``` 10 | 11 | Everything else is a problem of osgeo, and not of PyQGIS, since you use 2 QGIS existing layers: 12 | 13 | ```python 14 | ##raster_1=raster 15 | ##raster_2=raster 16 | ``` 17 | 18 | you don't need it. To process the layers, the correct code is: 19 | 20 | ```python 21 | raster_1 = processing.getobject(raster_1) 22 | raster_2 = processing.getobject(raster_2) 23 | ``` 24 | 25 | an the crs is given by: 26 | 27 | ```python 28 | 29 | new_proj = raster.crs() 30 | ``` 31 | 32 | - second thing, you cannot load a raster in QGIS without projection (if not yet existing, it is chosen by QGIS, according to some criteria): 33 | 34 | ![enter image description here][1] 35 | 36 | So your first condition `if proj is None:`, is unnecessary and your script become (you don't need a list with only two layers): 37 | 38 | ```python 39 | raster_1 = processing.getobject(raster_1) 40 | raster_2 = processing.getobject(raster_2) 41 | if raster_1.crs()==raster_2.crs(): 42 | action 43 | else: 44 | WrongCRS() 45 | ``` 46 | 47 | and the script terminate by himself. 48 | 49 | PS: 50 | in the last version of the processing module, it is now: 51 | 52 | ```python 53 | processing.getObjects() 54 | ``` 55 | PS2: 56 | 57 | For terminate the script, you can embed your script in a function and use `sys.exitfunc()` 58 | (I use the Python console to to see the results) 59 | 60 | example: 61 | 62 | ```python 63 | 64 | import atexit 65 | ..... 66 | def all_done(): 67 | message = '- Rasters must have the same CRS!\n\nExecution cancelled!' 68 | print message 69 | atexit.register(all_done) 70 | raster_1 = processing.getObject(raster_1) 71 | raster_2 = processing.getObject(raster_2) 72 | def main(): 73 | if raster_1.crs() != raster_2.crs(): 74 | sys.exitfunc() 75 | else: 76 | message = "ok" 77 | print message 78 | continue 79 | main() 80 | ``` 81 | 82 | Result in the Python console: 83 | 84 | ![enter image description here][2] 85 | 86 | 87 | [1]: http://i.stack.imgur.com/ioUad.jpg 88 | [2]: http://i.stack.imgur.com/tWuJK.jpg 89 | -------------------------------------------------------------------------------- /Extract a record by name in pyshp?.md: -------------------------------------------------------------------------------- 1 | 2 | from [Extract a record by name in pyshp?](http://gis.stackexchange.com/questions/74808/extract-a-record-by-name-in-pyshp/74828) 3 | 4 | You can easily create a dictionary of attributes: 5 | 6 | ```python 7 | 8 | import shapefile 9 | sf = shapefile.Reader('MyFile.shp') 10 | # name of fields 11 | fields = sf.fields[1:] 12 | field_names = [field[0] for field in fields] 13 | # construction of a dctionary field_name:value 14 | for r in sf.shapeRecords(): 15 | atr = dict(zip(field_names, sr.record)) 16 | ``` 17 | 18 | As a result: 19 | 20 | ```python 21 | 22 | {'field1': 'value1', 'field2': 'value2', ..., 'fieldn': 'valuen'} 23 | ``` 24 | 25 | and 26 | 27 | ```python 28 | 29 | if atr['field1'] == value: 30 | print atr 31 | action 32 | ``` 33 | 34 | With large/many files, you can use a generator: 35 | 36 | ```python 37 | 38 | def records(filename): 39 | # generator 40 | reader = shapefile.Reader(filename) 41 | fields = reader.fields[1:] 42 | field_names = [field[0] for field in fields] 43 | for sr in reader.shapeRecords(): 44 | yield dict(zip(field_names, sr.record)) 45 | rec = records('MyFile.shp') 46 | rec.next() 47 | {'field1': 'value1', 'field2': 'value2', ..., 'fieldn': 'valuen'} 48 | # or 49 | for rec in records('MyFile.shp') 50 | if rec['field1'] == value: 51 | data = rec 52 | ``` 53 | 54 | 55 | 56 | Sean Gillies has proposed the [The geo_interface protocol][1], an interface that describes a spatial object using a GeoJSON like structure (dictionaries). Many modules implement this protocol (see [Python Geo_interface applications][2]), including pyshp, since version 1.1.7: 57 | 58 | With one of my examples: 59 | 60 | ```python 61 | 62 | for r in sf.shapeRecords(): 63 | atr = dict(zip(field_names, r.record)) 64 | geom = r.shape.__geo_interface__ 65 | print dict(geometry=geom,properties=atr) 66 | {'geometry': {'type': 'Point', 'coordinates': (161821.09375, 79076.0703125)}, 'properties': {'DIP_DIR': 120, 'STRATI_TYP': 1, 'DIP': 30}} 67 | ``` 68 | You can also use [Fiona][2] or [osgeo.ogr][4] in the same way. 69 | 70 | 71 | [1]: https://gist.github.com/sgillies/2217756 72 | [2]: https://github.com/mlaloux/Python-geo_interface-applications 73 | [3]: https://gist.github.com/sgillies/2217756 74 | [4]: https://github.com/mlaloux/Python-geo_interface-applications/blob/master/ogr_geointerface.py 75 | [5]: https://github.com/mlaloux/Python-geo_interface-applications/blob/master/spatialite_geointerface.py 76 | -------------------------------------------------------------------------------- /TIN Interpolation using a vector layer.md: -------------------------------------------------------------------------------- 1 | From [TIN Interpolation using a vector layer](http://gis.stackexchange.com/questions/41891/tin-interpolation-using-a-vector-layer) 2 | 3 | see [Is there are QGIS plugin to allow the 3d visualisation of geological borehole data similar to the functionality of Target for ArcGIS?][1] for my solution in Python with the modules Matplotlib and [Visvis][2] 4 | 5 | The Interpolation plugin generates surfaces in ArcInfo ASCII grid format (. asc) but it offers no way to visualize the results in 3D or to process the 3d shapefiles (PointZ,..) 6 | 7 | I presented a solution and the scripts in the QGIS-Developer list [visualizing 3D data (Z values) or data with z attribute: a solution ][3] 8 | and, in French, in [QGIS, représentation 3D des couches vectorielles (shapefiles dits 3D ou shapefiles avec attributs z) avec les modules Python Matplotlib ou Visvis à partir de la console Python][4] or in Spanish in [QGIS, visualización 3D de capas vectoriales con Python ][5] 9 | 10 | **3d visualisation of the points** (Visvis) 11 | 12 | ![points][6] 13 | 14 | **a resulting 3d grid** (here with matplolib function **griddata** but you can use all the interpolation algorithms of Scipy or others modules) 15 | 16 | ![grid][7] 17 | 18 | **The shaded surface** with an elevation colormap (Visvis) 19 | 20 | ![surfaces][8] 21 | 22 | **3d contour lines (Matplotlib)** 23 | ![enter image description here][9] 24 | 25 | **and for fun ...(Visvis)** 26 | 27 | ![enter image description here][10] 28 | 29 | 30 | But build a plugin seems a priori to me very complex and time consuming: 31 | 32 | - plot 3 d points is easy. 33 | - but in all other cases, all the scenarios (3D shapefile points, lines or polygons, shapefile with z attribute, interpolation algorithm, ...) should be considered before. 34 | - You need Python modules that are not present by default in QGIS (like Shapely, Scipy or Visvis) 35 | 36 | 37 | [1]: http://gis.stackexchange.com/questions/41701/is-there-are-qgis-plugin-to-allow-the-3d-visualisation-of-geological-borehole-da 38 | [2]: http://code.google.com/p/visvis/ 39 | [3]: http://osgeo-org.1560.n6.nabble.com/visualizing-3D-data-Z-values-or-data-with-z-attribute-a-solution-td5005360.html 40 | [4]: http://www.portailsig.org/content/qgis-representation-3d-des-couches-vectorielles-shapefiles-dits-3d-ou-shapefiles-avec-attrib 41 | [5]: http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/315-qgis-visualizacion-3d-de-capas-vectoriales-con-python 42 | [6]: http://i.stack.imgur.com/AtIdL.png 43 | [7]: http://i.stack.imgur.com/43dng.png 44 | [8]: http://i.stack.imgur.com/GK4kV.png 45 | [9]: http://i.stack.imgur.com/TQI5Y.png 46 | [10]: http://i.stack.imgur.com/q3mf7.gif 47 | -------------------------------------------------------------------------------- /Problem with converting rasters to arrays and adding them to main array, then converting to raster via NumPyArrayToRaster : output is NoData values.md: -------------------------------------------------------------------------------- 1 | From [Problem with converting rasters to arrays and adding them to main array, then converting to raster via NumPyArrayToRaster : output is NoData values](http://gis.stackexchange.com/questions/72336/problem-with-converting-rasters-to-arrays-and-adding-them-to-main-array-then-co) 2 | 3 | 4 | Some points need to be clarified: 5 | 6 | - Are the rasters single-band or multi-bands ? 7 | - what is the shape of your main_array ? 8 | - What is the final result of your main_array ? 9 | 10 | Example with numpy 11 | ------------- 12 | 13 | Create an array filled with zeros: 14 | 15 | ```python 16 | import numpy as np 17 | main_array= np.zeros((4,5),dtype=np.float64) 18 | # In your case: 19 | # main_array = np.zeros(template_array.shape, dtype=np.float64) 20 | print main_array 21 | array([[ 0., 0., 0., 0., 0.], 22 | [ 0., 0., 0., 0., 0.], 23 | [ 0., 0., 0., 0., 0.], 24 | [ 0., 0., 0., 0., 0.]]) 25 | main_array.shape 26 | (4, 5) 27 | main_array.size 28 | 20 29 | ``` 30 | 31 | 32 | Sums of arrays: 33 | 34 | ```python 35 | 36 | newarray = np.array([[ 1., 2., 3., 4., 5.], 37 | [ 1., 2., 3., 4., 5.], 38 | [1., 2., 3., 4., 5.], 39 | [1., 2., 3., 4., 5.]]) 40 | 41 | main_array = main_array + newarray 42 | print main_array 43 | array([[ 1., 2., 3., 4., 5.], 44 | [ 1., 2., 3., 4., 5.], 45 | [ 1., 2., 3., 4., 5.], 46 | [ 1., 2., 3., 4., 5.]]) 47 | main_array = main_array + newarray 48 | print main_array 49 | array([[ 2., 4., 6., 8., 10.], 50 | [ 2., 4., 6., 8., 10.], 51 | [ 2., 4., 6., 8., 10.], 52 | [ 2., 4., 6., 8., 10.]]) 53 | etc. 54 | ``` 55 | 56 | I don't use ArcPy but with GDAL/OGR the result is not NULL: 57 | ```python 58 | import numpy as np 59 | from osgeo import gdal 60 | ds = gdal.Open('myraster') 61 | array = np.array(ds.GetRasterBand(1).ReadAsArray()) 62 | array.shape 63 | (62, 90) 64 | main_array = np.zeros(array.shape, dtype=np.float64) 65 | main_array.shape 66 | (62, 90) 67 | main_array + array == array 68 | array([[ True, True, True, ..., True, True, True], 69 | [ True, True, True, ..., True, True, True], 70 | [ True, True, True, ..., True, True, True], 71 | ..., 72 | [ True, True, True, ..., True, True, True], 73 | [ True, True, True, ..., True, True, True], 74 | [ True, True, True, ..., True, True, True]], dtype=bool) 75 | ```python 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Programmatically manipulate GPX data.md: -------------------------------------------------------------------------------- 1 | From [Programmatically manipulate GPX data](http://gis.stackexchange.com/questions/64818/programmatically-manipulate-gpx-data) 2 | 3 | - osgeo.ogr can read all these formats: [OGR Vector Formats][1] 4 | - osgeo.ogr and shapely support 3D: 5 | 6 | ```python 7 | 8 | from osgeo import ogr 9 | point = ogr.Geometry(ogr.wkbPoint25D) 10 | point.AddPoint(5,4,4) 11 | point.GetZ() 12 | 4.0 13 | 14 | from shapely.geometry import Point 15 | point1 = Point(5,4,4) 16 | point1.has_z 17 | True 18 | point1.z 19 | 4.0 20 | ``` 21 | 22 | 23 | - you can change projections with osgeo.ogr: see [Projecting shapefile with transformation using OGR in python][2] and many, many other examples 24 | 25 | - transform the geometries between ogr and shapely is easy: 26 | 27 | ```python 28 | 29 | from shapely.wkb import loads 30 | point = ogr.Geometry(ogr.wkbPoint25D) 31 | point.AddPoint(5,4,4) 32 | point_shapely = loads(point.ExportToWkb()) 33 | point_shapely.has_z 34 | True 35 | ``` 36 | - inverse 37 | 38 | ```python 39 | 40 | point_ogr = ogr.CreateGeometryFromWkb(point_shapely.wkb) 41 | print point_ogr.GetX(), point_ogr.GetY(), point_ogr.GetZ() 42 | 5.0 4.0 0.0 43 | ``` 44 | - so you can use ogr or pyproj to change the projection of a shapely geometry, (see [Measuring distance in spherical Mercator vs zoned UTM][3] for example) 45 | - and shapely or analytical geometry allows to project a point on a PoLyline (see [How to draw perpendicular lines in QGIS?][4], with PyQGIS, but it is similar with ogr) 46 | 47 | As one example of the process, here are the results of the creation of geological cross-sections from 3D points (from [Python: Using vector and raster layers in a geological perspective, without GIS software][7], in French, but the scripts and the figures are universal). 48 | 49 | 3D representation (distance between points): 50 | 51 | ![enter image description here][5] 52 | 53 | cumulative distance (geological cross-section) 54 | 55 | ![enter image description here][6] 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | [1]: http://www.gdal.org/ogr/ogr_formats.html 65 | [2]: http://gis.stackexchange.com/questions/19401/projecting-shapefile-with-transformation-using-ogr-in-python 66 | [3]: http://gis.stackexchange.com/questions/7293/measuring-distance-in-spherical-mercator-vs-zoned-utm 67 | [4]: http://gis.stackexchange.com/questions/59169/how-to-draw-perpendicular-lines-in-qgis/59196#59196 68 | [5]: http://i.stack.imgur.com/qaCB1.jpg 69 | [6]: http://i.stack.imgur.com/hwRDo.jpg 70 | [7]: http://www.portailsig.org/content/python-utilisation-des-couches-vectorielles-et-matricielles-dans-une-perspective-geologique- 71 | -------------------------------------------------------------------------------- /PyQGIS 2.0 API problem reading attributes.md: -------------------------------------------------------------------------------- 1 | From [](http://gis.stackexchange.com/questions/85110/pyqgis-2-0-api-problem-reading-attributes) 2 | 3 | To know the available functions, in the Python console type: 4 | 5 | ```python 6 | dir(mylayer) 7 | # and 8 | dir(geom) 9 | ``` 10 | and one answer is (always in the Python console, slightly different with Processing or for a plugin): 11 | 12 | ```python 13 | fields = mylayer.pendingFields() 14 | field_names = [field.name() for field in fields] 15 | for feature in mylayer.getFeatures(): 16 | geom= feature.geometry() 17 | point = geom.asPoint() 18 | print point 19 | attributes = features.attributes() 20 | print attributes 21 | dip_dir = feature['dip_dir'] 22 | print dip_dir 23 | # with a dictionary 24 | atr = dict(zip(field_names, feature.attributes())) 25 | print atr 26 | print atr['dip_direct'] 27 | ``` 28 | 29 | Result with one of my shapefiles 30 | 31 | ```python 32 | print field_names 33 | [u'dip_direct', u'dip', u'type'] 34 | # some results of the for loop 35 | # geom.asPoint() 36 | (198236,89025.8) 37 | # attributes of the feature 38 | [180, 26, u'N'] 39 | # dip_dir value 40 | 180 41 | # attributes as dictionary 42 | {u'type': u'N', u'dip': 26, u'dip_direct': 180} 43 | # one particular value (dip_dir) 44 | 180 45 | (199847,89197.1) 46 | [335, 50, u'N'] 47 | 335 48 | {u'type': u'N', u'dip': 50, u'dip_direct': 335} 49 | 335 50 | etc. 51 | ``` 52 | and also: 53 | 54 | ```python 55 | 56 | # GeoJSON 57 | for ... 58 | print geom.exportToGeoJSON() 59 | { "type": "Point", "coordinates": [198235.93072444110293873, 89025.821821038480266] } 60 | { "type": "Point", "coordinates": [199847.19120459226542152, 89197.0735811617487343] } 61 | 62 | ``` 63 | or 64 | 65 | ```python 66 | # WKT 67 | for ... 68 | print geom.exportToWkt() 69 | POINT(198235.93072444110293873 89025.821821038480266) 70 | POINT(199847.19120459226542152 89197.0735811617487343) 71 | 72 | ``` 73 | 74 | And a true [GeoJSON][1] with attributes ('properties'): 75 | 76 | ```python 77 | for elem in layer.getFeatures(): 78 | geom= elem.geometry() 79 | atr = dict(zip(field_names, elem.attributes())) 80 | print dict(geometry=geom.exportToGeoJSON(),properties=atr) 81 | 82 | {'geometry': u'{ "type": "Point", "coordinates": [198235.93072444110293873, 89025.821821038480266] }', 'properties': {u'type': u'N', u'dip': 26, u'dip_direct': 180}} 83 | {'geometry': u'{ "type": "Point", "coordinates": [199847.19120459226542152, 89197.0735811617487343] }', 'properties': {u'type': u'N', u'dip': 50, u'dip_direct': 335}} 84 | ``` 85 | 86 | [1]: http://geojson.org/geojson-spec.html 87 | -------------------------------------------------------------------------------- /Updating Attributes using Pyshp.md: -------------------------------------------------------------------------------- 1 | 2 | from [Updating Attributes using Pyshp](is.stackexchange.com/questions/57635/updating-attributes-using-pyshp/57696) 3 | 4 | 5 | It is the same thing with pyshp, except that you cannot update directly the dbf file. 6 | When you read a shapefile, the data are stored in Python lists 7 | 8 | ```python 9 | import shapefile 10 | input = shapefile.Reader("yourfile.shp") 11 | shapes = input.shapes() # -> the geometries in a list 12 | fields = input.fields[1:] -> the fields definition in a list 13 | fields_name = = [field[0] for field in fields] -> the fields names in a list 14 | attributes = input.records() -> the attributes in a list 15 | 16 | # now you can modify an attribute value in the list: 17 | attributes[0][1] = "what you want" # second attribute of the first record 18 | # if you want to use a field name for the attribute, like in dbfpy, you must use a dictionary 19 | list = [(i,dict(zip(fields, attri))) for i,attri in enumerate(attributes)] 20 | dict = dict((key, value) for (key, value) in list) 21 | # now you can modify an attribute value in the dictionary: 22 | dict[0]['field']='whatyouwant' # attribute of "field" in the first record 23 | # and return to the original attributes list 24 | attributes_cor = [i.values() for i in dict.values()] 25 | ``` 26 | 27 | but this changes the value in the list or in the dictionary, not in the dbf file. To do this, rather than affecting the original shapefile, it is better to create a copy with the new attribute list (same as [Add a Field to an Existing Shapefile ][2] or [Subsetting a Shapefile by Attributes ][3]). 28 | 29 | 30 | You can also use other Python libraries like ogr or [Fiona][4] (see [Using the API of QSpatiaLite plugin][5] for the principles, the data are stored as Python dictionaries) 31 | 32 | ```python 33 | from shapely.geometry import mapping, shape 34 | import fiona 35 | # Read the original Shapefile 36 | with fiona.collection('yourfile.shp', 'r') as input: 37 | # The output has the same schema 38 | schema = input.schema.copy() 39 | # write a new shapefile 40 | with fiona.collection('yourcopyfile.shp', 'w', 'ESRI Shapefile', schema) as output: 41 | for elem in input: 42 | elem['properties']['field'] = 'whatyouwant' # or a function, or... 43 | output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))}) 44 | ``` 45 | 46 | 47 | 48 | 49 | [1]: http://geospatialpython.com/2013/04/add-field-to-existing-shapefile.html 50 | [2]: http://geospatialpython.com/2013/04/add-field-to-existing-shapefile.html 51 | [3]: http://geospatialpython.com/2010/12/subsetting-shapefile-by-attributes.html 52 | [4]: https://pypi.python.org/pypi/Fiona 53 | [5]: http://gis.stackexchange.com/questions/57208/using-the-api-of-qspatialite-plugin/57215#57215 54 | -------------------------------------------------------------------------------- /What is the unit the shapely length attribute?.md: -------------------------------------------------------------------------------- 1 | From [What is the unit the shapely length attribute?](http://gis.stackexchange.com/questions/80881/what-is-the-unit-the-shapely-length-attribute/) 2 | 3 | 4 | As [alfaciano][1] says in shapely, the distance is the Euclidean Distance or Linear distance between two points on a plane and not the [Great-circle distance][2] between two points on a sphere. 5 | 6 | ```Python 7 | 8 | from shapely.geometry import Point 9 | point1 = Point(50.67,4.62) 10 | point2 = Point(51.67, 4.64) 11 | import math 12 | # Euclidean Dustance 13 | def Euclidean_distance(point1,point2): 14 | return math.sqrt((point2.x()-point1.x())**2 + (point2.y()-point1.y())**2) 15 | 16 | print Euclidean_distance(point1,point2) 17 | 1.00019998 # distance in degrees (coordinates of the points in degrees) 18 | 19 | # with Shapely 20 | print point1.distance(point2) 21 | 1.0001999800039989 #distance in degrees (coordinates of the points in degrees) 22 | ``` 23 | 24 | For the great-circle distance, you need to use algorithms as the law of cosines or the Haversine formula (look at [Why is law of cosines more preferable than haversine when calculating distance between two latitude-longitude points?][3]) or use the module [pyproj][4] that performs geodetic calculations. 25 | 26 | 27 | 28 | ```Python 29 | 30 | # law of cosines 31 | distance = math.acos(math.sin(math.radians(point1.y))*math.sin(math.radians(point2.y))+math.cos(math.radians(point1.y))*math.cos(math.radians(point2.y))*math.cos(math.radians(point2.x)-math.radians(point1.x)))*6371 32 | print "{0:8.4f}".format(distance) 33 | 110.8544 # in km 34 | # Haversine formula 35 | dLat = math.radians(point2.y) - math.radians(point1.y) 36 | dLon = math.radians(point2.x) - math.radians(point1.x) 37 | a = math.sin(dLat/2) * math.sin(dLat/2) + math.cos(math.radians(point1.y)) * math.cos(math.radians(point2.y)) * math.sin(dLon/2) * math.sin(dLon/2) 38 | distance = 6371 * 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) 39 | print "{0:8.4f}".format(distance)distance 40 | 110.8544 #in km 41 | 42 | # with pyproj 43 | import pyproj 44 | geod = pyproj.Geod(ellps='WGS84') 45 | angle1,angle2,distance = geod.inv(point1.x, point1.y, point2.x, point2.y) 46 | print "{0:8.4f}".format(distance/1000) 47 | 110.9807 #in km 48 | ``` 49 | 50 | 51 | You can test the result at [Longitude Latitude Distance Calculator][5] 52 | 53 | ![enter image description here][6] 54 | 55 | 56 | [1]: http://gis.stackexchange.com/users/22405/afalciano 57 | [2]: http://en.wikipedia.org/wiki/Great-circle_distance 58 | [3]: http://gis.stackexchange.com/questions/4906/why-is-law-of-cosines-more-preferable-than-haversine-when-calculating-distance-b 59 | [4]: http://code.google.com/p/pyproj/ 60 | [5]: http://www.csgnetwork.com/lldistcalc.html 61 | [6]: http://i.stack.imgur.com/EGC8k.jpg 62 | -------------------------------------------------------------------------------- /How to add a column in QGIS via python.md: -------------------------------------------------------------------------------- 1 | From [How to add a column in QGIS via python](http://gis.stackexchange.com/questions/56826/how-to-add-a-column-in-qgis-via-python) 2 | 3 | 4 | If you want to use Python, you don't need QGIS, except if you want to create a plugin. 5 | In this case, you should consider PyQGIS with the reference given by Curlew 6 | 7 | But you can also use Python modules like [pyshp][1], [osgeo (gdal and ogr][2]) or [Fiona][3] and [Shapely][4] without QGIS 8 | 9 | In both cases, you need a join field that will link the polygon shapefile to the point shapefile. 10 | 11 | **Example with Fiona and Shapely** (all the elements of a shapefile (schema,geometry, records) are processed using Python dictionaries). 12 | 13 | With ogr and Fiona it is easier to create a new shapefile, copying the original shapefile (geometry and attributes), and adding new fields with the desired values than modify the original shapefile. 14 | 15 | ```python 16 | 17 | from shapely.geometry import mapping 18 | import fiona 19 | # open the polygon shapefile 20 | with fiona.collection('polygon.shp', 'r') as polygon: 21 | # copy of the schema of the original polygon shapefile to the output shapefile (copy) 22 | schema = polygon.schema.copy() 23 | # creation of the new field color in the new schema 24 | schema['properties']['color'] = 'str' 25 | # output shapefile with the new schema 26 | with fiona.collection('join_poly_pt.shp', 'w', 'ESRI Shapefile', schema) as output: 27 | # open the point shapefile with colors 28 | with fiona.collection('point.shp', 'r') as points: 29 | polygons = [elem for elem in polygon] 30 | points = [elem for elem in point] 31 | # joint 32 | for poly in polygons: 33 | for pt in points: 34 | # common field for the join 35 | if poly['properties']['test'] == pt['properties']['test']: 36 | # construction of the new shapefile 37 | res = {} 38 | res['properties'] = poly['properties'] 39 | res['properties']['color'] = pt['properties']['color'] 40 | # geometry of of the original polygon shapefile 41 | res['geometry'] = mapping(shape(poly['geometry'])) 42 | output.write(res) 43 | ``` 44 | 45 | simple example 46 | ![enter image description here][5] 47 | 48 | 49 | 50 | [1]: https://pypi.python.org/pypi/pyshp/1.1.4 51 | [2]: https://pypi.python.org/pypi/GDAL/1.9.1 52 | [3]: https://pypi.python.org/pypi/Fiona/0.10 53 | [4]: https://pypi.python.org/pypi/Shapely/1.2.17 54 | [5]: http://i.stack.imgur.com/xpfbd.jpg 55 | -------------------------------------------------------------------------------- /How to programmatically convert arbitrary XML data to shapefile?.md: -------------------------------------------------------------------------------- 1 | From [How to programmatically convert arbitrary XML data to shapefile?](http://gis.stackexchange.com/questions/71182/how-to-programmatically-convert-arbitrary-xml-data-to-shapefile) 2 | 3 | 4 | I wrote the reply at the same time as blah238 so I modified it consequently. 5 | 6 | The problem is more complex because you need to: 7 | 8 | - "learn" the structure of the [XML][1] file to extract the data as: 9 | - lat="35" lon="-180" from the location tag = the vertices of the polygon (y, x); 10 | 11 | 12 | - rebuild the polygon in a text format with: 13 | 14 | - text or list: (-180, 35), (-170, -33),..., (-153, -30) 15 | - [WKT][2]: ('POLYGON ((-180 35, -170 -33, ..., -153 -30))' ) 16 | - [GeoJSON ][3]: ({"type": "Polygon", "coordinates": [[ [-180.0, 35.0], ..., [-153.0, -30.0]]]}) 17 | 18 | I do not know what application could do so. They generally process [XML][4] files with known schemas. 19 | 20 | The only solution I see is with a Python script as blah238 propose: 21 | 22 | 1. process the XML file with a module like [ElementTree][5] (see blah238 script above) 23 | 24 | 2. build the geometry and create the shapefile with modules like: 25 | 26 | [Pyshp][6] (another solution with directly a Polygon) 27 | 28 | ```python 29 | 30 | 31 | import shapefile 32 | w = shapefile.Writer(shapefile.POLYGON) 33 | # geometry 34 | w.poly(parts=[[[-180, 35],[-170, -33],..,[-153, -30]]]) 35 | # fields 36 | w.field('FIRST_FLD','C','40') 37 | .... 38 | w.record('one', ) 39 | w.save('polygon') 40 | ``` 41 | 42 | [Fiona][7] and [shapely][8] or [PyGeoif][9] 43 | 44 | ```python 45 | 46 | 47 | import fiona 48 | from shapely.geometry import Polygon, mapping 49 | polygon = Polygon([(-180, 35), (-170, -33),..., (-153, -30)]) 50 | # schema of the shapefile 51 | schema = {'geometry': 'Polygon','properties': {'FIRST_FLD': 'char'}} 52 | # write the shapefile 53 | with fiona.collection('polygon.shp', 'w', 'ESRI Shapefile', schema) as layer: 54 | feature = {} 55 | feature['geometry'] = mapping(polygon) 56 | feature['properties'] = {'FIRST_FLD': ...} 57 | layer.write(feature) 58 | ``` 59 | 60 | [Osgeo (GDAL/OGR)][10] 61 | 62 | see [Python GDAL/OGR Cookbook 1.0 documentation ][11] 63 | 64 | You have the choice 65 | 66 | [1]: http://en.wikipedia.org/wiki/XML 67 | [2]: http://en.wikipedia.org/wiki/Well-known_text 68 | [3]: http://www.geojson.org/geojson-spec.html 69 | [4]: http://en.wikipedia.org/wiki/XML 70 | [5]: http://docs.python.org/2/library/xml.etree.elementtree.html 71 | [6]: http://code.google.com/p/pyshp/ 72 | [7]: http://toblerity.org/fiona/manual.html 73 | [8]: http://toblerity.org/shapely/manual.html 74 | [9]: https://github.com/cleder/pygeoif 75 | [10]: https://pypi.python.org/pypi/GDAL/1.10.0 76 | [11]: http://pcjericks.github.io/py-gdalogr-cookbook/geometry.html#create-a-polygon 77 | -------------------------------------------------------------------------------- /Standalone applications using QGIS and environment variables.md: -------------------------------------------------------------------------------- 1 | 2 | From [Standalone applications using QGIS and environment variables](http://gis.stackexchange.com/questions/77660/standalone-applications-using-qgis-and-environment-variables) 3 | 4 | Consulting the PyQGis documentation, you’ll find that there are four main ways to utilize the PyQGis API: 5 | 6 | 1. via commands in the Python console 7 | 2. via Python scripts in Processing or with the [ScritRunner][1] plugin of Gary Sherman 8 | 3. via development of custom plugins to the QGis application 9 | 4. outside QGIS (in the Python shell or creating an applications with PyQt4 and not Tkinter (why import Tkinter twice ?) 10 | 11 | and you are interested in this last point: 12 | 13 | - you can use PyQGIS as any other Python module. But Python does not know where to find PyQGIS. For that, you need to add the PyQGIS folder to the PYTHONPATH (for Windows, look at [How to add to the pythonpath in windows 7?][2]). 14 | 15 | > Certainly ArcPy doesn't require people to mess around with the computer's environmental settings, so I'm having difficulty understanding why PyQGIS does 16 | 17 | Because you use the Python version of ArcGIS, in other cases, the same is true, look [using arcpy outside arcmap][3] or [Configure PyScripter to use with QGIS (and still use arcpy) on Windows][4], for example. 18 | 19 | You don't need here PyQt4, Tkinter or qgis.gui: 20 | 21 | ```Python 22 | 23 | from qgis.core import * 24 | QgsApplication.setPrefixPath("yourpath", True) 25 | QgsApplication.initQgis() 26 | # or your solution 27 | # read a shapefile 28 | layer = QgsVectorLayer('your.shp', 'your', 'ogr') 29 | layer.isValid() 30 | True 31 | # loop through layer 32 | for elem in layer.getFeatures(): 33 | geom= elem.geometry() 34 | attr =elem.attributes() 35 | (processing) 36 | 37 | # interaction with other Python module: Shapely, for example 38 | from shapely.geometry import shape 39 | from json import loads 40 | for elem in layer.getFeatures(): 41 | shapely_geometry = shape(loads(elem.geometry().exportToGeoJSON())) 42 | ``` 43 | 44 | - you can create an application. You need here PyQt4 (and not Tkinter) and qgis.gui. 45 | 46 | > I would like to program a standalone application using PyQGIS the way I can already program standalone applications using ArcPy. 47 | 48 | So, for that, you must learn PyQt4 , as you have to learn Tkinter (or wxPython), for example. This is another problem: the solution given by gsherman is a problem of PyQt4, not of PyQGIS (look at [PyQt4 tutorial][5], for example) 49 | 50 | 51 | 52 | 53 | 54 | 55 | [1]: http://plugins.qgis.org/plugins/scriptrunner/ 56 | [2]: http://stackoverflow.com/questions/3701646/how-to-add-to-the-pythonpath-in-windows-7 57 | [3]: http://gis.stackexchange.com/questions/18781/using-arcpy-outside-arcmap 58 | [4]: http://mapoholic.wordpress.com/2012/06/28/configure-pyscripter-qgis/ 59 | [5]: http://zetcode.com/gui/pyqt4/ 60 | -------------------------------------------------------------------------------- /Is it possible to open rasters as array in NumPy without using another library?.md: -------------------------------------------------------------------------------- 1 | from [Is it possible to open rasters as array in NumPy without using another library?](http://gis.stackexchange.com/questions/76919/is-it-possible-to-open-rasters-as-array-in-numpy-without-using-another-library) 2 | 3 | 4 | Numpy is made for processing arrays and not for reading image files. You need other modules to read the raster and convert it to an array. 5 | 6 | If you do not want use GDAL or ArcPy: 7 | 8 | - Numpy use Scipy for that: [Image manipulation and processing using Numpy and Scipy][1] 9 | 10 | ```python 11 | 12 | from scipy import misc 13 | raster = misc.imread('image.tif') 14 | type(raster) 15 | 16 | ``` 17 | 18 | 19 | from [Is it possible to open rasters as array in NumPy without using another library?](http://gis.stackexchange.com/questions/76919/is-it-possible-to-open-rasters-as-array-in-numpy-without-using-another-library/76937) 20 | 21 | - but you can also use the [Python Image Library or PIL][2], forked in [Pillow][3]: see [Python for graphics][4] 22 | 23 | ```python 24 | 25 | import Image 26 | import numpy as np 27 | raster =Image.open('image.tif') 28 | print raster.format, raster.size, raster.mode, raster.info 29 | TIFF (330, 440) P {'compression': 'raw', 'dpi': (300, 300) 30 | imarray=np.array(raster) 31 | type(imarray) 32 | 33 | ``` 34 | 35 | - you can also use [matplotlib][7], only png file natively, using PIL for the others 36 | 37 | ```python 38 | 39 | 40 | import matplotlib.pyplot as plt 41 | imarray = plt.imread('image.tif') 42 | type(imarray) 43 | 44 | 45 | 46 | ``` 47 | 48 | - and a lot of other modules as [OpenCV][5]: see [Numpy Tips and Tricks][6] 49 | 50 | ```python 51 | 52 | import cv2 53 | im = cv2.imread("image.tif") 54 | type(im) 55 | 56 | ``` 57 | 58 | 59 | If you use Python 3.3 you can use [Pillow][8] or the last version of Scipy (> 0.12) 60 | 61 | ![enter image description here][9] 62 | 63 | But you have no information about the georeferencing parameters of the raster 64 | 65 | ```python 66 | 67 | from osgeo import gdal 68 | raster = gdal.Open("image.tif") 69 | imarray = np.array(raster.ReadAsArray()) 70 | type(imarray) 71 | 72 | # georeferencing parameters 73 | geotransform = raster.GetGeoTransform() 74 | print geotransform 75 | (162012.67788132755, 1.00078911763392, 0.0, 108172.86938540942, 0.0, -1.00078911763392) 76 | ``` 77 | 78 | 79 | 80 | [1]: http://scipy-lectures.github.io/advanced/image_processing/ 81 | [2]: http://effbot.org/zone/pil-changes-116.htm 82 | [3]: https://pypi.python.org/pypi/Pillow/2.2.1 83 | [4]: http://dmr.ath.cx/gfx/python/ 84 | [5]: http://opencv.org/#numpy-and-opencv 85 | [6]: http://jayrambhia.com/blog/numpy-tricks/ 86 | [7]: http://matplotlib.org/users/image_tutorial.html 87 | [8]: https://pypi.python.org/pypi/Pillow/2.2.1 88 | [9]: http://i.stack.imgur.com/cW0Bo.jpg 89 | -------------------------------------------------------------------------------- /OGR: retrieved feature is NoneType.md: -------------------------------------------------------------------------------- 1 | from [Python GDAL/OGR: retrieved feature is NoneType](http://gis.stackexchange.com/questions/65832/python-gdal-ogr-retrieved-feature-is-nonetype/65847) 2 | 3 | 4 | It is a pure Python problem and not an GDAL/OGR problem. But if you want to program in Python,you need to understand the difference between an iterator and an iterable (many, many references on the Web, but one of the best is [Loop Like A Native][1] by Ned Batchelder). These are fundamental concepts in Python. 5 | 6 | 7 | > "The important operation on an iterable is **iter()**, which will return an iterator. And the only operation available on an iterator is **next()**, which either returns the next value, or raises StopIteration, a special exception that means the iteration is finished." (from Ned Batchelder) 8 | 9 | An iterable produces an iterator and an iterator produces a stream of values. 10 | 11 | **So what's the difference between the for loop and pointsLayer.GetNextFeature() ?** 12 | 13 | **the for loops = iterator and pointsLayer= iterable** 14 | 15 | ```python 16 | 17 | for feature in iterable: 18 | statements 19 | ``` 20 | so with your example: 21 | 22 | ```python 23 | from osgeo import ogr 24 | source = ogr.Open('yourpointshapefile.shp') 25 | pointsLayer = source.GetLayer() 26 | for feature in pointsLayer: 27 | geom =feature.GetGeometryRef() 28 | xy = geom.GetPoint() 29 | print xy 30 | 31 | (272022.68669955182, 155404.12013724342, 0.0) 32 | (272904.99338241993, 152881.6706538822, 0.0) 33 | ..... 34 | (272796.14718989708, 152075.00336062044, 0.0) 35 | ``` 36 | 37 | 38 | [1]: http://nedbatchelder.com/text/iter.html 39 | 40 | But we can create another type of iterator with iter() and next(): 41 | 42 | ```python 43 | 44 | source = ogr.Open('yourpointshapefile.shp') 45 | pointsLayer = source.GetLayer() 46 | iterator = iter(pointsLayer) 47 | # first feature in pointsLayer 48 | feature = iterator.next() 49 | geom = feature.GetGeometryRef() 50 | xy = geom.GetPoint() 51 | print xy 52 | (272022.68669955182, 155404.12013724342, 0.0) 53 | # second feature in pointsLayer 54 | feature = iterator.next() 55 | geom = feature.GetGeometryRef() 56 | xy = geom.GetPoint() 57 | print xy 58 | (272904.99338241993, 152881.6706538822, 0.0) 59 | .... 60 | # end raises StopIteration error to signal that iteration is complete 61 | feature = iterator.next() 62 | Traceback (most recent call last): 63 | ... 64 | StopIteration 65 | ``` 66 | 67 | Unlike the for loop that handles the StopIteration error, you need here another control structure (while loop,if,...) 68 | 69 | **Thus, what is pointsLayer.GetNextFeature() ?** 70 | 71 | It is an iterator and you can replace iterator = iter(pointsLayer) and iterator.next() by 72 | 73 | ```python 74 | 75 | feature = pointsLayers.GetNextFeature() 76 | geom = feature.GetGeometryRef() 77 | xy = geom.GetPoint() 78 | ..... 79 | feature = pointsLayers.GetNextFeature() 80 | .... 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /Is it possible to route shapefiles using python and without ArcGIS, QGIS, or Pgrouting?.md: -------------------------------------------------------------------------------- 1 | from [Is it possible to route shapefiles using python and without ArcGIS, QGIS, or Pgrouting?](http://gis.stackexchange.com/questions/65056/is-it-possible-to-route-shapefiles-using-python-and-without-arcgis-qgis-or-pgr/65087) 2 | 3 | The link given by MappaGnosis is the first attempt to implement Graph theory algorithms in Python (by Guido van Rossum, the creator of Python). 4 | 5 | Since, many modules were developed: 6 | 7 | - [Graph theory][1] 8 | - [network][2] 9 | - [routing network][3] 10 | 11 | One of the most comprehensive is [NetworkX][4], mentioned before in GS 12 | 13 | - it can read or write shapefiles natively (thanks to bwreilly in [nx_spatial][5]) 14 | - all the graph algorithms are implemented ([Graph traversal][6], [Shortests Paths][7] with the A* algorithm and many more) 15 | 16 | ```python 17 | 18 | import networkx as nx 19 | graph = nx.read_shp('lines.shp') 20 | print graph.nodes() 21 | [(1.0, 2.0), (3.0, 2.0),...] 22 | print graph.edges() 23 | [((1.0, 2.0), (1.0, 1.0)),...] 24 | ``` 25 | 26 | Result with matplotlib 27 | ![enter image description here][8] 28 | 29 | Result with graphviz: 30 | ![enter image description here][9] 31 | 32 | A* Algorithm 33 | 34 | ```python 35 | 36 | def dist(a, b): 37 | (x1, y1) = a 38 | (x2, y2) = b 39 | return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5 40 | 41 | print(nx.astar_path(graph,(3.0,2.0),(1.0, 1.0),dist)) 42 | [(3.0, 2.0), (2.0, 1.0), (1.0, 1.0)] 43 | ``` 44 | 45 | and you can export the results: 46 | 47 | to shapefiles: 48 | 49 | ```python 50 | 51 | nx.write_shp(graph, ‘/shapefiles’) 52 | ``` 53 | 54 | to ogr geometries: 55 | 56 | ```python 57 | from osgeo import ogr 58 | line = osgeo.ogr.Geometry(ogr.wkbLineString) 59 | from points in (nx.astar_path(graph,(3.0,2.0),(1.0, 1.0),dist)): 60 | line.AddPoint(points[0],points[1]) 61 | 62 | print line.ExportToWkt() 63 | LINESTRING (3 2 0,2 1 0,1 1 0) 64 | ``` 65 | 66 | or to [shapely][10] geometries: 67 | 68 | ```python 69 | 70 | from shapely.geometry import LineString 71 | line = LineString(nx.astar_path(graph,(3.0,2.0),(1.0, 1.0),dist)) 72 | print line.wkt 73 | LINESTRING (3.00 2.00, 2.00 1.00, 1.00 1.00) 74 | ``` 75 | 76 | ![enter image description here][11] 77 | 78 | 79 | 80 | 81 | [1]: http://wiki.python.org/moin/PythonGraphApi 82 | [2]: https://pypi.python.org/pypi?:action=search&term=network&submit=search 83 | [3]: https://pypi.python.org/pypi?:action=search&term=routing%20network&submit=search 84 | [4]: http://networkx.github.io/documentation/latest/reference/index.html 85 | [5]: https://bitbucket.org/gallipoli/nx_spatial/wiki/Home 86 | [6]: http://networkx.lanl.gov/reference/algorithms.traversal.html 87 | [7]: http://networkx.lanl.gov/reference/algorithms.shortest_paths.html 88 | [8]: http://i.stack.imgur.com/3dVYG.png 89 | [9]: http://i.stack.imgur.com/gEvg4.png 90 | [10]: http://toblerity.github.io/shapely/manual.html 91 | [11]: http://i.stack.imgur.com/um8uh.png 92 | -------------------------------------------------------------------------------- /OGR Layer Intersection.md: -------------------------------------------------------------------------------- 1 | From [OGR Layer Intersection](http://gis.stackexchange.com/questions/82935/ogr-layer-intersection) 2 | 3 | There are some errors in your script but it is not the most important problem: 4 | 5 | You cannot create a valid shapefile without specifying the geometry of the layer: 6 | 7 | ```Python 8 | driver = ogr.GetDriverByName('ESRI Shapefile') 9 | dstshp = driver.CreateDataSource('SomeFilename.shp') 10 | dstlayer = dstshp.CreateLayer('mylayer',geom_type=ogr.wkbPolygon) 11 | ``` 12 | 13 | And you don't know a priory the geometry of the resulting intersection layer. The intersection of two polygon layers is different from the intersection of a polygon layer and a polyline layer for example. 14 | 15 | For that, you can get the geometry of the intersection by: 16 | 17 | For example (with two polygons shapefiles): 18 | 19 | ```Python 20 | layer1.GetGeomType() 21 | 3 # -> polygon 22 | # create an empty geometry of the same type 23 | union1=ogr.Geometry(3) 24 | # union all the geometrical features of layer 1 25 | for feat in layer1: 26 | geom =feat.GetGeometryRef() 27 | union1 = union1.Union(geom) 28 | # same for layer2 29 | union2=ogr.Geometry(layer2.GetGeomType()) 30 | for feat in layer2: 31 | geom =feat.GetGeometryRef() 32 | union2 = union2.Union(geom) 33 | # intersection 34 | intersection = union1.Intersection(union2) 35 | print intersection.GetGeometryName() 36 | 'MultiPolygon' 37 | ``` 38 | 39 | At this stage, you can save the resulting geometry to a shapefile (without the fields of the original layers): 40 | 41 | ```Python 42 | 43 | dstshp = driver.CreateDataSource('SomeotherFilename.shp') 44 | dstlayer = dstshp.CreateLayer('mylayer',geom_type=ogr.wkbMultiPolygon) 45 | ``` 46 | 47 | 48 | But if you want to use your script (a MultiPolygon is a collection of Polygons): 49 | 50 | ```Python 51 | driver = ogr.GetDriverByName('ESRI Shapefile') 52 | dstshp = driver.CreateDataSource('SomeFilename.shp') 53 | dstlayer = dstshp.CreateLayer('mylayer',geom_type=ogr.wkbPolygon) 54 | for feature1 in layer1: 55 | geom1 = feature1.GetGeometryRef() 56 | attribute1 = feature1.GetField('FieldName1') 57 | for feature2 in layer2: 58 | geom2 = feature2.GetGeometryRef() 59 | attribute2 = feature2.GetField('FieldName2') 60 | # select only the intersections 61 | if geom2.Intersects(geom1): 62 | intersection = geom2.Intersection(geom1) 63 | dstfeature = ogr.Feature(dstlayer.GetLayerDefn()) 64 | dstfeature.SetGeometry(intersection) 65 | dstfeature.setField(attribute1) 66 | dstfeature.setField(attribute2) 67 | dstfeature.Destroy() 68 | ``` 69 | 70 | Don't forget to define the fields before (look at [Python GDAL/OGR Cookbook:Vector Layers][1]). And it is much easier with the module [Fiona][2] 71 | 72 | 73 | 74 | 75 | [1]: http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html#create-a-new-shapefile-and-add-data 76 | [2]: http://toblerity.org/fiona/manual.html 77 | -------------------------------------------------------------------------------- /How to add Direction and Distance to attribute table?.md: -------------------------------------------------------------------------------- 1 | From [How to add Direction and Distance to attribute table?](http://gis.stackexchange.com/questions/24260/how-to-add-direction-and-distance-to-attribute-table) 2 | 3 | You do not need a plugin. Everything is in the class QgsPoint of PyQGIS 4 | 5 | If you examine the contents of a QGIS point class with the Python built-in function dir() in the Python Console. 6 | 7 | ```python 8 | dir(point]) 9 | ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__' 10 | , '__getitem__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__module__', 11 | '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 12 | '__str__', '__subclasshook__', '__weakref__', 'azimuth', 13 | 'multiply', 'set', 'setX', 'setY', 'sqrDist', 'sqrDistToSegment', 'toDegreesMinutesSeconds', 'toString', 'wellKnownText', 'x', 'y'] 14 | 15 | ``` 16 | You can see there are **azimuth** and **sqrDist** functions and after a few tries: 17 | 18 | - xy[0].azimuth(xy[1]) or xy[1].azimuth(xy[0]) gives the azimuth direction between two points(in degrees, +/- 180°) 19 | - xy[0].sqrDist(xy[1]) give the square distance between two points (in the unit of the project) 20 | 21 | The problem 22 | ![enter image description here][1] 23 | 24 | 25 | So in the Python console 26 | 27 | ```python 28 | 29 | def select_all(layer): 30 | layer.select([]) 31 | layer.setSelectedFeatures([obj.id() for obj in layer]) 32 | 33 | myline = qgis.utils.iface.activeLayer() 34 | select_all(myline) 35 | for elem in myline.selectedFeatures(): 36 | xy = elem.geometry().asPolyline() 37 | ``` 38 | 39 | now xy contains all the nodes (points) of the line 40 | 41 | ```python 42 | # first point 43 | print "x=%2d y=%2d" % (xy[0].x(),xy[0].y()) 44 | x=112935 y=117784 45 | # and others... 46 | ``` 47 | 48 | Using all node points of the line: 49 | 50 | 1) azimuth point i to point i + 1 (+/- 180°) (nodes of a line) 51 | 52 | ```python 53 | for i in range(len(xy)-1): 54 | print "x=%2d y=%2d azim=%6.1f azim2=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].azimuth(xy[i+1]), xy[i+1].azimuth(xy[i])) 55 | 56 | x=112935 y=117784 azim= 168.4 azim2= -11.6 57 | x=113032 y=117312 azim=-167.5 azim2= 12.5 58 | x=112926 y=116835 azim= 177.3 azim2= -2.7 59 | x=112943 y=116472 azim= 145.1 azim2= -34.9 60 | [...] 61 | ``` 62 | 2) euclidean distance between point i and point i + 1 63 | 64 | ```python 65 | for i in range(len(xy)-1): 66 | print "x=%2d y=%2d dist=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].sqrDist(xy[i+1])) 67 | 68 | x=112935 y=117784 dist=232533.9 69 | x=113032 y=117311 dist=238243.6 70 | x=112926 y=116835 dist=131839.8 71 | x=112943 y=116472 dist=209268.1 72 | [...] 73 | ``` 74 | 75 | After, it is not very difficult to add these values to the attribute table. 76 | 77 | I use this technique to analyze the lineaments (geology) with matplotlib and the Script Runner plugin 78 | 79 | ![enter image description here][2] 80 | 81 | 82 | [1]: http://i.stack.imgur.com/2qeVk.png 83 | [2]: http://i.stack.imgur.com/d6LyM.png 84 | -------------------------------------------------------------------------------- /Python-GDAL/OGR:retrieved feature is NoneType.md: -------------------------------------------------------------------------------- 1 | from [Python GDAL/OGR: retrieved feature is NoneType](http://gis.stackexchange.com/questions/65832/python-gdal-ogr-retrieved-feature-is-nonetype/65847) 2 | 3 | 4 | It is a pure Python problem and not an GDAL/OGR problem. But if you want to program in Python,you need to understand the difference between an iterator and an iterable (many, many references on the Web, but one of the best is [Loop Like A Native][1] by Ned Batchelder). These are fundamental concepts in Python. 5 | 6 | 7 | > "The important operation on an iterable is **iter()**, which will return an iterator. And the only operation available on an iterator is **next()**, which either returns the next value, or raises StopIteration, a special exception that means the iteration is finished." (from Ned Batchelder) 8 | 9 | An iterable produces an iterator and an iterator produces a stream of values. 10 | 11 | **So what's the difference between the for loop and pointsLayer.GetNextFeature() ?** 12 | 13 | **the for loops = iterator and pointsLayer= iterable** 14 | 15 | ```python 16 | 17 | for feature in iterable: 18 | statements 19 | ``` 20 | so with your example: 21 | 22 | ```python 23 | from osgeo import ogr 24 | source = ogr.Open('yourpointshapefile.shp') 25 | pointsLayer = source.GetLayer() 26 | for feature in pointsLayer: 27 | geom =feature.GetGeometryRef() 28 | xy = geom.GetPoint() 29 | print xy 30 | 31 | (272022.68669955182, 155404.12013724342, 0.0) 32 | (272904.99338241993, 152881.6706538822, 0.0) 33 | ..... 34 | (272796.14718989708, 152075.00336062044, 0.0) 35 | ``` 36 | 37 | 38 | [1]: http://nedbatchelder.com/text/iter.html 39 | 40 | But we can create another type of iterator with iter() and next(): 41 | 42 | ```python 43 | 44 | source = ogr.Open('yourpointshapefile.shp') 45 | pointsLayer = source.GetLayer() 46 | iterator = iter(pointsLayer) 47 | # first feature in pointsLayer 48 | feature = iterator.next() 49 | geom = feature.GetGeometryRef() 50 | xy = geom.GetPoint() 51 | print xy 52 | (272022.68669955182, 155404.12013724342, 0.0) 53 | # second feature in pointsLayer 54 | feature = iterator.next() 55 | geom = feature.GetGeometryRef() 56 | xy = geom.GetPoint() 57 | print xy 58 | (272904.99338241993, 152881.6706538822, 0.0) 59 | .... 60 | # end raises StopIteration error to signal that iteration is complete 61 | feature = iterator.next() 62 | Traceback (most recent call last): 63 | ... 64 | StopIteration 65 | ``` 66 | 67 | Unlike the for loop that handles the StopIteration error, you need here another control structure (while loop,if,...) 68 | 69 | **Thus, what is pointsLayer.GetNextFeature() ?** 70 | 71 | It is an iterator and you can replace iterator = iter(pointsLayer) and iterator.next() by 72 | 73 | ```python 74 | 75 | feature = pointsLayers.GetNextFeature() 76 | geom = feature.GetGeometryRef() 77 | xy = geom.GetPoint() 78 | ..... 79 | feature = pointsLayers.GetNextFeature() 80 | .... 81 | ``` 82 | 83 | 84 | **I hope that I have been able to explain why you should not mix the for loops (iterator) with .GetNextFeature() (another iterator)**. 85 | -------------------------------------------------------------------------------- /How to find the polygons bordering a feature programmatically with qgis?.md: -------------------------------------------------------------------------------- 1 | From [How to find the polygons bordering a feature programmatically with qgis?](http://gis.stackexchange.com/questions/86591/how-to-find-the-polygons-bordering-a-feature-programmatically-with-qgis) 2 | 3 | In the given solution, Ujaval Gandhi uses [shapely][1] to find all neighboring polygons of each of the polygons in a layer (function shapely [object.touches(other)][2]). 4 | 5 | In PyQGIS 2.x, this function is available (function PyQGIS `object.touches(other)`) 6 | 7 | An example: 8 | 9 | ![enter image description here][3] 10 | 11 | For iterating over the features/geometry and compare polygon by polygon I will use the standard [itertools][4] module in the console: 12 | 13 | ```python 14 | layer = qgis.utils.iface.activeLayer() 15 | import itertools 16 | # with itertools permutations, length of the permutations(2) in this case. 17 | for geom1,geom2 in itertools.permutations(layer.getFeatures(),r=2): 18 | if geom1.geometry().touches(geom2.geometry()): 19 | print geom1.attributes(),geom2.attributes() 20 | [3] [1] 21 | [2] [1] 22 | [1] [3] 23 | [1] [2] 24 | # with itertools combinations, length of the combinations(2) in this case. 25 | for geom1,geom2 in itertools.combinations(layer.getFeatures(),r=2): 26 | if geom1.geometry().touches(geom2.geometry()): 27 | print geom1.attributes(),geom2.attributes() 28 | layer.select(geom1.id()) 29 | [3] [1] 30 | [2] [1] 31 | 32 | ``` 33 | ![enter image description here][11] 34 | 35 | no neighbours (function `disjoint`): 36 | 37 | ```python 38 | 39 | for geom1,geom2 in itertools.combinations(layer.getFeatures(),r=2): 40 | if geom1.geometry().disjoint(geom2.geometry()): 41 | print geom1.attributes(),geom2.attributes() 42 | [4] [3] 43 | [4] [2] 44 | [4] [1] 45 | [3] [2] 46 | ``` 47 | 48 | And the intersections: 49 | 50 | ```python 51 | 52 | for geom1,geom2 in itertools.combinations(layer.getFeatures(),r=2): 53 | if geom1.geometry().intersects(geom2.geometry()): 54 | print geom1.attributes(),geom2.attributes() 55 | [3] [1] 56 | [2] [1] 57 | 58 | ``` 59 | 60 | ![enter image description here][18] 61 | 62 | 63 | [1]: http://gispython.org/shapely/manual.html 64 | [2]: http://toblerity.org/shapely/manual.html#object.touches 65 | [3]: http://i.stack.imgur.com/Pv0S3.jpg 66 | [4]: http://pythonarticles.com/itertools.html 67 | [5]: http://gispython.org/shapely/manual.html 68 | [6]: http://gispython.org/shapely/manual.html 69 | [7]: http://i.stack.imgur.com/Pv0S3.jpg 70 | [8]: http://toblerity.org/shapely/manual.html#object.touches 71 | [9]: http://gispython.org/shapely/manual.html 72 | [10]: http://gispython.org/shapely/manual.html 73 | [11]: http://i.stack.imgur.com/rvr9w.jpg 74 | [12]: http://i.stack.imgur.com/Pv0S3.jpg 75 | [13]: http://toblerity.org/shapely/manual.html#object.touches 76 | [14]: http://gispython.org/shapely/manual.html 77 | [15]: http://toblerity.org/shapely/manual.html#object.touches 78 | [16]: http://gispython.org/shapely/manual.html 79 | [17]: http://gispython.org/shapely/manual.html 80 | [18]: http://i.stack.imgur.com/kGUEk.jpg 81 | -------------------------------------------------------------------------------- /Save input in plugin as pdf format file.md: -------------------------------------------------------------------------------- 1 | From [Save input in plugin as pdf format file](http://gis.stackexchange.com/questions/81621/save-input-in-plugin-as-pdf-format-file/) 2 | 3 | 4 | You need a Python script to to convert your resulting text file in PDF or a Python module to write pdf files and there are many... (look at [PiPY:pdf][1]). 5 | 6 | ####1) first solution with a Python script: 7 | 8 | - [Text to PDF Converter (rewrite) (Python recipe) ][10], for example. 9 | 10 | ####2) second solution with a Python module 11 | 12 | The problem is that you need to install the module in the Python used by QGIS (easy in Mac OS X or Linux, difficult in Windows) or in the folder of your plugin. 13 | 14 | - the most complete module is [reportlab][7], but it is difficult to use (look at [reportlab-userguide.pdf][8]) 15 | 16 | - One of the easiest is the pure Python [PyFPDF][2] module (it is used by Joel Lawhead in his book, [Learning Geospatial Analysis with Python][3], to produce PDF reports with maps) 17 | 18 | ```python 19 | 20 | 21 | def _save(self, simpan): 22 | import fpdf 23 | # Portrait, millimeter units, A4 page size 24 | pdf=fpdf.FPDF("P", "mm", "A4") 25 | # Set font: Times, normal, size 10 26 | pdf.set_font('Times','', 10) 27 | # Layout cell: 0 x 5 mm, text, no border, Left 28 | pdf.cell(0,5,'Input 1 : ' + self.ui.lineInput1.text(), border=0, align="L" ) 29 | pdf.cell(0,5,'Input 2 : ' + self.ui.lineInput2.text(), border=0, align="L") 30 | pdf.cell(0,5,'Recomendation : ' + (str(compare), border=0, align="L") 31 | pdf.cell(0,5,'Data 1 :' + self.ui.lineCond1.text(), border=0, align="L" ) 32 | pdf.cell(0,5,'Data 2 :' + self.ui.lineCond2.text(), border=0, align="L" ) 33 | pdf.output( simpan+'.pdf','F') 34 | 35 | ``` 36 | 37 | - Another solution is to use the single file [PDFWriter.py][4] from the [xtopdf][5] toolkit (as easy as [PyFPDF][6], but it requires the [reportlab][7] module) of [Vasudev Ram][9] but I do not know if you can use a single file and you must install [reportlab][7]... 38 | 39 | ```python 40 | 41 | def _save(self, simpan): 42 | from PDFWriter import PDFWriter 43 | pw = PDFWriter(simpan+'.pdf') 44 | pw.setFont("Courier", 10) 45 | pw.writeLine('Input 1 : ' + self.ui.lineInput1.text() ) 46 | pw.writeLine('Input 2 : ' + self.ui.lineInput2.text() ) 47 | pw.writeLine('Recomendation :' + (str(compare)) 48 | pw.writeLine('Data 1 : ' + self.ui.lineCond1.text() ) 49 | pw.writeLine('Data 2 : ' + self.ui.lineCond2.text() ) 50 | pw.close 51 | 52 | ``` 53 | 54 | 55 | [1]: https://pypi.python.org/pypi?:action=search&term=Pdf&submit=search 56 | [2]: http://code.google.com/p/pyfpdf/ 57 | [3]: http://www.packtpub.com/learning-geospatial-analysis-with-python/book 58 | [4]: https://bitbucket.org/vasudevram/xtopdf/src/854a19c557af9040d74e23c10fa2a6d108d77c68/PDFWriter.py?at=default 59 | [5]: https://bitbucket.org/vasudevram/xtopdf 60 | [6]: http://code.google.com/p/pyfpdf/ 61 | [7]: https://bitbucket.org/rptlab/reportlab 62 | [8]: https://www.reportlab.com/docs/reportlab-userguide.pdf 63 | [9]: http://jugad2.blogspot.be/ 64 | [10]: http://code.activestate.com/recipes/532908/ 65 | -------------------------------------------------------------------------------- /Display a georeferenced DEM surface in 3D matplotlib.md: -------------------------------------------------------------------------------- 1 | From [Display a georeferenced DEM surface in 3D matplotlib](http://gis.stackexchange.com/questions/66367/display-a-georeferenced-dem-surface-in-3d-matplotlib) 2 | 3 | Matplotlib knows nothing about georeferenced surfaces, it only knows x,y,z coordinates. You can also use [Visvis][1] or [Mayavi][2]. 4 | 5 | - the original DEM 6 | 7 | ![enter image description here][3] 8 | 9 | - you must first extract the x,y, z coordinates of the grid ( a raster is a grid of pixels and with a DEM, the value of the pixel is the elevation, z) with osgeo.gdal. No script here because it is possible to find the solutions on Gis StackExchange or on the web. 10 | 11 | - after, you can plot the points in 3D 12 | 13 | ```Python 14 | from mpl_toolkits.mplot3d.axes3d import * 15 | import matplotlib.pyplot as plt 16 | from matplotlib import cm 17 | fig = plt.figure() 18 | ax = Axes3D(fig) 19 | ax.scatter3D(x,y,z,c=z,cmap=plt.cm.jet) 20 | plt.show() 21 | ``` 22 | 23 | ![enter image description here][4] 24 | 25 | - and you must reconstruct a 3D grid (surface) with the function griddata of matplotlib (Delaunay) 26 | 27 | ```Python 28 | import numpy as np 29 | from matplotlib.mlab import griddata 30 | # craation of a 2D grid 31 | xi = np.linspace(min(x), max(x)) 32 | yi = np.linspace(min(y), max(y)) 33 | X, Y = np.meshgrid(xi, yi) 34 | # interpolation 35 | Z = griddata(x, y, z, xi, yi) 36 | fig = plt.figure() 37 | ax = Axes3D(fig) 38 | ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,linewidth=1, antialiased=True) 39 | plt.show() 40 | ``` 41 | The grid (with visvis): 42 | 43 | ![enter image description here][5]! 44 | 45 | The coloured grid (with matplotlib): 46 | 47 | ![enter image description here][6] 48 | 49 | - but you can also use others interpolation algorithms (Scipy thin-plate spline here) and drape colours 50 | 51 | ```Python 52 | import scipy as sp 53 | import scipy.interpolate 54 | # 2D grid construction 55 | spline = sp.interpolate.Rbf(x,y,z,function='thin-plate') 56 | xi = np.linspace(min(x), max(x)) 57 | yi = np.linspace(min(y), max(y)) 58 | X, Y = np.meshgrid(xi, yi) 59 | # interpolation 60 | Z = spline(X,Y) 61 | ``` 62 | 63 | ![enter image description here][7] 64 | 65 | With [Visvis][8], you can make animations: 66 | 67 | ![enter image description here][9] 68 | 69 | You can even plot the 3D contours: 70 | 71 | ![enter image description here][10] 72 | 73 | - Comparison between a projected DEM (with GRASS GIS, x 1) and the equivalent non projected DEM (x,y,z, with Visvis x 1) 74 | 75 | 76 | 77 | ![enter image description here][11] ![enter image description here][12] 78 | 79 | 80 | [1]: http://code.google.com/p/visvis/ 81 | [2]: http://code.enthought.com/projects/mayavi/ 82 | [3]: http://i.stack.imgur.com/TOfgK.jpg 83 | [4]: http://i.stack.imgur.com/CVTA4.jpg 84 | [5]: http://i.stack.imgur.com/QybsO.jpg 85 | [6]: http://i.stack.imgur.com/ZanzF.jpg 86 | [7]: http://i.stack.imgur.com/Bdj00.jpg 87 | [8]: http://code.google.com/p/visvis/ 88 | [9]: http://i.stack.imgur.com/BZYZH.gif 89 | [10]: http://i.stack.imgur.com/9RfoP.jpg 90 | [11]: http://i.stack.imgur.com/40dOl.jpg 91 | [12]: http://i.stack.imgur.com/asW5r.jpg 92 | -------------------------------------------------------------------------------- /How to create equidistant points in QGIS along a polygon?.md: -------------------------------------------------------------------------------- 1 | From [Python: How to create equidistant points in QGIS along a polygon?](gis.stackexchange.com/questions/81481/how-to-create-equidistant-points-in-qgis-along-a-polygon) 2 | 3 | You cannot use interpolate() with polygons: 4 | 5 | If you have a polygon: 6 | 7 | ```python 8 | geom.exportToGeoJSON() 9 | u'{ "type": "Polygon", "coordinates": [ [ [167546.39129160347511061, 156935.60758662305306643], [167464.55340823522419669, 154998.77768024150282145], [169183.148958968144143, 154698.70544122465071268], [167901.02211953248479404, 153498.41648515724227764], [167109.92258030621451326, 152734.59624038706533611], [165364.04773511723033153, 154725.98473568074405193], [167546.39129160347511061, 156935.60758662305306643] ] ] }' 10 | geom.asPolygon() 11 | [[(167546,156936), (167465,154999), (169183,154699), (167901,153498), (167110,152735), (165364,154726), (167546,156936)]] 12 | # interpolate 13 | geom.interpolate(100).asPoint() 14 | Traceback (most recent call last): 15 | File "", line 1, in 16 | AttributeError: 'NoneType' object has no attribute 'asPoint' 17 | ``` 18 | 19 | The LinearRing of the Polygon is: 20 | 21 | ```python 22 | 23 | LinearRing = QgsGeometry.fromPolyline(geom.asPolygon()[0]) 24 | LinearRing.exportToGeoJSON() 25 | u'{ "type": "LineString", "coordinates": [ [167546.39129160347511061, 156935.60758662305306643], [167464.55340823522419669, 154998.77768024150282145], [169183.148958968144143, 154698.70544122465071268], [167901.02211953248479404, 153498.41648515724227764], [167109.92258030621451326, 152734.59624038706533611], [165364.04773511723033153, 154725.98473568074405193], [167546.39129160347511061, 156935.60758662305306643] ] }' 26 | # interpolate 27 | LinearRing.interpolate(100).asPoint() 28 | (167542,156836) 29 | ``` 30 | 31 | Polygons: 32 | 33 | ![enter image description here][1] 34 | 35 | 36 | Part of a class to create memory layers from the Python console: 37 | 38 | ```python 39 | 40 | class Crea_layer(object): 41 | def __init__(self,nom,type): 42 | self.type=type 43 | self.name = nom 44 | self.layer = QgsVectorLayer(self.type, self.name , "memory") 45 | self.pr =self.layer.dataProvider() 46 | def create_point(self,geometry): 47 | self.seg = QgsFeature() 48 | self.seg.setGeometry(QgsGeometry.fromPoint(geometry)) 49 | self.pr.addFeatures([self.seg]) 50 | self.layer.updateExtents() 51 | @property 52 | def show_layer(self): 53 | QgsMapLayerRegistry.instance().addMapLayers([self.layer]) 54 | 55 | ``` 56 | 57 | Creation of the equidistant points (step = 100m) 58 | 59 | ```python 60 | 61 | polys = qgis.utils.iface.activeLayer() 62 | points = Crea_layer("equidistant", "Point") 63 | for feat in polys.getFeatures(): 64 | geom = feat.geometry() 65 | line = QgsGeometry.fromPolyline(geom.asPolygon()[0]) 66 | for distance in xrange(0,line.length(),100): 67 | point = line.interpolate(distance) 68 | point = point.asPoint() 69 | point.create_point(QgsPoint(point.x(),point.y())) 70 | 71 | points.show_layer 72 | ``` 73 | Result: 74 | 75 | ![enter image description here][2] 76 | 77 | 78 | 79 | [1]: http://i.stack.imgur.com/4Umdz.jpg 80 | [2]: http://i.stack.imgur.com/dCvZu.jpg 81 | -------------------------------------------------------------------------------- /Creating Shapely MultiPolygons from shape file MultiPolygons.md: -------------------------------------------------------------------------------- 1 | from [Creating Shapely MultiPolygons from shape file MultiPolygons](http://gis.stackexchange.com/questions/70591/creating-shapely-multipolygons-from-shape-file-multipolygons/70608) 2 | 3 | You can use the shape function of Shapely: 4 | 5 | ```python 6 | from shapely.geometry import shape 7 | c = fiona.open('data/boroughs/boroughs_n.shp') 8 | pol = c.next() 9 | geom = shape(pol['geometry']) 10 | 11 | ``` 12 | 13 | and a MultiPolygon is a list of Polygons,so 14 | 15 | 16 | ```python 17 | 18 | Multi = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('data/boroughs/boroughs_n.shp')]) 19 | 20 | ``` 21 | 22 | Example with one of my data: 23 | 24 | 25 | ```python 26 | 27 | # the dictionaries 28 | for pol in fiona.open('poly.shp'): 29 | print pol['geometry'] 30 | 31 | {'type': 'Polygon', 'coordinates': [[(249744.23153029341, 142798.16434689672), (250113.79108725351, 142132.95714436853), (250062.62130244367, 141973.76225829343), (249607.77877080048, 141757.71205576291), (249367.77424759799, 142304.68402918623), (249367.77424759799, 142304.68402918623), (249744.23153029341, 142798.16434689672)]]} 32 | {'type': 'Polygon', 'coordinates': [[(249175.78991730965, 142292.53526406409), (249367.77424759799, 142304.68402918623), (249607.77877080048, 141757.71205576291), (249014.45396077307, 141876.13484290778), (249175.78991730965, 142292.53526406409)]]} 33 | {'type': 'Polygon', 'coordinates': [[(249026.74622412826, 142549.13626160321), (249223.42243781092, 142496.89414234375), (249175.78991730965, 142292.53526406409), (249026.74622412826, 142549.13626160321)]]} 34 | ... 35 | 36 | ``` 37 | 38 | and 39 | 40 | 41 | ```python 42 | 43 | # MultiPolygon from the list of Polygons 44 | Multi = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('poly.shp')]) 45 | Multi.wkt 46 | 'MULTIPOLYGON (((249744.2315302934148349 142798.1643468967231456, 250113.7910872535139788 142132.9571443685272243, 250062.6213024436729029 141973.7622582934272941, 249607.7787708004761953 141757.7120557629095856, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249744.2315302934148349 142798.1643468967231456)), ((249175.7899173096520826 142292.5352640640921891, 249367.7742475979903247 142304.6840291862317827, 249607.7787708004761953 141757.7120557629095856, 249014.4539607730694115 141876.1348429077770561, 249175.7899173096520826 142292.5352640640921891)), ((249026.7462241282628383 142549.1362616032129154, 249223.4224378109211102 142496.8941423437499907, 249175.7899173096520826 142292.5352640640921891, 249026.7462241282628383 142549.1362616032129154)), ((249244.9338986824732274 142733.5202119307068642, 249744.2315302934148349 142798.1643468967231456, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249367.7742475979903247 142304.6840291862317827, 249175.7899173096520826 142292.5352640640921891, 249223.4224378109211102 142496.8941423437499907, 249244.9338986824732274 142733.5202119307068642)), ((249870.8182051893090829 142570.3083320840960369, 250034.3015973484434653 142613.6706442178401630, 250152.6146321419219021 142438.5058914067049045, 250015.3392731740023009 142310.1704097116598859, 249870.8182051893090829 142570.3083320840960369)))' 47 | 48 | ``` 49 | 50 | see also [Append support for MultiPolygons in shapefiles][1] 51 | 52 | 53 | [1]: https://github.com/Toblerity/Fiona/issues/18 54 | -------------------------------------------------------------------------------- /How to get field names in pyqgis 2.0.md: -------------------------------------------------------------------------------- 1 | From [How to get field names in pyqgis 2.0](http://gis.stackexchange.com/questions/76364/how-to-get-field-names-in-pyqgis-2-0) 2 | 3 | It is simpler than with version 1.8: 4 | 5 | ```python 6 | layer = qgis.utils.iface.activeLayer() 7 | fields = layer.pendingFields() 8 | field_names = [field.name() for field in fields] 9 | ``` 10 | 11 | or in one line 12 | 13 | ```python 14 | field_names = [field.name() for field in layer.pendingFields() ] 15 | ``` 16 | an after 17 | 18 | ```python 19 | 20 | for elem in layer.getFeatures(): 21 | print dict(zip(field_names, elem.attributes())) 22 | {u'adip': 17, u'dipdir': 130, u'tdip': 29} 23 | {u'adip': 55, u'dipdir': 325, u'tdip': 75} 24 | ..... 25 | ``` 26 | 27 | Generally to explore a new function, I use the dir() or the [see][1] module to examine what's inside: 28 | 29 | ```python 30 | dir(fields) 31 | ['FieldOrigin', 'OriginEdit', 'OriginJoin', 'OriginProvider', 'OriginUnknown', '__class__', '__delattr__', '__delitem__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'append', 'at', 'clear', 'count', 'extend', 'field', 'fieldOrigin', 'fieldOriginIndex', 'indexFromName', 'isEmpty', 'remove', 'size', 'toList'] 32 | ``` 33 | or 34 | 35 | ```python 36 | see(fields) 37 | [] hash() help() len() 38 | repr() str() .FieldOrigin() .OriginEdit 39 | .OriginJoin .OriginProvider .OriginUnknown .append() 40 | .at() .clear() .count() .extend() 41 | .field() .fieldOrigin() .fieldOriginIndex() 42 | .indexFromName() .isEmpty() .remove() .size() 43 | .toList() 44 | 45 | ``` 46 | 47 | And you can see that there is a field() function 48 | so 49 | 50 | ```python 51 | 52 | print fields.field(0) 53 | qgis.core.QgsField object at 0x163E39C0 54 | ``` 55 | 56 | 57 | and a field has a name, a type, a precision,...: 58 | 59 | ```python 60 | see(fields.field(0)) 61 | < <= == != > 62 | >= hash() help() repr() 63 | str() .comment() .displayString() .length() 64 | .name() .precision() .setComment() .setLength() 65 | .setName() .setPrecision() .setType() .setTypeName() 66 | .type() .typeName() 67 | ``` 68 | so: 69 | 70 | ```python 71 | fields.field(0).name() 72 | u'adip' 73 | fields.field(0).type() 74 | 2 75 | fields.field(0).typeName() 76 | u'Integer' 77 | fields.field(0).precision() 78 | 0 79 | .... 80 | ``` 81 | 82 | ---------------------------------- 83 | #with .dataProvider() 84 | 85 | It is .field() 86 | 87 | ```python 88 | .... 89 | prov = layer.dataProvider() 90 | prov.fields().field(0).name() 91 | u'adip' 92 | prov.fields().field(0).typeName() 93 | u'Integer' 94 | ``` 95 | 96 | and 97 | 98 | ```python 99 | 100 | field_names = [field.name() for field in prov.fields()] 101 | ``` 102 | 103 | 104 | [1]: https://github.com/inky/see 105 | -------------------------------------------------------------------------------- /Fiona - Preffered method for defining a schema.md: -------------------------------------------------------------------------------- 1 | From [Fiona - Preffered method for defining a schema](http://gis.stackexchange.com/questions/74858/fiona-preffered-method-for-defining-a-schema) 2 | 3 | 4 | I don't really understand your problem. Some explanations: for example, we want to 5 | 6 | 1. create a new shapefile 7 | 2. modify the original schema: for that, it's easier to just copy things to a new shapefile and make the changes as you copy 8 | 9 | - Create a new Polyline shapefile: 10 | 11 | ```python 12 | 13 | import fiona 14 | # schema: it is a simple dictionary with geometry and properties as keys 15 | schema = {'geometry': 'LineString','properties': {'test': 'int'}} 16 | # for defining the geometry, you need Shapely 17 | from shapely.geometry import LineString, mapping 18 | # two simples geometries 19 | lines = [LineString([(272830.63,155125.73),(273770.32,155467.75)]),LineString([(273536.47,155914.07),(272033.12,152265.71)])] 20 | with fiona.open('myshp.shp', 'w', 'ESRI Shapefile', schema) as layer: 21 | for line in lines: 22 | # filling schema 23 | elem = {} 24 | # geometry with mapping function of shapely 25 | elem['geometry'] = mapping(line) 26 | # attribute value (the same here) 27 | elem['properties'] = {'test': 145} 28 | # writing element in the file 29 | layer.write(elem) 30 | ``` 31 | 32 | - Now we want to modify the schema of the original shapefile in a new shapefile: 33 | 34 | 1) Open the original shapefile: 35 | 36 | ```python 37 | 38 | shapefile =fiona.open('myshp.shp') 39 | #read the schema 40 | schema2 = shapefile.schema 41 | print schema2 42 | {'geometry': 'LineString', 'properties': OrderedDict([(u'test', 'int:10')])} 43 | ``` 44 | 45 | 2) As it is a dictionary, it is easy to add new fields/keys in the properties: 46 | 47 | ```python 48 | 49 | schema2['properties']['string']='str' 50 | ``` 51 | 52 | 3) Now we create a new shapefile copying myshp.shp with the new schema : 53 | 54 | ```python 55 | 56 | with fiona.open('myshp.shp', 'r') as input: 57 | schema = schema2 58 | # writing the new shapefile 59 | with fiona.open('myshp_copy.shp', 'w', 'ESRI Shapefile', schema) as output: 60 | for elem in input: 61 | # add the new attribute value 62 | elem['properties']['string']="hello" 63 | output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))}) 64 | ``` 65 | 66 | - verification 67 | 68 | ```python 69 | 70 | c = fiona.open('myshp_copy.shp') 71 | c.schema 72 | {'geometry': 'LineString', 'properties': OrderedDict([(u'test', 'int:10'), (u'string', 'str')])} 73 | # first element of the shapefile 74 | c.next() 75 | {'geometry': {'type': 'LineString', 'coordinates': [(272830.63, 155125.73000000001), (273770.32000000001, 155467.75)]}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'test', 145), (u'string', u'hello')])} 76 | ``` 77 | 78 | - Conclusion 79 | 80 | If you don't want to modify the shapefile, it is easier with **schema.copy()** that is only used to get a copy of the original schema (no definition here) 81 | 82 | ```python 83 | with fiona.open('myshp.shp', 'r') as input: 84 | schema = input.schema.copy() 85 | with fiona.open('myshp_copy2.shp', 'w', 'ESRI Shapefile', schema) as output: 86 | for elem in input: 87 | output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))}) 88 | ``` 89 | -------------------------------------------------------------------------------- /Using the python shape library: pyshp - how to convert polygons in .csv file to .shp.md: -------------------------------------------------------------------------------- 1 | From [Using the python shape library: pyshp - how to convert polygons in .csv file to .shp](http://gis.stackexchange.com/questions/70786/using-the-python-shape-library-pyshp-how-to-convert-polygons-in-csv-file-to) 2 | 3 | 4 | Your approach is good, but you could make things clearer using dictionaries instead of list and the csv module allows it. 5 | Moreover, your script use two loops while it is possible to simplify using only one (the second loop is redundant, one line of the csv file = one record of the shapefile). 6 | 7 | **1) With dictionaries:** 8 | 9 | Reading the csv file: 10 | -------------------- 11 | 12 | ```python 13 | with open('your.csv', 'rb') as f: 14 | reader = csv.DictReader(f) 15 | for row in reader: 16 | print row 17 | {'xr': '22.5', 'yb': '31.353634', 'name': 'some Name', 'xl': '-25.3125', 'yt': '47.517193'} 18 | {'xr': '-0.703125', 'yb': '74.40216', 'name': 'another Name', 'xl': '-103.359375', 'yt': '80.87282'} 19 | ``` 20 | 21 | You can now use row['xr'] or row['name'] instead of row[n] (more explicit) 22 | 23 | So your script becomes: 24 | 25 | ```python 26 | 27 | import csv 28 | polyName, polyPart = [],[] 29 | with open('your.csv', 'rb') as f: 30 | reader = csv.DictReader(f) 31 | for row in reader: 32 | bl = [float(row['xl']),float(row['yb'])] 33 | tl = [float(row['xl']),float(row['yt'])] 34 | br = [float(row['xr']),float(row['yb'])] 35 | tr = [float(row['xr']),float(row['yt'])] 36 | parr = [tl, tr, br, bl, tl] 37 | polyName.append(row['name']) 38 | polyPart.append(parr) 39 | ``` 40 | 41 | Writing the polygon shapefile 42 | -------------------- 43 | 44 | If you look at [PyShpDocs][1] you can see that: 45 | 46 | A polygon is defined by: 47 | 48 | ```python 49 | 50 | w = shapefile.Writer(shapefile.POLYGON) 51 | w.line(parts=[[[1,5],[5,5],[5,1],[3,3],[1,1]]]) 52 | ``` 53 | 54 | and the script, as you wrote is: 55 | 56 | ```python 57 | 58 | import shapefile 59 | # create the Polygon shapefile 60 | w = shapefile.Writer(shapefile.POLYGON) 61 | # the field 62 | w.field('name','C',maxStringLength) 63 | # write the polygons in the shapefile 64 | for part,name in zip(polyPart, polyName): 65 | w.poly(parts=[part]) 66 | w.record(name) 67 | #save the shapefile 68 | w.save('your.shp') 69 | ``` 70 | 71 | **2) Final solution using only one loop** 72 | 73 | But the second loop is not necessary here: you can do it all with one loop (reading the csv file and writing the shapefile without using the polyName and polyPart lists). 74 | 75 | ```python 76 | w = shapefile.Writer(shapefile.POLYGON) 77 | w.field('name','C',50) 78 | with open('your.csv', 'rb') as f: 79 | reader = csv.DictReader(f) 80 | for row in reader: 81 | bl = [float(row['xl']),float(row['yb'])] 82 | tl = [float(row['xl']),float(row['yt'])] 83 | br = [float(row['xr']),float(row['yb'])] 84 | tr = [float(row['xr']),float(row['yt'])] 85 | parr = [tl, tr, br, bl, tl] 86 | w.poly(parts=[parr]) 87 | w.record(row['name']) 88 | 89 | w.save("your.shp') 90 | ``` 91 | 92 | 93 | Result in QGIS: 94 | 95 | ![enter image description here][2] 96 | 97 | 98 | [1]: http://code.google.com/p/pyshp/wiki/PyShpDocs 99 | [2]: http://i.stack.imgur.com/hNMLC.jpg 100 | -------------------------------------------------------------------------------- /How to create a 3D shapefile from a raster?.md: -------------------------------------------------------------------------------- 1 | From [How to create a 3D shapefile from a raster?] 2 | 3 | 4 | For the moment, the geometry system of QGIS does not handle z-values but z-coordinates can be read by parsing the binary format of the geometry (see [Why is it not possible to extract the z value of a wkb geometry with PyQGIS while it is possible with ogr or Shapely ?][1]) of which I take the example: 5 | 6 | With a 3D point shapefile in the Python console of QGIS: 7 | 8 | ```python 9 | 10 | mylayer = qgis.utils.iface.activeLayer() 11 | mylayer.geometryType() == QGis.Point 12 | True 13 | # select the first object 14 | sel = mylayer.selectedFeatures()[0] 15 | qgisgeom = sel.geometry() 16 | qgisgeom.wkbType() == QGis.WKBPoint 17 | False 18 | qgisgeom.wkbType() == QGis.WKBPoint25D 19 | True 20 | # QGIS recognizes that the WKB geometry is 3D but is is impossible to extract the z value 21 | qgisgeom.asPoint() 22 | (205553,89857.7) 23 | # no z in the functions of geom.asPoint, only x and y in dir() 24 | dir(qgisgeom.asPoint()) 25 | ['__class__', ..., 'x', 'y'] 26 | ``` 27 | 28 | But using other Python modules like osgeo.ogr or Shapely, you can extract the z value from the binary format of the QGIS geometry: 29 | 30 | ```python 31 | 32 | # with shapely 33 | from shapely.wkb import loads 34 | wkb = qgisgeom.asWkb() 35 | transfshapely = loads(wkb) 36 | transfshapely.has_z 37 | True 38 | list(transfshapely.coords) 39 | [(205552.628666262, 89857.66932836606, 222.1999969482422)] 40 | 41 | # with osgeo.ogr 42 | from osgeo import ogr 43 | wkb = qgisgeom.asWkb() 44 | geom_wkb = ogr.CreateGeometryFromWkb(wkb) 45 | geom_wkb.GetGeometryType() == ogr.wkbPoint25D 46 | True 47 | geom_wkb.GetX(),geom_wkb.GetY(),geom_wkb.GetZ() 48 | (205552.628666262, 89857.66932836606, 222.1999969482422) 49 | ``` 50 | 51 | So, for create a 3D shapefile in the Python console or in the Python shell you must use modules that are able to handle the z value like ogr, Fiona with Shapely or Pyshp ([CreateElevationValues][2]) 52 | 53 | Example with Fiona: 54 | 55 | ```python 56 | 57 | import fiona 58 | from shapely.geometry import mapping, Point 59 | # example of a 3D point (Shapely) 60 | point = Point(0, 0, 3) 61 | # schema of the shapefile 62 | schema = {'geometry': '3D Point','properties': {'id': 'int'},} 63 | with fiona.collection('my_shp3D.shp', 'w', 'ESRI Shapefile', schema) as output: 64 | ## If there are multiple geometries, put the "for" loop here 65 | feat = {} 66 | feat['geometry'] = mapping(point) 67 | feat['properties'] = {'id': 1} 68 | output.write(feat) 69 | ``` 70 | 71 | Control: 72 | ```python 73 | 74 | d = fiona.open('my_shp3D.shp') 75 | d.schema 76 | {'geometry': '3D Point', 'properties': {u'id': 'int'}} 77 | d.next() 78 | {'geometry': {'type': 'Point', 'coordinates': (0.0, 0.0, 3.0)}, 'id': '0', 'properties': {'id': 1}} 79 | ``` 80 | 81 | As an example of extracting the z value from a DEM and the color value from a geological map, see "Python: Using vector and raster layer in a geological perspective without GIS software", [Python: utilisation des couches vectorielles et matricielles dans une perspective géologique, sans logiciel SIG ][3], in French but the Python scripts are universal... 82 | 83 | 84 | 85 | 86 | 87 | 88 | [1]: http://osgeo-org.1560.n6.nabble.com/Why-is-it-not-possible-to-extract-the-z-value-of-a-wkb-geometry-with-PyQGIS-while-it-is-possible-wit-td5006814.html 89 | [2]: http://code.google.com/p/pyshp/wiki/CreateElevationValues 90 | [3]: http://www.portailsig.org/content/python-utilisation-des-couches-vectorielles-et-matricielles-dans-une-perspective-geologique- 91 | -------------------------------------------------------------------------------- /Efficient algorithms to split and join lines?.md: -------------------------------------------------------------------------------- 1 | From [Efficient algorithms to split and join lines?](http://gis.stackexchange.com/questions/61474/efficient-algorithms-to-split-and-join-lines) 2 | 3 | 4 | You can use effectively Shapely, and [Fiona][1] to read a shapefile for example: 5 | 6 | ```python 7 | import fiona 8 | # open a line shapefile 9 | file = fiona.open('lines.shp') 10 | # first element of the shapefile 11 | first = file.next 12 | print first 13 | {'geometry': {'type': 'LineString', 'coordinates': [(203317.23, 90448.75), (203679.62, 90105.68), (203882.57, 89902.74), (204143.49, 89641.81), (204394.75, 89385.72), (204563.87, 89235.93)]}, 'id': '0', 'properties': {u'id': "1"}} 14 | ``` 15 | 16 | Now import Shapely 17 | 18 | ```python 19 | from shapely.geometry import Point, LineString, shape 20 | geom = shape(first['geometry']) 21 | # now it is a Shapely geometry 22 | print geom 23 | LINESTRING (203317.23 90448.75, 203679.62 90105.68, 203882.57 89902.74, 204143.49 89641.81, 204394.75 89385.72, 204563.87 89235.93) 24 | ``` 25 | 26 | **Splitting** 27 | 28 | **We can split the line in segments**, each pair of coordinates (Point) define a line segment: 29 | 30 | ```python 31 | def pair(list): 32 | '''Iterate over pairs in a list -> pair of points ''' 33 | for i in range(1, len(list)): 34 | yield list[i-1], list[i] 35 | 36 | for seg_start, seg_end in pair(geom.coords): 37 | line_start = Point(seg_start) 38 | line_end = Point(seg_end) 39 | segment = LineString([line_start.coords[0],line_end.coords[0]]) 40 | print segment 41 | LINESTRING (203317.23 90448.75, 203679.62 90105.68) 42 | LINESTRING (203679.62 90105.68, 203882.57 89902.74) 43 | LINESTRING (203882.57 89902.74, 204143.49 89641.81) 44 | LINESTRING (204143.49 89641.81, 204394.75 89385.72) 45 | LINESTRING (204394.75 89385.72, 204563.87 89235.93) 46 | ``` 47 | 48 | You could do it directly with Fiona: 49 | 50 | ```python 51 | for seg_start, seg_end in paires(first['geometry']['coordinates']): 52 | .... 53 | ``` 54 | 55 | **Union** 56 | 57 | 1. If the line is straight, simply use the first and the last point to make the LineString 58 | 59 | ```python 60 | LINESTRING (203317.23 90448.75, 204563.87 89235.93) 61 | ``` 62 | 2. In other cases, with shapely, you can use union, cascaded_union(geoms) or unary_union(geoms) and the result is a MULTILINESTRING; 63 | 64 | With union: 65 | 66 | ```python 67 | line = LineString() 68 | for element in line['geometry']['coordinates']: 69 | geom =shape(line['geometry']) 70 | profile = profile.union(geom) 71 | print line 72 | MULTILINESTRING ((203317.23 90448.75, 203679.62 90105.68), (203679.62 90105.68, 203882.57 89902.74), (203882.57 89902.74, 204143.49 89641.81), (204143.49 89641.81, 204394.756 89385.72), (204394.75 89385.72, 204563.87 89235.93)) 73 | ``` 74 | or directly with shapely: 75 | 76 | ```python 77 | line = LineString() 78 | for seg_start, seg_end in paires(geom.coords): 79 | line = line.union(LineString([Point(seg_start).coords[0],Point(seg_end).coords[0]])) 80 | ``` 81 | 82 | **Intersection** 83 | 84 | The shapely function is geom1.intersection(geom2) 85 | 86 | 1. for two straight lines, it is simply 87 | ```python 88 | 89 | line1.intersection(line2) # the result is a Point 90 | ``` 91 | 2. for two lines with segments, it is 92 | 93 | ```python 94 | (union of segments of line1).intersection(union of segments of line2) # the result is a Point or a MultiPoint (more than a single intersection) 95 | ``` 96 | And saving the results is easy with Fiona 97 | 98 | 99 | [1]: https://pypi.python.org/pypi/Fiona 100 | -------------------------------------------------------------------------------- /OGR Projection transformation error.md: -------------------------------------------------------------------------------- 1 | From [OGR Projection transformation error](http://gis.stackexchange.com/questions/61823/ogr-projection-transformation-error/61830) 2 | 3 | 4 | For a complete history of the evolution from EPSG:900913 to EPSG 3785 and finally EPSG:3857, look at [Análisis de Google Maps][1] (in Spanish) and the conclusions are: 5 | 6 | - The projection parameters defined for the EPSG: 900913 or 3785 describe a Mercator projection with geographic coordinates defined on a spherical model of the Earth, 6378.137m ratio, as specified in the following line (see [EPSG:3785][2]) : 7 | 8 | SPHEROID["**Popular Visualisation Sphere", 6378137,** 0, AUTHORITY["EPSG","7059"]] 9 | 10 | - The official EPSG: 3857, in contrast, suggests a Mercator projection with coordinates defined on the WGS84 ellipsoid with a flattening (f) of 1/298.257223563: 11 | 12 | SPHEROID["**WGS 84", 6378137, 298.257223563**, AUTHORITY["EPSG","7030"]] 13 | 14 | And the prj of the shapefile is EPSG 3857 and not EPSG 900913/3785 witch is ([3785 ESRI .prj][3]): 15 | 16 | > PROJCS["Popular Visualisation CRS / Mercator",GEOGCS["Popular Visualisation CRS",DATUM["D_Popular_Visualisation_Datum",SPHEROID["Popular_Visualisation_Sphere",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] 17 | 18 | If I try with the definitions of the module osr, the transformation works: 19 | 20 | 21 | ```python 22 | from osgeo import osr 23 | x,y = (6000,5000) 24 | p3857 = osr.SpatialReference() 25 | p3857.ImportFromEPSG(3857) 26 | p900913 = osr.SpatialReference() 27 | p900913.ImportFromEPSG(900913) 28 | transformation = osr.CoordinateTransformation(p900913,p3857) 29 | x2,y2 = transformation.TransformPoint(x, y) 30 | print "%.3f, %.3f" % (x2,y2) 31 | 6000.000, 5000.000 32 | 33 | ``` 34 | 35 | and 36 | 37 | 38 | ```python 39 | 40 | p3857.ExportToWkt() 41 | 'PROJCS["WGS_84_Pseudo_Mercator",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984", 42 | SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree", 43 | 0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",0], 44 | PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1], 45 | PARAMETER["standard_parallel_1",0.0]]' 46 | 47 | p900913.ExportToWkt() 48 | 'PROJCS["Google Maps Global Mercator",GEOGCS["WGS84",DATUM["WGS_1984", 49 | SPHEROID["WG84",6378137,298.257223563,AUTHORITY["EPSG","7030"]], 50 | AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"], 51 | UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]], 52 | AUTHORITY["EPSG","4326"]],PROJECTION["Mercator_2SP"], 53 | PARAMETER["standard_parallel_1",0],PARAMETER["latitude_of_origin",0], 54 | PARAMETER["central_meridian",0],,PARAMETER["false_easting",0], 55 | PARAMETER["false_northing",0],UNIT["Meter",1],EXTENSION["PROJ4", 56 | "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 57 | +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","900913"]]' 58 | 59 | ``` 60 | 61 | But if you use the WKT provided by your .prj file, the result is: 62 | 63 | 64 | ```python 65 | 66 | p = osr.SpatialReference() 67 | p.ImportFromWkt(yourwkt) 68 | p.ExportToProj4() 69 | ERROR 6: No translation for Mercator_Auxiliary_Sphere to PROJ.4 format is known. 70 | 71 | ``` 72 | 73 | 74 | So, it is the prj from FME that is the problem and not that of QGIS. 75 | 76 | 77 | [1]: http://www.ign.gob.ar/argenmap/argenmap.jquery/docs/analisisdegooglemaps.html 78 | [2]: http://spatialreference.org/ref/epsg/3785/html/ 79 | [3]: http://spatialreference.org/ref/epsg/3785/esriwkt/ 80 | -------------------------------------------------------------------------------- /How to count the number of lines connected to a point?.md: -------------------------------------------------------------------------------- 1 | From [How to count the number of lines connected to a point?](http://gis.stackexchange.com/questions/86613/how-to-count-the-number-of-lines-connected-to-a-point) 2 | 3 | It is not a problem of geometry (buffer, etc.) but a simple problem of Graph Theory (nodes and connected edges) and Python has many modules for dealing with Graphs ([PythonGraphApi][1], [Graphs in Python][2], [Python Patterns - Implementing Graphs][3], ...) 4 | 5 | In your problem, you don't need a point layer, you only need the points/nodes of the polyline. They are the vertex/nodes of a Graph and the segments between two nodes are the edges of the same Graph. And you want to find the nodes with a [degree][4] 2 and 3 (number of edges incident to the vertex = when 2 lines connect to a point, I want to install an elbow, when 3 lines connect, I want to install a Tee) 6 | 7 | The layer: 8 | 9 | ![enter image description here][5] 10 | 11 | 12 | The corresponding Graph where we can see directly the desired points (2 and 3 lines connect - figure made with the [NetworkX][8] module): 13 | 14 | ![enter image description here][6] 15 | 16 | 17 | 18 | I will use here the [NetworkX][8] module (pure Python module). The module can directly open shapefiles to generates a networkx.Graph ([Networkx: GIS shapefile][9]) but I do so in the Python console of QGIS: 19 | 20 | We need to extract all the segments of the layer (from point to point): the LineString must be iterated over pairs to divide the polyline in segments. 21 | 22 | ```Python 23 | 24 | def pairs(list): 25 | '''generator to iterate over pairs in a list ''' 26 | for i in range(1, len(list)): 27 | yield list[i-1], list[i] 28 | ``` 29 | 30 | Creation of the Graph: 31 | 32 | ```Python 33 | 34 | import networkx as nx 35 | # select the polyline layer 36 | layer = qgis.utils.iface.activeLayer() 37 | # create a Graph 38 | G = nx.Graph() 39 | # add the nodes and the edges to the Graph = segment point i -> point i+1 40 | for features in layer.getFeatures(): 41 | segment = features.geometry().asPolyline() 42 | # add the two end points of a segment as two nodes and an edge (point1 -> point2) to the Graph 43 | for seg_start, seg_end in pair(segment): 44 | G.add_edges_from([(seg_start, seg_end)]) 45 | ``` 46 | 47 | Now we have the nodes and the edges of the Graph: 48 | 49 | ```Python 50 | 51 | print G.nodes() # = nodes of the polyline in (x,y) form 52 | [(198133,93258.8), (198757,93232.4), (197592,94296.2), (197579,93232.4), (198761,94274.3), (198146,94287.5)] 53 | print G.edges() # = all the segments of the polyline 54 | [((198133,93258.8), (198146,94287.5)), ((198757,93232.4), (198761,94274.3)), ((197592,94296.2), (197579,93232.4)), ((197592,94296.2), (198146,94287.5)), ((198761,94274.3), (198146,94287.5))] 55 | 56 | ``` 57 | 58 | We search the nodes which the degree is > 1: 59 | 60 | ```Python 61 | 62 | for i in G.nodes(): 63 | if G.degree(i) > 1: 64 | print QgsPoint(i), G.degree(i) 65 | (197592,94296.2) 2 66 | (198761,94274.3) 2 67 | (198146,94287.5) 3 68 | ``` 69 | 70 | And we obtain the desired points: 71 | 72 | Result: 73 | 74 | ![enter image description here][10] 75 | 76 | 77 | [1]: https://wiki.python.org/moin/PythonGraphApi 78 | [2]: http://www.python-course.eu/graphs_python.php 79 | [3]: http://www.python.org/doc/essays/graphs.html 80 | [4]: http://en.wikipedia.org/wiki/Degree_%28graph_theory%29 81 | [5]: http://i.stack.imgur.com/gJnoD.jpg 82 | [6]: http://i.stack.imgur.com/3pFJV.jpg 83 | [7]: http://i.stack.imgur.com/lrJQ6.jpg 84 | [8]: http://networkx.github.io/ 85 | [9]: http://networkx.github.io/documentation/latest/reference/readwrite.nx_shp.html?highlight=shapefile 86 | [10]: http://i.stack.imgur.com/QdCDs.jpg 87 | -------------------------------------------------------------------------------- /How to script map production in GRASS?.md: -------------------------------------------------------------------------------- 1 | From [How to script map production in GRASS?](http://gis.stackexchange.com/questions/70945/how-to-script-map-production-in-grass) 2 | 3 | 4 | For that, you need; 5 | 6 | 1. to import the files (shapefiles, raster) in GRASS GIS 7 | 2. use the adequate modules 8 | 9 | You can use Bash or Python from: 10 | 11 | - the Command Console or the Python Shell of the Layer manager 12 | 13 | ![enter image description here][1] 14 | 15 | - the GRASS shell (Python here, but you can also use [R][2]) 16 | 17 | ![enter image description here][3] 18 | 19 | - the Mac shell (Python, here, but you can also use [R][4]) 20 | 21 | ![enter image description here][5] 22 | 23 | 24 | To use bash scripts, see [Shell Scripting][6] or [On scripting GRASS GIS: Building location-independent command line tools][7] 25 | To use Python, see [GRASS and Python][8] or [Python Scripts For GRASS GIS][9] 26 | 27 | I will develop Python that I know best. 28 | 29 | **Python with grass module** 30 | 31 | In Python, you simply access the GRASS functions as: 32 | 33 | ```python 34 | 35 | debligne =grass.read_command("v.to.db", flags="p", map="testgrass", type="line", option="start", units="meters" , quiet=True) 36 | ``` 37 | 38 | If you want to import all the tif files in a directory, see , for example, [Python: script to import multiple LANDSAT images to Grass GIS][10] 39 | 40 | ```python 41 | 42 | 43 | for dirpath, dirname, filenames in os.walk(dirpath): 44 | # Iterate through the files 45 | for raster in filenames: 46 | # If the suffix is '.TIF', process 47 | if raster.upper().endswith('.tif'): 48 | # full path to your file 49 | full_path = os.path.join(dirpath, tif_file) 50 | # GRASS commands 51 | grass.message('Importing %s -> %s@%s...' % (full_path, tif_file, dirpath)) 52 | grass.run_command('r.in.gdal',flags = 'o',input = full_path, output = tif_file,quiet = True,overwrite = True) 53 | ``` 54 | 55 | See other example in the above-mentioned references or in [Automatic 3D geological boreholes representation (automate v.extrude from a table ?): my solution in Python ][11] or [GRASS and the Python geospatial modules (Shapely, PySAL,...) ][12] 56 | 57 | **Python with osgeo module** 58 | 59 | You can also use the osgeo (GDAL/OGR) Python module: 60 | 61 | ```python 62 | 63 | 64 | from osgeo import ogr 65 | # open grass vector layer 66 | ds = ogr.Open('/Users/username/grassdata/geol/mymapset/vector/testgrass/head') 67 | # vector layer 68 | layer = ds.GetLayer(0) 69 | layer.GetName() 70 | 'testgrass' 71 | feat = layer.GetFeature(0) 72 | # geometry 73 | geom = feat.GetGeometryRef() 74 | geom.ExportToWkt() 75 | 'LINESTRING (186139.123704173340229 53082.654193976894021,188199.122798504744424 53467.758558732457459)' 76 | ``` 77 | 78 | [1]: http://i.stack.imgur.com/pzWgb.png 79 | [2]: http://www.r-project.org/ 80 | [3]: http://i.stack.imgur.com/TgTQ8.png 81 | [4]: http://www.r-project.org/ 82 | [5]: http://i.stack.imgur.com/hRlph.jpg 83 | [6]: http://grasswiki.osgeo.org/wiki/Shell_scripting 84 | [7]: http://geoinformatics.fsv.cvut.cz/gwiki/On_scripting_GRASS_GIS:_Building_location-independent_command_line_tools 85 | [8]: http://grasswiki.osgeo.org/wiki/GRASS_and_Python 86 | [9]: http://code.google.com/p/postgis-grass-r-py/wiki/0003_01_PythonForGrassGis 87 | [10]: http://stackoverflow.com/questions/13073855/python-script-to-import-multiple-landsat-images-to-grass-gis 88 | [11]: http://osgeo-org.1560.x6.nabble.com/Automatic-3D-geological-boreholes-representation-automate-v-extrude-from-a-table-my-solution-in-Pythn-td4978801.html 89 | [12]: http://osgeo-org.1560.x6.nabble.com/GRASS-and-the-Python-geospatial-modules-Shapely-PySAL-td4985075.html 90 | -------------------------------------------------------------------------------- /Using Python to parse an XML containing GML tags.md: -------------------------------------------------------------------------------- 1 | From [Using Python to parse an XML containing GML tags](http://gis.stackexchange.com/questions/58271/using-python-to-parse-an-xml-containing-gml-tags) 2 | 3 | And in addition to the reply of sgillies, if you want the wkt format (wkt = "" ?), use his Shapely module: 4 | 5 | ```python 6 | from shapely.geometry.polygon import LinearRing 7 | 8 | linearing = [] 9 | for polygon in geography.findall('{http://www.opengis.net/gml}Polygon'): 10 | for coord in polygon.findall("{http://www.opengis.net/gml}outerBoundaryIs/{http://www.opengis.net/gml}LinearRing/{http://www.opengis.net/gml}coord"): 11 | linearing.append((float(coord.findtext("{http://www.opengis.net/gml}X")),float(coord.findtext("{http://www.opengis.net/gml}Y")))) 12 | 13 | print LinearRing(a).wkt 14 | 'LINEARRING (452847.6009000000194646 18596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 452847.6009000000194646 18596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 452847.6009000000194646 18596.0495999999984633)' 15 | 16 | ``` 17 | or with the two outerBoundaryIs: 18 | 19 | ```python 20 | for outerBoundaryIs in geography.findall('{http://www.opengis.net/gml}Polygon/{http://www.opengis.net/gml}outerBoundaryIs'): 21 | linearing = [] 22 | for coord in outerBoundaryIs.findall("{http://www.opengis.net/gml}LinearRing/{http://www.opengis.net/gml}coord"): 23 | linearing.append((float(coord.findtext("{http://www.opengis.net/gml}X")),float(coord.findtext("{http://www.opengis.net/gml}Y")))) 24 | print LinearRing(linearing).wkt 25 | 26 | 'LINEARRING (452847.6009000000194646 18596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 452847.6009000000194646 18596.0495999999984633)' 27 | 'LINEARRING (452847.6009000000194646 18596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 415847.6009000000194646 184596.0495999999984633, 452847.6009000000194646 18596.0495999999984633)' 28 | ``` 29 | and if you want the srsName of the polygon: 30 | 31 | ```python 32 | for polygon in geography.findall('{http://www.opengis.net/gml}Polygon'): 33 | polygon.attrib.get('srsName') 34 | ``` 35 | 36 | From Sean Gillies: 37 | ---- 38 | 39 | I enjoy using ElementTree. It's standardized in Python since 2.5 as xml.etree.ElementTree. Forgive me for being blunt, but you're using it wrong. I suggest trying the find, findtext, and findall methods when you know the structure of the data. Is Order your root element? If so, 40 | 41 | ```python 42 | >>> geography = rootElement.find('OrderRequest/SiteGeography') 43 | >>> for polygon in geography.findall('{http://www.opengis.net/gml}Polygon'): 44 | ... for coord in polygon.findall( 45 | ... "{http://www.opengis.net/gml}outerBoundaryIs/" 46 | ... "{http://www.opengis.net/gml}LinearRing/" 47 | ... "{http://www.opengis.net/gml}coord"): 48 | ... print( 49 | ... coord.findtext("{http://www.opengis.net/gml}X"), 50 | ... coord.findtext("{http://www.opengis.net/gml}Y")) 51 | ... 52 | ('452847.6009', '18596.0496') 53 | ('415847.6009', '184596.0496') 54 | ('415847.6009', '184596.0496') 55 | ('452847.6009', '18596.0496') 56 | ('415847.6009', '184596.0496') 57 | ('415847.6009', '184596.0496') 58 | ``` 59 | 60 | http://pymotw.com/2/xml/etree/ElementTree/parse.html#finding-nodes-in-a-document has more advice on using ElementTree. 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | [1]: https://pypi.python.org/pypi/Shapely/1.2.17 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | [1]: https://pypi.python.org/pypi/Shapely/1.2.17 80 | -------------------------------------------------------------------------------- /Shapely MultiPolygon Construction - Will not accept the entire set of Polygons.md: -------------------------------------------------------------------------------- 1 | From [Shapely MultiPolygon Construction - Will not accept the entire set of Polygons](http://gis.stackexchange.com/questions/83084/shapely-multipolygon-construction-will-not-accept-the-entire-set-of-polygons) 2 | look at [Creating Shapely MultiPolygons from shape file MultiPolygons][1] and I detail below the process: 3 | 4 | 5 | 1) browse through the shapefile : 6 | 7 | - with next() 8 | 9 | ```Python 10 | 11 | import fiona 12 | c = fiona.open('polygons.shp') 13 | # the result is a Python iterator, so to read the first feature of the shapefile 14 | print c.next() 15 | # the result is a Python dictionary (GeoJSON)format 16 | {'geometry': {'type': 'Polygon', 'coordinates': [[(249744.23153029341, 142798.16434689672), (250113.79108725351, 142132.95714436853), (250062.62130244367, 141973.76225829343), (249607.77877080048, 141757.71205576291), (249367.77424759799, 142304.68402918623), (249367.77424759799, 142304.68402918623), (249744.23153029341, 142798.16434689672)]]}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'id', 1), (u'couleur', 1), (u'id_class', None)])} 17 | # if you want the geometry only 18 | print c.next()['geometry'] 19 | {'type': 'Polygon', 'coordinates': [[(249175.78991730965, 142292.53526406409), (249367.77424759799, 142304.68402918623), (249607.77877080048, 141757.71205576291), (249014.45396077307, 141876.13484290778), (249175.78991730965, 142292.53526406409)]]} 20 | .... 21 | ``` 22 | 23 | but as all the iterators, this method raises a built-in StopIteration exception at the end of the iterator or end of the file: 24 | 25 | ```Python 26 | 27 | c.next() 28 | Traceback (most recent call last): ..... 29 | StopIteration 30 | ``` 31 | 32 | - so the solution is a list (iterator without the StopIteration exception) 33 | 34 | ```Python 35 | 36 | c = fiona.open('polygons.shp') 37 | features = list(c) 38 | # and the result is a list of all the features in the shapefile: 39 | # or 40 | for features in fiona.open('polygons.shp'): 41 | .... 42 | ``` 43 | 44 | 2) Therefore to convert the polygons to a multipolygon: 45 | 46 | 47 | ```Python 48 | 49 | from shapely.geometry import MultiPolygo 50 | multi = [] 51 | # append the geometries to the list 52 | for pol in fiona.open('polygons.shp'): 53 | multi.append(shape(pol['geometry']) 54 | # create the MultiPolygon from the list of Polygons 55 | Multi = MultiPolygon(multi) 56 | print Multi.wkt 57 | 'MULTIPOLYGON (((249744.2315302934148349 142798.1643468967231456, 250113.7910872535139788 142132.9571443685272243, ..., 249870.8182051893090829 142570.3083320840960369)))' 58 | 59 | ``` 60 | Or in one line with a list comprehension: 61 | 62 | ```Python 63 | 64 | Multi = MultiPolygon([shape(pol['geometry']) for pol in fiona.open('polygons.shp')] 65 | ``` 66 | 67 | Note: 68 | 69 | If there are different types of geometries in the shapefile (MultiPolygon embedded in polygons) use [unary_union][2]: "the unary union function can operate on different geometry types, not only polygons as is the case for the older cascaded unions" 70 | 71 | ```Python 72 | 73 | from shapely.ops import unary_union 74 | polygon1 = Polygon([(0, 0), (1, 1), (1, 0)]) 75 | polygon2 = Polygon([(1, 1), (2,2), (2, 0)]) 76 | poly = MultiPolygon([polygon1,polygon2]) 77 | list = [polygon1,polygon2,poly] 78 | result = unary_union(list) 79 | print result 80 | MULTIPOLYGON (((0.00 0.00, 1.00 1.00, 1.00 0.00, 0.00 0.00)), ((1.00 1.00, 2.00 2.00, 2.00 0.00, 1.0 1.00))) 81 | ``` 82 | So: 83 | 84 | ```Python 85 | 86 | geoms =[shape(feature['geometry']) for feature in fiona.open("polygons.shp")] 87 | result = unary_union(geoms) 88 | ``` 89 | 90 | 91 | [1]: http://gis.stackexchange.com/questions/70591/creating-shapely-multipolygons-from-shape-file-multipolygons/70608#70608 92 | [2]: http://toblerity.org/shapely/manual.html#shapely.ops.unary_union 93 | -------------------------------------------------------------------------------- /Visualize shapefile in Python.md: -------------------------------------------------------------------------------- 1 | From [Visualize shapefile in Python](http://gis.stackexchange.com/questions/61862/visualize-shapefile-in-python) 2 | 3 | 4 | I do not know ArcPy, but I work with shapefiles and raster in Python for years 5 | 6 | 1. For processing shapefiles in Python, there are many modules like [osgeo/ogr][1], [Fiona][2], [Pysal][3] or [Pyshp][4] ([shpUtils][5] is one of them and 7 | not the most used), and others, see [Pypi: GIS][6] and examples on gis.stackexchange and many examples on the Web (not only in English). Most of them are much older than ArcPy (or arcgisscripting)... 8 | 2. for processing raster you can use [osgeo/gdal][7], the standard 9 | 3. For processing geospatial geometries, there is [shapely][8] 10 | 4. For plotting the geometries you can use [matplotlib][9] and possibly [descartes][10], "extension" of matplotlib for areas, but also many, many other modules, see [Pypi: Plotting][11] and modules like [mayavi][12] for 3D representation (matplotlib also) 11 | 5. There are also modules like [mapnik][13] which give you directly the possibilities of 1) read a shapefile and 4) plotting with the module [Pycairo][14]. 12 | 13 | After that, it's like a GIS: 14 | 15 | - you use the modules 1) to open, save the shapefiles and carry out the treatments with other modules like numpy or scipy, if you want. 16 | - you can use shapely for manipulation and analysis of the geometric objects (buffer, etc.). 17 | - you can use matplotlib to plot the geometries, but matplotlib do not know what you want to plot. It is your work with modules 1) or 3) to specify what to plot (attributes, etc,.) and how. 18 | 19 | > If I want to visualise one certain column of my shapefile, how can I implement this in the code? 20 | 21 | So, you must learn matplotib and the other modules. You have to learn ArcPy, it's the same...(there are lots of excellent tutorials on the web, especially for matplolib, and it's easier that ArcPy because it is pure Python). 22 | 23 | Some examples with Python only 24 | 25 | ![enter image description here][15] 26 | 27 | Geological map (polygon shapefile) with colors based on an attribute 28 | 29 | ![enter image description here][16] 30 | 31 | 3D Points (PointZ shapefile) with color based on an attribute 32 | 33 | ![enter image description here][17] 34 | 35 | 3D points (Point shapefile with z as attribute) and 3D line (PolyLineZ shapefile) on a DEM, and on a raster draped onto the DEM surface. 36 | 37 | ![enter image description here][18] 38 | 39 | Topographic profile with z values and colors based on attributes (geological formations = Cross section) of the original shapefile (Polyline shapefile) 40 | 41 | ![enter image description here][19] 42 | 43 | DEM (GeoTIFF) with the module Mayavi2 44 | 45 | ![enter image description here][20] 46 | 47 | DEM (ESRI ascii grid, .asc) and Point shapefiles (with z as attribute) with the module [visvis][21] 48 | 49 | ![enter image description here][22] 50 | 51 | Boreholes (3D buffer of a polylineZ with colors based on an attribute (geological formations), with a grid surface calculated with the modules numpy and matplotlib from a points shapefile (with z as an attribute), visualized with the module [visvis][23] 52 | 53 | 54 | [1]: https://pypi.python.org/pypi/GDAL 55 | [2]: https://pypi.python.org/pypi/Fiona 56 | [3]: https://pypi.python.org/pypi/PySAL/ 57 | [4]: https://pypi.python.org/pypi/pyshp 58 | [5]: http://indiemaps.com/blog/2008/03/easy-shapefile-loading-in-python/ 59 | [6]: https://pypi.python.org/pypi?:action=browse&show=all&c=391 60 | [7]: https://pypi.python.org/pypi/GDAL 61 | [8]: https://pypi.python.org/pypi/Shapely 62 | [9]: https://pypi.python.org/pypi/matplotlib 63 | [10]: https://pypi.python.org/pypi/descartes 64 | [11]: https://pypi.python.org/pypi?:action=search&term=plotting&submit=search 65 | [12]: https://pypi.python.org/pypi/mayavi 66 | [13]: http://mapnik.org/ 67 | [14]: http://cairographics.org/pycairo/ 68 | [15]: http://i.stack.imgur.com/hm9DT.jpg 69 | [16]: http://i.stack.imgur.com/Rqiav.jpg 70 | [17]: http://i.stack.imgur.com/b6NWR.jpg 71 | [18]: http://i.stack.imgur.com/CoZQn.jpg 72 | [19]: http://i.stack.imgur.com/9olre.png 73 | [20]: http://i.stack.imgur.com/FYEXG.png 74 | [21]: http://code.google.com/p/visvis/ 75 | [22]: http://i.stack.imgur.com/nXZJD.jpg 76 | [23]: http://code.google.com/p/visvis/ 77 | -------------------------------------------------------------------------------- /Shapely-Finding differences between two shapefiles.md: -------------------------------------------------------------------------------- 1 | from [Shapely-Finding differences between two shapefiles](http://gis.stackexchange.com/questions/80090/finding-differences-between-two-shapefiles-in-python/80524#80524) 2 | 3 | 4 | Suppose we have two polygons (green and blue): 5 | 6 | ![enter image description here][1] 7 | 8 | They are not equal (as [Fetzer][2] suggest): 9 | 10 | ```python 11 | green.equals(blue) 12 | False 13 | ``` 14 | and 15 | 16 | ```python 17 | blue.equals(green) 18 | False 19 | ``` 20 | 21 | And we can can determine the [difference][3] (in red): 22 | 23 | ```python 24 | blue.difference(green) 25 | ``` 26 | 27 | ![enter image description here][4] 28 | 29 | and 30 | 31 | ```python 32 | green.difference(blue) 33 | ``` 34 | gives an empty geometry 35 | 36 | Thus, you can use a supplementary condition: 37 | 38 | if not poly1.difference(poly2).is_empty: 39 | process 40 | 41 | And if you want to find the nodes that have been modified: 42 | 43 | ```python 44 | S1 = set(list(blue.difference(green).exterior.coords) 45 | S2 = set(list(blue.exterior.coords) 46 | S3 = set(list(green.exterior.coords) 47 | ``` 48 | 49 | S1 - S2 and S1 - S3 gives the points (two here blue and red): 50 | 51 | ![enter image description here][5] 52 | 53 | and the distance: 54 | 55 | ```python 56 | point1.distance(point2) 57 | ``` 58 | 59 | ##new : compare multiple polygons: 60 | 61 | Here is one solution: 62 | For that, I use [Fiona][6] to open the polygon shapefiles and save a resulting shapefile with differences: 63 | 64 | ![enter image description here][7] 65 | 66 | ```python 67 | 68 | import fiona 69 | from shapely.geometry import shape 70 | green = fiona.open("poly1.shp") 71 | blue = fiona.open("poly2.shp") 72 | # test the function difference between green and blue shapefiles 73 | [not shape(i['geometry']).difference(shape(j['geometry'])).is_empty for i,j in zip(list(green),list(blue))] 74 | [False, False, False, True] 75 | # control 76 | for geom in [shape(i['geometry']).difference(shape(j['geometry'])) for i,j in zip(list(green),list(blue))]: 77 | print geom 78 | GEOMETRYCOLLECTION EMPTY 79 | GEOMETRYCOLLECTION EMPTY 80 | GEOMETRYCOLLECTION EMPTY 81 | POLYGON ((-0.0806077747083538 0.6329375155131045, 0.0085568963219002 0.5081069760707490, -0.0816567708381215 0.6025166277498414, -0.1529885076623247 0.5437728444828506, -0.1292856235630944 0.6206937720158269, -0.0806077747083538 0.6329375155131045)) 82 | # test the function difference between blue and green shapefiles 83 | [not shape(i['geometry']).difference(shape(j['geometry'])).is_empty for i,j in zip(list(blue),list(green))] 84 | [True, False, False, False] 85 | # control 86 | for geom in [shape(i['geometry']).difference(shape(j['geometry'])) for i,j in zip(list(blue),list(green))]: 87 | POLYGON ((0.2292711598746081 0.7386363636363635, 0.6691026645768023 0.6691026645768023, 0.2440830721003134 0.7205329153605015, 0.1074843260188087 0.3452978056426331, 0.2292711598746081 0.7386363636363635)) 88 | GEOMETRYCOLLECTION EMPTY 89 | GEOMETRYCOLLECTION EMPTY 90 | GEOMETRYCOLLECTION EMPTY 91 | # thus you can write a resulting shapefile withe the differences 92 | from shapely.geometry import mapping 93 | schema = {'geometry': 'Polygon','properties': {'test': 'int'}} 94 | with fiona.open('diff.shp','w','ESRI Shapefile', schema) as e: 95 | for geom in [shape(i['geometry']).difference(shape(j['geometry'])) for i,j in zip(list(green),list(blue)]: 96 | if not geom.is_empty: 97 | e.write({'geometry':mapping(geom), 'properties':{'test':1}}) 98 | for geom in [shape(i['geometry']).difference(shape(j['geometry'])) for i,j in zip(list(blue),list(green))]: 99 | if not geom.is_empty: 100 | e.write({'geometry':mapping(geom), 'properties':{'test':2}}) 101 | 102 | ``` 103 | 104 | Result: 105 | 106 | ![enter image description here][8] 107 | 108 | 109 | [1]: http://i.stack.imgur.com/6t3NL.jpg 110 | [2]: http://gis.stackexchange.com/users/7424/fezter 111 | [3]: http://toblerity.org/shapely/manual.html#object.difference 112 | [4]: http://i.stack.imgur.com/uyq97.jpg 113 | [5]: http://i.stack.imgur.com/0H4m7.jpg 114 | [6]: http://toblerity.github.com/fiona/manual.html 115 | [7]: http://i.stack.imgur.com/KMPiR.jpg 116 | [8]: http://i.stack.imgur.com/P7Sqm.jpg 117 | -------------------------------------------------------------------------------- /How to create points in a specified distance along the line in QGIS.md: -------------------------------------------------------------------------------- 1 | from [How to create points in a specified distance along the line in QGIS?](http://gis.stackexchange.com/questions/63201/how-to-create-points-in-a-specified-distance-along-the-line-in-qgis/63238) 2 | 3 | In the Python console: 4 | 5 | - you can use the [Shapely][1] module (as in [How to create equidistant points in QGIS?][2]) with the function 6 | 7 | ```python 8 | point = line.interpolate(currentdistance) 9 | ``` 10 | 11 | - The new Python API of the master version (1.9) has an equivalent command (as in [Generating chainage (distance) nodes in QGIS ][3] of Nathan Woodrow) 12 | 13 | ```python 14 | point = geom.interpolate(currentdistance) 15 | ``` 16 | 17 | - or you can use vector algebra and direction cosines (as in [PyQGIS: geometries, vectors, vector algebra or direction cosines, application examples][4], in French) 18 | 19 | 1) create a memory layer class (complete class (without attributes) at [crea_mem_layer.py][5]) 20 | 21 | ```python 22 | class Create_vlayer(object): 23 | '''creation of a virtual layer''' 24 | def __init__(self,nom,type): 25 | self.type=type 26 | self.name = nom 27 | self.layer = QgsVectorLayer(self.type, self.name , "memory") 28 | self.pr =self.layer.dataProvider() 29 | def create_point(self,geometry): 30 | # add point to the layer 31 | self.seg = QgsFeature() 32 | self.seg.setGeometry(QgsGeometry.fromPoint(geometry)) 33 | self.pr.addFeatures([self.seg]) 34 | self.layer.updateExtents() 35 | @property 36 | def display_layer(self): 37 | #end of layer and display layer 38 | QgsMapLayerRegistry.instance().addMapLayers([self.couche]) 39 | ``` 40 | 41 | 2) vector algebra functions (from [algèbre_vect_PyQGIS.py][6]) 42 | 43 | ```python 44 | import math 45 | def mag(point): 46 | # magnitude of a vector 47 | return math.sqrt(point.x()**2 + point.y()**2) 48 | def diff(point2, point1): 49 | # substraction betwen two vector 50 | return QgsPoint(point2.x()-point1.x(), point2.y() - point1.y()) 51 | def length(point1,point2): 52 | # with PyQGIS: sqrDist 53 | return math.sqrt(point1.sqrDist(point2)) 54 | ``` 55 | 56 | 3) direction cosines 57 | 58 | ```python 59 | def dircos(point): 60 | cosa = point.x() / mag(point) 61 | cosb = point.y()/ mag(point) 62 | return cosa,cosb 63 | ``` 64 | 65 | 4) process line or line segments 66 | 67 | ```python 68 | def pairs(list): 69 | # list pairs iteration 70 | for i in range(1, len(list)): 71 | yield list[i-1], list[i] 72 | 73 | layer = qgis.utils.iface.activeLayer() 74 | # interval between points 75 | interval = 5 m 76 | # create virtual layer 77 | gen_pt = Create_vlayer("mid5", "Point") 78 | 79 | for elem in layer(): 80 | line = elem.geometry() 81 | for seg_start, seg_end in pairs(line.asPolyline()): 82 | line_start = QgsPoint(seg_start) 83 | line_end = QgsPoint(seg_end) 84 | # mid point = vector coordinates [x2-x1,y2-y1] 85 | pointm =diff(line_end, line_start) 86 | # direction cosines of the segment 87 | cosa,cosb = dircos(pointm) 88 | # length of the segment 89 | lg = length(line_end, line_start) 90 | # generate and add points to the virtual layer 91 | for i in range(interval,lg,interval): 92 | gen_pt.create_point(QgsPoint(line_start.x() + (i * cosa), line_start.y() + (i*cosb))) 93 | 94 | # display layer 95 | gen_pt.display_layer 96 | ```python 97 | 98 | Results 99 | 100 | polyline, equidistant point with Shapely or PyQGIS2, with direction cosines 101 | 102 | ![polyline][7]![shapely][8]![vector_algebra][9] 103 | 104 | Then just adjust the interval 105 | 106 | 107 | [1]: https://pypi.python.org/pypi/Shapely/1.2.17 108 | [2]: http://gis.stackexchange.com/questions/27102/how-to-create-equidistant-points-in-qgis 109 | [3]: http://nathanw.net/2012/08/05/generating-chainage-distance-nodes-in-qgis/ 110 | [4]: http://www.portailsig.org/content/pyqgis-des-geometries-des-vecteurs-de-l-algebre-vectorielle-ou-des-cosinus-directeurs-exempl 111 | [5]: http://www.portailsig.org/content/creamemlayerpy 112 | [6]: http://www.portailsig.org/content/algebrevectpyqgispy 113 | [7]: http://i.stack.imgur.com/4eVCT.jpg 114 | [8]: http://i.stack.imgur.com/Exju5.jpg 115 | [9]: http://i.stack.imgur.com/drkqP.jpg 116 | -------------------------------------------------------------------------------- /Geoprocessing across multiple vector layers QGIS2.md: -------------------------------------------------------------------------------- 1 | From [geoprocessing across multiple vector layers QGIS2](http://gis.stackexchange.com/questions/77974/how-to-convert-gml-to-geojson-using-python-and-ogr-with-geometry-transformation/77999) 2 | 3 | 4 | 5 | It is possible in Python, pure Python without QGIS with modules such as [Fiona][1], [Pyshp][2], [shapely][3] with [rtree][4] (see [rtree python polygon index][5]) and with PyQGIS. 6 | 7 | ###The problem: 6 points layers and an unique grid: 8 | 9 | ![enter image description here][6] 10 | 11 | ###A possible solution with PyQGIS: 12 | 13 | 1) Using a spatial index for the grid (see Using Spatial Index in [Using Vector Layers][7], [Using a QGIS spatial index to speed up your code ][8] or [How to do a spatial search without select() using PyQGIS?][9]): 14 | 15 | 16 | ```python 17 | grid = iface.activeLayer() 18 | index = QgsSpatialIndex() 19 | for elem in grid.getFeatures(): 20 | index.insertFeature(elem) 21 | ``` 22 | 23 | or more "Pythonic" 24 | 25 | ```python 26 | index = QgsSpatialIndex() 27 | map(index.insertFeature, grid.getFeatures()) 28 | ``` 29 | 30 | 31 | 2) Creation of a dictionary to collect the results (index of the grid squares where there are points inside and layers) and a function to complete it: 32 | 33 | ```python 34 | results = {} 35 | # fonction to find the indexes of the grid squares inside which a point lies. 36 | def mydict(layer, dictionary): 37 | for elem in layer.getFeatures(): 38 | geom = elem.geometry().asPoint() 39 | nearestIds = index.nearestNeighbor(geom,1) 40 | results.setdefault(str(nearestIds[0]), set()).add(layer.name()) 41 | ``` 42 | 43 | 3) Iteration over point layers and application of the function: 44 | 45 | ```python 46 | canvas= qgis.utils.iface.mapCanvas() 47 | for layer in canvas.layers(): 48 | elem = layer.getFeatures().next() 49 | geom = elem.geometry() 50 | # only points layers 51 | if geom.wkbType() == QGis.WKBPoint: 52 | mydict(layer, results) 53 | ``` 54 | 55 | The result is a dictionary with the grid squares spatial index as key and the layers which have points in the square grid as values: 56 | 57 | ```python 58 | print results 59 | {'11': set([u'point1', u'point3', u'point4']), 60 | '10': set([u'point5']), 61 | '13': set([u'point4']), 62 | '12': set([u'point3', u'point5', u'point6']), 63 | '15': set([u'point4', u'point6']), 64 | '14': set([u'point1', u'point2', u'point3', u'point4', u'point5', u'point6']), 65 | '1': set([u'point4', u'point5', u'point6']), 66 | '0': set([u'point1', u'point2', u'point3', u'point4', u'point5', u'point6']), 67 | '3': set([u'point4', u'point5']), 68 | '2': set([u'point3', u'point6']), 69 | '5': set([u'point4']), 70 | '4': set([u'point3', u'point5']), 71 | '7': set([u'point3', u'point6']), 72 | '6': set([u'point1', u'point3']), 73 | '9': set([u'point3']), 74 | '8': set([u'point1', u'point2'])} 75 | ``` 76 | 77 | If you want to preserve the order of the indexes, you can use an [OrderedDict][10] 78 | 79 | 4) And if you only want the grid squares with six years of data: 80 | 81 | ```python 82 | 83 | for index_gridsquare, layers in results.iteritems(): 84 | if len(values) == 6: 85 | print index_gridsquare,": ", values 86 | 14: set([u'point1', u'point2', u'point3', u'point4', u'point5', u'point6']) 87 | 0 : set([u'point1', u'point2', u'point3', u'point4', u'point5', u'point6']) 88 | ``` 89 | 90 | 91 | ##After that, I do not understand if you want to select: 92 | 93 | - the square grids: 94 | 95 | ![enter image description here][11] 96 | 97 | - the points of the six layers present in the square grids: 98 | 99 | ![enter image description here][12] 100 | 101 | 102 | [1]: http://toblerity.org/fiona/manual.html 103 | [2]: http://code.google.com/p/pyshp/ 104 | [3]: http://toblerity.org/shapely/manual.html 105 | [4]: http://toblerity.org/rtree/tutorial.html 106 | [5]: http://gis.stackexchange.com/questions/42931/rtree-python-polygon-index 107 | [6]: http://i.stack.imgur.com/5mrur.jpg 108 | [7]: http://www.qgis.org/fr/docs/pyqgis_developer_cookbook/vector.html 109 | [8]: http://nathanw.net/2013/01/04/using-a-qgis-spatial-index-to-speed-up-your-code/ 110 | [9]: http://gis.stackexchange.com/questions/36887/how-to-do-a-spatial-search-without-select-using-pyqgis 111 | [10]: http://docs.python.org/2/library/collections.html#collections.OrderedDict 112 | [11]: http://i.stack.imgur.com/70gx2.jpg 113 | [12]: http://i.stack.imgur.com/xs7Cb.jpg 114 | -------------------------------------------------------------------------------- /Convert points to lines with Python GDAL.md: -------------------------------------------------------------------------------- 1 | From [Convert points to lines with Python GDAL](http://gis.stackexchange.com/questions/78275/convert-points-to-lines-with-python-gdal) 2 | 3 | 4 | Why not work globally ? 5 | 6 | 1. calculate the distances between all points 7 | 2. union the resulting lines pointx - pointy with a distance < 14m 8 | 9 | I will use [Shapely][1], much easier for resolving these kinds of problems. 10 | You must iterate through all pairs of points to calculate the distance once (as distance point1-point2 = distance point2-point1). There are many solutions in Python and I choose the itertools standard module with [combinations][2]. 11 | 12 | example: 13 | 14 | ```python 15 | 16 | myPointDict = {0:(1,1), 1:(2,2), 2:(3,3),3:(4,4),4:(5,5)} 17 | import itertools 18 | for i in itertools.combinations(PointDict.values(), 2): 19 | print i 20 | ((1, 1), (2, 2)) 21 | ((1, 1), (3, 3)) 22 | ((1, 1), (4, 4)) 23 | ((1, 1), (5, 5)) 24 | ((2, 2), (3, 3)) 25 | ((2, 2), (4, 4)) 26 | ((2, 2), (5, 5)) 27 | ((3, 3), (4, 4)) 28 | ((3, 3), (5, 5)) 29 | ((4, 4), (5, 5)) 30 | ``` 31 | 32 | With ogr (look at [the Python GDAL/OGR Cookbook!][3]): 33 | 34 | ```python 35 | 36 | point = ogr.Geometry(ogr.wkbPoint) 37 | point.AddPoint(x,y) 38 | distance = point1.Distance(point2) 39 | line = ogr.Geometry(ogr.wkbLineString) 40 | line.AddPoint(x1, y1) 41 | .... 42 | line.AddPoint(xn,yn) 43 | ``` 44 | 45 | With shapely: 46 | 47 | ```python 48 | 49 | point = Point(x,y) 50 | distance = Point(x1,y1).distance(Point(x2,y2) 51 | linestring = LineString([point1,..., pointn] 52 | ``` 53 | 54 | So, in your case: 55 | 56 | ```python 57 | 58 | from shapely.geometry import Point, LineString 59 | # creation of a empty line for unioning the resulting geometries 60 | line = LineString() 61 | for i in itertools.combinations(pointDict.values(), 2): 62 | # if distance < 14m union the line ptx-pty to line 63 | if Point(i[0]).distance(Point(i[1])) < 14: 64 | line = line.union(LineString([(Point(i[0]).x, Point(i[0]).y), (Point(i[1]).x, Point(i[1]).y)])) 65 | # result 66 | print line.wkt 67 | 'MULTILINESTRING ((345672.493225679441821 1267286.555012494325638,345681.57590266619809 1267286.555012494325638),(345672.493225679441821 1267286.555012494325638,345663.410548692685552 1267277.472335507394746),(345672.493225679441821 1267286.555012494325638,345681.57590266619809 1267277.472335507394746),(345681.57590266619809 1267286.555012494325638,345681.57590266619809 1267277.472335507394746),(345654.327871705929283 1267277.472335507394746,345663.410548692685552 1267277.472335507394746),(345654.327871705929283 1267277.472335507394746,345645.245194719173014 1267268.389658520696685),(345681.57590266619809 1267277.472335507394746,345690.658579652954359 1267268.389658520696685),(345636.162517732358538 1267268.389658520696685,345645.245194719173014 1267268.389658520696685),(345636.162517732358538 1267268.389658520696685,345627.079840745602269 1267259.306981533998623),(345690.658579652954359 1267268.389658520696685,345681.57590266619809 1267259.306981533998623),(345608.914486772089731 1267259.306981533998623,345617.997163758846 1267259.306981533998623),(345608.914486772089731 1267259.306981533998623,345599.831809785333462 1267250.224304547300562),(345617.997163758846 1267259.306981533998623,345627.079840745602269 1267259.306981533998623),(345681.57590266619809 1267259.306981533998623,345672.493225679441821 1267250.224304547300562),(345590.749132798577193 1267250.224304547300562,345599.831809785333462 1267250.224304547300562),(345672.493225679441821 1267250.224304547300562,345663.410548692685552 1267241.14162756036967))' 68 | ``` 69 | 70 | And if you want to use the end of your script: 71 | ```python 72 | multiline = ogr.CreateGeometryFromWkt(line.wkt) 73 | ``` 74 | or using [Fiona][4] (an easier Python wrapper of the ogr library) 75 | 76 | ```python 77 | import fiona 78 | from shapely.geometry import mapping 79 | # schema of the shapefile 80 | schema = {'geometry': 'MultiLineString','properties': {'test': 'int'} 81 | with fiona.open('myshp3.shp','w','ESRI Shapefile', schema) as c: 82 | record = {'geometry':mapping(line), 'properties':{'test':1}} 83 | c.write(record) 84 | ``` 85 | Result: 86 | 87 | ![enter image description here][5] 88 | 89 | But, I do not know if this is what you want. 90 | 91 | 92 | [1]: http://gispython.org/shapely/manual.html 93 | [2]: http://docs.python.org/2.7/library/itertools.html#itertools.combinations 94 | [3]: http://pcjericks.github.io/py-gdalogr-cookbook/geometry.htm 95 | [4]: http://toblerity.org/fiona/manual.html 96 | [5]: http://i.stack.imgur.com/HE9kx.jpg 97 | -------------------------------------------------------------------------------- /Find Nearest Line Segments to Point.md: -------------------------------------------------------------------------------- 1 | From [Find Nearest Line Segments to Point](http://gis.stackexchange.com/questions/81613/find-nearest-line-segments-to-point/) 2 | 3 | I have reproduced your example with shapefiles. 4 | 5 | You can use [Shapely][1] and [Fiona][2] to solve your problem. 6 | 7 | ####1) Your problem (with a shapely `Point`): 8 | 9 | ![enter image description here][3] 10 | 11 | ####2) starting with an arbitrary line (with an adequate length): 12 | 13 | 14 | ```python 15 | 16 | from shapely.geometry import Point, LineString 17 | line = LineString([(point.x,point.y),(final_pt.x,final_pt.y)]) 18 | ``` 19 | 20 | 21 | ![enter image description here][4] 22 | 23 | ####3) using [shapely.affinity.rotate][5] to create the radii (rotating the line from the point, look also the [Mike Toews][6]'s answer at [Python, shapely library: is it possible to do an affine operation on shape polygon?][7]): 24 | 25 | 26 | ```python 27 | 28 | from shapely import affinity 29 | # Rotate i degrees CCW from origin at point (step 10°) 30 | radii= [affinity.rotate(line, i, (point.x,point.y)) for i in range(0,360,10)] 31 | 32 | 33 | ``` 34 | 35 | ![enter image description here][8] 36 | 37 | ####4) now, using [shapely:cascaded_union][9] (or [shapely:unary_union][10]) to get a MultiLineString: 38 | 39 | 40 | 41 | from shapely.ops import cascaded_union 42 | mergedradii = cascaded_union(radii) 43 | print mergedradii.type 44 | MultiLineString 45 | 46 | 47 | ####5) the same with the original lines (shapefile) 48 | 49 | 50 | ```python 51 | 52 | import fiona 53 | from shapely.geometry import shape 54 | orlines = fiona.open("orlines.shp") 55 | shapes = [shape(f['geometry']) for f in orlines] 56 | mergedlines = cascaded_union(shapes) 57 | print mergedlines.type 58 | MultiLineString 59 | 60 | ``` 61 | 62 | ####6) the intersection between the two multigeometries is computed and the result is saved to a shapefile: 63 | 64 | 65 | ```python 66 | 67 | points = mergedlines.intersection(mergedradii) 68 | print points.type 69 | MultiPoint 70 | from shapely.geometry import mapping 71 | schema = {'geometry': 'MultiPoint','properties': {'test': 'int'}} 72 | with fiona.open('intersect.shp','w','ESRI Shapefile', schema) as e: 73 | e.write({'geometry':mapping(points), 'properties':{'test':1}}) 74 | 75 | ``` 76 | 77 | Result: 78 | 79 | ![enter image description here][11] 80 | 81 | ####7) but, problem, if you use a a longer radius, the result is different: 82 | 83 | ![enter image description here][12] 84 | 85 | ####8) And if you want to get your result, you need to select only the point with the shortest distance from the original point on a radius: 86 | 87 | 88 | ```python 89 | 90 | 91 | points_ok = [] 92 | for line in mergeradii: 93 | if line.intersects(mergedlines): 94 | if line.intersection(mergedlines).type == "MultiPoint": 95 | # multiple points: select the point with the minimum distance 96 | a = {} 97 | for pt in line.intersection(merged): 98 | a[point.distance(pt)] = pt 99 | points_ok.append(a[min(a.keys())]) 100 | if line.intersection(mergedlines).type == "Point": 101 | # ok, only one intersection 102 | points_ok.append(line.intersection(mergedlines)) 103 | solution = cascaded_union(points_ok) 104 | schema = {'geometry': 'MultiPoint','properties': {'test': 'int'}} 105 | with fiona.open('intersect3.shp','w','ESRI Shapefile', schema) as e: 106 | e.write({'geometry':mapping(solution), 'properties':{'test':1}}) 107 | 108 | 109 | ``` 110 | 111 | Final result: 112 | 113 | ![enter image description here][13] 114 | 115 | I hope that is what you want. 116 | 117 | 118 | 119 | 120 | [1]: http://toblerity.org/shapely/manual.html 121 | [2]: http://toblerity.org/fiona/manual.htm 122 | [3]: http://i.stack.imgur.com/CrbO3.jpg 123 | [4]: http://i.stack.imgur.com/vhnvh.jpg 124 | [5]: https://github.com/Toblerity/Shapely/blob/master/shapely/affinity.py 125 | [6]: http://gis.stackexchange.com/users/1872/mike-toews 126 | [7]: http://gis.stackexchange.com/questions/13383/python-shapely-library-is-it-possible-to-do-an-affine-operation-on-shape-polyg/13431#13431 127 | [8]: http://i.stack.imgur.com/5xvF6.jpg 128 | [9]: http://toblerity.org/shapely/manual.html#shapely.ops.cascaded_union 129 | [10]: http://toblerity.org/shapely/manual.html#shapely.ops.unary_union 130 | [11]: http://i.stack.imgur.com/OaYmn.jpg 131 | [12]: http://i.stack.imgur.com/YF5Ns.jpg 132 | [13]: http://i.stack.imgur.com/QR1ko.jpg 133 | -------------------------------------------------------------------------------- /How to use a field-to-RGB mapping for symbology in QGIS?.md: -------------------------------------------------------------------------------- 1 | from [How to use a field-to-RGB mapping for symbology in QGIS?](http://gis.stackexchange.com/questions/15135/how-to-use-a-field-to-rgb-mapping-for-symbology-in-qgis/15299) 2 | 3 | You can use Python with ElementTree module : 4 | 5 | ```python 6 | 7 | from string import * 8 | from xml.etree import cElementTree as ET 9 | 10 | class symbol: 11 | def __init__(self,b=[]): 12 | self.typec= typec 13 | self.b = b 14 | self.key = ['MAPCODE','R','G','B'] 15 | self.data = dict(zip(self.key,self.b)) 16 | self.symb = ET.SubElement(typec,"symbol") 17 | self.lower = ET.SubElement(self.symb, "lowervalue") 18 | self.upper = ET.SubElement(self.symb, "uppervalue") 19 | self.outline = ET.SubElement(self.symb,"outlinecolor") 20 | self.outsty = ET.SubElement(self.symb, "outlinestyle") 21 | self.outtail = ET.SubElement(self.symb, "outlinewidth") 22 | self.fillc = ET.SubElement(self.symb,"fillcolor") 23 | self.fillp = ET.SubElement(self.symb,"fillpattern") 24 | 25 | def creation(self): 26 | self.lower.text = self.data['MAPCODE'] 27 | self.upper.text = self.data['MAPCODE'] 28 | self.outsty.text="SolidLine" 29 | self.outtail.text="0.26" 30 | self.outline.set("red",str(self.data['R'])) 31 | self.outline.set("green",str(self.data['G'])) 32 | self.outline.set("blue",str(self.data['B'])) 33 | self.fillc.set("red",str(self.data['R'])) 34 | self.fillc.set("green",str(self.data['G'])) 35 | self.fillc.set("blue",str(self.data['B'])) 36 | self.fillp.text = "SolidPattern" 37 | 38 | # QML file creation 39 | intro = ET.Element("qgis") 40 | transp = ET.SubElement(intro,"transparencyLevelInt") 41 | transp.text = '255' 42 | classatr = ET.SubElement(intro, "classificationattribute") 43 | classatr.text= "MAPCODE" 44 | typec = ET.SubElement(intro,"uniquevalue") 45 | classif = ET.SubElement(typec,"classificationfield") 46 | classif.text="MAPCODE" 47 | 48 | # RGB file processing 49 | def main(): 50 | file = "RGB.txt" 51 | f= open(file,"r") 52 | while 1 : 53 | line = f.readline() 54 | if not line : 55 | break 56 | elem = split(line,',') #or tab, or space, or 57 | symboltag = symbol(elem) 58 | symboltag.creation() 59 | result = ET.ElementTree(intro) 60 | result.write("RGB.qml") 61 | 62 | if __name__ == '__main__': 63 | main() 64 | ```python 65 | 66 | The style file generated by this script is (and it works) : 67 | 68 | > 69 | > 255 70 | > MAPCODE 71 | > 72 | > MAPCODE 73 | > 74 | > Oc 75 | > Oc 76 | > 77 | > SolidLine 78 | > 0.26 79 | > 80 | > SolidPattern 81 | > 82 | > 83 | > WAT 84 | > WAT 85 | > 86 | > SolidLine 87 | > 0.26 88 | > 89 | > SolidPattern 90 | > 91 | > and so... 92 | > 93 | > 94 | 95 | You can also use the shapefile module ([shapefile])[1] for shapefiles with RGB columns 96 | 97 | ```python 98 | import shapefile .... 99 | [....] 100 | noduplicates = [] 101 | 102 | def main(): 103 | sf = shapefile.Reader("RGBshape") 104 | for rec in enumerate(sf.records()): 105 | if rec[1][0] not in noduplicates: 106 | noduplicates.append(rec[1][0]) 107 | symboltag = symbol(rec[1]) 108 | symboltag.creation() 109 | else: 110 | continue 111 | ``` 112 | 113 | and so... 114 | 115 | [1]: http://pypi.python.org/pypi/pyshp/1.1.4 116 | -------------------------------------------------------------------------------- /Is there Python library (other than ArcPy) for geoprocessing such as buffer?.md: -------------------------------------------------------------------------------- 1 | From [Is there Python library (other than ArcPy) for geoprocessing such as buffer?](http://gis.stackexchange.com/questions/82521/is-there-python-library-other-than-arcpy-for-geoprocessing-such-as-buffer/82555#82555) 2 | 3 | To simplify, [Shapely: manual][1] allows all geometry processing of PostGIS in Python. 4 | 5 | >The first premise of Shapely is that Python programmers should be able to perform PostGIS type geometry operations outside of an RDBMS... 6 | 7 | The first example of PolyGeo 8 | 9 | ```python 10 | 11 | from shapely.geometry import Point, LineString, Polygon, mapping 12 | from shapely.wkt import loads 13 | pt = Point(1198054.34,648493.09) 14 | # or 15 | pt = loads("POINT (1198054.34 648493.09)") 16 | bufferDistance = 500 17 | poly = pt.buffer(bufferDistance) 18 | print poly.wkt 19 | 'POLYGON ((1198554.3400000001000000 648493.0899999999700000, 1198551.9323633362000000 20 | # GeoJSON 21 | print mapping(poly) 22 | {'type': 'Polygon', 'coordinates': (((1198554.34, 648493.09), (1198551.9323633362, 648444.0814298352), (1198544.7326402017, 648395.544838992), ....} 23 | 24 | ``` 25 | 26 | The polygon's example from PolyGeo: 27 | 28 | ```python 29 | 30 | poly1 = Polygon([(1208064.271243039,624154.6783778917), (1208064.271243039,601260.9785661874), (1231345.9998651114,601260.9785661874),(1231345.9998651114,624154.6783778917),(1208064.271243039,624154.6783778917)]) 31 | poly2 = loads("POLYGON ((1199915.6662253144 633079.3410163528, 1199915.6662253144 614453.958118695, 1219317.1067437078 614453.958118695, 1219317.1067437078 633079.3410163528, 1199915.6662253144 633079.3410163528)))" 32 | 33 | intersection = poly1.intersection(poly2) 34 | print intersection.wkt 35 | print mapping(intersection) -> GeoJSON 36 | 37 | ``` 38 | 39 | > The second premise is that the persistence, serialization, and map projection of features are significant, but orthogonal problems. You may not need a hundred GIS format readers and writers or the multitude of State Plane projections, and Shapely doesn’t burden you with them. 40 | 41 | So you combine it with other Python modules to read or write shapefiles and manipulate projections as osgeo.ogr, [Fiona][2] or [PyShp][3]. 42 | Searching in Gis StackExchange, you can find many examples but I give you another one to illustrate the combination of shapely and Fiona and the use of the shapely functions intersection() and buffer() (This could have been done with PyShp). 43 | 44 | Given two polyline shapefiles: 45 | 46 | ![enter image description here][4] 47 | 48 | Compute the intersection (function intersection() of shapely) 49 | 50 | ```python 51 | 52 | from shapely.geometry import Point, Polygon, MultiPolygon, MumtiPoint, MultiLineString,shape, mapping 53 | import fiona 54 | # read the shapefiles and transform to MultilineString shapely geometry (shape()) 55 | layer1 = MultiLineString([shape(line['geometry']) for line in fiona.open('polyline1.shp')]) 56 | layer2 = MultiLineString([shape(line['geometry']) for line in fiona.open('polyline2.shp')]) 57 | points_intersect = layer1.intersection(layer2) 58 | ``` 59 | 60 | Save the result as a new shapefile 61 | 62 | ```python 63 | 64 | # schema of the new shapefile 65 | schema = {'geometry': 'MultiPoint','properties': {'test': 'int'}} 66 | # write the new shapefile (function mapping() of shapely) 67 | with fiona.open('intersect.shp','w','ESRI Shapefile', schema) as e: 68 | e.write({'geometry':mapping(points_intersect), 'properties':{'test':1}}) 69 | ``` 70 | 71 | Result: 72 | 73 | ![enter image description here][5] 74 | 75 | Buffer individual points (function buffer() of shapely) 76 | 77 | ```python 78 | 79 | # new schema 80 | schema = {'geometry': 'Polygon','properties': {'test': 'int'}} 81 | with fiona.open('buffer.shp','w','ESRI Shapefile', schema) as e: 82 | for point in points: 83 | e.write({'geometry':mapping(point.buffer(300)), 'properties':{'test':1}}) 84 | ``` 85 | 86 | Result 87 | 88 | ![enter image description here][6] 89 | 90 | Buffer the MultiPoint geometry 91 | 92 | ```python 93 | 94 | schema = {'geometry': 'MultiPolygon','properties': {'test': 'int'}} 95 | points.buffer(300) 96 | with fiona.open('buffer2.shp','w','ESRI Shapefile', schema) as e: 97 | e.write({'geometry':mapping(points.buffer(300)), 'properties':{'test':1}}) 98 | ``` 99 | 100 | ![enter image description here][7] 101 | 102 | 103 | [1]: http://toblerity.org/shapely/manual.html 104 | [2]: http://toblerity.org/fiona/manual.html 105 | [3]: http://code.google.com/p/pyshp/ 106 | [4]: http://i.stack.imgur.com/bb6HE.jpg 107 | [5]: http://i.stack.imgur.com/jryaY.jpg 108 | [6]: http://i.stack.imgur.com/NTtsd.jpg 109 | [7]: http://i.stack.imgur.com/WnC9M.jpg 110 | -------------------------------------------------------------------------------- /Python Script for getting elevation difference between two points.md: -------------------------------------------------------------------------------- 1 | from [Python Script for getting elevation difference between two points](http://gis.stackexchange.com/questions/59316/python-script-for-getting-elevation-difference-between-two-points/59322) 2 | 3 | As a geologist, I often use this technique to make geological cross section in pure Python. I presented a complete solution in [Python: Using vector and raster layers in a geological perspective, without GIS software][1] (in French) 4 | 5 | I present here a summary in English: 6 | 7 | - to show you how to extract the elevation values ​​of a DEM 8 | - how to treat these values 9 | 10 | If you open a DEM with GDAL/OGR Python module: 11 | 12 | ```python 13 | from osgeo import gdal 14 | # raster dem10m 15 | file = 'dem10m.asc' 16 | layer = gdal.Open(file) 17 | gt =layer.GetGeoTransform() 18 | bands = layer.RasterCount 19 | print bands 20 | 1 21 | print gt 22 | (263104.72544800001, 10.002079999999999, 0.0, 155223.647811, 0.0, -10.002079999999999) 23 | ``` 24 | 25 | As a result, you have the number of bands and the geotransform parameters. If you want to extract the value of the raster under a xy point: 26 | 27 | ```python 28 | x,y = (263220.5,155110.6) 29 | # transform to raster point coordinates 30 | rasterx = int((x - gt[0]) / gt[1]) 31 | rastery = int((y - gt[3]) / gt[5]) 32 | # only one band here 33 | print layer.GetRasterBand(1).ReadAsArray(rasterx,rasterx, 1, 1) 34 | array([[222]]) 35 | ``` 36 | 37 | As it is a DEM, you get the elevation value under the point. With 3 raster bands with the same xy point you get 3 values (R,G,B). So you could make a function that allows to get the values of multiple rasters under a xy point: 38 | 39 | ```python 40 | def Val_raster(x,y,layer,bands,gt): 41 | col=[] 42 | px = int((x - gt[0]) / gt[1]) 43 | py =int((y - gt[3]) / gt[5]) 44 | for j in range(bands): 45 | band = layer.GetRasterBand(j+1) 46 | data = band.ReadAsArray(px,py, 1, 1) 47 | col.append(data[0][0]) 48 | return col 49 | ``` 50 | 51 | application 52 | 53 | ```python 54 | # with a DEM (1 band) 55 | px1 = int((x - gt1[0]) / gt1[1]) 56 | py1 = int((y - gt1[3]) / gt1[5]) 57 | print Val_raster(x,y,layer, band,gt) 58 | [222] # elevation 59 | # with a geological map (3 bands) 60 | px2 = int((x - gt2[0]) / gt2[1]) 61 | py2 = int((y - gt2[3]) / gt2[5]) 62 | print Val_raster(x,y,couche2, bandes2,gt2) 63 | [253, 215, 118] # RGB color 64 | ``` 65 | 66 | After that, you process the line profile (which may have segments): 67 | 68 | ```python 69 | # creation of an empty ogr linestring to handle all possible segments of a line with Union (combining the segements) 70 | profilogr = ogr.Geometry(ogr.wkbLineString) 71 | # open the profile shapefile 72 | source = ogr.Open('profilline.shp') 73 | cshp = source.GetLayer() 74 | # union the segments of the line 75 | for element in cshp: 76 | geom =element.GetGeometryRef() 77 | profilogr = profilogr.Union(geom) 78 | ``` 79 | 80 | To generate equidistant points on the line, you can use the [Shapely][2] module with interpolate (easier than ogr) 81 | 82 | ```python 83 | from shapely.wkb import loads 84 | # transformation in Shapely geometry 85 | profilshp = loads(profilogr.ExportToWkb()) 86 | # creation the equidistant points on the line with a step of 20m 87 | lenght=profilshp.length 88 | x = [] 89 | y = [] 90 | z = [] 91 | # distance of the topographic profile 92 | dista = [] 93 | for currentdistance in range(0,lenght,20): 94 | # creation of the point on the line 95 | point = profilshp.interpolate(currentdistance) 96 | xp,yp=point.x, point.y 97 | x.append(xp) 98 | y.append(yp) 99 | # extraction of the elevation value from the MNT 100 | z.append(Val_raster(xp,yp,layer, bands,gt)[0] 101 | dista.append(currentdistance) 102 | ``` 103 | 104 | and the results (with also the RGB values of a geologic map) with the x,y,z, distance values of the lists 105 | In 3D with [matplotlib][3] and [Visvis][4] (x,y,z values) 106 | 107 | ![enter image description here][5] 108 | 109 | Cross sections (x, elevation from currentdistance (dista list)) with [matplotlib][3]: 110 | ![enter image description here][6] 111 | 112 | ![enter image description here][7] 113 | 114 | 115 | 116 | [1]: http://www.portailsig.org/content/python-utilisation-des-couches-vectorielles-et-matricielles-dans-une-perspective-geologique- 117 | [2]: https://pypi.python.org/pypi/Shapely/1.2.17 118 | [3]: https://pypi.python.org/pypi/matplotlib/1.2.1 119 | [4]: https://pypi.python.org/pypi/visvis/1.8 120 | [5]: http://i.stack.imgur.com/fsTaZ.jpg 121 | [6]: http://i.stack.imgur.com/Bu6SE.jpg 122 | [7]: http://i.stack.imgur.com/xRrbC.jpg 123 | 124 | 125 | -------------------------------------------------------------------------------- /How to access vector coordinates in GRASS GIS from python?.md: -------------------------------------------------------------------------------- 1 | 2 | From [How to access vector coordinates in GRASS GIS from python?](http://gis.stackexchange.com/questions/28061/how-to-access-vector-coordinates-in-grass-gis-from-python) 3 | 4 | For walking a graph you have all the v.net family. 5 | To extract the vertices coordinates of lines or polygons (and other columns) one solution is, as always, through v.out.ascii that gives you the xy(z) coordinates(see [How one can find the starting and end point of a line in a vector file or how one can connect two line end to end using C code][1]) 6 | 7 | ```python 8 | test = grass.read_command("v.out.ascii", input="yourvector", format="standard") 9 | ``` 10 | The result is given in [v.out.ascii][2]. In my case, for example, the variable test is: 11 | 12 | ORGANIZATION: 13 | DIGIT DATE: 14 | MAP NAME: 15 | MAP DATE: Sun Jun 24 10:16:35 2012 16 | MAP SCALE: 1 17 | OTHER INFO: 18 | ZONE: 0 19 | MAP THRESH: 0.000000 20 | VERTI: 21 | L 7 1 22 | 206643.21517601 125181.18058576 23 | 201007.33432923 121517.8555206 24 | 208615.77587567 118699.91687157 25 | 199034.77765775 115036.59058769 26 | 200725.54321492 111936.8560102 27 | 192835.30987687 107428.14794157 28 | 192835.30987687 107428.14794157 29 | 1 1 30 | 31 | It is a (poly)line with one element and 7 vertices (L 7 1) and test is a Python string so 32 | ```python 33 | result = test.split("\n") 34 | ``` 35 | and you have a list with the lines of test. If you use regular expressions: 36 | 37 | ```python 38 | for line in result: 39 | if re.findall(r'^.[0-9]+\.',line): 40 | print line 41 | 42 | 206643.21517601 125181.18058576 43 | 201007.33432923 121517.8555206 44 | 208615.77587567 118699.91687157 45 | 199034.77765775 115036.59058769 46 | 200725.54321492 111936.8560102 47 | 192835.30987687 107428.14794157 48 | 192835.30987687 107428.14794157 49 | ``` 50 | and 51 | ```python 52 | coords = [] 53 | for line in result: 54 | if re.findall(r'^.[0-9]+\.',line): 55 | coords.append(line.strip().split(" ")) 56 | ``` 57 | gives you the solution 58 | ```python 59 | 60 | [['206643.21517601', '125181.18058576'], ['201007.33432923', '121517.8555206'], ['208615.77587567', '118699.91687157'], ['199034.77765775', '115036.59058769'], ['200725.54321492', '111936.8560102'], ['192835.30987687', '107428.14794157'], ['192835.30987687', '107428.14794157'], ['206643.21517601', '125181.18058576'], ['201007.33432923', '121517.8555206'], ['208615.77587567', '118699.91687157'], ['199034.77765775', '115036.59058769'], ['200725.54321492', '111936.8560102'], ['192835.30987687', '107428.14794157'], ['192835.30987687', '107428.14794157']] 61 | ``` 62 | After that, you can create a new point vector file with the xy values and [How one can find the starting and end point of a line in a vector file or how one can connect two line end to end using C code][1] 63 | 64 | 65 | If you want to use OGR python bindings, it is easy 66 | 67 | ```python 68 | from osgeo import ogr 69 | # open grass vector 70 | ds = ogr.Open('/grassdata/geol/test/vector/testline/head') 71 | layer = ds.GetLayer(0) 72 | layer.GetName() 73 | 'testline' 74 | feat = layer.GetFeature(0) 75 | geom = feature.GetGeometryRef() 76 | geom.ExportToWkt() 77 | 'LINESTRING (206643.21517600651714 125181.180585758760571,201007.334329231875017 121517.855520597659051,208615.775875667924993 118699.916871574707329,199034.77765774706495 115036.59058768954128,200725.543214922072366 111936.85601020231843,192835.30987687263405 107428.147941565141082,192835.30987687263405 107428.147941565141082)' 78 | for i in range(geometry.GetPointCount()): 79 | xy = geometry.GetPoint(i) 80 | print xy 81 | 82 | (206643.21517600652, 125181.18058575876, 0.0) 83 | (201007.33432923188, 121517.85552059766, 0.0) 84 | (208615.77587566792, 118699.91687157471, 0.0) 85 | (199034.77765774706, 115036.59058768954, 0.0) 86 | (200725.54321492207, 111936.85601020232, 0.0) 87 | (192835.30987687263, 107428.14794156514, 0.0) 88 | (192835.30987687263, 107428.14794156514, 0.0) 89 | ``` 90 | 91 | After that you can use other modules like shapely 92 | 93 | ```python 94 | from shapely.wkt import loads 95 | line =loads(geometry.ExportToWkt()) 96 | list(line.coords) 97 | [(206643.21517600652, 125181.18058575876), (201007.33432923188, 121517.85552059766), (208615.77587566792, 118699.91687157471), (199034.77765774706, 115036.59058768954), (200725.54321492207, 111936.85601020232), (192835.30987687263, 107428.14794156514), (192835.30987687263, 107428.14794156514)] 98 | 99 | ``` 100 | 101 | 102 | [1]: http://osgeo-org.1560.n6.nabble.com/How-one-can-find-the-starting-and-end-point-of-a-line-in-a-vector-file-or-how-one-can-connect-two-lie-td4542252.html 103 | [2]: http://grass.fbk.eu/gdp/html_grass64/v.in.ascii.html 104 | -------------------------------------------------------------------------------- /QGIS - How to store attributes of a large shapefile in a list?.md: -------------------------------------------------------------------------------- 1 | from [How to store attributes of a large shapefile in a list?](http://gis.stackexchange.com/questions/61935/how-to-store-attributes-of-a-large-shapefile-in-a-list/61968) 2 | 3 | 4 | It is not a problem of numpy arrays or other things, it's a problem of garbage collection. Each time you create a list, everything is stored in memory and if the list is big.... So you need to know Python (and not only PyQGIS) and the tricks to get out ("big data problem", you should reduce memory usage and use algorithms that do not slow down the process): 5 | 6 | **First: do not use a while loop (see [While loop][1]):** 7 | 8 | > "**While loops**, like the For Loop, are used for repeating sections of code - 9 | but unlike a for loop, the while loop will not run n times, 10 | but until a defined condition is met. As the for loop in Python is so powerful, 11 | while **is rarely used, except in cases where a user's input is required**" 12 | 13 | which is not the case here and it slows things due to first testing the True condition every loop. 14 | 15 | If you want to process all data in a layer in QGIS 1.8 (not necessary in master version which allows any process, even if the elements of a layer are not selected). 16 | 17 | ```python 18 | def select_all(layer): 19 | # select all elements of a layer, geometry and attributes 20 | layer.select([]) 21 | layer.setSelectedFeatures([obj.id() for obj in layer]) 22 | 23 | layer = qgis.utils.iface.activeLayer() 24 | select_all(layer) 25 | ``` 26 | And after 27 | 28 | ```python 29 | 30 | for elem in layer.selectedFeatures(): 31 | geom= elem.geometry() 32 | attrs = elem.attributeMap() 33 | ``` 34 | 35 | and no more while loop ! 36 | 37 | **Secondly, if you only need the values of a dictionary, uses attrs.values() and not attrs.iteritems(), forcing the loop to go through all keys and values** 38 | 39 | ```python 40 | addA = [] 41 | for elem in layer.selectedFeatures(): 42 | attrs = elem.attributeMap() 43 | for value in attrs.values(): 44 | addA.append(value.toString()) 45 | ``` 46 | 47 | **Thirdly, you can use iterators, generators or list comprehension**, see [Python Generator Hacking][3]: 48 | 49 | List comprehension (can be used anywhere a sequence is expected) 50 | 51 | what it means: 52 | 53 | ```python 54 | result = [] 55 | for x in s: 56 | if condition: 57 | result.append(expression) 58 | ``` 59 | 60 | so: 61 | 62 | ```python 63 | addA = [] 64 | for elem in layer.selectedFeatures(): 65 | attrs = elem.attributeMap() 66 | addA.append([value.toString() for value in attrs.values()]) 67 | ``` 68 | 69 | **and if you want, you can construct a nested list comprehension for addA in one line (without using a preliminary empty list, saving memory):** 70 | 71 | ```python 72 | addA = [[value.toString() for value in elem.attributeMap().values()] for elem in macouche.selectedFeatures()] 73 | ``` 74 | 75 | > "This means that list comprehensions aren’t useful if you’re working with iterators that return an infinite stream or a very large amount of data. Generator expressions are preferable in these situations" ([functional Python][4]) 76 | 77 | with Generators: 78 | 79 | > A generator is a one-time operation. It does not construct a list and you can iterate over the generated data once, but if you want to do it again, you have to call the generator function again. Once consumed, it disappears from memory. 80 | 81 | what it means (no list, return one value): 82 | 83 | ```python 84 | 85 | for x in s: 86 | if condition: 87 | yield expression 88 | ``` 89 | 90 | so: 91 | 92 | ```python 93 | 94 | addA = [] 95 | for elem in layer.selectedFeatures(): 96 | attrs = elem.attributeMap() 97 | generator =(value.toString() for value in attrs.values()) 98 | print generator 99 | 100 | at 0x12bff6eb0> 101 | .... 102 | ``` 103 | 104 | Its purpose is only iteration: 105 | 106 | ```python 107 | 108 | addA = [] 109 | for elem in layer.selectedFeatures(): 110 | attrs = elem.attributeMap() 111 | generator =(value.toString() for value in attrs.values()) 112 | for i in generator: 113 | addA.append(i) 114 | ``` 115 | 116 | and with a huge savings in memory area: 117 | 118 | ```python 119 | 120 | addA = [] 121 | # generator 122 | for i in ((value.toString() for value in elem.attributeMap().values()) for elem in macouche.selectedFeatures()): 123 | for j in i: 124 | addA.append(j) 125 | ``` 126 | 127 | I hope this will help 128 | 129 | 130 | 131 | [1]: http://wiki.python.org/moin/WhileLoop 132 | [2]: http://docs.python.org/2/howto/functional.html 133 | [3]: http://www.dabeaz.com/usenix2009/generators/GeneratorUSENIX.pdf 134 | [4]: http://docs.python.org/2/howto/functional.html 135 | -------------------------------------------------------------------------------- /How to install Fiona to read Shapefile attributes with OSGeo4W?.md: -------------------------------------------------------------------------------- 1 | 2 | From [How to install Fiona to read Shapefile attributes with OSGeo4W?](http://gis.stackexchange.com/questions/82200/how-to-install-fiona-to-read-shapefile-attributes-with-osgeo4w/82207) 3 | 4 | 1. Why would you want install [Fiona][1] if you can use PyQGIS to read the shapefile attributes ? 5 | 2. [Fiona][2] is for reading geometries **and** attributes of a shapefile file (as [PyShp][3]), therefore you don't need [dbfpy][4] (look at [Python Script examples for geoprocessing shapefiles without using arcpy][5]). 6 | 3. [Fiona][6] is a Python module so you must install it as any Python module in the site-packages folder of your Python installation as SaultDon says. 7 | 4. but as [Fiona][7] needs to compile C++ code (from GDAL/OGR) to install, you cannot use `pip` or `easy-install` on Windows (no compiler).You can try to install the "ready to use" version of [Christoph Gohlke][8] but it is linked to his version of [GDAL][9]) 8 | 5. this procedure works with the standalone version of QGIS. 9 | 10 | ###Examples of reading attributes of a shapefile: 11 | 12 | With Fiona: 13 | 14 | ```python 15 | 16 | import fiona 17 | features = fiona.open("strati.shp") 18 | features.schema 19 | {'geometry': 'Point', 'properties': OrderedDict([(u'PENDAGE', 'int:2'), (u'DIRECTION', 'int:3'), (u'TYPE', 'str:10')])} 20 | for feat in features: 21 | print feat['properties'] 22 | 23 | OrderedDict([(u'PENDAGE', 30), (u'DIRECTION', 120), (u'TYPE', u'incl')]) 24 | OrderedDict([(u'PENDAGE', 45), (u'DIRECTION', 145), (u'TYPE', u'incl')]) 25 | OrderedDict([(u'PENDAGE', 78), (u'DIRECTION', 148), (u'TYPE', u'incl')]) 26 | 27 | ``` 28 | 29 | With PyShp: 30 | 31 | ```python 32 | 33 | import shapefile 34 | reader = shapefile.Reader("strati.shp") 35 | fields = reader.fields[1:] 36 | print fields 37 | [['PENDAGE', 'N', 2, 0], ['DIRECTION', 'N', 3, 0], ['TYPE', 'C', 10, 0]] 38 | field_names = [field[0] for field in fields] 39 | schema = dict((d[0],d[1:]) for d in reader.fields[1:]) 40 | print schema 41 | {'DIRECTION': ['N', 3, 0], 'PENDAGE': ['N', 2, 0], 'TYPE': ['C', 10, 0]} 42 | for feat in reader.shapeRecords(): 43 | print dict(zip(field_names, sr.record)) 44 | 45 | {'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'} 46 | {'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'} 47 | {'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'} 48 | 49 | ``` 50 | 51 | with PyQGIS in the Python console: 52 | 53 | ```python 54 | 55 | layer = qgis.utils.iface.activeLayer() 56 | fields = layer.pendingFields() 57 | field_names = [field.name() for field in fields] 58 | field_types = [field.typeName() for field in fields] 59 | field_precision = [field.precision() for field in fields] 60 | print field_precision 61 | [0,0,0] 62 | print dict(zip(field_names,field_types)) 63 | {u'DIRECTION': u'Integer', u'PENDAGE': u'Integer', u'TYPE': u'String'} 64 | schema = dict((field_names[i], {field_types[i]:field_precision[i] if field_precision[i] > 0 else field_types[i]:'' }) for i in range(len(field_names))) 65 | print schema 66 | {u'DIRECTION': {u'Integer': ''}, u'PENDAGE': {u'Integer': ''}, u'TYPE': {u'String': ''}} 67 | for feat in layer.getFeatures(): 68 | print dict(zip(field_names, feat.attributes())) 69 | 70 | {u'DIRECTION': 120, u'PENDAGE': 30, u'TYPE': u'incl'} 71 | {u'DIRECTION': 145, u'PENDAGE': 45, u'TYPE': u'incl'} 72 | {u'DIRECTION': 148, u'PENDAGE': 78, u'TYPE': u'incl'} 73 | 74 | ``` 75 | 76 | With dbfpy: 77 | 78 | ```python 79 | 80 | 81 | from dbfpy import dbf 82 | db = dbf.Dbf("strati.dbf") 83 | print db.fieldNames 84 | ['PENDAGE', 'DIRECTION', 'TYPE'] 85 | print db.fieldDefs 86 | [PENDAGE N 2 0, DIRECTION N 3 0, TYPE C 10 0] 87 | schema = dict(zip(db.fieldNames,db.fieldDefs)) 88 | print schema 89 | {'DIRECTION': DIRECTION N 3 0, 'PENDAGE': PENDAGE N 2 0, 'TYPE': TYPE C 10 0} 90 | for feat in db: 91 | print dict(zip(db.fieldNames, feat.asList())) 92 | 93 | {'DIRECTION': 120, 'PENDAGE': 30, 'TYPE': 'incl'} 94 | {'DIRECTION': 145, 'PENDAGE': 45, 'TYPE': 'incl'} 95 | {'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'} 96 | 97 | ``` 98 | 99 | So you don't need dbfpy or other dbf Python module ([PyPI:dbf][10]) 100 | 101 | 102 | [1]: http://toblerity.org/fiona/manual.html 103 | [2]: http://toblerity.org/fiona/manual.html 104 | [3]: http://code.google.com/p/pyshp/ 105 | [4]: https://pypi.python.org/pypi/dbfpy/2.2.0 106 | [5]: http://gis.stackexchange.com/questions/64146/python-script-examples-for-geoprocessing-shapefiles-without-using-arcpy/64158#64158 107 | [6]: http://toblerity.org/fiona/manual.html 108 | [7]: http://toblerity.org/fiona/manual.html 109 | [8]: http://www.lfd.uci.edu/~gohlke/pythonlibs/#fiona 110 | [9]: http://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal 111 | [10]: https://pypi.python.org/pypi?:action=search&term=dbf&submit=search 112 | -------------------------------------------------------------------------------- /How do I find vector line bearing in QGIS or GRASS?.md: -------------------------------------------------------------------------------- 1 | 2 | from [How do I find vector line bearing in QGIS or GRASS?](http://gis.stackexchange.com/questions/55449/how-do-i-find-vector-line-bearing-in-qgis-or-grass/55480) 3 | 4 | 1. With PyQGIS in the Python console, see [How to add Direction and Distance to attribute table?][1] for the azimuths of the segments of a line (with the azimuth functions of Points: **point1.azimuth(point2**)) 5 | 2. but you can use many other Python modules like Shapely and Fiona without using QGIS see [Python: traitement des couches vectorielles dans une perspective géologique, lecture et enregistrement des couches sous forme de dictionnaires avec le module Fiona][2] (in French) 6 | 7 | ```python 8 | 9 | from shapely.geometry import Point, LineString, mapping 10 | import fiona 11 | import math 12 | 13 | def azimuth(point1, point2): 14 | '''azimuth between 2 shapely points (interval 0 - 180°, for my work)''' 15 | angle = math.atan2(point2.x - point1.x, point2.y - point1.y) 16 | return math.degrees(angle)if angle>0 else math.degrees(angle) + 180 17 | 18 | def pair(list): 19 | '''Iterate over pairs in a list ''' 20 | for i in range(1, len(list)): 21 | yield list[i-1], list[i] 22 | 23 | with fiona.collection('testline.shp', 'r') as input: 24 | # copy of the input schema' 25 | schema = input.schema.copy() 26 | # creation of a new field for storing azimuth 27 | schema['properties']['azimuth'] = 'int' 28 | # copy of the original shapefile with the field azimuth to a new shapefile 29 | with fiona.collection('testline_azim.shp', 'w', 'ESRI Shapefile', schema) as output: 30 | for line in input: 31 | # use of pair function to extract the line segments 32 | for seg_start, seg_end in pair(line['geometry']['coordinates']): 33 | line_start = Point(seg_start) 34 | line_end = Point(seg_end) 35 | segment = LineString([line_start.coords[0],line_end.coords[0]]) 36 | elem = {} 37 | elem['properties'] = line['properties'] 38 | elem['properties']['azimuth'] = azimuth(line_start, line_end) 39 | elem['geometry'] = mapping(segment) 40 | output.write(elem) 41 | ``` 42 | 43 | Result 44 | ![from Portail SIG][3] 45 | image from [PortailSIG][4] 46 | 47 | **With GRASS:** 48 | 49 | 1. split the polyline into individual segments with v.split vertices=1 50 | 2. upload the azimuth of each segment into the attribute table with v.to.db option=azimuth 51 | 52 | see [Angle between segments of a polyline ][5] or [azimuth of lines with v.to.db? ][6] 53 | 54 | **Update** 55 | 56 | in the Python console of QGIS with only PyQGIS 57 | 58 | ```python 59 | 60 | from PyQt4.QtCore import * 61 | import math 62 | 63 | def select_all(layer): 64 | layer.select([]) 65 | layer.setSelectedFeatures([obj.id() for obj in layer]) 66 | 67 | def azimuth(point1, point2): 68 | '''azimuth between 2 QGIS points ->must be adapted to 0-360°''' 69 | angle = math.atan2(point2.x() - point1.x(), point2.y() - point1.y()) 70 | return math.degrees(angle) 71 | 72 | def pair(list): 73 | '''Iterate over pairs in a list ''' 74 | for i in range(1, len(list)): 75 | yield list[i-1], list[i] 76 | 77 | mylayer = qgis.utils.iface.activeLayer() 78 | # select all the elements of the layer 79 | select_all(mylayer) 80 | 81 | # Memory layer 82 | v_layer = QgsVectorLayer("LineString", "azimuth_lines", "memory") 83 | pr = v_layer.dataProvider() 84 | pr.addAttributes( [ QgsField("azimuth", QVariant.Int), QgsField("az_pt1pt2",QVariant.Int),QgsField("az_pt2-1",QVariant.Int)]) 85 | 86 | for elem in mylayer.selectedFeatures(): 87 | line = elem.geometry().asPolyline() 88 | for seg_start, seg_end in pair(line): 89 | line_start = QgsPoint(seg_start) 90 | line_end = QgsPoint(seg_end) 91 | seg = QgsFeature() 92 | seg.addAttribute(0, QVariant(int(azimut(line_start,line_end)))) 93 | # with the functions of PyQGIS 94 | seg.addAttribute(1, QVariant(int(line_start.azimuth(line_end)))) 95 | seg.addAttribute(2, QVariant(int(line_end.azimuth(line_start)))) 96 | seg.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 97 | pr.addFeatures( [ seg ] ) 98 | v_layer.updateExtents() 99 | v_layer.updateFieldMap() 100 | 101 | QgsMapLayerRegistry.instance().addMapLayers([v_layer]) 102 | ``` 103 | 104 | Result 105 | ![enter image description here][7] 106 | 107 | and 360 -159 = 201 -180 = 21 108 | 109 | [1]: http://gis.stackexchange.com/questions/24260/how-to-add-direction-and-distance-to-attribute-table/24430#24430 110 | [2]: http://www.portailsig.org/content/python-traitement-des-couches-vectorielles-dans-une-perspective-geologique-lecture-et-enregi 111 | [3]: http://i.stack.imgur.com/Xg98Z.jpg 112 | [4]: http://www.portailsig.org/ 113 | [5]: http://osgeo-org.1560.n6.nabble.com/Angle-between-segments-of-a-polyline-td3895453.html 114 | [6]: http://osgeo-org.1560.n6.nabble.com/azimuth-of-lines-with-v-to-db-td3915504.html 115 | [7]: http://i.stack.imgur.com/WC51u.jpg 116 | -------------------------------------------------------------------------------- /How to calculate distances in a point sequence?.md: -------------------------------------------------------------------------------- 1 | From [How to calculate distances in a point sequence?](http://gis.stackexchange.com/questions/44064/how-to-calculate-distances-in-a-point-sequence) 2 | 3 | I return to this issue because it is very similar to [How do I find vector line bearing in QGIS or GRASS?][1] and it can be solved with Python in the same way: 4 | 5 | 1) Haversine distance 6 | 7 | One can find lots of scripts by searching Haversine distance with Python on the Internet and I choose one of them in [Haversine Formula in Python (Bearing and Distance between two GPS points)][2] 8 | 9 | ```python 10 | 11 | def haversine(lon1, lat1, lon2, lat2): 12 | """ 13 | Calculate the great circle distance between two points 14 | on the earth (specified in decimal degrees) 15 | """ 16 | # convert decimal degrees to radians 17 | lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2]) 18 | # haversine formula 19 | dlon = lon2 - lon1 20 | dlat = lat2 - lat1 21 | a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2 22 | c = 2 * math.asin(math.sqrt(a)) 23 | km = 6367 * c 24 | return km 25 | ``` 26 | 27 | We have a series of lines (points) in the file that must be treated in pairs (point1 - point2) to calculate the distance. For this we will use a simple iterator from [Most pythonic way to get the previous element][3] 28 | 29 | ```python 30 | 31 | def offset(iterable): 32 | prev = None 33 | for elem in iterable: 34 | yield prev, elem 35 | prev = elem 36 | ``` 37 | 38 | Now it is possible to read the file (example of Kerrie) in pairs of lines/points 39 | 40 | ```python 41 | 42 | import csv 43 | with open('testhavers.csv', 'rb') as f: 44 | reader = csv.DictReader(f) 45 | for pair in offset(reader): 46 | print pair 47 | 48 | (None, {'LAT': '10.08527', 'LON': '124.59833', 'ID': '1', 'TIME': '21:24:37'}) 49 | ({'LAT': '10.08527', 'LON': '124.59833', 'ID': '1', 'TIME': '21:24:37'}, 50 | {'LAT': '10.08523', 'LON': '124.59830', 'ID': '2', 'TIME': '21:25:07'}) 51 | ({'LAT': '10.08523', 'LON': '124.59830', 'ID': '2', 'TIME': '21:25:07'}, 52 | {'LAT': '10.08526', 'LON': '124.59832', 'ID': '3', 'TIME': '21:25:37'}) 53 | ({'LAT': '10.08526', 'LON': '124.59832', 'ID': '3', 'TIME': '21:25:37'}, 54 | {'LAT': '10.08526', 'LON': '124.59831', 'ID': '4', 'TIME': '21:26:07'}) 55 | 56 | ``` 57 | 58 | Then create a shapefile containing the original fields of the csv file and a new field for the distance with the Python modules Shapely and Fiona of Sean Gillies: 59 | 60 | ```python 61 | 62 | import fiona 63 | from shapely.geometry import Point, mapping 64 | # creation of the schema of the shapefile (geometry and fields) 65 | schema = { 'geometry': 'Point', 'properties':{'ID': 'int', 'LAT':'float', 'LON':'float', 'TIME':'str','distance' : 'float'}} 66 | # creation of the shapefile: 67 | with fiona.collection("result.shp", "w", "ESRI Shapefile", schema) as output: 68 | # reading the csv file 69 | with open('testhavers.csv', 'rb') as f: 70 | reader = csv.DictReader(f) 71 | # we need here to eliminate the first pair of point with None 72 | for i, pair in enumerate(offset(reader)): 73 | if i == 0: (pair with None) 74 | # writing of the point geometry and the attributes 75 | point = Point(float(pair[1]['LON']), float(pair[1]['LAT'])) 76 | dist = 0 # None 77 | output.write({'properties': {'ID':int(pair[1]['ID']),'LAT':float(pair[1]['LAT']),'LON':float(pair[1]['LON']), 'TIME':pair[1]['TIME'],'distance': dist},'geometry': mapping(point)}) 78 | else: 79 | # writing of the point geometry and the attributes 80 | point = Point(float(pair[1]['LON']), float(pair[1]['LAT'])) 81 | # Haversine distance between pairs of points 82 | dist = haversine(float(pair[0]['LON']), float(pair[0]['LAT']), float(pair[1]['LON']),float(pair[1]['LAT'])) 83 | output.write({'properties': {'ID':int(pair[1]['ID']),'LAT':float(pair[1]['LAT']),'LON':float(pair[1]['LON']), 'TIME':pair[1]['TIME'],'distance': dist},'geometry': mapping(point)}) 84 | 85 | ``` 86 | and the result: 87 | ![enter image description here][4] 88 | 89 | It is also possible to do it with PyQGIS but it is more complex than Fiona which uses simple dictionaries to create shapefiles. 90 | 91 | You can use another function to calculate the Haversine distance ([Why is law of cosines more preferable than haversine when calculating distance between two latitude-longitude points?][5]) without any problem, only the distance calculation changes, not the process of creating the shapefile. 92 | 93 | 94 | 95 | 96 | 97 | [1]: http://gis.stackexchange.com/questions/55449/how-do-i-find-vector-line-bearing-in-qgis-or-grass/55480#55480 98 | [2]: http://stackoverflow.com/questions/4913349/haversine-formula-in-python-bearing-and-distance-between-two-gps-points 99 | [3]: http://stackoverflow.com/questions/12076270/most-pythonic-way-to-get-the-previous-element/12076386#12076386 100 | [4]: http://i.stack.imgur.com/7UzpA.jpg 101 | [5]: http://gis.stackexchange.com/questions/4906/why-is-law-of-cosines-more-preferable-than-haversine-when-calculating-distance-b 102 | -------------------------------------------------------------------------------- /Python Script examples for geoprocessing shapefiles without using arcpy.md: -------------------------------------------------------------------------------- 1 | from [Python Script examples for geoprocessing shapefiles without using arcpy](http://gis.stackexchange.com/questions/64146/python-script-examples-for-geoprocessing-shapefiles-without-using-arcpy/64158) 2 | 3 | 4 | That's strange, as if people suddenly discovered the power of Python (without ArcPy which is just one Python module among others), see for example the question [Visualize shapefile in Python][1]: 5 | 6 | - **geospatial processing in Python has a very long history, much older than Arcpy (or arcgisscripting)** -> no "mimic" the capabilities of ArcPy here, as Paul says, most were already there before ArcPy. 7 | - the reference for the Python modules is the **Python Package Index** (**Pypi**) and there is a dedicated section: [Topic :: Scientific/Engineering :: GIS][2] 8 | - you can do anything with these modules and it is often easier and faster than ArcPy because it is pure Python (no cursors...). 9 | - [Shapely][3] is one of these modules for processing geospatial geometries -> calculate areas of a polygon and convert polygons to points.. 10 | - if you want to process vector layers, there is [osgeo/ogr][4], [Fiona][5] or [Pyshp][6] (and others, less used) -> query a shapefile by attributes, create new layer from selection, calculate areas of a polygon, convert polygons to points 11 | - for processing rasters, the standard is [osgeo/gdal][7] 12 | - for spatial analysis, there is [Pysal][8] 13 | - for 3D, you can use other Scientific modules like [numpy][9] or [scipy][10] (3D algorithms, grids, but also statistics, geostatistics, 2D or 3D) 14 | - And I don't talk about [mapnik][11], [matplotlib/basemap][12],[Geodjango][13] and ... 15 | 16 | 17 | You can combine all (Pysal with shapely, ...) and mix them with the other Scientific modules. 18 | 19 | **Thus for Python Script examples, search for Pyshp Fiona, ogr, gdal or shapely in gis.stackexchange or the internet** (many examples, not only in English).) 20 | One of them in French (the scripts and the figures are universal !): 21 | - [Python: Using vector and raster layers in a geological perspective, without GIS software][14] 22 | an other in English: 23 | - [GIS with Python, Shapely, and Fiona][15] 24 | and in Spanish 25 | - [Determination of areas of irregular polygons using the coordinates of the vertices ][16] 26 | in gis.stackexchange 27 | - [Elevation profile 10 km each side of a line][17] 28 | - [Updating Attributes using Pyshp][18] 29 | - [How to create a 3D shapefile from a raster?][19] 30 | - [Python Script for getting elevation difference between two points][20] 31 | - etc 32 | 33 | The script presented by Aaron can be written more simply with Fiona that uses only Python dictionaries: 34 | 35 | ```python 36 | import fiona 37 | with fiona.open('sites.shp', 'r') as input: 38 | with open('hw1a.txt', 'w') as output: 39 | for pt in input: 40 | id = pt['properties']['id'] 41 | cover = pt['properties']['cover'] 42 | x = str(point['geometry']['coordinates'][0]) 43 | y = str(point['geometry']['coordinates'][21]) 44 | output.write(id + ' ' + x + ' ' + y+ ' ' + cover + '\n') 45 | ``` 46 | 47 | and if you use shapely in addition: 48 | 49 | ```python 50 | from shapely.geometry import shape 51 | with fiona.open('sites.shp', 'r') as input: 52 | with open('hw1a.txt', 'w') as output: 53 | for pt in input: 54 | id = pt['properties']['id'] 55 | cover = pt['properties']['cover'] 56 | x = str(shape(pt['geometry']).x) 57 | y = str(shape(pt['geometry']).y) 58 | output.write(id + ' ' + x + ' ' + y+ ' ' + cover + '\n') 59 | ``` 60 | 61 | There are also two books: 62 | 63 | [Python Geospatial Development][22] of Eric Westra. 64 | 65 | ![enter image description here][23] 66 | 67 | [Learning Geospatial Analysis with Python][27] of Joel Lawhead 68 | 69 | ![enter image description here][28] 70 | 71 | 72 | Python is also used as a scripting language in other GIS applications like QGIS (Quantum GIS), GRASS GIS, gvSIG or OpenJump or 3D modelers like [Paraview][24] (and [Blender][25] also !). And you can use the majority of the geospatial modules in all these application (see [Visualising QGIS data with Blender][26]) 73 | 74 | 75 | [1]: http://gis.stackexchange.com/questions/61862/visualize-shapefile-in-python/61868#61868 76 | [2]: https://pypi.python.org/pypi?:action=browse&show=all&c=391 77 | [3]: https://pypi.python.org/pypi/Shapely 78 | [4]: https://pypi.python.org/pypi/GDAL 79 | [5]: https://pypi.python.org/pypi/Fiona 80 | [6]: https://pypi.python.org/pypi/Fiona 81 | [7]: https://pypi.python.org/pypi/GDAL 82 | [8]: http://pythonhosted.org/PySAL/ 83 | [9]: http://www.numpy.org/ 84 | [10]: https://pypi.python.org/pypi/mayavi 85 | [11]: http://mapnik.org/ 86 | [12]: http://matplotlib.org/basemap/ 87 | [13]: http://geodjango.org/ 88 | [14]: http://www.portailsig.org/content/python-utilisation-des-couches-vectorielles-et-matricielles-dans-une-perspective-geologique- 89 | [15]: http://macwright.org/2012/10/31/gis-with-python-shapely-fiona.html 90 | [16]: http://joseguerreroa.wordpress.com/2012/10/27/determinacion-de-areas-de-poligonos-irregulares-usando-las-coordenadas-de-sus-vertices-en-un-script-de-python/ 91 | [17]: http://gis.stackexchange.com/questions/50108/elevation-profile-10-km-each-side-of-a-line/50841#50841 92 | [18]: http://gis.stackexchange.com/questions/57635/updating-attributes-using-pyshp/57696#57696 93 | [19]: http://gis.stackexchange.com/questions/56703/better-way-to-duplicate-a-layer-using-ogr-in-python/56722#56722 94 | [20]: http://gis.stackexchange.com/questions/59316/python-script-for-getting-elevation-difference-between-two-points/59322#59322 95 | [21]: http://gis.stackexchange.com/questions/61862/visualize-shapefile-in-python/61868#61868 96 | [22]: http://www.packtpub.com/python-geospatial-development/book 97 | [23]: http://i.stack.imgur.com/4yW9e.png 98 | [24]: http://www.paraview.org/ 99 | [25]: http://www.blender.org/ 100 | [26]: http://kodex.tumblr.com/post/37038839550/visualising-qgis-data-with-blender 101 | [27]:http://www.packtpub.com/learning-geospatial-analysis-with-python/book 102 | [28]:http://dgdsbygo8mp3h.cloudfront.net/sites/default/files/imagecache/productview_larger/1138OS_Cov.jpg 103 | 104 | --------------------------------------------------------------------------------