Click here to Skip to main content
Click here to Skip to main content

Mapping Zip Code From Your Database.

By , 25 Jul 2004
 

Sample Image - zipcodemapping.gif

Introduction

This application was designed to help me figure out the demographics of my address list. I was curious as to where the various people were located in the continental United States. After a while, I found a couple of interesting articles that pointed me in the right direction, but nothing that was going to save me from writing a solution myself... So, here it is... The Zip Code Mapping Solution (Free). Now, please be patient with this article as it is the first one I have posted...

How it works:

The Database:

This application has some pretty simple source code in it... but the main guts and glory come from the database. In the demonstration database, you will find two tables and three queries.

  • Table 1: PUBLISHERS

    (A sample table of data put out by Microsoft, normally this would be your customer base... or whoever you would like mapped.)

  • Table 2: ZIPCODES

    (This table is something I put together through the US Census and through a free Zip Code database that I found online.

  • Query 1: ALLZIPS

    (This query simply filters out all zip codes from the ZIPCODES table that are not in the continental United States.)

  • Query 2: ZIPCODEADDRESS

    (This query also filters out zip codes that are not in the continental US as well as removes null zip codes, non-numeric zip codes [e.g. foreign], and spaces from the "PUBLISHERS" table.)

  • Query 3: ZIPLOCATIONS

    (This query counts the number of people at each zip code, gets the latitude and longitude, and lists the zip code by matching through ZIPCODEADDRESS and ZIPCODES.)

The Mathematics:

I had to determine a certain amount of mathematical formulae in order to get this to work. Basically, what the application needs to do is scale down the zip codes into a grid, based on the latitude and longitude coordinates being converted into pixels, on an image. Here are the pieces of data that are needed (these are explained in the demo project).

  • +48.987386 is the highest latitude in the continental US.
  • +18.005611 is a latitude lower than the southern most latitude (used for buffer).
  • -124.626080 is the west most longitude in the continental US.
  • -62.361014 is a longitude more east than the eastern most longitude (used for buffer).

To find out the scale, I simply figured out the difference in latitudes, and divided it by the height of my image... and then figured out the difference in the longitudes, and divided it by the width of my image. For example:

I selected a 701w X 565h pixel image. To calculate the scale, I did the following math:

Latitude:  (48.987386-18.005611)/565h  = .054835 latitude  unit/pixel
Longitude: (124.656080-67.040767)/701w = .088866 longitude unit/pixel

To put this into code, I just created two functions:

Function getLat(byVal y1)
    Return cInt((48.987386 - (cDbl(y1))) / 0.054835)
End Function
Function getLong(byVal x1)
    Return cInt((124.62608 - (cDbls(x1) * -1)) / 0.088866)
End Function

*Note that the longitude was multiplied * -1... that was to make it a positive number for the subtraction routine.

Now with these functions, I can simply send the latitudes and longitudes from the database to those functions in order to get the correct pixel area that I need to map.

The Application:

Now that we have determined the canvas size and the scale, we create a canvas:

    'declare variables
    Dim objBitmap As Bitmap = New Bitmap(701, 565) 
    Dim objGraphics As Graphics = Graphics.FromImage(objBitmap)

    'create the colors and the shapes
    Dim objBrush As SolidBrush = _
      New SolidBrush(System.Drawing.Color.LightGray) 'for US Contour
    Dim objWhite As SolidBrush = _
      New SolidBrush(System.Drawing.Color.White) 'for background
    Dim objNewBrush As SolidBrush
    Dim myRect As Rectangle

Here, I have created the Bitmap and Graphics objects to draw with. I also have created some brushes in order to draw some stuff.

The next step I took was to access everything from a database. I have tested this with both Oracle 9i and MS Access... as long as you change where you are getting your data... everything works the same. So, I am going to skip the database connection stuff as you should be able to figure that out.... if not, it is still in the demo program.

The first step I take (maybe there is an easier way) but I draw a white rectangle for the background of my bitmap.

    myRect = New Rectange(0,0,701,565)
    objGraphics.FillRectangle(objWhite, myRect)

The next step is to select all records from the "ALLZIPS" table and draw a dot at each of the records. (This is actually quite fast on my computer, but results could vary).

    rs.Open("SELECT * FROM ALLZIPS", DB, 3, 3)
    
    'LOOP THROUGH
    WHILE NOT RS.EOF
        myRect = New Rectangle(getLong(rs("LONGITUDE").value)+50, _
                                getLat(rs("LATITUDE").value)+50,2,2)
        objGraphics.FillEllipse(objBrush, myRect)
        rs.MoveNext()
    Wend

As you can notice, it is creating an Ellipse (2x2), colored LightGray, at the coordinates specified by "getLong({DB-LONGITUDE})" and "getLat({DB-LATITUDE})", and I add 50 pixels for my surrounding border on the image.

Now, I do it again, but I do it with the records that I want to mark with a different color.

    rs.close 'close previous recordset
    rs.open("SELECT * FROM ZIPLOCATIONS"), DB, 3, 3)
    'LOOP THROUGH
    WHILE NOT RS.EOF
        myRect = New Rectangle(getLong(rs("LONGITUDE").value)+50, _
                                getLat(rs("LATITUDE").value)+50,4,4)
        'now determine the color based on number of matches
        Select Case (rs("ZIPCOUNT").Value)
        Case 1
            objNewBrush = New SolidBrush(System.Drawing.Color.RoyalBlue)
        Case 2
            objNewBrush = New SolidBrush(System.Drawing.Color.MediumSeaGreen)
        Case 3
            objNewBrush = New SolidBrush(System.Drawing.Color.LawnGreen)
        Case 4
            objNewBrush = New SolidBrush(System.Drawing.Color.OliveDrab)
        Case 5
            objNewBrush = New SolidBrush(System.Drawing.Color.DarkKhaki)
        Case 6
            objNewBrush = New SolidBrush(System.Drawing.Color.Goldenrod)
        Case 7
            objNewBrush = New SolidBrush(System.Drawing.Color.DarkOrange)
        Case 8
            objNewBrush = New SolidBrush(System.Drawing.Color.Coral)
        Case 9
            objNewBrush = New SolidBrush(System.Drawing.Color.Red)
        Case 10
            objNewBrush = New SolidBrush(System.Drawing.Color.Firebrick)
        Case Else
            objNewBrush = New SolidBrush(System.Drawing.Color.DarkRed)
        End Select
        'fill the elipse with the selected color
        objGraphics.FillEllipse(objNewBrush, myRect)
        rs.MoveNext()
    Wend

