Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Open Source Geospatial Spatial Programming Barry Rowlingson School of Health and Medicine, Lancaster University 1 Spatial programming is just combining any programming language with spatial data. Now because spatial data can be so complicated, you may find someone has already done some of the work for you. Laziness C C++ Python GDAL DATA OGR R Fortran 2 Laziness is one of the three virtues of programmers. I can't be bothered to tell you the other two, go look them up. Laziness means we never do anything more times than we have to. We don't reinvent that wheel. So If we want to get to our precious geodata, we use the existing libraries – most likely GDAL for rasters and OGR for vectors. ”bindings” to different languages exist – for gdal and ogr the most common ones are C, C++, and Python, and there's also a way to use them from R. Sadly Fortran programmers may be a bit stuck. There might be a way in via the C library, but I'm not sure anyone has ever attempted it. Good luck. So what does it look like to use these libraries? OGR in Python >>> import ogr >>> europe = ogr.Open(”europe.shp”) >>> europe <ogr.DataSource instance at 0xb59f2c0c> >>> layer = europe.GetLayer(0) >>> layer <ogr.Layer instance at 0xb59f2c8c> >>> f = layer.GetFeature(3) >>> [f.GetFieldDefnRef(i).GetName() for i in range(f.GetFieldCount())] ['CNTRY_NAME', 'COUNT', 'FIRST_FIPS', 'FIRST_REGI', 'FIRST_CONT', 'SUM_POP_AD', 'SUM_SQKM_A', 'SUM_SQMI_A'] >>> f.GetFieldAsInteger("COUNT") 11 >>> f.GetFieldAsString("CNTRY_NAME") 'Belgium' 3 Here's how you do it in Python. Python is an easy to learn general purpose programming language, with lots of extra modules. Here I'm using the ogr module. I import it, and then I can use it. I can open a shapefile just like that. Or any other data type that OGR supports. The details are hidden from me. Once I have the shapefile read in, I can query it. Technically now its an OGR Data Source, and it has Layers. So I get the first layer (which python calls layer zero). Now I can query that layer. Layers have Features, so I get the fourth feature (they start with zero) and now I have a feature object. I can query that. Here's the names of its attributes and the value of two of them. We now know that the fourth feature in Europe.shp is Belgium. OGR in Python >>> geom = f.GetGeometryRef() >>> geom.GetGeometryType() == ogr.wkbPolygon True >>> geom.GetArea() 3.89416677221379 >>> geom.GetEnvelope() (2.5416665077209473, 6.3982038497924805, 49.504165649414062, 51.503608703613281) >>> geom.ExportToGML() '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing> <gml:coordinates>3.182874202728271,50.757049560546875 3.164721965789795,50.780548095703125 3.162221908569336,50.783607482910156 3.154444217681885,50.788330078125 3.149722099304199,50.789993286132812 3.143332958221436,50.79083251953125 ..... 4 As well as the attributes you can also query the geometry of a feature. Here I've confirmed that what I've got are polygons, I've got the area of Belgium (in square degrees, so not a very useful measure), and the coordinates of the bounding box. Then I've converted it to GML. So I can get in a few lines of Python all my geoinformation. And once it's in my programming language I can do anything with it. And then I can write it back out into maps or tables of summaries or stick it in a database or email it to my friends or whatever. OGR in C++ OGRRegisterAll(); OGRDataSource *poDS; poDS = OGRSFDriverRegistrar::Open( "point.shp", FALSE ); if( poDS == NULL ) { printf( "Open failed.\n" ); exit( 1 ); } OGRLayer *poLayer; poLayer = poDS>GetLayerByName( "point" ); OGRFeature *poFeature; poLayer>ResetReading(); 5 Here's how to do a similar thing in C++. The concepts are the same – data source, layer, feature – but the syntax is different because this is C++ and not Python. If you understand one, you can understand the other. Laziness. OGR in C++ poFeature = poLayer>GetNextFeature() OGRFeatureDefn *poFDefn = poLayer>GetLayerDefn(); int iField; for( iField = 0; iField < poFDefn>GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn>GetFieldDefn( iField ); if( poFieldDefn>GetType() == OFTInteger ) printf( "%d,", poFeature>GetFieldAsInteger( iField ) ); else if( poFieldDefn>GetType() == OFTReal ) printf( "%.3f,", poFeature>GetFieldAsDouble(iField) ); else if( poFieldDefn>GetType() == OFTString ) printf( "%s,", poFeature>GetFieldAsString(iField) ); else printf( "%s,", poFeature>GetFieldAsString(iField) ); } OGRGeometry *poGeometry; OGRPoint *poPoint = (OGRPoint *) poGeometry; printf( "%.3f,%3.f\n", poPoint>getX(), poPoint>getY() ); 6 And here's how you get the feature attributes and the geometry. This example actually loops over all attributes of the feature and prints the data out. So how do you figure out how to do all this stuff? Well you read the documentation, learn about the architecture, and consult the API. API 7 The API is the public face of a library. It tells you what you can do with it. This page from the OGR documentation explains the fundamentals – data sources, layers, features, attributes and so on. OGR reference api 8 From there you can click through to get documentation for specific functions in the library – here is the help for the Open function that opens a data source. This example is for C++. There's another good source of help, and that is other people's source. Use The Source, Luke! 9 Here's a chunk of the source code from the OGR library. It's open source, so you can read and learn. It's also very neatly laid out with hyperlinks between functions and clicks to get you to the documentation. You can very rapidly jump around in the code and as long as you dont get lost you'll learn stuff pretty quickly and soon be writing your own programs. Virgilio is now going to show you some applications of spatial programming using the R programming language.