Oracle9iAS Wireless Developer's Guide Release 2 (9.0.2) Part Number A90485-02 |
|
This chapter provides conceptual and usage information for developers of location-based applications. It contains the following major sections:
Developers of location-based applications need specialized services for:
Several companies provide these types of specialized content and applications. For example, some Web sites have categories for business directories, and some sites provide driving directions. Developers building mobile applications based on the Oracle9iAS Wireless framework can benefit from being able to use the specialized content and services. It is inefficient for each application to write custom interfaces to all the services that it wants to access.
The Oracle9iAS Wireless location application components are a set of APIs (application programming interfaces) for performing geocoding, providing driving directions, and looking up business directories. Service proxies are included that map existing important providers to the APIs, and additional providers are expected to be accommodated in the future.
Oracle9iAS Wireless application developers can take advantage of a uniform interface to access different service providers without having to make any changes to their applications. They can also use the infrastructure to prioritize services based on criteria such as quality, availability, or cost. Service providers also benefit from the fact that their contents and specialized functions are available "out-of-the-box" to all Oracle9iAS Wireless application developers.
This section introduces the location application components API, describes how to find the detailed javadoc-generated documentation and online examples, and explains conceptual and usage information that you must understand before using the components. It contains the following major subsections:
To get started using the Oracle9iAS Wireless location application components, follow these steps:
sample
directory, which contains example files. Read the Readme.txt
file in that directory; examine the supplied files, and use any that meet your needs.
iAS-Wireless-Home/wireless/doc/index.html
where ias-Wireless-home is your Oracle9iAS Wireless home directory.
Figure 15-1 shows part of the index.html
display. Navigate to find detailed information about packages and classes.
Location services are provided in the following major categories: geocoding, mapping, routing, business directory (Yellow Page), and traffic.
Other sections in this chapter describe how to specify and configure external providers for location services, and describe each type of service in greater detail.
The SpatialManager
Java class manages all these location services.
The SpatialManager
class is defined as follows:
package oracle.panama.spatial; import ...; public class SpatialManager { public static synchronized Geocoder getGeocoder() {...} public static synchronized Router getRouter() {...} public static synchronized YPFinder getYPFinder() {...} public static synchronized Mapper getMapper() {...} public static synchronized TrafficReporter getTrafficReporter() {...} }
The actual core computation for location services is generally performed at an external provider. The external provider might be accessed over the Internet or other means of communication, or might be local. The Oracle9iAS Wireless Location Application Components API performs the communication and adaptation of results in a unified framework, so that users are generally not aware of which provider is supplying a particular service. In addition, the API minimizes the application developer's implementation effort and dependence on specific providers.
Access to an initial set of providers for most services is included. Some providers have full configuration information included, and some do not. (For providers that do not have configuration information, you usually receive the necessary information after you purchase the right to use their user name and password.)
You can provide access to additional providers by using the webtool. If a a new provider is added and if the provider does not use the same interface as an existing provider, a Java class must be created to translate between the provider's format and the Oracle9iAS Wireless location application components API. (This program is specified as the ProviderImpl
attribute.) In addition, the implementing class file for the program must be added to the class path.
Using multiple providers for a service increases the probable reliability of the service. The API fails only either if all providers fail or if Web access is temporarily unavailable. Because providers are specified in preference list, the API automatically fails over when the preferred provider cannot perform the requested service, such as when any of the following occurs:
Location services use a list of providers and support fail-over between them. The sequence in which providers are tried should ideally represent an order of preference. The preference ranking can be a simple ranking of providers, or it might be affected by region, time, performance, reliability, and cost.Whichever criteria are used, they are evaluated by a provider selection framework that determines provider order of preference.
The provider selection framework needs to be configured, as described in this section. If a service request is not satisfied by the framework, then either the provider selection framework implementation has been incorrectly configured or all providers have failed. You can find information about any problems or failures from the console log or the log file, as explained in Section 15.1.3.2.
You must select a provider selection framework to be used. To select the framework, use the Oracle9iAS Wireless webtool and follow these steps:
Your choice of a provider selection framework implementation determines whether more or less complex rules can be used for provider selection. The following implementations are available:
oracle.panama.spatial.core.ruleengine.SimpleRuleEngineImpl
This simple implementation tries all providers until one succeeds. The sequence in which providers are tried is specified in the provider configuration list.
oracle.panama.spatial.core.ruleengine.RuleEngineImpl
This implementation can select providers based on whether or not they provide satisfactory coverage for a given country. Among all providers that provide satisfactory coverage for a given country, providers are tried based on the sequence in the provider configuration list.
This implementation avoids time being wasted trying providers that do not provide coverage for a country or that provide unsatisfactory service (for example, if the cost is too high or the service quality is poor). However, this selection framework does require more configuration: lists of countries and country aliases need to be specified for each provider (although examples of such configurations are provided).
Other provider selection framework implementations can be added later.
To configure the provider information, use the Oracle9iAS Wireless webtool and go to the same page as for provider selection, then select the appropriate type of service for configuration. Follow these steps:
The provider information (described in Section 15.1.3.1.2) is very similar for all types of services (geocoding, mapping, routing, traffic, and YP).
For geocoding and perhaps other services, you may need to provide configuration information for country name aliases (see Section 15.1.3.1.3) and address formats (see Section 15.1.3.1.4).
An ordered list of providers is configured with the following parameters:
The country name alias configuration relates country names and synonyms to a single standard identifier for a given country. This standard identifier should be the ISO name (US for US, DE for Germany, and so on), although you can specify other identifiers.
The aliases are used in combination with the oracle.panama.spatial.core.ruleengine.RuleEngineImpl
provider selection framework implementation. Each provider is configured for a set of countries, specified by their IDs. For example, when a service request is made, for example to geocode an address in the United States, the country alias table is consulted to find the standard ID US. Subsequently, only providers with US in their list of covered countries are tried.
If a country name is used which is not configured as a known alias for some country ID, the ID unknown is used, instead. In this case, providers with unknown in the covered country list are tried.
If the simple provider selection framework implementation (oracle.panama.spatial.core.ruleengine.SimpleRuleEngineImpl
) is used, country aliases are not required for provider selection.
The address format configuration is used to specify international address formats. The oracle.panama.spatial.intladdress
package in the API uses this list to determine which components are part of an address (US, French, German, Chinese, and so on) and how they are presented for input and output.
The international address framework is configured with a list of address formats in the repository, accessible through the webtool. This configuration specifies all components of an address, aliases for the components, and mappings to standard concepts such as city, state, and street name. The format of the textual representation is also configured, to determine such things as:
This approach requires that users specify a country-specific format for addresses, in order to view and enter addresses in that format. Otherwise, for example, the system cannot know whether to ask a user to specify a state or province before the country.
The benefits of this approach include the following:
Several international address formats are supplied. Two examples are as follows.
For the US:
{name} {house number/house} {street}[ Apt {apt}] {city} {state} {postal code}[-{postal code ext}] {country}
For Germany:
{Name/name} {Strasse/street/first line} {Hausnummer/house}[ Wohnung {Wohnung/apt}] {PLZ/postal code} {Stadt/city} [{Bundesland/state}] {Land/country}
Syntax notes:
For programming information and examples relating to international address formats, see Section 15.2.2.1.1.
The provider selection framework implementation logs selection, success, and failure of providers on the iAS servlet container console or in the Oracle9iAS Wireless log file (for example, sys_panama.log
). For example, you can look for events such as the following:
The geocoding API provides the geographic location of a given address. For a user of Oracle9iAS Wireless, an address is the most common way to specify a location. However, for finding restaurants in close vicinity or providing driving directions, the text representation of an address may not be useful unless it is first geocoded, that is, translated to geographic coordinates.
The address to be geocoded has a textual representation like that from a standard mailed letter. The result returned is the longitude/latitude corresponding to the address. For example, the input to geocoding might include the following:
In this example, the result is: Point( x = -71.455, y = 42.7117)
Because a user might specify an ambiguous address, the GeocodeResult
contains an array of Location objects instead of a single object.
This section describes the geocoding API for location application components.
Two of the following classes, Point
and Location
, are used by the whole API and are not specific to geocoding. However, they are described here because they represent components central to the geocoding service, both for input and output.
The Point
class defines a longitude/latitude coordinate point. Additional values for a label and a radius can be used for representing a point on a map. The label and radius are not used by any other functions than map display.
The Location
class defines a location with address and longitude/latitude. If the location object is constructed using firstLine
, secondLine
, and lastLine
, then some external providers might not correctly identify the city or state, because lastLine
can contain city, state, and postal code in a country-specific and relatively flexible format.
If no specific substring can be identified as the component representing the city, the city is "unknown". In this case, the API itself might not try complex analysis, but instead leave this task to the experts, that is, the external geocode providers.
The Geocoder
interface defines how an application programmer accesses the geocoding service. An object of a class implementing this interface is returned by the SpatialManager
.
Due to the limitations of certain mobile devices such as telephones, it is difficult to input/display lengthy alphanumeric strings. A location mark stores a piece of spatial information identified by a concise, easy-to-understand name. For example, "My home" might be the name of a location mark, while the underlying spatial information might be "123 Main Street, Somewhere City, CA, 12345; Lon = -122.42, Lat = 37.58".
[preceding for when rectangles are allowed] For example, "My home" and "Downtown San Francisco" might be the names of two location marks, while the underlying spatial information might be "123 Main Street, Somewhere City, CA, 12345; Lon = -122.42, Lat = 37.58" for the first location mark, and "The rectangle geometry within bounding points (Lon/Lat = -122.49, 37.79) and (Lon/Lat = -122.41, 37.74)" for the second location mark.
Location marks allow users to avoid inconvenient string input on mobile devices. Users can manage their location marks on a desktop and then access them by referring to their names from mobile devices. Today's location-aware applications typically just use a point location (such as an address or a road intersection). In this case, the spatial information can be provided by geocoding. In this release, a location mark must be a point. However, in a future release it is planned to allow a location mark to be something other than a point; for example, it could be the current position associated with automatic mobile positioning or a region defined by region modeling.
Location marks also allow users to try "what-if" scenarios: to make an application behave as if they were in a location different from their default or current location. For example, a user of an entertainment services application might actually be in Boston now, but will be traveling to San Francisco in a few days. This person could set a location mark in San Francisco as the default, and be presented with information relevant to the San Francisco area.
Each user has personalized location marks, which are stored in the Oracle9iAS Wireless repository.
Location marks are created using the LocationMark
class. Users can also create location marks by logging into the iAS Personalization Portal, clicking the LocationMarks tab, and clicking Create.
For information about using a location mark to enable mobile positioning, see Section 15.3.1.
A new table named LOCATIONMARK is added to the Oracle9iAS Wireless repository schema. This table contains detailed information about each location mark, including the user associated with each location mark. For example, several users might have a location mark named Office but with a different location for each.
Table 15-1 lists the columns in the LOCATIONMARK table.
The mapping API provides functions for creating map images for any of the following:
The mapping API lets you specify the size (resolution) of the map and the image format. Image transformation is also provided through the oracle.panama.spatial.imagex
class (discussed in Section 15.1.8.3). For example, if the provider only supports GIF format but the user requires WBMP format, the imagex
API can perform the transformation.
Mapping capabilities can be made visible to users as a purely mapping application or as part of a routing application. In a routing application, the mapping of routes and driving maneuvers is performed by the routing provider. For information about routing services, see Section 15.1.8.
The routing API provides routing (driving directions) information based on a start point, an end point, and optionally a list of intermediate via points. All points are specified as longitude/latitude pairs or addresses.
The routing result consists of a set of maneuvers. A maneuver corresponds to a driving instruction, such as "turn left onto I-93" or "bear right and merge to Route 3". The routing result also includes estimated driving time and distance. Optionally, maps and route coordinates can be requested.
Routing can be influenced by preferences or requirements, called routing options. These options are combined in a set, called routing settings. There are two types of routing options: basic options and secondary options.
Basic options include:
Secondary options include:
Secondary options can be mandatory or preferred:
If the application developer requests a secondary option without specifying whether it is mandatory or preferred, the following defaults are applied:
The application can query the following components of a returned route:
An overview map shows the source and destination, with the route highlighted. Figure 15-5 shows an overview map for the driving direction from New York City to Washington, DC.
A set of maneuvers (driving directions) is returned as part of the routing result. Each maneuver corresponds to a driving instruction and contains the following information:
Figure 15-6 shows a maneuver map for merging onto Interstate Route 95. The narrative might be "Continue on ramp at sign reading 'Exit 5 I-95 South Del. Tpke. To Baltimore' and go southwest for 0.4 miles."
Maps of the complete route or maneuvers can be requested as Java Image objects or as Strings representing a URL.
The application can affect the size of the map. Because different devices (for example, a desktop web browser, a Palm device, and a phone) may need specific image formats (for example, GIF, BMP, or WBMP) and because most providers support only a single format, the application currently is responsible for image transformation between formats.
Transformation support is provided in the oracle.panama.spatial.imagex
class. This class provides functions for transforming images to different image formats, sizes, and orientations. You can use this class to perform the following operations on images:
If the routing provider supports multiple languages, the API chooses a language based on the Java locale
object specified in the request to the router. The language setting can affect the maneuver narratives and distance measures.
This section describes the routing API for location application components.
The Router
interface defines how an application programmer accesses the routing service. An object of a class implementing this interface is returned by the SpatialManager
.
The RoutingSettings
class defines a set of options passed to routing. There are two types of routing options: basic and secondary.
Basic options include whether or not to request a map or a geometry. Basic options can be specified in the constructor of a RoutingSettings
object.
Secondary options can be set using setSecondaryOption
. The first parameter is a RoutingOption
object, which is a static constant defined in the RoutingOption
class. It identifies the option for which a value is set. The second parameter is a String
representing the value.
Whether or not the secondary option is mandatory is defined by setSecondaryOptionRequired
. The first parameter is the RoutingOption
and the second parameter specifies whether this option requirement is mandatory. Unless this function is called, the default value is assumed.
The RoutingResult
class defines the routing results, which are described in Section 15.1.8.2.
The Maneuver
class defines a single maneuver in a route (see Section 15.1.8.2 for the maneuver attributes).
Business directory (Yellow Page, or YP) services provide lists of businesses in a given area and matching a specified name or category.
Existing providers use YP services with different interfaces. Specifically, they all have different YP categories, and even different hierarchical structures. The categories might be organized in a flat list or in a hierarchy of categories and subcategories. A hierarchy tree might be deep or shallow, with a high or low fanout, and might be balanced or unbalanced.
To unify the service of different providers, the Oracle business directory services use a custom hierarchy that the Oracle9iAS Wireless developer defines in an XML file. Each leaf in this hierarchy has a reference to a category of one or more providers. Non-leaf nodes might also have such references. This custom hierarchy defines preferred categories first. Subsequently, the carrier using Oracle9iAS Wireless tries to match these categories to semantically similar categories supported by external providers.
The customized hierarchy with the references to external providers' categories is represented in an XML file that stores hierarchical and ordered structures. Representing order in the category hierarchy can account for the popularity of different categories. For example, on a device with a limited screen size, an application might restrict the choices among the most popular categories.
Several providers offer YP services on the web; however, the approaches taken by these providers differ significantly and do not offer a uniform interface. Furthermore, the respective approaches are not final in their methodology and can be expected to change.
A unifying pattern in the various approaches is that businesses are categorized by subject and location. The location component is well understood in that either a ZIP code or the combination of a city and state can be used to determine the location.
The categorization of businesses, on the other hand, is not uniformly implemented. Some providers offer a flat list of categories, user-selected by simple substring matching. Another approach is a 3-level or 4-level hierarchical organization of subcategories, often with a fanout of 20 to 50, sometimes more than 100. A user might start the hierarchy traversal at the root of the hierarchy (by default). Alternatively, a user might enter a keyword that is matched to an appropriate starting point within the hierarchy. Such keyword matching might go beyond simple substring search and result in more intelligent choices.
Support for business categories and the hierarchy of categories is provided through an XML configuration file. (You should view and modify business directory provider information using the webtool; however, you must view and modify business directory category information using the XML file.)
The category hierarchy definition file in Example 15-1 represents the custom hierarchy of business directory categories. Each category can have any number of subcategories. There is no restriction to the level of nesting. A category can be linked to multiple business directory content providers. The flexibility allowed by this file accommodates the different approaches of various business directory service providers, as discussed in Section 15.1.9.1.
<?xml version="1.0" standalone="yes"?> <Categories> ... <Category CategoryName = "Berry crops"> <Provider Name = "..." Parameter = "..."/> <Category CategoryName = "Cranberry farm"> <Provider Name = "..." Parameter = "..."/> </Category> </Category> ... <Category CategoryName = "Ornamental nursery products"> <Provider Name = "..." Parameter = "..."/> <Category CategoryName = "Florists' greens and flowers"> <Provider Name = "..." Parameter = "..."/> </Category> <Category CategoryName = "Bulbs and seeds"> <Provider Name = "..." Parameter = "..."/> </Category> </Category> <Category CategoryName = "Crops grown under cover"> <Provider Name = "..." Parameter = "..."/> <Category CategoryName = "Mushrooms grown under cover"> <Provider Name = "..." Parameter = "..."/> </Category> </Category> ... </Categories>
The application developers can traverse the category hierarchy by using the functions in the YPFinder
interface. For any resulting category, the following can be requested:
The YPFinder
interface defines how an application programmer accesses the YP service. An object of a class implementing this interface is returned by the SpatialManager
.
An object of this class lets the user query:
In each of these region types, businesses can be found:
The YPCategory
class defines a single category that is part of the hierarchy. This class lets users access businesses in the category. It also lets users find subcategories of the category; specifically, you can find:
One of the most popular applications probably is to find subcategories of the root matching a given keyword.
The YPBusiness
class defines a single business. It represents an address (Location
interface) that also has a telephone number, a description, and a list of categories it matches. You can get all businesses in a category or all categories for each of these businesses. For example, a given bookstore might be both in the categories book store and cafe.
The traffic API provides information about conditions that can affect traffic flow on road networks in major metropolitan areas. These areas are typically further divided into smaller areas, such as downtown, metro West, metro East, and so on. Real-time traffic reports update conditions in short time periods (such as every 5 minutes), thus providing information that is important for fleet management as well as personal navigation.
The major components of traffic reports are incidents. An incident is an event that will probably affect the flow of traffic. Examples of incidents are accidents, construction activity, and traffic congestion (normal or unexpected). Each incident includes such information as the type of incident, where the incident occurred (such as the route number, the location, or the region), the direction along the route (such as northbound), the expected delay, and the length of the traffic backup.
For the current release, the following kinds of queries are supported for incident-based traffic information:
Examples of traffic queries include returning the traffic report for:
The traffic API processes requests and returns responses. The requests and responses can be in Java or XML format. Section 15.1.10.2 provides examples of an XML request and response in XML format. Section 15.1.10.3 describes the traffic Java API.
Traffic report information is cached at the city level. The first time that a traffic report on a city is fetched, the report is written to the traffic report cache. The cached report is considered invalid after a maximum cache age time (for example, 15 minutes), which can be set using the iAS webtool.
A network round-trip operation to the traffic service provider is required to update the cached traffic report for the city. The cached report is updated only when both of the following conditions are true:
Example 15-2 shows a city-level request in XML format for traffic information for Boston.
<?xml version="1.0" encoding="UTF-8"?> <traffic_request> <query_list> <query_info query_type="city_level_query" city_name="boston" state_name="MA" country_name="US" /> </query_list> </traffic_request>
Example 15-3 shows a response in XML format for traffic information for Boston.
<?xml version="1.0" encoding="UTF-8"?> <traffic_response> <report_list> <traffic_report> <provider name="Trafficstation" covered_city_name="Boston" state_name="MA" country_name="US"/> <report_time month="6" day="19" year="2001" hour="5" minute="28" meridian = "PM"/> <unit distance_unit="MILES" time_unit="MINUTE"/> <incident_list> <incident id = "1"> <incident_type>ACCIDENT</incident_type> <description>CAR ACCIDENT</description> <route type = "Interstate" name = "I-93" direction = "SOUTH"/> <geo_location longitude = "-71.0607" latitude = "42.3659" radius = "5.0"/> <location_range> <at_location>EXIT 26</from_location> </location_range> <time_range> <from_time month = "6" day = "19" year = "2001" hour = "5" minute = "28" meridian = "PM"/> <to_time month = "6" day = "19" year = "2001" hour = "5" minute = "28" meridian = "PM"/> </time_range> <severity>HEAVY</severity> <speed>15.0</speed> <impact>EXPECT DELAY</impact> <advice>TAKE LEFT LANE</advice> </incident> <incident id = "2"> <incident_type>CONSTRUCTION</incident_type> <description>REGULAR MAINTENANCE</description> <route type = "Interstate" name = "I-95" direction = "NORTH"/> <geo_location longitude = "-71.3555" latitude = "42.3601" radius = "30.0"/> <location_range> <at_location>EXIT 36</at_location> </location_range> <time_range> <at_time month = "6" day = "19" year = "2001" hour = "5" minute = "28" meridian = "PM"/> </time_range> <severity>MINOR</severity> <speed>35.0</speed> <impact>EXPECT DELAY</impact> <advice>USE I-495</advice> </incident> </incident_list> </traffic_report> </report_list> </traffic_response>
This section describes the traffic Java API for location application components.
The CityInfo
class provides the city name, state name, and country name for a city. A common use of this class is to create a CityInfo
instance with city name, state name (optional), and country name, and pass it to the query for a traffic report at city level, route level, or point and radius level with a city.
The City
interface provides information about a city from a specified service provider. The information includes the city name, state name, country name, and information about routes. A City
instance could be obtained from the TrafficReport
interface.
The RouteInfo
class provides the name and type for a route. A common use of this class is to create a RouteInfo
instance and pass it to the query for a traffic report at route level.
The TrafficRoute
interface provides information for a route from a specified service provider. The information includes the route name, route type, geometry that represents the route, and the city name. A TrafficRoute
instance could be obtained from the TrafficIncident
interface.
The TrafficReport
interface provides information for an incident-based traffic report, such as the report time, the number of incidents, the provider's information, the city, and the incidents. A report could then be created to show to users or administrators of the application.
The TrafficIncident
interface provides information for a traffic incident, such as the severity, type, description, route and direction on which the occurred, location, time range, impact, and advice.
The TrafficReporter
interface provides functions that return a traffic report based on different queries. The following kinds of queries are supported:
When using SpatialManager.createLocation()
to get an instance of Location
, you must specify the city name and country name. Do not use the LastLine
attribute to combine these pieces of information. Set the value of the Point
geometry to null to avoid automatic geocoding.
The TrafficCityManager
interface provides two functions, one to obtain all the cities for which traffic information is provided, and the other to obtain the routes info for a given city. A common use of these functions is to call them to create a drop-down list of cities and routes supported by the application.
After the region modeling data and city coverage data has been loaded into the repository during the Oracle9iAS Wireless installation, you can add traffic providers and supported cities for a provider.
To add support for a new traffic service provider, follow these steps:
UPDATE city_coverage SET covered_by_traffic = 'Y' WHERE id = 12345; COMMIT;
If there is not already an entry in the CITY_COVERAGE table for this city, add a row and set the value of the COVERED_BY_TRAFFIC column to 'Y', and be sure that the ID value in this table is the same as the ID value for the city in the CITY table. For example:
INSERT INTO city_coverage (id, name, state_name, country_name, covered_by_traffic) VALUES (10750, 'BOSTON', 'MA', 'US', 'Y'); COMMIT;
To add support for a new city for an existing traffic service provider, follow these steps:
UPDATE city_coverage SET covered_by_traffic = 'Y' WHERE id = 12345; COMMIT;
If there is not already an entry in the CITY_COVERAGE table for this city, add a row and set the value of the COVERED_BY_TRAFFIC column to 'Y', and be sure that the ID value in this table is the same as the ID value for the city in the CITY table. For example:
INSERT INTO city_coverage (id, name, state_name, country_name, covered_by_traffic) VALUES (10750, 'BOSTON', 'MA', 'US', 'Y'); COMMIT;
You can develop a location-based application by using either of the following approaches:
Creating JSP files is often easier and more convenient that writing an adapter; however, writing an adapter gives you greater flexibility and control over the program logic. This section describes both approaches.
If you do not need to write an adapter, you can create Java Server Pages (JSP files) to provide location-based capabilities to users.
This section provides detailed information about the Oracle-supplied tags that you can use. Each reference section includes an example.
Table 15-2 groups the JSP tags for location services by the type of application for which the tag is useful, and briefly describes the information specified by the tag.
These tags must be used with a prefix, which must be specified in the JSP file. The following example defines the loc
prefix, which is used in other examples of specific tags:
<%@ taglib uri="LocationTags" prefix="loc" %>
The following example shows the loc
prefix used with the address
tag:
<loc:address name="hq" type="oracle.panama.model.Location" businessName="Oracle Headquarters" firstLine="500 Oracle Parkway" city="Redwood City" state="CA" postalCode="94065" country="US"/>
The following sections (in alphabetical order by tag name) provide reference information for all the parameters available for each tag: the parameter name, a description, and whether or not the parameter is required. If a parameter is required, it must be included with the tag. If a parameter is not required and you omit it, the interpretation is performed by the service provider.
Short examples are provided in the reference sections for JSP tags, and more comprehensive examples are provided in Section 15.2.1.10.
and evaluated at run time:
The address
tag specifies an address to be geocoded, located on a map, or used as the start or end address of a route or as the center for a business directory query.
Table 15-3 lists the address tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example of the address
tag specifies an address (for a store named Mike's Hardware) to be geocoded.
<loc:address name = "hardware_1" type = "oracle.panama.model.Location" businessName = "Mike's Hardware" firstLine = "22 Monument Sq" city = "Concord" state = "MA" postalCode = "01742" country = "US" />
The businesses
tag specifies a collection of businesses that share one or more attributes.
Table 15-4 lists the businesses tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example of the businesses
tag specifies all businesses named Borders in the state of California in the United States. The use of the map
tag to enclose the businesses
tag causes a map to be created that includes and labels each Borders bookstore.
<loc:map name="map1" type="oracle.panama.spatial.jsptags.beans.Map" xres="1000" yres="500"> <loc:businesses name="bord" type="java.util.Collection" businessName="Borders" country="US" state="CA"/> </loc:map>
The category
tag specifies a business category (for example, Dealers).
Table 15-5 lists the category tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example uses two category
tags. The first category
tag creates an object named cat_auto
that specifies a category named Automotive
. The second category
tag creates an object named cat_dealers
that specifies a category named Dealers
that is a child of the cat_auto
(Automotive) parent category.
<mt:category name="cat_auto" type="oracle.panama.spatial.yp.YPCategory" categoryName="Automotive" /> <mt:category name="cat_dealers" type="oracle.panama.spatial.yp.YPCategory" parentCategory="cat_auto" categoryName="Dealers" />
The iterateBusinesses
tag presents individually the businesses in a collection returned by the businesses
tag.
Table 15-6 lists the iterateBusinesses
tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example creates a collection of all Borders stores in California and then uses the iterateBusinesses
tag to present each Borders store location in the collection.
<loc:businesses name="bord" type="java.util.Collection" businessName="Borders" country="US" state="CA"/> <loc:iterateBusinesses name="iter_borders" type="oracle.panama.model.Point" collection="bord" />
The iterateCategoriesMatchingKeyword
tag creates a collection of categories that match a specified keyword value, and presents the categories individually.
Table 15-7 lists the iterateCategoriesMatchingKeyword
tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example shows the category
tag used to create an object named cat_auto
that specifies a category named Automotive
. The iterateCategoriesMatchingKeyword
tag is then used to create an object named key
that contains each category containing Dealers
under the Automotive parent category, and the fully qualified name of each returned category is displayed.
<mt:category name="cat_auto" type="oracle.panama.spatial.yp.YPCategory" categoryName="Automotive" /> <mt:iterateCategoriesMatchingKeyword name="key" type="oracle.panama.spatial.yp.YPCategory" keyword="Dealers" parentCategory="cat_auto"> >>> <%= key.getFullyQualifiedName() %> </mt:iterateCategoriesMatchingKeyword>
The iterateChildCategories
tag specifies a collection of immediate child subcategories, presented individually.
Table 15-8 lists the iterateChildCategories
tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example of the iterateChildCategories
tag presents each immediate child category under the automotiveDealers
category.
<loc:category name="automotiveDealers" type="oracle.panama.spatial.yp.YPCategory" categoryName="Dealers"> <loc:category name="automotive" type="oracle.panama.spatial.yp.YPCategory" categoryName="Automotive"/> </loc:category> <loc:iterateChildCategories name="cat" type="oracle.panama.spatial.yp.YPCategory" parentCategory="automotiveDealers"> <%= cat %>
The iterateManeuvers
tag creates a collection of driving maneuvers, and it presents the maneuvers individually.
Table 15-9 lists the iterateManeuvers
tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example creates a route named myRoute
between two Oracle offices, displays a map of the route, and presents each driving maneuver (using the iterateManeuvers
tag and the getMap
and getNarrative
function calls).
<loc:route name="myRoute" type="oracle.panama.spatial.jsptags.beans.Route" xres="800" yres="600"> <loc:address name="NEDC" type="oracle.panama.model.Location" businessName="NEDC" firstLine="1 Oracle Dr" city="Nashua" state="NH" postalCode="03062" country="US"/> <loc:address name="HQ" type="oracle.panama.model.Location" businessName="HQ" firstLine="500 Oracle Parkway" city="Redwood City" state="CA" postalCode="94065" country="US"/> </loc:route> <img src="<%= myRoute.getMap() %>"> <loc:iterateManeuvers name="aManeuver" type="oracle.panama.spatial.jsptags.beans.Maneuver" routeID="myRoute"> <a href="<%= aManeuver.getMap() %>"> <%= aManeuver.getNarrative() %> </a> </loc:iterateManeuvers>
The map
tag specifies a map with a specified resolution and showing one of the following:
Table 15-10 lists the map
tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example of the map
tag creates a map named NEDCSmall
400 pixels wide and 300 pixels high. The center point for the map is the address defined by the address
tag enclosed in the map
tag.
<loc:map name="NEDCSmall" type="oracle.panama.spatial.jsptags.beans.Map" xres="400" yres="300"> <loc:address name="NEDC" type="oracle.panama.model.Location" businessName="NEDC" firstLine="1 Oracle Dr" city="Nashua" state="NH" postalCode="03062" country="US"/> </loc:map>
The route
tag specifies a route with a specified map resolution. It includes maneuvers, an overview map, and maneuver maps.
Table 15-11 lists the route
tag parameters. (See Section 15.2.1 for an explanation of the information provided.)
The following example of the route
tag specifies the route between two addresses (an Oracle office in New Hampshire and Oracle headquarters in California).
<loc:route name="myRoute" type="oracle.panama.spatial.jsptags.beans.Route" xres="800" yres="600"> <loc:address name="NEDC" type="oracle.panama.model.Location" businessName="NEDC" firstLine="1 Oracle Dr" city="Nashua" state="NH" postalCode="03062" country="US"/> <loc:address name="HQ" type="oracle.panama.model.Location" businessName="HQ" firstLine="500 Oracle Parkway" city="Redwood City" state="CA" postalCode="94065" country="US"/> </loc:route>
This section includes several examples of JSP code to perform operations that involve location services. In these examples, addresses are specified in the points
attribute of the appropriate tag (<map>
or <route>
).
Example 15-4 displays small and large maps of two locations.
<%@ taglib uri="LocationTags" prefix="loc" %> <%! public String transformString(String orig) { String result = ""; for (int i=0;i<orig.length();i++) { if (orig.charAt(i) == '&') result = result + "&"; else if (orig.charAt(i) == '<') result = result + "<"; else if (orig.charAt(i) == '>') result = result + ">"; else result = result + orig.charAt(i); } return result; } %> <SimpleResult> <loc:address name="NEDC" type="oracle.panama.model.Location" businessName="NEDC" firstLine="1 Oracle Dr" city="Nashua" state="NH" postalCode="03062" country="US"/> <loc:map name="NEDCSmall" type="oracle.panama.spatial.jsptags.beans.Map" xres="400" yres="300" points="NEDC"> </loc:map> <loc:address name="HQ" type="oracle.panama.model.Location" businessName="HQ" firstLine="500 Oracle Parkway" city="Redwood City" state="CA" postalCode="94065" country="US"/> <loc:map name="HQSmall" type="oracle.panama.spatial.jsptags.beans.Map" xres="400" yres="300" points="HQ"> </loc:map> <loc:map name="BothSmall" type="oracle.panama.spatial.jsptags.beans.Map" xres="400" yres="300" points="NEDC HQ"/> <loc:map name="NEDCLarge" type="oracle.panama.spatial.jsptags.beans.Map" xres="800" yres="600" points="NEDC"/> <loc:map name="HQLarge" type="oracle.panama.spatial.jsptags.beans.Map" xres="800" yres="600" points="HQ"/> <loc:map name="BothLarge" type="oracle.panama.spatial.jsptags.beans.Map" xres="800" yres="600" points="NEDC HQ"/> <SimpleImage target="<%= transformString(NEDCLarge.toString()) %>" src="<%= transformString(NEDCSmall.toString()) %>"/> <SimpleImage target="<%= transformString(HQLarge.toString()) %>" src="<%= transformString(HQSmall.toString()) %>"/> <SimpleImage target="<%= transformString(BothLarge.toString()) %>" src="<%= transformString(BothSmall.toString()) %>"/> </SimpleResult>
Example 15-5 displays the route between two locations and the driving directions (maneuvers).
<%@ taglib uri="LocationTags" prefix="loc" %> <%! public String transformString(String orig) { String result = ""; for (int i=0;i<orig.length();i++) { if (orig.charAt(i) == '&') result = result + "&"; else if (orig.charAt(i) == '<') result = result + "<"; else if (orig.charAt(i) == '>') result = result + ">"; else result = result + orig.charAt(i); } return result; } %> <SimpleResult> <loc:address name="NEDC" type="oracle.panama.model.Location" businessName="NEDC" firstLine="1 Oracle Dr" city="Nashua" state="NH" postalCode="03062" country="US"/> <loc:address name="HQ" type="oracle.panama.model.Location" businessName="HQ" firstLine="500 Oracle Parkway" city="Redwood City" state="CA" postalCode="94065" country="US"/> <loc:route name="myRoute" type="oracle.panama.spatial.jsptags.beans.Route" xres="800" yres="600" points="NEDC HQ"> </loc:route> <SimpleImage src="<%= transformString(myRoute.getMap()) %>"/> <SimpleText> <loc:iterateManeuvers name="aManeuver" type="oracle.panama.spatial.jsptags.beans.Maneuver" routeID="myRoute"> <SimpleTextItem> <%= aManeuver.getNarrative() %> </SimpleTextItem> </loc:iterateManeuvers> </SimpleText> </SimpleResult>
Example 15-6 displays business directory (YP) information by name within a specified distance of a location: specifically, a map with the ten Starbucks locations nearest to Oracle headquarters.
<%@ taglib uri="LocationTags" prefix="loc" %> <%! public String transformString(String orig) { String result = ""; for (int i=0;i<orig.length();i++) { if (orig.charAt(i) == '&') result = result + "&"; else if (orig.charAt(i) == '<') result = result + "<"; else if (orig.charAt(i) == '>') result = result + ">"; else result = result + orig.charAt(i); } return result; } %> <SimpleResult> <loc:address name="HQ" type="oracle.panama.model.Location" businessName="HQ" firstLine="500 Oracle Parkway" city="Redwood City" state="CA" postalCode="94065" country="US"/> <loc:businesses name="starbucks" type="java.util.Collection" businessName="Starbucks" centerID="HQ" nearestN="10"/> <loc:map name="starbucksMap" type="oracle.panama.spatial.jsptags.beans.Map" xres="800" yres="600" points="starbucks"> </loc:map> <SimpleImage src="<%= transformString(starbucksMap.toString()) %>"/> <SimpleText> <loc:iterateBusinesses name="singleStarbucks" type="oracle.panama.model.Point" collection="starbucks"> <SimpleTextItem> <%= singleStarbucks %> </SimpleTextItem> </loc:iterateBusinesses> </SimpleText> </SimpleResult>
Example 15-7 displays business directory (YP) information by category within a specified area: specifically, a map with all automobile dealers (new cars) in San Francisco, California.
<%@ taglib uri="LocationTags" prefix="loc" %> <%! public String transformString(String orig) { String result = ""; for (int i=0;i<orig.length();i++) { if (orig.charAt(i) == '&') result = result + "&"; else if (orig.charAt(i) == '<') result = result + "<"; else if (orig.charAt(i) == '>') result = result + ">"; else result = result + orig.charAt(i); } return result; } %> <SimpleResult> <loc:category name="automotive" type="oracle.panama.spatial.yp.YPCategory" categoryName="Automotive"> </loc:category> <loc:category name="automotiveDealers" type="oracle.panama.spatial.yp.YPCategory" categoryName="Dealers" parentCategory="automotive"> </loc:category> <loc:category name="newAutomotiveDealers" type="oracle.panama.spatial.yp.YPCategory" categoryName="New" parentCategory="automotiveDealers"> </loc:category> <loc:businesses name="dealers" type="java.util.Collection" categoryID="newAutomotiveDealers" country="US" state="CA" city="San Francisco"/> <loc:map name="dealerMap" type="oracle.panama.spatial.jsptags.beans.Map" xres="800" yres="600" points="dealers"> </loc:map> <SimpleImage src="<%= transformString(dealerMap.toString()) %>"/> <SimpleText> <loc:iterateBusinesses name="dealer" type="oracle.panama.model.Point" collection="dealers"> <SimpleTextItem> <%= transformString(dealer.toString()) %> </SimpleTextItem> </loc:iterateBusinesses> </SimpleText> </SimpleResult>
You can use the location API to write an adapter, which is a Java program that represents the location-based application to its end users.
This section provides information specific to creating an adapter for a location-based application. It does not describe adapter concepts or the general procedure for writing an adapter, because these topics are covered in the Oracle9iAS Wireless Developer's Guide.
In a geocoding application, the user is asked for an address and the adapter geocodes that address. Such an application can start by constructing a SimpleForm object for the address, as shown in Example 15-8.
Element sf = XML.makeElement(result, "SimpleForm"); sf.setAttribute("target", targetString); result.appendChild(sf); Element sfi = XML.makeElement(sf, "SimpleFormItem"); sfi.setAttribute("name", "adrLine1"); sfi.setAttribute("title", "address line 1"); sf.appendChild(sfi); sfi = XML.makeElement(sf, "SimpleFormItem"); sfi.setAttribute("name", "city"); sfi.setAttribute("title", "city"); sf.appendChild(sfi); sfi = XML.makeElement(sf, "SimpleFormItem"); sfi.setAttribute("name", "state"); sfi.setAttribute("title", "state"); sf.appendChild(sfi); sfi = XML.makeElement(sf, "SimpleFormItem"); sfi.setAttribute("name", "postalcode"); sfi.setAttribute("title", "postal code"); sf.appendChild(sfi); sfi = XML.makeElement(sf, "SimpleFormItem"); sfi.setAttribute("name", "country"); sfi.setAttribute("title", "country"); sf.appendChild(sfi);
The next time the adapter is invoked (after the user has entered values into the fields), the adapter can access the data, as shown in Example 15-9.
String adrLine1 = sr.getInputArguments().getInputValue("adrLine1"), city = sr.getInputArguments().getInputValue("city"), state = sr.getInputArguments().getInputValue("state"), postalcode = sr.getInputArguments().getInputValue("postalcode"), country = sr.getInputArguments().getInputValue("country");
Geocoding can be done with a call, as shown in Example 15-10. (Another format of SpatialManager.createlocation
, not shown in Example 15-10, specifies a point with longitude and latitude coordinates, in which case a Location
object is created but no geocoding is done.)
Location address = SpatialManager.createLocation( companyName, adrLine1, // "500 Oracle Parkway" null, city, // "Redwood City" state, // "CA" postalcode, // "94065" postalCodeExtension, // null country); // "US"
The resulting longitude and latitude values can be accessed as shown in Example 15-11.
address.getLongitude() address.getLatitude() address.getAddressLine1() address.getCity() address.getState()
Note that the getLongitude
and getLatitude
methods are inherited from the Point
interface.
To better adapt to local address formats, you can use the international address formatting options provided in the oracle.panama.spatial.intladdress
package. (For information about international address formats, see Section 15.1.3.1.4.) The number of steps necessary to have a user input an address increases by one: the user first has to select a country (address format) in order to be presented with a form for entering the address. Obviously, the form depends on the choice of country, so that the two separate steps cannot be merged to one.
Example 15-12 creates a drop-down SimpleFormSelect
element that lets the user select an address format (US, German, French, and so on).
protected void addAdrFormatChoice( Element result, String targetString) { Element sf = XML.makeElement(result, "SimpleForm"); sf.setAttribute("target", targetString); result.appendChild(sf); Element sfs = XML.makeElement(sf, "SimpleFormSelect"); sfs.setAttribute("name", "adrFormat"); sfs.setAttribute("title", "address format"); sf.appendChild(sfs); Iterator it = IntlAddressManager.getAddressFormats(); while(it.hasNext()) { String name = (String)it.next(); Element sfo = XML.makeElement(sfs, "SimpleFormOption"); sfo.setAttribute("value", name); sfs.appendChild(sfo); sfo.appendChild(XML.makeText(sfo, name)); } }
The next step is to provide a form requesting all address components relevant to the given address format. The components are determined dynamically based on the chosen country, as shown in Example 15-13.
protected void chooseAdr( Element result, String targetString, String adrFormat) { Element sf = XML.makeElement(result, "SimpleForm"); sf.setAttribute("target", targetString); result.appendChild(sf); Iterator addressComponentNames = IntlAddressManager.getAddressFormat(adrFormat).getComponentNames(); while(addressComponentNames.hasNext()) { Element sfi = XML.makeElement(sf, "SimpleFormItem"); String name = (String)addressComponentNames.next(); sfi.setAttribute("name", "adr_" + name.replace(' ', '_')); sfi.setAttribute("title", name); sf.appendChild(sfi); } }
Example 15-14 displays the result. The components to display and the number of lines depend on the chosen country.
protected void printResult( Element result, String targetString, String adrComp[], String adrFormat) { IntlAddress loc = IntlAddressManager.createAddress( adrFormat, adrComp); Element sf = XML.makeElement(result, "SimpleText"); result.appendChild(sf); Iterator lines = loc.getAddressLines(false, true); while(lines.hasNext()) { Element sfi = XML.makeElement(sf, "SimpleTextItem"); sfi.appendChild(XML.makeText(sfi, (String)lines.next())); sf.appendChild(sfi); } Element sfi = XML.makeElement(sf, "SimpleTextItem"); sfi.appendChild(XML.makeText(sfi, "lat: " + loc.getLatitude())); sf.appendChild(sfi); sfi = XML.makeElement(sf, "SimpleTextItem"); sfi.appendChild(XML.makeText(sfi, "lon: " + loc.getLongitude())); sf.appendChild(sfi); }
An adapter can work with location marks. Example 15-15 retrieves the location marks into an array. (Code not relevant to location marks is omitted from this example.)
public Element invoke (ServiceContext sr) throws AdapterException { ... LocationMark locMarks[] = sr.getSession().getUser().getLocationMarks(); ... }
Note that LocationMark
extends Location
(an address).
You can create an adapter that provides routing information between a start address and an end address that the user enters. The adapter must:
Example 15-16 sets the routing settings and options by constructing a RoutingSettings
object and specifying the resolution (height and width) of the resulting overview and maneuver maps.
RoutingSettings rS = new RoutingSettings(true, false); rS.setSecondaryOption(RoutingOption.overviewMapHeight, "600"); rS.setSecondaryOption(RoutingOption.overviewMapWidth, "800"); rS.setSecondaryOption(RoutingOption.maneuverMapHeight, "600"); rS.setSecondaryOption(RoutingOption.maneuverMapWidth, "800");
Example 15-17 computes the route, returning a RoutingResult
object.
RoutingResult rR = SpatialManager.getRouter().computeRoute( startLoc, endLoc, null, // via points rS, // routing options Locale.US);
Example 15-18 presents the resulting route to the user, displaying a list of maneuvers and maneuver maps, plus an overview map. (In this example, code specific to the routing API is shown in bold.)
Element sm = XML.makeElement(result, "SimpleMenu"); result.appendChild(sm); Element smi = XML.makeElement(sm, "SimpleMenuItem"); smi.setAttribute("target", rR.getOverviewMapURL()[0].toString()); // first of // possibly several overview maps sm.appendChild(smi); Text txt2 = XML.makeText(smi, "Map of complete route"); smi.appendChild(txt2); Maneuver man[] = rR.getManeuvers(); for(int maneuver = 0; maneuver < man.length; maneuver++) { Element sti = XML.makeElement(sm, "SimpleMenuItem"); sti.setAttribute("target", man[maneuver].getManeuverMapURL().toString()); sm.appendChild(sti); String str; str = man[maneuver].getNarrative(); Text txt = XML.makeText(sti, str); sti.appendChild(txt); }
In a typical mapping application, the user enters an address and wants to see a map. Example 15-19 gets the map image URL of an address (loc) to be mapped. (The variable loc of type Location contains an address that had been previously geocoded.)
String url = SpatialManager.getMapper().getMapURL( loc, oracle.panama.imagex.ImageFormats.GIF, 800, // width 600, // height false); // allow turning
In Example 15-19, the last parameter specifies whether or not the API can switch the width and height of the image to fit the map better to some mobile device screens. In this example, this option is disabled.
As alternatives to passing a single point object as the first parameter as shown in Example 15-19, you can pass an array of Point
objects or an object of type Location
(address) or YPBusiness
, which extend the Point
interface.
In a typical business directory (YP) application, the user enters a region specifying a country, state, and city, and wants to get businesses in some category, such as relating to wine tasting or wineries. The user must be asked for country, state, and city, and the application must determine the exact category and then all the relevant businesses.
The first step in determining the category is usually to ask the user for a category keyword (for example, wine) through a SimpleForm
object.
The next step is to determine all the categories that match the keyword, as shown in Example 15-20.
YPFinder ypF = SpatialManager.getYPFinder(); YPCategory cats[] = ypF.getCategoryAtRoot().getCategoriesMatchingName(keyword);
Example 15-21 shows a simple user interface that presents categories from which to choose. The user is presented a drop-down menu from which select the category that best matches what he or she is looking for.
Element sf = XML.makeElement(result, "SimpleForm"); sf.setAttribute("target", targetString); result.appendChild(sf); Element sfs = XML.makeElement(sf, "SimpleFormSelect"); sfs.setAttribute("name", "category"); sfs.setAttribute("title", "Business category"); sf.appendChild(sfs); for(int i = 0; i < cats.length; i++) { String name = cats[i].getFullyQualifiedName(); Element sfo = XML.makeElement(sfs, "SimpleFormOption"); sfo.setAttribute("value", name); sfs.appendChild(sfo); sfo.appendChild(XML.makeText(sfo, name)); }
When the adapter determines the fully qualified name of the chosen category, you can obtain the appropriate category, as shown in Example 15-22.
YPCategory cat = YPCategory.fromFullyQualifiedName(categoryNameString); YPBusiness b[] = SpatialManager.getYPFinder().getBusinessesInCity(cat, country, state, city, Locale.US);
The conversion in Example 15-22 from category to String
back to category is required because a drop-down menu lets you make a selection among String
objects, not among general objects.
To create an application based on the traffic services API, you must do the following:
CityInfo
, RouteInfo
, Point
, and Location
) for the query.
TrafficReporter
and summit the query.
TrafficReport
and process the information.
The rest of this section contains examples of typical operations. Example 15-23 performs a city-level query.
TrafficReporter reporter = SpatialManager.getTrafficReporter(); CityInfo c = new CityInfo("BOSTON", "MA", "US"); TrafficReport report = null; try{ report = reporter.getReportViaCity(c); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
Example 15-24 performs a route-level query without specifying a direction, and returns incidents in both directions.
RouteInfo r = new RouteInfo("US 3", null); try{ report = reporter.getReportViaRoute(r,c); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
Example 15-25 performs a route-level query for a specified direction (north).
try{ report = reporter.getReportViaRoute(r,TrafficReporter.North,c); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
Example 15-26 performs a route-level query for an area 10 miles around a specified longitude/latitude point.
p = SpatialManager.createPoint(-71.0607, 42.3659); try{ report = reporter.getReportViaLocation(p, 10, TrafficReporter.MILES, c); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
Example 15-27 performs a route-level query for an area 10 miles around a specified address.
Location loc = SpatialManager.createLocation(null, null, "839 Kearny Street", null, "San Francisco", "CA", null, null, "US"); try{ report = reporter.getReportViaAddress(loc, 10, TrafficReporter.MILES); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
Example 15-28 processes a traffic report to get useful information.
Calendar rTime = report.getReportTime(); TrafficIncident[] incidents = report.getIncidents(); if(incidents != null){ for(int i=0; i<incidents.length; i++){ TrafficIncident inc = incidents[i]; String desc = inc.getDescription(); String severity = inc.getSeverity(); String type = inc.getType(); TrafficRoute route = inc.getIncidentRoute(); String[] locations = inc.getLocationRange(); //text description if(locations.length == 2){ //a location range String exit1 = locations[0]; String exit2 = locations[1]; } else if(locations.length == 1){ String exit1 = locations[0]; //one location } Point geoLocation = inc.getIncidentLocation(); //lon/lat or lon/lat+radius Calendar[] tr = inc.getTimeRange(); } }
Example 15-29 returns a list of cities for which traffic support is provided.
TrafficCityManager manager = reporter.getCityManager(); CityInfo[] cities = null; try{ cities = manager.getActiveCities(); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
Example 15-30 returns a list of routes for which traffic support is provided in a specified city (San Francisco, California).
TrafficCityManager manager = reporter.getCityManager(); CityInfo sf = new CityInfo("SAN FRANCISCO", "CA", "US"); RouteInfo[] routes = null; try{ routes = manager.getRoutesInCity(sf); }catch(LBSException e){ System.out.println(e.getLocalizedMessage()); }
You can enable mobile positioning for individual users or groups of users of a location-based application. Mobile positioning of a user refers to associating a location with that user. When mobile positioning is enabled for a user, the user's current location, whether it is obtained dynamically from automatic positioning or from a default location mark, is used by Oracle9iAS Wireless to determine the visibility of location-based services or folders. A service or folder can be defined as location-dependent (as described in Section 15.4.4) by associating it with a system region or a previously defined custom region. A location-dependent service or folder appears in a user's portal only when the user's current location (from automatic positioning or from a default location mark) is within the associated region. For example, if the user's current location is in Boston, a Boston traffic information service would be visible to the user; otherwise, the service would not be visible to that user.
Mobile positioning can be manual or automatic:
Automatic positioning provides several options relating to frequency of position updates and user privacy.
This section describes manual and automatic positioning in more detail, and describes how to enable each type of positioning.
Manual positioning associates a specific location with the mobile application user. The location can be explicitly specified (such as the user entering an address or the name of a location mark), or it can be a default location mark for that user. A location mark is a position that is typically associated with longitude and latitude coordinates and that has a name. For example, an application user can create location marks named MyHome
and MyOffice
(for the person's home and office locations, respectively), and associate a geocoded address with each one. If this person designated MyHome
as the default location mark, the mobile application would consider the person's home address as the person's location.
If a user tries to set a default location mark that is not geocoded, a geocoding operation is performed before the location mark is made the default. If the geocoding operation fails, it is recommended that you not set that location mark as the default, because many capabilities (such as location-dependent service visibility) depend on the geocoded information of the default location mark.
For more information about location marks, see Section 15.1.5.
To enable manual positioning for a user, first set up any location marks that you might want to use. Use the API (LocationMark
class) or the Personalization Portal Web interface to create one of more location marks (if they do not already exist), and specify a location mark as the default for that user.
Note: If automatic positioning (described in Section 15.3.2) is turned off or if the positioning server is temporarily unavailable, manual positioning is used, and the user's default location mark is used. (Automatic positioning can be turned on and off using the Oracle9iAS Wireless webtool.) |
To enable manual positioning using the Personalization Portal interface, follow these steps:
Automatic positioning allows the user's location to be determined based on a position based on the location of the user's mobile device. You can determine how timely, and thus potentially how accurate, the location is by setting a positioning quality of service (QoS) value.
The Oracle9iAS Wireless API enables an application to access a mobile user's current location through the current session (see getCurrentLocation()
in the oracle.panama.rt.Session
interface). If automatic positioning is turned on in the system, the user's current physical location is returned from the mobile positioning system. If automatic positioning is turned off or if the positioning server is temporarily unavailable, the user's default location mark is returned.
Privacy and the security of privacy-related information are important concerns in a location acquisition system. The Oracle9iAS Wireless location services provide a privacy management component that allows users to view and edit their privacy settings, to enable and disable the positioning operation on themselves, and to authorize one or more people (a mobile community) to obtain positioning information on them within certain time frames. It also allows application developers to access these capabilities through a public API.
Automatic positioning is controlled by the mobile positioning framework, which is shown in Figure 15-7.
As Figure 15-7 shows:
The location cache is an area in memory that temporarily stores a mobile user's ID, the most recently acquired location information, and the time when that information was gathered. If the location cache is searched for a mobile positioning request, and if there is an entry in the cache for the user whose location is requested, the time difference between the cache entry time and the current request time is compared against the positioning quality of service level of the positioning request. (Positioning quality of service is explained in Section 15.3.2.2.)
When a positioning request is satisfied by information in the cache, no position sensing is required; that is, no network round-trip operation is required.
The positioning quality of service (QoS) value controls:
You can specify the positioning quality of service value in either of the following ways:
For the High, Medium, and Low values, the positioning framework determines an age value (number of seconds) in a heuristic manner.
There is a system default positioning quality of service level, which you can set. If a positioning quality of service level is not specified with a positioning request, the system default is used. The level can be set using the mobile positioning API (see Section 15.3.2.7).
The trade-off in selecting a positioning quality of service level is probable accuracy versus application performance. A value of 0 seconds or Exact guarantees that the actual current position is obtained; however, obtaining the actual position requires network round-trip to the service provider for each mobile positioning request. Such round-trip operations can slow application performance, especially if there are positioning requests for many users or many requests for the same user. You should use a value of 0 seconds or Exact only if the application always needs to know the actual position. A value of Low returns a location that is least likely to be accurate (unless the user has not moved at all); however, it increases the probability that the location will be obtained from the cache, eliminating the need for a network round-trip operation. If the user is not likely to move very far or fast, or if it is not important to know the actual current location, a value of Low may be best.
Automatic mobile position is queried by calling the Positioner.requestPosition
function. (Positioner
is a class in the oracle.panama.mp
package). A Positioner
object is based on one or more mobile positioning providers. As with other location service providers, a mobile positioning is configured by specifying information such as the name, version, URL, user name, and password.
However, a mobile positioning service differs from other location services in that in some cases positioning can only be handled by one specific provider, which is less likely to be true for other location based services. For example, if you request a map of California, several mapping providers are able to provide the map. However, if you request mobile position for a specific phone number (such as +4412345678), it is very likely only one provider can provide the position. A mobile ID (typically a phone number) usually identifies a wireless carrier and thus also determines the mobile positioning provider or providers. Therefore, application developers need to be able to get a positioner based on specific mobile positioning providers.
To meet different application needs, several getPositioner
signatures are provided in the MPManager
class:
An Internet portal may have subscribers from different carriers, and they may need to decide dynamically, based on the mobile ID, which provider to use at run time. This need is supported by mobile positioning provider selector hooks (implemented through the oracle.panama.mp.MPProviderSelector
interface).
A provider selector hook takes a mobile ID and returns an array of MPProvider
objects that can handle the positioning request. The default provider selector hook is provided by oracle.panama.mp.core.ProviderSelectorImpl
, which returns all providers in the system, which means by default the positioning framework does not attempt to choose a provider. A selector hook is used by a positioner when calling positioner.requestPosition
and is applicable for the getPositioner()
signature. If the providers are already specified when the positioner is called, the selector hook is not used.
The Oracle9iAS Wireless API enables an application to access a mobile user's current location through the current session (Session.getCurrentLocation()
). By default, the user's mobile ID (which is in the user's profile) is used to call the mobile positioning API to get the current position. However, if advanced users want to use a different value for positioning, they can write their own mobile ID hook by implementing the oracle.panama.rt.hook.MobileIDHook
interface. A mobile ID hook takes the current user's information and returns his or her mobile ID for positioning. If the automatic positioning fails, the system fails over to the user's default location mark as the current location.
Note that you do not have to implement either the provider selector hook or the mobile ID hook. If the default settings meet your needs, you can simply configure mobile positioning providers and call MPManager.getPositioner().requestPosition()
.
To summarize:
Positioner
can be a system default based on all mobile positioning providers configured in the system, or it can be customized based only on one or more specific providers.
Programs should check that the PositionResult
has a nonzero error code before using it.
Example 15-31 gets the user's position using system default providers and the default positioning quality of service.
Positioner positioner = MPManager.getPositioner(); PositionResult res = positioner.requestPosition("46708123456790"); Date timeStamp = res.getTimeStamp(); double lon = res.getPositionAreas()[0].getCenterPointLongitude(); double lat = res.getPositionAreas()[0].getCenterPointLatitude();
Example 15-32 shows two examples of getting the user's position and specifying a positioning quality of service level. The first example specifies the quality descriptively as high, and the second example specifies the quality as a number of seconds. (Section 15.3.2.2 explains the ways in which you can specify positioning quality of service.)
PositionResult res = positioner.requestPosition("46708123456790", ServiceQoS.HIGH_QUAL); PositionResult res = positioner.requestPosition("46708123456790", new ServiceQos(120));
Example 15-33 gets the user's position based on an array of specific providers.
MPProvider[] providers = new MPProvider[2]; providers[0] = MPManager.lookup("CellPoint", "1.2"); providers[1] = MPManager.lookup("Ericsson", "3.0"); Positioner positioner = MPManager.getPositioner(providers);
By default a user's location information can only be accessed by himself or herself. No other user has the right to access the user's location information. If users want to allow other users to access their location information, they must grant the positioning right to those users. A user granting the positioning right can later revoke the granted right.
The positioning right can also be granted for a certain duration or recurring interval of time. In many cases, users want to restrict the time periods to grant other users the right to access their location information. For example, users may want to grant coworkers this right from 9:00 am to 5:00 pm during weekdays, but they do not want coworkers to position them at night or during weekends. Users can specify such time restrictions as:
A mobile community is a collection of one or more users who can be granted or denied positioning rights. Mobile users can be assigned to one or more communities, and users can grant and deny positioning rights to communities. Users can view and manage their community information through the Personalization Portal, and application developers can access these capabilities through the public API.
The concept of mobile community is useful in many mobile application scenarios. For example, a project team can create a project community. A team member can grant to the project community the right of accessing to his or her location information instead of granting the right to each team member individually. For example, with mobile positioning and location-based alerts, a field service manager could know when service representatives are nearby and could contact them to get status updates or to have them respond to local problems.
The concept of visibility applies to communities and to members of communities. Visibility refers to the ability of system users to see that a community or member exists and to obtain some relevant information. Visibility can depend on the relationship of the requesting user to the community or member: for example, whether the requesting user has administrator privileges or is a member of the community in question. Visibility is implemented using calls to the privacy API, which is described in Section 15.3.2.8.
For any given request by a user to see information about a community or members of a community, the following visibility conditions are possible:
Different types of communities are supported, to accommodate different user requirements for visibility. When you create a community, you can specify the type of community, namely:
The following community operations are supported:
With the initial default privacy settings, the system does not have the right to position a user and temporarily store the user's position in the location cache, and write the user's location information to the cache log. However, the administrator can specify a different system default level of privacy -- and users can control their level or privacy through the Personalization Portal -- by using any of the following privacy directives, listed in decreasing order of privacy provided:
For example, with this directive a mobile user's movements might not be tracked, and the position at any time might be reported as the user's office or whatever location the service provider supplies.
For example, with the No Log directive, a mobile user's current position might be available, but earlier positions might not be available if they had discarded from the location cache.
Mobile device positioning is performed by calling the corresponding requestPosition
functions in the Positioner
class. The API allows application developers to specify the positioning quality of service (QoS) level. (These levels are explained in Section 15.3.2.2.)
Developers of mobile applications can manage the privacy capabilities through the location services privacy API. This section describes the privacy API and provides examples.
The LocationPrivacyManager
class handles all the location privacy-related operations, such as granting and revoking positioning rights, enabling and disabling positioning rights, setting and getting system privacy options, and checking if a user has right to position another user. The class also provides ways to retrieve the LocationPrivacyAuth
object, which stores information about a privacy authorization item.
A user can grant authorization to another user or to a mobile community using grantAuthorization
. The authorization can be temporarily disabled using disableAuthorization
. The disabled authorization can be recovered by using enableAuthorization
. The granted right can be permanently revoked using revokeAuthorization
. checkAuthorization
can be used to check whether a user has right to position another user at specific time.
All the privacy authorization operations are application-specific, which means that they only affects the application in which the operation is performed.
The CommunityManager class handles community-related operations, such as creating and deleting community and retrieving community information. Community operations specific to a single community are defined in the Community
interface.
The LocationPrivacyAuth
interface provides methods to retrieve information specific to a location authorization item, such as the authorization period, the service where the authorization occurs, the user granting the right, and the user receiving the right.
The Community
interface provides methods to retrieve information about the community object, add members to and remove members from the community, and set community attributes.
The AuthPeriod
class maintains a time range that is used when a user grants the positioning right to other users. An authorization period is composed of start date, end date, start time, end time, and exclusions. The class also provides a method contains to check whether a specific time falls in the time range represented by the class.
The LocationPrivacyException
class is a subclass of PanamaException
. It represents a location privacy-specific exception.
This section contains examples of the location services privacy API. The examples are taken from the sample adapters SampleCommunityManager.java and SampleFriendFinder.java is the iAS-wireless-home\sample\sampleadapter\mp\privacy
directory. These two sample adapters demonstrate the major capabilities of the privacy API.
Example 15-34 lists all communities of a specified type that are visible to a user.
CommunityManager commMan = CommunityManager.getInstance(); ... try{ ResultSetEnumeration comms = commMan.getVisibleCommunities(user,type); while (comms.hasNextElement()){ sfo = XML.makeElement(sfs,"SimpleFormOption"); oracle.panama.model.Community comm = (oracle.panama.model.Community)(comms.next()); sfo.setAttribute("value",String.valueOf(comm.getId())); txt = XML.makeText(sfo,comm.getCreator().getName()+":"+ comm.getName() ); sfo.appendChild(txt); sfs.appendChild(sfo); } }catch(Exception e){ throw new AdapterException(e); }
Example 15-35 grants the positioning right to a user or a community based on user input.
CommunityManager commMan = CommunityManager.getInstance(); LocationPrivacyManager priMan = LocationPrivacyManager.getInstance(); ... SimpleDateFormat ddf = new SimpleDateFormat("MM/dd/yyyy"); SimpleDateFormat tdf = new SimpleDateFormat("HH:mm"); Calendar startD,endD,startT,endT=null; try{ startD = Calendar.getInstance(); startD.setTime(ddf.parse(sdate)); endD = Calendar.getInstance(); endD.setTime(ddf.parse(edate)); startT = Calendar.getInstance(); startT.setTime(tdf.parse(stime)); endT = Calendar.getInstance(); endT.setTime(tdf.parse(etime)); }catch(ParseException e){ showError(result,sr,"Illegal Date Format","&grantmenu=y"); return; } StringTokenizer st = new StringTokenizer(excl,","); String exclDate = null; byte exclusions=0; while (st.hasMoreTokens()) { exclDate=st.nextToken(); if ("Mon".equals(exclDate)) exclusions =(byte)(exclusions|AuthPeriod.MONDAY); else if ("Tue".equals(exclDate)) exclusions =(byte)(exclusions | AuthPeriod.TUESDAY); else if ("Wed".equals(exclDate)) exclusions =(byte)(exclusions | AuthPeriod.WEDNESDAY); else if ("Thu".equals(exclDate)) exclusions =(byte)(exclusions | AuthPeriod.THURSDAY); else if ("Fri".equals(exclDate)) exclusions =(byte)(exclusions | AuthPeriod.FRIDAY); else if ("Sat".equals(exclDate)) exclusions =(byte)(exclusions | AuthPeriod.SATURDAY); else if ("Sun".equals(exclDate)) exclusions =(byte)(exclusions | AuthPeriod.SUNDAY); else { showError(result,sr,"Illegal Exclusions.", "&grantmenu=y"); return; } } AuthPeriod period = new AuthPeriod(startD,endD, startT,endT, exclusions); oracle.panama.model.Community commObj = null; User posUserObj = null; try{ if (community!=null && !community.equals("")){ commObj = commMan.getCommunity(Long.parseLong(community)); priMan.grantAuthorization(service,owner,commObj,period); } else{ posUserObj = services.lookupUser(positionUser); priMan.grantAuthorization(service,owner,posUserObj,period); } }catch(PanamaException e){ throw new AdapterException(e); }
The region modeling tool lets administrators of a wireless portal service manage regions and make a service or folder location-dependent. When you create a service or a folder, you can specify that it is location-dependent by associating a system region or a previously created custom region with the service or folder. A location-dependent service or folder appears is a user's portal only when the user's current location (either from automatic mobile positioning or from the user's default location mark) is within the specified region.
A region is simply a geographic entity, or location. A region can be small (such as a street address) or large (such as a country). A region can be represented by a point, as is often done for addresses and locations of interest (such as airports and museums), or by a polygon, as is usually done for states and countries.
You may want to define specific regions for a variety of applications and services, such as:
Your company may provide many specialized services, and users may be able to subscribe to and pay for individual services tied to regions. For example, one user might subscribe to city guides for the entire United States, while another user might subscribe only to city guides for southeastern states.
To implement the city guide example, you could do the following:
In another example scenario, several services may be relevant to a region, in which case you can create a location-dependent folder and place the relevant services in that folder (instead of designating each service as location-dependent on the region). For example, assume that you have ATM Locator, Flight Gate Information, Airport Parking Information, and Taxi Finder services associated with a region named Airport, and that you have Printer Finder, Conference Room Scheduler, and Cafeteria Menu services associated with a region named Office. In this case, you can create two location-dependent folders named Airport and Office, and associate them with the Airport and Office regions, respectively.
Regions are stored in folders. Folders can be in a hierarchy (that is, there can be folders in folders). There are two top-level folders: System-Defined Regions and Custom Regions.
The region modeling tool's Web interface is part of the Oracle9iAS Wireless Service Designer, which is part of the webtool. In the Service Designer, click the Regions tab to display the region modeling tool, shown in Figure 15-8.
The Web browser window initially displays the top level of the region hierarchy, with two entries: system-defined regions and custom regions. You can find regions, and you can select regions for viewing or for adding to a collection from which you create a custom region.
To find a region, enter a character string that is in its name to search by name, or enter a number to search by ID (by region ID). Specify to search all regions or only under current region (the currently selected region), then click Go.
To select a region to perform an operation on it, click the box to the left of its icon and name. (To deselect a selected item, click the box.) You can select all regions in the current display by clicking Select All, and deselect all regions in the current display by clicking Select None.
To perform an operation on the selected region or regions, click the command text link or button shown in Table 15-12.
When you create a service and make it location dependent, you must specify the region for which the service applies or is relevant. Before you can specify the region, it must already exist, either as a system-defined region or a custom region. If it is a custom region, it must have been created using the region modeling tool, using one of the methods described in Section 15.4.3 for creating a region.
To associate a region with a service, you must specify Location Dependent when creating the service, and you must click the flashlight icon to select the region. Figure Figure 15-9 shows an example of a service specified as location dependent.
When you click the flashlight icon, a window is displayed showing the top of the region hierarchy. You can select any region (but only one region) in the region hierarchy.
To associate the selected region with the service, click Done.
The region modeling tool is installed with an extensive set of data for the United States, as well as country data for many countries. However, you can add data about other countries, states, cities, and so on by adding rows to the tables where the region data is stored. For example, you could add a row for each state in India to the STATE table. If you are careful and know what you are doing, you can also modify certain data in those tables, such as editing the DESCRIPTION column values for certain cities or states.
Region data is stored in the Oracle9iAS Wireless repository in the tables listed in Table 15-13.
Table Name | Contains Information About |
---|---|
CONTINENT |
Continents |
COUNTRY |
Countries |
STATE |
States |
COUNTY |
Counties |
CITY |
Cities |
POSTALCODE |
Postal codes |
USERDEFINED |
Custom regions |
To see the definition of any of these tables, use the SQL statement DESCRIBE. Example 15-36 shows the DESCRIBE statement output with information about all of the tables.
SQL> DESCRIBE continent; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(100) REFCNT NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY SQL> DESCRIBE country; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(300) REFCNT NUMBER CONT_ID NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY SQL> DESCRIBE state; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(400) REFCNT NUMBER ABBR VARCHAR2(32) CONT_ID NUMBER COUNTRY_ID NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY SQL> DESCRIBE county; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(400) REFCNT NUMBER CONT_ID NUMBER COUNTRY_ID NUMBER STATE_ID NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY SQL> DESCRIBE city; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(400) REFCNT NUMBER CONT_ID NUMBER COUNTRY_ID NUMBER STATE_ID NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY MIN_LON NUMBER MIN_LAT NUMBER MAX_LON NUMBER MAX_LAT NUMBER SQL> DESCRIBE postalcode; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(400) REFCNT NUMBER CONT_ID NUMBER COUNTRY_ID NUMBER STATE_ID NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY SQL> DESCRIBE userdefined; Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(200) REFCNT NUMBER TYPE NUMBER PARENT_FOLDER_ID NUMBER DESCRIPTION VARCHAR2(2000) GEOMETRY MDSYS.SDO_GEOMETRY
You can use the SQL statement INSERT to insert rows into the region tables. The following considerations apply when you are inserting region data:
idseq.nextval
to generate the ID column value whenever you insert a new row, as shown in Example 15-37. The idseq sequence is created automatically during the iAS installation; you should not create it.
Example 15-37 shows an INSERT statement to insert a row for Concord, Massachusetts into the CITY table. It assumes that the geometry representing Concord exists in another table named MY_CITIES.
DECLARE city_geom MDSYS.SDO_GEOMETRY; BEGIN -- Populate geometry variable with city geometry from another table. SELECT m.geometry into city_geom FROM my_cities m WHERE m.name = 'Concord'; -- Insert into the CITY table. INSERT INTO CITY VALUES ( idseq.nextval, 'Concord', 0, 5004, -- continent ID for North America 5006, -- country ID for USA 5028, -- state ID for Massachusetts 'The historic town of Concord', city_geom, -71.37, -- minimum longitude 42.46, -- minimum latitude -71.36, -- maximum longitude 42.47); -- maximum latitude END; /
The minimum and maximum longitude and latitude values in the CITY table are required and are used by traffic support services. The minimum longitude and latitude values identify the lower-left corner, and the maximum longitude and latitude values identify the upper-right corner, of the bounding rectangle.
The region modeling tool is based on the region modeling API, which is implemented through the RegionModel
interface of the oracle.panama.spatial.region
package. The RegionModel
interface includes methods for getting the postal code, state, and country, and for determining different kinds of interaction among regions.
|
Copyright © 2002 Oracle Corporation. All Rights Reserved. |
|