At this point, the image is drawn and stored in the variable... so we just need to finish up the export of the image and set it to the Image object.

    'finish up
    objBitmap.Save(Server.MapPath(Request.ApplicationPath) _
            & "\newGlobe.gif", Imaging.ImageFormat.Gif)
    objGraphics.Dispose()
    objBitmap.Dispose()
    rs.Close()

    'set source
    imageButton.ImageUrl = "newGlobe.gif"

And that is all she wrote... that will create everything that you need.

Additional Comments:

There is another procedure in the demo program that helps you "Zoom in", that is based off an article by: Harish Palaniappan (also found on TheCodeProject). I hope that this article has helped you out and I really would like to hear about anybody who uses this application for their web sites. Just drop me a line: aamittee{at}mtu.edu.

Regards,

Adam A. Mitteer

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Adam A. Mitteer
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralIndividual statesmemberramprasadr3 Mar '05 - 7:25 
Hello Adam,   Thanks for the well explained article. I'm trying to take this further ahead, by plotting zipcodes for any specific state with the same bitmap size.   When I attempted it with MA, either I get a tiny represenation for the whole state, or only the eastern half...
GeneralLegal NoticessussAnonymous5 Aug '04 - 11:34 
Is there a way to add two legal notices to windows logon. They must appear sequencially as soon as you press ALT+CTRL+DEL to logon.
GeneralA tip about storing numeric values with leading zeros.memberAshaman30 Jul '04 - 2:37 
You should be storing your Zip codes as a char(5) instead of as an Int32.   I changed the data type and used the following super simple function in an update query to fix the zip codes so that they'd include their leading zeros if they needed one.   Public Function FixZips(ByVal...
GeneralRe: A tip about storing numeric values with leading zeros.memberkcl4 Aug '04 - 0:45 
You could also format the number to a string using "00000" as the formatting string, e.g.:   myZipString = String.Format(myNumericZipCode,"00000")   This (to me at least) would seem to be more obvious as to what the intention is when you (or someone else) reads the code back at a...
GeneralRe: A tip about storing numeric values with leading zeros.memberAshaman4 Aug '04 - 1:53 
Either way, it's a simple process to convert the Zips. My point was that it is critical when storing numeric values that require leading zeros that you store them as a character type.   The reason I like my conversion solution is that it is a language independant process. Using the...
GeneralErrorsussAnonymous28 Jul '04 - 13:40 
Great stuff but I receive a GDI error when trying to save the image.
GeneralRe: ErrormemberAdam A. Mitteer29 Jul '04 - 3:56 
I have a hunch that it has to do with the permissions of your folder. I would play around with IUSR_account and make sure that it has the proper permissions. Check the permissions and if that doesn't solve the problem can you copy/paste the error output to this forum so that I may analyze it...
GeneralRe: Errormemberkcl4 Aug '04 - 0:03 
Possibly try ASP.NET user instead of IUSR_account....   Hope that helps   Chris
Generalneed help with errormembermkane727 Jul '04 - 18:08 
Server Error in '/zipcodemapping_demo' Application. -----------------------------------------------------------------   Parser Error Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error...
GeneralRe: need help with errormemberAdam A. Mitteer28 Jul '04 - 4:18 
mkane7,   Okay... I managed to duplicate your error and I think that I have the following solution for you. Because this is my first post on this web site I really don't have much of a clue as to what files I need to attach and which ones I shouldn't. So... here is how you can get the...
GeneralRe: need help with errormembermkane728 Jul '04 - 17:14 
Adam,   Thanks for your help. I got the project to compile but now I get a runtime error.   I have followed all the steps here http://www.attention-to-details.com/newslog/38n-temporary-volatile-jet-dsn-for-process.asp but I get the below error.   By the way I included the...
GeneralRe: need help with errormembermkane728 Jul '04 - 18:33 
Adam I figured it out. For some reason giving the IUSR_ account access to demo.mdb wasn't enough. When I gave the Everyone account access to demo.mdb it worked!   By the way, I figured it out by temporarily changing the connection string as follows: conn =...
GeneralRe: need help with errormemberAdam A. Mitteer29 Jul '04 - 3:44 
Mark,   That is odd that IUSR_account wasn't enough for the project. I am glad you figured it out. And thanks for the info on the provider string... that is something I will keep in mind in the future when using those tedious ADODB connection strings. It seems like I get more and more...
GeneralRe: need help with errormemberkcl3 Aug '04 - 23:30 
Try the ASP.NET user account - rather than the IUSR_account or Everyone.   Hope that helps.   Chris
GeneralRe: need help with errorsussAnonymous9 Aug '04 - 9:32 
Can you explain how to use the ASPNET account, rather than the   IUSR account?   I am getting a GDI error when running in debug mode: Source Error:   Line 141: Line 142:            'finish up Line 143:     ...
GeneralRe: need help with errormemberAdam A. Mitteer9 Aug '04 - 10:27 
Hmmm...   Let me first give you the permissions I have set for my folder... I know my machine isn't set up as securely as it could be... but good enough to develop. Maybe what I have will help you.   F = Full control M = Modify E = Read and Execute L = List folder contents R...
GeneralRe: need help with errormemberCat Doan1 Apr '09 - 18:07 
Hi Mr. Mitteer,   Your program (Mapping Zip Code From Your Database) is very helful. Do you have it in VB6 or could you explain it in VB6. Thank you very much.   Cat Doan catdoan@worldnet.att.net
GeneralRe: need help with errormemberkcl10 Aug '04 - 2:50 
By default...The ASP.NET engine operates under the ASPNET user account.   If you have administrator access on the machine hosting your website you can set security permissions on files & folders for the APSNET account as you need to.   Impersonation... If you want to have the...
GeneralRe: need help with errorsussanonymous10 Aug '04 - 3:50 
Well, I appreciate the help. I got it to work after Adam's suggestion. I work in a government agency that has tight control over permissions and was finally able to get to the folder to assign permissions. I don't think I will be having those problems again. I appreciate the explanation. I...

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 26 Jul 2004
Article Copyright 2004 by Adam A. Mitteer
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid