Python JSON libraries

JavaScript Object Notation (JSON) is rapidly becoming the number one data exchange format across a lot of fields. The lightweight syntax and the similarity to existing data structures in both the JavaScript from which Python borrows some data structures makes it a perfect match for Python.

The following GeoJSON sample document contains a single point:

{
    "type": "Feature",
    "id": "OpenLayers.Feature.Vector_314",
    "properties": {},
    "geometry": {
        "type": "Point",
        "coordinates": [
            97.03125,
            39.7265625
        ]
    },
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
        }
    }
}

This sample is just a simple point with new attributes, which would be stored in the properties data structure of the geometry. First, we'll compact the sample document into a single string to make it easier to handle:

>>> jsdata = """{ "type": "Feature", "id": "OpenLayers.Feature.Vector_314", "pro
perties": {}, "geometry": { "type": "Point", "coordinates": [ 97.03125, 39.72656
25 ] }, "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.
3:CRS84" } } }"""

The json module

GeoJSON looks very similar to a nested set of Python's dictionaries and lists. Just for fun, let's just try and use Python's eval() function to parse it as Python code:

>>> point = eval(jsdata)
>>> point["geometry"]
{'type': 'Point', 'coordinates': [97.03125, 39.7265625]}

Wow! That just worked! We turned that random GeoJSON string into native Python data in one easy step. Keep in mind that the JSON data format is based on JavaScript syntax which happens to be similar to Python. Also, as you get deeper into GeoJSON data and work with larger data, you'll find that JSON allows characters that Python does not. Using Python's eval() function is considered very insecure as well. But as far as keeping things simple is concerned, note that it doesn't get any simpler than that!

Thanks to Python's drive towards simplicity, the more advanced method doesn't get much more complicated. Let's use Python's json module, which is part of the standard library, to turn the same string into Python the right way:

>>> import json
>>> json.loads(jsdata)
{u'geometry': {u'type': u'Point', u'coordinates': [97.03125, 39.7265625]}, u'crs
': {u'type': u'name', u'properties': {u'name': u'urn:ogc:def:crs:OGC:1.3:CRS84'}
}, u'type': u'Feature', u'id': u'OpenLayers.Feature.Vector_314', u'properties':
{}}

As a side note, in the previous example the CRS84 property is a synonym for the common WGS84 coordinate system. The json module adds some nice features such as safer parsing and conversion of strings to Unicode. We can export Python data structures to JSON in almost the same way:

>>> pydata = json.loads(jsdata)
>>> json.dumps(pydata)
'{"geometry": {"type": "Point", "coordinates": [97.03125, 39.7265625]}, "crs": {
"type": "name", "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}}, "type"
: "Feature", "id": "OpenLayers.Feature.Vector_314", "properties": {}}'

The geojson module

We could happily go on reading and writing GeoJSON data using the json module forever, but there's an even better way. The geojson module available on PyPI offers some distinct advantages. For starters, it knows the requirements of the GeoJSON specification, which can save a lot of typing. Let's create a simple point using this module and export it to GeoJSON:

>>> import geojson
>>> p = geojson.Point([-92, 37])
>>> geojs = geojson.dumps(p)
>>> geojs
'{"type": "Point", "coordinates": [-92, 37]}'

Notice that the geojson module has an interface for different data types and saves us from setting the type and coordinates attributes manually. Now imagine if you had a geographic object with hundreds of features. You could programmatically build this data structure instead of building a very large string. The geojson module is also the reference implementation for the Python __geo_interface__ convention. This interface allows cooperating programs to exchange data seamlessly and in a Pythonic way without the programmer explicitly exporting and importing GeoJSON strings. So, if we wanted to feed the point we created with the geojson module to the Shapely module, we could perform the following command, which reads the geojson module's point object straight into Shapely after which we'll export it as WKT:

>>> from shapely.geometry import asShape
>>> point = asShape(p)
>>> point.wkt
'POINT (-92.0000000000000000 37.0000000000000000)'

More and more geospatial Python libraries are implementing both the geojson and __geo_interface__ functionality including PyShp, Fiona, Karta, and ArcGIS. Third-party implementations exist for QGIS.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset