├── Data ├── sf_blocks.cpg ├── sf_blocks.dbf ├── sf_blocks.sbn ├── sf_blocks.sbx ├── sf_blocks.shp ├── sf_blocks.shx ├── SFFind_Neighborhoods.dbf ├── SFFind_Neighborhoods.sbn ├── SFFind_Neighborhoods.sbx ├── SFFind_Neighborhoods.shp ├── SFFind_Neighborhoods.shx ├── SFFind_Neighborhoods.prj ├── sf_blocks.prj └── sf_blocks.shp.xml ├── Build_Query_Spatial_Database_files └── Thumbs.db ├── README.md ├── Build_Query_Spatial_Database.ipynb └── .ipynb_checkpoints └── Build_Query_Spatial_Database-checkpoint.ipynb /Data/sf_blocks.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /Data/sf_blocks.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/sf_blocks.dbf -------------------------------------------------------------------------------- /Data/sf_blocks.sbn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/sf_blocks.sbn -------------------------------------------------------------------------------- /Data/sf_blocks.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/sf_blocks.sbx -------------------------------------------------------------------------------- /Data/sf_blocks.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/sf_blocks.shp -------------------------------------------------------------------------------- /Data/sf_blocks.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/sf_blocks.shx -------------------------------------------------------------------------------- /Data/SFFind_Neighborhoods.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/SFFind_Neighborhoods.dbf -------------------------------------------------------------------------------- /Data/SFFind_Neighborhoods.sbn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/SFFind_Neighborhoods.sbn -------------------------------------------------------------------------------- /Data/SFFind_Neighborhoods.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/SFFind_Neighborhoods.sbx -------------------------------------------------------------------------------- /Data/SFFind_Neighborhoods.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/SFFind_Neighborhoods.shp -------------------------------------------------------------------------------- /Data/SFFind_Neighborhoods.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Data/SFFind_Neighborhoods.shx -------------------------------------------------------------------------------- /Build_Query_Spatial_Database_files/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agaidus/PostgreSQL_PostGIS_Databases_Python/HEAD/Build_Query_Spatial_Database_files/Thumbs.db -------------------------------------------------------------------------------- /Data/SFFind_Neighborhoods.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] -------------------------------------------------------------------------------- /Data/sf_blocks.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | In the notebook Build_Query_Spatial_Database.ipynb, I demonstrate a workflow for building, querying, and extracting data from spatial databases using the psycopg2 module in Python. -------------------------------------------------------------------------------- /Data/sf_blocks.shp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | U.S. Department of Commerce, U.S. Census Bureau, Geography Division 7 | 2010 8 | TIGER/Line Shapefile, 2010, 2010 state, California, 2010 Census Block State-based 9 | 2010 10 | vector digital data 11 | http://www.census.gov/geo/www/tiger 12 | 13 | 14 | 15 | The TIGER/Line Files are shapefiles and related database files (.dbf) that are an extract of selected geographic and cartographic information from the U.S. Census Bureau's Master Address File / Topologically Integrated Geographic Encoding and Referencing (MAF/TIGER) Database (MTDB). The purpose of this file is to provide the geography for the 2010 Census Blocks along with their 2010 housing unit count and population. Census Blocks are statistical areas bounded on all sides by visible features, such as streets, roads, streams, and railroad tracks, and/or by nonvisible boundaries such as city, town, township, and county limits, and short line-of-sight extensions of streets and roads. Blocks are the smallest geographic areas for which the Census Bureau publishes data from the decennial census. A block may consist of one or more faces. 16 | 17 | In order for others to use the information in the Census MAF/TIGER database in a geographic information system (GIS) or for other geographic applications, the Census Bureau releases to the public extracts of the database in the form of TIGER/Line Shapefiles. 18 | California(06) 19 | 20 | 21 | 22 | 23 | 201001 24 | 201007 25 | 26 | 27 | Publication Date 28 | 29 | 30 | Complete 31 | TIGER/Line Shapefiles are extracted from the Census MAF/TIGER database. No changes or updates will be made to this version of the TIGER/Line Shapefiles. Future releases of TIGER/Line Shapefiles will reflect updates made to the Census MAF/TIGER database. 32 | 33 | 34 | 35 | -124.482003 36 | -114.131211 37 | 42.009517 38 | 32.528832 39 | 40 | 41 | 42 | 43 | ISO 19115 Topic Categories 44 | boundaries 45 | 46 | 47 | None 48 | State or equivalent entity 49 | Polygon 50 | Block 51 | Census Block 52 | 53 | 54 | INCITS.38-200x (R2004),INCITS.31-200x (R2007),INCITS.454-200x,INCITS 455-200x,INCITS 446-2008 55 | United States 56 | U.S. 57 | State or Equivalent Entity 58 | California 59 | CA 60 | 06 61 | 62 | 63 | None 64 | The TIGER/Line Shapefile products are not copyrighted however TIGER/Line and Census TIGER are registered trademarks of the U.S. Census Bureau. These products are free to use in a product or publication, however acknowledgement must be given to the U.S. Census Bureau as the source. 65 | The boundary information in the TIGER/Line Shapefiles are for statistical data collection and tabulation purposes only; their depiction and designation for statistical purposes does not constitute a determination of jurisdictional authority or rights of ownership or entitlement and they are not legal land descriptions.Coordinates in the TIGER/Line shapefiles have six implied decimal places, but the positional accuracy of these coordinates is not as great as the six decimal places suggest. 66 | Yes, the data are free from Title 13 restrictions 67 | 68 | 69 | 70 | U.S. Department of Commerce, U.S. Census Bureau, Geography Division, Geographic Products Branch 71 | 72 | 73 | Mailing address 74 |
4600 Silver Hill Road, Stop 7400
75 | Washington 76 | DC 77 | 20233-7400 78 | United States 79 |
80 | 301-763-1128 81 | 301-763-4710 82 | geo.tiger@census.gov 83 |
84 |
85 |
86 | 8859part1 87 | eng 88 | 89 | 90 | Accurate against Federal Information Processing Standards (FIPS), FIPS Publication 6-4, and FIPS-55 at the 100% level for the codes and base names. The remaining attribute information has been examined but has not been fully tested for accuracy. 91 | 92 | The Census Bureau performed automated tests to ensure logical consistency and limits of shapefiles. Segments making up the outer and inner boundaries of a polygon tie end-to-end to completely enclose the area. All polygons are tested for closure. 93 | The Census Bureau uses its internally developed geographic update system to enhance and modify spatial and attribute data in the Census MAF/TIGER database. Standard geographic codes, such as FIPS codes for states, counties, municipalities, county subdivisions, places, American Indian/Alaska Native/Native Hawaiian areas, and congressional districts are used when encoding spatial entities. The Census Bureau performed spatial data tests for logical consistency of the codes during the compilation of the original Census MAF/TIGER database files. Most of the codes for geographic entities except states, counties, urban areas, Core Based Statistical Areas (CBSAs), American Indian Areas (AIAs), and congressional districts were provided to the Census Bureau by the USGS, the agency responsible for maintaining FIPS 55. Feature attribute information has been examined but has not been fully tested for consistency. 94 | For the TIGER/Line Shapefiles, the Point and Vector Object Count for the G-polygon SDTS Point and Vector Object Type reflects the number of records in the shapefile attribute table. For multi-polygon features, only one attribute record exists for each multi-polygon rather than one attribute record per individual G-polygon component of the multi-polygon feature. TIGER/Line Shapefile multi-polygons are an exception to the G-polygon object type classification. Therefore, when multi-polygons exist in a shapefile, the object count will be less than the actual number of G-polygons. 95 | Data completeness of the TIGER/Line Shapefiles reflects the contents of the Census MAF/TIGER database at the time the TIGER/Line Shapefiles were created. 96 | 97 | 98 | 99 | 100 | U.S. Department of Commerce, U.S. Census Bureau, Geography Division 101 | Unpublished material 102 | Census MAF/TIGER database 103 | 104 | 105 | online 106 | 107 | 108 | 109 | 201001 110 | 201007 111 | 112 | 113 | Publication Date 114 | 115 | MAF/TIGER 116 | The selected geographic and cartographic information (line segments) are derived from the U.S. Census Bureau's Master Address File Topologically Integrated Geographic Encoding and Referencing (MAF/TIGER) database. 117 | 118 | 119 | TIGER/Line Shapefiles are extracted from the Census MAF/TIGER database by nation, state, county, and entity. Census MAF/TIGER data for all of the aforementioned geographic entities are then distributed among the shapefiles each containing attributes for line, polygon, or landmark geographic data. 120 | Census MAF/TIGER 121 | 2010 122 | 123 | 124 | 125 | 126 | Federal Information Processing Standards (FIPS), ANSI, and feature names. 127 | Vector 128 | 129 | 130 | G-polygon 131 | 710145 132 | 133 | 134 | 135 | 136 | 137 | 138 | 0.000458 139 | 0.000458 140 | Decimal degrees 141 | 142 | 143 | North American Datum of 1983 in the 48 contiguous states, the District of Columbia, Alaska, Hawaii, Puerto Rico, the Virgin Islands of the United States, and the Pacific Island Areas. 144 | Geodetic Reference System 80 145 | 6378137 146 | 298257 147 | 148 | 149 | 150 | 151 | 152 | 153 | tabblock2010_06_pophu.shp 154 | 2010 Census Block State-based 155 | U.S. Census Bureau 156 | 157 | 158 | STATEFP10 159 | 2010 Census state Federal Information Processing Standards 160 | (FIPS) codes 161 | U.S. Census Bureau 162 | 163 | 164 | INCITS.38-200x (R2004), Codes for the Identification of 165 | the States, the District of Columbia, Puerto Rico, and the 166 | Insular Areas of the United States (Formerly FIPS 5-2) 167 | U.S. Census Bureau 168 | 169 | 170 | 171 | 172 | COUNTYFP10 173 | 2010 Census county Federal Information Processing Standards 174 | (FIPS) code 175 | U.S. Census Bureau 176 | 177 | 178 | INCITS.31-200x (R2007), Codes for the Identification of 179 | the Counties and Equivalent Areas of the United States, 180 | Puerto Rico, and the Insular Areas of the United States 181 | (Formerly FIPS 6-4) 182 | U.S. Census Bureau 183 | 184 | 185 | 186 | 187 | TRACTCE10 188 | 2010 Census census tract code 189 | U.S. Census Bureau 190 | 191 | 192 | 000000 193 | Water tract in some coastal and Great Lakes water and 194 | territorial sea 195 | U.S. Census 196 | 197 | 198 | 000100 to 998999 199 | Census tract number 200 | U.S. Census Bureau 201 | 202 | 203 | 204 | 205 | BLOCKCE 206 | 2010 Census tabulation block number 207 | U.S. Census Bureau 208 | 209 | 210 | 0001 to 9999 211 | tabulation block number 212 | U.S. Census Bureau 213 | 214 | 215 | 216 | 217 | BLOCKID10 218 | Block identifier; a concatenation of 2010 Census state Federal 219 | Information Processing Standards (FIPS) code, county FIPS code, 220 | census tract code, and tabulation block number 221 | U.S. Census Bureau 222 | 223 | 224 | INCITS.38-200x (R2004), Codes for the Identification of 225 | the States, the District of Columbia, Puerto Rico, and the 226 | Insular Areas of the United States (Formerly FIPS 5-2), 227 | INCITS.31-200x (R2007), Codes for the Identification of 228 | the Counties and Equivalent Areas of the United States, 229 | Puerto Rico, and the Insular Areas of the United States 230 | (Formerly FIPS 6-4), the census tract code that appears in 231 | TRACTCE10 and the tabulation block number that appears in 232 | BLOCKCE10 233 | U.S. Census Bureau 234 | 235 | 236 | 237 | 238 | PARTFLG 239 | 2010 Census Partial Block Flag 240 | U.S. Census Bureau 241 | 242 | 243 | N 244 | No, Block is not a partial block 245 | U.S. Census 246 | 247 | 248 | Y 249 | Yes, Block is a partial block 250 | U.S. Census Bureau 251 | 252 | 253 | 254 | 255 | HOUSING10 256 | 2010 Census number of housing units 257 | U.S. Census Bureau 258 | 259 | 260 | 0 to 9,999,999,999,999 261 | Blank 262 | U.S. Census Bureau 263 | 264 | 265 | 266 | 267 | POP10 268 | 2010 Census population 269 | U.S. Census Bureau 270 | 271 | 272 | 0 to 9,999,999,999,999 273 | Blank 274 | U.S. Census Bureau 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | U.S. Department of Commerce, U.S. Census Bureau, Geography Division, Geographic Products Branch 285 | 286 | 287 | Mailing address 288 |
4600 Silver Hill Road, Stop 7400
289 | Washington 290 | DC 291 | 20233-7400 292 | United States 293 |
294 | 301-763-1128 295 | 301-763-4710 296 | geo.tiger@census.gov 297 |
298 |
299 | No warranty, expressed or implied is made with regard to the accuracy of these data, and no liability is assumed by the U.S. Government in general or the U.S. Census Bureau in specific as to the spatial or attribute accuracy of the data. The act of distribution shall not constitute any such warranty and no responsibility is assumed by the U.S. government in the use of these files. The boundary information in the TIGER/Line Shapefiles is for statistical data collection and tabulation purposes only; their depiction and designation for statistical purposes do not constitute a determination of jurisdictional authority or rights of ownership or entitlement and they are not legal land descriptions. 300 | 301 | 302 | 303 | TGRSHP (compressed) 304 | PK-ZIP, version 1.93 A or higher 305 | 306 | 307 | 308 | 309 | 310 | http://www.census.gov/geo/www/tiger 311 | 312 | 313 | 314 | 315 | DVD-ROM (Only if offered offline) 316 | ISO 9660 317 | 318 | 319 | 320 | The online copy of the TIGER/Line files may be accessed without charge. 321 | To obtain more information about ordering TIGER/Line shapefiles visit http://www.census.gov/geo/www/tiger 322 | 323 | The TIGER/Line shapefiles contain geographic data only and do not include display mapping software or statistical data. For information on how to use the TIGER/Line shapefile data with specific software package users shall contact the company that produced the software. 324 |
325 | 326 | 20100507 327 | 328 | 329 | 330 | U.S. Department of Commerce, U.S. Census Bureau, Geography Division, Geographic Products Branch 331 | 332 | 333 | Mailing address 334 |
4600 Silver Hill Road, Stop 7400
335 | Washington 336 | DC 337 | 20233-7400 338 | United States 339 |
340 | 301-763-1128 341 | 301-763-4710 342 | geo.tiger@census.gov 343 |
344 |
345 | FGDC Content Standards for Digital Geospatial Metadata 346 | FGDC-STD-001-1998 347 | 8859part1 348 | tabblock2010_06_pophu.shp.xml 349 | eng 350 |
351 | 20160414164522001.0TRUE
352 | -------------------------------------------------------------------------------- /Build_Query_Spatial_Database.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Querying PostgreSQL / PostGIS Databases in Python\n", 8 | "\n", 9 | "### Introduction and Spatial Database Background\n", 10 | "\n", 11 | "In the following notebook, I show how to build a PostgreSQL relational database with the PostGIS extension that supports spatial databases. I'll use the ```psycopg2``` Python module to access the database and import data, manipulate data, make a query, and then extract the data. I do a lot of data wrangling, analysis, and visualization using Python and find it really nice and efficient to be able to access and query SQL databases within the same environment!\n", 12 | "\n", 13 | "In this example I will perform simple spatial query. This methodology is much more efficient with large datasets than using ```Shapely``` or ```Geopandas``` to make spatial queries because the entire dataset does not have to be loaded into memory and the entire dataset does not need to be searched when a spatial query is made. Spatial databases uses spatial indices to optimize spatial queries. A spatial index is efficient because rather than indexing the geometry directly, it calculates the minimum bounding rectangle for each geometry, and indexes that bounding box. When a query is made, the database first identifies the potentially matching records using the bounding rectangles stored in the spatial index and then loads each potential geometry into memory to check it.\n", 14 | "\n", 15 | "In this example I populate a database with the contents from a shapefile of census blocks in San Francisco and then query those blocks that have non-zero population values and their centroid within the Inner Richmond neighborhood in San Francisco. I then extract the results of this query into a GeoPandas dataframe.\n", 16 | "\n", 17 | "### Installing PostgreSQL with PostGIS Extension\n", 18 | "The first step is to get PostgreSQL and the PostGIS extension installed. Windows versions of PostgreSQL can be downloaded here: http://www.enterprisedb.com/products-services-training/pgdownload#windows\n", 19 | "\n", 20 | "When following the installation steps, there will be an option to install PostGIS. Make sure to check this box.\n", 21 | "\n", 22 | "Once you have PostGIS and PostgreSQL installed, you need to make sure that the Windows path variable includes the \"bin\" folder of the Postgres installation, if you want to be able to execute Postgres functions from the command line. For my installation, that is located here: ```C:\\Program Files (x86)\\PostgreSQL\\9.5\\bin```\n", 23 | "\n", 24 | "This can also be done temporarily from within the command line with: \n", 25 | "```\n", 26 | "set PATH=%PATH%;C:\\Program Files (x86)\\PostgreSQL\\9.5\\bin\n", 27 | "```\n", 28 | "\n", 29 | "### Creating Spatial Database from Command Line\n", 30 | "\n", 31 | "The next steps are to create the new database with the PostGIS extension. From the command line, I run the following two commands to create my database called \"ca_blocks:\n", 32 | "```\n", 33 | "createdb -U postgres ca_blocks\n", 34 | "psql -U postgres -d ca_blocks -c \"CREATE EXTENSION postgis;\"\n", 35 | "```\n", 36 | "\n", 37 | "I then install ```psycopg2``` using the pip Python package manager and am all ready to go! \n", 38 | "\n", 39 | "\n", 40 | "```pip install psycopg2```\n", 41 | "\n", 42 | "## Connecting to the Database from Python using ```psycopg2```\n", 43 | "I first need to install necessary modules: ```psycopg2``` for connecting to the database, ```osgeo``` for reading in shapefiles, ```shapely``` to convert between different geography formats, and ```geopandas``` to store my final set of ```shapely``` geometries. \n", 44 | "\n", 45 | "I downloaded the Census Block File with population values from [Census TIGER/Line](https://www.census.gov/geo/maps-data/data/tiger-data.html) and a shapefile of San Francisco neighborhoods from the city's [data portal](https://data.sfgov.org/)." 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "metadata": { 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "import psycopg2\n", 57 | "import osgeo.ogr\n", 58 | "import shapely\n", 59 | "import shapely.wkt\n", 60 | "import geopandas as gpd\n", 61 | "%matplotlib inline" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "Now that I have everything installed and my database is created, the first step is to connect to the database and set up a cursor object which is used to issue commands." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 2, 74 | "metadata": { 75 | "collapsed": false 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "connection = psycopg2.connect(database=\"ca_blocks\",user=\"postgres\", password=\"mypw\")\n", 80 | "cursor = connection.cursor()\n" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "### Creating an Empty Table in the Database\n", 88 | "Next I create a table within my database called \"blocks\" with 4 fields, each of a different type. However, before I do that, I'm going to delete the table if it already exists, just so I can run the code multiple times without causing any errors. The 4 fields I create are an ID field which is automatically allocated by the database; a field \"fips\" that holds the block FIPS code; a field \"pop\" that holds the population value of that block; and a field \"outline\" which holds the geography. Note that I am using the \"GEOGRAPHY\" field type, which is just a variant of the \"GEOMETRY\" field type. \"GEOGRAPHY\" fields hold unprojected lat/long coordinates as my shapefile contains. This could be projected and converted to a \"GEOMETRY\" field, but for this example I choose to stay with the \"GEOGRAPHY\" type." 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 3, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [], 98 | "source": [ 99 | "cursor.execute(\"DROP TABLE IF EXISTS blocks\")\n", 100 | "cursor.execute(\"CREATE TABLE blocks (id SERIAL PRIMARY KEY, fips VARCHAR NOT NULL, pop BIGINT NOT NULL, outline GEOGRAPHY)\")" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Next I create a spatial index for the outline field, which is necessary to make efficient spatial queries. Then I commit the changes to my database." 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 4, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "cursor.execute(\"CREATE INDEX block_index ON blocks USING GIST(outline)\")\n", 119 | "connection.commit()" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "### Populating the Database with Spatial Data\n", 127 | "\n", 128 | "Now I use the GDAL/OGR library to read in the shapefile of San Francisco census blocks and add the contents of this shapefile to my newly created database. I loop through each feature in the shapefile and extract the FIPS code, population value, and geometry. Note, that I use the well-known text (WKT) format to transfer geometries from one format to another. The WKT format is just a string representation of a geometry that can easily be converted. In this example it serves as the bridge between the OGR geometry format and the PostGIS format. \n", 129 | "\n", 130 | "I use ```cursor.execute()``` to run a SQL command that converts the Python values to SQL string literals. There is an additional conversion for the geometry value where the ```ST_GeoFromText``` function is used to convert the WKT format to a PostGIS geography." 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 5, 136 | "metadata": { 137 | "collapsed": false 138 | }, 139 | "outputs": [], 140 | "source": [ 141 | "shapefile = osgeo.ogr.Open(\"Data/sf_blocks.shp\")\n", 142 | "layer = shapefile.GetLayer(0)\n", 143 | "\n", 144 | "#First delete the existing contents of this table in case we want to run the code multiple times.\n", 145 | "cursor.execute(\"DELETE FROM blocks\")\n", 146 | "\n", 147 | "for i in range(layer.GetFeatureCount()):\n", 148 | " feature = layer.GetFeature(i)\n", 149 | " fips = feature.GetField(\"BLOCKID10\")\n", 150 | " pop = feature.GetField(\"POP10\")\n", 151 | " #Get feature geometry\n", 152 | " geometry = feature.GetGeometryRef()\n", 153 | " #Convert geometry to WKT format\n", 154 | " wkt = geometry.ExportToWkt()\n", 155 | " #Insert data into database, converting WKT geometry to a PostGIS geography\n", 156 | " cursor.execute(\"INSERT INTO blocks (fips, pop, outline) VALUES ({}, {}, ST_GeogFromText('{}'))\".format(fips, pop, wkt))\n", 157 | "connection.commit() \n" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "### Manipulating the Database and Calculating New Columns\n", 165 | "\n", 166 | "Next, I'm going to manipulate the spatial database and add a new geography that will hold the centroid value of each census block. This will be done so we can later make a query based on centroid location. I nest the SQL command in a try / except statement so that we can catch the programming error that will come up if we run the script more than once and try to create a column that already exists." 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 6, 172 | "metadata": { 173 | "collapsed": true 174 | }, 175 | "outputs": [], 176 | "source": [ 177 | "try:\n", 178 | " cursor.execute(\"ALTER TABLE blocks ADD COLUMN centroid GEOGRAPHY\")\n", 179 | "except psycopg2.ProgrammingError:\n", 180 | " connection.rollback" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "In the following SQL statement I update the spatial dataset and set the centroid field equal to the result from the ```ST_Centroid``` function. Notice that with the ```ST_Centroid``` function, in addition to telling it to calculate the centroid on the outline geography field, I also have to include ```::geometry```, which casts the geography type to a geometry type. This is because the ```ST_Centroid``` function works on geometry fields, not geography fields (these kind of calculations require a projected coordinate system). However, what I'm doing here is telling it to just treat my unprojected coordinate system as if it were projected. This is not a big deal in this case because we are working over such a small area, where a calculation that treats degrees as if they were projected will not make much of a difference in terms of centroid location. If I were working over a larger area, it would be better to use a geometry type from the beginning and then use ```ST_Transform``` to transform the data into a projected coordinate system that applies to California." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 7, 193 | "metadata": { 194 | "collapsed": false 195 | }, 196 | "outputs": [], 197 | "source": [ 198 | "cursor.execute(\"UPDATE blocks SET centroid=ST_Centroid(outline::geometry)\")\n", 199 | "connection.commit() " 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "### Reading in and Manipulating Other Spatial Data to Make Queries\n", 207 | "\n", 208 | "Now I will read the shapefile of SF neighborhoods. In this case, rather than reading in the data with GDAL/OGR, I will read it in with Geopandas, which will provide me with a really easy way to extract the geometry for the Inner Richmond, the neighborhood that I'm interested in for this example." 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 8, 214 | "metadata": { 215 | "collapsed": false 216 | }, 217 | "outputs": [ 218 | { 219 | "data": { 220 | "text/plain": [ 221 | "name\n", 222 | "Seacliff POLYGON ((-122.4934552679999 37.78351817100008...\n", 223 | "Lake Street POLYGON ((-122.4871507149999 37.78378542700006...\n", 224 | "Presidio National Park POLYGON ((-122.4775801709999 37.81099311300005...\n", 225 | "Presidio Terrace POLYGON ((-122.4724105299999 37.78734653900006...\n", 226 | "Inner Richmond POLYGON ((-122.4726257899999 37.78631480600006...\n", 227 | "Name: geometry, dtype: object" 228 | ] 229 | }, 230 | "execution_count": 8, 231 | "metadata": {}, 232 | "output_type": "execute_result" 233 | } 234 | ], 235 | "source": [ 236 | "sf_neighs=gpd.read_file('Data/SFFind_Neighborhoods.shp').set_index('name')['geometry']\n", 237 | "sf_neighs.head()" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "As I did earlier, I will convert the Shapely geometry object to a WKT so that it can be converted to a PostGIS geography." 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 9, 250 | "metadata": { 251 | "collapsed": false 252 | }, 253 | "outputs": [ 254 | { 255 | "name": "stdout", 256 | "output_type": "stream", 257 | "text": [ 258 | "POLYGON ((-122.4726257899999400 37.7863148060000640, -122.4668303349999400 37.7865681350000390, -122.4666944429999400 37.7847155220000560, -122.4591787659999200 37.7856816910000360, -122.4583710989999200 37.7743088950000470, -122.4651708719999300 37.7734429910000810, -122.4658831629999400 37.7733982040000460, -122.4777669469999100 37.7728636550000370, -122.4785619299999000 37.7841768850000790, -122.4725858689999400 37.7844488900000780, -122.4726257899999400 37.7863148060000640))\n" 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "inner_richmond_wkt=shapely.wkt.dumps(sf_neighs['Inner Richmond'])\n", 264 | "print inner_richmond_wkt" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "### Make a Spatial Query\n", 272 | "\n", 273 | "Next I execute an SQL command that queries the database with two criteria - one spatial and one non-spatial. I look for those records that have a centroid within the Inner Richmond neighborhood and have a population value greater than 0. Again, the Inner Richmond WKT is converted to a PostGIS geography using ```ST_GeomFromText```, and the ```ST_Intersects``` tool is used to identify those blocks who's centroid intersect this geography. I extract the FIPS code, the population and value, and the geography, which I first convert to WKT using ```ST_AsText```" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 10, 279 | "metadata": { 280 | "collapsed": false 281 | }, 282 | "outputs": [], 283 | "source": [ 284 | "cursor.execute(\"SELECT fips,pop,ST_AsText(outline) FROM blocks \"+\\\n", 285 | "\"WHERE ST_Intersects(ST_GeomFromText('{}'), centroid) \".format(inner_richmond_wkt)+\\\n", 286 | "\"AND POP>0\")" 287 | ] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "### Extract Data from Database and Convert to GeoDataFrame\n", 294 | "\n", 295 | "Now, I want to get my data out of PostGIS. I loop through the records in the cursor, and store them as a list of dictionaries. This puts them in a format that can easily be read in by Pandas/Geopandas. Note that I specify that the geometry is in the WGS84 spatial reference system because Shapely geometries do not inherently have any spatial reference." 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 11, 301 | "metadata": { 302 | "collapsed": false 303 | }, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/html": [ 308 | "
\n", 309 | "\n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | "
POPgeometry
FIPS
607504020020051POLYGON ((-122.471915 37.782596, -122.471775 3...
60750476002002176POLYGON ((-122.473833 37.778653, -122.473698 3...
60750402002003285POLYGON ((-122.469627 37.780769, -122.469757 3...
60750476002001246POLYGON ((-122.472708 37.778704, -122.472572 3...
6075040100200239POLYGON ((-122.461369 37.785403, -122.461336 3...
\n", 350 | "
" 351 | ], 352 | "text/plain": [ 353 | " POP geometry\n", 354 | "FIPS \n", 355 | "60750402002005 1 POLYGON ((-122.471915 37.782596, -122.471775 3...\n", 356 | "60750476002002 176 POLYGON ((-122.473833 37.778653, -122.473698 3...\n", 357 | "60750402002003 285 POLYGON ((-122.469627 37.780769, -122.469757 3...\n", 358 | "60750476002001 246 POLYGON ((-122.472708 37.778704, -122.472572 3...\n", 359 | "60750401002002 39 POLYGON ((-122.461369 37.785403, -122.461336 3..." 360 | ] 361 | }, 362 | "execution_count": 11, 363 | "metadata": {}, 364 | "output_type": "execute_result" 365 | } 366 | ], 367 | "source": [ 368 | "rows_list=[]\n", 369 | "for fips,pop,geo in cursor:\n", 370 | " data={'FIPS':fips,'POP':pop,'geometry':shapely.wkt.loads(geo)}\n", 371 | " rows_list.append(data)\n", 372 | "gdf=gpd.GeoDataFrame(rows_list,crs='epsg:4326').set_index('FIPS')\n", 373 | "gdf.head()" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": {}, 379 | "source": [ 380 | "I can then really easily get the number blocks and number of people in the Inner Richmond neighborhood, as well as make a quick map of my data using the built in plot feature of Geopandas. Here I symbolize the blocks based on population values divided into quantiles. Note the missing data where there was no population and were therefore not queried in the PostGIS database." 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 12, 386 | "metadata": { 387 | "collapsed": false 388 | }, 389 | "outputs": [ 390 | { 391 | "name": "stdout", 392 | "output_type": "stream", 393 | "text": [ 394 | "There are 118 census blocks in the Inner Richmond Neighborhood, representing a populaton of 24635\n" 395 | ] 396 | } 397 | ], 398 | "source": [ 399 | "print 'There are '+str(len(gdf)) +' census blocks in the Inner Richmond Neighborhood, \\\n", 400 | "representing a populaton of ' + str(gdf.POP.sum())" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": 13, 406 | "metadata": { 407 | "collapsed": false 408 | }, 409 | "outputs": [ 410 | { 411 | "data": { 412 | "text/plain": [ 413 | "" 414 | ] 415 | }, 416 | "execution_count": 13, 417 | "metadata": {}, 418 | "output_type": "execute_result" 419 | }, 420 | { 421 | "data": { 422 | "image/png": "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\n", 423 | "text/plain": [ 424 | "" 425 | ] 426 | }, 427 | "metadata": {}, 428 | "output_type": "display_data" 429 | } 430 | ], 431 | "source": [ 432 | "gdf.plot(column='POP', scheme='QUANTILES', k=5, colormap='OrRd')" 433 | ] 434 | }, 435 | { 436 | "cell_type": "markdown", 437 | "metadata": {}, 438 | "source": [ 439 | "### Conclusion\n", 440 | "\n", 441 | "This was a pretty basic example that shows how to set up and populate spatial databases to make spatial and non-spatial queries. The ```psycopg2``` modules makes it really easy to execute SQL commands from within Python, which is nice if you do all of your other work in Python like I do.\n", 442 | "\n", 443 | "One potential point of confusion is all of the different geometry types used. Even in this small script, we worked with 5 different geometry types - Shapefiles, OGR, WKT, PostGIS, and Shapely. Basically these are all used as a way to link Shapefiles (our native format in this case) to PostGIS (the format that the analysis is done in) to a Geopandas Dataframe storing Shapely geometries (our output). The well-known text type is the key way to link these together.\n", 444 | "\n", 445 | "I hope this was helpful in showing how to access spatial databases in Python!" 446 | ] 447 | } 448 | ], 449 | "metadata": { 450 | "kernelspec": { 451 | "display_name": "Python 2", 452 | "language": "python", 453 | "name": "python2" 454 | }, 455 | "language_info": { 456 | "codemirror_mode": { 457 | "name": "ipython", 458 | "version": 2 459 | }, 460 | "file_extension": ".py", 461 | "mimetype": "text/x-python", 462 | "name": "python", 463 | "nbconvert_exporter": "python", 464 | "pygments_lexer": "ipython2", 465 | "version": "2.7.8" 466 | } 467 | }, 468 | "nbformat": 4, 469 | "nbformat_minor": 0 470 | } 471 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/Build_Query_Spatial_Database-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Querying PostgreSQL / PostGIS Databases in Python\n", 8 | "\n", 9 | "### Introduction and Spatial Database Background\n", 10 | "\n", 11 | "In the following notebook, I show how to build a PostgreSQL relational database with the PostGIS extension that supports spatial databases. I'll use the ```psycopg2``` Python module to access the database and import data, manipulate data, make a query, and then extract the data. I do a lot of data wrangling, analysis, and visualization using Python and find it really nice and efficient to be able to access and query SQL databases within the same environment!\n", 12 | "\n", 13 | "In this example I will perform simple spatial query. This methodology is much more efficient with large datasets than using ```Shapely``` or ```Geopandas``` to make spatial queries because the entire dataset does not have to be loaded into memory and the entire dataset does not need to be searched when a spatial query is made. Spatial databases uses spatial indices to optimize spatial queries. A spatial index is efficient because rather than indexing the geometry directly, it calculates the minimum bounding rectangle for each geometry, and indexes that bounding box. When a query is made, the database first identifies the potentially matching records using the bounding rectangles stored in the spatial index and then loads each potential geometry into memory to check it.\n", 14 | "\n", 15 | "In this example I populate a database with the contents from a shapefile of census blocks in San Francisco and then query those blocks that have non-zero population values and their centroid within the Inner Richmond neighborhood in San Francisco. I then extract the results of this query into a GeoPandas dataframe.\n", 16 | "\n", 17 | "### Installing PostgreSQL with PostGIS Extension\n", 18 | "The first step is to get PostgreSQL and the PostGIS extension installed. Windows versions of PostgreSQL can be downloaded here: http://www.enterprisedb.com/products-services-training/pgdownload#windows\n", 19 | "\n", 20 | "When following the installation steps, there will be an option to install PostGIS. Make sure to check this box.\n", 21 | "\n", 22 | "Once you have PostGIS and PostgreSQL installed, you need to make sure that the Windows path variable includes the \"bin\" folder of the Postgres installation, if you want to be able to execute Postgres functions from the command line. For my installation, that is located here: ```C:\\Program Files (x86)\\PostgreSQL\\9.5\\bin```\n", 23 | "\n", 24 | "This can also be done temporarily from within the command line with: \n", 25 | "```\n", 26 | "set PATH=%PATH%;C:\\Program Files (x86)\\PostgreSQL\\9.5\\bin\n", 27 | "```\n", 28 | "\n", 29 | "### Creating Spatial Database from Command Line\n", 30 | "\n", 31 | "The next steps are to create the new database with the PostGIS extension. From the command line, I run the following two commands to create my database called \"ca_blocks:\n", 32 | "```\n", 33 | "createdb -U postgres ca_blocks\n", 34 | "psql -U postgres -d ca_blocks -c \"CREATE EXTENSION postgis;\"\n", 35 | "```\n", 36 | "\n", 37 | "I then install ```psycopg2``` using the pip Python package manager and am all ready to go! \n", 38 | "\n", 39 | "\n", 40 | "```pip install psycopg2```\n", 41 | "\n", 42 | "## Connecting to the Database from Python using ```psycopg2```\n", 43 | "I first need to install necessary modules: ```psycopg2``` for connecting to the database, ```osgeo``` for reading in shapefiles, ```shapely``` to convert between different geography formats, and ```geopandas``` to store my final set of ```shapely``` geometries. \n", 44 | "\n", 45 | "I downloaded the Census Block File with population values from [Census TIGER/Line](https://www.census.gov/geo/maps-data/data/tiger-data.html) and a shapefile of San Francisco neighborhoods from the city's [data portal](https://data.sfgov.org/)." 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "metadata": { 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "import psycopg2\n", 57 | "import osgeo.ogr\n", 58 | "import shapely\n", 59 | "import shapely.wkt\n", 60 | "import geopandas as gpd\n", 61 | "%matplotlib inline" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "Now that I have everything installed and my database is created, the first step is to connect to the database and set up a cursor object which is used to issue commands." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 2, 74 | "metadata": { 75 | "collapsed": false 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "connection = psycopg2.connect(database=\"ca_blocks\",user=\"postgres\", password=\"mypw\")\n", 80 | "cursor = connection.cursor()\n" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "### Creating an Empty Table in the Database\n", 88 | "Next I create a table within my database called \"blocks\" with 4 fields, each of a different type. However, before I do that, I'm going to delete the table if it already exists, just so I can run the code multiple times without causing any errors. The 4 fields I create are an ID field which is automatically allocated by the database; a field \"fips\" that holds the block FIPS code; a field \"pop\" that holds the population value of that block; and a field \"outline\" which holds the geography. Note that I am using the \"GEOGRAPHY\" field type, which is just a variant of the \"GEOMETRY\" field type. \"GEOGRAPHY\" fields hold unprojected lat/long coordinates as my shapefile contains. This could be projected and converted to a \"GEOMETRY\" field, but for this example I choose to stay with the \"GEOGRAPHY\" type." 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 3, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [], 98 | "source": [ 99 | "cursor.execute(\"DROP TABLE IF EXISTS blocks\")\n", 100 | "cursor.execute(\"CREATE TABLE blocks (id SERIAL PRIMARY KEY, fips VARCHAR NOT NULL, pop BIGINT NOT NULL, outline GEOGRAPHY)\")" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Next I create a spatial index for the outline field, which is necessary to make efficient spatial queries. Then I commit the changes to my database." 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 4, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "cursor.execute(\"CREATE INDEX block_index ON blocks USING GIST(outline)\")\n", 119 | "connection.commit()" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "### Populating the Database with Spatial Data\n", 127 | "\n", 128 | "Now I use the GDAL/OGR library to read in the shapefile of San Francisco census blocks and add the contents of this shapefile to my newly created database. I loop through each feature in the shapefile and extract the FIPS code, population value, and geometry. Note, that I use the well-known text (WKT) format to transfer geometries from one format to another. The WKT format is just a string representation of a geometry that can easily be converted. In this example it serves as the bridge between the OGR geometry format and the PostGIS format. \n", 129 | "\n", 130 | "I use ```cursor.execute()``` to run a SQL command that converts the Python values to SQL string literals. There is an additional conversion for the geometry value where the ```ST_GeoFromText``` function is used to convert the WKT format to a PostGIS geography." 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 5, 136 | "metadata": { 137 | "collapsed": false 138 | }, 139 | "outputs": [], 140 | "source": [ 141 | "shapefile = osgeo.ogr.Open(\"Data/sf_blocks.shp\")\n", 142 | "layer = shapefile.GetLayer(0)\n", 143 | "\n", 144 | "#First delete the existing contents of this table in case we want to run the code multiple times.\n", 145 | "cursor.execute(\"DELETE FROM blocks\")\n", 146 | "\n", 147 | "for i in range(layer.GetFeatureCount()):\n", 148 | " feature = layer.GetFeature(i)\n", 149 | " fips = feature.GetField(\"BLOCKID10\")\n", 150 | " pop = feature.GetField(\"POP10\")\n", 151 | " #Get feature geometry\n", 152 | " geometry = feature.GetGeometryRef()\n", 153 | " #Convert geometry to WKT format\n", 154 | " wkt = geometry.ExportToWkt()\n", 155 | " #Insert data into database, converting WKT geometry to a PostGIS geography\n", 156 | " cursor.execute(\"INSERT INTO blocks (fips, pop, outline) VALUES ({}, {}, ST_GeogFromText('{}'))\".format(fips, pop, wkt))\n", 157 | "connection.commit() \n" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "### Manipulating the Database and Calculating New Columns\n", 165 | "\n", 166 | "Next, I'm going to manipulate the spatial database and add a new geography that will hold the centroid value of each census block. This will be done so we can later make a query based on centroid location. I nest the SQL command in a try / except statement so that we can catch the programming error that will come up if we run the script more than once and try to create a column that already exists." 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 6, 172 | "metadata": { 173 | "collapsed": true 174 | }, 175 | "outputs": [], 176 | "source": [ 177 | "try:\n", 178 | " cursor.execute(\"ALTER TABLE blocks ADD COLUMN centroid GEOGRAPHY\")\n", 179 | "except psycopg2.ProgrammingError:\n", 180 | " connection.rollback" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "In the following SQL statement I update the spatial dataset and set the centroid field equal to the result from the ```ST_Centroid``` function. Notice that with the ```ST_Centroid``` function, in addition to telling it to calculate the centroid on the outline geography field, I also have to include ```::geometry```, which casts the geography type to a geometry type. This is because the ```ST_Centroid``` function works on geometry fields, not geography fields (these kind of calculations require a projected coordinate system). However, what I'm doing here is telling it to just treat my unprojected coordinate system as if it were projected. This is not a big deal in this case because we are working over such a small area, where a calculation that treats degrees as if they were projected will not make much of a difference in terms of centroid location. If I were working over a larger area, it would be better to use a geometry type from the beginning and then use ```ST_Transform``` to transform the data into a projected coordinate system that applies to California." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 7, 193 | "metadata": { 194 | "collapsed": false 195 | }, 196 | "outputs": [], 197 | "source": [ 198 | "cursor.execute(\"UPDATE blocks SET centroid=ST_Centroid(outline::geometry)\")\n", 199 | "connection.commit() " 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "### Reading in and Manipulating Other Spatial Data to Make Queries\n", 207 | "\n", 208 | "Now I will read the shapefile of SF neighborhoods. In this case, rather than reading in the data with GDAL/OGR, I will read it in with Geopandas, which will provide me with a really easy way to extract the geometry for the Inner Richmond, the neighborhood that I'm interested in for this example." 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 8, 214 | "metadata": { 215 | "collapsed": false 216 | }, 217 | "outputs": [ 218 | { 219 | "data": { 220 | "text/plain": [ 221 | "name\n", 222 | "Seacliff POLYGON ((-122.4934552679999 37.78351817100008...\n", 223 | "Lake Street POLYGON ((-122.4871507149999 37.78378542700006...\n", 224 | "Presidio National Park POLYGON ((-122.4775801709999 37.81099311300005...\n", 225 | "Presidio Terrace POLYGON ((-122.4724105299999 37.78734653900006...\n", 226 | "Inner Richmond POLYGON ((-122.4726257899999 37.78631480600006...\n", 227 | "Name: geometry, dtype: object" 228 | ] 229 | }, 230 | "execution_count": 8, 231 | "metadata": {}, 232 | "output_type": "execute_result" 233 | } 234 | ], 235 | "source": [ 236 | "sf_neighs=gpd.read_file('Data/SFFind_Neighborhoods.shp').set_index('name')['geometry']\n", 237 | "sf_neighs.head()" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "As I did earlier, I will convert the Shapely geometry object to a WKT so that it can be converted to a PostGIS geography." 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 9, 250 | "metadata": { 251 | "collapsed": false 252 | }, 253 | "outputs": [ 254 | { 255 | "name": "stdout", 256 | "output_type": "stream", 257 | "text": [ 258 | "POLYGON ((-122.4726257899999400 37.7863148060000640, -122.4668303349999400 37.7865681350000390, -122.4666944429999400 37.7847155220000560, -122.4591787659999200 37.7856816910000360, -122.4583710989999200 37.7743088950000470, -122.4651708719999300 37.7734429910000810, -122.4658831629999400 37.7733982040000460, -122.4777669469999100 37.7728636550000370, -122.4785619299999000 37.7841768850000790, -122.4725858689999400 37.7844488900000780, -122.4726257899999400 37.7863148060000640))\n" 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "inner_richmond_wkt=shapely.wkt.dumps(sf_neighs['Inner Richmond'])\n", 264 | "print inner_richmond_wkt" 265 | ] 266 | }, 267 | { 268 | "cell_type": "markdown", 269 | "metadata": {}, 270 | "source": [ 271 | "### Make a Spatial Query\n", 272 | "\n", 273 | "Next I execute an SQL command that queries the database with two criteria - one spatial and one non-spatial. I look for those records that have a centroid within the Inner Richmond neighborhood and have a population value greater than 0. Again, the Inner Richmond WKT is converted to a PostGIS geography using ```ST_GeomFromText```, and the ```ST_Intersects``` tool is used to identify those blocks who's centroid intersect this geography. I extract the FIPS code, the population and value, and the geography, which I first convert to WKT using ```ST_AsText```" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 10, 279 | "metadata": { 280 | "collapsed": false 281 | }, 282 | "outputs": [], 283 | "source": [ 284 | "cursor.execute(\"SELECT fips,pop,ST_AsText(outline) FROM blocks \"+\\\n", 285 | "\"WHERE ST_Intersects(ST_GeomFromText('{}'), centroid) \".format(inner_richmond_wkt)+\\\n", 286 | "\"AND POP>0\")" 287 | ] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "### Extract Data from Database and Convert to GeoDataFrame\n", 294 | "\n", 295 | "Now, I want to get my data out of PostGIS. I loop through the records in the cursor, and store them as a list of dictionaries. This puts them in a format that can easily be read in by Pandas/Geopandas. Note that I specify that the geometry is in the WGS84 spatial reference system because Shapely geometries do not inherently have any spatial reference." 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 11, 301 | "metadata": { 302 | "collapsed": false 303 | }, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/html": [ 308 | "
\n", 309 | "\n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | "
POPgeometry
FIPS
607504020020051POLYGON ((-122.471915 37.782596, -122.471775 3...
60750476002002176POLYGON ((-122.473833 37.778653, -122.473698 3...
60750402002003285POLYGON ((-122.469627 37.780769, -122.469757 3...
60750476002001246POLYGON ((-122.472708 37.778704, -122.472572 3...
6075040100200239POLYGON ((-122.461369 37.785403, -122.461336 3...
\n", 350 | "
" 351 | ], 352 | "text/plain": [ 353 | " POP geometry\n", 354 | "FIPS \n", 355 | "60750402002005 1 POLYGON ((-122.471915 37.782596, -122.471775 3...\n", 356 | "60750476002002 176 POLYGON ((-122.473833 37.778653, -122.473698 3...\n", 357 | "60750402002003 285 POLYGON ((-122.469627 37.780769, -122.469757 3...\n", 358 | "60750476002001 246 POLYGON ((-122.472708 37.778704, -122.472572 3...\n", 359 | "60750401002002 39 POLYGON ((-122.461369 37.785403, -122.461336 3..." 360 | ] 361 | }, 362 | "execution_count": 11, 363 | "metadata": {}, 364 | "output_type": "execute_result" 365 | } 366 | ], 367 | "source": [ 368 | "rows_list=[]\n", 369 | "for fips,pop,geo in cursor:\n", 370 | " data={'FIPS':fips,'POP':pop,'geometry':shapely.wkt.loads(geo)}\n", 371 | " rows_list.append(data)\n", 372 | "gdf=gpd.GeoDataFrame(rows_list,crs='epsg:4326').set_index('FIPS')\n", 373 | "gdf.head()" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": {}, 379 | "source": [ 380 | "I can then really easily get the number blocks and number of people in the Inner Richmond neighborhood, as well as make a quick map of my data using the built in plot feature of Geopandas. Here I symbolize the blocks based on population values divided into quantiles. Note the missing data where there was no population and were therefore not queried in the PostGIS database." 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 12, 386 | "metadata": { 387 | "collapsed": false 388 | }, 389 | "outputs": [ 390 | { 391 | "name": "stdout", 392 | "output_type": "stream", 393 | "text": [ 394 | "There are 118 census blocks in the Inner Richmond Neighborhood, representing a populaton of 24635\n" 395 | ] 396 | } 397 | ], 398 | "source": [ 399 | "print 'There are '+str(len(gdf)) +' census blocks in the Inner Richmond Neighborhood, \\\n", 400 | "representing a populaton of ' + str(gdf.POP.sum())" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": 13, 406 | "metadata": { 407 | "collapsed": false 408 | }, 409 | "outputs": [ 410 | { 411 | "data": { 412 | "text/plain": [ 413 | "" 414 | ] 415 | }, 416 | "execution_count": 13, 417 | "metadata": {}, 418 | "output_type": "execute_result" 419 | }, 420 | { 421 | "data": { 422 | "image/png": "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\n", 423 | "text/plain": [ 424 | "" 425 | ] 426 | }, 427 | "metadata": {}, 428 | "output_type": "display_data" 429 | } 430 | ], 431 | "source": [ 432 | "gdf.plot(column='POP', scheme='QUANTILES', k=5, colormap='OrRd')" 433 | ] 434 | }, 435 | { 436 | "cell_type": "markdown", 437 | "metadata": {}, 438 | "source": [ 439 | "### Conclusion\n", 440 | "\n", 441 | "This was a pretty basic example that shows how to set up and populate spatial databases to make spatial and non-spatial queries. The ```psycopg2``` modules makes it really easy to execute SQL commands from within Python, which is nice if you do all of your other work in Python like I do.\n", 442 | "\n", 443 | "One potential point of confusion is all of the different geometry types used. Even in this small script, we worked with 5 different geometry types - Shapefiles, OGR, WKT, PostGIS, and Shapely. Basically these are all used as a way to link Shapefiles (our native format in this case) to PostGIS (the format that the analysis is done in) to a Geopandas Dataframe storing Shapely geometries (our output). The well-known text type is the key way to link these together.\n", 444 | "\n", 445 | "I hope this was helpful in showing how to access spatial databases in Python!" 446 | ] 447 | } 448 | ], 449 | "metadata": { 450 | "kernelspec": { 451 | "display_name": "Python 2", 452 | "language": "python", 453 | "name": "python2" 454 | }, 455 | "language_info": { 456 | "codemirror_mode": { 457 | "name": "ipython", 458 | "version": 2 459 | }, 460 | "file_extension": ".py", 461 | "mimetype": "text/x-python", 462 | "name": "python", 463 | "nbconvert_exporter": "python", 464 | "pygments_lexer": "ipython2", 465 | "version": "2.7.8" 466 | } 467 | }, 468 | "nbformat": 4, 469 | "nbformat_minor": 0 470 | } 471 | --------------------------------------------------------------------------------