Tag Archives: shapefile.py

JSON to Shapefile

31 Jan

Toronto has a bunch of open data – which is awesome! Someone I follow on Twitter was looking to convert some parking JSON to a Shapefile. I haven’t used it much, but python has a JSON module in 2.7 and SimpleJSON in 2.5. And of course, writing shapefiles is simple with shapefile.py.

JSON is a dictionary. Once it is loaded in a data variable, you can call items by the key. So for the carparks, I could call: data[“carparks”][i][“id”] or data[“carparks”][i][“lat”], where i is the index or the array. Then iterate, while i < len(data[“carparks”]).

Here is the full code:

import shapefile
import json

json_data=open(‘greenPParking.json’)
data = json.load(json_data)

w=shapefile.Writer(shapefile.POINT)
w.field(“id”)
w.field(“address”)
w.field(“lat”)
w.field(“lng”)
w.field(“rate”)
w.field(“rate_half_hour”)
w.field(“carpark_type”)
w.field(“carpark_type_str”)
w.field(“capacity”)
w.field(“max_height”)
w.field(“payment_options”)

i=0 # should be changed to — while (i < len(data[“carparks”]))
while (i<243):

w.point(float(data[“carparks”][i][“lng”]),float(data[“carparks”][i][“lat”]))
w.record(data[“carparks”][i][“id”],data[“carparks”][i][“address”],data[“carparks”][i][“lat”],data[“carparks”][i][“lng”],data[“carparks”][i][“rate”],data[“carparks”][i][“rate_half_hour”],data[“carparks”][i][“carpark_type”],data[“carparks”][i][“carpark_type_str”],data[“carparks”][i][“max_height”],data[“carparks”][i][“capacity”],data[“carparks”][i][“payment_options”],data[“carparks”][i][“rate_details”])
i+=1

prj = open(“csvSHP.prj”, “w”)
epsg = ‘GEOGCS[“WGS 84”,’
epsg += ‘DATUM[“WGS_1984”,’
epsg += ‘SPHEROID[“WGS 84”,6378137,298.257223563]]’
epsg += ‘,PRIMEM[“Greenwich”,0],’
epsg += ‘UNIT[“degree”,0.0174532925199433]]’
prj.write(epsg)
prj.close()

w.save(“greenPParkingSHP”)
json_data.close()

Advertisements

Creating a Shapefile From a MongoDB Using Python

14 Nov

I am always looking for ways to store data and create shapefiles, or other filetypes I need, from it. Just picked up a book on MongoDB last night and have thrown together a quick example of how to enter some point data using Long and Lat and then retrieving the data and sending it to Shapefile.py. This is the first example, if I get around to it, the next example will query for 10 points near another then spit that out to a shapefile. But I need to walk before I run, so here are my first steps.

  1. Install Mongo
  2. Install pymongo
  3. Install Shapefile.py Check out this blog for more info – this guy is awesome, it is where I got the code to write the projection: GeoSpatial Python.
  4. Run mongod
  5. You can use mongo, a full JavaScript Shell, to enter data, but I used Python.
  6. Enter some data. I entered two points (35,-106) and (35.8,-106.8)
  7. write a python program to convert this data to a shapefile.

Here is the python program to retrieve these two points, write a shapefile and a PRJ:

from pymongo import Connection,GEO2D
import shapefile

db=Connection().geo
w=shapefile.Writer(shapefile.POINT)
w.field(“comment”)

for x in db.places.find():
w.point(float(x[“loc”][0]),float(x[“loc”][1]))
w.record(“Booya!”)

prj = open(“Web.prj”, “w”)
epsg = ‘GEOGCS[“WGS 84”,’
epsg += ‘DATUM[“WGS_1984”,’
epsg += ‘SPHEROID[“WGS 84”,6378137,298.257223563]]’
epsg += ‘,PRIMEM[“Greenwich”,0],’
epsg += ‘UNIT[“degree”,0.0174532925199433]]’
prj.write(epsg)
prj.close()

w.save(“mongoSHP”)

;

Now you should have a shapefile with 2 points in WGS84

Shapefile Creator Website Using Cherrypy

8 Nov

I showed how to create a shapefile using python, now I want to make the tool public with a web based front-end. My python web framework of choice is Cherrypy. -a minimal web framework.

My website will allow you to enter Longitude, Latitude and a comment. I am working on a text area where you can paste data. Here ie my website:

And when you submit, you can download a ZIP of your shapefile.

Pretty simple. I don’t really know what the use case is – if you have GIS and Long/Lat you would just import it directly. And if you don’t have GIS, why do you need a shapefile? But I guess this shows how you can perform GIS data functions through the web using python. Maybe connect some toolboxes and use Arcpy to allow people to run your models with their data – without giving your model and logic away.

My code is not pretty and no built for production – it is built to work. Here it is.

import cherrypy
import shapefile
from cherrypy.lib.static import serve_file
import zipfile

class SHP(object):

