Modeling Energy System Investment Planning Infrastructure for the State of Iowa Final Design Report Project ID: Dec09-02 Group Members Mubarak Abbas Mohammed Ahmed Austin Lyons Muhammad Rahim Client Dr. James McCalley DISCLAIMER: This document was developed as part of the requirements of an electrical and computer engineering course at Iowa State University, Ames, Iowa. The document does not constitute a professional engineering design or a professional land surveying document. Although the information is intended to be accurate, the associated students, faculty, and Iowa State University make no claims, promises, or guarantees about the accuracy, completeness, quality, or adequacy of the information. Document users shall ensure that any such use does not violate any laws with regard to professional licensing and certification requirements. Such use includes any work resulting from this student-prepared document that is required to be under the responsible charge of a licensed engineer or surveyor. This document is copyrighted by the students who produced the document and the associated faculty advisors. No part may be reproduced without the written permission of the senior design course coordinator. Dec09-02 Final Report Contents Problem Statement ....................................................................................................................................... 4 Solution ......................................................................................................................................................... 4 Audience ....................................................................................................................................................... 4 Requirements System Requirements ........................................................................................................... 4 Functional Requirements ...................................................................................................................... 4 Nonfunctional Requirements ................................................................................................................ 5 Design............................................................................................................................................................ 6 System Description ................................................................................................................................... 6 System Block Diagram............................................................................................................................... 6 Data ....................................................................................................................................................... 7 Storage ................................................................................................................................................ 10 Acquiring Data..................................................................................................................................... 10 Visualization ............................................................................................................................................ 10 Analysis ................................................................................................................................................... 10 Operating Environment .......................................................................................................................... 11 Data ..................................................................................................................................................... 11 Visualization ........................................................................................................................................ 11 Analysis ............................................................................................................................................... 11 User Interface Description ...................................................................................................................... 11 Implementation .......................................................................................................................................... 11 Data ......................................................................................................................................................... 11 Obtaining Data .................................................................................................................................... 11 Translating Data .................................................................................................................................. 12 Visualization ............................................................................................................................................ 14 Data Conversion Program ................................................................................................................... 15 Google Earth ........................................................................................................................................... 18 Website ................................................................................................................................................... 19 WASP-IV .................................................................................................................................................. 21 Functionality ....................................................................................................................................... 21 Detailed Instruction – LOADSY ............................................................................................................ 22 Detailed Instruction – FIXSYS .............................................................................................................. 23 Dec09-02 Final Report Detailed Instruction – VARSYS ............................................................................................................ 25 Testing ......................................................................................................................................................... 26 Data Conversion Program ....................................................................................................................... 26 WASP-IV .................................................................................................................................................. 28 Conclusion ................................................................................................................................................... 30 References .................................................................................................................................................. 30 Appendix I: Additional Documentation - Visualization ............................................................................... 31 Basic Instructions for Data Conversion Program ........................................................................................ 31 Line Data Specification ................................................................................................................................ 31 Examples ................................................................................................................................................. 32 Point Data Specification .............................................................................................................................. 34 Examples ................................................................................................................................................. 34 Data Conversion Program – Test Descriptions ........................................................................................... 36 Test Description ...................................................................................................................................... 36 Test File ................................................................................................................................................... 36 Line Data ............................................................................................................................................. 36 Point Data ........................................................................................................................................... 36 Appendix II: Additional Documentation – Analysis..................................................................................... 37 CONGEN (CONFIGURATION GENERATION) ............................................................................................ 37 MERSIM (MERGE and SIMULATE) ........................................................................................................... 37 DYNPRO (DYNAMIC PROGRAMMING OPTIMIZATION)........................................................................... 38 Appendix III: Source Code ........................................................................................................................... 39 GUI.java ................................................................................................................................................... 39 Line.java .................................................................................................................................................. 71 Point.java ................................................................................................................................................ 75 Website Source Code .................................................................................................................................. 78 Dec09-02 Final Report Problem Statement The state of Iowa needs to make investment decisions to meet increasing demands on its energy infrastructure. To make educated decisions, a comprehensive and interactive model of the state’s energy infrastructure is needed. Such a model currently does not exist. [1] Solution Our solution is to design and implement an interactive model of the energy infrastructure of Iowa that can be used to make investment decisions. Audience It is our desire that our model can reach a broad audience who might be interested in visualizing or analyzing the energy infrastructure of Iowa. This audience could include engineers, government officials, city planners, entrepreneurs, educators, and the general public. Requirements System Requirements Functional Requirements Data Create an interactive database of Iowa energy data from 2001 up to 2006. The time-frame of 2001-2006 has been chosen because we were able to obtain most of the data during this period. The data prior to 2001 has no real purpose except for maybe seeing historical trends; however, 2001 to 2006 data helps us see the more recent trends. For generation, transmission and distribution, we wanted to work with the most recent data we had (2006-2008) because that would be most related to the present. It should be noted that 2009 data is impossible to acquire at this time because public sources like EIA will have such information ready by 2010 at the earliest. Visualization Use Google Earth software to visualize power generation, transmission line, and energy resource data. The visualization system will need to be interactive, easy to use, free, and platform independent. Analysis Use Wien Automatic System Planning Package (WASP-IV) with generation data to perform generation system expansion planning. Dec09-02 Final Report Nonfunctional Requirements The database should include all information pertaining to energy resources necessary for making energy investment decisions. The required information is summarized in the following tables. ENERGY RESOURCES Wind Solar Hydro Nuclear Generation Plants Coal Natural Gas Petroleum Ethanol Nuclear Wind Hydro FUEL NETWORK Natural gas Ammonia ELECTRICITY INFRASTRUCTURE Transmission Plants Lines Substation Locations Figure 1 – Required Energy Infrastructure Data The required data must be accurate and reliable. For example, data used from year 2005 cannot be used in 2006 if the actual data for 2006 does not exist. If any data for a specific year cannot be located, then the information pertaining to that year will be left blank. Any data used for projections into the future needs to be based on some reference to actual data from previous year; that is, the projected data cannot be arbitrary. Dec09-02 Final Report Design System Description The system we have designed for making energy infrastructure investment decisions has three major components: data, visualization, and analysis. We will acquire energy infrastructure data and store it in comma separated files (.csv). We will then write software to convert the .csv files into files that Google Earth can display (.kml). We will also learn how to use WASP-IV and integrate the data we acquired into WASP-IV for generation expansion analysis. A block diagram of the system will be presented and details about each component will follow. System Block Diagram Figure 2 - System Block Diagram Dec09-02 Final Report Data The data that will be accumulated will primarily revolve around 3 components: 1. Energy resources 2. Electricity infrastructure 3. Natural gas and liquid fuel infrastructure We will store our accumulated data in a single Microsoft Excel file. The Excel file will contain several spreadsheets, each corresponding to a layer of information. The layers that we will create are as follows: LAYERS Hydro energy resource locations Solar energy resource locations Nuclear Plant Location Wind Farm Locations 345KV Network 230kV Network 161kV Network 115kV Network Petroleum Network Ethanol Network Liquid Fuel Networks Transmission Substation Locations Distribution Substation Locations Power Plant Locations Energy Resources We are only interested in energy sources that are used to generate electricity. Wind Wind is an important energy resource since it is primarily used for electricity generation. Our main concern is to find information about the locations of wind farms in Iowa. Solar Solar energy is an available energy resource in the United States. The amount of power that can be accumulated from the sun depends on several factors including the amount of sunshine each state receives and the cost of land used to house the solar panels. Some states get a lot of sunshine throughout the year, and they have taken advantage of this buy building large solar panel arrays that they use to generate respectable amounts of electricity. However, Iowa is not as ideal of a state for solar power generation; land is fertile and therefore expensive and the sun is not as potent as in southern states. Knowing this information, we expect that the data we accumulate regarding solar power could be minimal or insignificant. Dec09-02 Final Report For example, there might be many solar panels in Iowa that are being used to power individual resources such as street lamps. Unless we discover that there are a vast number of street lamps in Iowa being powered by solar panels, we will declare this type of information insignificant for investment decision making purposes. We are only interested in solar panels that generate significant amounts of energy. We are also interested in finding data regarding the feasibility of solar panels in Iowa. For example, we are interested in seeing if there are any maps that exist that show the thermal generation per county or the amount of available public roof space per county. This information would be useful in determining where to put new solar panels. Hydro We are interested in the location of hydro plants in Iowa. We are also interested in information regarding the amount of energy generated per hydro plant. Nuclear It is a common knowledge that only one nuclear plant exists in the state of Iowa and is located in Palo. We will find generation information about this power plant. Coal Coal resources in Iowa are used for other purposes other than generating electricity. However, we will focus only on those that are used for generating electricity. We will be interested in location and net electricity generation. Biomass & Biofuel Resources The primary source of biofuel in Iowa is ethanol. Ethanol can be used to create electricity; for example, there are ethanol powered gas turbines that are used to generate electricity. We are interested in finding out how much electricity in Iowa is generated from ethanol or other biofuels. We are also interested in determining the location of the biofuel to electricity conversions. Biomasses can also be used to generate electricity. For example, wood can be burned as fuel for generation of steam and ultimately electricity. We are interested in the amount of electricity produced from biomass and the location of such productions. Electricity Infrastructure The electricity infrastructure in the state of Iowa can be broken up into generation, transmission, and distribution. Generation Generation data in Iowa is related to the energy resources. We are interested in the location of the power plants, the amount of electricity each plant is generating, the type of fuel used to generate the electricity, and the amount of fuel being used. Dec09-02 Final Report Transmission In this section of our research we are trying to gather any information regarding Iowa transmission. National security issues may make this section of our research very challenging. However, the information is important and must be obtained. We are interested in knowing the location of the lines, the voltage they are carrying, and whether they are overhead or underground transmission lines. We are also interested in the location and voltage of transmission substations. Distribution Our lowest priority is to find information about the distribution networks in Iowa. This type of information is granular, and though it could be important on a city or county level it is not as important on a state level. We would be interested in the larger distribution voltage networks and their substations. Natural Gas We are interested in information about the natural gas pipelines in Iowa. We want to know the location of the pipelines and their capacity. Liquid/Gas Fuel Lines There exist some liquid/gas fuel lines in Iowa, such as ammonia. We are interested in finding information about these lines, such as their location, capacity, and what fuel they are carrying. Note: Even though the layers we created do not match exactly by the names, we do have all the data in the layers for visualization that were asked from us in some form. Dec09-02 Final Report Storage We will develop an inventory of the existing energy infrastructure of Iowa by acquiring data and storing it in Excel as a comma separated file (.csv). Acquiring Data We will try to acquire data that is available to the public for free. However, due to confidentiality issues, not all of the data is freely available. For any data that cannot be freely acquired we will contact companies that sell energy infrastructure data. Regardless of the source of the information, we will check the validity of the data by asking the source and cross-checking with other acquired data. Visualization Visualization of the entire state’s energy infrastructure is an integral part of investment decision making. We will use Google Earth to create an interactive visual model of the state’s energy infrastructure. Analysis Wien Automatic System Planning (WASP) Package is a comprehensive electric power system expansion analysis tool. We will utilize its powerful calculation abilities to analyze the energy infrastructure. Two primary reasons exist for choosing WASP-IV. The first reason for choosing WASP-IV is for its unparalleled power system analysis abilities. It can make many power system calculations that would be very beneficial when making energy infrastructure investment decisions. The second reason for choosing the software is our familiarity with it. None of the four undergraduates working on this project have ever used WASP-IV, but Dr. McCalley and his graduate students are very familiar with the software and will be able to teach us what we need to know. Our primary use of WASP-IV will be to find the optimal expansion plan for our power generating infrastructure. We will use relevant portions of our energy infrastructure data as an input for WASP-IV. When making investment decisions, users can either choose to input current energy infrastructure data or change the data to represent plausible future scenarios. We will demonstrate the functionality of our system by creating spreadsheets with realistic future scenario data, such as additional power plants or different constraints, inputting the data into WASP, and observing the optimal output. WASP-IV is complex and will take time to learn. It is not expected that all future users will be interested in the analysis functionality that WASP-IV will provide. However, there will be a smaller audience that will be very interested in using WASP-IV with the energy infrastructure data that we have collected. We will create a tutorial for this audience that assumes no prior knowledge of WASP-IV but does assume an understanding of power systems. Dec09-02 Final Report Operating Environment Data The data will be platform independent. To achieve this we will store data as comma separated value (.csv) files. This file type is commonly associated with Microsoft Excel, but it can be edited from many other spreadsheet programs or even just a text editor. Visualization The visualization component of our system will be platform independent. Google Earth can run on a PC, Mac, or Linux. The .kml files can also be viewed in a web browser with the Google Earth plugin, which exists for different browsers across platforms. The data conversion program (will be discussed in detail later) is written in Java, which runs on PC, Mac, or Linux. Analysis Our system uses WASP-IV for generation expansion analysis. WASP-IV only works on Windows. The portion of our audience that is interested in generation expansion analysis will need Windows machines to use WASP-IV. User Interface Description We desire to have any easily accessible user interface that anyone could use. Viewing the data in with a spreadsheet editor or text editor is easily accessible for everyone. The data conversion program will have to be designed ease of use in mind. Viewing the data with Google Earth or a web-browser is also user friendly from a user interface perspective. WASP-IV does not have a nice user interface, but we chose it for reasons other than its interface. In summary, our data and visualization software will have friendly user interfaces. Implementation Data Obtaining Data Most of our generation data was taken from the Energy Information Administration (EIA) Website. All of the data for generation, fuel consumptions, facility and operator names, have been organized in an excel sheet based on the years 2006, 2007 and 2008. Please refer to the excel files, “Modeling_Data_2006”, “Modeling_Data_2007”, and “Modeling_Data_2008” for all of these data. The files were included in the final deliverable. For specific information regarding facilities (capacity, year in service, no. of units, etc), we used a thirdparty source known as Power Plant Jobs. We were able to verify the validity of this website by checking if the plant data from the website actually matches the information from the modeling data. The link for the website is http://www.powerplantjobs.com/ppj.nsf/powerplants1?openform&cat=ia&Count=500. In terms of specific data regarding fuel networks, transmission lines (115kV, 230kV, 345kV), and substation data, we were not able to obtain such information from a free public source. Dr. McCalley Dec09-02 Final Report supplied us with the necessary maps and have all been included in the folder that will be given back to client. The fuel networks were bought from the Iowa Pipeline Association (IPA), and the transmission map was supplied by Dr. McCalley. In addition, we also gathered specific data regarding wind (wind farms, manufacturers, planned or under construction) from the American Wind Energy Association (AWEA) and Iowa Wind Energy Association (IWEA). Both are excellent sources to get information and the actual map used has been included in the data folder in the deliverable as well (titled “IA_WindTurbine.pdf”). Translating Data This section will not go through every single aspect for translating data from one form to another. However, we will try to give the reader some idea on how we accomplished the data translation. Following is the conceptual idea: Info from Organize into Appropriate Find Coordinates Map Excel sheets Based on Location So for instance, we took the wind information from the map and converted into an excel sheet shown below: Shows part of the data translation process Dec09-02 Final Report The idea is the same for all of the other map-to-excel sheet conversions. It just ends up being a matter of how we put the coordinates in the excel sheet to visualize the energy infrastructure of Iowa. For example, in the case of the Iowa transmission lines (map not shown due to confidential information), we had to determine the starting and ending coordinates for all of the lines: Transmission Map Shows part of the data translation process for the 345kV line For more information regarding how this file was converted into .csv files, please refer to the Visualization section. The above screenshot has been taken from the excel file, “Iowa Transmission” which has been included in the final deliverable and holds all our transmission data. The last and final method of data translation involved taking information from unorganized excel sheets as in the “Modeling_Data_2008” and organizing it in an orderly fashion based on company names, net generation, fuel types, etc as shown in “Facility Locations” (excel file included). Unorganized data under Modeling_Data_2008.xls Organized data under Facility Locations.xls Dec09-02 Final Report Visualization To visualize data in Google Earth, we need to represent our data in KML form. However, we are storing our data in CSV files. We need a way to convert CSV file to KML files. To solve this problem we wrote a Java program to convert our data for us. A view of some data in .csv format. Shown in Excel (left) and Notepad++ (right). An example of a KML file, shown in Notepad++. Dec09-02 Final Report Data Conversion Program What it looks like Here is a screenshot of the graphical user interface (GUI). It was designed with simplicity and ease of use in mind. A screenshot of the data conversion program How it was built The program was written in Java using NetBeans Integrated Development Environment. The program consists of three files – GUI.java, Line.java, and Point.java. The program was written with the intent of keeping things as concise as possible while also coding in a simple fashion so anyone with programming knowledge could maintain or extend the code. The program is roughly 1200 lines of code between the three files. See Appendix II for the source code. Basic Instructions For basic instructions on how to run the program, see “Basic Instructions” in Appendix I or in the accompanying folder. Functionality The program has two main features – to convert network (line) data, or to convert location (point) data. The users being by inputting the location of a .csv file to convert. They then tell the GUI whether to expect line data or point data. This is important, as .csv files containing point data are formatted different than those containing line data. The data formatting guidelines are documented in “Line Data Specification” and “Point Data Specification”, which are included in the deliverable and can also be found in Appendix I. Dec09-02 Final Report After choosing the type of file they expect the GUI to parse, the user can then configure the appearance of the resulting map. If the user chooses “Lines”, they are able to pick a line color and line width. If instead they choose “Point”, they are able to set the point color and the point icon. Configuring line data in the data conversion program Configuring point data in the data conversion program After configuring the GUI, one simply needs to click the “Convert” button. This triggers the process. Data Conversion Process When “Convert” is clicked, the data conversion begins. Depending on the map type that was specified by the user, the program calls one of two functions to parse the data according to either the line specifications or the point specifications. The first step in each of these functions is to check whether the specified .csv file exists, and if it does, can be opened. If it does not exist or cannot be opened, an error message box pops up and the conversion stops. The program then reads the first line of the file to see if it actually contains the correct data. If the first line of the file contains “Start City, End City, Start Latitude, Start Longitude, End Latitude, End Longitude” it is assumed to contain line data. If the first line of the file contains “Location, Longitude, Latitude” it is assumed to contain point data. If the CSV file Dec09-02 Final Report does not start with either of these two strings, an error message is shown and the conversion process stops. After determining that the file does contain the correct contents, the program begins to work its way through the data, one row at a time. Each row contains either a point or a line, so the program stores the data in a list of lines or a list of points. If the data is incorrectly formatted, the program skips the row and prints an error message to an error log. For example, if a point’s latitude is given as a number that is not between -180 and 180, the row is skipped. The process continues until the end of the input file is reached. After reaching the end of the input file, all of the properly formatted points or lines have been stored and any improperly formatted points or lines are reported to (name _of_input_file)_error_log.txt. The program then starts the output process. It opens an output file – (name_of_input_file).kml – and prints the standard KML header information. Then it starts working its way through the list of stored points or lines, printing the necessary KML information for each data point. For example, the file prints KML point data as follows (in psuedocode): for each point in the array of points: get the next point print to output file: “<Point><coordinates>” + point.getLongitude() + “, “ + point.getLatitude + “</coordinates></Point>” end After looping through all of the points or lines and printing the necessary KML, the standard closing portion of the KML file is printed and the output file is closed. Finally, if everything was successful, a message box pops up and tells the user that the data conversion was successful. Error Handling As mentioned in “Data Conversion Process” section, there is a lot of error handling going on behind the scenes. The program checks to make sure the file can be opened, that it’s a .csv, that it contains the correct information, and that each piece of information is properly formatted. If the error is with the format of the data, a message is printed to an accompanying error log. Because the improper data is never written to the KML file, the error log exists to let the user know the data was skipped. If the user had a file with 500 lines, they would never be able to tell by looking at the KML in Google earth that 10 lines were missing. However, they also don’t want to click on 10 pop up boxes each time the program encounters an incorrectly formatted piece of data. So the program has one pop up box at the end of a run letting the user know that there was incorrectly formatted data, and to check the error log. Dec09-02 Final Report Google Earth The KML files can be viewed with Google Earth software. They can be viewed directly in Google Earth or in a web browser using the Google Earth plug-in. In addition to being free and platform independent, Google Earth is desirable because it has “layering” functionality – it lets users interactively choose which maps they wish to view. The software is also easy to use and very well documented. Some examples are shown below: Google Earth displaying four maps – the 115 kV network, 161 kV network, 230 kV network, and 345 kV network in Iowa. Dec09-02 Final Report Google Earth displaying E85 refueling locations in Iowa. The user clicked on Ames and information about the specific refueling location is shown. Website For demonstration purposes, we created a website with some energy infrastructure data we collected. At the time of writing, the website is hosted at: http://seniord.ece.iastate.edu/dec0902/ge/ The source code for the website is included in the deliverable and in Appendix II. The following is a screen shot of the website: Dec09-02 Final Report A screenshot of the example website. The author’s browser is running the Google Earth plug-in and the website and KML files are hosted on the university server. Dec09-02 Final Report WASP-IV Functionality The Wien Automatic System Planning Package (WASP-IV) takes in the data for the main routines (LOADSY, FIXSYS, VARSYS, CONGEN, MERSIM and DYNPRO) to perform generation system expansion planning. Our focus this semester was on the first 3 main routines (LOADSY, FIXSYS, and VARSYS). See figure below: The GUI for WASP-IV Assumptions made for the WASP package are that the study period is divided into a number of stages and that each stage corresponds to one year (up to 30 years can be considered). The user can further sub-divide each year into a number of equal periods with a maximum of 12 periods being allowed. The period is the basic unit of simulation, and the number of periods used in a given study should be chosen to adequately represent seasonal characteristics such as load shape, hydroelectric characteristics, and scheduled maintenance for generating units. The year is the basic unit for economic comparison of alternative expansion policies for the generating system in study, and the total number of years defined should be selected to correspond to the period of time for which the optimal expansion policy is sought (i.e. the planning period) with proper allowance for some years before and after this period of interest (i.e. the study period). [2] For our analysis component, we chose the years 1998 to 2027 and only one period for simplicity (this was inserted for the Common Case Data). We weren’t able Dec09-02 Final Report to completely finish the analysis since all the routines flow sequentially and to completely finish this part of our project; we needed to get to final main routine DYNPRO (explained in Appendix II). Detailed Instruction – LOADSY The Load Description Program (LOADSY) defines the forecasted load and energy demand that will be imposed on the system during the study period. For this purpose a peak load must be specified for each year of study and, if the year is sub-divided into periods, the peak load for each period must be also specified and designated in terms of a fraction of the annual peak. The shape of the load duration curve for each period must be also specified in this module. The entered input for LOADSY has been shown in the next page. Please note that the Annual Peak Loads were determined from the file “Peak_Load_Wasp.ppt” till the year 2006. After 2006, we used linear regression analysis based on population and peak temperatures to estimate future peak loads. LOADSY Input The Period Peak Load Ratio is the fraction of the Annual Peak Load. Since we chose just one period for our analysis, the Period Peak Load Ratio will be very close to one for all years considered. As far as the Load Duration Curve data is concerned, we used an approximate LDC curve for Iowa, based on what Dr. McCalley gave us. We used the LDC curve as an approximate for the Load Duration curve data for 2005, 2006, and 2007 to allow the program to forecast an output for the energy demand as well as minimum loads for 2008 till 2027. Output is shown on the next page. Dec09-02 Final Report LOADSY Output Detailed Instruction – FIXSYS This module describes the committed (fixed) state of the generating system for each year in study. From input data, it reads: the general information on number of periods and hydroconditions, types of plants defined in the study, number of thermal plants used, hydroconditions probabilities, etc.; economic and technical data of existing and committed thermal plants (number of sets, capacities, heat rates, fuel costs, etc.); seasonal and hydroconditional characteristics of each hydroelectric project (if any); and, the yearly commitments for plant additions or retirements (if any). FIXSYS Input Dec09-02 Final Report For this part of the analysis, we decided to ignore the hydroconditions, simply because Iowa does not have an abundance of hydro plants (in fact, there is just one). Note that all the characteristic information of the thermal plants is the sum average of the specific plants. We made a rough estimation that a plant would retire after 10 years and an additional plant will take its place after 15. We also had to make assumptions and generalizations for all thermal plants regarding “spinning reserve as % of unit capacity”, and “forced outage rate”. They were assigned values of 13 and 2, respectively, and were the default values that Dr. McCalley asked us to use. We kept the emissions and group limits as defaults that were set for the program. This information and other data have been included in the WASP-IV folder. Most of the data was a straight look-up from file “Electricity.pdf”. We just had to make sure that the conversions were accurate from the file data to WASP-IV FIXSYS input. Based on these data FIXSYS calculates the basic economic loading order of thermal plants based on unit full-load production costs also calculated by the program. Additionally, FIXSYS evaluates the mode of operation and base and peak capacities of each hydroelectric project in each season and hydrocondition and the characteristics of each composite hydro plant type representing the combination of individual hydro projects of the same type for each year of study; and finally, it affects the number of sets of thermal plants associated with the additions or retirements specified. The yearly results on thermal plant characteristics and composite hydro plants parameters are written onto the FIXSYS output file (IF10: FIXPLANT). These results, together with the hydro project individual characteristics, are also printed on the report produced by this module. FIXSYS Input FIXSYS Output Dec09-02 Final Report Note that since we are not concerned with the hydro conditions, we are primarily more focused on how a specific thermal plant’s capacity changes as plants retire and new additions are made. The output shows the full analysis from 1998 to 2027. Only a certain part of the output is shown below: Detailed Instruction – VARSYS Alternative plants which can be used for system expansion are described in this module. From input data provided for the run, VARSYS reads: the general information on number of periods and hydroconditions and their probabilities, number of thermal alternatives, etc.; techno-economical data for these thermal plants (capacity, fuel costs, heat rate, etc.); seasonal and hydroconditional characteristics of each hydroelectric project (if any) available for system expansion. This can alternatively be thought of as the creative component of the analysis project. We are looking at how alternative thermal plants can affect the future of Iowa’s energy infrastructure. Looking at the input (shown below), we can see that it requires a lot of the same information as in the FIXSYS except that we can change the inputs to a certain extent. VARSYS Input Among the calculations performed by VARSYS are: the basic economic loading order of thermal plants based on unit production costs at full load; mode of operation and capacities for each hydro project in Dec09-02 Final Report each season and hydrocondition; and the characteristics of the composite hydro plants, combining the individual parameters of all hydro projects of the same type. The results of the analysis are written on the VARSYS output file (IF11: VARPLANT) and printed on the report produced by this module. A portion of the output is shown below: VARSYS Output Note that neither FIXSYS nor VARSYS give any real analytical information in their output. This is because WASP-IV stores the information from these two main routines and uses it later for analysis (See Appendix II). Testing Data Conversion Program The goal of the data conversion program is to convert data from .csv to .kml in an easily accessible manner for a broad audience. Though data formatting guidelines are given, we must assume that mistakes will be made in formatting the data. Also, mistakes might be made when operating the GUI, such as giving the GUI point data but telling the GUI that it was given line data. The program must handle all of these situations without crashing, and must notify the user of their mistake when possible. Dec09-02 Final Report To test all of the ways that the program could be incorrectly used or data incorrectly formatted, we have created a folder of tests and documentation about the expected output and error handling associated with each test. For example, to test that the program does not blow up if something other than a number is mistakenly typed into the “Latitude” field of a row of point data, we created a spreadsheet that contained corresponding incorrectly formatted data. We then ran the program and gave it the bad spreadsheet data as input. We first checked to see that the program notified the user of bad data by way of a single pop up box. Then we checked the output KML to ensure that all of the correctly formatted data was still printed and all of the incorrectly formatted data was not written. Lastly, we checked to see that an output file was created and that the file identified the incorrectly formatted data. This was done to test every possible scenario. There is one scenario that the program cannot handle – extra commas. Because the program works by parsing comma-separated data, it uses the location of the commas to determine the value for each variable in a line object. For example, the program reads everything until the first comma and assigns it as the line’s start city, everything till the second comma is assigned to the end city, etc. (Start, End, 94.345, 101.234, 95.555, 101.294). If the program is instead written with a comma in the city name (Start,City, End City, 93.345, …) the program will assign “Start” as the name of the starting city and “City” as the name of the ending city. This should not be an issue if the user edits the files in a text editor, as it is obvious. However, it is not as obvious when viewing the data in Excel: The user must just be aware that commas are not allowed. For similar reasons, if the program hangs for any reason it is highly recommended that the user view their input file in a text editor to see if anything is out of the ordinary. Another example: Deleting a row in Excel can seem inconspicuous, but an additional unwanted comma will be put in the .csv file. Though the Excel data appears to be correctly formatted, a deleted column results in an unwanted comma in the .csv file. Dec09-02 Final Report For more information about the testing, see “DataConversionProgram-Test Descriptions” in Appendix I or look at the suite of tests in the deliverable. WASP-IV In terms of the main routines (LOADSY, FIXSYS, and VARSYS), only LOADSY can be tested in reality. The FIXSYS and VARSYS do not provide any profound analytical result due to the nature of the two routines and cannot be tested for validity until we do the later routines (CONGEN, MERSIM, and DYNPRO). Therefore, the testing for the analysis (more specifically LOADSY) will be made by using the forecasted data for 2008 and comparing it with the actual data for 2008. If the energy demand data is correctly forecasted within +/-10-15%, it will prove that the software and the input data are accurate (or very close). Please refer to the LOADSY output shown below: LOADSY Output Dec09-02 Final Report The output was generated using the Iowa data that we accumulated. As shown, the energy demand and minimum load forecasted by the software are 45193.6 GWh and 3366 MW, respectively. From the source that was supplied to us by Dr. McCalley in the file “MEC 2008 FERC Form 1 p 401b.pdf”, we determined that the actual demand for energy supplied by MidAmerican was approximately 22227719 MWh for 2008. MidAmerican owns a market share of roughly 47%, which allows us to calculate that the actual energy demand for Iowa will be 47567319 MWh or 47567.32 GWh. See work shown in excel file “LDC.xls”. Calculations made in Excel We can see then that we have an error for the energy demand of roughly 5% (1 - 45193.6/47567.32). In other words, this program was able to simulate the data correctly and our input data were fairly close to being accurate. An additional note to be made here is that we calculated the minimum peak to be around 3958 MW (shown above). The program forecasted the minimum for Iowa demand in 2008 to be 3366 MW which is also fairly close considering the fact that we are using approximate data. Dec09-02 Final Report Conclusion In conclusion, we have designed a system to act as a comprehensive and interactive model of Iowa’s energy infrastructure for energy investment decision making. Our system consists of a database, a visualization component, and an analysis component. The energy data was collected and stored as .csv files. A Java program was written to allow users to convert CSV data into KML data. The KML files can be viewed in Google Earth or in a web browser using the Google Earth plug-in. The data can be analyzed using the generation expansion analysis tool WASPIV. References [1] NETSCORE 21 - http://www.ece.iastate.edu/research/research-projects/netscore-21.html [2] WASP-IV - Manual Dec09-02 Final Report Appendix I: Additional Documentation - Visualization Basic Instructions for Data Conversion Program Austin Lyons Senior Design Dec09-02 To run the visualization program, the computer must have the Java runtime installed. If you can’t run the program, you likely don’t have Java installed – Google search “Java JRE” and download. To run the program, simply double click on the executable file in the “dist” folder of CSV_To_KML called “CSV_To_KML.jar” To run the program and see the debugging output, run the program from the command line. From the Windows command line use the following command “java -jar CSV_To_KML.jar”. You will need to be in the directory with the JAR file or instead use the command “java –jar <location>\CSV_To_KML.jar” where <location> is the location of the jar file (ex: C:\temp\CSV_To_KML\dist) If the program seems to hang or freeze when you click “convert” it is due to an error in your input. Check that your input formatting matches that of the formatting guides. Also, check your input CSV with a text editor instead of Excel to see if you notice anything troublesome (like extra commas). Line Data Specification Austin Lyons Senior Design Project Dec09-02 File Type Line data must be saved as a .csv file. Format Line data must have at least 6 columns of data in this order: Start City End City Start Latitude Start Longitude End Latitude End Longitude First Line The first line of the spreadsheet containing line data must have to following: Start City End City Start Latitude Start Longitude End Latitude End Longitude The program knows the input file has line data by checking the contents of the first line. It is case insensitive. Dec09-02 Final Report Start City Put the name of the city in which the line will start. If the line does not need to be named, leave this space blank. End City Put the name of the city in which the line will end. If the line does not need to be named, leave this space blank. Start Latitude Put the latitude of the starting city here. This entry cannot be left blank and must be a number between -180 and 180. Start Longitude Put the longitude of the starting city here. This entry cannot be left blank and must be a number between -180 and 180. End Latitude Put the latitude of the city where the line ends here. This entry cannot be left blank and must be a number between -180 and 180. End Longitude Put the longitude of the city where the line ends here. This entry cannot be left blank and must be a number between -180 and 180. Additional Info Any data put in column 7, 8, etc will be concatenated into a single string and put in the <description> KML tag. Examples Acceptable START CITY AGENCY AGENCY ALLEMAN END CITY UNION VILLE FAIRFIELD ELKHART START START END END LATITUDE LONGITUDE LATITUDE LONGITUDE OWNERSHIP 40.99547 -92.3041 40.83305 -92.6867 40.99547 -92.3041 41.01774 -91.95 41.80488 -93.6048 41.79212 -93.526 CIPCO Unacceptable Missing Header: AGENCY AGENCY ALLEMAN UNION VILLE FAIRFIELD ELKHART 40.99547 40.99547 41.80488 -92.3041 -92.3041 -93.6048 40.83305 41.01774 41.79212 -92.6867 -91.95 -93.526 Dec09-02 Final Report This example needs the first line to contain “Start City, End City” etc. Missing Coordinate: START CITY AGENCY AGENCY ALLEMAN END CITY UNION VILLE FAIRFIELD ELKHART START LATITUDE START END END LONGITUDE LATITUDE LONGITUDE OWNERSHIP -92.3041 40.83305 -92.6867 40.99547 -92.3041 41.01774 -91.95 41.80488 -93.6048 41.79212 -93.526 CIPCO This example is missing a coordinate. The entire line will be ignored and the program will continue with the next line. An error message will be written to the error log to note the incorrectly formatted data. Dec09-02 Final Report Point Data Specification Austin Lyons Senior Design Project Dec09-02 File Type Point data must be saved as a .csv file. Format Point data must have at least 3 columns of data in this order: Location Latitude Longitude First Point The first Point of the spreadsheet containing point data must have to following: Location Latitude Longitude The program knows the input file has point data by checking the contents of the first line. It is case insensitive. Location Put the name of the city or location of the point Latitude Put the latitude of the point here. This entry cannot be left blank and must be a number between -180 and 180. Longitude Put the longitude of the point here. This entry cannot be left blank and must be a number between -180 and 180. Additional Info Any data put in column 4, 5, etc will be concatenated into a single string and put in the <description> KML tag. Examples Acceptable LOCATION FAIRFIELD AGENCY START START LATITUDE LONGITUDE POPULATION 41.01774 -91.95 9,459 40.99547 -92.3041 622 Dec09-02 Final Report Unacceptable Missing Header: FAIRFIELD AGENCY 41.01774 40.99547 -91.95 9,459 -92.3041 622 This example needs the first Point to contain “Location, Latitude,Longitude” etc. Missing Coordinate: LOCATION FAIRFIELD AGENCY START START LATITUDE LONGITUDE POPULATION 41.01774 9,459 40.99547 -92.3041 622 This example is missing a coordinate. The point will be ignored and the program will continue with the next point. An error message will be written to the error log to note the incorrectly formatted data. Dec09-02 Final Report Data Conversion Program – Test Descriptions Test Description Check to see that file is a .csv Test File Test001.txt Line Data Check that file containing line data will be processed when “line” selected and that output is as expected Test002.csv Check that file containing point data will not be processed when “line” selected Test003.csv Allow empty “Start City” (no name for start city) Test004.csv Allow empty “End City” (no name for end city) Test005.csv Throw out element if “Start Latitude” is missing or is not a number between -180 and 180 – print error to log Test006.csv Throw out element if “Start Longitude” is missing or is not a number between -180 and 180 – print error to log Test007.csv Throw out element if “End Latitude” is missing or is not a number between -180 and 180 – print error to log Test008.csv Throw out element if “End Longitude” is missing or is not a number between -180 and 180 – print error to log Test009.csv Check that additional data is appended in the “description” section Test010.csv Point Data Check that file containing point data will be processed when “point” selected and that output is as expected Test011.csv Check that file containing line data will not be processed when “point” selected Test012.csv Allow empty “Location” (no name for start city) Test013.csv Throw out element if “Latitude” is missing or is not a number between -180 and 180 – print error to log Test014.csv Throw out element if “Longitude” is missing or is not a number between -180 and 180 – print error to log Test015.csv Check that additional data is appended in the “description” section Test016.csv Dec09-02 Final Report Appendix II: Additional Documentation – Analysis Muhammad Rahim For any help with WASP-IV, please contact Muhammad Rahim at rahimakif at gmail dot com We were not able to complete the analysis component due to time contraints; however, we were able to study the software enough to give some help to future senior design students that may finish what we started. This additional information is intended to give a general outline of the other main routines (CONGEN, MERSIM, and DYNPRO). CONGEN (CONFIGURATION GENERATION) This module is used to produce the states or configurations of the expanded system which respect certain constraints for each year of study. For this purpose CONGEN uses some information provided by the output files generated by preceding WASP modules and some other information supplied as input data to this module. From output files of other WASP modules, CONGEN reads the load information on the load description file (IF12); characteristics of the existing plants in the year considered from the fixed system file (IF10) and those of the expansion candidates from the variable alternative file (IF11). From the input data, it reads: the yearly constraints on permitted number of sets of each expansion candidate, permissible range for system reserve, the option for LOLP calculation, and if applicable, the maximum allowed value for the period and annual LOLP. Using all this information, CONGEN determines the possible combinations of VARSYS plant additions (i.e. system expansion configurations); calculates the associated capacity (including the fixed system plus VARSYS plants added by the configuration and merging all VARSYS hydro projects of a given type into the composite hydro plant of the same type existing in the fixed system); and finally, it checks if the configuration satisfies the specified constraints while being accessible from configurations already accepted for previous years. Any configuration satisfying these requirements is considered as accepted for the given year and written onto the configuration generator output file (IF13: EXPANALT) and in the printout for the run. MERSIM (MERGE and SIMULATE) This module carries out the simulation of system operation for each expansion configuration proposed by the configuration generator program. These simulations are performed for each period and hydrocondition, taking into account plant forced outages of thermal units. Maintenance requirements of these units are also considered and for this purpose, MERSIM prepares a maintenance schedule for the units included in the configuration and based on system load and plant characteristics. The primary results of the simulations are the expected annual operating costs and LOLP, and the annual energy not served per hydrocondition, associated with each configuration. The expected values of annual operating costs and LOLP are calculated considering the respective values determined for the periods of the year weighted by the hydrocondition probabilities. All this information will be necessary for the economic comparison of alternative expansion plans to be carried out by DYNPRO. Dec09-02 Final Report Execution of the program requires a considerable amount of input information which is read from the output files generated by the preceding modules or by previous MERSIM runs, while some instructions are read directly from the input data for the run. From the output files of other WASP modules or of previous MERSIM runs, it reads: the yearly configurations contained in the configuration generator file (IF13); the information about simulations already performed in previous runs which is stored in the "old" simulation file (IF16: SIMULOLD); yearly load characteristics from the LOADSY file; the plant data from the fixed system file (IF10) and the variable alternative file (IF11). From the input data, it reads: information on plant loading order, the number of Fourier coefficients for LDC approximation to be used in the simulations, and any changes in the maximum amount of fuel that is associated to thermal fuel types with limitations. For each year of study MERSIM compares the configurations on the CONGEN file with those on the SIMULOLD file and for identical configuration on both files, it simply copies the results of previous simulation runs into the new simulation file (IF15: SIMULNEW). Onto this file MERSIM also copies the results of simulations for any configuration included in the SIMULOLD file and not considered by the current CONGEN file. If a configuration on the CONGEN file is not found in SIMULOLD, the program simulates it and writes the results on the new simulation file. DYNPRO (DYNAMIC PROGRAMMING OPTIMIZATION) The dynamic programming optimization technique used by this module carries out the economic comparison of the alternative system expansion plans, allowed by the yearly configurations contained in the current configuration generator file, and selects among these plans, the one having the least cost while respecting certain specified restrictions. Some economic data required for this comparison and optimization are specified as part of the input data of DYNPRO, while the rest of the information needed is read from the output files generated by preceding WASP modules. From other WASP module files, DYNPRO reads: the candidate plant description on the variable system description file (IF11); the yearly expansion configurations of the system contained in the configuration generator file (IF13); the system operating costs, reliability (LOLP) and amount of energy not served (per hydrocondition) associated with each configuration from the (new) simulation file (IF15) created by the latest MERSIM run. From the input data, DYNPRO reads: the general economic information on base years for present worth (discounting) and cost escalation calculations and the applicable discount rates and escalation ratios, shadow exchange rate affecting foreign costs, coefficients for calculating the cost of energy not served, etc.; the expansion candidate economic data on investment costs, plant economic life, etc.; and any additional constraints on system reliability and schedule of plant additions which are to be respected by the expansion plans examined. Using all the above data, DYNPRO calculates investment cost and energy not served cost associated with each configuration; performs cost escalation and cost discounting calculations of these expenditures and Dec09-02 Final Report of the respective operating costs; calculates the objective function (total cost of expansion) of each state combining all costs while carrying out the sub-optimum search for each state in each year. Finally, it finds the desired number of optimum and near optimum solutions at the horizon of the study and traces backward the configurations in these solutions for intermediate years while identifying which tunnel constraints used in CONGEN have restricted the solutions. Appendix III: Source Code GUI.java // ------------------------// Data Conversion GUI // Senior Design DEC0902 // By Austin Lyons // ------------------------- package src; import java.io.*; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; /** * This GUI is used to convert .csv files to .kml files * It accepts two types of input to represent point data * and network data. See the accompanying documentation * for information on how to correctly format the data. * * @author Austin Lyons * **/ public class GUI extends javax.swing.JFrame { Dec09-02 Final Report private String m_lineColor = "0000ff"; //default to red private int m_lineWidth = 3; //default to 3 private String m_iconHref= // default to pushpin "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"; private boolean debug = true; // enable output commenting ArrayList<Line> arrLines; ArrayList<Point> arrPoints; /** Creates the GUI and initializes it's components */ public GUI() { initComponents(); } /** * This method is called from within the constructor to * initialize the form. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jLabel1 = new javax.swing.JLabel(); convert_button = new javax.swing.JButton(); locationOfCSV = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); colorOfLines = new javax.swing.JComboBox(); lineWidth = new javax.swing.JLabel(); lineWidthBox = new javax.swing.JComboBox(); jLabel4 = new javax.swing.JLabel(); mapType = new javax.swing.JComboBox(); jLabel5 = new javax.swing.JLabel(); Dec09-02 Final Report iconBox = new javax.swing.JComboBox(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); About = new javax.swing.JMenuItem(); close = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setResizable(false); jLabel1.setFont(new java.awt.Font("Tahoma", 0, 14)); jLabel1.setText("Visualization Data Converter"); convert_button.setText("Convert!"); convert_button.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { convert_buttonActionPerformed(evt); } }); locationOfCSV.setText("C:\\data\\test.csv"); locationOfCSV.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { locationOfCSV(evt); } }); jLabel2.setText("Location of .csv file:"); jLabel3.setText("Line or Point Color"); colorOfLines.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Black", "Red", "Green", "Blue", "Yellow", "Purple", "Pink" })); Dec09-02 Final Report colorOfLines.setSelectedIndex(1); colorOfLines.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { colorOfLinesActionPerformed(evt); } }); lineWidth.setText("Line Width"); lineWidthBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "3", "4", "5", "6" })); lineWidthBox.setSelectedIndex(2); lineWidthBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { lineWidthBoxActionPerformed(evt); } }); jLabel4.setText("Map Type"); mapType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Lines", "Points" })); mapType.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mapTypeActionPerformed(evt); } }); jLabel5.setText("Point Icon"); iconBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Pushpin", "Paddle", "Dot", "Circle", "Square", "Star" })); iconBox.setEnabled(false); iconBox.addActionListener(new java.awt.event.ActionListener() { Dec09-02 Final Report public void actionPerformed(java.awt.event.ActionEvent evt) { iconBoxActionPerformed(evt); } }); jMenu1.setText("File"); jMenu1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { close(evt); } }); About.setText("About"); About.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { AboutActionPerformed(evt); } }); jMenu1.add(About); close.setText("Close"); close.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { close(evt); } }); jMenu1.add(close); jMenuBar1.add(jMenu1); setJMenuBar(jMenuBar1); Dec09-02 Final Report javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(69, 69, 69) .addComponent(jLabel1) .addContainerGap(63, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(locationOfCSV, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 282, Short.MAX_VALUE) .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)) .addContainerGap()) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(lineWidth) .addContainerGap(242, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addGap(110, 110, 110) .addComponent(convert_button) .addContainerGap(117, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE) .addGap(4, 4, 4)) .addGroup(layout.createSequentialGroup() Dec09-02 Final Report .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) .addGap(17, 17, 17)) .addGroup(layout.createSequentialGroup() .addComponent(jLabel5) .addGap(60, 60, 60))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createSequentialGroup() .addComponent(iconBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(mapType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lineWidthBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(colorOfLines, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGap(129, 129, 129)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(locationOfCSV, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) Dec09-02 Final Report .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE) .addComponent(mapType, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE) .addComponent(colorOfLines, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(14, 14, 14) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(lineWidth, javax.swing.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE) .addComponent(lineWidthBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel5) .addComponent(iconBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(37, 37, 37) .addComponent(convert_button) .addGap(26, 26, 26)) ); pack(); }// </editor-fold> /** * When the 'convert' button is pushed, this function is called. * It checks whether 'point' or 'line' was selected * in the GUI and then tries to parse the specified input file * If it is successful in reading the input file, it prints * the contents in KML form */ private void convert_buttonActionPerformed(java.awt.event.ActionEvent evt) { Dec09-02 Final Report boolean parseWorked = false; int i = mapType.getSelectedIndex(); if(i == 0) parseWorked = parseLinesCSV(); else parseWorked = parsePointsCSV(); if(parseWorked) { if(i == 0) outputLineKML(); else outputPointKML(); } } private void locationOfCSV(java.awt.event.ActionEvent evt) { } /** * This function is called when the dropdown 'Line or Point color' * box is manipulated. It stores the corresponding KML color in * a string for later use. */ private void colorOfLinesActionPerformed(java.awt.event.ActionEvent evt) { int i = colorOfLines.getSelectedIndex(); switch(i) { case 0: // black m_lineColor = "0f0f0f"; break; case 1: // red Dec09-02 Final Report m_lineColor = "0000ff"; break; case 2: // green m_lineColor = "00ff00"; break; case 3: // blue m_lineColor = "ff0000"; break; case 4: // yellow m_lineColor = "00ffff"; break; case 5: // purple lines, orange points m_lineColor = "c53668"; break; case 6: // pink lines, brown points m_lineColor = "b1a3ff"; break; } if(debug)System.out.println("** Changed color ** " + m_lineColor); } /** * This function is called when File->Close chosen */ private void close(java.awt.event.ActionEvent evt) { System.exit(1); } /** * This function is called when the 'Line Width' dropdown is manipulated */ Dec09-02 Final Report private void lineWidthBoxActionPerformed(java.awt.event.ActionEvent evt) { // index ranges from 0 to n, line width from 1 to n+1 m_lineWidth = lineWidthBox.getSelectedIndex()+1; if(debug)System.out.println("!! Changed line width !! " + m_lineWidth); } /** * This function is called when the 'Map Type' drop down is selected * It enables and disables certain features based on the choice of * point or line data. */ private void mapTypeActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: if(debug)System.out.println("Changed map type " + mapType.getSelectedIndex()); int i = mapType.getSelectedIndex(); if(i == 0) { lineWidthBox.setEnabled(true); iconBox.setEnabled(false); } else { lineWidthBox.setEnabled(false); iconBox.setEnabled(true); } } /** * This function is called when File->About is chosen * It makes a pop up box appear with information about the program */ private void AboutActionPerformed(java.awt.event.ActionEvent evt) { Dec09-02 Final Report JOptionPane.showMessageDialog(null, "This program was created by Austin Lyons \n" + "for EE 491/492 Senior Design team DEC0902 ","About", JOptionPane.PLAIN_MESSAGE); } /** * This function is called when 'Point Icon' dropdown is selected * It stores the URL of an the corresponding in a string for later * use in printing KML */ private void iconBoxActionPerformed(java.awt.event.ActionEvent evt) { int i = iconBox.getSelectedIndex(); switch(i) { case 0: // Pushpin m_iconHref = "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"; break; case 1: // Paddle m_iconHref = "http://maps.google.com/mapfiles/kml/paddle/wht-blank.png"; break; case 2: // Dot m_iconHref = "http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png"; break; case 3: // Circle m_iconHref = "http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png"; break; case 4: // Square m_iconHref = "http://maps.google.com/mapfiles/kml/shapes/placemark_square.png"; break; case 5: // Star m_iconHref = "http://maps.google.com/mapfiles/kml/shapes/star.png"; break; Dec09-02 Final Report } if(debug)System.out.println("** Changed icon ** "); } /** * This is the main function * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new GUI().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JMenuItem About; private javax.swing.JMenuItem close; private javax.swing.JComboBox colorOfLines; private javax.swing.JButton convert_button; private javax.swing.JComboBox iconBox; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JMenu jMenu1; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JLabel lineWidth; private javax.swing.JComboBox lineWidthBox; private javax.swing.JTextField locationOfCSV; Dec09-02 Final Report private javax.swing.JComboBox mapType; // End of variables declaration /** * This function checks if the input string, s, is a coordinate. * It tries to convert the string to a floating point number. * If successful, it then checks if the number is between -180 and 180 * @param String s * @return true if s is a coordinate or false otherwise */ private boolean isCoordinate(String s) { boolean yes = false; boolean done = false; float i = 0; try { i = Float.parseFloat(s); } catch(NumberFormatException e) { if(debug)System.out.println(e); done = true; } if(!done && (i <= 180) && (i >= -180)) yes = true; return yes; } /** Dec09-02 Final Report * This function parses comma separated files (.csv) containing * point data. The data must be formatted according to the accompanying * specifications. If any error occurs, a pop-up box will inform the user * of the error and the parsing will stop. The correctly formatted data is * stored in an arrayList containing point objects. * * @return true if input file is a .csv containing point data * and is parsed without error */ private boolean parsePointsCSV() { boolean usedErrorLog = false; // open input String in = locationOfCSV.getText(); System.out.println(in); // first check to see that file is a .csv if(!in.endsWith(".csv")) { System.out.println("File not a .csv: " + in); JOptionPane.showMessageDialog(null, "Specified file was not a .csv file","error", JOptionPane.ERROR_MESSAGE); return false; } // it is a .csv, so try to open it BufferedReader iS = null; try { iS = new BufferedReader(new FileReader(in)); } catch (FileNotFoundException ex) { System.out.println("Couldn't open the file " + in); JOptionPane.showMessageDialog(null, "Couldn't open the file " + in,"error", JOptionPane.ERROR_MESSAGE); Dec09-02 Final Report return false; } BufferedWriter bW = null; String out = in+ "_errorLog.txt"; try { bW = new BufferedWriter(new FileWriter(out)); } catch (IOException ex) { System.out.println("Couldn't write to the file " + out +"\n"+ex); JOptionPane.showMessageDialog(null, "Couldn't open the file " + out,"error", JOptionPane.ERROR_MESSAGE); return false; } arrPoints = new ArrayList<Point>(); String iLine = null; // get first line (Location, Latitude, Longitude) try { iLine = iS.readLine(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); return false; } // check to make sure it's point data if(!checkPointData(iLine)) { JOptionPane.showMessageDialog(null, "Input file does not contain point data.\n" + "Check input file and try again.","error", JOptionPane.ERROR_MESSAGE); return false; } Dec09-02 Final Report // get the first line of data try { iLine = iS.readLine(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); return false; } // parse the data; while ((iLine != null) && (!iLine.isEmpty())) { Point temp = new Point(); String name = ""; boolean done = false; boolean bad = false; int i = 0; while (!done && !iLine.isEmpty()) { int index = iLine.indexOf(','); // if there is still data left (col 1, col 2, col 3) // or if there aren't any more commas but still data if (index != -1 || i == 2 || i == 3) { String t; if(index != -1 && i != 3) t = iLine.substring(0, index); else t = iLine; switch (i) { case 0: Dec09-02 Final Report temp.setName(t); i++; break; case 1: if (isCoordinate(t)) { temp.setLat(t); } else bad = true; i++; break; case 2: if (isCoordinate(t)) { temp.setLong(t); temp.setDescrip(temp.getName()); // if no description, use name temp.setComplete(); if(index == -1) done = true; } else bad = true; i++; break; case 3: // set everything in columns 4+ into the description temp.setDescrip(t); done = true; break; default: Dec09-02 Final Report break; } } iLine = iLine.substring(index + 1); } // only add it if it's a complete line ie has all coordinates if(temp.isComplete() && !bad) { if (debug) { System.out.println(temp.getName() + " " + temp.getLat() + " " + temp.getLong()); } // insert point into list arrPoints.add(temp); } else { // else write to error log that an improperly formatted row of data was skipped try { if(!usedErrorLog) // only update this variable once usedErrorLog = true; bW.write("Not a valid point: "); bW.write(temp.getName()+"\n"); bW.write("\tLat: " + temp.getLat()+"\n"); bW.write("\tLon: " + temp.getLong()+"\n"); bW.write("\tDescrip: " + temp.getDescrip()+"\n"); } catch(IOException ex) { Dec09-02 Final Report Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } } try { iLine = iS.readLine(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); return false; } } try { iS.close(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } try { bW.close(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } if(usedErrorLog) JOptionPane.showMessageDialog(null, "One or more elements were incorrectly" + " formatted.\nCheck error log for details.","error", JOptionPane.ERROR_MESSAGE); return true; } /** * This function parses comma separated files (.csv) containing * line data. The data must be formatted according to the accompanying * specifications. If any error occurs, a pop-up box will inform the user Dec09-02 Final Report * of the error and the parsing will stop. The correctly formatted data is * stored in an arrayList containing line objects. * * @return true if input file is a .csv containing line data * and is parsed without error */ private boolean parseLinesCSV() { boolean usedErrorLog = false; // open input String in = locationOfCSV.getText(); System.out.println(in); // first check to see that file is a .csv if(!in.endsWith(".csv")) { System.out.println("File not a .csv: " + in); JOptionPane.showMessageDialog(null, "Specified file is not a .csv file","error", JOptionPane.ERROR_MESSAGE); return false; } // it's a .csv so try to open the file BufferedReader iS = null; try { iS = new BufferedReader(new FileReader(in)); } catch (FileNotFoundException ex) { System.out.println("Couldn't open the file " + in); JOptionPane.showMessageDialog(null, "Couldn't open the file " + in,"error", JOptionPane.ERROR_MESSAGE); return false; } Dec09-02 Final Report // create an error log BufferedWriter bW = null; String out = in+ "_errorLog.txt"; try { bW = new BufferedWriter(new FileWriter(out)); } catch (IOException ex) { System.out.println("Couldn't write to the file " + out +"\n"+ex); JOptionPane.showMessageDialog(null, "Couldn't open the file " + out,"error", JOptionPane.ERROR_MESSAGE); return false; } arrLines = new ArrayList<Line>(); String iLine = null; // get first line (Start City, End City, Start Latitude, Start Longitude, End Latitude, End Longitude) try { iLine = iS.readLine(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); return false; } // check first line to see if it's line data if(!checkLineData(iLine)) { JOptionPane.showMessageDialog(null, "Input file does not contain line data.\n" + "Check input file and try again.","error", JOptionPane.ERROR_MESSAGE); return false; } // get the first line of data Dec09-02 Final Report try { iLine = iS.readLine(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); return false; } // parse the line of data while ((iLine != null) && (!iLine.isEmpty())) { Line temp = new Line(); String name = ""; boolean done = false; boolean bad = false; int i = 0; while (!done && !iLine.isEmpty()) { int index = iLine.indexOf(','); // if line has more data (col 1, col 2, col 3, col 4, ..... ) if ((index != -1)||(i == 5)||(i == 6)) { String t; if((i == 5 && index == -1) || i == 6 ) t = iLine; else t = iLine.substring(0, index); switch (i) { case 0: if(t.isEmpty()) name = ""; else name = t; Dec09-02 Final Report i++; break; case 1: if(!name.isEmpty() && !t.isEmpty()) name = name + " to " + t; else name = name + t; temp.setName(name); i++; break; case 2: if (isCoordinate(t)) temp.setStartLat(t); else bad = true; i++; break; case 3: if (isCoordinate(t)) temp.setStartLong(t); else bad = true; i++; break; case 4: if (isCoordinate(t)) temp.setEndLat(t); Dec09-02 Final Report else bad = true; i++; break; case 5: if (isCoordinate(t)) { temp.setEndLong(t); } else bad = true; if(!bad) { temp.setComplete(); temp.setDescrip(temp.getName()); } else { try { if(!usedErrorLog) usedErrorLog = true; bW.write("Not a valid line: "); bW.write(temp.getName()+"\n"); bW.write("\tStart Lat: "+temp.getStartLat()+"\n"); bW.write("\tStart Long: "+temp.getStartLong()+"\n"); bW.write("\tEnd Lat: "+temp.getEndLat()+ "\n"); bW.write("\tEnd Long: "+temp.getEndLong()+"\n"); } catch(IOException ex) { Dec09-02 Final Report Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } } i++; break; case 6: temp.setDescrip(t); done = true; break; default: break; } } if(index != -1) iLine = iLine.substring(index + 1); else done = true; } // only add it if it's a complete line ie has all coordinates if(temp.isComplete()) { if (debug) { System.out.println(temp.getName() + " " + temp.getStartLat() + " " + temp.getStartLong() + " " + temp.getEndLat() + " " + temp.getEndLong()); } Dec09-02 Final Report // insert point into list arrLines.add(temp); } try { iLine = iS.readLine(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); return false; } } try { iS.close(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } try { bW.close(); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); } if(usedErrorLog) JOptionPane.showMessageDialog(null, "One or more elements were incorrectly" + " formatted.\nCheck error log for details.","error", JOptionPane.ERROR_MESSAGE); return true; } /** * This function uses the stored line data to print a KML file. * The KML file is simply the name of the input file + .kml * example: input.csv -> input.kml Dec09-02 Final Report */ private void outputLineKML() { String in = locationOfCSV.getText(); String output = in.substring(0, in.indexOf(".csv")) + ".kml"; if(debug)System.out.println(output); PrintWriter oS = null; try { oS = new PrintWriter(new FileWriter(output)); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); } String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" + "<Document>\n" + "\t<name>" + output + "</name>\n" + "\t<open>1</open>\n" + "\t<Style id=\"s1\">\n" + "\t\t<LineStyle>\n" + "\t\t\t<color>ff" + m_lineColor + "</color>\n" + "\t\t\t<width>" + m_lineWidth + "</width>\n" + "\t\t\t<Icon><href>" + m_iconHref + "</href></Icon>\n" + "\t\t</LineStyle>\n" + "\t\t</Style>\n"; if(debug)System.out.print(s); oS.print(s); for(int i = 0; i < arrLines.size(); i++){ Line l = arrLines.get(i); String t = "\t<Placemark>\n" + "\t\t<name>" + l.getName() + "</name>\n" + Dec09-02 Final Report "\t\t<description>" + l.getDescrip() + "</description>\n" + "\t\t<styleUrl>#s1</styleUrl>\n" + "\t\t<LineString>\n" + "\t\t\t<extrude>1</extrude>\n" + "\t\t\t<tessellate>1</tessellate>\n" + "\t\t\t<coordinates>\n" + "\t\t\t\t" + l.getStartLong() + ", " + l.getStartLat() + ", 0, " + l.getEndLong() + ", " + l.getEndLat() + ", 0\n" + "\t\t\t</coordinates>\n" + "\t\t</LineString>\n" + "\t</Placemark>\n"; oS.print(t); if(debug)System.out.print(t); } String e ="</Document>\n</kml>"; oS.print(e); if(debug)System.out.print(e); oS.close(); JOptionPane.showMessageDialog(null,"CSV to KML conversion successful!","Success!", JOptionPane.INFORMATION_MESSAGE); } /** * This function uses the stored point data to print a KML file. * The KML file is simply the name of the input file + .kml * example: input.csv -> input.kml */ private void outputPointKML() { String in = locationOfCSV.getText(); Dec09-02 Final Report String output = in.substring(0, in.indexOf(".csv")) + ".kml"; if(debug)System.out.println(output); PrintWriter oS = null; try { oS = new PrintWriter(new FileWriter(output)); } catch (IOException ex) { Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, ex.getMessage(),"error", JOptionPane.ERROR_MESSAGE); } String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" + "<Document>\n" + "\t<name>" + output + "</name>\n" + "\t<Style id=\"s1\">\n" + "\t\t<IconStyle>\n"+ "\t\t\t<color>ff"+m_lineColor+"</color>\n"+ "\t\t\t<Icon><href>" + m_iconHref + "</href></Icon>\n" + "\t\t</IconStyle>\n"+ "\t</Style>\n"; if(debug)System.out.print(s); oS.print(s); for(int i = 0; i < arrPoints.size(); i++){ Point p = arrPoints.get(i); String t = "\t<Placemark>\n" + "\t\t<name>" + p.getName() + "</name>\n" + "\t\t<styleUrl>#s1</styleUrl>\n" + "\t\t<description>" + p.getDescrip() + "</description>\n" + "\t\t<Point>\n" + "\t\t\t<coordinates>" + p.getLong() + ", " + p.getLat() + ", 0</coordinates>\n" + "\t\t</Point>\n" + Dec09-02 Final Report "\t</Placemark>\n"; oS.print(t); if(debug)System.out.print(t); } String e ="</Document>\n</kml>"; oS.print(e); if(debug)System.out.print(e); oS.close(); JOptionPane.showMessageDialog(null,"CSV to KML conversion successful!","Success!", JOptionPane.INFORMATION_MESSAGE); } /** * This function checks that line data starts with "Start City" * This is how it is determined that the input .csv file contains line data * It ignores trailing whitespace and is case insensitive * @param in - string to be checked * @return true if in contains "Start City" */ private boolean checkLineData(String in){ boolean isLine = false; int index = in.indexOf(','); if(index != -1) { String t = in.substring(0,index); t= t.trim(); if(t.compareToIgnoreCase("Start City")==0) { isLine = true; if(debug)System.out.println("Input file contains line data."); } } Dec09-02 Final Report return isLine; } /** * This function checks that line data starts with "Location" * This is how it is determined that the input .csv file contains line data * It ignores trailing whitespace and is case insensitive * @param in - string to be checked * @return true if in contains "Start City" */ private boolean checkPointData(String in){ boolean isLine = false; int index = in.indexOf(','); if(index != -1) { String t = in.substring(0,index); t= t.trim(); if(t.compareToIgnoreCase("Location")==0) { isLine = true; if(debug)System.out.println("Input file contains point data."); } } return isLine; } } Dec09-02 Final Report Line.java // ------------------------// Line.java // Senior Design DEC0902 // By Austin Lyons // ------------------------package src; /** * Line.java is used to created a Line object and store * data about a line. It was written for use by a data * conversion program that converts a .CSV containing * line data into a .KML. * @author Austin Lyons */ public class Line { private String m_name; private String m_start_long; private String m_start_lat; private String m_end_long; private String m_end_lat; private String m_descrip; private boolean c; /** * This is the Line object constructor. It sets all variables to null. */ public Line(){ m_name = m_start_long = m_start_lat = m_end_long = m_end_lat = m_descrip = ""; c = false; } Dec09-02 Final Report /** * getName gets the name of the line * @return name of the line as a String */ public String getName(){ return m_name; } /** * getStartLongitude returns the starting longitude of the line * @return starting longitude of the line as a String */ public String getStartLong(){ return m_start_long; } /** * getStartLat returns the starting latitude of the line * @return starting latitude of the line as a String */ public String getStartLat(){ return m_start_lat; } /** * getEndLong returns the ending longitude of the line * @return ending longitude of the line as a String */ public String getEndLong(){ return m_end_long; } /** * getEndLat returns the ending latitude of the line * @return ending latitude of the line as a String */ public String getEndLat(){ return m_end_lat; } /** * getDescrip returns the description of the line Dec09-02 Final Report * @return description of the line as a String */ public String getDescrip(){ return m_descrip; } /** * If the line has all four coordinates successfully set, * it is considered "complete" * @return true if all four coordinates were successfully set */ public boolean isComplete(){return c;} /** * setName is used to set the name of the line * @param n - input string with the name to set */ public void setName(String n){m_name=n;} /** * setName is used to set the name of the line * sets name as "n to m" ie "Ames to Des Moines" * @param n - start city * @param m - end city */ public void setName(String n, String m){m_name = n + " to " + m;} /** * setStartLong is used to set the starting longitude of the line * @param slo - input string with the starting longitude */ public void setStartLong(String slo){ m_start_long = slo; } /** Dec09-02 Final Report * setStartLat is used to set the starting latitude of the line * @param sla - input string with the starting latitude */ public void setStartLat(String sla){ m_start_lat = sla; } /** * setEndLong is used to set the ending longitude of the line * @param elo - input string with the ending longitude */ public void setEndLong(String elo){ m_end_long = elo; } /** * setEndLat is used to set the ending latitude of the line * @param ela - input string with the ending latitude */ public void setEndLat(String ela){ m_end_lat = ela; } /** * setDescrip is used to set the description of the line * @param d - input string with the description of the line */ public void setDescrip(String d){m_descrip=d;} /** * setComplete is used to declare the line "complete" */ public void setComplete(){c = true;} } Dec09-02 Final Report Point.java // ------------------------// Point.java // Senior Design DEC0902 // By Austin Lyons // ------------------------package src; /** * Point.java is used to created a Point object and store * data about a point. It was written for use by a data * conversion program that converts a .CSV containing * point data into a .KML. * @author Austin Lyons */ public class Point { private String m_name; private String m_long; private String m_lat; private String m_descrip; private boolean c; /** * This constructor creates a Point object and sets all internal variables * to null */ public Point(){ m_name = m_long = m_lat = m_descrip = ""; c = false; } /** Dec09-02 Final Report * getName returns the name of the point as a String * @return the name of the point as a String */ public String getName(){ return m_name; } /** * getLong returns the longitude of the point as a String * @return the longitude of the point as a String */ public String getLong(){ return m_long; } /** * getLat returns the latitude of the point as a String * @return the latitude of the point as a String */ public String getLat(){ return m_lat; } /** * getDescrip returns the description of the point as a String * @return the description of the point as a String */ public String getDescrip(){ return m_descrip; } /** * isComplete returns whether or not the poin is "complete" * The point is considered "complete" if it's coordinates * were successfully set * @return true if the point is "complete" */ public boolean isComplete(){return c;} /** Dec09-02 Final Report * setName sets the name of the point * @param n - name of the point */ public void setName(String n){m_name=n;} /** * setLong sets the longitude of the point * @param slo - longitude of point as a String */ public void setLong(String slo){ m_long = slo; } /** * setLat sets the latitude of the point * @param sla - latitude of point as a String */ public void setLat(String sla){ m_lat = sla; } /** * setDescrip sets the description of the point * @param d - description of point */ public void setDescrip(String d){m_descrip=d;} /** * setComplete declares the point "complete" * The point is considered "complete" if both it's * latitude and longitude were successfully set */ public void setComplete(){c = true;} } Dec09-02 Final Report Website Source Code <!-Google Earth + Energy Infrastructure website Austin Lyons Senior Design Dec09-02 http://seniord.ece.iastate.edu/dec0902/ge/index.html --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Visualization of Iowa Energy Infrastructure</title> <script src="http://www.google.com/jsapi?key=ABQIAAAANHwzuutjukqdPvWi10NDTBRO9d4XlPs2kP5zcEGJSZiDgzzcuxQ_ qKVrf0Ftr4s3TQ108WrBn7ENJQ"></script> <script type="text/javascript"> function addSampleButton(caption, clickHandler) { var btn = document.createElement('input'); btn.type = 'button'; btn.value = caption; if (btn.attachEvent) btn.attachEvent('onclick', clickHandler); else btn.addEventListener('click', clickHandler, false); // add the button to the Sample UI document.getElementById('sample-ui').appendChild(btn); Dec09-02 Final Report } function addSampleUIHtml(html) { document.getElementById('sample-ui').innerHTML += html; } </script> <script type="text/javascript"> var ge; // store the object loaded for the given file... initially none of the objects // are loaded, so initialize these to null var currentKmlObjects = { '345': null, '230': null, '161': null, '115': null, 'turbines': null, 'turbines_man':null, 'turbines_con':null, 'industrialenergy':null, 'interstatelightpower':null, 'midamerican': null, 'otherfacilities':null, 'e85':null, 'igaslines':null, 'hliquid':null, 'cavern':null }; google.load("earth", "1"); function init() { Dec09-02 Final Report google.earth.createInstance('map3d', initCallback, failureCallback); addSampleUIHtml( '<h2>Energy Infrastructure of Iowa</h2>' + '<table width="800px" style="font-size:11px;">'+ '<tr><td width="90px" style="vertical-align:top;"><input type="checkbox" id="kml-345check" onclick="toggleKml(\'345\');"/><label for="kml-345-check">345 kV Lines</label><br/>' + '<input type="checkbox" id="kml-230-check" onclick="toggleKml(\'230\');"/><label for="kml-230-check">230 kV Lines</label><br/>' + '<input type="checkbox" id="kml-161-check" onclick="toggleKml(\'161\');"/><label for="kml-161-check">161 kV Lines</label><br/>'+ '<input type="checkbox" id="kml-115-check" onclick="toggleKml(\'115\');"/><label for="kml-115-check">115 kV Lines</label><br/>'+ '<td width="180px" style="vertical-align:top;">'+ '<input type="checkbox" id="kml-e85-check" onclick="toggleKml(\'e85\');"/><label for="kml-e85-check">E85 refueling locations</label><br/>'+ '<input type="checkbox" id="kml-turbines-check" onclick="toggleKml(\'turbines\');"/><label for="kml-turbines-check">Operating Wind Turbines by County</label><br/>'+ '<input type="checkbox" id="kml-turbines_con-check" onclick="toggleKml(\'turbines_con\');"/><label for="kml-turbines_con-check">Wind Turbines Planned or<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Under Construction by County</label><br/>'+ '<input type="checkbox" id="kml-turbines_man-check" onclick="toggleKml(\'turbines_man\');"/><label for="kml-turbines_man-check">Wind Turbine Manufacturers</label><br/>'+ '</td>'+ '<td width="160px" style="vertical-align:top;">'+ '<input type="checkbox" id="kml-igaslines-check" onclick="toggleKml(\'igaslines\');"/><label for="kml-igaslines-check">Industrial Energy Gas Lines</label><br/>'+ '<input type="checkbox" id="kml-hliquid-check" onclick="toggleKml(\'hliquid\');"/><label for="kml-hliquid-check">Hazardous Liquid Pipelines</label><br/>'+ '<input type="checkbox" id="kml-cavern-check" onclick="toggleKml(\'cavern\');"/><label for="kml-cavern-check">Underground Liquid Caverns</label><br/>'+ '</td>'+ '<td width="250px" style="vertical-align:top;">'+ '<input type="checkbox" id="kml-midamerican-check" onclick="toggleKml(\'midamerican\');"/><label for="kml-midamerican-check">MidAmerican Energy Facility Locations</label><br/>'+ Dec09-02 Final Report '<input type="checkbox" id="kml-industrialenergy-check" onclick="toggleKml(\'industrialenergy\');"/><label for="kml-industrialenergy-check">Industrial Energy Applications Facility Locations</label><br/>'+ '<input type="checkbox" id="kml-interstatelightpower-check" onclick="toggleKml(\'interstatelightpower\');"/><label for="kml-interstatelightpowercheck">Interstate Light & Power Co. Facility Locations</label><br/>'+ '<input type="checkbox" id="kml-otherfacilities-check" onclick="toggleKml(\'otherfacilities\');"/><label for="kml-otherfacilities-check">Other Facility Locations</label>'+ '</td>' + '</tr>'+ '</table>' ); } function initCallback(instance) { ge = instance; ge.getWindow().setVisibility(true); // add a navigation control ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO); // add some layers ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true); ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true); // fly to Iowa var la = ge.createLookAt(''); la.set(42.028045, -93.651914, 0, // altitude ge.ALTITUDE_RELATIVE_TO_GROUND, 0, // heading 0, // straight-down tilt 500000 // range (inverse of zoom) ); Dec09-02 Final Report ge.getView().setAbstractView(la); // if the page loaded with checkboxes checked, load the appropriate // KML files if (document.getElementById('kml-345-check').checked) loadKml('345'); if (document.getElementById('kml-230-check').checked) loadKml('230'); if (document.getElementById('kml-161-check').checked) loadKml('161'); if (document.getElementById('kml-115-check').checked) loadKml('115'); if (document.getElementById('kml-turbines-check').checked) loadKml('turbines'); if (document.getElementById('kml-turbines_con-check').checked) loadKml('turbines_con'); if (document.getElementById('kml-turbines_man-check').checked) loadKml('turbines_man'); if (document.getElementById('kml-e85-check').checked) loadKml('e85'); if (document.getElementById('kml-midamerican-check').checked) loadKml('midamerican'); if (document.getElementById('kml-industrialenergy-check').checked) loadKml('industrialenergy'); if (document.getElementById('kml-interstatelightpower-check').checked) loadKml('interstatelightpower'); if (document.getElementById('kml-otherfacilities-check').checked) loadKml('otherfacilities'); if (document.getElementById('kml-igaslines-check').checked) loadKml('igaslines'); if (document.getElementById('kml-hliquid-check').checked) loadKml('hliquid'); Dec09-02 Final Report if (document.getElementById('kml-cavern-check').checked) loadKml('cavern'); document.getElementById('installed-plugin-version').innerHTML = ge.getPluginVersion().toString(); } function failureCallback(errorCode) { } function toggleKml(file) { // remove the old KML object if it exists if (currentKmlObjects[file]) { ge.getFeatures().removeChild(currentKmlObjects[file]); currentKmlObject = null; } // if the checkbox is checked, fetch the KML and show it on Earth var kmlCheckbox = document.getElementById('kml-' + file + '-check'); if (kmlCheckbox.checked) loadKml(file); } function loadKml(file) { var kmlUrl = 'http://www.ece.iastate.edu/~alyons/' + file + '.kml'; // fetch the KML google.earth.fetchKml(ge, kmlUrl, function(kmlObject) { // NOTE: we still have access to the 'file' variable (via JS closures) if (kmlObject) { // show it on Earth Dec09-02 Final Report currentKmlObjects[file] = kmlObject; ge.getFeatures().appendChild(kmlObject); } else { // bad KML currentKmlObjects[file] = null; // wrap alerts in API callbacks and event handlers // in a setTimeout to prevent deadlock in some browsers setTimeout(function() { alert('Bad or null KML.'); }, 0); // uncheck the box document.getElementById('kml-' + file + '-check').checked = ''; } }); } </script> </head> <body onload="init()" style="font-family: arial, sans-serif; font-size: 13px; border: 0;"> <div id="sample-ui"></div> <div id="map3d" style="width: 800px; height: 640px;"></div> </body> </html> Dec09-02 Final Report