Google Map Application Generator
←
→
Page content transcription
If your browser does not render page correctly, please read the page content below
Google Map Application Generator Malte Winkler, Brice Pelle Dec 9, 2005 The Google Maps interface has become a very popular tool on the Internet in the last couple of years. Google Map allows Internet users to explore locations on a world map, look up addresses and get driving directions from one specified location to another. Google also offers an API that allows developers to implement their own solutions using the Google Maps technology. The availability of the API has been a huge hit with developers, however the average Internet user does not posses the skills needed to build their own applications. The aim of this project is to remove the steep learning curve associated with the API. With this tool, the user only needs to learn a simple specification language designed to customized Google Maps. Once the input specification language is compiled by ELI, the end product is a JAVASCRIPT file that contains the code needed to create the desired maps. This JAVASCRIPT file can be included in any HTML page which will render the maps. This document describes the specification language used to create these maps and the concepts used to create the compiler which was built using ELI. The following sections describe the creation and use of this tool: 1. Specification Language 1. Creating map objects. 2. Using objects on a map. 3. Nested statements. 2. Usage. 3. Compiler Concepts. 3.1 Abstract Tree Creation. 3.2 Name,Type, and Scope Analysis. 3.3 Structured output. 1. Specification Language
1. Creating map objects The specification language is built to be as simple as possible and to use key words that are intuitive. We list below examples that reflect features of the language. a) Creating a point A user can define a point which is an abstract location on the globle. This point can later be used to specify a map's center or a marker's position. The general pattern to declare a point is: Create Point PointName(longitude, latitude); Longitude and latitude specify the point's coordinates. These points must be given in double formate. b) Creating a map The general pattern to declare a new map is: Create Map MapName with ListOfAttributes on tagname; The statement declares a new Google Map to be created. ListOfAttributes is a list of attributes for the map. “tagname” is a uniquie identifier used in the html page to reference this object. Possible attributes are: – Name: sets the tab name. – View: defines the initial map view (map, satellite or hybrid) – Location: sets the location on which the map is centered – Zoom: sets the initial zoom of the map An example of the Create Map feature is: Create Map BoulderMap with Name “Boulder, CO”, Location (105.5, 40.0), View map; If a certain attribute is not defined for a map, a default will be set. c) Creating a marker A marker is an icon that can appear at a single point on a map. The general pattern to declare a new marker is: Create Marker MarkerName with ListOfAttributes; ListOfAttributes is a list of attributes for the marker. The following attributes are required : – Name: sets the name to be displayed in the marker's info window – Location: sets the location at which the marker is to be placed – Info: defines the information to be displayed in the info window An example of the Create Marker feature is: Create Marker MyHouse with Name “Brice's House”, Location BricePoint, Info “this is were I live!”; Here BricePoint refers to a point that has been previously declared with a Create Point
statement. d) Creating a trace A trace represents a line that passes by a set of points. The trace starts at the first given location point and end at the last given location point. The general pattern to define a trace is: Create Trace TraceName(ListOfPoints); ListOfPoints is a list of previously declared points. An example of the Create Trace feature is: Create Trace pathToMyHouse(P1, P2); 2. Using objects on a map Once a trace or a marker is created, they can be placed on any previously declared map object. The general pattern to place a marker on a map is: Place MarkerName on ListofMaps; ListofMaps is a list of previously declared maps to place the marker on. An example of the Place features is: Place MyHouse on BoulderMap, M1, M2, M3; The general pattern to place a trace on a map is: DrawTrace TraceName on ListofMaps; 3. Nested statements The specification language also allows for various scopes. For example, the following statements are allowed: Create Map BoulderMap with Location P1 on tagID; Create Marker M1 with Location P1; Create Marker M2 with Location P2; For WorkSheet1 Create Marker M1 with Location P2; Place M1 on BoulderMap; Place M2 on BoulderMap; End; A work sheet has similar scoping rule as a block statement in C. In the above example, the applied occurrence of M1 in WorkSheet1 refers to the defining occurrence in the worksheet, whereas the applied occurrence of M2 refers to the defining occurrence above
the For statement. 2. Usage This tool is primarily aimed at aiding the developer. The developer can use this tool to simplify the creation of a webpage containing maps with specific elements such as traces, markers, and map locations. A simple text input file can be generated using the following specification language and run through our compiler in ELI. The output will be a JAVASCRIPT file that can be included in a HTML file. A DIV tag in the HTML file will specify the location of the map on the page. An Example: Example input: Create Map M1 with Location(94.0, 34.0) on mine; Create Marker Mac with Info("changes man"), Location(34,56), Name("dfsda"); Create Point Brice (23.0, 34.0); Create Trace myTrace (Brice, (23.0, 34.0)); Example JAVASCRIPT Output file: function writeInfo(name, info){ var html = "Name: " + name + ""; html += info; return html; } function createMarker(point, name, info) { var marker = new GMarker(point); marker.point = point; marker.name = name; marker.info = info; GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(writeInfo(name, info)); }); return marker; } function createMark(m){ var marker = new GMarker(m.point); marker.point = m.point; marker.name = m.name; marker.info = m.info; GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(writeInfo(m.name, m.info)); }); return marker; } function createPL(points){
var pl = new GPolyline(points, "#ff0000", 2); pl.points = points; alert(pl.points[1]); return pl; } function initMap(){ var ELI_Boulder = new Gpoint(115.0, 37.0); var ELI_Chi = new Gpoint(34.0, 56.0); var ELI_Mine = new Gpoint(56.0, 76.0); var ELI_M1 = new GMap(document.getElementById("map")); ELI_M1.addControl(new GSmallMapControl()) ELI_M1.addControl(new GMapTypeControl()) ELI_M1.centerAtLatLng(new Gpoint(115.0, 37.0)); ELI_M1.zoomTo(16); ELI_M1.setMapType(G_HYBRID_TYPE); var tempArray = new Array(ELI_M1); for (var i=0; i
The html page can then call the function "initMap()" in the body tag like: This is a function included in the JAVASCRIPT file to set up the Map as specified in the input file. The map will now show up in the place of the the div tag in the html page where the following code is placed: To get this to run on any given server locally one must also get a key from Google and replace the key in the HTML file found on this line: Keys are available at: http://www.google.com/apis/maps/ In this manor a developer can simply create said JAVASCRIPT files and include them at will in any given HTML file. This will allow the developer to bypass the concerns of creating the maps and concentrate on the presentation of the webpage or whatever is currently burning. 3. Compiler Concepts. This tool was built using basic compiler construction in ELI. The idea was to build an abstract syntax tree that contained all the information needed to make decisions about proper output. Computations are made in the tree to determine if proper input was given . Tree computations are also done to ensure proper output. These concepts fit into 3 categories: Abstract tree creation, analysis, and structured output. 2.1 Abstract Tree Creation. Creating the abstract syntax tree involved making rules in the .lido files that would encompass all the possible input. This part handled syntax error and set the tone for our tree. We choose our tree implementation based on a set of criteria that would allow for simple input analysis. At the same time the tree structure would allow for
effective output generation. We took these conditions into account as well as the need for name analysis as we selected criteria that were important to our project. 3.2 Analysis. In the analysis part of the project we needed to deal with several issues: computational order, name and type analysis, semantic error checking, and determining unique parameters. Computational Order: The syntax for our specification language has a Cstyle scoping. For us this means that computations happen in textual order. Every variable must be declared before it can be used. However if an object is redefined further along in the input then its old variables are simply over written and this does not cause an error. To ensure this order every rule in our AST is tied into a single chain. Every computation in a rule must be completed before the chain is allowed to leave the rule. Name Analysis: Name analysis occurs in a couple places in our application. The names of Maps, Points, Markers, and Traces have both defining and use occurrences. These objects can be created and then reset throughout the input file. This means use occurrences must be tied with the defining occurrences. Once one of these objects is created it can also be used as a parameter in the creation of another object. An example: Create Point P1(78,98); Create Map B1 with Name(“Boulder”), Location P1; Here P1 is created and then used as the Location parameter in the Create Map sentence. Our name analysis is done in symbol computations. Defining occurrences inherit IdDefScope. This computational role enters the object into the definition table. The use occurrences inherit IdUseEnv. This computational role allows use to retrieve the info stored by the create sentence. Semantic Error Checking and Type Analysis: Error checking is also done in Symbol Computations. All the objects such as Map, Marker, Point, and Trace can be created and then used again. This means that we need to check whether the input has properly used these objects in say the creation of other objects. An example: Create Map M1; Create Map B1 with Name(“Boulder”), Location M1; Here a Map M1 is created and then used where a Point object is expected. Another
example: Create Point P1(78,98); Create Map B1 with Name(“Boulder”), Location P1x; Here we are correctly using a Point object where we want but we have a typo of an added “x”. Both these situation are handled in the Symbol computations of these objects by inheriting from two Modules. Use occurrences inherit both ChkIdUse and GetKind. The defining occurrences inherit SetKind. When these Objects are instantiated they receive a kind of type int assigned by us. When they are used we again check the kind in the symbol computation of the use occurrence. This will ensure that we catch errors like the ones found in the first example. Inheriting from ChkIdUse ensures that error like the ones found in the second example are caught. Uniqueness and Quantity of Parameters: Our specification language defines several statements that take parameters as input. An example would be the creation of a map with the statement: Create Map theMapName with Name(“Boulder”), Location(6,5), View(satellite), Zoom 3; Everything following the with clause is a parameter that is optional but if it occurs it may only occur once. In our AST we have these defined as MapAttribute Symbols that inherit Unique from the Unique module. Every MapAttributte is assigned its terminal value. The module will then send an error message if an attribute is used more than one time in a given sentence. If a value is followed by the with clause that is not a defined MapAttribute then this will appear as a syntax error in the construction of the AST. We also ran into the problem of having arbitrarily long parameters for a given sentence. In the sentence: Create Trace theTraceName ((6, 5), (4,8), (23,99)); The number of points taken is unbounded. To solve this problem we simple constructed a PTGNode that encompassed all the points given. This PTGNode is then stored as a property of Trace node facilitating easy data recovery. 3.3 Structured output. Generating output from a tree built in the previous two sections provides quite a challenge. This is where the follies of a given language specification come out to show themselves. Here we dealt with sever issues: maintaining textual order, scopes, and
optional parameters. Maintaining textual order: The input has a certain logical order. Objects created in a certain order must maintain their relation to each other. To ensure that the output maitains this order we used a PTG chain. This chain was tied in to every node in the tree. If a node in the tree has something to add to the overall output it simply needs to concatenate its information to the end of the PTG chain. If nothing needs to be added the node can simple concatenate a null PTGNode to the end of the chain. Scopes: Our language specifications has the ability to add blocks in the form of worksheets. If an object is created in a worksheet then it should behave as though within that scope. We accomplish this by concatenating the name of the worksheet to the beginning on the object name before outputting this variable to the JAVASCRIPT file. In this way we created something similar to a namespace in the JAVASCRIPT environment. Optional parameters: In the creation of an object such as a map object not all parameters must be included in the parameter list of that object. This means that we have check if a parameter has been set before we can determine the proper JAVASCRIPT output. For example the sentence for creating a Map is as such: Create Map M1 with Location(45, 56); The corresponding output in a JAVASCRIPT file would look like: var M1 = new GMap(document.getElementById("mine")); M1.centerAtLatLng(new GPoint(45, 56)); To ensure that only the parameters that are set are output we run a simple check on the constituents of the node to check for there presents.
You can also read