def index(self):
return “””<HTML><HEAD><TITLE>SHAPEFILE CREATOR</TITLE></HEAD>
<BODY><FORM NAME=’shp’ action=’paul’>Latitude: <input type=’text’ name=’lat’><BR>Longitude: <input type=’text’ name=’long’>
<BR>Comment: <input type=’text’ name=’comment’><BR><input type=’submit’ Value=’SUBMIT’>
</FORM></BODY></HTML>”””

index.exposed = True

def paul(self,lat,long,comment):
w = shapefile.Writer(shapefile.POINT)
Flat=float(lat)
Flong=float(long)
w.point(Flong, Flat)
w.field(‘Comment’)
w.record(comment)
w.save(‘Web’)
prj = open(“Web.prj”, “w”)
epsg = ‘GEOGCS[“WGS 84”,’
epsg += ‘DATUM[“WGS_1984”,’
epsg += ‘SPHEROID[“WGS 84”,6378137,298.257223563]]’
epsg += ‘,PRIMEM[“Greenwich”,0],’
epsg += ‘UNIT[“degree”,0.0174532925199433]]’
prj.write(epsg)
prj.close()
zipped = zipfile.ZipFile(‘YourShapefile.zip’, mode=’w’)
zipped.write(‘Web.shp’)
zipped.write(‘Web.shx’)
zipped.write(‘Web.dbf’)
zipped.write(‘Web.prj’)
zipped.close()
return “Download Shapefile: <a href=’/get?filepath=C:\Documents and Settings\user\Desktop\YourShapefile.zip’>YourShapefile</a>”

paul.exposed = True

def get(self, filepath):
return serve_file(filepath, “application/x-download”, “attachment”)
get.exposed = True

cherrypy.config.update({‘server.socket_host’: ‘127.0.0.1’,
‘server.socket_port’: 8000,
})

cherrypy.quickstart(SHP())

Shapefiles to Revit or AutoCAD: Using Python to write DXF

29 Oct

I have shown how to get shapefiles in Revit Using Qgis, and mentioned how to do the same with AutoDesk Civil and ESRI ArcMap. But I have another way – Python.

I have written a program that will read in a point shapefile and convert it to DXF. If you have a survey point shapefile, run my script and you will have a survey point DXF. I would love to write to DWG but AutoDesk charges for that library – proprietary file formats and all….

I always start my programs with baby steps – no matter how simple the problem. So let me walk through how this code developed.

First, I drew a DXF from Python manually – lines then points.

Lines:

from dxfwrite import DXFEngine as dxf
drawing = dxf.drawing(‘testLines.dxf’)
drawing.add_layer(‘SURVEY’)
drawing.add(dxf.line((0, 0), (1, 0), color=7, layer=’SURVEY’))
drawing.add(dxf.line((2, 0), (3, 0), color=5, layer=’SURVEY’))
drawing.save()

Points:

from dxfwrite import DXFEngine as dxf
drawing = dxf.drawing(‘DXF.dxf’)
drawing.add_layer(‘SURVEY’)
points = dxf.point((1, 5), color=7, layer=’SURVEY’)

drawing.add(points)

drawing.save()

Then I wanted to try from an Excel file since this is easy practice for passing points to the DXFEngine:

from dxfwrite import DXFEngine as dxf
import xlrd
book = xlrd.open_workbook(“readdxf.xls”)
sh = book.sheet_by_index(0)
drawing = dxf.drawing(‘DXFFromExcel.dxf’)
drawing.add_layer(‘SURVEY’)

def readRow():
for rownum in range(sh.nrows):
rows=sh.row_values(rownum)
points = dxf.point((sh.cell_value(rowx=rownum, colx=0), sh.cell_value(rowx=rownum, colx=1)), color=7, layer=’SURVEY’)
drawing.add(points)
print ‘Reading Record: ‘+ str(rownum)

else:
print ‘Complete…’

readRow()
drawing.save()

Lastly, I read from a shapefile:

from dxfwrite import DXFEngine as dxf
import shapefile
drawing = dxf.drawing(‘DXFFromSHP.dxf’)
drawing.add_layer(‘SURVEY’)
openshape = shapefile.Reader(“C:\Documents and Settings\user\Desktop\surveyShapefile”)
shpPoints = openshape.shapes()

def readShapefile():
x = 0
while (x <= 100):
points = dxf.point((shpPoints[x].points[0]), color=7, layer=’SURVEY’)
drawing.add(points)
print ‘Reading Record: ‘+ str(x)
x=x+1

else:
print ‘Complete…’

readShapefile()
drawing.save()

The loop is lame and only grabs the first 100 points. I just wanted to quickly show how to do it. Modify this anyway you want – you will need to add your file names anyway.

This file can also be modified to read and write polyline shapefiles too.

You will need to install Python, shapefile.py and DXFwrite.py for this to work. I have tested the DXF files in Qgis, but not in AutoCAD or Revit.