I'm trying to annotate specific street addresses onto a map, I've seen some examples of this around (such as Outdoor Dramas in North Carolina) but I am unable to get my process to work when trying to display the entire U.S. and just show the addresses as dots. I think the trouble is coming with the gproject piece but I am unsure of how to correct it. When I run the code as is, I do not get any annotations and the map is rotated about 45 degrees. Any advice is greatly appreciated. Thanks!
data teams;
input address $ 1-25 City $ 26-40 State $ 41-42 Zip comma9.0;
datalines;
2001 Blake St. Denver CO 80205
1000 Elysian Park Ave. Los Angeles CA 90090
100 Park Blvd. San Diego CA 92101
24 Willie Mays Plaza San Francisco CA 94107
;
run;
proc geocode
method=street
data=teams
out=teams_geocoded
lookupstreet=sashelp.geoexm;
run;
quit;
data my_anno; set teams_geocoded;
length function $8 color $8;
xsys='2'; ysys='2'; when='a';
anno_flag=1;
rename state=statecode;
function='pie'; rotate=360; size=.65;
if current='y' then do;
style='psolid';
color='blue';
output;
end;
href='';
style='pempty';
color='gray99';
output;
run;
data my_map; set maps.US (where=(statecode not in ("AK", "HI", "PR")));
run;
data combined; set my_map my_anno; run;
proc gproject data=combined out=combined eastlong degrees;
id state;
run;
data my_map my_anno;
set combined;
if anno_flag=1 then output my_anno;
else output my_map;
run;
proc gmap data=my_map map=my_map anno=my_anno;
id state;
choro state / nolegend;
run;
quit;
You're on the right track! ...
But the maps.us you're trying to use is an already-projected map. In order to geocode addresses and then annotate them at their lat/long positions on a map, you'll want to start with a map containing unprojected lat/long coordinates such as mapsgfk.us_states. And in this case, since gproject is storing the coordinates in variables called lat & long, and the mapsgfk.us_states is also using variables called lat & long, you'll want to use gproject's "latlong" option (alternatively you could rename the variables as y & x).
Here's the code, with those 2 changes ...
data teams;
input address $ 1-25 City $ 26-40 State $ 41-42 Zip comma9.0;
datalines;
2001 Blake St. Denver CO 80205
1000 Elysian Park Ave. Los Angeles CA 90090
100 Park Blvd. San Diego CA 92101
24 Willie Mays Plaza San Francisco CA 94107
;
run;
proc geocode
method=street
data=teams
out=teams_geocoded (rename=(x=long y=lat))
lookupstreet=sashelp.geoexm;
run;
quit;
data my_anno; set teams_geocoded;
length function $8 color $8;
xsys='2'; ysys='2'; when='a';
anno_flag=1;
rename state=statecode;
function='pie'; rotate=360; size=.65;
if current='y' then do;
style='psolid';
color='blue';
output;
end;
href='';
style='pempty';
color='gray99';
output;
run;
data my_map; set mapsgfk.us_states (where=(statecode not in ("AK", "HI", "PR")));
run;
data combined; set my_map my_anno; run;
proc gproject data=combined out=combined eastlong latlong degrees;
id state;
run;
data my_map my_anno;
set combined;
if anno_flag=1 then output my_anno;
else output my_map;
run;
proc gmap data=my_map map=my_map anno=my_anno;
id state;
choro state / nolegend;
run;
quit;
You're on the right track! ...
But the maps.us you're trying to use is an already-projected map. In order to geocode addresses and then annotate them at their lat/long positions on a map, you'll want to start with a map containing unprojected lat/long coordinates such as mapsgfk.us_states. And in this case, since gproject is storing the coordinates in variables called lat & long, and the mapsgfk.us_states is also using variables called lat & long, you'll want to use gproject's "latlong" option (alternatively you could rename the variables as y & x).
Here's the code, with those 2 changes ...
data teams;
input address $ 1-25 City $ 26-40 State $ 41-42 Zip comma9.0;
datalines;
2001 Blake St. Denver CO 80205
1000 Elysian Park Ave. Los Angeles CA 90090
100 Park Blvd. San Diego CA 92101
24 Willie Mays Plaza San Francisco CA 94107
;
run;
proc geocode
method=street
data=teams
out=teams_geocoded (rename=(x=long y=lat))
lookupstreet=sashelp.geoexm;
run;
quit;
data my_anno; set teams_geocoded;
length function $8 color $8;
xsys='2'; ysys='2'; when='a';
anno_flag=1;
rename state=statecode;
function='pie'; rotate=360; size=.65;
if current='y' then do;
style='psolid';
color='blue';
output;
end;
href='';
style='pempty';
color='gray99';
output;
run;
data my_map; set mapsgfk.us_states (where=(statecode not in ("AK", "HI", "PR")));
run;
data combined; set my_map my_anno; run;
proc gproject data=combined out=combined eastlong latlong degrees;
id state;
run;
data my_map my_anno;
set combined;
if anno_flag=1 then output my_anno;
else output my_map;
run;
proc gmap data=my_map map=my_map anno=my_anno;
id state;
choro state / nolegend;
run;
quit;
Always great to learn from the master! Thanks Dr. Allison!
So in general, do the map and the annotation need to be projected in the same step, or would it be possible to project the annotate data into the same format as maps.us?
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.