├── DensityProfiler_pure.py ├── PiP_Edge.py ├── PureShp2Img.py ├── README.md ├── changeShapeType.py ├── editshp.py ├── logo.png ├── pointinpoly.py ├── pyshpLargeWriter.py ├── shp2img.py ├── subset.py └── zipshape.py /DensityProfiler_pure.py: -------------------------------------------------------------------------------- 1 | import random 2 | import shapefile 3 | import pngcanvas 4 | 5 | def pip(x,y,poly): 6 | n = len(poly) 7 | inside = False 8 | p1x,p1y = poly[0] 9 | for i in range(n+1): 10 | p2x,p2y = poly[i % n] 11 | if y > min(p1y,p2y): 12 | if y <= max(p1y,p2y): 13 | if x <= max(p1x,p2x): 14 | if p1y != p2y: 15 | xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x 16 | if p1x == p2x or x <= xinters: 17 | inside = not inside 18 | p1x,p1y = p2x,p2y 19 | return inside 20 | 21 | # Source shapefile 22 | r = shapefile.Reader("GIS_CensusTract_poly.shp") 23 | 24 | # pixel to coordinate info 25 | xdist = r.bbox[2] - r.bbox[0] 26 | ydist = r.bbox[3] - r.bbox[1] 27 | iwidth = 600 28 | iheight = 500 29 | xratio = iwidth/xdist 30 | yratio = iheight/ydist 31 | 32 | c = pngcanvas.PNGCanvas(iwidth,iheight,color=[255,255,255,0xff]) 33 | 34 | # background color 35 | c.filledRectangle(0,0,iwidth,iheight) 36 | 37 | # Pen color 38 | c.color = [139,137,137,0xff] 39 | 40 | # Draw the polygons 41 | for shape in r.shapes(): 42 | pixels = [] 43 | for x,y in shape.points: 44 | px = int(iwidth - ((r.bbox[2] - x) * xratio)) 45 | py = int((r.bbox[3] - y) * yratio) 46 | pixels.append([px,py]) 47 | c.polyline(pixels) 48 | 49 | rnum = 0 50 | trnum = len(r.shapeRecords()) 51 | for sr in r.shapeRecords(): 52 | rnum += 1 53 | #print rnum, " of ", trnum 54 | density = sr.record[20] 55 | total = int(density / 50) 56 | count = 0 57 | minx, miny, maxx, maxy = sr.shape.bbox 58 | while count < total: 59 | x = random.uniform(minx,maxx) 60 | y = random.uniform(miny,maxy) 61 | if pip(x,y,sr.shape.points): 62 | count += 1 63 | #print " ", count, " of ", total 64 | px = int(iwidth - ((r.bbox[2] - x) * xratio)) 65 | py = int((r.bbox[3] - y) * yratio) 66 | c.point(px,py,color=[255,0,0,0xff]) 67 | 68 | f = file("density_pure.png", "wb") 69 | f.write(c.dump()) 70 | f.close() 71 | -------------------------------------------------------------------------------- /PiP_Edge.py: -------------------------------------------------------------------------------- 1 | # Improved point in polygon test which includes edge 2 | # and vertex points 3 | 4 | def point_in_poly(x,y,poly): 5 | 6 | # check if point is a vertex 7 | if (x,y) in poly: return "IN" 8 | 9 | # check if point is on a boundary 10 | for i in range(len(poly)): 11 | p1 = None 12 | p2 = None 13 | if i==0: 14 | p1 = poly[0] 15 | p2 = poly[1] 16 | else: 17 | p1 = poly[i-1] 18 | p2 = poly[i] 19 | if p1[1] == p2[1] and p1[1] == y and x > min(p1[0], p2[0]) and x < max(p1[0], p2[0]): 20 | return "IN" 21 | 22 | n = len(poly) 23 | inside = False 24 | 25 | p1x,p1y = poly[0] 26 | for i in range(n+1): 27 | p2x,p2y = poly[i % n] 28 | if y > min(p1y,p2y): 29 | if y <= max(p1y,p2y): 30 | if x <= max(p1x,p2x): 31 | if p1y != p2y: 32 | xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x 33 | if p1x == p2x or x <= xints: 34 | inside = not inside 35 | p1x,p1y = p2x,p2y 36 | 37 | if inside: return "IN" 38 | else: return "OUT" 39 | 40 | # Test a vertex for inclusion 41 | poligono = [(-33.416032,-70.593016), (-33.415370,-70.589604), 42 | (-33.417340,-70.589046), (-33.417949,-70.592351), 43 | (-33.416032,-70.593016)] 44 | lat= -33.416032 45 | lon= -70.593016 46 | 47 | print point_in_poly(lat, lon, poligono) 48 | 49 | # test a boundary point for inclusion 50 | poly2 = [(1,1), (5,1), (5,5), (1,5), (1,1)] 51 | x = 3 52 | y = 1 53 | print point_in_poly(x, y, poly2) 54 | -------------------------------------------------------------------------------- /PureShp2Img.py: -------------------------------------------------------------------------------- 1 | """ 2 | PureShp2Img - Convert a shapefile polygon to a PNG image using pure python 3 | 4 | Requires Rui Carmo's PNGCanvas module from http://the.taoofmac.com 5 | """ 6 | 7 | import shapefile 8 | import pngcanvas 9 | 10 | # Read in a shapefile and write png image 11 | r = shapefile.Reader("mississippi") 12 | xdist = r.bbox[2] - r.bbox[0] 13 | ydist = r.bbox[3] - r.bbox[1] 14 | iwidth = 400 15 | iheight = 600 16 | xratio = iwidth/xdist 17 | yratio = iheight/ydist 18 | pixels = [] 19 | # 20 | # Only using the first shape record 21 | for x,y in r.shapes()[0].points: 22 | px = int(iwidth - ((r.bbox[2] - x) * xratio)) 23 | py = int((r.bbox[3] - y) * yratio) 24 | pixels.append([px,py]) 25 | c = pngcanvas.PNGCanvas(iwidth,iheight) 26 | c.polyline(pixels) 27 | f = file("mississippi.png","wb") 28 | f.write(c.dump()) 29 | f.close() 30 | # 31 | # Create a world file 32 | wld = file("mississippi.pgw", "w") 33 | wld.write("%s\n" % (xdist/iwidth)) 34 | wld.write("0.0\n") 35 | wld.write("0.0\n") 36 | wld.write("-%s\n" % (ydist/iheight)) 37 | wld.write("%s\n" % r.bbox[0]) 38 | wld.write("%s\n" % r.bbox[3]) 39 | wld.close -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # geospatialpython 2 | Code examples from GeospatialPython.com 3 | 4 | Sample projects and libraries from [GeospatialPython.com](http://www.GeospatialPython.com) 5 | 6 | Sample data and some scripts used in the examples on [GeospatialPython.com](http://www.GeospatialPython.com) can be found in the [Downloads](http://code.google.com/p/geospatialpython/downloads/list) section. Most sample source code is located in the [Subversion Repository](http://code.google.com/p/geospatialpython/source/browse/#svn%2Ftrunk). 7 | 8 | A good bit of the examples are based on the the [Python Shapefile Library](http://code.google.com/p/pyshp/) also hosted on Google Code. 9 | 10 | There is a discussion group for everything above on [Google Groups](http://groups.google.com/group/geospatialpython). 11 | -------------------------------------------------------------------------------- /changeShapeType.py: -------------------------------------------------------------------------------- 1 | """ 2 | Convert one shapefile type to another 3 | """ 4 | 5 | import shapefile 6 | 7 | 8 | # Create a line and a multi-point 9 | # and single point version of 10 | # a polygon shapefile 11 | 12 | 13 | ## POLYLINE version 14 | # The shapefile type we are converting to 15 | newType = shapefile.POLYLINE 16 | 17 | r = shapefile.Reader("Mississippi") 18 | w = shapefile.Writer(newType) 19 | w._shapes.extend(r.shapes()) 20 | # You must explicity set the shapeType of each record. 21 | # Eventually the library will set them to the same 22 | # as the file shape type automatically. 23 | for s in w.shapes(): 24 | s.shapeType = newType 25 | w.fields = list(r.fields) 26 | w.records.extend(r.records()) 27 | w.save("Miss_Line") 28 | 29 | ## MULTIPOINT version 30 | newType = shapefile.MULTIPOINT 31 | 32 | w = shapefile.Writer(newType) 33 | w._shapes.extend(r.shapes()) 34 | for s in w.shapes(): 35 | s.shapeType = newType 36 | w.fields = list(r.fields) 37 | w.records.extend(r.records()) 38 | w.save("Miss_MPoint") 39 | 40 | ## POINT version 41 | newType = shapefile.POINT 42 | 43 | w = shapefile.Writer(newType) 44 | # For a single point shapefile 45 | # from another type we 46 | # "flatten" each shape 47 | # so each point is a new record. 48 | # This means we must also assign 49 | # each point a record which means 50 | # records are usually duplicated. 51 | for s in r.shapeRecords(): 52 | for p in s.shape.points: 53 | w.point(*p) 54 | w.records.append(s.record) 55 | w.fields = list(r.fields) 56 | w.save("Miss_Point") -------------------------------------------------------------------------------- /editshp.py: -------------------------------------------------------------------------------- 1 | import shapefile 2 | # Polygon shapefile we are updating. 3 | # We must include a file extension in 4 | # this case because the file name 5 | # has multiple dots and pyshp would get 6 | # confused otherwise. 7 | file_name = "ep202009.026_5day_pgn.shp" 8 | # Create a shapefile reader 9 | r = shapefile.Reader(file_name) 10 | # Create a shapefile writer 11 | # using the same shape type 12 | # as our reader 13 | w = shapefile.Writer(r.shapeType) 14 | # Copy over the existing dbf fields 15 | w.fields = list(r.fields) 16 | # Copy over the existing dbf records 17 | w.records.extend(r.records()) 18 | # Copy over the existing polygons 19 | w._shapes.extend(r.shapes()) 20 | # Add a new polygon 21 | w.poly(parts=[[[-104,24],[-104,25],[-103,25],[-103,24],[-104,24]]]) 22 | # Add a new dbf record for our polygon making sure we include 23 | # all of the fields in the original file (r.fields) 24 | w.record("STANLEY","TD","091022/1500","27","21","48","ep") 25 | # Overwrite the old shapefile or change the name and make a copy 26 | w.save(file_name) -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeospatialPython/geospatialpython/d01c1f86a8b1ee427bef621c29a18aa730451383/logo.png -------------------------------------------------------------------------------- /pointinpoly.py: -------------------------------------------------------------------------------- 1 | 2 | # Determine if a point is inside a given polygon or not 3 | # Polygon is a list of (x,y) pairs. This fuction 4 | # returns True or False. The algorithm is called 5 | # "Ray Casting Method". 6 | 7 | def point_in_poly(x,y,poly): 8 | 9 | n = len(poly) 10 | inside = False 11 | 12 | p1x,p1y = poly[0] 13 | for i in range(n+1): 14 | p2x,p2y = poly[i % n] 15 | if y > min(p1y,p2y): 16 | if y <= max(p1y,p2y): 17 | if x <= max(p1x,p2x): 18 | if p1y != p2y: 19 | xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x 20 | if p1x == p2x or x <= xinters: 21 | inside = not inside 22 | p1x,p1y = p2x,p2y 23 | 24 | return inside 25 | 26 | ## Test 27 | 28 | polygon = [(0,10),(10,10),(10,0),(0,0)] 29 | 30 | point_x = 5 31 | point_y = 5 32 | 33 | ## Call the fuction with the points and the polygon 34 | print point_in_poly(point_x,point_y,polygon) -------------------------------------------------------------------------------- /pyshpLargeWriter.py: -------------------------------------------------------------------------------- 1 | import cStringIO 2 | import struct 3 | import shapefile 4 | import random 5 | import time 6 | 7 | class LargeWriter: 8 | def __init__(self, filename=None, shapeType=1, hasShx=True): 9 | self.filename = filename 10 | self.hasShx = hasShx 11 | # Count records for metadata 12 | self.count = 0 13 | # Maximum number of records before disk flush 14 | self.max = 1000 15 | self.started = False 16 | self.minx = 0 17 | self.miny = 0 18 | self.maxx = 0 19 | self.maxy = 0 20 | self.numRecs = 0 21 | self.tmpShp = cStringIO.StringIO() 22 | if self.hasShx: 23 | self.tmpShx = cStringIO.StringIO() 24 | self.tmpDbf = cStringIO.StringIO() 25 | self.shp = open("%s.shp" % self.filename, "wb") 26 | if self.hasShx: 27 | self.shx = open("%s.shx" % self.filename, "wb") 28 | self.dbf = open("%s.dbf" % self.filename, "wb") 29 | self.dbfHdrLen = 0 30 | self.w = shapefile.Writer(shapeType) 31 | 32 | def endcap(self): 33 | """First and last batches""" 34 | self.started = True 35 | self.tmpShp.seek(36) 36 | self.xmin = struct.unpack("i", self.tmpShx.read(4))[0] 63 | newOffset = adder + offset 64 | self.tmpShx.seek(-4, 1) 65 | self.tmpShx.write(struct.pack(">i", newOffset)) 66 | self.tmpShx.seek(8, 1) 67 | shxcur = self.tmpShx.tell() 68 | # Get shp bounding box 69 | self.tmpShp.seek(36) 70 | xmin = struct.unpack("= self.max: 92 | if self.hasShx: 93 | self.w.save(shp=self.tmpShp, shx=self.tmpShx, dbf=self.tmpDbf) 94 | else: 95 | self.w.save(shp=self.tmpShp, dbf=self.tmpDbf) 96 | if not self.started: 97 | self.endcap() 98 | else: 99 | self.batch() 100 | # Reset the buffers for the next batch 101 | self.tmpShp = cStringIO.StringIO() 102 | if self.hasShx: 103 | self.tmpShx = cStringIO.StringIO() 104 | self.tmpDbf = cStringIO.StringIO() 105 | self.count = 0 106 | 107 | def save(self): 108 | self.shp.seek(0,2) 109 | shpLength = self.shp.tell() / 2 110 | self.shp.seek(24) 111 | self.shp.write(struct.pack(">i", shpLength)) 112 | self.shp.seek(36) 113 | self.shp.write(struct.pack("<4d", self.xmin,self.ymin,self.xmax,self.ymax)) 114 | if self.hasShx: 115 | self.shx.seek(0,2) 116 | shxLength = self.shx.tell() / 2 117 | self.shx.seek(24) 118 | self.shx.write(struct.pack(">i", shxLength)) 119 | self.shx.seek(36) 120 | self.shx.write(struct.pack("<4d", self.xmin,self.ymin,self.xmax,self.ymax)) 121 | # update dbf record count 122 | self.dbf.seek(4) 123 | self.dbf.write(struct.pack(" last: 139 | print "%s %% done - Shape %s/%s at %s" % (percent, count, total, time.asctime()) 140 | return percent 141 | 142 | 143 | # Create a large shapefile writer with 144 | # a filname and a shapefile type. 145 | # 1=Point, 5=Polygon 146 | lw = LargeWriter("giantShp", 1, hasShx=True) 147 | #lw = LargeWriter("giantShp", 1, hasShx=False) 148 | 149 | # Add some dbf fields 150 | lw.w.field("ID", "C", "40") 151 | lw.w.field("X", "C", "40") 152 | lw.w.field("Y", "C", "40") 153 | 154 | # Progress counter 155 | status = 0 156 | 157 | # Number of random points to write 158 | total = 107374177 159 | 160 | for i in range(total): 161 | # Progress meter 162 | status = progress(status, i, total) 163 | # Generate a random point 164 | x,y = random_point() 165 | x1,y1 = random_point() 166 | x2,y2 = random_point() 167 | x3,y3 = random_point() 168 | x4,y4 = random_point() 169 | # Call the shapefile point() method 170 | lw.w.point(x,y) 171 | # Call the specialized record method 172 | lw.record(i,x,y) 173 | #lw.w.poly(parts=[[[x,y],[x1,y1],[x2,y2],[x3,y3],[x4,y4]]]) 174 | #lw.record(i,x,y) 175 | #x,y = random_point() 176 | #x1,y1 = random_point() 177 | #x2,y2 = random_point() 178 | #x3,y3 = random_point() 179 | #x4,y4 = random_point() 180 | #Call the shapefile poly() method 181 | #lw.w.poly(parts=[[[x,y],[x1,y1],[x2,y2],[x3,y3],[x4,y4]]]) 182 | #Call the specialized record method 183 | #lw.record(i,x,y) 184 | 185 | # Special LargeWriter save method 186 | lw.save() -------------------------------------------------------------------------------- /shp2img.py: -------------------------------------------------------------------------------- 1 | """ 2 | shp2img.py - creates a png image and world file (.pgw) from a shapefile 3 | containing a single polygon. 4 | author: jlawhead@geospatialpyton.com 5 | date: 20101204 6 | 7 | This script requires the Python Imaging Library. 8 | The sample shapefile used is available at: 9 | http://geospatialpython.googlecode.com/files/Mississippi.zip 10 | """ 11 | 12 | import shapefile 13 | import Image, ImageDraw 14 | 15 | # Read in a shapefile 16 | r = shapefile.Reader("mississippi") 17 | xdist = r.bbox[2] - r.bbox[0] 18 | ydist = r.bbox[3] - r.bbox[1] 19 | iwidth = 400 20 | iheight = 600 21 | xratio = iwidth/xdist 22 | yratio = iheight/ydist 23 | pixels = [] 24 | for x,y in r.shapes()[0].points: 25 | px = int(iwidth - ((r.bbox[2] - x) * xratio)) 26 | py = int((r.bbox[3] - y) * yratio) 27 | pixels.append((px,py)) 28 | img = Image.new("RGB", (iwidth, iheight), "white") 29 | draw = ImageDraw.Draw(img) 30 | draw.polygon(pixels, outline="rgb(203, 196, 190)", fill="rgb(198, 204, 189)") 31 | img.save("mississippi.png") 32 | 33 | # Create a world file 34 | wld = file("mississippi.pgw", "w") 35 | wld.write("%s\n" % (xdist/iwidth)) 36 | wld.write("0.0\n") 37 | wld.write("0.0\n") 38 | wld.write("-%s\n" % (ydist/iheight)) 39 | wld.write("%s\n" % r.bbox[0]) 40 | wld.write("%s\n" % r.bbox[3]) 41 | wld.close -------------------------------------------------------------------------------- /subset.py: -------------------------------------------------------------------------------- 1 | import shapefile 2 | 3 | # Create a reader instance 4 | r = shapefile.Reader("buildingfootprints/Building_Footprint") 5 | # Create a writer instance 6 | w = shapefile.Writer(shapeType=shapefile.POLYGON) 7 | # Copy the fields to the writer 8 | w.fields = list(r.fields) 9 | # Grab the geometry and records from all features 10 | # with the correct county name 11 | selection = [] 12 | for rec in enumerate(r.records()): 13 | if rec[1][1].startswith("Hancock"): 14 | selection.append(rec) 15 | # Add the geometry and records to the writer 16 | for rec in selection: 17 | w._shapes.append(r.shape(rec[0])) 18 | w.records.append(rec[1]) 19 | # Save the new shapefile 20 | w.save("buildingfootprints/HancockFootprints") 21 | -------------------------------------------------------------------------------- /zipshape.py: -------------------------------------------------------------------------------- 1 | """ 2 | Example of saving a shapefile to a file-like 3 | object using a zip file as the target. Uses 4 | the individual save methods for each type 5 | of file instead of the general pyshp 6 | save method. 7 | """ 8 | 9 | import zipfile 10 | import StringIO 11 | import shapefile 12 | 13 | # Set up buffers for saving 14 | shp = StringIO.StringIO() 15 | shx = StringIO.StringIO() 16 | dbf = StringIO.StringIO() 17 | 18 | # Make a point shapefile 19 | w = shapefile.Writer(shapefile.POINT) 20 | w.point(90.3, 30) 21 | w.point(92, 40) 22 | w.point(-122.4, 30) 23 | w.point(-90, 35.1) 24 | w.field('FIRST_FLD') 25 | w.field('SECOND_FLD','C','40') 26 | w.record('First','Point') 27 | w.record('Second','Point') 28 | w.record('Third','Point') 29 | w.record('Fourth','Point') 30 | 31 | # Save shapefile components to buffers 32 | w.saveShp(shp) 33 | w.saveShx(shx) 34 | w.saveDbf(dbf) 35 | 36 | # Save shapefile buffers to zip file 37 | # Note: zlib must be available for 38 | # ZIP_DEFLATED to compress. Otherwise 39 | # just use ZIP_STORED. 40 | z = zipfile.ZipFile("myshape.zip", "w", zipfile.ZIP_DEFLATED) 41 | z.writestr("myshape.shp", shp.getvalue()) 42 | z.writestr("myshape.shx", shx.getvalue()) 43 | z.writestr("myshape.dbf", dbf.getvalue()) 44 | z.close() 45 | 46 | --------------------------------------------------------------------------------