Exploring Property Data for Fun and (No) Profit!
Who Am I?
Agenda
Lots of Data is Straightforward to Access
Cambridge Property Database
Property Listing: Making your way to the map
Exploring GIS Data
Deed Registry
Deeds: Basic Search
Looking up a Property by Address
Deeds: A Link to the Past
Page/Book: Further in the past
Open Data Portal
Geographic Information Systems
Downloading Data from Cambridge
qgis
Using processing tools on data
Imagery Data
More Advanced Analysis Tools
The remainder will focus on a combination of command line tools and using the output in qgis.
sqlite: lightweight database
Loading Property Data into sqlite
$ wget -O ‘assess2020.csv' 'https://data.cambridgema.gov/api/views/aezj-8mpy/rows.csv?accessType=DOWNLOAD'
$ sqlite3 cambridge.db
.mode csv
.separator ','
.import assess2020.csv Properties
alter table Properties add column year_sold integer;
select pid, interior_bedrooms from properties where PropertyClass='SNGL-FAM-RES' and cast(condition_yearbuilt as integer)>'2015';
select pid, landarea, condition_yearbuilt from Properties where Interior_Bedrooms='9' and PropertyClass='SNGL-FAM-RES';
Creating per-parcel data
create table lots AS select min(PID) as pid,
GISID as gisid,
count(PID) as props_in_lot,
count(distinct BldgNum) as buildings,
sum(Interior_NumUnits) as units,
sum(LandArea) as lot_size,
sum(Interior_LivingArea) as living_size,
sum(Interior_Bedrooms) as bedrooms,
address as address,
min(PropertyClass) as type,
min(Owner_Name) as owner,
cast(sum(AssessedValue) as integer) as assessed_value,
cast(sum(PropertyTaxAmount) as float) as tax,
cast(CASE WHEN Condition_YearBuilt != '0' THEN min(cast(Condition_YearBuilt as integer)) ELSE -1 END as integer) as year_built,
max(cast(substr(SALEDATE, -4) as integer)) as sale_year,
cast(sum(CASE WHEN PropertyClass != 'CONDO-BLDG' THEN SalePrice ELSE 0 END) as integer) as sale_price,
max(Exterior_NumStories) as num_stories,
max(Exterior_WallHeight) as story_height,
sum(Parking_Open)+sum(Parking_Covered)+sum(Parking_Garage) as parking_spaces,
max(Zoning) as zone
from properties
group by GISID;
OGR: tool for processing vector data
$ wget -O 'parcels.geojson' 'https://github.com/cambridgegis/cambridgegis_data/raw/master/Assessing/FY2021/FY2021_Parcels/ASSESSING_ParcelsFY2021.geojson'
$ ogr2ogr -append -f sqlite \� -nln parcels \� cambridge.db parcels.geojson
Join Assessor data + Parcel Data; Export to GeoJSON
$ sqlite3 cambridge.db
create table meta_parcels as select * from lots LEFT JOIN parcels on lots.gisid = parcels.ml;
-- This line just tells ogr how to read the data
INSERT INTO geometry_columns VALUES ('meta_parcels', 'GEOMETRY', 0, 2, 4326, 'WKB');
$ ogr2ogr -f geojson meta_parcels.geojson cambridge.db meta_parcels
Load Parcel Data into qgis
Software installation