21 May 2008, 15:04
Generic-user-small

Charity Sipe (2 posts)

Hi all,

I think GIS for Web Developers is a great book … up until chapter 8. Chapters 8 & 9 are riddled with errors (especially chapter 9!) I came to these forums hoping to get some answers however support for the book seems to be lax.

Here are a couple issues I had:

  1. Chapter 8, pg. 269. In the last paragraph, the author instructs us to visit geoserver/webapps/geoserver/preview to view default map files for preview maps. However, my directory was empty. I think this is because the latest version of geoserver uses OpenLayers (discussed in section 8.2) instead of Mapbuilder. Since OpenLayers supports tiled maps, geoserver doesn’t need to preload the maps on startup hence the directory is empty (this is my best guess anyway).

  2. Chapter 9, pg. 211. The author uses groovy scripting language to create a sql script to import comma delimited data into postgis. The script building is clear up until pg. 211. There are missing methods, and methods that don’t appear to be supported by groovy (for example, I am using the windows version and noQuote() is not supported). I am not an experienced groovy user however I created a script that works (at least for me). I was able to create the script file, load the data into the database and use the database to view it in Google Earth and NASA World Wind. I have included my version of the script (as it should work with geocoder.us on pg. 214) at the end of the post for anyone who needs help. Please note that I didn’t include the code for Yahoo (pg. 215).

Overall the book is well written, and I love the tutorial style the author uses. My issue was with the editing at the end of the book. I understand that open source applications change so I can forgive issue (1). However, the script in chapter 9 should have worked. There are too many missing pieces. The author needs to secure a more thorough and detail oriented editor for the next edition of the book.

Thanks and have a great day! Charity

Remember to change the paths to point to your input and output files!

`
// Script state for querying geocoder on page 214 of GIS for Web Developers (Chapter 9)
public class GetNext
{
     public String[] getNext(String self, int numberOf)
     {
         def list = [];
         def st = new StringTokenizer(self, ",")
         numberOf.times
         {
              def thisToken = st.nextToken()
              while(thisToken.startsWith("\"") && !thisToken.endsWith("\"") )
              {
                   thisToken += "," + st.nextToken()
              }
              list << thisToken
         }
         return list
    } // End  getNext
}

public class Addr
{
     String id
     String name
     String address
     String city
     String state
     String zip
     String lat
     String lon
     String epsg
     String addressNormalized
     String cityNormalized
     String stateNormalized
     String zipNormalized
     def theGeom = "null"
     def matcher

     public Addr(String[] tokens)
     {
          // Strip out all quotes
          matcher = (tokens[0] =~ /"/)
          id = matcher.replaceAll("")
          matcher = (tokens[1] =~ /"/)
          name = matcher.replaceAll("")
          matcher = (tokens[2] =~ /"/)
          address = matcher.replaceAll("")
          matcher = (tokens[3] =~ /"/)
          city = matcher.replaceAll("")
          matcher = (tokens[4] =~ /"/)
          state = matcher.replaceAll("")
          matcher = (tokens[5] =~ /"/)
          zip = matcher.replaceAll("")
     }

    public boolean geoCode()
    {
        def urlStart = "http://rpc.geocoder.us/service/csv?address="
        def urlBody = "${address},${city},${state},${zip}"
        def urlEncoded = urlStart + URLEncoder.encode(urlBody, "UTF-8")


        new URL(urlEncoded).eachLine{ line->
             println "\t$line}"
             if(line.startsWith("2"))
             {
                  addressNormalized = "NOT FOUND"
             }
             else
             {

                  def getNextObj = new GetNext()
                  def tokens = getNextObj.getNext(line,6)
                  lat = tokens[0]
                  lon = tokens[1]
                  addressNormalized = tokens[2].fixQuote()
                  cityNormalized = tokens[3].fixQuote()
                  stateNormalized = tokens[4].fixQuote()
                  zipNormalized = tokens[5].fixQuote()
                  theGeom = "GeomFromText('POINT(${lon} ${lat})', 4326)"
             }
         }

         return addressNormalized != "NOT FOUND"
    }

    // This method is missing from example
    public String toSql(String inString)
    {
          return inString + "${theGeom}," + "'${addressNormalized}'," +
               "'${cityNormalized}'," + "'${stateNormalized}'," + "'${zipNormalized}'"
    }

} // End class Addr


class Fixer
{
     static String fixQuote(String self)
     {
          self = self[0] + self[1..-2].replaceAll("\'", "\'\'") + self[-1]

          if(self.startsWith("\""))
          {
               return "'" + self[1..-2] + "'"
          }
          else
          {
               return self
          }
     }

}  // End class Fixer


// On your mark, get set, go!
def outputFile = new File("college.sql")
if(outputFile.exists()){ outputFile.delete() }
def ddl = """
BEGIN;
CREATE TABLE college (
"id" numeric PRIMARY KEY,
"name" varchar(255),
"address" varchar(255),
"city" varchar(255),
"state" varchar(255),
"zip" varchar(255),
"address_n" varchar(255),
"city_n" varchar(255),
"state_n" varchar(255),
"zip_n" varchar(255)
);
SELECT
AddGeometryColumn('college','location',4326,'POINT',2);
"""

outputFile.append(ddl)

def insertStart = """insert into college("id", "name", "address",
                    "city", "state", "zip", "location",
                    "address_n", "city_n", "state_n", "zip_n") values ("""
def insertEnd = ");"

def counter = 0
def found = 0
def notFound = 0
def inputFile = new File("..//CollegesandUniversities//sample2.csv")  //USER DEFINED
use(Fixer)
{
     inputFile.eachLine{ line ->
          def getNextObj = new GetNext()
          def String[] tokens = getNextObj.getNext(line, 6)

          if(counter == 0)
          {
               counter++;
          }
          else
          {
               println  "${counter++} ${tokens[1].fixQuote()}"  // show what is going on

               def addr = new Addr(tokens)
               if(addr.geoCode())
               {
                    found++
                    insertMiddle = ""
                    for(i in 0..5)
                    {
                         insertMiddle += "${tokens[i].fixQuote()},"
                    }
                    println insertMiddle
                    insertMiddle = addr.toSql(insertMiddle)
                    println insertMiddle

                    //insertMiddle = insertMiddle[0..-2] // strip off trailing comma
                    outputFile.append("${insertStart}${insertMiddle}${insertEnd}\n")
               }
               else
               {
                    notFound++
               }

          }  // end if counter == 0
          
         // Write out current status
         statusFile = new File("status.txt")
         statusFile.append("Total: ${counter}     Found: ${found}     Unfound:${notFound}\n")

     }  // End eachLine
} // end use(Fixer)
outputFile.append("END;")


`
08 Aug 2011, 17:11
Generic-user-small

CharlieB (1 post)

I’m have broad GIS experience but am new to web-based GIS. I’d like to publish some data for Google Earth (kml/kmz). The description of GIS for Developers does not mention Google Earth, but this forum post does. Can you tell me if this book explains how to publish data for Google Earth? (Does the Google Maps API work for Google Earth as well?) Ttanks for any help! Charlie

  You must be logged in to comment