%let name=legendizer; filename odsout '.'; %let st=NY; data mymap; set mapsgfk.us_counties (where=(statecode="&st" and density<=2) drop=resolution); flag=1; run; /* This is fake data, for demo purposes. In your real situation, you'd have zipcodes, and some real quantity, or count, of something in that zipcode. I conveniently already have county in my fake data ... but if you didn't, you could use Proc Ginside to determine that! */ proc sql noprint; create table mydata as select unique zip, 1 as quantity from sashelp.zipcode where state=stfips("&st"); quit; run; /* Lookup the long/lat, and county name for each zipcode */ proc sql noprint; create table mydata as select unique mydata.*, zipcode.x as long, zipcode.y as lat, zipcode.state, zipcode.county from mydata left join sashelp.zipcode on mydata.zip=zipcode.zip; quit; run; /* Look up the text County names */ proc sql noprint; create table mydata as select unique mydata.*, us_counties_attr.idname as countynm from mydata left join mapsgfk.us_counties_attr on mydata.state=us_counties_attr.state and mydata.county=us_counties_attr.county; quit; run; /* Sum up the number of 'whatevers' in each county, or you could use count(*) to just do a count of the number of markers in that county, etc. Adjust the hardcoded legend label accordingly. */ proc sql noprint; create table counts as select unique state, county, countynm, sum(quantity) as total_quantity from mydata group by state, county; quit; run; proc sort data=counts out=counts; by descending total_quantity; run; data counts; set counts; legend_num = _n_; length county_info $75; county_info=trim(left(propcase(countynm)))||': '||trim(left(total_quantity)); length myhtml $500; myhtml= 'title='||quote( 'County: '|| trim(left(propcase(countynm))) ||'0D'x|| 'Total: '|| trim(left(total_quantity)))|| ' href="legendizer_info.htm"'; run; /* I want the legend in the gmap to be in a certain order, so I put a numeric variable in the dataset with the values in the order I want (I just happen to call that variable 'legend_num' - you could call it anything). I then create a dynamic user-defined format on-the-fly that maps the numeric values to the county name & info. */ proc sql noprint; create table control as select unique legend_num as start, county_info as label from counts; quit; run; data control; set control; fmtname='my_fmt'; type='N'; run; proc format lib=work cntlin=control; run; data anno_city; set mydata; flag=2; run; /* combine, project, separate */ data combined; set mymap anno_city; run; proc gproject data=combined out=combined latlong eastlong degrees project=robinson; id state county; run; data anno_city mymap; set combined; if flag eq 1 then output mymap; else output anno_city; run; data anno_city; set anno_city; xsys='2'; ysys='2'; hsys='3'; when='a'; function='label'; size=2; text='25cf'x; style='albany amt/unicode'; color='A0000ff77'; run; goptions device=png; goptions border; goptions xpixels=1000 ypixels=600; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" (title="Map, with summary counts in legend") style=htmlblue; goptions gunit=pct htitle=4 htext=1.75 ftitle="albany amt/bold" ftext="albany amt"; goptions ctext=gray33; pattern1 v=s c=cornsilk repeat=1000; legend1 across=2 colmajor /* colmajor is a new v9.2 feature */ position=(left middle) label=(position=top height=2.5 font="albany amt/bold" 'Total per County:') shape=bar(.0001,.0001) value=(justify=right); title1 ls=1.5 "Using GMAP's Legend & User-Defined Format"; title2 ls=0.8 h=2.5 font="albany amt/bold" "to to show summary counts per county"; proc gmap data=counts map=mymap anno=anno_city; format legend_num my_fmt.; id state county; choro legend_num / discrete legend=legend1 coutline=gray html=myhtml des='' name="&name"; run; quit; ODS HTML CLOSE; ODS LISTING;