/*--------------------------------------------------------------------* | PURPOSE: Create a map of imported shapefile polygons using | a custom ODS style for the response values. | | Version: SAS 9.40M5 or later | | Data Source: Durham, NC Neighborhood Compass program | | Usage: 1) Download 'CompassSHP.zip' file from the Durham | Neighborhoods site: | compass.durhamnc.gov/#/13/neighborhoods/RVALPSM/ | 2) Extract files to your local system: | CompassDataDictionary_021815.csv | DurhamNeighborhoods_6_12_2015.dbf | DurhamNeighborhoods_6_12_2015.prj | DurhamNeighborhoods_6_12_2015.shp | DurhamNeighborhoods_6_12_2015.shp.rtree | DurhamNeighborhoods_6_12_2015.shx | 3) Set PATHIN variable to extracted file location. | 4) Set PATHOUT variable to location to write html | and image output files. | 5) Submit program to import shapefile and create map. | | Assistance: communities.sas.com *--------------------------------------------------------------------*/ /*--- Specify location of unzipped shapefile components. */ %let pathin=/folders/myfolders; /*--- Specify location to write SGMAP output files. The location must already exist. */ %let pathout=/folders/myfolders; /*--- Import the neighborhood shapefile to create a SAS map data set of polygons. The CREATE_ID_ statement will add a variable named _ID_ containing unique values for each polygon. */ proc mapimport datafile="&pathin/DurhamNeighborhoods_6_12_2015.shp" /* Shapefile */ out=neighborhoods /* Name of SAS map data set to create */ create_id_; /* Add variable _ID_ to map data set */ run; /*--- The map polygons will be colored to show response values. Create a response data set having one observation per polygon. Values will be voting participation in the 2014 general election. PTGNRL_14 is the voting percentage in each neighborhood. The _ID_ created by MAPIMPORT variable links the voting percentages to the polygons in the WORK.NEIGHBORHOODS map data set. The NODUPKEY option keeps only one observation per polygon. */ proc sort data=neighborhoods /* Map data set created by MAPIMPORT */ out=voting_rates /* Response data set to create */ (keep=_id_ /* Variable that defines polygons */ ptgnrl_14) /* Voting percentage in each polygon */ nodupkey; /* Keep only one observation per polygon */ by _id_; /* Variable with unique value per polygon */ run; /*--- Create range categories for voting percentages. Using specific ranges allows SGMAP to display them as discrete categories. There are too many voting percentages to treat them as discrete values. This will be SGMAP's map response data set. */ data voting_categories (label='General election participation'); set voting_rates; length category $16; if ptgnrl_14 < 70 then category='<70%'; else if ptgnrl_14 < 75 then category='70% - 75%'; else if ptgnrl_14 < 80 then category='75% - 80%'; else if ptgnrl_14 < 85 then category='80% - 85%'; else category='>85%'; run; /*--- Create a custom ODS style named 'custom_map' to apply specific colors to the above voting percentage ranges. First color is used for first category, second color for second category, and so on. */ proc template; define Style Styles.custom_map; parent = styles.listing; style GraphColors from graphcolors / "gdata1" = cxff0000 /* <70% - red */ "gdata2" = cxffff00 /* 75-75% - yellow */ "gdata3" = cxffffff /* 75-80% - white */ "gdata4" = cx00ffff /* 80-85% - cyan */ "gdata5" = cx006600; /* >85% - dark green */ end; run; /*--- It is not possible to use a custom style in the SAS Studio Results output area. Open a new HTML destination. */ ods html /* Open new html destination */ path="&pathout" /* Location to write output files */ (url=none) /* Use relative paths in html file */ file='Durham_voting.html' /* Name of .html file created */ style=custom_map; /* Use style created above */ ods graphics / /* Specify graphics parameters */ reset /* Cleans up any artifacts */ imagename='custom_style'; /* Name for .png file created */ /*--- Specify titles for map. */ title 'Durham Neighborhood 2014 General Election'; title2 'Style: custom_map'; /*--- Draw a map using the map data set imported from a shapefile. Use the WORK.VOTING_CATEGORIES response data set to show the voting percentage category in each polygon. */ proc sgmap mapdata=neighborhoods maprespdata=voting_categories; /*--- Draw an Open Street Map base first. */ openstreetmap; /*--- Draw the polygons from the map data set on top of the base map. The CATEGORY variable notes which variable in the map response data set contains the voting percentage for each polygon. MAPID=_ID_ specifies the variable in the map data set that defines the polygonal boundaries. That same _ID_ variable is also used in the map response data set to link the voting categories to the polygons. Then NAME= assigns a name for the polygon map so we can reference it in the legend. */ choromap category / mapid=_id_ name='voting'; /*--- Add a legend to display the discrete categories. Note the polygon map NAME= is included. We also set a title in the legend. */ keylegend 'voting' / title='Participation'; run; /*--- Close the HTML destination. */ ods html close;